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