forked from mirror/unalz
1277 lines
32 KiB
C++
1277 lines
32 KiB
C++
|
//#include "stdafx.h"
|
|||
|
#include "zlib/zlib.h"
|
|||
|
#include "bzip2/bzlib.h"
|
|||
|
#include "UnAlz.h"
|
|||
|
#ifdef _WIN32
|
|||
|
#include <direct.h> // mkdir
|
|||
|
#else
|
|||
|
#include <sys/stat.h>
|
|||
|
#endif
|
|||
|
|
|||
|
#ifndef MAX_PATH
|
|||
|
#define MAX_PATH 260
|
|||
|
#endif
|
|||
|
|
|||
|
#ifdef _WIN32
|
|||
|
#define PATHSEP "\\"
|
|||
|
#define PATHSEPC '\\'
|
|||
|
#else
|
|||
|
#define PATHSEP "/"
|
|||
|
#define PATHSEPC '/'
|
|||
|
#endif
|
|||
|
|
|||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|||
|
/// 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;
|
|||
|
}
|
|||
|
|
|||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|||
|
/// 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;
|
|||
|
}
|
|||
|
|
|||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|||
|
/// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
|||
|
/// @param szPathName
|
|||
|
/// @return
|
|||
|
/// @date 2004-03-06 <20><><EFBFBD><EFBFBD> 11:03:59
|
|||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|||
|
#ifdef _WIN32
|
|||
|
/*
|
|||
|
BOOL CUnAlz::Open(LPCWSTR szPathName)
|
|||
|
{
|
|||
|
USES_CONVERSION;
|
|||
|
return Open(W2A(szPathName));
|
|||
|
}
|
|||
|
*/
|
|||
|
#endif // _WIN32
|
|||
|
|
|||
|
BOOL CUnAlz::Open(const char* szPathName)
|
|||
|
{
|
|||
|
if(FOpen(szPathName)==FALSE)
|
|||
|
{
|
|||
|
m_nErr = ERR_CANT_OPEN_FILE;
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
// 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;
|
|||
|
}
|
|||
|
if(sig==SIG_ERR)
|
|||
|
{
|
|||
|
return FALSE; // <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>..
|
|||
|
}
|
|||
|
|
|||
|
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
|
|||
|
{
|
|||
|
// <20>̱<EFBFBD><CCB1><EFBFBD><EFBFBD><EFBFBD> signature
|
|||
|
ASSERT(0);
|
|||
|
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()
|
|||
|
{
|
|||
|
DWORD 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_ERR;
|
|||
|
}
|
|||
|
|
|||
|
return (SIGNATURE)dwSig;
|
|||
|
}
|
|||
|
|
|||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|||
|
/// 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>..
|
|||
|
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); // <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>.
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
// 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;
|
|||
|
|
|||
|
/*
|
|||
|
// 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);
|
|||
|
}
|
|||
|
*/
|
|||
|
|
|||
|
// 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;
|
|||
|
}
|
|||
|
|
|||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|||
|
/// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϱ<EFBFBD>.
|
|||
|
/// @param szFileName
|
|||
|
/// @return
|
|||
|
/// @date 2004-03-06 <20><><EFBFBD><EFBFBD> 11:06:20
|
|||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|||
|
#ifdef _WIN32
|
|||
|
/*
|
|||
|
BOOL CUnAlz::SetCurrentFile(LPCWSTR szFileName)
|
|||
|
{
|
|||
|
USES_CONVERSION;
|
|||
|
return SetCurrentFile(W2A(szFileName));
|
|||
|
}
|
|||
|
*/
|
|||
|
#endif // _WIN32
|
|||
|
|
|||
|
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;
|
|||
|
}
|
|||
|
|
|||
|
#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];
|
|||
|
|
|||
|
// <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);
|
|||
|
|
|||
|
// <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");
|
|||
|
}
|
|||
|
|
|||
|
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;
|
|||
|
}
|
|||
|
|
|||
|
// CALLBACK <20><><EFBFBD><EFBFBD>
|
|||
|
if(m_pFuncCallBack) m_pFuncCallBack(m_posCur->fileName, 0,0,m_pCallbackParam, NULL);
|
|||
|
|
|||
|
ret = ExtractTo(&dest);
|
|||
|
fclose(dest.fp);
|
|||
|
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
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
ASSERT(0); // <20><><EFBFBD>ο<EFBFBD> <20><><EFBFBD><EFBFBD> ???
|
|||
|
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;
|
|||
|
ExtractCurrentFile(szDestPathName);
|
|||
|
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
|
|||
|
//printf("mkdir:%s\n", path);
|
|||
|
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
|
|||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|||
|
BOOL CUnAlz::IsFolder(LPCSTR szPathName)
|
|||
|
{
|
|||
|
#ifdef _WIN32
|
|||
|
DWORD 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
|
|||
|
}
|
|||
|
#ifdef _WIN32
|
|||
|
/*
|
|||
|
BOOL CUnAlz::IsFolder(LPCWSTR szPathName)
|
|||
|
{
|
|||
|
DWORD dwRet;
|
|||
|
dwRet = GetFileAttributesW(szPathName);
|
|||
|
if(dwRet==0xffffffff) return FALSE;
|
|||
|
if(dwRet & FILE_ATTRIBUTE_DIRECTORY) return TRUE;
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
*/
|
|||
|
#endif // _WIN32
|
|||
|
|
|||
|
|
|||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|||
|
/// <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)
|
|||
|
{
|
|||
|
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;
|
|||
|
DWORD 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 <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)
|
|||
|
{
|
|||
|
BOOL ret = FALSE;
|
|||
|
BYTE buf[BUF_LEN];
|
|||
|
INT64 read;
|
|||
|
INT64 sizeToRead;
|
|||
|
INT64 bufLen = BUF_LEN;
|
|||
|
INT64 nWritten = 0;
|
|||
|
BOOL bHalt = FALSE;
|
|||
|
|
|||
|
// <20><>ġ <20><><EFBFBD><EFBFBD>.
|
|||
|
FSeek(file.dwFileDataPos);
|
|||
|
|
|||
|
sizeToRead = file.compressedSize; // <20><><EFBFBD><EFBFBD> ũ<><C5A9>.
|
|||
|
|
|||
|
while(sizeToRead)
|
|||
|
{
|
|||
|
read = min(sizeToRead, bufLen);
|
|||
|
if(FRead(buf, (int)read)==FALSE)
|
|||
|
{
|
|||
|
break;
|
|||
|
}
|
|||
|
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 <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)
|
|||
|
{
|
|||
|
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* <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;
|
|||
|
*/
|
|||
|
|
|||
|
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 <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;
|
|||
|
DWORD 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;
|
|||
|
|
|||
|
// <20><><EFBFBD><EFBFBD> <20>κ<EFBFBD>.
|
|||
|
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; // <20><><EFBFBD><EFBFBD> ũ<><C5A9>.
|
|||
|
|
|||
|
if (uReadThis == 0)
|
|||
|
break; // <20><><EFBFBD><EFBFBD>
|
|||
|
|
|||
|
if(FRead(pInBuf, uReadThis)==FALSE)
|
|||
|
{
|
|||
|
m_nErr = ERR_CANT_READ_FILE;
|
|||
|
goto END;
|
|||
|
}
|
|||
|
|
|||
|
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)
|
|||
|
{
|
|||
|
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;
|
|||
|
}
|
|||
|
|
|||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|||
|
/// <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);
|
|||
|
DWORD dwFileSizeLow,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 <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;
|
|||
|
dwFileSizeLow = GetFileSize(m_files[i].fp, &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);
|
|||
|
dwFileSizeLow=ftell(m_files[i].fp);
|
|||
|
fseek(m_files[i].fp,0,SEEK_SET);
|
|||
|
#endif
|
|||
|
m_nFileCount++;
|
|||
|
m_files[i].nFileSize = ((INT64)dwFileSizeLow) + (((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; // <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
|
|||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|||
|
BOOL CUnAlz::FRead(void* buffer, DWORD nBytesToRead, int* pTotRead )
|
|||
|
{
|
|||
|
BOOL ret;
|
|||
|
DWORD nNumOfBytesRead;
|
|||
|
INT64 dwRemain;
|
|||
|
DWORD dwRead;
|
|||
|
DWORD dwTotRead;
|
|||
|
|
|||
|
dwRemain = nBytesToRead;
|
|||
|
dwTotRead = 0;
|
|||
|
if(pTotRead) *pTotRead=0;
|
|||
|
|
|||
|
while(dwRemain)
|
|||
|
{
|
|||
|
dwRead = (DWORD)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, &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) // <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;
|
|||
|
}
|
|||
|
|