fw4spl
unzip.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 /* unzip.c -- IO for uncompress .zip files using zlib
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 of Unzip for Zip64
14  Copyright (C) 2007-2008 Even Rouault
15 
16  Modifications for Zip64 support on both zip and unzip
17  Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
18 
19  For more info read MiniZip_info.txt
20 
21 
22  ------------------------------------------------------------------------------------
23  Decryption code comes from crypt.c by Info-ZIP but has been greatly reduced in terms of
24  compatibility with older software. The following is from the original crypt.c.
25  Code woven in by Terry Thorsen 1/2003.
26 
27  Copyright (c) 1990-2000 Info-ZIP. All rights reserved.
28 
29  See the accompanying file LICENSE, version 2000-Apr-09 or later
30  (the contents of which are also included in zip.h) for terms of use.
31  If, for some reason, all these files are missing, the Info-ZIP license
32  also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
33 
34  crypt.c (full version) by Info-ZIP. Last revised: [see crypt.h]
35 
36  The encryption/decryption parts of this source code (as opposed to the
37  non-echoing password parts) were originally written in Europe. The
38  whole source package can be freely distributed, including from the USA.
39  (Prior to January 2000, re-export from the US was a violation of US law.)
40 
41  This encryption code is a direct transcription of the algorithm from
42  Roger Schlafly, described by Phil Katz in the file appnote.txt. This
43  file (appnote.txt) is distributed with the PKZIP program (even in the
44  version without encryption capabilities).
45 
46  ------------------------------------------------------------------------------------
47 
48  Changes in unzip.c
49 
50  2007-2008 - Even Rouault - Addition of cpl_unzGetCurrentFileZStreamPos
51  2007-2008 - Even Rouault - Decoration of symbol names unz* -> cpl_unz*
52  2007-2008 - Even Rouault - Remove old C style function prototypes
53  2007-2008 - Even Rouault - Add unzip support for ZIP64
54 
55  Copyright (C) 2007-2008 Even Rouault
56 
57 
58  Oct-2009 - Mathias Svensson - Removed cpl_* from symbol names (Even Rouault added them but since this is now moved to a new project (minizip64) I renamed them again).
59  Oct-2009 - Mathias Svensson - Fixed problem if uncompressed size was > 4G and compressed size was <4G
60  should only read the compressed/uncompressed size from the Zip64 format if
61  the size from normal header was 0xFFFFFFFF
62  Oct-2009 - Mathias Svensson - Applied some bug fixes from paches recived from Gilles Vollant
63  Oct-2009 - Mathias Svensson - Applied support to unzip files with compression mathod BZIP2 (bzip2 lib is required)
64  Patch created by Daniel Borca
65 
66  Jan-2010 - back to unzip and minizip 1.0 name scheme, with compatibility layer
67 
68  Copyright (C) 1998 - 2010 Gilles Vollant, Even Rouault, Mathias Svensson
69 
70  */
71 
72 
73 #include <stdio.h>
74 #include <stdlib.h>
75 #include <string.h>
76 
77 #ifndef NOUNCRYPT
78  #define NOUNCRYPT
79 #endif
80 
81 #include <zlib.h>
82 #include "minizip/unzip.h"
83 
84 #ifdef STDC
85 # include <stddef.h>
86 # include <string.h>
87 # include <stdlib.h>
88 #endif
89 #ifdef NO_ERRNO_H
90 extern int errno;
91 #else
92 # include <errno.h>
93 #endif
94 
95 
96 #ifndef local
97 # define local static
98 #endif
99 /* compile with -Dlocal if your debugger can't find static symbols */
100 
101 
102 #ifndef CASESENSITIVITYDEFAULT_NO
103 # if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES)
104 # define CASESENSITIVITYDEFAULT_NO
105 # endif
106 #endif
107 
108 
109 #ifndef UNZ_BUFSIZE
110 #define UNZ_BUFSIZE (16384)
111 #endif
112 
113 #ifndef UNZ_MAXFILENAMEINZIP
114 #define UNZ_MAXFILENAMEINZIP (256)
115 #endif
116 
117 #ifndef ALLOC
118 # define ALLOC(size) (malloc(size))
119 #endif
120 #ifndef TRYFREE
121 # define TRYFREE(p) {if (p) {free(p); }}
122 #endif
123 
124 #define SIZECENTRALDIRITEM (0x2e)
125 #define SIZEZIPLOCALHEADER (0x1e)
126 
127 
128 const char unz_copyright[] =
129  " unzip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll";
130 
131 /* unz_file_info_interntal contain internal info about a file in zipfile*/
133 {
134  ZPOS64_T offset_curfile;/* relative offset of local header 8 bytes */
136 
137 
138 /* file_in_zip_read_info_s contain internal information about a file in zipfile,
139  when reading and decompress it */
140 typedef struct
141 {
142  char *read_buffer; /* internal buffer for compressed data */
143  z_stream stream; /* zLib stream structure for inflate */
144 
145 #ifdef HAVE_BZIP2
146  bz_stream bstream; /* bzLib stream structure for bziped */
147 #endif
148 
149  ZPOS64_T pos_in_zipfile; /* position in byte on the zipfile, for fseek*/
150  uLong stream_initialised; /* flag set if stream structure is initialised*/
151 
152  ZPOS64_T offset_local_extrafield;/* offset of the local extra field */
153  uInt size_local_extrafield; /* size of the local extra field */
154  ZPOS64_T pos_local_extrafield; /* position in the local extra field in read*/
155  ZPOS64_T total_out_64;
156 
157  uLong crc32; /* crc32 of all data uncompressed */
158  uLong crc32_wait; /* crc32 we must obtain after decompress all */
159  ZPOS64_T rest_read_compressed; /* number of byte to be decompressed */
160  ZPOS64_T rest_read_uncompressed;/*number of byte to be obtained after decomp*/
161  zlib_filefunc64_32_def z_filefunc;
162  voidpf filestream; /* io structore of the zipfile */
163  uLong compression_method; /* compression method (0==store) */
164  ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
165  int raw;
167 
168 
169 /* unz64_s contain internal information about the zipfile
170  */
171 typedef struct
172 {
173  zlib_filefunc64_32_def z_filefunc;
174  int is64bitOpenFunction;
175  voidpf filestream; /* io structore of the zipfile */
176  unz_global_info64 gi; /* public global information */
177  ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
178  ZPOS64_T num_file; /* number of the current file in the zipfile*/
179  ZPOS64_T pos_in_central_dir; /* pos of the current file in the central dir*/
180  ZPOS64_T current_file_ok; /* flag about the usability of the current file*/
181  ZPOS64_T central_pos; /* position of the beginning of the central dir*/
182 
183  ZPOS64_T size_central_dir; /* size of the central directory */
184  ZPOS64_T offset_central_dir; /* offset of start of central directory with
185  respect to the starting disk number */
186 
187  unz_file_info64 cur_file_info; /* public info about the current file in zip*/
188  unz_file_info64_internal cur_file_info_internal; /* private info about it*/
189  file_in_zip64_read_info_s* pfile_in_zip_read; /* structure about the current
190  file if we are decompressing it */
191  int encrypted;
192 
193  int isZip64;
194 
195 # ifndef NOUNCRYPT
196  unsigned long keys[3]; /* keys defining the pseudo-random sequence */
197  const unsigned long* pcrc_32_tab;
198 # endif
199 } unz64_s;
200 
201 
202 #ifndef NOUNCRYPT
203 #include "minizip/crypt.h"
204 #endif
205 
206 /* ===========================================================================
207  Read a byte from a gz_stream; update next_in and avail_in. Return EOF
208  for end of file.
209  IN assertion: the stream s has been sucessfully opened for reading.
210  */
211 
212 
213 local int unz64local_getByte OF((
214  const zlib_filefunc64_32_def* pzlib_filefunc_def,
215  voidpf filestream,
216  int *pi));
217 
218 local int unz64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, int *pi)
219 {
220  unsigned char c;
221  int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,&c,1);
222  if (err==1)
223  {
224  *pi = (int)c;
225  return UNZ_OK;
226  }
227  else
228  {
229  if (ZERROR64(*pzlib_filefunc_def,filestream))
230  {
231  return UNZ_ERRNO;
232  }
233  else
234  {
235  return UNZ_EOF;
236  }
237  }
238 }
239 
240 
241 /* ===========================================================================
242  Reads a long in LSB order from the given gz_stream. Sets
243  */
244 local int unz64local_getShort OF((
245  const zlib_filefunc64_32_def* pzlib_filefunc_def,
246  voidpf filestream,
247  uLong *pX));
248 
249 local int unz64local_getShort (const zlib_filefunc64_32_def* pzlib_filefunc_def,
250  voidpf filestream,
251  uLong *pX)
252 {
253  uLong x;
254  int i = 0;
255  int err;
256 
257  err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
258  x = (uLong)i;
259 
260  if (err==UNZ_OK)
261  {
262  err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
263  }
264  x |= ((uLong)i)<<8;
265 
266  if (err==UNZ_OK)
267  {
268  *pX = x;
269  }
270  else
271  {
272  *pX = 0;
273  }
274  return err;
275 }
276 
277 local int unz64local_getLong OF((
278  const zlib_filefunc64_32_def* pzlib_filefunc_def,
279  voidpf filestream,
280  uLong *pX));
281 
282 local int unz64local_getLong (const zlib_filefunc64_32_def* pzlib_filefunc_def,
283  voidpf filestream,
284  uLong *pX)
285 {
286  uLong x;
287  int i = 0;
288  int err;
289 
290  err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
291  x = (uLong)i;
292 
293  if (err==UNZ_OK)
294  {
295  err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
296  }
297  x |= ((uLong)i)<<8;
298 
299  if (err==UNZ_OK)
300  {
301  err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
302  }
303  x |= ((uLong)i)<<16;
304 
305  if (err==UNZ_OK)
306  {
307  err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
308  }
309  x += ((uLong)i)<<24;
310 
311  if (err==UNZ_OK)
312  {
313  *pX = x;
314  }
315  else
316  {
317  *pX = 0;
318  }
319  return err;
320 }
321 
322 local int unz64local_getLong64 OF((
323  const zlib_filefunc64_32_def* pzlib_filefunc_def,
324  voidpf filestream,
325  ZPOS64_T *pX));
326 
327 
328 local int unz64local_getLong64 (const zlib_filefunc64_32_def* pzlib_filefunc_def,
329  voidpf filestream,
330  ZPOS64_T *pX)
331 {
332  ZPOS64_T x;
333  int i = 0;
334  int err;
335 
336  err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
337  x = (ZPOS64_T)i;
338 
339  if (err==UNZ_OK)
340  {
341  err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
342  }
343  x |= ((ZPOS64_T)i)<<8;
344 
345  if (err==UNZ_OK)
346  {
347  err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
348  }
349  x |= ((ZPOS64_T)i)<<16;
350 
351  if (err==UNZ_OK)
352  {
353  err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
354  }
355  x |= ((ZPOS64_T)i)<<24;
356 
357  if (err==UNZ_OK)
358  {
359  err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
360  }
361  x |= ((ZPOS64_T)i)<<32;
362 
363  if (err==UNZ_OK)
364  {
365  err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
366  }
367  x |= ((ZPOS64_T)i)<<40;
368 
369  if (err==UNZ_OK)
370  {
371  err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
372  }
373  x |= ((ZPOS64_T)i)<<48;
374 
375  if (err==UNZ_OK)
376  {
377  err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
378  }
379  x |= ((ZPOS64_T)i)<<56;
380 
381  if (err==UNZ_OK)
382  {
383  *pX = x;
384  }
385  else
386  {
387  *pX = 0;
388  }
389  return err;
390 }
391 
392 /* My own strcmpi / strcasecmp */
393 local int strcmpcasenosensitive_internal (const char* fileName1, const char* fileName2)
394 {
395  for (;; )
396  {
397  char c1 = *(fileName1++);
398  char c2 = *(fileName2++);
399  if ((c1>='a') && (c1<='z'))
400  {
401  c1 -= 0x20;
402  }
403  if ((c2>='a') && (c2<='z'))
404  {
405  c2 -= 0x20;
406  }
407  if (c1=='\0')
408  {
409  return ((c2=='\0') ? 0 : -1);
410  }
411  if (c2=='\0')
412  {
413  return 1;
414  }
415  if (c1<c2)
416  {
417  return -1;
418  }
419  if (c1>c2)
420  {
421  return 1;
422  }
423  }
424 }
425 
426 
427 #ifdef CASESENSITIVITYDEFAULT_NO
428 #define CASESENSITIVITYDEFAULTVALUE 2
429 #else
430 #define CASESENSITIVITYDEFAULTVALUE 1
431 #endif
432 
433 #ifndef STRCMPCASENOSENTIVEFUNCTION
434 #define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal
435 #endif
436 
437 /*
438  Compare two filename (fileName1,fileName2).
439  If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
440  If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
441  or strcasecmp)
442  If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
443  (like 1 on Unix, 2 on Windows)
444 
445  */
446 extern MINIZIP_API int unzStringFileNameCompare (const char* fileName1,
447  const char* fileName2,
448  int iCaseSensitivity)
449 
450 {
451  if (iCaseSensitivity==0)
452  {
453  iCaseSensitivity = CASESENSITIVITYDEFAULTVALUE;
454  }
455 
456  if (iCaseSensitivity==1)
457  {
458  return strcmp(fileName1,fileName2);
459  }
460 
461  return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2);
462 }
463 
464 #ifndef BUFREADCOMMENT
465 #define BUFREADCOMMENT (0x400)
466 #endif
467 
468 /*
469  Locate the Central directory of a zipfile (at the end, just before
470  the global comment)
471  */
472 local ZPOS64_T unz64local_SearchCentralDir OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream));
473 local ZPOS64_T unz64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)
474 {
475  unsigned char* buf;
476  ZPOS64_T uSizeFile;
477  ZPOS64_T uBackRead;
478  ZPOS64_T uMaxBack = 0xffff; /* maximum size of global comment */
479  ZPOS64_T uPosFound = 0;
480 
481  if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
482  {
483  return 0;
484  }
485 
486 
487  uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream);
488 
489  if (uMaxBack>uSizeFile)
490  {
491  uMaxBack = uSizeFile;
492  }
493 
494  buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
495  if (buf==NULL)
496  {
497  return 0;
498  }
499 
500  uBackRead = 4;
501  while (uBackRead<uMaxBack)
502  {
503  uLong uReadSize;
504  ZPOS64_T uReadPos;
505  int i;
506  if (uBackRead+BUFREADCOMMENT>uMaxBack)
507  {
508  uBackRead = uMaxBack;
509  }
510  else
511  {
512  uBackRead += BUFREADCOMMENT;
513  }
514  uReadPos = uSizeFile-uBackRead;
515 
516  uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
517  (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos);
518  if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
519  {
520  break;
521  }
522 
523  if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
524  {
525  break;
526  }
527 
528  for (i = (int)uReadSize-3; (i--)>0; )
529  {
530  if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
531  ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
532  {
533  uPosFound = uReadPos+i;
534  break;
535  }
536  }
537 
538  if (uPosFound!=0)
539  {
540  break;
541  }
542  }
543  TRYFREE(buf);
544  return uPosFound;
545 }
546 
547 
548 /*
549  Locate the Central directory 64 of a zipfile (at the end, just before
550  the global comment)
551  */
552 local ZPOS64_T unz64local_SearchCentralDir64 OF((
553  const zlib_filefunc64_32_def* pzlib_filefunc_def,
554  voidpf filestream));
555 
556 local ZPOS64_T unz64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib_filefunc_def,
557  voidpf filestream)
558 {
559  unsigned char* buf;
560  ZPOS64_T uSizeFile;
561  ZPOS64_T uBackRead;
562  ZPOS64_T uMaxBack = 0xffff; /* maximum size of global comment */
563  ZPOS64_T uPosFound = 0;
564  uLong uL;
565  ZPOS64_T relativeOffset;
566 
567  if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
568  {
569  return 0;
570  }
571 
572 
573  uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream);
574 
575  if (uMaxBack>uSizeFile)
576  {
577  uMaxBack = uSizeFile;
578  }
579 
580  buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
581  if (buf==NULL)
582  {
583  return 0;
584  }
585 
586  uBackRead = 4;
587  while (uBackRead<uMaxBack)
588  {
589  uLong uReadSize;
590  ZPOS64_T uReadPos;
591  int i;
592  if (uBackRead+BUFREADCOMMENT>uMaxBack)
593  {
594  uBackRead = uMaxBack;
595  }
596  else
597  {
598  uBackRead += BUFREADCOMMENT;
599  }
600  uReadPos = uSizeFile-uBackRead;
601 
602  uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
603  (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos);
604  if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
605  {
606  break;
607  }
608 
609  if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
610  {
611  break;
612  }
613 
614  for (i = (int)uReadSize-3; (i--)>0; )
615  {
616  if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
617  ((*(buf+i+2))==0x06) && ((*(buf+i+3))==0x07))
618  {
619  uPosFound = uReadPos+i;
620  break;
621  }
622  }
623 
624  if (uPosFound!=0)
625  {
626  break;
627  }
628  }
629  TRYFREE(buf);
630  if (uPosFound == 0)
631  {
632  return 0;
633  }
634 
635  /* Zip64 end of central directory locator */
636  if (ZSEEK64(*pzlib_filefunc_def,filestream, uPosFound,ZLIB_FILEFUNC_SEEK_SET)!=0)
637  {
638  return 0;
639  }
640 
641  /* the signature, already checked */
642  if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
643  {
644  return 0;
645  }
646 
647  /* number of the disk with the start of the zip64 end of central directory */
648  if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
649  {
650  return 0;
651  }
652  if (uL != 0)
653  {
654  return 0;
655  }
656 
657  /* relative offset of the zip64 end of central directory record */
658  if (unz64local_getLong64(pzlib_filefunc_def,filestream,&relativeOffset)!=UNZ_OK)
659  {
660  return 0;
661  }
662 
663  /* total number of disks */
664  if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
665  {
666  return 0;
667  }
668  if (uL != 1)
669  {
670  return 0;
671  }
672 
673  /* Goto end of central directory record */
674  if (ZSEEK64(*pzlib_filefunc_def,filestream, relativeOffset,ZLIB_FILEFUNC_SEEK_SET)!=0)
675  {
676  return 0;
677  }
678 
679  /* the signature */
680  if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
681  {
682  return 0;
683  }
684 
685  if (uL != 0x06064b50)
686  {
687  return 0;
688  }
689 
690  return relativeOffset;
691 }
692 
693 /*
694  Open a Zip file. path contain the full pathname (by example,
695  on a Windows NT computer "c:\\test\\zlib114.zip" or on an Unix computer
696  "zlib/zlib114.zip".
697  If the zipfile cannot be opened (file doesn't exist or in not valid), the
698  return value is NULL.
699  Else, the return value is a unzFile Handle, usable with other function
700  of this unzip package.
701  */
702 local unzFile unzOpenInternal (const void *path,
703  zlib_filefunc64_32_def* pzlib_filefunc64_32_def,
704  int is64bitOpenFunction)
705 {
706  unz64_s us;
707  unz64_s *s;
708  ZPOS64_T central_pos;
709  uLong uL;
710 
711  uLong number_disk; /* number of the current dist, used for
712  spaning ZIP, unsupported, always 0*/
713  uLong number_disk_with_CD; /* number the the disk with central dir, used
714  for spaning ZIP, unsupported, always 0*/
715  ZPOS64_T number_entry_CD; /* total number of entries in
716  the central dir
717  (same than number_entry on nospan) */
718 
719  int err = UNZ_OK;
720 
721  if (unz_copyright[0]!=' ')
722  {
723  return NULL;
724  }
725 
726  us.z_filefunc.zseek32_file = NULL;
727  us.z_filefunc.ztell32_file = NULL;
728  if (pzlib_filefunc64_32_def==NULL)
729  {
730  fill_fopen64_filefunc(&us.z_filefunc.zfile_func64);
731  }
732  else
733  {
734  us.z_filefunc = *pzlib_filefunc64_32_def;
735  }
736  us.is64bitOpenFunction = is64bitOpenFunction;
737 
738 
739 
740  us.filestream = ZOPEN64(us.z_filefunc,
741  path,
742  ZLIB_FILEFUNC_MODE_READ |
743  ZLIB_FILEFUNC_MODE_EXISTING);
744  if (us.filestream==NULL)
745  {
746  return NULL;
747  }
748 
749  central_pos = unz64local_SearchCentralDir64(&us.z_filefunc,us.filestream);
750  if (central_pos)
751  {
752  uLong uS;
753  ZPOS64_T uL64;
754 
755  us.isZip64 = 1;
756 
757  if (ZSEEK64(us.z_filefunc, us.filestream,
758  central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
759  {
760  err = UNZ_ERRNO;
761  }
762 
763  /* the signature, already checked */
764  if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
765  {
766  err = UNZ_ERRNO;
767  }
768 
769  /* size of zip64 end of central directory record */
770  if (unz64local_getLong64(&us.z_filefunc, us.filestream,&uL64)!=UNZ_OK)
771  {
772  err = UNZ_ERRNO;
773  }
774 
775  /* version made by */
776  if (unz64local_getShort(&us.z_filefunc, us.filestream,&uS)!=UNZ_OK)
777  {
778  err = UNZ_ERRNO;
779  }
780 
781  /* version needed to extract */
782  if (unz64local_getShort(&us.z_filefunc, us.filestream,&uS)!=UNZ_OK)
783  {
784  err = UNZ_ERRNO;
785  }
786 
787  /* number of this disk */
788  if (unz64local_getLong(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK)
789  {
790  err = UNZ_ERRNO;
791  }
792 
793  /* number of the disk with the start of the central directory */
794  if (unz64local_getLong(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK)
795  {
796  err = UNZ_ERRNO;
797  }
798 
799  /* total number of entries in the central directory on this disk */
800  if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.gi.number_entry)!=UNZ_OK)
801  {
802  err = UNZ_ERRNO;
803  }
804 
805  /* total number of entries in the central directory */
806  if (unz64local_getLong64(&us.z_filefunc, us.filestream,&number_entry_CD)!=UNZ_OK)
807  {
808  err = UNZ_ERRNO;
809  }
810 
811  if ((number_entry_CD!=us.gi.number_entry) ||
812  (number_disk_with_CD!=0) ||
813  (number_disk!=0))
814  {
815  err = UNZ_BADZIPFILE;
816  }
817 
818  /* size of the central directory */
819  if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.size_central_dir)!=UNZ_OK)
820  {
821  err = UNZ_ERRNO;
822  }
823 
824  /* offset of start of central directory with respect to the
825  starting disk number */
826  if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.offset_central_dir)!=UNZ_OK)
827  {
828  err = UNZ_ERRNO;
829  }
830 
831  us.gi.size_comment = 0;
832  }
833  else
834  {
835  central_pos = unz64local_SearchCentralDir(&us.z_filefunc,us.filestream);
836  if (central_pos==0)
837  {
838  err = UNZ_ERRNO;
839  }
840 
841  us.isZip64 = 0;
842 
843  if (ZSEEK64(us.z_filefunc, us.filestream,
844  central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
845  {
846  err = UNZ_ERRNO;
847  }
848 
849  /* the signature, already checked */
850  if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
851  {
852  err = UNZ_ERRNO;
853  }
854 
855  /* number of this disk */
856  if (unz64local_getShort(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK)
857  {
858  err = UNZ_ERRNO;
859  }
860 
861  /* number of the disk with the start of the central directory */
862  if (unz64local_getShort(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK)
863  {
864  err = UNZ_ERRNO;
865  }
866 
867  /* total number of entries in the central dir on this disk */
868  if (unz64local_getShort(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
869  {
870  err = UNZ_ERRNO;
871  }
872  us.gi.number_entry = uL;
873 
874  /* total number of entries in the central dir */
875  if (unz64local_getShort(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
876  {
877  err = UNZ_ERRNO;
878  }
879  number_entry_CD = uL;
880 
881  if ((number_entry_CD!=us.gi.number_entry) ||
882  (number_disk_with_CD!=0) ||
883  (number_disk!=0))
884  {
885  err = UNZ_BADZIPFILE;
886  }
887 
888  /* size of the central directory */
889  if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
890  {
891  err = UNZ_ERRNO;
892  }
893  us.size_central_dir = uL;
894 
895  /* offset of start of central directory with respect to the
896  starting disk number */
897  if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
898  {
899  err = UNZ_ERRNO;
900  }
901  us.offset_central_dir = uL;
902 
903  /* zipfile comment length */
904  if (unz64local_getShort(&us.z_filefunc, us.filestream,&us.gi.size_comment)!=UNZ_OK)
905  {
906  err = UNZ_ERRNO;
907  }
908  }
909 
910  if ((central_pos<us.offset_central_dir+us.size_central_dir) &&
911  (err==UNZ_OK))
912  {
913  err = UNZ_BADZIPFILE;
914  }
915 
916  if (err!=UNZ_OK)
917  {
918  ZCLOSE64(us.z_filefunc, us.filestream);
919  return NULL;
920  }
921 
922  us.byte_before_the_zipfile = central_pos -
923  (us.offset_central_dir+us.size_central_dir);
924  us.central_pos = central_pos;
925  us.pfile_in_zip_read = NULL;
926  us.encrypted = 0;
927 
928 
929  s = (unz64_s*)ALLOC(sizeof(unz64_s));
930  if( s != NULL)
931  {
932  *s = us;
933  unzGoToFirstFile((unzFile)s);
934  }
935  return (unzFile)s;
936 }
937 
938 
939 extern unzFile MINIZIP_API unzOpen2 (const char *path,
940  zlib_filefunc_def* pzlib_filefunc32_def)
941 {
942  if (pzlib_filefunc32_def != NULL)
943  {
944  zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;
945  fill_zlib_filefunc64_32_def_from_filefunc32(&zlib_filefunc64_32_def_fill,pzlib_filefunc32_def);
946  return unzOpenInternal(path, &zlib_filefunc64_32_def_fill, 0);
947  }
948  else
949  {
950  return unzOpenInternal(path, NULL, 0);
951  }
952 }
953 
954 extern unzFile MINIZIP_API unzOpen2_64 (const void *path,
955  zlib_filefunc64_def* pzlib_filefunc_def)
956 {
957  if (pzlib_filefunc_def != NULL)
958  {
959  zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;
960  zlib_filefunc64_32_def_fill.zfile_func64 = *pzlib_filefunc_def;
961  zlib_filefunc64_32_def_fill.ztell32_file = NULL;
962  zlib_filefunc64_32_def_fill.zseek32_file = NULL;
963  return unzOpenInternal(path, &zlib_filefunc64_32_def_fill, 1);
964  }
965  else
966  {
967  return unzOpenInternal(path, NULL, 1);
968  }
969 }
970 
971 extern unzFile MINIZIP_API unzOpen (const char *path)
972 {
973  return unzOpenInternal(path, NULL, 0);
974 }
975 
976 extern unzFile MINIZIP_API unzOpen64 (const void *path)
977 {
978  return unzOpenInternal(path, NULL, 1);
979 }
980 
981 /*
982  Close a ZipFile opened with unzipOpen.
983  If there is files inside the .Zip opened with unzipOpenCurrentFile (see later),
984  these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
985  return UNZ_OK if there is no problem. */
986 extern MINIZIP_API int unzClose (unzFile file)
987 {
988  unz64_s* s;
989  if (file==NULL)
990  {
991  return UNZ_PARAMERROR;
992  }
993  s = (unz64_s*)file;
994 
995  if (s->pfile_in_zip_read!=NULL)
996  {
997  unzCloseCurrentFile(file);
998  }
999 
1000  ZCLOSE64(s->z_filefunc, s->filestream);
1001  TRYFREE(s);
1002  return UNZ_OK;
1003 }
1004 
1005 
1006 /*
1007  Write info about the ZipFile in the *pglobal_info structure.
1008  No preparation of the structure is needed
1009  return UNZ_OK if there is no problem. */
1010 extern MINIZIP_API int unzGetGlobalInfo64 (unzFile file, unz_global_info64* pglobal_info)
1011 {
1012  unz64_s* s;
1013  if (file==NULL)
1014  {
1015  return UNZ_PARAMERROR;
1016  }
1017  s = (unz64_s*)file;
1018  *pglobal_info = s->gi;
1019  return UNZ_OK;
1020 }
1021 
1022 extern MINIZIP_API int unzGetGlobalInfo (unzFile file, unz_global_info* pglobal_info32)
1023 {
1024  unz64_s* s;
1025  if (file==NULL)
1026  {
1027  return UNZ_PARAMERROR;
1028  }
1029  s = (unz64_s*)file;
1030  /* to do : check if number_entry is not truncated */
1031  pglobal_info32->number_entry = (uLong)s->gi.number_entry;
1032  pglobal_info32->size_comment = s->gi.size_comment;
1033  return UNZ_OK;
1034 }
1035 /*
1036  Translate date/time from Dos format to tm_unz (readable more easilty)
1037  */
1038 local void unz64local_DosDateToTmuDate (ZPOS64_T ulDosDate, tm_unz* ptm)
1039 {
1040  ZPOS64_T uDate;
1041  uDate = (ZPOS64_T)(ulDosDate>>16);
1042  ptm->tm_mday = (uInt)(uDate&0x1f);
1043  ptm->tm_mon = (uInt)((((uDate)&0x1E0)/0x20)-1);
1044  ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980);
1045 
1046  ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800);
1047  ptm->tm_min = (uInt) ((ulDosDate&0x7E0)/0x20);
1048  ptm->tm_sec = (uInt) (2*(ulDosDate&0x1f));
1049 }
1050 
1051 /*
1052  Get Info about the current file in the zipfile, with internal only info
1053  */
1054 local int unz64local_GetCurrentFileInfoInternal OF((unzFile file,
1055  unz_file_info64 *pfile_info,
1057  *pfile_info_internal,
1058  char *szFileName,
1059  uLong fileNameBufferSize,
1060  void *extraField,
1061  uLong extraFieldBufferSize,
1062  char *szComment,
1063  uLong commentBufferSize));
1064 
1065 local int unz64local_GetCurrentFileInfoInternal (unzFile file,
1066  unz_file_info64 *pfile_info,
1068  *pfile_info_internal,
1069  char *szFileName,
1070  uLong fileNameBufferSize,
1071  void *extraField,
1072  uLong extraFieldBufferSize,
1073  char *szComment,
1074  uLong commentBufferSize)
1075 {
1076  unz64_s* s;
1077  unz_file_info64 file_info;
1078  unz_file_info64_internal file_info_internal;
1079  int err = UNZ_OK;
1080  uLong uMagic;
1081  long lSeek = 0;
1082  uLong uL;
1083 
1084  if (file==NULL)
1085  {
1086  return UNZ_PARAMERROR;
1087  }
1088  s = (unz64_s*)file;
1089  if (ZSEEK64(s->z_filefunc, s->filestream,
1090  s->pos_in_central_dir+s->byte_before_the_zipfile,
1091  ZLIB_FILEFUNC_SEEK_SET)!=0)
1092  {
1093  err = UNZ_ERRNO;
1094  }
1095 
1096 
1097  /* we check the magic */
1098  if (err==UNZ_OK)
1099  {
1100  if (unz64local_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)
1101  {
1102  err = UNZ_ERRNO;
1103  }
1104  else if (uMagic!=0x02014b50)
1105  {
1106  err = UNZ_BADZIPFILE;
1107  }
1108  }
1109 
1110  if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.version) != UNZ_OK)
1111  {
1112  err = UNZ_ERRNO;
1113  }
1114 
1115  if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.version_needed) != UNZ_OK)
1116  {
1117  err = UNZ_ERRNO;
1118  }
1119 
1120  if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.flag) != UNZ_OK)
1121  {
1122  err = UNZ_ERRNO;
1123  }
1124 
1125  if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.compression_method) != UNZ_OK)
1126  {
1127  err = UNZ_ERRNO;
1128  }
1129 
1130  if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.dosDate) != UNZ_OK)
1131  {
1132  err = UNZ_ERRNO;
1133  }
1134 
1135  unz64local_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date);
1136 
1137  if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.crc) != UNZ_OK)
1138  {
1139  err = UNZ_ERRNO;
1140  }
1141 
1142  if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
1143  {
1144  err = UNZ_ERRNO;
1145  }
1146  file_info.compressed_size = uL;
1147 
1148  if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
1149  {
1150  err = UNZ_ERRNO;
1151  }
1152  file_info.uncompressed_size = uL;
1153 
1154  if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_filename) != UNZ_OK)
1155  {
1156  err = UNZ_ERRNO;
1157  }
1158 
1159  if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_extra) != UNZ_OK)
1160  {
1161  err = UNZ_ERRNO;
1162  }
1163 
1164  if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_comment) != UNZ_OK)
1165  {
1166  err = UNZ_ERRNO;
1167  }
1168 
1169  if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.disk_num_start) != UNZ_OK)
1170  {
1171  err = UNZ_ERRNO;
1172  }
1173 
1174  if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.internal_fa) != UNZ_OK)
1175  {
1176  err = UNZ_ERRNO;
1177  }
1178 
1179  if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.external_fa) != UNZ_OK)
1180  {
1181  err = UNZ_ERRNO;
1182  }
1183 
1184  // relative offset of local header
1185  if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
1186  {
1187  err = UNZ_ERRNO;
1188  }
1189  file_info_internal.offset_curfile = uL;
1190 
1191  lSeek += file_info.size_filename;
1192  if ((err==UNZ_OK) && (szFileName!=NULL))
1193  {
1194  uLong uSizeRead;
1195  if (file_info.size_filename<fileNameBufferSize)
1196  {
1197  *(szFileName+file_info.size_filename) = '\0';
1198  uSizeRead = file_info.size_filename;
1199  }
1200  else
1201  {
1202  uSizeRead = fileNameBufferSize;
1203  }
1204 
1205  if ((file_info.size_filename>0) && (fileNameBufferSize>0))
1206  {
1207  if (ZREAD64(s->z_filefunc, s->filestream,szFileName,uSizeRead)!=uSizeRead)
1208  {
1209  err = UNZ_ERRNO;
1210  }
1211  }
1212  lSeek -= uSizeRead;
1213  }
1214 
1215  // Read extrafield
1216  if ((err==UNZ_OK) && (extraField!=NULL))
1217  {
1218  ZPOS64_T uSizeRead;
1219  if (file_info.size_file_extra<extraFieldBufferSize)
1220  {
1221  uSizeRead = file_info.size_file_extra;
1222  }
1223  else
1224  {
1225  uSizeRead = extraFieldBufferSize;
1226  }
1227 
1228  if (lSeek!=0)
1229  {
1230  if (ZSEEK64(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
1231  {
1232  lSeek = 0;
1233  }
1234  else
1235  {
1236  err = UNZ_ERRNO;
1237  }
1238  }
1239 
1240  if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0))
1241  {
1242  if (ZREAD64(s->z_filefunc, s->filestream,extraField,(uLong)uSizeRead)!=uSizeRead)
1243  {
1244  err = UNZ_ERRNO;
1245  }
1246  }
1247 
1248  lSeek += file_info.size_file_extra - (uLong)uSizeRead;
1249  }
1250  else
1251  {
1252  lSeek += file_info.size_file_extra;
1253  }
1254 
1255 
1256  if ((err==UNZ_OK) && (file_info.size_file_extra != 0))
1257  {
1258  uLong acc = 0;
1259 
1260  // since lSeek now points to after the extra field we need to move back
1261  lSeek -= file_info.size_file_extra;
1262 
1263  if (lSeek!=0)
1264  {
1265  if (ZSEEK64(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
1266  {
1267  lSeek = 0;
1268  }
1269  else
1270  {
1271  err = UNZ_ERRNO;
1272  }
1273  }
1274 
1275  while(acc < file_info.size_file_extra)
1276  {
1277  uLong headerId;
1278  uLong dataSize;
1279 
1280  if (unz64local_getShort(&s->z_filefunc, s->filestream,&headerId) != UNZ_OK)
1281  {
1282  err = UNZ_ERRNO;
1283  }
1284 
1285  if (unz64local_getShort(&s->z_filefunc, s->filestream,&dataSize) != UNZ_OK)
1286  {
1287  err = UNZ_ERRNO;
1288  }
1289 
1290  /* ZIP64 extra fields */
1291  if (headerId == 0x0001)
1292  {
1293  uLong uL;
1294 
1295  if(file_info.uncompressed_size == (ZPOS64_T)(unsigned long)-1)
1296  {
1297  if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.uncompressed_size) != UNZ_OK)
1298  {
1299  err = UNZ_ERRNO;
1300  }
1301  }
1302 
1303  if(file_info.compressed_size == (ZPOS64_T)(unsigned long)-1)
1304  {
1305  if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.compressed_size) != UNZ_OK)
1306  {
1307  err = UNZ_ERRNO;
1308  }
1309  }
1310 
1311  if(file_info_internal.offset_curfile == (ZPOS64_T)(unsigned long)-1)
1312  {
1313  /* Relative Header offset */
1314  if (unz64local_getLong64(&s->z_filefunc, s->filestream,
1315  &file_info_internal.offset_curfile) != UNZ_OK)
1316  {
1317  err = UNZ_ERRNO;
1318  }
1319  }
1320 
1321  if(file_info.disk_num_start == (unsigned long)-1)
1322  {
1323  /* Disk Start Number */
1324  if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
1325  {
1326  err = UNZ_ERRNO;
1327  }
1328  }
1329 
1330  }
1331  else
1332  {
1333  if (ZSEEK64(s->z_filefunc, s->filestream,dataSize,ZLIB_FILEFUNC_SEEK_CUR)!=0)
1334  {
1335  err = UNZ_ERRNO;
1336  }
1337  }
1338 
1339  acc += 2 + 2 + dataSize;
1340  }
1341  }
1342 
1343  if ((err==UNZ_OK) && (szComment!=NULL))
1344  {
1345  uLong uSizeRead;
1346  if (file_info.size_file_comment<commentBufferSize)
1347  {
1348  *(szComment+file_info.size_file_comment) = '\0';
1349  uSizeRead = file_info.size_file_comment;
1350  }
1351  else
1352  {
1353  uSizeRead = commentBufferSize;
1354  }
1355 
1356  if (lSeek!=0)
1357  {
1358  if (ZSEEK64(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
1359  {
1360  lSeek = 0;
1361  }
1362  else
1363  {
1364  err = UNZ_ERRNO;
1365  }
1366  }
1367 
1368  if ((file_info.size_file_comment>0) && (commentBufferSize>0))
1369  {
1370  if (ZREAD64(s->z_filefunc, s->filestream,szComment,uSizeRead)!=uSizeRead)
1371  {
1372  err = UNZ_ERRNO;
1373  }
1374  }
1375  lSeek += file_info.size_file_comment - uSizeRead;
1376  }
1377  else
1378  {
1379  lSeek += file_info.size_file_comment;
1380  }
1381 
1382 
1383  if ((err==UNZ_OK) && (pfile_info!=NULL))
1384  {
1385  *pfile_info = file_info;
1386  }
1387 
1388  if ((err==UNZ_OK) && (pfile_info_internal!=NULL))
1389  {
1390  *pfile_info_internal = file_info_internal;
1391  }
1392 
1393  return err;
1394 }
1395 
1396 
1397 
1398 /*
1399  Write info about the ZipFile in the *pglobal_info structure.
1400  No preparation of the structure is needed
1401  return UNZ_OK if there is no problem.
1402  */
1403 extern MINIZIP_API int unzGetCurrentFileInfo64 (unzFile file,
1404  unz_file_info64 * pfile_info,
1405  char * szFileName, uLong fileNameBufferSize,
1406  void *extraField, uLong extraFieldBufferSize,
1407  char* szComment, uLong commentBufferSize)
1408 {
1409  return unz64local_GetCurrentFileInfoInternal(file,pfile_info,NULL,
1410  szFileName,fileNameBufferSize,
1411  extraField,extraFieldBufferSize,
1412  szComment,commentBufferSize);
1413 }
1414 
1415 extern MINIZIP_API int unzGetCurrentFileInfo (unzFile file,
1416  unz_file_info * pfile_info,
1417  char * szFileName, uLong fileNameBufferSize,
1418  void *extraField, uLong extraFieldBufferSize,
1419  char* szComment, uLong commentBufferSize)
1420 {
1421  int err;
1422  unz_file_info64 file_info64;
1423  err = unz64local_GetCurrentFileInfoInternal(file,&file_info64,NULL,
1424  szFileName,fileNameBufferSize,
1425  extraField,extraFieldBufferSize,
1426  szComment,commentBufferSize);
1427  if (err==UNZ_OK)
1428  {
1429  pfile_info->version = file_info64.version;
1430  pfile_info->version_needed = file_info64.version_needed;
1431  pfile_info->flag = file_info64.flag;
1432  pfile_info->compression_method = file_info64.compression_method;
1433  pfile_info->dosDate = file_info64.dosDate;
1434  pfile_info->crc = file_info64.crc;
1435 
1436  pfile_info->size_filename = file_info64.size_filename;
1437  pfile_info->size_file_extra = file_info64.size_file_extra;
1438  pfile_info->size_file_comment = file_info64.size_file_comment;
1439 
1440  pfile_info->disk_num_start = file_info64.disk_num_start;
1441  pfile_info->internal_fa = file_info64.internal_fa;
1442  pfile_info->external_fa = file_info64.external_fa;
1443 
1444  pfile_info->tmu_date = file_info64.tmu_date,
1445 
1446 
1447  pfile_info->compressed_size = (uLong)file_info64.compressed_size;
1448  pfile_info->uncompressed_size = (uLong)file_info64.uncompressed_size;
1449 
1450  }
1451  return err;
1452 }
1453 /*
1454  Set the current file of the zipfile to the first file.
1455  return UNZ_OK if there is no problem
1456  */
1457 extern MINIZIP_API int unzGoToFirstFile (unzFile file)
1458 {
1459  int err = UNZ_OK;
1460  unz64_s* s;
1461  if (file==NULL)
1462  {
1463  return UNZ_PARAMERROR;
1464  }
1465  s = (unz64_s*)file;
1466  s->pos_in_central_dir = s->offset_central_dir;
1467  s->num_file = 0;
1468  err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,
1469  &s->cur_file_info_internal,
1470  NULL,0,NULL,0,NULL,0);
1471  s->current_file_ok = (err == UNZ_OK);
1472  return err;
1473 }
1474 
1475 /*
1476  Set the current file of the zipfile to the next file.
1477  return UNZ_OK if there is no problem
1478  return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
1479  */
1480 extern MINIZIP_API int unzGoToNextFile (unzFile file)
1481 {
1482  unz64_s* s;
1483  int err;
1484 
1485  if (file==NULL)
1486  {
1487  return UNZ_PARAMERROR;
1488  }
1489  s = (unz64_s*)file;
1490  if (!s->current_file_ok)
1491  {
1492  return UNZ_END_OF_LIST_OF_FILE;
1493  }
1494  if (s->gi.number_entry != 0xffff) /* 2^16 files overflow hack */
1495  {
1496  if (s->num_file+1==s->gi.number_entry)
1497  {
1498  return UNZ_END_OF_LIST_OF_FILE;
1499  }
1500  }
1501 
1502  s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename +
1503  s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment;
1504  s->num_file++;
1505  err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,
1506  &s->cur_file_info_internal,
1507  NULL,0,NULL,0,NULL,0);
1508  s->current_file_ok = (err == UNZ_OK);
1509  return err;
1510 }
1511 
1512 
1513 /*
1514  Try locate the file szFileName in the zipfile.
1515  For the iCaseSensitivity signification, see unzipStringFileNameCompare
1516 
1517  return value :
1518  UNZ_OK if the file is found. It becomes the current file.
1519  UNZ_END_OF_LIST_OF_FILE if the file is not found
1520  */
1521 extern MINIZIP_API int unzLocateFile (unzFile file, const char *szFileName, int iCaseSensitivity)
1522 {
1523  unz64_s* s;
1524  int err;
1525 
1526  /* We remember the 'current' position in the file so that we can jump
1527  * back there if we fail.
1528  */
1529  unz_file_info64 cur_file_infoSaved;
1530  unz_file_info64_internal cur_file_info_internalSaved;
1531  ZPOS64_T num_fileSaved;
1532  ZPOS64_T pos_in_central_dirSaved;
1533 
1534 
1535  if (file==NULL)
1536  {
1537  return UNZ_PARAMERROR;
1538  }
1539 
1540  if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP)
1541  {
1542  return UNZ_PARAMERROR;
1543  }
1544 
1545  s = (unz64_s*)file;
1546  if (!s->current_file_ok)
1547  {
1548  return UNZ_END_OF_LIST_OF_FILE;
1549  }
1550 
1551  /* Save the current state */
1552  num_fileSaved = s->num_file;
1553  pos_in_central_dirSaved = s->pos_in_central_dir;
1554  cur_file_infoSaved = s->cur_file_info;
1555  cur_file_info_internalSaved = s->cur_file_info_internal;
1556 
1557  err = unzGoToFirstFile(file);
1558 
1559  while (err == UNZ_OK)
1560  {
1561  char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1];
1562  err = unzGetCurrentFileInfo64(file,NULL,
1563  szCurrentFileName,sizeof(szCurrentFileName)-1,
1564  NULL,0,NULL,0);
1565  if (err == UNZ_OK)
1566  {
1567  if (unzStringFileNameCompare(szCurrentFileName,
1568  szFileName,iCaseSensitivity)==0)
1569  {
1570  return UNZ_OK;
1571  }
1572  err = unzGoToNextFile(file);
1573  }
1574  }
1575 
1576  /* We failed, so restore the state of the 'current file' to where we
1577  * were.
1578  */
1579  s->num_file = num_fileSaved;
1580  s->pos_in_central_dir = pos_in_central_dirSaved;
1581  s->cur_file_info = cur_file_infoSaved;
1582  s->cur_file_info_internal = cur_file_info_internalSaved;
1583  return err;
1584 }
1585 
1586 
1587 /*
1589  // Contributed by Ryan Haksi (mailto://cryogen@infoserve.net)
1590  // I need random access
1591  //
1592  // Further optimization could be realized by adding an ability
1593  // to cache the directory in memory. The goal being a single
1594  // comprehensive file read to put the file I need in a memory.
1595  */
1596 
1597 /*
1598  typedef struct unz_file_pos_s
1599  {
1600  ZPOS64_T pos_in_zip_directory; // offset in file
1601  ZPOS64_T num_of_file; // # of file
1602  } unz_file_pos;
1603  */
1604 
1605 extern MINIZIP_API int unzGetFilePos64(unzFile file, unz64_file_pos* file_pos)
1606 {
1607  unz64_s* s;
1608 
1609  if (file==NULL || file_pos==NULL)
1610  {
1611  return UNZ_PARAMERROR;
1612  }
1613  s = (unz64_s*)file;
1614  if (!s->current_file_ok)
1615  {
1616  return UNZ_END_OF_LIST_OF_FILE;
1617  }
1618 
1619  file_pos->pos_in_zip_directory = s->pos_in_central_dir;
1620  file_pos->num_of_file = s->num_file;
1621 
1622  return UNZ_OK;
1623 }
1624 
1625 extern MINIZIP_API int unzGetFilePos(
1626  unzFile file,
1627  unz_file_pos* file_pos)
1628 {
1629  unz64_file_pos file_pos64;
1630  int err = unzGetFilePos64(file,&file_pos64);
1631  if (err==UNZ_OK)
1632  {
1633  file_pos->pos_in_zip_directory = (uLong)file_pos64.pos_in_zip_directory;
1634  file_pos->num_of_file = (uLong)file_pos64.num_of_file;
1635  }
1636  return err;
1637 }
1638 
1639 extern MINIZIP_API int unzGoToFilePos64(unzFile file, const unz64_file_pos* file_pos)
1640 {
1641  unz64_s* s;
1642  int err;
1643 
1644  if (file==NULL || file_pos==NULL)
1645  {
1646  return UNZ_PARAMERROR;
1647  }
1648  s = (unz64_s*)file;
1649 
1650  /* jump to the right spot */
1651  s->pos_in_central_dir = file_pos->pos_in_zip_directory;
1652  s->num_file = file_pos->num_of_file;
1653 
1654  /* set the current file */
1655  err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,
1656  &s->cur_file_info_internal,
1657  NULL,0,NULL,0,NULL,0);
1658  /* return results */
1659  s->current_file_ok = (err == UNZ_OK);
1660  return err;
1661 }
1662 
1663 extern MINIZIP_API int unzGoToFilePos(
1664  unzFile file,
1665  unz_file_pos* file_pos)
1666 {
1667  unz64_file_pos file_pos64;
1668  if (file_pos == NULL)
1669  {
1670  return UNZ_PARAMERROR;
1671  }
1672 
1673  file_pos64.pos_in_zip_directory = file_pos->pos_in_zip_directory;
1674  file_pos64.num_of_file = file_pos->num_of_file;
1675  return unzGoToFilePos64(file,&file_pos64);
1676 }
1677 
1678 /*
1679  // Unzip Helper Functions - should be here?
1681  */
1682 
1683 /*
1684  Read the local header of the current zipfile
1685  Check the coherency of the local header and info in the end of central
1686  directory about this file
1687  store in *piSizeVar the size of extra info in local header
1688  (filename and size of extra field data)
1689  */
1690 local int unz64local_CheckCurrentFileCoherencyHeader (unz64_s* s, uInt* piSizeVar,
1691  ZPOS64_T * poffset_local_extrafield,
1692  uInt * psize_local_extrafield)
1693 {
1694  uLong uMagic,uData,uFlags;
1695  uLong size_filename;
1696  uLong size_extra_field;
1697  int err = UNZ_OK;
1698 
1699  *piSizeVar = 0;
1700  *poffset_local_extrafield = 0;
1701  *psize_local_extrafield = 0;
1702 
1703  if (ZSEEK64(s->z_filefunc, s->filestream,s->cur_file_info_internal.offset_curfile +
1704  s->byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0)
1705  {
1706  return UNZ_ERRNO;
1707  }
1708 
1709 
1710  if (err==UNZ_OK)
1711  {
1712  if (unz64local_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)
1713  {
1714  err = UNZ_ERRNO;
1715  }
1716  else if (uMagic!=0x04034b50)
1717  {
1718  err = UNZ_BADZIPFILE;
1719  }
1720  }
1721 
1722  if (unz64local_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK)
1723  {
1724  err = UNZ_ERRNO;
1725  }
1726 /*
1727  else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion))
1728  err=UNZ_BADZIPFILE;
1729  */
1730  if (unz64local_getShort(&s->z_filefunc, s->filestream,&uFlags) != UNZ_OK)
1731  {
1732  err = UNZ_ERRNO;
1733  }
1734 
1735  if (unz64local_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK)
1736  {
1737  err = UNZ_ERRNO;
1738  }
1739  else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method))
1740  {
1741  err = UNZ_BADZIPFILE;
1742  }
1743 
1744  if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) &&
1745 /* #ifdef HAVE_BZIP2 */
1746  (s->cur_file_info.compression_method!=Z_BZIP2ED) &&
1747 /* #endif */
1748  (s->cur_file_info.compression_method!=Z_DEFLATED))
1749  {
1750  err = UNZ_BADZIPFILE;
1751  }
1752 
1753  if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* date/time */
1754  {
1755  err = UNZ_ERRNO;
1756  }
1757 
1758  if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* crc */
1759  {
1760  err = UNZ_ERRNO;
1761  }
1762  else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) && ((uFlags & 8)==0))
1763  {
1764  err = UNZ_BADZIPFILE;
1765  }
1766 
1767  if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size compr */
1768  {
1769  err = UNZ_ERRNO;
1770  }
1771  else if (uData != 0xFFFFFFFF && (err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) && ((uFlags & 8)==0))
1772  {
1773  err = UNZ_BADZIPFILE;
1774  }
1775 
1776  if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size uncompr */
1777  {
1778  err = UNZ_ERRNO;
1779  }
1780  else if (uData != 0xFFFFFFFF && (err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) && ((uFlags & 8)==0))
1781  {
1782  err = UNZ_BADZIPFILE;
1783  }
1784 
1785  if (unz64local_getShort(&s->z_filefunc, s->filestream,&size_filename) != UNZ_OK)
1786  {
1787  err = UNZ_ERRNO;
1788  }
1789  else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename))
1790  {
1791  err = UNZ_BADZIPFILE;
1792  }
1793 
1794  *piSizeVar += (uInt)size_filename;
1795 
1796  if (unz64local_getShort(&s->z_filefunc, s->filestream,&size_extra_field) != UNZ_OK)
1797  {
1798  err = UNZ_ERRNO;
1799  }
1800  *poffset_local_extrafield = s->cur_file_info_internal.offset_curfile +
1801  SIZEZIPLOCALHEADER + size_filename;
1802  *psize_local_extrafield = (uInt)size_extra_field;
1803 
1804  *piSizeVar += (uInt)size_extra_field;
1805 
1806  return err;
1807 }
1808 
1809 /*
1810  Open for reading data the current file in the zipfile.
1811  If there is no error and the file is opened, the return value is UNZ_OK.
1812  */
1813 extern MINIZIP_API int unzOpenCurrentFile3 (unzFile file, int* method,
1814  int* level, int raw, const char* password)
1815 {
1816  int err = UNZ_OK;
1817  uInt iSizeVar;
1818  unz64_s* s;
1819  file_in_zip64_read_info_s* pfile_in_zip_read_info;
1820  ZPOS64_T offset_local_extrafield; /* offset of the local extra field */
1821  uInt size_local_extrafield; /* size of the local extra field */
1822 # ifndef NOUNCRYPT
1823  char source[12];
1824 # else
1825  if (password != NULL)
1826  {
1827  return UNZ_PARAMERROR;
1828  }
1829 # endif
1830 
1831  if (file==NULL)
1832  {
1833  return UNZ_PARAMERROR;
1834  }
1835  s = (unz64_s*)file;
1836  if (!s->current_file_ok)
1837  {
1838  return UNZ_PARAMERROR;
1839  }
1840 
1841  if (s->pfile_in_zip_read != NULL)
1842  {
1843  unzCloseCurrentFile(file);
1844  }
1845 
1846  if (unz64local_CheckCurrentFileCoherencyHeader(s,&iSizeVar, &offset_local_extrafield,
1847  &size_local_extrafield)!=UNZ_OK)
1848  {
1849  return UNZ_BADZIPFILE;
1850  }
1851 
1852  pfile_in_zip_read_info = (file_in_zip64_read_info_s*)ALLOC(sizeof(file_in_zip64_read_info_s));
1853  if (pfile_in_zip_read_info==NULL)
1854  {
1855  return UNZ_INTERNALERROR;
1856  }
1857 
1858  pfile_in_zip_read_info->read_buffer = (char*)ALLOC(UNZ_BUFSIZE);
1859  pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield;
1860  pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield;
1861  pfile_in_zip_read_info->pos_local_extrafield = 0;
1862  pfile_in_zip_read_info->raw = raw;
1863 
1864  if (pfile_in_zip_read_info->read_buffer==NULL)
1865  {
1866  TRYFREE(pfile_in_zip_read_info);
1867  return UNZ_INTERNALERROR;
1868  }
1869 
1870  pfile_in_zip_read_info->stream_initialised = 0;
1871 
1872  if (method!=NULL)
1873  {
1874  *method = (int)s->cur_file_info.compression_method;
1875  }
1876 
1877  if (level!=NULL)
1878  {
1879  *level = 6;
1880  switch (s->cur_file_info.flag & 0x06)
1881  {
1882  case 6: *level = 1; break;
1883  case 4: *level = 2; break;
1884  case 2: *level = 9; break;
1885  }
1886  }
1887 
1888  if ((s->cur_file_info.compression_method!=0) &&
1889 /* #ifdef HAVE_BZIP2 */
1890  (s->cur_file_info.compression_method!=Z_BZIP2ED) &&
1891 /* #endif */
1892  (s->cur_file_info.compression_method!=Z_DEFLATED))
1893  {
1894 
1895  err = UNZ_BADZIPFILE;
1896  }
1897 
1898  pfile_in_zip_read_info->crc32_wait = s->cur_file_info.crc;
1899  pfile_in_zip_read_info->crc32 = 0;
1900  pfile_in_zip_read_info->total_out_64 = 0;
1901  pfile_in_zip_read_info->compression_method = s->cur_file_info.compression_method;
1902  pfile_in_zip_read_info->filestream = s->filestream;
1903  pfile_in_zip_read_info->z_filefunc = s->z_filefunc;
1904  pfile_in_zip_read_info->byte_before_the_zipfile = s->byte_before_the_zipfile;
1905 
1906  pfile_in_zip_read_info->stream.total_out = 0;
1907 
1908  if ((s->cur_file_info.compression_method==Z_BZIP2ED) && (!raw))
1909  {
1910 #ifdef HAVE_BZIP2
1911  pfile_in_zip_read_info->bstream.bzalloc = (void *(*)(void *, int, int)) 0;
1912  pfile_in_zip_read_info->bstream.bzfree = (free_func)0;
1913  pfile_in_zip_read_info->bstream.opaque = (voidpf)0;
1914  pfile_in_zip_read_info->bstream.state = (voidpf)0;
1915 
1916  pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;
1917  pfile_in_zip_read_info->stream.zfree = (free_func)0;
1918  pfile_in_zip_read_info->stream.opaque = (voidpf)0;
1919  pfile_in_zip_read_info->stream.next_in = (voidpf)0;
1920  pfile_in_zip_read_info->stream.avail_in = 0;
1921 
1922  err = BZ2_bzDecompressInit(&pfile_in_zip_read_info->bstream, 0, 0);
1923  if (err == Z_OK)
1924  {
1925  pfile_in_zip_read_info->stream_initialised = Z_BZIP2ED;
1926  }
1927  else
1928  {
1929  TRYFREE(pfile_in_zip_read_info);
1930  return err;
1931  }
1932 #else
1933  pfile_in_zip_read_info->raw = 1;
1934 #endif
1935  }
1936  else if ((s->cur_file_info.compression_method==Z_DEFLATED) && (!raw))
1937  {
1938  pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;
1939  pfile_in_zip_read_info->stream.zfree = (free_func)0;
1940  pfile_in_zip_read_info->stream.opaque = (voidpf)0;
1941  pfile_in_zip_read_info->stream.next_in = 0;
1942  pfile_in_zip_read_info->stream.avail_in = 0;
1943 
1944  err = inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS);
1945  if (err == Z_OK)
1946  {
1947  pfile_in_zip_read_info->stream_initialised = Z_DEFLATED;
1948  }
1949  else
1950  {
1951  TRYFREE(pfile_in_zip_read_info);
1952  return err;
1953  }
1954  /* windowBits is passed < 0 to tell that there is no zlib header.
1955  * Note that in this case inflate *requires* an extra "dummy" byte
1956  * after the compressed stream in order to complete decompression and
1957  * return Z_STREAM_END.
1958  * In unzip, i don't wait absolutely Z_STREAM_END because I known the
1959  * size of both compressed and uncompressed data
1960  */
1961  }
1962  pfile_in_zip_read_info->rest_read_compressed =
1963  s->cur_file_info.compressed_size;
1964  pfile_in_zip_read_info->rest_read_uncompressed =
1965  s->cur_file_info.uncompressed_size;
1966 
1967 
1968  pfile_in_zip_read_info->pos_in_zipfile =
1969  s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER +
1970  iSizeVar;
1971 
1972  pfile_in_zip_read_info->stream.avail_in = (uInt)0;
1973 
1974  s->pfile_in_zip_read = pfile_in_zip_read_info;
1975  s->encrypted = 0;
1976 
1977 # ifndef NOUNCRYPT
1978  if (password != NULL)
1979  {
1980  int i;
1981  s->pcrc_32_tab = get_crc_table();
1982  init_keys(password,s->keys,s->pcrc_32_tab);
1983  if (ZSEEK64(s->z_filefunc, s->filestream,
1984  s->pfile_in_zip_read->pos_in_zipfile +
1985  s->pfile_in_zip_read->byte_before_the_zipfile,
1986  SEEK_SET)!=0)
1987  {
1988  return UNZ_INTERNALERROR;
1989  }
1990  if(ZREAD64(s->z_filefunc, s->filestream,source, 12)<12)
1991  {
1992  return UNZ_INTERNALERROR;
1993  }
1994 
1995  for (i = 0; i<12; i++)
1996  {
1997  zdecode(s->keys,s->pcrc_32_tab,source[i]);
1998  }
1999 
2000  s->pfile_in_zip_read->pos_in_zipfile += 12;
2001  s->encrypted = 1;
2002  }
2003 # endif
2004 
2005 
2006  return UNZ_OK;
2007 }
2008 
2009 extern MINIZIP_API int unzOpenCurrentFile (unzFile file)
2010 {
2011  return unzOpenCurrentFile3(file, NULL, NULL, 0, NULL);
2012 }
2013 
2014 extern MINIZIP_API int unzOpenCurrentFilePassword (unzFile file, const char* password)
2015 {
2016  return unzOpenCurrentFile3(file, NULL, NULL, 0, password);
2017 }
2018 
2019 extern MINIZIP_API int unzOpenCurrentFile2 (unzFile file, int* method, int* level, int raw)
2020 {
2021  return unzOpenCurrentFile3(file, method, level, raw, NULL);
2022 }
2023 
2026 extern ZPOS64_T MINIZIP_API unzGetCurrentFileZStreamPos64( unzFile file)
2027 {
2028  unz64_s* s;
2029  file_in_zip64_read_info_s* pfile_in_zip_read_info;
2030  s = (unz64_s*)file;
2031  if (file==NULL)
2032  {
2033  return 0; //UNZ_PARAMERROR;
2034  }
2035  pfile_in_zip_read_info = s->pfile_in_zip_read;
2036  if (pfile_in_zip_read_info==NULL)
2037  {
2038  return 0; //UNZ_PARAMERROR;
2039  }
2040  return pfile_in_zip_read_info->pos_in_zipfile +
2041  pfile_in_zip_read_info->byte_before_the_zipfile;
2042 }
2043 
2046 /*
2047  Read bytes from the current file.
2048  buf contain buffer where data must be copied
2049  len the size of buf.
2050 
2051  return the number of byte copied if somes bytes are copied
2052  return 0 if the end of file was reached
2053  return <0 with error code if there is an error
2054  (UNZ_ERRNO for IO error, or zLib error for uncompress error)
2055  */
2056 extern MINIZIP_API int unzReadCurrentFile (unzFile file, voidp buf, unsigned len)
2057 {
2058  int err = UNZ_OK;
2059  uInt iRead = 0;
2060  unz64_s* s;
2061  file_in_zip64_read_info_s* pfile_in_zip_read_info;
2062  if (file==NULL)
2063  {
2064  return UNZ_PARAMERROR;
2065  }
2066  s = (unz64_s*)file;
2067  pfile_in_zip_read_info = s->pfile_in_zip_read;
2068 
2069  if (pfile_in_zip_read_info==NULL)
2070  {
2071  return UNZ_PARAMERROR;
2072  }
2073 
2074 
2075  if ((pfile_in_zip_read_info->read_buffer == NULL))
2076  {
2077  return UNZ_END_OF_LIST_OF_FILE;
2078  }
2079  if (len==0)
2080  {
2081  return 0;
2082  }
2083 
2084  pfile_in_zip_read_info->stream.next_out = (Bytef*)buf;
2085 
2086  pfile_in_zip_read_info->stream.avail_out = (uInt)len;
2087 
2088  if ((len>pfile_in_zip_read_info->rest_read_uncompressed) &&
2089  (!(pfile_in_zip_read_info->raw)))
2090  {
2091  pfile_in_zip_read_info->stream.avail_out =
2092  (uInt)pfile_in_zip_read_info->rest_read_uncompressed;
2093  }
2094 
2095  if ((len>pfile_in_zip_read_info->rest_read_compressed+
2096  pfile_in_zip_read_info->stream.avail_in) &&
2097  (pfile_in_zip_read_info->raw))
2098  {
2099  pfile_in_zip_read_info->stream.avail_out =
2100  (uInt)pfile_in_zip_read_info->rest_read_compressed+
2101  pfile_in_zip_read_info->stream.avail_in;
2102  }
2103 
2104  while (pfile_in_zip_read_info->stream.avail_out>0)
2105  {
2106  if ((pfile_in_zip_read_info->stream.avail_in==0) &&
2107  (pfile_in_zip_read_info->rest_read_compressed>0))
2108  {
2109  uInt uReadThis = UNZ_BUFSIZE;
2110  if (pfile_in_zip_read_info->rest_read_compressed<uReadThis)
2111  {
2112  uReadThis = (uInt)pfile_in_zip_read_info->rest_read_compressed;
2113  }
2114  if (uReadThis == 0)
2115  {
2116  return UNZ_EOF;
2117  }
2118  if (ZSEEK64(pfile_in_zip_read_info->z_filefunc,
2119  pfile_in_zip_read_info->filestream,
2120  pfile_in_zip_read_info->pos_in_zipfile +
2121  pfile_in_zip_read_info->byte_before_the_zipfile,
2122  ZLIB_FILEFUNC_SEEK_SET)!=0)
2123  {
2124  return UNZ_ERRNO;
2125  }
2126  if (ZREAD64(pfile_in_zip_read_info->z_filefunc,
2127  pfile_in_zip_read_info->filestream,
2128  pfile_in_zip_read_info->read_buffer,
2129  uReadThis)!=uReadThis)
2130  {
2131  return UNZ_ERRNO;
2132  }
2133 
2134 
2135 # ifndef NOUNCRYPT
2136  if(s->encrypted)
2137  {
2138  uInt i;
2139  for(i = 0; i<uReadThis; i++)
2140  {
2141  pfile_in_zip_read_info->read_buffer[i] =
2142  zdecode(s->keys,s->pcrc_32_tab,
2143  pfile_in_zip_read_info->read_buffer[i]);
2144  }
2145  }
2146 # endif
2147 
2148 
2149  pfile_in_zip_read_info->pos_in_zipfile += uReadThis;
2150 
2151  pfile_in_zip_read_info->rest_read_compressed -= uReadThis;
2152 
2153  pfile_in_zip_read_info->stream.next_in =
2154  (Bytef*)pfile_in_zip_read_info->read_buffer;
2155  pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis;
2156  }
2157 
2158  if ((pfile_in_zip_read_info->compression_method==0) || (pfile_in_zip_read_info->raw))
2159  {
2160  uInt uDoCopy,i;
2161 
2162  if ((pfile_in_zip_read_info->stream.avail_in == 0) &&
2163  (pfile_in_zip_read_info->rest_read_compressed == 0))
2164  {
2165  return (iRead==0) ? UNZ_EOF : iRead;
2166  }
2167 
2168  if (pfile_in_zip_read_info->stream.avail_out <
2169  pfile_in_zip_read_info->stream.avail_in)
2170  {
2171  uDoCopy = pfile_in_zip_read_info->stream.avail_out;
2172  }
2173  else
2174  {
2175  uDoCopy = pfile_in_zip_read_info->stream.avail_in;
2176  }
2177 
2178  for (i = 0; i<uDoCopy; i++)
2179  {
2180  *(pfile_in_zip_read_info->stream.next_out+i) =
2181  *(pfile_in_zip_read_info->stream.next_in+i);
2182  }
2183 
2184  pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uDoCopy;
2185 
2186  pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,
2187  pfile_in_zip_read_info->stream.next_out,
2188  uDoCopy);
2189  pfile_in_zip_read_info->rest_read_uncompressed -= uDoCopy;
2190  pfile_in_zip_read_info->stream.avail_in -= uDoCopy;
2191  pfile_in_zip_read_info->stream.avail_out -= uDoCopy;
2192  pfile_in_zip_read_info->stream.next_out += uDoCopy;
2193  pfile_in_zip_read_info->stream.next_in += uDoCopy;
2194  pfile_in_zip_read_info->stream.total_out += uDoCopy;
2195  iRead += uDoCopy;
2196  }
2197  else if (pfile_in_zip_read_info->compression_method==Z_BZIP2ED)
2198  {
2199 #ifdef HAVE_BZIP2
2200  uLong uTotalOutBefore,uTotalOutAfter;
2201  const Bytef *bufBefore;
2202  uLong uOutThis;
2203 
2204  pfile_in_zip_read_info->bstream.next_in = (char*)pfile_in_zip_read_info->stream.next_in;
2205  pfile_in_zip_read_info->bstream.avail_in = pfile_in_zip_read_info->stream.avail_in;
2206  pfile_in_zip_read_info->bstream.total_in_lo32 = pfile_in_zip_read_info->stream.total_in;
2207  pfile_in_zip_read_info->bstream.total_in_hi32 = 0;
2208  pfile_in_zip_read_info->bstream.next_out = (char*)pfile_in_zip_read_info->stream.next_out;
2209  pfile_in_zip_read_info->bstream.avail_out = pfile_in_zip_read_info->stream.avail_out;
2210  pfile_in_zip_read_info->bstream.total_out_lo32 = pfile_in_zip_read_info->stream.total_out;
2211  pfile_in_zip_read_info->bstream.total_out_hi32 = 0;
2212 
2213  uTotalOutBefore = pfile_in_zip_read_info->bstream.total_out_lo32;
2214  bufBefore = (const Bytef *)pfile_in_zip_read_info->bstream.next_out;
2215 
2216  err = BZ2_bzDecompress(&pfile_in_zip_read_info->bstream);
2217 
2218  uTotalOutAfter = pfile_in_zip_read_info->bstream.total_out_lo32;
2219  uOutThis = uTotalOutAfter-uTotalOutBefore;
2220 
2221  pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis;
2222 
2223  pfile_in_zip_read_info->crc32 =
2224  crc32(pfile_in_zip_read_info->crc32,bufBefore, (uInt)(uOutThis));
2225  pfile_in_zip_read_info->rest_read_uncompressed -= uOutThis;
2226  iRead += (uInt)(uTotalOutAfter - uTotalOutBefore);
2227 
2228  pfile_in_zip_read_info->stream.next_in = (Bytef*)pfile_in_zip_read_info->bstream.next_in;
2229  pfile_in_zip_read_info->stream.avail_in = pfile_in_zip_read_info->bstream.avail_in;
2230  pfile_in_zip_read_info->stream.total_in = pfile_in_zip_read_info->bstream.total_in_lo32;
2231  pfile_in_zip_read_info->stream.next_out = (Bytef*)pfile_in_zip_read_info->bstream.next_out;
2232  pfile_in_zip_read_info->stream.avail_out = pfile_in_zip_read_info->bstream.avail_out;
2233  pfile_in_zip_read_info->stream.total_out = pfile_in_zip_read_info->bstream.total_out_lo32;
2234 
2235  if (err==BZ_STREAM_END)
2236  {
2237  return (iRead==0) ? UNZ_EOF : iRead;
2238  }
2239  if (err!=BZ_OK)
2240  {
2241  break;
2242  }
2243 #endif
2244  } // end Z_BZIP2ED
2245  else
2246  {
2247  ZPOS64_T uTotalOutBefore,uTotalOutAfter;
2248  const Bytef *bufBefore;
2249  ZPOS64_T uOutThis;
2250  int flush = Z_SYNC_FLUSH;
2251 
2252  uTotalOutBefore = pfile_in_zip_read_info->stream.total_out;
2253  bufBefore = pfile_in_zip_read_info->stream.next_out;
2254 
2255  /*
2256  if ((pfile_in_zip_read_info->rest_read_uncompressed ==
2257  pfile_in_zip_read_info->stream.avail_out) &&
2258  (pfile_in_zip_read_info->rest_read_compressed == 0))
2259  flush = Z_FINISH;
2260  */
2261  err = inflate(&pfile_in_zip_read_info->stream,flush);
2262 
2263  if ((err>=0) && (pfile_in_zip_read_info->stream.msg!=NULL))
2264  {
2265  err = Z_DATA_ERROR;
2266  }
2267 
2268  uTotalOutAfter = pfile_in_zip_read_info->stream.total_out;
2269  uOutThis = uTotalOutAfter-uTotalOutBefore;
2270 
2271  pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis;
2272 
2273  pfile_in_zip_read_info->crc32 =
2274  crc32(pfile_in_zip_read_info->crc32,bufBefore,
2275  (uInt)(uOutThis));
2276 
2277  pfile_in_zip_read_info->rest_read_uncompressed -=
2278  uOutThis;
2279 
2280  iRead += (uInt)(uTotalOutAfter - uTotalOutBefore);
2281 
2282  if (err==Z_STREAM_END)
2283  {
2284  return (iRead==0) ? UNZ_EOF : iRead;
2285  }
2286  if (err!=Z_OK)
2287  {
2288  break;
2289  }
2290  }
2291  }
2292 
2293  if (err==Z_OK)
2294  {
2295  return iRead;
2296  }
2297  return err;
2298 }
2299 
2300 
2301 /*
2302  Give the current position in uncompressed data
2303  */
2304 extern z_off_t MINIZIP_API unztell (unzFile file)
2305 {
2306  unz64_s* s;
2307  file_in_zip64_read_info_s* pfile_in_zip_read_info;
2308  if (file==NULL)
2309  {
2310  return UNZ_PARAMERROR;
2311  }
2312  s = (unz64_s*)file;
2313  pfile_in_zip_read_info = s->pfile_in_zip_read;
2314 
2315  if (pfile_in_zip_read_info==NULL)
2316  {
2317  return UNZ_PARAMERROR;
2318  }
2319 
2320  return (z_off_t)pfile_in_zip_read_info->stream.total_out;
2321 }
2322 
2323 extern ZPOS64_T MINIZIP_API unztell64 (unzFile file)
2324 {
2325 
2326  unz64_s* s;
2327  file_in_zip64_read_info_s* pfile_in_zip_read_info;
2328  if (file==NULL)
2329  {
2330  return (ZPOS64_T)-1;
2331  }
2332  s = (unz64_s*)file;
2333  pfile_in_zip_read_info = s->pfile_in_zip_read;
2334 
2335  if (pfile_in_zip_read_info==NULL)
2336  {
2337  return (ZPOS64_T)-1;
2338  }
2339 
2340  return pfile_in_zip_read_info->total_out_64;
2341 }
2342 
2343 
2344 /*
2345  return 1 if the end of file was reached, 0 elsewhere
2346  */
2347 extern MINIZIP_API int unzeof (unzFile file)
2348 {
2349  unz64_s* s;
2350  file_in_zip64_read_info_s* pfile_in_zip_read_info;
2351  if (file==NULL)
2352  {
2353  return UNZ_PARAMERROR;
2354  }
2355  s = (unz64_s*)file;
2356  pfile_in_zip_read_info = s->pfile_in_zip_read;
2357 
2358  if (pfile_in_zip_read_info==NULL)
2359  {
2360  return UNZ_PARAMERROR;
2361  }
2362 
2363  if (pfile_in_zip_read_info->rest_read_uncompressed == 0)
2364  {
2365  return 1;
2366  }
2367  else
2368  {
2369  return 0;
2370  }
2371 }
2372 
2373 
2374 
2375 /*
2376  Read extra field from the current file (opened by unzOpenCurrentFile)
2377  This is the local-header version of the extra field (sometimes, there is
2378  more info in the local-header version than in the central-header)
2379 
2380  if buf==NULL, it return the size of the local extra field that can be read
2381 
2382  if buf!=NULL, len is the size of the buffer, the extra header is copied in
2383  buf.
2384  the return value is the number of bytes copied in buf, or (if <0)
2385  the error code
2386  */
2387 extern MINIZIP_API int unzGetLocalExtrafield (unzFile file, voidp buf, unsigned len)
2388 {
2389  unz64_s* s;
2390  file_in_zip64_read_info_s* pfile_in_zip_read_info;
2391  uInt read_now;
2392  ZPOS64_T size_to_read;
2393 
2394  if (file==NULL)
2395  {
2396  return UNZ_PARAMERROR;
2397  }
2398  s = (unz64_s*)file;
2399  pfile_in_zip_read_info = s->pfile_in_zip_read;
2400 
2401  if (pfile_in_zip_read_info==NULL)
2402  {
2403  return UNZ_PARAMERROR;
2404  }
2405 
2406  size_to_read = (pfile_in_zip_read_info->size_local_extrafield -
2407  pfile_in_zip_read_info->pos_local_extrafield);
2408 
2409  if (buf==NULL)
2410  {
2411  return (int)size_to_read;
2412  }
2413 
2414  if (len>size_to_read)
2415  {
2416  read_now = (uInt)size_to_read;
2417  }
2418  else
2419  {
2420  read_now = (uInt)len;
2421  }
2422 
2423  if (read_now==0)
2424  {
2425  return 0;
2426  }
2427 
2428  if (ZSEEK64(pfile_in_zip_read_info->z_filefunc,
2429  pfile_in_zip_read_info->filestream,
2430  pfile_in_zip_read_info->offset_local_extrafield +
2431  pfile_in_zip_read_info->pos_local_extrafield,
2432  ZLIB_FILEFUNC_SEEK_SET)!=0)
2433  {
2434  return UNZ_ERRNO;
2435  }
2436 
2437  if (ZREAD64(pfile_in_zip_read_info->z_filefunc,
2438  pfile_in_zip_read_info->filestream,
2439  buf,read_now)!=read_now)
2440  {
2441  return UNZ_ERRNO;
2442  }
2443 
2444  return (int)read_now;
2445 }
2446 
2447 /*
2448  Close the file in zip opened with unzipOpenCurrentFile
2449  Return UNZ_CRCERROR if all the file was read but the CRC is not good
2450  */
2451 extern MINIZIP_API int unzCloseCurrentFile (unzFile file)
2452 {
2453  int err = UNZ_OK;
2454 
2455  unz64_s* s;
2456  file_in_zip64_read_info_s* pfile_in_zip_read_info;
2457  if (file==NULL)
2458  {
2459  return UNZ_PARAMERROR;
2460  }
2461  s = (unz64_s*)file;
2462  pfile_in_zip_read_info = s->pfile_in_zip_read;
2463 
2464  if (pfile_in_zip_read_info==NULL)
2465  {
2466  return UNZ_PARAMERROR;
2467  }
2468 
2469 
2470  if ((pfile_in_zip_read_info->rest_read_uncompressed == 0) &&
2471  (!pfile_in_zip_read_info->raw))
2472  {
2473  if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait)
2474  {
2475  err = UNZ_CRCERROR;
2476  }
2477  }
2478 
2479 
2480  TRYFREE(pfile_in_zip_read_info->read_buffer);
2481  pfile_in_zip_read_info->read_buffer = NULL;
2482  if (pfile_in_zip_read_info->stream_initialised == Z_DEFLATED)
2483  {
2484  inflateEnd(&pfile_in_zip_read_info->stream);
2485  }
2486 #ifdef HAVE_BZIP2
2487  else if (pfile_in_zip_read_info->stream_initialised == Z_BZIP2ED)
2488  {
2489  BZ2_bzDecompressEnd(&pfile_in_zip_read_info->bstream);
2490  }
2491 #endif
2492 
2493 
2494  pfile_in_zip_read_info->stream_initialised = 0;
2495  TRYFREE(pfile_in_zip_read_info);
2496 
2497  s->pfile_in_zip_read = NULL;
2498 
2499  return err;
2500 }
2501 
2502 
2503 /*
2504  Get the global comment string of the ZipFile, in the szComment buffer.
2505  uSizeBuf is the size of the szComment buffer.
2506  return the number of byte copied or an error code <0
2507  */
2508 extern MINIZIP_API int unzGetGlobalComment (unzFile file, char * szComment, uLong uSizeBuf)
2509 {
2510  unz64_s* s;
2511  uLong uReadThis;
2512  if (file==NULL)
2513  {
2514  return (int)UNZ_PARAMERROR;
2515  }
2516  s = (unz64_s*)file;
2517 
2518  uReadThis = uSizeBuf;
2519  if (uReadThis>s->gi.size_comment)
2520  {
2521  uReadThis = s->gi.size_comment;
2522  }
2523 
2524  if (ZSEEK64(s->z_filefunc,s->filestream,s->central_pos+22,ZLIB_FILEFUNC_SEEK_SET)!=0)
2525  {
2526  return UNZ_ERRNO;
2527  }
2528 
2529  if (uReadThis>0)
2530  {
2531  *szComment = '\0';
2532  if (ZREAD64(s->z_filefunc,s->filestream,szComment,uReadThis)!=uReadThis)
2533  {
2534  return UNZ_ERRNO;
2535  }
2536  }
2537 
2538  if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment))
2539  {
2540  *(szComment+s->gi.size_comment) = '\0';
2541  }
2542  return (int)uReadThis;
2543 }
2544 
2545 /* Additions by RX '2004 */
2546 extern ZPOS64_T MINIZIP_API unzGetOffset64(unzFile file)
2547 {
2548  unz64_s* s;
2549 
2550  if (file==NULL)
2551  {
2552  return 0; //UNZ_PARAMERROR;
2553  }
2554  s = (unz64_s*)file;
2555  if (!s->current_file_ok)
2556  {
2557  return 0;
2558  }
2559  if (s->gi.number_entry != 0 && s->gi.number_entry != 0xffff)
2560  {
2561  if (s->num_file==s->gi.number_entry)
2562  {
2563  return 0;
2564  }
2565  }
2566  return s->pos_in_central_dir;
2567 }
2568 
2569 extern uLong MINIZIP_API unzGetOffset (unzFile file)
2570 {
2571  ZPOS64_T offset64;
2572 
2573  if (file==NULL)
2574  {
2575  return 0; //UNZ_PARAMERROR;
2576  }
2577  offset64 = unzGetOffset64(file);
2578  return (uLong)offset64;
2579 }
2580 
2581 extern MINIZIP_API int unzSetOffset64(unzFile file, ZPOS64_T pos)
2582 {
2583  unz64_s* s;
2584  int err;
2585 
2586  if (file==NULL)
2587  {
2588  return UNZ_PARAMERROR;
2589  }
2590  s = (unz64_s*)file;
2591 
2592  s->pos_in_central_dir = pos;
2593  s->num_file = s->gi.number_entry; /* hack */
2594  err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,
2595  &s->cur_file_info_internal,
2596  NULL,0,NULL,0,NULL,0);
2597  s->current_file_ok = (err == UNZ_OK);
2598  return err;
2599 }
2600 
2601 extern MINIZIP_API int unzSetOffset (unzFile file, uLong pos)
2602 {
2603  return unzSetOffset64(file,pos);
2604 }
Definition: unzip.h:92
Definition: unzip.c:171