https://git.reactos.org/?p=reactos.git;a=commitdiff;h=bf2cec186cc7655e062ec…
commit bf2cec186cc7655e062ec0e53ccfac860bcae70d
Author: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com>
AuthorDate: Mon Jul 17 20:12:45 2023 +0900
Commit: GitHub <noreply(a)github.com>
CommitDate: Mon Jul 17 20:12:45 2023 +0900
[ZIPFLDR] Support UTF-8 Zip extraction (#5411)
- Extend some Ansi strings to Wide strings.
- Check the UTF-8 flag (1 << 11). If UTF-8, then use CP_UTF8.
- s/LPCWSTR/PCWSTR/.
- s/LPWSTR/PWSTR/.
CORE-16668
---
dll/shellext/zipfldr/CConfirmReplace.cpp | 15 ++++----
dll/shellext/zipfldr/CEnumZipContents.cpp | 11 +++---
dll/shellext/zipfldr/CExplorerCommand.cpp | 6 +--
dll/shellext/zipfldr/CZipCreator.cpp | 20 +++++-----
dll/shellext/zipfldr/CZipCreator.hpp | 2 +-
dll/shellext/zipfldr/CZipEnumerator.hpp | 29 ++++++++------
dll/shellext/zipfldr/CZipExtract.cpp | 63 +++++++++++++++++--------------
dll/shellext/zipfldr/CZipFolder.hpp | 33 +++++++---------
dll/shellext/zipfldr/CZipPassword.cpp | 17 +++++----
dll/shellext/zipfldr/precomp.h | 9 +++--
dll/shellext/zipfldr/zipfldr.cpp | 16 ++++++--
dll/shellext/zipfldr/zippidl.cpp | 15 +++++---
dll/shellext/zipfldr/zippidl.hpp | 10 ++---
13 files changed, 134 insertions(+), 112 deletions(-)
diff --git a/dll/shellext/zipfldr/CConfirmReplace.cpp
b/dll/shellext/zipfldr/CConfirmReplace.cpp
index 8ee027a52ec..cdbf9be5ece 100644
--- a/dll/shellext/zipfldr/CConfirmReplace.cpp
+++ b/dll/shellext/zipfldr/CConfirmReplace.cpp
@@ -3,6 +3,7 @@
* LICENSE: GPL-2.0+ (
https://spdx.org/licenses/GPL-2.0+)
* PURPOSE: Ask the user to replace a file
* COPYRIGHT: Copyright 2017-2019 Mark Jansen (mark.jansen(a)reactos.org)
+ * Copyright 2023 Katayama Hirofumi MZ (katayama.hirofumi.mz(a)gmail.com)
*/
#include "precomp.h"
@@ -10,10 +11,9 @@
class CConfirmReplace : public CDialogImpl<CConfirmReplace>
{
private:
- CStringA m_Filename;
+ CStringW m_Filename;
public:
-
- CConfirmReplace(const char* filename)
+ CConfirmReplace(PCWSTR filename)
: m_Filename(filename)
{
}
@@ -25,9 +25,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;
}
@@ -50,10 +50,9 @@ public:
END_MSG_MAP()
};
-
-eZipConfirmResponse _CZipAskReplace(HWND hDlg, PCSTR FullPath)
+eZipConfirmResponse _CZipAskReplace(HWND hDlg, PCWSTR FullPath)
{
- PCSTR Filename = PathFindFileNameA(FullPath);
+ PCWSTR Filename = PathFindFileNameW(FullPath);
CConfirmReplace confirm(Filename);
INT_PTR Result = confirm.DoModal(hDlg);
switch (Result)
diff --git a/dll/shellext/zipfldr/CEnumZipContents.cpp
b/dll/shellext/zipfldr/CEnumZipContents.cpp
index 0899468f9d7..372e21ba772 100644
--- a/dll/shellext/zipfldr/CEnumZipContents.cpp
+++ b/dll/shellext/zipfldr/CEnumZipContents.cpp
@@ -3,6 +3,7 @@
* LICENSE: GPL-2.0+ (
https://spdx.org/licenses/GPL-2.0+)
* PURPOSE: CEnumZipContents
* COPYRIGHT: Copyright 2017 Mark Jansen (mark.jansen(a)reactos.org)
+ * Copyright 2023 Katayama Hirofumi MZ (katayama.hirofumi.mz(a)gmail.com)
*/
#include "precomp.h"
@@ -14,14 +15,14 @@ class CEnumZipContents :
private:
CZipEnumerator mEnumerator;
DWORD dwFlags;
- CStringA m_Prefix;
+ CStringW m_Prefix;
public:
CEnumZipContents()
:dwFlags(0)
{
}
- STDMETHODIMP Initialize(IZip* zip, DWORD flags, const char* prefix)
+ STDMETHODIMP Initialize(IZip* zip, DWORD flags, PCWSTR prefix)
{
dwFlags = flags;
m_Prefix = prefix;
@@ -41,7 +42,7 @@ public:
if (celt != 1)
return E_FAIL;
- CStringA name;
+ CStringW name;
bool dir;
unz_file_info64 info;
if (mEnumerator.next_unique(m_Prefix, name, dir, info))
@@ -55,7 +56,7 @@ public:
}
STDMETHODIMP Skip(ULONG celt)
{
- CStringA name;
+ CStringW name;
bool dir;
unz_file_info64 info;
while (celt--)
@@ -88,7 +89,7 @@ public:
};
-HRESULT _CEnumZipContents_CreateInstance(IZip* zip, DWORD flags, const char* prefix,
REFIID riid, LPVOID * ppvOut)
+HRESULT _CEnumZipContents_CreateInstance(IZip* zip, DWORD flags, PCWSTR prefix, REFIID
riid, LPVOID * ppvOut)
{
return ShellObjectCreatorInit<CEnumZipContents>(zip, flags, prefix, riid,
ppvOut);
}
diff --git a/dll/shellext/zipfldr/CExplorerCommand.cpp
b/dll/shellext/zipfldr/CExplorerCommand.cpp
index 1e634f81c81..8f007509d86 100644
--- a/dll/shellext/zipfldr/CExplorerCommand.cpp
+++ b/dll/shellext/zipfldr/CExplorerCommand.cpp
@@ -23,17 +23,17 @@ public:
}
// *** IExplorerCommand methods ***
- STDMETHODIMP GetTitle(IShellItemArray *psiItemArray, LPWSTR *ppszName)
+ STDMETHODIMP GetTitle(IShellItemArray *psiItemArray, PWSTR *ppszName)
{
CStringW Title(MAKEINTRESOURCEW(IDS_MENUITEM));
return SHStrDup(Title, ppszName);
}
- STDMETHODIMP GetIcon(IShellItemArray *psiItemArray, LPWSTR *ppszIcon)
+ STDMETHODIMP GetIcon(IShellItemArray *psiItemArray, PWSTR *ppszIcon)
{
CStringW IconName = L"zipfldr.dll,-1";
return SHStrDup(IconName, ppszIcon);
}
- STDMETHODIMP GetToolTip(IShellItemArray *psiItemArray, LPWSTR *ppszInfotip)
+ STDMETHODIMP GetToolTip(IShellItemArray *psiItemArray, PWSTR *ppszInfotip)
{
CStringW HelpText(MAKEINTRESOURCEW(IDS_HELPTEXT));
return SHStrDup(HelpText, ppszInfotip);
diff --git a/dll/shellext/zipfldr/CZipCreator.cpp b/dll/shellext/zipfldr/CZipCreator.cpp
index 62b6a3929e7..00f44932b42 100644
--- a/dll/shellext/zipfldr/CZipCreator.cpp
+++ b/dll/shellext/zipfldr/CZipCreator.cpp
@@ -12,7 +12,7 @@
#include "minizip/iowin32.h"
#include <process.h>
-static CStringW DoGetZipName(LPCWSTR filename)
+static CStringW DoGetZipName(PCWSTR filename)
{
WCHAR szPath[MAX_PATH];
StringCbCopyW(szPath, sizeof(szPath), filename);
@@ -34,14 +34,14 @@ static CStringW DoGetZipName(LPCWSTR filename)
return ret;
}
-static CStringA DoGetAnsiName(LPCWSTR filename)
+static CStringA DoGetAnsiName(PCWSTR filename)
{
CHAR buf[MAX_PATH];
WideCharToMultiByte(CP_ACP, 0, filename, -1, buf, _countof(buf), NULL, NULL);
return buf;
}
-static CStringW DoGetBaseName(LPCWSTR filename)
+static CStringW DoGetBaseName(PCWSTR filename)
{
WCHAR szBaseName[MAX_PATH];
StringCbCopyW(szBaseName, sizeof(szBaseName), filename);
@@ -69,7 +69,7 @@ DoGetNameInZip(const CStringW& basename, const CStringW&
filename)
}
static BOOL
-DoReadAllOfFile(LPCWSTR filename, CSimpleArray<BYTE>& contents,
+DoReadAllOfFile(PCWSTR filename, CSimpleArray<BYTE>& contents,
zip_fileinfo *pzi)
{
contents.RemoveAll();
@@ -124,7 +124,7 @@ DoReadAllOfFile(LPCWSTR filename, CSimpleArray<BYTE>&
contents,
}
static void
-DoAddFilesFromItem(CSimpleArray<CStringW>& files, LPCWSTR item)
+DoAddFilesFromItem(CSimpleArray<CStringW>& files, PCWSTR item)
{
if (!PathIsDirectoryW(item))
{
@@ -208,7 +208,7 @@ BOOL CZipCreator::runThread(CZipCreator *pCreator)
return FALSE;
}
-void CZipCreator::DoAddItem(LPCWSTR pszFile)
+void CZipCreator::DoAddItem(PCWSTR pszFile)
{
// canonicalize path
WCHAR szPath[MAX_PATH];
@@ -247,7 +247,7 @@ unsigned CZipCreatorImpl::JustDoIt()
CStringW strTitle(MAKEINTRESOURCEW(IDS_ERRORTITLE));
CStringW strText;
- strText.Format(IDS_NOFILES, static_cast<LPCWSTR>(m_items[0]));
+ strText.Format(IDS_NOFILES, static_cast<PCWSTR>(m_items[0]));
MessageBoxW(NULL, strText, strTitle, MB_ICONERROR);
return CZCERR_NOFILES;
@@ -266,7 +266,7 @@ unsigned CZipCreatorImpl::JustDoIt()
CStringW strTitle(MAKEINTRESOURCEW(IDS_ERRORTITLE));
CStringW strText;
- strText.Format(IDS_CANTCREATEZIP, static_cast<LPCWSTR>(strZipName), err);
+ strText.Format(IDS_CANTCREATEZIP, static_cast<PCWSTR>(strZipName), err);
MessageBoxW(NULL, strText, strTitle, MB_ICONERROR);
return err;
@@ -347,9 +347,9 @@ unsigned CZipCreatorImpl::JustDoIt()
CStringW strText;
if (err < 0)
- strText.Format(IDS_CANTCREATEZIP, static_cast<LPCWSTR>(strZipName),
err);
+ strText.Format(IDS_CANTCREATEZIP, static_cast<PCWSTR>(strZipName),
err);
else
- strText.Format(IDS_CANTREADFILE, static_cast<LPCWSTR>(strTarget));
+ strText.Format(IDS_CANTREADFILE, static_cast<PCWSTR>(strTarget));
MessageBoxW(NULL, strText, strTitle, MB_ICONERROR);
}
diff --git a/dll/shellext/zipfldr/CZipCreator.hpp b/dll/shellext/zipfldr/CZipCreator.hpp
index 1a77451ea8f..8e5ffa8e093 100644
--- a/dll/shellext/zipfldr/CZipCreator.hpp
+++ b/dll/shellext/zipfldr/CZipCreator.hpp
@@ -22,7 +22,7 @@ public:
return new CZipCreator();
}
- virtual void DoAddItem(LPCWSTR pszFile);
+ virtual void DoAddItem(PCWSTR pszFile);
static BOOL runThread(CZipCreator* pCreator);
protected:
diff --git a/dll/shellext/zipfldr/CZipEnumerator.hpp
b/dll/shellext/zipfldr/CZipEnumerator.hpp
index 9948413d908..3e7037c1e5d 100644
--- a/dll/shellext/zipfldr/CZipEnumerator.hpp
+++ b/dll/shellext/zipfldr/CZipEnumerator.hpp
@@ -3,6 +3,7 @@
* LICENSE: GPL-2.0+ (
https://spdx.org/licenses/GPL-2.0+)
* PURPOSE: CZipEnumerator
* COPYRIGHT: Copyright 2017 Mark Jansen (mark.jansen(a)reactos.org)
+ * Copyright 2023 Katayama Hirofumi MZ (katayama.hirofumi.mz(a)gmail.com)
*/
struct CZipEnumerator
@@ -10,7 +11,7 @@ struct CZipEnumerator
private:
CComPtr<IZip> m_Zip;
bool m_First;
- CAtlList<CStringA> m_Returned;
+ CAtlList<CStringW> m_Returned;
public:
CZipEnumerator()
:m_First(true)
@@ -33,15 +34,15 @@ public:
return true;
}
- bool next_unique(const char* prefix, CStringA& name, bool& folder,
unz_file_info64& info)
+ bool next_unique(PCWSTR prefix, CStringW& name, bool& folder,
unz_file_info64& info)
{
- size_t len = strlen(prefix);
- CStringA tmp;
+ size_t len = wcslen(prefix);
+ CStringW tmp;
while (next(tmp, info))
{
- if (!_strnicmp(tmp, prefix, len))
+ if (!_wcsnicmp(tmp, prefix, len))
{
- int pos = tmp.Find('/', len);
+ int pos = tmp.Find(L'/', len);
if (pos < 0)
{
name = tmp.Mid(len);
@@ -66,7 +67,7 @@ public:
return false;
}
- bool next(CStringA& name, unz_file_info64& info)
+ bool next(CStringW& name, unz_file_info64& info)
{
int err;
@@ -84,10 +85,16 @@ public:
err = unzGetCurrentFileInfo64(uf, &info, NULL, 0, NULL, 0, NULL, 0);
if (err == UNZ_OK)
{
- PSTR buf = name.GetBuffer(info.size_filename);
- err = unzGetCurrentFileInfo64(uf, NULL, buf, name.GetAllocLength(), NULL, 0,
NULL, 0);
- name.ReleaseBuffer(info.size_filename);
- name.Replace('\\', '/');
+ CStringA nameA;
+ PSTR buf = nameA.GetBuffer(info.size_filename);
+ err = unzGetCurrentFileInfo64(uf, NULL, buf, nameA.GetAllocLength(), NULL, 0,
NULL, 0);
+ nameA.ReleaseBuffer(info.size_filename);
+ nameA.Replace('\\', '/');
+
+ if (info.flag & MINIZIP_UTF8_FLAG)
+ Utf8ToWide(nameA, name);
+ else
+ name = CStringW(nameA);
}
return err == UNZ_OK;
}
diff --git a/dll/shellext/zipfldr/CZipExtract.cpp b/dll/shellext/zipfldr/CZipExtract.cpp
index 20a8087a029..2e58d7564f6 100644
--- a/dll/shellext/zipfldr/CZipExtract.cpp
+++ b/dll/shellext/zipfldr/CZipExtract.cpp
@@ -3,9 +3,11 @@
* LICENSE: GPL-2.0+ (
https://spdx.org/licenses/GPL-2.0+)
* PURPOSE: Zip extraction
* COPYRIGHT: Copyright 2017-2019 Mark Jansen (mark.jansen(a)reactos.org)
+ * Copyright 2023 Katayama Hirofumi MZ (katayama.hirofumi.mz(a)gmail.com)
*/
#include "precomp.h"
+#include <atlpath.h>
class CZipExtract :
public IZip
@@ -204,7 +206,7 @@ public:
struct browse_info
{
HWND hWnd;
- LPCWSTR Directory;
+ PCWSTR Directory;
};
static INT CALLBACK s_BrowseCallbackProc(HWND hWnd, UINT uMsg, LPARAM lp, LPARAM
pData)
@@ -370,10 +372,10 @@ public:
eZipExtractError ExtractSingle(
HWND hDlg,
- LPCSTR FullPath,
+ PCWSTR FullPath,
bool is_dir,
unz_file_info64* Info,
- CStringA Name,
+ CStringW Name,
CStringA Password,
bool* bOverwriteAll,
const bool* bCancel,
@@ -383,7 +385,7 @@ public:
int err;
BYTE Buffer[2048];
DWORD dwFlags = SHPPFW_DIRCREATE | (is_dir ? SHPPFW_NONE :
SHPPFW_IGNOREFILENAME);
- HRESULT hr = SHPathPrepareForWriteA(hDlg, NULL, FullPath, dwFlags);
+ HRESULT hr = SHPathPrepareForWriteW(hDlg, NULL, FullPath, dwFlags);
if (FAILED_UNEXPECTEDLY(hr))
{
*ErrorCode = hr;
@@ -439,7 +441,7 @@ public:
return eOpenError;
}
- HANDLE hFile = CreateFileA(FullPath, GENERIC_WRITE, 0, NULL, CREATE_NEW,
FILE_ATTRIBUTE_NORMAL, NULL);
+ HANDLE hFile = CreateFileW(FullPath, GENERIC_WRITE, 0, NULL, CREATE_NEW,
FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
DWORD dwErr = GetLastError();
@@ -467,7 +469,7 @@ public:
if (bOverwrite)
{
- hFile = CreateFileA(FullPath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL, NULL);
+ hFile = CreateFileW(FullPath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
dwErr = GetLastError();
@@ -482,7 +484,7 @@ public:
if (hFile == INVALID_HANDLE_VALUE)
{
unzCloseCurrentFile(uf);
- DPRINT1("ERROR, CreateFileA: 0x%x (%s)\n", dwErr,
*bOverwriteAll ? "Y" : "N");
+ DPRINT1("ERROR, CreateFile: 0x%x (%s)\n", dwErr, *bOverwriteAll
? "Y" : "N");
*ErrorCode = dwErr;
return eFileError;
}
@@ -493,9 +495,9 @@ public:
if (*bCancel)
{
CloseHandle(hFile);
- BOOL deleteResult = DeleteFileA(FullPath);
+ BOOL deleteResult = DeleteFileW(FullPath);
if (!deleteResult)
- DPRINT1("ERROR, DeleteFileA: 0x%x\n", GetLastError());
+ DPRINT1("ERROR, DeleteFile: 0x%x\n", GetLastError());
return eExtractAbort;
}
@@ -575,8 +577,8 @@ public:
Progress.SendMessage(PBM_SETRANGE32, 0, gi.number_entry);
Progress.SendMessage(PBM_SETPOS, 0, 0);
- CStringA BaseDirectory = m_Directory;
- CStringA Name;
+ CStringW BaseDirectory = m_Directory;
+ CStringW Name;
CStringA Password = m_Password;
unz_file_info64 Info;
int CurrentFile = 0;
@@ -591,10 +593,15 @@ public:
bool is_dir = Name.GetLength() > 0 && Name[Name.GetLength()-1] ==
'/';
- char CombinedPath[MAX_PATH * 2] = { 0 };
- PathCombineA(CombinedPath, BaseDirectory, Name);
- CStringA FullPath = CombinedPath;
- FullPath.Replace('/', '\\'); /* SHPathPrepareForWriteA
does not handle '/' */
+ // Build a combined path
+ CPathW FullPath(BaseDirectory);
+ FullPath += Name;
+
+ // We use SHPathPrepareForWrite for this path.
+ // SHPathPrepareForWrite will prepare the necessary directories.
+ // Windows and ReactOS SHPathPrepareForWrite do not support '/'.
+ FullPath.m_strPath.Replace(L'/', L'\\');
+
Retry:
eZipExtractError Result = ExtractSingle(hDlg, FullPath, is_dir, &Info,
Name, Password, &bOverwriteAll, bCancel, &err);
if (Result != eDirectoryError)
@@ -613,13 +620,13 @@ public:
case eDirectoryError:
{
- char StrippedPath[MAX_PATH] = { 0 };
+ WCHAR StrippedPath[MAX_PATH] = { 0 };
- StrCpyNA(StrippedPath, FullPath, _countof(StrippedPath));
+ StrCpyNW(StrippedPath, FullPath, _countof(StrippedPath));
if (!is_dir)
- PathRemoveFileSpecA(StrippedPath);
- PathStripPathA(StrippedPath);
- if (ShowExtractError(hDlg, (LPCSTR)&StrippedPath, err,
eDirectoryError) == IDRETRY)
+ PathRemoveFileSpecW(StrippedPath);
+ PathStripPathW(StrippedPath);
+ if (ShowExtractError(hDlg, StrippedPath, err, eDirectoryError) ==
IDRETRY)
goto Retry;
Close();
return false;
@@ -665,11 +672,11 @@ public:
return true;
}
- int ShowExtractError(HWND hDlg, LPCSTR path, int Error, eZipExtractError ErrorType)
+ int ShowExtractError(HWND hDlg, PCWSTR path, int Error, eZipExtractError ErrorType)
{
- CStringA strTitle(MAKEINTRESOURCEW(IDS_ERRORTITLE));
- CStringA strErr, strText;
- PSTR Win32ErrorString;
+ CStringW strTitle(MAKEINTRESOURCEW(IDS_ERRORTITLE));
+ CStringW strErr, strText;
+ PWSTR Win32ErrorString;
if (ErrorType == eFileError || ErrorType == eOpenError)
strText.LoadString(IDS_CANTEXTRACTFILE);
@@ -680,9 +687,9 @@ public:
if (ErrorType == eFileError || HRESULT_FACILITY(Error) == FACILITY_WIN32)
{
- if (FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM,
+ if (FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM,
NULL, ErrorType == eFileError ? Error :
HRESULT_CODE(Error), 0,
- (PSTR)&Win32ErrorString, 0, NULL) != 0)
+ (PWSTR)&Win32ErrorString, 0, NULL) != 0)
{
strErr.SetString(Win32ErrorString);
LocalFree(Win32ErrorString);
@@ -693,7 +700,7 @@ public:
else if (strErr.GetLength() == 0)
strErr.Format(IDS_UNKNOWNERROR, Error);
- strText.Append("\r\n\r\n" + strErr);
+ strText.Append(L"\r\n\r\n" + strErr);
UINT mbFlags = MB_ICONWARNING;
if (ErrorType == eDirectoryError)
@@ -703,7 +710,7 @@ public:
else if (ErrorType == eOpenError)
mbFlags |= MB_YESNO;
- return MessageBoxA(hDlg, strText, strTitle, mbFlags);
+ return MessageBoxW(hDlg, strText, strTitle, mbFlags);
}
};
diff --git a/dll/shellext/zipfldr/CZipFolder.hpp b/dll/shellext/zipfldr/CZipFolder.hpp
index 29644d95c2b..09a3f84ff69 100644
--- a/dll/shellext/zipfldr/CZipFolder.hpp
+++ b/dll/shellext/zipfldr/CZipFolder.hpp
@@ -3,6 +3,7 @@
* LICENSE: GPL-2.0+ (
https://spdx.org/licenses/GPL-2.0+)
* PURPOSE: Main class
* COPYRIGHT: Copyright 2017 Mark Jansen (mark.jansen(a)reactos.org)
+ * Copyright 2023 Katayama Hirofumi MZ (katayama.hirofumi.mz(a)gmail.com)
*/
struct FolderViewColumns
@@ -37,7 +38,7 @@ class CZipFolder :
public IZip
{
CStringW m_ZipFile;
- CStringA m_ZipDir;
+ CStringW m_ZipDir;
CComHeapPtr<ITEMIDLIST> m_CurDir;
unzFile m_UnzipFile;
@@ -99,7 +100,7 @@ public:
return E_NOTIMPL;
}
// Adapted from CFileDefExt::GetFileTimeString
- BOOL _GetFileTimeString(LPFILETIME lpFileTime, LPWSTR pwszResult, UINT cchResult)
+ BOOL _GetFileTimeString(LPFILETIME lpFileTime, PWSTR pwszResult, UINT cchResult)
{
SYSTEMTIME st;
@@ -107,7 +108,7 @@ public:
return FALSE;
size_t cchRemaining = cchResult;
- LPWSTR pwszEnd = pwszResult;
+ PWSTR pwszEnd = pwszResult;
int cchWritten = GetDateFormatW(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &st,
NULL, pwszEnd, cchRemaining);
if (cchWritten)
--cchWritten; // GetDateFormatW returns count with terminating zero
@@ -158,9 +159,9 @@ public:
return GetDisplayNameOf(pidl, 0, &psd->str);
case 1: /* Type */
{
- SHFILEINFOA shfi;
+ SHFILEINFOW shfi;
DWORD dwAttributes = isDir ? FILE_ATTRIBUTE_DIRECTORY :
FILE_ATTRIBUTE_NORMAL;
- ULONG_PTR firet = SHGetFileInfoA(zipEntry->Name, dwAttributes, &shfi,
sizeof(shfi), SHGFI_USEFILEATTRIBUTES | SHGFI_TYPENAME);
+ ULONG_PTR firet = SHGetFileInfoW(zipEntry->Name, dwAttributes, &shfi,
sizeof(shfi), SHGFI_USEFILEATTRIBUTES | SHGFI_TYPENAME);
if (!firet)
return E_FAIL;
return SHSetStrRet(&psd->str, shfi.szTypeName);
@@ -226,7 +227,7 @@ public:
{
if (riid == IID_IShellFolder)
{
- CStringA newZipDir = m_ZipDir;
+ CStringW newZipDir = m_ZipDir;
PCUIDLIST_RELATIVE curpidl = pidl;
while (curpidl->mkid.cb)
{
@@ -236,7 +237,7 @@ public:
return E_FAIL;
}
newZipDir += zipEntry->Name;
- newZipDir += '/';
+ newZipDir += L'/';
curpidl = ILGetNext(curpidl);
}
@@ -262,7 +263,7 @@ public:
if (zipEntry1->ZipType != zipEntry2->ZipType)
result = zipEntry1->ZipType - zipEntry2->ZipType;
else
- result = stricmp(zipEntry1->Name, zipEntry2->Name);
+ result = _wcsicmp(zipEntry1->Name, zipEntry2->Name);
if (!result && zipEntry1->ZipType == ZIP_PIDL_DIRECTORY)
{
@@ -392,14 +393,8 @@ public:
const ZipPidlEntry* zipEntry = _ZipFromIL(*apidl);
if (zipEntry)
{
- CComHeapPtr<WCHAR> pathW;
-
- int len = MultiByteToWideChar(CP_ACP, 0, zipEntry->Name, -1, NULL,
0);
- pathW.Allocate(len);
- MultiByteToWideChar(CP_ACP, 0, zipEntry->Name, -1, pathW, len);
-
DWORD dwAttributes = (zipEntry->ZipType == ZIP_PIDL_DIRECTORY) ?
FILE_ATTRIBUTE_DIRECTORY : FILE_ATTRIBUTE_NORMAL;
- return SHCreateFileExtractIconW(pathW, dwAttributes, riid, ppvOut);
+ return SHCreateFileExtractIconW(zipEntry->Name, dwAttributes, riid,
ppvOut);
}
}
else if (riid == IID_IContextMenu && cidl >= 0)
@@ -444,7 +439,7 @@ public:
if (!zipEntry)
return E_FAIL;
- return SHSetStrRet(strRet, (LPCSTR)zipEntry->Name);
+ return SHSetStrRet(strRet, zipEntry->Name);
}
STDMETHODIMP SetNameOf(HWND hwndOwner, PCUITEMID_CHILD pidl, LPCOLESTR lpName, DWORD
dwFlags, PITEMID_CHILD *pPidlOut)
{
@@ -479,7 +474,7 @@ public:
case GCS_VERBA:
return StringCchCopyA(pszName, cchMax, EXTRACT_VERBA);
case GCS_VERBW:
- return StringCchCopyW((LPWSTR)pszName, cchMax, EXTRACT_VERBW);
+ return StringCchCopyW((PWSTR)pszName, cchMax, EXTRACT_VERBW);
case GCS_HELPTEXTA:
{
CStringA helpText(MAKEINTRESOURCEA(IDS_HELPTEXT));
@@ -488,7 +483,7 @@ public:
case GCS_HELPTEXTW:
{
CStringW helpText(MAKEINTRESOURCEA(IDS_HELPTEXT));
- return StringCchCopyW((LPWSTR)pszName, cchMax, helpText);
+ return StringCchCopyW((PWSTR)pszName, cchMax, helpText);
}
case GCS_VALIDATEA:
case GCS_VALIDATEW:
@@ -621,7 +616,7 @@ public:
}
- STDMETHODIMP Initialize(PCWSTR zipFile, PCSTR zipDir, PCUIDLIST_ABSOLUTE curDir,
PCUIDLIST_RELATIVE pidl)
+ STDMETHODIMP Initialize(PCWSTR zipFile, PCWSTR zipDir, PCUIDLIST_ABSOLUTE curDir,
PCUIDLIST_RELATIVE pidl)
{
m_ZipFile = zipFile;
m_ZipDir = zipDir;
diff --git a/dll/shellext/zipfldr/CZipPassword.cpp
b/dll/shellext/zipfldr/CZipPassword.cpp
index 0a1964a23d1..919c8c219fd 100644
--- a/dll/shellext/zipfldr/CZipPassword.cpp
+++ b/dll/shellext/zipfldr/CZipPassword.cpp
@@ -3,6 +3,7 @@
* LICENSE: GPL-2.0+ (
https://spdx.org/licenses/GPL-2.0+)
* PURPOSE: Ask the user for a password
* COPYRIGHT: Copyright 2019 Mark Jansen (mark.jansen(a)reactos.org)
+ * Copyright 2023 Katayama Hirofumi MZ (katayama.hirofumi.mz(a)gmail.com)
*/
#include "precomp.h"
@@ -10,10 +11,10 @@
class CZipPassword : public CDialogImpl<CZipPassword>
{
private:
- CStringA m_Filename;
+ CStringW m_Filename;
CStringA* m_pPassword;
public:
- CZipPassword(const char* filename, CStringA* Password)
+ CZipPassword(PCWSTR filename, CStringA* Password)
:m_pPassword(Password)
{
if (filename != NULL)
@@ -27,15 +28,15 @@ public:
/* No filename, so this is the question before starting to extract */
if (m_Filename.IsEmpty())
{
- CStringA message(MAKEINTRESOURCE(IDS_PASSWORD_ZIP_TEXT));
- ::SetDlgItemTextA(m_hWnd, IDC_MESSAGE, message);
+ CStringW message(MAKEINTRESOURCEW(IDS_PASSWORD_ZIP_TEXT));
+ ::SetDlgItemTextW(m_hWnd, IDC_MESSAGE, message);
::ShowWindow(GetDlgItem(IDSKIP), SW_HIDE);
}
else
{
- CStringA message;
+ CStringW message;
message.FormatMessage(IDS_PASSWORD_FILE_TEXT, m_Filename.GetString());
- ::SetDlgItemTextA(m_hWnd, IDC_MESSAGE, message);
+ ::SetDlgItemTextW(m_hWnd, IDC_MESSAGE, message);
}
return TRUE;
}
@@ -64,10 +65,10 @@ public:
END_MSG_MAP()
};
-eZipPasswordResponse _CZipAskPassword(HWND hDlg, const char* filename, CStringA&
Password)
+eZipPasswordResponse _CZipAskPassword(HWND hDlg, PCWSTR filename, CStringA&
Password)
{
if (filename)
- filename = PathFindFileNameA(filename);
+ filename = PathFindFileNameW(filename);
CZipPassword password(filename, &Password);
INT_PTR Result = password.DoModal(hDlg);
switch (Result)
diff --git a/dll/shellext/zipfldr/precomp.h b/dll/shellext/zipfldr/precomp.h
index b5845168073..7eaab9c3738 100644
--- a/dll/shellext/zipfldr/precomp.h
+++ b/dll/shellext/zipfldr/precomp.h
@@ -21,7 +21,7 @@
#include <reactos/debug.h>
#include <shellutils.h>
-
+void Utf8ToWide(const CStringA& strUtf8, CStringW& strWide);
#define EXTRACT_VERBA "extract"
#define EXTRACT_VERBW L"extract"
@@ -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"
@@ -52,7 +53,7 @@ extern zlib_filefunc64_def g_FFunc;
#include "zippidl.hpp"
#include "IZip.hpp"
-HRESULT _CEnumZipContents_CreateInstance(IZip* zip, DWORD flags, const char* prefix,
REFIID riid, LPVOID * ppvOut);
+HRESULT _CEnumZipContents_CreateInstance(IZip* zip, DWORD flags, PCWSTR prefix, REFIID
riid, LPVOID * ppvOut);
HRESULT _CExplorerCommandProvider_CreateInstance(IContextMenu* zipObject, REFIID riid,
LPVOID * ppvOut);
HRESULT _CFolderViewCB_CreateInstance(REFIID riid, LPVOID * ppvOut);
void _CZipExtract_runWizard(PCWSTR Filename);
@@ -64,7 +65,7 @@ enum eZipPasswordResponse
eAccept,
};
-eZipPasswordResponse _CZipAskPassword(HWND hDlg, const char* filename, CStringA&
Password);
+eZipPasswordResponse _CZipAskPassword(HWND hDlg, PCWSTR filename, CStringA&
Password);
enum eZipConfirmResponse
{
@@ -74,7 +75,7 @@ enum eZipConfirmResponse
eCancel
};
-eZipConfirmResponse _CZipAskReplace(HWND hDlg, const char* FullPath);
+eZipConfirmResponse _CZipAskReplace(HWND hDlg, PCWSTR FullPath);
enum eZipExtractError
{
diff --git a/dll/shellext/zipfldr/zipfldr.cpp b/dll/shellext/zipfldr/zipfldr.cpp
index 5dee2d1cb24..07fcc3a01b5 100644
--- a/dll/shellext/zipfldr/zipfldr.cpp
+++ b/dll/shellext/zipfldr/zipfldr.cpp
@@ -3,6 +3,7 @@
* LICENSE: GPL-2.0+ (
https://spdx.org/licenses/GPL-2.0+)
* PURPOSE: zipfldr entrypoint
* COPYRIGHT: Copyright 2017 Mark Jansen (mark.jansen(a)reactos.org)
+ * Copyright 2023 Katayama Hirofumi MZ (katayama.hirofumi.mz(a)gmail.com)
*/
#include "precomp.h"
@@ -47,8 +48,15 @@ static void init_zlib()
fill_win32_filefunc64W(&g_FFunc);
}
+void Utf8ToWide(const CStringA& strUtf8, CStringW& strWide)
+{
+ INT cchWide = MultiByteToWideChar(CP_UTF8, 0, strUtf8, -1, NULL, 0);
+ MultiByteToWideChar(CP_UTF8, 0, strUtf8, -1, strWide.GetBuffer(cchWide), cchWide);
+ strWide.ReleaseBuffer();
+}
+
static BOOL
-CreateEmptyFile(LPCWSTR pszFile)
+CreateEmptyFile(PCWSTR pszFile)
{
HANDLE hFile;
hFile = CreateFileW(pszFile, GENERIC_WRITE, FILE_SHARE_READ, NULL,
@@ -62,7 +70,7 @@ CreateEmptyFile(LPCWSTR pszFile)
}
static HRESULT
-CreateSendToZip(LPCWSTR pszSendTo)
+CreateSendToZip(PCWSTR pszSendTo)
{
WCHAR szTarget[MAX_PATH], szSendToFile[MAX_PATH];
@@ -80,7 +88,7 @@ CreateSendToZip(LPCWSTR pszSendTo)
}
static HRESULT
-GetDefaultUserSendTo(LPWSTR pszPath)
+GetDefaultUserSendTo(PWSTR pszPath)
{
return SHGetFolderPathW(NULL, CSIDL_SENDTO, INVALID_HANDLE_VALUE,
SHGFP_TYPE_DEFAULT, pszPath);
@@ -154,7 +162,7 @@ BOOL WINAPI
RouteTheCall(
IN HWND hWndOwner,
IN HINSTANCE hInstance,
- IN LPCSTR lpStringArg,
+ IN PCWSTR lpStringArg,
IN INT Show)
{
CStringW path = lpStringArg;
diff --git a/dll/shellext/zipfldr/zippidl.cpp b/dll/shellext/zipfldr/zippidl.cpp
index 09f26cd6f21..3f3b2cbc862 100644
--- a/dll/shellext/zipfldr/zippidl.cpp
+++ b/dll/shellext/zipfldr/zippidl.cpp
@@ -3,20 +3,24 @@
* LICENSE: GPL-2.0+ (
https://spdx.org/licenses/GPL-2.0+)
* PURPOSE: zip pidl handling
* COPYRIGHT: Copyright 2017-2019 Mark Jansen (mark.jansen(a)reactos.org)
+ * Copyright 2023 Katayama Hirofumi MZ (katayama.hirofumi.mz(a)gmail.com)
*/
#include "precomp.h"
-LPITEMIDLIST _ILCreate(ZipPidlType Type, LPCSTR lpString, unz_file_info64& info)
+LPITEMIDLIST _ILCreate(ZipPidlType Type, PCWSTR lpString, unz_file_info64& info)
{
- int cbData = sizeof(ZipPidlEntry) + strlen(lpString);
+ size_t cbData = sizeof(ZipPidlEntry) + wcslen(lpString) * sizeof(WCHAR);
+ if (cbData > MAXWORD)
+ return NULL;
+
ZipPidlEntry* pidl = (ZipPidlEntry*)SHAlloc(cbData + sizeof(WORD));
if (!pidl)
return NULL;
ZeroMemory(pidl, cbData + sizeof(WORD));
- pidl->cb = cbData;
+ pidl->cb = (WORD)cbData;
pidl->MagicType = 'z';
pidl->ZipType = Type;
@@ -28,13 +32,12 @@ LPITEMIDLIST _ILCreate(ZipPidlType Type, LPCSTR lpString,
unz_file_info64& info)
pidl->Password = info.flag & MINIZIP_PASSWORD_FLAG;
}
- strcpy(pidl->Name, lpString);
- *(WORD*)((char*)pidl + cbData) = 0;
+ wcscpy(pidl->Name, lpString);
+ *(WORD*)((char*)pidl + cbData) = 0; // The end of an ITEMIDLIST
return (LPITEMIDLIST)pidl;
}
-
const ZipPidlEntry* _ZipFromIL(LPCITEMIDLIST pidl)
{
const ZipPidlEntry* zipPidl = (const ZipPidlEntry*)pidl;
diff --git a/dll/shellext/zipfldr/zippidl.hpp b/dll/shellext/zipfldr/zippidl.hpp
index 8c81158525f..dae339a7aea 100644
--- a/dll/shellext/zipfldr/zippidl.hpp
+++ b/dll/shellext/zipfldr/zippidl.hpp
@@ -3,6 +3,7 @@
* LICENSE: GPL-2.0+ (
https://spdx.org/licenses/GPL-2.0+)
* PURPOSE: zip pidl handling
* COPYRIGHT: Copyright 2017 Mark Jansen (mark.jansen(a)reactos.org)
+ * Copyright 2023 Katayama Hirofumi MZ (katayama.hirofumi.mz(a)gmail.com)
*/
@@ -15,20 +16,19 @@ enum ZipPidlType
#include <pshpack1.h>
struct ZipPidlEntry
{
- WORD cb;
+ WORD cb; // This must be a WORD to keep compatibility to SHITEMID
BYTE MagicType;
+ BOOLEAN Password;
ZipPidlType ZipType;
ULONG64 CompressedSize;
ULONG64 UncompressedSize;
ULONG DosDate;
- BYTE Password;
- char Name[1];
+ WCHAR Name[1];
};
#include <poppack.h>
-LPITEMIDLIST _ILCreate(ZipPidlType Type, LPCSTR lpString, unz_file_info64& info);
+LPITEMIDLIST _ILCreate(ZipPidlType Type, PCWSTR lpString, unz_file_info64& info);
const ZipPidlEntry* _ZipFromIL(LPCITEMIDLIST pidl);
-