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