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 } 441