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