1/*	$NetBSD: iowin32.c,v 1.1.1.1 2006/01/14 20:10:57 christos Exp $	*/
2
3/* iowin32.c -- IO base function header for compress/uncompress .zip
4   files using zlib + zip or unzip API
5   This IO API version uses the Win32 API (for Microsoft Windows)
6
7   Version 1.01e, February 12th, 2005
8
9   Copyright (C) 1998-2005 Gilles Vollant
10*/
11
12#include <stdlib.h>
13
14#include "zlib.h"
15#include "ioapi.h"
16#include "iowin32.h"
17
18#ifndef INVALID_HANDLE_VALUE
19#define INVALID_HANDLE_VALUE (0xFFFFFFFF)
20#endif
21
22#ifndef INVALID_SET_FILE_POINTER
23#define INVALID_SET_FILE_POINTER ((DWORD)-1)
24#endif
25
26voidpf ZCALLBACK win32_open_file_func OF((
27   voidpf opaque,
28   const char* filename,
29   int mode));
30
31uLong ZCALLBACK win32_read_file_func OF((
32   voidpf opaque,
33   voidpf stream,
34   void* buf,
35   uLong size));
36
37uLong ZCALLBACK win32_write_file_func OF((
38   voidpf opaque,
39   voidpf stream,
40   const void* buf,
41   uLong size));
42
43long ZCALLBACK win32_tell_file_func OF((
44   voidpf opaque,
45   voidpf stream));
46
47long ZCALLBACK win32_seek_file_func OF((
48   voidpf opaque,
49   voidpf stream,
50   uLong offset,
51   int origin));
52
53int ZCALLBACK win32_close_file_func OF((
54   voidpf opaque,
55   voidpf stream));
56
57int ZCALLBACK win32_error_file_func OF((
58   voidpf opaque,
59   voidpf stream));
60
61typedef struct
62{
63    HANDLE hf;
64    int error;
65} WIN32FILE_IOWIN;
66
67voidpf ZCALLBACK win32_open_file_func (opaque, filename, mode)
68   voidpf opaque;
69   const char* filename;
70   int mode;
71{
72    const char* mode_fopen = NULL;
73    DWORD dwDesiredAccess,dwCreationDisposition,dwShareMode,dwFlagsAndAttributes ;
74    HANDLE hFile = 0;
75    voidpf ret=NULL;
76
77    dwDesiredAccess = dwShareMode = dwFlagsAndAttributes = 0;
78
79    if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ)
80    {
81        dwDesiredAccess = GENERIC_READ;
82        dwCreationDisposition = OPEN_EXISTING;
83        dwShareMode = FILE_SHARE_READ;
84    }
85    else
86    if (mode & ZLIB_FILEFUNC_MODE_EXISTING)
87    {
88        dwDesiredAccess = GENERIC_WRITE | GENERIC_READ;
89        dwCreationDisposition = OPEN_EXISTING;
90    }
91    else
92    if (mode & ZLIB_FILEFUNC_MODE_CREATE)
93    {
94        dwDesiredAccess = GENERIC_WRITE | GENERIC_READ;
95        dwCreationDisposition = CREATE_ALWAYS;
96    }
97
98    if ((filename!=NULL) && (dwDesiredAccess != 0))
99        hFile = CreateFile((LPCTSTR)filename, dwDesiredAccess, dwShareMode, NULL,
100                      dwCreationDisposition, dwFlagsAndAttributes, NULL);
101
102    if (hFile == INVALID_HANDLE_VALUE)
103        hFile = NULL;
104
105    if (hFile != NULL)
106    {
107        WIN32FILE_IOWIN w32fiow;
108        w32fiow.hf = hFile;
109        w32fiow.error = 0;
110        ret = malloc(sizeof(WIN32FILE_IOWIN));
111        if (ret==NULL)
112            CloseHandle(hFile);
113        else *((WIN32FILE_IOWIN*)ret) = w32fiow;
114    }
115    return ret;
116}
117
118
119uLong ZCALLBACK win32_read_file_func (opaque, stream, buf, size)
120   voidpf opaque;
121   voidpf stream;
122   void* buf;
123   uLong size;
124{
125    uLong ret=0;
126    HANDLE hFile = NULL;
127    if (stream!=NULL)
128        hFile = ((WIN32FILE_IOWIN*)stream) -> hf;
129    if (hFile != NULL)
130        if (!ReadFile(hFile, buf, size, &ret, NULL))
131        {
132            DWORD dwErr = GetLastError();
133            if (dwErr == ERROR_HANDLE_EOF)
134                dwErr = 0;
135            ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr;
136        }
137
138    return ret;
139}
140
141
142uLong ZCALLBACK win32_write_file_func (opaque, stream, buf, size)
143   voidpf opaque;
144   voidpf stream;
145   const void* buf;
146   uLong size;
147{
148    uLong ret=0;
149    HANDLE hFile = NULL;
150    if (stream!=NULL)
151        hFile = ((WIN32FILE_IOWIN*)stream) -> hf;
152
153    if (hFile !=NULL)
154        if (!WriteFile(hFile, buf, size, &ret, NULL))
155        {
156            DWORD dwErr = GetLastError();
157            if (dwErr == ERROR_HANDLE_EOF)
158                dwErr = 0;
159            ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr;
160        }
161
162    return ret;
163}
164
165long ZCALLBACK win32_tell_file_func (opaque, stream)
166   voidpf opaque;
167   voidpf stream;
168{
169    long ret=-1;
170    HANDLE hFile = NULL;
171    if (stream!=NULL)
172        hFile = ((WIN32FILE_IOWIN*)stream) -> hf;
173    if (hFile != NULL)
174    {
175        DWORD dwSet = SetFilePointer(hFile, 0, NULL, FILE_CURRENT);
176        if (dwSet == INVALID_SET_FILE_POINTER)
177        {
178            DWORD dwErr = GetLastError();
179            ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr;
180            ret = -1;
181        }
182        else
183            ret=(long)dwSet;
184    }
185    return ret;
186}
187
188long ZCALLBACK win32_seek_file_func (opaque, stream, offset, origin)
189   voidpf opaque;
190   voidpf stream;
191   uLong offset;
192   int origin;
193{
194    DWORD dwMoveMethod=0xFFFFFFFF;
195    HANDLE hFile = NULL;
196
197    long ret=-1;
198    if (stream!=NULL)
199        hFile = ((WIN32FILE_IOWIN*)stream) -> hf;
200    switch (origin)
201    {
202    case ZLIB_FILEFUNC_SEEK_CUR :
203        dwMoveMethod = FILE_CURRENT;
204        break;
205    case ZLIB_FILEFUNC_SEEK_END :
206        dwMoveMethod = FILE_END;
207        break;
208    case ZLIB_FILEFUNC_SEEK_SET :
209        dwMoveMethod = FILE_BEGIN;
210        break;
211    default: return -1;
212    }
213
214    if (hFile != NULL)
215    {
216        DWORD dwSet = SetFilePointer(hFile, offset, NULL, dwMoveMethod);
217        if (dwSet == INVALID_SET_FILE_POINTER)
218        {
219            DWORD dwErr = GetLastError();
220            ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr;
221            ret = -1;
222        }
223        else
224            ret=0;
225    }
226    return ret;
227}
228
229int ZCALLBACK win32_close_file_func (opaque, stream)
230   voidpf opaque;
231   voidpf stream;
232{
233    int ret=-1;
234
235    if (stream!=NULL)
236    {
237        HANDLE hFile;
238        hFile = ((WIN32FILE_IOWIN*)stream) -> hf;
239        if (hFile != NULL)
240        {
241            CloseHandle(hFile);
242            ret=0;
243        }
244        free(stream);
245    }
246    return ret;
247}
248
249int ZCALLBACK win32_error_file_func (opaque, stream)
250   voidpf opaque;
251   voidpf stream;
252{
253    int ret=-1;
254    if (stream!=NULL)
255    {
256        ret = ((WIN32FILE_IOWIN*)stream) -> error;
257    }
258    return ret;
259}
260
261void fill_win32_filefunc (pzlib_filefunc_def)
262  zlib_filefunc_def* pzlib_filefunc_def;
263{
264    pzlib_filefunc_def->zopen_file = win32_open_file_func;
265    pzlib_filefunc_def->zread_file = win32_read_file_func;
266    pzlib_filefunc_def->zwrite_file = win32_write_file_func;
267    pzlib_filefunc_def->ztell_file = win32_tell_file_func;
268    pzlib_filefunc_def->zseek_file = win32_seek_file_func;
269    pzlib_filefunc_def->zclose_file = win32_close_file_func;
270    pzlib_filefunc_def->zerror_file = win32_error_file_func;
271    pzlib_filefunc_def->opaque=NULL;
272}
273