#include "bzlib.h" #include "UnAlz.h" #ifdef _WIN32 # include "zlib/zlib.h" #else # include #endif #ifdef _WIN32 # pragma warning( disable : 4996 ) // crt secure warning #endif // utime ÇÔ¼ö ó¸® #if defined(_WIN32) || defined(__CYGWIN__) # include # include #endif #ifdef __GNUC__ # include # include #endif // mkdir #ifdef _WIN32 # include #else # include #endif #ifdef _UNALZ_ICONV // code page support # include #endif #if defined(__linux__) || defined(__GLIBC__) || defined(__GNU__) || defined(__APPLE__) # include #endif #if defined(__NetBSD__) # include // __NetBSD_Version__ # include // iconv.h ¶§¹®¿¡ ÇÊ¿ä #endif #ifdef _WIN32 // safe string ó¸® # include #endif // ENDIAN ó¸® #ifdef _WIN32 // (L) # define swapint64(a) (UINT64) ( (((a)&0x00000000000000FFL) << 56) | (((a)&0x000000000000FF00L) << 40) | (((a)&0x0000000000FF0000L) << 24) | (((a)&0x00000000FF000000L) << 8) | (((a)&0x000000FF00000000L) >> 8) | (((a)&0x0000FF0000000000L) >> 24) | (((a)&0x00FF000000000000L) >> 40) | (((a)&0xFF00000000000000L) >> 56) ) #else // (LL) # define swapint64(a) (UINT64) ( (((a)&0x00000000000000FFLL) << 56) | (((a)&0x000000000000FF00LL) << 40) | (((a)&0x0000000000FF0000LL) << 24) | (((a)&0x00000000FF000000LL) << 8) | (((a)&0x000000FF00000000LL) >> 8) | (((a)&0x0000FF0000000000LL) >> 24) | (((a)&0x00FF000000000000LL) >> 40) | (((a)&0xFF00000000000000LL) >> 56) ) #endif #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)) typedef UINT16 (*_unalz_le16toh)(UINT16 a); typedef UINT32 (*_unalz_le32toh)(UINT32 a); typedef UINT64 (*_unalz_le64toh)(UINT64 a); static _unalz_le16toh unalz_le16toh=NULL; static _unalz_le32toh unalz_le32toh=NULL; static _unalz_le64toh unalz_le64toh=NULL; static UINT16 le16tole(UINT16 a){return a;} static UINT32 le32tole(UINT32 a){return a;} static UINT64 le64tole(UINT64 a){return a;} static UINT16 le16tobe(UINT16 a){return swapint16(a);} static UINT32 le32tobe(UINT32 a){return swapint32(a);} static UINT64 le64tobe(UINT64 a){return swapint64(a);} #ifndef MAX_PATH # define MAX_PATH 260*6 // ±×³É .. ÃæºÐÈ÷.. #endif #ifdef _WIN32 # define PATHSEP "\\" # define PATHSEPC '\\' #else # define PATHSEP "/" # define PATHSEPC '/' #endif static time_t dosTime2TimeT(UINT32 dostime) // from INFO-ZIP src { struct tm t; t.tm_isdst = -1; t.tm_sec = (((int)dostime) << 1) & 0x3e; t.tm_min = (((int)dostime) >> 5) & 0x3f; t.tm_hour = (((int)dostime) >> 11) & 0x1f; t.tm_mday = (int)(dostime >> 16) & 0x1f; t.tm_mon = ((int)(dostime >> 21) & 0x0f) - 1; t.tm_year = ((int)(dostime >> 25) & 0x7f) + 80; return mktime(&t); } static BOOL IsBigEndian(void) { union { short a; char b[2]; } endian; endian.a = 0x0102; if(endian.b[0] == 0x02) return FALSE; return TRUE; } #ifdef _WIN32 # define safe_sprintf StringCbPrintfA #else # define safe_sprintf snprintf #endif // 64bit file handling support #if (_FILE_OFFSET_BITS==64) # define unalz_fseek fseeko # define unalz_ftell ftello #else # define unalz_fseek fseek # define unalz_ftell ftell #endif // error string table <- CUnAlz::ERR ÀÇ ¹ø¿ª static const char* errorstrtable[]= { "no error", // ERR_NOERR "general error", // ERR_GENERAL "can't open archive file", // ERR_CANT_OPEN_FILE "can't open dest file or path", // ERR_CANT_OPEN_DEST_FILE // "can't create dest path", // ERR_CANT_CREATE_DEST_PATH "corrupted file", // ERR_CORRUPTED_FILE "not alz file", // ERR_NOT_ALZ_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 error", // ERR_FILE_READ_ERROR, "inflate failed", // ERR_INFLATE_FAILED, "bzip2 decompress failed", // ERR_BZIP2_FAILED, "invalid file CRC", // ERR_INVALID_FILE_CRC "unknown compression method", // ERR_UNKNOWN_COMPRESSION_METHOD "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 was 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 = m_fileList.end();//(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; m_bPipeMode = FALSE; #ifdef _UNALZ_ICONV #ifdef _UNALZ_UTF8 safe_strcpy(m_szToCodepage, "UTF-8",UNALZ_LEN_CODEPAGE) ; // ±âº»ÀûÀ¸·Î utf-8 #else safe_strcpy(m_szToCodepage, "CP949",UNALZ_LEN_CODEPAGE) ; // ±âº»ÀûÀ¸·Î CP949 #endif // _UNALZ_UTF8 safe_strcpy(m_szFromCodepage, "CP949",UNALZ_LEN_CODEPAGE); // alz ´Â 949 ¸¸ Áö¿ø #endif // _UNALZ_ICONV // check endian if(unalz_le16toh==NULL) { if(IsBigEndian()) { unalz_le16toh = le16tobe; unalz_le32toh = le32tobe; unalz_le64toh = le64tobe; } else { unalz_le16toh = le16tole; unalz_le32toh = le32tole; unalz_le64toh = le64tole; } } } //////////////////////////////////////////////////////////////////////////////////////////////////// /// 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 //////////////////////////////////////////////////////////////////////////////////////////////////// BOOL CUnAlz::Open(LPCWSTR szPathName) { char szPathNameA[MAX_PATH]; ::WideCharToMultiByte(CP_ACP, 0, szPathName, -1, szPathNameA, MAX_PATH, NULL, NULL); return Open(szPathNameA); } //////////////////////////////////////////////////////////////////////////////////////////////////// /// ´ë»ó ÆÄÀÏ ¼¼ÆÃÇϱâ. /// @param szFileName /// @return /// @date 2004-03-06 ¿ÀÈÄ 11:06:20 //////////////////////////////////////////////////////////////////////////////////////////////////// BOOL CUnAlz::SetCurrentFile(LPCWSTR szFileName) { char szFileNameA[MAX_PATH]; ::WideCharToMultiByte(CP_ACP, 0, szFileName, -1, szFileNameA, MAX_PATH, NULL, NULL); return SetCurrentFile(szFileNameA); } 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; } BOOL bValidAlzHeader = FALSE; // file ºÐ¼®½ÃÀÛ.. for(;;) { SIGNATURE sig; BOOL ret; if(FEof()) break; //int pos = unalz_ftell(m_fp); sig = ReadSignature(); if(sig==SIG_EOF) { break; } if(sig==SIG_ERROR) { if(bValidAlzHeader) m_nErr = ERR_CORRUPTED_FILE; // ¼Õ»óµÈ ÆÄÀÏ else m_nErr = ERR_NOT_ALZ_FILE; // alz ÆÄÀÏÀÌ ¾Æ´Ï´Ù. return FALSE; // ±úÁø ÆÄÀÏ.. } if(sig==SIG_ALZ_FILE_HEADER) { ret = ReadAlzFileHeader(); bValidAlzHeader = TRUE; // alz ÆÄÀÏÀº ¸Â´Ù. } 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); m_nErr = ERR_CORRUPTED_FILE; 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(); iClear(); } m_posCur = m_fileList.end();//(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) { 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() { SAlzLocalFileHeader 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.fileDescriptor & (SHORT)1) != 0){ m_bIsEncrypted = TRUE; // Çϳª¶óµµ ¾ÏÈ£ °É·ÈÀ¸¸é ¼¼ÆÃÇÑ´Ù. } if( (zipHeader.head.fileDescriptor & (SHORT)8) != 0){ m_bIsDataDescr = TRUE; } int byteLen = zipHeader.head.fileDescriptor/0x10; if(byteLen) { FRead(&(zipHeader.compressionMethod), sizeof(zipHeader.compressionMethod)); FRead(&(zipHeader.unknown), sizeof(zipHeader.unknown)); FRead(&(zipHeader.fileCRC), sizeof(zipHeader.fileCRC)); FRead(&(zipHeader.compressedSize), byteLen); FRead(&(zipHeader.uncompressedSize), byteLen); // ¾ÐÃà »çÀÌÁî°¡ ¾ø´Ù. } // little to system zipHeader.fileCRC = unalz_le32toh(zipHeader.fileCRC); zipHeader.head.fileNameLength = unalz_le16toh(zipHeader.head.fileNameLength); zipHeader.compressedSize = unalz_le64toh(zipHeader.compressedSize); zipHeader.uncompressedSize = unalz_le64toh(zipHeader.uncompressedSize); // FILE NAME zipHeader.fileName = (char*)malloc(zipHeader.head.fileNameLength+sizeof(char)); if(zipHeader.fileName==NULL) { m_nErr = ERR_INVALID_FILENAME_LENGTH; return FALSE; } FRead(zipHeader.fileName, zipHeader.head.fileNameLength); if(zipHeader.head.fileNameLength > MAX_PATH - 5) zipHeader.head.fileNameLength = MAX_PATH - 5; 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]; #if defined(__FreeBSD__) || defined(__CYGWIN__) || defined(__NetBSD__) 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; if(zipHeader.fileName) free(zipHeader.fileName); zipHeader.fileName = strdup(outbuf); if (zipHeader.fileName == NULL) { m_nErr = ERR_ICONV_ETC; iconv_close(cd); return FALSE; } // 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(IsEncryptedFile(zipHeader.head.fileDescriptor)) FRead(zipHeader.encChk, ALZ_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(); ifileName, szFileName)==0) #else if(strcmp(i->fileName, szFileName)==0) #endif { m_posCur = i; return TRUE; } } m_posCur = m_fileList.end();//(FileList::iterator)NULL; return FALSE; } void CUnAlz::SetCurrentFile(FileList::iterator newPos) { m_posCur = newPos; } #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==m_fileList.end()/*(FileList::iterator)NULL*/) {ASSERT(0); return FALSE;} BOOL ret=FALSE; SExtractDest dest; char szDestPathFileName[MAX_PATH]; if(chkValidPassword() == FALSE) { return FALSE; } if( szDestPathName==NULL|| strlen(szDestPathName) + (szDestFileName?strlen(szDestFileName):strlen(m_posCur->fileName))+1 > MAX_PATH ) // check buffer overflow { ASSERT(0); m_nErr = ERR_GENERAL; return FALSE; } // °æ·Î¸í safe_strcpy(szDestPathFileName, szDestPathName, MAX_PATH); if(szDestPathFileName[strlen(szDestPathFileName)]!=PATHSEPC) safe_strcat(szDestPathFileName, PATHSEP, MAX_PATH); // ÆÄÀϸí if(szDestFileName) safe_strcat(szDestPathFileName, szDestFileName, MAX_PATH); else safe_strcat(szDestPathFileName, m_posCur->fileName, MAX_PATH); // ../../ Çü½ÄÀÇ º¸¾È ¹ö±× È®ÀÎ if( strstr(szDestPathFileName, "../")|| strstr(szDestPathFileName, "..\\")) { ASSERT(0); m_nErr = ERR_GENERAL; return FALSE; } #ifndef _WIN32 { char* p = szDestPathFileName; // °æ·Î delimiter ¹Ù²Ù±â while(*p) { if(*p=='\\') *p='/'; p++; } } #endif // ¾ÐÃàÇ® ´ë»ó ( ÆÄÀÏ ) dest.nType = ET_FILE; if(m_bPipeMode) dest.fp = stdout; // pipe mode ÀÏ °æ¿ì stdout Ãâ·Â else dest.fp = fopen(szDestPathFileName, "wb"); // ŸÀÔÀÌ Æú´õÀÏ °æ¿ì.. if(m_bPipeMode==FALSE && (m_posCur->head.fileAttribute) & ALZ_FILEATTR_DIRECTORY ) { //printf("digpath:%s\n", szDestPathFileName); // °æ·ÎÆıâ DigPath(szDestPathFileName); return TRUE; // m_nErr = ERR_CANT_CREATE_DEST_PATH; // return FALSE; } // ÆÄÀÏ ¿­±â ½ÇÆнà - °æ·Î¸¦ Æĺ»´Ù if(dest.fp==NULL) { DigPath(szDestPathFileName); dest.fp = fopen(szDestPathFileName, "wb"); } // ±×·¡µµ ÆÄÀÏ¿­±â ½ÇÆнÃ. if(dest.fp==NULL) { // ´ë»ó ÆÄÀÏ ¿­±â ½ÇÆÐ m_nErr = ERR_CANT_OPEN_DEST_FILE; //printf("dest pathfilename:%s\n",szDestPathFileName); 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); // file time setting - from unalz_wcx_01i.zip utimbuf tmp; tmp.actime = 0; // ¸¶Áö¸· ¿¢¼¼½º ŸÀÓ tmp.modtime = dosTime2TimeT(m_posCur->head.fileTimeDate); // ¸¶Áö¸· ¼öÁ¤ÀÏÀÚ¸¸ º¯°æ(¸¸µç ³¯ÀÚ´Â ¾î¶»°Ô ¹Ù²ÙÁö?) utime(m_posCur->fileName, &tmp); } 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 // COMP_UNKNOWN { // alzip 5.6 ºÎÅÍ Ãß°¡µÈ Æ÷¸Ë(5.5 ¿¡¼­´Â Ç®Áö ¸øÇÑ´Ù. ¿µ¹® 5.51 Àº Ǭ´Ù ) // ÇÏÁö¸¸ ¾î¶² ¹öÀü¿¡¼­ ÀÌ Æ÷¸ËÀ» ¸¸µé¾î ³»´ÂÁö Á¤È®È÷ ¾Ë ¼ö ¾ø´Ù. // °ø½ÄÀ¸·Î ¸±¸®ÁîµÈ ¾ËÁýÀº ÀÌ Æ÷¸ËÀ» ¸¸µé¾î³»Áö ¾Ê´Â´Ù. ºñ°ø½Ä(º£Å¸?)À¸·Î ¹èÆ÷µÈ ¹öÀü¿¡¼­¸¸ ÀÌ Æ÷¸ËÀ» ¸¸µé¾î³½´Ù. m_nErr = ERR_UNKNOWN_COMPRESSION_METHOD; ASSERT(0); ret = FALSE; } return ret; } //////////////////////////////////////////////////////////////////////////////////////////////////// /// DEFLATE ·Î Ç®±â - Å×½ºÆ®¿ë ÇÔ¼ö. ¸ðµç ÆÄÀÏÀ» ÇѲ¨¹ø¿¡ Àо Ǭ´Ù. ½ÇÁ¦ »ç¿ë ¾ÈÇÔ. /// @param fp - ´ë»ó ÆÄÀÏ /// @param file - ¼Ò½º ÆÄÀÏ Á¤º¸ /// @return /// @date 2004-03-06 ¿ÀÈÄ 11:09:17 //////////////////////////////////////////////////////////////////////////////////////////////////// /* BOOL CUnAlz::ExtractDeflate(FILE* fp, SAlzLocalFileHeader& 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(); inType==ET_FILE) { return fwrite(buf, 1, nSize, dest->fp); } else if(dest->nType==ET_MEM) { if(dest->buf==NULL) return nSize; // ´ë»óÀÌ NULL ÀÌ´Ù... ¾ÐÃàǪ´Â ½Ã´¿¸¸ ÇÑ´Ù.. 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, SAlzLocalFileHeader& 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, SAlzLocalFileHeader& file) { BOOL ret = FALSE; BYTE buf[BUF_LEN]; INT64 read; INT64 sizeToRead; INT64 bufLen = BUF_LEN; INT64 nWritten = 0; BOOL bHalt = FALSE; BOOL bIsEncrypted = IsEncryptedFile(); // ¾ÏÈ£°É¸° ÆÄÀÏÀΰ¡? UINT32 dwCRC32= 0; // À§Ä¡ Àâ°í. FSeek(file.dwFileDataPos); sizeToRead = file.compressedSize; // ÀÐÀ» Å©±â. m_nErr = ERR_NOERR; while(sizeToRead) { read = min(sizeToRead, bufLen); if(FRead(buf, (int)read)==FALSE) { break; } if(bIsEncrypted) DecryptingData((int)read, buf); // xf86 dwCRC32 = crc32(dwCRC32, buf, (UINT)(read)); 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; if(m_nErr==ERR_NOERR) // ¼º°øÀûÀ¸·Î ¾ÐÃàÀ» Ç®¾ú´Ù.. CRC °Ë»çÇϱâ.. { if(file.fileCRC==dwCRC32) { ret = TRUE; } else { m_nErr = ERR_INVALID_FILE_CRC; } } 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, SAlzLocalFileHeader& file) { 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; FSeek(file.dwFileDataPos); bzfp = BZ2_bzReadOpen(&bzerr,this,verbosity,smallMode,0,0); if(bzfp==NULL){ASSERT(0); return FALSE;} m_nErr = ERR_NOERR; while((len=BZ2_bzread(bzfp,buff,BZIP2_EXTRACT_BUF_SIZE))>0) { WriteToDest(dest, (BYTE*)buff, (int)len); //fwrite(buff,1,len,fp_w); dwCRC32 = crc32(dwCRC32,buff, (UINT)(len)); nWritten+=len; // progress callback if(m_pFuncCallBack) { m_pFuncCallBack(NULL, nWritten, file.uncompressedSize, m_pCallbackParam, &bHalt); if(bHalt) { break; } } } if(len<0) // ¿¡·¯ »óȲ.. { m_nErr = ERR_INFLATE_FAILED; } BZ2_bzReadClose( &bzerr, bzfp); m_bHalt = bHalt; if(m_nErr==ERR_NOERR) // ¼º°øÀûÀ¸·Î ¾ÐÃàÀ» Ç®¾ú´Ù.. CRC °Ë»çÇϱâ.. { if(file.fileCRC==dwCRC32) { ret = TRUE; } else { m_nErr = ERR_INVALID_FILE_CRC; } } /* // 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 ret; } #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, SAlzLocalFileHeader& 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; BOOL bIsEncrypted = IsEncryptedFile(); // ¾ÏÈ£°É¸° ÆÄÀÏÀΰ¡? 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; m_nErr = ERR_NOERR; 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; } if(bIsEncrypted) DecryptingData(uReadThis, pInBuf); // xf86 // dwCRC32 = crc32(dwCRC32,pInBuf, (UINT)(uReadThis)); 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) { m_nErr = ERR_USER_ABORTED; 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; if(m_nErr==ERR_NOERR) // ¼º°øÀûÀ¸·Î ¾ÐÃàÀ» Ç®¾ú´Ù.. CRC °Ë»çÇϱâ.. { if(file.fileCRC==dwCRC32) { ret = TRUE; } else { m_nErr = ERR_INVALID_FILE_CRC; } } 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;i0) safe_sprintf(temp+nLen-3, 4, "%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; unalz_fseek(m_files[i].fp,0,SEEK_END); nFileSizeLow=unalz_ftell(m_files[i].fp); unalz_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>32)&0xffffffff); #ifdef _WIN32 SetFilePointer(m_files[i].fp, LONG(m_nCurFilePos), &remainHigh, FILE_BEGIN); #else unalz_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 unalz_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(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; } 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 < ALZ_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); } */ //////////////////////////////////////////////////////////////////////////////////////////////////// /// ¾ÏÈ£°É¸° ÆÄÀÏÀÎÁö ¿©ºÎ /// @param fileDescriptor /// @return /// @date 2004-11-27 ¿ÀÈÄ 11:25:32 //////////////////////////////////////////////////////////////////////////////////////////////////// BOOL CUnAlz::IsEncryptedFile(BYTE fileDescriptor) { return fileDescriptor&0x01; } BOOL CUnAlz::IsEncryptedFile() { return m_posCur->head.fileDescriptor&0x01; } //////////////////////////////////////////////////////////////////////////////////////////////////// /// ¾ÏÈ£·Î Å° ÃʱâÈ­ /// @param szPassword /// @return /// @date 2004-11-27 ¿ÀÈÄ 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]); } } //////////////////////////////////////////////////////////////////////////////////////////////////// /// µ¥ÀÌŸ·Î Å° ¾÷µ¥ÀÌÆ®Çϱâ /// @param c /// @return /// @date 2004-11-27 ¿ÀÈÄ 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); } //////////////////////////////////////////////////////////////////////////////////////////////////// /// ¾ÏÈ£°¡ ¸Â´ÂÁö Çì´õ üũÇϱâ /// @param buf /// @return /// @date 2004-11-27 ¿ÀÈÄ 11:04:24 //////////////////////////////////////////////////////////////////////////////////////////////////// BOOL CUnAlz::CryptCheck(const BYTE* buf) { int i; BYTE c; BYTE temp[ALZ_ENCR_HEADER_LEN]; memcpy(temp, buf, ALZ_ENCR_HEADER_LEN); // Àӽà º¹»ç. for(i=0;ihead.fileTimeDate >> 8) == c; else return ( ((m_posCur->fileCRC)>>24) ) == c; // ÆÄÀÏ crc ÀÇ ÃÖ»óÀ§ byte } //////////////////////////////////////////////////////////////////////////////////////////////////// /// Å°¿¡¼­ µ¥ÀÌŸ ÃßÃâ /// @return /// @date 2004-11-27 ¿ÀÈÄ 11:05:36 //////////////////////////////////////////////////////////////////////////////////////////////////// BYTE CUnAlz::DecryptByte() { UINT16 temp; temp = m_key[2] | 2; return (temp * (temp^1))>>8; } //////////////////////////////////////////////////////////////////////////////////////////////////// /// µ¥ÀÌŸ ¾ÐÃà Ç®±â /// @param nSize /// @param data /// @return /// @date 2004-11-27 ¿ÀÈÄ 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 Å×À̺í ÂüÁ¶ /// @param l /// @param c /// @return /// @date 2004-11-27 ¿ÀÈÄ 11:14:16 //////////////////////////////////////////////////////////////////////////////////////////////////// UINT32 CUnAlz::CRC32(UINT32 l, BYTE c) { const z_crc_t *CRC_TABLE = get_crc_table(); return CRC_TABLE[(l ^ c) & 0xff] ^ (l >> 8); } void CUnAlz::SetPassword(char *passwd) { if(strlen(passwd) == 0) return; safe_strcpy(m_szPasswd, passwd, UNALZ_LEN_PASSWORD); } #ifdef _UNALZ_ICONV void CUnAlz::SetDestCodepage(const char* szToCodepage) { safe_strcpy(m_szToCodepage, szToCodepage, UNALZ_LEN_CODEPAGE); } #endif //////////////////////////////////////////////////////////////////////////////////////////////////// /// ¹®ÀÚ¿­ ó¸® ÇÔ¼öµé /// @param l /// @param c /// @return /// @date 2007-02 //////////////////////////////////////////////////////////////////////////////////////////////////// unsigned int CUnAlz::_strlcpy (char *dest, const char *src, unsigned int size) { register unsigned int i = 0; if (size > 0) { size--; for (i=0; size > 0 && src[i] != '\0'; ++i, size--) dest[i] = src[i]; dest[i] = '\0'; } while (src[i++]); return i; } unsigned int CUnAlz::_strlcat (char *dest, const char *src, unsigned int size) { register char *d = dest; for (; size > 0 && *d != '\0'; size--, d++); return (d - dest) + _strlcpy(d, src, size); } // ¾ÈÀüÇÑ strcpy void CUnAlz::safe_strcpy(char* dst, const char* src, size_t dst_size) { #ifdef _WIN32 lstrcpynA(dst, src, dst_size); #else _strlcpy(dst, src, dst_size); #endif } void CUnAlz::safe_strcat(char* dst, const char* src, size_t dst_size) { #ifdef _WIN32 StringCchCatExA(dst, dst_size, src, NULL, NULL, STRSAFE_FILL_BEHIND_NULL); //lstrcatA(dst, src); // not safe!! #else _strlcat(dst, src, dst_size); #endif }