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