mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 09:34:43 +00:00
[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:
parent
bfadb22da1
commit
bf2cec186c
13 changed files with 134 additions and 112 deletions
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ public:
|
|||
return new CZipCreator();
|
||||
}
|
||||
|
||||
virtual void DoAddItem(LPCWSTR pszFile);
|
||||
virtual void DoAddItem(PCWSTR pszFile);
|
||||
static BOOL runThread(CZipCreator* pCreator);
|
||||
|
||||
protected:
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in a new issue