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 )
5
Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
7
Modifications of Unzip for Zip64
8
Copyright (C) 2007-2008 Even Rouault
10
Modifications for Zip64 support on both zip and unzip
11
Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
13
For more info read MiniZip_info.txt
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.
21
Copyright (c) 1990-2000 Info-ZIP. All rights reserved.
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
28
crypt.c (full version) by Info-ZIP. Last revised: [see crypt.h]
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.)
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).
40
------------------------------------------------------------------------------------
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
49
Copyright (C) 2007-2008 Even Rouault
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
60
Jan-2010 - back to unzip and minizip 1.0 name scheme, with compatibility layer
62
Copyright (C) 1998 - 2010 Gilles Vollant, Even Rouault, Mathias Svensson
93
/* compile with -Dlocal if your debugger can't find static symbols */
96
#ifndef CASESENSITIVITYDEFAULT_NO
97
# if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES)
98
# define CASESENSITIVITYDEFAULT_NO
104
#define UNZ_BUFSIZE (16384)
107
#ifndef UNZ_MAXFILENAMEINZIP
108
#define UNZ_MAXFILENAMEINZIP (256)
112
# define ALLOC(size) (malloc(size))
115
# define TRYFREE(p) {if (p) free(p);}
118
#define SIZECENTRALDIRITEM (0x2e)
119
#define SIZEZIPLOCALHEADER (0x1e)
122
const char unz_copyright[] =
123
" unzip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll";
125
/* unz_file_info_interntal contain internal info about a file in zipfile*/
126
typedef struct unz_file_info64_internal_s
128
ZPOS64_T offset_curfile;/* relative offset of local header 8 bytes */
129
} unz_file_info64_internal;
132
/* file_in_zip_read_info_s contain internal information about a file in zipfile,
133
when reading and decompress it */
136
char *read_buffer; /* internal buffer for compressed data */
137
z_stream stream; /* zLib stream structure for inflate */
140
bz_stream bstream; /* bzLib stream structure for bziped */
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*/
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;
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)*/
160
} file_in_zip64_read_info_s;
163
/* unz64_s contain internal information about the zipfile
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*/
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 */
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 */
190
unsigned long keys[3]; /* keys defining the pseudo-random sequence */
191
const unsigned long* pcrc_32_tab;
200
/* ===========================================================================
201
Read a byte from a gz_stream; update next_in and avail_in. Return EOF
203
IN assertion: the stream s has been sucessfully opened for reading.
207
local int unz64local_getByte OF((
208
const zlib_filefunc64_32_def* pzlib_filefunc_def,
212
local int unz64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, int *pi)
215
int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,&c,1);
223
if (ZERROR64(*pzlib_filefunc_def,filestream))
231
/* ===========================================================================
232
Reads a long in LSB order from the given gz_stream. Sets
234
local int unz64local_getShort OF((
235
const zlib_filefunc64_32_def* pzlib_filefunc_def,
239
local int unz64local_getShort (const zlib_filefunc64_32_def* pzlib_filefunc_def,
247
err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
251
err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
261
local int unz64local_getLong OF((
262
const zlib_filefunc64_32_def* pzlib_filefunc_def,
266
local int unz64local_getLong (const zlib_filefunc64_32_def* pzlib_filefunc_def,
274
err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
278
err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
282
err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
286
err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
296
local int unz64local_getLong64 OF((
297
const zlib_filefunc64_32_def* pzlib_filefunc_def,
302
local int unz64local_getLong64 (const zlib_filefunc64_32_def* pzlib_filefunc_def,
310
err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
314
err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
315
x |= ((ZPOS64_T)i)<<8;
318
err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
319
x |= ((ZPOS64_T)i)<<16;
322
err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
323
x |= ((ZPOS64_T)i)<<24;
326
err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
327
x |= ((ZPOS64_T)i)<<32;
330
err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
331
x |= ((ZPOS64_T)i)<<40;
334
err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
335
x |= ((ZPOS64_T)i)<<48;
338
err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
339
x |= ((ZPOS64_T)i)<<56;
348
/* My own strcmpi / strcasecmp */
349
local int strcmpcasenosensitive_internal (const char* fileName1, const char* fileName2)
353
char c1=*(fileName1++);
354
char c2=*(fileName2++);
355
if ((c1>='a') && (c1<='z'))
357
if ((c2>='a') && (c2<='z'))
360
return ((c2=='\0') ? 0 : -1);
371
#ifdef CASESENSITIVITYDEFAULT_NO
372
#define CASESENSITIVITYDEFAULTVALUE 2
374
#define CASESENSITIVITYDEFAULTVALUE 1
377
#ifndef STRCMPCASENOSENTIVEFUNCTION
378
#define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal
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
386
If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
387
(like 1 on Unix, 2 on Windows)
390
extern int ZEXPORT unzStringFileNameCompare (const char* fileName1,
391
const char* fileName2,
392
int iCaseSensitivity)
395
if (iCaseSensitivity==0)
396
iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE;
398
if (iCaseSensitivity==1)
399
return strcmp(fileName1,fileName2);
401
return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2);
404
#ifndef BUFREADCOMMENT
405
#define BUFREADCOMMENT (0x400)
409
Locate the Central directory of a zipfile (at the end, just before
412
local ZPOS64_T unz64local_SearchCentralDir OF((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)
418
ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */
419
ZPOS64_T uPosFound=0;
421
if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
425
uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream);
427
if (uMaxBack>uSizeFile)
428
uMaxBack = uSizeFile;
430
buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
435
while (uBackRead<uMaxBack)
440
if (uBackRead+BUFREADCOMMENT>uMaxBack)
441
uBackRead = uMaxBack;
443
uBackRead+=BUFREADCOMMENT;
444
uReadPos = uSizeFile-uBackRead ;
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)
451
if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
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))
458
uPosFound = uReadPos+i;
471
Locate the Central directory 64 of a zipfile (at the end, just before
474
local ZPOS64_T unz64local_SearchCentralDir64 OF((
475
const zlib_filefunc64_32_def* pzlib_filefunc_def,
478
local ZPOS64_T unz64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib_filefunc_def,
484
ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */
485
ZPOS64_T uPosFound=0;
487
ZPOS64_T relativeOffset;
489
if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
493
uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream);
495
if (uMaxBack>uSizeFile)
496
uMaxBack = uSizeFile;
498
buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
503
while (uBackRead<uMaxBack)
508
if (uBackRead+BUFREADCOMMENT>uMaxBack)
509
uBackRead = uMaxBack;
511
uBackRead+=BUFREADCOMMENT;
512
uReadPos = uSizeFile-uBackRead ;
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)
519
if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
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))
526
uPosFound = uReadPos+i;
537
/* Zip64 end of central directory locator */
538
if (ZSEEK64(*pzlib_filefunc_def,filestream, uPosFound,ZLIB_FILEFUNC_SEEK_SET)!=0)
541
/* the signature, already checked */
542
if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
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)
551
/* relative offset of the zip64 end of central directory record */
552
if (unz64local_getLong64(pzlib_filefunc_def,filestream,&relativeOffset)!=UNZ_OK)
555
/* total number of disks */
556
if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
561
/* Goto end of central directory record */
562
if (ZSEEK64(*pzlib_filefunc_def,filestream, relativeOffset,ZLIB_FILEFUNC_SEEK_SET)!=0)
566
if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
569
if (uL != 0x06064b50)
572
return relativeOffset;
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
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.
584
local unzFile unzOpenInternal (const void *path,
585
zlib_filefunc64_32_def* pzlib_filefunc64_32_def,
586
int is64bitOpenFunction)
590
ZPOS64_T central_pos;
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
599
(same than number_entry on nospan) */
603
if (unz_copyright[0]!=' ')
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);
611
us.z_filefunc = *pzlib_filefunc64_32_def;
612
us.is64bitOpenFunction = is64bitOpenFunction;
616
us.filestream = ZOPEN64(us.z_filefunc,
618
ZLIB_FILEFUNC_MODE_READ |
619
ZLIB_FILEFUNC_MODE_EXISTING);
620
if (us.filestream==NULL)
623
central_pos = unz64local_SearchCentralDir64(&us.z_filefunc,us.filestream);
631
if (ZSEEK64(us.z_filefunc, us.filestream,
632
central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
635
/* the signature, already checked */
636
if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
639
/* size of zip64 end of central directory record */
640
if (unz64local_getLong64(&us.z_filefunc, us.filestream,&uL64)!=UNZ_OK)
643
/* version made by */
644
if (unz64local_getShort(&us.z_filefunc, us.filestream,&uS)!=UNZ_OK)
647
/* version needed to extract */
648
if (unz64local_getShort(&us.z_filefunc, us.filestream,&uS)!=UNZ_OK)
651
/* number of this disk */
652
if (unz64local_getLong(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK)
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)
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)
663
/* total number of entries in the central directory */
664
if (unz64local_getLong64(&us.z_filefunc, us.filestream,&number_entry_CD)!=UNZ_OK)
667
if ((number_entry_CD!=us.gi.number_entry) ||
668
(number_disk_with_CD!=0) ||
672
/* size of the central directory */
673
if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.size_central_dir)!=UNZ_OK)
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)
681
us.gi.size_comment = 0;
685
central_pos = unz64local_SearchCentralDir(&us.z_filefunc,us.filestream);
691
if (ZSEEK64(us.z_filefunc, us.filestream,
692
central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
695
/* the signature, already checked */
696
if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
699
/* number of this disk */
700
if (unz64local_getShort(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK)
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)
707
/* total number of entries in the central dir on this disk */
708
if (unz64local_getShort(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
710
us.gi.number_entry = uL;
712
/* total number of entries in the central dir */
713
if (unz64local_getShort(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
715
number_entry_CD = uL;
717
if ((number_entry_CD!=us.gi.number_entry) ||
718
(number_disk_with_CD!=0) ||
722
/* size of the central directory */
723
if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
725
us.size_central_dir = uL;
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)
731
us.offset_central_dir = uL;
733
/* zipfile comment length */
734
if (unz64local_getShort(&us.z_filefunc, us.filestream,&us.gi.size_comment)!=UNZ_OK)
738
if ((central_pos<us.offset_central_dir+us.size_central_dir) &&
744
ZCLOSE64(us.z_filefunc, us.filestream);
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;
755
s=(unz64_s*)ALLOC(sizeof(unz64_s));
759
unzGoToFirstFile((unzFile)s);
765
extern unzFile ZEXPORT unzOpen2 (const char *path,
766
zlib_filefunc_def* pzlib_filefunc32_def)
768
if (pzlib_filefunc32_def != NULL)
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);
775
return unzOpenInternal(path, NULL, 0);
778
extern unzFile ZEXPORT unzOpen2_64 (const void *path,
779
zlib_filefunc64_def* pzlib_filefunc_def)
781
if (pzlib_filefunc_def != NULL)
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);
790
return unzOpenInternal(path, NULL, 1);
793
extern unzFile ZEXPORT unzOpen (const char *path)
795
return unzOpenInternal(path, NULL, 0);
798
extern unzFile ZEXPORT unzOpen64 (const void *path)
800
return unzOpenInternal(path, NULL, 1);
804
Close a ZipFile opened with unzipOpen.
805
If there is files inside the .Zip opened with unzipOpenCurrentFile (see later),
806
these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
807
return UNZ_OK if there is no problem. */
808
extern int ZEXPORT unzClose (unzFile file)
812
return UNZ_PARAMERROR;
815
if (s->pfile_in_zip_read!=NULL)
816
unzCloseCurrentFile(file);
818
ZCLOSE64(s->z_filefunc, s->filestream);
825
Write info about the ZipFile in the *pglobal_info structure.
826
No preparation of the structure is needed
827
return UNZ_OK if there is no problem. */
828
extern int ZEXPORT unzGetGlobalInfo64 (unzFile file, unz_global_info64* pglobal_info)
832
return UNZ_PARAMERROR;
838
extern int ZEXPORT unzGetGlobalInfo (unzFile file, unz_global_info* pglobal_info32)
842
return UNZ_PARAMERROR;
844
/* to do : check if number_entry is not truncated */
845
pglobal_info32->number_entry = (uLong)s->gi.number_entry;
846
pglobal_info32->size_comment = s->gi.size_comment;
850
Translate date/time from Dos format to tm_unz (readable more easilty)
852
local void unz64local_DosDateToTmuDate (ZPOS64_T ulDosDate, tm_unz* ptm)
855
uDate = (ZPOS64_T)(ulDosDate>>16);
856
ptm->tm_mday = (uInt)(uDate&0x1f) ;
857
ptm->tm_mon = (uInt)((((uDate)&0x1E0)/0x20)-1) ;
858
ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ;
860
ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800);
861
ptm->tm_min = (uInt) ((ulDosDate&0x7E0)/0x20) ;
862
ptm->tm_sec = (uInt) (2*(ulDosDate&0x1f)) ;
866
Get Info about the current file in the zipfile, with internal only info
868
local int unz64local_GetCurrentFileInfoInternal OF((unzFile file,
869
unz_file_info64 *pfile_info,
870
unz_file_info64_internal
871
*pfile_info_internal,
873
uLong fileNameBufferSize,
875
uLong extraFieldBufferSize,
877
uLong commentBufferSize));
879
local int unz64local_GetCurrentFileInfoInternal (unzFile file,
880
unz_file_info64 *pfile_info,
881
unz_file_info64_internal
882
*pfile_info_internal,
884
uLong fileNameBufferSize,
886
uLong extraFieldBufferSize,
888
uLong commentBufferSize)
891
unz_file_info64 file_info;
892
unz_file_info64_internal file_info_internal;
899
return UNZ_PARAMERROR;
901
if (ZSEEK64(s->z_filefunc, s->filestream,
902
s->pos_in_central_dir+s->byte_before_the_zipfile,
903
ZLIB_FILEFUNC_SEEK_SET)!=0)
907
/* we check the magic */
910
if (unz64local_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)
912
else if (uMagic!=0x02014b50)
916
if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.version) != UNZ_OK)
919
if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.version_needed) != UNZ_OK)
922
if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.flag) != UNZ_OK)
925
if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.compression_method) != UNZ_OK)
928
if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.dosDate) != UNZ_OK)
931
unz64local_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date);
933
if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.crc) != UNZ_OK)
936
if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
938
file_info.compressed_size = uL;
940
if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
942
file_info.uncompressed_size = uL;
944
if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_filename) != UNZ_OK)
947
if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_extra) != UNZ_OK)
950
if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_comment) != UNZ_OK)
953
if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.disk_num_start) != UNZ_OK)
956
if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.internal_fa) != UNZ_OK)
959
if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.external_fa) != UNZ_OK)
962
// relative offset of local header
963
if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
965
file_info_internal.offset_curfile = uL;
967
lSeek+=file_info.size_filename;
968
if ((err==UNZ_OK) && (szFileName!=NULL))
971
if (file_info.size_filename<fileNameBufferSize)
973
*(szFileName+file_info.size_filename)='\0';
974
uSizeRead = file_info.size_filename;
977
uSizeRead = fileNameBufferSize;
979
if ((file_info.size_filename>0) && (fileNameBufferSize>0))
980
if (ZREAD64(s->z_filefunc, s->filestream,szFileName,uSizeRead)!=uSizeRead)
986
if ((err==UNZ_OK) && (extraField!=NULL))
989
if (file_info.size_file_extra<extraFieldBufferSize)
990
uSizeRead = file_info.size_file_extra;
992
uSizeRead = extraFieldBufferSize;
996
if (ZSEEK64(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
1002
if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0))
1003
if (ZREAD64(s->z_filefunc, s->filestream,extraField,(uLong)uSizeRead)!=uSizeRead)
1006
lSeek += file_info.size_file_extra - (uLong)uSizeRead;
1009
lSeek += file_info.size_file_extra;
1012
if ((err==UNZ_OK) && (file_info.size_file_extra != 0))
1016
// since lSeek now points to after the extra field we need to move back
1017
lSeek -= file_info.size_file_extra;
1021
if (ZSEEK64(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
1027
while(acc < file_info.size_file_extra)
1032
if (unz64local_getShort(&s->z_filefunc, s->filestream,&headerId) != UNZ_OK)
1035
if (unz64local_getShort(&s->z_filefunc, s->filestream,&dataSize) != UNZ_OK)
1038
/* ZIP64 extra fields */
1039
if (headerId == 0x0001)
1043
if(file_info.uncompressed_size == (ZPOS64_T)(unsigned long)-1)
1045
if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.uncompressed_size) != UNZ_OK)
1049
if(file_info.compressed_size == (ZPOS64_T)(unsigned long)-1)
1051
if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.compressed_size) != UNZ_OK)
1055
if(file_info_internal.offset_curfile == (ZPOS64_T)(unsigned long)-1)
1057
/* Relative Header offset */
1058
if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info_internal.offset_curfile) != UNZ_OK)
1062
if(file_info.disk_num_start == (unsigned long)-1)
1064
/* Disk Start Number */
1065
if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
1072
if (ZSEEK64(s->z_filefunc, s->filestream,dataSize,ZLIB_FILEFUNC_SEEK_CUR)!=0)
1076
acc += 2 + 2 + dataSize;
1080
if ((err==UNZ_OK) && (szComment!=NULL))
1083
if (file_info.size_file_comment<commentBufferSize)
1085
*(szComment+file_info.size_file_comment)='\0';
1086
uSizeRead = file_info.size_file_comment;
1089
uSizeRead = commentBufferSize;
1093
if (ZSEEK64(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
1099
if ((file_info.size_file_comment>0) && (commentBufferSize>0))
1100
if (ZREAD64(s->z_filefunc, s->filestream,szComment,uSizeRead)!=uSizeRead)
1102
lSeek+=file_info.size_file_comment - uSizeRead;
1105
lSeek+=file_info.size_file_comment;
1108
if ((err==UNZ_OK) && (pfile_info!=NULL))
1109
*pfile_info=file_info;
1111
if ((err==UNZ_OK) && (pfile_info_internal!=NULL))
1112
*pfile_info_internal=file_info_internal;
1120
Write info about the ZipFile in the *pglobal_info structure.
1121
No preparation of the structure is needed
1122
return UNZ_OK if there is no problem.
1124
extern int ZEXPORT unzGetCurrentFileInfo64 (unzFile file,
1125
unz_file_info64 * pfile_info,
1126
char * szFileName, uLong fileNameBufferSize,
1127
void *extraField, uLong extraFieldBufferSize,
1128
char* szComment, uLong commentBufferSize)
1130
return unz64local_GetCurrentFileInfoInternal(file,pfile_info,NULL,
1131
szFileName,fileNameBufferSize,
1132
extraField,extraFieldBufferSize,
1133
szComment,commentBufferSize);
1136
extern int ZEXPORT unzGetCurrentFileInfo (unzFile file,
1137
unz_file_info * pfile_info,
1138
char * szFileName, uLong fileNameBufferSize,
1139
void *extraField, uLong extraFieldBufferSize,
1140
char* szComment, uLong commentBufferSize)
1143
unz_file_info64 file_info64;
1144
err = unz64local_GetCurrentFileInfoInternal(file,&file_info64,NULL,
1145
szFileName,fileNameBufferSize,
1146
extraField,extraFieldBufferSize,
1147
szComment,commentBufferSize);
1150
pfile_info->version = file_info64.version;
1151
pfile_info->version_needed = file_info64.version_needed;
1152
pfile_info->flag = file_info64.flag;
1153
pfile_info->compression_method = file_info64.compression_method;
1154
pfile_info->dosDate = file_info64.dosDate;
1155
pfile_info->crc = file_info64.crc;
1157
pfile_info->size_filename = file_info64.size_filename;
1158
pfile_info->size_file_extra = file_info64.size_file_extra;
1159
pfile_info->size_file_comment = file_info64.size_file_comment;
1161
pfile_info->disk_num_start = file_info64.disk_num_start;
1162
pfile_info->internal_fa = file_info64.internal_fa;
1163
pfile_info->external_fa = file_info64.external_fa;
1165
pfile_info->tmu_date = file_info64.tmu_date,
1168
pfile_info->compressed_size = (uLong)file_info64.compressed_size;
1169
pfile_info->uncompressed_size = (uLong)file_info64.uncompressed_size;
1175
Set the current file of the zipfile to the first file.
1176
return UNZ_OK if there is no problem
1178
extern int ZEXPORT unzGoToFirstFile (unzFile file)
1183
return UNZ_PARAMERROR;
1185
s->pos_in_central_dir=s->offset_central_dir;
1187
err=unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,
1188
&s->cur_file_info_internal,
1189
NULL,0,NULL,0,NULL,0);
1190
s->current_file_ok = (err == UNZ_OK);
1195
Set the current file of the zipfile to the next file.
1196
return UNZ_OK if there is no problem
1197
return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
1199
extern int ZEXPORT unzGoToNextFile (unzFile file)
1205
return UNZ_PARAMERROR;
1207
if (!s->current_file_ok)
1208
return UNZ_END_OF_LIST_OF_FILE;
1209
if (s->gi.number_entry != 0xffff) /* 2^16 files overflow hack */
1210
if (s->num_file+1==s->gi.number_entry)
1211
return UNZ_END_OF_LIST_OF_FILE;
1213
s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename +
1214
s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ;
1216
err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,
1217
&s->cur_file_info_internal,
1218
NULL,0,NULL,0,NULL,0);
1219
s->current_file_ok = (err == UNZ_OK);
1225
Try locate the file szFileName in the zipfile.
1226
For the iCaseSensitivity signification, see unzipStringFileNameCompare
1229
UNZ_OK if the file is found. It becomes the current file.
1230
UNZ_END_OF_LIST_OF_FILE if the file is not found
1232
extern int ZEXPORT unzLocateFile (unzFile file, const char *szFileName, int iCaseSensitivity)
1237
/* We remember the 'current' position in the file so that we can jump
1238
* back there if we fail.
1240
unz_file_info64 cur_file_infoSaved;
1241
unz_file_info64_internal cur_file_info_internalSaved;
1242
ZPOS64_T num_fileSaved;
1243
ZPOS64_T pos_in_central_dirSaved;
1247
return UNZ_PARAMERROR;
1249
if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP)
1250
return UNZ_PARAMERROR;
1253
if (!s->current_file_ok)
1254
return UNZ_END_OF_LIST_OF_FILE;
1256
/* Save the current state */
1257
num_fileSaved = s->num_file;
1258
pos_in_central_dirSaved = s->pos_in_central_dir;
1259
cur_file_infoSaved = s->cur_file_info;
1260
cur_file_info_internalSaved = s->cur_file_info_internal;
1262
err = unzGoToFirstFile(file);
1264
while (err == UNZ_OK)
1266
char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1];
1267
err = unzGetCurrentFileInfo64(file,NULL,
1268
szCurrentFileName,sizeof(szCurrentFileName)-1,
1272
if (unzStringFileNameCompare(szCurrentFileName,
1273
szFileName,iCaseSensitivity)==0)
1275
err = unzGoToNextFile(file);
1279
/* We failed, so restore the state of the 'current file' to where we
1282
s->num_file = num_fileSaved ;
1283
s->pos_in_central_dir = pos_in_central_dirSaved ;
1284
s->cur_file_info = cur_file_infoSaved;
1285
s->cur_file_info_internal = cur_file_info_internalSaved;
1291
///////////////////////////////////////////
1292
// Contributed by Ryan Haksi (mailto://cryogen@infoserve.net)
1293
// I need random access
1295
// Further optimization could be realized by adding an ability
1296
// to cache the directory in memory. The goal being a single
1297
// comprehensive file read to put the file I need in a memory.
1301
typedef struct unz_file_pos_s
1303
ZPOS64_T pos_in_zip_directory; // offset in file
1304
ZPOS64_T num_of_file; // # of file
1308
extern int ZEXPORT unzGetFilePos64(unzFile file, unz64_file_pos* file_pos)
1312
if (file==NULL || file_pos==NULL)
1313
return UNZ_PARAMERROR;
1315
if (!s->current_file_ok)
1316
return UNZ_END_OF_LIST_OF_FILE;
1318
file_pos->pos_in_zip_directory = s->pos_in_central_dir;
1319
file_pos->num_of_file = s->num_file;
1324
extern int ZEXPORT unzGetFilePos(
1326
unz_file_pos* file_pos)
1328
unz64_file_pos file_pos64;
1329
int err = unzGetFilePos64(file,&file_pos64);
1332
file_pos->pos_in_zip_directory = (uLong)file_pos64.pos_in_zip_directory;
1333
file_pos->num_of_file = (uLong)file_pos64.num_of_file;
1338
extern int ZEXPORT unzGoToFilePos64(unzFile file, const unz64_file_pos* file_pos)
1343
if (file==NULL || file_pos==NULL)
1344
return UNZ_PARAMERROR;
1347
/* jump to the right spot */
1348
s->pos_in_central_dir = file_pos->pos_in_zip_directory;
1349
s->num_file = file_pos->num_of_file;
1351
/* set the current file */
1352
err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,
1353
&s->cur_file_info_internal,
1354
NULL,0,NULL,0,NULL,0);
1355
/* return results */
1356
s->current_file_ok = (err == UNZ_OK);
1360
extern int ZEXPORT unzGoToFilePos(
1362
unz_file_pos* file_pos)
1364
unz64_file_pos file_pos64;
1365
if (file_pos == NULL)
1366
return UNZ_PARAMERROR;
1368
file_pos64.pos_in_zip_directory = file_pos->pos_in_zip_directory;
1369
file_pos64.num_of_file = file_pos->num_of_file;
1370
return unzGoToFilePos64(file,&file_pos64);
1374
// Unzip Helper Functions - should be here?
1375
///////////////////////////////////////////
1379
Read the local header of the current zipfile
1380
Check the coherency of the local header and info in the end of central
1381
directory about this file
1382
store in *piSizeVar the size of extra info in local header
1383
(filename and size of extra field data)
1385
local int unz64local_CheckCurrentFileCoherencyHeader (unz64_s* s, uInt* piSizeVar,
1386
ZPOS64_T * poffset_local_extrafield,
1387
uInt * psize_local_extrafield)
1389
uLong uMagic,uData,uFlags;
1390
uLong size_filename;
1391
uLong size_extra_field;
1395
*poffset_local_extrafield = 0;
1396
*psize_local_extrafield = 0;
1398
if (ZSEEK64(s->z_filefunc, s->filestream,s->cur_file_info_internal.offset_curfile +
1399
s->byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0)
1405
if (unz64local_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)
1407
else if (uMagic!=0x04034b50)
1411
if (unz64local_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK)
1414
else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion))
1417
if (unz64local_getShort(&s->z_filefunc, s->filestream,&uFlags) != UNZ_OK)
1420
if (unz64local_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK)
1422
else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method))
1425
if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) &&
1426
/* #ifdef HAVE_BZIP2 */
1427
(s->cur_file_info.compression_method!=Z_BZIP2ED) &&
1429
(s->cur_file_info.compression_method!=Z_DEFLATED))
1432
if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* date/time */
1435
if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* crc */
1437
else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) && ((uFlags & 8)==0))
1440
if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size compr */
1442
else if (uData != 0xFFFFFFFF && (err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) && ((uFlags & 8)==0))
1445
if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size uncompr */
1447
else if (uData != 0xFFFFFFFF && (err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) && ((uFlags & 8)==0))
1450
if (unz64local_getShort(&s->z_filefunc, s->filestream,&size_filename) != UNZ_OK)
1452
else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename))
1455
*piSizeVar += (uInt)size_filename;
1457
if (unz64local_getShort(&s->z_filefunc, s->filestream,&size_extra_field) != UNZ_OK)
1459
*poffset_local_extrafield= s->cur_file_info_internal.offset_curfile +
1460
SIZEZIPLOCALHEADER + size_filename;
1461
*psize_local_extrafield = (uInt)size_extra_field;
1463
*piSizeVar += (uInt)size_extra_field;
1469
Open for reading data the current file in the zipfile.
1470
If there is no error and the file is opened, the return value is UNZ_OK.
1472
extern int ZEXPORT unzOpenCurrentFile3 (unzFile file, int* method,
1473
int* level, int raw, const char* password)
1478
file_in_zip64_read_info_s* pfile_in_zip_read_info;
1479
ZPOS64_T offset_local_extrafield; /* offset of the local extra field */
1480
uInt size_local_extrafield; /* size of the local extra field */
1484
if (password != NULL)
1485
return UNZ_PARAMERROR;
1489
return UNZ_PARAMERROR;
1491
if (!s->current_file_ok)
1492
return UNZ_PARAMERROR;
1494
if (s->pfile_in_zip_read != NULL)
1495
unzCloseCurrentFile(file);
1497
if (unz64local_CheckCurrentFileCoherencyHeader(s,&iSizeVar, &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK)
1498
return UNZ_BADZIPFILE;
1500
pfile_in_zip_read_info = (file_in_zip64_read_info_s*)ALLOC(sizeof(file_in_zip64_read_info_s));
1501
if (pfile_in_zip_read_info==NULL)
1502
return UNZ_INTERNALERROR;
1504
pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE);
1505
pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield;
1506
pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield;
1507
pfile_in_zip_read_info->pos_local_extrafield=0;
1508
pfile_in_zip_read_info->raw=raw;
1510
if (pfile_in_zip_read_info->read_buffer==NULL)
1512
TRYFREE(pfile_in_zip_read_info);
1513
return UNZ_INTERNALERROR;
1516
pfile_in_zip_read_info->stream_initialised=0;
1519
*method = (int)s->cur_file_info.compression_method;
1524
switch (s->cur_file_info.flag & 0x06)
1526
case 6 : *level = 1; break;
1527
case 4 : *level = 2; break;
1528
case 2 : *level = 9; break;
1532
if ((s->cur_file_info.compression_method!=0) &&
1533
/* #ifdef HAVE_BZIP2 */
1534
(s->cur_file_info.compression_method!=Z_BZIP2ED) &&
1536
(s->cur_file_info.compression_method!=Z_DEFLATED))
1540
pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc;
1541
pfile_in_zip_read_info->crc32=0;
1542
pfile_in_zip_read_info->total_out_64=0;
1543
pfile_in_zip_read_info->compression_method = s->cur_file_info.compression_method;
1544
pfile_in_zip_read_info->filestream=s->filestream;
1545
pfile_in_zip_read_info->z_filefunc=s->z_filefunc;
1546
pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile;
1548
pfile_in_zip_read_info->stream.total_out = 0;
1550
if ((s->cur_file_info.compression_method==Z_BZIP2ED) && (!raw))
1553
pfile_in_zip_read_info->bstream.bzalloc = (void *(*) (void *, int, int))0;
1554
pfile_in_zip_read_info->bstream.bzfree = (free_func)0;
1555
pfile_in_zip_read_info->bstream.opaque = (voidpf)0;
1556
pfile_in_zip_read_info->bstream.state = (voidpf)0;
1558
pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;
1559
pfile_in_zip_read_info->stream.zfree = (free_func)0;
1560
pfile_in_zip_read_info->stream.opaque = (voidpf)0;
1561
pfile_in_zip_read_info->stream.next_in = (voidpf)0;
1562
pfile_in_zip_read_info->stream.avail_in = 0;
1564
err=BZ2_bzDecompressInit(&pfile_in_zip_read_info->bstream, 0, 0);
1566
pfile_in_zip_read_info->stream_initialised=Z_BZIP2ED;
1569
TRYFREE(pfile_in_zip_read_info);
1573
pfile_in_zip_read_info->raw=1;
1576
else if ((s->cur_file_info.compression_method==Z_DEFLATED) && (!raw))
1578
pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;
1579
pfile_in_zip_read_info->stream.zfree = (free_func)0;
1580
pfile_in_zip_read_info->stream.opaque = (voidpf)0;
1581
pfile_in_zip_read_info->stream.next_in = 0;
1582
pfile_in_zip_read_info->stream.avail_in = 0;
1584
err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS);
1586
pfile_in_zip_read_info->stream_initialised=Z_DEFLATED;
1589
TRYFREE(pfile_in_zip_read_info);
1592
/* windowBits is passed < 0 to tell that there is no zlib header.
1593
* Note that in this case inflate *requires* an extra "dummy" byte
1594
* after the compressed stream in order to complete decompression and
1595
* return Z_STREAM_END.
1596
* In unzip, i don't wait absolutely Z_STREAM_END because I known the
1597
* size of both compressed and uncompressed data
1600
pfile_in_zip_read_info->rest_read_compressed =
1601
s->cur_file_info.compressed_size ;
1602
pfile_in_zip_read_info->rest_read_uncompressed =
1603
s->cur_file_info.uncompressed_size ;
1606
pfile_in_zip_read_info->pos_in_zipfile =
1607
s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER +
1610
pfile_in_zip_read_info->stream.avail_in = (uInt)0;
1612
s->pfile_in_zip_read = pfile_in_zip_read_info;
1616
if (password != NULL)
1619
s->pcrc_32_tab = get_crc_table();
1620
init_keys(password,s->keys,s->pcrc_32_tab);
1621
if (ZSEEK64(s->z_filefunc, s->filestream,
1622
s->pfile_in_zip_read->pos_in_zipfile +
1623
s->pfile_in_zip_read->byte_before_the_zipfile,
1625
return UNZ_INTERNALERROR;
1626
if(ZREAD64(s->z_filefunc, s->filestream,source, 12)<12)
1627
return UNZ_INTERNALERROR;
1629
for (i = 0; i<12; i++)
1630
zdecode(s->keys,s->pcrc_32_tab,source[i]);
1632
s->pfile_in_zip_read->pos_in_zipfile+=12;
1641
extern int ZEXPORT unzOpenCurrentFile (unzFile file)
1643
return unzOpenCurrentFile3(file, NULL, NULL, 0, NULL);
1646
extern int ZEXPORT unzOpenCurrentFilePassword (unzFile file, const char* password)
1648
return unzOpenCurrentFile3(file, NULL, NULL, 0, password);
1651
extern int ZEXPORT unzOpenCurrentFile2 (unzFile file, int* method, int* level, int raw)
1653
return unzOpenCurrentFile3(file, method, level, raw, NULL);
1656
/** Addition for GDAL : START */
1658
extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64( unzFile file)
1661
file_in_zip64_read_info_s* pfile_in_zip_read_info;
1664
return 0; //UNZ_PARAMERROR;
1665
pfile_in_zip_read_info=s->pfile_in_zip_read;
1666
if (pfile_in_zip_read_info==NULL)
1667
return 0; //UNZ_PARAMERROR;
1668
return pfile_in_zip_read_info->pos_in_zipfile +
1669
pfile_in_zip_read_info->byte_before_the_zipfile;
1672
/** Addition for GDAL : END */
1675
Read bytes from the current file.
1676
buf contain buffer where data must be copied
1677
len the size of buf.
1679
return the number of byte copied if somes bytes are copied
1680
return 0 if the end of file was reached
1681
return <0 with error code if there is an error
1682
(UNZ_ERRNO for IO error, or zLib error for uncompress error)
1684
extern int ZEXPORT unzReadCurrentFile (unzFile file, voidp buf, unsigned len)
1689
file_in_zip64_read_info_s* pfile_in_zip_read_info;
1691
return UNZ_PARAMERROR;
1693
pfile_in_zip_read_info=s->pfile_in_zip_read;
1695
if (pfile_in_zip_read_info==NULL)
1696
return UNZ_PARAMERROR;
1699
if ((pfile_in_zip_read_info->read_buffer == NULL))
1700
return UNZ_END_OF_LIST_OF_FILE;
1704
pfile_in_zip_read_info->stream.next_out = (Bytef*)buf;
1706
pfile_in_zip_read_info->stream.avail_out = (uInt)len;
1708
if ((len>pfile_in_zip_read_info->rest_read_uncompressed) &&
1709
(!(pfile_in_zip_read_info->raw)))
1710
pfile_in_zip_read_info->stream.avail_out =
1711
(uInt)pfile_in_zip_read_info->rest_read_uncompressed;
1713
if ((len>pfile_in_zip_read_info->rest_read_compressed+
1714
pfile_in_zip_read_info->stream.avail_in) &&
1715
(pfile_in_zip_read_info->raw))
1716
pfile_in_zip_read_info->stream.avail_out =
1717
(uInt)pfile_in_zip_read_info->rest_read_compressed+
1718
pfile_in_zip_read_info->stream.avail_in;
1720
while (pfile_in_zip_read_info->stream.avail_out>0)
1722
if ((pfile_in_zip_read_info->stream.avail_in==0) &&
1723
(pfile_in_zip_read_info->rest_read_compressed>0))
1725
uInt uReadThis = UNZ_BUFSIZE;
1726
if (pfile_in_zip_read_info->rest_read_compressed<uReadThis)
1727
uReadThis = (uInt)pfile_in_zip_read_info->rest_read_compressed;
1730
if (ZSEEK64(pfile_in_zip_read_info->z_filefunc,
1731
pfile_in_zip_read_info->filestream,
1732
pfile_in_zip_read_info->pos_in_zipfile +
1733
pfile_in_zip_read_info->byte_before_the_zipfile,
1734
ZLIB_FILEFUNC_SEEK_SET)!=0)
1736
if (ZREAD64(pfile_in_zip_read_info->z_filefunc,
1737
pfile_in_zip_read_info->filestream,
1738
pfile_in_zip_read_info->read_buffer,
1739
uReadThis)!=uReadThis)
1747
for(i=0;i<uReadThis;i++)
1748
pfile_in_zip_read_info->read_buffer[i] =
1749
zdecode(s->keys,s->pcrc_32_tab,
1750
pfile_in_zip_read_info->read_buffer[i]);
1755
pfile_in_zip_read_info->pos_in_zipfile += uReadThis;
1757
pfile_in_zip_read_info->rest_read_compressed-=uReadThis;
1759
pfile_in_zip_read_info->stream.next_in =
1760
(Bytef*)pfile_in_zip_read_info->read_buffer;
1761
pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis;
1764
if ((pfile_in_zip_read_info->compression_method==0) || (pfile_in_zip_read_info->raw))
1768
if ((pfile_in_zip_read_info->stream.avail_in == 0) &&
1769
(pfile_in_zip_read_info->rest_read_compressed == 0))
1770
return (iRead==0) ? UNZ_EOF : iRead;
1772
if (pfile_in_zip_read_info->stream.avail_out <
1773
pfile_in_zip_read_info->stream.avail_in)
1774
uDoCopy = pfile_in_zip_read_info->stream.avail_out ;
1776
uDoCopy = pfile_in_zip_read_info->stream.avail_in ;
1778
for (i=0;i<uDoCopy;i++)
1779
*(pfile_in_zip_read_info->stream.next_out+i) =
1780
*(pfile_in_zip_read_info->stream.next_in+i);
1782
pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uDoCopy;
1784
pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,
1785
pfile_in_zip_read_info->stream.next_out,
1787
pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy;
1788
pfile_in_zip_read_info->stream.avail_in -= uDoCopy;
1789
pfile_in_zip_read_info->stream.avail_out -= uDoCopy;
1790
pfile_in_zip_read_info->stream.next_out += uDoCopy;
1791
pfile_in_zip_read_info->stream.next_in += uDoCopy;
1792
pfile_in_zip_read_info->stream.total_out += uDoCopy;
1795
else if (pfile_in_zip_read_info->compression_method==Z_BZIP2ED)
1798
uLong uTotalOutBefore,uTotalOutAfter;
1799
const Bytef *bufBefore;
1802
pfile_in_zip_read_info->bstream.next_in = (char*)pfile_in_zip_read_info->stream.next_in;
1803
pfile_in_zip_read_info->bstream.avail_in = pfile_in_zip_read_info->stream.avail_in;
1804
pfile_in_zip_read_info->bstream.total_in_lo32 = pfile_in_zip_read_info->stream.total_in;
1805
pfile_in_zip_read_info->bstream.total_in_hi32 = 0;
1806
pfile_in_zip_read_info->bstream.next_out = (char*)pfile_in_zip_read_info->stream.next_out;
1807
pfile_in_zip_read_info->bstream.avail_out = pfile_in_zip_read_info->stream.avail_out;
1808
pfile_in_zip_read_info->bstream.total_out_lo32 = pfile_in_zip_read_info->stream.total_out;
1809
pfile_in_zip_read_info->bstream.total_out_hi32 = 0;
1811
uTotalOutBefore = pfile_in_zip_read_info->bstream.total_out_lo32;
1812
bufBefore = (const Bytef *)pfile_in_zip_read_info->bstream.next_out;
1814
err=BZ2_bzDecompress(&pfile_in_zip_read_info->bstream);
1816
uTotalOutAfter = pfile_in_zip_read_info->bstream.total_out_lo32;
1817
uOutThis = uTotalOutAfter-uTotalOutBefore;
1819
pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis;
1821
pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,bufBefore, (uInt)(uOutThis));
1822
pfile_in_zip_read_info->rest_read_uncompressed -= uOutThis;
1823
iRead += (uInt)(uTotalOutAfter - uTotalOutBefore);
1825
pfile_in_zip_read_info->stream.next_in = (Bytef*)pfile_in_zip_read_info->bstream.next_in;
1826
pfile_in_zip_read_info->stream.avail_in = pfile_in_zip_read_info->bstream.avail_in;
1827
pfile_in_zip_read_info->stream.total_in = pfile_in_zip_read_info->bstream.total_in_lo32;
1828
pfile_in_zip_read_info->stream.next_out = (Bytef*)pfile_in_zip_read_info->bstream.next_out;
1829
pfile_in_zip_read_info->stream.avail_out = pfile_in_zip_read_info->bstream.avail_out;
1830
pfile_in_zip_read_info->stream.total_out = pfile_in_zip_read_info->bstream.total_out_lo32;
1832
if (err==BZ_STREAM_END)
1833
return (iRead==0) ? UNZ_EOF : iRead;
1840
ZPOS64_T uTotalOutBefore,uTotalOutAfter;
1841
const Bytef *bufBefore;
1843
int flush=Z_SYNC_FLUSH;
1845
uTotalOutBefore = pfile_in_zip_read_info->stream.total_out;
1846
bufBefore = pfile_in_zip_read_info->stream.next_out;
1849
if ((pfile_in_zip_read_info->rest_read_uncompressed ==
1850
pfile_in_zip_read_info->stream.avail_out) &&
1851
(pfile_in_zip_read_info->rest_read_compressed == 0))
1854
err=inflate(&pfile_in_zip_read_info->stream,flush);
1856
if ((err>=0) && (pfile_in_zip_read_info->stream.msg!=NULL))
1859
uTotalOutAfter = pfile_in_zip_read_info->stream.total_out;
1860
uOutThis = uTotalOutAfter-uTotalOutBefore;
1862
pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis;
1864
pfile_in_zip_read_info->crc32 =
1865
crc32(pfile_in_zip_read_info->crc32,bufBefore,
1868
pfile_in_zip_read_info->rest_read_uncompressed -=
1871
iRead += (uInt)(uTotalOutAfter - uTotalOutBefore);
1873
if (err==Z_STREAM_END)
1874
return (iRead==0) ? UNZ_EOF : iRead;
1887
Give the current position in uncompressed data
1889
extern z_off_t ZEXPORT unztell (unzFile file)
1892
file_in_zip64_read_info_s* pfile_in_zip_read_info;
1894
return UNZ_PARAMERROR;
1896
pfile_in_zip_read_info=s->pfile_in_zip_read;
1898
if (pfile_in_zip_read_info==NULL)
1899
return UNZ_PARAMERROR;
1901
return (z_off_t)pfile_in_zip_read_info->stream.total_out;
1904
extern ZPOS64_T ZEXPORT unztell64 (unzFile file)
1908
file_in_zip64_read_info_s* pfile_in_zip_read_info;
1910
return (ZPOS64_T)-1;
1912
pfile_in_zip_read_info=s->pfile_in_zip_read;
1914
if (pfile_in_zip_read_info==NULL)
1915
return (ZPOS64_T)-1;
1917
return pfile_in_zip_read_info->total_out_64;
1922
return 1 if the end of file was reached, 0 elsewhere
1924
extern int ZEXPORT unzeof (unzFile file)
1927
file_in_zip64_read_info_s* pfile_in_zip_read_info;
1929
return UNZ_PARAMERROR;
1931
pfile_in_zip_read_info=s->pfile_in_zip_read;
1933
if (pfile_in_zip_read_info==NULL)
1934
return UNZ_PARAMERROR;
1936
if (pfile_in_zip_read_info->rest_read_uncompressed == 0)
1945
Read extra field from the current file (opened by unzOpenCurrentFile)
1946
This is the local-header version of the extra field (sometimes, there is
1947
more info in the local-header version than in the central-header)
1949
if buf==NULL, it return the size of the local extra field that can be read
1951
if buf!=NULL, len is the size of the buffer, the extra header is copied in
1953
the return value is the number of bytes copied in buf, or (if <0)
1956
extern int ZEXPORT unzGetLocalExtrafield (unzFile file, voidp buf, unsigned len)
1959
file_in_zip64_read_info_s* pfile_in_zip_read_info;
1961
ZPOS64_T size_to_read;
1964
return UNZ_PARAMERROR;
1966
pfile_in_zip_read_info=s->pfile_in_zip_read;
1968
if (pfile_in_zip_read_info==NULL)
1969
return UNZ_PARAMERROR;
1971
size_to_read = (pfile_in_zip_read_info->size_local_extrafield -
1972
pfile_in_zip_read_info->pos_local_extrafield);
1975
return (int)size_to_read;
1977
if (len>size_to_read)
1978
read_now = (uInt)size_to_read;
1980
read_now = (uInt)len ;
1985
if (ZSEEK64(pfile_in_zip_read_info->z_filefunc,
1986
pfile_in_zip_read_info->filestream,
1987
pfile_in_zip_read_info->offset_local_extrafield +
1988
pfile_in_zip_read_info->pos_local_extrafield,
1989
ZLIB_FILEFUNC_SEEK_SET)!=0)
1992
if (ZREAD64(pfile_in_zip_read_info->z_filefunc,
1993
pfile_in_zip_read_info->filestream,
1994
buf,read_now)!=read_now)
1997
return (int)read_now;
2001
Close the file in zip opened with unzipOpenCurrentFile
2002
Return UNZ_CRCERROR if all the file was read but the CRC is not good
2004
extern int ZEXPORT unzCloseCurrentFile (unzFile file)
2009
file_in_zip64_read_info_s* pfile_in_zip_read_info;
2011
return UNZ_PARAMERROR;
2013
pfile_in_zip_read_info=s->pfile_in_zip_read;
2015
if (pfile_in_zip_read_info==NULL)
2016
return UNZ_PARAMERROR;
2019
if ((pfile_in_zip_read_info->rest_read_uncompressed == 0) &&
2020
(!pfile_in_zip_read_info->raw))
2022
if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait)
2027
TRYFREE(pfile_in_zip_read_info->read_buffer);
2028
pfile_in_zip_read_info->read_buffer = NULL;
2029
if (pfile_in_zip_read_info->stream_initialised == Z_DEFLATED)
2030
inflateEnd(&pfile_in_zip_read_info->stream);
2032
else if (pfile_in_zip_read_info->stream_initialised == Z_BZIP2ED)
2033
BZ2_bzDecompressEnd(&pfile_in_zip_read_info->bstream);
2037
pfile_in_zip_read_info->stream_initialised = 0;
2038
TRYFREE(pfile_in_zip_read_info);
2040
s->pfile_in_zip_read=NULL;
2047
Get the global comment string of the ZipFile, in the szComment buffer.
2048
uSizeBuf is the size of the szComment buffer.
2049
return the number of byte copied or an error code <0
2051
extern int ZEXPORT unzGetGlobalComment (unzFile file, char * szComment, uLong uSizeBuf)
2056
return (int)UNZ_PARAMERROR;
2059
uReadThis = uSizeBuf;
2060
if (uReadThis>s->gi.size_comment)
2061
uReadThis = s->gi.size_comment;
2063
if (ZSEEK64(s->z_filefunc,s->filestream,s->central_pos+22,ZLIB_FILEFUNC_SEEK_SET)!=0)
2069
if (ZREAD64(s->z_filefunc,s->filestream,szComment,uReadThis)!=uReadThis)
2073
if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment))
2074
*(szComment+s->gi.size_comment)='\0';
2075
return (int)uReadThis;
2078
/* Additions by RX '2004 */
2079
extern ZPOS64_T ZEXPORT unzGetOffset64(unzFile file)
2084
return 0; //UNZ_PARAMERROR;
2086
if (!s->current_file_ok)
2088
if (s->gi.number_entry != 0 && s->gi.number_entry != 0xffff)
2089
if (s->num_file==s->gi.number_entry)
2091
return s->pos_in_central_dir;
2094
extern uLong ZEXPORT unzGetOffset (unzFile file)
2099
return 0; //UNZ_PARAMERROR;
2100
offset64 = unzGetOffset64(file);
2101
return (uLong)offset64;
2104
extern int ZEXPORT unzSetOffset64(unzFile file, ZPOS64_T pos)
2110
return UNZ_PARAMERROR;
2113
s->pos_in_central_dir = pos;
2114
s->num_file = s->gi.number_entry; /* hack */
2115
err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,
2116
&s->cur_file_info_internal,
2117
NULL,0,NULL,0,NULL,0);
2118
s->current_file_ok = (err == UNZ_OK);
2122
extern int ZEXPORT unzSetOffset (unzFile file, uLong pos)
2124
return unzSetOffset64(file,pos);