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