1 /* iowin32.c -- IO base function header for compress/uncompress .zip
2 Version 1.1, February 14h, 2010
3 part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
4
5 Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
6
7 Modifications for Zip64 support
8 Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
9
10 For more info read MiniZip_info.txt
11
12 */
13
14 #include <stdlib.h>
15
16 #include "zlib.h"
17 #include "ioapi.h"
18 #include "iowin32.h"
19
20 #ifndef INVALID_HANDLE_VALUE
21 #define INVALID_HANDLE_VALUE (0xFFFFFFFF)
22 #endif
23
24 #ifndef INVALID_SET_FILE_POINTER
25 #define INVALID_SET_FILE_POINTER ((DWORD)-1)
26 #endif
27
28 #ifdef _WIN32_WINNT
29 #undef _WIN32_WINNT
30 #define _WIN32_WINNT 0x601
31 #endif
32
33 #if !defined(IOWIN32_USING_WINRT_API)
34 #if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP)
35 // Windows Store or Universal Windows Platform
36 #define IOWIN32_USING_WINRT_API 1
37 #endif
38 #endif
39
40 typedef struct
41 {
42 HANDLE hf;
43 int error;
44 } WIN32FILE_IOWIN;
45
46
win32_translate_open_mode(int mode,DWORD * lpdwDesiredAccess,DWORD * lpdwCreationDisposition,DWORD * lpdwShareMode,DWORD * lpdwFlagsAndAttributes)47 static void win32_translate_open_mode(int mode,
48 DWORD* lpdwDesiredAccess,
49 DWORD* lpdwCreationDisposition,
50 DWORD* lpdwShareMode,
51 DWORD* lpdwFlagsAndAttributes) {
52 *lpdwDesiredAccess = *lpdwShareMode = *lpdwFlagsAndAttributes = *lpdwCreationDisposition = 0;
53
54 if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ)
55 {
56 *lpdwDesiredAccess = GENERIC_READ;
57 *lpdwCreationDisposition = OPEN_EXISTING;
58 *lpdwShareMode = FILE_SHARE_READ;
59 }
60 else if (mode & ZLIB_FILEFUNC_MODE_EXISTING)
61 {
62 *lpdwDesiredAccess = GENERIC_WRITE | GENERIC_READ;
63 *lpdwCreationDisposition = OPEN_EXISTING;
64 }
65 else if (mode & ZLIB_FILEFUNC_MODE_CREATE)
66 {
67 *lpdwDesiredAccess = GENERIC_WRITE | GENERIC_READ;
68 *lpdwCreationDisposition = CREATE_ALWAYS;
69 }
70 }
71
win32_build_iowin(HANDLE hFile)72 static voidpf win32_build_iowin(HANDLE hFile) {
73 voidpf ret=NULL;
74
75 if ((hFile != NULL) && (hFile != INVALID_HANDLE_VALUE))
76 {
77 WIN32FILE_IOWIN w32fiow;
78 w32fiow.hf = hFile;
79 w32fiow.error = 0;
80 ret = malloc(sizeof(WIN32FILE_IOWIN));
81
82 if (ret==NULL)
83 CloseHandle(hFile);
84 else
85 *((WIN32FILE_IOWIN*)ret) = w32fiow;
86 }
87 return ret;
88 }
89
win32_open64_file_func(voidpf opaque,const void * filename,int mode)90 voidpf ZCALLBACK win32_open64_file_func(voidpf opaque, const void* filename, int mode) {
91 const char* mode_fopen = NULL;
92 DWORD dwDesiredAccess,dwCreationDisposition,dwShareMode,dwFlagsAndAttributes ;
93 HANDLE hFile = NULL;
94
95 win32_translate_open_mode(mode,&dwDesiredAccess,&dwCreationDisposition,&dwShareMode,&dwFlagsAndAttributes);
96
97 #ifdef IOWIN32_USING_WINRT_API
98 #ifdef UNICODE
99 if ((filename!=NULL) && (dwDesiredAccess != 0))
100 hFile = CreateFile2((LPCTSTR)filename, dwDesiredAccess, dwShareMode, dwCreationDisposition, NULL);
101 #else
102 if ((filename!=NULL) && (dwDesiredAccess != 0))
103 {
104 WCHAR filenameW[FILENAME_MAX + 0x200 + 1];
105 MultiByteToWideChar(CP_ACP,0,(const char*)filename,-1,filenameW,FILENAME_MAX + 0x200);
106 hFile = CreateFile2(filenameW, dwDesiredAccess, dwShareMode, dwCreationDisposition, NULL);
107 }
108 #endif
109 #else
110 if ((filename!=NULL) && (dwDesiredAccess != 0))
111 hFile = CreateFile((LPCTSTR)filename, dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, dwFlagsAndAttributes, NULL);
112 #endif
113
114 return win32_build_iowin(hFile);
115 }
116
117
win32_open64_file_funcA(voidpf opaque,const void * filename,int mode)118 voidpf ZCALLBACK win32_open64_file_funcA(voidpf opaque, const void* filename, int mode) {
119 const char* mode_fopen = NULL;
120 DWORD dwDesiredAccess,dwCreationDisposition,dwShareMode,dwFlagsAndAttributes ;
121 HANDLE hFile = NULL;
122
123 win32_translate_open_mode(mode,&dwDesiredAccess,&dwCreationDisposition,&dwShareMode,&dwFlagsAndAttributes);
124
125 #ifdef IOWIN32_USING_WINRT_API
126 if ((filename!=NULL) && (dwDesiredAccess != 0))
127 {
128 WCHAR filenameW[FILENAME_MAX + 0x200 + 1];
129 MultiByteToWideChar(CP_ACP,0,(const char*)filename,-1,filenameW,FILENAME_MAX + 0x200);
130 hFile = CreateFile2(filenameW, dwDesiredAccess, dwShareMode, dwCreationDisposition, NULL);
131 }
132 #else
133 if ((filename!=NULL) && (dwDesiredAccess != 0))
134 hFile = CreateFileA((LPCSTR)filename, dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, dwFlagsAndAttributes, NULL);
135 #endif
136
137 return win32_build_iowin(hFile);
138 }
139
140
win32_open64_file_funcW(voidpf opaque,const void * filename,int mode)141 voidpf ZCALLBACK win32_open64_file_funcW(voidpf opaque, const void* filename, int mode) {
142 const char* mode_fopen = NULL;
143 DWORD dwDesiredAccess,dwCreationDisposition,dwShareMode,dwFlagsAndAttributes ;
144 HANDLE hFile = NULL;
145
146 win32_translate_open_mode(mode,&dwDesiredAccess,&dwCreationDisposition,&dwShareMode,&dwFlagsAndAttributes);
147
148 #ifdef IOWIN32_USING_WINRT_API
149 if ((filename!=NULL) && (dwDesiredAccess != 0))
150 hFile = CreateFile2((LPCWSTR)filename, dwDesiredAccess, dwShareMode, dwCreationDisposition,NULL);
151 #else
152 if ((filename!=NULL) && (dwDesiredAccess != 0))
153 hFile = CreateFileW((LPCWSTR)filename, dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, dwFlagsAndAttributes, NULL);
154 #endif
155
156 return win32_build_iowin(hFile);
157 }
158
159
win32_open_file_func(voidpf opaque,const char * filename,int mode)160 voidpf ZCALLBACK win32_open_file_func(voidpf opaque, const char* filename, int mode) {
161 const char* mode_fopen = NULL;
162 DWORD dwDesiredAccess,dwCreationDisposition,dwShareMode,dwFlagsAndAttributes ;
163 HANDLE hFile = NULL;
164
165 win32_translate_open_mode(mode,&dwDesiredAccess,&dwCreationDisposition,&dwShareMode,&dwFlagsAndAttributes);
166
167 #ifdef IOWIN32_USING_WINRT_API
168 #ifdef UNICODE
169 if ((filename!=NULL) && (dwDesiredAccess != 0))
170 hFile = CreateFile2((LPCTSTR)filename, dwDesiredAccess, dwShareMode, dwCreationDisposition, NULL);
171 #else
172 if ((filename!=NULL) && (dwDesiredAccess != 0))
173 {
174 WCHAR filenameW[FILENAME_MAX + 0x200 + 1];
175 MultiByteToWideChar(CP_ACP,0,(const char*)filename,-1,filenameW,FILENAME_MAX + 0x200);
176 hFile = CreateFile2(filenameW, dwDesiredAccess, dwShareMode, dwCreationDisposition, NULL);
177 }
178 #endif
179 #else
180 if ((filename!=NULL) && (dwDesiredAccess != 0))
181 hFile = CreateFile((LPCTSTR)filename, dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, dwFlagsAndAttributes, NULL);
182 #endif
183
184 return win32_build_iowin(hFile);
185 }
186
187
win32_read_file_func(voidpf opaque,voidpf stream,void * buf,uLong size)188 uLong ZCALLBACK win32_read_file_func(voidpf opaque, voidpf stream, void* buf,uLong size) {
189 uLong ret=0;
190 HANDLE hFile = NULL;
191 if (stream!=NULL)
192 hFile = ((WIN32FILE_IOWIN*)stream) -> hf;
193
194 if (hFile != NULL)
195 {
196 if (!ReadFile(hFile, buf, size, &ret, NULL))
197 {
198 DWORD dwErr = GetLastError();
199 if (dwErr == ERROR_HANDLE_EOF)
200 dwErr = 0;
201 ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr;
202 }
203 }
204
205 return ret;
206 }
207
208
win32_write_file_func(voidpf opaque,voidpf stream,const void * buf,uLong size)209 uLong ZCALLBACK win32_write_file_func(voidpf opaque, voidpf stream, const void* buf, uLong size) {
210 uLong ret=0;
211 HANDLE hFile = NULL;
212 if (stream!=NULL)
213 hFile = ((WIN32FILE_IOWIN*)stream) -> hf;
214
215 if (hFile != NULL)
216 {
217 if (!WriteFile(hFile, buf, size, &ret, NULL))
218 {
219 DWORD dwErr = GetLastError();
220 if (dwErr == ERROR_HANDLE_EOF)
221 dwErr = 0;
222 ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr;
223 }
224 }
225
226 return ret;
227 }
228
MySetFilePointerEx(HANDLE hFile,LARGE_INTEGER pos,LARGE_INTEGER * newPos,DWORD dwMoveMethod)229 static BOOL MySetFilePointerEx(HANDLE hFile, LARGE_INTEGER pos, LARGE_INTEGER *newPos, DWORD dwMoveMethod) {
230 #ifdef IOWIN32_USING_WINRT_API
231 return SetFilePointerEx(hFile, pos, newPos, dwMoveMethod);
232 #else
233 LONG lHigh = pos.HighPart;
234 DWORD dwNewPos = SetFilePointer(hFile, pos.LowPart, &lHigh, dwMoveMethod);
235 BOOL fOk = TRUE;
236 if (dwNewPos == 0xFFFFFFFF)
237 if (GetLastError() != NO_ERROR)
238 fOk = FALSE;
239 if ((newPos != NULL) && (fOk))
240 {
241 newPos->LowPart = dwNewPos;
242 newPos->HighPart = lHigh;
243 }
244 return fOk;
245 #endif
246 }
247
win32_tell_file_func(voidpf opaque,voidpf stream)248 long ZCALLBACK win32_tell_file_func(voidpf opaque, voidpf stream) {
249 long ret=-1;
250 HANDLE hFile = NULL;
251 if (stream!=NULL)
252 hFile = ((WIN32FILE_IOWIN*)stream) -> hf;
253 if (hFile != NULL)
254 {
255 LARGE_INTEGER pos;
256 pos.QuadPart = 0;
257
258 if (!MySetFilePointerEx(hFile, pos, &pos, FILE_CURRENT))
259 {
260 DWORD dwErr = GetLastError();
261 ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr;
262 ret = -1;
263 }
264 else
265 ret=(long)pos.LowPart;
266 }
267 return ret;
268 }
269
win32_tell64_file_func(voidpf opaque,voidpf stream)270 ZPOS64_T ZCALLBACK win32_tell64_file_func(voidpf opaque, voidpf stream) {
271 ZPOS64_T ret= (ZPOS64_T)-1;
272 HANDLE hFile = NULL;
273 if (stream!=NULL)
274 hFile = ((WIN32FILE_IOWIN*)stream)->hf;
275
276 if (hFile)
277 {
278 LARGE_INTEGER pos;
279 pos.QuadPart = 0;
280
281 if (!MySetFilePointerEx(hFile, pos, &pos, FILE_CURRENT))
282 {
283 DWORD dwErr = GetLastError();
284 ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr;
285 ret = (ZPOS64_T)-1;
286 }
287 else
288 ret=pos.QuadPart;
289 }
290 return ret;
291 }
292
293
win32_seek_file_func(voidpf opaque,voidpf stream,uLong offset,int origin)294 long ZCALLBACK win32_seek_file_func(voidpf opaque, voidpf stream, uLong offset, int origin) {
295 DWORD dwMoveMethod=0xFFFFFFFF;
296 HANDLE hFile = NULL;
297
298 long ret=-1;
299 if (stream!=NULL)
300 hFile = ((WIN32FILE_IOWIN*)stream) -> hf;
301 switch (origin)
302 {
303 case ZLIB_FILEFUNC_SEEK_CUR :
304 dwMoveMethod = FILE_CURRENT;
305 break;
306 case ZLIB_FILEFUNC_SEEK_END :
307 dwMoveMethod = FILE_END;
308 break;
309 case ZLIB_FILEFUNC_SEEK_SET :
310 dwMoveMethod = FILE_BEGIN;
311 break;
312 default: return -1;
313 }
314
315 if (hFile != NULL)
316 {
317 LARGE_INTEGER pos;
318 pos.QuadPart = offset;
319 if (!MySetFilePointerEx(hFile, pos, NULL, dwMoveMethod))
320 {
321 DWORD dwErr = GetLastError();
322 ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr;
323 ret = -1;
324 }
325 else
326 ret=0;
327 }
328 return ret;
329 }
330
win32_seek64_file_func(voidpf opaque,voidpf stream,ZPOS64_T offset,int origin)331 long ZCALLBACK win32_seek64_file_func(voidpf opaque, voidpf stream, ZPOS64_T offset, int origin) {
332 DWORD dwMoveMethod=0xFFFFFFFF;
333 HANDLE hFile = NULL;
334 long ret=-1;
335
336 if (stream!=NULL)
337 hFile = ((WIN32FILE_IOWIN*)stream)->hf;
338
339 switch (origin)
340 {
341 case ZLIB_FILEFUNC_SEEK_CUR :
342 dwMoveMethod = FILE_CURRENT;
343 break;
344 case ZLIB_FILEFUNC_SEEK_END :
345 dwMoveMethod = FILE_END;
346 break;
347 case ZLIB_FILEFUNC_SEEK_SET :
348 dwMoveMethod = FILE_BEGIN;
349 break;
350 default: return -1;
351 }
352
353 if (hFile)
354 {
355 LARGE_INTEGER pos;
356 pos.QuadPart = offset;
357 if (!MySetFilePointerEx(hFile, pos, NULL, dwMoveMethod))
358 {
359 DWORD dwErr = GetLastError();
360 ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr;
361 ret = -1;
362 }
363 else
364 ret=0;
365 }
366 return ret;
367 }
368
win32_close_file_func(voidpf opaque,voidpf stream)369 int ZCALLBACK win32_close_file_func(voidpf opaque, voidpf stream) {
370 int ret=-1;
371
372 if (stream!=NULL)
373 {
374 HANDLE hFile;
375 hFile = ((WIN32FILE_IOWIN*)stream) -> hf;
376 if (hFile != NULL)
377 {
378 CloseHandle(hFile);
379 ret=0;
380 }
381 free(stream);
382 }
383 return ret;
384 }
385
win32_error_file_func(voidpf opaque,voidpf stream)386 int ZCALLBACK win32_error_file_func(voidpf opaque, voidpf stream) {
387 int ret=-1;
388 if (stream!=NULL)
389 {
390 ret = ((WIN32FILE_IOWIN*)stream) -> error;
391 }
392 return ret;
393 }
394
fill_win32_filefunc(zlib_filefunc_def * pzlib_filefunc_def)395 void fill_win32_filefunc(zlib_filefunc_def* pzlib_filefunc_def) {
396 pzlib_filefunc_def->zopen_file = win32_open_file_func;
397 pzlib_filefunc_def->zread_file = win32_read_file_func;
398 pzlib_filefunc_def->zwrite_file = win32_write_file_func;
399 pzlib_filefunc_def->ztell_file = win32_tell_file_func;
400 pzlib_filefunc_def->zseek_file = win32_seek_file_func;
401 pzlib_filefunc_def->zclose_file = win32_close_file_func;
402 pzlib_filefunc_def->zerror_file = win32_error_file_func;
403 pzlib_filefunc_def->opaque = NULL;
404 }
405
fill_win32_filefunc64(zlib_filefunc64_def * pzlib_filefunc_def)406 void fill_win32_filefunc64(zlib_filefunc64_def* pzlib_filefunc_def) {
407 pzlib_filefunc_def->zopen64_file = win32_open64_file_func;
408 pzlib_filefunc_def->zread_file = win32_read_file_func;
409 pzlib_filefunc_def->zwrite_file = win32_write_file_func;
410 pzlib_filefunc_def->ztell64_file = win32_tell64_file_func;
411 pzlib_filefunc_def->zseek64_file = win32_seek64_file_func;
412 pzlib_filefunc_def->zclose_file = win32_close_file_func;
413 pzlib_filefunc_def->zerror_file = win32_error_file_func;
414 pzlib_filefunc_def->opaque = NULL;
415 }
416
417
fill_win32_filefunc64A(zlib_filefunc64_def * pzlib_filefunc_def)418 void fill_win32_filefunc64A(zlib_filefunc64_def* pzlib_filefunc_def) {
419 pzlib_filefunc_def->zopen64_file = win32_open64_file_funcA;
420 pzlib_filefunc_def->zread_file = win32_read_file_func;
421 pzlib_filefunc_def->zwrite_file = win32_write_file_func;
422 pzlib_filefunc_def->ztell64_file = win32_tell64_file_func;
423 pzlib_filefunc_def->zseek64_file = win32_seek64_file_func;
424 pzlib_filefunc_def->zclose_file = win32_close_file_func;
425 pzlib_filefunc_def->zerror_file = win32_error_file_func;
426 pzlib_filefunc_def->opaque = NULL;
427 }
428
429
fill_win32_filefunc64W(zlib_filefunc64_def * pzlib_filefunc_def)430 void fill_win32_filefunc64W(zlib_filefunc64_def* pzlib_filefunc_def) {
431 pzlib_filefunc_def->zopen64_file = win32_open64_file_funcW;
432 pzlib_filefunc_def->zread_file = win32_read_file_func;
433 pzlib_filefunc_def->zwrite_file = win32_write_file_func;
434 pzlib_filefunc_def->ztell64_file = win32_tell64_file_func;
435 pzlib_filefunc_def->zseek64_file = win32_seek64_file_func;
436 pzlib_filefunc_def->zclose_file = win32_close_file_func;
437 pzlib_filefunc_def->zerror_file = win32_error_file_func;
438 pzlib_filefunc_def->opaque = NULL;
439 }
440