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