unalz/UnAlz.cpp

1794 lines
47 KiB
C++
Raw Normal View History

2020-05-05 18:22:29 +00:00
//#include "stdafx.h"
#include "zlib/zlib.h"
#include "bzip2/bzlib.h"
#include "UnAlz.h"
2020-05-05 18:22:31 +00:00
// mkdir
#ifdef _WIN32
# include <direct.h>
2020-05-05 18:22:29 +00:00
#else
2020-05-05 18:22:31 +00:00
# include <sys/stat.h>
#endif
#ifdef _UNALZ_ICONV // code page support
# include <iconv.h>
#endif
2020-05-05 18:22:33 +00:00
#ifdef __linux__ // __BYTE_ORDER <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
# include <errno.h> // iconv.h <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ʿ<EFBFBD>
2020-05-05 18:22:31 +00:00
#endif
2020-05-05 18:22:33 +00:00
#define swapint64(Data) (INT64) ( (((Data)&0x00000000000000FFLL) << 56) | (((Data)&0x000000000000FF00LL) << 40) | (((Data)&0x0000000000FF0000LL) << 24) | (((Data)&0x00000000FF000000LL) << 8) | (((Data)&0x000000FF00000000LL) >> 8) | (((Data)&0x0000FF0000000000LL) >> 24) | (((Data)&0x00FF000000000000LL) >> 40) | (((Data)&0xFF00000000000000LL) >> 56) )
#define swapint32(a) ((((a)&0xff)<<24)+(((a>>8)&0xff)<<16)+(((a>>16)&0xff)<<8)+(((a>>24)&0xff)))
#define swapint16(a) (((a)&0xff)<<8)+(((a>>8)&0xff))
2020-05-05 18:22:31 +00:00
2020-05-05 18:22:33 +00:00
////////////////////////////////////////////////////////////////////////////
//// byte-order : little to host ////
////////////////////////////////////////////////////////////////////////////
2020-05-05 18:22:31 +00:00
2020-05-05 18:22:38 +00:00
#if defined(_WIN32) ||defined(__CYGWIN__) // little to little
2020-05-05 18:22:31 +00:00
inline UINT16 unalz_le16toh(UINT16 a){return a;}
inline UINT32 unalz_le32toh(UINT32 a){return a;}
inline UINT64 unalz_le64toh(UINT64 a){return a;}
#endif
2020-05-05 18:22:33 +00:00
#ifdef __FreeBSD__
# include <sys/endian.h>
2020-05-05 18:22:31 +00:00
inline UINT16 unalz_le16toh(UINT16 a){return le16toh(a);}
inline UINT32 unalz_le32toh(UINT32 a){return le32toh(a);}
inline UINT64 unalz_le64toh(UINT64 a){return le64toh(a);}
#endif
2020-05-05 18:22:33 +00:00
#ifdef __APPLE__
# include <machine/byte_order.h>
inline UINT16 unalz_le16toh(UINT16 a){return NXSwapShort(a);}
inline UINT32 unalz_le32toh(UINT32 a){return NXSwapLong(a);}
inline UINT64 unalz_le64toh(UINT64 a){return NXSwapLongLong(a);}
#endif
#ifdef __linux__
# include <endian.h>
2020-05-05 18:22:31 +00:00
# if __BYTE_ORDER == __BIG_ENDIAN
inline UINT16 unalz_le16toh(UINT16 a){return swapint16(a);}
inline UINT32 unalz_le32toh(UINT32 a){return swapint32(a);}
inline UINT64 unalz_le64toh(UINT64 a){return swapint64(a);}
# else // __LITTLE_ENDIAN
inline UINT16 unalz_le16toh(UINT16 a){return (a);}
inline UINT32 unalz_le32toh(UINT32 a){return (a);}
inline UINT64 unalz_le64toh(UINT64 a){return (a);}
# endif
2020-05-05 18:22:33 +00:00
//# include <asm/byteorder.h>
// inline UINT16 unalz_le16toh(UINT16 a){return le16_to_cpu(a);}
// inline UINT32 unalz_le32toh(UINT32 a){return le32_to_cpu(a);}
// inline UINT64 unalz_le64toh(UINT64 a){return le64_to_cpu(a);}
2020-05-05 18:22:29 +00:00
#endif
2020-05-05 18:22:31 +00:00
2020-05-05 18:22:29 +00:00
#ifndef MAX_PATH
2020-05-05 18:22:31 +00:00
# define MAX_PATH 260
2020-05-05 18:22:29 +00:00
#endif
#ifdef _WIN32
2020-05-05 18:22:31 +00:00
# define PATHSEP "\\"
# define PATHSEPC '\\'
2020-05-05 18:22:29 +00:00
#else
2020-05-05 18:22:31 +00:00
# define PATHSEP "/"
# define PATHSEPC '/'
2020-05-05 18:22:29 +00:00
#endif
2020-05-05 18:22:31 +00:00
// error string table <- CUnAlz::ERR <20><> <20><><EFBFBD><EFBFBD>
static const char* errorstrtable[]=
{
"no error", // ERR_NOERR
"can't open file", // ERR_CANT_OPEN_FILE
2020-05-05 18:22:38 +00:00
"corrupted file", // ERR_CORRUPTED_FILE
2020-05-05 18:22:39 +00:00
"not alz file", // ERR_NOT_ALZ_FILE
2020-05-05 18:22:31 +00:00
"can't read signature", // ERR_CANT_READ_SIG
"can't read file", // ERR_CANT_READ_FILE
"error at read header", // ERR_AT_READ_HEADER
"invalid filename length", // ERR_INVALID_FILENAME_LENGTH
"invalid extrafield length", // ERR_INVALID_EXTRAFIELD_LENGTH,
"can't read central directory structure head", // ERR_CANT_READ_CENTRAL_DIRECTORY_STRUCTURE_HEAD,
"invalid filename size", // ERR_INVALID_FILENAME_SIZE,
"invalid extrafield size", // ERR_INVALID_EXTRAFIELD_SIZE,
"invalid filecomment size", // ERR_INVALID_FILECOMMENT_SIZE,
"cant' read header", // ERR_CANT_READ_HEADER,
"memory allocation failed", // ERR_MEM_ALLOC_FAILED,
2020-05-05 18:22:38 +00:00
"file read error", // ERR_FILE_READ_ERROR,
2020-05-05 18:22:31 +00:00
"inflate failed", // ERR_INFLATE_FAILED,
2020-05-05 18:22:39 +00:00
"bzip2 decompress failed", // ERR_BZIP2_FAILED,
"invalid file CRC", // ERR_INVALID_FILE_CRC
"unknown compression method", // ERR_UNKNOWN_COMPRESSION_METHOD
2020-05-05 18:22:31 +00:00
"iconv-can't open iconv", // ERR_ICONV_CANT_OPEN,
"iconv-invalid multisequence of characters", // ERR_ICONV_INVALID_MULTISEQUENCE_OF_CHARACTERS,
"iconv-incomplete multibyte sequence", // ERR_ICONV_INCOMPLETE_MULTIBYTE_SEQUENCE,
"iconv-not enough space of buffer to convert", // ERR_ICONV_NOT_ENOUGH_SPACE_OF_BUFFER_TO_CONVERT,
"iconv-etc", // ERR_ICONV_ETC,
2020-05-05 18:22:35 +00:00
2020-05-05 18:22:39 +00:00
"password was not set", // ERR_PASSWD_NOT_SET,
"invalid password", // ERR_INVALID_PASSWD,
"user aborted",
2020-05-05 18:22:31 +00:00
};
2020-05-05 18:22:29 +00:00
////////////////////////////////////////////////////////////////////////////////////////////////////
/// ctor
/// @date 2004-03-06 <20><><EFBFBD><EFBFBD> 11:19:49
////////////////////////////////////////////////////////////////////////////////////////////////////
CUnAlz::CUnAlz()
{
memset(m_files, 0, sizeof(m_files));
m_nErr = ERR_NOERR;
m_posCur = (FileList::iterator)NULL;
m_pFuncCallBack = NULL;
m_pCallbackParam = NULL;
m_bHalt = FALSE;
m_nFileCount = 0;
m_nCurFile = -1;
m_nVirtualFilePos = 0;
m_nCurFilePos = 0;
m_bIsEOF = FALSE;
2020-05-05 18:22:35 +00:00
m_bIsEncrypted = FALSE;
m_bIsDataDescr = FALSE;
2020-05-05 18:22:31 +00:00
#ifdef _UNALZ_ICONV
#ifdef _UNALZ_UTF8
strcpy(m_szToCodepage, "UTF-8") ; // <20><EFBFBD><E2BABB><EFBFBD><EFBFBD><EFBFBD><EFBFBD> utf-8
#else
strcpy(m_szToCodepage, "CP949") ; // <20><EFBFBD><E2BABB><EFBFBD><EFBFBD><EFBFBD><EFBFBD> CP949
#endif // _UNALZ_UTF8
strcpy(m_szFromCodepage, "CP949"); // alz <20><> 949 <20><> <20><><EFBFBD><EFBFBD>
#endif // _UNALZ_ICONV
2020-05-05 18:22:29 +00:00
}
////////////////////////////////////////////////////////////////////////////////////////////////////
/// dtor
/// @date 2004-03-06 <20><><EFBFBD><EFBFBD> 11:19:52
////////////////////////////////////////////////////////////////////////////////////////////////////
CUnAlz::~CUnAlz()
{
Close();
}
////////////////////////////////////////////////////////////////////////////////////////////////////
/// progress callback func setting
/// @date 2004-03-01 <20><><EFBFBD><EFBFBD> 6:02:05
////////////////////////////////////////////////////////////////////////////////////////////////////
void CUnAlz::SetCallback(_UnAlzCallback* pFunc, void* param)
{
m_pFuncCallBack = pFunc;
m_pCallbackParam = param;
}
2020-05-05 18:22:31 +00:00
#ifdef _WIN32
2020-05-05 18:22:35 +00:00
#if !defined(__GNUWIN32__) && !defined(__GNUC__)
2020-05-05 18:22:29 +00:00
////////////////////////////////////////////////////////////////////////////////////////////////////
/// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
/// @param szPathName
/// @return
/// @date 2004-03-06 <20><><EFBFBD><EFBFBD> 11:03:59
////////////////////////////////////////////////////////////////////////////////////////////////////
2020-05-05 18:22:31 +00:00
#include <atlbase.h>
#include <atlconv.h>
2020-05-05 18:22:29 +00:00
BOOL CUnAlz::Open(LPCWSTR szPathName)
{
USES_CONVERSION;
return Open(W2A(szPathName));
}
2020-05-05 18:22:31 +00:00
////////////////////////////////////////////////////////////////////////////////////////////////////
/// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϱ<EFBFBD>.
/// @param szFileName
/// @return
/// @date 2004-03-06 <20><><EFBFBD><EFBFBD> 11:06:20
////////////////////////////////////////////////////////////////////////////////////////////////////
BOOL CUnAlz::SetCurrentFile(LPCWSTR szFileName)
{
USES_CONVERSION;
return SetCurrentFile(W2A(szFileName));
}
BOOL CUnAlz::IsFolder(LPCWSTR szPathName)
{
UINT32 dwRet;
dwRet = GetFileAttributesW(szPathName);
if(dwRet==0xffffffff) return FALSE;
if(dwRet & FILE_ATTRIBUTE_DIRECTORY) return TRUE;
return FALSE;
}
#endif // __GNUWIN32__
2020-05-05 18:22:29 +00:00
#endif // _WIN32
BOOL CUnAlz::Open(const char* szPathName)
{
if(FOpen(szPathName)==FALSE)
{
m_nErr = ERR_CANT_OPEN_FILE;
return FALSE;
}
2020-05-05 18:22:39 +00:00
BOOL bValidAlzHeader = FALSE;
2020-05-05 18:22:29 +00:00
// file <20>м<EFBFBD><D0BC><EFBFBD><EFBFBD><EFBFBD>..
for(;;)
{
SIGNATURE sig;
BOOL ret;
if(FEof()) break;
//int pos = ftell(m_fp);
sig = ReadSignature();
if(sig==SIG_EOF)
{
break;
}
2020-05-05 18:22:31 +00:00
if(sig==SIG_ERROR)
2020-05-05 18:22:29 +00:00
{
2020-05-05 18:22:39 +00:00
if(bValidAlzHeader)
m_nErr = ERR_CORRUPTED_FILE; // <20>ջ<EFBFBD><D5BB><EFBFBD> <20><><EFBFBD><EFBFBD>
else
m_nErr = ERR_NOT_ALZ_FILE; // alz <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ƴϴ<C6B4>.
2020-05-05 18:22:29 +00:00
return FALSE; // <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>..
}
2020-05-05 18:22:39 +00:00
if(sig==SIG_ALZ_FILE_HEADER)
{
ret = ReadAlzFileHeader();
bValidAlzHeader = TRUE; // alz <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>´<EFBFBD>.
}
2020-05-05 18:22:29 +00:00
else if(sig==SIG_LOCAL_FILE_HEADER) ret = ReadLocalFileheader();
else if(sig==SIG_CENTRAL_DIRECTORY_STRUCTURE) ret = ReadCentralDirectoryStructure();
else if(sig==SIG_ENDOF_CENTRAL_DIRECTORY_RECORD) ret = ReadEndofCentralDirectoryRecord();
else
{
2020-05-05 18:22:38 +00:00
// <20>̱<EFBFBD><CCB1><EFBFBD><EFBFBD><EFBFBD> signature ? <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> ?
2020-05-05 18:22:29 +00:00
ASSERT(0);
2020-05-05 18:22:38 +00:00
m_nErr = ERR_CORRUPTED_FILE;
2020-05-05 18:22:29 +00:00
return FALSE;
}
if(ret==FALSE)
{
return FALSE;
}
if(FEof()) break;
}
return TRUE;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
/// <20><><EFBFBD><EFBFBD> <20>ݱ<EFBFBD>..
/// @return
/// @date 2004-03-06 <20><><EFBFBD><EFBFBD> 11:04:21
////////////////////////////////////////////////////////////////////////////////////////////////////
void CUnAlz::Close()
{
FClose();
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>..
FileList::iterator i;
for(i=m_fileList.begin(); i<m_fileList.end(); i++)
{
i->Clear();
}
m_posCur = (FileList::iterator)NULL;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
/// FILE <20><><EFBFBD><EFBFBD> SIGNATURE <20>б<EFBFBD>
/// @return
/// @date 2004-03-06 <20><><EFBFBD><EFBFBD> 11:04:47
////////////////////////////////////////////////////////////////////////////////////////////////////
CUnAlz::SIGNATURE CUnAlz::ReadSignature()
{
2020-05-05 18:22:31 +00:00
UINT32 dwSig;
2020-05-05 18:22:29 +00:00
if(FRead(&dwSig, sizeof(dwSig))==FALSE)
{
//int pos = ftell(m_fp);
if(FEof())
return SIG_EOF;
m_nErr = ERR_CANT_READ_SIG;
2020-05-05 18:22:31 +00:00
return SIG_ERROR;
2020-05-05 18:22:29 +00:00
}
2020-05-05 18:22:31 +00:00
return (SIGNATURE)unalz_le32toh(dwSig); // little to host;
2020-05-05 18:22:29 +00:00
}
////////////////////////////////////////////////////////////////////////////////////////////////////
/// ALZ HEADER SIGNATURE <20>б<EFBFBD>
/// @return
/// @date 2004-03-06 <20><><EFBFBD><EFBFBD> 11:05:11
////////////////////////////////////////////////////////////////////////////////////////////////////
BOOL CUnAlz::ReadAlzFileHeader()
{
SAlzHeader header;
if(FRead(&header, sizeof(header))==FALSE)
{
ASSERT(0);
m_nErr = ERR_CANT_READ_FILE;
return FALSE;
}
return TRUE;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>б<EFBFBD>
/// @return
/// @date 2004-03-06 <20><><EFBFBD><EFBFBD> 11:05:18
////////////////////////////////////////////////////////////////////////////////////////////////////
BOOL CUnAlz::ReadLocalFileheader()
{
SLocalFileHeader zipHeader;
int ret;
ret = FRead(&(zipHeader.head), sizeof(zipHeader.head));
if(ret==FALSE)
{
m_nErr = ERR_AT_READ_HEADER;
return FALSE;
}
// ALZ Ȯ<><C8AE>..
2020-05-05 18:22:38 +00:00
if( (zipHeader.head.fileDescriptor & (SHORT)1) != 0){
m_bIsEncrypted = TRUE; // <20>ϳ<EFBFBD><CFB3><EFBFBD><EFBFBD><EFBFBD> <20><>ȣ <20>ɷ<EFBFBD><C9B7><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
2020-05-05 18:22:35 +00:00
}
2020-05-05 18:22:38 +00:00
if( (zipHeader.head.fileDescriptor & (SHORT)8) != 0){
2020-05-05 18:22:35 +00:00
m_bIsDataDescr = TRUE;
}
2020-05-05 18:22:38 +00:00
int byteLen = zipHeader.head.fileDescriptor/0x10;
2020-05-05 18:22:29 +00:00
if(byteLen)
{
FRead(&(zipHeader.compressionMethod), sizeof(zipHeader.compressionMethod));
2020-05-05 18:22:39 +00:00
FRead(&(zipHeader.unknown), sizeof(zipHeader.unknown));
FRead(&(zipHeader.fileCRC), sizeof(zipHeader.fileCRC));
// FRead(&(zipHeader.passwordCRC), sizeof(zipHeader.passwordCRC));
2020-05-05 18:22:29 +00:00
FRead(&(zipHeader.compressedSize), byteLen);
FRead(&(zipHeader.uncompressedSize), byteLen); // <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><20><><EFBFBD><EFBFBD>.
}
2020-05-05 18:22:31 +00:00
// little to system
zipHeader.head.fileNameLength = unalz_le16toh(zipHeader.head.fileNameLength);
zipHeader.compressedSize = unalz_le64toh(zipHeader.compressedSize);
zipHeader.uncompressedSize = unalz_le64toh(zipHeader.uncompressedSize);
2020-05-05 18:22:29 +00:00
// FILE NAME
2020-05-05 18:22:39 +00:00
zipHeader.fileName = (char*)malloc(zipHeader.head.fileNameLength+sizeof(char));
2020-05-05 18:22:29 +00:00
if(zipHeader.fileName==NULL)
{
m_nErr = ERR_INVALID_FILENAME_LENGTH;
return FALSE;
}
FRead(zipHeader.fileName, zipHeader.head.fileNameLength);
zipHeader.fileName[zipHeader.head.fileNameLength] = (CHAR)NULL;
2020-05-05 18:22:31 +00:00
#ifdef _UNALZ_ICONV // codepage convert
if(strlen(m_szToCodepage))
{
#define ICONV_BUF_SIZE (260*6) // utf8 <20><> <20>ִ<EFBFBD> 6byte
size_t ileft, oleft;
iconv_t cd;
size_t iconv_result;
size_t size;
char inbuf[ICONV_BUF_SIZE];
char outbuf[ICONV_BUF_SIZE];
2020-05-05 18:22:38 +00:00
#if defined(__FreeBSD__) || defined(__CYGWIN__)
2020-05-05 18:22:31 +00:00
const char *inptr = inbuf;
#else
char *inptr = inbuf;
#endif
char *outptr = outbuf;
size = strlen(zipHeader.fileName)+1;
strncpy(inbuf, zipHeader.fileName, size);
ileft = size;
oleft = sizeof(outbuf);
cd = iconv_open(m_szToCodepage, m_szFromCodepage); // <20><><EFBFBD><EFBFBD> "CP949" <20><><EFBFBD><EFBFBD> "UTF-8" <20><>
iconv(cd, NULL, NULL, NULL, NULL);
if( cd == (iconv_t)(-1))
{
m_nErr = ERR_ICONV_CANT_OPEN; // printf("Converting Error : Cannot open iconv");
return FALSE;
}
else
{
iconv_result = iconv(cd, &inptr, &ileft, &outptr, &oleft);
if(iconv_result== (size_t)(-1)) // iconv <20><><EFBFBD><EFBFBD>..
{
if (errno == EILSEQ)
m_nErr = ERR_ICONV_INVALID_MULTISEQUENCE_OF_CHARACTERS; // printf("Invalid Multibyte Sequence of Characters");
else if (errno == EINVAL)
m_nErr = ERR_ICONV_INCOMPLETE_MULTIBYTE_SEQUENCE; //printf("Incomplete multibyte sequence");
else if (errno != E2BIG)
m_nErr = ERR_ICONV_NOT_ENOUGH_SPACE_OF_BUFFER_TO_CONVERT; // printf("Not enough space of buffer to convert");
else
m_nErr = ERR_ICONV_ETC;
iconv_close(cd);
return FALSE;
}
else
{
outbuf[ICONV_BUF_SIZE-oleft] = 0;
2020-05-05 18:22:39 +00:00
if(zipHeader.fileName) free(zipHeader.fileName);
zipHeader.fileName = strdup(outbuf);
if (zipHeader.fileName == NULL)
{
m_nErr = ERR_ICONV_ETC;
iconv_close(cd);
return FALSE;
}
2020-05-05 18:22:31 +00:00
// printf("\n Converted File Name : %s", outbuf);
}
iconv_close(cd);
}
}
#endif
2020-05-05 18:22:29 +00:00
/*
// EXTRA FIELD LENGTH
if(zipHeader.head.extraFieldLength)
{
zipHeader.extraField = (BYTE*)malloc(zipHeader.head.extraFieldLength);
if(zipHeader.extraField==NULL)
{
m_nErr = ERR_INVALID_EXTRAFIELD_LENGTH;
return FALSE;
}
FRead(zipHeader.extraField, 1, zipHeader.head.extraFieldLength);
}
*/
2020-05-05 18:22:38 +00:00
if(IsEncryptedFile(zipHeader.head.fileDescriptor))
FRead(zipHeader.encChk, ENCR_HEADER_LEN); // xf86
2020-05-05 18:22:35 +00:00
2020-05-05 18:22:29 +00:00
// SKIP FILE DATA
zipHeader.dwFileDataPos = FTell(); // data <20><> <20><>ġ <20><><EFBFBD><EFBFBD><EFBFBD>ϱ<EFBFBD>..
FSeek(FTell()+zipHeader.compressedSize);
// DATA DESCRIPTOR
/*
if(zipHeader.head.generalPurposeBitFlag.bit1)
{
FRead(zipHeader.extraField, 1, sizeof(zipHeader.extraField),);
}
*/
#ifdef _DEBUG
printf("NAME:%s COMPRESSED SIZE:%d UNCOMPRESSED SIZE:%d COMP METHOD:%d\n",
zipHeader.fileName,
zipHeader.compressedSize,
zipHeader.uncompressedSize,
zipHeader.compressionMethod
);
#endif
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>Ͽ<EFBFBD> <20>߰<EFBFBD><DFB0>Ѵ<EFBFBD>..
m_fileList.push_back(zipHeader);
return TRUE;
}
BOOL CUnAlz::ReadCentralDirectoryStructure()
{
SCentralDirectoryStructure header;
if(FRead(&header, sizeof(header.head))==FALSE)
{
m_nErr = ERR_CANT_READ_CENTRAL_DIRECTORY_STRUCTURE_HEAD;
return FALSE;
}
/*
// read file name
if(header.head.fileNameLength)
{
header.fileName = (char*)malloc(header.head.fileNameLength+1);
if(header.fileName==NULL)
{
m_nErr = ERR_INVALID_FILENAME_SIZE;
return FALSE;
}
FRead(header.fileName, 1, header.head.fileNameLength, m_fp);
header.fileName[header.head.fileNameLength] = NULL;
}
// extra field;
if(header.head.extraFieldLength)
{
header.extraField = (BYTE*)malloc(header.head.extraFieldLength);
if(header.extraField==NULL)
{
m_nErr = ERR_INVALID_EXTRAFIELD_SIZE;
return FALSE;
}
FRead(header.extraField, 1, header.head.extraFieldLength, m_fp);
}
// file comment;
if(header.head.fileCommentLength)
{
header.fileComment = (char*)malloc(header.head.fileCommentLength+1);
if(header.fileComment==NULL)
{
m_nErr = ERR_INVALID_FILECOMMENT_SIZE;
return FALSE;
}
FRead(header.fileComment, 1, header.head.fileCommentLength, m_fp);
header.fileComment[header.head.fileCommentLength] = NULL;
}
*/
return TRUE;
}
BOOL CUnAlz::ReadEndofCentralDirectoryRecord()
{
/*
SEndOfCentralDirectoryRecord header;
if(FRead(&header, sizeof(header.head), 1, m_fp)!=1)
{
m_nErr = ERR_CANT_READ_HEADER;
return FALSE;
}
if(header.head.zipFileCommentLength)
{
header.fileComment = (char*)malloc(header.head.zipFileCommentLength+1);
if(header.fileComment==NULL)
{
m_nErr = ERR_INVALID_FILECOMMENT_SIZE;
return FALSE;
}
FRead(header.fileComment, 1, header.head.zipFileCommentLength, m_fp);
header.fileComment[header.head.zipFileCommentLength] = NULL;
}
*/
return TRUE;
}
BOOL CUnAlz::SetCurrentFile(const char* szFileName)
{
FileList::iterator i;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ã<>´<EFBFBD>.
for(i=m_fileList.begin(); i<m_fileList.end(); i++)
{
#ifdef _WIN32
if(stricmp(i->fileName, szFileName)==0)
#else
if(strcmp(i->fileName, szFileName)==0)
#endif
{
m_posCur = i;
return TRUE;
}
}
m_posCur = (FileList::iterator)NULL;
return FALSE;
}
2020-05-05 18:22:39 +00:00
void CUnAlz::SetCurrentFile(FileList::iterator newPos)
{
m_posCur = newPos;
}
2020-05-05 18:22:29 +00:00
#ifndef MAX_WBITS
# define MAX_WBITS 15 /* 32K LZ77 window */
#endif
////////////////////////////////////////////////////////////////////////////////////////////////////
/// <20><><EFBFBD>ۿ<EFBFBD> <20><><EFBFBD><EFBFBD> Ǯ<><C7AE>. <20><><EFBFBD>۴<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ũ<><20>غ<EFBFBD><D8BA>Ǿ<EFBFBD> <20>־<EFBFBD><D6BE><EFBFBD> <20>Ѵ<EFBFBD>.
/// @param pDestBuf
/// @return
/// @date 2004-03-07 <20><><EFBFBD><EFBFBD> 12:26:13
////////////////////////////////////////////////////////////////////////////////////////////////////
BOOL CUnAlz::ExtractCurrentFileToBuf(BYTE* pDestBuf, int nBufSize)
{
SExtractDest dest;
dest.nType = ET_MEM;
dest.buf = pDestBuf;
dest.bufpos = 0;
dest.bufsize = nBufSize;
return ExtractTo(&dest);
}
////////////////////////////////////////////////////////////////////////////////////////////////////
/// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> (SetCurrentFile<6C><65> <20><>)<29><> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>ο<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>Ϸ<EFBFBD> Ǭ<><C7AC>.
/// @param szDestPathName - <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
/// @param szDestFileName - <20><><EFBFBD><EFBFBD> <20><><EFBFBD>ϸ<EFBFBD>, NULL <20≯<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>ϸ<EFBFBD> <20><><EFBFBD><EFBFBD>
/// @return
/// @date 2004-03-06 <20><><EFBFBD><EFBFBD> 11:06:59
////////////////////////////////////////////////////////////////////////////////////////////////////
BOOL CUnAlz::ExtractCurrentFile(const char* szDestPathName, const char* szDestFileName)
{
if(m_posCur==(FileList::iterator)NULL) {ASSERT(0); return FALSE;}
BOOL ret=FALSE;
SExtractDest dest;
char szDestPathFileName[MAX_PATH];
2020-05-05 18:22:35 +00:00
if(chkValidPassword() == FALSE)
{
return FALSE;
}
2020-05-05 18:22:29 +00:00
// <20><><EFBFBD>θ<EFBFBD>
strcpy(szDestPathFileName, szDestPathName);
if(szDestPathFileName[strlen(szDestPathFileName)]!=PATHSEPC)
strcat(szDestPathFileName, PATHSEP);
// <20><><EFBFBD>ϸ<EFBFBD>
if(szDestFileName) strcat(szDestPathFileName, szDestFileName);
else strcat(szDestPathFileName, m_posCur->fileName);
2020-05-05 18:22:31 +00:00
#ifndef _WIN32
{
char* p = szDestPathFileName; // <20><><EFBFBD><EFBFBD> delimiter <20>ٲٱ<D9B2>
while(*p)
{
if(*p=='\\') *p='/';
p++;
}
}
#endif
2020-05-05 18:22:29 +00:00
// <20><><EFBFBD><EFBFBD>Ǯ <20><><EFBFBD><EFBFBD> ( <20><><EFBFBD><EFBFBD> )
dest.nType = ET_FILE;
dest.fp = fopen(szDestPathFileName, "wb");
if(dest.fp==NULL)
{
DigPath(szDestPathFileName); // <20><><EFBFBD>θ<EFBFBD><CEB8><EFBFBD> / <20><> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>..
dest.fp = fopen(szDestPathFileName, "wb");
}
2020-05-05 18:22:31 +00:00
#ifdef _WIN32
2020-05-05 18:22:29 +00:00
if(dest.fp==NULL)
{
ASSERT(0);
if(m_pFuncCallBack)
{
CHAR buf[1024];
sprintf(buf, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> : %s", szDestPathFileName);
m_pFuncCallBack(buf, 0,0,m_pCallbackParam, NULL);
}
return FALSE;
}
2020-05-05 18:22:31 +00:00
#endif
2020-05-05 18:22:29 +00:00
// CALLBACK <20><><EFBFBD><EFBFBD>
2020-05-05 18:22:33 +00:00
if(m_pFuncCallBack) m_pFuncCallBack(m_posCur->fileName, 0,m_posCur->uncompressedSize,m_pCallbackParam, NULL);
2020-05-05 18:22:29 +00:00
ret = ExtractTo(&dest);
2020-05-05 18:22:31 +00:00
if(dest.fp!=NULL)fclose(dest.fp);
2020-05-05 18:22:29 +00:00
return ret;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> Ǯ<><C7AE>..
/// @param dest
/// @return
/// @date 2004-03-07 <20><><EFBFBD><EFBFBD> 12:44:36
////////////////////////////////////////////////////////////////////////////////////////////////////
BOOL CUnAlz::ExtractTo(SExtractDest* dest)
{
BOOL ret = FALSE;
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> Ǯ<><C7AE>
if(m_posCur->compressionMethod==COMP_NOCOMP)
{
ret = ExtractRawfile(dest, *m_posCur);
}
else if(m_posCur->compressionMethod==COMP_BZIP2)
{
ret = ExtractBzip2(dest, *m_posCur); // bzip2
}
else if(m_posCur->compressionMethod==COMP_DEFLATE)
{
ret = ExtractDeflate2(dest, *m_posCur); // deflate
}
2020-05-05 18:22:39 +00:00
else // COMP_UNKNOWN
2020-05-05 18:22:29 +00:00
{
2020-05-05 18:22:39 +00:00
// alzip 5.6 <20><><EFBFBD><EFBFBD> <20>߰<EFBFBD><DFB0><EFBFBD> <20><><EFBFBD><EFBFBD>(5.5 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Ǯ<><C7AE> <20><><EFBFBD>Ѵ<EFBFBD>. <20><><EFBFBD><EFBFBD> 5.51 <20><> Ǭ<><C7AC> )
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>Ȯ<EFBFBD><C8AE> <20><> <20><> <20><><EFBFBD><EFBFBD>.
m_nErr = ERR_UNKNOWN_COMPRESSION_METHOD;
ASSERT(0);
2020-05-05 18:22:29 +00:00
ret = FALSE;
}
return ret;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
/// DEFLATE <20><> Ǯ<><C7AE> - <20>׽<EFBFBD>Ʈ<EFBFBD><C6AE> <20>Լ<EFBFBD>. <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Ѳ<EFBFBD><D1B2><EFBFBD><EFBFBD><EFBFBD> <20>о Ǭ<><C7AC>. <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>.
/// @param fp - <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
/// @param file - <20>ҽ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
/// @return
/// @date 2004-03-06 <20><><EFBFBD><EFBFBD> 11:09:17
////////////////////////////////////////////////////////////////////////////////////////////////////
/*
BOOL CUnAlz::ExtractDeflate(FILE* fp, SLocalFileHeader& file)
{
z_stream stream;
BYTE* pInBuf=NULL;
BYTE* pOutBuf=NULL;
int nInBufSize = file.compressedSize;
int nOutBufSize = file.uncompressedSize;
int err;
int flush=Z_SYNC_FLUSH;
BOOL ret = FALSE;
memset(&stream, 0, sizeof(stream));
pInBuf = (BYTE*)malloc(nInBufSize);
if(pInBuf==NULL)
{
m_nErr = ERR_MEM_ALLOC_FAILED;
goto END;
}
pOutBuf = (BYTE*)malloc(nOutBufSize);
if(pOutBuf==NULL)
{
m_nErr = ERR_MEM_ALLOC_FAILED;
goto END;
}
// <20>ѹ<EFBFBD><D1B9><EFBFBD> <20>о
fseek(m_fp, file.dwFileDataPos, SEEK_SET);
if(FRead(pInBuf, nInBufSize, 1, m_fp)!=1)
{
m_nErr = ERR_FILE_READ_ERROR;
goto END;
}
// <20>ʱ<EFBFBD>ȭ..
inflateInit2(&stream, -MAX_WBITS);
stream.next_out = pOutBuf;
stream.avail_out = nOutBufSize;
stream.next_in = pInBuf;
stream.avail_in = nInBufSize;
err = inflate(&stream, flush);
if(err!=Z_OK && err!=Z_STREAM_END )
{
m_nErr = ERR_INFLATE_FAILED;
goto END;
}
fwrite(pOutBuf, 1, nOutBufSize, fp);
ret = TRUE;
END :
inflateEnd(&stream);
if(pInBuf) free(pInBuf);
if(pOutBuf) free(pOutBuf);
return ret;
}
*/
////////////////////////////////////////////////////////////////////////////////////////////////////
/// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> Ǯ<><C7AE>
/// @param szDestPathName - <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
/// @return
/// @date 2004-03-06 <20><><EFBFBD><EFBFBD> 11:09:49
////////////////////////////////////////////////////////////////////////////////////////////////////
BOOL CUnAlz::ExtractAll(const char* szDestPathName)
{
FileList::iterator i;
for(i=m_fileList.begin(); i<m_fileList.end(); i++)
{
m_posCur = i;
2020-05-05 18:22:35 +00:00
if(ExtractCurrentFile(szDestPathName)==FALSE) return FALSE;
2020-05-05 18:22:29 +00:00
if(m_bHalt)
break; // <20><><EFBFBD>߱<EFBFBD>..
}
return TRUE;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
/// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ı<EFBFBD> - <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Ǵ<EFBFBD>(dig)
/// @param szPathName
/// @return
/// @date 2004-03-06 <20><><EFBFBD><EFBFBD> 11:10:12
////////////////////////////////////////////////////////////////////////////////////////////////////
BOOL CUnAlz::DigPath(const char* szPathName)
{
char* dup = strdup(szPathName);
char seps[] = "/\\";
char *token;
char path[MAX_PATH] = {0};
char* last;
// <20><><EFBFBD>θ<EFBFBD> <20>̱<EFBFBD>.
last = dup + strlen(dup);
while(last!=dup)
{
if(*last=='/' || *last=='\\')
{
*last = (char)NULL;
break;
}
last --;
}
token = strtok( dup, seps );
while( token != NULL )
{
if(strlen(path)==0)
strcpy(path, token);
else
{
strcat(path, PATHSEP);
strcat(path, token);
}
if(IsFolder(path)==FALSE)
#ifdef _WIN32
_mkdir(path);
#else
mkdir(path, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
#endif
token = strtok( NULL, seps );
}
free(dup);
if(IsFolder(szPathName)) return TRUE;
return FALSE;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
/// <20><><EFBFBD><EFBFBD><EFBFBD>ε<EFBFBD> <20><><EFBFBD><EFBFBD> <20>ΰ<EFBFBD>?
/// @param szPathName
/// @return
/// @date 2004-03-06 <20><><EFBFBD><EFBFBD> 11:03:26
////////////////////////////////////////////////////////////////////////////////////////////////////
2020-05-05 18:22:38 +00:00
BOOL CUnAlz::IsFolder(const CHAR* szPathName)
2020-05-05 18:22:29 +00:00
{
#ifdef _WIN32
2020-05-05 18:22:31 +00:00
UINT32 dwRet;
2020-05-05 18:22:29 +00:00
dwRet = GetFileAttributesA(szPathName);
if(dwRet==0xffffffff) return FALSE;
if(dwRet & FILE_ATTRIBUTE_DIRECTORY) return TRUE;
return FALSE;
#else
struct stat buf;
int result;
result = stat(szPathName, &buf);
if(result!=0) return FALSE;
//printf("isfolder:%s, %d,%d,%d\n", szPathName, buf.st_mode, S_IFDIR, buf.st_mode & S_IFDIR);
if(buf.st_mode & S_IFDIR) return TRUE;
return FALSE;
#endif
}
////////////////////////////////////////////////////////////////////////////////////////////////////
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Ǯ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Ǭ<><C7AC>.
/// @param dest - <20><><EFBFBD><EFBFBD> OBJECT
/// @param buf - Ǯ<><C7AE> <20><><EFBFBD><EFBFBD>Ÿ
/// @param nSize - <20><><EFBFBD><EFBFBD>Ÿ<EFBFBD><C5B8> ũ<><C5A9>
/// @return <20><> <20><><EFBFBD><EFBFBD>Ʈ<EFBFBD><C6AE>. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> -1 <20><><EFBFBD><EFBFBD>
/// @date 2004-03-07 <20><><EFBFBD><EFBFBD> 12:37:41
////////////////////////////////////////////////////////////////////////////////////////////////////
int CUnAlz::WriteToDest(SExtractDest* dest, BYTE* buf, int nSize)
{
if(dest->nType==ET_FILE)
{
return fwrite(buf, 1, nSize, dest->fp);
}
else if(dest->nType==ET_MEM)
{
2020-05-05 18:22:39 +00:00
if(dest->buf==NULL) return nSize; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> NULL <20>̴<EFBFBD>... <20><><EFBFBD><EFBFBD>Ǫ<EFBFBD><C7AA> <20>ô<EFBFBD><C3B4><EFBFBD> <20>Ѵ<EFBFBD>..
2020-05-05 18:22:29 +00:00
if(dest->bufpos+nSize >dest->bufsize) // <20><><EFBFBD><EFBFBD>.. <20><><EFBFBD>۰<EFBFBD> <20><><EFBFBD>ƴ<EFBFBD>.
{
ASSERT(0);
return -1;
}
// memcpy
memcpy(dest->buf + dest->bufpos, buf, nSize);
dest->bufpos += nSize;
return nSize;
}
else
{
ASSERT(0);
}
return -1;
}
/* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>.. <20><><EFBFBD><EFBFBD><EFBFBD>Ѱ<EFBFBD> <20>Ʊ<EFBFBD><C6B1><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
#define ALZDLZ_HEADER_SIZE 4 // alz <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> bzip2 <20><><EFBFBD><EFBFBD> ũ<><C5A9>
#define BZIP2_HEADER_SIZE 10 // bzip <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> ũ<><C5A9>
#define BZIP2_CRC_SIZE 4 // bzip2 <20><> crc
#define BZIP2_TAIL_SIZE 10 // <20><><EFBFBD><EFBFBD> 4+5 <20><><EFBFBD><EFBFBD>.?
BYTE bzip2Header[BZIP2_HEADER_SIZE] = {0x42, 0x5a, 0x68, 0x39, 0x31, 0x41, 0x59, 0x26, 0x53, 0x59};
BOOL CUnAlz::ExtractBzip2_bak(FILE* fp, SLocalFileHeader& file)
{
bz_stream stream;
BYTE* pInBuf=NULL;
BYTE* pOutBuf=NULL;
int nInBufSize = file.compressedSize;
int nOutBufSize = file.uncompressedSize;
//int err;
int flush=Z_SYNC_FLUSH;
BOOL ret = FALSE;
2020-05-05 18:22:31 +00:00
UINT32 crc = 0xffffffff;
2020-05-05 18:22:29 +00:00
//BYTE temp[100];
memset(&stream, 0, sizeof(stream));
pInBuf = (BYTE*)malloc(nInBufSize + BZIP2_HEADER_SIZE + BZIP2_CRC_SIZE - ALZDLZ_HEADER_SIZE + BZIP2_TAIL_SIZE);
if(pInBuf==NULL)
{
m_nErr = ERR_MEM_ALLOC_FAILED;
goto END;
}
pOutBuf = (BYTE*)malloc(nOutBufSize);
if(pOutBuf==NULL)
{
m_nErr = ERR_MEM_ALLOC_FAILED;
goto END;
}
// ALZ <20><> BZIP <20><><EFBFBD><EFBFBD> ("DLZ.") <20><>ŵ<EFBFBD>ϱ<EFBFBD>.
fseek(m_fp, ALZDLZ_HEADER_SIZE, SEEK_CUR);
// BZIP2 <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
memcpy(pInBuf, bzip2Header, BZIP2_HEADER_SIZE);
// BZIP2 CRC
memcpy(pInBuf+BZIP2_HEADER_SIZE, &(crc), BZIP2_CRC_SIZE);
// <20><>¥ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>Ÿ<EFBFBD><C5B8> <20>ѹ<EFBFBD><D1B9><EFBFBD> <20>о
fseek(m_fp, file.dwFileDataPos+ALZDLZ_HEADER_SIZE, SEEK_SET);
if(FRead(pInBuf+BZIP2_HEADER_SIZE+BZIP2_CRC_SIZE, nInBufSize-ALZDLZ_HEADER_SIZE, 1, m_fp)!=1)
{
m_nErr = ERR_FILE_READ_ERROR;
goto END;
}
// <20>ʱ<EFBFBD>ȭ..
stream.bzalloc = NULL;
stream.bzfree = NULL;
stream.opaque = NULL;
ret = BZ2_bzDecompressInit ( &stream, 3,0 );
if (ret != BZ_OK) goto END;
//memcpy(temp, pInBuf, 100);
stream.next_in = (char*)pInBuf;
stream.next_out = (char*)pOutBuf;
stream.avail_in = nInBufSize+BZIP2_HEADER_SIZE+BZIP2_CRC_SIZE+BZIP2_TAIL_SIZE;
stream.avail_out = nOutBufSize;
ret = BZ2_bzDecompress ( &stream );
// BZ_DATA_ERROR <20><> <20><><EFBFBD>ϵ<EFBFBD> <20><> <20>ִ<EFBFBD>..
//if (ret == BZ_OK) goto END;
//if (ret != BZ_STREAM_END) goto END;
BZ2_bzDecompressEnd(&stream);
fwrite(pOutBuf, 1, nOutBufSize, fp);
ret = TRUE;
END :
if(pInBuf) free(pInBuf);
if(pOutBuf) free(pOutBuf);
if(ret==FALSE) BZ2_bzDecompressEnd(&stream);
return ret;
}
*/
////////////////////////////////////////////////////////////////////////////////////////////////////
/// RAW <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> Ǯ<><C7AE>
/// @param fp - <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
/// @param file - <20>ҽ<EFBFBD> <20><><EFBFBD><EFBFBD>
/// @return
/// @date 2004-03-06 <20><><EFBFBD><EFBFBD> 11:10:53
////////////////////////////////////////////////////////////////////////////////////////////////////
#define BUF_LEN (4096*2)
BOOL CUnAlz::ExtractRawfile(SExtractDest* dest, SLocalFileHeader& file)
{
2020-05-05 18:22:39 +00:00
BOOL ret = FALSE;
BYTE buf[BUF_LEN];
INT64 read;
INT64 sizeToRead;
INT64 bufLen = BUF_LEN;
INT64 nWritten = 0;
BOOL bHalt = FALSE;
BOOL bIsEncrypted = IsEncryptedFile(); // <20><>ȣ<EFBFBD>ɸ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ΰ<EFBFBD>?
UINT32 dwCRC32= 0;
2020-05-05 18:22:38 +00:00
2020-05-05 18:22:29 +00:00
// <20><>ġ <20><><EFBFBD><EFBFBD>.
FSeek(file.dwFileDataPos);
sizeToRead = file.compressedSize; // <20><><EFBFBD><EFBFBD> ũ<><C5A9>.
2020-05-05 18:22:39 +00:00
m_nErr = ERR_NOERR;
2020-05-05 18:22:29 +00:00
while(sizeToRead)
{
read = min(sizeToRead, bufLen);
if(FRead(buf, (int)read)==FALSE)
{
break;
}
2020-05-05 18:22:38 +00:00
if(bIsEncrypted)
DecryptingData((int)read, buf); // xf86
2020-05-05 18:22:35 +00:00
2020-05-05 18:22:39 +00:00
dwCRC32 = crc32(dwCRC32, buf, (UINT)(read));
2020-05-05 18:22:29 +00:00
WriteToDest(dest, buf, (int)read);
//fwrite(buf, read, 1, fp);
sizeToRead -= read;
nWritten+=read;
// progress callback
if(m_pFuncCallBack)
{
m_pFuncCallBack(NULL, nWritten, file.uncompressedSize, m_pCallbackParam, &bHalt);
if(bHalt)
{
break;
}
}
}
m_bHalt = bHalt;
2020-05-05 18:22:39 +00:00
if(m_nErr==ERR_NOERR) // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Ǯ<><C7AE><EFBFBD><EFBFBD>.. CRC <20>˻<EFBFBD><CBBB>ϱ<EFBFBD>..
{
if(file.fileCRC==dwCRC32)
{
ret = TRUE;
}
else
{
m_nErr = ERR_INVALID_FILE_CRC;
}
}
2020-05-05 18:22:29 +00:00
return ret;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
/// BZIP2 <20><><EFBFBD><EFBFBD> Ǯ<><C7AE>..
/// @param fp_w - <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
/// @param file - <20>ҽ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
/// @return
/// @date 2004-03-01 <20><><EFBFBD><EFBFBD> 5:47:36
////////////////////////////////////////////////////////////////////////////////////////////////////
#define BZIP2_EXTRACT_BUF_SIZE 0x2000
BOOL CUnAlz::ExtractBzip2(SExtractDest* dest, SLocalFileHeader& file)
{
2020-05-05 18:22:39 +00:00
BZFILE *bzfp = NULL;
int smallMode = 0;
int verbosity = 1;
int bzerr;
INT64 len;
BYTE buff[BZIP2_EXTRACT_BUF_SIZE];
INT64 nWritten = 0;
BOOL bHalt = FALSE;
UINT32 dwCRC32= 0;
BOOL ret = FALSE;
2020-05-05 18:22:29 +00:00
FSeek(file.dwFileDataPos);
bzfp = BZ2_bzReadOpen(&bzerr,this,verbosity,smallMode,0,0);
if(bzfp==NULL){ASSERT(0); return FALSE;}
2020-05-05 18:22:39 +00:00
m_nErr = ERR_NOERR;
2020-05-05 18:22:29 +00:00
while((len=BZ2_bzread(bzfp,buff,BZIP2_EXTRACT_BUF_SIZE))>0)
{
WriteToDest(dest, (BYTE*)buff, (int)len);
//fwrite(buff,1,len,fp_w);
2020-05-05 18:22:39 +00:00
dwCRC32 = crc32(dwCRC32,buff, (UINT)(len));
2020-05-05 18:22:29 +00:00
nWritten+=len;
// progress callback
if(m_pFuncCallBack)
{
m_pFuncCallBack(NULL, nWritten, file.uncompressedSize, m_pCallbackParam, &bHalt);
if(bHalt)
{
break;
}
}
}
2020-05-05 18:22:39 +00:00
if(len<0) // <20><><EFBFBD><EFBFBD> <20><>Ȳ..
{
m_nErr = ERR_INFLATE_FAILED;
}
2020-05-05 18:22:29 +00:00
BZ2_bzReadClose( &bzerr, bzfp);
m_bHalt = bHalt;
2020-05-05 18:22:39 +00:00
if(m_nErr==ERR_NOERR) // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Ǯ<><C7AE><EFBFBD><EFBFBD>.. CRC <20>˻<EFBFBD><CBBB>ϱ<EFBFBD>..
{
if(file.fileCRC==dwCRC32)
{
ret = TRUE;
}
else
{
m_nErr = ERR_INVALID_FILE_CRC;
}
}
2020-05-05 18:22:29 +00:00
/*
// FILE* <20><> <20><><EFBFBD><EFBFBD><EFBFBD>Ұ<EFBFBD><D2B0><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD> <20>ڵ<EFBFBD>. - <20><>Ƽ <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>..
BZFILE *bzfp = NULL;
int smallMode = 0;
int verbosity = 1;
int bzerr;
int len;
char buff[BZIP2_EXTRACT_BUF_SIZE];
INT64 nWritten = 0;
BOOL bHalt = FALSE;
FSeek(file.dwFileDataPos, SEEK_SET);
bzfp = BZ2_bzReadOpen(&bzerr,m_fp,verbosity,smallMode,0,0);
while((len=BZ2_bzread(bzfp,buff,BZIP2_EXTRACT_BUF_SIZE))>0)
{
WriteToDest(dest, (BYTE*)buff, len);
//fwrite(buff,1,len,fp_w);
nWritten+=len;
// progress callback
if(m_pFuncCallBack)
{
m_pFuncCallBack(NULL, nWritten, file.uncompressedSize, m_pCallbackParam, &bHalt);
if(bHalt)
{
break;
}
}
}
BZ2_bzReadClose( &bzerr, bzfp);
m_bHalt = bHalt;
*/
2020-05-05 18:22:39 +00:00
return ret;
2020-05-05 18:22:29 +00:00
}
#ifndef UNZ_BUFSIZE
#define UNZ_BUFSIZE 0x1000 // (16384)
#endif
#define IN_BUF_SIZE UNZ_BUFSIZE
#define OUT_BUF_SIZE 0x1000 //IN_BUF_SIZE
////////////////////////////////////////////////////////////////////////////////////////////////////
/// deflate <20><> <20><><EFBFBD><EFBFBD> Ǯ<><C7AE>. ExtractDeflate() <20><> <20>޸<EFBFBD> <20><><EFBFBD>ݾ<EFBFBD> <20>о Ǭ<><C7AC>.
/// @param fp
/// @param file
/// @return
/// @date 2004-03-06 <20><><EFBFBD><EFBFBD> 11:11:36
////////////////////////////////////////////////////////////////////////////////////////////////////
BOOL CUnAlz::ExtractDeflate2(SExtractDest* dest, SLocalFileHeader& file)
{
z_stream stream;
BYTE pInBuf[IN_BUF_SIZE];
BYTE pOutBuf[OUT_BUF_SIZE];
int nInBufSize = IN_BUF_SIZE;
int nOutBufSize = OUT_BUF_SIZE;
int err;
int flush=Z_SYNC_FLUSH;
BOOL ret = FALSE;
INT64 nRestReadCompressed;
2020-05-05 18:22:31 +00:00
UINT32 dwCRC32= 0;
2020-05-05 18:22:29 +00:00
INT64 rest_read_uncompressed;
UINT iRead = 0;
INT64 nWritten = 0;
BOOL bHalt = FALSE;
2020-05-05 18:22:38 +00:00
BOOL bIsEncrypted = IsEncryptedFile(); // <20><>ȣ<EFBFBD>ɸ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ΰ<EFBFBD>?
2020-05-05 18:22:29 +00:00
memset(&stream, 0, sizeof(stream));
FSeek(file.dwFileDataPos);
inflateInit2(&stream, -MAX_WBITS);
nRestReadCompressed = file.compressedSize;
rest_read_uncompressed = file.uncompressedSize;
// <20><><EFBFBD><EFBFBD> <20>κ<EFBFBD>.
stream.next_out = pOutBuf;
stream.avail_out = OUT_BUF_SIZE;
2020-05-05 18:22:39 +00:00
m_nErr = ERR_NOERR;
2020-05-05 18:22:29 +00:00
while(stream.avail_out>0)
{
if(stream.avail_in==0 && nRestReadCompressed>0)
{
UINT uReadThis = UNZ_BUFSIZE;
if (nRestReadCompressed<(int)uReadThis)
uReadThis = (UINT)nRestReadCompressed; // <20><><EFBFBD><EFBFBD> ũ<><C5A9>.
if (uReadThis == 0)
break; // <20><><EFBFBD><EFBFBD>
if(FRead(pInBuf, uReadThis)==FALSE)
{
m_nErr = ERR_CANT_READ_FILE;
goto END;
}
2020-05-05 18:22:39 +00:00
2020-05-05 18:22:38 +00:00
if(bIsEncrypted)
DecryptingData(uReadThis, pInBuf); // xf86
2020-05-05 18:22:39 +00:00
// dwCRC32 = crc32(dwCRC32,pInBuf, (UINT)(uReadThis));
2020-05-05 18:22:35 +00:00
2020-05-05 18:22:29 +00:00
nRestReadCompressed -= uReadThis;
stream.next_in = pInBuf;
stream.avail_in = uReadThis;
}
UINT uTotalOutBefore,uTotalOutAfter;
const BYTE *bufBefore;
UINT uOutThis;
int flush=Z_SYNC_FLUSH;
uTotalOutBefore = stream.total_out;
bufBefore = stream.next_out;
err=inflate(&stream,flush);
uTotalOutAfter = stream.total_out;
uOutThis = uTotalOutAfter-uTotalOutBefore;
dwCRC32 = crc32(dwCRC32,bufBefore, (UINT)(uOutThis));
rest_read_uncompressed -= uOutThis;
iRead += (UINT)(uTotalOutAfter - uTotalOutBefore);
WriteToDest(dest, pOutBuf, uOutThis);
//fwrite(pOutBuf, uOutThis, 1, fp); // file <20><> <20><><EFBFBD><EFBFBD>.
stream.next_out = pOutBuf;
stream.avail_out = OUT_BUF_SIZE;
nWritten+=uOutThis;
// progress callback
if(m_pFuncCallBack)
{
m_pFuncCallBack(NULL, nWritten, file.uncompressedSize, m_pCallbackParam, &bHalt);
if(bHalt)
{
2020-05-05 18:22:39 +00:00
m_nErr = ERR_USER_ABORTED;
2020-05-05 18:22:29 +00:00
break;
}
}
if (err==Z_STREAM_END)
break;
//if(iRead==0) break; // UNZ_EOF;
if (err!=Z_OK)
{
m_nErr = ERR_INFLATE_FAILED;
goto END;
}
}
m_bHalt = bHalt;
2020-05-05 18:22:39 +00:00
if(m_nErr==ERR_NOERR) // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Ǯ<><C7AE><EFBFBD><EFBFBD>.. CRC <20>˻<EFBFBD><CBBB>ϱ<EFBFBD>..
{
if(file.fileCRC==dwCRC32)
{
ret = TRUE;
}
else
{
m_nErr = ERR_INVALID_FILE_CRC;
}
}
2020-05-05 18:22:29 +00:00
END :
inflateEnd(&stream);
return ret;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
/// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
/// @param szPathName
/// @return
/// @date 2004-10-02 <20><><EFBFBD><EFBFBD> 11:47:14
////////////////////////////////////////////////////////////////////////////////////////////////////
BOOL CUnAlz::FOpen(const char* szPathName)
{
char* temp = strdup(szPathName); // <20><><EFBFBD>ϸ<EFBFBD> <20><><EFBFBD><EFBFBD>..
int i;
int nLen = strlen(szPathName);
2020-05-05 18:22:33 +00:00
UINT64 nFileSizeLow;
UINT32 dwFileSizeHigh;
2020-05-05 18:22:29 +00:00
m_nFileCount = 0;
m_nCurFile = 0;
m_nVirtualFilePos = 0;
m_nCurFilePos = 0;
m_bIsEOF = FALSE;
for(i=0;i<MAX_FILES;i++) // aa.alz <20><><EFBFBD>ϸ<EFBFBD><CFB8><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> aa.a00 aa.a01 aa.a02 .. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
{
if(i>0) sprintf(temp+nLen-3, "%c%02d", (i-1)/100+'a', (i-1)%100);
#ifdef _WIN32
m_files[i].fp = CreateFileA(temp, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
if(m_files[i].fp==INVALID_HANDLE_VALUE) break;
2020-05-05 18:22:33 +00:00
nFileSizeLow = GetFileSize(m_files[i].fp, (DWORD*)&dwFileSizeHigh);
2020-05-05 18:22:29 +00:00
#else
m_files[i].fp = fopen(temp, "rb");
if(m_files[i].fp==NULL) break;
dwFileSizeHigh=0;
2020-05-05 18:22:31 +00:00
fseek(m_files[i].fp,0,SEEK_END);
2020-05-05 18:22:33 +00:00
nFileSizeLow=ftell(m_files[i].fp);
2020-05-05 18:22:29 +00:00
fseek(m_files[i].fp,0,SEEK_SET);
#endif
m_nFileCount++;
2020-05-05 18:22:33 +00:00
m_files[i].nFileSize = ((INT64)nFileSizeLow) + (((INT64)dwFileSizeHigh)<<32);
2020-05-05 18:22:29 +00:00
if(i==0) m_files[i].nMultivolHeaderSize = 0;
else m_files[i].nMultivolHeaderSize = MULTIVOL_HEAD_SIZE;
m_files[i].nMultivolTailSize = MULTIVOL_TAIL_SIZE;
}
free(temp);
if(m_nFileCount==0) return FALSE;
m_files[m_nFileCount-1].nMultivolTailSize = 0; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ö<EFBFBD><C3B6><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>..
return TRUE;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
/// <20><><EFBFBD><EFBFBD> <20>ݱ<EFBFBD>
/// @return
/// @date 2004-10-02 <20><><EFBFBD><EFBFBD> 11:48:53
////////////////////////////////////////////////////////////////////////////////////////////////////
void CUnAlz::FClose()
{
int i;
#ifdef _WIN32
for(i=0;i<m_nFileCount;i++) CloseHandle(m_files[i].fp);
#else
for(i=0;i<m_nFileCount;i++) fclose(m_files[i].fp);
#endif
memset(m_files, 0, sizeof(m_files));
m_nFileCount = 0;
m_nCurFile = -1;
m_nVirtualFilePos = 0;
m_nCurFilePos = 0;
m_bIsEOF = FALSE;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>ΰ<EFBFBD>?
/// @return
/// @date 2004-10-02 <20><><EFBFBD><EFBFBD> 11:48:21
////////////////////////////////////////////////////////////////////////////////////////////////////
BOOL CUnAlz::FEof()
{
return m_bIsEOF;
/*
if(m_fp==NULL){ASSERT(0); return TRUE;}
if(feof(m_fp)) return TRUE;
return FALSE;
*/
}
////////////////////////////////////////////////////////////////////////////////////////////////////
/// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><>ġ
/// @return
/// @date 2004-10-02 <20><><EFBFBD><EFBFBD> 11:50:50
////////////////////////////////////////////////////////////////////////////////////////////////////
INT64 CUnAlz::FTell()
{
return m_nVirtualFilePos; // return ftell(m_fp);
}
////////////////////////////////////////////////////////////////////////////////////////////////////
/// <20><><EFBFBD><EFBFBD> <20><>ġ <20><><EFBFBD><EFBFBD>
/// @param offset
/// @param origin
/// @return
/// @date 2004-10-02 <20><><EFBFBD><EFBFBD> 11:51:53
////////////////////////////////////////////////////////////////////////////////////////////////////
BOOL CUnAlz::FSeek(INT64 offset)
{
m_nVirtualFilePos = offset;
int i;
INT64 remain=offset;
LONG remainHigh;
m_bIsEOF = FALSE;
for(i=0;i<m_nFileCount;i++) // <20>տ<EFBFBD><D5BF><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><20><>ġ <20><><EFBFBD><EFBFBD><EFBFBD>ϱ<EFBFBD>..
{
if(remain<=m_files[i].nFileSize-m_files[i].nMultivolHeaderSize-m_files[i].nMultivolTailSize)
{
m_nCurFile = i;
m_nCurFilePos = remain+m_files[i].nMultivolHeaderSize; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ġ.
remainHigh = (LONG)((m_nCurFilePos>>32)&0xffffffff);
#ifdef _WIN32
SetFilePointer(m_files[i].fp, LONG(m_nCurFilePos), &remainHigh, FILE_BEGIN);
#else
fseek(m_files[i].fp, m_nCurFilePos, SEEK_SET);
#endif
return TRUE;
}
remain -= (m_files[i].nFileSize-m_files[i].nMultivolHeaderSize-m_files[i].nMultivolTailSize);
}
// <20><><EFBFBD><EFBFBD>..?
ASSERT(0);
return FALSE;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
/// <20><><EFBFBD><EFBFBD> <20>б<EFBFBD>
/// @param buffer
/// @param size
/// @param count
/// @return
/// @date 2004-10-02 <20><><EFBFBD><EFBFBD> 11:44:05
////////////////////////////////////////////////////////////////////////////////////////////////////
2020-05-05 18:22:31 +00:00
BOOL CUnAlz::FRead(void* buffer, UINT32 nBytesToRead, int* pTotRead )
2020-05-05 18:22:29 +00:00
{
BOOL ret;
2020-05-05 18:22:31 +00:00
UINT32 nNumOfBytesRead;
2020-05-05 18:22:29 +00:00
INT64 dwRemain;
2020-05-05 18:22:31 +00:00
UINT32 dwRead;
UINT32 dwTotRead;
2020-05-05 18:22:29 +00:00
dwRemain = nBytesToRead;
dwTotRead = 0;
if(pTotRead) *pTotRead=0;
while(dwRemain)
{
2020-05-05 18:22:31 +00:00
dwRead = (UINT32)min(dwRemain, (m_files[m_nCurFile].nFileSize-m_nCurFilePos-m_files[m_nCurFile].nMultivolTailSize));
2020-05-05 18:22:29 +00:00
if(dwRead==0) {
m_bIsEOF = TRUE;return FALSE;
}
#ifdef _WIN32
2020-05-05 18:22:31 +00:00
ret = ReadFile(m_files[m_nCurFile].fp, ((BYTE*)buffer)+dwTotRead, dwRead, (DWORD*)&nNumOfBytesRead, NULL);
2020-05-05 18:22:29 +00:00
if(ret==FALSE && GetLastError()==ERROR_HANDLE_EOF)
{
m_bIsEOF = TRUE;return FALSE;
}
2020-05-05 18:22:38 +00:00
2020-05-05 18:22:29 +00:00
#else
nNumOfBytesRead = fread(((BYTE*)buffer)+dwTotRead, 1,dwRead ,m_files[m_nCurFile].fp);
if(nNumOfBytesRead<=0)
{
m_bIsEOF = TRUE;return FALSE;
}
ret=TRUE;
#endif
if(dwRead!=nNumOfBytesRead) // <20>߻<EFBFBD><DFBB>ϸ<EFBFBD> <20>ȵȴ<C8B5>..
{
ASSERT(0); return FALSE;
}
m_nVirtualFilePos += nNumOfBytesRead; // virtual <20><><EFBFBD><EFBFBD> <20><>ġ..
m_nCurFilePos+=nNumOfBytesRead; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><>ġ.
dwRemain-=nNumOfBytesRead;
dwTotRead+=nNumOfBytesRead;
if(pTotRead) *pTotRead=dwTotRead;
if(m_nCurFilePos==m_files[m_nCurFile].nFileSize-m_files[m_nCurFile].nMultivolTailSize) // overflow
{
m_nCurFile++;
#ifdef _WIN32
if(m_files[m_nCurFile].fp==INVALID_HANDLE_VALUE)
#else
if(m_files[m_nCurFile].fp==NULL)
#endif
{
m_bIsEOF = TRUE;
if(dwRemain==0) return TRUE; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>о<EFBFBD><D0BE><EFBFBD>..
return FALSE;
}
m_nCurFilePos = m_files[m_nCurFile].nMultivolHeaderSize; // header skip
#ifdef _WIN32
SetFilePointer(m_files[m_nCurFile].fp, (int)m_nCurFilePos, NULL, FILE_BEGIN);
#else
fseek(m_files[m_nCurFile].fp, m_nCurFilePos, SEEK_SET);
#endif
}
else
if(m_nCurFilePos>m_files[m_nCurFile].nFileSize-m_files[m_nCurFile].nMultivolTailSize) ASSERT(0);
}
return ret;
}
2020-05-05 18:22:31 +00:00
////////////////////////////////////////////////////////////////////////////////////////////////////
/// error code <20><> <20><>Ʈ<EFBFBD><C6AE><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ٲ<EFBFBD> <20>ش<EFBFBD>.
/// @param nERR
/// @return
/// @date 2004-10-24 <20><><EFBFBD><EFBFBD> 3:28:39
////////////////////////////////////////////////////////////////////////////////////////////////////
const char* CUnAlz::LastErrToStr(ERR nERR)
{
if(nERR>= sizeof(errorstrtable)/sizeof(errorstrtable[0])) {ASSERT(0); return NULL; }
return errorstrtable[nERR];
}
2020-05-05 18:22:35 +00:00
// by xf86
BOOL CUnAlz::chkValidPassword()
{
2020-05-05 18:22:39 +00:00
if(IsEncryptedFile()==FALSE) {return TRUE;}
if (getPasswordLen() == 0){
m_nErr = ERR_PASSWD_NOT_SET;
return FALSE;
}
InitCryptKeys(m_szPasswd);
if(CryptCheck(m_posCur->encChk) == FALSE){
m_nErr = ERR_INVALID_PASSWD;
return FALSE;
2020-05-05 18:22:35 +00:00
}
return TRUE;
}
2020-05-05 18:22:38 +00:00
/*
2020-05-05 18:22:35 +00:00
////////////////////////////////////////////////////////////////////////////////////////////////////
// from CZipArchive
// Copyright (C) 2000 - 2004 Tadeusz Dracz
//
// http://www.artpol-software.com
//
// it's under GPL.
////////////////////////////////////////////////////////////////////////////////////////////////////
void CUnAlz::CryptDecodeBuffer(UINT32 uCount, CHAR *buf)
{
if (IsEncrypted())
for (UINT32 i = 0; i < uCount; i++)
CryptDecode(buf[i]);
}
void CUnAlz::CryptInitKeys()
{
m_keys[0] = 305419896L;
m_keys[1] = 591751049L;
m_keys[2] = 878082192L;
for (int i = 0; i < strlen(m_szPasswd); i++)
CryptUpdateKeys(m_szPasswd[i]);
}
void CUnAlz::CryptUpdateKeys(CHAR c)
{
m_keys[0] = CryptCRC32(m_keys[0], c);
m_keys[1] += m_keys[0] & 0xff;
m_keys[1] = m_keys[1] * 134775813L + 1;
c = CHAR(m_keys[1] >> 24);
m_keys[2] = CryptCRC32(m_keys[2], c);
}
BOOL CUnAlz::CryptCheck(CHAR *buf)
{
CHAR b = 0;
for (int i = 0; i < ENCR_HEADER_LEN; i++)
{
b = buf[i];
CryptDecode((CHAR&)b);
}
if (IsDataDescr()) // Data descriptor present
return CHAR(m_posCur->head.fileTimeDate >> 8) == b;
else
return CHAR(m_posCur->maybeCRC >> 24) == b;
}
CHAR CUnAlz::CryptDecryptCHAR()
{
int temp = (m_keys[2] & 0xffff) | 2;
return (CHAR)(((temp * (temp ^ 1)) >> 8) & 0xff);
}
void CUnAlz::CryptDecode(CHAR &c)
{
c ^= CryptDecryptCHAR();
CryptUpdateKeys(c);
}
UINT32 CUnAlz::CryptCRC32(UINT32 l, CHAR c)
{
const ULONG *CRC_TABLE = get_crc_table();
return CRC_TABLE[(l ^ c) & 0xff] ^ (l >> 8);
}
2020-05-05 18:22:38 +00:00
*/
////////////////////////////////////////////////////////////////////////////////////////////////////
/// <20><>ȣ<EFBFBD>ɸ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
/// @param fileDescriptor
/// @return
/// @date 2004-11-27 <20><><EFBFBD><EFBFBD> 11:25:32
////////////////////////////////////////////////////////////////////////////////////////////////////
BOOL CUnAlz::IsEncryptedFile(BYTE fileDescriptor)
{
return fileDescriptor&0x01;
}
BOOL CUnAlz::IsEncryptedFile()
{
return m_posCur->head.fileDescriptor&0x01;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
/// <20><>ȣ<EFBFBD><C8A3> Ű <20>ʱ<EFBFBD>ȭ
/// @param szPassword
/// @return
/// @date 2004-11-27 <20><><EFBFBD><EFBFBD> 11:04:01
////////////////////////////////////////////////////////////////////////////////////////////////////
void CUnAlz::InitCryptKeys(const CHAR* szPassword)
{
m_key[0] = 305419896;
m_key[1] = 591751049;
m_key[2] = 878082192;
int i;
for(i=0;i<(int)strlen(szPassword);i++)
{
UpdateKeys(szPassword[i]);
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////
/// <20><><EFBFBD><EFBFBD>Ÿ<EFBFBD><C5B8> Ű <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ʈ<EFBFBD>ϱ<EFBFBD>
/// @param c
/// @return
/// @date 2004-11-27 <20><><EFBFBD><EFBFBD> 11:04:09
////////////////////////////////////////////////////////////////////////////////////////////////////
void CUnAlz::UpdateKeys(BYTE c)
{
m_key[0] = CRC32(m_key[0], c);
m_key[1] = m_key[1]+(m_key[0]&0x000000ff);
m_key[1] = m_key[1]*134775813+1;
m_key[2] = CRC32(m_key[2],m_key[1]>>24);
}
////////////////////////////////////////////////////////////////////////////////////////////////////
/// <20><>ȣ<EFBFBD><C8A3> <20>´<EFBFBD><C2B4><EFBFBD> <20><><EFBFBD><EFBFBD> üũ<C3BC>ϱ<EFBFBD>
/// @param buf
/// @return
/// @date 2004-11-27 <20><><EFBFBD><EFBFBD> 11:04:24
////////////////////////////////////////////////////////////////////////////////////////////////////
2020-05-05 18:22:39 +00:00
BOOL CUnAlz::CryptCheck(const BYTE* buf)
2020-05-05 18:22:38 +00:00
{
int i;
BYTE c;
2020-05-05 18:22:39 +00:00
BYTE temp[ENCR_HEADER_LEN];
memcpy(temp, buf, ENCR_HEADER_LEN); // <20>ӽ<EFBFBD> <20><><EFBFBD><EFBFBD>.
2020-05-05 18:22:38 +00:00
for(i=0;i<ENCR_HEADER_LEN;i++)
{
2020-05-05 18:22:39 +00:00
c = temp[i] ^ DecryptByte();
2020-05-05 18:22:38 +00:00
UpdateKeys(c);
2020-05-05 18:22:39 +00:00
temp[i] = c;
2020-05-05 18:22:38 +00:00
}
if (IsDataDescr()) // Data descriptor present
return (m_posCur->head.fileTimeDate >> 8) == c;
else
2020-05-05 18:22:39 +00:00
return ( ((m_posCur->fileCRC)>>24) ) == c; // <20><><EFBFBD><EFBFBD> crc <20><> <20>ֻ<EFBFBD><D6BB><EFBFBD> byte
2020-05-05 18:22:38 +00:00
}
////////////////////////////////////////////////////////////////////////////////////////////////////
/// Ű<><C5B0><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>Ÿ <20><><EFBFBD><EFBFBD>
/// @return
/// @date 2004-11-27 <20><><EFBFBD><EFBFBD> 11:05:36
////////////////////////////////////////////////////////////////////////////////////////////////////
BYTE CUnAlz::DecryptByte()
{
UINT16 temp;
temp = m_key[2] | 2;
return (temp * (temp^1))>>8;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
/// <20><><EFBFBD><EFBFBD>Ÿ <20><><EFBFBD><EFBFBD> Ǯ<><C7AE>
/// @param nSize
/// @param data
/// @return
/// @date 2004-11-27 <20><><EFBFBD><EFBFBD> 11:03:30
////////////////////////////////////////////////////////////////////////////////////////////////////
void CUnAlz::DecryptingData(int nSize, BYTE* data)
{
BYTE* p = data;
BYTE temp;
while(nSize)
{
temp = *p ^ DecryptByte();
UpdateKeys(temp);
*p = temp;
nSize--;
p++;
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////
/// CRC <20><><EFBFBD>̺<EFBFBD> <20><><EFBFBD><EFBFBD>
/// @param l
/// @param c
/// @return
/// @date 2004-11-27 <20><><EFBFBD><EFBFBD> 11:14:16
////////////////////////////////////////////////////////////////////////////////////////////////////
UINT32 CUnAlz::CRC32(UINT32 l, BYTE c)
{
const ULONG *CRC_TABLE = get_crc_table();
return CRC_TABLE[(l ^ c) & 0xff] ^ (l >> 8);
}
2020-05-05 18:22:39 +00:00