1 /* unzip.c -- IO for uncompress .zip files using zlib
\r
2 Version 1.01e, February 12th, 2005
\r
4 Copyright (C) 1998-2005 Gilles Vollant
\r
6 Read unzip.h for more info
\r
9 /* Decryption code comes from crypt.c by Info-ZIP but has been greatly reduced in terms of
\r
10 compatibility with older software. The following is from the original crypt.c. Code
\r
11 woven in by Terry Thorsen 1/2003.
\r
14 Copyright (c) 1990-2000 Info-ZIP. All rights reserved.
\r
16 See the accompanying file LICENSE, version 2000-Apr-09 or later
\r
17 (the contents of which are also included in zip.h) for terms of use.
\r
18 If, for some reason, all these files are missing, the Info-ZIP license
\r
19 also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
\r
22 crypt.c (full version) by Info-ZIP. Last revised: [see crypt.h]
\r
24 The encryption/decryption parts of this source code (as opposed to the
\r
25 non-echoing password parts) were originally written in Europe. The
\r
26 whole source package can be freely distributed, including from the USA.
\r
27 (Prior to January 2000, re-export from the US was a violation of US law.)
\r
31 This encryption code is a direct transcription of the algorithm from
\r
32 Roger Schlafly, described by Phil Katz in the file appnote.txt. This
\r
33 file (appnote.txt) is distributed with the PKZIP program (even in the
\r
34 version without encryption capabilities).
\r
45 # include <stddef.h>
\r
46 # include <string.h>
\r
47 # include <stdlib.h>
\r
57 # define local static
\r
59 /* compile with -Dlocal if your debugger can't find static symbols */
\r
62 #ifndef CASESENSITIVITYDEFAULT_NO
\r
63 # if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES)
\r
64 # define CASESENSITIVITYDEFAULT_NO
\r
70 #define UNZ_BUFSIZE (16384)
\r
73 #ifndef UNZ_MAXFILENAMEINZIP
\r
74 #define UNZ_MAXFILENAMEINZIP (256)
\r
78 # define ALLOC(size) (malloc(size))
\r
81 # define TRYFREE(p) {if (p) free(p);}
\r
84 #define SIZECENTRALDIRITEM (0x2e)
\r
85 #define SIZEZIPLOCALHEADER (0x1e)
\r
90 const char unz_copyright[] =
\r
91 " unzip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll";
\r
93 /* unz_file_info_interntal contain internal info about a file in zipfile*/
\r
94 typedef struct unz_file_info_internal_s
\r
96 uLong offset_curfile;/* relative offset of local header 4 bytes */
\r
97 } unz_file_info_internal;
\r
100 /* file_in_zip_read_info_s contain internal information about a file in zipfile,
\r
101 when reading and decompress it */
\r
104 char *read_buffer; /* internal buffer for compressed data */
\r
105 z_stream stream; /* zLib stream structure for inflate */
\r
107 uLong pos_in_zipfile; /* position in byte on the zipfile, for fseek*/
\r
108 uLong stream_initialised; /* flag set if stream structure is initialised*/
\r
110 uLong offset_local_extrafield;/* offset of the local extra field */
\r
111 uInt size_local_extrafield;/* size of the local extra field */
\r
112 uLong pos_local_extrafield; /* position in the local extra field in read*/
\r
114 uLong crc32; /* crc32 of all data uncompressed */
\r
115 uLong crc32_wait; /* crc32 we must obtain after decompress all */
\r
116 uLong rest_read_compressed; /* number of byte to be decompressed */
\r
117 uLong rest_read_uncompressed;/*number of byte to be obtained after decomp*/
\r
118 zlib_filefunc_def z_filefunc;
\r
119 voidpf filestream; /* io structore of the zipfile */
\r
120 uLong compression_method; /* compression method (0==store) */
\r
121 uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
\r
123 } file_in_zip_read_info_s;
\r
126 /* unz_s contain internal information about the zipfile
\r
130 zlib_filefunc_def z_filefunc;
\r
131 voidpf filestream; /* io structore of the zipfile */
\r
132 unz_global_info gi; /* public global information */
\r
133 uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
\r
134 uLong num_file; /* number of the current file in the zipfile*/
\r
135 uLong pos_in_central_dir; /* pos of the current file in the central dir*/
\r
136 uLong current_file_ok; /* flag about the usability of the current file*/
\r
137 uLong central_pos; /* position of the beginning of the central dir*/
\r
139 uLong size_central_dir; /* size of the central directory */
\r
140 uLong offset_central_dir; /* offset of start of central directory with
\r
141 respect to the starting disk number */
\r
143 unz_file_info cur_file_info; /* public info about the current file in zip*/
\r
144 unz_file_info_internal cur_file_info_internal; /* private info about it*/
\r
145 file_in_zip_read_info_s* pfile_in_zip_read; /* structure about the current
\r
146 file if we are decompressing it */
\r
149 unsigned long keys[3]; /* keys defining the pseudo-random sequence */
\r
150 const unsigned long* pcrc_32_tab;
\r
159 /* ===========================================================================
\r
160 Read a byte from a gz_stream; update next_in and avail_in. Return EOF
\r
162 IN assertion: the stream s has been sucessfully opened for reading.
\r
166 local int unzlocal_getByte OF((
\r
167 const zlib_filefunc_def* pzlib_filefunc_def,
\r
171 local int unzlocal_getByte(pzlib_filefunc_def,filestream,pi)
\r
172 const zlib_filefunc_def* pzlib_filefunc_def;
\r
177 int err = (int)ZREAD(*pzlib_filefunc_def,filestream,&c,1);
\r
185 if (ZERROR(*pzlib_filefunc_def,filestream))
\r
193 /* ===========================================================================
\r
194 Reads a long in LSB order from the given gz_stream. Sets
\r
196 local int unzlocal_getShort OF((
\r
197 const zlib_filefunc_def* pzlib_filefunc_def,
\r
201 local int unzlocal_getShort (pzlib_filefunc_def,filestream,pX)
\r
202 const zlib_filefunc_def* pzlib_filefunc_def;
\r
210 err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
\r
214 err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
\r
215 x += ((uLong)i)<<8;
\r
224 local int unzlocal_getLong OF((
\r
225 const zlib_filefunc_def* pzlib_filefunc_def,
\r
229 local int unzlocal_getLong (pzlib_filefunc_def,filestream,pX)
\r
230 const zlib_filefunc_def* pzlib_filefunc_def;
\r
238 err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
\r
242 err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
\r
243 x += ((uLong)i)<<8;
\r
246 err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
\r
247 x += ((uLong)i)<<16;
\r
250 err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
\r
251 x += ((uLong)i)<<24;
\r
261 /* My own strcmpi / strcasecmp */
\r
262 local int strcmpcasenosensitive_internal (fileName1,fileName2)
\r
263 const char* fileName1;
\r
264 const char* fileName2;
\r
268 char c1=*(fileName1++);
\r
269 char c2=*(fileName2++);
\r
270 if ((c1>='a') && (c1<='z'))
\r
272 if ((c2>='a') && (c2<='z'))
\r
275 return ((c2=='\0') ? 0 : -1);
\r
286 #ifdef CASESENSITIVITYDEFAULT_NO
\r
287 #define CASESENSITIVITYDEFAULTVALUE 2
\r
289 #define CASESENSITIVITYDEFAULTVALUE 1
\r
292 #ifndef STRCMPCASENOSENTIVEFUNCTION
\r
293 #define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal
\r
297 Compare two filename (fileName1,fileName2).
\r
298 If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
\r
299 If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
\r
301 If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
\r
302 (like 1 on Unix, 2 on Windows)
\r
305 extern int ZEXPORT unzStringFileNameCompare (fileName1,fileName2,iCaseSensitivity)
\r
306 const char* fileName1;
\r
307 const char* fileName2;
\r
308 int iCaseSensitivity;
\r
310 if (iCaseSensitivity==0)
\r
311 iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE;
\r
313 if (iCaseSensitivity==1)
\r
314 return strcmp(fileName1,fileName2);
\r
316 return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2);
\r
319 #ifndef BUFREADCOMMENT
\r
320 #define BUFREADCOMMENT (0x400)
\r
324 Locate the Central directory of a zipfile (at the end, just before
\r
325 the global comment)
\r
327 local uLong unzlocal_SearchCentralDir OF((
\r
328 const zlib_filefunc_def* pzlib_filefunc_def,
\r
329 voidpf filestream));
\r
331 local uLong unzlocal_SearchCentralDir(pzlib_filefunc_def,filestream)
\r
332 const zlib_filefunc_def* pzlib_filefunc_def;
\r
335 unsigned char* buf;
\r
338 uLong uMaxBack=0xffff; /* maximum size of global comment */
\r
341 if (ZSEEK(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
\r
345 uSizeFile = ZTELL(*pzlib_filefunc_def,filestream);
\r
347 if (uMaxBack>uSizeFile)
\r
348 uMaxBack = uSizeFile;
\r
350 buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
\r
355 while (uBackRead<uMaxBack)
\r
357 uLong uReadSize,uReadPos ;
\r
359 if (uBackRead+BUFREADCOMMENT>uMaxBack)
\r
360 uBackRead = uMaxBack;
\r
362 uBackRead+=BUFREADCOMMENT;
\r
363 uReadPos = uSizeFile-uBackRead ;
\r
365 uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
\r
366 (BUFREADCOMMENT+4) : (uSizeFile-uReadPos);
\r
367 if (ZSEEK(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
\r
370 if (ZREAD(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
\r
373 for (i=(int)uReadSize-3; (i--)>0;)
\r
374 if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
\r
375 ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
\r
377 uPosFound = uReadPos+i;
\r
389 Open a Zip file. path contain the full pathname (by example,
\r
390 on a Windows NT computer "c:\\test\\zlib114.zip" or on an Unix computer
\r
391 "zlib/zlib114.zip".
\r
392 If the zipfile cannot be opened (file doesn't exist or in not valid), the
\r
393 return value is NULL.
\r
394 Else, the return value is a unzFile Handle, usable with other function
\r
395 of this unzip package.
\r
397 extern unzFile ZEXPORT unzOpen2 (path, pzlib_filefunc_def)
\r
399 zlib_filefunc_def* pzlib_filefunc_def;
\r
403 uLong central_pos,uL;
\r
405 uLong number_disk; /* number of the current dist, used for
\r
406 spaning ZIP, unsupported, always 0*/
\r
407 uLong number_disk_with_CD; /* number the the disk with central dir, used
\r
408 for spaning ZIP, unsupported, always 0*/
\r
409 uLong number_entry_CD; /* total number of entries in
\r
411 (same than number_entry on nospan) */
\r
415 if (unz_copyright[0]!=' ')
\r
418 if (pzlib_filefunc_def==NULL)
\r
419 fill_fopen_filefunc(&us.z_filefunc);
\r
421 us.z_filefunc = *pzlib_filefunc_def;
\r
423 us.filestream= (*(us.z_filefunc.zopen_file))(us.z_filefunc.opaque,
\r
425 ZLIB_FILEFUNC_MODE_READ |
\r
426 ZLIB_FILEFUNC_MODE_EXISTING);
\r
427 if (us.filestream==NULL)
\r
430 central_pos = unzlocal_SearchCentralDir(&us.z_filefunc,us.filestream);
\r
431 if (central_pos==0)
\r
434 if (ZSEEK(us.z_filefunc, us.filestream,
\r
435 central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
\r
438 /* the signature, already checked */
\r
439 if (unzlocal_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
\r
442 /* number of this disk */
\r
443 if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK)
\r
446 /* number of the disk with the start of the central directory */
\r
447 if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK)
\r
450 /* total number of entries in the central dir on this disk */
\r
451 if (unzlocal_getShort(&us.z_filefunc, us.filestream,&us.gi.number_entry)!=UNZ_OK)
\r
454 /* total number of entries in the central dir */
\r
455 if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_entry_CD)!=UNZ_OK)
\r
458 if ((number_entry_CD!=us.gi.number_entry) ||
\r
459 (number_disk_with_CD!=0) ||
\r
461 err=UNZ_BADZIPFILE;
\r
463 /* size of the central directory */
\r
464 if (unzlocal_getLong(&us.z_filefunc, us.filestream,&us.size_central_dir)!=UNZ_OK)
\r
467 /* offset of start of central directory with respect to the
\r
468 starting disk number */
\r
469 if (unzlocal_getLong(&us.z_filefunc, us.filestream,&us.offset_central_dir)!=UNZ_OK)
\r
472 /* zipfile comment length */
\r
473 if (unzlocal_getShort(&us.z_filefunc, us.filestream,&us.gi.size_comment)!=UNZ_OK)
\r
476 if ((central_pos<us.offset_central_dir+us.size_central_dir) &&
\r
478 err=UNZ_BADZIPFILE;
\r
482 ZCLOSE(us.z_filefunc, us.filestream);
\r
486 us.byte_before_the_zipfile = central_pos -
\r
487 (us.offset_central_dir+us.size_central_dir);
\r
488 us.central_pos = central_pos;
\r
489 us.pfile_in_zip_read = NULL;
\r
493 s=(unz_s*)ALLOC(sizeof(unz_s));
\r
495 unzGoToFirstFile((unzFile)s);
\r
500 extern unzFile ZEXPORT unzOpen (path)
\r
503 return unzOpen2(path, NULL);
\r
507 Close a ZipFile opened with unzipOpen.
\r
508 If there is files inside the .Zip opened with unzipOpenCurrentFile (see later),
\r
509 these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
\r
510 return UNZ_OK if there is no problem. */
\r
511 extern int ZEXPORT unzClose (file)
\r
516 return UNZ_PARAMERROR;
\r
519 if (s->pfile_in_zip_read!=NULL)
\r
520 unzCloseCurrentFile(file);
\r
522 ZCLOSE(s->z_filefunc, s->filestream);
\r
529 Write info about the ZipFile in the *pglobal_info structure.
\r
530 No preparation of the structure is needed
\r
531 return UNZ_OK if there is no problem. */
\r
532 extern int ZEXPORT unzGetGlobalInfo (file,pglobal_info)
\r
534 unz_global_info *pglobal_info;
\r
538 return UNZ_PARAMERROR;
\r
540 *pglobal_info=s->gi;
\r
546 Translate date/time from Dos format to tm_unz (readable more easilty)
\r
548 local void unzlocal_DosDateToTmuDate (ulDosDate, ptm)
\r
553 uDate = (uLong)(ulDosDate>>16);
\r
554 ptm->tm_mday = (uInt)(uDate&0x1f) ;
\r
555 ptm->tm_mon = (uInt)((((uDate)&0x1E0)/0x20)-1) ;
\r
556 ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ;
\r
558 ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800);
\r
559 ptm->tm_min = (uInt) ((ulDosDate&0x7E0)/0x20) ;
\r
560 ptm->tm_sec = (uInt) (2*(ulDosDate&0x1f)) ;
\r
564 Get Info about the current file in the zipfile, with internal only info
\r
566 local int unzlocal_GetCurrentFileInfoInternal OF((unzFile file,
\r
567 unz_file_info *pfile_info,
\r
568 unz_file_info_internal
\r
569 *pfile_info_internal,
\r
571 uLong fileNameBufferSize,
\r
573 uLong extraFieldBufferSize,
\r
575 uLong commentBufferSize));
\r
577 local int unzlocal_GetCurrentFileInfoInternal (file,
\r
579 pfile_info_internal,
\r
580 szFileName, fileNameBufferSize,
\r
581 extraField, extraFieldBufferSize,
\r
582 szComment, commentBufferSize)
\r
584 unz_file_info *pfile_info;
\r
585 unz_file_info_internal *pfile_info_internal;
\r
587 uLong fileNameBufferSize;
\r
589 uLong extraFieldBufferSize;
\r
591 uLong commentBufferSize;
\r
594 unz_file_info file_info;
\r
595 unz_file_info_internal file_info_internal;
\r
601 return UNZ_PARAMERROR;
\r
603 if (ZSEEK(s->z_filefunc, s->filestream,
\r
604 s->pos_in_central_dir+s->byte_before_the_zipfile,
\r
605 ZLIB_FILEFUNC_SEEK_SET)!=0)
\r
609 /* we check the magic */
\r
612 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)
\r
614 else if (uMagic!=0x02014b50)
\r
615 err=UNZ_BADZIPFILE;
\r
618 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.version) != UNZ_OK)
\r
621 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.version_needed) != UNZ_OK)
\r
624 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.flag) != UNZ_OK)
\r
627 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.compression_method) != UNZ_OK)
\r
630 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.dosDate) != UNZ_OK)
\r
633 unzlocal_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date);
\r
635 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.crc) != UNZ_OK)
\r
638 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.compressed_size) != UNZ_OK)
\r
641 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.uncompressed_size) != UNZ_OK)
\r
644 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_filename) != UNZ_OK)
\r
647 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_extra) != UNZ_OK)
\r
650 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_comment) != UNZ_OK)
\r
653 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.disk_num_start) != UNZ_OK)
\r
656 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.internal_fa) != UNZ_OK)
\r
659 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.external_fa) != UNZ_OK)
\r
662 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info_internal.offset_curfile) != UNZ_OK)
\r
665 lSeek+=file_info.size_filename;
\r
666 if ((err==UNZ_OK) && (szFileName!=NULL))
\r
669 if (file_info.size_filename<fileNameBufferSize)
\r
671 *(szFileName+file_info.size_filename)='\0';
\r
672 uSizeRead = file_info.size_filename;
\r
675 uSizeRead = fileNameBufferSize;
\r
677 if ((file_info.size_filename>0) && (fileNameBufferSize>0))
\r
678 if (ZREAD(s->z_filefunc, s->filestream,szFileName,uSizeRead)!=uSizeRead)
\r
680 lSeek -= uSizeRead;
\r
684 if ((err==UNZ_OK) && (extraField!=NULL))
\r
687 if (file_info.size_file_extra<extraFieldBufferSize)
\r
688 uSizeRead = file_info.size_file_extra;
\r
690 uSizeRead = extraFieldBufferSize;
\r
694 if (ZSEEK(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
\r
699 if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0))
\r
700 if (ZREAD(s->z_filefunc, s->filestream,extraField,uSizeRead)!=uSizeRead)
\r
702 lSeek += file_info.size_file_extra - uSizeRead;
\r
705 lSeek+=file_info.size_file_extra;
\r
708 if ((err==UNZ_OK) && (szComment!=NULL))
\r
711 if (file_info.size_file_comment<commentBufferSize)
\r
713 *(szComment+file_info.size_file_comment)='\0';
\r
714 uSizeRead = file_info.size_file_comment;
\r
717 uSizeRead = commentBufferSize;
\r
721 if (ZSEEK(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
\r
726 if ((file_info.size_file_comment>0) && (commentBufferSize>0))
\r
727 if (ZREAD(s->z_filefunc, s->filestream,szComment,uSizeRead)!=uSizeRead)
\r
729 lSeek+=file_info.size_file_comment - uSizeRead;
\r
732 lSeek+=file_info.size_file_comment;
\r
734 if ((err==UNZ_OK) && (pfile_info!=NULL))
\r
735 *pfile_info=file_info;
\r
737 if ((err==UNZ_OK) && (pfile_info_internal!=NULL))
\r
738 *pfile_info_internal=file_info_internal;
\r
746 Write info about the ZipFile in the *pglobal_info structure.
\r
747 No preparation of the structure is needed
\r
748 return UNZ_OK if there is no problem.
\r
750 extern int ZEXPORT unzGetCurrentFileInfo (file,
\r
752 szFileName, fileNameBufferSize,
\r
753 extraField, extraFieldBufferSize,
\r
754 szComment, commentBufferSize)
\r
756 unz_file_info *pfile_info;
\r
758 uLong fileNameBufferSize;
\r
760 uLong extraFieldBufferSize;
\r
762 uLong commentBufferSize;
\r
764 return unzlocal_GetCurrentFileInfoInternal(file,pfile_info,NULL,
\r
765 szFileName,fileNameBufferSize,
\r
766 extraField,extraFieldBufferSize,
\r
767 szComment,commentBufferSize);
\r
771 Set the current file of the zipfile to the first file.
\r
772 return UNZ_OK if there is no problem
\r
774 extern int ZEXPORT unzGoToFirstFile (file)
\r
780 return UNZ_PARAMERROR;
\r
782 s->pos_in_central_dir=s->offset_central_dir;
\r
784 err=unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
\r
785 &s->cur_file_info_internal,
\r
786 NULL,0,NULL,0,NULL,0);
\r
787 s->current_file_ok = (err == UNZ_OK);
\r
792 Set the current file of the zipfile to the next file.
\r
793 return UNZ_OK if there is no problem
\r
794 return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
\r
796 extern int ZEXPORT unzGoToNextFile (file)
\r
803 return UNZ_PARAMERROR;
\r
805 if (!s->current_file_ok)
\r
806 return UNZ_END_OF_LIST_OF_FILE;
\r
807 if (s->gi.number_entry != 0xffff) /* 2^16 files overflow hack */
\r
808 if (s->num_file+1==s->gi.number_entry)
\r
809 return UNZ_END_OF_LIST_OF_FILE;
\r
811 s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename +
\r
812 s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ;
\r
814 err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
\r
815 &s->cur_file_info_internal,
\r
816 NULL,0,NULL,0,NULL,0);
\r
817 s->current_file_ok = (err == UNZ_OK);
\r
823 Try locate the file szFileName in the zipfile.
\r
824 For the iCaseSensitivity signification, see unzipStringFileNameCompare
\r
827 UNZ_OK if the file is found. It becomes the current file.
\r
828 UNZ_END_OF_LIST_OF_FILE if the file is not found
\r
830 extern int ZEXPORT unzLocateFile (file, szFileName, iCaseSensitivity)
\r
832 const char *szFileName;
\r
833 int iCaseSensitivity;
\r
838 /* We remember the 'current' position in the file so that we can jump
\r
839 * back there if we fail.
\r
841 unz_file_info cur_file_infoSaved;
\r
842 unz_file_info_internal cur_file_info_internalSaved;
\r
843 uLong num_fileSaved;
\r
844 uLong pos_in_central_dirSaved;
\r
848 return UNZ_PARAMERROR;
\r
850 if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP)
\r
851 return UNZ_PARAMERROR;
\r
854 if (!s->current_file_ok)
\r
855 return UNZ_END_OF_LIST_OF_FILE;
\r
857 /* Save the current state */
\r
858 num_fileSaved = s->num_file;
\r
859 pos_in_central_dirSaved = s->pos_in_central_dir;
\r
860 cur_file_infoSaved = s->cur_file_info;
\r
861 cur_file_info_internalSaved = s->cur_file_info_internal;
\r
863 err = unzGoToFirstFile(file);
\r
865 while (err == UNZ_OK)
\r
867 char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1];
\r
868 err = unzGetCurrentFileInfo(file,NULL,
\r
869 szCurrentFileName,sizeof(szCurrentFileName)-1,
\r
873 if (unzStringFileNameCompare(szCurrentFileName,
\r
874 szFileName,iCaseSensitivity)==0)
\r
876 err = unzGoToNextFile(file);
\r
880 /* We failed, so restore the state of the 'current file' to where we
\r
883 s->num_file = num_fileSaved ;
\r
884 s->pos_in_central_dir = pos_in_central_dirSaved ;
\r
885 s->cur_file_info = cur_file_infoSaved;
\r
886 s->cur_file_info_internal = cur_file_info_internalSaved;
\r
892 ///////////////////////////////////////////
\r
893 // Contributed by Ryan Haksi (mailto://cryogen@infoserve.net)
\r
894 // I need random access
\r
896 // Further optimization could be realized by adding an ability
\r
897 // to cache the directory in memory. The goal being a single
\r
898 // comprehensive file read to put the file I need in a memory.
\r
902 typedef struct unz_file_pos_s
\r
904 uLong pos_in_zip_directory; // offset in file
\r
905 uLong num_of_file; // # of file
\r
909 extern int ZEXPORT unzGetFilePos(file, file_pos)
\r
911 unz_file_pos* file_pos;
\r
915 if (file==NULL || file_pos==NULL)
\r
916 return UNZ_PARAMERROR;
\r
918 if (!s->current_file_ok)
\r
919 return UNZ_END_OF_LIST_OF_FILE;
\r
921 file_pos->pos_in_zip_directory = s->pos_in_central_dir;
\r
922 file_pos->num_of_file = s->num_file;
\r
927 extern int ZEXPORT unzGoToFilePos(file, file_pos)
\r
929 unz_file_pos* file_pos;
\r
934 if (file==NULL || file_pos==NULL)
\r
935 return UNZ_PARAMERROR;
\r
938 /* jump to the right spot */
\r
939 s->pos_in_central_dir = file_pos->pos_in_zip_directory;
\r
940 s->num_file = file_pos->num_of_file;
\r
942 /* set the current file */
\r
943 err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
\r
944 &s->cur_file_info_internal,
\r
945 NULL,0,NULL,0,NULL,0);
\r
946 /* return results */
\r
947 s->current_file_ok = (err == UNZ_OK);
\r
952 // Unzip Helper Functions - should be here?
\r
953 ///////////////////////////////////////////
\r
957 Read the local header of the current zipfile
\r
958 Check the coherency of the local header and info in the end of central
\r
959 directory about this file
\r
960 store in *piSizeVar the size of extra info in local header
\r
961 (filename and size of extra field data)
\r
963 local int unzlocal_CheckCurrentFileCoherencyHeader (s,piSizeVar,
\r
964 poffset_local_extrafield,
\r
965 psize_local_extrafield)
\r
968 uLong *poffset_local_extrafield;
\r
969 uInt *psize_local_extrafield;
\r
971 uLong uMagic,uData,uFlags;
\r
972 uLong size_filename;
\r
973 uLong size_extra_field;
\r
977 *poffset_local_extrafield = 0;
\r
978 *psize_local_extrafield = 0;
\r
980 if (ZSEEK(s->z_filefunc, s->filestream,s->cur_file_info_internal.offset_curfile +
\r
981 s->byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0)
\r
987 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)
\r
989 else if (uMagic!=0x04034b50)
\r
990 err=UNZ_BADZIPFILE;
\r
992 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK)
\r
995 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion))
\r
996 err=UNZ_BADZIPFILE;
\r
998 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uFlags) != UNZ_OK)
\r
1001 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK)
\r
1003 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method))
\r
1004 err=UNZ_BADZIPFILE;
\r
1006 if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) &&
\r
1007 (s->cur_file_info.compression_method!=Z_DEFLATED))
\r
1008 err=UNZ_BADZIPFILE;
\r
1010 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* date/time */
\r
1013 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* crc */
\r
1015 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) &&
\r
1016 ((uFlags & 8)==0))
\r
1017 err=UNZ_BADZIPFILE;
\r
1019 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size compr */
\r
1021 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) &&
\r
1022 ((uFlags & 8)==0))
\r
1023 err=UNZ_BADZIPFILE;
\r
1025 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size uncompr */
\r
1027 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) &&
\r
1028 ((uFlags & 8)==0))
\r
1029 err=UNZ_BADZIPFILE;
\r
1032 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&size_filename) != UNZ_OK)
\r
1034 else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename))
\r
1035 err=UNZ_BADZIPFILE;
\r
1037 *piSizeVar += (uInt)size_filename;
\r
1039 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&size_extra_field) != UNZ_OK)
\r
1041 *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile +
\r
1042 SIZEZIPLOCALHEADER + size_filename;
\r
1043 *psize_local_extrafield = (uInt)size_extra_field;
\r
1045 *piSizeVar += (uInt)size_extra_field;
\r
1051 Open for reading data the current file in the zipfile.
\r
1052 If there is no error and the file is opened, the return value is UNZ_OK.
\r
1054 extern int ZEXPORT unzOpenCurrentFile3 (file, method, level, raw, password)
\r
1059 const char* password;
\r
1064 file_in_zip_read_info_s* pfile_in_zip_read_info;
\r
1065 uLong offset_local_extrafield; /* offset of the local extra field */
\r
1066 uInt size_local_extrafield; /* size of the local extra field */
\r
1067 # ifndef NOUNCRYPT
\r
1070 if (password != NULL)
\r
1071 return UNZ_PARAMERROR;
\r
1075 return UNZ_PARAMERROR;
\r
1077 if (!s->current_file_ok)
\r
1078 return UNZ_PARAMERROR;
\r
1080 if (s->pfile_in_zip_read != NULL)
\r
1081 unzCloseCurrentFile(file);
\r
1083 if (unzlocal_CheckCurrentFileCoherencyHeader(s,&iSizeVar,
\r
1084 &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK)
\r
1085 return UNZ_BADZIPFILE;
\r
1087 pfile_in_zip_read_info = (file_in_zip_read_info_s*)
\r
1088 ALLOC(sizeof(file_in_zip_read_info_s));
\r
1089 if (pfile_in_zip_read_info==NULL)
\r
1090 return UNZ_INTERNALERROR;
\r
1092 pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE);
\r
1093 pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield;
\r
1094 pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield;
\r
1095 pfile_in_zip_read_info->pos_local_extrafield=0;
\r
1096 pfile_in_zip_read_info->raw=raw;
\r
1098 if (pfile_in_zip_read_info->read_buffer==NULL)
\r
1100 TRYFREE(pfile_in_zip_read_info);
\r
1101 return UNZ_INTERNALERROR;
\r
1104 pfile_in_zip_read_info->stream_initialised=0;
\r
1107 *method = (int)s->cur_file_info.compression_method;
\r
1112 switch (s->cur_file_info.flag & 0x06)
\r
1114 case 6 : *level = 1; break;
\r
1115 case 4 : *level = 2; break;
\r
1116 case 2 : *level = 9; break;
\r
1120 if ((s->cur_file_info.compression_method!=0) &&
\r
1121 (s->cur_file_info.compression_method!=Z_DEFLATED))
\r
1122 err=UNZ_BADZIPFILE;
\r
1124 pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc;
\r
1125 pfile_in_zip_read_info->crc32=0;
\r
1126 pfile_in_zip_read_info->compression_method =
\r
1127 s->cur_file_info.compression_method;
\r
1128 pfile_in_zip_read_info->filestream=s->filestream;
\r
1129 pfile_in_zip_read_info->z_filefunc=s->z_filefunc;
\r
1130 pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile;
\r
1132 pfile_in_zip_read_info->stream.total_out = 0;
\r
1134 if ((s->cur_file_info.compression_method==Z_DEFLATED) &&
\r
1137 pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;
\r
1138 pfile_in_zip_read_info->stream.zfree = (free_func)0;
\r
1139 pfile_in_zip_read_info->stream.opaque = (voidpf)0;
\r
1140 pfile_in_zip_read_info->stream.next_in = (voidpf)0;
\r
1141 pfile_in_zip_read_info->stream.avail_in = 0;
\r
1143 err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS);
\r
1145 pfile_in_zip_read_info->stream_initialised=1;
\r
1148 TRYFREE(pfile_in_zip_read_info);
\r
1151 /* windowBits is passed < 0 to tell that there is no zlib header.
\r
1152 * Note that in this case inflate *requires* an extra "dummy" byte
\r
1153 * after the compressed stream in order to complete decompression and
\r
1154 * return Z_STREAM_END.
\r
1155 * In unzip, i don't wait absolutely Z_STREAM_END because I known the
\r
1156 * size of both compressed and uncompressed data
\r
1159 pfile_in_zip_read_info->rest_read_compressed =
\r
1160 s->cur_file_info.compressed_size ;
\r
1161 pfile_in_zip_read_info->rest_read_uncompressed =
\r
1162 s->cur_file_info.uncompressed_size ;
\r
1165 pfile_in_zip_read_info->pos_in_zipfile =
\r
1166 s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER +
\r
1169 pfile_in_zip_read_info->stream.avail_in = (uInt)0;
\r
1171 s->pfile_in_zip_read = pfile_in_zip_read_info;
\r
1173 # ifndef NOUNCRYPT
\r
1174 if (password != NULL)
\r
1177 s->pcrc_32_tab = get_crc_table();
\r
1178 init_keys(password,s->keys,s->pcrc_32_tab);
\r
1179 if (ZSEEK(s->z_filefunc, s->filestream,
\r
1180 s->pfile_in_zip_read->pos_in_zipfile +
\r
1181 s->pfile_in_zip_read->byte_before_the_zipfile,
\r
1183 return UNZ_INTERNALERROR;
\r
1184 if(ZREAD(s->z_filefunc, s->filestream,source, 12)<12)
\r
1185 return UNZ_INTERNALERROR;
\r
1187 for (i = 0; i<12; i++)
\r
1188 zdecode(s->keys,s->pcrc_32_tab,source[i]);
\r
1190 s->pfile_in_zip_read->pos_in_zipfile+=12;
\r
1199 extern int ZEXPORT unzOpenCurrentFile (file)
\r
1202 return unzOpenCurrentFile3(file, NULL, NULL, 0, NULL);
\r
1205 extern int ZEXPORT unzOpenCurrentFilePassword (file, password)
\r
1207 const char* password;
\r
1209 return unzOpenCurrentFile3(file, NULL, NULL, 0, password);
\r
1212 extern int ZEXPORT unzOpenCurrentFile2 (file,method,level,raw)
\r
1218 return unzOpenCurrentFile3(file, method, level, raw, NULL);
\r
1222 Read bytes from the current file.
\r
1223 buf contain buffer where data must be copied
\r
1224 len the size of buf.
\r
1226 return the number of byte copied if somes bytes are copied
\r
1227 return 0 if the end of file was reached
\r
1228 return <0 with error code if there is an error
\r
1229 (UNZ_ERRNO for IO error, or zLib error for uncompress error)
\r
1231 extern int ZEXPORT unzReadCurrentFile (file, buf, len)
\r
1239 file_in_zip_read_info_s* pfile_in_zip_read_info;
\r
1241 return UNZ_PARAMERROR;
\r
1243 pfile_in_zip_read_info=s->pfile_in_zip_read;
\r
1245 if (pfile_in_zip_read_info==NULL)
\r
1246 return UNZ_PARAMERROR;
\r
1249 if ((pfile_in_zip_read_info->read_buffer == NULL))
\r
1250 return UNZ_END_OF_LIST_OF_FILE;
\r
1254 pfile_in_zip_read_info->stream.next_out = (Bytef*)buf;
\r
1256 pfile_in_zip_read_info->stream.avail_out = (uInt)len;
\r
1258 if ((len>pfile_in_zip_read_info->rest_read_uncompressed) &&
\r
1259 (!(pfile_in_zip_read_info->raw)))
\r
1260 pfile_in_zip_read_info->stream.avail_out =
\r
1261 (uInt)pfile_in_zip_read_info->rest_read_uncompressed;
\r
1263 if ((len>pfile_in_zip_read_info->rest_read_compressed+
\r
1264 pfile_in_zip_read_info->stream.avail_in) &&
\r
1265 (pfile_in_zip_read_info->raw))
\r
1266 pfile_in_zip_read_info->stream.avail_out =
\r
1267 (uInt)pfile_in_zip_read_info->rest_read_compressed+
\r
1268 pfile_in_zip_read_info->stream.avail_in;
\r
1270 while (pfile_in_zip_read_info->stream.avail_out>0)
\r
1272 if ((pfile_in_zip_read_info->stream.avail_in==0) &&
\r
1273 (pfile_in_zip_read_info->rest_read_compressed>0))
\r
1275 uInt uReadThis = UNZ_BUFSIZE;
\r
1276 if (pfile_in_zip_read_info->rest_read_compressed<uReadThis)
\r
1277 uReadThis = (uInt)pfile_in_zip_read_info->rest_read_compressed;
\r
1278 if (uReadThis == 0)
\r
1280 if (ZSEEK(pfile_in_zip_read_info->z_filefunc,
\r
1281 pfile_in_zip_read_info->filestream,
\r
1282 pfile_in_zip_read_info->pos_in_zipfile +
\r
1283 pfile_in_zip_read_info->byte_before_the_zipfile,
\r
1284 ZLIB_FILEFUNC_SEEK_SET)!=0)
\r
1286 if (ZREAD(pfile_in_zip_read_info->z_filefunc,
\r
1287 pfile_in_zip_read_info->filestream,
\r
1288 pfile_in_zip_read_info->read_buffer,
\r
1289 uReadThis)!=uReadThis)
\r
1293 # ifndef NOUNCRYPT
\r
1297 for(i=0;i<uReadThis;i++)
\r
1298 pfile_in_zip_read_info->read_buffer[i] =
\r
1299 zdecode(s->keys,s->pcrc_32_tab,
\r
1300 pfile_in_zip_read_info->read_buffer[i]);
\r
1305 pfile_in_zip_read_info->pos_in_zipfile += uReadThis;
\r
1307 pfile_in_zip_read_info->rest_read_compressed-=uReadThis;
\r
1309 pfile_in_zip_read_info->stream.next_in =
\r
1310 (Bytef*)pfile_in_zip_read_info->read_buffer;
\r
1311 pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis;
\r
1314 if ((pfile_in_zip_read_info->compression_method==0) || (pfile_in_zip_read_info->raw))
\r
1318 if ((pfile_in_zip_read_info->stream.avail_in == 0) &&
\r
1319 (pfile_in_zip_read_info->rest_read_compressed == 0))
\r
1320 return (iRead==0) ? UNZ_EOF : iRead;
\r
1322 if (pfile_in_zip_read_info->stream.avail_out <
\r
1323 pfile_in_zip_read_info->stream.avail_in)
\r
1324 uDoCopy = pfile_in_zip_read_info->stream.avail_out ;
\r
1326 uDoCopy = pfile_in_zip_read_info->stream.avail_in ;
\r
1328 for (i=0;i<uDoCopy;i++)
\r
1329 *(pfile_in_zip_read_info->stream.next_out+i) =
\r
1330 *(pfile_in_zip_read_info->stream.next_in+i);
\r
1332 pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,
\r
1333 pfile_in_zip_read_info->stream.next_out,
\r
1335 pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy;
\r
1336 pfile_in_zip_read_info->stream.avail_in -= uDoCopy;
\r
1337 pfile_in_zip_read_info->stream.avail_out -= uDoCopy;
\r
1338 pfile_in_zip_read_info->stream.next_out += uDoCopy;
\r
1339 pfile_in_zip_read_info->stream.next_in += uDoCopy;
\r
1340 pfile_in_zip_read_info->stream.total_out += uDoCopy;
\r
1345 uLong uTotalOutBefore,uTotalOutAfter;
\r
1346 const Bytef *bufBefore;
\r
1348 int flush=Z_SYNC_FLUSH;
\r
1350 uTotalOutBefore = pfile_in_zip_read_info->stream.total_out;
\r
1351 bufBefore = pfile_in_zip_read_info->stream.next_out;
\r
1354 if ((pfile_in_zip_read_info->rest_read_uncompressed ==
\r
1355 pfile_in_zip_read_info->stream.avail_out) &&
\r
1356 (pfile_in_zip_read_info->rest_read_compressed == 0))
\r
1359 err=inflate(&pfile_in_zip_read_info->stream,flush);
\r
1361 if ((err>=0) && (pfile_in_zip_read_info->stream.msg!=NULL))
\r
1362 err = Z_DATA_ERROR;
\r
1364 uTotalOutAfter = pfile_in_zip_read_info->stream.total_out;
\r
1365 uOutThis = uTotalOutAfter-uTotalOutBefore;
\r
1367 pfile_in_zip_read_info->crc32 =
\r
1368 crc32(pfile_in_zip_read_info->crc32,bufBefore,
\r
1369 (uInt)(uOutThis));
\r
1371 pfile_in_zip_read_info->rest_read_uncompressed -=
\r
1374 iRead += (uInt)(uTotalOutAfter - uTotalOutBefore);
\r
1376 if (err==Z_STREAM_END)
\r
1377 return (iRead==0) ? UNZ_EOF : iRead;
\r
1390 Give the current position in uncompressed data
\r
1392 extern z_off_t ZEXPORT unztell (file)
\r
1396 file_in_zip_read_info_s* pfile_in_zip_read_info;
\r
1398 return UNZ_PARAMERROR;
\r
1400 pfile_in_zip_read_info=s->pfile_in_zip_read;
\r
1402 if (pfile_in_zip_read_info==NULL)
\r
1403 return UNZ_PARAMERROR;
\r
1405 return (z_off_t)pfile_in_zip_read_info->stream.total_out;
\r
1410 return 1 if the end of file was reached, 0 elsewhere
\r
1412 extern int ZEXPORT unzeof (file)
\r
1416 file_in_zip_read_info_s* pfile_in_zip_read_info;
\r
1418 return UNZ_PARAMERROR;
\r
1420 pfile_in_zip_read_info=s->pfile_in_zip_read;
\r
1422 if (pfile_in_zip_read_info==NULL)
\r
1423 return UNZ_PARAMERROR;
\r
1425 if (pfile_in_zip_read_info->rest_read_uncompressed == 0)
\r
1434 Read extra field from the current file (opened by unzOpenCurrentFile)
\r
1435 This is the local-header version of the extra field (sometimes, there is
\r
1436 more info in the local-header version than in the central-header)
\r
1438 if buf==NULL, it return the size of the local extra field that can be read
\r
1440 if buf!=NULL, len is the size of the buffer, the extra header is copied in
\r
1442 the return value is the number of bytes copied in buf, or (if <0)
\r
1445 extern int ZEXPORT unzGetLocalExtrafield (file,buf,len)
\r
1451 file_in_zip_read_info_s* pfile_in_zip_read_info;
\r
1453 uLong size_to_read;
\r
1456 return UNZ_PARAMERROR;
\r
1458 pfile_in_zip_read_info=s->pfile_in_zip_read;
\r
1460 if (pfile_in_zip_read_info==NULL)
\r
1461 return UNZ_PARAMERROR;
\r
1463 size_to_read = (pfile_in_zip_read_info->size_local_extrafield -
\r
1464 pfile_in_zip_read_info->pos_local_extrafield);
\r
1467 return (int)size_to_read;
\r
1469 if (len>size_to_read)
\r
1470 read_now = (uInt)size_to_read;
\r
1472 read_now = (uInt)len ;
\r
1477 if (ZSEEK(pfile_in_zip_read_info->z_filefunc,
\r
1478 pfile_in_zip_read_info->filestream,
\r
1479 pfile_in_zip_read_info->offset_local_extrafield +
\r
1480 pfile_in_zip_read_info->pos_local_extrafield,
\r
1481 ZLIB_FILEFUNC_SEEK_SET)!=0)
\r
1484 if (ZREAD(pfile_in_zip_read_info->z_filefunc,
\r
1485 pfile_in_zip_read_info->filestream,
\r
1486 buf,read_now)!=read_now)
\r
1489 return (int)read_now;
\r
1493 Close the file in zip opened with unzipOpenCurrentFile
\r
1494 Return UNZ_CRCERROR if all the file was read but the CRC is not good
\r
1496 extern int ZEXPORT unzCloseCurrentFile (file)
\r
1502 file_in_zip_read_info_s* pfile_in_zip_read_info;
\r
1504 return UNZ_PARAMERROR;
\r
1506 pfile_in_zip_read_info=s->pfile_in_zip_read;
\r
1508 if (pfile_in_zip_read_info==NULL)
\r
1509 return UNZ_PARAMERROR;
\r
1512 if ((pfile_in_zip_read_info->rest_read_uncompressed == 0) &&
\r
1513 (!pfile_in_zip_read_info->raw))
\r
1515 if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait)
\r
1520 TRYFREE(pfile_in_zip_read_info->read_buffer);
\r
1521 pfile_in_zip_read_info->read_buffer = NULL;
\r
1522 if (pfile_in_zip_read_info->stream_initialised)
\r
1523 inflateEnd(&pfile_in_zip_read_info->stream);
\r
1525 pfile_in_zip_read_info->stream_initialised = 0;
\r
1526 TRYFREE(pfile_in_zip_read_info);
\r
1528 s->pfile_in_zip_read=NULL;
\r
1535 Get the global comment string of the ZipFile, in the szComment buffer.
\r
1536 uSizeBuf is the size of the szComment buffer.
\r
1537 return the number of byte copied or an error code <0
\r
1539 extern int ZEXPORT unzGetGlobalComment (file, szComment, uSizeBuf)
\r
1547 return UNZ_PARAMERROR;
\r
1550 uReadThis = uSizeBuf;
\r
1551 if (uReadThis>s->gi.size_comment)
\r
1552 uReadThis = s->gi.size_comment;
\r
1554 if (ZSEEK(s->z_filefunc,s->filestream,s->central_pos+22,ZLIB_FILEFUNC_SEEK_SET)!=0)
\r
1560 if (ZREAD(s->z_filefunc,s->filestream,szComment,uReadThis)!=uReadThis)
\r
1564 if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment))
\r
1565 *(szComment+s->gi.size_comment)='\0';
\r
1566 return (int)uReadThis;
\r
1569 /* Additions by RX '2004 */
\r
1570 extern uLong ZEXPORT unzGetOffset (file)
\r
1576 return UNZ_PARAMERROR;
\r
1578 if (!s->current_file_ok)
\r
1580 if (s->gi.number_entry != 0 && s->gi.number_entry != 0xffff)
\r
1581 if (s->num_file==s->gi.number_entry)
\r
1583 return s->pos_in_central_dir;
\r
1586 extern int ZEXPORT unzSetOffset (file, pos)
\r
1594 return UNZ_PARAMERROR;
\r
1597 s->pos_in_central_dir = pos;
\r
1598 s->num_file = s->gi.number_entry; /* hack */
\r
1599 err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
\r
1600 &s->cur_file_info_internal,
\r
1601 NULL,0,NULL,0,NULL,0);
\r
1602 s->current_file_ok = (err == UNZ_OK);
\r