ReactOS 0.4.16-dev-2274-gc61d98f
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_HEADER_SIZE 4 // Extra field header size (ID + size)
12#define EF_UNIPATH_VERSION 1 // Unicode Path extra field version
13
15{
16}
17
19{
20 ATLASSERT(zip);
21 m_Zip = zip;
22 return Reset();
23}
24
26{
27 unzFile uf = m_Zip->getZip();
28 m_First = TRUE;
29 if (unzGoToFirstFile(uf) != UNZ_OK)
30 return FALSE;
32 return TRUE;
33}
34
36{
38 DWORD crc = crc32(0, Z_NULL, 0);
39 crc = crc32(crc, (const Bytef*)filename, strlen(filename));
40 return crc;
41}
42
45 PCSTR originalName,
46 const BYTE* extraField,
47 DWORD extraFieldLen)
48{
49 ATLASSERT(originalName);
50 ATLASSERT(extraField);
51
52 if (extraFieldLen < EF_HEADER_SIZE)
53 return ""; // Failure
54
55 const BYTE* pbField = extraField;
56 const BYTE* pbEnd = extraField + extraFieldLen;
57
58 while (pbField + EF_HEADER_SIZE <= pbEnd)
59 {
60 // Beware of alignment exception
61 WORD fieldId, fieldSize;
62 CopyMemory(&fieldId, pbField, sizeof(fieldId));
63 CopyMemory(&fieldSize, pbField + 2, sizeof(fieldSize));
64
65 if (fieldId != EF_UNIPATH)
66 {
67 pbField += EF_HEADER_SIZE + fieldSize; // Next field
68 continue;
69 }
70
71 if (fieldSize < 5 || pbField + EF_HEADER_SIZE + fieldSize > pbEnd)
72 return "";
73
74 const BYTE* fieldData = pbField + EF_HEADER_SIZE;
75 BYTE version = fieldData[0];
77 return ""; // Failure
78
79 DWORD storedCRC, calculatedCRC = CalculateCRC32(originalName);
80 CopyMemory(&storedCRC, fieldData + 1, sizeof(storedCRC));
81 if (storedCRC != calculatedCRC)
82 return ""; // Failure
83
84 DWORD utf8NameLen = fieldSize - 5;
85 if (utf8NameLen > 0)
86 return CStringA((LPCSTR)(fieldData + 5), utf8NameLen); // Success
87
88 pbField += EF_HEADER_SIZE + fieldSize; // Next field
89 }
90
91 return ""; // Failure
92}
93
95{
96 INT err;
97 unzFile uf = m_Zip->getZip();
98
99 if (!m_First)
100 {
101 err = unzGoToNextFile(uf);
103 return FALSE;
104 }
105 m_First = FALSE;
106
107 err = unzGetCurrentFileInfo64(uf, &info, NULL, 0, NULL, 0, NULL, 0);
108 if (err != UNZ_OK)
109 return FALSE;
110
112 extra.SetCount(info.size_file_extra);
113
114 CStringA nameA;
115 PSTR buf = nameA.GetBuffer(info.size_filename);
117 (info.size_file_extra > 0) ? extra.GetData() : NULL, info.size_file_extra,
118 NULL, 0);
119 nameA.ReleaseBuffer(info.size_filename);
120
121 if (err != UNZ_OK)
122 return FALSE;
123
124 CStringA utf8Name;
125 if (info.size_file_extra > 0)
126 utf8Name = GetUtf8Name(nameA, extra.GetData(), info.size_file_extra);
127
128 if (utf8Name.GetLength() > 0)
129 name = CA2WEX<MAX_PATH>(utf8Name, CP_UTF8);
130 else if (info.flag & MINIZIP_UTF8_FLAG)
131 name = CA2WEX<MAX_PATH>(nameA, CP_UTF8);
132 else
134
135 name.Replace('\\', '/');
136
137 return TRUE;
138}
139
141{
143 CStringW tmp;
144 SIZE_T cchPrefix = wcslen(prefix);
145 while (Next(tmp, info))
146 {
147 if (StrCmpNIW(tmp, prefix, cchPrefix) != 0)
148 continue;
149
150 INT ichSlash = tmp.Find(L'/', cchPrefix);
151 folder = (ichSlash >= 0);
152 tmp = name = (folder ? tmp.Mid(cchPrefix, ichSlash - cchPrefix) : tmp.Mid(cchPrefix));
153 tmp.MakeLower();
154
155 POSITION it = m_Returned.Find(tmp);
156 if (!name.IsEmpty() && !it)
157 {
158 m_Returned.AddTail(tmp);
159 return TRUE;
160 }
161 }
162 return FALSE;
163}
#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