/* 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 0.22, May 19th, 2003 Copyright (C) 1998-2003 Gilles Vollant */ #include #include #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)); long 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; } long ZCALLBACK win32_close_file_func (opaque, stream) voidpf opaque; voidpf stream; { long 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; }