https://git.reactos.org/?p=reactos.git;a=commitdiff;h=bf2cec186cc7655e062ec0e53ccfac860bcae70d

commit bf2cec186cc7655e062ec0e53ccfac860bcae70d
Author:     Katayama Hirofumi MZ <[email protected]>
AuthorDate: Mon Jul 17 20:12:45 2023 +0900
Commit:     GitHub <[email protected]>
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 ([email protected])
+ *              Copyright 2023 Katayama Hirofumi MZ 
([email protected])
  */
 
 #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 ([email protected])
+ *              Copyright 2023 Katayama Hirofumi MZ 
([email protected])
  */
 
 #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 ([email protected])
+ *              Copyright 2023 Katayama Hirofumi MZ 
([email protected])
  */
 
 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 ([email protected])
+ *              Copyright 2023 Katayama Hirofumi MZ 
([email protected])
  */
 
 #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 ([email protected])
+ *              Copyright 2023 Katayama Hirofumi MZ 
([email protected])
  */
 
 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 ([email protected])
+ *              Copyright 2023 Katayama Hirofumi MZ 
([email protected])
  */
 
 #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 ([email protected])
+ *              Copyright 2023 Katayama Hirofumi MZ 
([email protected])
  */
 
 #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 ([email protected])
+ *              Copyright 2023 Katayama Hirofumi MZ 
([email protected])
  */
 
 #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 ([email protected])
+ *              Copyright 2023 Katayama Hirofumi MZ 
([email protected])
  */
 
 
@@ -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);
-

Reply via email to