fw4spl
iowin32.c
1 /* ***** BEGIN LICENSE BLOCK *****
2  * FW4SPL - Copyright (C) IRCAD, 2009-2015.
3  * Distributed under the terms of the GNU Lesser General Public License (LGPL) as
4  * published by the Free Software Foundation.
5  * ****** END LICENSE BLOCK ****** */
6 
7 /* iowin32.c -- IO base function header for compress/uncompress .zip
8  Version 1.1, February 14h, 2010
9  part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
10 
11  Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
12 
13  Modifications for Zip64 support
14  Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
15 
16  For more info read MiniZip_info.txt
17 
18  */
19 #ifdef _WIN32
20 
21 #include <stdlib.h>
22 
23 #include <zlib.h>
24 #include "minizip/ioapi.h"
25 #include "minizip/iowin32.h"
26 
27 #ifndef INVALID_HANDLE_VALUE
28 #define INVALID_HANDLE_VALUE (0xFFFFFFFF)
29 #endif
30 
31 #ifndef INVALID_SET_FILE_POINTER
32 #define INVALID_SET_FILE_POINTER ((DWORD)-1)
33 #endif
34 
35 voidpf ZCALLBACK win32_open_file_func OF((voidpf opaque, const char* filename, int mode));
36 uLong ZCALLBACK win32_read_file_func OF((voidpf opaque, voidpf stream, void* buf, uLong size));
37 uLong ZCALLBACK win32_write_file_func OF((voidpf opaque, voidpf stream, const void* buf, uLong size));
38 ZPOS64_T ZCALLBACK win32_tell64_file_func OF((voidpf opaque, voidpf stream));
39 long ZCALLBACK win32_seek64_file_func OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int origin));
40 int ZCALLBACK win32_close_file_func OF((voidpf opaque, voidpf stream));
41 int ZCALLBACK win32_error_file_func OF((voidpf opaque, voidpf stream));
42 
43 typedef struct
44 {
45  HANDLE hf;
46  int error;
47 } WIN32FILE_IOWIN;
48 
49 
50 static void win32_translate_open_mode(int mode,
51  DWORD* lpdwDesiredAccess,
52  DWORD* lpdwCreationDisposition,
53  DWORD* lpdwShareMode,
54  DWORD* lpdwFlagsAndAttributes)
55 {
56  *lpdwDesiredAccess = *lpdwShareMode = *lpdwFlagsAndAttributes = *lpdwCreationDisposition = 0;
57 
58  if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ)
59  {
60  *lpdwDesiredAccess = GENERIC_READ;
61  *lpdwCreationDisposition = OPEN_EXISTING;
62  *lpdwShareMode = FILE_SHARE_READ;
63  }
64  else if (mode & ZLIB_FILEFUNC_MODE_EXISTING)
65  {
66  *lpdwDesiredAccess = GENERIC_WRITE | GENERIC_READ;
67  *lpdwCreationDisposition = OPEN_EXISTING;
68  }
69  else if (mode & ZLIB_FILEFUNC_MODE_CREATE)
70  {
71  *lpdwDesiredAccess = GENERIC_WRITE | GENERIC_READ;
72  *lpdwCreationDisposition = CREATE_ALWAYS;
73  }
74 }
75 
76 static voidpf win32_build_iowin(HANDLE hFile)
77 {
78  voidpf ret = NULL;
79 
80  if ((hFile != NULL) && (hFile != INVALID_HANDLE_VALUE))
81  {
82  WIN32FILE_IOWIN w32fiow;
83  w32fiow.hf = hFile;
84  w32fiow.error = 0;
85  ret = malloc(sizeof(WIN32FILE_IOWIN));
86 
87  if (ret==NULL)
88  {
89  CloseHandle(hFile);
90  }
91  else
92  {
93  *((WIN32FILE_IOWIN*)ret) = w32fiow;
94  }
95  }
96  return ret;
97 }
98 
99 voidpf ZCALLBACK win32_open64_file_func (voidpf opaque,const void* filename,int mode)
100 {
101  const char* mode_fopen = NULL;
102  DWORD dwDesiredAccess,dwCreationDisposition,dwShareMode,dwFlagsAndAttributes;
103  HANDLE hFile = NULL;
104 
105  win32_translate_open_mode(mode,&dwDesiredAccess,&dwCreationDisposition,&dwShareMode,&dwFlagsAndAttributes);
106 
107  if ((filename!=NULL) && (dwDesiredAccess != 0))
108  {
109  hFile = CreateFile((LPCTSTR)filename, dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition,
110  dwFlagsAndAttributes, NULL);
111  }
112 
113  return win32_build_iowin(hFile);
114 }
115 
116 
117 voidpf ZCALLBACK win32_open64_file_funcA (voidpf opaque,const void* filename,int mode)
118 {
119  const char* mode_fopen = NULL;
120  DWORD dwDesiredAccess,dwCreationDisposition,dwShareMode,dwFlagsAndAttributes;
121  HANDLE hFile = NULL;
122 
123  win32_translate_open_mode(mode,&dwDesiredAccess,&dwCreationDisposition,&dwShareMode,&dwFlagsAndAttributes);
124 
125  if ((filename!=NULL) && (dwDesiredAccess != 0))
126  {
127  hFile = CreateFileA((LPCSTR)filename, dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition,
128  dwFlagsAndAttributes, NULL);
129  }
130 
131  return win32_build_iowin(hFile);
132 }
133 
134 
135 voidpf ZCALLBACK win32_open64_file_funcW (voidpf opaque,const void* filename,int mode)
136 {
137  const char* mode_fopen = NULL;
138  DWORD dwDesiredAccess,dwCreationDisposition,dwShareMode,dwFlagsAndAttributes;
139  HANDLE hFile = NULL;
140 
141  win32_translate_open_mode(mode,&dwDesiredAccess,&dwCreationDisposition,&dwShareMode,&dwFlagsAndAttributes);
142 
143  if ((filename!=NULL) && (dwDesiredAccess != 0))
144  {
145  hFile = CreateFileW((LPCWSTR)filename, dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition,
146  dwFlagsAndAttributes, NULL);
147  }
148 
149  return win32_build_iowin(hFile);
150 }
151 
152 
153 voidpf ZCALLBACK win32_open_file_func (voidpf opaque,const char* filename,int mode)
154 {
155  const char* mode_fopen = NULL;
156  DWORD dwDesiredAccess,dwCreationDisposition,dwShareMode,dwFlagsAndAttributes;
157  HANDLE hFile = NULL;
158 
159  win32_translate_open_mode(mode,&dwDesiredAccess,&dwCreationDisposition,&dwShareMode,&dwFlagsAndAttributes);
160 
161  if ((filename!=NULL) && (dwDesiredAccess != 0))
162  {
163  hFile = CreateFile((LPCTSTR)filename, dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition,
164  dwFlagsAndAttributes, NULL);
165  }
166 
167  return win32_build_iowin(hFile);
168 }
169 
170 
171 uLong ZCALLBACK win32_read_file_func (voidpf opaque, voidpf stream, void* buf,uLong size)
172 {
173  uLong ret = 0;
174  HANDLE hFile = NULL;
175  if (stream!=NULL)
176  {
177  hFile = ((WIN32FILE_IOWIN*)stream)->hf;
178  }
179 
180  if (hFile != NULL)
181  {
182  if (!ReadFile(hFile, buf, size, &ret, NULL))
183  {
184  DWORD dwErr = GetLastError();
185  if (dwErr == ERROR_HANDLE_EOF)
186  {
187  dwErr = 0;
188  }
189  ((WIN32FILE_IOWIN*)stream)->error = (int)dwErr;
190  }
191  }
192 
193  return ret;
194 }
195 
196 
197 uLong ZCALLBACK win32_write_file_func (voidpf opaque,voidpf stream,const void* buf,uLong size)
198 {
199  uLong ret = 0;
200  HANDLE hFile = NULL;
201  if (stream!=NULL)
202  {
203  hFile = ((WIN32FILE_IOWIN*)stream)->hf;
204  }
205 
206  if (hFile != NULL)
207  {
208  if (!WriteFile(hFile, buf, size, &ret, NULL))
209  {
210  DWORD dwErr = GetLastError();
211  if (dwErr == ERROR_HANDLE_EOF)
212  {
213  dwErr = 0;
214  }
215  ((WIN32FILE_IOWIN*)stream)->error = (int)dwErr;
216  }
217  }
218 
219  return ret;
220 }
221 
222 long ZCALLBACK win32_tell_file_func (voidpf opaque,voidpf stream)
223 {
224  long ret = -1;
225  HANDLE hFile = NULL;
226  if (stream!=NULL)
227  {
228  hFile = ((WIN32FILE_IOWIN*)stream)->hf;
229  }
230  if (hFile != NULL)
231  {
232  DWORD dwSet = SetFilePointer(hFile, 0, NULL, FILE_CURRENT);
233  if (dwSet == INVALID_SET_FILE_POINTER)
234  {
235  DWORD dwErr = GetLastError();
236  ((WIN32FILE_IOWIN*)stream)->error = (int)dwErr;
237  ret = -1;
238  }
239  else
240  {
241  ret = (long)dwSet;
242  }
243  }
244  return ret;
245 }
246 
247 ZPOS64_T ZCALLBACK win32_tell64_file_func (voidpf opaque, voidpf stream)
248 {
249  ZPOS64_T ret = (ZPOS64_T)-1;
250  HANDLE hFile = NULL;
251  if (stream!=NULL)
252  {
253  hFile = ((WIN32FILE_IOWIN*)stream)->hf;
254  }
255 
256  if (hFile)
257  {
258  LARGE_INTEGER li;
259  li.QuadPart = 0;
260  li.u.LowPart = SetFilePointer(hFile, li.u.LowPart, &li.u.HighPart, FILE_CURRENT);
261  if ( (li.LowPart == 0xFFFFFFFF) && (GetLastError() != NO_ERROR))
262  {
263  DWORD dwErr = GetLastError();
264  ((WIN32FILE_IOWIN*)stream)->error = (int)dwErr;
265  ret = (ZPOS64_T)-1;
266  }
267  else
268  {
269  ret = li.QuadPart;
270  }
271  }
272  return ret;
273 }
274 
275 
276 long ZCALLBACK win32_seek_file_func (voidpf opaque,voidpf stream,uLong offset,int origin)
277 {
278  DWORD dwMoveMethod = 0xFFFFFFFF;
279  HANDLE hFile = NULL;
280 
281  long ret = -1;
282  if (stream!=NULL)
283  {
284  hFile = ((WIN32FILE_IOWIN*)stream)->hf;
285  }
286  switch (origin)
287  {
288  case ZLIB_FILEFUNC_SEEK_CUR:
289  dwMoveMethod = FILE_CURRENT;
290  break;
291  case ZLIB_FILEFUNC_SEEK_END:
292  dwMoveMethod = FILE_END;
293  break;
294  case ZLIB_FILEFUNC_SEEK_SET:
295  dwMoveMethod = FILE_BEGIN;
296  break;
297  default: return -1;
298  }
299 
300  if (hFile != NULL)
301  {
302  DWORD dwSet = SetFilePointer(hFile, offset, NULL, dwMoveMethod);
303  if (dwSet == INVALID_SET_FILE_POINTER)
304  {
305  DWORD dwErr = GetLastError();
306  ((WIN32FILE_IOWIN*)stream)->error = (int)dwErr;
307  ret = -1;
308  }
309  else
310  {
311  ret = 0;
312  }
313  }
314  return ret;
315 }
316 
317 long ZCALLBACK win32_seek64_file_func (voidpf opaque, voidpf stream,ZPOS64_T offset,int origin)
318 {
319  DWORD dwMoveMethod = 0xFFFFFFFF;
320  HANDLE hFile = NULL;
321  long ret = -1;
322 
323  if (stream!=NULL)
324  {
325  hFile = ((WIN32FILE_IOWIN*)stream)->hf;
326  }
327 
328  switch (origin)
329  {
330  case ZLIB_FILEFUNC_SEEK_CUR:
331  dwMoveMethod = FILE_CURRENT;
332  break;
333  case ZLIB_FILEFUNC_SEEK_END:
334  dwMoveMethod = FILE_END;
335  break;
336  case ZLIB_FILEFUNC_SEEK_SET:
337  dwMoveMethod = FILE_BEGIN;
338  break;
339  default: return -1;
340  }
341 
342  if (hFile)
343  {
344  LARGE_INTEGER* li = (LARGE_INTEGER*)&offset;
345  DWORD dwSet = SetFilePointer(hFile, li->u.LowPart, &li->u.HighPart, dwMoveMethod);
346  if (dwSet == INVALID_SET_FILE_POINTER)
347  {
348  DWORD dwErr = GetLastError();
349  ((WIN32FILE_IOWIN*)stream)->error = (int)dwErr;
350  ret = -1;
351  }
352  else
353  {
354  ret = 0;
355  }
356  }
357  return ret;
358 }
359 
360 int ZCALLBACK win32_close_file_func (voidpf opaque, voidpf stream)
361 {
362  int ret = -1;
363 
364  if (stream!=NULL)
365  {
366  HANDLE hFile;
367  hFile = ((WIN32FILE_IOWIN*)stream)->hf;
368  if (hFile != NULL)
369  {
370  CloseHandle(hFile);
371  ret = 0;
372  }
373  free(stream);
374  }
375  return ret;
376 }
377 
378 int ZCALLBACK win32_error_file_func (voidpf opaque,voidpf stream)
379 {
380  int ret = -1;
381  if (stream!=NULL)
382  {
383  ret = ((WIN32FILE_IOWIN*)stream)->error;
384  }
385  return ret;
386 }
387 
388 void fill_win32_filefunc (zlib_filefunc_def* pzlib_filefunc_def)
389 {
390  pzlib_filefunc_def->zopen_file = win32_open_file_func;
391  pzlib_filefunc_def->zread_file = win32_read_file_func;
392  pzlib_filefunc_def->zwrite_file = win32_write_file_func;
393  pzlib_filefunc_def->ztell_file = win32_tell_file_func;
394  pzlib_filefunc_def->zseek_file = win32_seek_file_func;
395  pzlib_filefunc_def->zclose_file = win32_close_file_func;
396  pzlib_filefunc_def->zerror_file = win32_error_file_func;
397  pzlib_filefunc_def->opaque = NULL;
398 }
399 
400 void fill_win32_filefunc64(zlib_filefunc64_def* pzlib_filefunc_def)
401 {
402  pzlib_filefunc_def->zopen64_file = win32_open64_file_func;
403  pzlib_filefunc_def->zread_file = win32_read_file_func;
404  pzlib_filefunc_def->zwrite_file = win32_write_file_func;
405  pzlib_filefunc_def->ztell64_file = win32_tell64_file_func;
406  pzlib_filefunc_def->zseek64_file = win32_seek64_file_func;
407  pzlib_filefunc_def->zclose_file = win32_close_file_func;
408  pzlib_filefunc_def->zerror_file = win32_error_file_func;
409  pzlib_filefunc_def->opaque = NULL;
410 }
411 
412 
413 void fill_win32_filefunc64A(zlib_filefunc64_def* pzlib_filefunc_def)
414 {
415  pzlib_filefunc_def->zopen64_file = win32_open64_file_funcA;
416  pzlib_filefunc_def->zread_file = win32_read_file_func;
417  pzlib_filefunc_def->zwrite_file = win32_write_file_func;
418  pzlib_filefunc_def->ztell64_file = win32_tell64_file_func;
419  pzlib_filefunc_def->zseek64_file = win32_seek64_file_func;
420  pzlib_filefunc_def->zclose_file = win32_close_file_func;
421  pzlib_filefunc_def->zerror_file = win32_error_file_func;
422  pzlib_filefunc_def->opaque = NULL;
423 }
424 
425 
426 void fill_win32_filefunc64W(zlib_filefunc64_def* pzlib_filefunc_def)
427 {
428  pzlib_filefunc_def->zopen64_file = win32_open64_file_funcW;
429  pzlib_filefunc_def->zread_file = win32_read_file_func;
430  pzlib_filefunc_def->zwrite_file = win32_write_file_func;
431  pzlib_filefunc_def->ztell64_file = win32_tell64_file_func;
432  pzlib_filefunc_def->zseek64_file = win32_seek64_file_func;
433  pzlib_filefunc_def->zclose_file = win32_close_file_func;
434  pzlib_filefunc_def->zerror_file = win32_error_file_func;
435  pzlib_filefunc_def->opaque = NULL;
436 }
437 
438 #endif // _WIN32