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).
41 #include "ZLIB/zlib.h"
59 /* compile with -Dlocal if your debugger can't find static symbols */
62 #ifndef CASESENSITIVITYDEFAULT_NO
63 # if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES)
64 # define CASESENSITIVITYDEFAULT_NO
70 #define UNZ_BUFSIZE (16384)
73 #ifndef UNZ_MAXFILENAMEINZIP
74 #define UNZ_MAXFILENAMEINZIP (256)
78 # define ALLOC(size) (malloc(size))
81 # define TRYFREE(p) {if (p) free(p);}
84 #define SIZECENTRALDIRITEM (0x2e)
85 #define SIZEZIPLOCALHEADER (0x1e)
90 const char unz_copyright
[] =
91 " unzip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll";
93 /* unz_file_info_interntal contain internal info about a file in zipfile*/
94 typedef struct unz_file_info_internal_s
96 uLong offset_curfile
;/* relative offset of local header 4 bytes */
97 } unz_file_info_internal
;
100 /* file_in_zip_read_info_s contain internal information about a file in zipfile,
101 when reading and decompress it */
104 char *read_buffer
; /* internal buffer for compressed data */
105 z_stream stream
; /* zLib stream structure for inflate */
107 uLong pos_in_zipfile
; /* position in byte on the zipfile, for fseek*/
108 uLong stream_initialised
; /* flag set if stream structure is initialised*/
110 uLong offset_local_extrafield
;/* offset of the local extra field */
111 uInt size_local_extrafield
;/* size of the local extra field */
112 uLong pos_local_extrafield
; /* position in the local extra field in read*/
114 uLong crc32
; /* crc32 of all data uncompressed */
115 uLong crc32_wait
; /* crc32 we must obtain after decompress all */
116 uLong rest_read_compressed
; /* number of byte to be decompressed */
117 uLong rest_read_uncompressed
;/*number of byte to be obtained after decomp*/
118 zlib_filefunc_def z_filefunc
;
119 voidpf filestream
; /* io structore of the zipfile */
120 uLong compression_method
; /* compression method (0==store) */
121 uLong byte_before_the_zipfile
;/* byte before the zipfile, (>0 for sfx)*/
123 } file_in_zip_read_info_s
;
126 /* unz_s contain internal information about the zipfile
130 zlib_filefunc_def z_filefunc
;
131 voidpf filestream
; /* io structore of the zipfile */
132 unz_global_info gi
; /* public global information */
133 uLong byte_before_the_zipfile
;/* byte before the zipfile, (>0 for sfx)*/
134 uLong num_file
; /* number of the current file in the zipfile*/
135 uLong pos_in_central_dir
; /* pos of the current file in the central dir*/
136 uLong current_file_ok
; /* flag about the usability of the current file*/
137 uLong central_pos
; /* position of the beginning of the central dir*/
139 uLong size_central_dir
; /* size of the central directory */
140 uLong offset_central_dir
; /* offset of start of central directory with
141 respect to the starting disk number */
143 unz_file_info cur_file_info
; /* public info about the current file in zip*/
144 unz_file_info_internal cur_file_info_internal
; /* private info about it*/
145 file_in_zip_read_info_s
* pfile_in_zip_read
; /* structure about the current
146 file if we are decompressing it */
149 unsigned long keys
[3]; /* keys defining the pseudo-random sequence */
150 const unsigned long* pcrc_32_tab
;
159 /* ===========================================================================
160 Read a byte from a gz_stream; update next_in and avail_in. Return EOF
162 IN assertion: the stream s has been sucessfully opened for reading.
166 local
int unzlocal_getByte
OF((
167 const zlib_filefunc_def
* pzlib_filefunc_def
,
171 local
int unzlocal_getByte(pzlib_filefunc_def
,filestream
,pi
)
172 const zlib_filefunc_def
* pzlib_filefunc_def
;
177 int err
= (int)ZREAD(*pzlib_filefunc_def
,filestream
,&c
,1);
185 if (ZERROR(*pzlib_filefunc_def
,filestream
))
193 /* ===========================================================================
194 Reads a long in LSB order from the given gz_stream. Sets
196 local
int unzlocal_getShort
OF((
197 const zlib_filefunc_def
* pzlib_filefunc_def
,
201 local
int unzlocal_getShort (pzlib_filefunc_def
,filestream
,pX
)
202 const zlib_filefunc_def
* pzlib_filefunc_def
;
210 err
= unzlocal_getByte(pzlib_filefunc_def
,filestream
,&i
);
214 err
= unzlocal_getByte(pzlib_filefunc_def
,filestream
,&i
);
224 local
int unzlocal_getLong
OF((
225 const zlib_filefunc_def
* pzlib_filefunc_def
,
229 local
int unzlocal_getLong (pzlib_filefunc_def
,filestream
,pX
)
230 const zlib_filefunc_def
* pzlib_filefunc_def
;
238 err
= unzlocal_getByte(pzlib_filefunc_def
,filestream
,&i
);
242 err
= unzlocal_getByte(pzlib_filefunc_def
,filestream
,&i
);
246 err
= unzlocal_getByte(pzlib_filefunc_def
,filestream
,&i
);
250 err
= unzlocal_getByte(pzlib_filefunc_def
,filestream
,&i
);
261 /* My own strcmpi / strcasecmp */
262 local
int strcmpcasenosensitive_internal (fileName1
,fileName2
)
263 const char* fileName1
;
264 const char* fileName2
;
268 char c1
=*(fileName1
++);
269 char c2
=*(fileName2
++);
270 if ((c1
>='a') && (c1
<='z'))
272 if ((c2
>='a') && (c2
<='z'))
275 return ((c2
=='\0') ? 0 : -1);
286 #ifdef CASESENSITIVITYDEFAULT_NO
287 #define CASESENSITIVITYDEFAULTVALUE 2
289 #define CASESENSITIVITYDEFAULTVALUE 1
292 #ifndef STRCMPCASENOSENTIVEFUNCTION
293 #define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal
297 Compare two filename (fileName1,fileName2).
298 If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
299 If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
301 If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
302 (like 1 on Unix, 2 on Windows)
305 extern int ZEXPORT
unzStringFileNameCompare (fileName1
,fileName2
,iCaseSensitivity
)
306 const char* fileName1
;
307 const char* fileName2
;
308 int iCaseSensitivity
;
310 if (iCaseSensitivity
==0)
311 iCaseSensitivity
=CASESENSITIVITYDEFAULTVALUE
;
313 if (iCaseSensitivity
==1)
314 return strcmp(fileName1
,fileName2
);
316 return STRCMPCASENOSENTIVEFUNCTION(fileName1
,fileName2
);
319 #ifndef BUFREADCOMMENT
320 #define BUFREADCOMMENT (0x400)
324 Locate the Central directory of a zipfile (at the end, just before
327 local uLong unzlocal_SearchCentralDir
OF((
328 const zlib_filefunc_def
* pzlib_filefunc_def
,
331 local uLong
unzlocal_SearchCentralDir(pzlib_filefunc_def
,filestream
)
332 const zlib_filefunc_def
* pzlib_filefunc_def
;
338 uLong uMaxBack
=0xffff; /* maximum size of global comment */
341 if (ZSEEK(*pzlib_filefunc_def
,filestream
,0,ZLIB_FILEFUNC_SEEK_END
) != 0)
345 uSizeFile
= ZTELL(*pzlib_filefunc_def
,filestream
);
347 if (uMaxBack
>uSizeFile
)
348 uMaxBack
= uSizeFile
;
350 buf
= (unsigned char*)ALLOC(BUFREADCOMMENT
+4);
355 while (uBackRead
<uMaxBack
)
357 uLong uReadSize
,uReadPos
;
359 if (uBackRead
+BUFREADCOMMENT
>uMaxBack
)
360 uBackRead
= uMaxBack
;
362 uBackRead
+=BUFREADCOMMENT
;
363 uReadPos
= uSizeFile
-uBackRead
;
365 uReadSize
= ((BUFREADCOMMENT
+4) < (uSizeFile
-uReadPos
)) ?
366 (BUFREADCOMMENT
+4) : (uSizeFile
-uReadPos
);
367 if (ZSEEK(*pzlib_filefunc_def
,filestream
,uReadPos
,ZLIB_FILEFUNC_SEEK_SET
)!=0)
370 if (ZREAD(*pzlib_filefunc_def
,filestream
,buf
,uReadSize
)!=uReadSize
)
373 for (i
=(int)uReadSize
-3; (i
--)>0;)
374 if (((*(buf
+i
))==0x50) && ((*(buf
+i
+1))==0x4b) &&
375 ((*(buf
+i
+2))==0x05) && ((*(buf
+i
+3))==0x06))
377 uPosFound
= uReadPos
+i
;
389 Open a Zip file. path contain the full pathname (by example,
390 on a Windows NT computer "c:\\test\\zlib114.zip" or on an Unix computer
392 If the zipfile cannot be opened (file doesn't exist or in not valid), the
393 return value is NULL.
394 Else, the return value is a unzFile Handle, usable with other function
395 of this unzip package.
397 extern unzFile ZEXPORT
unzOpen2 (path
, pzlib_filefunc_def
)
399 zlib_filefunc_def
* pzlib_filefunc_def
;
403 uLong central_pos
,uL
;
405 uLong number_disk
; /* number of the current dist, used for
406 spaning ZIP, unsupported, always 0*/
407 uLong number_disk_with_CD
; /* number the the disk with central dir, used
408 for spaning ZIP, unsupported, always 0*/
409 uLong number_entry_CD
; /* total number of entries in
411 (same than number_entry on nospan) */
415 if (unz_copyright
[0]!=' ')
418 if (pzlib_filefunc_def
==NULL
)
419 fill_fopen_filefunc(&us
.z_filefunc
);
421 us
.z_filefunc
= *pzlib_filefunc_def
;
423 us
.filestream
= (*(us
.z_filefunc
.zopen_file
))(us
.z_filefunc
.opaque
,
425 ZLIB_FILEFUNC_MODE_READ
|
426 ZLIB_FILEFUNC_MODE_EXISTING
);
427 if (us
.filestream
==NULL
)
430 central_pos
= unzlocal_SearchCentralDir(&us
.z_filefunc
,us
.filestream
);
434 if (ZSEEK(us
.z_filefunc
, us
.filestream
,
435 central_pos
,ZLIB_FILEFUNC_SEEK_SET
)!=0)
438 /* the signature, already checked */
439 if (unzlocal_getLong(&us
.z_filefunc
, us
.filestream
,&uL
)!=UNZ_OK
)
442 /* number of this disk */
443 if (unzlocal_getShort(&us
.z_filefunc
, us
.filestream
,&number_disk
)!=UNZ_OK
)
446 /* number of the disk with the start of the central directory */
447 if (unzlocal_getShort(&us
.z_filefunc
, us
.filestream
,&number_disk_with_CD
)!=UNZ_OK
)
450 /* total number of entries in the central dir on this disk */
451 if (unzlocal_getShort(&us
.z_filefunc
, us
.filestream
,&us
.gi
.number_entry
)!=UNZ_OK
)
454 /* total number of entries in the central dir */
455 if (unzlocal_getShort(&us
.z_filefunc
, us
.filestream
,&number_entry_CD
)!=UNZ_OK
)
458 if ((number_entry_CD
!=us
.gi
.number_entry
) ||
459 (number_disk_with_CD
!=0) ||
463 /* size of the central directory */
464 if (unzlocal_getLong(&us
.z_filefunc
, us
.filestream
,&us
.size_central_dir
)!=UNZ_OK
)
467 /* offset of start of central directory with respect to the
468 starting disk number */
469 if (unzlocal_getLong(&us
.z_filefunc
, us
.filestream
,&us
.offset_central_dir
)!=UNZ_OK
)
472 /* zipfile comment length */
473 if (unzlocal_getShort(&us
.z_filefunc
, us
.filestream
,&us
.gi
.size_comment
)!=UNZ_OK
)
476 if ((central_pos
<us
.offset_central_dir
+us
.size_central_dir
) &&
482 ZCLOSE(us
.z_filefunc
, us
.filestream
);
486 us
.byte_before_the_zipfile
= central_pos
-
487 (us
.offset_central_dir
+us
.size_central_dir
);
488 us
.central_pos
= central_pos
;
489 us
.pfile_in_zip_read
= NULL
;
493 s
=(unz_s
*)ALLOC(sizeof(unz_s
));
495 unzGoToFirstFile((unzFile
)s
);
500 extern unzFile ZEXPORT
unzOpen (path
)
503 return unzOpen2(path
, NULL
);
507 Close a ZipFile opened with unzipOpen.
508 If there is files inside the .Zip opened with unzipOpenCurrentFile (see later),
509 these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
510 return UNZ_OK if there is no problem. */
511 extern int ZEXPORT
unzClose (file
)
516 return UNZ_PARAMERROR
;
519 if (s
->pfile_in_zip_read
!=NULL
)
520 unzCloseCurrentFile(file
);
522 ZCLOSE(s
->z_filefunc
, s
->filestream
);
529 Write info about the ZipFile in the *pglobal_info structure.
530 No preparation of the structure is needed
531 return UNZ_OK if there is no problem. */
532 extern int ZEXPORT
unzGetGlobalInfo (file
,pglobal_info
)
534 unz_global_info
*pglobal_info
;
538 return UNZ_PARAMERROR
;
546 Translate date/time from Dos format to tm_unz (readable more easilty)
548 local
void unzlocal_DosDateToTmuDate (ulDosDate
, ptm
)
553 uDate
= (uLong
)(ulDosDate
>>16);
554 ptm
->tm_mday
= (uInt
)(uDate
&0x1f) ;
555 ptm
->tm_mon
= (uInt
)((((uDate
)&0x1E0)/0x20)-1) ;
556 ptm
->tm_year
= (uInt
)(((uDate
&0x0FE00)/0x0200)+1980) ;
558 ptm
->tm_hour
= (uInt
) ((ulDosDate
&0xF800)/0x800);
559 ptm
->tm_min
= (uInt
) ((ulDosDate
&0x7E0)/0x20) ;
560 ptm
->tm_sec
= (uInt
) (2*(ulDosDate
&0x1f)) ;
564 Get Info about the current file in the zipfile, with internal only info
566 local
int unzlocal_GetCurrentFileInfoInternal
OF((unzFile file
,
567 unz_file_info
*pfile_info
,
568 unz_file_info_internal
569 *pfile_info_internal
,
571 uLong fileNameBufferSize
,
573 uLong extraFieldBufferSize
,
575 uLong commentBufferSize
));
577 local
int unzlocal_GetCurrentFileInfoInternal (file
,
580 szFileName
, fileNameBufferSize
,
581 extraField
, extraFieldBufferSize
,
582 szComment
, commentBufferSize
)
584 unz_file_info
*pfile_info
;
585 unz_file_info_internal
*pfile_info_internal
;
587 uLong fileNameBufferSize
;
589 uLong extraFieldBufferSize
;
591 uLong commentBufferSize
;
594 unz_file_info file_info
;
595 unz_file_info_internal file_info_internal
;
601 return UNZ_PARAMERROR
;
603 if (ZSEEK(s
->z_filefunc
, s
->filestream
,
604 s
->pos_in_central_dir
+s
->byte_before_the_zipfile
,
605 ZLIB_FILEFUNC_SEEK_SET
)!=0)
609 /* we check the magic */
611 if (unzlocal_getLong(&s
->z_filefunc
, s
->filestream
,&uMagic
) != UNZ_OK
)
613 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
;
691 if (ZSEEK(s
->z_filefunc
, s
->filestream
,lSeek
,ZLIB_FILEFUNC_SEEK_CUR
)==0)
695 if ((file_info
.size_file_extra
>0) && (extraFieldBufferSize
>0))
696 if (ZREAD(s
->z_filefunc
, s
->filestream
,extraField
,uSizeRead
)!=uSizeRead
)
698 lSeek
+= file_info
.size_file_extra
- uSizeRead
;
701 lSeek
+=file_info
.size_file_extra
;
704 if ((err
==UNZ_OK
) && (szComment
!=NULL
))
707 if (file_info
.size_file_comment
<commentBufferSize
)
709 *(szComment
+file_info
.size_file_comment
)='\0';
710 uSizeRead
= file_info
.size_file_comment
;
713 uSizeRead
= commentBufferSize
;
716 if (ZSEEK(s
->z_filefunc
, s
->filestream
,lSeek
,ZLIB_FILEFUNC_SEEK_CUR
)==0)
720 if ((file_info
.size_file_comment
>0) && (commentBufferSize
>0))
721 if (ZREAD(s
->z_filefunc
, s
->filestream
,szComment
,uSizeRead
)!=uSizeRead
)
723 lSeek
+=file_info
.size_file_comment
- uSizeRead
;
726 lSeek
+=file_info
.size_file_comment
;
728 if ((err
==UNZ_OK
) && (pfile_info
!=NULL
))
729 *pfile_info
=file_info
;
731 if ((err
==UNZ_OK
) && (pfile_info_internal
!=NULL
))
732 *pfile_info_internal
=file_info_internal
;
740 Write info about the ZipFile in the *pglobal_info structure.
741 No preparation of the structure is needed
742 return UNZ_OK if there is no problem.
744 extern int ZEXPORT
unzGetCurrentFileInfo (file
,
746 szFileName
, fileNameBufferSize
,
747 extraField
, extraFieldBufferSize
,
748 szComment
, commentBufferSize
)
750 unz_file_info
*pfile_info
;
752 uLong fileNameBufferSize
;
754 uLong extraFieldBufferSize
;
756 uLong commentBufferSize
;
758 return unzlocal_GetCurrentFileInfoInternal(file
,pfile_info
,NULL
,
759 szFileName
,fileNameBufferSize
,
760 extraField
,extraFieldBufferSize
,
761 szComment
,commentBufferSize
);
765 Set the current file of the zipfile to the first file.
766 return UNZ_OK if there is no problem
768 extern int ZEXPORT
unzGoToFirstFile (file
)
774 return UNZ_PARAMERROR
;
776 s
->pos_in_central_dir
=s
->offset_central_dir
;
778 err
=unzlocal_GetCurrentFileInfoInternal(file
,&s
->cur_file_info
,
779 &s
->cur_file_info_internal
,
780 NULL
,0,NULL
,0,NULL
,0);
781 s
->current_file_ok
= (err
== UNZ_OK
);
786 Set the current file of the zipfile to the next file.
787 return UNZ_OK if there is no problem
788 return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
790 extern int ZEXPORT
unzGoToNextFile (file
)
797 return UNZ_PARAMERROR
;
799 if (!s
->current_file_ok
)
800 return UNZ_END_OF_LIST_OF_FILE
;
801 if (s
->gi
.number_entry
!= 0xffff) /* 2^16 files overflow hack */
802 if (s
->num_file
+1==s
->gi
.number_entry
)
803 return UNZ_END_OF_LIST_OF_FILE
;
805 s
->pos_in_central_dir
+= SIZECENTRALDIRITEM
+ s
->cur_file_info
.size_filename
+
806 s
->cur_file_info
.size_file_extra
+ s
->cur_file_info
.size_file_comment
;
808 err
= unzlocal_GetCurrentFileInfoInternal(file
,&s
->cur_file_info
,
809 &s
->cur_file_info_internal
,
810 NULL
,0,NULL
,0,NULL
,0);
811 s
->current_file_ok
= (err
== UNZ_OK
);
817 Try locate the file szFileName in the zipfile.
818 For the iCaseSensitivity signification, see unzipStringFileNameCompare
821 UNZ_OK if the file is found. It becomes the current file.
822 UNZ_END_OF_LIST_OF_FILE if the file is not found
824 extern int ZEXPORT
unzLocateFile (file
, szFileName
, iCaseSensitivity
)
826 const char *szFileName
;
827 int iCaseSensitivity
;
832 /* We remember the 'current' position in the file so that we can jump
833 * back there if we fail.
835 unz_file_info cur_file_infoSaved
;
836 unz_file_info_internal cur_file_info_internalSaved
;
838 uLong pos_in_central_dirSaved
;
842 return UNZ_PARAMERROR
;
844 if (strlen(szFileName
)>=UNZ_MAXFILENAMEINZIP
)
845 return UNZ_PARAMERROR
;
848 if (!s
->current_file_ok
)
849 return UNZ_END_OF_LIST_OF_FILE
;
851 /* Save the current state */
852 num_fileSaved
= s
->num_file
;
853 pos_in_central_dirSaved
= s
->pos_in_central_dir
;
854 cur_file_infoSaved
= s
->cur_file_info
;
855 cur_file_info_internalSaved
= s
->cur_file_info_internal
;
857 err
= unzGoToFirstFile(file
);
859 while (err
== UNZ_OK
)
861 char szCurrentFileName
[UNZ_MAXFILENAMEINZIP
+1];
862 err
= unzGetCurrentFileInfo(file
,NULL
,
863 szCurrentFileName
,sizeof(szCurrentFileName
)-1,
867 if (unzStringFileNameCompare(szCurrentFileName
,
868 szFileName
,iCaseSensitivity
)==0)
870 err
= unzGoToNextFile(file
);
874 /* We failed, so restore the state of the 'current file' to where we
877 s
->num_file
= num_fileSaved
;
878 s
->pos_in_central_dir
= pos_in_central_dirSaved
;
879 s
->cur_file_info
= cur_file_infoSaved
;
880 s
->cur_file_info_internal
= cur_file_info_internalSaved
;
886 ///////////////////////////////////////////
887 // Contributed by Ryan Haksi (mailto://cryogen@infoserve.net)
888 // I need random access
890 // Further optimization could be realized by adding an ability
891 // to cache the directory in memory. The goal being a single
892 // comprehensive file read to put the file I need in a memory.
896 typedef struct unz_file_pos_s
898 uLong pos_in_zip_directory; // offset in file
899 uLong num_of_file; // # of file
903 extern int ZEXPORT
unzGetFilePos(file
, file_pos
)
905 unz_file_pos
* file_pos
;
909 if (file
==NULL
|| file_pos
==NULL
)
910 return UNZ_PARAMERROR
;
912 if (!s
->current_file_ok
)
913 return UNZ_END_OF_LIST_OF_FILE
;
915 file_pos
->pos_in_zip_directory
= s
->pos_in_central_dir
;
916 file_pos
->num_of_file
= s
->num_file
;
921 extern int ZEXPORT
unzGoToFilePos(file
, file_pos
)
923 unz_file_pos
* file_pos
;
928 if (file
==NULL
|| file_pos
==NULL
)
929 return UNZ_PARAMERROR
;
932 /* jump to the right spot */
933 s
->pos_in_central_dir
= file_pos
->pos_in_zip_directory
;
934 s
->num_file
= file_pos
->num_of_file
;
936 /* set the current file */
937 err
= unzlocal_GetCurrentFileInfoInternal(file
,&s
->cur_file_info
,
938 &s
->cur_file_info_internal
,
939 NULL
,0,NULL
,0,NULL
,0);
941 s
->current_file_ok
= (err
== UNZ_OK
);
946 // Unzip Helper Functions - should be here?
947 ///////////////////////////////////////////
951 Read the local header of the current zipfile
952 Check the coherency of the local header and info in the end of central
953 directory about this file
954 store in *piSizeVar the size of extra info in local header
955 (filename and size of extra field data)
957 local
int unzlocal_CheckCurrentFileCoherencyHeader (s
,piSizeVar
,
958 poffset_local_extrafield
,
959 psize_local_extrafield
)
962 uLong
*poffset_local_extrafield
;
963 uInt
*psize_local_extrafield
;
965 uLong uMagic
,uData
,uFlags
;
967 uLong size_extra_field
;
971 *poffset_local_extrafield
= 0;
972 *psize_local_extrafield
= 0;
974 if (ZSEEK(s
->z_filefunc
, s
->filestream
,s
->cur_file_info_internal
.offset_curfile
+
975 s
->byte_before_the_zipfile
,ZLIB_FILEFUNC_SEEK_SET
)!=0)
980 if (unzlocal_getLong(&s
->z_filefunc
, s
->filestream
,&uMagic
) != UNZ_OK
)
982 else if (uMagic
!=0x04034b50)
985 if (unzlocal_getShort(&s
->z_filefunc
, s
->filestream
,&uData
) != UNZ_OK
)
988 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion))
991 if (unzlocal_getShort(&s
->z_filefunc
, s
->filestream
,&uFlags
) != UNZ_OK
)
994 if (unzlocal_getShort(&s
->z_filefunc
, s
->filestream
,&uData
) != UNZ_OK
)
996 else if ((err
==UNZ_OK
) && (uData
!=s
->cur_file_info
.compression_method
))
999 if ((err
==UNZ_OK
) && (s
->cur_file_info
.compression_method
!=0) &&
1000 (s
->cur_file_info
.compression_method
!=Z_DEFLATED
))
1003 if (unzlocal_getLong(&s
->z_filefunc
, s
->filestream
,&uData
) != UNZ_OK
) /* date/time */
1006 if (unzlocal_getLong(&s
->z_filefunc
, s
->filestream
,&uData
) != UNZ_OK
) /* crc */
1008 else if ((err
==UNZ_OK
) && (uData
!=s
->cur_file_info
.crc
) &&
1012 if (unzlocal_getLong(&s
->z_filefunc
, s
->filestream
,&uData
) != UNZ_OK
) /* size compr */
1014 else if ((err
==UNZ_OK
) && (uData
!=s
->cur_file_info
.compressed_size
) &&
1018 if (unzlocal_getLong(&s
->z_filefunc
, s
->filestream
,&uData
) != UNZ_OK
) /* size uncompr */
1020 else if ((err
==UNZ_OK
) && (uData
!=s
->cur_file_info
.uncompressed_size
) &&
1025 if (unzlocal_getShort(&s
->z_filefunc
, s
->filestream
,&size_filename
) != UNZ_OK
)
1027 else if ((err
==UNZ_OK
) && (size_filename
!=s
->cur_file_info
.size_filename
))
1030 *piSizeVar
+= (uInt
)size_filename
;
1032 if (unzlocal_getShort(&s
->z_filefunc
, s
->filestream
,&size_extra_field
) != UNZ_OK
)
1034 *poffset_local_extrafield
= s
->cur_file_info_internal
.offset_curfile
+
1035 SIZEZIPLOCALHEADER
+ size_filename
;
1036 *psize_local_extrafield
= (uInt
)size_extra_field
;
1038 *piSizeVar
+= (uInt
)size_extra_field
;
1044 Open for reading data the current file in the zipfile.
1045 If there is no error and the file is opened, the return value is UNZ_OK.
1047 extern int ZEXPORT
unzOpenCurrentFile3 (file
, method
, level
, raw
, password
)
1052 const char* password
;
1057 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1058 uLong offset_local_extrafield
; /* offset of the local extra field */
1059 uInt size_local_extrafield
; /* size of the local extra field */
1063 if (password
!= NULL
)
1064 return UNZ_PARAMERROR
;
1068 return UNZ_PARAMERROR
;
1070 if (!s
->current_file_ok
)
1071 return UNZ_PARAMERROR
;
1073 if (s
->pfile_in_zip_read
!= NULL
)
1074 unzCloseCurrentFile(file
);
1076 if (unzlocal_CheckCurrentFileCoherencyHeader(s
,&iSizeVar
,
1077 &offset_local_extrafield
,&size_local_extrafield
)!=UNZ_OK
)
1078 return UNZ_BADZIPFILE
;
1080 pfile_in_zip_read_info
= (file_in_zip_read_info_s
*)
1081 ALLOC(sizeof(file_in_zip_read_info_s
));
1082 if (pfile_in_zip_read_info
==NULL
)
1083 return UNZ_INTERNALERROR
;
1085 pfile_in_zip_read_info
->read_buffer
=(char*)ALLOC(UNZ_BUFSIZE
);
1086 pfile_in_zip_read_info
->offset_local_extrafield
= offset_local_extrafield
;
1087 pfile_in_zip_read_info
->size_local_extrafield
= size_local_extrafield
;
1088 pfile_in_zip_read_info
->pos_local_extrafield
=0;
1089 pfile_in_zip_read_info
->raw
=raw
;
1091 if (pfile_in_zip_read_info
->read_buffer
==NULL
)
1093 TRYFREE(pfile_in_zip_read_info
);
1094 return UNZ_INTERNALERROR
;
1097 pfile_in_zip_read_info
->stream_initialised
=0;
1100 *method
= (int)s
->cur_file_info
.compression_method
;
1105 switch (s
->cur_file_info
.flag
& 0x06)
1107 case 6 : *level
= 1; break;
1108 case 4 : *level
= 2; break;
1109 case 2 : *level
= 9; break;
1113 if ((s
->cur_file_info
.compression_method
!=0) &&
1114 (s
->cur_file_info
.compression_method
!=Z_DEFLATED
))
1117 pfile_in_zip_read_info
->crc32_wait
=s
->cur_file_info
.crc
;
1118 pfile_in_zip_read_info
->crc32
=0;
1119 pfile_in_zip_read_info
->compression_method
=
1120 s
->cur_file_info
.compression_method
;
1121 pfile_in_zip_read_info
->filestream
=s
->filestream
;
1122 pfile_in_zip_read_info
->z_filefunc
=s
->z_filefunc
;
1123 pfile_in_zip_read_info
->byte_before_the_zipfile
=s
->byte_before_the_zipfile
;
1125 pfile_in_zip_read_info
->stream
.total_out
= 0;
1127 if ((s
->cur_file_info
.compression_method
==Z_DEFLATED
) &&
1130 pfile_in_zip_read_info
->stream
.zalloc
= (alloc_func
)0;
1131 pfile_in_zip_read_info
->stream
.zfree
= (free_func
)0;
1132 pfile_in_zip_read_info
->stream
.opaque
= (voidpf
)0;
1133 pfile_in_zip_read_info
->stream
.next_in
= (voidpf
)0;
1134 pfile_in_zip_read_info
->stream
.avail_in
= 0;
1136 err
=inflateInit2(&pfile_in_zip_read_info
->stream
, -MAX_WBITS
);
1138 pfile_in_zip_read_info
->stream_initialised
=1;
1141 TRYFREE(pfile_in_zip_read_info
);
1144 /* windowBits is passed < 0 to tell that there is no zlib header.
1145 * Note that in this case inflate *requires* an extra "dummy" byte
1146 * after the compressed stream in order to complete decompression and
1147 * return Z_STREAM_END.
1148 * In unzip, i don't wait absolutely Z_STREAM_END because I known the
1149 * size of both compressed and uncompressed data
1152 pfile_in_zip_read_info
->rest_read_compressed
=
1153 s
->cur_file_info
.compressed_size
;
1154 pfile_in_zip_read_info
->rest_read_uncompressed
=
1155 s
->cur_file_info
.uncompressed_size
;
1158 pfile_in_zip_read_info
->pos_in_zipfile
=
1159 s
->cur_file_info_internal
.offset_curfile
+ SIZEZIPLOCALHEADER
+
1162 pfile_in_zip_read_info
->stream
.avail_in
= (uInt
)0;
1164 s
->pfile_in_zip_read
= pfile_in_zip_read_info
;
1167 if (password
!= NULL
)
1170 s
->pcrc_32_tab
= get_crc_table();
1171 init_keys(password
,s
->keys
,s
->pcrc_32_tab
);
1172 if (ZSEEK(s
->z_filefunc
, s
->filestream
,
1173 s
->pfile_in_zip_read
->pos_in_zipfile
+
1174 s
->pfile_in_zip_read
->byte_before_the_zipfile
,
1176 return UNZ_INTERNALERROR
;
1177 if(ZREAD(s
->z_filefunc
, s
->filestream
,source
, 12)<12)
1178 return UNZ_INTERNALERROR
;
1180 for (i
= 0; i
<12; i
++)
1181 zdecode(s
->keys
,s
->pcrc_32_tab
,source
[i
]);
1183 s
->pfile_in_zip_read
->pos_in_zipfile
+=12;
1192 extern int ZEXPORT
unzOpenCurrentFile (file
)
1195 return unzOpenCurrentFile3(file
, NULL
, NULL
, 0, NULL
);
1198 extern int ZEXPORT
unzOpenCurrentFilePassword (file
, password
)
1200 const char* password
;
1202 return unzOpenCurrentFile3(file
, NULL
, NULL
, 0, password
);
1205 extern int ZEXPORT
unzOpenCurrentFile2 (file
,method
,level
,raw
)
1211 return unzOpenCurrentFile3(file
, method
, level
, raw
, NULL
);
1215 Read bytes from the current file.
1216 buf contain buffer where data must be copied
1217 len the size of buf.
1219 return the number of byte copied if somes bytes are copied
1220 return 0 if the end of file was reached
1221 return <0 with error code if there is an error
1222 (UNZ_ERRNO for IO error, or zLib error for uncompress error)
1224 extern int ZEXPORT
unzReadCurrentFile (file
, buf
, len
)
1232 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1234 return UNZ_PARAMERROR
;
1236 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1238 if (pfile_in_zip_read_info
==NULL
)
1239 return UNZ_PARAMERROR
;
1242 if ((pfile_in_zip_read_info
->read_buffer
== NULL
))
1243 return UNZ_END_OF_LIST_OF_FILE
;
1247 pfile_in_zip_read_info
->stream
.next_out
= (Bytef
*)buf
;
1249 pfile_in_zip_read_info
->stream
.avail_out
= (uInt
)len
;
1251 if ((len
>pfile_in_zip_read_info
->rest_read_uncompressed
) &&
1252 (!(pfile_in_zip_read_info
->raw
)))
1253 pfile_in_zip_read_info
->stream
.avail_out
=
1254 (uInt
)pfile_in_zip_read_info
->rest_read_uncompressed
;
1256 if ((len
>pfile_in_zip_read_info
->rest_read_compressed
+
1257 pfile_in_zip_read_info
->stream
.avail_in
) &&
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_compressed
+
1261 pfile_in_zip_read_info
->stream
.avail_in
;
1263 while (pfile_in_zip_read_info
->stream
.avail_out
>0)
1265 if ((pfile_in_zip_read_info
->stream
.avail_in
==0) &&
1266 (pfile_in_zip_read_info
->rest_read_compressed
>0))
1268 uInt uReadThis
= UNZ_BUFSIZE
;
1269 if (pfile_in_zip_read_info
->rest_read_compressed
<uReadThis
)
1270 uReadThis
= (uInt
)pfile_in_zip_read_info
->rest_read_compressed
;
1273 if (ZSEEK(pfile_in_zip_read_info
->z_filefunc
,
1274 pfile_in_zip_read_info
->filestream
,
1275 pfile_in_zip_read_info
->pos_in_zipfile
+
1276 pfile_in_zip_read_info
->byte_before_the_zipfile
,
1277 ZLIB_FILEFUNC_SEEK_SET
)!=0)
1279 if (ZREAD(pfile_in_zip_read_info
->z_filefunc
,
1280 pfile_in_zip_read_info
->filestream
,
1281 pfile_in_zip_read_info
->read_buffer
,
1282 uReadThis
)!=uReadThis
)
1290 for(i
=0;i
<uReadThis
;i
++)
1291 pfile_in_zip_read_info
->read_buffer
[i
] =
1292 zdecode(s
->keys
,s
->pcrc_32_tab
,
1293 pfile_in_zip_read_info
->read_buffer
[i
]);
1298 pfile_in_zip_read_info
->pos_in_zipfile
+= uReadThis
;
1300 pfile_in_zip_read_info
->rest_read_compressed
-=uReadThis
;
1302 pfile_in_zip_read_info
->stream
.next_in
=
1303 (Bytef
*)pfile_in_zip_read_info
->read_buffer
;
1304 pfile_in_zip_read_info
->stream
.avail_in
= (uInt
)uReadThis
;
1307 if ((pfile_in_zip_read_info
->compression_method
==0) || (pfile_in_zip_read_info
->raw
))
1311 if ((pfile_in_zip_read_info
->stream
.avail_in
== 0) &&
1312 (pfile_in_zip_read_info
->rest_read_compressed
== 0))
1313 return (iRead
==0) ? UNZ_EOF
: iRead
;
1315 if (pfile_in_zip_read_info
->stream
.avail_out
<
1316 pfile_in_zip_read_info
->stream
.avail_in
)
1317 uDoCopy
= pfile_in_zip_read_info
->stream
.avail_out
;
1319 uDoCopy
= pfile_in_zip_read_info
->stream
.avail_in
;
1321 for (i
=0;i
<uDoCopy
;i
++)
1322 *(pfile_in_zip_read_info
->stream
.next_out
+i
) =
1323 *(pfile_in_zip_read_info
->stream
.next_in
+i
);
1325 pfile_in_zip_read_info
->crc32
= crc32(pfile_in_zip_read_info
->crc32
,
1326 pfile_in_zip_read_info
->stream
.next_out
,
1328 pfile_in_zip_read_info
->rest_read_uncompressed
-=uDoCopy
;
1329 pfile_in_zip_read_info
->stream
.avail_in
-= uDoCopy
;
1330 pfile_in_zip_read_info
->stream
.avail_out
-= uDoCopy
;
1331 pfile_in_zip_read_info
->stream
.next_out
+= uDoCopy
;
1332 pfile_in_zip_read_info
->stream
.next_in
+= uDoCopy
;
1333 pfile_in_zip_read_info
->stream
.total_out
+= uDoCopy
;
1338 uLong uTotalOutBefore
,uTotalOutAfter
;
1339 const Bytef
*bufBefore
;
1341 int flush
=Z_SYNC_FLUSH
;
1343 uTotalOutBefore
= pfile_in_zip_read_info
->stream
.total_out
;
1344 bufBefore
= pfile_in_zip_read_info
->stream
.next_out
;
1347 if ((pfile_in_zip_read_info->rest_read_uncompressed ==
1348 pfile_in_zip_read_info->stream.avail_out) &&
1349 (pfile_in_zip_read_info->rest_read_compressed == 0))
1352 err
=inflate(&pfile_in_zip_read_info
->stream
,flush
);
1354 if ((err
>=0) && (pfile_in_zip_read_info
->stream
.msg
!=NULL
))
1357 uTotalOutAfter
= pfile_in_zip_read_info
->stream
.total_out
;
1358 uOutThis
= uTotalOutAfter
-uTotalOutBefore
;
1360 pfile_in_zip_read_info
->crc32
=
1361 crc32(pfile_in_zip_read_info
->crc32
,bufBefore
,
1364 pfile_in_zip_read_info
->rest_read_uncompressed
-=
1367 iRead
+= (uInt
)(uTotalOutAfter
- uTotalOutBefore
);
1369 if (err
==Z_STREAM_END
)
1370 return (iRead
==0) ? UNZ_EOF
: iRead
;
1383 Give the current position in uncompressed data
1385 extern z_off_t ZEXPORT
unztell (file
)
1389 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1391 return UNZ_PARAMERROR
;
1393 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1395 if (pfile_in_zip_read_info
==NULL
)
1396 return UNZ_PARAMERROR
;
1398 return (z_off_t
)pfile_in_zip_read_info
->stream
.total_out
;
1403 return 1 if the end of file was reached, 0 elsewhere
1405 extern int ZEXPORT
unzeof (file
)
1409 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1411 return UNZ_PARAMERROR
;
1413 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1415 if (pfile_in_zip_read_info
==NULL
)
1416 return UNZ_PARAMERROR
;
1418 if (pfile_in_zip_read_info
->rest_read_uncompressed
== 0)
1427 Read extra field from the current file (opened by unzOpenCurrentFile)
1428 This is the local-header version of the extra field (sometimes, there is
1429 more info in the local-header version than in the central-header)
1431 if buf==NULL, it return the size of the local extra field that can be read
1433 if buf!=NULL, len is the size of the buffer, the extra header is copied in
1435 the return value is the number of bytes copied in buf, or (if <0)
1438 extern int ZEXPORT
unzGetLocalExtrafield (file
,buf
,len
)
1444 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1449 return UNZ_PARAMERROR
;
1451 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1453 if (pfile_in_zip_read_info
==NULL
)
1454 return UNZ_PARAMERROR
;
1456 size_to_read
= (pfile_in_zip_read_info
->size_local_extrafield
-
1457 pfile_in_zip_read_info
->pos_local_extrafield
);
1460 return (int)size_to_read
;
1462 if (len
>size_to_read
)
1463 read_now
= (uInt
)size_to_read
;
1465 read_now
= (uInt
)len
;
1470 if (ZSEEK(pfile_in_zip_read_info
->z_filefunc
,
1471 pfile_in_zip_read_info
->filestream
,
1472 pfile_in_zip_read_info
->offset_local_extrafield
+
1473 pfile_in_zip_read_info
->pos_local_extrafield
,
1474 ZLIB_FILEFUNC_SEEK_SET
)!=0)
1477 if (ZREAD(pfile_in_zip_read_info
->z_filefunc
,
1478 pfile_in_zip_read_info
->filestream
,
1479 buf
,read_now
)!=read_now
)
1482 return (int)read_now
;
1486 Close the file in zip opened with unzipOpenCurrentFile
1487 Return UNZ_CRCERROR if all the file was read but the CRC is not good
1489 extern int ZEXPORT
unzCloseCurrentFile (file
)
1495 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1497 return UNZ_PARAMERROR
;
1499 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1501 if (pfile_in_zip_read_info
==NULL
)
1502 return UNZ_PARAMERROR
;
1505 if ((pfile_in_zip_read_info
->rest_read_uncompressed
== 0) &&
1506 (!pfile_in_zip_read_info
->raw
))
1508 if (pfile_in_zip_read_info
->crc32
!= pfile_in_zip_read_info
->crc32_wait
)
1513 TRYFREE(pfile_in_zip_read_info
->read_buffer
);
1514 pfile_in_zip_read_info
->read_buffer
= NULL
;
1515 if (pfile_in_zip_read_info
->stream_initialised
)
1516 inflateEnd(&pfile_in_zip_read_info
->stream
);
1518 pfile_in_zip_read_info
->stream_initialised
= 0;
1519 TRYFREE(pfile_in_zip_read_info
);
1521 s
->pfile_in_zip_read
=NULL
;
1528 Get the global comment string of the ZipFile, in the szComment buffer.
1529 uSizeBuf is the size of the szComment buffer.
1530 return the number of byte copied or an error code <0
1532 extern int ZEXPORT
unzGetGlobalComment (file
, szComment
, uSizeBuf
)
1541 return UNZ_PARAMERROR
;
1544 uReadThis
= uSizeBuf
;
1545 if (uReadThis
>s
->gi
.size_comment
)
1546 uReadThis
= s
->gi
.size_comment
;
1548 if (ZSEEK(s
->z_filefunc
,s
->filestream
,s
->central_pos
+22,ZLIB_FILEFUNC_SEEK_SET
)!=0)
1554 if (ZREAD(s
->z_filefunc
,s
->filestream
,szComment
,uReadThis
)!=uReadThis
)
1558 if ((szComment
!= NULL
) && (uSizeBuf
> s
->gi
.size_comment
))
1559 *(szComment
+s
->gi
.size_comment
)='\0';
1560 return (int)uReadThis
;
1563 /* Additions by RX '2004 */
1564 extern uLong ZEXPORT
unzGetOffset (file
)
1570 return UNZ_PARAMERROR
;
1572 if (!s
->current_file_ok
)
1574 if (s
->gi
.number_entry
!= 0 && s
->gi
.number_entry
!= 0xffff)
1575 if (s
->num_file
==s
->gi
.number_entry
)
1577 return s
->pos_in_central_dir
;
1580 extern int ZEXPORT
unzSetOffset (file
, pos
)
1588 return UNZ_PARAMERROR
;
1591 s
->pos_in_central_dir
= pos
;
1592 s
->num_file
= s
->gi
.number_entry
; /* hack */
1593 err
= unzlocal_GetCurrentFileInfoInternal(file
,&s
->cur_file_info
,
1594 &s
->cur_file_info_internal
,
1595 NULL
,0,NULL
,0,NULL
,0);
1596 s
->current_file_ok
= (err
== UNZ_OK
);