ReactOS 0.4.15-dev-5893-g1bb4167
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 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{
41 return buf;
42}
43
45{
46 WCHAR szBaseName[MAX_PATH];
47 StringCbCopyW(szBaseName, sizeof(szBaseName), filename);
48 PathRemoveFileSpecW(szBaseName);
49 PathAddBackslashW(szBaseName);
50 return szBaseName;
51}
52
53static CStringA
55{
56 CStringW basenameI = basename, filenameI = filename;
57 basenameI.MakeUpper();
58 filenameI.MakeUpper();
59
61 if (filenameI.Find(basenameI) == 0)
62 ret = filename.Mid(basename.GetLength());
63 else
64 ret = filename;
65
66 ret.Replace(L'\\', L'/');
67
68 return DoGetAnsiName(ret);
69}
70
71static BOOL
73 zip_fileinfo *pzi)
74{
75 contents.RemoveAll();
76
81 {
82 DPRINT1("%S: cannot open\n", filename);
83 return FALSE;
84 }
85
86 FILETIME ft, ftLocal;
87 ZeroMemory(pzi, sizeof(*pzi));
88 if (GetFileTime(hFile, NULL, NULL, &ft))
89 {
90 SYSTEMTIME st;
91 FileTimeToLocalFileTime(&ft, &ftLocal);
92 FileTimeToSystemTime(&ftLocal, &st);
93 pzi->tmz_date.tm_sec = st.wSecond;
94 pzi->tmz_date.tm_min = st.wMinute;
95 pzi->tmz_date.tm_hour = st.wHour;
96 pzi->tmz_date.tm_mday = st.wDay;
97 pzi->tmz_date.tm_mon = st.wMonth - 1;
98 pzi->tmz_date.tm_year = st.wYear;
99 }
100
101 const DWORD cbBuff = 0x7FFF;
102 LPBYTE pbBuff = reinterpret_cast<LPBYTE>(CoTaskMemAlloc(cbBuff));
103 if (!pbBuff)
104 {
105 DPRINT1("Out of memory\n");
107 return FALSE;
108 }
109
110 for (;;)
111 {
112 DWORD cbRead;
113 if (!ReadFile(hFile, pbBuff, cbBuff, &cbRead, NULL) || !cbRead)
114 break;
115
116 for (DWORD i = 0; i < cbRead; ++i)
117 contents.Add(pbBuff[i]);
118 }
119
120 CoTaskMemFree(pbBuff);
122
123 return TRUE;
124}
125
126static void
128{
130 {
131 files.Add(item);
132 return;
133 }
134
136 StringCbCopyW(szPath, sizeof(szPath), item);
137 PathAppendW(szPath, L"*");
138
140 HANDLE hFind = FindFirstFileW(szPath, &find);
141 if (hFind == INVALID_HANDLE_VALUE)
142 return;
143
144 do
145 {
146 if (wcscmp(find.cFileName, L".") == 0 ||
147 wcscmp(find.cFileName, L"..") == 0)
148 {
149 continue;
150 }
151
152 StringCbCopyW(szPath, sizeof(szPath), item);
153 PathAppendW(szPath, find.cFileName);
154
155 if (find.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
157 else
158 files.Add(szPath);
159 } while (FindNextFileW(hFind, &find));
160
161 FindClose(hFind);
162}
163
165{
167
168 unsigned JustDoIt();
169};
170
172{
174}
175
177{
179 delete m_pimpl;
180}
181
182static unsigned __stdcall
184{
185 CZipCreator *pCreator = reinterpret_cast<CZipCreator *>(arg);
186 return pCreator->m_pimpl->JustDoIt();
187}
188
190{
191 unsigned tid = 0;
192 HANDLE hThread = reinterpret_cast<HANDLE>(
193 _beginthreadex(NULL, 0, create_zip_function, pCreator, 0, &tid));
194
195 if (hThread)
196 {
198 return TRUE;
199 }
200
201 DPRINT1("hThread == NULL\n");
202
205 MessageBoxW(NULL, strText, strTitle, MB_ICONERROR);
206
207 delete pCreator;
208 return FALSE;
209}
210
212{
213 // canonicalize path
216
217 m_pimpl->m_items.Add(szPath);
218}
219
221{
227
229{
230 // TODO: Show progress.
231
232 if (m_items.GetSize() <= 0)
233 {
234 DPRINT1("GetSize() <= 0\n");
235 return CZCERR_ZEROITEMS;
236 }
237
239 for (INT iItem = 0; iItem < m_items.GetSize(); ++iItem)
240 {
241 DoAddFilesFromItem(files, m_items[iItem]);
242 }
243
244 if (files.GetSize() <= 0)
245 {
246 DPRINT1("files.GetSize() <= 0\n");
247
249 CStringW strText;
250 strText.Format(IDS_NOFILES, static_cast<LPCWSTR>(m_items[0]));
251 MessageBoxW(NULL, strText, strTitle, MB_ICONERROR);
252
253 return CZCERR_NOFILES;
254 }
255
258
259 CStringW strZipName = DoGetZipName(m_items[0]);
260 zipFile zf = zipOpen2_64(strZipName, APPEND_STATUS_CREATE, NULL, &ffunc);
261 if (zf == 0)
262 {
263 DPRINT1("zf == 0\n");
264
265 int err = CZCERR_CREATE;
266
268 CStringW strText;
269 strText.Format(IDS_CANTCREATEZIP, static_cast<LPCWSTR>(strZipName), err);
270 MessageBoxW(NULL, strText, strTitle, MB_ICONERROR);
271
272 return err;
273 }
274
275 // TODO: password
276 const char *password = NULL;
277 int zip64 = 1; // always zip64
278 zip_fileinfo zi;
279
280 int err = 0;
281 CStringW strTarget, strBaseName = DoGetBaseName(m_items[0]);
282 for (INT iFile = 0; iFile < files.GetSize(); ++iFile)
283 {
284 const CStringW& strFile = files[iFile];
285
287 if (!DoReadAllOfFile(strFile, contents, &zi))
288 {
289 DPRINT1("DoReadAllOfFile failed\n");
291 strTarget = strFile;
292 break;
293 }
294
295 unsigned long crc = 0;
296 if (password)
297 {
298 // TODO: crc = ...;
299 }
300
301 CStringA strNameInZip = DoGetNameInZip(strBaseName, strFile);
303 strNameInZip,
304 &zi,
305 NULL,
306 0,
307 NULL,
308 0,
309 NULL,
312 0,
313 -MAX_WBITS,
316 password,
317 crc,
318 zip64);
319 if (err)
320 {
321 DPRINT1("zipOpenNewFileInZip3_64\n");
322 break;
323 }
324
325 err = zipWriteInFileInZip(zf, contents.GetData(), contents.GetSize());
326 if (err)
327 {
328 DPRINT1("zipWriteInFileInZip\n");
329 break;
330 }
331
333 if (err)
334 {
335 DPRINT1("zipCloseFileInZip\n");
336 break;
337 }
338 }
339
340 zipClose(zf, NULL);
341
342 if (err)
343 {
344 DeleteFileW(strZipName);
345
347
348 CStringW strText;
349 if (err < 0)
350 strText.Format(IDS_CANTCREATEZIP, static_cast<LPCWSTR>(strZipName), err);
351 else
352 strText.Format(IDS_CANTREADFILE, static_cast<LPCWSTR>(strTarget));
353
354 MessageBoxW(NULL, strText, strTitle, MB_ICONERROR);
355 }
356 else
357 {
358 WCHAR szFullPath[MAX_PATH];
359 GetFullPathNameW(strZipName, _countof(szFullPath), szFullPath, NULL);
361 }
362
363 return err;
364}
LONG g_ModuleRefCnt
Definition: ACPPage.cpp:13
CZC_ERROR
@ CZCERR_NOFILES
@ CZCERR_ZEROITEMS
@ CZCERR_READ
@ CZCERR_CREATE
static unsigned __stdcall create_zip_function(void *arg)
static CStringW DoGetBaseName(LPCWSTR filename)
Definition: CZipCreator.cpp:44
static CStringA DoGetAnsiName(LPCWSTR filename)
Definition: CZipCreator.cpp:37
static void DoAddFilesFromItem(CSimpleArray< CStringW > &files, LPCWSTR item)
static BOOL DoReadAllOfFile(LPCWSTR filename, CSimpleArray< BYTE > &contents, zip_fileinfo *pzi)
Definition: CZipCreator.cpp:72
static CStringW DoGetZipName(LPCWSTR filename)
Definition: CZipCreator.cpp:15
static CStringA DoGetNameInZip(const CStringW &basename, const CStringW &filename)
Definition: CZipCreator.cpp:54
#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:753
CStringT & MakeUpper()
Definition: cstringt.h:637
static BOOL runThread(CZipCreator *pCreator)
virtual void DoAddItem(LPCWSTR pszFile)
struct CZipCreatorImpl * m_pimpl
Definition: CZipCreator.hpp:16
virtual ~CZipCreator()
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 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 CP_ACP
Definition: compat.h:109
#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 WideCharToMultiByte
Definition: compat.h:111
#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
LPWSTR WINAPI PathAddBackslashW(LPWSTR lpszPath)
Definition: path.c:294
BOOL WINAPI PathRemoveFileSpecW(LPWSTR lpszPath)
Definition: path.c:629
void WINAPI PathRemoveExtensionW(LPWSTR lpszPath)
Definition: path.c:823
BOOL WINAPI PathAppendW(LPWSTR lpszPath, LPCWSTR lpszAppend)
Definition: path.c:126
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
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
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
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 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 SHCNE_CREATE
Definition: shlobj.h:1743
#define SHCNF_PATHW
Definition: shlobj.h:1777
#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
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:1670
_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:781
#define MAKEINTRESOURCEW(i)
Definition: winuser.h:582
__wchar_t WCHAR
Definition: xmlstorage.h:180
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
char CHAR
Definition: xmlstorage.h:175
int ZEXPORT zipClose(zipFile file, const char *global_comment)
Definition: zip.c:1883
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 zipOpenNewFileInZip3_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, int zip64)
Definition: zip.c:1302
int ZEXPORT zipCloseFileInZip(zipFile file)
Definition: zip.c:1751
#define APPEND_STATUS_CREATE
Definition: zip.h:112
voidp zipFile
Definition: zip.h:69