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