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