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