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 uint32_t ZCALLBACK win32_read_file_func (voidpf opaque, voidpf stream, void* buf, uint32_t size);
41 uint32_t ZCALLBACK win32_write_file_func (voidpf opaque, voidpf stream, const void *buf, uint32_t size);
42 uint64_t ZCALLBACK win32_tell64_file_func (voidpf opaque, voidpf stream);
43 long ZCALLBACK win32_seek64_file_func (voidpf opaque, voidpf stream, uint64_t offset, int origin);
44 int ZCALLBACK win32_close_file_func (voidpf opaque, voidpf stream);
45 int ZCALLBACK win32_error_file_func (voidpf opaque, voidpf stream);
56 static void win32_translate_open_mode(int mode,
57 DWORD* lpdwDesiredAccess,
58 DWORD* lpdwCreationDisposition,
60 DWORD* lpdwFlagsAndAttributes)
62 *lpdwDesiredAccess = 0;
64 *lpdwCreationDisposition = 0;
65 *lpdwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL;
67 if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER) == ZLIB_FILEFUNC_MODE_READ)
69 *lpdwDesiredAccess = GENERIC_READ;
70 *lpdwCreationDisposition = OPEN_EXISTING;
71 *lpdwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
73 else if (mode & ZLIB_FILEFUNC_MODE_EXISTING)
75 *lpdwDesiredAccess = GENERIC_WRITE | GENERIC_READ;
76 *lpdwCreationDisposition = OPEN_EXISTING;
78 else if (mode & ZLIB_FILEFUNC_MODE_CREATE)
80 *lpdwDesiredAccess = GENERIC_WRITE | GENERIC_READ;
81 *lpdwCreationDisposition = CREATE_ALWAYS;
85 static voidpf win32_build_iowin(HANDLE hFile)
87 WIN32FILE_IOWIN *iowin = NULL;
89 if ((hFile != NULL) && (hFile != INVALID_HANDLE_VALUE))
91 iowin = (WIN32FILE_IOWIN *)malloc(sizeof(WIN32FILE_IOWIN));
97 memset(iowin, 0, sizeof(WIN32FILE_IOWIN));
100 return (voidpf)iowin;
103 static voidpf ZCALLBACK win32_open64_file_funcA(voidpf opaque, const void *filename, int mode)
105 DWORD dwDesiredAccess, dwCreationDisposition, dwShareMode, dwFlagsAndAttributes ;
107 WIN32FILE_IOWIN *iowin = NULL;
109 win32_translate_open_mode(mode, &dwDesiredAccess, &dwCreationDisposition, &dwShareMode, &dwFlagsAndAttributes);
111 if ((filename != NULL) && (dwDesiredAccess != 0))
113 #ifdef IOWIN32_USING_WINRT_API
114 WCHAR filenameW[FILENAME_MAX + 0x200 + 1];
115 MultiByteToWideChar(CP_ACP, 0, (const char*)filename, -1, filenameW, FILENAME_MAX + 0x200);
116 hFile = CreateFile2(filenameW, dwDesiredAccess, dwShareMode, dwCreationDisposition, NULL);
118 hFile = CreateFileA((LPCSTR)filename, dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, dwFlagsAndAttributes, NULL);
122 iowin = win32_build_iowin(hFile);
125 iowin->filenameLength = strlen(filename) + 1;
126 iowin->filename = (void*)malloc(iowin->filenameLength * sizeof(char));
127 strncpy(iowin->filename, filename, iowin->filenameLength);
131 static voidpf ZCALLBACK win32_opendisk64_file_funcA(voidpf opaque, voidpf stream, uint32_t number_disk, int mode)
133 WIN32FILE_IOWIN *iowin = NULL;
134 char *diskFilename = NULL;
140 iowin = (WIN32FILE_IOWIN*)stream;
141 diskFilename = (char*)malloc(iowin->filenameLength * sizeof(char));
142 strncpy(diskFilename, iowin->filename, iowin->filenameLength);
143 for (i = iowin->filenameLength - 1; i >= 0; i -= 1)
145 if (diskFilename[i] != '.')
147 _snprintf(&diskFilename[i], iowin->filenameLength - i, ".z%02d", number_disk + 1);
151 ret = win32_open64_file_funcA(opaque, diskFilename, mode);
156 uint32_t ZCALLBACK win32_read_file_func(voidpf opaque, voidpf stream, void* buf, uint32_t size)
161 hFile = ((WIN32FILE_IOWIN*)stream)->hf;
165 if (!ReadFile(hFile, buf, size, &ret, NULL))
167 DWORD dwErr = GetLastError();
168 if (dwErr == ERROR_HANDLE_EOF)
170 ((WIN32FILE_IOWIN*)stream)->error = (int)dwErr;
174 return (uint32_t)ret;
177 uint32_t ZCALLBACK win32_write_file_func(voidpf opaque, voidpf stream, const void *buf, uint32_t size)
182 hFile = ((WIN32FILE_IOWIN*)stream)->hf;
186 if (!WriteFile(hFile, buf, size, &ret, NULL))
188 DWORD dwErr = GetLastError();
189 if (dwErr == ERROR_HANDLE_EOF)
191 ((WIN32FILE_IOWIN*)stream)->error = (int)dwErr;
195 return (uint32_t)ret;
198 static BOOL win32_setfilepointer_internal(HANDLE hFile, LARGE_INTEGER pos, LARGE_INTEGER *newPos, DWORD dwMoveMethod)
200 #ifdef IOWIN32_USING_WINRT_API
201 return SetFilePointerEx(hFile, pos, newPos, dwMoveMethod);
203 LONG lHigh = pos.HighPart;
205 DWORD dwNewPos = SetFilePointer(hFile, pos.LowPart, &lHigh, dwMoveMethod);
206 if ((dwNewPos == INVALID_SET_FILE_POINTER) && (GetLastError() != NO_ERROR))
208 if ((newPos != NULL) && (ret))
210 newPos->LowPart = dwNewPos;
211 newPos->HighPart = lHigh;
217 uint64_t ZCALLBACK win32_tell64_file_func(voidpf opaque, voidpf stream)
219 uint64_t ret = (uint64_t)-1;
222 hFile = ((WIN32FILE_IOWIN*)stream)->hf;
228 if (!win32_setfilepointer_internal(hFile, pos, &pos, FILE_CURRENT))
230 DWORD dwErr = GetLastError();
231 ((WIN32FILE_IOWIN*)stream)->error = (int)dwErr;
240 long ZCALLBACK win32_seek64_file_func(voidpf opaque, voidpf stream, uint64_t offset, int origin)
242 DWORD dwMoveMethod = 0xFFFFFFFF;
247 hFile = ((WIN32FILE_IOWIN*)stream)->hf;
251 case ZLIB_FILEFUNC_SEEK_CUR:
252 dwMoveMethod = FILE_CURRENT;
254 case ZLIB_FILEFUNC_SEEK_END:
255 dwMoveMethod = FILE_END;
257 case ZLIB_FILEFUNC_SEEK_SET:
258 dwMoveMethod = FILE_BEGIN;
267 pos.QuadPart = offset;
268 if (!win32_setfilepointer_internal(hFile, pos, NULL, dwMoveMethod))
270 DWORD dwErr = GetLastError();
271 ((WIN32FILE_IOWIN*)stream)->error = (int)dwErr;
280 int ZCALLBACK win32_close_file_func(voidpf opaque, voidpf stream)
282 WIN32FILE_IOWIN* iowin = NULL;
287 iowin = ((WIN32FILE_IOWIN*)stream);
288 if (iowin->filename != NULL)
289 free(iowin->filename);
290 if (iowin->hf != NULL)
292 CloseHandle(iowin->hf);
299 int ZCALLBACK win32_error_file_func(voidpf opaque, voidpf stream)
304 ret = ((WIN32FILE_IOWIN*)stream)->error;
308 void fill_win32_filefunc64A(zlib_filefunc64_def *pzlib_filefunc_def)
310 pzlib_filefunc_def->zopen64_file = win32_open64_file_funcA;
311 pzlib_filefunc_def->zopendisk64_file = win32_opendisk64_file_funcA;
312 pzlib_filefunc_def->zread_file = win32_read_file_func;
313 pzlib_filefunc_def->zwrite_file = win32_write_file_func;
314 pzlib_filefunc_def->ztell64_file = win32_tell64_file_func;
315 pzlib_filefunc_def->zseek64_file = win32_seek64_file_func;
316 pzlib_filefunc_def->zclose_file = win32_close_file_func;
317 pzlib_filefunc_def->zerror_file = win32_error_file_func;
318 pzlib_filefunc_def->opaque = NULL;