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