ReactOS 0.4.16-dev-2204-g370eb8c
CZipEnumerator.cpp
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS Zip Shell Extension
3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4 * PURPOSE: CZipEnumerator
5 * COPYRIGHT: Copyright 2017 Mark Jansen (mark.jansen@reactos.org)
6 * Copyright 2023-2026 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
7 */
8
9#include "precomp.h"
10
11#define EF_UNIPATH 0x7075 // Unicode Path extra field ID
12#define EF_HEADER_SIZE 4 // Extra field header size (ID + size)
13#define EF_UNIPATH_VERSION 1 // Unicode Path extra field version
14
16{
17}
18
20{
21 ATLASSERT(zip);
22 m_Zip = zip;
23 return Reset();
24}
25
27{
28 unzFile uf = m_Zip->getZip();
29 m_First = TRUE;
30 if (unzGoToFirstFile(uf) != UNZ_OK)
31 return FALSE;
33 return TRUE;
34}
35
37{
39 DWORD crc = crc32(0, Z_NULL, 0);
40 crc = crc32(crc, (const Bytef*)filename, strlen(filename));
41 return crc;
42}
43
46 PCSTR originalName,
47 const BYTE* extraField,
48 DWORD extraFieldLen)
49{
50 ATLASSERT(originalName);
51 ATLASSERT(extraField);
52
53 if (extraFieldLen < EF_HEADER_SIZE)
54 return ""; // Failure
55
56 const BYTE* pbField = extraField;
57 const BYTE* pbEnd = extraField + extraFieldLen;
58
59 while (pbField + EF_HEADER_SIZE <= pbEnd)
60 {
61 // Beware of alignment exception
62 WORD fieldId, fieldSize;
63 CopyMemory(&fieldId, pbField, sizeof(fieldId));
64 CopyMemory(&fieldSize, pbField + 2, sizeof(fieldSize));
65
66 if (fieldId != EF_UNIPATH)
67 {
68 pbField += EF_HEADER_SIZE + fieldSize; // Next field
69 continue;
70 }
71
72 if (fieldSize < 5 || pbField + EF_HEADER_SIZE + fieldSize > pbEnd)
73 return "";
74
75 const BYTE* fieldData = pbField + EF_HEADER_SIZE;
76 BYTE version = fieldData[0];
78 return ""; // Failure
79
80 DWORD storedCRC, calculatedCRC = CalculateCRC32(originalName);
81 CopyMemory(&storedCRC, fieldData + 1, sizeof(storedCRC));
82 if (storedCRC != calculatedCRC)
83 return ""; // Failure
84
85 DWORD utf8NameLen = fieldSize - 5;
86 if (utf8NameLen > 0)
87 return CStringA((LPCSTR)(fieldData + 5), utf8NameLen); // Success
88
89 pbField += EF_HEADER_SIZE + fieldSize; // Next field
90 }
91
92 return ""; // Failure
93}
94
96{
97 INT err;
98 unzFile uf = m_Zip->getZip();
99
100 if (!m_First)
101 {
102 err = unzGoToNextFile(uf);
104 return FALSE;
105 }
106 m_First = FALSE;
107
108 err = unzGetCurrentFileInfo64(uf, &info, NULL, 0, NULL, 0, NULL, 0);
109 if (err != UNZ_OK)
110 return FALSE;
111
113 extra.SetCount(info.size_file_extra);
114
115 CStringA nameA;
116 PSTR buf = nameA.GetBuffer(info.size_filename);
118 (info.size_file_extra > 0) ? extra.GetData() : NULL, info.size_file_extra,
119 NULL, 0);
120 nameA.ReleaseBuffer(info.size_filename);
121
122 if (err != UNZ_OK)
123 return FALSE;
124
125 CStringA utf8Name;
126 if (info.size_file_extra > 0)
127 utf8Name = GetUtf8Name(nameA, extra.GetData(), info.size_file_extra);
128
129 if (utf8Name.GetLength() > 0)
130 name = CA2WEX<MAX_PATH>(utf8Name, CP_UTF8);
131 else if (info.flag & MINIZIP_UTF8_FLAG)
132 name = CA2WEX<MAX_PATH>(nameA, CP_UTF8);
133 else
135
136 name.Replace('\\', '/');
137
138 return TRUE;
139}
140
142{
144 CStringW tmp;
145 SIZE_T cchPrefix = wcslen(prefix);
146 while (Next(tmp, info))
147 {
148 if (StrCmpNIW(tmp, prefix, cchPrefix) != 0)
149 continue;
150
151 INT ichSlash = tmp.Find(L'/', cchPrefix);
152 folder = (ichSlash >= 0);
153 tmp = name = (folder ? tmp.Mid(cchPrefix, ichSlash - cchPrefix) : tmp.Mid(cchPrefix));
154 tmp.MakeLower();
155
156 POSITION it = m_Returned.Find(tmp);
157 if (!name.IsEmpty() && !it)
158 {
159 m_Returned.AddTail(tmp);
160 return TRUE;
161 }
162 }
163 return FALSE;
164}
#define ATLASSERT(x)
Definition: CComVariant.cpp:10
#define EF_HEADER_SIZE
#define EF_UNIPATH_VERSION
#define EF_UNIPATH
POSITION AddTail(INARGTYPE element)
Definition: atlcoll.h:629
void RemoveAll()
Definition: atlcoll.h:748
POSITION Find(INARGTYPE element, _In_opt_ POSITION posStartAfter=NULL) const
Definition: atlcoll.h:794
int GetAllocLength() const noexcept
Definition: atlsimpstr.h:357
void ReleaseBuffer(_In_ int nNewLength=-1)
Definition: atlsimpstr.h:387
int GetLength() const noexcept
Definition: atlsimpstr.h:362
int Find(_In_ PCXSTR pszSub, _In_opt_ int iStart=0) const noexcept
Definition: cstringt.h:696
CStringT Mid(int iFirst, int nCount) const
Definition: cstringt.h:748
CStringT & MakeLower()
Definition: cstringt.h:674
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define MINIZIP_UTF8_FLAG
Definition: precomp.h:43
INT WINAPI StrCmpNIW(LPCWSTR lpszStr, LPCWSTR lpszComp, INT iLen)
Definition: string.c:307
#define crc32(crc, buf, len)
Definition: inflate.c:1081
#define Z_NULL
Definition: zlib.h:149
Byte FAR Bytef
Definition: zlib.h:41
static const WCHAR version[]
Definition: asmname.c:66
_ACRTIMP size_t __cdecl wcslen(const wchar_t *)
Definition: wcs.c:2983
_ACRTIMP size_t __cdecl strlen(const char *)
Definition: string.c:1592
#define L(x)
Definition: resources.c:13
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
@ extra
Definition: id3.c:95
const char * filename
Definition: ioapi.h:137
#define CopyMemory
Definition: minwinbase.h:29
CAtlStringA CStringA
Definition: atlstr.h:131
#define err(...)
#define CP_UTF8
Definition: nls.h:20
BOOL NextUnique(PCWSTR prefix, CStringW &name, bool &folder, unz_file_info64 &info)
static CStringA GetUtf8Name(PCSTR originalName, const BYTE *extraField, DWORD extraFieldLen)
BOOL Next(CStringW &name, unz_file_info64 &info)
CComPtr< IZip > m_Zip
static DWORD CalculateCRC32(PCSTR filename)
BOOL Initialize(IZip *zip)
CAtlList< CStringW > m_Returned
Definition: IZip.hpp:9
Definition: fci.c:116
Definition: name.c:39
Character const *const prefix
Definition: tempnam.cpp:195
char * PSTR
Definition: typedefs.h:51
const uint16_t * PCWSTR
Definition: typedefs.h:57
ULONG_PTR SIZE_T
Definition: typedefs.h:80
int32_t INT
Definition: typedefs.h:58
const char * PCSTR
Definition: typedefs.h:52
int ZEXPORT unzGetCurrentFileInfo64(unzFile file, unz_file_info64 *pfile_info, char *szFileName, uLong fileNameBufferSize, void *extraField, uLong extraFieldBufferSize, char *szComment, uLong commentBufferSize)
Definition: unzip.c:1129
int ZEXPORT unzGoToFirstFile(unzFile file)
Definition: unzip.c:1183
int ZEXPORT unzGoToNextFile(unzFile file)
Definition: unzip.c:1204
#define UNZ_END_OF_LIST_OF_FILE
Definition: unzip.h:75
voidp unzFile
Definition: unzip.h:70
#define UNZ_OK
Definition: unzip.h:74
const char * LPCSTR
Definition: xmlstorage.h:183
unsigned char BYTE
Definition: xxhash.c:193