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