forked from mirror/unalz
1571 lines
41 KiB
C++
1571 lines
41 KiB
C++
//#include "stdafx.h"
|
||
#include "zlib/zlib.h"
|
||
#include "bzip2/bzlib.h"
|
||
#include "UnAlz.h"
|
||
|
||
// mkdir
|
||
#ifdef _WIN32
|
||
# include <direct.h>
|
||
#else
|
||
# include <sys/stat.h>
|
||
#endif
|
||
|
||
#ifdef _UNALZ_ICONV // code page support
|
||
# include <iconv.h>
|
||
#endif
|
||
|
||
#ifdef __linux__ // __BYTE_ORDER °¡Á®¿À±â
|
||
# include <errno.h> // iconv.h ¶§¹®¿¡ ÇÊ¿ä
|
||
#endif
|
||
|
||
|
||
#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))
|
||
|
||
////////////////////////////////////////////////////////////////////////////
|
||
//// byte-order : little to host ////
|
||
////////////////////////////////////////////////////////////////////////////
|
||
|
||
#ifdef _WIN32 // little to little
|
||
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
|
||
|
||
#ifdef __FreeBSD__
|
||
# include <sys/endian.h>
|
||
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
|
||
|
||
#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>
|
||
# 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
|
||
//# 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);}
|
||
#endif
|
||
|
||
|
||
|
||
#ifndef MAX_PATH
|
||
# define MAX_PATH 260
|
||
#endif
|
||
|
||
#ifdef _WIN32
|
||
# define PATHSEP "\\"
|
||
# define PATHSEPC '\\'
|
||
#else
|
||
# define PATHSEP "/"
|
||
# define PATHSEPC '/'
|
||
#endif
|
||
|
||
|
||
|
||
// error string table <- CUnAlz::ERR ÀÇ ¹ø¿ª
|
||
static const char* errorstrtable[]=
|
||
{
|
||
"no error", // ERR_NOERR
|
||
"can't open file", // ERR_CANT_OPEN_FILE
|
||
"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,
|
||
"file read eror", // ERR_FILE_READ_ERROR,
|
||
"inflate failed", // ERR_INFLATE_FAILED,
|
||
|
||
"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,
|
||
|
||
"password not set", //ERR_PASSWD_NOT_SET,
|
||
"invalid password", //ERR_INVALID_PASSWD,
|
||
"User Aborted",
|
||
};
|
||
|
||
|
||
|
||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
/// ctor
|
||
/// @date 2004-03-06 ¿ÀÈÄ 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;
|
||
m_bIsEncrypted = FALSE;
|
||
m_bIsDataDescr = FALSE;
|
||
|
||
#ifdef _UNALZ_ICONV
|
||
|
||
#ifdef _UNALZ_UTF8
|
||
strcpy(m_szToCodepage, "UTF-8") ; // ±âº»ÀûÀ¸·Î utf-8
|
||
#else
|
||
strcpy(m_szToCodepage, "CP949") ; // ±âº»ÀûÀ¸·Î CP949
|
||
#endif // _UNALZ_UTF8
|
||
|
||
strcpy(m_szFromCodepage, "CP949"); // alz ´Â 949 ¸¸ Áö¿ø
|
||
#endif // _UNALZ_ICONV
|
||
}
|
||
|
||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
/// dtor
|
||
/// @date 2004-03-06 ¿ÀÈÄ 11:19:52
|
||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
CUnAlz::~CUnAlz()
|
||
{
|
||
Close();
|
||
}
|
||
|
||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
/// progress callback func setting
|
||
/// @date 2004-03-01 ¿ÀÀü 6:02:05
|
||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
void CUnAlz::SetCallback(_UnAlzCallback* pFunc, void* param)
|
||
{
|
||
m_pFuncCallBack = pFunc;
|
||
m_pCallbackParam = param;
|
||
}
|
||
|
||
#ifdef _WIN32
|
||
#if !defined(__GNUWIN32__) && !defined(__GNUC__)
|
||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
/// ÆÄÀÏ ¿±â
|
||
/// @param szPathName
|
||
/// @return
|
||
/// @date 2004-03-06 ¿ÀÈÄ 11:03:59
|
||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
#include <atlbase.h>
|
||
#include <atlconv.h>
|
||
BOOL CUnAlz::Open(LPCWSTR szPathName)
|
||
{
|
||
USES_CONVERSION;
|
||
return Open(W2A(szPathName));
|
||
}
|
||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
/// ´ë»ó ÆÄÀÏ ¼¼ÆÃÇϱâ.
|
||
/// @param szFileName
|
||
/// @return
|
||
/// @date 2004-03-06 ¿ÀÈÄ 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__
|
||
#endif // _WIN32
|
||
|
||
BOOL CUnAlz::Open(const char* szPathName)
|
||
{
|
||
if(FOpen(szPathName)==FALSE)
|
||
{
|
||
m_nErr = ERR_CANT_OPEN_FILE;
|
||
return FALSE;
|
||
}
|
||
|
||
// file ºÐ¼®½ÃÀÛ..
|
||
for(;;)
|
||
{
|
||
SIGNATURE sig;
|
||
BOOL ret;
|
||
|
||
if(FEof()) break;
|
||
//int pos = ftell(m_fp);
|
||
sig = ReadSignature();
|
||
if(sig==SIG_EOF)
|
||
{
|
||
break;
|
||
}
|
||
if(sig==SIG_ERROR)
|
||
{
|
||
return FALSE; // ±úÁø ÆÄÀÏ..
|
||
}
|
||
|
||
if(sig==SIG_ALZ_FILE_HEADER) ret = ReadAlzFileHeader();
|
||
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
|
||
{
|
||
// ¹Ì±¸ÇöµÈ signature
|
||
ASSERT(0);
|
||
return FALSE;
|
||
}
|
||
|
||
if(ret==FALSE)
|
||
{
|
||
return FALSE;
|
||
}
|
||
|
||
if(FEof()) break;
|
||
}
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
/// ÆÄÀÏ ´Ý±â..
|
||
/// @return
|
||
/// @date 2004-03-06 ¿ÀÈÄ 11:04:21
|
||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
void CUnAlz::Close()
|
||
{
|
||
FClose();
|
||
|
||
// ¸ñ·Ï ³¯¸®±â..
|
||
FileList::iterator i;
|
||
|
||
for(i=m_fileList.begin(); i<m_fileList.end(); i++)
|
||
{
|
||
i->Clear();
|
||
}
|
||
|
||
m_posCur = (FileList::iterator)NULL;
|
||
}
|
||
|
||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
/// FILE ³»ÀÇ SIGNATURE Àбâ
|
||
/// @return
|
||
/// @date 2004-03-06 ¿ÀÈÄ 11:04:47
|
||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
CUnAlz::SIGNATURE CUnAlz::ReadSignature()
|
||
{
|
||
UINT32 dwSig;
|
||
if(FRead(&dwSig, sizeof(dwSig))==FALSE)
|
||
{
|
||
//int pos = ftell(m_fp);
|
||
if(FEof())
|
||
return SIG_EOF;
|
||
m_nErr = ERR_CANT_READ_SIG;
|
||
return SIG_ERROR;
|
||
}
|
||
|
||
return (SIGNATURE)unalz_le32toh(dwSig); // little to host;
|
||
}
|
||
|
||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
/// ALZ HEADER SIGNATURE Àбâ
|
||
/// @return
|
||
/// @date 2004-03-06 ¿ÀÈÄ 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;
|
||
}
|
||
|
||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
/// °¢°¢ÀÇ ÆÄÀÏ Çì´õ Àбâ
|
||
/// @return
|
||
/// @date 2004-03-06 ¿ÀÈÄ 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 È®Àå..
|
||
if( (zipHeader.head.fileSizeByte & (SHORT)1) != 0){
|
||
m_bIsEncrypted = TRUE;
|
||
}
|
||
if( (zipHeader.head.fileSizeByte & (SHORT)8) != 0){
|
||
m_bIsDataDescr = TRUE;
|
||
}
|
||
|
||
int byteLen = zipHeader.head.fileSizeByte/0x10;
|
||
|
||
if(byteLen)
|
||
{
|
||
FRead(&(zipHeader.compressionMethod), sizeof(zipHeader.compressionMethod));
|
||
FRead(&(zipHeader.unknown3), sizeof(zipHeader.unknown3));
|
||
FRead(&(zipHeader.maybeCRC), sizeof(zipHeader.maybeCRC));
|
||
|
||
FRead(&(zipHeader.compressedSize), byteLen);
|
||
FRead(&(zipHeader.uncompressedSize), byteLen); // ¾ÐÃà »çÀÌÁî°¡ ¾ø´Ù.
|
||
}
|
||
|
||
// little to system
|
||
zipHeader.head.fileNameLength = unalz_le16toh(zipHeader.head.fileNameLength);
|
||
zipHeader.compressedSize = unalz_le64toh(zipHeader.compressedSize);
|
||
zipHeader.uncompressedSize = unalz_le64toh(zipHeader.uncompressedSize);
|
||
zipHeader.maybeCRC = unalz_le32toh(zipHeader.maybeCRC);
|
||
|
||
// FILE NAME
|
||
zipHeader.fileName = (char*)malloc(zipHeader.head.fileNameLength+1);
|
||
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;
|
||
|
||
|
||
#ifdef _UNALZ_ICONV // codepage convert
|
||
|
||
if(strlen(m_szToCodepage))
|
||
{
|
||
|
||
#define ICONV_BUF_SIZE (260*6) // utf8 Àº ÃÖ´ë 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];
|
||
#ifdef __FreeBSD__
|
||
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); // º¸Åë "CP949" ¿¡¼ "UTF-8" ·Î
|
||
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 ½ÇÆÐ..
|
||
{
|
||
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;
|
||
strcpy(zipHeader.fileName, outbuf);
|
||
// printf("\n Converted File Name : %s", outbuf);
|
||
}
|
||
|
||
iconv_close(cd);
|
||
}
|
||
|
||
}
|
||
#endif
|
||
|
||
/*
|
||
// 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);
|
||
}
|
||
*/
|
||
|
||
if(IsEncrypted()) FRead(zipHeader.encChk, ENCR_HEADER_LEN); // xf86
|
||
|
||
// SKIP FILE DATA
|
||
zipHeader.dwFileDataPos = FTell(); // data ÀÇ À§Ä¡ ÀúÀåÇϱâ..
|
||
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
|
||
|
||
// ÆÄÀÏÀ» ¸ñ·Ï¿¡ Ãß°¡ÇÑ´Ù..
|
||
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;
|
||
|
||
// ¼øÂ÷ÀûÀ¸·Î ã´Â´Ù.
|
||
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;
|
||
}
|
||
|
||
#ifndef MAX_WBITS
|
||
# define MAX_WBITS 15 /* 32K LZ77 window */
|
||
#endif
|
||
|
||
|
||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
/// ¹öÆÛ¿¡ ¾ÐÃà Ç®±â. ¹öÆÛ´Â ´ç±Ù ÃæºÐÇÑ Å©±â°¡ ÁغñµÇ¾î ÀÖ¾î¾ß ÇÑ´Ù.
|
||
/// @param pDestBuf
|
||
/// @return
|
||
/// @date 2004-03-07 ¿ÀÀü 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);
|
||
}
|
||
|
||
|
||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
/// ÇöÀç ÆÄÀÏ (SetCurrentFile·Î Áö)À» ´ë»ó °æ·Î¿¡ ´ë»ó ÆÄÀϷΠǬ´Ù.
|
||
/// @param szDestPathName - ´ë»ó °æ·Î
|
||
/// @param szDestFileName - ´ë»ó ÆÄÀϸí, NULL ÀÌ¸é ¿ø·¡ ÆÄÀÏ¸í »ç¿ë
|
||
/// @return
|
||
/// @date 2004-03-06 ¿ÀÈÄ 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];
|
||
|
||
if(chkValidPassword() == FALSE)
|
||
{
|
||
return FALSE;
|
||
}
|
||
|
||
// °æ·Î¸í
|
||
strcpy(szDestPathFileName, szDestPathName);
|
||
if(szDestPathFileName[strlen(szDestPathFileName)]!=PATHSEPC)
|
||
strcat(szDestPathFileName, PATHSEP);
|
||
|
||
// ÆÄÀϸí
|
||
if(szDestFileName) strcat(szDestPathFileName, szDestFileName);
|
||
else strcat(szDestPathFileName, m_posCur->fileName);
|
||
|
||
#ifndef _WIN32
|
||
{
|
||
char* p = szDestPathFileName; // °æ·Î delimiter ¹Ù²Ù±â
|
||
while(*p)
|
||
{
|
||
if(*p=='\\') *p='/';
|
||
p++;
|
||
}
|
||
}
|
||
#endif
|
||
|
||
// ¾ÐÃàÇ® ´ë»ó ( ÆÄÀÏ )
|
||
dest.nType = ET_FILE;
|
||
dest.fp = fopen(szDestPathFileName, "wb");
|
||
|
||
if(dest.fp==NULL)
|
||
{
|
||
DigPath(szDestPathFileName); // °æ·Î¸í¿¡ / °¡ ÀÖÀ» °æ¿ì..
|
||
dest.fp = fopen(szDestPathFileName, "wb");
|
||
}
|
||
|
||
#ifdef _WIN32
|
||
if(dest.fp==NULL)
|
||
{
|
||
ASSERT(0);
|
||
if(m_pFuncCallBack)
|
||
{
|
||
CHAR buf[1024];
|
||
sprintf(buf, "ÆÄÀÏ ¿±â ½ÇÆÐ : %s", szDestPathFileName);
|
||
m_pFuncCallBack(buf, 0,0,m_pCallbackParam, NULL);
|
||
}
|
||
return FALSE;
|
||
}
|
||
#endif
|
||
// CALLBACK ¼¼ÆÃ
|
||
if(m_pFuncCallBack) m_pFuncCallBack(m_posCur->fileName, 0,m_posCur->uncompressedSize,m_pCallbackParam, NULL);
|
||
|
||
ret = ExtractTo(&dest);
|
||
if(dest.fp!=NULL)fclose(dest.fp);
|
||
return ret;
|
||
}
|
||
|
||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
/// ´ë»ó¿¡ ¾ÐÃà Ç®±â..
|
||
/// @param dest
|
||
/// @return
|
||
/// @date 2004-03-07 ¿ÀÀü 12:44:36
|
||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
BOOL CUnAlz::ExtractTo(SExtractDest* dest)
|
||
{
|
||
BOOL ret = FALSE;
|
||
// ¾ÐÃà ¹æ¹ý¿¡ µû¶ó¼ ¾ÐÃà Ç®±â
|
||
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
|
||
}
|
||
else
|
||
{
|
||
ASSERT(0); // »õ·Î¿î ¹æ¹ý ???
|
||
ret = FALSE;
|
||
}
|
||
return ret;
|
||
}
|
||
|
||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
/// DEFLATE ·Î Ç®±â - Å×½ºÆ®¿ë ÇÔ¼ö. ¸ðµç ÆÄÀÏÀ» ÇѲ¨¹ø¿¡ ÀÐ¾î¼ Ç¬´Ù. ½ÇÁ¦ »ç¿ë ¾ÈÇÔ.
|
||
/// @param fp - ´ë»ó ÆÄÀÏ
|
||
/// @param file - ¼Ò½º ÆÄÀÏ Á¤º¸
|
||
/// @return
|
||
/// @date 2004-03-06 ¿ÀÈÄ 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;
|
||
}
|
||
|
||
// Çѹø¿¡ Àоî¼
|
||
fseek(m_fp, file.dwFileDataPos, SEEK_SET);
|
||
if(FRead(pInBuf, nInBufSize, 1, m_fp)!=1)
|
||
{
|
||
m_nErr = ERR_FILE_READ_ERROR;
|
||
goto END;
|
||
}
|
||
|
||
// ÃʱâÈ..
|
||
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;
|
||
}
|
||
*/
|
||
|
||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
/// ´ë»ó Æú´õ¿¡ ÇöÀç ¾ÐÃàÆÄÀÏÀ» ÀüºÎ Ç®±â
|
||
/// @param szDestPathName - ´ë»ó °æ·Î
|
||
/// @return
|
||
/// @date 2004-03-06 ¿ÀÈÄ 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;
|
||
if(ExtractCurrentFile(szDestPathName)==FALSE) return FALSE;
|
||
if(m_bHalt)
|
||
break; // ¸ØÃß±â..
|
||
}
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
/// ´ë»ó °æ·Î Æıâ - ¾ÐÃà ÆÄÀÏ ³»¿¡ Æú´õ Á¤º¸°¡ ÀÖÀ» °æ¿ì, ´ÙÁß Æú´õ¸¦ ÆÇ´Ù(dig)
|
||
/// @param szPathName
|
||
/// @return
|
||
/// @date 2004-03-06 ¿ÀÈÄ 11:10:12
|
||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
BOOL CUnAlz::DigPath(const char* szPathName)
|
||
{
|
||
char* dup = strdup(szPathName);
|
||
char seps[] = "/\\";
|
||
char *token;
|
||
char path[MAX_PATH] = {0};
|
||
char* last;
|
||
|
||
// °æ·Î¸¸ »Ì±â.
|
||
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;
|
||
}
|
||
|
||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
/// Á¦´ë·ÎµÈ Æú´õ Àΰ¡?
|
||
/// @param szPathName
|
||
/// @return
|
||
/// @date 2004-03-06 ¿ÀÈÄ 11:03:26
|
||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
BOOL CUnAlz::IsFolder(LPCSTR szPathName)
|
||
{
|
||
#ifdef _WIN32
|
||
UINT32 dwRet;
|
||
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
|
||
}
|
||
|
||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
/// ¾ÐÃàÀ» Ç® ´ë»ó¿¡ ¾ÐÃàÀ» Ǭ´Ù.
|
||
/// @param dest - ´ë»ó OBJECT
|
||
/// @param buf - Ç®¸° µ¥ÀÌŸ
|
||
/// @param nSize - µ¥ÀÌŸÀÇ Å©±â
|
||
/// @return ¾´ ¹ÙÀÌÆ®¼ö. ¿¡·¯½Ã -1 ¸®ÅÏ
|
||
/// @date 2004-03-07 ¿ÀÀü 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)
|
||
{
|
||
if(dest->bufpos+nSize >dest->bufsize) // ¿¡·¯.. ¹öÆÛ°¡ ³ÑÃÆ´Ù.
|
||
{
|
||
ASSERT(0);
|
||
return -1;
|
||
}
|
||
// memcpy
|
||
memcpy(dest->buf + dest->bufpos, buf, nSize);
|
||
dest->bufpos += nSize;
|
||
return nSize;
|
||
}
|
||
else
|
||
{
|
||
ASSERT(0);
|
||
}
|
||
return -1;
|
||
}
|
||
|
||
/* ½ÇÆÐÇÑ ¹æ¹ý.. °í»ýÇÑ°Ô ¾Æ±î¿ö¼ ¸øÁö¿ò.
|
||
#define ALZDLZ_HEADER_SIZE 4 // alz ÆÄÀÏÀÇ bzip2 Çì´õ Å©±â
|
||
#define BZIP2_HEADER_SIZE 10 // bzip ÆÄÀÏÀÇ Çì´õ Å©±â
|
||
#define BZIP2_CRC_SIZE 4 // bzip2 ÀÇ crc
|
||
#define BZIP2_TAIL_SIZE 10 // ´ëÃæ 4+5 Á¤µµ.?
|
||
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;
|
||
UINT32 crc = 0xffffffff;
|
||
|
||
//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 ÀÇ BZIP Çì´õ ("DLZ.") ½ºÅµÇϱâ.
|
||
fseek(m_fp, ALZDLZ_HEADER_SIZE, SEEK_CUR);
|
||
// BZIP2 Çì´õ »ðÀÔ
|
||
memcpy(pInBuf, bzip2Header, BZIP2_HEADER_SIZE);
|
||
// BZIP2 CRC
|
||
memcpy(pInBuf+BZIP2_HEADER_SIZE, &(crc), BZIP2_CRC_SIZE);
|
||
|
||
// ÁøÂ¥ ¾ÐÃàµÈ µ¥ÀÌŸ¸¦ Çѹø¿¡ Àоî¼
|
||
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;
|
||
}
|
||
|
||
|
||
// ÃʱâÈ..
|
||
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 °¡ ¸®Å쵃 ¼ö ÀÖ´Ù..
|
||
//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 ·Î ¾ÐÃàµÈ ÆÄÀÏ Ç®±â
|
||
/// @param fp - ´ë»ó ÆÄÀÏ
|
||
/// @param file - ¼Ò½º ÆÄÀÏ
|
||
/// @return
|
||
/// @date 2004-03-06 ¿ÀÈÄ 11:10:53
|
||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
#define BUF_LEN (4096*2)
|
||
BOOL CUnAlz::ExtractRawfile(SExtractDest* dest, SLocalFileHeader& file)
|
||
{
|
||
BOOL ret = FALSE;
|
||
BYTE buf[BUF_LEN];
|
||
INT64 read;
|
||
INT64 sizeToRead;
|
||
INT64 bufLen = BUF_LEN;
|
||
INT64 nWritten = 0;
|
||
BOOL bHalt = FALSE;
|
||
|
||
// À§Ä¡ Àâ°í.
|
||
FSeek(file.dwFileDataPos);
|
||
|
||
sizeToRead = file.compressedSize; // ÀÐÀ» Å©±â.
|
||
|
||
while(sizeToRead)
|
||
{
|
||
read = min(sizeToRead, bufLen);
|
||
if(FRead(buf, (int)read)==FALSE)
|
||
{
|
||
break;
|
||
}
|
||
|
||
CryptDecodeBuffer((int)read, (CHAR *)buf); // xf86
|
||
|
||
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;
|
||
ret = TRUE;
|
||
return ret;
|
||
}
|
||
|
||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
/// BZIP2 ¾ÐÃà Ç®±â..
|
||
/// @param fp_w - ´ë»ó ÆÄÀÏ
|
||
/// @param file - ¼Ò½º ÆÄÀÏ Á¤º¸
|
||
/// @return
|
||
/// @date 2004-03-01 ¿ÀÀü 5:47:36
|
||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
#define BZIP2_EXTRACT_BUF_SIZE 0x2000
|
||
BOOL CUnAlz::ExtractBzip2(SExtractDest* dest, SLocalFileHeader& file)
|
||
{
|
||
BZFILE *bzfp = NULL;
|
||
int smallMode = 0;
|
||
int verbosity = 1;
|
||
int bzerr;
|
||
INT64 len;
|
||
char buff[BZIP2_EXTRACT_BUF_SIZE];
|
||
INT64 nWritten = 0;
|
||
BOOL bHalt = FALSE;
|
||
|
||
FSeek(file.dwFileDataPos);
|
||
|
||
bzfp = BZ2_bzReadOpen(&bzerr,this,verbosity,smallMode,0,0);
|
||
|
||
if(bzfp==NULL){ASSERT(0); return FALSE;}
|
||
|
||
while((len=BZ2_bzread(bzfp,buff,BZIP2_EXTRACT_BUF_SIZE))>0)
|
||
{
|
||
WriteToDest(dest, (BYTE*)buff, (int)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;
|
||
|
||
/*
|
||
// FILE* ¸¦ »ç¿ëÇÒ°æ¿ì »ç¿ëÇÏ´ø ÄÚµå. - ¸ÖƼ º¼·ý Áö¿ø ¾ÈÇÔ..
|
||
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;
|
||
*/
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
|
||
#ifndef UNZ_BUFSIZE
|
||
#define UNZ_BUFSIZE 0x1000 // (16384)
|
||
#endif
|
||
|
||
#define IN_BUF_SIZE UNZ_BUFSIZE
|
||
#define OUT_BUF_SIZE 0x1000 //IN_BUF_SIZE
|
||
|
||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
/// deflate ·Î ¾ÐÃà Ç®±â. ExtractDeflate() ¿Í ´Þ¸® Á¶±Ý¾¿ ÀÐ¾î¼ Ç¬´Ù.
|
||
/// @param fp
|
||
/// @param file
|
||
/// @return
|
||
/// @date 2004-03-06 ¿ÀÈÄ 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;
|
||
UINT32 dwCRC32= 0;
|
||
INT64 rest_read_uncompressed;
|
||
UINT iRead = 0;
|
||
INT64 nWritten = 0;
|
||
BOOL bHalt = FALSE;
|
||
|
||
memset(&stream, 0, sizeof(stream));
|
||
|
||
FSeek(file.dwFileDataPos);
|
||
|
||
inflateInit2(&stream, -MAX_WBITS);
|
||
nRestReadCompressed = file.compressedSize;
|
||
rest_read_uncompressed = file.uncompressedSize;
|
||
|
||
// Ãâ·Â ºÎºÐ.
|
||
stream.next_out = pOutBuf;
|
||
stream.avail_out = OUT_BUF_SIZE;
|
||
|
||
while(stream.avail_out>0)
|
||
{
|
||
if(stream.avail_in==0 && nRestReadCompressed>0)
|
||
{
|
||
UINT uReadThis = UNZ_BUFSIZE;
|
||
if (nRestReadCompressed<(int)uReadThis)
|
||
uReadThis = (UINT)nRestReadCompressed; // ÀÐÀ» Å©±â.
|
||
|
||
if (uReadThis == 0)
|
||
break; // ÁßÁö
|
||
|
||
if(FRead(pInBuf, uReadThis)==FALSE)
|
||
{
|
||
m_nErr = ERR_CANT_READ_FILE;
|
||
goto END;
|
||
}
|
||
|
||
CryptDecodeBuffer(uReadThis, (CHAR *)pInBuf); // xf86
|
||
|
||
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 ¿¡ ¾²±â.
|
||
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)
|
||
{
|
||
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;
|
||
|
||
ret = TRUE;
|
||
|
||
END :
|
||
inflateEnd(&stream);
|
||
|
||
return ret;
|
||
}
|
||
|
||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
/// ÆÄÀÏ ¿±â
|
||
/// @param szPathName
|
||
/// @return
|
||
/// @date 2004-10-02 ¿ÀÈÄ 11:47:14
|
||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
BOOL CUnAlz::FOpen(const char* szPathName)
|
||
{
|
||
char* temp = strdup(szPathName); // ÆÄÀÏ¸í º¹»ç..
|
||
int i;
|
||
int nLen = strlen(szPathName);
|
||
UINT64 nFileSizeLow;
|
||
UINT32 dwFileSizeHigh;
|
||
m_nFileCount = 0;
|
||
m_nCurFile = 0;
|
||
m_nVirtualFilePos = 0;
|
||
m_nCurFilePos = 0;
|
||
m_bIsEOF = FALSE;
|
||
for(i=0;i<MAX_FILES;i++) // aa.alz ÆÄÀϸíÀ» °¡Áö°í aa.a00 aa.a01 aa.a02 .. ¸¸µé±â
|
||
{
|
||
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;
|
||
nFileSizeLow = GetFileSize(m_files[i].fp, (DWORD*)&dwFileSizeHigh);
|
||
#else
|
||
m_files[i].fp = fopen(temp, "rb");
|
||
if(m_files[i].fp==NULL) break;
|
||
dwFileSizeHigh=0;
|
||
fseek(m_files[i].fp,0,SEEK_END);
|
||
nFileSizeLow=ftell(m_files[i].fp);
|
||
fseek(m_files[i].fp,0,SEEK_SET);
|
||
#endif
|
||
m_nFileCount++;
|
||
m_files[i].nFileSize = ((INT64)nFileSizeLow) + (((INT64)dwFileSizeHigh)<<32);
|
||
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; // ¸¶Áö¸· ÆÄÀÏÀº ²Ã¶ûÁö°¡ ¾ø´Ù..
|
||
return TRUE;
|
||
}
|
||
|
||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
/// ÆÄÀÏ ´Ý±â
|
||
/// @return
|
||
/// @date 2004-10-02 ¿ÀÈÄ 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;
|
||
}
|
||
|
||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
/// ÆÄÀÏÀÇ ³¡Àΰ¡?
|
||
/// @return
|
||
/// @date 2004-10-02 ¿ÀÈÄ 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;
|
||
*/
|
||
}
|
||
|
||
|
||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
/// ÇöÀç ÆÄÀÏ À§Ä¡
|
||
/// @return
|
||
/// @date 2004-10-02 ¿ÀÈÄ 11:50:50
|
||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
INT64 CUnAlz::FTell()
|
||
{
|
||
return m_nVirtualFilePos; // return ftell(m_fp);
|
||
}
|
||
|
||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
/// ÆÄÀÏ À§Ä¡ ¼¼ÆÃ
|
||
/// @param offset
|
||
/// @param origin
|
||
/// @return
|
||
/// @date 2004-10-02 ¿ÀÈÄ 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++) // ¾Õ¿¡¼ ·çÇÁ¸¦ µ¹¸é¼ À§Ä¡ ¼±Á¤Çϱâ..
|
||
{
|
||
if(remain<=m_files[i].nFileSize-m_files[i].nMultivolHeaderSize-m_files[i].nMultivolTailSize)
|
||
{
|
||
m_nCurFile = i;
|
||
m_nCurFilePos = remain+m_files[i].nMultivolHeaderSize; // ¹°¸®Àû À§Ä¡.
|
||
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);
|
||
}
|
||
|
||
// ½ÇÆÐ..?
|
||
ASSERT(0);
|
||
return FALSE;
|
||
}
|
||
|
||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
/// ÆÄÀÏ Àбâ
|
||
/// @param buffer
|
||
/// @param size
|
||
/// @param count
|
||
/// @return
|
||
/// @date 2004-10-02 ¿ÀÈÄ 11:44:05
|
||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
BOOL CUnAlz::FRead(void* buffer, UINT32 nBytesToRead, int* pTotRead )
|
||
{
|
||
BOOL ret;
|
||
UINT32 nNumOfBytesRead;
|
||
INT64 dwRemain;
|
||
UINT32 dwRead;
|
||
UINT32 dwTotRead;
|
||
|
||
dwRemain = nBytesToRead;
|
||
dwTotRead = 0;
|
||
if(pTotRead) *pTotRead=0;
|
||
|
||
while(dwRemain)
|
||
{
|
||
dwRead = (UINT32)min(dwRemain, (m_files[m_nCurFile].nFileSize-m_nCurFilePos-m_files[m_nCurFile].nMultivolTailSize));
|
||
if(dwRead==0) {
|
||
m_bIsEOF = TRUE;return FALSE;
|
||
}
|
||
#ifdef _WIN32
|
||
ret = ReadFile(m_files[m_nCurFile].fp, ((BYTE*)buffer)+dwTotRead, dwRead, (DWORD*)&nNumOfBytesRead, NULL);
|
||
if(ret==FALSE && GetLastError()==ERROR_HANDLE_EOF)
|
||
{
|
||
m_bIsEOF = TRUE;return FALSE;
|
||
}
|
||
#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) // ¹ß»ýÇÏ¸é ¾ÈµÈ´Ù..
|
||
{
|
||
ASSERT(0); return FALSE;
|
||
}
|
||
|
||
m_nVirtualFilePos += nNumOfBytesRead; // virtual ÆÄÀÏ À§Ä¡..
|
||
|
||
m_nCurFilePos+=nNumOfBytesRead; // ¹°¸®Àû ÆÄÀÏ À§Ä¡.
|
||
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; // ¿ÏÀüÈ÷ ³¡±îÁö Àоú´Ù..
|
||
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;
|
||
}
|
||
|
||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
/// error code ¸¦ ½ºÆ®¸µÀ¸·Î ¹Ù²ã ÁØ´Ù.
|
||
/// @param nERR
|
||
/// @return
|
||
/// @date 2004-10-24 ¿ÀÈÄ 3:28:39
|
||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
const char* CUnAlz::LastErrToStr(ERR nERR)
|
||
{
|
||
if(nERR>= sizeof(errorstrtable)/sizeof(errorstrtable[0])) {ASSERT(0); return NULL; }
|
||
return errorstrtable[nERR];
|
||
}
|
||
|
||
|
||
// by xf86
|
||
BOOL CUnAlz::chkValidPassword()
|
||
{
|
||
if (IsEncrypted()) {
|
||
if (getPasswordLen() == 0){
|
||
m_nErr = ERR_PASSWD_NOT_SET;
|
||
return FALSE;
|
||
}
|
||
CryptInitKeys();
|
||
if(CryptCheck(m_posCur->encChk) == FALSE){
|
||
m_nErr = ERR_INVALID_PASSWD;
|
||
return FALSE;
|
||
}
|
||
}
|
||
return TRUE;
|
||
}
|
||
|
||
|
||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
// 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);
|
||
}
|
||
|