Home | History | Annotate | Download | only in minizip
      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 }
    462