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