• CEF3资源重定向、读取加密资源、读取zip资源


    网上关于CEF3读取加密资源的中文资料特别少~,所以我就来写一篇教程吧

     

    实际应用: PC版的“网易云音乐”就是把H5资源加密成zip文件,启动时动态读取。

    原理:

    让自己的MyClientHandler来继承 CefRequestHandler这个抽象类,然对其下面的纯虚函数进行重写

    simple_handler.h:

    1.  
      #include "include/wrapper/cef_resource_manager.h"
    2.  
      class SimpleHandler : public CefClient,
    3.  
      public CefDisplayHandler,
    4.  
      public CefLifeSpanHandler,
    5.  
      public CefRequestHandler{
    6.  
       
    7.  
      virtual CefRefPtr<CefRequestHandler> GetRequestHandler() OVERRIDE { return this; }
    8.  
       
    9.  
      // CefRequestHandler methods:
    10.  
      virtual cef_return_value_t OnBeforeResourceLoad(
    11.  
      CefRefPtr<CefBrowser> browser,
    12.  
      CefRefPtr<CefFrame> frame,
    13.  
      CefRefPtr<CefRequest> request,
    14.  
      CefRefPtr<CefRequestCallback> callback) OVERRIDE;
    15.  
      virtual CefRefPtr<CefResourceHandler> GetResourceHandler(
    16.  
      CefRefPtr<CefBrowser> browser,
    17.  
      CefRefPtr<CefFrame> frame,
    18.  
      CefRefPtr<CefRequest> request) OVERRIDE;
    19.  
       
    20.  
      private:
    21.  
      // Manages the registration and delivery of resources.
    22.  
      CefRefPtr<CefResourceManager> resource_manager_;

    simple_handler.cc:

    1.  
      #include "include/wrapper/cef_stream_resource_handler.h"
    2.  
       
    3.  
       
    4.  
      namespace {
    5.  
       
    6.  
      SimpleHandler* g_instance = NULL;
    7.  
       
    8.  
      } // namespace
    9.  
       
    10.  
       
    11.  
       
    12.  
      // Demonstrate a custom Provider implementation by dumping the request contents.
    13.  
      class RequestDumpResourceProvider : public CefResourceManager::Provider {
    14.  
      public:
    15.  
      explicit RequestDumpResourceProvider(const std::string& url) : url_(url) {
    16.  
      DCHECK(!url.empty());
    17.  
      }
    18.  
       
    19.  
      bool OnRequest(scoped_refptr<CefResourceManager::Request> request) OVERRIDE
    20.  
      {
    21.  
      CEF_REQUIRE_IO_THREAD();
    22.  
       
    23.  
      const std::string& url = request->url();
    24.  
      if (url != url_)
    25.  
      {
    26.  
      // Not handled by this provider.
    27.  
      return false;
    28.  
      }
    29.  
       
    30.  
      //const std::string& dump = shared::DumpRequestContents(request->request());
    31.  
      std::string str =
    32.  
      //"<html><body bgcolor="white"><pre>" + dump + "</pre></body></html>";
    33.  
      "<html><body bgcolor="white"><pre>123123123123</pre></body></html>";
    34.  
      CefRefPtr<CefStreamReader> stream = CefStreamReader::CreateForData(
    35.  
      static_cast<void*>(const_cast<char*>(str.c_str())), str.size());
    36.  
      DCHECK(stream.get());
    37.  
      request->Continue(new CefStreamResourceHandler("text/html", stream));
    38.  
      return true;
    39.  
      }
    40.  
       
    41.  
      private:
    42.  
      std::string url_;
    43.  
       
    44.  
      DISALLOW_COPY_AND_ASSIGN(RequestDumpResourceProvider);
    45.  
      };
    46.  
       
    47.  
      // Add example Providers to the CefResourceManager.
    48.  
      void SetupResourceManager(CefRefPtr<CefResourceManager> resource_manager)
    49.  
      {
    50.  
      if (!CefCurrentlyOn(TID_IO))
    51.  
      {
    52.  
      // Execute on the browser IO thread.
    53.  
      CefPostTask(TID_IO, base::Bind(SetupResourceManager, resource_manager));
    54.  
      return;
    55.  
      }
    56.  
       
    57.  
      // Add the Provider for dumping request contents.
    58.  
      resource_manager->AddProvider(
    59.  
      new RequestDumpResourceProvider("http://www.baidu.com/"), 0,
    60.  
      std::string());
    61.  
      }
    62.  
       
    63.  
       
    64.  
       
    65.  
      SimpleHandler::SimpleHandler(bool use_views)
    66.  
      : use_views_(use_views), is_closing_(false) {
    67.  
      DCHECK(!g_instance);
    68.  
      g_instance = this;
    69.  
       
    70.  
      //安装资源管理器
    71.  
      resource_manager_ = new CefResourceManager();
    72.  
      SetupResourceManager(resource_manager_);
    73.  
      }

    至此,打开http://www.baidu.com,都会被拦截下来,显示123123123123 

    实际应用- 带zip解压解密版:

    simple_handler.h:

    1.  
      #include "include/wrapper/cef_resource_manager.h"
    2.  
       
    3.  
      #pragma region 使用Zip管理类
    4.  
      #include "ResourcesManager/ZipFolder.h"
    5.  
      #pragma endregion
    6.  
       
    7.  
       
    8.  
      class SimpleHandler : public CefClient,
    9.  
      public CefDisplayHandler,
    10.  
      public CefLifeSpanHandler,
    11.  
      public CefRequestHandler{
    12.  
       
    13.  
      virtual CefRefPtr<CefRequestHandler> GetRequestHandler() OVERRIDE { return this; }
    14.  
       
    15.  
      // CefRequestHandler methods:
    16.  
      virtual cef_return_value_t OnBeforeResourceLoad(
    17.  
      CefRefPtr<CefBrowser> browser,
    18.  
      CefRefPtr<CefFrame> frame,
    19.  
      CefRefPtr<CefRequest> request,
    20.  
      CefRefPtr<CefRequestCallback> callback) OVERRIDE;
    21.  
      virtual CefRefPtr<CefResourceHandler> GetResourceHandler(
    22.  
      CefRefPtr<CefBrowser> browser,
    23.  
      CefRefPtr<CefFrame> frame,
    24.  
      CefRefPtr<CefRequest> request) OVERRIDE;
    25.  
       
    26.  
      private:
    27.  
      // Manages the registration and delivery of resources.
    28.  
      CefRefPtr<CefResourceManager> resource_manager_;
    29.  
      ZipFolder m_zip;

    simple_handler.cc:

    1.  
      #include "include/wrapper/cef_stream_resource_handler.h"
    2.  
       
    3.  
       
    4.  
      namespace {
    5.  
       
    6.  
      SimpleHandler* g_instance = NULL;
    7.  
       
    8.  
      } // namespace
    9.  
       
    10.  
       
    11.  
       
    12.  
      // Demonstrate a custom Provider implementation by dumping the request contents.
    13.  
      class RequestDumpResourceProvider : public CefResourceManager::Provider {
    14.  
      public:
    15.  
      explicit RequestDumpResourceProvider(ZipFolder *pZip)
    16.  
      {
    17.  
      m_pZip = pZip;
    18.  
      }
    19.  
       
    20.  
      //去除URL中的百分号%转码
    21.  
      std::string UrlDecode(std::string &SRC)
    22.  
      {
    23.  
      std::string ret;
    24.  
      char ch;
    25.  
      int ii;
    26.  
      for (size_t i = 0; i < SRC.length(); i++) {
    27.  
      if (int(SRC[i]) == 37) {
    28.  
      sscanf(SRC.substr(i + 1, 2).c_str(), "%x", &ii);
    29.  
      ch = static_cast<char>(ii);
    30.  
      ret += ch;
    31.  
      i = i + 2;
    32.  
      }
    33.  
      else {
    34.  
      ret += SRC[i];
    35.  
      }
    36.  
      }
    37.  
      return (ret);
    38.  
      }
    39.  
      bool OnRequest(scoped_refptr<CefResourceManager::Request> request) OVERRIDE
    40.  
      {
    41.  
      CEF_REQUIRE_IO_THREAD();
    42.  
       
    43.  
      std::string url = request->url();
    44.  
      //if (url != url_)
    45.  
      //{
    46.  
      // // Not handled by this provider.
    47.  
      // return false;
    48.  
      //}
    49.  
       
    50.  
      url = UrlDecode(url); //去除百分号
    51.  
      url = UTF8_To_string(url); //UTF8网址转回ANSI编码文本
    52.  
       
    53.  
      //把http://、https://和file:///去掉
    54.  
      if (url.substr(0, 7) == "http://")
    55.  
      {
    56.  
      url.erase(0, 7);
    57.  
      }
    58.  
      else if (url.substr(0, 8) == "https://")
    59.  
      {
    60.  
      url.erase(0, 8);
    61.  
      }
    62.  
      else if (url.substr(0,8) == "file:///")
    63.  
      {
    64.  
      url.erase(0, 8);
    65.  
      }
    66.  
       
    67.  
      string strMyPath2 = g_strMyPath;
    68.  
      strMyPath2 = replace_all_distinct(strMyPath2, "\", "/"); //把自身路径的转成/
    69.  
       
    70.  
      url = replace_all_distinct(url, strMyPath2, "");
    71.  
       
    72.  
      //如果最后一个字符是/也去掉
    73.  
      //if (url.substr(url.length()-1) == "/")
    74.  
      //{
    75.  
      // url = url.substr(0, url.length() - 1);
    76.  
      //}
    77.  
       
    78.  
       
    79.  
      //在map资源图中寻找
    80.  
      std::map<std::string, MyResourcesBuf*>::iterator it;
    81.  
      it = m_pZip->m_mapResources.find(url);
    82.  
      if (it == m_pZip->m_mapResources.end())
    83.  
      {
    84.  
      return false;
    85.  
      }
    86.  
       
    87.  
      //const std::string& dump = shared::DumpRequestContents(request->request());
    88.  
      //std::string str =
    89.  
      //"<html><body bgcolor="white"><pre>" + dump + "</pre></body></html>";
    90.  
      // "<html><body bgcolor="white"><pre>123123123123</pre></body></html>";
    91.  
       
    92.  
       
    93.  
      CefRefPtr<CefStreamReader> stream = CefStreamReader::CreateForData(
    94.  
      static_cast<void*>(it->second->lpBuf), it->second->nBufSize);
    95.  
      DCHECK(stream.get());
    96.  
      request->Continue(new CefStreamResourceHandler(it->second->lpType, stream));
    97.  
      return true;
    98.  
      }
    99.  
       
    100.  
      private:
    101.  
      ZipFolder *m_pZip;
    102.  
       
    103.  
      DISALLOW_COPY_AND_ASSIGN(RequestDumpResourceProvider);
    104.  
      };
    105.  
       
    106.  
      // Add example Providers to the CefResourceManager.
    107.  
      void SetupResourceManager(CefRefPtr<CefResourceManager> resource_manager)
    108.  
      {
    109.  
      if (!CefCurrentlyOn(TID_IO))
    110.  
      {
    111.  
      // Execute on the browser IO thread.
    112.  
      CefPostTask(TID_IO, base::Bind(SetupResourceManager, resource_manager));
    113.  
      return;
    114.  
      }
    115.  
       
    116.  
      // Add the Provider for dumping request contents.
    117.  
      resource_manager->AddProvider(
    118.  
      new RequestDumpResourceProvider(pZip), 0,
    119.  
      std::string());
    120.  
      }
    121.  
       
    122.  
       
    123.  
       
    124.  
      SimpleHandler::SimpleHandler(bool use_views)
    125.  
      : use_views_(use_views), is_closing_(false) {
    126.  
      DCHECK(!g_instance);
    127.  
      g_instance = this;
    128.  
       
    129.  
      //从zip文件中加载H5资源
    130.  
      std::string strMyZipFilePath = g_strMyPath + "native.ntpk"; //模仿PC网易云客户端
    131.  
      m_zip.LoadZipToMem(strMyZipFilePath,false, "123",16); //解密zip
    132.  
       
    133.  
      resource_manager_ = new CefResourceManager();
    134.  
      SetupResourceManager(resource_manager_, &m_zip);
    135.  
       
    136.  
       
    137.  
      }

     ZipFolder.h(注意,只能操作不带密码的zip压缩包,不要问我为什么,因为zlib不支持

    1.  
      #pragma once
    2.  
      #define WRITEBUFFERSIZE 16384
    3.  
      #include <iostream>
    4.  
      #include <map>
    5.  
       
    6.  
       
    7.  
      #pragma region 使用zlib库
    8.  
      #include "../../zlib/include/zlib.h"
    9.  
      #include "../../zlib/include/zip.h"
    10.  
      #include "../../zlib/include/unzip.h"
    11.  
       
    12.  
      #ifdef _DEBUG
    13.  
      #pragma comment(lib,"zlib/lib/x86/Debug/zlib.lib")
    14.  
      #else
    15.  
      #pragma comment(lib,"zlib/lib/x86/Release/zlib.lib")
    16.  
      #endif
    17.  
      #pragma endregion
    18.  
       
    19.  
       
    20.  
      struct MyResourcesBuf
    21.  
      {
    22.  
      void *lpBuf;
    23.  
      int nBufSize;
    24.  
      char *lpType; //资源类型
    25.  
      };
    26.  
       
    27.  
      class ZipFolder
    28.  
      {
    29.  
      public:
    30.  
      ZipFolder();
    31.  
      virtual ~ZipFolder();
    32.  
       
    33.  
      public:
    34.  
       
    35.  
      //压缩文件夹
    36.  
      bool Zip_Folder(
    37.  
      std::string strFolder, //将要被压缩的文件夹路径
    38.  
      std::string strZipFilePath, //将要生成的zip文件路径
    39.  
      std::string strZipFileComment, //将要生成的zip文件注释,可以为NULL
    40.  
      bool bWriteFolderChangeDate, //是否写入文件夹修改日期
    41.  
      bool bWriteFileChangeDate); //是否写入文件夹里的文件修改日期
    42.  
       
    43.  
       
    44.  
       
    45.  
      //解压缩zip文件(支持多级文件夹)
    46.  
      bool UnZip(
    47.  
      std::string strZipFilePath, //将要被解压的zip文件路径
    48.  
      std::string strExistingFolder); //解压文件存放的路径,路径必须存在
    49.  
       
    50.  
      //解压zip内容到内存
    51.  
      std::map<std::string, MyResourcesBuf*> m_mapResources;
    52.  
      bool LoadZipToMem(std::string strZipFilePath, //将要被解压读取的zip文件路径
    53.  
      bool use3DES_ECB_Decrypt = false, //解压读取时是否使用3DES ECB模式解密
    54.  
      char* lpsz3DES_ECB_KEY = NULL, //3DES_ECB模式的KEY
    55.  
      int n3DES_ECB_KEY_LEN = 0); //3DES_ECB模式的KEY 长度
    56.  
       
    57.  
       
    58.  
       
    59.  
      private:
    60.  
       
    61.  
      bool ExistFolder(char *lpszFolder);
    62.  
      bool DetectFolderFile(char *szFolder);
    63.  
       
    64.  
      bool ZipTraversalFolder(
    65.  
      zipFile zip,
    66.  
      std::string strSourceFolder,
    67.  
      std::string strInZipFolder,
    68.  
      bool bWriteFolderChangeDate,
    69.  
      bool bWriteFileChangeDate);
    70.  
       
    71.  
      int CreateDir(char *pszDir);
    72.  
       
    73.  
      };

     

    ZipFolder.cpp (将zip解压读取到内存后,默认不进行任何解密操作,进行3DES解密部分的算法代码太长了就不粘贴了,屏蔽掉即可完美运行)

    1.  
      // ZipFolder.cpp: implementation of the ZipFolder class.
    2.  
      //
    3.  
      //////////////////////////////////////////////////////////////////////
    4.  
       
    5.  
      #include "ZipFolder.h"
    6.  
      #include <windows.h>
    7.  
       
    8.  
      #include <time.h>
    9.  
      #include <utility>
    10.  
      #include <algorithm>
    11.  
       
    12.  
      #pragma region 使用3DES库
    13.  
      #include "../../DES/DES.h"
    14.  
      #pragma endregion
    15.  
       
    16.  
       
    17.  
      //////////////////////////////////////////////////////////////////////
    18.  
      // Construction/Destruction
    19.  
      //////////////////////////////////////////////////////////////////////
    20.  
       
    21.  
      ZipFolder::ZipFolder()
    22.  
      {
    23.  
       
    24.  
      }
    25.  
       
    26.  
      ZipFolder::~ZipFolder()
    27.  
      {
    28.  
       
    29.  
      }
    30.  
       
    31.  
      bool ZipFolder::Zip_Folder(
    32.  
      std::string strFolder,
    33.  
      std::string strZipFilePath,
    34.  
      std::string strZipFileComment,
    35.  
      bool bWriteFolderChangeDate,
    36.  
      bool bWriteFileChangeDate)
    37.  
      {
    38.  
      if (strFolder.substr(strFolder.length() - 1) != "\")
    39.  
      {
    40.  
      //补上斜杠
    41.  
      strFolder += "\";
    42.  
      }
    43.  
      if (!ExistFolder((char*)strFolder.c_str()))
    44.  
      {
    45.  
      return false;
    46.  
      }
    47.  
       
    48.  
      if (!DetectFolderFile((char*)strFolder.c_str()))
    49.  
      {
    50.  
      return FALSE;
    51.  
      }
    52.  
       
    53.  
      zipFile zip = zipOpen(strZipFilePath.c_str(), APPEND_STATUS_CREATE);
    54.  
      if (zip == NULL)
    55.  
      {
    56.  
      //如果zip文件已存在
    57.  
      zip = zipOpen(strZipFilePath.c_str(), APPEND_STATUS_ADDINZIP);
    58.  
      if (zip == NULL)
    59.  
      {
    60.  
      return false;
    61.  
      }
    62.  
      }
    63.  
       
    64.  
      bool bRet = ZipTraversalFolder(
    65.  
      zip,
    66.  
      strFolder,
    67.  
      "",
    68.  
      bWriteFolderChangeDate,
    69.  
      bWriteFileChangeDate);
    70.  
       
    71.  
      zipClose(zip, strZipFileComment.c_str());
    72.  
      return bRet;
    73.  
      }
    74.  
       
    75.  
      bool ZipFolder::UnZip(
    76.  
      std::string strZipFilePath,
    77.  
      std::string strExistingFolder)
    78.  
      {
    79.  
      if (strExistingFolder.substr(strExistingFolder.length() - 1) != "\")
    80.  
      {
    81.  
      //补上斜杠
    82.  
      strExistingFolder += "\";
    83.  
      }
    84.  
      unzFile zip = unzOpen(strZipFilePath.c_str());
    85.  
      if (zip == NULL)
    86.  
      {
    87.  
      return false;
    88.  
      }
    89.  
      unz_global_info GlobalInfo;
    90.  
      if (unzGetGlobalInfo(zip, &GlobalInfo) != UNZ_OK)
    91.  
      {
    92.  
      unzClose(zip);
    93.  
      return false;
    94.  
      }
    95.  
      if (unzGoToFirstFile(zip) != UNZ_OK)
    96.  
      {
    97.  
      unzClose(zip);
    98.  
      return false;
    99.  
      }
    100.  
      for (int i = 0; i < GlobalInfo.number_entry; i++)
    101.  
      {
    102.  
      unz_file_info FileInfo;
    103.  
      char szFileName[MAX_PATH] = { 0 };
    104.  
      char szExtraField[MAX_PATH] = { 0 };
    105.  
      char szComment[MAX_PATH] = { 0 };
    106.  
      if (unzGetCurrentFileInfo(zip, &FileInfo, szFileName, MAX_PATH, szExtraField, MAX_PATH, szComment, MAX_PATH) != UNZ_OK)
    107.  
      {
    108.  
      unzClose(zip);
    109.  
      return FALSE;
    110.  
      }
    111.  
      // MessageBox(NULL,szFileName,"Zip中的文件名",0);
    112.  
       
    113.  
      if (std::string(szFileName).substr(std::string(szFileName).length() - 1) == "/")
    114.  
      {
    115.  
      //当zip里是目录的时候
    116.  
       
    117.  
      // MessageBox(NULL,szFileName,"经过处理的目录名",0);
    118.  
      std::string strNewDir = strExistingFolder;
    119.  
      strNewDir += szFileName;
    120.  
      //MessageBox(NULL,szDirectory,"要创建的目录名",0);
    121.  
      if (CreateDir((char*)strNewDir.c_str()) == -1)
    122.  
      {
    123.  
      unzClose(zip);
    124.  
      return FALSE;
    125.  
      }
    126.  
      }
    127.  
      else
    128.  
      {
    129.  
       
    130.  
      std::string strNewFile = strExistingFolder;
    131.  
      strNewFile += szFileName;
    132.  
      //MessageBox(NULL,szNewFileName,"即将新建的文件名",0);
    133.  
       
    134.  
      if (unzOpenCurrentFile(zip) != UNZ_OK)
    135.  
      {
    136.  
      unzClose(zip);
    137.  
      return FALSE;
    138.  
      }
    139.  
      HANDLE hNewFile = CreateFileA(strNewFile.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
    140.  
      if (hNewFile == INVALID_HANDLE_VALUE)
    141.  
      {
    142.  
      unzCloseCurrentFile(zip);
    143.  
      unzClose(zip);
    144.  
      return FALSE;
    145.  
      }
    146.  
      LARGE_INTEGER lisize = { 0 };
    147.  
      lisize.QuadPart = 0;
    148.  
      lisize.LowPart = SetFilePointer(hNewFile, lisize.LowPart, &lisize.HighPart, FILE_BEGIN);
    149.  
      if (lisize.LowPart == INVALID_SET_FILE_POINTER && GetLastError() != NO_ERROR)
    150.  
      {
    151.  
      unzCloseCurrentFile(zip);
    152.  
      unzClose(zip);
    153.  
      CloseHandle(hNewFile);
    154.  
      return FALSE;
    155.  
      }
    156.  
      char szFileDataBuf[WRITEBUFFERSIZE];
    157.  
      ULONGLONG uCycles = FileInfo.uncompressed_size / WRITEBUFFERSIZE;
    158.  
      for (ULONGLONG i = 0; i <= uCycles; i++)
    159.  
      {
    160.  
      ZeroMemory(szFileDataBuf, WRITEBUFFERSIZE);
    161.  
      int nRead = unzReadCurrentFile(zip, szFileDataBuf, WRITEBUFFERSIZE);
    162.  
      if (nRead == 0)
    163.  
      {
    164.  
      break;
    165.  
      }
    166.  
      else if (nRead <= 0)
    167.  
      {
    168.  
      CloseHandle(hNewFile);
    169.  
      unzCloseCurrentFile(zip);
    170.  
      unzClose(zip);
    171.  
      return FALSE;
    172.  
      }
    173.  
      DWORD dwWrite = 0;
    174.  
      if (!WriteFile(hNewFile, szFileDataBuf, nRead, &dwWrite, NULL))
    175.  
      {
    176.  
      CloseHandle(hNewFile);
    177.  
      unzCloseCurrentFile(zip);
    178.  
      unzClose(zip);
    179.  
      return FALSE;
    180.  
      }
    181.  
      }
    182.  
      CloseHandle(hNewFile);
    183.  
      }
    184.  
      unzCloseCurrentFile(zip);
    185.  
      unzGoToNextFile(zip);
    186.  
      }
    187.  
      unzClose(zip);
    188.  
      return TRUE;
    189.  
      }
    190.  
       
    191.  
       
    192.  
      bool ZipFolder::LoadZipToMem(std::string strZipFilePath,
    193.  
      bool use3DES_ECB_Decrypt, char* lpsz3DES_ECB_KEY,int n3DES_ECB_KEY_LEN)
    194.  
      {
    195.  
      unzFile zip = unzOpen(strZipFilePath.c_str());
    196.  
      if (zip == NULL)
    197.  
      {
    198.  
      return false;
    199.  
      }
    200.  
      unz_global_info GlobalInfo;
    201.  
      if (unzGetGlobalInfo(zip, &GlobalInfo) != UNZ_OK)
    202.  
      {
    203.  
      unzClose(zip);
    204.  
      return false;
    205.  
      }
    206.  
      if (unzGoToFirstFile(zip) != UNZ_OK)
    207.  
      {
    208.  
      unzClose(zip);
    209.  
      return false;
    210.  
      }
    211.  
      for (int i = 0; i < GlobalInfo.number_entry; i++)
    212.  
      {
    213.  
      unz_file_info FileInfo;
    214.  
      char szFileName[MAX_PATH] = { 0 };
    215.  
      char szExtraField[MAX_PATH] = { 0 };
    216.  
      char szComment[MAX_PATH] = { 0 };
    217.  
      if (unzGetCurrentFileInfo(zip, &FileInfo, szFileName, MAX_PATH, szExtraField, MAX_PATH, szComment, MAX_PATH) != UNZ_OK)
    218.  
      {
    219.  
      unzClose(zip);
    220.  
      return FALSE;
    221.  
      }
    222.  
      // MessageBox(NULL,szFileName,"Zip中的文件名",0);
    223.  
       
    224.  
      if (std::string(szFileName).substr(std::string(szFileName).length() - 1) == "/")
    225.  
      {
    226.  
      //当zip里是目录的时候
    227.  
       
    228.  
      }
    229.  
      else
    230.  
      {
    231.  
      //MessageBox(NULL,szNewFileName,"即将新建的文件名",0);
    232.  
       
    233.  
      if (unzOpenCurrentFile(zip) != UNZ_OK)
    234.  
      {
    235.  
      unzClose(zip);
    236.  
      return FALSE;
    237.  
      }
    238.  
       
    239.  
      char *lpFileDataBuf = new char[FileInfo.uncompressed_size];
    240.  
      memset(lpFileDataBuf, 0, FileInfo.uncompressed_size);
    241.  
      unzReadCurrentFile(zip, lpFileDataBuf, FileInfo.uncompressed_size);
    242.  
       
    243.  
       
    244.  
       
    245.  
       
    246.  
      //取后缀名
    247.  
      std::string strEndName = szFileName;
    248.  
      strEndName = strEndName.substr(strEndName.find_last_of("."));
    249.  
      transform(strEndName.begin(), strEndName.end(), strEndName.begin(), tolower); //转小写
    250.  
       
    251.  
       
    252.  
      MyResourcesBuf *pResBuf = new MyResourcesBuf;
    253.  
       
    254.  
      //如果需要使用3DES解密
    255.  
      if ( (use3DES_ECB_Decrypt && lpsz3DES_ECB_KEY && n3DES_ECB_KEY_LEN) &&
    256.  
      (
    257.  
      strEndName == ".html" ||
    258.  
      strEndName == ".js" ||
    259.  
      strEndName == ".css"
    260.  
      )
    261.  
      )
    262.  
       
    263.  
      {
    264.  
      //开始进行3DES解密
    265.  
       
    266.  
      char *lpDecrypt = new char[FileInfo.uncompressed_size];
    267.  
      memset(lpDecrypt, 0, FileInfo.uncompressed_size);
    268.  
       
    269.  
      des3_ecb_decrypt((unsigned char*)lpDecrypt,
    270.  
      (unsigned char*)lpFileDataBuf,
    271.  
      FileInfo.uncompressed_size,
    272.  
      (unsigned char*)lpsz3DES_ECB_KEY, 16);
    273.  
       
    274.  
      std::string strConvert = lpDecrypt; //利用string来截断最后的00
    275.  
       
    276.  
      delete lpDecrypt;
    277.  
      delete lpFileDataBuf;
    278.  
       
    279.  
       
    280.  
      lpFileDataBuf = new char[strConvert.length()]; //UTF8不能包含最后的00,不然Chrome会报错 好奇怪
    281.  
      memcpy(lpFileDataBuf, strConvert.c_str(), strConvert.length());
    282.  
       
    283.  
      pResBuf->nBufSize = strConvert.length();
    284.  
       
    285.  
      }
    286.  
      else
    287.  
      {
    288.  
      pResBuf->nBufSize = FileInfo.uncompressed_size;
    289.  
      }
    290.  
      pResBuf->lpBuf = lpFileDataBuf;
    291.  
       
    292.  
       
    293.  
       
    294.  
      #pragma region 分配类型名
    295.  
      std::string strType = "";
    296.  
      if (strEndName == ".html")
    297.  
      {
    298.  
      strType = "text/html";
    299.  
      }
    300.  
      else if (strEndName == ".js")
    301.  
      {
    302.  
      strType = "application/javascript";
    303.  
      }
    304.  
      else if (strEndName == ".css")
    305.  
      {
    306.  
      strType = "text/css";
    307.  
      }
    308.  
      else if (strEndName == ".jpg" || strEndName == ".jpeg")
    309.  
      {
    310.  
      strType = "image/jpeg";
    311.  
      }
    312.  
      else if (strEndName == ".png")
    313.  
      {
    314.  
      strType = "image/png";
    315.  
      }
    316.  
      else if (strEndName == ".gif")
    317.  
      {
    318.  
      strType = "image/gif";
    319.  
      }
    320.  
      if (!strType.empty())
    321.  
      {
    322.  
      char*lpType = new char[strType.length() + 1];
    323.  
      strcpy(lpType, strType.c_str());
    324.  
      pResBuf->lpType = lpType;
    325.  
      }
    326.  
      #pragma endregion
    327.  
       
    328.  
       
    329.  
       
    330.  
      m_mapResources.insert(std::pair<std::string, MyResourcesBuf*>(szFileName, pResBuf));
    331.  
       
    332.  
      }
    333.  
      unzCloseCurrentFile(zip);
    334.  
      unzGoToNextFile(zip);
    335.  
      }
    336.  
      unzClose(zip);
    337.  
      return true;
    338.  
      }
    339.  
       
    340.  
       
    341.  
      bool ZipFolder::ZipTraversalFolder(
    342.  
      zipFile zip,
    343.  
      std::string strSourceFolder,
    344.  
      std::string strInZipFolder,
    345.  
      bool bWriteFolderChangeDate,
    346.  
      bool bWriteFileChangeDate)
    347.  
      {
    348.  
       
    349.  
      std::string strFindPath = strSourceFolder;
    350.  
      strFindPath += "*.*";
    351.  
       
    352.  
      WIN32_FIND_DATAA wfd = { 0 };
    353.  
      HANDLE fhn = FindFirstFileA(strFindPath.c_str(), &wfd);
    354.  
      if (fhn == INVALID_HANDLE_VALUE)
    355.  
      {
    356.  
      FindClose(fhn);
    357.  
      return FALSE;
    358.  
      }
    359.  
      BOOL bRet = TRUE;
    360.  
      while (bRet)
    361.  
      {
    362.  
      if (
    363.  
      (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) &&
    364.  
      (lstrcmpA(".", wfd.cFileName) != 0) &&
    365.  
      (lstrcmpA("..", wfd.cFileName) != 0))
    366.  
      {
    367.  
      //zip里的文件夹名
    368.  
       
    369.  
      std::string strNewZipDir = strInZipFolder;
    370.  
      strNewZipDir += wfd.cFileName;
    371.  
      strNewZipDir += "/";
    372.  
       
    373.  
      zip_fileinfo ZipFileInfo = { 0 };
    374.  
      if (bWriteFolderChangeDate)
    375.  
      {
    376.  
      time_t CurTime = time(NULL);
    377.  
      tm * mytime = localtime(&CurTime);
    378.  
      ZipFileInfo.tmz_date.tm_hour = mytime->tm_hour;
    379.  
      ZipFileInfo.tmz_date.tm_mday = mytime->tm_mday;
    380.  
      ZipFileInfo.tmz_date.tm_min = mytime->tm_min;
    381.  
      ZipFileInfo.tmz_date.tm_mon = mytime->tm_mon;
    382.  
      ZipFileInfo.tmz_date.tm_sec = mytime->tm_sec;
    383.  
      ZipFileInfo.tmz_date.tm_year = mytime->tm_year;
    384.  
      ZipFileInfo.dosDate = 0;
    385.  
      }
    386.  
       
    387.  
      if (zipOpenNewFileInZip(zip, strNewZipDir.c_str(), &ZipFileInfo, NULL, 0, NULL, 0, NULL, Z_DEFLATED, Z_BEST_COMPRESSION) != UNZ_OK)
    388.  
      {
    389.  
      return FALSE;
    390.  
      }
    391.  
      zipCloseFileInZip(zip);
    392.  
       
    393.  
      std::string strNewSourceFolder = strSourceFolder;
    394.  
      strNewSourceFolder += wfd.cFileName;
    395.  
      strNewSourceFolder += "\";
    396.  
      ZipTraversalFolder(zip,
    397.  
      strNewSourceFolder,
    398.  
      strNewZipDir,
    399.  
      bWriteFolderChangeDate,
    400.  
      bWriteFileChangeDate);
    401.  
       
    402.  
      }
    403.  
      else if (lstrcmpA(".", wfd.cFileName) != 0 && lstrcmpA("..", wfd.cFileName) != 0)
    404.  
      {
    405.  
       
    406.  
      std::string strInZipFilePath = strInZipFolder;
    407.  
      strInZipFilePath += wfd.cFileName;
    408.  
       
    409.  
      zip_fileinfo ZipFileInfo = { 0 };
    410.  
      if (bWriteFileChangeDate)
    411.  
      {
    412.  
      time_t CurTime = time(NULL);
    413.  
      tm * mytime = localtime(&CurTime);
    414.  
      ZipFileInfo.tmz_date.tm_hour = mytime->tm_hour;
    415.  
      ZipFileInfo.tmz_date.tm_mday = mytime->tm_mday;
    416.  
      ZipFileInfo.tmz_date.tm_min = mytime->tm_min;
    417.  
      ZipFileInfo.tmz_date.tm_mon = mytime->tm_mon;
    418.  
      ZipFileInfo.tmz_date.tm_sec = mytime->tm_sec;
    419.  
      ZipFileInfo.tmz_date.tm_year = mytime->tm_year;
    420.  
      ZipFileInfo.dosDate = 0;
    421.  
      }
    422.  
       
    423.  
       
    424.  
      if (zipOpenNewFileInZip(zip, strInZipFilePath.c_str(), &ZipFileInfo, NULL, 0, NULL, 0, NULL, Z_DEFLATED, Z_BEST_COMPRESSION) != UNZ_OK)
    425.  
      {
    426.  
      return FALSE;
    427.  
      }
    428.  
       
    429.  
      std::string strLocalFile = strSourceFolder;
    430.  
      strLocalFile += wfd.cFileName;
    431.  
      // MessageBox(NULL,szDestinationFile,"硬盘中的文件名",0);
    432.  
       
    433.  
      HANDLE hDesFile = CreateFileA(strLocalFile.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    434.  
      if (hDesFile == INVALID_HANDLE_VALUE)
    435.  
      {
    436.  
      return FALSE;
    437.  
      }
    438.  
      LARGE_INTEGER lisize = { 0 };
    439.  
      lisize.QuadPart = 0;
    440.  
      lisize.LowPart = SetFilePointer(hDesFile, lisize.LowPart, &lisize.HighPart, FILE_BEGIN);
    441.  
      if (lisize.LowPart == INVALID_SET_FILE_POINTER && GetLastError() != NO_ERROR)
    442.  
      {
    443.  
      return FALSE;
    444.  
      }
    445.  
      ULARGE_INTEGER ulisize = { 0 };
    446.  
      ulisize.LowPart = GetFileSize(hDesFile, &ulisize.HighPart);
    447.  
      if (ulisize.LowPart == INVALID_FILE_SIZE && (GetLastError()) != NO_ERROR)
    448.  
      {
    449.  
      return FALSE;
    450.  
      }
    451.  
      char szFileDataBuf[WRITEBUFFERSIZE];
    452.  
      ULONGLONG uCycles = ulisize.QuadPart / WRITEBUFFERSIZE;
    453.  
      for (ULONGLONG i = 0; i <= uCycles; i++)
    454.  
      {
    455.  
      ZeroMemory(szFileDataBuf, WRITEBUFFERSIZE);
    456.  
      DWORD dwWrite = 0;
    457.  
      if (!ReadFile(hDesFile, szFileDataBuf, WRITEBUFFERSIZE, &dwWrite, NULL))
    458.  
      {
    459.  
      // CDatabase::ShowError(GetDesktopWindow());
    460.  
      zipCloseFileInZip(zip);
    461.  
      return FALSE;
    462.  
      }
    463.  
      zipWriteInFileInZip(zip, szFileDataBuf, dwWrite);
    464.  
       
    465.  
      if (dwWrite < WRITEBUFFERSIZE)
    466.  
      {
    467.  
      //MessageBox(NULL,"dwWrite<WRITEBUFFERSIZE","",0);
    468.  
      break;
    469.  
      }
    470.  
      }
    471.  
      zipCloseFileInZip(zip);
    472.  
      CloseHandle(hDesFile);
    473.  
      //MessageBox(NULL,"CloseHandle(hDestinationFile);","",0);
    474.  
      }
    475.  
      ZeroMemory(&wfd, sizeof(WIN32_FIND_DATAA));
    476.  
      bRet = FindNextFileA(fhn, &wfd);
    477.  
      }
    478.  
      FindClose(fhn);
    479.  
      return TRUE;
    480.  
      }
    481.  
       
    482.  
      bool ZipFolder::DetectFolderFile(char *szFolder)
    483.  
      {
    484.  
      char Path[MAX_PATH] = { 0 };
    485.  
      lstrcpyA(Path, szFolder);
    486.  
      lstrcatA(Path, "*.*");
    487.  
      WIN32_FIND_DATAA wfd = { 0 };
    488.  
      HANDLE fhn = FindFirstFileA(Path, &wfd);
    489.  
      if (fhn == INVALID_HANDLE_VALUE)
    490.  
      {
    491.  
      FindClose(fhn);
    492.  
      return false;
    493.  
      }
    494.  
      bool bRet = TRUE;
    495.  
      while (bRet)
    496.  
      {
    497.  
      char TempName[MAX_PATH] = { 0 };
    498.  
      if (
    499.  
      (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) &&
    500.  
      (lstrcmpA(".", wfd.cFileName) != 0) &&
    501.  
      (lstrcmpA("..", wfd.cFileName) != 0))
    502.  
      {
    503.  
      lstrcatA(TempName, szFolder);
    504.  
      lstrcatA(TempName, wfd.cFileName);
    505.  
      lstrcatA(TempName, "\");
    506.  
      DetectFolderFile(TempName);
    507.  
       
    508.  
      }
    509.  
      else if (lstrcmpA(".", wfd.cFileName) != 0 && lstrcmpA("..", wfd.cFileName) != 0)
    510.  
      {
    511.  
      lstrcatA(TempName, szFolder);
    512.  
      lstrcatA(TempName, wfd.cFileName);
    513.  
      HANDLE hFile = CreateFileA(TempName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    514.  
      if (hFile == INVALID_HANDLE_VALUE)
    515.  
      {
    516.  
      FindClose(fhn);
    517.  
      CloseHandle(hFile);
    518.  
      return false;
    519.  
      }
    520.  
      CloseHandle(hFile);
    521.  
      }
    522.  
      ZeroMemory(&wfd, sizeof(WIN32_FIND_DATAA));
    523.  
      bRet = FindNextFileA(fhn, &wfd);
    524.  
      }
    525.  
      FindClose(fhn);
    526.  
      return true;
    527.  
      }
    528.  
       
    529.  
      bool ZipFolder::ExistFolder(char *lpszFolder)
    530.  
      {
    531.  
      DWORD ftyp = GetFileAttributesA(lpszFolder);
    532.  
      if (ftyp == INVALID_FILE_ATTRIBUTES)
    533.  
      {
    534.  
      return false; //something is wrong with your path!
    535.  
      }
    536.  
      if (ftyp & FILE_ATTRIBUTE_DIRECTORY)
    537.  
      {
    538.  
      return true; // this is a directory!
    539.  
      }
    540.  
      return false; // this is not a directory!
    541.  
      }
    542.  
       
    543.  
      #pragma region 创建多级目录
    544.  
       
    545.  
      #ifdef WIN32
    546.  
      #include <direct.h>
    547.  
      #include <io.h>
    548.  
      #elif LINUX
    549.  
      #include <stdarg.h>
    550.  
      #include <sys/stat.h>
    551.  
      #endif
    552.  
      #ifdef WIN32
    553.  
      #define ACCESS _access
    554.  
      #define MKDIR(a) _mkdir((a))
    555.  
      #elif LINUX
    556.  
      #define ACCESS access
    557.  
      #define MKDIR(a) mkdir((a),0755)
    558.  
      #endif
    559.  
      int ZipFolder::CreateDir(char *pszDir)
    560.  
      {
    561.  
      int i = 0;
    562.  
      int iRet;
    563.  
      int iLen = strlen(pszDir);
    564.  
      //在末尾加/
    565.  
      if (pszDir[iLen - 1] != '\'&&pszDir[iLen - 1] != '/')
    566.  
      {
    567.  
      pszDir[iLen] = '/';
    568.  
      pszDir[iLen + 1] = '';
    569.  
      }
    570.  
      // 创建目录
    571.  
      for (i = 0; i <= iLen; i++)
    572.  
      {
    573.  
      if (pszDir[i] == '\' || pszDir[i] == '/')
    574.  
      {
    575.  
      pszDir[i] = '';
    576.  
       
    577.  
      //如果不存在,创建
    578.  
      iRet = ACCESS(pszDir, 0);
    579.  
      if (iRet != 0)
    580.  
      {
    581.  
      iRet = MKDIR(pszDir);
    582.  
      if (iRet != 0)
    583.  
      {
    584.  
      return-1;
    585.  
      }
    586.  
      }
    587.  
      //支持linux,将所有换成/
    588.  
      pszDir[i] = '/';
    589.  
      }
    590.  
      }
    591.  
      return 0;
    592.  
      }
    593.  
      #pragma endregion
    594.  
  • 相关阅读:
    MSP430:实时时钟-DS1302
    STM32: TIMER门控模式控制PWM输出长度
    LVM磁盘管理
    python的面向对象,类,以及类的使用
    pymysql模块
    paramiko模块
    正则表达式和re模块
    python3的soker模块实现功能
    根据生日测星座
    多进程,进程池,协程
  • 原文地址:https://www.cnblogs.com/h2zZhou/p/12502229.html
Copyright © 2020-2023  润新知