mirror of
https://github.com/reactos/reactos.git
synced 2024-08-24 20:28:57 +00:00
![Katayama Hirofumi MZ](/assets/img/avatar_default.png)
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
105 lines
2.7 KiB
C++
105 lines
2.7 KiB
C++
/*
|
|
* PROJECT: ReactOS Zip Shell Extension
|
|
* 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
|
|
{
|
|
private:
|
|
CComPtr<IZip> m_Zip;
|
|
bool m_First;
|
|
CAtlList<CStringW> m_Returned;
|
|
UINT m_nCodePage;
|
|
public:
|
|
CZipEnumerator()
|
|
: m_First(true)
|
|
, m_nCodePage(GetZipCodePage(TRUE))
|
|
{
|
|
}
|
|
|
|
bool initialize(IZip* zip)
|
|
{
|
|
m_Zip = zip;
|
|
return reset();
|
|
}
|
|
|
|
bool reset()
|
|
{
|
|
unzFile uf = m_Zip->getZip();
|
|
m_First = true;
|
|
if (unzGoToFirstFile(uf) != UNZ_OK)
|
|
return false;
|
|
m_Returned.RemoveAll();
|
|
return true;
|
|
}
|
|
|
|
bool next_unique(PCWSTR prefix, CStringW& name, bool& folder, unz_file_info64& info)
|
|
{
|
|
size_t len = wcslen(prefix);
|
|
CStringW tmp;
|
|
while (next(tmp, info))
|
|
{
|
|
if (!_wcsnicmp(tmp, prefix, len))
|
|
{
|
|
int pos = tmp.Find(L'/', len);
|
|
if (pos < 0)
|
|
{
|
|
name = tmp.Mid(len);
|
|
folder = false;
|
|
}
|
|
else
|
|
{
|
|
name = tmp.Mid(len, pos - len);
|
|
folder = true;
|
|
}
|
|
tmp = name;
|
|
tmp.MakeLower();
|
|
|
|
POSITION it = m_Returned.Find(tmp);
|
|
if (!name.IsEmpty() && !it)
|
|
{
|
|
m_Returned.AddTail(tmp);
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool next(CStringW& name, unz_file_info64& info)
|
|
{
|
|
int err;
|
|
|
|
unzFile uf = m_Zip->getZip();
|
|
if (!m_First)
|
|
{
|
|
err = unzGoToNextFile(uf);
|
|
if (err == UNZ_END_OF_LIST_OF_FILE)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
m_First = false;
|
|
|
|
err = unzGetCurrentFileInfo64(uf, &info, NULL, 0, NULL, 0, NULL, 0);
|
|
if (err == UNZ_OK)
|
|
{
|
|
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)
|
|
name = CA2WEX<MAX_PATH>(nameA, CP_UTF8);
|
|
else
|
|
name = CA2WEX<MAX_PATH>(nameA, m_nCodePage);
|
|
}
|
|
return err == UNZ_OK;
|
|
}
|
|
};
|
|
|