1 #include "bzip2/bzlib.h"
2 #include "UnAlz.h"
3 
4 #ifdef _WIN32
5 #	include "zlib/zlib.h"
6 #else
7 #	include <zlib.h>
8 #endif
9 
10 
11 #ifdef _WIN32
12 #	pragma warning( disable : 4996 )		// crt secure warning
13 #endif
14 
15 // utime
16 #if defined(_WIN32) || defined(__CYGWIN__)
17 #	include <time.h>
18 #	include <sys/utime.h>
19 #endif
20 #ifdef __GNUC__
21 #	include <time.h>
22 #	include <utime.h>
23 #endif
24 
25 // mkdir
26 #ifdef _WIN32
27 #	include <direct.h>
28 #else
29 #	include <sys/stat.h>
30 #endif
31 
32 #ifdef _UNALZ_ICONV			// code page support
33 #	include <iconv.h>
34 #endif
35 
36 #if defined(__linux__) || defined(__GLIBC__) || defined(__GNU__) || defined(__APPLE__)
37 #	include <errno.h>
38 #endif
39 
40 #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__DragonFly__)
41 #	include <sys/param.h>	// __NetBSD_Version__
42 #	include <errno.h>		// iconv.h
43 #endif
44 
45 #ifdef _WIN32				// safe string
46 #	include <strsafe.h>
47 #endif
48 
49 
50 // ENDIAN
51 #ifdef _WIN32	// (L)
52 #	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) )
53 #else			// (LL)
54 #	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) )
55 #endif
56 #define swapint32(a)    ((((a)&0xff)<<24)+(((a>>8)&0xff)<<16)+(((a>>16)&0xff)<<8)+(((a>>24)&0xff)))
57 #define swapint16(a)    (((a)&0xff)<<8)+(((a>>8)&0xff))
58 
59 typedef UINT16	(*_unalz_le16toh)(UINT16 a);
60 typedef UINT32	(*_unalz_le32toh)(UINT32 a);
61 typedef UINT64	(*_unalz_le64toh)(UINT64 a);
62 
63 static _unalz_le16toh unalz_le16toh=NULL;
64 static _unalz_le32toh unalz_le32toh=NULL;
65 static _unalz_le64toh unalz_le64toh=NULL;
66 
le16tole(UINT16 a)67 static UINT16	le16tole(UINT16 a){return a;}
le32tole(UINT32 a)68 static UINT32	le32tole(UINT32 a){return a;}
le64tole(UINT64 a)69 static UINT64	le64tole(UINT64 a){return a;}
le16tobe(UINT16 a)70 static UINT16	le16tobe(UINT16 a){return swapint16(a);}
le32tobe(UINT32 a)71 static UINT32	le32tobe(UINT32 a){return swapint32(a);}
le64tobe(UINT64 a)72 static UINT64	le64tobe(UINT64 a){return swapint64(a);}
73 
74 
75 #ifndef MAX_PATH
76 #	define MAX_PATH 260*6			//
77 #endif
78 
79 #ifdef _WIN32
80 #	define PATHSEP "\\"
81 #	define PATHSEPC '\\'
82 #else
83 #	define PATHSEP "/"
84 #	define PATHSEPC '/'
85 #endif
86 
dosTime2TimeT(UINT32 dostime)87 static time_t dosTime2TimeT(UINT32 dostime)   // from INFO-ZIP src
88 {
89 	struct tm t;
90 	t.tm_isdst = -1;
91 	t.tm_sec  = (((int)dostime) <<  1) & 0x3e;
92 	t.tm_min  = (((int)dostime) >>  5) & 0x3f;
93 	t.tm_hour = (((int)dostime) >> 11) & 0x1f;
94 	t.tm_mday = (int)(dostime >> 16) & 0x1f;
95 	t.tm_mon  = ((int)(dostime >> 21) & 0x0f) - 1;
96 	t.tm_year = ((int)(dostime >> 25) & 0x7f) + 80;
97 	return mktime(&t);
98 }
99 
IsBigEndian(void)100 static BOOL IsBigEndian(void)
101 {
102    union {
103         short a;
104         char  b[2];
105    } endian;
106 
107    endian.a = 0x0102;
108    if(endian.b[0] == 0x02) return FALSE;
109    return TRUE;
110 }
111 
112 
113 #ifdef _WIN32
114 #	define safe_sprintf	StringCbPrintfA
115 #else
116 #	define safe_sprintf	snprintf
117 #endif
118 
119 
120 // 64bit file handling support
121 #if (_FILE_OFFSET_BITS==64)
122 #	define unalz_fseek	fseeko
123 #	define unalz_ftell	ftello
124 #else
125 #	define unalz_fseek	fseek
126 #	define unalz_ftell	ftell
127 #endif
128 
129 // error string table <- CUnAlz::ERR
130 static const char* errorstrtable[]=
131 {
132 	"no error",										// ERR_NOERR
133 	"general error",								// ERR_GENERAL
134 	"can't open archive file",						// ERR_CANT_OPEN_FILE
135 	"can't open dest file or path",					// ERR_CANT_OPEN_DEST_FILE
136 //	"can't create dest path",						// ERR_CANT_CREATE_DEST_PATH
137 	"corrupted file",								// ERR_CORRUPTED_FILE
138 	"not alz file",									// ERR_NOT_ALZ_FILE
139 	"can't read signature",							// ERR_CANT_READ_SIG
140 	"can't read file",								// ERR_CANT_READ_FILE
141 	"error at read header",							// ERR_AT_READ_HEADER
142 	"invalid filename length",						// ERR_INVALID_FILENAME_LENGTH
143 	"invalid extrafield length",					// ERR_INVALID_EXTRAFIELD_LENGTH,
144 	"can't read central directory structure head",	// ERR_CANT_READ_CENTRAL_DIRECTORY_STRUCTURE_HEAD,
145 	"invalid filename size",						// ERR_INVALID_FILENAME_SIZE,
146 	"invalid extrafield size",						// ERR_INVALID_EXTRAFIELD_SIZE,
147 	"invalid filecomment size",						// ERR_INVALID_FILECOMMENT_SIZE,
148 	"cant' read header",							// ERR_CANT_READ_HEADER,
149 	"memory allocation failed",						// ERR_MEM_ALLOC_FAILED,
150 	"file read error",								// ERR_FILE_READ_ERROR,
151 	"inflate failed",								// ERR_INFLATE_FAILED,
152 	"bzip2 decompress failed",						// ERR_BZIP2_FAILED,
153 	"invalid file CRC",								// ERR_INVALID_FILE_CRC
154 	"unknown compression method",					// ERR_UNKNOWN_COMPRESSION_METHOD
155 	"iconv-can't open iconv",						// ERR_ICONV_CANT_OPEN,
156 	"iconv-invalid multisequence of characters",	// ERR_ICONV_INVALID_MULTISEQUENCE_OF_CHARACTERS,
157 	"iconv-incomplete multibyte sequence",			// ERR_ICONV_INCOMPLETE_MULTIBYTE_SEQUENCE,
158 	"iconv-not enough space of buffer to convert",	// ERR_ICONV_NOT_ENOUGH_SPACE_OF_BUFFER_TO_CONVERT,
159 	"iconv-etc",									// ERR_ICONV_ETC,
160 	"password was not set",							// ERR_PASSWD_NOT_SET,
161 	"invalid password",								// ERR_INVALID_PASSWD,
162 	"user aborted",
163 };
164 
165 ////////////////////////////////////////////////////////////////////////////////////////////////////
166 //          ctor
167 // @date    2004-03-06 ¿ÀÈÄ 11:19:49
168 ////////////////////////////////////////////////////////////////////////////////////////////////////
CUnAlz()169 CUnAlz::CUnAlz()
170 {
171 	memset(m_files, 0, sizeof(m_files));
172 	m_nErr = ERR_NOERR;
173 	m_posCur = m_fileList.end();//(FileList::iterator)NULL;
174 	m_pFuncCallBack = NULL;
175 	m_pCallbackParam = NULL;
176 	m_bHalt = FALSE;
177 	m_nFileCount = 0;
178 	m_nCurFile = -1;
179 	m_nVirtualFilePos = 0;
180 	m_nCurFilePos = 0;
181 	m_bIsEOF = FALSE;
182 	m_bIsEncrypted = FALSE;
183 	m_bIsDataDescr = FALSE;
184 	m_bPipeMode = FALSE;
185 
186 #ifdef _UNALZ_ICONV
187 
188 #ifdef _UNALZ_UTF8
189 	safe_strcpy(m_szToCodepage, "UTF-8",UNALZ_LEN_CODEPAGE) ;		// utf-8
190 #else
191 	safe_strcpy(m_szToCodepage, "CP949",UNALZ_LEN_CODEPAGE) ;		// CP949
192 #endif // _UNALZ_UTF8
193 
194 	safe_strcpy(m_szFromCodepage, "CP949",UNALZ_LEN_CODEPAGE);		// alz 949
195 #endif // _UNALZ_ICONV
196 
197 	// check endian
198 	if(unalz_le16toh==NULL)
199 	{
200 		if(IsBigEndian())
201 		{
202 			unalz_le16toh = le16tobe;
203 			unalz_le32toh = le32tobe;
204 			unalz_le64toh = le64tobe;
205 		}
206 		else
207 		{
208 			unalz_le16toh = le16tole;
209 			unalz_le32toh = le32tole;
210 			unalz_le64toh = le64tole;
211 		}
212 	}
213 }
214 
215 ////////////////////////////////////////////////////////////////////////////////////////////////////
216 //          dtor
217 // @date    2004-03-06 11:19:52
218 ////////////////////////////////////////////////////////////////////////////////////////////////////
~CUnAlz()219 CUnAlz::~CUnAlz()
220 {
221 	Close();
222 }
223 
224 ////////////////////////////////////////////////////////////////////////////////////////////////////
225 //          progress callback func setting
226 // @date    2004-03-01 6:02:05
227 ////////////////////////////////////////////////////////////////////////////////////////////////////
SetCallback(_UnAlzCallback * pFunc,void * param)228 void CUnAlz::SetCallback(_UnAlzCallback* pFunc, void* param)
229 {
230 	m_pFuncCallBack = pFunc;
231 	m_pCallbackParam = param;
232 }
233 
234 #ifdef _WIN32
235 #if !defined(__GNUWIN32__) && !defined(__GNUC__)
236 ////////////////////////////////////////////////////////////////////////////////////////////////////
237 // @param   szPathName
238 // @return
239 // @date    2004-03-06 11:03:59
240 ////////////////////////////////////////////////////////////////////////////////////////////////////
Open(LPCWSTR szPathName)241 BOOL CUnAlz::Open(LPCWSTR szPathName)
242 {
243 	char szPathNameA[MAX_PATH];
244 	::WideCharToMultiByte(CP_ACP, 0, szPathName, -1, szPathNameA, MAX_PATH, NULL, NULL);
245 	return Open(szPathNameA);
246 }
247 ////////////////////////////////////////////////////////////////////////////////////////////////////
248 // @param   szFileName
249 // @return
250 // @date    2004-03-06 11:06:20
251 ////////////////////////////////////////////////////////////////////////////////////////////////////
SetCurrentFile(LPCWSTR szFileName)252 BOOL CUnAlz::SetCurrentFile(LPCWSTR szFileName)
253 {
254 	char szFileNameA[MAX_PATH];
255 	::WideCharToMultiByte(CP_ACP, 0, szFileName, -1, szFileNameA, MAX_PATH, NULL, NULL);
256 	return SetCurrentFile(szFileNameA);
257 }
IsFolder(LPCWSTR szPathName)258 BOOL CUnAlz::IsFolder(LPCWSTR szPathName)
259 {
260 	UINT32 dwRet;
261 	dwRet = GetFileAttributesW(szPathName);
262 	if(dwRet==0xffffffff) return FALSE;
263 	if(dwRet & FILE_ATTRIBUTE_DIRECTORY) return TRUE;
264 	return FALSE;
265 }
266 #endif // __GNUWIN32__
267 #endif // _WIN32
268 
Open(const char * szPathName)269 BOOL CUnAlz::Open(const char* szPathName)
270 {
271 	if(FOpen(szPathName)==FALSE)
272 	{
273 		m_nErr = ERR_CANT_OPEN_FILE;
274 		return FALSE;
275 	}
276 
277 	BOOL	bValidAlzHeader = FALSE;
278 
279 	// file
280 	for(;;)
281 	{
282 		SIGNATURE	sig;
283 		BOOL		ret;
284 
285 		if(FEof()) break;
286 		//int pos = unalz_ftell(m_fp);
287 		sig = ReadSignature();
288 		if(sig==SIG_EOF)
289 		{
290 			break;
291 		}
292 		if(sig==SIG_ERROR)
293 		{
294 			if(bValidAlzHeader)
295 				m_nErr = ERR_CORRUPTED_FILE;	//
296 			else
297 				m_nErr = ERR_NOT_ALZ_FILE;	// alz
298 			return FALSE;						//
299 		}
300 
301 		if(sig==SIG_ALZ_FILE_HEADER)
302 		{
303 			ret = ReadAlzFileHeader();
304 			bValidAlzHeader = TRUE;					// alz
305 		}
306 		else if(sig==SIG_LOCAL_FILE_HEADER) ret = ReadLocalFileheader();
307 		else if(sig==SIG_CENTRAL_DIRECTORY_STRUCTURE) ret = ReadCentralDirectoryStructure();
308 		else if(sig==SIG_ENDOF_CENTRAL_DIRECTORY_RECORD) ret = ReadEndofCentralDirectoryRecord();
309 		else
310 		{
311 			// signature
312 			ASSERT(0);
313 			m_nErr = ERR_CORRUPTED_FILE;
314 			return FALSE;
315 		}
316 
317 		if(ret==FALSE)
318 		{
319 			return FALSE;
320 		}
321 
322 		if(FEof()) break;
323 	}
324 
325 	return TRUE;
326 }
327 
328 ////////////////////////////////////////////////////////////////////////////////////////////////////
329 // @return
330 // @date    2004-03-06 11:04:21
331 ////////////////////////////////////////////////////////////////////////////////////////////////////
Close()332 void CUnAlz::Close()
333 {
334 	FClose();
335 
336 	//
337 	FileList::iterator	i;
338 
339 	for(i=m_fileList.begin(); i<m_fileList.end(); i++)
340 	{
341 		i->Clear();
342 	}
343 
344 	m_posCur = m_fileList.end();//(FileList::iterator)NULL;
345 }
346 
347 ////////////////////////////////////////////////////////////////////////////////////////////////////
348 //          FILE SIGNATURE
349 // @return
350 // @date    2004-03-06 11:04:47
351 ////////////////////////////////////////////////////////////////////////////////////////////////////
ReadSignature()352 CUnAlz::SIGNATURE CUnAlz::ReadSignature()
353 {
354 	UINT32	dwSig;
355 	if(FRead(&dwSig, sizeof(dwSig))==FALSE)
356 	{
357 		if(FEof())
358 			return SIG_EOF;
359 		m_nErr = ERR_CANT_READ_SIG;
360 		return SIG_ERROR;
361 	}
362 
363 	return (SIGNATURE)unalz_le32toh(dwSig);		// little to host;
364 }
365 
366 ////////////////////////////////////////////////////////////////////////////////////////////////////
367 //          ALZ HEADER SIGNATURE
368 // @return
369 // @date    2004-03-06 11:05:11
370 ////////////////////////////////////////////////////////////////////////////////////////////////////
ReadAlzFileHeader()371 BOOL CUnAlz::ReadAlzFileHeader()
372 {
373 	SAlzHeader	header;
374 	if(FRead(&header, sizeof(header))==FALSE)
375 	{
376 		ASSERT(0);
377 		m_nErr = ERR_CANT_READ_FILE;
378 		return FALSE;
379 	}
380 	return TRUE;
381 }
382 
383 ////////////////////////////////////////////////////////////////////////////////////////////////////
384 // @return
385 // @date    2004-03-06 11:05:18
386 ////////////////////////////////////////////////////////////////////////////////////////////////////
ReadLocalFileheader()387 BOOL CUnAlz::ReadLocalFileheader()
388 {
389 	SAlzLocalFileHeader zipHeader;
390 	int ret;
391 
392 	ret = FRead(&(zipHeader.head), sizeof(zipHeader.head));
393 	if(ret==FALSE)
394 	{
395 		m_nErr = ERR_AT_READ_HEADER;
396 		return FALSE;
397 	}
398 
399 	// ALZ
400 	if( (zipHeader.head.fileDescriptor & (SHORT)1) != 0){
401 		m_bIsEncrypted = TRUE;									//
402 	}
403 	if( (zipHeader.head.fileDescriptor & (SHORT)8) != 0){
404 		m_bIsDataDescr = TRUE;
405 	}
406 
407 	int byteLen = zipHeader.head.fileDescriptor/0x10;
408 
409 	if(byteLen)
410 	{
411 		FRead(&(zipHeader.compressionMethod),	sizeof(zipHeader.compressionMethod));
412 		FRead(&(zipHeader.unknown),				sizeof(zipHeader.unknown));
413 		FRead(&(zipHeader.fileCRC),				sizeof(zipHeader.fileCRC));
414 
415 		FRead(&(zipHeader.compressedSize), byteLen);
416 		FRead(&(zipHeader.uncompressedSize),  byteLen);			//
417 	}
418 
419 	// little to system
420     zipHeader.fileCRC				=   unalz_le32toh(zipHeader.fileCRC);
421     zipHeader.head.fileNameLength   =   unalz_le16toh(zipHeader.head.fileNameLength);
422     zipHeader.compressedSize        =   unalz_le64toh(zipHeader.compressedSize);
423     zipHeader.uncompressedSize      =   unalz_le64toh(zipHeader.uncompressedSize);
424 
425 	// FILE NAME
426 	zipHeader.fileName = (char*)malloc(zipHeader.head.fileNameLength+sizeof(char));
427 	if(zipHeader.fileName==NULL)
428 	{
429 		m_nErr = ERR_INVALID_FILENAME_LENGTH;
430 		return FALSE;
431 	}
432 	FRead(zipHeader.fileName, zipHeader.head.fileNameLength);
433 	if(zipHeader.head.fileNameLength > MAX_PATH - 5)
434 		zipHeader.head.fileNameLength = MAX_PATH - 5;
435 	zipHeader.fileName[zipHeader.head.fileNameLength] = (CHAR)0;
436 
437 
438 #ifdef _UNALZ_ICONV		// codepage convert
439 
440 	if(strlen(m_szToCodepage))
441 	{
442 
443 	#define ICONV_BUF_SIZE	(260*6)			// utf8 6byte
444 	size_t ileft, oleft;
445 	iconv_t cd;
446 	size_t iconv_result;
447 	size_t size;
448 	char inbuf[ICONV_BUF_SIZE];
449 	char outbuf[ICONV_BUF_SIZE];
450 #if defined(__CYGWIN__) ||  defined(__NetBSD__)
451 	const char *inptr = inbuf;
452 #else
453 	char *inptr = inbuf;
454 #endif
455 	char *outptr = outbuf;
456 
457 	size = strlen(zipHeader.fileName)+1;
458 	strncpy(inbuf, zipHeader.fileName, size);
459 	ileft = size;
460 	oleft = sizeof(outbuf);
461 
462 	cd = iconv_open(m_szToCodepage, m_szFromCodepage);		// "UTF-8"
463 	iconv(cd, NULL, NULL, NULL, NULL);
464 	if( cd == (iconv_t)(-1))
465 	{
466 		m_nErr = ERR_ICONV_CANT_OPEN;		// printf("Converting Error : Cannot open iconv");
467 		return FALSE;
468 	}
469 	else
470 	{
471 		iconv_result = iconv(cd, &inptr, &ileft, &outptr, &oleft);
472 
473 		if(iconv_result== (size_t)(-1))		// iconv
474 		{
475 			if (errno == EILSEQ)
476 				m_nErr = ERR_ICONV_INVALID_MULTISEQUENCE_OF_CHARACTERS; // printf("Invalid Multibyte Sequence of Characters");
477 			else if (errno == EINVAL)
478 				m_nErr = ERR_ICONV_INCOMPLETE_MULTIBYTE_SEQUENCE; // printf("Incomplete  multibyte sequence");
479 			else if (errno != E2BIG)
480 				m_nErr = ERR_ICONV_NOT_ENOUGH_SPACE_OF_BUFFER_TO_CONVERT;	// printf("Not enough space of buffer to convert");
481 			else
482 				m_nErr = ERR_ICONV_ETC;
483 			iconv_close(cd);
484 			return FALSE;
485 		}
486 		else
487 		{
488 			outbuf[ICONV_BUF_SIZE-oleft] = 0;
489 			if(zipHeader.fileName) free(zipHeader.fileName);
490 			zipHeader.fileName = strdup(outbuf);
491 			if (zipHeader.fileName == NULL)
492 			{
493 				m_nErr = ERR_ICONV_ETC;
494 				iconv_close(cd);
495 				return FALSE;
496 			}
497 			// printf("\n  Converted File Name : %s", outbuf);
498 		}
499 
500 		iconv_close(cd);
501     }
502 
503 	}
504 #endif
505 
506 	/*
507 	// EXTRA FIELD LENGTH
508 	if(zipHeader.head.extraFieldLength)
509 	{
510 		zipHeader.extraField = (BYTE*)malloc(zipHeader.head.extraFieldLength);
511 		if(zipHeader.extraField==NULL)
512 		{
513 			m_nErr = ERR_INVALID_EXTRAFIELD_LENGTH;
514 			return FALSE;
515 		}
516 		FRead(zipHeader.extraField, 1, zipHeader.head.extraFieldLength);
517 	}
518 	*/
519 
520 	if(IsEncryptedFile(zipHeader.head.fileDescriptor))
521 		FRead(zipHeader.encChk, ALZ_ENCR_HEADER_LEN);  // xf86
522 
523 	// SKIP FILE DATA
524 	zipHeader.dwFileDataPos = FTell();						// data
525 	FSeek(FTell()+zipHeader.compressedSize);
526 
527 	// DATA DESCRIPTOR
528 	/*
529 	if(zipHeader.head.generalPurposeBitFlag.bit1)
530 	{
531 		FRead(zipHeader.extraField, 1, sizeof(zipHeader.extraField),);
532 	}
533 	*/
534 
535 	/*
536 #ifdef _DEBUG
537 	printf("NAME:%s COMPRESSED SIZE:%d UNCOMPRESSED SIZE:%d COMP METHOD:%d\n",
538 		zipHeader.fileName,
539 		zipHeader.compressedSize,
540 		zipHeader.uncompressedSize,
541 		zipHeader.compressionMethod
542 		);
543 #endif
544 	*/
545 
546 	//
547 	m_fileList.push_back(zipHeader);
548 
549 	return TRUE;
550 }
551 
ReadCentralDirectoryStructure()552 BOOL CUnAlz::ReadCentralDirectoryStructure()
553 {
554 	SCentralDirectoryStructure header;
555 
556 	if(FRead(&header, sizeof(header.head))==FALSE)
557 	{
558 		m_nErr = ERR_CANT_READ_CENTRAL_DIRECTORY_STRUCTURE_HEAD;
559 		return FALSE;
560 	}
561 
562 	/*
563 	// read file name
564 	if(header.head.fileNameLength)
565 	{
566 		header.fileName = (char*)malloc(header.head.fileNameLength+1);
567 		if(header.fileName==NULL)
568 		{
569 			m_nErr = ERR_INVALID_FILENAME_SIZE;
570 			return FALSE;
571 		}
572 		FRead(header.fileName, 1, header.head.fileNameLength, m_fp);
573 		header.fileName[header.head.fileNameLength] = NULL;
574 	}
575 
576 	// extra field;
577 	if(header.head.extraFieldLength)
578 	{
579 		header.extraField = (BYTE*)malloc(header.head.extraFieldLength);
580 		if(header.extraField==NULL)
581 		{
582 			m_nErr = ERR_INVALID_EXTRAFIELD_SIZE;
583 			return FALSE;
584 		}
585 		FRead(header.extraField, 1, header.head.extraFieldLength, m_fp);
586 	}
587 
588 	// file comment;
589 	if(header.head.fileCommentLength)
590 	{
591 		header.fileComment = (char*)malloc(header.head.fileCommentLength+1);
592 		if(header.fileComment==NULL)
593 		{
594 			m_nErr = ERR_INVALID_FILECOMMENT_SIZE;
595 			return FALSE;
596 		}
597 		FRead(header.fileComment, 1, header.head.fileCommentLength, m_fp);
598 		header.fileComment[header.head.fileCommentLength] = NULL;
599 	}
600 	*/
601 
602 	return TRUE;
603 }
604 
ReadEndofCentralDirectoryRecord()605 BOOL CUnAlz::ReadEndofCentralDirectoryRecord()
606 {
607 	/*
608 	SEndOfCentralDirectoryRecord	header;
609 
610 	if(FRead(&header, sizeof(header.head), 1, m_fp)!=1)
611 	{
612 		m_nErr = ERR_CANT_READ_HEADER;
613 		return FALSE;
614 	}
615 
616 	if(header.head.zipFileCommentLength)
617 	{
618 		header.fileComment = (char*)malloc(header.head.zipFileCommentLength+1);
619 		if(header.fileComment==NULL)
620 		{
621 			m_nErr = ERR_INVALID_FILECOMMENT_SIZE;
622 			return FALSE;
623 		}
624 		FRead(header.fileComment, 1, header.head.zipFileCommentLength, m_fp);
625 		header.fileComment[header.head.zipFileCommentLength] = NULL;
626 	}
627 	*/
628 
629 	return TRUE;
630 }
631 
SetCurrentFile(const char * szFileName)632 BOOL CUnAlz::SetCurrentFile(const char* szFileName)
633 {
634 	FileList::iterator	i;
635 
636 	//
637 	for(i=m_fileList.begin(); i<m_fileList.end(); i++)
638 	{
639 #ifdef _WIN32
640 		if(stricmp(i->fileName, szFileName)==0)
641 #else
642 		if(strcmp(i->fileName, szFileName)==0)
643 #endif
644 		{
645 			m_posCur = i;
646 			return TRUE;
647 		}
648 	}
649 
650 	m_posCur = m_fileList.end();//(FileList::iterator)NULL;
651 
652 	return FALSE;
653 }
654 
SetCurrentFile(FileList::iterator newPos)655 void CUnAlz::SetCurrentFile(FileList::iterator newPos)
656 {
657 	m_posCur = newPos;
658 }
659 
660 #ifndef MAX_WBITS
661 #  define MAX_WBITS   15 /* 32K LZ77 window */
662 #endif
663 
664 ////////////////////////////////////////////////////////////////////////////////////////////////////
665 // @param   pDestBuf
666 // @return
667 // @date    2004-03-07 12:26:13
668 ////////////////////////////////////////////////////////////////////////////////////////////////////
ExtractCurrentFileToBuf(BYTE * pDestBuf,int nBufSize)669 BOOL CUnAlz::ExtractCurrentFileToBuf(BYTE* pDestBuf, int nBufSize)
670 {
671 	SExtractDest	dest;
672 	dest.nType = ET_MEM;
673 	dest.buf = pDestBuf;
674 	dest.bufpos = 0;
675 	dest.bufsize = nBufSize;
676 	return ExtractTo(&dest);
677 }
678 
679 ////////////////////////////////////////////////////////////////////////////////////////////////////
680 //			(SetCurrentFile)
681 // @param   szDestPathName  -
682 // @param   szDestFileName  -
683 // @return
684 // @date    2004-03-06 11:06:59
685 ////////////////////////////////////////////////////////////////////////////////////////////////////
ExtractCurrentFile(const char * szDestPathName,const char * szDestFileName)686 BOOL CUnAlz::ExtractCurrentFile(const char* szDestPathName, const char* szDestFileName)
687 {
688 	if(m_posCur==m_fileList.end()/*(FileList::iterator)NULL*/) {ASSERT(0); return FALSE;}
689 	BOOL	ret=FALSE;
690 
691 	SExtractDest	dest;
692 	char			szDestPathFileName[MAX_PATH];
693 
694 	if(chkValidPassword() == FALSE)
695 	{
696 		return FALSE;
697 	}
698 
699 	if( szDestPathName==NULL||
700 		strlen(szDestPathName) + (szDestFileName?strlen(szDestFileName):strlen(m_posCur->fileName))+1 > MAX_PATH
701 	   )	// check buffer overflow
702 	{
703 		ASSERT(0);
704 		m_nErr = ERR_GENERAL;
705 		return FALSE;
706 	}
707 
708 	//
709 	safe_strcpy(szDestPathFileName, szDestPathName, MAX_PATH);
710 	if(szDestPathFileName[strlen(szDestPathFileName)]!=PATHSEPC)
711 		safe_strcat(szDestPathFileName, PATHSEP, MAX_PATH);
712 
713 	//
714 	if(szDestFileName) safe_strcat(szDestPathFileName, szDestFileName, MAX_PATH);
715 	else safe_strcat(szDestPathFileName, m_posCur->fileName, MAX_PATH);
716 
717 	// ../../
718 	if( strstr(szDestPathFileName, "../")||
719 		strstr(szDestPathFileName, "..\\"))
720 	{
721 		ASSERT(0);
722 		m_nErr = ERR_GENERAL;
723 		return FALSE;
724 	}
725 
726 #ifndef _WIN32
727 	{
728 		char* p = szDestPathFileName;			// delimiter
729 		while(*p)
730 		{
731 			if(*p=='\\') *p='/';
732 			p++;
733 		}
734 	}
735 #endif
736 
737 	//
738 	dest.nType = ET_FILE;
739 
740 	if(m_bPipeMode)
741 		dest.fp = stdout;				// pipe mode stdout
742 	else
743 		dest.fp = fopen(szDestPathFileName, "wb");
744 
745 	//
746 	if(m_bPipeMode==FALSE && (m_posCur->head.fileAttribute) & ALZ_FILEATTR_DIRECTORY )
747 	{
748 //printf("digpath:%s\n", szDestPathFileName);
749 		//
750 		DigPath(szDestPathFileName);
751 		return TRUE;
752 //		m_nErr = ERR_CANT_CREATE_DEST_PATH;
753 //		return FALSE;
754 	}
755 
756 	//
757 	if(dest.fp==NULL)
758 	{
759 		DigPath(szDestPathFileName);
760 		dest.fp = fopen(szDestPathFileName, "wb");
761 	}
762 
763 	//
764 	if(dest.fp==NULL)
765 	{
766 		//
767 		m_nErr = ERR_CANT_OPEN_DEST_FILE;
768 //printf("dest pathfilename:%s\n",szDestPathFileName);
769 		if(m_pFuncCallBack)
770 		{
771 			CHAR buf[1024];
772 //			sprintf(buf, : %s", szDestPathFileName);
773 //			m_pFuncCallBack(buf, 0,0,m_pCallbackParam, NULL);
774 		}
775 		return FALSE;
776 	}
777 //#endif
778 
779 	// CALLBACK
780 	if(m_pFuncCallBack) m_pFuncCallBack(m_posCur->fileName, 0,m_posCur->uncompressedSize,m_pCallbackParam, NULL);
781 
782 	ret = ExtractTo(&dest);
783 	if(dest.fp!=NULL)
784 	{
785 		fclose(dest.fp);
786 		// file time setting - from unalz_wcx_01i.zip
787 		utimbuf tmp;
788 		tmp.actime = 0;													//
789 		tmp.modtime = dosTime2TimeT(m_posCur->head.fileTimeDate);		//
790 		utime(m_posCur->fileName, &tmp);
791 	}
792 	return ret;
793 }
794 
795 ////////////////////////////////////////////////////////////////////////////////////////////////////
796 // @param   dest
797 // @return
798 // @date    2004-03-07 12:44:36
799 ////////////////////////////////////////////////////////////////////////////////////////////////////
ExtractTo(SExtractDest * dest)800 BOOL CUnAlz::ExtractTo(SExtractDest* dest)
801 {
802 	BOOL ret = FALSE;
803 	//
804 	if(m_posCur->compressionMethod==COMP_NOCOMP)
805 	{
806 		ret = ExtractRawfile(dest, *m_posCur);
807 	}
808 	else if(m_posCur->compressionMethod==COMP_BZIP2)
809 	{
810 		ret = ExtractBzip2(dest, *m_posCur);			// bzip2
811 	}
812 	else if(m_posCur->compressionMethod==COMP_DEFLATE)
813 	{
814 		ret = ExtractDeflate2(dest, *m_posCur);			// deflate
815 	}
816 	else	// COMP_UNKNOWN
817 	{
818 		// alzip 5.6 5.51
819 		//
820 		//
821 		m_nErr = ERR_UNKNOWN_COMPRESSION_METHOD;
822 		ASSERT(0);
823 		ret = FALSE;
824 	}
825 	return ret;
826 }
827 
828 ////////////////////////////////////////////////////////////////////////////////////////////////////
829 //          DEFLATE
830 // @param   fp  -
831 // @param   file  -
832 // @return
833 // @date    2004-03-06 11:09:17
834 ////////////////////////////////////////////////////////////////////////////////////////////////////
835 /*
836 BOOL CUnAlz::ExtractDeflate(FILE* fp, SAlzLocalFileHeader& file)
837 {
838 	z_stream	stream;
839 	BYTE*		pInBuf=NULL;
840 	BYTE*		pOutBuf=NULL;
841 	int			nInBufSize = file.compressedSize;
842 	int			nOutBufSize = file.uncompressedSize;
843 	int			err;
844 	int			flush=Z_SYNC_FLUSH;
845 	BOOL		ret = FALSE;
846 
847 	memset(&stream, 0, sizeof(stream));
848 
849 	pInBuf = (BYTE*)malloc(nInBufSize);
850 	if(pInBuf==NULL)
851 	{
852 		m_nErr = ERR_MEM_ALLOC_FAILED;
853 		goto END;
854 	}
855 
856 	pOutBuf = (BYTE*)malloc(nOutBufSize);
857 	if(pOutBuf==NULL)
858 	{
859 		m_nErr = ERR_MEM_ALLOC_FAILED;
860 		goto END;
861 	}
862 
863 	//
864 	fseek(m_fp, file.dwFileDataPos, SEEK_SET);
865 	if(FRead(pInBuf, nInBufSize, 1, m_fp)!=1)
866 	{
867 		m_nErr = ERR_FILE_READ_ERROR;
868 		goto END;
869 	}
870 
871 	//
872 	inflateInit2(&stream, -MAX_WBITS);
873 
874 	stream.next_out = pOutBuf;
875 	stream.avail_out = nOutBufSize;
876 	stream.next_in = pInBuf;
877 	stream.avail_in = nInBufSize;
878 
879 	err = inflate(&stream, flush);
880 
881 	if(err!=Z_OK && err!=Z_STREAM_END )
882 	{
883 		m_nErr = ERR_INFLATE_FAILED;
884 		goto END;
885 	}
886 
887 	fwrite(pOutBuf, 1, nOutBufSize, fp);
888 
889 	ret = TRUE;
890 
891 END :
892 	inflateEnd(&stream);
893 
894 	if(pInBuf) free(pInBuf);
895 	if(pOutBuf) free(pOutBuf);
896 	return ret;
897 }
898 */
899 
900 ////////////////////////////////////////////////////////////////////////////////////////////////////
901 // @param   szDestPathName  -
902 // @return
903 // @date    2004-03-06 11:09:49
904 ////////////////////////////////////////////////////////////////////////////////////////////////////
ExtractAll(const char * szDestPathName)905 BOOL CUnAlz::ExtractAll(const char* szDestPathName)
906 {
907 	FileList::iterator	i;
908 
909 	for(i=m_fileList.begin(); i<m_fileList.end(); i++)
910 	{
911 		m_posCur = i;
912 		if(ExtractCurrentFile(szDestPathName)==FALSE) return FALSE;
913 		if(m_bHalt)
914 			break;							//
915 	}
916 
917 	return TRUE;
918 }
919 
920 ////////////////////////////////////////////////////////////////////////////////////////////////////
921 //          (dig)
922 // @param   szPathName
923 // @return
924 // @date    2004-03-06 11:10:12
925 ////////////////////////////////////////////////////////////////////////////////////////////////////
DigPath(const char * szPathName)926 BOOL CUnAlz::DigPath(const char* szPathName)
927 {
928 	char*	dup = strdup(szPathName);
929 	char	seps[]   = "/\\";
930 	char*	token;
931 	char	path[MAX_PATH] = {0};
932 	char*	last;
933 
934 	//
935 	last = dup + strlen(dup);
936 	while(last!=dup)
937 	{
938 		if(*last=='/' || *last=='\\')
939 		{
940 			*last = (char)0;
941 			break;
942 		}
943 		last --;
944 	}
945 
946 
947 	token = strtok( dup, seps );
948 	while( token != NULL )
949 	{
950 		if(strlen(path)==0)
951 		{
952 			if(szPathName[0]=='/')			// is absolute path ?
953 				safe_strcpy(path,"/", MAX_PATH);
954 			else if(szPathName[0]=='\\' && szPathName[1]=='\\')	// network drive ?
955 				safe_strcpy(path,"\\\\", MAX_PATH);
956 			safe_strcat(path, token, MAX_PATH);
957 		}
958 		else
959 		{
960 			safe_strcat(path, PATHSEP,MAX_PATH);
961 			safe_strcat(path, token,MAX_PATH);
962 		}
963 
964 		if(IsFolder(path)==FALSE)
965 #ifdef _WIN32
966 			_mkdir(path);
967 #else
968 			mkdir(path,  S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
969 #endif
970 //printf("path:%s\n", path);
971 		token = strtok( NULL, seps );
972 	}
973 
974 	free(dup);
975 	if(IsFolder(szPathName)) return TRUE;
976 	return FALSE;
977 }
978 
979 ////////////////////////////////////////////////////////////////////////////////////////////////////
980 // @param   szPathName
981 // @return
982 // @date    2004-03-06 11:03:26
983 ////////////////////////////////////////////////////////////////////////////////////////////////////
IsFolder(const CHAR * szPathName)984 BOOL CUnAlz::IsFolder(const CHAR* szPathName)
985 {
986 #ifdef _WIN32
987 	UINT32 dwRet;
988 	dwRet = GetFileAttributesA(szPathName);
989 	if(dwRet==0xffffffff) return FALSE;
990 	if(dwRet & FILE_ATTRIBUTE_DIRECTORY) return TRUE;
991 	return FALSE;
992 #else
993 
994 	struct stat buf;
995 	int result;
996 
997 	result = stat(szPathName, &buf);
998 	if(result!=0) return FALSE;
999 //printf("isfolder:%s, %d,%d,%d\n", szPathName, buf.st_mode, S_IFDIR, buf.st_mode & S_IFDIR);
1000 	if(buf.st_mode & S_IFDIR) return TRUE;
1001 	return FALSE;
1002 #endif
1003 }
1004 
1005 ////////////////////////////////////////////////////////////////////////////////////////////////////
1006 // @param   dest  - OBJECT
1007 // @param   buf  -
1008 // @param   nSize  -
1009 // @return
1010 // @date    2004-03-07 12:37:41
1011 ////////////////////////////////////////////////////////////////////////////////////////////////////
WriteToDest(SExtractDest * dest,BYTE * buf,int nSize)1012 int	CUnAlz::WriteToDest(SExtractDest* dest, BYTE* buf, int nSize)
1013 {
1014 	if(dest->nType==ET_FILE)
1015 	{
1016 		return fwrite(buf,  1, nSize, dest->fp);
1017 	}
1018 	else if(dest->nType==ET_MEM)
1019 	{
1020 		if(dest->buf==NULL) return nSize;			// NULL
1021 		if(dest->bufpos+nSize >dest->bufsize)		//
1022 		{
1023 			ASSERT(0);
1024 			return -1;
1025 		}
1026 		// memcpy
1027 		memcpy(dest->buf + dest->bufpos, buf, nSize);
1028 		dest->bufpos += nSize;
1029 		return nSize;
1030 	}
1031 	else
1032 	{
1033 		ASSERT(0);
1034 	}
1035 	return -1;
1036 }
1037 
1038 /*
1039 #define ALZDLZ_HEADER_SIZE	4		// alz bzip2
1040 #define BZIP2_HEADER_SIZE	10		// bzip
1041 #define BZIP2_CRC_SIZE		4		// bzip2 crc
1042 #define BZIP2_TAIL_SIZE		10		// 4+5
1043 BYTE bzip2Header[BZIP2_HEADER_SIZE] = {0x42, 0x5a, 0x68, 0x39, 0x31, 0x41, 0x59, 0x26, 0x53, 0x59};
1044 
1045 BOOL CUnAlz::ExtractBzip2_bak(FILE* fp, SAlzLocalFileHeader& file)
1046 {
1047 	bz_stream	stream;
1048 	BYTE*		pInBuf=NULL;
1049 	BYTE*		pOutBuf=NULL;
1050 	int			nInBufSize = file.compressedSize;
1051 	int			nOutBufSize = file.uncompressedSize;
1052 	//int			err;
1053 	int			flush=Z_SYNC_FLUSH;
1054 	BOOL		ret = FALSE;
1055 	UINT32 crc = 0xffffffff;
1056 
1057 	//BYTE		temp[100];
1058 
1059 	memset(&stream, 0, sizeof(stream));
1060 
1061 	pInBuf = (BYTE*)malloc(nInBufSize + BZIP2_HEADER_SIZE + BZIP2_CRC_SIZE - ALZDLZ_HEADER_SIZE + BZIP2_TAIL_SIZE);
1062 	if(pInBuf==NULL)
1063 	{
1064 		m_nErr = ERR_MEM_ALLOC_FAILED;
1065 		goto END;
1066 	}
1067 
1068 	pOutBuf = (BYTE*)malloc(nOutBufSize);
1069 	if(pOutBuf==NULL)
1070 	{
1071 		m_nErr = ERR_MEM_ALLOC_FAILED;
1072 		goto END;
1073 	}
1074 
1075 	// ALZ BZIP ("DLZ.").
1076 	fseek(m_fp, ALZDLZ_HEADER_SIZE, SEEK_CUR);
1077 	// BZIP2
1078 	memcpy(pInBuf, bzip2Header, BZIP2_HEADER_SIZE);
1079 	// BZIP2 CRC
1080 	memcpy(pInBuf+BZIP2_HEADER_SIZE, &(crc), BZIP2_CRC_SIZE);
1081 
1082 	//
1083 	fseek(m_fp, file.dwFileDataPos+ALZDLZ_HEADER_SIZE, SEEK_SET);
1084 	if(FRead(pInBuf+BZIP2_HEADER_SIZE+BZIP2_CRC_SIZE, nInBufSize-ALZDLZ_HEADER_SIZE, 1, m_fp)!=1)
1085 	{
1086 		m_nErr = ERR_FILE_READ_ERROR;
1087 		goto END;
1088 	}
1089 
1090 	//
1091 	stream.bzalloc = NULL;
1092 	stream.bzfree = NULL;
1093 	stream.opaque = NULL;
1094 	ret = BZ2_bzDecompressInit ( &stream, 3,0 );
1095 	if (ret != BZ_OK) goto END;
1096 
1097 	//memcpy(temp, pInBuf, 100);
1098 
1099 	stream.next_in = (char*)pInBuf;
1100 	stream.next_out = (char*)pOutBuf;
1101 	stream.avail_in = nInBufSize+BZIP2_HEADER_SIZE+BZIP2_CRC_SIZE+BZIP2_TAIL_SIZE;
1102 	stream.avail_out = nOutBufSize;
1103 
1104 	ret = BZ2_bzDecompress ( &stream );
1105 
1106 	// BZ_DATA_ERROR
1107 	//if (ret == BZ_OK) goto END;
1108 	//if (ret != BZ_STREAM_END) goto END;
1109 
1110 	BZ2_bzDecompressEnd(&stream);
1111 
1112 	fwrite(pOutBuf, 1, nOutBufSize, fp);
1113 
1114 	ret = TRUE;
1115 
1116 END :
1117 
1118 	if(pInBuf) free(pInBuf);
1119 	if(pOutBuf) free(pOutBuf);
1120 
1121 	if(ret==FALSE) 	BZ2_bzDecompressEnd(&stream);
1122 
1123 	return ret;
1124 }
1125 */
1126 
1127 ////////////////////////////////////////////////////////////////////////////////////////////////////
1128 //          RAW
1129 // @param   fp  -
1130 // @param   file  -
1131 // @return
1132 // @date    2004-03-06 11:10:53
1133 ////////////////////////////////////////////////////////////////////////////////////////////////////
1134 #define BUF_LEN		(4096*2)
ExtractRawfile(SExtractDest * dest,SAlzLocalFileHeader & file)1135 BOOL CUnAlz::ExtractRawfile(SExtractDest* dest, SAlzLocalFileHeader& file)
1136 {
1137 	BOOL		ret = FALSE;
1138 	BYTE		buf[BUF_LEN];
1139 	INT64		read;
1140 	INT64		sizeToRead;
1141 	INT64		bufLen = BUF_LEN;
1142 	INT64		nWritten = 0;
1143 	BOOL		bHalt = FALSE;
1144 	BOOL		bIsEncrypted = 	IsEncryptedFile();		//
1145 	UINT32		dwCRC32= 0;
1146 
1147 	//
1148 	FSeek(file.dwFileDataPos);
1149 
1150 	sizeToRead = file.compressedSize;			//
1151 
1152 	m_nErr = ERR_NOERR;
1153 	while(sizeToRead)
1154 	{
1155 		read = min(sizeToRead, bufLen);
1156 		if(FRead(buf, (int)read)==FALSE)
1157 		{
1158 			break;
1159 		}
1160 
1161 		if(bIsEncrypted)
1162 			DecryptingData((int)read, buf); // xf86
1163 
1164 		dwCRC32 = crc32(dwCRC32, buf, (UINT)(read));
1165 
1166 		WriteToDest(dest, buf, (int)read);
1167 		//fwrite(buf, read, 1, fp);
1168 		sizeToRead -= read;
1169 
1170 		nWritten+=read;
1171 
1172 		// progress callback
1173 		if(m_pFuncCallBack)
1174 		{
1175 			m_pFuncCallBack(NULL, nWritten, file.uncompressedSize, m_pCallbackParam, &bHalt);
1176 			if(bHalt)
1177 			{
1178 				break;
1179 			}
1180 		}
1181 	}
1182 
1183 	m_bHalt = bHalt;
1184 
1185 	if(m_nErr==ERR_NOERR)			//
1186 	{
1187 		if(file.fileCRC==dwCRC32)
1188 		{
1189 			ret = TRUE;
1190 		}
1191 		else
1192 		{
1193 			m_nErr = ERR_INVALID_FILE_CRC;
1194 		}
1195 	}
1196 
1197 
1198 	return ret;
1199 }
1200 
1201 ////////////////////////////////////////////////////////////////////////////////////////////////////
1202 //          BZIP2
1203 // @param   fp_w  -
1204 // @param   file  -
1205 // @return
1206 // @date    2004-03-01 5:47:36
1207 ////////////////////////////////////////////////////////////////////////////////////////////////////
1208 #define BZIP2_EXTRACT_BUF_SIZE	0x2000
ExtractBzip2(SExtractDest * dest,SAlzLocalFileHeader & file)1209 BOOL CUnAlz::ExtractBzip2(SExtractDest* dest, SAlzLocalFileHeader& file)
1210 {
1211 	BZFILE		*bzfp = NULL;
1212 	int			smallMode = 0;
1213 	int			verbosity = 1;
1214 	int			bzerr;
1215 	INT64		len;
1216 	BYTE		buff[BZIP2_EXTRACT_BUF_SIZE];
1217 	INT64		nWritten = 0;
1218 	BOOL		bHalt = FALSE;
1219 	UINT32		dwCRC32= 0;
1220 	BOOL		ret = FALSE;
1221 
1222 	FSeek(file.dwFileDataPos);
1223 
1224 	bzfp = BZ2_bzReadOpen(&bzerr,this,verbosity,smallMode,0,0);
1225 
1226 	if(bzfp==NULL){ASSERT(0); return FALSE;}
1227 
1228 	m_nErr = ERR_NOERR;
1229 	while((len=BZ2_bzread(bzfp,buff,BZIP2_EXTRACT_BUF_SIZE))>0)
1230 	{
1231 		WriteToDest(dest, (BYTE*)buff, (int)len);
1232 		//fwrite(buff,1,len,fp_w);
1233 
1234 		dwCRC32 = crc32(dwCRC32,buff, (UINT)(len));
1235 
1236 
1237 		nWritten+=len;
1238 
1239 		// progress callback
1240 		if(m_pFuncCallBack)
1241 		{
1242 			m_pFuncCallBack(NULL, nWritten, file.uncompressedSize, m_pCallbackParam, &bHalt);
1243 			if(bHalt)
1244 			{
1245 				break;
1246 			}
1247 		}
1248 	}
1249 
1250 	if(len<0)			//
1251 	{
1252 		m_nErr = ERR_INFLATE_FAILED;
1253 	}
1254 
1255 	BZ2_bzReadClose( &bzerr, bzfp);
1256 
1257 	m_bHalt = bHalt;
1258 
1259 	if(m_nErr==ERR_NOERR)			//
1260 	{
1261 		if(file.fileCRC==dwCRC32)
1262 		{
1263 			ret = TRUE;
1264 		}
1265 		else
1266 		{
1267 			m_nErr = ERR_INVALID_FILE_CRC;
1268 		}
1269 	}
1270 
1271 	/*
1272 	// FILE*
1273 	BZFILE	*bzfp = NULL;
1274 	int		smallMode = 0;
1275 	int		verbosity = 1;
1276 	int		bzerr;
1277 	int		len;
1278 	char	buff[BZIP2_EXTRACT_BUF_SIZE];
1279 	INT64	nWritten = 0;
1280 	BOOL	bHalt = FALSE;
1281 
1282 	FSeek(file.dwFileDataPos, SEEK_SET);
1283 
1284 	bzfp = BZ2_bzReadOpen(&bzerr,m_fp,verbosity,smallMode,0,0);
1285 
1286 	while((len=BZ2_bzread(bzfp,buff,BZIP2_EXTRACT_BUF_SIZE))>0)
1287 	{
1288 		WriteToDest(dest, (BYTE*)buff, len);
1289 		//fwrite(buff,1,len,fp_w);
1290 
1291 		nWritten+=len;
1292 
1293 		// progress callback
1294 		if(m_pFuncCallBack)
1295 		{
1296 			m_pFuncCallBack(NULL, nWritten, file.uncompressedSize, m_pCallbackParam, &bHalt);
1297 			if(bHalt)
1298 			{
1299 				break;
1300 			}
1301 		}
1302 	}
1303 
1304 	BZ2_bzReadClose( &bzerr, bzfp);
1305 
1306 	m_bHalt = bHalt;
1307 	*/
1308 
1309 	return ret;
1310 }
1311 
1312 
1313 #ifndef UNZ_BUFSIZE
1314 #define UNZ_BUFSIZE		0x1000 // (16384)
1315 #endif
1316 
1317 #define IN_BUF_SIZE		UNZ_BUFSIZE
1318 #define OUT_BUF_SIZE	0x1000 //IN_BUF_SIZE
1319 
1320 ////////////////////////////////////////////////////////////////////////////////////////////////////
1321 //          deflate ExtractDeflate()
1322 // @param   fp
1323 // @param   file
1324 // @return
1325 // @date    2004-03-06 11:11:36
1326 ////////////////////////////////////////////////////////////////////////////////////////////////////
ExtractDeflate2(SExtractDest * dest,SAlzLocalFileHeader & file)1327 BOOL CUnAlz::ExtractDeflate2(SExtractDest* dest, SAlzLocalFileHeader& file)
1328 {
1329 	z_stream	stream;
1330 	BYTE		pInBuf[IN_BUF_SIZE];
1331 	BYTE		pOutBuf[OUT_BUF_SIZE];
1332 	int			nInBufSize = IN_BUF_SIZE;
1333 	int			nOutBufSize = OUT_BUF_SIZE;
1334 	int			err;
1335 	int			flush=Z_SYNC_FLUSH;
1336 	BOOL		ret = FALSE;
1337 	INT64		nRestReadCompressed;
1338 	UINT32		dwCRC32= 0;
1339 	INT64		rest_read_uncompressed;
1340 	UINT		iRead = 0;
1341 	INT64	nWritten = 0;
1342 	BOOL	bHalt = FALSE;
1343 	BOOL	bIsEncrypted = 	IsEncryptedFile();		//
1344 
1345 	memset(&stream, 0, sizeof(stream));
1346 
1347 	FSeek(file.dwFileDataPos);
1348 
1349 	inflateInit2(&stream, -MAX_WBITS);
1350 	nRestReadCompressed = file.compressedSize;
1351 	rest_read_uncompressed = file.uncompressedSize;
1352 
1353 	//
1354 	stream.next_out = pOutBuf;
1355 	stream.avail_out = OUT_BUF_SIZE;
1356 
1357 	m_nErr = ERR_NOERR;
1358 	while(stream.avail_out>0)
1359 	{
1360 		if(stream.avail_in==0 && nRestReadCompressed>0)
1361 		{
1362 			UINT uReadThis = UNZ_BUFSIZE;
1363 			if (nRestReadCompressed<(int)uReadThis)
1364 				uReadThis = (UINT)nRestReadCompressed;		//
1365 
1366 			if (uReadThis == 0)
1367 				break;					//
1368 
1369 			if(FRead(pInBuf, uReadThis)==FALSE)
1370 			{
1371 				m_nErr = ERR_CANT_READ_FILE;
1372 				goto END;
1373 			}
1374 
1375 			if(bIsEncrypted)
1376 				DecryptingData(uReadThis, pInBuf); // xf86
1377 
1378 //			dwCRC32 = crc32(dwCRC32,pInBuf, (UINT)(uReadThis));
1379 
1380 			nRestReadCompressed -= uReadThis;
1381 			stream.next_in = pInBuf;
1382 			stream.avail_in = uReadThis;
1383 		}
1384 
1385         UINT uTotalOutBefore,uTotalOutAfter;
1386         const BYTE *bufBefore;
1387         UINT uOutThis;
1388         int flush=Z_SYNC_FLUSH;
1389 
1390         uTotalOutBefore = stream.total_out;
1391         bufBefore = stream.next_out;
1392 
1393         err=inflate(&stream,flush);
1394 
1395         uTotalOutAfter = stream.total_out;
1396         uOutThis = uTotalOutAfter-uTotalOutBefore;
1397 
1398         dwCRC32 = crc32(dwCRC32,bufBefore, (UINT)(uOutThis));
1399 
1400         rest_read_uncompressed -= uOutThis;
1401 
1402         iRead += (UINT)(uTotalOutAfter - uTotalOutBefore);
1403 
1404 		WriteToDest(dest, pOutBuf, uOutThis);
1405 		//fwrite(pOutBuf, uOutThis, 1, fp);		// file
1406 		stream.next_out = pOutBuf;
1407 		stream.avail_out = OUT_BUF_SIZE;
1408 
1409 		nWritten+=uOutThis;
1410 
1411 		// progress callback
1412 		if(m_pFuncCallBack)
1413 		{
1414 			m_pFuncCallBack(NULL, nWritten, file.uncompressedSize, m_pCallbackParam, &bHalt);
1415 			if(bHalt)
1416 			{
1417 				m_nErr = ERR_USER_ABORTED;
1418 				break;
1419 			}
1420 		}
1421 
1422         if (err==Z_STREAM_END)
1423 			break;
1424 			//if(iRead==0) break; // UNZ_EOF;
1425         if (err!=Z_OK)
1426 		{
1427 			m_nErr = ERR_INFLATE_FAILED;
1428             goto END;
1429 		}
1430 	}
1431 	m_bHalt = bHalt;
1432 
1433 
1434 	if(m_nErr==ERR_NOERR)			//
1435 	{
1436 		if(file.fileCRC==dwCRC32)
1437 		{
1438 			ret = TRUE;
1439 		}
1440 		else
1441 		{
1442 			m_nErr = ERR_INVALID_FILE_CRC;
1443 		}
1444 	}
1445 
1446 
1447 END :
1448 	inflateEnd(&stream);
1449 
1450 	return ret;
1451 }
1452 
1453 ////////////////////////////////////////////////////////////////////////////////////////////////////
1454 // @param   szPathName
1455 // @return
1456 // @date    2004-10-02 11:47:14
1457 ////////////////////////////////////////////////////////////////////////////////////////////////////
FOpen(const char * szPathName)1458 BOOL CUnAlz::FOpen(const char* szPathName)
1459 {
1460 	char* temp = strdup(szPathName);			//
1461 	int	  i;
1462 	int	  nLen = strlen(szPathName);
1463 	UINT64 nFileSizeLow;
1464 	UINT32 dwFileSizeHigh;
1465 	m_nFileCount = 0;
1466 	m_nCurFile = 0;
1467 	m_nVirtualFilePos = 0;
1468 	m_nCurFilePos = 0;
1469 	m_bIsEOF = FALSE;
1470 	for(i=0;i<MAX_FILES;i++)						//
1471 	{
1472 		if(i>0)
1473 			safe_sprintf(temp+nLen-3, 4, "%c%02d", (i-1)/100+'a', (i-1)%100);
1474 
1475 #ifdef _WIN32
1476 		m_files[i].fp = CreateFileA(temp, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
1477 		if(m_files[i].fp==INVALID_HANDLE_VALUE) break;
1478 		nFileSizeLow = GetFileSize(m_files[i].fp, (DWORD*)&dwFileSizeHigh);
1479 #else
1480 		m_files[i].fp = fopen(temp, "rb");
1481 		if(m_files[i].fp==NULL) break;
1482 		dwFileSizeHigh=0;
1483 		unalz_fseek(m_files[i].fp,0,SEEK_END);
1484 		nFileSizeLow=unalz_ftell(m_files[i].fp);
1485 		unalz_fseek(m_files[i].fp,0,SEEK_SET);
1486 #endif
1487 		m_nFileCount++;
1488 		m_files[i].nFileSize = ((INT64)nFileSizeLow) + (((INT64)dwFileSizeHigh)<<32);
1489 		if(i==0) m_files[i].nMultivolHeaderSize = 0;
1490 		else m_files[i].nMultivolHeaderSize = MULTIVOL_HEAD_SIZE;
1491 		m_files[i].nMultivolTailSize = MULTIVOL_TAIL_SIZE;
1492 	}
1493 	free(temp);
1494 	if(m_nFileCount==0) return FALSE;
1495 	m_files[m_nFileCount-1].nMultivolTailSize = 0;			//
1496 	return TRUE;
1497 }
1498 
1499 ////////////////////////////////////////////////////////////////////////////////////////////////////
1500 // @return
1501 // @date    2004-10-02 11:48:53
1502 ////////////////////////////////////////////////////////////////////////////////////////////////////
FClose()1503 void CUnAlz::FClose()
1504 {
1505 	int i;
1506 #ifdef _WIN32
1507 	for(i=0;i<m_nFileCount;i++) CloseHandle(m_files[i].fp);
1508 #else
1509 	for(i=0;i<m_nFileCount;i++) fclose(m_files[i].fp);
1510 #endif
1511 	memset(m_files, 0, sizeof(m_files));
1512 	m_nFileCount = 0;
1513 	m_nCurFile = -1;
1514 	m_nVirtualFilePos = 0;
1515 	m_nCurFilePos = 0;
1516 	m_bIsEOF = FALSE;
1517 
1518 }
1519 
1520 ////////////////////////////////////////////////////////////////////////////////////////////////////
1521 // @return
1522 // @date    2004-10-02 11:48:21
1523 ////////////////////////////////////////////////////////////////////////////////////////////////////
FEof()1524 BOOL CUnAlz::FEof()
1525 {
1526 	return m_bIsEOF;
1527 	/*
1528 	if(m_fp==NULL){ASSERT(0); return TRUE;}
1529 	if(feof(m_fp)) return TRUE;
1530 	return FALSE;
1531 	*/
1532 }
1533 
1534 
1535 ////////////////////////////////////////////////////////////////////////////////////////////////////
1536 // @return
1537 // @date    2004-10-02 11:50:50
1538 ////////////////////////////////////////////////////////////////////////////////////////////////////
FTell()1539 INT64 CUnAlz::FTell()
1540 {
1541 	return m_nVirtualFilePos;	//	return ftell(m_fp);
1542 }
1543 
1544 ////////////////////////////////////////////////////////////////////////////////////////////////////
1545 // @param   offset
1546 // @param   origin
1547 // @return
1548 // @date    2004-10-02 11:51:53
1549 ////////////////////////////////////////////////////////////////////////////////////////////////////
FSeek(INT64 offset)1550 BOOL CUnAlz::FSeek(INT64 offset)
1551 {
1552 	m_nVirtualFilePos = offset;
1553 	int		i;
1554 	INT64	remain=offset;
1555 	LONG	remainHigh;
1556 
1557 	m_bIsEOF = FALSE;
1558 
1559 	for(i=0;i<m_nFileCount;i++)			//
1560 	{
1561 		if(remain<=m_files[i].nFileSize-m_files[i].nMultivolHeaderSize-m_files[i].nMultivolTailSize)
1562 		{
1563 			m_nCurFile = i;
1564 			m_nCurFilePos = remain+m_files[i].nMultivolHeaderSize;			//
1565 			remainHigh = (LONG)((m_nCurFilePos>>32)&0xffffffff);
1566 #ifdef _WIN32
1567 			SetFilePointer(m_files[i].fp, LONG(m_nCurFilePos), &remainHigh, FILE_BEGIN);
1568 #else
1569 			unalz_fseek(m_files[i].fp, m_nCurFilePos, SEEK_SET);
1570 #endif
1571 			return TRUE;
1572 		}
1573 		remain -= (m_files[i].nFileSize-m_files[i].nMultivolHeaderSize-m_files[i].nMultivolTailSize);
1574 	}
1575 
1576 	//
1577 	ASSERT(0);
1578 	return FALSE;
1579 }
1580 
1581 ////////////////////////////////////////////////////////////////////////////////////////////////////
1582 // @param   buffer
1583 // @param   size
1584 // @param   count
1585 // @return
1586 // @date    2004-10-02 11:44:05
1587 ////////////////////////////////////////////////////////////////////////////////////////////////////
FRead(void * buffer,UINT32 nBytesToRead,int * pTotRead)1588 BOOL CUnAlz::FRead(void* buffer, UINT32 nBytesToRead, int* pTotRead )
1589 {
1590 	BOOL ret;
1591 	UINT32 nNumOfBytesRead;
1592 	INT64 dwRemain;
1593 	UINT32 dwRead;
1594 	UINT32 dwTotRead;
1595 
1596 	dwRemain = nBytesToRead;
1597 	dwTotRead = 0;
1598 	if(pTotRead) *pTotRead=0;
1599 
1600 	while(dwRemain)
1601 	{
1602 		dwRead = (UINT32)min(dwRemain, (m_files[m_nCurFile].nFileSize-m_nCurFilePos-m_files[m_nCurFile].nMultivolTailSize));
1603 		if(dwRead==0) {
1604 			m_bIsEOF = TRUE;return FALSE;
1605 		}
1606 #ifdef _WIN32
1607 		ret = ReadFile(m_files[m_nCurFile].fp, ((BYTE*)buffer)+dwTotRead, dwRead, (DWORD*)&nNumOfBytesRead, NULL);
1608 		if(ret==FALSE && GetLastError()==ERROR_HANDLE_EOF)
1609 		{
1610 			m_bIsEOF = TRUE;return FALSE;
1611 		}
1612 
1613 #else
1614 		nNumOfBytesRead = fread(((BYTE*)buffer)+dwTotRead, 1,dwRead ,m_files[m_nCurFile].fp);
1615 		if(nNumOfBytesRead<=0)
1616 		{
1617 			m_bIsEOF = TRUE;return FALSE;
1618 		}
1619 		ret=TRUE;
1620 #endif
1621 		if(dwRead!=nNumOfBytesRead)					//
1622 		{
1623 			ASSERT(0); return FALSE;
1624 		}
1625 
1626 		m_nVirtualFilePos += nNumOfBytesRead;	// virtual
1627 
1628 		m_nCurFilePos+=nNumOfBytesRead;					//
1629 		dwRemain-=nNumOfBytesRead;
1630 		dwTotRead+=nNumOfBytesRead;
1631 		if(pTotRead) *pTotRead=dwTotRead;
1632 
1633 		if(m_nCurFilePos==m_files[m_nCurFile].nFileSize-m_files[m_nCurFile].nMultivolTailSize)	// overflow
1634 		{
1635 			m_nCurFile++;
1636 
1637 #ifdef _WIN32
1638 			if(m_files[m_nCurFile].fp==INVALID_HANDLE_VALUE)
1639 #else
1640 			if(m_files[m_nCurFile].fp==NULL)
1641 #endif
1642 			{
1643 				m_bIsEOF = TRUE;
1644 				if(dwRemain==0) return TRUE;						//
1645 				return FALSE;
1646 			}
1647 
1648 			m_nCurFilePos = m_files[m_nCurFile].nMultivolHeaderSize;					// header skip
1649 #ifdef _WIN32
1650 			SetFilePointer(m_files[m_nCurFile].fp, (int)m_nCurFilePos, NULL, FILE_BEGIN);
1651 #else
1652 			unalz_fseek(m_files[m_nCurFile].fp, m_nCurFilePos, SEEK_SET);
1653 #endif
1654 		}
1655 		else
1656 			if(m_nCurFilePos>m_files[m_nCurFile].nFileSize-m_files[m_nCurFile].nMultivolTailSize) ASSERT(0);
1657 	}
1658 
1659 	return ret;
1660 }
1661 
1662 ////////////////////////////////////////////////////////////////////////////////////////////////////
1663 //          error code
1664 // @param   nERR
1665 // @return
1666 // @date    2004-10-24 3:28:39
1667 ////////////////////////////////////////////////////////////////////////////////////////////////////
LastErrToStr(ERR nERR)1668 const char* CUnAlz::LastErrToStr(ERR nERR)
1669 {
1670 	if(nERR>= sizeof(errorstrtable)/sizeof(errorstrtable[0])) {ASSERT(0); return NULL; }
1671 	return errorstrtable[nERR];
1672 }
1673 
1674 
1675 // by xf86
chkValidPassword()1676 BOOL	CUnAlz::chkValidPassword()
1677 {
1678 	if(IsEncryptedFile()==FALSE) {return TRUE;}
1679 
1680 	if (getPasswordLen() == 0){
1681 		m_nErr = ERR_PASSWD_NOT_SET;
1682 		return FALSE;
1683 	}
1684 	InitCryptKeys(m_szPasswd);
1685 	if(CryptCheck(m_posCur->encChk) == FALSE){
1686 		m_nErr = ERR_INVALID_PASSWD;
1687 		return FALSE;
1688 	}
1689 	return TRUE;
1690 }
1691 
1692 /*
1693 ////////////////////////////////////////////////////////////////////////////////////////////////////
1694 //	from CZipArchive
1695 //	Copyright (C) 2000 - 2004 Tadeusz Dracz
1696 //
1697 //		http://www.artpol-software.com
1698 //
1699 //	it's under GPL.
1700 ////////////////////////////////////////////////////////////////////////////////////////////////////
1701 void CUnAlz::CryptDecodeBuffer(UINT32 uCount, CHAR *buf)
1702 {
1703 	if (IsEncrypted())
1704 		for (UINT32 i = 0; i < uCount; i++)
1705 			CryptDecode(buf[i]);
1706 }
1707 
1708 void CUnAlz::CryptInitKeys()
1709 {
1710 	m_keys[0] = 305419896L;
1711 	m_keys[1] = 591751049L;
1712 	m_keys[2] = 878082192L;
1713 	for (int i = 0; i < strlen(m_szPasswd); i++)
1714 		CryptUpdateKeys(m_szPasswd[i]);
1715 }
1716 
1717 void CUnAlz::CryptUpdateKeys(CHAR c)
1718 {
1719 
1720 	m_keys[0] = CryptCRC32(m_keys[0], c);
1721 	m_keys[1] += m_keys[0] & 0xff;
1722 	m_keys[1] = m_keys[1] * 134775813L + 1;
1723 	c = CHAR(m_keys[1] >> 24);
1724 	m_keys[2] = CryptCRC32(m_keys[2], c);
1725 }
1726 
1727 BOOL CUnAlz::CryptCheck(CHAR *buf)
1728 {
1729 	CHAR b = 0;
1730 	for (int i = 0; i < ALZ_ENCR_HEADER_LEN; i++)
1731 	{
1732 		b = buf[i];
1733 		CryptDecode((CHAR&)b);
1734 	}
1735 
1736 	if (IsDataDescr()) // Data descriptor present
1737 		return CHAR(m_posCur->head.fileTimeDate >> 8) == b;
1738 	else
1739 		return CHAR(m_posCur->maybeCRC >> 24) == b;
1740 }
1741 
1742 CHAR CUnAlz::CryptDecryptCHAR()
1743 {
1744 	int temp = (m_keys[2] & 0xffff) | 2;
1745 	return (CHAR)(((temp * (temp ^ 1)) >> 8) & 0xff);
1746 }
1747 
1748 void CUnAlz::CryptDecode(CHAR &c)
1749 {
1750 	c ^= CryptDecryptCHAR();
1751 	CryptUpdateKeys(c);
1752 }
1753 
1754 UINT32 CUnAlz::CryptCRC32(UINT32 l, CHAR c)
1755 {
1756 	const ULONG *CRC_TABLE = get_crc_table();
1757 	return CRC_TABLE[(l ^ c) & 0xff] ^ (l >> 8);
1758 }
1759 */
1760 
1761 ////////////////////////////////////////////////////////////////////////////////////////////////////
1762 // @param   fileDescriptor
1763 // @return
1764 // @date    2004-11-27 11:25:32
1765 ////////////////////////////////////////////////////////////////////////////////////////////////////
IsEncryptedFile(BYTE fileDescriptor)1766 BOOL CUnAlz::IsEncryptedFile(BYTE fileDescriptor)
1767 {
1768 	return fileDescriptor&0x01;
1769 }
IsEncryptedFile()1770 BOOL CUnAlz::IsEncryptedFile()
1771 {
1772 	return m_posCur->head.fileDescriptor&0x01;
1773 }
1774 
1775 ////////////////////////////////////////////////////////////////////////////////////////////////////
1776 // @param   szPassword
1777 // @return
1778 // @date    2004-11-27 11:04:01
1779 ////////////////////////////////////////////////////////////////////////////////////////////////////
InitCryptKeys(const CHAR * szPassword)1780 void CUnAlz::InitCryptKeys(const CHAR* szPassword)
1781 {
1782 	m_key[0] = 305419896;
1783 	m_key[1] = 591751049;
1784 	m_key[2] = 878082192;
1785 
1786 	int i;
1787 	for(i=0;i<(int)strlen(szPassword);i++)
1788 	{
1789 		UpdateKeys(szPassword[i]);
1790 	}
1791 }
1792 
1793 ////////////////////////////////////////////////////////////////////////////////////////////////////
1794 // @param   c
1795 // @return
1796 // @date    2004-11-27 11:04:09
1797 ////////////////////////////////////////////////////////////////////////////////////////////////////
UpdateKeys(BYTE c)1798 void CUnAlz::UpdateKeys(BYTE c)
1799 {
1800 	m_key[0] = CRC32(m_key[0], c);
1801 	m_key[1] = m_key[1]+(m_key[0]&0x000000ff);
1802 	m_key[1] = m_key[1]*134775813+1;
1803 	m_key[2] = CRC32(m_key[2],m_key[1]>>24);
1804 }
1805 
1806 ////////////////////////////////////////////////////////////////////////////////////////////////////
1807 // @param   buf
1808 // @return
1809 // @date    2004-11-27 11:04:24
1810 ////////////////////////////////////////////////////////////////////////////////////////////////////
CryptCheck(const BYTE * buf)1811 BOOL CUnAlz::CryptCheck(const BYTE* buf)
1812 {
1813 	int i;
1814 	BYTE c;
1815 	BYTE temp[ALZ_ENCR_HEADER_LEN];
1816 
1817 	memcpy(temp, buf, ALZ_ENCR_HEADER_LEN);		//
1818 
1819 	for(i=0;i<ALZ_ENCR_HEADER_LEN;i++)
1820 	{
1821 		c = temp[i] ^ DecryptByte();
1822 		UpdateKeys(c);
1823 		temp[i] = c;
1824 	}
1825 
1826 	if (IsDataDescr()) // Data descriptor present
1827 		return (m_posCur->head.fileTimeDate >> 8) == c;
1828 	else
1829 		return ( ((m_posCur->fileCRC)>>24) ) == c;		// crc byte
1830 }
1831 
1832 ////////////////////////////////////////////////////////////////////////////////////////////////////
1833 // @return
1834 // @date    2004-11-27 11:05:36
1835 ////////////////////////////////////////////////////////////////////////////////////////////////////
DecryptByte()1836 BYTE CUnAlz::DecryptByte()
1837 {
1838 	UINT16 temp;
1839 	temp = m_key[2] | 2;
1840 	return (temp * (temp^1))>>8;
1841 }
1842 
1843 ////////////////////////////////////////////////////////////////////////////////////////////////////
1844 // @param   nSize
1845 // @param   data
1846 // @return
1847 // @date    2004-11-27 11:03:30
1848 ////////////////////////////////////////////////////////////////////////////////////////////////////
DecryptingData(int nSize,BYTE * data)1849 void CUnAlz::DecryptingData(int nSize, BYTE* data)
1850 {
1851 	BYTE* p = data;
1852 	BYTE temp;
1853 
1854 	while(nSize)
1855 	{
1856 		temp = *p ^ DecryptByte();
1857 		UpdateKeys(temp);
1858 		*p = temp;
1859 		nSize--;
1860 		p++;
1861 	}
1862 }
1863 
1864 ////////////////////////////////////////////////////////////////////////////////////////////////////
1865 //          CRC
1866 // @param   l
1867 // @param   c
1868 // @return
1869 // @date    2004-11-27 11:14:16
1870 ////////////////////////////////////////////////////////////////////////////////////////////////////
CRC32(UINT32 l,BYTE c)1871 UINT32 CUnAlz::CRC32(UINT32 l, BYTE c)
1872 {
1873 #ifndef Z_U4
1874 	const unsigned long *CRC_TABLE = get_crc_table();
1875 #else
1876 	const Z_U4 *CRC_TABLE = get_crc_table();
1877 #endif
1878 	return CRC_TABLE[(l ^ c) & 0xff] ^ (l >> 8);
1879 }
1880 
SetPassword(char * passwd)1881 void CUnAlz::SetPassword(char *passwd)
1882 {
1883 	if(strlen(passwd) == 0) return;
1884 	safe_strcpy(m_szPasswd, passwd, UNALZ_LEN_PASSWORD);
1885 }
1886 
1887 #ifdef _UNALZ_ICONV
SetDestCodepage(const char * szToCodepage)1888 void CUnAlz::SetDestCodepage(const char* szToCodepage)
1889 {
1890 	safe_strcpy(m_szToCodepage, szToCodepage, UNALZ_LEN_CODEPAGE);
1891 }
1892 #endif
1893 
1894 ////////////////////////////////////////////////////////////////////////////////////////////////////
1895 // @param   l
1896 // @param   c
1897 // @return
1898 // @date    2007-02
1899 ////////////////////////////////////////////////////////////////////////////////////////////////////
_strlcpy(char * dest,const char * src,unsigned int size)1900 unsigned int CUnAlz::_strlcpy (char *dest, const char *src, unsigned int size)
1901 {
1902 	register unsigned int i = 0;
1903 	if (size > 0) {
1904 	size--;
1905 	for (i=0; size > 0 && src[i] != '\0'; ++i, size--)
1906 		dest[i] = src[i];
1907 	dest[i] = '\0';
1908 	}
1909 	while (src[i++]);
1910 	return i;
1911 }
_strlcat(char * dest,const char * src,unsigned int size)1912 unsigned int CUnAlz::_strlcat (char *dest, const char *src, unsigned int size)
1913 {
1914 	register char *d = dest;
1915 	for (; size > 0 && *d != '\0'; size--, d++);
1916 	return (d - dest) + _strlcpy(d, src, size);
1917 }
1918 
1919 // strcpy
safe_strcpy(char * dst,const char * src,size_t dst_size)1920 void CUnAlz::safe_strcpy(char* dst, const char* src, size_t dst_size)
1921 {
1922 #ifdef _WIN32
1923 	lstrcpynA(dst, src, dst_size);
1924 #else
1925 	_strlcpy(dst, src, dst_size);
1926 #endif
1927 }
1928 
safe_strcat(char * dst,const char * src,size_t dst_size)1929 void CUnAlz::safe_strcat(char* dst, const char* src, size_t dst_size)
1930 {
1931 #ifdef _WIN32
1932 	StringCchCatExA(dst, dst_size, src, NULL, NULL, STRSAFE_FILL_BEHIND_NULL);
1933 	//lstrcatA(dst, src);			// not safe!!
1934 #else
1935 	_strlcat(dst, src, dst_size);
1936 #endif
1937 }
1938