Subversion Repositories spk

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
148 cycrow 1
// XLib.cpp : Defines the functions for the static library.
2
//
3
 
4
#include "pch.h"
5
#include "framework.h"
6
 
7
unsigned char* UnPCKFile(const char* file, size_t* len, bool nocrypt)
8
{
9
	FileIO File(file);
10
	if (!File.startRead()) return NULL;
11
 
12
	size_t size;
13
	unsigned char* data = File.readAll(&size);
14
 
15
	if (data) {
16
		unsigned char* unData = UnPCKData(data, size, len, nocrypt);
17
		delete data;
18
		return unData;
19
	}
20
 
21
	return NULL;
22
}
23
 
24
unsigned char* UnPCKData(unsigned char* data, size_t datasize, size_t* len) { return UnPCKData(data, datasize, len, IsDataPCK(data, datasize)); }
25
unsigned char* UnPCKData(unsigned char* data, size_t datasize, size_t* len, bool nocrypt)
26
{
27
	bool isPCK = IsDataPCK(data, datasize);
28
 
29
	unsigned char* newData = data;
30
	unsigned char* tempData = NULL;
31
 
32
	if (nocrypt)
33
	{
34
		tempData = new unsigned char[datasize];
35
		newData = tempData;
36
		memcpy(newData, data, datasize);
37
		unsigned char magic = newData[0] ^ 0xC8;
38
 
39
		for (size_t i = 1; i < datasize; i++)
40
			newData[i] ^= magic;
41
		++newData;
42
		--datasize;
43
	}
44
 
45
	// create data buffer
46
	size_t* uncomprLenSize = (size_t*)(newData + (datasize - 4));
47
	unsigned long uncomprLen = (unsigned long)*uncomprLenSize;
48
	if (uncomprLen > (datasize * 100))
49
	{
50
		if (tempData) delete[]tempData;
51
		*len = 0;
52
		return NULL;
53
	}
54
	unsigned char* uncompr = new unsigned char[uncomprLen + 1];
55
	if (!uncompr) {
56
		if (tempData) delete[]tempData;
57
		return NULL;
58
	}
59
	memset(uncompr, 0, sizeof(uncompr));
60
 
61
 
62
	// find header size
63
	unsigned char* buf = newData + PCKHEADERSIZE;
64
 
65
	//	buf = data + (6 + sizeof(time_t));
66
	char flag = newData[3];
67
 
68
	if (flag & GZ_FLAG_EXTRA)
69
	{
70
		size_t xlen = *((short int*)(buf));
71
		buf += xlen;
72
	}
73
 
74
	if (flag & GZ_FLAG_FILENAME)
75
	{
76
		char* origname = (char*)(buf);
77
		buf += strlen(origname) + 1;
78
	}
79
	if (flag & GZ_FLAG_COMMENT)
80
	{
81
		char* comment = (char*)(buf);
82
		buf += strlen(comment) + 1;
83
	}
84
	if (flag & GZ_FLAG_HCRC)
85
		buf += 2;
86
	long bufSize = (long)(datasize - (buf - newData) - 8);
87
 
88
	int err = uncompress2(uncompr, &uncomprLen, buf, bufSize);
89
	if (err != Z_OK)
90
	{
91
		if (tempData) delete[]tempData;
92
		delete uncompr;
93
		*len = 0;
94
		return NULL;
95
	}
96
 
97
	*len = uncomprLen;
98
	uncompr[uncomprLen] = '\0';
99
	if (tempData) delete[]tempData;
100
	return uncompr;
101
}
102
 
103
bool IsDataPCK(const unsigned char* data, size_t size)
104
{
105
	if (size >= 3)
106
	{
107
		unsigned char magic = data[0] ^ 0xC8;
108
		return ((data[1] ^ magic) == 0x1F && (data[2] ^ magic) == 0x8B);
109
	}
110
	else
111
		return false;
112
 
113
}