• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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