Subversion Repositories spk

Rev

Rev 285 | Rev 317 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 285 Rev 308
Line 779... Line 779...
779
	if ( !this->CompressData(compressionType, progress) )
779
	if ( !this->CompressData(compressionType, progress) )
780
		return false;
780
		return false;
781
	return true;
781
	return true;
782
}
782
}
783
 
783
 
784
unsigned char *C_File::CompressToData(int compressionType, unsigned long *outSize, CProgressInfo *progress, int level)
784
unsigned char* C_File::CompressToData(int compressionType, size_t* outSize, CProgressInfo* progress, int level)
785
{
785
{
-
 
786
	if (outSize) *outSize = 0;
786
	unsigned long comprLen = m_lDataSize;
787
	size_t initialLen = m_lDataSize;
787
	if ( comprLen < 100 )		comprLen = 200;
788
	if (initialLen < 100) initialLen = 200;
788
	else if ( comprLen < 1000 )	comprLen *= 2;
789
	else if (initialLen < 1000) initialLen *= 2;
789
	comprLen += 1000;
790
	initialLen += 1000;
790
 
-
 
791
	switch(compressionType)
-
 
792
	{
-
 
793
		case SPKCOMPRESS_ZLIB:
-
 
794
			{
-
 
795
				unsigned char *compr = (unsigned char *)calloc(comprLen, 1);
-
 
796
				int err = Z_NOTENOUGH_BUF;
-
 
797
				while ( err == Z_NOTENOUGH_BUF )
-
 
798
				{
-
 
799
					err = compress2 ( compr, &comprLen, (const unsigned char *)m_sData, m_lDataSize, (progress) ? progress->GetDonePointer() : 0, level );
-
 
800
					if ( err == Z_NOTENOUGH_BUF )
-
 
801
					{
-
 
802
						comprLen += (CHUNK * 2);
-
 
803
						compr = (unsigned char *)realloc(compr, comprLen);
-
 
804
					}
-
 
805
					else
-
 
806
						break;
-
 
807
				}	
-
 
808
 
791
 
809
				// if its compressed ok, remove old data and use new one
792
	switch (compressionType)
-
 
793
	{
810
				if ( err == Z_OK )
794
	case SPKCOMPRESS_ZLIB:
811
				{
795
	{
812
					unsigned char *retData = new unsigned char[comprLen];
796
		unsigned long comprLen = static_cast<unsigned long>(initialLen);
813
					(*outSize) = comprLen;
797
		unsigned char* compr = (unsigned char*)calloc(comprLen, 1);
814
					memcpy(retData, compr, comprLen);
798
		if (!compr) return NULL;
-
 
799
 
815
					free(compr);
800
		int err = Z_NOTENOUGH_BUF;
816
					return retData;
801
		while (err == Z_NOTENOUGH_BUF)
817
				}
802
		{
-
 
803
			err = compress2(compr, &comprLen, (const unsigned char*)m_sData, m_lDataSize,
-
 
804
				(progress) ? progress->GetDonePointer() : 0, level);
-
 
805
			if (err == Z_NOTENOUGH_BUF)
818
 
806
			{
-
 
807
				unsigned long newLen = comprLen + (CHUNK * 2);
-
 
808
				unsigned char* newCompr = (unsigned char*)realloc(compr, newLen);
-
 
809
				if (!newCompr) { free(compr); return NULL; }
819
				free(compr);
810
				compr = newCompr;
820
				return NULL;
811
				comprLen = newLen;
821
			}
812
			}
822
			break;
813
		}
823
 
814
 
824
		case SPKCOMPRESS_LZMA:
815
		if (err == Z_OK && comprLen > 0)
825
			{
816
		{
826
				unsigned char *compr = (unsigned char *)malloc(comprLen);
817
			unsigned char* retData = new (std::nothrow) unsigned char[comprLen];
-
 
818
			if (!retData) { free(compr); return NULL; }
-
 
819
			memcpy(retData, compr, comprLen);
827
				if (!compr) {
820
			free(compr);
-
 
821
			if (outSize) *outSize = static_cast<size_t>(comprLen);
-
 
822
			return retData;
-
 
823
		}
-
 
824
 
-
 
825
		free(compr);
828
					return NULL;
826
		return NULL;
829
				}
827
	}
-
 
828
	break;
-
 
829
 
-
 
830
	case SPKCOMPRESS_LZMA:
-
 
831
	{
-
 
832
		size_t comprLen = initialLen;
-
 
833
		unsigned char* compr = new (std::nothrow) unsigned char[comprLen];
-
 
834
		if (!compr) return NULL;
-
 
835
 
830
				SRes res = Lzma86_Encode((Byte *)compr, (size_t *)&comprLen, (const Byte *)m_sData, (size_t)m_lDataSize, level, LZMA_DICT, SZ_FILTER_NO, (progress) ? progress->GetDonePointer() : NULL);
836
		SRes res = Lzma86_Encode((Byte*)compr, (size_t*)&comprLen, (const Byte*)m_sData, (size_t)m_lDataSize,
-
 
837
			level, LZMA_DICT, SZ_FILTER_NO, (progress) ? progress->GetDonePointer() : NULL);
831
 
838
 
832
				if ( res == SZ_OK )
839
		if (res == SZ_OK && comprLen > 0)
833
				{
840
		{
834
					unsigned char *retData = new unsigned char[comprLen];
841
			unsigned char* retData = new (std::nothrow) unsigned char[comprLen];
835
					(*outSize) = comprLen;
842
			if (!retData) { delete[] compr; return NULL; }
836
					memcpy(retData, compr, comprLen);
843
			memcpy(retData, compr, comprLen);
837
					free(compr);
844
			delete[] compr;
-
 
845
			if (outSize) *outSize = comprLen;
838
					return retData;
846
			return retData;
839
				}
847
		}
840
 
848
 
841
				free(compr);
849
		delete[] compr;
842
				return NULL;
850
		return NULL;
843
			}
851
	}
844
			break;
852
	break;
845
	}
853
	}
846
 
854
 
847
	return NULL;
855
	return NULL;
848
}
856
}
849
 
