📄 unzip.c
字号:
ptm->tm_mon = (DWORD)((((uDate) &0x1E0) / 0x20) - 1);
ptm->tm_year = (DWORD)(((uDate &0x0FE00) / 0x0200) + 1980);
ptm->tm_hour = (DWORD)((ulDosDate &0xF800) / 0x800);
ptm->tm_min = (DWORD)((ulDosDate &0x7E0) / 0x20);
ptm->tm_sec = (DWORD)(2 *(ulDosDate &0x1f));
}
/*
Get Info about the current file in the zipfile, with internal only info
*/
static int unzlocal_GetCurrentFileInfoInternal(unzFile file, unz_file_info *pfile_info, unz_file_info_internal *pfile_info_internal, char *szFileName, DWORD fileNameBufferSize, void *extraField, DWORD extraFieldBufferSize, char *szComment, DWORD commentBufferSize)
{
unz_s *s;
unz_file_info file_info;
unz_file_info_internal file_info_internal;
int err = UNZ_OK;
DWORD uMagic;
long lSeek = 0;
if (file == NULL)
{
return UNZ_PARAMERROR;
}
s = (unz_s*)file;
if (ZSEEK(s->z_filefunc, s->filestream, s->pos_in_central_dir + s->byte_before_the_zipfile, SEEK_SET) != 0)
{
err = UNZ_ERRNO;
}
/* we check the magic */
if (err == UNZ_OK)
{
if (unzlocal_getLong(&s->z_filefunc, s->filestream, &uMagic) != UNZ_OK)
{
err = UNZ_ERRNO;
}
else if (uMagic != 0x02014b50)
{
err = UNZ_BADZIPFILE;
}
}
if (unzlocal_getShort(&s->z_filefunc, s->filestream, &file_info.version) != UNZ_OK)
{
err = UNZ_ERRNO;
}
if (unzlocal_getShort(&s->z_filefunc, s->filestream, &file_info.version_needed) != UNZ_OK)
{
err = UNZ_ERRNO;
}
if (unzlocal_getShort(&s->z_filefunc, s->filestream, &file_info.flag) != UNZ_OK)
{
err = UNZ_ERRNO;
}
if (unzlocal_getShort(&s->z_filefunc, s->filestream, &file_info.compression_method) != UNZ_OK)
{
err = UNZ_ERRNO;
}
if (unzlocal_getLong(&s->z_filefunc, s->filestream, &file_info.dosDate) != UNZ_OK)
{
err = UNZ_ERRNO;
}
unzlocal_DosDateToTmuDate(file_info.dosDate, &file_info.tmu_date);
if (unzlocal_getLong(&s->z_filefunc, s->filestream, &file_info.crc) != UNZ_OK)
{
err = UNZ_ERRNO;
}
if (unzlocal_getLong(&s->z_filefunc, s->filestream, &file_info.compressed_size) != UNZ_OK)
{
err = UNZ_ERRNO;
}
if (unzlocal_getLong(&s->z_filefunc, s->filestream, &file_info.uncompressed_size) != UNZ_OK)
{
err = UNZ_ERRNO;
}
if (unzlocal_getShort(&s->z_filefunc, s->filestream, &file_info.size_filename) != UNZ_OK)
{
err = UNZ_ERRNO;
}
if (unzlocal_getShort(&s->z_filefunc, s->filestream, &file_info.size_file_extra) != UNZ_OK)
{
err = UNZ_ERRNO;
}
if (unzlocal_getShort(&s->z_filefunc, s->filestream, &file_info.size_file_comment) != UNZ_OK)
{
err = UNZ_ERRNO;
}
if (unzlocal_getShort(&s->z_filefunc, s->filestream, &file_info.disk_num_start) != UNZ_OK)
{
err = UNZ_ERRNO;
}
if (unzlocal_getShort(&s->z_filefunc, s->filestream, &file_info.internal_fa) != UNZ_OK)
{
err = UNZ_ERRNO;
}
if (unzlocal_getLong(&s->z_filefunc, s->filestream, &file_info.external_fa) != UNZ_OK)
{
err = UNZ_ERRNO;
}
if (unzlocal_getLong(&s->z_filefunc, s->filestream, &file_info_internal.offset_curfile) != UNZ_OK)
{
err = UNZ_ERRNO;
}
lSeek += file_info.size_filename;
if ((err == UNZ_OK) && (szFileName != NULL))
{
DWORD uSizeRead;
if (file_info.size_filename < fileNameBufferSize)
{
*(szFileName + file_info.size_filename) = '\0';
uSizeRead = file_info.size_filename;
}
else
{
uSizeRead = fileNameBufferSize;
}
if ((file_info.size_filename > 0) && (fileNameBufferSize > 0))
if (ZREAD(s->z_filefunc, s->filestream, szFileName, uSizeRead) != uSizeRead)
{
err = UNZ_ERRNO;
}
lSeek -= uSizeRead;
}
if ((err == UNZ_OK) && (extraField != NULL))
{
DWORD uSizeRead;
if (file_info.size_file_extra < extraFieldBufferSize)
{
uSizeRead = file_info.size_file_extra;
}
else
{
uSizeRead = extraFieldBufferSize;
}
if (lSeek != 0)
{
if (ZSEEK(s->z_filefunc, s->filestream, lSeek, SEEK_CUR) == 0)
{
lSeek = 0;
}
else
{
err = UNZ_ERRNO;
}
}
if ((file_info.size_file_extra > 0) && (extraFieldBufferSize > 0))
{
if (ZREAD(s->z_filefunc, s->filestream, extraField, uSizeRead) != uSizeRead)
{
err = UNZ_ERRNO;
}
}
lSeek += file_info.size_file_extra - uSizeRead;
}
else
{
lSeek += file_info.size_file_extra;
}
if ((err == UNZ_OK) && (szComment != NULL))
{
DWORD uSizeRead;
if (file_info.size_file_comment < commentBufferSize)
{
*(szComment + file_info.size_file_comment) = '\0';
uSizeRead = file_info.size_file_comment;
}
else
{
uSizeRead = commentBufferSize;
}
if (lSeek != 0)
{
if (ZSEEK(s->z_filefunc, s->filestream, lSeek, SEEK_CUR) == 0)
{
lSeek = 0;
}
else
{
err = UNZ_ERRNO;
}
}
if ((file_info.size_file_comment > 0) && (commentBufferSize > 0))
{
if (ZREAD(s->z_filefunc, s->filestream, szComment, uSizeRead) != uSizeRead)
{
err = UNZ_ERRNO;
}
}
lSeek += file_info.size_file_comment - uSizeRead;
}
else
{
lSeek += file_info.size_file_comment;
}
if ((err == UNZ_OK) && (pfile_info != NULL))
{
*pfile_info = file_info;
}
if ((err == UNZ_OK) && (pfile_info_internal != NULL))
{
*pfile_info_internal = file_info_internal;
}
return err;
}
/*
Write info about the ZipFile in the *pglobal_info structure.
No preparation of the structure is needed
return UNZ_OK if there is no problem.
*/
extern int ZEXPORT unzGetCurrentFileInfo(unzFile file, unz_file_info *pfile_info, char *szFileName, DWORD fileNameBufferSize, void *extraField, DWORD extraFieldBufferSize, char *szComment, DWORD commentBufferSize)
{
return unzlocal_GetCurrentFileInfoInternal(file, pfile_info, NULL, szFileName, fileNameBufferSize, extraField, extraFieldBufferSize, szComment, commentBufferSize);
}
/*
Set the current file of the zipfile to the first file.
return UNZ_OK if there is no problem
*/
extern int ZEXPORT unzGoToFirstFile(unzFile file)
{
int err = UNZ_OK;
unz_s *s;
if (file == NULL)
{
return UNZ_PARAMERROR;
}
s = (unz_s*)file;
s->pos_in_central_dir = s->offset_central_dir;
s->num_file = 0;
err = unzlocal_GetCurrentFileInfoInternal(file, &s->cur_file_info, &s->cur_file_info_internal, NULL, 0, NULL, 0, NULL, 0);
s->current_file_ok = (err == UNZ_OK);
return err;
}
/*
Set the current file of the zipfile to the next file.
return UNZ_OK if there is no problem
return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
*/
extern int ZEXPORT unzGoToNextFile(unzFile file)
{
unz_s *s;
int err;
if (file == NULL)
{
return UNZ_PARAMERROR;
}
s = (unz_s*)file;
if (!s->current_file_ok)
{
return UNZ_END_OF_LIST_OF_FILE;
}
if (s->gi.number_entry != 0xffff)
{
/* 2^16 files overflow hack */
if (s->num_file + 1 == s->gi.number_entry)
{
return UNZ_END_OF_LIST_OF_FILE;
}
}
s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename + s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment;
s->num_file++;
err = unzlocal_GetCurrentFileInfoInternal(file, &s->cur_file_info, &s->cur_file_info_internal, NULL, 0, NULL, 0, NULL, 0);
s->current_file_ok = (err == UNZ_OK);
return err;
}
extern int ZEXPORT unzGetCurrentFileID(unzFile file, DWORD *file_num, DWORD *pos_in_central_dir)
{
unz_s *s;
if (file == NULL)
{
return UNZ_PARAMERROR;
}
s = (unz_s*)file;
*file_num = s->num_file;
*pos_in_central_dir = s->pos_in_central_dir;
return UNZ_OK;
}
extern int ZEXPORT unzGoToFileID(unzFile file, DWORD file_num, DWORD pos_in_central_dir)
{
unz_s *s;
int err;
if (file == NULL)
{
return UNZ_PARAMERROR;
}
s = (unz_s*)file;
s->num_file = file_num;
s->pos_in_central_dir = pos_in_central_dir;
err = unzlocal_GetCurrentFileInfoInternal(file, &s->cur_file_info, &s->cur_file_info_internal, NULL, 0, NULL, 0, NULL, 0);
s->current_file_ok = (err == UNZ_OK);
return err;
}
/*
Try locate the file szFileName in the zipfile.
For the iCaseSensitivity signification, see unzipStringFileNameCompare
return value :
UNZ_OK if the file is found. It becomes the current file.
UNZ_END_OF_LIST_OF_FILE if the file is not found
*/
//-------------------------------------------------------------------------
/*
// Unzip Helper Functions - should be here?
///////////////////////////////////////////
*/
/*
Read the local header of the current zipfile
Check the coherency of the local header and info in the end of central
directory about this file
store in *piSizeVar the size of extra info in local header
(filename and size of extra field data)
*/
static int unzlocal_CheckCurrentFileCoherencyHeader(unz_s *s, DWORD *piSizeVar, DWORD *poffset_local_extrafield, DWORD *psize_local_extrafield)
{
DWORD uMagic, uData, uFlags;
DWORD size_filename;
DWORD size_extra_field;
int err = UNZ_OK;
*piSizeVar = 0;
*poffset_local_extrafield = 0;
*psize_local_extrafield = 0;
if (ZSEEK(s->z_filefunc, s->filestream, s->cur_file_info_internal.offset_curfile + s->byte_before_the_zipfile, SEEK_SET) != 0)
{
return UNZ_ERRNO;
}
if (err == UNZ_OK)
{
if (unzlocal_getLong(&s->z_filefunc, s->filestream, &uMagic) != UNZ_OK)
{
err = UNZ_ERRNO;
}
else if (uMagic != 0x04034b50)
{
err = UNZ_BADZIPFILE;
}
}
if (unzlocal_getShort(&s->z_filefunc, s->filestream, &uData) != UNZ_OK)
{
err = UNZ_ERRNO;
}
if (unzlocal_getShort(&s->z_filefunc, s->filestream, &uFlags) != UNZ_OK)
{
err = UNZ_ERRNO;
}
if (unzlocal_getShort(&s->z_filefunc, s->filestream, &uData) != UNZ_OK)
{
err = UNZ_ERRNO;
}
else if ((err == UNZ_OK) && (uData != s->cur_file_info.compression_method))
{
err = UNZ_BADZIPFILE;
}
if ((err == UNZ_OK) && (s->cur_file_info.compression_method != 0) && (s->cur_file_info.compression_method != Z_DEFLATED))
{
err = UNZ_BADZIPFILE;
}
if (unzlocal_getLong(&s->z_filefunc, s->filestream, &uData) != UNZ_OK)
// date/time
{
err = UNZ_ERRNO;
}
if (unzlocal_getLong(&s->z_filefunc, s->filestream, &uData) != UNZ_OK)
// crc
{
err = UNZ_ERRNO;
}
else if ((err == UNZ_OK) && (uData != s->cur_file_info.crc) && ((uFlags &8) == 0))
{
err = UNZ_BADZIPFILE;
}
if (unzlocal_getLong(&s->z_filefunc, s->filestream, &uData) != UNZ_OK)
// size compr
{
err = UNZ_ERRNO;
}
else if ((err == UNZ_OK) && (uData != s->cur_file_info.compressed_size) && ((uFlags &8) == 0))
{
err = UNZ_BADZIPFILE;
}
if (unzlocal_getLong(&s->z_filefunc, s->filestream, &uData) != UNZ_OK)
// size uncompr
{
err = UNZ_ERRNO;
}
else if ((err == UNZ_OK) && (uData != s->cur_file_info.uncompressed_size) && ((uFlags &8) == 0))
{
err = UNZ_BADZIPFILE;
}
if (unzlocal_getShort(&s->z_filefunc, s->filestream, &size_filename) != UNZ_OK)
{
err = UNZ_ERRNO;
}
else if ((err == UNZ_OK) && (size_filename != s->cur_file_info.size_filename))
{
err = UNZ_BADZIPFILE;
}
*piSizeVar += (DWORD)size_filename;
if (unzlocal_getShort(&s->z_filefunc, s->filestream, &size_extra_field) != UNZ_OK)
{
err = UNZ_ERRNO;
}
*poffset_local_extrafield = s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER + size_filename;
*psize_local_extrafield = (DWORD)size_extra_field;
*piSizeVar += (DWORD)size_extra_field;
return err;
}
/*
Open for reading data the current file in the zipfile.
If there is no error and the file is opened, the return value is UNZ_OK.
*/
extern int ZEXPORT unzOpenCurrentFile3(unzFile file, int *method, int *level, int raw, const char *password)
{
int err = UNZ_OK;
DWORD iSizeVar;
unz_s *s;
file_in_zip_read_info_s *pfile_in_zip_read_info;
DWORD offset_local_extrafield; // offset of the local extra field
DWORD size_local_extrafield; // size of the local extra field
#ifndef NOUNCRYPT
char source[12];
#else
if (password != NULL)
{
return UNZ_PARAMERROR;
}
#endif
if (file == NULL)
{
return UNZ_PARAMERROR;
}
s = (unz_s*)file;
if (!s->current_file_ok)
{
return UNZ_PARAMERROR;
}
if (s->pfile_in_zip_read != NULL)
{
unzCloseCurrentFile(file);
}
if (unzlocal_CheckCurrentFileCoherencyHeader(s, &iSizeVar, &offset_local_extrafield, &size_local_extrafield) != UNZ_OK)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -