123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352 |
- //------------------------------------------------------------------------------
- //
- // Copyright (C) Streamlet. All rights reserved.
- //
- // File Name: ZLibWrapLib.cpp
- // Author: Streamlet
- // Create Time: 2010-09-16
- // Description:
- //
- // Version history:
- //
- //
- //
- //------------------------------------------------------------------------------
- #include "stdafx.h"
- #include "ZLibWrapLib.h"
- #include "Encoding.h"
- #include "Loki/ScopeGuard.h"
- #include "ZLib/zip.h"
- #include "ZLib/unzip.h"
- #include <atlstr.h>
- #define ZIP_GPBF_LANGUAGE_ENCODING_FLAG 0x800
- BOOL ZipAddFile(zipFile zf, LPCTSTR lpszFileNameInZip, LPCTSTR lpszFilePath, bool bUtf8 = false)
- {
- DWORD dwFileAttr = GetFileAttributes(lpszFilePath);
- if (dwFileAttr == INVALID_FILE_ATTRIBUTES)
- {
- return false;
- }
- DWORD dwOpenAttr = (dwFileAttr & FILE_ATTRIBUTE_DIRECTORY) != 0 ? FILE_FLAG_BACKUP_SEMANTICS : 0;
- HANDLE hFile = CreateFile(lpszFilePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, dwOpenAttr, NULL);
- if (hFile == INVALID_HANDLE_VALUE)
- {
- return FALSE;
- }
- LOKI_ON_BLOCK_EXIT(CloseHandle, hFile);
-
- FILETIME ftUTC, ftLocal;
- GetFileTime(hFile, NULL, NULL, &ftUTC);
- FileTimeToLocalFileTime(&ftUTC, &ftLocal);
- WORD wDate, wTime;
- FileTimeToDosDateTime(&ftLocal, &wDate, &wTime);
- zip_fileinfo FileInfo;
- ZeroMemory(&FileInfo, sizeof(FileInfo));
- FileInfo.dosDate = ((((DWORD)wDate) << 16) | (DWORD)wTime);
- FileInfo.external_fa |= dwFileAttr;
- if (bUtf8)
- {
- CStringA strFileNameInZipA = UCS2ToANSI(lpszFileNameInZip, CP_UTF8);
- if (zipOpenNewFileInZip4(zf, strFileNameInZipA, &FileInfo, NULL, 0, NULL, 0, NULL, Z_DEFLATED, 9,
- 0, -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, NULL, 0, 0, ZIP_GPBF_LANGUAGE_ENCODING_FLAG) != ZIP_OK)
- {
- return FALSE;
- }
- }
- else
- {
- CStringA strFileNameInZipA = UCS2ToANSI(lpszFileNameInZip);
- if (zipOpenNewFileInZip(zf, strFileNameInZipA, &FileInfo, NULL, 0, NULL, 0, NULL, Z_DEFLATED, 9) != ZIP_OK)
- {
- return FALSE;
- }
- }
- LOKI_ON_BLOCK_EXIT(zipCloseFileInZip, zf);
- if ((dwFileAttr & FILE_ATTRIBUTE_DIRECTORY) != 0)
- {
- return TRUE;
- }
- const DWORD BUFFER_SIZE = 4096;
- BYTE byBuffer[BUFFER_SIZE];
- LARGE_INTEGER li = {};
- if (!GetFileSizeEx(hFile, &li))
- {
- return FALSE;
- }
- while (li.QuadPart > 0)
- {
- DWORD dwSizeToRead = li.QuadPart > (LONGLONG)BUFFER_SIZE ? BUFFER_SIZE : (DWORD)li.LowPart;
- DWORD dwRead = 0;
- if (!ReadFile(hFile, byBuffer, dwSizeToRead, &dwRead, NULL))
- {
- return FALSE;
- }
- if (zipWriteInFileInZip(zf, byBuffer, dwRead) < 0)
- {
- return FALSE;
- }
- li.QuadPart -= (LONGLONG)dwRead;
- }
- return TRUE;
- }
- BOOL ZipAddFiles(zipFile zf, LPCTSTR lpszFileNameInZip, LPCTSTR lpszFiles, bool bUtf8 = false)
- {
- WIN32_FIND_DATA wfd;
- ZeroMemory(&wfd, sizeof(wfd));
- HANDLE hFind = FindFirstFile(lpszFiles, &wfd);
- if (hFind == INVALID_HANDLE_VALUE)
- {
- return FALSE;
- }
- LOKI_ON_BLOCK_EXIT(FindClose, hFind);
- CString strFilePath = lpszFiles;
- int nPos = strFilePath.ReverseFind('\\');
- if (nPos != -1)
- {
- strFilePath = strFilePath.Left(nPos + 1);
- }
- else
- {
- strFilePath.Empty();
- }
- CString strFileNameInZip = lpszFileNameInZip;
-
- do
- {
- CString strFileName = wfd.cFileName;
- if (strFileName == _T(".") || strFileName == _T(".."))
- {
- continue;
- }
- if ((wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0)
- {
- if (!ZipAddFile(zf, strFileNameInZip + strFileName + _T("/"), strFilePath + strFileName, bUtf8))
- {
- return FALSE;
- }
- if (!ZipAddFiles(zf, strFileNameInZip + strFileName + _T("/"), strFilePath + strFileName + _T("\\*"), bUtf8))
- {
- return FALSE;
- }
- }
- else
- {
- if (!ZipAddFile(zf, strFileNameInZip + strFileName, strFilePath + strFileName, bUtf8))
- {
- return FALSE;
- }
- }
- } while (FindNextFile(hFind, &wfd));
- return TRUE;
- }
- BOOL ZipCompress(LPCTSTR lpszSourceFiles, LPCTSTR lpszDestFile, bool bUtf8 /*= false*/)
- {
- CStringA strDestFile = UCS2ToANSI(lpszDestFile);
- zipFile zf = zipOpen64(strDestFile, 0);
- if (zf == NULL)
- {
- return FALSE;
- }
- LOKI_ON_BLOCK_EXIT(zipClose, zf, (const char *)NULL);
- if (!ZipAddFiles(zf, _T(""), lpszSourceFiles, bUtf8))
- {
- return FALSE;
- }
- return TRUE;
- }
- BOOL ZipExtractCurrentFile(unzFile uf, LPCTSTR lpszDestFolder)
- {
- char szFilePathA[MAX_PATH];
- unz_file_info64 FileInfo;
- if (unzGetCurrentFileInfo64(uf, &FileInfo, szFilePathA, sizeof(szFilePathA), NULL, 0, NULL, 0) != UNZ_OK)
- {
- return FALSE;
- }
- if (unzOpenCurrentFile(uf) != UNZ_OK)
- {
- return FALSE;
- }
-
- LOKI_ON_BLOCK_EXIT(unzCloseCurrentFile, uf);
- CString strDestPath = lpszDestFolder;
- CString strFileName;
- if ((FileInfo.flag & ZIP_GPBF_LANGUAGE_ENCODING_FLAG) != 0)
- {
- strFileName = ANSIToUCS2(szFilePathA, CP_UTF8);
- }
- else
- {
- strFileName = ANSIToUCS2(szFilePathA);
- }
- int nLength = strFileName.GetLength();
- LPTSTR lpszFileName = strFileName.GetBuffer();
- LPTSTR lpszCurrentFile = lpszFileName;
- LOKI_ON_BLOCK_EXIT_OBJ(strFileName, &CString::ReleaseBuffer, -1);
- for (int i = 0; i <= nLength; ++i)
- {
- if (lpszFileName[i] == _T('\0'))
- {
- strDestPath += lpszCurrentFile;
- break;
- }
- if (lpszFileName[i] == '\\' || lpszFileName[i] == '/')
- {
- lpszFileName[i] = '\0';
- strDestPath += lpszCurrentFile;
- strDestPath += _T("\\");
- CreateDirectory(strDestPath, NULL);
-
- lpszCurrentFile = lpszFileName + i + 1;
- }
- }
- if (lpszCurrentFile[0] == _T('\0'))
- {
- return TRUE;
- }
- HANDLE hFile = CreateFile(strDestPath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
- if (hFile == INVALID_HANDLE_VALUE)
- {
- DWORD error = GetLastError();
- return FALSE;
- }
- LOKI_ON_BLOCK_EXIT(CloseHandle, hFile);
-
- const DWORD BUFFER_SIZE = 4096;
- BYTE byBuffer[BUFFER_SIZE];
- while (true)
- {
- int nSize = unzReadCurrentFile(uf, byBuffer, BUFFER_SIZE);
- if (nSize < 0)
- {
- return FALSE;
- }
- else if (nSize == 0)
- {
- break;
- }
- else
- {
- DWORD dwWritten = 0;
- if (!WriteFile(hFile, byBuffer, (DWORD)nSize, &dwWritten, NULL) || dwWritten != (DWORD)nSize)
- {
- return FALSE;
- }
- }
- }
- FILETIME ftLocal, ftUTC;
- DosDateTimeToFileTime((WORD)(FileInfo.dosDate>>16), (WORD)FileInfo.dosDate, &ftLocal);
- LocalFileTimeToFileTime(&ftLocal, &ftUTC);
- SetFileTime(hFile, &ftUTC, &ftUTC, &ftUTC);
-
- return TRUE;
- }
- BOOL ZipExtract(LPCTSTR lpszSourceFile, LPCTSTR lpszDestFolder)
- {
- CStringA strSourceFileA = UCS2ToANSI(lpszSourceFile);
- unzFile uf = unzOpen64(strSourceFileA);
- if (uf == NULL)
- {
- return FALSE;
- }
- LOKI_ON_BLOCK_EXIT(unzClose, uf);
- unz_global_info64 gi;
- if (unzGetGlobalInfo64(uf, &gi) != UNZ_OK)
- {
- return FALSE;
- }
- CString strDestFolder = lpszDestFolder;
- CreateDirectory(lpszDestFolder, NULL);
- if (!strDestFolder.IsEmpty() && strDestFolder[strDestFolder.GetLength() - 1] != _T('\\'))
- {
- strDestFolder += _T("\\");
- }
-
- for (int i = 0; i < gi.number_entry; ++i)
- {
- if (!ZipExtractCurrentFile(uf, strDestFolder))
- {
- return FALSE;
- }
-
- if (i < gi.number_entry - 1)
- {
- if (unzGoToNextFile(uf) != UNZ_OK)
- {
- return FALSE;
- }
- }
- }
-
- return TRUE;
- }
|