1 /* iowin32.c -- IO base function header for compress/uncompress .zip
2 Version 1.2.0, September 16th, 2017
3 part of the MiniZip project
5 Copyright (C) 2012-2017 Nathan Moinvaziri
6 https://github.com/nmoinvaz/minizip
7 Copyright (C) 2009-2010 Mathias Svensson
8 Modifications for Zip64 support
10 Copyright (C) 1998-2010 Gilles Vollant
11 http://www.winimage.com/zLibDll/minizip.html
13 This program is distributed under the terms of the same license as zlib.
14 See the accompanying LICENSE file for the full text of the license.
26 #ifndef INVALID_HANDLE_VALUE
27 # define INVALID_HANDLE_VALUE (0xFFFFFFFF)
30 #ifndef INVALID_SET_FILE_POINTER
31 # define INVALID_SET_FILE_POINTER ((DWORD)-1)
34 #if defined(WINAPI_FAMILY_PARTITION) && (!(defined(IOWIN32_USING_WINRT_API)))
35 # if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
36 # define IOWIN32_USING_WINRT_API 1
40 voidpf ZCALLBACK win32_open_file_func (voidpf opaque, const char *filename, int mode);
41 uint32_t ZCALLBACK win32_read_file_func (voidpf opaque, voidpf stream, void* buf, uint32_t size);
42 uint32_t ZCALLBACK win32_write_file_func (voidpf opaque, voidpf stream, const void *buf, uint32_t size);
43 uint64_t ZCALLBACK win32_tell64_file_func (voidpf opaque, voidpf stream);
44 long ZCALLBACK win32_seek64_file_func (voidpf opaque, voidpf stream, uint64_t offset, int origin);
45 int ZCALLBACK win32_close_file_func (voidpf opaque, voidpf stream);
46 int ZCALLBACK win32_error_file_func (voidpf opaque, voidpf stream);
57 static void win32_translate_open_mode(int mode,
58 DWORD* lpdwDesiredAccess,
59 DWORD* lpdwCreationDisposition,
61 DWORD* lpdwFlagsAndAttributes)
63 *lpdwDesiredAccess = 0;
65 *lpdwCreationDisposition = 0;
66 *lpdwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL;
68 if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER) == ZLIB_FILEFUNC_MODE_READ)
70 *lpdwDesiredAccess = GENERIC_READ;
71 *lpdwCreationDisposition = OPEN_EXISTING;
72 *lpdwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
74 else if (mode & ZLIB_FILEFUNC_MODE_EXISTING)
76 *lpdwDesiredAccess = GENERIC_WRITE | GENERIC_READ;
77 *lpdwCreationDisposition = OPEN_EXISTING;
79 else if (mode & ZLIB_FILEFUNC_MODE_CREATE)
81 *lpdwDesiredAccess = GENERIC_WRITE | GENERIC_READ;
82 *lpdwCreationDisposition = CREATE_ALWAYS;
86 static voidpf win32_build_iowin(HANDLE hFile)
88 WIN32FILE_IOWIN *iowin = NULL;
90 if ((hFile != NULL) && (hFile != INVALID_HANDLE_VALUE))
92 iowin = (WIN32FILE_IOWIN *)malloc(sizeof(WIN32FILE_IOWIN));
98 memset(iowin, 0, sizeof(WIN32FILE_IOWIN));
101 return (voidpf)iowin;
104 static voidpf ZCALLBACK win32_open64_file_func(voidpf opaque, const void *filename, int mode)
106 DWORD dwDesiredAccess,dwCreationDisposition,dwShareMode,dwFlagsAndAttributes;
108 WIN32FILE_IOWIN *iowin = NULL;
110 win32_translate_open_mode(mode, &dwDesiredAccess, &dwCreationDisposition, &dwShareMode, &dwFlagsAndAttributes);
112 if ((filename != NULL) && (dwDesiredAccess != 0))
114 #ifdef IOWIN32_USING_WINRT_API
116 hFile = CreateFile2((LPCTSTR)filename, dwDesiredAccess, dwShareMode, dwCreationDisposition, NULL);
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);
123 hFile = CreateFile((LPCTSTR)filename, dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, dwFlagsAndAttributes, NULL);
127 iowin = win32_build_iowin(hFile);
130 iowin->filenameLength = _tcslen(filename) + 1;
131 iowin->filename = (void*)malloc(iowin->filenameLength * sizeof(TCHAR));
132 _tcsncpy(iowin->filename, filename, iowin->filenameLength);
136 static voidpf ZCALLBACK win32_open64_file_funcA(voidpf opaque, const void *filename, int mode)
138 DWORD dwDesiredAccess, dwCreationDisposition, dwShareMode, dwFlagsAndAttributes ;
140 WIN32FILE_IOWIN *iowin = NULL;
142 win32_translate_open_mode(mode, &dwDesiredAccess, &dwCreationDisposition, &dwShareMode, &dwFlagsAndAttributes);
144 if ((filename != NULL) && (dwDesiredAccess != 0))
146 #ifdef IOWIN32_USING_WINRT_API
147 WCHAR filenameW[FILENAME_MAX + 0x200 + 1];
148 MultiByteToWideChar(CP_ACP, 0, (const char*)filename, -1, filenameW, FILENAME_MAX + 0x200);
149 hFile = CreateFile2(filenameW, dwDesiredAccess, dwShareMode, dwCreationDisposition, NULL);
151 hFile = CreateFileA((LPCSTR)filename, dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, dwFlagsAndAttributes, NULL);
155 iowin = win32_build_iowin(hFile);
158 iowin->filenameLength = strlen(filename) + 1;
159 iowin->filename = (void*)malloc(iowin->filenameLength * sizeof(char));
160 strncpy(iowin->filename, filename, iowin->filenameLength);
164 static voidpf ZCALLBACK win32_open64_file_funcW(voidpf opaque, const void *filename, int mode)
166 DWORD dwDesiredAccess, dwCreationDisposition, dwShareMode, dwFlagsAndAttributes;
168 WIN32FILE_IOWIN *iowin = NULL;
170 win32_translate_open_mode(mode, &dwDesiredAccess, &dwCreationDisposition, &dwShareMode, &dwFlagsAndAttributes);
172 if ((filename != NULL) && (dwDesiredAccess != 0))
174 #ifdef IOWIN32_USING_WINRT_API
175 hFile = CreateFile2((LPCWSTR)filename, dwDesiredAccess, dwShareMode, dwCreationDisposition, NULL);
177 hFile = CreateFileW((LPCWSTR)filename, dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, dwFlagsAndAttributes, NULL);
181 iowin = win32_build_iowin(hFile);
184 if (iowin->filename == NULL)
186 iowin->filenameLength = wcslen(filename) + 1;
187 iowin->filename = (void*)malloc(iowin->filenameLength * sizeof(WCHAR));
188 wcsncpy(iowin->filename, filename, iowin->filenameLength);
193 voidpf ZCALLBACK win32_open_file_func(voidpf opaque, const char *filename, int mode)
195 DWORD dwDesiredAccess, dwCreationDisposition, dwShareMode, dwFlagsAndAttributes ;
197 WIN32FILE_IOWIN *iowin = NULL;
199 win32_translate_open_mode(mode, &dwDesiredAccess, &dwCreationDisposition, &dwShareMode, &dwFlagsAndAttributes);
201 if ((filename != NULL) && (dwDesiredAccess != 0))
203 #ifdef IOWIN32_USING_WINRT_API
205 hFile = CreateFile2((LPCTSTR)filename, dwDesiredAccess, dwShareMode, dwCreationDisposition, NULL);
207 WCHAR filenameW[FILENAME_MAX + 0x200 + 1];
208 MultiByteToWideChar(CP_ACP, 0, (const char*)filename, -1, filenameW, FILENAME_MAX + 0x200);
209 hFile = CreateFile2(filenameW, dwDesiredAccess, dwShareMode, dwCreationDisposition, NULL);
212 hFile = CreateFile((LPCTSTR)filename, dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, dwFlagsAndAttributes, NULL);
216 iowin = win32_build_iowin(hFile);
219 iowin->filenameLength = _tcslen((TCHAR*)filename) + 1;
220 iowin->filename = (void*)malloc(iowin->filenameLength * sizeof(TCHAR));
221 _tcsncpy(iowin->filename, (TCHAR*)filename, iowin->filenameLength);
225 static voidpf ZCALLBACK win32_opendisk64_file_func(voidpf opaque, voidpf stream, uint32_t number_disk, int mode)
227 WIN32FILE_IOWIN *iowin = NULL;
228 TCHAR *diskFilename = NULL;
234 iowin = (WIN32FILE_IOWIN*)stream;
235 diskFilename = (TCHAR*)malloc(iowin->filenameLength * sizeof(TCHAR));
236 _tcsncpy(diskFilename, iowin->filename, iowin->filenameLength);
237 for (i = iowin->filenameLength - 1; i >= 0; i -= 1)
239 if (diskFilename[i] != _T('.'))
241 _sntprintf(&diskFilename[i], iowin->filenameLength - i, _T(".z%02d"), number_disk + 1);
245 ret = win32_open64_file_func(opaque, (char*)diskFilename, mode);
250 static voidpf ZCALLBACK win32_opendisk64_file_funcW(voidpf opaque, voidpf stream, uint32_t number_disk, int mode)
252 WIN32FILE_IOWIN *iowin = NULL;
253 WCHAR *diskFilename = NULL;
259 iowin = (WIN32FILE_IOWIN*)stream;
260 diskFilename = (WCHAR*)malloc((iowin->filenameLength + 10) * sizeof(WCHAR));
261 wcsncpy(diskFilename, iowin->filename, iowin->filenameLength);
262 for (i = iowin->filenameLength - 1; i >= 0; i -= 1)
264 if (diskFilename[i] != L'.')
266 _snwprintf(&diskFilename[i], (iowin->filenameLength + 10) - i, L".z%02d", number_disk + 1);
270 ret = win32_open64_file_funcW(opaque, diskFilename, mode);
275 static voidpf ZCALLBACK win32_opendisk64_file_funcA(voidpf opaque, voidpf stream, uint32_t number_disk, int mode)
277 WIN32FILE_IOWIN *iowin = NULL;
278 char *diskFilename = NULL;
284 iowin = (WIN32FILE_IOWIN*)stream;
285 diskFilename = (char*)malloc(iowin->filenameLength * sizeof(char));
286 strncpy(diskFilename, iowin->filename, iowin->filenameLength);
287 for (i = iowin->filenameLength - 1; i >= 0; i -= 1)
289 if (diskFilename[i] != '.')
291 _snprintf(&diskFilename[i], iowin->filenameLength - i, ".z%02d", number_disk + 1);
295 ret = win32_open64_file_funcA(opaque, diskFilename, mode);
300 static voidpf ZCALLBACK win32_opendisk_file_func(voidpf opaque, voidpf stream, uint32_t number_disk, int mode)
302 WIN32FILE_IOWIN *iowin = NULL;
303 TCHAR *diskFilename = NULL;
309 iowin = (WIN32FILE_IOWIN*)stream;
310 diskFilename = (TCHAR*)malloc(iowin->filenameLength * sizeof(TCHAR));
311 _tcsncpy(diskFilename, iowin->filename, iowin->filenameLength);
312 for (i = iowin->filenameLength - 1; i >= 0; i -= 1)
314 if (diskFilename[i] != _T('.'))
316 _sntprintf(&diskFilename[i], iowin->filenameLength - i, _T(".z%02d"), number_disk + 1);
320 ret = win32_open_file_func(opaque, (char*)diskFilename, mode);
325 uint32_t ZCALLBACK win32_read_file_func(voidpf opaque, voidpf stream, void* buf, uint32_t size)
330 hFile = ((WIN32FILE_IOWIN*)stream)->hf;
334 if (!ReadFile(hFile, buf, size, &ret, NULL))
336 DWORD dwErr = GetLastError();
337 if (dwErr == ERROR_HANDLE_EOF)
339 ((WIN32FILE_IOWIN*)stream)->error = (int)dwErr;
343 return (uint32_t)ret;
346 uint32_t ZCALLBACK win32_write_file_func(voidpf opaque, voidpf stream, const void *buf, uint32_t size)
351 hFile = ((WIN32FILE_IOWIN*)stream)->hf;
355 if (!WriteFile(hFile, buf, size, &ret, NULL))
357 DWORD dwErr = GetLastError();
358 if (dwErr == ERROR_HANDLE_EOF)
360 ((WIN32FILE_IOWIN*)stream)->error = (int)dwErr;
364 return (uint32_t)ret;
367 static BOOL win32_setfilepointer_internal(HANDLE hFile, LARGE_INTEGER pos, LARGE_INTEGER *newPos, DWORD dwMoveMethod)
369 #ifdef IOWIN32_USING_WINRT_API
370 return SetFilePointerEx(hFile, pos, newPos, dwMoveMethod);
372 LONG lHigh = pos.HighPart;
374 DWORD dwNewPos = SetFilePointer(hFile, pos.LowPart, &lHigh, dwMoveMethod);
375 if ((dwNewPos == INVALID_SET_FILE_POINTER) && (GetLastError() != NO_ERROR))
377 if ((newPos != NULL) && (ret))
379 newPos->LowPart = dwNewPos;
380 newPos->HighPart = lHigh;
386 static long ZCALLBACK win32_tell_file_func(voidpf opaque, voidpf stream)
391 hFile = ((WIN32FILE_IOWIN*)stream)->hf;
396 if (!win32_setfilepointer_internal(hFile, pos, &pos, FILE_CURRENT))
398 DWORD dwErr = GetLastError();
399 ((WIN32FILE_IOWIN*)stream)->error = (int)dwErr;
403 ret = (long)pos.LowPart;
408 uint64_t ZCALLBACK win32_tell64_file_func(voidpf opaque, voidpf stream)
410 uint64_t ret = (uint64_t)-1;
413 hFile = ((WIN32FILE_IOWIN*)stream)->hf;
419 if (!win32_setfilepointer_internal(hFile, pos, &pos, FILE_CURRENT))
421 DWORD dwErr = GetLastError();
422 ((WIN32FILE_IOWIN*)stream)->error = (int)dwErr;
431 static long ZCALLBACK win32_seek_file_func(voidpf opaque, voidpf stream, uint32_t offset, int origin)
433 DWORD dwMoveMethod = 0xFFFFFFFF;
438 hFile = ((WIN32FILE_IOWIN*)stream)->hf;
442 case ZLIB_FILEFUNC_SEEK_CUR:
443 dwMoveMethod = FILE_CURRENT;
445 case ZLIB_FILEFUNC_SEEK_END:
446 dwMoveMethod = FILE_END;
448 case ZLIB_FILEFUNC_SEEK_SET:
449 dwMoveMethod = FILE_BEGIN;
458 pos.QuadPart = offset;
459 if (!win32_setfilepointer_internal(hFile, pos, NULL, dwMoveMethod))
461 DWORD dwErr = GetLastError();
462 ((WIN32FILE_IOWIN*)stream)->error = (int)dwErr;
471 long ZCALLBACK win32_seek64_file_func(voidpf opaque, voidpf stream, uint64_t offset, int origin)
473 DWORD dwMoveMethod = 0xFFFFFFFF;
478 hFile = ((WIN32FILE_IOWIN*)stream)->hf;
482 case ZLIB_FILEFUNC_SEEK_CUR:
483 dwMoveMethod = FILE_CURRENT;
485 case ZLIB_FILEFUNC_SEEK_END:
486 dwMoveMethod = FILE_END;
488 case ZLIB_FILEFUNC_SEEK_SET:
489 dwMoveMethod = FILE_BEGIN;
498 pos.QuadPart = offset;
499 if (!win32_setfilepointer_internal(hFile, pos, NULL, dwMoveMethod))
501 DWORD dwErr = GetLastError();
502 ((WIN32FILE_IOWIN*)stream)->error = (int)dwErr;
511 int ZCALLBACK win32_close_file_func(voidpf opaque, voidpf stream)
513 WIN32FILE_IOWIN* iowin = NULL;
518 iowin = ((WIN32FILE_IOWIN*)stream);
519 if (iowin->filename != NULL)
520 free(iowin->filename);
521 if (iowin->hf != NULL)
523 CloseHandle(iowin->hf);
530 int ZCALLBACK win32_error_file_func(voidpf opaque, voidpf stream)
535 ret = ((WIN32FILE_IOWIN*)stream)->error;
539 void fill_win32_filefunc(zlib_filefunc_def *pzlib_filefunc_def)
541 pzlib_filefunc_def->zopen_file = win32_open_file_func;
542 pzlib_filefunc_def->zopendisk_file = win32_opendisk_file_func;
543 pzlib_filefunc_def->zread_file = win32_read_file_func;
544 pzlib_filefunc_def->zwrite_file = win32_write_file_func;
545 pzlib_filefunc_def->ztell_file = win32_tell_file_func;
546 pzlib_filefunc_def->zseek_file = win32_seek_file_func;
547 pzlib_filefunc_def->zclose_file = win32_close_file_func;
548 pzlib_filefunc_def->zerror_file = win32_error_file_func;
549 pzlib_filefunc_def->opaque = NULL;
552 void fill_win32_filefunc64(zlib_filefunc64_def *pzlib_filefunc_def)
554 pzlib_filefunc_def->zopen64_file = win32_open64_file_func;
555 pzlib_filefunc_def->zopendisk64_file = win32_opendisk64_file_func;
556 pzlib_filefunc_def->zread_file = win32_read_file_func;
557 pzlib_filefunc_def->zwrite_file = win32_write_file_func;
558 pzlib_filefunc_def->ztell64_file = win32_tell64_file_func;
559 pzlib_filefunc_def->zseek64_file = win32_seek64_file_func;
560 pzlib_filefunc_def->zclose_file = win32_close_file_func;
561 pzlib_filefunc_def->zerror_file = win32_error_file_func;
562 pzlib_filefunc_def->opaque = NULL;
565 void fill_win32_filefunc64A(zlib_filefunc64_def *pzlib_filefunc_def)
567 pzlib_filefunc_def->zopen64_file = win32_open64_file_funcA;
568 pzlib_filefunc_def->zopendisk64_file = win32_opendisk64_file_funcA;
569 pzlib_filefunc_def->zread_file = win32_read_file_func;
570 pzlib_filefunc_def->zwrite_file = win32_write_file_func;
571 pzlib_filefunc_def->ztell64_file = win32_tell64_file_func;
572 pzlib_filefunc_def->zseek64_file = win32_seek64_file_func;
573 pzlib_filefunc_def->zclose_file = win32_close_file_func;
574 pzlib_filefunc_def->zerror_file = win32_error_file_func;
575 pzlib_filefunc_def->opaque = NULL;
578 void fill_win32_filefunc64W(zlib_filefunc64_def *pzlib_filefunc_def)
580 pzlib_filefunc_def->zopen64_file = win32_open64_file_funcW;
581 pzlib_filefunc_def->zopendisk64_file = win32_opendisk64_file_funcW;
582 pzlib_filefunc_def->zread_file = win32_read_file_func;
583 pzlib_filefunc_def->zwrite_file = win32_write_file_func;
584 pzlib_filefunc_def->ztell64_file = win32_tell64_file_func;
585 pzlib_filefunc_def->zseek64_file = win32_seek64_file_func;
586 pzlib_filefunc_def->zclose_file = win32_close_file_func;
587 pzlib_filefunc_def->zerror_file = win32_error_file_func;
588 pzlib_filefunc_def->opaque = NULL;