857
 
Line 876... Line 884...
876
	if ( m_iDataCompression != SPKCOMPRESS_NONE )
884
	if ( m_iDataCompression != SPKCOMPRESS_NONE )
877
		return true;
885
		return true;
878
 
886
 
879
	m_lUncomprDataSize = m_lDataSize;
887
	m_lUncomprDataSize = m_lDataSize;
880
 
888
 
881
	unsigned long comprLen = m_lDataSize;
889
	size_t comprLen = static_cast<size_t>(m_lDataSize);
882
	if ( comprLen < 100 )
890
	if ( comprLen < 100 )
883
		comprLen = 200;
891
		comprLen = 200;
884
	else if ( comprLen < 1000 )
892
	else if ( comprLen < 1000 )
885
		comprLen *= 2;
893
		comprLen *= 2;
886
	comprLen += 1000;
894
	comprLen += 1000;
Line 892... Line 900...
892
	// best compression, attempt to compress the file multiple times until we get the best one
900
	// best compression, attempt to compress the file multiple times until we get the best one
893
	if ( compressionType == SPKCOMPRESS_BEST )
901
	if ( compressionType == SPKCOMPRESS_BEST )
894
	{
902
	{
895
		int compress[] = { SPKCOMPRESS_ZLIB, SPKCOMPRESS_LZMA };
903
		int compress[] = { SPKCOMPRESS_ZLIB, SPKCOMPRESS_LZMA };
896
		int bestCompress = -1;
904
		int bestCompress = -1;
897
		unsigned int bestSize = 0;
905
		size_t bestSize = 0;
898
		unsigned char *bestCompr = NULL;
906
		unsigned char *bestCompr = NULL;
899
		for ( int i = 0; i < 2; i++ )
907
		for ( int i = 0; i < 2; i++ )
900
		{
908
		{
901
			unsigned long checkSize = 0;
909
			size_t checkSize = 0;
902
			unsigned char *compr = this->CompressToData(compress[i], &checkSize, progress, level);
910
			unsigned char *compr = this->CompressToData(compress[i], &checkSize, progress, level);
903
			if ( compr )
911
			if ( compr )
904
			{
912
			{
905
				if ( checkSize < bestSize || bestCompress == -1 )
913
				if ( checkSize < bestSize || bestCompress == -1 )
906
				{
914
				{
Line 1007... Line 1015...
1007
		{
1015
		{
1008
			DeleteData ();
1016
			DeleteData ();
1009
			m_sData = compr;
1017
			m_sData = compr;
1010
			m_lDataSize = len;
1018
			m_lDataSize = len;
1011
			m_iDataCompression = SPKCOMPRESS_NONE;
1019
			m_iDataCompression = SPKCOMPRESS_NONE;
1012
			return true;
1020
			return true;
1013
		}
1021
		}
1014
	}
1022
	}
1015
 
1023
 
1016
	return false;
1024
	return false;
1017
}
1025
}
1018
 
1026
 
Line 1196... Line 1204...
1196
	char    dateString[100];
1204
	char    dateString[100];
1197
 
1205
 
1198
	time_t n = m_tTime;
1206
	time_t n = m_tTime;
1199
 
1207
 
1200
	currDate = localtime(&n);
1208
	currDate = localtime(&n);
1201
 
1209
 
1202
	strftime(dateString, sizeof dateString, "(%d/%m/%Y) %H:%M", currDate);
1210
	strftime(dateString, sizeof dateString, "(%d/%m/%Y) %H:%M", currDate);
1203
 
1211
 
1204
	return Utils::WString(dateString);
1212
	return Utils::WString(dateString);
1205
}
1213
}
1206
 
1214
 
Line 1384... Line 1392...
1384
		case SPKINSTALL_ORIGINAL_BACKUP_FAIL:
1392
		case SPKINSTALL_ORIGINAL_BACKUP_FAIL:
1385
			errorStr = L"Unable to back up original file: %1";
1393
			errorStr = L"Unable to back up original file: %1";
1386
			break;
1394
			break;
1387
		case SPKINSTALL_ORIGINAL_RESTORE:
1395
		case SPKINSTALL_ORIGINAL_RESTORE:
1388
			errorStr = L"Restoring original file: %1";
1396
			errorStr = L"Restoring original file: %1";
1389
			break;
1397
			break;
1390
		case SPKINSTALL_ORIGINAL_RESTORE_FAIL:
1398
		case SPKINSTALL_ORIGINAL_RESTORE_FAIL:
1391
			errorStr = L"Unable to restore original file: %1";
1399
			errorStr = L"Unable to restore original file: %1";
1392
			break;
1400
			break;
1393
		case SPKINSTALL_FAKEPATCH:
1401
		case SPKINSTALL_FAKEPATCH:
1394
			errorStr = L"Shifted fake patch: %1 to %2";
1402
			errorStr = L"Shifted fake patch: %1 to %2";
Line 1478... Line 1486...
1478
		CFileIO File(filePointer());
1486
		CFileIO File(filePointer());
1479
		if ( File.startRead() ) data = File.readAll(&datasize);
1487
		if ( File.startRead() ) data = File.readAll(&datasize);
1480
	}
1488
	}
