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 // 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