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