diff --git a/dll/shellext/zipfldr/CConfirmReplace.cpp b/dll/shellext/zipfldr/CConfirmReplace.cpp index 8ee027a52ec..632fd378b28 100644 --- a/dll/shellext/zipfldr/CConfirmReplace.cpp +++ b/dll/shellext/zipfldr/CConfirmReplace.cpp @@ -10,7 +10,7 @@ class CConfirmReplace : public CDialogImpl { private: - CStringA m_Filename; + CStringW m_Filename; public: CConfirmReplace(const char* filename) @@ -18,6 +18,11 @@ public: { } + CConfirmReplace(const wchar_t* filename) + : m_Filename(filename) + { + } + LRESULT OnInitDialog(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { CenterWindow(GetParent()); @@ -25,9 +30,9 @@ public: HICON hIcon = LoadIcon(NULL, IDI_EXCLAMATION); SendDlgItemMessage(IDC_EXCLAMATION_ICON, STM_SETICON, (WPARAM)hIcon); - CStringA message; + CStringW message; message.FormatMessage(IDS_OVERWRITEFILE_TEXT, m_Filename.GetString()); - ::SetDlgItemTextA(m_hWnd, IDC_MESSAGE, message); + ::SetDlgItemTextW(m_hWnd, IDC_MESSAGE, message); return TRUE; } @@ -65,3 +70,18 @@ eZipConfirmResponse _CZipAskReplace(HWND hDlg, PCSTR FullPath) case IDCANCEL: return eCancel; } } + +eZipConfirmResponse _CZipAskReplaceW(HWND hDlg, PCWSTR FullPath) +{ + PCWSTR Filename = PathFindFileNameW(FullPath); + CConfirmReplace confirm(Filename); + INT_PTR Result = confirm.DoModal(hDlg); + switch (Result) + { + case IDYES: return eYes; + case IDYESALL: return eYesToAll; + default: + case IDNO: return eNo; + case IDCANCEL: return eCancel; + } +} diff --git a/dll/shellext/zipfldr/CZipExtract.cpp b/dll/shellext/zipfldr/CZipExtract.cpp index 20a8087a029..20e31257c5e 100644 --- a/dll/shellext/zipfldr/CZipExtract.cpp +++ b/dll/shellext/zipfldr/CZipExtract.cpp @@ -439,7 +439,18 @@ public: return eOpenError; } - HANDLE hFile = CreateFileA(FullPath, GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL); + HANDLE hFile; + WCHAR WideFullPath[MAX_PATH]; + if (Info->flag & MINIZIP_UTF8_FLAG) + { + MultiByteToWideChar(CP_UTF8, 0, FullPath, -1, WideFullPath, _countof(WideFullPath)); + hFile = CreateFileW(WideFullPath, GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL); + } + else + { + hFile = CreateFileA(FullPath, GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL); + } + if (hFile == INVALID_HANDLE_VALUE) { DWORD dwErr = GetLastError(); @@ -448,7 +459,11 @@ public: bool bOverwrite = *bOverwriteAll; if (!*bOverwriteAll) { - eZipConfirmResponse Result = _CZipAskReplace(hDlg, FullPath); + eZipConfirmResponse Result; + if (Info->flag & MINIZIP_UTF8_FLAG) + Result = _CZipAskReplace(hDlg, FullPath); + else + Result = _CZipAskReplaceW(hDlg, WideFullPath); switch (Result) { case eYesToAll: @@ -467,7 +482,10 @@ public: if (bOverwrite) { - hFile = CreateFileA(FullPath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + if (Info->flag & MINIZIP_UTF8_FLAG) + hFile = CreateFileW(WideFullPath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + else + hFile = CreateFileA(FullPath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) { dwErr = GetLastError(); @@ -493,9 +511,13 @@ public: if (*bCancel) { CloseHandle(hFile); - BOOL deleteResult = DeleteFileA(FullPath); + BOOL deleteResult; + if (Info->flag & MINIZIP_UTF8_FLAG) + deleteResult = DeleteFileW(WideFullPath); + else + deleteResult = DeleteFileA(FullPath); if (!deleteResult) - DPRINT1("ERROR, DeleteFileA: 0x%x\n", GetLastError()); + DPRINT1("ERROR, DeleteFile: 0x%x\n", GetLastError()); return eExtractAbort; } diff --git a/dll/shellext/zipfldr/CZipFolder.hpp b/dll/shellext/zipfldr/CZipFolder.hpp index 29644d95c2b..7931aebf216 100644 --- a/dll/shellext/zipfldr/CZipFolder.hpp +++ b/dll/shellext/zipfldr/CZipFolder.hpp @@ -444,6 +444,12 @@ public: if (!zipEntry) return E_FAIL; + if (zipEntry->Utf8) + { + WCHAR wide[MAX_PATH]; + ::MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)zipEntry->Name, -1, wide, _countof(wide)); + return SHSetStrRet(strRet, wide); + } return SHSetStrRet(strRet, (LPCSTR)zipEntry->Name); } STDMETHODIMP SetNameOf(HWND hwndOwner, PCUITEMID_CHILD pidl, LPCOLESTR lpName, DWORD dwFlags, PITEMID_CHILD *pPidlOut) diff --git a/dll/shellext/zipfldr/precomp.h b/dll/shellext/zipfldr/precomp.h index b5845168073..d7b2ef1263b 100644 --- a/dll/shellext/zipfldr/precomp.h +++ b/dll/shellext/zipfldr/precomp.h @@ -41,6 +41,7 @@ WCHAR* guid2string(REFCLSID iid); #define MINIZIP_PASSWORD_FLAG 1 +#define MINIZIP_UTF8_FLAG (1 << 11) #include "minizip/unzip.h" #include "minizip/ioapi.h" @@ -75,6 +76,7 @@ enum eZipConfirmResponse }; eZipConfirmResponse _CZipAskReplace(HWND hDlg, const char* FullPath); +eZipConfirmResponse _CZipAskReplaceW(HWND hDlg, const wchar_t* FullPath); enum eZipExtractError { diff --git a/dll/shellext/zipfldr/zippidl.cpp b/dll/shellext/zipfldr/zippidl.cpp index 09f26cd6f21..f906863b3f8 100644 --- a/dll/shellext/zipfldr/zippidl.cpp +++ b/dll/shellext/zipfldr/zippidl.cpp @@ -26,6 +26,7 @@ LPITEMIDLIST _ILCreate(ZipPidlType Type, LPCSTR lpString, unz_file_info64& info) pidl->UncompressedSize = info.uncompressed_size; pidl->DosDate = info.dosDate; pidl->Password = info.flag & MINIZIP_PASSWORD_FLAG; + pidl->Utf8 = !!(info.flag & MINIZIP_UTF8_FLAG); } strcpy(pidl->Name, lpString); diff --git a/dll/shellext/zipfldr/zippidl.hpp b/dll/shellext/zipfldr/zippidl.hpp index 8c81158525f..ae3b45ee7f7 100644 --- a/dll/shellext/zipfldr/zippidl.hpp +++ b/dll/shellext/zipfldr/zippidl.hpp @@ -23,6 +23,7 @@ struct ZipPidlEntry ULONG64 UncompressedSize; ULONG DosDate; BYTE Password; + BYTE Utf8; char Name[1]; };