[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
This commit is contained in:
Katayama Hirofumi MZ 2023-07-17 20:12:45 +09:00 committed by GitHub
parent bfadb22da1
commit bf2cec186c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 134 additions and 112 deletions

View file

@ -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@reactos.org)
* Copyright 2023 Katayama Hirofumi MZ (katayama.hirofumi.mz@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)

View file

@ -3,6 +3,7 @@
* LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
* PURPOSE: CEnumZipContents
* COPYRIGHT: Copyright 2017 Mark Jansen (mark.jansen@reactos.org)
* Copyright 2023 Katayama Hirofumi MZ (katayama.hirofumi.mz@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);
}

View file

@ -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);

View file

@ -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);
}

View file

@ -22,7 +22,7 @@ public:
return new CZipCreator();
}
virtual void DoAddItem(LPCWSTR pszFile);
virtual void DoAddItem(PCWSTR pszFile);
static BOOL runThread(CZipCreator* pCreator);
protected:

View file

@ -3,6 +3,7 @@
* LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
* PURPOSE: CZipEnumerator
* COPYRIGHT: Copyright 2017 Mark Jansen (mark.jansen@reactos.org)
* Copyright 2023 Katayama Hirofumi MZ (katayama.hirofumi.mz@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;
}

View file

@ -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@reactos.org)
* Copyright 2023 Katayama Hirofumi MZ (katayama.hirofumi.mz@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);
}
};

View file

@ -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@reactos.org)
* Copyright 2023 Katayama Hirofumi MZ (katayama.hirofumi.mz@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;

View file

@ -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@reactos.org)
* Copyright 2023 Katayama Hirofumi MZ (katayama.hirofumi.mz@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)

View file

@ -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
{

View file

@ -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@reactos.org)
* Copyright 2023 Katayama Hirofumi MZ (katayama.hirofumi.mz@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;

View file

@ -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@reactos.org)
* Copyright 2023 Katayama Hirofumi MZ (katayama.hirofumi.mz@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;

View file

@ -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@reactos.org)
* Copyright 2023 Katayama Hirofumi MZ (katayama.hirofumi.mz@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);