1 /* iowin32.c -- IO base function header for compress/uncompress .zip
2    files using zlib + zip or unzip API
3    This IO API version uses the Win32 API (for Microsoft Windows)
4 
5    Version 1.01e, February 12th, 2005
6 
7    Copyright (C) 1998-2005 Gilles Vollant
8 */
9 
10 #if defined(_WIN32)
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 
26 voidpf ZCALLBACK win32_open_file_func OF((
27    voidpf opaque,
28    const char* filename,
29    int mode));
30 
31 uLong ZCALLBACK win32_read_file_func OF((
32    voidpf opaque,
33    voidpf stream,
34    void* buf,
35    uLong size));
36 
37 uLong ZCALLBACK win32_write_file_func OF((
38    voidpf opaque,
39    voidpf stream,
40    const void* buf,
41    uLong size));
42 
43 long ZCALLBACK win32_tell_file_func OF((
44    voidpf opaque,
45    voidpf stream));
46 
47 long ZCALLBACK win32_seek_file_func OF((
48    voidpf opaque,
49    voidpf stream,
50    uLong offset,
51    int origin));
52 
53 int ZCALLBACK win32_close_file_func OF((
54    voidpf opaque,
55    voidpf stream));
56 
57 int ZCALLBACK win32_error_file_func OF((
58    voidpf opaque,
59    voidpf stream));
60 
61 typedef struct
62 {
63     HANDLE hf;
64     int error;
65 } WIN32FILE_IOWIN;
66 
win32_open_file_func(opaque,filename,mode)67 voidpf 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 
win32_read_file_func(opaque,stream,buf,size)119 uLong 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 
win32_write_file_func(opaque,stream,buf,size)142 uLong 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 
win32_tell_file_func(opaque,stream)165 long 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 
win32_seek_file_func(opaque,stream,offset,origin)188 long 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 
win32_close_file_func(opaque,stream)229 int 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 
win32_error_file_func(opaque,stream)249 int 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 
fill_win32_filefunc(pzlib_filefunc_def)261 void 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 
274 #endif
275