forked from mirror/unalz
v0.30
This commit is contained in:
parent
06b37f8d16
commit
725a6ca583
7 changed files with 170 additions and 12 deletions
118
UnAlz.cpp
118
UnAlz.cpp
|
@ -105,6 +105,10 @@ static const char* errorstrtable[]=
|
|||
"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",
|
||||
};
|
||||
|
||||
|
||||
|
@ -126,6 +130,8 @@ CUnAlz::CUnAlz()
|
|||
m_nVirtualFilePos = 0;
|
||||
m_nCurFilePos = 0;
|
||||
m_bIsEOF = FALSE;
|
||||
m_bIsEncrypted = FALSE;
|
||||
m_bIsDataDescr = FALSE;
|
||||
|
||||
#ifdef _UNALZ_ICONV
|
||||
|
||||
|
@ -159,7 +165,7 @@ void CUnAlz::SetCallback(_UnAlzCallback* pFunc, void* param)
|
|||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifndef __GNUWIN32__
|
||||
#if !defined(__GNUWIN32__) && !defined(__GNUC__)
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// 파일 열기
|
||||
/// @param szPathName
|
||||
|
@ -319,6 +325,13 @@ BOOL CUnAlz::ReadLocalFileheader()
|
|||
}
|
||||
|
||||
// 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)
|
||||
|
@ -335,6 +348,7 @@ BOOL CUnAlz::ReadLocalFileheader()
|
|||
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);
|
||||
|
@ -422,6 +436,8 @@ BOOL CUnAlz::ReadLocalFileheader()
|
|||
}
|
||||
*/
|
||||
|
||||
if(IsEncrypted()) FRead(zipHeader.encChk, ENCR_HEADER_LEN); // xf86
|
||||
|
||||
// SKIP FILE DATA
|
||||
zipHeader.dwFileDataPos = FTell(); // data 의 위치 저장하기..
|
||||
FSeek(FTell()+zipHeader.compressedSize);
|
||||
|
@ -594,6 +610,11 @@ BOOL CUnAlz::ExtractCurrentFile(const char* szDestPathName, const char* szDestFi
|
|||
SExtractDest dest;
|
||||
char szDestPathFileName[MAX_PATH];
|
||||
|
||||
if(chkValidPassword() == FALSE)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// 경로명
|
||||
strcpy(szDestPathFileName, szDestPathName);
|
||||
if(szDestPathFileName[strlen(szDestPathFileName)]!=PATHSEPC)
|
||||
|
@ -760,7 +781,7 @@ BOOL CUnAlz::ExtractAll(const char* szDestPathName)
|
|||
for(i=m_fileList.begin(); i<m_fileList.end(); i++)
|
||||
{
|
||||
m_posCur = i;
|
||||
ExtractCurrentFile(szDestPathName);
|
||||
if(ExtractCurrentFile(szDestPathName)==FALSE) return FALSE;
|
||||
if(m_bHalt)
|
||||
break; // 멈추기..
|
||||
}
|
||||
|
@ -1001,6 +1022,9 @@ BOOL CUnAlz::ExtractRawfile(SExtractDest* dest, SLocalFileHeader& file)
|
|||
{
|
||||
break;
|
||||
}
|
||||
|
||||
CryptDecodeBuffer((int)read, (CHAR *)buf); // xf86
|
||||
|
||||
WriteToDest(dest, buf, (int)read);
|
||||
//fwrite(buf, read, 1, fp);
|
||||
sizeToRead -= read;
|
||||
|
@ -1172,6 +1196,8 @@ BOOL CUnAlz::ExtractDeflate2(SExtractDest* dest, SLocalFileHeader& file)
|
|||
goto END;
|
||||
}
|
||||
|
||||
CryptDecodeBuffer(uReadThis, (CHAR *)pInBuf); // xf86
|
||||
|
||||
nRestReadCompressed -= uReadThis;
|
||||
stream.next_in = pInBuf;
|
||||
stream.avail_in = uReadThis;
|
||||
|
@ -1455,3 +1481,91 @@ 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);
|
||||
}
|
||||
|
||||
|
|
44
UnAlz.h
44
UnAlz.h
|
@ -2,7 +2,7 @@
|
|||
|
||||
COPYRIGHT(C) 2004 hardkoder@gmail.com / http://www.kipple.pe.kr
|
||||
|
||||
저작권 정보 :
|
||||
저작권 정보 : ( BSD License )
|
||||
- 이 소스는 자유로이 사용/수정/재배포 가능합니다.
|
||||
- 단, 당신이 만들었다고 주장하거나 거짓말하면 안됨.
|
||||
- 소스의 오류를 찾았거나, 문제점을 수정하였을 경우 이에 대한 내용을 알려주면 정말 고마울껄..
|
||||
|
@ -39,13 +39,14 @@
|
|||
2004/10/25 - by yongari : __LP64__ , 빅엔디안(le64toh/le132oh/le16toh) 관련 이슈 수정
|
||||
2004/10/26 - BSD/LINUX : byte-order, libiconv 이슈 정리
|
||||
2004/10/30 - 정리 & 정리..
|
||||
2004/11/14 - by xxfre86 : 암호 걸린 파일 처리 추가
|
||||
|
||||
|
||||
할일 : ( * 표는 한거 )
|
||||
- bzip2 로 압축된 파일의 압축 해제 *
|
||||
- UI 개선 ( PROGRESS, 에러 메시지 출력, 압축 해제 결과 ) *
|
||||
- 분할 압축 파일 지원 *
|
||||
- 암호 걸린 파일 지원
|
||||
- 암호 걸린 파일 지원 *
|
||||
- 손상된 파일에서의 좀더 많은 테스트
|
||||
- 파일 CRC 체크
|
||||
|
||||
|
@ -107,6 +108,9 @@ using namespace std;
|
|||
#ifndef LONG
|
||||
typedef long LONG;
|
||||
#endif
|
||||
#ifndef ULONG
|
||||
typedef unsigned long ULONG; // same as DWORD? i don't know.
|
||||
#endif
|
||||
#ifndef BOOL
|
||||
typedef int BOOL;
|
||||
#endif
|
||||
|
@ -144,10 +148,10 @@ namespace UNALZ
|
|||
# pragma pack(1)
|
||||
#endif
|
||||
|
||||
static const char UNALZ_VERSION[] = "CUnAlz0.23";
|
||||
static const char UNALZ_VERSION[] = "CUnAlz0.30";
|
||||
static const char UNALZ_COPYRIGHT[] = "Copyright(C) 2004 hardkoder@gmail.com";
|
||||
|
||||
|
||||
enum {ENCR_HEADER_LEN=12}; // xf86
|
||||
// 맨 파일 앞..
|
||||
struct SAlzHeader
|
||||
{
|
||||
|
@ -180,7 +184,9 @@ enum COMPRESSION_METHOD ///<
|
|||
struct _SLocalFileHeaderHead ///< 고정 헤더.
|
||||
{
|
||||
SHORT fileNameLength;
|
||||
BYTE unknown[5]; ///< ???
|
||||
BYTE fileAttribute; // from http://www.zap.pe.kr
|
||||
UINT32 fileTimeDate;
|
||||
|
||||
BYTE fileSizeByte; ///< 파일 크기 필드의 크기 : 0x10, 0x20, 0x40, 0x80 각각 1byte, 2byte, 4byte, 8byte
|
||||
BYTE unknown2[1]; ///< ???
|
||||
|
||||
|
@ -212,7 +218,7 @@ struct SLocalFileHeader
|
|||
void Clear() { if(fileName) free(fileName); fileName=NULL; if(extraField) free(extraField);extraField=NULL; }
|
||||
_SLocalFileHeaderHead head;
|
||||
|
||||
BYTE compressionMethod; ///< 압축 방법 : 2 - deflate, 1 - bzip2(?), 0 - 압축 안함.
|
||||
BYTE compressionMethod; ///< 압축 방법 : 2 - deflate, 1 - 변형 bzip2, 0 - 압축 안함.
|
||||
BYTE unknown3[1]; ///< ???
|
||||
UINT32 maybeCRC; ///< 아마도 crc
|
||||
|
||||
|
@ -223,6 +229,8 @@ struct SLocalFileHeader
|
|||
BYTE* extraField;
|
||||
_SDataDescriptor dataDescriptor;
|
||||
INT64 dwFileDataPos; ///< file data 가 저장된 위치..
|
||||
|
||||
CHAR encChk[ENCR_HEADER_LEN]; // xf86
|
||||
};
|
||||
|
||||
struct _SCentralDirectoryStructureHead
|
||||
|
@ -314,6 +322,9 @@ public:
|
|||
BOOL ExtractAll(const char* szDestPathName);
|
||||
void SetCallback(_UnAlzCallback* pFunc, void* param=NULL);
|
||||
|
||||
void setPassword(char *passwd) { if(strlen(passwd) == 0) return; strcpy(m_szPasswd, passwd); }; // xf86
|
||||
BOOL IsEncrypted() { return m_bIsEncrypted; };
|
||||
|
||||
#ifdef _UNALZ_ICONV
|
||||
void SetDestCodepage(const char* szToCodepage) { strcpy(m_szToCodepage, szToCodepage); }
|
||||
#endif
|
||||
|
@ -363,6 +374,10 @@ public :
|
|||
ERR_ICONV_NOT_ENOUGH_SPACE_OF_BUFFER_TO_CONVERT,
|
||||
ERR_ICONV_ETC,
|
||||
|
||||
ERR_PASSWD_NOT_SET,
|
||||
ERR_INVALID_PASSWD,
|
||||
ERR_USER_ABORTED,
|
||||
|
||||
};
|
||||
ERR GetLastErr(){return m_nErr;}
|
||||
const char* GetLastErrStr(){return LastErrToStr(m_nErr);}
|
||||
|
@ -383,6 +398,7 @@ public :
|
|||
static BOOL IsFolder(LPCSTR szPathName);
|
||||
static const char* GetVersion() { return UNALZ_VERSION; }
|
||||
static const char* GetCopyright() { return UNALZ_COPYRIGHT; }
|
||||
BOOL IsHalted() { return m_bHalt; } // by xf86
|
||||
|
||||
private :
|
||||
SIGNATURE ReadSignature();
|
||||
|
@ -432,6 +448,17 @@ private : //
|
|||
BOOL FSeek(INT64 offset);
|
||||
BOOL FRead(void* buffer, UINT32 nBytesToRead, int* pTotRead=NULL);
|
||||
|
||||
BOOL IsDataDescr() { return m_bIsDataDescr; }; // xf86
|
||||
int getPasswordLen() { return strlen(m_szPasswd); };
|
||||
void CryptDecodeBuffer(UINT32 uCount, CHAR *buf);
|
||||
void CryptInitKeys();
|
||||
void CryptUpdateKeys(CHAR c);
|
||||
BOOL CryptCheck(CHAR *buf);
|
||||
CHAR CryptDecryptCHAR();
|
||||
void CryptDecode(CHAR &c);
|
||||
UINT32 CryptCRC32(UINT32 l, CHAR c);
|
||||
BOOL chkValidPassword(); // xf86
|
||||
|
||||
enum {MAX_FILES=1000}; ///< 처리 가능한 분할 압축 파일 수.
|
||||
enum {MULTIVOL_TAIL_SIZE=16,MULTIVOL_HEAD_SIZE=8}; ///< 분할 압축시 꼴랑지, 헤더 크기
|
||||
struct SFile ///< 분할 파일 정보
|
||||
|
@ -449,6 +476,11 @@ private : //
|
|||
INT64 m_nCurFilePos; ///< 현재 파일의 물리적 위치.
|
||||
BOOL m_bIsEOF; ///< 파일의 끝까지 (분할 파일 포함해서) 왔나?
|
||||
|
||||
BOOL m_bIsEncrypted; // xf86
|
||||
BOOL m_bIsDataDescr;
|
||||
char m_szPasswd[256];
|
||||
UINT32 m_keys[3];
|
||||
|
||||
|
||||
private :
|
||||
FileList m_fileList; ///< 압축파일 내의 파일 목록
|
||||
|
|
|
@ -131,6 +131,8 @@ int CUnAlz::BZ2_bzRead(int* bzerror, MYBZFILE* b, void* buf, int len)
|
|||
if (bzf->strm.avail_in == 0 && !bzf->handle->FEof()) {
|
||||
bzf->handle->FRead(bzf->buf, sizeof(UChar)*BZ_MAX_UNUSED, &n);
|
||||
|
||||
bzf->handle->CryptDecodeBuffer(n, (CHAR *)bzf->buf); // xf86 NOT tested -> tested
|
||||
|
||||
if(n==0)
|
||||
{ BZ_SETERR(BZ_IO_ERROR); return 0; };
|
||||
bzf->bufN = n;
|
||||
|
|
0
clear.bat
Normal file → Executable file
0
clear.bat
Normal file → Executable file
13
main.cpp
13
main.cpp
|
@ -1,4 +1,5 @@
|
|||
#include <stdio.h>
|
||||
#include <iostream>
|
||||
#include "UnAlz.h"
|
||||
|
||||
|
||||
|
@ -69,7 +70,8 @@ int main(int argc, char* argv[])
|
|||
{
|
||||
// printf("unalz v0.20 (2004/10/22) \n");
|
||||
// printf("unalz v0.22 (2004/10/27) \n");
|
||||
printf("unalz v0.23 (2004/10/30) \n");
|
||||
// printf("unalz v0.23 (2004/10/30) \n");
|
||||
printf("unalz v0.30 (2004/11/14) \n");
|
||||
printf("copyright(C) 2004 http://www.kipple.pe.kr\n");
|
||||
|
||||
if(argc<2)
|
||||
|
@ -126,8 +128,15 @@ int main(int argc, char* argv[])
|
|||
return 0;
|
||||
}
|
||||
|
||||
printf("\nExtract %s to %s\n", source, destpath);
|
||||
|
||||
if(unalz.IsEncrypted()){
|
||||
char pwd[256];
|
||||
cout << "Enter Password : ";
|
||||
cin >> pwd;
|
||||
unalz.setPassword(pwd);
|
||||
}
|
||||
|
||||
printf("\nExtract %s to %s\n", source, destpath);
|
||||
|
||||
// callback 窃荐 技泼
|
||||
unalz.SetCallback(UnAlzCallback, (void*)NULL);
|
||||
|
|
2
makefile
2
makefile
|
@ -18,7 +18,7 @@ all:
|
|||
@echo ""
|
||||
@echo " posix : POSIX system (FreeBSD/linux/OSX/sparc)"
|
||||
@echo " posix-utf8 : POSIX with utf8 filesystem(OSX)"
|
||||
@echo " posix-noiconv : POSIX without libiconv (CP949 only)"
|
||||
@echo " posix-noiconv : POSIX without libiconv (MINGW32,CP949 file system)"
|
||||
|
||||
@echo ""
|
||||
@echo " and 'clean' for clean"
|
||||
|
|
|
@ -2,7 +2,8 @@
|
|||
|
||||
PROG= unalz
|
||||
NOMAN=
|
||||
SRCS= main.cpp UnAlz.cpp UnAlzBz2decompress.c UnAlzBzip2.cpp UnAlzbzlib.c
|
||||
SRCS= main.cpp UnAlz.cpp UnAlzBz2decompress.c UnAlzBzip2.cpp \
|
||||
UnAlzbzlib.c
|
||||
LDADD+= -lz -lbz2 -liconv -lstdc++
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
|
Loading…
Reference in a new issue