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