diff options
Diffstat (limited to 'src/Common')
-rw-r--r-- | src/Common/Dlgcode.c | 69 | ||||
-rw-r--r-- | src/Common/Dlgcode.h | 5 |
2 files changed, 74 insertions, 0 deletions
diff --git a/src/Common/Dlgcode.c b/src/Common/Dlgcode.c index 5ff9a83b..fcc69514 100644 --- a/src/Common/Dlgcode.c +++ b/src/Common/Dlgcode.c @@ -59,6 +59,7 @@ #include "Xts.h" #include "Boot/Windows/BootCommon.h" #include "Progress.h" +#include "zip.h" #ifdef TCMOUNT #include "Mount/Mount.h" @@ -6967,6 +6968,17 @@ void CorrectFileName (wchar_t* fileName) } } +void CorrectFileName (std::wstring& fileName) +{ + /* replace '/' by '\' */ + size_t i, len = fileName.length(); + for (i = 0; i < len; i++) + { + if (fileName [i] == L'/') + fileName [i] = L'\\'; + } +} + void CorrectURL (wchar_t* fileName) { /* replace '\' by '/' */ @@ -8578,6 +8590,63 @@ BOOL TCCopyFile (wchar_t *sourceFileName, wchar_t *destinationFile) return TCCopyFileBase (src, dst); } +BOOL DecompressZipToDir (const unsigned char *inputBuffer, DWORD inputLength, const wchar_t *destinationDir, ProgressFn progressFnPtr, HWND hwndDlg) +{ + BOOL res = TRUE; + zip_error_t zerr; + zip_int64_t numFiles, i; + zip_stat_t sb; + zip_source_t* zsrc = zip_source_buffer_create (inputBuffer, inputLength, 0, &zerr); + if (!zsrc) + return FALSE; + zip_t* z = zip_open_from_source (zsrc, ZIP_CHECKCONS | ZIP_RDONLY, &zerr); + if (!z) + { + zip_source_free (zsrc); + return FALSE; + } + + finally_do_arg (zip_t*, z, { zip_close (finally_arg); }); + + numFiles = zip_get_num_entries (z, 0); + if (numFiles <= 0) + return FALSE; + + for (i = 0; (i < numFiles) && res; i++) + { + ZeroMemory (&sb, sizeof (sb)); + if ((0 == zip_stat_index (z, i, 0, &sb)) && (sb.valid & (ZIP_STAT_NAME | ZIP_STAT_SIZE)) && (sb.size > 0)) + { + std::wstring wname = Utf8StringToWide (sb.name); + CorrectFileName (wname); + + std::wstring filePath = destinationDir + wname; + size_t pos = filePath.find_last_of (L"/\\"); + // create the parent directory if it doesn't exist + if (pos != std::wstring::npos) + { + SHCreateDirectoryEx (NULL, filePath.substr (0, pos).c_str(), NULL); + } + + zip_file_t *f = zip_fopen_index (z, i, 0); + if (f) + { + ByteArray buffer((ByteArray::size_type) sb.size); + + zip_fread (f, buffer.data(), sb.size); + zip_fclose (f); + + if (progressFnPtr) + progressFnPtr (hwndDlg, filePath.c_str()); + + res = SaveBufferToFile ((char *) buffer.data(), filePath.c_str(), (DWORD) buffer.size(), FALSE, TRUE); + } + } + } + + return res; +} + // If bAppend is TRUE, the buffer is appended to an existing file. If bAppend is FALSE, any existing file // is replaced. If an error occurs, the incomplete file is deleted (provided that bAppend is FALSE). BOOL SaveBufferToFile (const char *inputBuffer, const wchar_t *destinationFile, DWORD inputLength, BOOL bAppend, BOOL bRenameIfFailed) diff --git a/src/Common/Dlgcode.h b/src/Common/Dlgcode.h index 8d92cf40..d902d3cc 100644 --- a/src/Common/Dlgcode.h +++ b/src/Common/Dlgcode.h @@ -368,6 +368,8 @@ BOOL FileExists (const wchar_t *filePathPtr); __int64 FindStringInFile (const wchar_t *filePath, const char *str, int strLen); BOOL TCCopyFile (wchar_t *sourceFileName, wchar_t *destinationFile); BOOL SaveBufferToFile (const char *inputBuffer, const wchar_t *destinationFile, DWORD inputLength, BOOL bAppend, BOOL bRenameIfFailed); +typedef void (_cdecl *ProgressFn) ( HWND hwndDlg , const wchar_t *txt ); +BOOL DecompressZipToDir (const unsigned char *inputBuffer, DWORD inputLength, const wchar_t *destinationFile, ProgressFn progressFnPtr, HWND hwndDlg); BOOL TCFlushFile (FILE *f); BOOL PrintHardCopyTextUTF16 (wchar_t *text, wchar_t *title, size_t byteLen); void GetSpeedString (unsigned __int64 speed, wchar_t *str, size_t cbStr); @@ -526,6 +528,8 @@ INT_PTR SecureDesktopDialogBoxParam (HINSTANCE, LPCWSTR, HWND, DLGPROC, LPARAM); #include <vector> #include <string> +typedef std::vector<unsigned char> ByteArray; + struct HostDevice { HostDevice () @@ -588,6 +592,7 @@ bool HexWideStringToArray (const wchar_t* hexStr, std::vector<byte>& arr); std::wstring FindDeviceByVolumeID (const BYTE volumeID [VOLUME_ID_SIZE]); void RegisterDriverInf (bool registerFilter, const std::string& filter, const std::string& filterReg, HWND ParentWindow, HKEY regKey); std::wstring GetTempPathString (); +void CorrectFileName (std::wstring& fileName); inline std::wstring AppendSrcPos (const wchar_t* msg, const char* srcPos) { return std::wstring (msg? msg : L"") + L"\n\nSource: " + SingleStringToWide (srcPos); |