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