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