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