| /* iowin32.c -- IO base function header for compress/uncompress .zip |
| files using zlib + zip or unzip API |
| This IO API version uses the Win32 API (for Microsoft Windows) |
| |
| Version 1.01e, February 12th, 2005 |
| |
| Copyright (C) 1998-2005 Gilles Vollant |
| */ |
| |
| #include <stdlib.h> |
| |
| #include "zlib.h" |
| #include "ioapi.h" |
| #include "iowin32.h" |
| |
| #ifndef INVALID_HANDLE_VALUE |
| #define INVALID_HANDLE_VALUE (0xFFFFFFFF) |
| #endif |
| |
| #ifndef INVALID_SET_FILE_POINTER |
| #define INVALID_SET_FILE_POINTER ((DWORD)-1) |
| #endif |
| |
| voidpf ZCALLBACK win32_open_file_func OF(( |
| voidpf opaque, |
| const char* filename, |
| int mode)); |
| |
| uLong ZCALLBACK win32_read_file_func OF(( |
| voidpf opaque, |
| voidpf stream, |
| void* buf, |
| uLong size)); |
| |
| uLong ZCALLBACK win32_write_file_func OF(( |
| voidpf opaque, |
| voidpf stream, |
| const void* buf, |
| uLong size)); |
| |
| long ZCALLBACK win32_tell_file_func OF(( |
| voidpf opaque, |
| voidpf stream)); |
| |
| long ZCALLBACK win32_seek_file_func OF(( |
| voidpf opaque, |
| voidpf stream, |
| uLong offset, |
| int origin)); |
| |
| int ZCALLBACK win32_close_file_func OF(( |
| voidpf opaque, |
| voidpf stream)); |
| |
| int ZCALLBACK win32_error_file_func OF(( |
| voidpf opaque, |
| voidpf stream)); |
| |
| typedef struct |
| { |
| HANDLE hf; |
| int error; |
| } WIN32FILE_IOWIN; |
| |
| voidpf ZCALLBACK win32_open_file_func (opaque, filename, mode) |
| voidpf opaque; |
| const char* filename; |
| int mode; |
| { |
| const char* mode_fopen = NULL; |
| DWORD dwDesiredAccess,dwCreationDisposition,dwShareMode,dwFlagsAndAttributes ; |
| HANDLE hFile = 0; |
| voidpf ret=NULL; |
| |
| dwDesiredAccess = dwShareMode = dwFlagsAndAttributes = 0; |
| |
| if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ) |
| { |
| dwDesiredAccess = GENERIC_READ; |
| dwCreationDisposition = OPEN_EXISTING; |
| dwShareMode = FILE_SHARE_READ; |
| } |
| else |
| if (mode & ZLIB_FILEFUNC_MODE_EXISTING) |
| { |
| dwDesiredAccess = GENERIC_WRITE | GENERIC_READ; |
| dwCreationDisposition = OPEN_EXISTING; |
| } |
| else |
| if (mode & ZLIB_FILEFUNC_MODE_CREATE) |
| { |
| dwDesiredAccess = GENERIC_WRITE | GENERIC_READ; |
| dwCreationDisposition = CREATE_ALWAYS; |
| } |
| |
| if ((filename!=NULL) && (dwDesiredAccess != 0)) |
| hFile = CreateFile((LPCTSTR)filename, dwDesiredAccess, dwShareMode, NULL, |
| dwCreationDisposition, dwFlagsAndAttributes, NULL); |
| |
| if (hFile == INVALID_HANDLE_VALUE) |
| hFile = NULL; |
| |
| if (hFile != NULL) |
| { |
| WIN32FILE_IOWIN w32fiow; |
| w32fiow.hf = hFile; |
| w32fiow.error = 0; |
| ret = malloc(sizeof(WIN32FILE_IOWIN)); |
| if (ret==NULL) |
| CloseHandle(hFile); |
| else *((WIN32FILE_IOWIN*)ret) = w32fiow; |
| } |
| return ret; |
| } |
| |
| |
| uLong ZCALLBACK win32_read_file_func (opaque, stream, buf, size) |
| voidpf opaque; |
| voidpf stream; |
| void* buf; |
| uLong size; |
| { |
| uLong ret=0; |
| HANDLE hFile = NULL; |
| if (stream!=NULL) |
| hFile = ((WIN32FILE_IOWIN*)stream) -> hf; |
| if (hFile != NULL) |
| if (!ReadFile(hFile, buf, size, &ret, NULL)) |
| { |
| DWORD dwErr = GetLastError(); |
| if (dwErr == ERROR_HANDLE_EOF) |
| dwErr = 0; |
| ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr; |
| } |
| |
| return ret; |
| } |
| |
| |
| uLong ZCALLBACK win32_write_file_func (opaque, stream, buf, size) |
| voidpf opaque; |
| voidpf stream; |
| const void* buf; |
| uLong size; |
| { |
| uLong ret=0; |
| HANDLE hFile = NULL; |
| if (stream!=NULL) |
| hFile = ((WIN32FILE_IOWIN*)stream) -> hf; |
| |
| if (hFile !=NULL) |
| if (!WriteFile(hFile, buf, size, &ret, NULL)) |
| { |
| DWORD dwErr = GetLastError(); |
| if (dwErr == ERROR_HANDLE_EOF) |
| dwErr = 0; |
| ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr; |
| } |
| |
| return ret; |
| } |
| |
| long ZCALLBACK win32_tell_file_func (opaque, stream) |
| voidpf opaque; |
| voidpf stream; |
| { |
| long ret=-1; |
| HANDLE hFile = NULL; |
| if (stream!=NULL) |
| hFile = ((WIN32FILE_IOWIN*)stream) -> hf; |
| if (hFile != NULL) |
| { |
| DWORD dwSet = SetFilePointer(hFile, 0, NULL, FILE_CURRENT); |
| if (dwSet == INVALID_SET_FILE_POINTER) |
| { |
| DWORD dwErr = GetLastError(); |
| ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr; |
| ret = -1; |
| } |
| else |
| ret=(long)dwSet; |
| } |
| return ret; |
| } |
| |
| long ZCALLBACK win32_seek_file_func (opaque, stream, offset, origin) |
| voidpf opaque; |
| voidpf stream; |
| uLong offset; |
| int origin; |
| { |
| DWORD dwMoveMethod=0xFFFFFFFF; |
| HANDLE hFile = NULL; |
| |
| long ret=-1; |
| if (stream!=NULL) |
| hFile = ((WIN32FILE_IOWIN*)stream) -> hf; |
| switch (origin) |
| { |
| case ZLIB_FILEFUNC_SEEK_CUR : |
| dwMoveMethod = FILE_CURRENT; |
| break; |
| case ZLIB_FILEFUNC_SEEK_END : |
| dwMoveMethod = FILE_END; |
| break; |
| case ZLIB_FILEFUNC_SEEK_SET : |
| dwMoveMethod = FILE_BEGIN; |
| break; |
| default: return -1; |
| } |
| |
| if (hFile != NULL) |
| { |
| DWORD dwSet = SetFilePointer(hFile, offset, NULL, dwMoveMethod); |
| if (dwSet == INVALID_SET_FILE_POINTER) |
| { |
| DWORD dwErr = GetLastError(); |
| ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr; |
| ret = -1; |
| } |
| else |
| ret=0; |
| } |
| return ret; |
| } |
| |
| int ZCALLBACK win32_close_file_func (opaque, stream) |
| voidpf opaque; |
| voidpf stream; |
| { |
| int ret=-1; |
| |
| if (stream!=NULL) |
| { |
| HANDLE hFile; |
| hFile = ((WIN32FILE_IOWIN*)stream) -> hf; |
| if (hFile != NULL) |
| { |
| CloseHandle(hFile); |
| ret=0; |
| } |
| free(stream); |
| } |
| return ret; |
| } |
| |
| int ZCALLBACK win32_error_file_func (opaque, stream) |
| voidpf opaque; |
| voidpf stream; |
| { |
| int ret=-1; |
| if (stream!=NULL) |
| { |
| ret = ((WIN32FILE_IOWIN*)stream) -> error; |
| } |
| return ret; |
| } |
| |
| void fill_win32_filefunc (pzlib_filefunc_def) |
| zlib_filefunc_def* pzlib_filefunc_def; |
| { |
| pzlib_filefunc_def->zopen_file = win32_open_file_func; |
| pzlib_filefunc_def->zread_file = win32_read_file_func; |
| pzlib_filefunc_def->zwrite_file = win32_write_file_func; |
| pzlib_filefunc_def->ztell_file = win32_tell_file_func; |
| pzlib_filefunc_def->zseek_file = win32_seek_file_func; |
| pzlib_filefunc_def->zclose_file = win32_close_file_func; |
| pzlib_filefunc_def->zerror_file = win32_error_file_func; |
| pzlib_filefunc_def->opaque=NULL; |
| } |