1
/* unzip.c -- IO for uncompress .zip files using zlib
2
Version 1.01e, February 12th, 2005
4
Copyright (C) 1998-2005 Gilles Vollant
6
Read unzip.h for more info
8
Modified by Sergey A. Tachenov to integrate with Qt.
11
/* Decryption code comes from crypt.c by Info-ZIP but has been greatly reduced in terms of
12
compatibility with older software. The following is from the original crypt.c. Code
13
woven in by Terry Thorsen 1/2003.
16
Copyright (c) 1990-2000 Info-ZIP. All rights reserved.
18
See the accompanying file LICENSE, version 2000-Apr-09 or later
19
(the contents of which are also included in zip.h) for terms of use.
20
If, for some reason, all these files are missing, the Info-ZIP license
21
also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
24
crypt.c (full version) by Info-ZIP. Last revised: [see crypt.h]
26
The encryption/decryption parts of this source code (as opposed to the
27
non-echoing password parts) were originally written in Europe. The
28
whole source package can be freely distributed, including from the USA.
29
(Prior to January 2000, re-export from the US was a violation of US law.)
33
This encryption code is a direct transcription of the algorithm from
34
Roger Schlafly, described by Phil Katz in the file appnote.txt. This
35
file (appnote.txt) is distributed with the PKZIP program (even in the
36
version without encryption capabilities).
61
/* compile with -Dlocal if your debugger can't find static symbols */
64
#ifndef CASESENSITIVITYDEFAULT_NO
65
# if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES)
66
# define CASESENSITIVITYDEFAULT_NO
72
#define UNZ_BUFSIZE (16384)
75
#ifndef UNZ_MAXFILENAMEINZIP
76
#define UNZ_MAXFILENAMEINZIP (256)
80
# define ALLOC(size) (malloc(size))
83
# define TRYFREE(p) {if (p) free(p);}
86
#define SIZECENTRALDIRITEM (0x2e)
87
#define SIZEZIPLOCALHEADER (0x1e)
92
const char unz_copyright[] =
93
" unzip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll";
95
/* unz_file_info_interntal contain internal info about a file in zipfile*/
96
typedef struct unz_file_info_internal_s
98
uLong offset_curfile;/* relative offset of local header 4 bytes */
99
} unz_file_info_internal;
102
/* file_in_zip_read_info_s contain internal information about a file in zipfile,
103
when reading and decompress it */
106
char *read_buffer; /* internal buffer for compressed data */
107
z_stream stream; /* zLib stream structure for inflate */
109
uLong pos_in_zipfile; /* position in byte on the zipfile, for fseek*/
110
uLong stream_initialised; /* flag set if stream structure is initialised*/
112
uLong offset_local_extrafield;/* offset of the local extra field */
113
uInt size_local_extrafield;/* size of the local extra field */
114
uLong pos_local_extrafield; /* position in the local extra field in read*/
116
uLong crc32; /* crc32 of all data uncompressed */
117
uLong crc32_wait; /* crc32 we must obtain after decompress all */
118
uLong rest_read_compressed; /* number of byte to be decompressed */
119
uLong rest_read_uncompressed;/*number of byte to be obtained after decomp*/
120
zlib_filefunc_def z_filefunc;
121
voidpf filestream; /* io structore of the zipfile */
122
uLong compression_method; /* compression method (0==store) */
123
uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
125
} file_in_zip_read_info_s;
128
/* unz_s contain internal information about the zipfile
132
zlib_filefunc_def z_filefunc;
133
voidpf filestream; /* io structore of the zipfile */
134
unz_global_info gi; /* public global information */
135
uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
136
uLong num_file; /* number of the current file in the zipfile*/
137
uLong pos_in_central_dir; /* pos of the current file in the central dir*/
138
uLong current_file_ok; /* flag about the usability of the current file*/
139
uLong central_pos; /* position of the beginning of the central dir*/
141
uLong size_central_dir; /* size of the central directory */
142
uLong offset_central_dir; /* offset of start of central directory with
143
respect to the starting disk number */
145
unz_file_info cur_file_info; /* public info about the current file in zip*/
146
unz_file_info_internal cur_file_info_internal; /* private info about it*/
147
file_in_zip_read_info_s* pfile_in_zip_read; /* structure about the current
148
file if we are decompressing it */
151
unsigned long keys[3]; /* keys defining the pseudo-random sequence */
152
const unsigned long* pcrc_32_tab;
161
/* ===========================================================================
162
Read a byte from a gz_stream; update next_in and avail_in. Return EOF
164
IN assertion: the stream s has been sucessfully opened for reading.
168
local int unzlocal_getByte OF((
169
const zlib_filefunc_def* pzlib_filefunc_def,
173
local int unzlocal_getByte(pzlib_filefunc_def,filestream,pi)
174
const zlib_filefunc_def* pzlib_filefunc_def;
179
int err = (int)ZREAD(*pzlib_filefunc_def,filestream,&c,1);
187
if (ZERROR(*pzlib_filefunc_def,filestream))
195
/* ===========================================================================
196
Reads a long in LSB order from the given gz_stream. Sets
198
local int unzlocal_getShort OF((
199
const zlib_filefunc_def* pzlib_filefunc_def,
203
local int unzlocal_getShort (pzlib_filefunc_def,filestream,pX)
204
const zlib_filefunc_def* pzlib_filefunc_def;
212
err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
216
err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
226
local int unzlocal_getLong OF((
227
const zlib_filefunc_def* pzlib_filefunc_def,
231
local int unzlocal_getLong (pzlib_filefunc_def,filestream,pX)
232
const zlib_filefunc_def* pzlib_filefunc_def;
240
err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
244
err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
248
err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
252
err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
263
/* My own strcmpi / strcasecmp */
264
local int strcmpcasenosensitive_internal (fileName1,fileName2)
265
const char* fileName1;
266
const char* fileName2;
270
char c1=*(fileName1++);
271
char c2=*(fileName2++);
272
if ((c1>='a') && (c1<='z'))
274
if ((c2>='a') && (c2<='z'))
277
return ((c2=='\0') ? 0 : -1);
288
#ifdef CASESENSITIVITYDEFAULT_NO
289
#define CASESENSITIVITYDEFAULTVALUE 2
291
#define CASESENSITIVITYDEFAULTVALUE 1
294
#ifndef STRCMPCASENOSENTIVEFUNCTION
295
#define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal
299
Compare two filename (fileName1,fileName2).
300
If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
301
If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
303
If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
304
(like 1 on Unix, 2 on Windows)
307
extern int ZEXPORT unzStringFileNameCompare (fileName1,fileName2,iCaseSensitivity)
308
const char* fileName1;
309
const char* fileName2;
310
int iCaseSensitivity;
312
if (iCaseSensitivity==0)
313
iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE;
315
if (iCaseSensitivity==1)
316
return strcmp(fileName1,fileName2);
318
return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2);
321
#ifndef BUFREADCOMMENT
322
#define BUFREADCOMMENT (0x400)
326
Locate the Central directory of a zipfile (at the end, just before
329
local uLong unzlocal_SearchCentralDir OF((
330
const zlib_filefunc_def* pzlib_filefunc_def,
333
local uLong unzlocal_SearchCentralDir(pzlib_filefunc_def,filestream)
334
const zlib_filefunc_def* pzlib_filefunc_def;
340
uLong uMaxBack=0xffff; /* maximum size of global comment */
343
if (ZSEEK(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
347
uSizeFile = ZTELL(*pzlib_filefunc_def,filestream);
349
if (uMaxBack>uSizeFile)
350
uMaxBack = uSizeFile;
352
buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
357
while (uBackRead<uMaxBack)
359
uLong uReadSize,uReadPos ;
361
if (uBackRead+BUFREADCOMMENT>uMaxBack)
362
uBackRead = uMaxBack;
364
uBackRead+=BUFREADCOMMENT;
365
uReadPos = uSizeFile-uBackRead ;
367
uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
368
(BUFREADCOMMENT+4) : (uSizeFile-uReadPos);
369
if (ZSEEK(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
372
if (ZREAD(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
375
for (i=(int)uReadSize-3; (i--)>0;)
376
if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
377
((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
379
uPosFound = uReadPos+i;
391
Open a Zip file. path contain the full pathname (by example,
392
on a Windows NT computer "c:\\test\\zlib114.zip" or on an Unix computer
394
If the zipfile cannot be opened (file doesn't exist or in not valid), the
395
return value is NULL.
396
Else, the return value is a unzFile Handle, usable with other function
397
of this unzip package.
399
extern unzFile ZEXPORT unzOpen2 (file, pzlib_filefunc_def)
401
zlib_filefunc_def* pzlib_filefunc_def;
405
uLong central_pos,uL;
407
uLong number_disk; /* number of the current dist, used for
408
spaning ZIP, unsupported, always 0*/
409
uLong number_disk_with_CD; /* number the the disk with central dir, used
410
for spaning ZIP, unsupported, always 0*/
411
uLong number_entry_CD; /* total number of entries in
413
(same than number_entry on nospan) */
417
if (unz_copyright[0]!=' ')
420
if (pzlib_filefunc_def==NULL)
421
fill_qiodevice_filefunc(&us.z_filefunc);
423
us.z_filefunc = *pzlib_filefunc_def;
425
us.filestream= (*(us.z_filefunc.zopen_file))(us.z_filefunc.opaque,
427
ZLIB_FILEFUNC_MODE_READ |
428
ZLIB_FILEFUNC_MODE_EXISTING);
429
if (us.filestream==NULL)
432
central_pos = unzlocal_SearchCentralDir(&us.z_filefunc,us.filestream);
436
if (ZSEEK(us.z_filefunc, us.filestream,
437
central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
440
/* the signature, already checked */
441
if (unzlocal_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
444
/* number of this disk */
445
if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK)
448
/* number of the disk with the start of the central directory */
449
if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK)
452
/* total number of entries in the central dir on this disk */
453
if (unzlocal_getShort(&us.z_filefunc, us.filestream,&us.gi.number_entry)!=UNZ_OK)
456
/* total number of entries in the central dir */
457
if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_entry_CD)!=UNZ_OK)
460
if ((number_entry_CD!=us.gi.number_entry) ||
461
(number_disk_with_CD!=0) ||
465
/* size of the central directory */
466
if (unzlocal_getLong(&us.z_filefunc, us.filestream,&us.size_central_dir)!=UNZ_OK)
469
/* offset of start of central directory with respect to the
470
starting disk number */
471
if (unzlocal_getLong(&us.z_filefunc, us.filestream,&us.offset_central_dir)!=UNZ_OK)
474
/* zipfile comment length */
475
if (unzlocal_getShort(&us.z_filefunc, us.filestream,&us.gi.size_comment)!=UNZ_OK)
478
if ((central_pos<us.offset_central_dir+us.size_central_dir) &&
484
ZCLOSE(us.z_filefunc, us.filestream);
488
us.byte_before_the_zipfile = central_pos -
489
(us.offset_central_dir+us.size_central_dir);
490
us.central_pos = central_pos;
491
us.pfile_in_zip_read = NULL;
495
s=(unz_s*)ALLOC(sizeof(unz_s));
497
unzGoToFirstFile((unzFile)s);
502
extern unzFile ZEXPORT unzOpen (file)
505
return unzOpen2(file, NULL);
509
Close a ZipFile opened with unzipOpen.
510
If there is files inside the .Zip opened with unzipOpenCurrentFile (see later),
511
these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
512
return UNZ_OK if there is no problem. */
513
extern int ZEXPORT unzClose (file)
518
return UNZ_PARAMERROR;
521
if (s->pfile_in_zip_read!=NULL)
522
unzCloseCurrentFile(file);
524
ZCLOSE(s->z_filefunc, s->filestream);
531
Write info about the ZipFile in the *pglobal_info structure.
532
No preparation of the structure is needed
533
return UNZ_OK if there is no problem. */
534
extern int ZEXPORT unzGetGlobalInfo (file,pglobal_info)
536
unz_global_info *pglobal_info;
540
return UNZ_PARAMERROR;
548
Translate date/time from Dos format to tm_unz (readable more easilty)
550
local void unzlocal_DosDateToTmuDate (ulDosDate, ptm)
555
uDate = (uLong)(ulDosDate>>16);
556
ptm->tm_mday = (uInt)(uDate&0x1f) ;
557
ptm->tm_mon = (uInt)((((uDate)&0x1E0)/0x20)-1) ;
558
ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ;
560
ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800);
561
ptm->tm_min = (uInt) ((ulDosDate&0x7E0)/0x20) ;
562
ptm->tm_sec = (uInt) (2*(ulDosDate&0x1f)) ;
566
Get Info about the current file in the zipfile, with internal only info
568
local int unzlocal_GetCurrentFileInfoInternal OF((unzFile file,
569
unz_file_info *pfile_info,
570
unz_file_info_internal
571
*pfile_info_internal,
573
uLong fileNameBufferSize,
575
uLong extraFieldBufferSize,
577
uLong commentBufferSize));
579
local int unzlocal_GetCurrentFileInfoInternal (file,
582
szFileName, fileNameBufferSize,
583
extraField, extraFieldBufferSize,
584
szComment, commentBufferSize)
586
unz_file_info *pfile_info;
587
unz_file_info_internal *pfile_info_internal;
589
uLong fileNameBufferSize;
591
uLong extraFieldBufferSize;
593
uLong commentBufferSize;
596
unz_file_info file_info;
597
unz_file_info_internal file_info_internal;
603
return UNZ_PARAMERROR;
605
if (ZSEEK(s->z_filefunc, s->filestream,
606
s->pos_in_central_dir+s->byte_before_the_zipfile,
607
ZLIB_FILEFUNC_SEEK_SET)!=0)
611
/* we check the magic */
613
if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)
615
else if (uMagic!=0x02014b50)
619
if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.version) != UNZ_OK)
622
if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.version_needed) != UNZ_OK)
625
if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.flag) != UNZ_OK)
628
if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.compression_method) != UNZ_OK)
631
if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.dosDate) != UNZ_OK)
634
unzlocal_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date);
636
if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.crc) != UNZ_OK)
639
if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.compressed_size) != UNZ_OK)
642
if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.uncompressed_size) != UNZ_OK)
645
if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_filename) != UNZ_OK)
648
if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_extra) != UNZ_OK)
651
if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_comment) != UNZ_OK)
654
if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.disk_num_start) != UNZ_OK)
657
if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.internal_fa) != UNZ_OK)
660
if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.external_fa) != UNZ_OK)
663
if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info_internal.offset_curfile) != UNZ_OK)
666
uSeek+=file_info.size_filename;
667
if ((err==UNZ_OK) && (szFileName!=NULL))
670
if (file_info.size_filename<fileNameBufferSize)
672
*(szFileName+file_info.size_filename)='\0';
673
uSizeRead = file_info.size_filename;
676
uSizeRead = fileNameBufferSize;
678
if ((file_info.size_filename>0) && (fileNameBufferSize>0))
679
if (ZREAD(s->z_filefunc, s->filestream,szFileName,uSizeRead)!=uSizeRead)
685
if ((err==UNZ_OK) && (extraField!=NULL))
688
if (file_info.size_file_extra<extraFieldBufferSize)
689
uSizeRead = file_info.size_file_extra;
691
uSizeRead = extraFieldBufferSize;
694
if (ZSEEK(s->z_filefunc, s->filestream,uSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
699
if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0))
700
if (ZREAD(s->z_filefunc, s->filestream,extraField,uSizeRead)!=uSizeRead)
702
uSeek += file_info.size_file_extra - uSizeRead;
705
uSeek+=file_info.size_file_extra;
708
if ((err==UNZ_OK) && (szComment!=NULL))
711
if (file_info.size_file_comment<commentBufferSize)
713
*(szComment+file_info.size_file_comment)='\0';
714
uSizeRead = file_info.size_file_comment;
717
uSizeRead = commentBufferSize;
720
if (ZSEEK(s->z_filefunc, s->filestream,uSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
725
if ((file_info.size_file_comment>0) && (commentBufferSize>0))
726
if (ZREAD(s->z_filefunc, s->filestream,szComment,uSizeRead)!=uSizeRead)
728
uSeek+=file_info.size_file_comment - uSizeRead;
731
uSeek+=file_info.size_file_comment;
733
if ((err==UNZ_OK) && (pfile_info!=NULL))
734
*pfile_info=file_info;
736
if ((err==UNZ_OK) && (pfile_info_internal!=NULL))
737
*pfile_info_internal=file_info_internal;
745
Write info about the ZipFile in the *pglobal_info structure.
746
No preparation of the structure is needed
747
return UNZ_OK if there is no problem.
749
extern int ZEXPORT unzGetCurrentFileInfo (file,
751
szFileName, fileNameBufferSize,
752
extraField, extraFieldBufferSize,
753
szComment, commentBufferSize)
755
unz_file_info *pfile_info;
757
uLong fileNameBufferSize;
759
uLong extraFieldBufferSize;
761
uLong commentBufferSize;
763
return unzlocal_GetCurrentFileInfoInternal(file,pfile_info,NULL,
764
szFileName,fileNameBufferSize,
765
extraField,extraFieldBufferSize,
766
szComment,commentBufferSize);
770
Set the current file of the zipfile to the first file.
771
return UNZ_OK if there is no problem
773
extern int ZEXPORT unzGoToFirstFile (file)
779
return UNZ_PARAMERROR;
781
s->pos_in_central_dir=s->offset_central_dir;
783
err=unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
784
&s->cur_file_info_internal,
785
NULL,0,NULL,0,NULL,0);
786
s->current_file_ok = (err == UNZ_OK);
791
Set the current file of the zipfile to the next file.
792
return UNZ_OK if there is no problem
793
return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
795
extern int ZEXPORT unzGoToNextFile (file)
802
return UNZ_PARAMERROR;
804
if (!s->current_file_ok)
805
return UNZ_END_OF_LIST_OF_FILE;
806
if (s->gi.number_entry != 0xffff) /* 2^16 files overflow hack */
807
if (s->num_file+1==s->gi.number_entry)
808
return UNZ_END_OF_LIST_OF_FILE;
810
s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename +
811
s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ;
813
err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
814
&s->cur_file_info_internal,
815
NULL,0,NULL,0,NULL,0);
816
s->current_file_ok = (err == UNZ_OK);
822
Try locate the file szFileName in the zipfile.
823
For the iCaseSensitivity signification, see unzipStringFileNameCompare
826
UNZ_OK if the file is found. It becomes the current file.
827
UNZ_END_OF_LIST_OF_FILE if the file is not found
829
extern int ZEXPORT unzLocateFile (file, szFileName, iCaseSensitivity)
831
const char *szFileName;
832
int iCaseSensitivity;
837
/* We remember the 'current' position in the file so that we can jump
838
* back there if we fail.
840
unz_file_info cur_file_infoSaved;
841
unz_file_info_internal cur_file_info_internalSaved;
843
uLong pos_in_central_dirSaved;
847
return UNZ_PARAMERROR;
849
if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP)
850
return UNZ_PARAMERROR;
853
if (!s->current_file_ok)
854
return UNZ_END_OF_LIST_OF_FILE;
856
/* Save the current state */
857
num_fileSaved = s->num_file;
858
pos_in_central_dirSaved = s->pos_in_central_dir;
859
cur_file_infoSaved = s->cur_file_info;
860
cur_file_info_internalSaved = s->cur_file_info_internal;
862
err = unzGoToFirstFile(file);
864
while (err == UNZ_OK)
866
char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1];
867
err = unzGetCurrentFileInfo(file,NULL,
868
szCurrentFileName,sizeof(szCurrentFileName)-1,
872
if (unzStringFileNameCompare(szCurrentFileName,
873
szFileName,iCaseSensitivity)==0)
875
err = unzGoToNextFile(file);
879
/* We failed, so restore the state of the 'current file' to where we
882
s->num_file = num_fileSaved ;
883
s->pos_in_central_dir = pos_in_central_dirSaved ;
884
s->cur_file_info = cur_file_infoSaved;
885
s->cur_file_info_internal = cur_file_info_internalSaved;
891
///////////////////////////////////////////
892
// Contributed by Ryan Haksi (mailto://cryogen@infoserve.net)
893
// I need random access
895
// Further optimization could be realized by adding an ability
896
// to cache the directory in memory. The goal being a single
897
// comprehensive file read to put the file I need in a memory.
901
typedef struct unz_file_pos_s
903
uLong pos_in_zip_directory; // offset in file
904
uLong num_of_file; // # of file
908
extern int ZEXPORT unzGetFilePos(file, file_pos)
910
unz_file_pos* file_pos;
914
if (file==NULL || file_pos==NULL)
915
return UNZ_PARAMERROR;
917
if (!s->current_file_ok)
918
return UNZ_END_OF_LIST_OF_FILE;
920
file_pos->pos_in_zip_directory = s->pos_in_central_dir;
921
file_pos->num_of_file = s->num_file;
926
extern int ZEXPORT unzGoToFilePos(file, file_pos)
928
unz_file_pos* file_pos;
933
if (file==NULL || file_pos==NULL)
934
return UNZ_PARAMERROR;
937
/* jump to the right spot */
938
s->pos_in_central_dir = file_pos->pos_in_zip_directory;
939
s->num_file = file_pos->num_of_file;
941
/* set the current file */
942
err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
943
&s->cur_file_info_internal,
944
NULL,0,NULL,0,NULL,0);
946
s->current_file_ok = (err == UNZ_OK);
951
// Unzip Helper Functions - should be here?
952
///////////////////////////////////////////
956
Read the local header of the current zipfile
957
Check the coherency of the local header and info in the end of central
958
directory about this file
959
store in *piSizeVar the size of extra info in local header
960
(filename and size of extra field data)
962
local int unzlocal_CheckCurrentFileCoherencyHeader (s,piSizeVar,
963
poffset_local_extrafield,
964
psize_local_extrafield)
967
uLong *poffset_local_extrafield;
968
uInt *psize_local_extrafield;
970
uLong uMagic,uData,uFlags;
972
uLong size_extra_field;
976
*poffset_local_extrafield = 0;
977
*psize_local_extrafield = 0;
979
if (ZSEEK(s->z_filefunc, s->filestream,s->cur_file_info_internal.offset_curfile +
980
s->byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0)
985
if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)
987
else if (uMagic!=0x04034b50)
991
if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK)
994
else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion))
997
if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uFlags) != UNZ_OK)
1000
if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK)
1002
else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method))
1005
if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) &&
1006
(s->cur_file_info.compression_method!=Z_DEFLATED))
1009
if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* date/time */
1012
if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* crc */
1014
else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) &&
1018
if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size compr */
1020
else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) &&
1024
if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size uncompr */
1026
else if ((err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) &&
1031
if (unzlocal_getShort(&s->z_filefunc, s->filestream,&size_filename) != UNZ_OK)
1033
else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename))
1036
*piSizeVar += (uInt)size_filename;
1038
if (unzlocal_getShort(&s->z_filefunc, s->filestream,&size_extra_field) != UNZ_OK)
1040
*poffset_local_extrafield= s->cur_file_info_internal.offset_curfile +
1041
SIZEZIPLOCALHEADER + size_filename;
1042
*psize_local_extrafield = (uInt)size_extra_field;
1044
*piSizeVar += (uInt)size_extra_field;
1050
Open for reading data the current file in the zipfile.
1051
If there is no error and the file is opened, the return value is UNZ_OK.
1053
extern int ZEXPORT unzOpenCurrentFile3 (file, method, level, raw, password)
1058
const char* password;
1063
file_in_zip_read_info_s* pfile_in_zip_read_info;
1064
uLong offset_local_extrafield; /* offset of the local extra field */
1065
uInt size_local_extrafield; /* size of the local extra field */
1069
if (password != NULL)
1070
return UNZ_PARAMERROR;
1074
return UNZ_PARAMERROR;
1076
if (!s->current_file_ok)
1077
return UNZ_PARAMERROR;
1079
if (s->pfile_in_zip_read != NULL)
1080
unzCloseCurrentFile(file);
1082
if (unzlocal_CheckCurrentFileCoherencyHeader(s,&iSizeVar,
1083
&offset_local_extrafield,&size_local_extrafield)!=UNZ_OK)
1084
return UNZ_BADZIPFILE;
1086
pfile_in_zip_read_info = (file_in_zip_read_info_s*)
1087
ALLOC(sizeof(file_in_zip_read_info_s));
1088
if (pfile_in_zip_read_info==NULL)
1089
return UNZ_INTERNALERROR;
1091
pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE);
1092
pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield;
1093
pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield;
1094
pfile_in_zip_read_info->pos_local_extrafield=0;
1095
pfile_in_zip_read_info->raw=raw;
1097
if (pfile_in_zip_read_info->read_buffer==NULL)
1099
TRYFREE(pfile_in_zip_read_info);
1100
return UNZ_INTERNALERROR;
1103
pfile_in_zip_read_info->stream_initialised=0;
1106
*method = (int)s->cur_file_info.compression_method;
1111
switch (s->cur_file_info.flag & 0x06)
1113
case 6 : *level = 1; break;
1114
case 4 : *level = 2; break;
1115
case 2 : *level = 9; break;
1119
if ((s->cur_file_info.compression_method!=0) &&
1120
(s->cur_file_info.compression_method!=Z_DEFLATED))
1123
pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc;
1124
pfile_in_zip_read_info->crc32=0;
1125
pfile_in_zip_read_info->compression_method =
1126
s->cur_file_info.compression_method;
1127
pfile_in_zip_read_info->filestream=s->filestream;
1128
pfile_in_zip_read_info->z_filefunc=s->z_filefunc;
1129
pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile;
1131
pfile_in_zip_read_info->stream.total_out = 0;
1133
if ((s->cur_file_info.compression_method==Z_DEFLATED) &&
1136
pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;
1137
pfile_in_zip_read_info->stream.zfree = (free_func)0;
1138
pfile_in_zip_read_info->stream.opaque = (voidpf)0;
1139
pfile_in_zip_read_info->stream.next_in = (voidpf)0;
1140
pfile_in_zip_read_info->stream.avail_in = 0;
1142
err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS);
1144
pfile_in_zip_read_info->stream_initialised=1;
1147
TRYFREE(pfile_in_zip_read_info);
1150
/* windowBits is passed < 0 to tell that there is no zlib header.
1151
* Note that in this case inflate *requires* an extra "dummy" byte
1152
* after the compressed stream in order to complete decompression and
1153
* return Z_STREAM_END.
1154
* In unzip, i don't wait absolutely Z_STREAM_END because I known the
1155
* size of both compressed and uncompressed data
1158
pfile_in_zip_read_info->rest_read_compressed =
1159
s->cur_file_info.compressed_size ;
1160
pfile_in_zip_read_info->rest_read_uncompressed =
1161
s->cur_file_info.uncompressed_size ;
1164
pfile_in_zip_read_info->pos_in_zipfile =
1165
s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER +
1168
pfile_in_zip_read_info->stream.avail_in = (uInt)0;
1170
s->pfile_in_zip_read = pfile_in_zip_read_info;
1173
if (password != NULL)
1176
s->pcrc_32_tab = get_crc_table();
1177
init_keys(password,s->keys,s->pcrc_32_tab);
1178
if (ZSEEK(s->z_filefunc, s->filestream,
1179
s->pfile_in_zip_read->pos_in_zipfile +
1180
s->pfile_in_zip_read->byte_before_the_zipfile,
1182
return UNZ_INTERNALERROR;
1183
if(ZREAD(s->z_filefunc, s->filestream,source, 12)<12)
1184
return UNZ_INTERNALERROR;
1186
for (i = 0; i<12; i++)
1187
zdecode(s->keys,s->pcrc_32_tab,source[i]);
1189
s->pfile_in_zip_read->pos_in_zipfile+=12;
1198
extern int ZEXPORT unzOpenCurrentFile (file)
1201
return unzOpenCurrentFile3(file, NULL, NULL, 0, NULL);
1204
extern int ZEXPORT unzOpenCurrentFilePassword (file, password)
1206
const char* password;
1208
return unzOpenCurrentFile3(file, NULL, NULL, 0, password);
1211
extern int ZEXPORT unzOpenCurrentFile2 (file,method,level,raw)
1217
return unzOpenCurrentFile3(file, method, level, raw, NULL);
1221
Read bytes from the current file.
1222
buf contain buffer where data must be copied
1223
len the size of buf.
1225
return the number of byte copied if somes bytes are copied
1226
return 0 if the end of file was reached
1227
return <0 with error code if there is an error
1228
(UNZ_ERRNO for IO error, or zLib error for uncompress error)
1230
extern int ZEXPORT unzReadCurrentFile (file, buf, len)
1238
file_in_zip_read_info_s* pfile_in_zip_read_info;
1240
return UNZ_PARAMERROR;
1242
pfile_in_zip_read_info=s->pfile_in_zip_read;
1244
if (pfile_in_zip_read_info==NULL)
1245
return UNZ_PARAMERROR;
1248
if ((pfile_in_zip_read_info->read_buffer == NULL))
1249
return UNZ_END_OF_LIST_OF_FILE;
1253
pfile_in_zip_read_info->stream.next_out = (Bytef*)buf;
1255
pfile_in_zip_read_info->stream.avail_out = (uInt)len;
1257
if ((len>pfile_in_zip_read_info->rest_read_uncompressed) &&
1258
(!(pfile_in_zip_read_info->raw)))
1259
pfile_in_zip_read_info->stream.avail_out =
1260
(uInt)pfile_in_zip_read_info->rest_read_uncompressed;
1262
if ((len>pfile_in_zip_read_info->rest_read_compressed+
1263
pfile_in_zip_read_info->stream.avail_in) &&
1264
(pfile_in_zip_read_info->raw))
1265
pfile_in_zip_read_info->stream.avail_out =
1266
(uInt)pfile_in_zip_read_info->rest_read_compressed+
1267
pfile_in_zip_read_info->stream.avail_in;
1269
while (pfile_in_zip_read_info->stream.avail_out>0)
1271
if ((pfile_in_zip_read_info->stream.avail_in==0) &&
1272
(pfile_in_zip_read_info->rest_read_compressed>0))
1274
uInt uReadThis = UNZ_BUFSIZE;
1275
if (pfile_in_zip_read_info->rest_read_compressed<uReadThis)
1276
uReadThis = (uInt)pfile_in_zip_read_info->rest_read_compressed;
1279
if (ZSEEK(pfile_in_zip_read_info->z_filefunc,
1280
pfile_in_zip_read_info->filestream,
1281
pfile_in_zip_read_info->pos_in_zipfile +
1282
pfile_in_zip_read_info->byte_before_the_zipfile,
1283
ZLIB_FILEFUNC_SEEK_SET)!=0)
1285
if (ZREAD(pfile_in_zip_read_info->z_filefunc,
1286
pfile_in_zip_read_info->filestream,
1287
pfile_in_zip_read_info->read_buffer,
1288
uReadThis)!=uReadThis)
1296
for(i=0;i<uReadThis;i++)
1297
pfile_in_zip_read_info->read_buffer[i] =
1298
zdecode(s->keys,s->pcrc_32_tab,
1299
pfile_in_zip_read_info->read_buffer[i]);
1304
pfile_in_zip_read_info->pos_in_zipfile += uReadThis;
1306
pfile_in_zip_read_info->rest_read_compressed-=uReadThis;
1308
pfile_in_zip_read_info->stream.next_in =
1309
(Bytef*)pfile_in_zip_read_info->read_buffer;
1310
pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis;
1313
if ((pfile_in_zip_read_info->compression_method==0) || (pfile_in_zip_read_info->raw))
1317
if ((pfile_in_zip_read_info->stream.avail_in == 0) &&
1318
(pfile_in_zip_read_info->rest_read_compressed == 0))
1319
return (iRead==0) ? UNZ_EOF : iRead;
1321
if (pfile_in_zip_read_info->stream.avail_out <
1322
pfile_in_zip_read_info->stream.avail_in)
1323
uDoCopy = pfile_in_zip_read_info->stream.avail_out ;
1325
uDoCopy = pfile_in_zip_read_info->stream.avail_in ;
1327
for (i=0;i<uDoCopy;i++)
1328
*(pfile_in_zip_read_info->stream.next_out+i) =
1329
*(pfile_in_zip_read_info->stream.next_in+i);
1331
pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,
1332
pfile_in_zip_read_info->stream.next_out,
1334
pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy;
1335
pfile_in_zip_read_info->stream.avail_in -= uDoCopy;
1336
pfile_in_zip_read_info->stream.avail_out -= uDoCopy;
1337
pfile_in_zip_read_info->stream.next_out += uDoCopy;
1338
pfile_in_zip_read_info->stream.next_in += uDoCopy;
1339
pfile_in_zip_read_info->stream.total_out += uDoCopy;
1344
uLong uTotalOutBefore,uTotalOutAfter;
1345
const Bytef *bufBefore;
1347
int flush=Z_SYNC_FLUSH;
1349
uTotalOutBefore = pfile_in_zip_read_info->stream.total_out;
1350
bufBefore = pfile_in_zip_read_info->stream.next_out;
1353
if ((pfile_in_zip_read_info->rest_read_uncompressed ==
1354
pfile_in_zip_read_info->stream.avail_out) &&
1355
(pfile_in_zip_read_info->rest_read_compressed == 0))
1358
err=inflate(&pfile_in_zip_read_info->stream,flush);
1360
if ((err>=0) && (pfile_in_zip_read_info->stream.msg!=NULL))
1363
uTotalOutAfter = pfile_in_zip_read_info->stream.total_out;
1364
uOutThis = uTotalOutAfter-uTotalOutBefore;
1366
pfile_in_zip_read_info->crc32 =
1367
crc32(pfile_in_zip_read_info->crc32,bufBefore,
1370
pfile_in_zip_read_info->rest_read_uncompressed -=
1373
iRead += (uInt)(uTotalOutAfter - uTotalOutBefore);
1375
if (err==Z_STREAM_END)
1376
return (iRead==0) ? UNZ_EOF : iRead;
1389
Give the current position in uncompressed data
1391
extern z_off_t ZEXPORT unztell (file)
1395
file_in_zip_read_info_s* pfile_in_zip_read_info;
1397
return UNZ_PARAMERROR;
1399
pfile_in_zip_read_info=s->pfile_in_zip_read;
1401
if (pfile_in_zip_read_info==NULL)
1402
return UNZ_PARAMERROR;
1404
return (z_off_t)pfile_in_zip_read_info->stream.total_out;
1409
return 1 if the end of file was reached, 0 elsewhere
1411
extern int ZEXPORT unzeof (file)
1415
file_in_zip_read_info_s* pfile_in_zip_read_info;
1417
return UNZ_PARAMERROR;
1419
pfile_in_zip_read_info=s->pfile_in_zip_read;
1421
if (pfile_in_zip_read_info==NULL)
1422
return UNZ_PARAMERROR;
1424
if (pfile_in_zip_read_info->rest_read_uncompressed == 0)
1433
Read extra field from the current file (opened by unzOpenCurrentFile)
1434
This is the local-header version of the extra field (sometimes, there is
1435
more info in the local-header version than in the central-header)
1437
if buf==NULL, it return the size of the local extra field that can be read
1439
if buf!=NULL, len is the size of the buffer, the extra header is copied in
1441
the return value is the number of bytes copied in buf, or (if <0)
1444
extern int ZEXPORT unzGetLocalExtrafield (file,buf,len)
1450
file_in_zip_read_info_s* pfile_in_zip_read_info;
1455
return UNZ_PARAMERROR;
1457
pfile_in_zip_read_info=s->pfile_in_zip_read;
1459
if (pfile_in_zip_read_info==NULL)
1460
return UNZ_PARAMERROR;
1462
size_to_read = (pfile_in_zip_read_info->size_local_extrafield -
1463
pfile_in_zip_read_info->pos_local_extrafield);
1466
return (int)size_to_read;
1468
if (len>size_to_read)
1469
read_now = (uInt)size_to_read;
1471
read_now = (uInt)len ;
1476
if (ZSEEK(pfile_in_zip_read_info->z_filefunc,
1477
pfile_in_zip_read_info->filestream,
1478
pfile_in_zip_read_info->offset_local_extrafield +
1479
pfile_in_zip_read_info->pos_local_extrafield,
1480
ZLIB_FILEFUNC_SEEK_SET)!=0)
1483
if (ZREAD(pfile_in_zip_read_info->z_filefunc,
1484
pfile_in_zip_read_info->filestream,
1485
buf,read_now)!=read_now)
1488
return (int)read_now;
1492
Close the file in zip opened with unzipOpenCurrentFile
1493
Return UNZ_CRCERROR if all the file was read but the CRC is not good
1495
extern int ZEXPORT unzCloseCurrentFile (file)
1501
file_in_zip_read_info_s* pfile_in_zip_read_info;
1503
return UNZ_PARAMERROR;
1505
pfile_in_zip_read_info=s->pfile_in_zip_read;
1507
if (pfile_in_zip_read_info==NULL)
1508
return UNZ_PARAMERROR;
1511
if ((pfile_in_zip_read_info->rest_read_uncompressed == 0) &&
1512
(!pfile_in_zip_read_info->raw))
1514
if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait)
1519
TRYFREE(pfile_in_zip_read_info->read_buffer);
1520
pfile_in_zip_read_info->read_buffer = NULL;
1521
if (pfile_in_zip_read_info->stream_initialised)
1522
inflateEnd(&pfile_in_zip_read_info->stream);
1524
pfile_in_zip_read_info->stream_initialised = 0;
1525
TRYFREE(pfile_in_zip_read_info);
1527
s->pfile_in_zip_read=NULL;
1534
Get the global comment string of the ZipFile, in the szComment buffer.
1535
uSizeBuf is the size of the szComment buffer.
1536
return the number of byte copied or an error code <0
1538
extern int ZEXPORT unzGetGlobalComment (file, szComment, uSizeBuf)
1546
return UNZ_PARAMERROR;
1549
uReadThis = uSizeBuf;
1550
if (uReadThis>s->gi.size_comment)
1551
uReadThis = s->gi.size_comment;
1553
if (ZSEEK(s->z_filefunc,s->filestream,s->central_pos+22,ZLIB_FILEFUNC_SEEK_SET)!=0)
1559
if (ZREAD(s->z_filefunc,s->filestream,szComment,uReadThis)!=uReadThis)
1563
if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment))
1564
*(szComment+s->gi.size_comment)='\0';
1565
return (int)uReadThis;
1568
/* Additions by RX '2004 */
1569
extern uLong ZEXPORT unzGetOffset (file)
1575
return UNZ_PARAMERROR;
1577
if (!s->current_file_ok)
1579
if (s->gi.number_entry != 0 && s->gi.number_entry != 0xffff)
1580
if (s->num_file==s->gi.number_entry)
1582
return s->pos_in_central_dir;
1585
extern int ZEXPORT unzSetOffset (file, pos)
1593
return UNZ_PARAMERROR;
1596
s->pos_in_central_dir = pos;
1597
s->num_file = s->gi.number_entry; /* hack */
1598
err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
1599
&s->cur_file_info_internal,
1600
NULL,0,NULL,0,NULL,0);
1601
s->current_file_ok = (err == UNZ_OK);