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
9
/* Decryption code comes from crypt.c by Info-ZIP but has been greatly reduced in terms of
10
compatibility with older software. The following is from the original crypt.c. Code
11
woven in by Terry Thorsen 1/2003.
14
Copyright (c) 1990-2000 Info-ZIP. All rights reserved.
16
See the accompanying file LICENSE, version 2000-Apr-09 or later
17
(the contents of which are also included in zip.h) for terms of use.
18
If, for some reason, all these files are missing, the Info-ZIP license
19
also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
22
crypt.c (full version) by Info-ZIP. Last revised: [see crypt.h]
24
The encryption/decryption parts of this source code (as opposed to the
25
non-echoing password parts) were originally written in Europe. The
26
whole source package can be freely distributed, including from the USA.
27
(Prior to January 2000, re-export from the US was a violation of US law.)
31
This encryption code is a direct transcription of the algorithm from
32
Roger Schlafly, described by Phil Katz in the file appnote.txt. This
33
file (appnote.txt) is distributed with the PKZIP program (even in the
34
version without encryption capabilities).
57
/* compile with -Dlocal if your debugger can't find static symbols */
60
#ifndef CASESENSITIVITYDEFAULT_NO
61
# if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES)
62
# define CASESENSITIVITYDEFAULT_NO
68
#define UNZ_BUFSIZE (16384)
71
#ifndef UNZ_MAXFILENAMEINZIP
72
#define UNZ_MAXFILENAMEINZIP (256)
76
# define ALLOC(size) (malloc(size))
79
# define TRYFREE(p) {free(p);}
82
#define SIZECENTRALDIRITEM (0x2e)
83
#define SIZEZIPLOCALHEADER (0x1e)
88
const char unz_copyright[] =
89
" unzip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll";
91
/* unz_file_info_interntal contain internal info about a file in zipfile*/
92
typedef struct unz_file_info_internal_s
94
uLong offset_curfile;/* relative offset of local header 4 bytes */
95
} unz_file_info_internal;
98
/* file_in_zip_read_info_s contain internal information about a file in zipfile,
99
when reading and decompress it */
102
char *read_buffer; /* internal buffer for compressed data */
103
z_stream stream; /* zLib stream structure for inflate */
105
uLong pos_in_zipfile; /* position in byte on the zipfile, for fseek*/
106
uLong stream_initialised; /* flag set if stream structure is initialised*/
108
uLong offset_local_extrafield;/* offset of the local extra field */
109
uInt size_local_extrafield;/* size of the local extra field */
110
uLong pos_local_extrafield; /* position in the local extra field in read*/
112
uLong crc32; /* crc32 of all data uncompressed */
113
uLong crc32_wait; /* crc32 we must obtain after decompress all */
114
uLong rest_read_compressed; /* number of byte to be decompressed */
115
uLong rest_read_uncompressed;/*number of byte to be obtained after decomp*/
116
zlib_filefunc_def z_filefunc;
117
voidpf filestream; /* io structore of the zipfile */
118
uLong compression_method; /* compression method (0==store) */
119
uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
121
} file_in_zip_read_info_s;
124
/* unz_s contain internal information about the zipfile
128
zlib_filefunc_def z_filefunc;
129
voidpf filestream; /* io structore of the zipfile */
130
unz_global_info gi; /* public global information */
131
uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
132
uLong num_file; /* number of the current file in the zipfile*/
133
uLong pos_in_central_dir; /* pos of the current file in the central dir*/
134
uLong current_file_ok; /* flag about the usability of the current file*/
135
uLong central_pos; /* position of the beginning of the central dir*/
137
uLong size_central_dir; /* size of the central directory */
138
uLong offset_central_dir; /* offset of start of central directory with
139
respect to the starting disk number */
141
unz_file_info cur_file_info; /* public info about the current file in zip*/
142
unz_file_info_internal cur_file_info_internal; /* private info about it*/
143
file_in_zip_read_info_s* pfile_in_zip_read; /* structure about the current
144
file if we are decompressing it */
147
unsigned long keys[3]; /* keys defining the pseudo-random sequence */
148
const unsigned long* pcrc_32_tab;
157
/* ===========================================================================
158
Read a byte from a gz_stream; update next_in and avail_in. Return EOF
160
IN assertion: the stream s has been sucessfully opened for reading.
164
local int unzlocal_getByte OF((
165
const zlib_filefunc_def* pzlib_filefunc_def,
169
local int unzlocal_getByte(pzlib_filefunc_def,filestream,pi)
170
const zlib_filefunc_def* pzlib_filefunc_def;
175
int err = (int)ZREAD(*pzlib_filefunc_def,filestream,&c,1);
183
if (ZERROR(*pzlib_filefunc_def,filestream))
191
/* ===========================================================================
192
Reads a long in LSB order from the given gz_stream. Sets
194
local int unzlocal_getShort OF((
195
const zlib_filefunc_def* pzlib_filefunc_def,
199
local int unzlocal_getShort (pzlib_filefunc_def,filestream,pX)
200
const zlib_filefunc_def* pzlib_filefunc_def;
208
err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
212
err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
222
local int unzlocal_getLong OF((
223
const zlib_filefunc_def* pzlib_filefunc_def,
227
local int unzlocal_getLong (pzlib_filefunc_def,filestream,pX)
228
const zlib_filefunc_def* pzlib_filefunc_def;
236
err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
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);
259
/* My own strcmpi / strcasecmp */
260
local int strcmpcasenosensitive_internal (fileName1,fileName2)
261
const char* fileName1;
262
const char* fileName2;
266
char c1=*(fileName1++);
267
char c2=*(fileName2++);
268
if ((c1>='a') && (c1<='z'))
270
if ((c2>='a') && (c2<='z'))
273
return ((c2=='\0') ? 0 : -1);
284
#ifdef CASESENSITIVITYDEFAULT_NO
285
#define CASESENSITIVITYDEFAULTVALUE 2
287
#define CASESENSITIVITYDEFAULTVALUE 1
290
#ifndef STRCMPCASENOSENTIVEFUNCTION
291
#define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal
295
Compare two filename (fileName1,fileName2).
296
If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
297
If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
299
If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
300
(like 1 on Unix, 2 on Windows)
303
extern int ZEXPORT unzStringFileNameCompare (fileName1,fileName2,iCaseSensitivity)
304
const char* fileName1;
305
const char* fileName2;
306
int iCaseSensitivity;
308
if (iCaseSensitivity==0)
309
iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE;
311
if (iCaseSensitivity==1)
312
return strcmp(fileName1,fileName2);
314
return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2);
317
#ifndef BUFREADCOMMENT
318
#define BUFREADCOMMENT (0x400)
322
Locate the Central directory of a zipfile (at the end, just before
325
local uLong unzlocal_SearchCentralDir OF((
326
const zlib_filefunc_def* pzlib_filefunc_def,
329
local uLong unzlocal_SearchCentralDir(pzlib_filefunc_def,filestream)
330
const zlib_filefunc_def* pzlib_filefunc_def;
336
uLong uMaxBack=0xffff; /* maximum size of global comment */
339
if (ZSEEK(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
343
uSizeFile = ZTELL(*pzlib_filefunc_def,filestream);
345
if (uMaxBack>uSizeFile)
346
uMaxBack = uSizeFile;
348
buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
353
while (uBackRead<uMaxBack)
355
uLong uReadSize,uReadPos ;
357
if (uBackRead+BUFREADCOMMENT>uMaxBack)
358
uBackRead = uMaxBack;
360
uBackRead+=BUFREADCOMMENT;
361
uReadPos = uSizeFile-uBackRead ;
363
uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
364
(BUFREADCOMMENT+4) : (uSizeFile-uReadPos);
365
if (ZSEEK(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
368
if (ZREAD(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
371
for (i=(int)uReadSize-3; (i--)>0;)
372
if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
373
((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
375
uPosFound = uReadPos+i;
387
Open a Zip file. path contain the full pathname (by example,
388
on a Windows NT computer "c:\\test\\zlib114.zip" or on an Unix computer
390
If the zipfile cannot be opened (file doesn't exist or in not valid), the
391
return value is NULL.
392
Else, the return value is a unzFile Handle, usable with other function
393
of this unzip package.
395
extern unzFile ZEXPORT unzOpen2 (path, pzlib_filefunc_def)
397
zlib_filefunc_def* pzlib_filefunc_def;
401
uLong central_pos,uL;
403
uLong number_disk; /* number of the current dist, used for
404
spaning ZIP, unsupported, always 0*/
405
uLong number_disk_with_CD; /* number the the disk with central dir, used
406
for spaning ZIP, unsupported, always 0*/
407
uLong number_entry_CD; /* total number of entries in
409
(same than number_entry on nospan) */
413
if (unz_copyright[0]!=' ')
416
if (pzlib_filefunc_def==NULL)
417
fill_fopen_filefunc(&us.z_filefunc);
419
us.z_filefunc = *pzlib_filefunc_def;
421
us.filestream= (*(us.z_filefunc.zopen_file))(us.z_filefunc.opaque,
423
ZLIB_FILEFUNC_MODE_READ |
424
ZLIB_FILEFUNC_MODE_EXISTING);
425
if (us.filestream==NULL)
428
central_pos = unzlocal_SearchCentralDir(&us.z_filefunc,us.filestream);
432
if (ZSEEK(us.z_filefunc, us.filestream,
433
central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
436
/* the signature, already checked */
437
if (unzlocal_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
440
/* number of this disk */
441
if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK)
444
/* number of the disk with the start of the central directory */
445
if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK)
448
/* total number of entries in the central dir on this disk */
449
if (unzlocal_getShort(&us.z_filefunc, us.filestream,&us.gi.number_entry)!=UNZ_OK)
452
/* total number of entries in the central dir */
453
if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_entry_CD)!=UNZ_OK)
456
if ((number_entry_CD!=us.gi.number_entry) ||
457
(number_disk_with_CD!=0) ||
461
/* size of the central directory */
462
if (unzlocal_getLong(&us.z_filefunc, us.filestream,&us.size_central_dir)!=UNZ_OK)
465
/* offset of start of central directory with respect to the
466
starting disk number */
467
if (unzlocal_getLong(&us.z_filefunc, us.filestream,&us.offset_central_dir)!=UNZ_OK)
470
/* zipfile comment length */
471
if (unzlocal_getShort(&us.z_filefunc, us.filestream,&us.gi.size_comment)!=UNZ_OK)
474
if ((central_pos<us.offset_central_dir+us.size_central_dir) &&
480
ZCLOSE(us.z_filefunc, us.filestream);
484
us.byte_before_the_zipfile = central_pos -
485
(us.offset_central_dir+us.size_central_dir);
486
us.central_pos = central_pos;
487
us.pfile_in_zip_read = NULL;
491
s=(unz_s*)ALLOC(sizeof(unz_s));
493
unzGoToFirstFile((unzFile)s);
498
extern unzFile ZEXPORT unzOpen (path)
501
return unzOpen2(path, NULL);
505
Close a ZipFile opened with unzipOpen.
506
If there is files inside the .Zip opened with unzipOpenCurrentFile (see later),
507
these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
508
return UNZ_OK if there is no problem. */
509
extern int ZEXPORT unzClose (file)
514
return UNZ_PARAMERROR;
517
if (s->pfile_in_zip_read!=NULL)
518
unzCloseCurrentFile(file);
520
ZCLOSE(s->z_filefunc, s->filestream);
527
Write info about the ZipFile in the *pglobal_info structure.
528
No preparation of the structure is needed
529
return UNZ_OK if there is no problem. */
530
extern int ZEXPORT unzGetGlobalInfo (file,pglobal_info)
532
unz_global_info *pglobal_info;
536
return UNZ_PARAMERROR;
544
Translate date/time from Dos format to tm_unz (readable more easilty)
546
local void unzlocal_DosDateToTmuDate (ulDosDate, ptm)
551
uDate = (uLong)(ulDosDate>>16);
552
ptm->tm_mday = (uInt)(uDate&0x1f) ;
553
ptm->tm_mon = (uInt)((((uDate)&0x1E0)/0x20)-1) ;
554
ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ;
556
ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800);
557
ptm->tm_min = (uInt) ((ulDosDate&0x7E0)/0x20) ;
558
ptm->tm_sec = (uInt) (2*(ulDosDate&0x1f)) ;
562
Get Info about the current file in the zipfile, with internal only info
564
local int unzlocal_GetCurrentFileInfoInternal OF((unzFile file,
565
unz_file_info *pfile_info,
566
unz_file_info_internal
567
*pfile_info_internal,
569
uLong fileNameBufferSize,
571
uLong extraFieldBufferSize,
573
uLong commentBufferSize));
575
local int unzlocal_GetCurrentFileInfoInternal (file,
578
szFileName, fileNameBufferSize,
579
extraField, extraFieldBufferSize,
580
szComment, commentBufferSize)
582
unz_file_info *pfile_info;
583
unz_file_info_internal *pfile_info_internal;
585
uLong fileNameBufferSize;
587
uLong extraFieldBufferSize;
589
uLong commentBufferSize;
592
unz_file_info file_info;
593
unz_file_info_internal file_info_internal;
599
return UNZ_PARAMERROR;
601
if (ZSEEK(s->z_filefunc, s->filestream,
602
s->pos_in_central_dir+s->byte_before_the_zipfile,
603
ZLIB_FILEFUNC_SEEK_SET)!=0)
607
/* we check the magic */
610
if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)
612
else if (uMagic!=0x02014b50)
616
if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.version) != UNZ_OK)
619
if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.version_needed) != UNZ_OK)
622
if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.flag) != UNZ_OK)
625
if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.compression_method) != UNZ_OK)
628
if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.dosDate) != UNZ_OK)
631
unzlocal_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date);
633
if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.crc) != UNZ_OK)
636
if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.compressed_size) != UNZ_OK)
639
if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.uncompressed_size) != UNZ_OK)
642
if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_filename) != UNZ_OK)
645
if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_extra) != UNZ_OK)
648
if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_comment) != UNZ_OK)
651
if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.disk_num_start) != UNZ_OK)
654
if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.internal_fa) != UNZ_OK)
657
if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.external_fa) != UNZ_OK)
660
if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info_internal.offset_curfile) != UNZ_OK)
663
lSeek+=file_info.size_filename;
664
if ((err==UNZ_OK) && (szFileName!=NULL))
667
if (file_info.size_filename<fileNameBufferSize)
669
*(szFileName+file_info.size_filename)='\0';
670
uSizeRead = file_info.size_filename;
673
uSizeRead = fileNameBufferSize;
675
if ((file_info.size_filename>0) && (fileNameBufferSize>0))
676
if (ZREAD(s->z_filefunc, s->filestream,szFileName,uSizeRead)!=uSizeRead)
682
if ((err==UNZ_OK) && (extraField!=NULL))
685
if (file_info.size_file_extra<extraFieldBufferSize)
686
uSizeRead = file_info.size_file_extra;
688
uSizeRead = extraFieldBufferSize;
692
if (ZSEEK(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
697
if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0))
698
if (ZREAD(s->z_filefunc, s->filestream,extraField,uSizeRead)!=uSizeRead)
700
lSeek += file_info.size_file_extra - uSizeRead;
703
lSeek+=file_info.size_file_extra;
706
if ((err==UNZ_OK) && (szComment!=NULL))
709
if (file_info.size_file_comment<commentBufferSize)
711
*(szComment+file_info.size_file_comment)='\0';
712
uSizeRead = file_info.size_file_comment;
715
uSizeRead = commentBufferSize;
719
if (ZSEEK(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
724
if ((file_info.size_file_comment>0) && (commentBufferSize>0))
725
if (ZREAD(s->z_filefunc, s->filestream,szComment,uSizeRead)!=uSizeRead)
727
lSeek+=file_info.size_file_comment - uSizeRead;
730
lSeek+=file_info.size_file_comment;
732
if ((err==UNZ_OK) && (pfile_info!=NULL))
733
*pfile_info=file_info;
735
if ((err==UNZ_OK) && (pfile_info_internal!=NULL))
736
*pfile_info_internal=file_info_internal;
744
Write info about the ZipFile in the *pglobal_info structure.
745
No preparation of the structure is needed
746
return UNZ_OK if there is no problem.
748
extern int ZEXPORT unzGetCurrentFileInfo (file,
750
szFileName, fileNameBufferSize,
751
extraField, extraFieldBufferSize,
752
szComment, commentBufferSize)
754
unz_file_info *pfile_info;
756
uLong fileNameBufferSize;
758
uLong extraFieldBufferSize;
760
uLong commentBufferSize;
762
return unzlocal_GetCurrentFileInfoInternal(file,pfile_info,NULL,
763
szFileName,fileNameBufferSize,
764
extraField,extraFieldBufferSize,
765
szComment,commentBufferSize);
769
Set the current file of the zipfile to the first file.
770
return UNZ_OK if there is no problem
772
extern int ZEXPORT unzGoToFirstFile (file)
778
return UNZ_PARAMERROR;
780
s->pos_in_central_dir=s->offset_central_dir;
782
err=unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
783
&s->cur_file_info_internal,
784
NULL,0,NULL,0,NULL,0);
785
s->current_file_ok = (err == UNZ_OK);
790
Set the current file of the zipfile to the next file.
791
return UNZ_OK if there is no problem
792
return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
794
extern int ZEXPORT unzGoToNextFile (file)
801
return UNZ_PARAMERROR;
803
if (!s->current_file_ok)
804
return UNZ_END_OF_LIST_OF_FILE;
805
if (s->gi.number_entry != 0xffff) /* 2^16 files overflow hack */
806
if (s->num_file+1==s->gi.number_entry)
807
return UNZ_END_OF_LIST_OF_FILE;
809
s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename +
810
s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ;
812
err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
813
&s->cur_file_info_internal,
814
NULL,0,NULL,0,NULL,0);
815
s->current_file_ok = (err == UNZ_OK);
821
Try locate the file szFileName in the zipfile.
822
For the iCaseSensitivity signification, see unzipStringFileNameCompare
825
UNZ_OK if the file is found. It becomes the current file.
826
UNZ_END_OF_LIST_OF_FILE if the file is not found
828
extern int ZEXPORT unzLocateFile (file, szFileName, iCaseSensitivity)
830
const char *szFileName;
831
int iCaseSensitivity;
836
/* We remember the 'current' position in the file so that we can jump
837
* back there if we fail.
839
unz_file_info cur_file_infoSaved;
840
unz_file_info_internal cur_file_info_internalSaved;
842
uLong pos_in_central_dirSaved;
846
return UNZ_PARAMERROR;
848
if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP)
849
return UNZ_PARAMERROR;
852
if (!s->current_file_ok)
853
return UNZ_END_OF_LIST_OF_FILE;
855
/* Save the current state */
856
num_fileSaved = s->num_file;
857
pos_in_central_dirSaved = s->pos_in_central_dir;
858
cur_file_infoSaved = s->cur_file_info;
859
cur_file_info_internalSaved = s->cur_file_info_internal;
861
err = unzGoToFirstFile(file);
863
while (err == UNZ_OK)
865
char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1];
866
err = unzGetCurrentFileInfo(file,NULL,
867
szCurrentFileName,sizeof(szCurrentFileName)-1,
871
if (unzStringFileNameCompare(szCurrentFileName,
872
szFileName,iCaseSensitivity)==0)
874
err = unzGoToNextFile(file);
878
/* We failed, so restore the state of the 'current file' to where we
881
s->num_file = num_fileSaved ;
882
s->pos_in_central_dir = pos_in_central_dirSaved ;
883
s->cur_file_info = cur_file_infoSaved;
884
s->cur_file_info_internal = cur_file_info_internalSaved;
890
///////////////////////////////////////////
891
// Contributed by Ryan Haksi (mailto://cryogen@infoserve.net)
892
// I need random access
894
// Further optimization could be realized by adding an ability
895
// to cache the directory in memory. The goal being a single
896
// comprehensive file read to put the file I need in a memory.
900
typedef struct unz_file_pos_s
902
uLong pos_in_zip_directory; // offset in file
903
uLong num_of_file; // # of file
907
extern int ZEXPORT unzGetFilePos(file, file_pos)
909
unz_file_pos* file_pos;
913
if (file==NULL || file_pos==NULL)
914
return UNZ_PARAMERROR;
916
if (!s->current_file_ok)
917
return UNZ_END_OF_LIST_OF_FILE;
919
file_pos->pos_in_zip_directory = s->pos_in_central_dir;
920
file_pos->num_of_file = s->num_file;
925
extern int ZEXPORT unzGoToFilePos(file, file_pos)
927
unz_file_pos* file_pos;
932
if (file==NULL || file_pos==NULL)
933
return UNZ_PARAMERROR;
936
/* jump to the right spot */
937
s->pos_in_central_dir = file_pos->pos_in_zip_directory;
938
s->num_file = file_pos->num_of_file;
940
/* set the current file */
941
err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
942
&s->cur_file_info_internal,
943
NULL,0,NULL,0,NULL,0);
945
s->current_file_ok = (err == UNZ_OK);
950
// Unzip Helper Functions - should be here?
951
///////////////////////////////////////////
955
Read the local header of the current zipfile
956
Check the coherency of the local header and info in the end of central
957
directory about this file
958
store in *piSizeVar the size of extra info in local header
959
(filename and size of extra field data)
961
local int unzlocal_CheckCurrentFileCoherencyHeader (s,piSizeVar,
962
poffset_local_extrafield,
963
psize_local_extrafield)
966
uLong *poffset_local_extrafield;
967
uInt *psize_local_extrafield;
969
uLong uMagic,uData,uFlags;
971
uLong size_extra_field;
975
*poffset_local_extrafield = 0;
976
*psize_local_extrafield = 0;
978
if (ZSEEK(s->z_filefunc, s->filestream,s->cur_file_info_internal.offset_curfile +
979
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)
990
if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK)
993
else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion))
996
if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uFlags) != UNZ_OK)
999
if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK)
1001
else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method))
1004
if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) &&
1005
(s->cur_file_info.compression_method!=Z_DEFLATED))
1008
if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* date/time */
1011
if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* crc */
1013
else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) &&
1017
if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size compr */
1019
else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) &&
1023
if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size uncompr */
1025
else if ((err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) &&
1030
if (unzlocal_getShort(&s->z_filefunc, s->filestream,&size_filename) != UNZ_OK)
1032
else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename))
1035
*piSizeVar += (uInt)size_filename;
1037
if (unzlocal_getShort(&s->z_filefunc, s->filestream,&size_extra_field) != UNZ_OK)
1039
*poffset_local_extrafield= s->cur_file_info_internal.offset_curfile +
1040
SIZEZIPLOCALHEADER + size_filename;
1041
*psize_local_extrafield = (uInt)size_extra_field;
1043
*piSizeVar += (uInt)size_extra_field;
1049
Open for reading data the current file in the zipfile.
1050
If there is no error and the file is opened, the return value is UNZ_OK.
1052
extern int ZEXPORT unzOpenCurrentFile3 (file, method, level, raw, password)
1057
const char* password;
1062
file_in_zip_read_info_s* pfile_in_zip_read_info;
1063
uLong offset_local_extrafield; /* offset of the local extra field */
1064
uInt size_local_extrafield; /* size of the local extra field */
1068
if (password != NULL)
1069
return UNZ_PARAMERROR;
1073
return UNZ_PARAMERROR;
1075
if (!s->current_file_ok)
1076
return UNZ_PARAMERROR;
1078
if (s->pfile_in_zip_read != NULL)
1079
unzCloseCurrentFile(file);
1081
if (unzlocal_CheckCurrentFileCoherencyHeader(s,&iSizeVar,
1082
&offset_local_extrafield,&size_local_extrafield)!=UNZ_OK)
1083
return UNZ_BADZIPFILE;
1085
pfile_in_zip_read_info = (file_in_zip_read_info_s*)
1086
ALLOC(sizeof(file_in_zip_read_info_s));
1087
if (pfile_in_zip_read_info==NULL)
1088
return UNZ_INTERNALERROR;
1090
pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE);
1091
pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield;
1092
pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield;
1093
pfile_in_zip_read_info->pos_local_extrafield=0;
1094
pfile_in_zip_read_info->raw=raw;
1096
if (pfile_in_zip_read_info->read_buffer==NULL)
1098
TRYFREE(pfile_in_zip_read_info);
1099
return UNZ_INTERNALERROR;
1102
pfile_in_zip_read_info->stream_initialised=0;
1105
*method = (int)s->cur_file_info.compression_method;
1110
switch (s->cur_file_info.flag & 0x06)
1112
case 6 : *level = 1; break;
1113
case 4 : *level = 2; break;
1114
case 2 : *level = 9; break;
1118
if ((s->cur_file_info.compression_method!=0) &&
1119
(s->cur_file_info.compression_method!=Z_DEFLATED))
1122
pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc;
1123
pfile_in_zip_read_info->crc32=0;
1124
pfile_in_zip_read_info->compression_method =
1125
s->cur_file_info.compression_method;
1126
pfile_in_zip_read_info->filestream=s->filestream;
1127
pfile_in_zip_read_info->z_filefunc=s->z_filefunc;
1128
pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile;
1130
pfile_in_zip_read_info->stream.total_out = 0;
1132
if ((s->cur_file_info.compression_method==Z_DEFLATED) &&
1135
pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;
1136
pfile_in_zip_read_info->stream.zfree = (free_func)0;
1137
pfile_in_zip_read_info->stream.opaque = (voidpf)0;
1138
pfile_in_zip_read_info->stream.next_in = (voidpf)0;
1139
pfile_in_zip_read_info->stream.avail_in = 0;
1141
err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS);
1143
pfile_in_zip_read_info->stream_initialised=1;
1146
TRYFREE(pfile_in_zip_read_info);
1149
/* windowBits is passed < 0 to tell that there is no zlib header.
1150
* Note that in this case inflate *requires* an extra "dummy" byte
1151
* after the compressed stream in order to complete decompression and
1152
* return Z_STREAM_END.
1153
* In unzip, i don't wait absolutely Z_STREAM_END because I known the
1154
* size of both compressed and uncompressed data
1157
pfile_in_zip_read_info->rest_read_compressed =
1158
s->cur_file_info.compressed_size ;
1159
pfile_in_zip_read_info->rest_read_uncompressed =
1160
s->cur_file_info.uncompressed_size ;
1163
pfile_in_zip_read_info->pos_in_zipfile =
1164
s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER +
1167
pfile_in_zip_read_info->stream.avail_in = (uInt)0;
1169
s->pfile_in_zip_read = pfile_in_zip_read_info;
1172
if (password != NULL)
1175
s->pcrc_32_tab = get_crc_table();
1176
init_keys(password,s->keys,s->pcrc_32_tab);
1177
if (ZSEEK(s->z_filefunc, s->filestream,
1178
s->pfile_in_zip_read->pos_in_zipfile +
1179
s->pfile_in_zip_read->byte_before_the_zipfile,
1181
return UNZ_INTERNALERROR;
1182
if(ZREAD(s->z_filefunc, s->filestream,source, 12)<12)
1183
return UNZ_INTERNALERROR;
1185
for (i = 0; i<12; i++)
1186
zdecode(s->keys,s->pcrc_32_tab,source[i]);
1188
s->pfile_in_zip_read->pos_in_zipfile+=12;
1197
extern int ZEXPORT unzOpenCurrentFile (file)
1200
return unzOpenCurrentFile3(file, NULL, NULL, 0, NULL);
1203
extern int ZEXPORT unzOpenCurrentFilePassword (file, password)
1205
const char* password;
1207
return unzOpenCurrentFile3(file, NULL, NULL, 0, password);
1210
extern int ZEXPORT unzOpenCurrentFile2 (file,method,level,raw)
1216
return unzOpenCurrentFile3(file, method, level, raw, NULL);
1220
Read bytes from the current file.
1221
buf contain buffer where data must be copied
1222
len the size of buf.
1224
return the number of byte copied if somes bytes are copied
1225
return 0 if the end of file was reached
1226
return <0 with error code if there is an error
1227
(UNZ_ERRNO for IO error, or zLib error for uncompress error)
1229
extern int ZEXPORT unzReadCurrentFile (file, buf, len)
1237
file_in_zip_read_info_s* pfile_in_zip_read_info;
1239
return UNZ_PARAMERROR;
1241
pfile_in_zip_read_info=s->pfile_in_zip_read;
1243
if (pfile_in_zip_read_info==NULL)
1244
return UNZ_PARAMERROR;
1247
if ((pfile_in_zip_read_info->read_buffer == NULL))
1248
return UNZ_END_OF_LIST_OF_FILE;
1252
pfile_in_zip_read_info->stream.next_out = (Bytef*)buf;
1254
pfile_in_zip_read_info->stream.avail_out = (uInt)len;
1256
if ((len>pfile_in_zip_read_info->rest_read_uncompressed) &&
1257
(!(pfile_in_zip_read_info->raw)))
1258
pfile_in_zip_read_info->stream.avail_out =
1259
(uInt)pfile_in_zip_read_info->rest_read_uncompressed;
1261
if ((len>pfile_in_zip_read_info->rest_read_compressed+
1262
pfile_in_zip_read_info->stream.avail_in) &&
1263
(pfile_in_zip_read_info->raw))
1264
pfile_in_zip_read_info->stream.avail_out =
1265
(uInt)pfile_in_zip_read_info->rest_read_compressed+
1266
pfile_in_zip_read_info->stream.avail_in;
1268
while (pfile_in_zip_read_info->stream.avail_out>0)
1270
if ((pfile_in_zip_read_info->stream.avail_in==0) &&
1271
(pfile_in_zip_read_info->rest_read_compressed>0))
1273
uInt uReadThis = UNZ_BUFSIZE;
1274
if (pfile_in_zip_read_info->rest_read_compressed<uReadThis)
1275
uReadThis = (uInt)pfile_in_zip_read_info->rest_read_compressed;
1278
if (ZSEEK(pfile_in_zip_read_info->z_filefunc,
1279
pfile_in_zip_read_info->filestream,
1280
pfile_in_zip_read_info->pos_in_zipfile +
1281
pfile_in_zip_read_info->byte_before_the_zipfile,
1282
ZLIB_FILEFUNC_SEEK_SET)!=0)
1284
if (ZREAD(pfile_in_zip_read_info->z_filefunc,
1285
pfile_in_zip_read_info->filestream,
1286
pfile_in_zip_read_info->read_buffer,
1287
uReadThis)!=uReadThis)
1295
for(i=0;i<uReadThis;i++)
1296
pfile_in_zip_read_info->read_buffer[i] =
1297
zdecode(s->keys,s->pcrc_32_tab,
1298
pfile_in_zip_read_info->read_buffer[i]);
1303
pfile_in_zip_read_info->pos_in_zipfile += uReadThis;
1305
pfile_in_zip_read_info->rest_read_compressed-=uReadThis;
1307
pfile_in_zip_read_info->stream.next_in =
1308
(Bytef*)pfile_in_zip_read_info->read_buffer;
1309
pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis;
1312
if ((pfile_in_zip_read_info->compression_method==0) || (pfile_in_zip_read_info->raw))
1316
if ((pfile_in_zip_read_info->stream.avail_in == 0) &&
1317
(pfile_in_zip_read_info->rest_read_compressed == 0))
1318
return (iRead==0) ? UNZ_EOF : iRead;
1320
if (pfile_in_zip_read_info->stream.avail_out <
1321
pfile_in_zip_read_info->stream.avail_in)
1322
uDoCopy = pfile_in_zip_read_info->stream.avail_out ;
1324
uDoCopy = pfile_in_zip_read_info->stream.avail_in ;
1326
for (i=0;i<uDoCopy;i++)
1327
*(pfile_in_zip_read_info->stream.next_out+i) =
1328
*(pfile_in_zip_read_info->stream.next_in+i);
1330
pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,
1331
pfile_in_zip_read_info->stream.next_out,
1333
pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy;
1334
pfile_in_zip_read_info->stream.avail_in -= uDoCopy;
1335
pfile_in_zip_read_info->stream.avail_out -= uDoCopy;
1336
pfile_in_zip_read_info->stream.next_out += uDoCopy;
1337
pfile_in_zip_read_info->stream.next_in += uDoCopy;
1338
pfile_in_zip_read_info->stream.total_out += uDoCopy;
1343
uLong uTotalOutBefore,uTotalOutAfter;
1344
const Bytef *bufBefore;
1346
int flush=Z_SYNC_FLUSH;
1348
uTotalOutBefore = pfile_in_zip_read_info->stream.total_out;
1349
bufBefore = pfile_in_zip_read_info->stream.next_out;
1352
if ((pfile_in_zip_read_info->rest_read_uncompressed ==
1353
pfile_in_zip_read_info->stream.avail_out) &&
1354
(pfile_in_zip_read_info->rest_read_compressed == 0))
1357
err=inflate(&pfile_in_zip_read_info->stream,flush);
1359
if ((err>=0) && (pfile_in_zip_read_info->stream.msg!=NULL))
1362
uTotalOutAfter = pfile_in_zip_read_info->stream.total_out;
1363
uOutThis = uTotalOutAfter-uTotalOutBefore;
1365
pfile_in_zip_read_info->crc32 =
1366
crc32(pfile_in_zip_read_info->crc32,bufBefore,
1369
pfile_in_zip_read_info->rest_read_uncompressed -=
1372
iRead += (uInt)(uTotalOutAfter - uTotalOutBefore);
1374
if (err==Z_STREAM_END)
1375
return (iRead==0) ? UNZ_EOF : iRead;
1388
Give the current position in uncompressed data
1390
extern z_off_t ZEXPORT unztell (file)
1394
file_in_zip_read_info_s* pfile_in_zip_read_info;
1396
return UNZ_PARAMERROR;
1398
pfile_in_zip_read_info=s->pfile_in_zip_read;
1400
if (pfile_in_zip_read_info==NULL)
1401
return UNZ_PARAMERROR;
1403
return (z_off_t)pfile_in_zip_read_info->stream.total_out;
1408
return 1 if the end of file was reached, 0 elsewhere
1410
extern int ZEXPORT unzeof (file)
1414
file_in_zip_read_info_s* pfile_in_zip_read_info;
1416
return UNZ_PARAMERROR;
1418
pfile_in_zip_read_info=s->pfile_in_zip_read;
1420
if (pfile_in_zip_read_info==NULL)
1421
return UNZ_PARAMERROR;
1423
if (pfile_in_zip_read_info->rest_read_uncompressed == 0)
1432
Read extra field from the current file (opened by unzOpenCurrentFile)
1433
This is the local-header version of the extra field (sometimes, there is
1434
more info in the local-header version than in the central-header)
1436
if buf==NULL, it return the size of the local extra field that can be read
1438
if buf!=NULL, len is the size of the buffer, the extra header is copied in
1440
the return value is the number of bytes copied in buf, or (if <0)
1443
extern int ZEXPORT unzGetLocalExtrafield (file,buf,len)
1449
file_in_zip_read_info_s* pfile_in_zip_read_info;
1454
return UNZ_PARAMERROR;
1456
pfile_in_zip_read_info=s->pfile_in_zip_read;
1458
if (pfile_in_zip_read_info==NULL)
1459
return UNZ_PARAMERROR;
1461
size_to_read = (pfile_in_zip_read_info->size_local_extrafield -
1462
pfile_in_zip_read_info->pos_local_extrafield);
1465
return (int)size_to_read;
1467
if (len>size_to_read)
1468
read_now = (uInt)size_to_read;
1470
read_now = (uInt)len ;
1475
if (ZSEEK(pfile_in_zip_read_info->z_filefunc,
1476
pfile_in_zip_read_info->filestream,
1477
pfile_in_zip_read_info->offset_local_extrafield +
1478
pfile_in_zip_read_info->pos_local_extrafield,
1479
ZLIB_FILEFUNC_SEEK_SET)!=0)
1482
if (ZREAD(pfile_in_zip_read_info->z_filefunc,
1483
pfile_in_zip_read_info->filestream,
1484
buf,read_now)!=read_now)
1487
return (int)read_now;
1491
Close the file in zip opened with unzipOpenCurrentFile
1492
Return UNZ_CRCERROR if all the file was read but the CRC is not good
1494
extern int ZEXPORT unzCloseCurrentFile (file)
1500
file_in_zip_read_info_s* pfile_in_zip_read_info;
1502
return UNZ_PARAMERROR;
1504
pfile_in_zip_read_info=s->pfile_in_zip_read;
1506
if (pfile_in_zip_read_info==NULL)
1507
return UNZ_PARAMERROR;
1510
if ((pfile_in_zip_read_info->rest_read_uncompressed == 0) &&
1511
(!pfile_in_zip_read_info->raw))
1513
if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait)
1518
TRYFREE(pfile_in_zip_read_info->read_buffer);
1519
pfile_in_zip_read_info->read_buffer = NULL;
1520
if (pfile_in_zip_read_info->stream_initialised)
1521
inflateEnd(&pfile_in_zip_read_info->stream);
1523
pfile_in_zip_read_info->stream_initialised = 0;
1524
TRYFREE(pfile_in_zip_read_info);
1526
s->pfile_in_zip_read=NULL;
1533
Get the global comment string of the ZipFile, in the szComment buffer.
1534
uSizeBuf is the size of the szComment buffer.
1535
return the number of byte copied or an error code <0
1537
extern int ZEXPORT unzGetGlobalComment (file, szComment, uSizeBuf)
1545
return UNZ_PARAMERROR;
1548
uReadThis = uSizeBuf;
1549
if (uReadThis>s->gi.size_comment)
1550
uReadThis = s->gi.size_comment;
1552
if (ZSEEK(s->z_filefunc,s->filestream,s->central_pos+22,ZLIB_FILEFUNC_SEEK_SET)!=0)
1558
if (ZREAD(s->z_filefunc,s->filestream,szComment,uReadThis)!=uReadThis)
1562
if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment))
1563
*(szComment+s->gi.size_comment)='\0';
1564
return (int)uReadThis;
1567
/* Additions by RX '2004 */
1568
extern uLong ZEXPORT unzGetOffset (file)
1574
return UNZ_PARAMERROR;
1576
if (!s->current_file_ok)
1578
if (s->gi.number_entry != 0 && s->gi.number_entry != 0xffff)
1579
if (s->num_file==s->gi.number_entry)
1581
return s->pos_in_central_dir;
1584
extern int ZEXPORT unzSetOffset (file, pos)
1592
return UNZ_PARAMERROR;
1595
s->pos_in_central_dir = pos;
1596
s->num_file = s->gi.number_entry; /* hack */
1597
err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
1598
&s->cur_file_info_internal,
1599
NULL,0,NULL,0,NULL,0);
1600
s->current_file_ok = (err == UNZ_OK);