duckstation

duckstation, but archived from the revision just before upstream changed it to a proprietary software project, this version is the libre one
git clone https://git.neptards.moe/u3shit/duckstation.git
Log | Files | Refs | README | LICENSE

iowin32.c (14373B)


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