ReactOS 0.4.15-dev-7906-g1b85a5f
CZipCreator.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: Create a zip file
5 * COPYRIGHT: Copyright 2019 Mark Jansen (mark.jansen@reactos.org)
6 * Copyright 2019-2023 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
7 */
8
9#include "precomp.h"
10#include "atlsimpcoll.h"
11#include "minizip/zip.h"
12#include "minizip/iowin32.h"
13#include <process.h>
14
16{
20
22 ret += L".zip";
23
24 UINT i = 2;
25 while (PathFileExistsW(ret))
26 {
28 str.Format(L" (%u).zip", i++);
29
30 ret = szPath;
31 ret += str;
32 }
33
34 return ret;
35}
36
38{
39 WCHAR szBaseName[MAX_PATH];
40 StringCbCopyW(szBaseName, sizeof(szBaseName), filename);
41 PathRemoveFileSpecW(szBaseName);
42 PathAddBackslashW(szBaseName);
43 return szBaseName;
44}
45
46static CStringA
48{
49 CStringW basenameI = basename, filenameI = filename;
50 basenameI.MakeUpper();
51 filenameI.MakeUpper();
52
54 if (filenameI.Find(basenameI) == 0)
55 ret = filename.Mid(basename.GetLength());
56 else
57 ret = filename;
58
59 ret.Replace(L'\\', L'/');
60
61 return CStringA(CW2AEX<MAX_PATH>(ret, nCodePage));
62}
63
64static BOOL
66 zip_fileinfo *pzi)
67{
68 contents.RemoveAll();
69
74 {
75 DPRINT1("%S: cannot open\n", filename);
76 return FALSE;
77 }
78
79 FILETIME ft, ftLocal;
80 ZeroMemory(pzi, sizeof(*pzi));
81 if (GetFileTime(hFile, NULL, NULL, &ft))
82 {
83 SYSTEMTIME st;
84 FileTimeToLocalFileTime(&ft, &ftLocal);
85 FileTimeToSystemTime(&ftLocal, &st);
86 pzi->tmz_date.tm_sec = st.wSecond;
87 pzi->tmz_date.tm_min = st.wMinute;
88 pzi->tmz_date.tm_hour = st.wHour;
89 pzi->tmz_date.tm_mday = st.wDay;
90 pzi->tmz_date.tm_mon = st.wMonth - 1;
91 pzi->tmz_date.tm_year = st.wYear;
92 }
93
94 const DWORD cbBuff = 0x7FFF;
95 LPBYTE pbBuff = reinterpret_cast<LPBYTE>(CoTaskMemAlloc(cbBuff));
96 if (!pbBuff)
97 {
98 DPRINT1("Out of memory\n");
100 return FALSE;
101 }
102
103 for (;;)
104 {
105 DWORD cbRead;
106 if (!ReadFile(hFile, pbBuff, cbBuff, &cbRead, NULL) || !cbRead)
107 break;
108
109 for (DWORD i = 0; i < cbRead; ++i)
110 contents.Add(pbBuff[i]);
111 }
112
113 CoTaskMemFree(pbBuff);
115
116 return TRUE;
117}
118
119static void
121{
123 {
124 files.Add(item);
125 return;
126 }
127
129 StringCbCopyW(szPath, sizeof(szPath), item);
130 PathAppendW(szPath, L"*");
131
133 HANDLE hFind = FindFirstFileW(szPath, &find);
134 if (hFind == INVALID_HANDLE_VALUE)
135 return;
136
137 do
138 {
139 if (wcscmp(find.cFileName, L".") == 0 ||
140 wcscmp(find.cFileName, L"..") == 0)
141 {
142 continue;
143 }
144
145 StringCbCopyW(szPath, sizeof(szPath), item);
146 PathAppendW(szPath, find.cFileName);
147
148 if (find.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
150 else
151 files.Add(szPath);
152 } while (FindNextFileW(hFind, &find));
153
154 FindClose(hFind);
155}
156
158{
160
161 unsigned JustDoIt();
162};
163
165{
167}
168
170{
172 delete m_pimpl;
173}
174
175static unsigned __stdcall
177{
178 CZipCreator *pCreator = reinterpret_cast<CZipCreator *>(arg);
179 return pCreator->m_pimpl->JustDoIt();
180}
181
183{
184 unsigned tid = 0;
185 HANDLE hThread = reinterpret_cast<HANDLE>(
186 _beginthreadex(NULL, 0, create_zip_function, pCreator, 0, &tid));
187
188 if (hThread)
189 {
191 return TRUE;
192 }
193
194 DPRINT1("hThread == NULL\n");
195
198 MessageBoxW(NULL, strText, strTitle, MB_ICONERROR);
199
200 delete pCreator;
201 return FALSE;
202}
203
205{
206 // canonicalize path
209
210 m_pimpl->m_items.Add(szPath);
211}
212
214{
220
222{
223 // TODO: Show progress.
224
225 if (m_items.GetSize() <= 0)
226 {
227 DPRINT1("GetSize() <= 0\n");
228 return CZCERR_ZEROITEMS;
229 }
230
232 for (INT iItem = 0; iItem < m_items.GetSize(); ++iItem)
233 {
234 DoAddFilesFromItem(files, m_items[iItem]);
235 }
236
237 if (files.GetSize() <= 0)
238 {
239 DPRINT1("files.GetSize() <= 0\n");
240
242 CStringW strText;
243 strText.Format(IDS_NOFILES, static_cast<PCWSTR>(m_items[0]));
244 MessageBoxW(NULL, strText, strTitle, MB_ICONERROR);
245
246 return CZCERR_NOFILES;
247 }
248
251
252 CStringW strZipName = DoGetZipName(m_items[0]);
253 zipFile zf = zipOpen2_64(strZipName, APPEND_STATUS_CREATE, NULL, &ffunc);
254 if (zf == 0)
255 {
256 DPRINT1("zf == 0\n");
257
258 int err = CZCERR_CREATE;
259
261 CStringW strText;
262 strText.Format(IDS_CANTCREATEZIP, static_cast<PCWSTR>(strZipName), err);
263 MessageBoxW(NULL, strText, strTitle, MB_ICONERROR);
264
265 return err;
266 }
267
268 // TODO: password
269 const char *password = NULL;
270 int zip64 = 1; // always zip64
271 zip_fileinfo zi;
272
273 int err = 0;
274 CStringW strTarget, strBaseName = DoGetBaseName(m_items[0]);
275 UINT nCodePage = GetZipCodePage(FALSE);
276 for (INT iFile = 0; iFile < files.GetSize(); ++iFile)
277 {
278 const CStringW& strFile = files[iFile];
279
281 if (!DoReadAllOfFile(strFile, contents, &zi))
282 {
283 DPRINT1("DoReadAllOfFile failed\n");
285 strTarget = strFile;
286 break;
287 }
288
289 unsigned long crc = 0;
290 if (password)
291 {
292 // TODO: crc = ...;
293 }
294
295 CStringA strNameInZip = DoGetNameInZip(strBaseName, strFile, nCodePage);
297 strNameInZip,
298 &zi,
299 NULL,
300 0,
301 NULL,
302 0,
303 NULL,
306 0,
307 -MAX_WBITS,
310 password,
311 crc,
313 (nCodePage == CP_UTF8 ? MINIZIP_UTF8_FLAG : 0),
314 zip64);
315 if (err)
316 {
317 DPRINT1("zipOpenNewFileInZip3_64\n");
318 break;
319 }
320
321 err = zipWriteInFileInZip(zf, contents.GetData(), contents.GetSize());
322 if (err)
323 {
324 DPRINT1("zipWriteInFileInZip\n");
325 break;
326 }
327
329 if (err)
330 {
331 DPRINT1("zipCloseFileInZip\n");
332 break;
333 }
334 }
335
336 zipClose(zf, NULL);
337
338 if (err)
339 {
340 DeleteFileW(strZipName);
341
343
344 CStringW strText;
345 if (err < 0)
346 strText.Format(IDS_CANTCREATEZIP, static_cast<PCWSTR>(strZipName), err);
347 else
348 strText.Format(IDS_CANTREADFILE, static_cast<PCWSTR>(strTarget));
349
350 MessageBoxW(NULL, strText, strTitle, MB_ICONERROR);
351 }
352 else
353 {
354 WCHAR szFullPath[MAX_PATH];
355 GetFullPathNameW(strZipName, _countof(szFullPath), szFullPath, NULL);
357 }
358
359 return err;
360}
LONG g_ModuleRefCnt
Definition: ACPPage.cpp:13
static CStringW DoGetZipName(PCWSTR filename)
Definition: CZipCreator.cpp:15
CZC_ERROR
@ CZCERR_NOFILES
@ CZCERR_ZEROITEMS
@ CZCERR_READ
@ CZCERR_CREATE
static unsigned __stdcall create_zip_function(void *arg)
static CStringA DoGetNameInZip(const CStringW &basename, const CStringW &filename, UINT nCodePage)
Definition: CZipCreator.cpp:47
static void DoAddFilesFromItem(CSimpleArray< CStringW > &files, PCWSTR item)
static CStringW DoGetBaseName(PCWSTR filename)
Definition: CZipCreator.cpp:37
static BOOL DoReadAllOfFile(PCWSTR filename, CSimpleArray< BYTE > &contents, zip_fileinfo *pzi)
Definition: CZipCreator.cpp:65
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
#define DPRINT1
Definition: precomp.h:8
EXTERN_C void WINAPI SHChangeNotify(LONG wEventId, UINT uFlags, LPCVOID dwItem1, LPCVOID dwItem2)
int GetSize() const
Definition: atlsimpcoll.h:104
void __cdecl Format(UINT nFormatID,...)
Definition: cstringt.h:818
CStringT & MakeUpper()
Definition: cstringt.h:685
static BOOL runThread(CZipCreator *pCreator)
struct CZipCreatorImpl * m_pimpl
Definition: CZipCreator.hpp:16
virtual ~CZipCreator()
virtual void DoAddItem(PCWSTR pszFile)
static TAGID TAGID find
Definition: db.cpp:155
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define MINIZIP_COMPATIBLE_VERSION
Definition: precomp.h:41
UINT GetZipCodePage(BOOL bUnZip)
Definition: zipfldr.cpp:90
#define MINIZIP_UTF8_FLAG
Definition: precomp.h:43
#define IDS_CANTCREATEZIP
Definition: resource.h:50
#define IDS_ERRORTITLE
Definition: resource.h:47
#define IDS_CANTSTARTTHREAD
Definition: resource.h:48
#define IDS_CANTREADFILE
Definition: resource.h:51
#define IDS_NOFILES
Definition: resource.h:49
#define CloseHandle
Definition: compat.h:739
#define OPEN_EXISTING
Definition: compat.h:775
#define ReadFile(a, b, c, d, e)
Definition: compat.h:742
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define GENERIC_READ
Definition: compat.h:135
#define MAX_PATH
Definition: compat.h:34
#define CreateFileW
Definition: compat.h:741
#define FILE_SHARE_READ
Definition: compat.h:136
#define Z_DEFLATED
Definition: zlib.h:146
#define Z_DEFAULT_STRATEGY
Definition: zlib.h:137
#define MAX_WBITS
Definition: zlib.h:151
#define Z_DEFAULT_COMPRESSION
Definition: zlib.h:130
BOOL WINAPI DeleteFileW(IN LPCWSTR lpFileName)
Definition: delete.c:39
BOOL WINAPI GetFileTime(IN HANDLE hFile, OUT LPFILETIME lpCreationTime OPTIONAL, OUT LPFILETIME lpLastAccessTime OPTIONAL, OUT LPFILETIME lpLastWriteTime OPTIONAL)
Definition: fileinfo.c:896
HANDLE WINAPI FindFirstFileW(IN LPCWSTR lpFileName, OUT LPWIN32_FIND_DATAW lpFindFileData)
Definition: find.c:320
BOOL WINAPI FindClose(HANDLE hFindFile)
Definition: find.c:502
BOOL WINAPI FindNextFileW(IN HANDLE hFindFile, OUT LPWIN32_FIND_DATAW lpFindFileData)
Definition: find.c:382
DWORD WINAPI GetFullPathNameW(IN LPCWSTR lpFileName, IN DWORD nBufferLength, OUT LPWSTR lpBuffer, OUT LPWSTR *lpFilePart)
Definition: path.c:1106
BOOL WINAPI FileTimeToSystemTime(IN CONST FILETIME *lpFileTime, OUT LPSYSTEMTIME lpSystemTime)
Definition: time.c:188
BOOL WINAPI FileTimeToLocalFileTime(IN CONST FILETIME *lpFileTime, OUT LPFILETIME lpLocalFileTime)
Definition: time.c:221
static void basename(LPCWSTR path, LPWSTR name)
Definition: profile.c:38
BOOL WINAPI PathRemoveFileSpecW(LPWSTR lpszPath)
Definition: path.c:629
void WINAPI PathRemoveExtensionW(LPWSTR lpszPath)
Definition: path.c:823
BOOL WINAPI PathFileExistsW(LPCWSTR lpszPath)
Definition: path.c:1777
BOOL WINAPI PathIsDirectoryW(LPCWSTR lpszPath)
Definition: path.c:1723
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
#define DEF_MEM_LEVEL
Definition: zutil.h:53
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
VOID WINAPI CoTaskMemFree(LPVOID ptr)
Definition: ifs.c:442
LPVOID WINAPI CoTaskMemAlloc(SIZE_T size)
Definition: ifs.c:426
const char * filename
Definition: ioapi.h:137
void fill_win32_filefunc64W(zlib_filefunc64_def *pzlib_filefunc_def)
Definition: iowin32.c:457
#define FILE_FLAG_SEQUENTIAL_SCAN
Definition: disk.h:43
LPCWSTR szPath
Definition: env.c:37
static TfClientId tid
static const char * contents
Definition: parser.c:511
static ATOM item
Definition: dde.c:856
static WCHAR password[]
Definition: url.c:33
_In_ HANDLE hFile
Definition: mswsock.h:90
CAtlStringA CStringA
Definition: atlstr.h:131
unsigned int UINT
Definition: ndis.h:50
HANDLE hThread
Definition: wizard.c:28
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705
#define L(x)
Definition: ntvdm.h:50
#define PathAddBackslashW
Definition: pathcch.h:301
#define PathAppendW
Definition: pathcch.h:309
#define err(...)
const WCHAR * str
_CRTIMP uintptr_t __cdecl _beginthreadex(_In_opt_ void *_Security, _In_ unsigned _StackSize, _In_ unsigned(__stdcall *_StartAddress)(void *), _In_opt_ void *_ArgList, _In_ unsigned _InitFlag, _Out_opt_ unsigned *_ThrdAddr)
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
#define CP_UTF8
Definition: nls.h:20
#define SHCNE_CREATE
Definition: shlobj.h:1876
#define SHCNF_PATHW
Definition: shlobj.h:1910
#define _countof(array)
Definition: sndvol32.h:68
STRSAFEAPI StringCbCopyW(STRSAFE_LPWSTR pszDest, size_t cbDest, STRSAFE_LPCWSTR pszSrc)
Definition: strsafe.h:166
unsigned JustDoIt()
CSimpleArray< CStringW > m_items
WORD wYear
Definition: winbase.h:905
WORD wMonth
Definition: winbase.h:906
WORD wHour
Definition: winbase.h:909
WORD wSecond
Definition: winbase.h:911
WORD wMinute
Definition: winbase.h:910
WORD wDay
Definition: winbase.h:908
int tm_hour
Definition: zip.h:93
int tm_min
Definition: zip.h:92
int tm_sec
Definition: zip.h:91
int tm_mon
Definition: zip.h:95
int tm_year
Definition: zip.h:96
int tm_mday
Definition: zip.h:94
tm_zip tmz_date
Definition: zip.h:101
#define new(TYPE, numElems)
Definition: treelist.c:54
const uint16_t * PCWSTR
Definition: typedefs.h:57
unsigned char * LPBYTE
Definition: typedefs.h:53
int32_t INT
Definition: typedefs.h:58
#define __stdcall
Definition: typedefs.h:25
int ret
#define ZeroMemory
Definition: winbase.h:1712
_In_ ULONG_PTR iFile
Definition: winddi.h:3835
void * arg
Definition: msvc.h:10
int WINAPI MessageBoxW(_In_opt_ HWND hWnd, _In_opt_ LPCWSTR lpText, _In_opt_ LPCWSTR lpCaption, _In_ UINT uType)
#define MB_ICONERROR
Definition: winuser.h:787
#define MAKEINTRESOURCEW(i)
Definition: winuser.h:582
__wchar_t WCHAR
Definition: xmlstorage.h:180
int ZEXPORT zipClose(zipFile file, const char *global_comment)
Definition: zip.c:1883
int ZEXPORT zipOpenNewFileInZip4_64(zipFile file, const char *filename, const zip_fileinfo *zipfi, const void *extrafield_local, uInt size_extrafield_local, const void *extrafield_global, uInt size_extrafield_global, const char *comment, int method, int level, int raw, int windowBits, int memLevel, int strategy, const char *password, uLong crcForCrypting, uLong versionMadeBy, uLong flagBase, int zip64)
Definition: zip.c:1061
zipFile ZEXPORT zipOpen2_64(const void *pathname, int append, zipcharpc *globalcomment, zlib_filefunc64_def *pzlib_filefunc_def)
Definition: zip.c:938
int ZEXPORT zipWriteInFileInZip(zipFile file, const void *buf, unsigned int len)
Definition: zip.c:1408
int ZEXPORT zipCloseFileInZip(zipFile file)
Definition: zip.c:1751
#define APPEND_STATUS_CREATE
Definition: zip.h:112
voidp zipFile
Definition: zip.h:69