1 /* unzip.c -- IO for uncompress .zip files using zlib
2 Version 1.01h, December 28th, 2009
4 Copyright (C) 1998-2009 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).
60 /* compile with -Dlocal if your debugger can't find static symbols */
63 #ifndef CASESENSITIVITYDEFAULT_NO
64 # if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES)
65 # define CASESENSITIVITYDEFAULT_NO
71 #define UNZ_BUFSIZE (16384)
74 #ifndef UNZ_MAXFILENAMEINZIP
75 #define UNZ_MAXFILENAMEINZIP (256)
79 # define ALLOC(size) (malloc(size))
82 # define TRYFREE(p) {if (p) free(p);}
85 #define SIZECENTRALDIRITEM (0x2e)
86 #define SIZEZIPLOCALHEADER (0x1e)
91 const char unz_copyright[] =
92 " unzip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll";
94 /* unz_file_info_interntal contain internal info about a file in zipfile*/
95 typedef struct unz_file_info_internal_s
97 uLong offset_curfile;/* relative offset of local header 4 bytes */
98 } unz_file_info_internal;
101 /* file_in_zip_read_info_s contain internal information about a file in zipfile,
102 when reading and decompress it */
105 char *read_buffer; /* internal buffer for compressed data */
106 z_stream stream; /* zLib stream structure for inflate */
108 bz_stream bstream; /* bzLib stream structure for bziped */
111 uLong pos_in_zipfile; /* position in byte on the zipfile, for fseek*/
112 uLong stream_initialised; /* flag set if stream structure is initialised*/
114 uLong offset_local_extrafield;/* offset of the local extra field */
115 uInt size_local_extrafield;/* size of the local extra field */
116 uLong pos_local_extrafield; /* position in the local extra field in read*/
118 uLong crc32; /* crc32 of all data uncompressed */
119 uLong crc32_wait; /* crc32 we must obtain after decompress all */
120 uLong rest_read_compressed; /* number of byte to be decompressed */
121 uLong rest_read_uncompressed;/*number of byte to be obtained after decomp*/
122 zlib_filefunc_def z_filefunc;
123 voidpf filestream; /* io structore of the zipfile */
124 uLong compression_method; /* compression method (0==store) */
125 uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
127 } file_in_zip_read_info_s;
130 /* unz_s contain internal information about the zipfile
134 zlib_filefunc_def z_filefunc;
135 voidpf filestream; /* io structore of the zipfile */
136 unz_global_info gi; /* public global information */
137 uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
138 uLong num_file; /* number of the current file in the zipfile*/
139 uLong pos_in_central_dir; /* pos of the current file in the central dir*/
140 uLong current_file_ok; /* flag about the usability of the current file*/
141 uLong central_pos; /* position of the beginning of the central dir*/
143 uLong size_central_dir; /* size of the central directory */
144 uLong offset_central_dir; /* offset of start of central directory with
145 respect to the starting disk number */
147 unz_file_info cur_file_info; /* public info about the current file in zip*/
148 unz_file_info_internal cur_file_info_internal; /* private info about it*/
149 file_in_zip_read_info_s* pfile_in_zip_read; /* structure about the current
150 file if we are decompressing it */
153 unsigned long keys[3]; /* keys defining the pseudo-random sequence */
154 const unsigned long* pcrc_32_tab;
163 /* ===========================================================================
164 Read a byte from a gz_stream; update next_in and avail_in. Return EOF
166 IN assertion: the stream s has been sucessfully opened for reading.
170 local int unzlocal_getByte OF((
171 const zlib_filefunc_def* pzlib_filefunc_def,
175 local int unzlocal_getByte(pzlib_filefunc_def,filestream,pi)
176 const zlib_filefunc_def* pzlib_filefunc_def;
181 int err = (int)ZREAD(*pzlib_filefunc_def,filestream,&c,1);
189 if (ZERROR(*pzlib_filefunc_def,filestream))
197 /* ===========================================================================
198 Reads a long in LSB order from the given gz_stream. Sets
200 local int unzlocal_getShort OF((
201 const zlib_filefunc_def* pzlib_filefunc_def,
205 local int unzlocal_getShort (pzlib_filefunc_def,filestream,pX)
206 const zlib_filefunc_def* pzlib_filefunc_def;
214 err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
218 err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
228 local int unzlocal_getLong OF((
229 const zlib_filefunc_def* pzlib_filefunc_def,
233 local int unzlocal_getLong (pzlib_filefunc_def,filestream,pX)
234 const zlib_filefunc_def* pzlib_filefunc_def;
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);
254 err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
265 /* My own strcmpi / strcasecmp */
266 local int strcmpcasenosensitive_internal (fileName1,fileName2)
267 const char* fileName1;
268 const char* fileName2;
272 char c1=*(fileName1++);
273 char c2=*(fileName2++);
274 if ((c1>='a') && (c1<='z'))
276 if ((c2>='a') && (c2<='z'))
279 return ((c2=='\0') ? 0 : -1);
290 #ifdef CASESENSITIVITYDEFAULT_NO
291 #define CASESENSITIVITYDEFAULTVALUE 2
293 #define CASESENSITIVITYDEFAULTVALUE 1
296 #ifndef STRCMPCASENOSENTIVEFUNCTION
297 #define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal
301 Compare two filename (fileName1,fileName2).
302 If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
303 If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
305 If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
306 (like 1 on Unix, 2 on Windows)
309 extern int ZEXPORT unzStringFileNameCompare (fileName1,fileName2,iCaseSensitivity)
310 const char* fileName1;
311 const char* fileName2;
312 int iCaseSensitivity;
314 if (iCaseSensitivity==0)
315 iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE;
317 if (iCaseSensitivity==1)
318 return strcmp(fileName1,fileName2);
320 return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2);
323 #ifndef BUFREADCOMMENT
324 #define BUFREADCOMMENT (0x400)
328 Locate the Central directory of a zipfile (at the end, just before
331 local uLong unzlocal_SearchCentralDir OF((
332 const zlib_filefunc_def* pzlib_filefunc_def,
335 local uLong unzlocal_SearchCentralDir(pzlib_filefunc_def,filestream)
336 const zlib_filefunc_def* pzlib_filefunc_def;
342 uLong uMaxBack=0xffff; /* maximum size of global comment */
345 if (ZSEEK(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
349 uSizeFile = ZTELL(*pzlib_filefunc_def,filestream);
351 if (uMaxBack>uSizeFile)
352 uMaxBack = uSizeFile;
354 buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
359 while (uBackRead<uMaxBack)
361 uLong uReadSize,uReadPos ;
363 if (uBackRead+BUFREADCOMMENT>uMaxBack)
364 uBackRead = uMaxBack;
366 uBackRead+=BUFREADCOMMENT;
367 uReadPos = uSizeFile-uBackRead ;
369 uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
370 (BUFREADCOMMENT+4) : (uSizeFile-uReadPos);
371 if (ZSEEK(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
374 if (ZREAD(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
377 for (i=(int)uReadSize-3; (i--)>0;)
378 if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
379 ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
381 uPosFound = uReadPos+i;
393 Open a Zip file. path contain the full pathname (by example,
394 on a Windows NT computer "c:\\test\\zlib114.zip" or on an Unix computer
396 If the zipfile cannot be opened (file doesn't exist or in not valid), the
397 return value is NULL.
398 Else, the return value is a unzFile Handle, usable with other function
399 of this unzip package.
401 extern unzFile ZEXPORT unzOpen2 (path, pzlib_filefunc_def)
403 zlib_filefunc_def* pzlib_filefunc_def;
407 uLong central_pos,uL;
409 uLong number_disk; /* number of the current dist, used for
410 spaning ZIP, unsupported, always 0*/
411 uLong number_disk_with_CD; /* number the the disk with central dir, used
412 for spaning ZIP, unsupported, always 0*/
413 uLong number_entry_CD; /* total number of entries in
415 (same than number_entry on nospan) */
419 if (unz_copyright[0]!=' ')
422 if (pzlib_filefunc_def==NULL)
423 fill_fopen_filefunc(&us.z_filefunc);
425 us.z_filefunc = *pzlib_filefunc_def;
427 us.filestream= (*(us.z_filefunc.zopen_file))(us.z_filefunc.opaque,
429 ZLIB_FILEFUNC_MODE_READ |
430 ZLIB_FILEFUNC_MODE_EXISTING);
431 if (us.filestream==NULL)
434 central_pos = unzlocal_SearchCentralDir(&us.z_filefunc,us.filestream);
438 if (ZSEEK(us.z_filefunc, us.filestream,
439 central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
442 /* the signature, already checked */
443 if (unzlocal_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
446 /* number of this disk */
447 if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK)
450 /* number of the disk with the start of the central directory */
451 if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK)
454 /* total number of entries in the central dir on this disk */
455 if (unzlocal_getShort(&us.z_filefunc, us.filestream,&us.gi.number_entry)!=UNZ_OK)
458 /* total number of entries in the central dir */
459 if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_entry_CD)!=UNZ_OK)
462 if ((number_entry_CD!=us.gi.number_entry) ||
463 (number_disk_with_CD!=0) ||
467 /* size of the central directory */
468 if (unzlocal_getLong(&us.z_filefunc, us.filestream,&us.size_central_dir)!=UNZ_OK)
471 /* offset of start of central directory with respect to the
472 starting disk number */
473 if (unzlocal_getLong(&us.z_filefunc, us.filestream,&us.offset_central_dir)!=UNZ_OK)
476 /* zipfile comment length */
477 if (unzlocal_getShort(&us.z_filefunc, us.filestream,&us.gi.size_comment)!=UNZ_OK)
480 if ((central_pos<us.offset_central_dir+us.size_central_dir) &&
486 ZCLOSE(us.z_filefunc, us.filestream);
490 us.byte_before_the_zipfile = central_pos -
491 (us.offset_central_dir+us.size_central_dir);
492 us.central_pos = central_pos;
493 us.pfile_in_zip_read = NULL;
497 s=(unz_s*)ALLOC(sizeof(unz_s));
501 unzGoToFirstFile((unzFile)s);
507 extern unzFile ZEXPORT unzOpen (path)
510 return unzOpen2(path, NULL);
514 Close a ZipFile opened with unzipOpen.
515 If there is files inside the .Zip opened with unzipOpenCurrentFile (see later),
516 these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
517 return UNZ_OK if there is no problem. */
518 extern int ZEXPORT unzClose (file)
523 return UNZ_PARAMERROR;
526 if (s->pfile_in_zip_read!=NULL)
527 unzCloseCurrentFile(file);
529 ZCLOSE(s->z_filefunc, s->filestream);
536 Write info about the ZipFile in the *pglobal_info structure.
537 No preparation of the structure is needed
538 return UNZ_OK if there is no problem. */
539 extern int ZEXPORT unzGetGlobalInfo (file,pglobal_info)
541 unz_global_info *pglobal_info;
545 return UNZ_PARAMERROR;
553 Translate date/time from Dos format to tm_unz (readable more easilty)
555 local void unzlocal_DosDateToTmuDate (ulDosDate, ptm)
560 uDate = (uLong)(ulDosDate>>16);
561 ptm->tm_mday = (uInt)(uDate&0x1f) ;
562 ptm->tm_mon = (uInt)((((uDate)&0x1E0)/0x20)-1) ;
563 ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ;
565 ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800);
566 ptm->tm_min = (uInt) ((ulDosDate&0x7E0)/0x20) ;
567 ptm->tm_sec = (uInt) (2*(ulDosDate&0x1f)) ;
571 Get Info about the current file in the zipfile, with internal only info
573 local int unzlocal_GetCurrentFileInfoInternal OF((unzFile file,
574 unz_file_info *pfile_info,
575 unz_file_info_internal
576 *pfile_info_internal,
578 uLong fileNameBufferSize,
580 uLong extraFieldBufferSize,
582 uLong commentBufferSize));
584 local int unzlocal_GetCurrentFileInfoInternal (file,
587 szFileName, fileNameBufferSize,
588 extraField, extraFieldBufferSize,
589 szComment, commentBufferSize)
591 unz_file_info *pfile_info;
592 unz_file_info_internal *pfile_info_internal;
594 uLong fileNameBufferSize;
596 uLong extraFieldBufferSize;
598 uLong commentBufferSize;
601 unz_file_info file_info;
602 unz_file_info_internal file_info_internal;
608 return UNZ_PARAMERROR;
610 if (ZSEEK(s->z_filefunc, s->filestream,
611 s->pos_in_central_dir+s->byte_before_the_zipfile,
612 ZLIB_FILEFUNC_SEEK_SET)!=0)
616 /* we check the magic */
619 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)
621 else if (uMagic!=0x02014b50)
625 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.version) != UNZ_OK)
628 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.version_needed) != UNZ_OK)
631 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.flag) != UNZ_OK)
634 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.compression_method) != UNZ_OK)
637 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.dosDate) != UNZ_OK)
640 unzlocal_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date);
642 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.crc) != UNZ_OK)
645 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.compressed_size) != UNZ_OK)
648 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.uncompressed_size) != UNZ_OK)
651 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_filename) != UNZ_OK)
654 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_extra) != UNZ_OK)
657 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_comment) != UNZ_OK)
660 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.disk_num_start) != UNZ_OK)
663 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.internal_fa) != UNZ_OK)
666 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.external_fa) != UNZ_OK)
669 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info_internal.offset_curfile) != UNZ_OK)
672 lSeek+=file_info.size_filename;
673 if ((err==UNZ_OK) && (szFileName!=NULL))
676 if (file_info.size_filename<fileNameBufferSize)
678 *(szFileName+file_info.size_filename)='\0';
679 uSizeRead = file_info.size_filename;
682 uSizeRead = fileNameBufferSize;
684 if ((file_info.size_filename>0) && (fileNameBufferSize>0))
685 if (ZREAD(s->z_filefunc, s->filestream,szFileName,uSizeRead)!=uSizeRead)
691 if ((err==UNZ_OK) && (extraField!=NULL))
694 if (file_info.size_file_extra<extraFieldBufferSize)
695 uSizeRead = file_info.size_file_extra;
697 uSizeRead = extraFieldBufferSize;
701 if (ZSEEK(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
707 if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0))
708 if (ZREAD(s->z_filefunc, s->filestream,extraField,uSizeRead)!=uSizeRead)
710 lSeek += file_info.size_file_extra - uSizeRead;
713 lSeek+=file_info.size_file_extra;
716 if ((err==UNZ_OK) && (szComment!=NULL))
719 if (file_info.size_file_comment<commentBufferSize)
721 *(szComment+file_info.size_file_comment)='\0';
722 uSizeRead = file_info.size_file_comment;
725 uSizeRead = commentBufferSize;
729 if (ZSEEK(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
735 if ((file_info.size_file_comment>0) && (commentBufferSize>0))
736 if (ZREAD(s->z_filefunc, s->filestream,szComment,uSizeRead)!=uSizeRead)
738 lSeek+=file_info.size_file_comment - uSizeRead;
741 lSeek+=file_info.size_file_comment;
743 if ((err==UNZ_OK) && (pfile_info!=NULL))
744 *pfile_info=file_info;
746 if ((err==UNZ_OK) && (pfile_info_internal!=NULL))
747 *pfile_info_internal=file_info_internal;
755 Write info about the ZipFile in the *pglobal_info structure.
756 No preparation of the structure is needed
757 return UNZ_OK if there is no problem.
759 extern int ZEXPORT unzGetCurrentFileInfo (file,
761 szFileName, fileNameBufferSize,
762 extraField, extraFieldBufferSize,
763 szComment, commentBufferSize)
765 unz_file_info *pfile_info;
767 uLong fileNameBufferSize;
769 uLong extraFieldBufferSize;
771 uLong commentBufferSize;
773 return unzlocal_GetCurrentFileInfoInternal(file,pfile_info,NULL,
774 szFileName,fileNameBufferSize,
775 extraField,extraFieldBufferSize,
776 szComment,commentBufferSize);
780 Set the current file of the zipfile to the first file.
781 return UNZ_OK if there is no problem
783 extern int ZEXPORT unzGoToFirstFile (file)
789 return UNZ_PARAMERROR;
791 s->pos_in_central_dir=s->offset_central_dir;
793 err=unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
794 &s->cur_file_info_internal,
795 NULL,0,NULL,0,NULL,0);
796 s->current_file_ok = (err == UNZ_OK);
801 Set the current file of the zipfile to the next file.
802 return UNZ_OK if there is no problem
803 return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
805 extern int ZEXPORT unzGoToNextFile (file)
812 return UNZ_PARAMERROR;
814 if (!s->current_file_ok)
815 return UNZ_END_OF_LIST_OF_FILE;
816 if (s->gi.number_entry != 0xffff) /* 2^16 files overflow hack */
817 if (s->num_file+1==s->gi.number_entry)
818 return UNZ_END_OF_LIST_OF_FILE;
820 s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename +
821 s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ;
823 err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
824 &s->cur_file_info_internal,
825 NULL,0,NULL,0,NULL,0);
826 s->current_file_ok = (err == UNZ_OK);
832 Try locate the file szFileName in the zipfile.
833 For the iCaseSensitivity signification, see unzipStringFileNameCompare
836 UNZ_OK if the file is found. It becomes the current file.
837 UNZ_END_OF_LIST_OF_FILE if the file is not found
839 extern int ZEXPORT unzLocateFile (file, szFileName, iCaseSensitivity)
841 const char *szFileName;
842 int iCaseSensitivity;
847 /* We remember the 'current' position in the file so that we can jump
848 * back there if we fail.
850 unz_file_info cur_file_infoSaved;
851 unz_file_info_internal cur_file_info_internalSaved;
853 uLong pos_in_central_dirSaved;
857 return UNZ_PARAMERROR;
859 if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP)
860 return UNZ_PARAMERROR;
863 if (!s->current_file_ok)
864 return UNZ_END_OF_LIST_OF_FILE;
866 /* Save the current state */
867 num_fileSaved = s->num_file;
868 pos_in_central_dirSaved = s->pos_in_central_dir;
869 cur_file_infoSaved = s->cur_file_info;
870 cur_file_info_internalSaved = s->cur_file_info_internal;
872 err = unzGoToFirstFile(file);
874 while (err == UNZ_OK)
876 char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1];
877 err = unzGetCurrentFileInfo(file,NULL,
878 szCurrentFileName,sizeof(szCurrentFileName)-1,
882 if (unzStringFileNameCompare(szCurrentFileName,
883 szFileName,iCaseSensitivity)==0)
885 err = unzGoToNextFile(file);
889 /* We failed, so restore the state of the 'current file' to where we
892 s->num_file = num_fileSaved ;
893 s->pos_in_central_dir = pos_in_central_dirSaved ;
894 s->cur_file_info = cur_file_infoSaved;
895 s->cur_file_info_internal = cur_file_info_internalSaved;
901 ///////////////////////////////////////////
902 // Contributed by Ryan Haksi (mailto://cryogen@infoserve.net)
903 // I need random access
905 // Further optimization could be realized by adding an ability
906 // to cache the directory in memory. The goal being a single
907 // comprehensive file read to put the file I need in a memory.
911 typedef struct unz_file_pos_s
913 uLong pos_in_zip_directory; // offset in file
914 uLong num_of_file; // # of file
918 extern int ZEXPORT unzGetFilePos(file, file_pos)
920 unz_file_pos* file_pos;
924 if (file==NULL || file_pos==NULL)
925 return UNZ_PARAMERROR;
927 if (!s->current_file_ok)
928 return UNZ_END_OF_LIST_OF_FILE;
930 file_pos->pos_in_zip_directory = s->pos_in_central_dir;
931 file_pos->num_of_file = s->num_file;
936 extern int ZEXPORT unzGoToFilePos(file, file_pos)
938 unz_file_pos* file_pos;
943 if (file==NULL || file_pos==NULL)
944 return UNZ_PARAMERROR;
947 /* jump to the right spot */
948 s->pos_in_central_dir = file_pos->pos_in_zip_directory;
949 s->num_file = file_pos->num_of_file;
951 /* set the current file */
952 err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
953 &s->cur_file_info_internal,
954 NULL,0,NULL,0,NULL,0);
956 s->current_file_ok = (err == UNZ_OK);
961 // Unzip Helper Functions - should be here?
962 ///////////////////////////////////////////
966 Read the local header of the current zipfile
967 Check the coherency of the local header and info in the end of central
968 directory about this file
969 store in *piSizeVar the size of extra info in local header
970 (filename and size of extra field data)
972 local int unzlocal_CheckCurrentFileCoherencyHeader (s,piSizeVar,
973 poffset_local_extrafield,
974 psize_local_extrafield)
977 uLong *poffset_local_extrafield;
978 uInt *psize_local_extrafield;
980 uLong uMagic,uData,uFlags;
982 uLong size_extra_field;
986 *poffset_local_extrafield = 0;
987 *psize_local_extrafield = 0;
989 if (ZSEEK(s->z_filefunc, s->filestream,s->cur_file_info_internal.offset_curfile +
990 s->byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0)
996 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)
998 else if (uMagic!=0x04034b50)
1002 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK)
1005 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion))
1008 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uFlags) != UNZ_OK)
1011 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK)
1013 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method))
1016 if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) &&
1017 /* #ifdef HAVE_BZIP2 */
1018 (s->cur_file_info.compression_method!=Z_BZIP2ED) &&
1020 (s->cur_file_info.compression_method!=Z_DEFLATED))
1023 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* date/time */
1026 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* crc */
1028 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) &&
1032 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size compr */
1034 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) &&
1038 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size uncompr */
1040 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) &&
1045 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&size_filename) != UNZ_OK)
1047 else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename))
1050 *piSizeVar += (uInt)size_filename;
1052 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&size_extra_field) != UNZ_OK)
1054 *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile +
1055 SIZEZIPLOCALHEADER + size_filename;
1056 *psize_local_extrafield = (uInt)size_extra_field;
1058 *piSizeVar += (uInt)size_extra_field;
1064 Open for reading data the current file in the zipfile.
1065 If there is no error and the file is opened, the return value is UNZ_OK.
1067 extern int ZEXPORT unzOpenCurrentFile3 (file, method, level, raw, password)
1072 const char* password;
1077 file_in_zip_read_info_s* pfile_in_zip_read_info;
1078 uLong offset_local_extrafield; /* offset of the local extra field */
1079 uInt size_local_extrafield; /* size of the local extra field */
1083 if (password != NULL)
1084 return UNZ_PARAMERROR;
1088 return UNZ_PARAMERROR;
1090 if (!s->current_file_ok)
1091 return UNZ_PARAMERROR;
1093 if (s->pfile_in_zip_read != NULL)
1094 unzCloseCurrentFile(file);
1096 if (unzlocal_CheckCurrentFileCoherencyHeader(s,&iSizeVar,
1097 &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK)
1098 return UNZ_BADZIPFILE;
1100 pfile_in_zip_read_info = (file_in_zip_read_info_s*)
1101 ALLOC(sizeof(file_in_zip_read_info_s));
1102 if (pfile_in_zip_read_info==NULL)
1103 return UNZ_INTERNALERROR;
1105 pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE);
1106 pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield;
1107 pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield;
1108 pfile_in_zip_read_info->pos_local_extrafield=0;
1109 pfile_in_zip_read_info->raw=raw;
1111 if (pfile_in_zip_read_info->read_buffer==NULL)
1113 TRYFREE(pfile_in_zip_read_info);
1114 return UNZ_INTERNALERROR;
1117 pfile_in_zip_read_info->stream_initialised=0;
1120 *method = (int)s->cur_file_info.compression_method;
1125 switch (s->cur_file_info.flag & 0x06)
1127 case 6 : *level = 1; break;
1128 case 4 : *level = 2; break;
1129 case 2 : *level = 9; break;
1133 if ((s->cur_file_info.compression_method!=0) &&
1134 /* #ifdef HAVE_BZIP2 */
1135 (s->cur_file_info.compression_method!=Z_BZIP2ED) &&
1137 (s->cur_file_info.compression_method!=Z_DEFLATED))
1140 pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc;
1141 pfile_in_zip_read_info->crc32=0;
1142 pfile_in_zip_read_info->compression_method =
1143 s->cur_file_info.compression_method;
1144 pfile_in_zip_read_info->filestream=s->filestream;
1145 pfile_in_zip_read_info->z_filefunc=s->z_filefunc;
1146 pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile;
1148 pfile_in_zip_read_info->stream.total_out = 0;
1150 if ((s->cur_file_info.compression_method==Z_BZIP2ED) &&
1154 pfile_in_zip_read_info->bstream.bzalloc = (void *(*) (void *, int, int))0;
1155 pfile_in_zip_read_info->bstream.bzfree = (free_func)0;
1156 pfile_in_zip_read_info->bstream.opaque = (voidpf)0;
1157 pfile_in_zip_read_info->bstream.state = (voidpf)0;
1159 pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;
1160 pfile_in_zip_read_info->stream.zfree = (free_func)0;
1161 pfile_in_zip_read_info->stream.opaque = (voidpf)0;
1162 pfile_in_zip_read_info->stream.next_in = (voidpf)0;
1163 pfile_in_zip_read_info->stream.avail_in = 0;
1165 err=BZ2_bzDecompressInit(&pfile_in_zip_read_info->bstream, 0, 0);
1167 pfile_in_zip_read_info->stream_initialised=Z_BZIP2ED;
1170 TRYFREE(pfile_in_zip_read_info);
1174 pfile_in_zip_read_info->raw=1;
1178 if ((s->cur_file_info.compression_method==Z_DEFLATED) &&
1181 pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;
1182 pfile_in_zip_read_info->stream.zfree = (free_func)0;
1183 pfile_in_zip_read_info->stream.opaque = (voidpf)0;
1184 pfile_in_zip_read_info->stream.next_in = (voidpf)0;
1185 pfile_in_zip_read_info->stream.avail_in = 0;
1187 err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS);
1189 pfile_in_zip_read_info->stream_initialised=Z_DEFLATED;
1192 TRYFREE(pfile_in_zip_read_info);
1195 /* windowBits is passed < 0 to tell that there is no zlib header.
1196 * Note that in this case inflate *requires* an extra "dummy" byte
1197 * after the compressed stream in order to complete decompression and
1198 * return Z_STREAM_END.
1199 * In unzip, i don't wait absolutely Z_STREAM_END because I known the
1200 * size of both compressed and uncompressed data
1203 pfile_in_zip_read_info->rest_read_compressed =
1204 s->cur_file_info.compressed_size ;
1205 pfile_in_zip_read_info->rest_read_uncompressed =
1206 s->cur_file_info.uncompressed_size ;
1209 pfile_in_zip_read_info->pos_in_zipfile =
1210 s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER +
1213 pfile_in_zip_read_info->stream.avail_in = (uInt)0;
1215 s->pfile_in_zip_read = pfile_in_zip_read_info;
1220 if (password != NULL)
1223 s->pcrc_32_tab = get_crc_table();
1224 init_keys(password,s->keys,s->pcrc_32_tab);
1225 if (ZSEEK(s->z_filefunc, s->filestream,
1226 s->pfile_in_zip_read->pos_in_zipfile +
1227 s->pfile_in_zip_read->byte_before_the_zipfile,
1229 return UNZ_INTERNALERROR;
1230 if(ZREAD(s->z_filefunc, s->filestream,source, 12)<12)
1231 return UNZ_INTERNALERROR;
1233 for (i = 0; i<12; i++)
1234 zdecode(s->keys,s->pcrc_32_tab,source[i]);
1236 s->pfile_in_zip_read->pos_in_zipfile+=12;
1245 extern int ZEXPORT unzOpenCurrentFile (file)
1248 return unzOpenCurrentFile3(file, NULL, NULL, 0, NULL);
1251 extern int ZEXPORT unzOpenCurrentFilePassword (file, password)
1253 const char* password;
1255 return unzOpenCurrentFile3(file, NULL, NULL, 0, password);
1258 extern int ZEXPORT unzOpenCurrentFile2 (file,method,level,raw)
1264 return unzOpenCurrentFile3(file, method, level, raw, NULL);
1268 Read bytes from the current file.
1269 buf contain buffer where data must be copied
1270 len the size of buf.
1272 return the number of byte copied if somes bytes are copied
1273 return 0 if the end of file was reached
1274 return <0 with error code if there is an error
1275 (UNZ_ERRNO for IO error, or zLib error for uncompress error)
1277 extern int ZEXPORT unzReadCurrentFile (file, buf, len)
1285 file_in_zip_read_info_s* pfile_in_zip_read_info;
1287 return UNZ_PARAMERROR;
1289 pfile_in_zip_read_info=s->pfile_in_zip_read;
1291 if (pfile_in_zip_read_info==NULL)
1292 return UNZ_PARAMERROR;
1295 if (pfile_in_zip_read_info->read_buffer == NULL)
1296 return UNZ_END_OF_LIST_OF_FILE;
1300 pfile_in_zip_read_info->stream.next_out = (Bytef*)buf;
1302 pfile_in_zip_read_info->stream.avail_out = (uInt)len;
1304 if ((len>pfile_in_zip_read_info->rest_read_uncompressed) &&
1305 (!(pfile_in_zip_read_info->raw)))
1306 pfile_in_zip_read_info->stream.avail_out =
1307 (uInt)pfile_in_zip_read_info->rest_read_uncompressed;
1309 if ((len>pfile_in_zip_read_info->rest_read_compressed+
1310 pfile_in_zip_read_info->stream.avail_in) &&
1311 (pfile_in_zip_read_info->raw))
1312 pfile_in_zip_read_info->stream.avail_out =
1313 (uInt)pfile_in_zip_read_info->rest_read_compressed+
1314 pfile_in_zip_read_info->stream.avail_in;
1316 while (pfile_in_zip_read_info->stream.avail_out>0)
1318 if ((pfile_in_zip_read_info->stream.avail_in==0) &&
1319 (pfile_in_zip_read_info->rest_read_compressed>0))
1321 uInt uReadThis = UNZ_BUFSIZE;
1322 if (pfile_in_zip_read_info->rest_read_compressed<uReadThis)
1323 uReadThis = (uInt)pfile_in_zip_read_info->rest_read_compressed;
1326 if (ZSEEK(pfile_in_zip_read_info->z_filefunc,
1327 pfile_in_zip_read_info->filestream,
1328 pfile_in_zip_read_info->pos_in_zipfile +
1329 pfile_in_zip_read_info->byte_before_the_zipfile,
1330 ZLIB_FILEFUNC_SEEK_SET)!=0)
1332 if (ZREAD(pfile_in_zip_read_info->z_filefunc,
1333 pfile_in_zip_read_info->filestream,
1334 pfile_in_zip_read_info->read_buffer,
1335 uReadThis)!=uReadThis)
1343 for(i=0;i<uReadThis;i++)
1344 pfile_in_zip_read_info->read_buffer[i] =
1345 zdecode(s->keys,s->pcrc_32_tab,
1346 pfile_in_zip_read_info->read_buffer[i]);
1351 pfile_in_zip_read_info->pos_in_zipfile += uReadThis;
1353 pfile_in_zip_read_info->rest_read_compressed-=uReadThis;
1355 pfile_in_zip_read_info->stream.next_in =
1356 (Bytef*)pfile_in_zip_read_info->read_buffer;
1357 pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis;
1360 if ((pfile_in_zip_read_info->compression_method==0) || (pfile_in_zip_read_info->raw))
1364 if ((pfile_in_zip_read_info->stream.avail_in == 0) &&
1365 (pfile_in_zip_read_info->rest_read_compressed == 0))
1366 return (iRead==0) ? UNZ_EOF : iRead;
1368 if (pfile_in_zip_read_info->stream.avail_out <
1369 pfile_in_zip_read_info->stream.avail_in)
1370 uDoCopy = pfile_in_zip_read_info->stream.avail_out ;
1372 uDoCopy = pfile_in_zip_read_info->stream.avail_in ;
1374 for (i=0;i<uDoCopy;i++)
1375 *(pfile_in_zip_read_info->stream.next_out+i) =
1376 *(pfile_in_zip_read_info->stream.next_in+i);
1378 pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,
1379 pfile_in_zip_read_info->stream.next_out,
1381 pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy;
1382 pfile_in_zip_read_info->stream.avail_in -= uDoCopy;
1383 pfile_in_zip_read_info->stream.avail_out -= uDoCopy;
1384 pfile_in_zip_read_info->stream.next_out += uDoCopy;
1385 pfile_in_zip_read_info->stream.next_in += uDoCopy;
1386 pfile_in_zip_read_info->stream.total_out += uDoCopy;
1390 if (pfile_in_zip_read_info->compression_method==Z_BZIP2ED)
1393 uLong uTotalOutBefore,uTotalOutAfter;
1394 const Bytef *bufBefore;
1397 pfile_in_zip_read_info->bstream.next_in = pfile_in_zip_read_info->stream.next_in;
1398 pfile_in_zip_read_info->bstream.avail_in = pfile_in_zip_read_info->stream.avail_in;
1399 pfile_in_zip_read_info->bstream.total_in_lo32 = pfile_in_zip_read_info->stream.total_in;
1400 pfile_in_zip_read_info->bstream.total_in_hi32 = 0;
1401 pfile_in_zip_read_info->bstream.next_out = pfile_in_zip_read_info->stream.next_out;
1402 pfile_in_zip_read_info->bstream.avail_out = pfile_in_zip_read_info->stream.avail_out;
1403 pfile_in_zip_read_info->bstream.total_out_lo32 = pfile_in_zip_read_info->stream.total_out;
1404 pfile_in_zip_read_info->bstream.total_out_hi32 = 0;
1406 uTotalOutBefore = pfile_in_zip_read_info->bstream.total_out_lo32;
1407 bufBefore = pfile_in_zip_read_info->bstream.next_out;
1409 err=BZ2_bzDecompress(&pfile_in_zip_read_info->bstream);
1411 uTotalOutAfter = pfile_in_zip_read_info->bstream.total_out_lo32;
1412 uOutThis = uTotalOutAfter-uTotalOutBefore;
1414 pfile_in_zip_read_info->crc32 =
1415 crc32(pfile_in_zip_read_info->crc32,bufBefore,
1418 pfile_in_zip_read_info->rest_read_uncompressed -=
1421 iRead += (uInt)(uTotalOutAfter - uTotalOutBefore);
1423 pfile_in_zip_read_info->stream.next_in = pfile_in_zip_read_info->bstream.next_in;
1424 pfile_in_zip_read_info->stream.avail_in = pfile_in_zip_read_info->bstream.avail_in;
1425 pfile_in_zip_read_info->stream.total_in = pfile_in_zip_read_info->bstream.total_in_lo32;
1426 pfile_in_zip_read_info->stream.next_out = pfile_in_zip_read_info->bstream.next_out;
1427 pfile_in_zip_read_info->stream.avail_out = pfile_in_zip_read_info->bstream.avail_out;
1428 pfile_in_zip_read_info->stream.total_out = pfile_in_zip_read_info->bstream.total_out_lo32;
1430 if (err==BZ_STREAM_END)
1431 return (iRead==0) ? UNZ_EOF : iRead;
1438 uLong uTotalOutBefore,uTotalOutAfter;
1439 const Bytef *bufBefore;
1441 int flush=Z_SYNC_FLUSH;
1443 uTotalOutBefore = pfile_in_zip_read_info->stream.total_out;
1444 bufBefore = pfile_in_zip_read_info->stream.next_out;
1447 if ((pfile_in_zip_read_info->rest_read_uncompressed ==
1448 pfile_in_zip_read_info->stream.avail_out) &&
1449 (pfile_in_zip_read_info->rest_read_compressed == 0))
1452 err=inflate(&pfile_in_zip_read_info->stream,flush);
1454 if ((err>=0) && (pfile_in_zip_read_info->stream.msg!=NULL))
1457 uTotalOutAfter = pfile_in_zip_read_info->stream.total_out;
1458 uOutThis = uTotalOutAfter-uTotalOutBefore;
1460 pfile_in_zip_read_info->crc32 =
1461 crc32(pfile_in_zip_read_info->crc32,bufBefore,
1464 pfile_in_zip_read_info->rest_read_uncompressed -=
1467 iRead += (uInt)(uTotalOutAfter - uTotalOutBefore);
1469 if (err==Z_STREAM_END)
1470 return (iRead==0) ? UNZ_EOF : iRead;
1483 Give the current position in uncompressed data
1485 extern z_off_t ZEXPORT unztell (file)
1489 file_in_zip_read_info_s* pfile_in_zip_read_info;
1491 return UNZ_PARAMERROR;
1493 pfile_in_zip_read_info=s->pfile_in_zip_read;
1495 if (pfile_in_zip_read_info==NULL)
1496 return UNZ_PARAMERROR;
1498 return (z_off_t)pfile_in_zip_read_info->stream.total_out;
1503 return 1 if the end of file was reached, 0 elsewhere
1505 extern int ZEXPORT unzeof (file)
1509 file_in_zip_read_info_s* pfile_in_zip_read_info;
1511 return UNZ_PARAMERROR;
1513 pfile_in_zip_read_info=s->pfile_in_zip_read;
1515 if (pfile_in_zip_read_info==NULL)
1516 return UNZ_PARAMERROR;
1518 if (pfile_in_zip_read_info->rest_read_uncompressed == 0)
1527 Read extra field from the current file (opened by unzOpenCurrentFile)
1528 This is the local-header version of the extra field (sometimes, there is
1529 more info in the local-header version than in the central-header)
1531 if buf==NULL, it return the size of the local extra field that can be read
1533 if buf!=NULL, len is the size of the buffer, the extra header is copied in
1535 the return value is the number of bytes copied in buf, or (if <0)
1538 extern int ZEXPORT unzGetLocalExtrafield (file,buf,len)
1544 file_in_zip_read_info_s* pfile_in_zip_read_info;
1549 return UNZ_PARAMERROR;
1551 pfile_in_zip_read_info=s->pfile_in_zip_read;
1553 if (pfile_in_zip_read_info==NULL)
1554 return UNZ_PARAMERROR;
1556 size_to_read = (pfile_in_zip_read_info->size_local_extrafield -
1557 pfile_in_zip_read_info->pos_local_extrafield);
1560 return (int)size_to_read;
1562 if (len>size_to_read)
1563 read_now = (uInt)size_to_read;
1565 read_now = (uInt)len ;
1570 if (ZSEEK(pfile_in_zip_read_info->z_filefunc,
1571 pfile_in_zip_read_info->filestream,
1572 pfile_in_zip_read_info->offset_local_extrafield +
1573 pfile_in_zip_read_info->pos_local_extrafield,
1574 ZLIB_FILEFUNC_SEEK_SET)!=0)
1577 if (ZREAD(pfile_in_zip_read_info->z_filefunc,
1578 pfile_in_zip_read_info->filestream,
1579 buf,read_now)!=read_now)
1582 return (int)read_now;
1586 Close the file in zip opened with unzipOpenCurrentFile
1587 Return UNZ_CRCERROR if all the file was read but the CRC is not good
1589 extern int ZEXPORT unzCloseCurrentFile (file)
1595 file_in_zip_read_info_s* pfile_in_zip_read_info;
1597 return UNZ_PARAMERROR;
1599 pfile_in_zip_read_info=s->pfile_in_zip_read;
1601 if (pfile_in_zip_read_info==NULL)
1602 return UNZ_PARAMERROR;
1605 if ((pfile_in_zip_read_info->rest_read_uncompressed == 0) &&
1606 (!pfile_in_zip_read_info->raw))
1608 if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait)
1613 TRYFREE(pfile_in_zip_read_info->read_buffer);
1614 pfile_in_zip_read_info->read_buffer = NULL;
1615 if (pfile_in_zip_read_info->stream_initialised == Z_DEFLATED)
1616 inflateEnd(&pfile_in_zip_read_info->stream);
1618 else if (pfile_in_zip_read_info->stream_initialised == Z_BZIP2ED)
1619 BZ2_bzDecompressEnd(&pfile_in_zip_read_info->bstream);
1622 pfile_in_zip_read_info->stream_initialised = 0;
1623 TRYFREE(pfile_in_zip_read_info);
1625 s->pfile_in_zip_read=NULL;
1632 Get the global comment string of the ZipFile, in the szComment buffer.
1633 uSizeBuf is the size of the szComment buffer.
1634 return the number of byte copied or an error code <0
1636 extern int ZEXPORT unzGetGlobalComment (file, szComment, uSizeBuf)
1644 return UNZ_PARAMERROR;
1647 uReadThis = uSizeBuf;
1648 if (uReadThis>s->gi.size_comment)
1649 uReadThis = s->gi.size_comment;
1651 if (ZSEEK(s->z_filefunc,s->filestream,s->central_pos+22,ZLIB_FILEFUNC_SEEK_SET)!=0)
1657 if (ZREAD(s->z_filefunc,s->filestream,szComment,uReadThis)!=uReadThis)
1661 if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment))
1662 *(szComment+s->gi.size_comment)='\0';
1663 return (int)uReadThis;
1666 /* Additions by RX '2004 */
1667 extern uLong ZEXPORT unzGetOffset (file)
1675 if (!s->current_file_ok)
1677 if (s->gi.number_entry != 0 && s->gi.number_entry != 0xffff)
1678 if (s->num_file==s->gi.number_entry)
1680 return s->pos_in_central_dir;
1683 extern int ZEXPORT unzSetOffset (file, pos)
1691 return UNZ_PARAMERROR;
1694 s->pos_in_central_dir = pos;
1695 s->num_file = s->gi.number_entry; /* hack */
1696 err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
1697 &s->cur_file_info_internal,
1698 NULL,0,NULL,0,NULL,0);
1699 s->current_file_ok = (err == UNZ_OK);