1481
 
1489
 
1482
	if ( !data )
1490
	if ( !data )
1483
	{
1491
	{
1484
		if ( !m_lDataSize )
1492
		if ( !m_lDataSize )
1485
		{
1493
		{
1486
			if ( !this->ReadFromFile() )
1494
			if ( !this->ReadFromFile() )
1487
				return NULL;
1495
				return NULL;
1488
		}
1496
		}
Line 1490... Line 1498...
1490
		data = new unsigned char[datasize];
1498
		data = new unsigned char[datasize];
1491
		memcpy ( data, m_sData, datasize );
1499
		memcpy ( data, m_sData, datasize );
1492
	}
1500
	}
1493
 
1501
 
1494
	if ( data )
1502
	if ( data )
1495
	{
1503
	{
1496
		unsigned char *newdata = UnPCKData ( data, datasize, len, CheckPCK() );
1504
		unsigned char *newdata = UnPCKData ( data, datasize, len, CheckPCK() );
1497
		delete data;
1505
		delete[] data;
1498
		return newdata;
1506
		return newdata;
1499
	}
1507
	}
1500
 
1508
 
1501
	return NULL;
1509
	return NULL;
1502
}
1510
}
Line 1547... Line 1555...
1547
 
1555
 
1548
	return NULL;
