网上关于CEF3读取加密资源的中文资料特别少~,所以我就来写一篇教程吧
实际应用: PC版的“网易云音乐”就是把H5资源加密成zip文件,启动时动态读取。
原理:
让自己的MyClientHandler来继承 CefRequestHandler这个抽象类,然对其下面的纯虚函数进行重写
simple_handler.h:
#include "include/wrapper/cef_resource_manager.h"
class SimpleHandler : public CefClient,
public CefDisplayHandler,
public CefLifeSpanHandler,
public CefRequestHandler{
virtual CefRefPtr<CefRequestHandler> GetRequestHandler() OVERRIDE { return this; }
// CefRequestHandler methods:
virtual cef_return_value_t OnBeforeResourceLoad(
CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefRequest> request,
CefRefPtr<CefRequestCallback> callback) OVERRIDE;
virtual CefRefPtr<CefResourceHandler> GetResourceHandler(
CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefRequest> request) OVERRIDE;
private:
// Manages the registration and delivery of resources.
CefRefPtr<CefResourceManager> resource_manager_;
simple_handler.cc:
#include "include/wrapper/cef_stream_resource_handler.h"
namespace {
SimpleHandler* g_instance = NULL;
} // namespace
// Demonstrate a custom Provider implementation by dumping the request contents.
class RequestDumpResourceProvider : public CefResourceManager::Provider {
public:
explicit RequestDumpResourceProvider(const std::string& url) : url_(url) {
DCHECK(!url.empty());
}
bool OnRequest(scoped_refptr<CefResourceManager::Request> request) OVERRIDE
{
CEF_REQUIRE_IO_THREAD();
const std::string& url = request->url();
if (url != url_)
{
// Not handled by this provider.
return false;
}
//const std::string& dump = shared::DumpRequestContents(request->request());
std::string str =
//"<html><body bgcolor=\"white\"><pre>" + dump + "</pre></body></html>";
"<html><body bgcolor=\"white\"><pre>123123123123</pre></body></html>";
CefRefPtr<CefStreamReader> stream = CefStreamReader::CreateForData(
static_cast<void*>(const_cast<char*>(str.c_str())), str.size());
DCHECK(stream.get());
request->Continue(new CefStreamResourceHandler("text/html", stream));
return true;
}
private:
std::string url_;
DISALLOW_COPY_AND_ASSIGN(RequestDumpResourceProvider);
};
// Add example Providers to the CefResourceManager.
void SetupResourceManager(CefRefPtr<CefResourceManager> resource_manager)
{
if (!CefCurrentlyOn(TID_IO))
{
// Execute on the browser IO thread.
CefPostTask(TID_IO, base::Bind(SetupResourceManager, resource_manager));
return;
}
// Add the Provider for dumping request contents.
resource_manager->AddProvider(
new RequestDumpResourceProvider("http://www.baidu.com/"), 0,
std::string());
}
SimpleHandler::SimpleHandler(bool use_views)
: use_views_(use_views), is_closing_(false) {
DCHECK(!g_instance);
g_instance = this;
//安装资源管理器
resource_manager_ = new CefResourceManager();
SetupResourceManager(resource_manager_);
}
至此,打开http://www.baidu.com,都会被拦截下来,显示123123123123
实际应用- 带zip解压解密版:
simple_handler.h:
#include "include/wrapper/cef_resource_manager.h"
#pragma region 使用Zip管理类
#include "ResourcesManager/ZipFolder.h"
#pragma endregion
class SimpleHandler : public CefClient,
public CefDisplayHandler,
public CefLifeSpanHandler,
public CefRequestHandler{
virtual CefRefPtr<CefRequestHandler> GetRequestHandler() OVERRIDE { return this; }
// CefRequestHandler methods:
virtual cef_return_value_t OnBeforeResourceLoad(
CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefRequest> request,
CefRefPtr<CefRequestCallback> callback) OVERRIDE;
virtual CefRefPtr<CefResourceHandler> GetResourceHandler(
CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefRequest> request) OVERRIDE;
private:
// Manages the registration and delivery of resources.
CefRefPtr<CefResourceManager> resource_manager_;
ZipFolder m_zip;
simple_handler.cc:
#include "include/wrapper/cef_stream_resource_handler.h"
namespace {
SimpleHandler* g_instance = NULL;
} // namespace
// Demonstrate a custom Provider implementation by dumping the request contents.
class RequestDumpResourceProvider : public CefResourceManager::Provider {
public:
explicit RequestDumpResourceProvider(ZipFolder *pZip)
{
m_pZip = pZip;
}
//去除URL中的百分号%转码
std::string UrlDecode(std::string &SRC)
{
std::string ret;
char ch;
int ii;
for (size_t i = 0; i < SRC.length(); i++) {
if (int(SRC[i]) == 37) {
sscanf(SRC.substr(i + 1, 2).c_str(), "%x", &ii);
ch = static_cast<char>(ii);
ret += ch;
i = i + 2;
}
else {
ret += SRC[i];
}
}
return (ret);
}
bool OnRequest(scoped_refptr<CefResourceManager::Request> request) OVERRIDE
{
CEF_REQUIRE_IO_THREAD();
std::string url = request->url();
//if (url != url_)
//{
// // Not handled by this provider.
// return false;
//}
url = UrlDecode(url); //去除百分号
url = UTF8_To_string(url); //UTF8网址转回ANSI编码文本
//把http://、https://和file:///去掉
if (url.substr(0, 7) == "http://")
{
url.erase(0, 7);
}
else if (url.substr(0, 8) == "https://")
{
url.erase(0, 8);
}
else if (url.substr(0,8) == "file:///")
{
url.erase(0, 8);
}
string strMyPath2 = g_strMyPath;
strMyPath2 = replace_all_distinct(strMyPath2, "\\", "/"); //把自身路径的\转成/
url = replace_all_distinct(url, strMyPath2, "");
//如果最后一个字符是/也去掉
//if (url.substr(url.length()-1) == "/")
//{
// url = url.substr(0, url.length() - 1);
//}
//在map资源图中寻找
std::map<std::string, MyResourcesBuf*>::iterator it;
it = m_pZip->m_mapResources.find(url);
if (it == m_pZip->m_mapResources.end())
{
return false;
}
//const std::string& dump = shared::DumpRequestContents(request->request());
//std::string str =
//"<html><body bgcolor=\"white\"><pre>" + dump + "</pre></body></html>";
// "<html><body bgcolor=\"white\"><pre>123123123123</pre></body></html>";
CefRefPtr<CefStreamReader> stream = CefStreamReader::CreateForData(
static_cast<void*>(it->second->lpBuf), it->second->nBufSize);
DCHECK(stream.get());
request->Continue(new CefStreamResourceHandler(it->second->lpType, stream));
return true;
}
private:
ZipFolder *m_pZip;
DISALLOW_COPY_AND_ASSIGN(RequestDumpResourceProvider);
};
// Add example Providers to the CefResourceManager.
void SetupResourceManager(CefRefPtr<CefResourceManager> resource_manager)
{
if (!CefCurrentlyOn(TID_IO))
{
// Execute on the browser IO thread.
CefPostTask(TID_IO, base::Bind(SetupResourceManager, resource_manager));
return;
}
// Add the Provider for dumping request contents.
resource_manager->AddProvider(
new RequestDumpResourceProvider(pZip), 0,
std::string());
}
SimpleHandler::SimpleHandler(bool use_views)
: use_views_(use_views), is_closing_(false) {
DCHECK(!g_instance);
g_instance = this;
//从zip文件中加载H5资源
std::string strMyZipFilePath = g_strMyPath + "native.ntpk"; //模仿PC网易云客户端
m_zip.LoadZipToMem(strMyZipFilePath,false, "123",16); //解密zip
resource_manager_ = new CefResourceManager();
SetupResourceManager(resource_manager_, &m_zip);
}
ZipFolder.h(注意,只能操作不带密码的zip压缩包,不要问我为什么,因为zlib不支持)
#pragma once
#define WRITEBUFFERSIZE 16384
#include <iostream>
#include <map>
#pragma region 使用zlib库
#include "../../zlib/include/zlib.h"
#include "../../zlib/include/zip.h"
#include "../../zlib/include/unzip.h"
#ifdef _DEBUG
#pragma comment(lib,"zlib/lib/x86/Debug/zlib.lib")
#else
#pragma comment(lib,"zlib/lib/x86/Release/zlib.lib")
#endif
#pragma endregion
struct MyResourcesBuf
{
void *lpBuf;
int nBufSize;
char *lpType; //资源类型
};
class ZipFolder
{
public:
ZipFolder();
virtual ~ZipFolder();
public:
//压缩文件夹
bool Zip_Folder(
std::string strFolder, //将要被压缩的文件夹路径
std::string strZipFilePath, //将要生成的zip文件路径
std::string strZipFileComment, //将要生成的zip文件注释,可以为NULL
bool bWriteFolderChangeDate, //是否写入文件夹修改日期
bool bWriteFileChangeDate); //是否写入文件夹里的文件修改日期
//解压缩zip文件(支持多级文件夹)
bool UnZip(
std::string strZipFilePath, //将要被解压的zip文件路径
std::string strExistingFolder); //解压文件存放的路径,路径必须存在
//解压zip内容到内存
std::map<std::string, MyResourcesBuf*> m_mapResources;
bool LoadZipToMem(std::string strZipFilePath, //将要被解压读取的zip文件路径
bool use3DES_ECB_Decrypt = false, //解压读取时是否使用3DES ECB模式解密
char* lpsz3DES_ECB_KEY = NULL, //3DES_ECB模式的KEY
int n3DES_ECB_KEY_LEN = 0); //3DES_ECB模式的KEY 长度
private:
bool ExistFolder(char *lpszFolder);
bool DetectFolderFile(char *szFolder);
bool ZipTraversalFolder(
zipFile zip,
std::string strSourceFolder,
std::string strInZipFolder,
bool bWriteFolderChangeDate,
bool bWriteFileChangeDate);
int CreateDir(char *pszDir);
};
ZipFolder.cpp (将zip解压读取到内存后,默认不进行任何解密操作,进行3DES解密部分的算法代码太长了就不粘贴了,屏蔽掉即可完美运行)
// ZipFolder.cpp: implementation of the ZipFolder class.
//
//
#include "ZipFolder.h"
#include <windows.h>
#include <time.h>
#include <utility>
#include <algorithm>
#pragma region 使用3DES库
#include "../../DES/DES.h"
#pragma endregion
//
// Construction/Destruction
//
ZipFolder::ZipFolder()
{
}
ZipFolder::~ZipFolder()
{
}
bool ZipFolder::Zip_Folder(
std::string strFolder,
std::string strZipFilePath,
std::string strZipFileComment,
bool bWriteFolderChangeDate,
bool bWriteFileChangeDate)
{
if (strFolder.substr(strFolder.length() - 1) != "\\")
{
//补上斜杠
strFolder += "\\";
}
if (!ExistFolder((char*)strFolder.c_str()))
{
return false;
}
if (!DetectFolderFile((char*)strFolder.c_str()))
{
return FALSE;
}
zipFile zip = zipOpen(strZipFilePath.c_str(), APPEND_STATUS_CREATE);
if (zip == NULL)
{
//如果zip文件已存在
zip = zipOpen(strZipFilePath.c_str(), APPEND_STATUS_ADDINZIP);
if (zip == NULL)
{
return false;
}
}
bool bRet = ZipTraversalFolder(
zip,
strFolder,
"",
bWriteFolderChangeDate,
bWriteFileChangeDate);
zipClose(zip, strZipFileComment.c_str());
return bRet;
}
bool ZipFolder::UnZip(
std::string strZipFilePath,
std::string strExistingFolder)
{
if (strExistingFolder.substr(strExistingFolder.length() - 1) != "\\")
{
//补上斜杠
strExistingFolder += "\\";
}
unzFile zip = unzOpen(strZipFilePath.c_str());
if (zip == NULL)
{
return false;
}
unz_global_info GlobalInfo;
if (unzGetGlobalInfo(zip, &GlobalInfo) != UNZ_OK)
{
unzClose(zip);
return false;
}
if (unzGoToFirstFile(zip) != UNZ_OK)
{
unzClose(zip);
return false;
}
for (int i = 0; i < GlobalInfo.number_entry; i++)
{
unz_file_info FileInfo;
char szFileName[MAX_PATH] = { 0 };
char szExtraField[MAX_PATH] = { 0 };
char szComment[MAX_PATH] = { 0 };
if (unzGetCurrentFileInfo(zip, &FileInfo, szFileName, MAX_PATH, szExtraField, MAX_PATH, szComment, MAX_PATH) != UNZ_OK)
{
unzClose(zip);
return FALSE;
}
// MessageBox(NULL,szFileName,"Zip中的文件名",0);
if (std::string(szFileName).substr(std::string(szFileName).length() - 1) == "/")
{
//当zip里是目录的时候
// MessageBox(NULL,szFileName,"经过处理的目录名",0);
std::string strNewDir = strExistingFolder;
strNewDir += szFileName;
//MessageBox(NULL,szDirectory,"要创建的目录名",0);
if (CreateDir((char*)strNewDir.c_str()) == -1)
{
unzClose(zip);
return FALSE;
}
}
else
{
std::string strNewFile = strExistingFolder;
strNewFile += szFileName;
//MessageBox(NULL,szNewFileName,"即将新建的文件名",0);
if (unzOpenCurrentFile(zip) != UNZ_OK)
{
unzClose(zip);
return FALSE;
}
HANDLE hNewFile = CreateFileA(strNewFile.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
if (hNewFile == INVALID_HANDLE_VALUE)
{
unzCloseCurrentFile(zip);
unzClose(zip);
return FALSE;
}
LARGE_INTEGER lisize = { 0 };
lisize.QuadPart = 0;
lisize.LowPart = SetFilePointer(hNewFile, lisize.LowPart, &lisize.HighPart, FILE_BEGIN);
if (lisize.LowPart == INVALID_SET_FILE_POINTER && GetLastError() != NO_ERROR)
{
unzCloseCurrentFile(zip);
unzClose(zip);
CloseHandle(hNewFile);
return FALSE;
}
char szFileDataBuf[WRITEBUFFERSIZE];
ULONGLONG uCycles = FileInfo.uncompressed_size / WRITEBUFFERSIZE;
for (ULONGLONG i = 0; i <= uCycles; i++)
{
ZeroMemory(szFileDataBuf, WRITEBUFFERSIZE);
int nRead = unzReadCurrentFile(zip, szFileDataBuf, WRITEBUFFERSIZE);
if (nRead == 0)
{
break;
}
else if (nRead <= 0)
{
CloseHandle(hNewFile);
unzCloseCurrentFile(zip);
unzClose(zip);
return FALSE;
}
DWORD dwWrite = 0;
if (!WriteFile(hNewFile, szFileDataBuf, nRead, &dwWrite, NULL))
{
CloseHandle(hNewFile);
unzCloseCurrentFile(zip);
unzClose(zip);
return FALSE;
}
}
CloseHandle(hNewFile);
}
unzCloseCurrentFile(zip);
unzGoToNextFile(zip);
}
unzClose(zip);
return TRUE;
}
bool ZipFolder::LoadZipToMem(std::string strZipFilePath,
bool use3DES_ECB_Decrypt, char* lpsz3DES_ECB_KEY,int n3DES_ECB_KEY_LEN)
{
unzFile zip = unzOpen(strZipFilePath.c_str());
if (zip == NULL)
{
return false;
}
unz_global_info GlobalInfo;
if (unzGetGlobalInfo(zip, &GlobalInfo) != UNZ_OK)
{
unzClose(zip);
return false;
}
if (unzGoToFirstFile(zip) != UNZ_OK)
{
unzClose(zip);
return false;
}
for (int i = 0; i < GlobalInfo.number_entry; i++)
{
unz_file_info FileInfo;
char szFileName[MAX_PATH] = { 0 };
char szExtraField[MAX_PATH] = { 0 };
char szComment[MAX_PATH] = { 0 };
if (unzGetCurrentFileInfo(zip, &FileInfo, szFileName, MAX_PATH, szExtraField, MAX_PATH, szComment, MAX_PATH) != UNZ_OK)
{
unzClose(zip);
return FALSE;
}
// MessageBox(NULL,szFileName,"Zip中的文件名",0);
if (std::string(szFileName).substr(std::string(szFileName).length() - 1) == "/")
{
//当zip里是目录的时候
}
else
{
//MessageBox(NULL,szNewFileName,"即将新建的文件名",0);
if (unzOpenCurrentFile(zip) != UNZ_OK)
{
unzClose(zip);
return FALSE;
}
char *lpFileDataBuf = new char[FileInfo.uncompressed_size];
memset(lpFileDataBuf, 0, FileInfo.uncompressed_size);
unzReadCurrentFile(zip, lpFileDataBuf, FileInfo.uncompressed_size);
//取后缀名
std::string strEndName = szFileName;
strEndName = strEndName.substr(strEndName.find_last_of("."));
transform(strEndName.begin(), strEndName.end(), strEndName.begin(), tolower); //转小写
MyResourcesBuf *pResBuf = new MyResourcesBuf;
//如果需要使用3DES解密
if ( (use3DES_ECB_Decrypt && lpsz3DES_ECB_KEY && n3DES_ECB_KEY_LEN) &&
(
strEndName == ".html" ||
strEndName == ".js" ||
strEndName == ".css"
)
)
{
//开始进行3DES解密
char *lpDecrypt = new char[FileInfo.uncompressed_size];
memset(lpDecrypt, 0, FileInfo.uncompressed_size);
des3_ecb_decrypt((unsigned char*)lpDecrypt,
(unsigned char*)lpFileDataBuf,
FileInfo.uncompressed_size,
(unsigned char*)lpsz3DES_ECB_KEY, 16);
std::string strConvert = lpDecrypt; //利用string来截断最后的00
delete lpDecrypt;
delete lpFileDataBuf;
lpFileDataBuf = new char[strConvert.length()]; //UTF8不能包含最后的00,不然Chrome会报错 好奇怪
memcpy(lpFileDataBuf, strConvert.c_str(), strConvert.length());
pResBuf->nBufSize = strConvert.length();
}
else
{
pResBuf->nBufSize = FileInfo.uncompressed_size;
}
pResBuf->lpBuf = lpFileDataBuf;
#pragma region 分配类型名
std::string strType = "";
if (strEndName == ".html")
{
strType = "text/html";
}
else if (strEndName == ".js")
{
strType = "application/javascript";
}
else if (strEndName == ".css")
{
strType = "text/css";
}
else if (strEndName == ".jpg" || strEndName == ".jpeg")
{
strType = "image/jpeg";
}
else if (strEndName == ".png")
{
strType = "image/png";
}
else if (strEndName == ".gif")
{
strType = "image/gif";
}
if (!strType.empty())
{
char*lpType = new char[strType.length() + 1];
strcpy(lpType, strType.c_str());
pResBuf->lpType = lpType;
}
#pragma endregion
m_mapResources.insert(std::pair<std::string, MyResourcesBuf*>(szFileName, pResBuf));
}
unzCloseCurrentFile(zip);
unzGoToNextFile(zip);
}
unzClose(zip);
return true;
}
bool ZipFolder::ZipTraversalFolder(
zipFile zip,
std::string strSourceFolder,
std::string strInZipFolder,
bool bWriteFolderChangeDate,
bool bWriteFileChangeDate)
{
std::string strFindPath = strSourceFolder;
strFindPath += "*.*";
WIN32_FIND_DATAA wfd = { 0 };
HANDLE fhn = FindFirstFileA(strFindPath.c_str(), &wfd);
if (fhn == INVALID_HANDLE_VALUE)
{
FindClose(fhn);
return FALSE;
}
BOOL bRet = TRUE;
while (bRet)
{
if (
(wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) &&
(lstrcmpA(".", wfd.cFileName) != 0) &&
(lstrcmpA("..", wfd.cFileName) != 0))
{
//zip里的文件夹名
std::string strNewZipDir = strInZipFolder;
strNewZipDir += wfd.cFileName;
strNewZipDir += "/";
zip_fileinfo ZipFileInfo = { 0 };
if (bWriteFolderChangeDate)
{
time_t CurTime = time(NULL);
tm * mytime = localtime(&CurTime);
ZipFileInfo.tmz_date.tm_hour = mytime->tm_hour;
ZipFileInfo.tmz_date.tm_mday = mytime->tm_mday;
ZipFileInfo.tmz_date.tm_min = mytime->tm_min;
ZipFileInfo.tmz_date.tm_mon = mytime->tm_mon;
ZipFileInfo.tmz_date.tm_sec = mytime->tm_sec;
ZipFileInfo.tmz_date.tm_year = mytime->tm_year;
ZipFileInfo.dosDate = 0;
}
if (zipOpenNewFileInZip(zip, strNewZipDir.c_str(), &ZipFileInfo, NULL, 0, NULL, 0, NULL, Z_DEFLATED, Z_BEST_COMPRESSION) != UNZ_OK)
{
return FALSE;
}
zipCloseFileInZip(zip);
std::string strNewSourceFolder = strSourceFolder;
strNewSourceFolder += wfd.cFileName;
strNewSourceFolder += "\\";
ZipTraversalFolder(zip,
strNewSourceFolder,
strNewZipDir,
bWriteFolderChangeDate,
bWriteFileChangeDate);
}
else if (lstrcmpA(".", wfd.cFileName) != 0 && lstrcmpA("..", wfd.cFileName) != 0)
{
std::string strInZipFilePath = strInZipFolder;
strInZipFilePath += wfd.cFileName;
zip_fileinfo ZipFileInfo = { 0 };
if (bWriteFileChangeDate)
{
time_t CurTime = time(NULL);
tm * mytime = localtime(&CurTime);
ZipFileInfo.tmz_date.tm_hour = mytime->tm_hour;
ZipFileInfo.tmz_date.tm_mday = mytime->tm_mday;
ZipFileInfo.tmz_date.tm_min = mytime->tm_min;
ZipFileInfo.tmz_date.tm_mon = mytime->tm_mon;
ZipFileInfo.tmz_date.tm_sec = mytime->tm_sec;
ZipFileInfo.tmz_date.tm_year = mytime->tm_year;
ZipFileInfo.dosDate = 0;
}
if (zipOpenNewFileInZip(zip, strInZipFilePath.c_str(), &ZipFileInfo, NULL, 0, NULL, 0, NULL, Z_DEFLATED, Z_BEST_COMPRESSION) != UNZ_OK)
{
return FALSE;
}
std::string strLocalFile = strSourceFolder;
strLocalFile += wfd.cFileName;
// MessageBox(NULL,szDestinationFile,"硬盘中的文件名",0);
HANDLE hDesFile = CreateFileA(strLocalFile.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hDesFile == INVALID_HANDLE_VALUE)
{
return FALSE;
}
LARGE_INTEGER lisize = { 0 };
lisize.QuadPart = 0;
lisize.LowPart = SetFilePointer(hDesFile, lisize.LowPart, &lisize.HighPart, FILE_BEGIN);
if (lisize.LowPart == INVALID_SET_FILE_POINTER && GetLastError() != NO_ERROR)
{
return FALSE;
}
ULARGE_INTEGER ulisize = { 0 };
ulisize.LowPart = GetFileSize(hDesFile, &ulisize.HighPart);
if (ulisize.LowPart == INVALID_FILE_SIZE && (GetLastError()) != NO_ERROR)
{
return FALSE;
}
char szFileDataBuf[WRITEBUFFERSIZE];
ULONGLONG uCycles = ulisize.QuadPart / WRITEBUFFERSIZE;
for (ULONGLONG i = 0; i <= uCycles; i++)
{
ZeroMemory(szFileDataBuf, WRITEBUFFERSIZE);
DWORD dwWrite = 0;
if (!ReadFile(hDesFile, szFileDataBuf, WRITEBUFFERSIZE, &dwWrite, NULL))
{
// CDatabase::ShowError(GetDesktopWindow());
zipCloseFileInZip(zip);
return FALSE;
}
zipWriteInFileInZip(zip, szFileDataBuf, dwWrite);
if (dwWrite < WRITEBUFFERSIZE)
{
//MessageBox(NULL,"dwWrite<WRITEBUFFERSIZE","",0);
break;
}
}
zipCloseFileInZip(zip);
CloseHandle(hDesFile);
//MessageBox(NULL,"CloseHandle(hDestinationFile);","",0);
}
ZeroMemory(&wfd, sizeof(WIN32_FIND_DATAA));
bRet = FindNextFileA(fhn, &wfd);
}
FindClose(fhn);
return TRUE;
}
bool ZipFolder::DetectFolderFile(char *szFolder)
{
char Path[MAX_PATH] = { 0 };
lstrcpyA(Path, szFolder);
lstrcatA(Path, "*.*");
WIN32_FIND_DATAA wfd = { 0 };
HANDLE fhn = FindFirstFileA(Path, &wfd);
if (fhn == INVALID_HANDLE_VALUE)
{
FindClose(fhn);
return false;
}
bool bRet = TRUE;
while (bRet)
{
char TempName[MAX_PATH] = { 0 };
if (
(wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) &&
(lstrcmpA(".", wfd.cFileName) != 0) &&
(lstrcmpA("..", wfd.cFileName) != 0))
{
lstrcatA(TempName, szFolder);
lstrcatA(TempName, wfd.cFileName);
lstrcatA(TempName, "\\");
DetectFolderFile(TempName);
}
else if (lstrcmpA(".", wfd.cFileName) != 0 && lstrcmpA("..", wfd.cFileName) != 0)
{
lstrcatA(TempName, szFolder);
lstrcatA(TempName, wfd.cFileName);
HANDLE hFile = CreateFileA(TempName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
FindClose(fhn);
CloseHandle(hFile);
return false;
}
CloseHandle(hFile);
}
ZeroMemory(&wfd, sizeof(WIN32_FIND_DATAA));
bRet = FindNextFileA(fhn, &wfd);
}
FindClose(fhn);
return true;
}
bool ZipFolder::ExistFolder(char *lpszFolder)
{
DWORD ftyp = GetFileAttributesA(lpszFolder);
if (ftyp == INVALID_FILE_ATTRIBUTES)
{
return false; //something is wrong with your path!
}
if (ftyp & FILE_ATTRIBUTE_DIRECTORY)
{
return true; // this is a directory!
}
return false; // this is not a directory!
}
#pragma region 创建多级目录
#ifdef WIN32
#include <direct.h>
#include <io.h>
#elif LINUX
#include <stdarg.h>
#include <sys/stat.h>
#endif
#ifdef WIN32
#define ACCESS _access
#define MKDIR(a) _mkdir((a))
#elif LINUX
#define ACCESS access
#define MKDIR(a) mkdir((a),0755)
#endif
int ZipFolder::CreateDir(char *pszDir)
{
int i = 0;
int iRet;
int iLen = strlen(pszDir);
//在末尾加/
if (pszDir[iLen - 1] != '\\'&&pszDir[iLen - 1] != '/')
{
pszDir[iLen] = '/';
pszDir[iLen + 1] = '\0';
}
// 创建目录
for (i = 0; i <= iLen; i++)
{
if (pszDir[i] == '\\' || pszDir[i] == '/')
{
pszDir[i] = '\0';
//如果不存在,创建
iRet = ACCESS(pszDir, 0);
if (iRet != 0)
{
iRet = MKDIR(pszDir);
if (iRet != 0)
{
return-1;
}
}
//支持linux,将所有\换成/
pszDir[i] = '/';
}
}
return 0;
}
#pragma endregion