Chris@43: /* iowin32.c -- IO base function header for compress/uncompress .zip Chris@43: Version 1.1, February 14h, 2010 Chris@43: part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) Chris@43: Chris@43: Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) Chris@43: Chris@43: Modifications for Zip64 support Chris@43: Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) Chris@43: Chris@43: For more info read MiniZip_info.txt Chris@43: Chris@43: */ Chris@43: Chris@43: #include Chris@43: Chris@43: #include "zlib.h" Chris@43: #include "ioapi.h" Chris@43: #include "iowin32.h" Chris@43: Chris@43: #ifndef INVALID_HANDLE_VALUE Chris@43: #define INVALID_HANDLE_VALUE (0xFFFFFFFF) Chris@43: #endif Chris@43: Chris@43: #ifndef INVALID_SET_FILE_POINTER Chris@43: #define INVALID_SET_FILE_POINTER ((DWORD)-1) Chris@43: #endif Chris@43: Chris@43: Chris@43: #if defined(WINAPI_FAMILY_PARTITION) && (!(defined(IOWIN32_USING_WINRT_API))) Chris@43: #if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) Chris@43: #define IOWIN32_USING_WINRT_API 1 Chris@43: #endif Chris@43: #endif Chris@43: Chris@43: voidpf ZCALLBACK win32_open_file_func OF((voidpf opaque, const char* filename, int mode)); Chris@43: uLong ZCALLBACK win32_read_file_func OF((voidpf opaque, voidpf stream, void* buf, uLong size)); Chris@43: uLong ZCALLBACK win32_write_file_func OF((voidpf opaque, voidpf stream, const void* buf, uLong size)); Chris@43: ZPOS64_T ZCALLBACK win32_tell64_file_func OF((voidpf opaque, voidpf stream)); Chris@43: long ZCALLBACK win32_seek64_file_func OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int origin)); Chris@43: int ZCALLBACK win32_close_file_func OF((voidpf opaque, voidpf stream)); Chris@43: int ZCALLBACK win32_error_file_func OF((voidpf opaque, voidpf stream)); Chris@43: Chris@43: typedef struct Chris@43: { Chris@43: HANDLE hf; Chris@43: int error; Chris@43: } WIN32FILE_IOWIN; Chris@43: Chris@43: Chris@43: static void win32_translate_open_mode(int mode, Chris@43: DWORD* lpdwDesiredAccess, Chris@43: DWORD* lpdwCreationDisposition, Chris@43: DWORD* lpdwShareMode, Chris@43: DWORD* lpdwFlagsAndAttributes) Chris@43: { Chris@43: *lpdwDesiredAccess = *lpdwShareMode = *lpdwFlagsAndAttributes = *lpdwCreationDisposition = 0; Chris@43: Chris@43: if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ) Chris@43: { Chris@43: *lpdwDesiredAccess = GENERIC_READ; Chris@43: *lpdwCreationDisposition = OPEN_EXISTING; Chris@43: *lpdwShareMode = FILE_SHARE_READ; Chris@43: } Chris@43: else if (mode & ZLIB_FILEFUNC_MODE_EXISTING) Chris@43: { Chris@43: *lpdwDesiredAccess = GENERIC_WRITE | GENERIC_READ; Chris@43: *lpdwCreationDisposition = OPEN_EXISTING; Chris@43: } Chris@43: else if (mode & ZLIB_FILEFUNC_MODE_CREATE) Chris@43: { Chris@43: *lpdwDesiredAccess = GENERIC_WRITE | GENERIC_READ; Chris@43: *lpdwCreationDisposition = CREATE_ALWAYS; Chris@43: } Chris@43: } Chris@43: Chris@43: static voidpf win32_build_iowin(HANDLE hFile) Chris@43: { Chris@43: voidpf ret=NULL; Chris@43: Chris@43: if ((hFile != NULL) && (hFile != INVALID_HANDLE_VALUE)) Chris@43: { Chris@43: WIN32FILE_IOWIN w32fiow; Chris@43: w32fiow.hf = hFile; Chris@43: w32fiow.error = 0; Chris@43: ret = malloc(sizeof(WIN32FILE_IOWIN)); Chris@43: Chris@43: if (ret==NULL) Chris@43: CloseHandle(hFile); Chris@43: else Chris@43: *((WIN32FILE_IOWIN*)ret) = w32fiow; Chris@43: } Chris@43: return ret; Chris@43: } Chris@43: Chris@43: voidpf ZCALLBACK win32_open64_file_func (voidpf opaque,const void* filename,int mode) Chris@43: { Chris@43: const char* mode_fopen = NULL; Chris@43: DWORD dwDesiredAccess,dwCreationDisposition,dwShareMode,dwFlagsAndAttributes ; Chris@43: HANDLE hFile = NULL; Chris@43: Chris@43: win32_translate_open_mode(mode,&dwDesiredAccess,&dwCreationDisposition,&dwShareMode,&dwFlagsAndAttributes); Chris@43: Chris@43: #ifdef IOWIN32_USING_WINRT_API Chris@43: #ifdef UNICODE Chris@43: if ((filename!=NULL) && (dwDesiredAccess != 0)) Chris@43: hFile = CreateFile2((LPCTSTR)filename, dwDesiredAccess, dwShareMode, dwCreationDisposition, NULL); Chris@43: #else Chris@43: if ((filename!=NULL) && (dwDesiredAccess != 0)) Chris@43: { Chris@43: WCHAR filenameW[FILENAME_MAX + 0x200 + 1]; Chris@43: MultiByteToWideChar(CP_ACP,0,(const char*)filename,-1,filenameW,FILENAME_MAX + 0x200); Chris@43: hFile = CreateFile2(filenameW, dwDesiredAccess, dwShareMode, dwCreationDisposition, NULL); Chris@43: } Chris@43: #endif Chris@43: #else Chris@43: if ((filename!=NULL) && (dwDesiredAccess != 0)) Chris@43: hFile = CreateFile((LPCTSTR)filename, dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, dwFlagsAndAttributes, NULL); Chris@43: #endif Chris@43: Chris@43: return win32_build_iowin(hFile); Chris@43: } Chris@43: Chris@43: Chris@43: voidpf ZCALLBACK win32_open64_file_funcA (voidpf opaque,const void* filename,int mode) Chris@43: { Chris@43: const char* mode_fopen = NULL; Chris@43: DWORD dwDesiredAccess,dwCreationDisposition,dwShareMode,dwFlagsAndAttributes ; Chris@43: HANDLE hFile = NULL; Chris@43: Chris@43: win32_translate_open_mode(mode,&dwDesiredAccess,&dwCreationDisposition,&dwShareMode,&dwFlagsAndAttributes); Chris@43: Chris@43: #ifdef IOWIN32_USING_WINRT_API Chris@43: if ((filename!=NULL) && (dwDesiredAccess != 0)) Chris@43: { Chris@43: WCHAR filenameW[FILENAME_MAX + 0x200 + 1]; Chris@43: MultiByteToWideChar(CP_ACP,0,(const char*)filename,-1,filenameW,FILENAME_MAX + 0x200); Chris@43: hFile = CreateFile2(filenameW, dwDesiredAccess, dwShareMode, dwCreationDisposition, NULL); Chris@43: } Chris@43: #else Chris@43: if ((filename!=NULL) && (dwDesiredAccess != 0)) Chris@43: hFile = CreateFileA((LPCSTR)filename, dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, dwFlagsAndAttributes, NULL); Chris@43: #endif Chris@43: Chris@43: return win32_build_iowin(hFile); Chris@43: } Chris@43: Chris@43: Chris@43: voidpf ZCALLBACK win32_open64_file_funcW (voidpf opaque,const void* filename,int mode) Chris@43: { Chris@43: const char* mode_fopen = NULL; Chris@43: DWORD dwDesiredAccess,dwCreationDisposition,dwShareMode,dwFlagsAndAttributes ; Chris@43: HANDLE hFile = NULL; Chris@43: Chris@43: win32_translate_open_mode(mode,&dwDesiredAccess,&dwCreationDisposition,&dwShareMode,&dwFlagsAndAttributes); Chris@43: Chris@43: #ifdef IOWIN32_USING_WINRT_API Chris@43: if ((filename!=NULL) && (dwDesiredAccess != 0)) Chris@43: hFile = CreateFile2((LPCWSTR)filename, dwDesiredAccess, dwShareMode, dwCreationDisposition,NULL); Chris@43: #else Chris@43: if ((filename!=NULL) && (dwDesiredAccess != 0)) Chris@43: hFile = CreateFileW((LPCWSTR)filename, dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, dwFlagsAndAttributes, NULL); Chris@43: #endif Chris@43: Chris@43: return win32_build_iowin(hFile); Chris@43: } Chris@43: Chris@43: Chris@43: voidpf ZCALLBACK win32_open_file_func (voidpf opaque,const char* filename,int mode) Chris@43: { Chris@43: const char* mode_fopen = NULL; Chris@43: DWORD dwDesiredAccess,dwCreationDisposition,dwShareMode,dwFlagsAndAttributes ; Chris@43: HANDLE hFile = NULL; Chris@43: Chris@43: win32_translate_open_mode(mode,&dwDesiredAccess,&dwCreationDisposition,&dwShareMode,&dwFlagsAndAttributes); Chris@43: Chris@43: #ifdef IOWIN32_USING_WINRT_API Chris@43: #ifdef UNICODE Chris@43: if ((filename!=NULL) && (dwDesiredAccess != 0)) Chris@43: hFile = CreateFile2((LPCTSTR)filename, dwDesiredAccess, dwShareMode, dwCreationDisposition, NULL); Chris@43: #else Chris@43: if ((filename!=NULL) && (dwDesiredAccess != 0)) Chris@43: { Chris@43: WCHAR filenameW[FILENAME_MAX + 0x200 + 1]; Chris@43: MultiByteToWideChar(CP_ACP,0,(const char*)filename,-1,filenameW,FILENAME_MAX + 0x200); Chris@43: hFile = CreateFile2(filenameW, dwDesiredAccess, dwShareMode, dwCreationDisposition, NULL); Chris@43: } Chris@43: #endif Chris@43: #else Chris@43: if ((filename!=NULL) && (dwDesiredAccess != 0)) Chris@43: hFile = CreateFile((LPCTSTR)filename, dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, dwFlagsAndAttributes, NULL); Chris@43: #endif Chris@43: Chris@43: return win32_build_iowin(hFile); Chris@43: } Chris@43: Chris@43: Chris@43: uLong ZCALLBACK win32_read_file_func (voidpf opaque, voidpf stream, void* buf,uLong size) Chris@43: { Chris@43: uLong ret=0; Chris@43: HANDLE hFile = NULL; Chris@43: if (stream!=NULL) Chris@43: hFile = ((WIN32FILE_IOWIN*)stream) -> hf; Chris@43: Chris@43: if (hFile != NULL) Chris@43: { Chris@43: if (!ReadFile(hFile, buf, size, &ret, NULL)) Chris@43: { Chris@43: DWORD dwErr = GetLastError(); Chris@43: if (dwErr == ERROR_HANDLE_EOF) Chris@43: dwErr = 0; Chris@43: ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr; Chris@43: } Chris@43: } Chris@43: Chris@43: return ret; Chris@43: } Chris@43: Chris@43: Chris@43: uLong ZCALLBACK win32_write_file_func (voidpf opaque,voidpf stream,const void* buf,uLong size) Chris@43: { Chris@43: uLong ret=0; Chris@43: HANDLE hFile = NULL; Chris@43: if (stream!=NULL) Chris@43: hFile = ((WIN32FILE_IOWIN*)stream) -> hf; Chris@43: Chris@43: if (hFile != NULL) Chris@43: { Chris@43: if (!WriteFile(hFile, buf, size, &ret, NULL)) Chris@43: { Chris@43: DWORD dwErr = GetLastError(); Chris@43: if (dwErr == ERROR_HANDLE_EOF) Chris@43: dwErr = 0; Chris@43: ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr; Chris@43: } Chris@43: } Chris@43: Chris@43: return ret; Chris@43: } Chris@43: Chris@43: static BOOL MySetFilePointerEx(HANDLE hFile, LARGE_INTEGER pos, LARGE_INTEGER *newPos, DWORD dwMoveMethod) Chris@43: { Chris@43: #ifdef IOWIN32_USING_WINRT_API Chris@43: return SetFilePointerEx(hFile, pos, newPos, dwMoveMethod); Chris@43: #else Chris@43: LONG lHigh = pos.HighPart; Chris@43: DWORD dwNewPos = SetFilePointer(hFile, pos.LowPart, &lHigh, FILE_CURRENT); Chris@43: BOOL fOk = TRUE; Chris@43: if (dwNewPos == 0xFFFFFFFF) Chris@43: if (GetLastError() != NO_ERROR) Chris@43: fOk = FALSE; Chris@43: if ((newPos != NULL) && (fOk)) Chris@43: { Chris@43: newPos->LowPart = dwNewPos; Chris@43: newPos->HighPart = lHigh; Chris@43: } Chris@43: return fOk; Chris@43: #endif Chris@43: } Chris@43: Chris@43: long ZCALLBACK win32_tell_file_func (voidpf opaque,voidpf stream) Chris@43: { Chris@43: long ret=-1; Chris@43: HANDLE hFile = NULL; Chris@43: if (stream!=NULL) Chris@43: hFile = ((WIN32FILE_IOWIN*)stream) -> hf; Chris@43: if (hFile != NULL) Chris@43: { Chris@43: LARGE_INTEGER pos; Chris@43: pos.QuadPart = 0; Chris@43: Chris@43: if (!MySetFilePointerEx(hFile, pos, &pos, FILE_CURRENT)) Chris@43: { Chris@43: DWORD dwErr = GetLastError(); Chris@43: ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr; Chris@43: ret = -1; Chris@43: } Chris@43: else Chris@43: ret=(long)pos.LowPart; Chris@43: } Chris@43: return ret; Chris@43: } Chris@43: Chris@43: ZPOS64_T ZCALLBACK win32_tell64_file_func (voidpf opaque, voidpf stream) Chris@43: { Chris@43: ZPOS64_T ret= (ZPOS64_T)-1; Chris@43: HANDLE hFile = NULL; Chris@43: if (stream!=NULL) Chris@43: hFile = ((WIN32FILE_IOWIN*)stream)->hf; Chris@43: Chris@43: if (hFile) Chris@43: { Chris@43: LARGE_INTEGER pos; Chris@43: pos.QuadPart = 0; Chris@43: Chris@43: if (!MySetFilePointerEx(hFile, pos, &pos, FILE_CURRENT)) Chris@43: { Chris@43: DWORD dwErr = GetLastError(); Chris@43: ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr; Chris@43: ret = (ZPOS64_T)-1; Chris@43: } Chris@43: else Chris@43: ret=pos.QuadPart; Chris@43: } Chris@43: return ret; Chris@43: } Chris@43: Chris@43: Chris@43: long ZCALLBACK win32_seek_file_func (voidpf opaque,voidpf stream,uLong offset,int origin) Chris@43: { Chris@43: DWORD dwMoveMethod=0xFFFFFFFF; Chris@43: HANDLE hFile = NULL; Chris@43: Chris@43: long ret=-1; Chris@43: if (stream!=NULL) Chris@43: hFile = ((WIN32FILE_IOWIN*)stream) -> hf; Chris@43: switch (origin) Chris@43: { Chris@43: case ZLIB_FILEFUNC_SEEK_CUR : Chris@43: dwMoveMethod = FILE_CURRENT; Chris@43: break; Chris@43: case ZLIB_FILEFUNC_SEEK_END : Chris@43: dwMoveMethod = FILE_END; Chris@43: break; Chris@43: case ZLIB_FILEFUNC_SEEK_SET : Chris@43: dwMoveMethod = FILE_BEGIN; Chris@43: break; Chris@43: default: return -1; Chris@43: } Chris@43: Chris@43: if (hFile != NULL) Chris@43: { Chris@43: LARGE_INTEGER pos; Chris@43: pos.QuadPart = offset; Chris@43: if (!MySetFilePointerEx(hFile, pos, NULL, dwMoveMethod)) Chris@43: { Chris@43: DWORD dwErr = GetLastError(); Chris@43: ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr; Chris@43: ret = -1; Chris@43: } Chris@43: else Chris@43: ret=0; Chris@43: } Chris@43: return ret; Chris@43: } Chris@43: Chris@43: long ZCALLBACK win32_seek64_file_func (voidpf opaque, voidpf stream,ZPOS64_T offset,int origin) Chris@43: { Chris@43: DWORD dwMoveMethod=0xFFFFFFFF; Chris@43: HANDLE hFile = NULL; Chris@43: long ret=-1; Chris@43: Chris@43: if (stream!=NULL) Chris@43: hFile = ((WIN32FILE_IOWIN*)stream)->hf; Chris@43: Chris@43: switch (origin) Chris@43: { Chris@43: case ZLIB_FILEFUNC_SEEK_CUR : Chris@43: dwMoveMethod = FILE_CURRENT; Chris@43: break; Chris@43: case ZLIB_FILEFUNC_SEEK_END : Chris@43: dwMoveMethod = FILE_END; Chris@43: break; Chris@43: case ZLIB_FILEFUNC_SEEK_SET : Chris@43: dwMoveMethod = FILE_BEGIN; Chris@43: break; Chris@43: default: return -1; Chris@43: } Chris@43: Chris@43: if (hFile) Chris@43: { Chris@43: LARGE_INTEGER pos; Chris@43: pos.QuadPart = offset; Chris@43: if (!MySetFilePointerEx(hFile, pos, NULL, FILE_CURRENT)) Chris@43: { Chris@43: DWORD dwErr = GetLastError(); Chris@43: ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr; Chris@43: ret = -1; Chris@43: } Chris@43: else Chris@43: ret=0; Chris@43: } Chris@43: return ret; Chris@43: } Chris@43: Chris@43: int ZCALLBACK win32_close_file_func (voidpf opaque, voidpf stream) Chris@43: { Chris@43: int ret=-1; Chris@43: Chris@43: if (stream!=NULL) Chris@43: { Chris@43: HANDLE hFile; Chris@43: hFile = ((WIN32FILE_IOWIN*)stream) -> hf; Chris@43: if (hFile != NULL) Chris@43: { Chris@43: CloseHandle(hFile); Chris@43: ret=0; Chris@43: } Chris@43: free(stream); Chris@43: } Chris@43: return ret; Chris@43: } Chris@43: Chris@43: int ZCALLBACK win32_error_file_func (voidpf opaque,voidpf stream) Chris@43: { Chris@43: int ret=-1; Chris@43: if (stream!=NULL) Chris@43: { Chris@43: ret = ((WIN32FILE_IOWIN*)stream) -> error; Chris@43: } Chris@43: return ret; Chris@43: } Chris@43: Chris@43: void fill_win32_filefunc (zlib_filefunc_def* pzlib_filefunc_def) Chris@43: { Chris@43: pzlib_filefunc_def->zopen_file = win32_open_file_func; Chris@43: pzlib_filefunc_def->zread_file = win32_read_file_func; Chris@43: pzlib_filefunc_def->zwrite_file = win32_write_file_func; Chris@43: pzlib_filefunc_def->ztell_file = win32_tell_file_func; Chris@43: pzlib_filefunc_def->zseek_file = win32_seek_file_func; Chris@43: pzlib_filefunc_def->zclose_file = win32_close_file_func; Chris@43: pzlib_filefunc_def->zerror_file = win32_error_file_func; Chris@43: pzlib_filefunc_def->opaque = NULL; Chris@43: } Chris@43: Chris@43: void fill_win32_filefunc64(zlib_filefunc64_def* pzlib_filefunc_def) Chris@43: { Chris@43: pzlib_filefunc_def->zopen64_file = win32_open64_file_func; Chris@43: pzlib_filefunc_def->zread_file = win32_read_file_func; Chris@43: pzlib_filefunc_def->zwrite_file = win32_write_file_func; Chris@43: pzlib_filefunc_def->ztell64_file = win32_tell64_file_func; Chris@43: pzlib_filefunc_def->zseek64_file = win32_seek64_file_func; Chris@43: pzlib_filefunc_def->zclose_file = win32_close_file_func; Chris@43: pzlib_filefunc_def->zerror_file = win32_error_file_func; Chris@43: pzlib_filefunc_def->opaque = NULL; Chris@43: } Chris@43: Chris@43: Chris@43: void fill_win32_filefunc64A(zlib_filefunc64_def* pzlib_filefunc_def) Chris@43: { Chris@43: pzlib_filefunc_def->zopen64_file = win32_open64_file_funcA; Chris@43: pzlib_filefunc_def->zread_file = win32_read_file_func; Chris@43: pzlib_filefunc_def->zwrite_file = win32_write_file_func; Chris@43: pzlib_filefunc_def->ztell64_file = win32_tell64_file_func; Chris@43: pzlib_filefunc_def->zseek64_file = win32_seek64_file_func; Chris@43: pzlib_filefunc_def->zclose_file = win32_close_file_func; Chris@43: pzlib_filefunc_def->zerror_file = win32_error_file_func; Chris@43: pzlib_filefunc_def->opaque = NULL; Chris@43: } Chris@43: Chris@43: Chris@43: void fill_win32_filefunc64W(zlib_filefunc64_def* pzlib_filefunc_def) Chris@43: { Chris@43: pzlib_filefunc_def->zopen64_file = win32_open64_file_funcW; Chris@43: pzlib_filefunc_def->zread_file = win32_read_file_func; Chris@43: pzlib_filefunc_def->zwrite_file = win32_write_file_func; Chris@43: pzlib_filefunc_def->ztell64_file = win32_tell64_file_func; Chris@43: pzlib_filefunc_def->zseek64_file = win32_seek64_file_func; Chris@43: pzlib_filefunc_def->zclose_file = win32_close_file_func; Chris@43: pzlib_filefunc_def->zerror_file = win32_error_file_func; Chris@43: pzlib_filefunc_def->opaque = NULL; Chris@43: }