/* 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; | |
} |