mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 09:34:43 +00:00
[ZIPFLDR][BOOTDATA] Support UTF-8 Zip packing (#5450)
New ReactOS can zip/unzip files and folders in UTF-8 filenames. You can also choose the codepage of filenames to zip/unzip via the ZipCodePage / UnZipCodePage registry values on the registry key HKEY_CURRENT_USER\Software\ReactOS. Windows 8 or later also support UTF-8 zipped folders. You can also use 3rd party software to zip/unzip in older Windows. - Use <atlconv.h> for string conversion. - Use zipOpenNewFileInZip4_64 instead of zipOpenNewFileInZip3_64, and then add MINIZIP_UTF8_FLAG flag. - Set the filenames in UTF-8 by using CP_UTF8 codepage. - Codepage is user selectable via registry settings. CORE-16668
This commit is contained in:
parent
059427e31d
commit
104ef25fcc
5 changed files with 42 additions and 26 deletions
|
@ -1978,6 +1978,10 @@ HKCU,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers\WINXP",
|
|||
HKCU,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers\WINXP","SPMajorVersion",0x00010001,0x00000001
|
||||
HKCU,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers\WINXP","SPMinorVersion",0x00010001,0x00000000
|
||||
|
||||
; Zip/UnZip codepages
|
||||
HKCU,"SOFTWARE\ReactOS","ZipCodePage",0x00000000,"65001" ; CP_UTF8
|
||||
HKCU,"SOFTWARE\ReactOS","UnZipCodePage",0x00000000,"0" ; CP_ACP
|
||||
|
||||
; DEBUG: Windows Messages SPY configuration
|
||||
HKCU,"SOFTWARE\ReactOS\Debug","SpyInclude",0x00020000,"INCLUDEALL"
|
||||
;HKCU,"SOFTWARE\ReactOS\Debug","SpyExclude",0x00020000,""
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
|
||||
* PURPOSE: Create a zip file
|
||||
* COPYRIGHT: Copyright 2019 Mark Jansen (mark.jansen@reactos.org)
|
||||
* Copyright 2019 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
|
||||
* Copyright 2019-2023 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
|
||||
*/
|
||||
|
||||
#include "precomp.h"
|
||||
|
@ -34,13 +34,6 @@ static CStringW DoGetZipName(PCWSTR filename)
|
|||
return ret;
|
||||
}
|
||||
|
||||
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(PCWSTR filename)
|
||||
{
|
||||
WCHAR szBaseName[MAX_PATH];
|
||||
|
@ -51,7 +44,7 @@ static CStringW DoGetBaseName(PCWSTR filename)
|
|||
}
|
||||
|
||||
static CStringA
|
||||
DoGetNameInZip(const CStringW& basename, const CStringW& filename)
|
||||
DoGetNameInZip(const CStringW& basename, const CStringW& filename, UINT nCodePage)
|
||||
{
|
||||
CStringW basenameI = basename, filenameI = filename;
|
||||
basenameI.MakeUpper();
|
||||
|
@ -65,7 +58,7 @@ DoGetNameInZip(const CStringW& basename, const CStringW& filename)
|
|||
|
||||
ret.Replace(L'\\', L'/');
|
||||
|
||||
return DoGetAnsiName(ret);
|
||||
return CStringA(CW2AEX<MAX_PATH>(ret, nCodePage));
|
||||
}
|
||||
|
||||
static BOOL
|
||||
|
@ -279,6 +272,7 @@ unsigned CZipCreatorImpl::JustDoIt()
|
|||
|
||||
int err = 0;
|
||||
CStringW strTarget, strBaseName = DoGetBaseName(m_items[0]);
|
||||
UINT nCodePage = GetZipCodePage(FALSE);
|
||||
for (INT iFile = 0; iFile < files.GetSize(); ++iFile)
|
||||
{
|
||||
const CStringW& strFile = files[iFile];
|
||||
|
@ -298,8 +292,8 @@ unsigned CZipCreatorImpl::JustDoIt()
|
|||
// TODO: crc = ...;
|
||||
}
|
||||
|
||||
CStringA strNameInZip = DoGetNameInZip(strBaseName, strFile);
|
||||
err = zipOpenNewFileInZip3_64(zf,
|
||||
CStringA strNameInZip = DoGetNameInZip(strBaseName, strFile, nCodePage);
|
||||
err = zipOpenNewFileInZip4_64(zf,
|
||||
strNameInZip,
|
||||
&zi,
|
||||
NULL,
|
||||
|
@ -315,6 +309,8 @@ unsigned CZipCreatorImpl::JustDoIt()
|
|||
Z_DEFAULT_STRATEGY,
|
||||
password,
|
||||
crc,
|
||||
MINIZIP_COMPATIBLE_VERSION,
|
||||
(nCodePage == CP_UTF8 ? MINIZIP_UTF8_FLAG : 0),
|
||||
zip64);
|
||||
if (err)
|
||||
{
|
||||
|
|
|
@ -12,9 +12,11 @@ private:
|
|||
CComPtr<IZip> m_Zip;
|
||||
bool m_First;
|
||||
CAtlList<CStringW> m_Returned;
|
||||
UINT m_nCodePage;
|
||||
public:
|
||||
CZipEnumerator()
|
||||
:m_First(true)
|
||||
: m_First(true)
|
||||
, m_nCodePage(GetZipCodePage(TRUE))
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -92,9 +94,9 @@ public:
|
|||
nameA.Replace('\\', '/');
|
||||
|
||||
if (info.flag & MINIZIP_UTF8_FLAG)
|
||||
Utf8ToWide(nameA, name);
|
||||
name = CA2WEX<MAX_PATH>(nameA, CP_UTF8);
|
||||
else
|
||||
name = CStringW(nameA);
|
||||
name = CA2WEX<MAX_PATH>(nameA, m_nCodePage);
|
||||
}
|
||||
return err == UNZ_OK;
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include <atlbase.h>
|
||||
#include <atlcom.h>
|
||||
#include <atlcoll.h>
|
||||
#include <atlconv.h>
|
||||
#include <atlstr.h>
|
||||
#include <ui/rosdlgs.h>
|
||||
#include <shlwapi.h>
|
||||
|
@ -21,8 +22,6 @@
|
|||
#include <reactos/debug.h>
|
||||
#include <shellutils.h>
|
||||
|
||||
void Utf8ToWide(const CStringA& strUtf8, CStringW& strWide);
|
||||
|
||||
#define EXTRACT_VERBA "extract"
|
||||
#define EXTRACT_VERBW L"extract"
|
||||
|
||||
|
@ -36,10 +35,10 @@ EXTERN_C const GUID CLSID_ZipFolderExtractAllCommand;
|
|||
|
||||
extern LONG g_ModuleRefCnt;
|
||||
|
||||
|
||||
UINT GetZipCodePage(BOOL bUnZip);
|
||||
WCHAR* guid2string(REFCLSID iid);
|
||||
|
||||
|
||||
#define MINIZIP_COMPATIBLE_VERSION 36
|
||||
#define MINIZIP_PASSWORD_FLAG 1
|
||||
#define MINIZIP_UTF8_FLAG (1 << 11)
|
||||
|
||||
|
|
|
@ -48,13 +48,6 @@ 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(PCWSTR pszFile)
|
||||
{
|
||||
|
@ -94,6 +87,28 @@ GetDefaultUserSendTo(PWSTR pszPath)
|
|||
SHGFP_TYPE_DEFAULT, pszPath);
|
||||
}
|
||||
|
||||
UINT GetZipCodePage(BOOL bUnZip)
|
||||
{
|
||||
WCHAR szValue[16];
|
||||
DWORD dwType, cbValue = sizeof(szValue);
|
||||
UINT nDefaultCodePage = (bUnZip ? CP_ACP : CP_UTF8);
|
||||
|
||||
LONG error = SHGetValueW(HKEY_CURRENT_USER, L"Software\\ReactOS",
|
||||
(bUnZip ? L"UnZipCodePage" : L"ZipCodePage"),
|
||||
&dwType, szValue, &cbValue);
|
||||
if (error != ERROR_SUCCESS)
|
||||
return nDefaultCodePage;
|
||||
|
||||
if (cbValue == sizeof(DWORD) && (dwType == REG_DWORD || dwType == REG_BINARY))
|
||||
return *(DWORD*)szValue;
|
||||
|
||||
if (dwType != REG_SZ && dwType != REG_EXPAND_SZ)
|
||||
return nDefaultCodePage;
|
||||
|
||||
szValue[_countof(szValue) - 1] = UNICODE_NULL;
|
||||
return (UINT)wcstol(szValue, NULL, 0);
|
||||
}
|
||||
|
||||
EXTERN_C
|
||||
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue