• 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 #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