1556
	return NULL;
1549
}
1557
}
1550
 
1558
 
1551
unsigned char *UnPCKData ( unsigned char *data, size_t datasize, size_t *len ) { return UnPCKData(data, datasize, len, IsDataPCK(data, datasize)); }
1559
unsigned char *UnPCKData ( unsigned char *data, size_t datasize, size_t *len ) { return UnPCKData(data, datasize, len, IsDataPCK(data, datasize)); }
1552
unsigned char *UnPCKData ( unsigned char *data, size_t datasize, size_t *len, bool nocrypt )
1560
unsigned char* UnPCKData(unsigned char* data, size_t datasize, size_t* len, bool nocrypt)
1553
{
1561
{
1554
	bool isPCK = IsDataPCK(data, datasize);
1562
	if (!data || datasize <; 8) { // Minimum size for header + length
-
 
1563
		if (len) *len = 0;
-
 
1564
		return nullptr;
-
 
1565
	}
1555
 
1566
 
-
 
1567
	bool isPCK = IsDataPCK(data, datasize);
1556
	unsigned char *newData = data;
1568
	unsigned char* newData = data;
1557
	unsigned char *tempData = NULL;
1569
	unsigned char* tempData = nullptr;
1558
 
1570
 
1559
	if ( nocrypt )
1571
	if (nocrypt) {
1560
	{
-
 
1561
		tempData = new unsigned char[datasize]; 
1572
		tempData = new (std::nothrow) unsigned char[datasize];
1562
		newData = tempData;
1573
		if (!tempData) { if (len) *len = 0; return nullptr; }
1563
		memcpy(newData, data, datasize);
1574
		memcpy(tempData, data, datasize);
1564
		unsigned char magic = newData[0] ^ 0xC8;
1575
		unsigned char magic = tempData[0] ^ 0xC8;
1565
 
-
 
1566
		for ( size_t i = 1; i <; datasize; i++ )
1576
		for (size_t i = 1; i <; datasize; i++)
1567
			newData[i] ^= magic;
1577
			tempData[i] ^= magic;
1568
		++newData;
1578
		newData = tempData + 1;
1569
		--datasize;
1579
		datasize -= 1;
-
 
1580
	}
-
 
1581
 
-
 
1582
	if (datasize < 4) { // Not enough data for length
-
 
1583
		if (tempData) delete[] tempData;
-
 
1584
		if (len) *len = 0;
-
 
1585
		return nullptr;
1570
	}
1586
	}
1571
 
1587
 
1572
	// create data buffer
1588
	// Read uncompressed length safely
1573
	size_t *uncomprLenSize = (size_t*)(newData + (datasize - 4));
1589
	size_t lenPos = datasize - 4;
1574
	unsigned long uncomprLen = (unsigned long)*uncomprLenSize;
1590
	unsigned long uncomprLen = 0;
-
 
1591
	memcpy(&uncomprLen, newData + lenPos, 4);
1575
	if ( uncomprLen > (datasize * 100) )
1592
	if (uncomprLen > datasize * 100 || uncomprLen == 0) {
-
 
1593
		if (tempData) delete[] tempData;
-
 
1594
		if (len) *len = 0;
-
 
1595
		return nullptr;
1576
	{
1596
	}
-
 
1597
 
-
 
1598
	unsigned char* uncompr = new (std::nothrow) unsigned char[uncomprLen + 1];
-
 
1599
	if (!uncompr) {
1577
		if ( tempData ) delete []tempData;
1600
		if (tempData) delete[] tempData;
1578
		*len = 0;
1601
		if (len) *len = 0;
1579
		return NULL;
1602
		return nullptr;
1580
	}
1603
	}
1581
	unsigned char *uncompr = new unsigned char[uncomprLen + 1];
1604
	memset(uncompr, 0, uncomprLen + 1);
-
 
1605
 
1582
	if ( !uncompr ) {
1606
	// Parse header
-
 
1607
	size_t bufOffset = PCKHEADERSIZE;
-
 
1608
	if (datasize < bufOffset + 8) { // Not enough data for header and footer
1583
		if ( tempData ) delete []tempData;
1609
		if (tempData) delete[] tempData;
-
 
1610
		delete[] uncompr;
-
 
1611
		if (len) *len = 0;
1584
		return NULL;
1612
		return nullptr;
1585
	}
1613
	}
-
 
1614
	unsigned char flag = newData[3];
1586
	memset ( uncompr, 0, sizeof(uncompr) );
1615
	unsigned char* buf = newData + bufOffset;
1587
 
1616
 
1588
 
-
 
1589
	// find header size
-
 
1590
	unsigned char *buf = newData + PCKHEADERSIZE;
-
 
1591
 
-
 
1592
//	buf = data + (6 + sizeof(time_t));
-
 
1593
	char flag = newData[3];
-
 
1594
 
-
 
1595
	if ( flag & GZ_FLAG_EXTRA )
1617
	if (flag & GZ_FLAG_EXTRA) {
1596
	{
-
 
-
 
1618
		if (datasize < bufOffset + 2) { if (tempData) delete[] tempData; delete[] uncompr; if (len) *len = 0; return nullptr; }
1597
		size_t xlen = *((short int*)(buf));
1619
		size_t xlen = *((short int*)(buf));
-
 
1620
		buf += 2;
1598
		buf += xlen;
1621
		buf += xlen;
1599
	}
1622
	}
1600
 
-
 
1601
	if ( flag & GZ_FLAG_FILENAME )
1623
	if (flag & GZ_FLAG_FILENAME) {
1602
	{
-
 
1603
		char *origname = (char*)(buf);
1624
		char* origname = (char*)(buf);
1604
		buf += strlen (origname) + 1;
1625
		buf += strlen(origname) + 1;
1605
	}
1626
	}
1606
	if ( flag & GZ_FLAG_COMMENT )
1627
	if (flag & GZ_FLAG_COMMENT) {
1607
	{
-
 
1608
		char *comment = (char*)(buf);
1628
		char* comment = (char*)(buf);
1609
		buf += strlen(comment) + 1;
1629
		buf += strlen(comment) + 1;
1610
	}
1630
	}
1611
	if ( flag & GZ_FLAG_HCRC )
1631
	if (flag & GZ_FLAG_HCRC) {
1612
		buf += 2;
1632
		buf += 2;
1613
	long bufSize = (long)(datasize - (buf-newData) - 8);
-
 
-
 
1633
	}
1614
 
1634
 
1615
	int err = uncompress2 ( uncompr, &uncomprLen, buf, bufSize );
1635
	long bufSize = (long)(datasize - (buf - newData) - 8);
1616
	if ( err != Z_OK )
1636
	if (bufSize <= 0) {
-
 
1637
		if (tempData) delete[] tempData;
-
 
1638
		delete[] uncompr;
-
 
1639
		if (len) *len = 0;
-
 
1640
		return nullptr;
1617
	{
1641
	}
-
 
1642
 
-
 
1643
	int err = uncompress2(uncompr, &uncomprLen, buf, bufSize);
-
 
1644
	if (err != Z_OK) {
1618
		if ( tempData ) delete []tempData;
1645
		if (tempData) delete[] tempData;
1619
		delete uncompr;
1646
		delete[] uncompr;
1620
		*len = 0;
1647
		if (len) *len = 0;
1621
		return NULL;
1648
		return nullptr;
1622
	}
1649
	}
1623
 
1650
 
1624
	*len = uncomprLen;
1651
	if (len) *len = uncomprLen;
1625
	uncompr[uncomprLen] = '\0';
1652
	uncompr[uncomprLen] = '\0';
1626
	if ( tempData ) delete []tempData;
1653
	if (tempData) delete[](tempData - 1); // tempData was offset by +1
1627
	return uncompr;
1654
	return uncompr;
1628
}
1655
}
1629
 
1656
 
1630
bool IsDataPCK ( const unsigned char *data, size_t size )
1657
bool IsDataPCK ( const unsigned char *data, size_t size )
1631
{
1658
{