Home | History | Annotate | Download | only in minizip
      1 /* iowin32.c -- IO base function header for compress/uncompress .zip
      2    files using zlib + zip or unzip API
      3    This IO API version uses the Win32 API (for Microsoft Windows)
      4 
      5    Version 1.01e, February 12th, 2005
      6 
      7    Copyright (C) 1998-2005 Gilles Vollant
      8 */
      9 
     10 #include <stdlib.h>
     11 
     12 #include "zlib.h"
     13 #include "ioapi.h"
     14 #include "iowin32.h"
     15 
     16 #ifndef INVALID_HANDLE_VALUE
     17 #define INVALID_HANDLE_VALUE (0xFFFFFFFF)
     18 #endif
     19 
     20 #ifndef INVALID_SET_FILE_POINTER
     21 #define INVALID_SET_FILE_POINTER ((DWORD)-1)
     22 #endif
     23 
     24 voidpf ZCALLBACK win32_open_file_func OF((
     25    voidpf opaque,
     26    const char* filename,
     27    int mode));
     28 
     29 uLong ZCALLBACK win32_read_file_func OF((
     30    voidpf opaque,
     31    voidpf stream,
     32    void* buf,
     33    uLong size));
     34 
     35 uLong ZCALLBACK win32_write_file_func OF((
     36    voidpf opaque,
     37    voidpf stream,
     38    const void* buf,
     39    uLong size));
     40 
     41 long ZCALLBACK win32_tell_file_func OF((
     42    voidpf opaque,
     43    voidpf stream));
     44 
     45 long ZCALLBACK win32_seek_file_func OF((
     46    voidpf opaque,
     47    voidpf stream,
     48    uLong offset,
     49    int origin));
     50 
     51 int ZCALLBACK win32_close_file_func OF((
     52    voidpf opaque,
     53    voidpf stream));
     54 
     55 int ZCALLBACK win32_error_file_func OF((
     56    voidpf opaque,
     57    voidpf stream));
     58 
     59 typedef struct
     60 {
     61     HANDLE hf;
     62     int error;
     63 } WIN32FILE_IOWIN;
     64 
     65 voidpf ZCALLBACK win32_open_file_func (opaque, filename, mode)
     66    voidpf opaque;
     67    const char* filename;
     68    int mode;
     69 {
     70     const char* mode_fopen = NULL;
     71     DWORD dwDesiredAccess,dwCreationDisposition,dwShareMode,dwFlagsAndAttributes ;
     72     HANDLE hFile = 0;
     73     voidpf ret=NULL;
     74 
     75     dwDesiredAccess = dwShareMode = dwFlagsAndAttributes = 0;
     76 
     77     if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ)
     78     {
     79         dwDesiredAccess = GENERIC_READ;
     80         dwCreationDisposition = OPEN_EXISTING;
     81         dwShareMode = FILE_SHARE_READ;
     82     }
     83     else
     84     if (mode & ZLIB_FILEFUNC_MODE_EXISTING)
     85     {
     86         dwDesiredAccess = GENERIC_WRITE | GENERIC_READ;
     87         dwCreationDisposition = OPEN_EXISTING;
     88     }
     89     else
     90     if (mode & ZLIB_FILEFUNC_MODE_CREATE)
     91     {
     92         dwDesiredAccess = GENERIC_WRITE | GENERIC_READ;
     93         dwCreationDisposition = CREATE_ALWAYS;
     94     }
     95 
     96     if ((filename!=NULL) && (dwDesiredAccess != 0))
     97         hFile = CreateFile((LPCTSTR)filename, dwDesiredAccess, dwShareMode, NULL,
     98                       dwCreationDisposition, dwFlagsAndAttributes, NULL);
     99 
    100     if (hFile == INVALID_HANDLE_VALUE)
    101         hFile = NULL;
    102 
    103     if (hFile != NULL)
    104     {
    105         WIN32FILE_IOWIN w32fiow;
    106         w32fiow.hf = hFile;
    107         w32fiow.error = 0;
    108         ret = malloc(sizeof(WIN32FILE_IOWIN));
    109         if (ret==NULL)
    110             CloseHandle(hFile);
    111         else *((WIN32FILE_IOWIN*)ret) = w32fiow;
    112     }
    113     return ret;
    114 }
    115 
    116 
    117 uLong ZCALLBACK win32_read_file_func (opaque, stream, buf, size)
    118    voidpf opaque;
    119    voidpf stream;
    120    void* buf;
    121    uLong size;
    122 {
    123     uLong ret=0;
    124     HANDLE hFile = NULL;
    125     if (stream!=NULL)
    126         hFile = ((WIN32FILE_IOWIN*)stream) -> hf;
    127     if (hFile != NULL)
    128         if (!ReadFile(hFile, buf, size, &ret, NULL))
    129         {
    130             DWORD dwErr = GetLastError();
    131             if (dwErr == ERROR_HANDLE_EOF)
    132                 dwErr = 0;
    133             ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr;
    134         }
    135 
    136     return ret;
    137 }
    138 
    139 
    140 uLong ZCALLBACK win32_write_file_func (opaque, stream, buf, size)
    141    voidpf opaque;
    142    voidpf stream;
    143    const void* buf;
    144    uLong size;
    145 {
    146     uLong ret=0;
    147     HANDLE hFile = NULL;
    148     if (stream!=NULL)
    149         hFile = ((WIN32FILE_IOWIN*)stream) -> hf;
    150 
    151     if (hFile !=NULL)
    152         if (!WriteFile(hFile, buf, size, &ret, NULL))
    153         {
    154             DWORD dwErr = GetLastError();
    155             if (dwErr == ERROR_HANDLE_EOF)
    156                 dwErr = 0;
    157             ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr;
    158         }
    159 
    160     return ret;
    161 }
    162 
    163 long ZCALLBACK win32_tell_file_func (opaque, stream)
    164    voidpf opaque;
    165    voidpf stream;
    166 {
    167     long ret=-1;
    168     HANDLE hFile = NULL;
    169     if (stream!=NULL)
    170         hFile = ((WIN32FILE_IOWIN*)stream) -> hf;
    171     if (hFile != NULL)
    172     {
    173         DWORD dwSet = SetFilePointer(hFile, 0, NULL, FILE_CURRENT);
    174         if (dwSet == INVALID_SET_FILE_POINTER)
    175         {
    176             DWORD dwErr = GetLastError();
    177             ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr;
    178             ret = -1;
    179         }
    180         else
    181             ret=(long)dwSet;
    182     }
    183     return ret;
    184 }
    185 
    186 long ZCALLBACK win32_seek_file_func (opaque, stream, offset, origin)
    187    voidpf opaque;
    188    voidpf stream;
    189    uLong offset;
    190    int origin;
    191 {
    192     DWORD dwMoveMethod=0xFFFFFFFF;
    193     HANDLE hFile = NULL;
    194 
    195     long ret=-1;
    196     if (stream!=NULL)
    197         hFile = ((WIN32FILE_IOWIN*)stream) -> hf;
    198     switch (origin)
    199     {
    200     case ZLIB_FILEFUNC_SEEK_CUR :
    201         dwMoveMethod = FILE_CURRENT;
    202         break;
    203     case ZLIB_FILEFUNC_SEEK_END :
    204         dwMoveMethod = FILE_END;
    205         break;
    206     case ZLIB_FILEFUNC_SEEK_SET :
    207         dwMoveMethod = FILE_BEGIN;
    208         break;
    209     default: return -1;
    210     }
    211 
    212     if (hFile != NULL)
    213     {
    214         DWORD dwSet = SetFilePointer(hFile, offset, NULL, dwMoveMethod);
    215         if (dwSet == INVALID_SET_FILE_POINTER)
    216         {
    217             DWORD dwErr = GetLastError();
    218             ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr;
    219             ret = -1;
    220         }
    221         else
    222             ret=0;
    223     }
    224     return ret;
    225 }
    226 
    227 int ZCALLBACK win32_close_file_func (opaque, stream)
    228    voidpf opaque;
    229    voidpf stream;
    230 {
    231     int ret=-1;
    232 
    233     if (stream!=NULL)
    234     {
    235         HANDLE hFile;
    236         hFile = ((WIN32FILE_IOWIN*)stream) -> hf;
    237         if (hFile != NULL)
    238         {
    239             CloseHandle(hFile);
    240             ret=0;
    241         }
    242         free(stream);
    243     }
    244     return ret;
    245 }
    246 
    247 int ZCALLBACK win32_error_file_func (opaque, stream)
    248    voidpf opaque;
    249    voidpf stream;
    250 {
    251     int ret=-1;
    252     if (stream!=NULL)
    253     {
    254         ret = ((WIN32FILE_IOWIN*)stream) -> error;
    255     }
    256     return ret;
    257 }
    258 
    259 void fill_win32_filefunc (pzlib_filefunc_def)
    260   zlib_filefunc_def* pzlib_filefunc_def;
    261 {
    262     pzlib_filefunc_def->zopen_file = win32_open_file_func;
    263     pzlib_filefunc_def->zread_file = win32_read_file_func;
    264     pzlib_filefunc_def->zwrite_file = win32_write_file_func;
    265     pzlib_filefunc_def->ztell_file = win32_tell_file_func;
    266     pzlib_filefunc_def->zseek_file = win32_seek_file_func;
    267     pzlib_filefunc_def->zclose_file = win32_close_file_func;
    268     pzlib_filefunc_def->zerror_file = win32_error_file_func;
    269     pzlib_filefunc_def->opaque=NULL;
    270 }
    271