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