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