Blame | Last modification | View Log | RSS feed
// XLib.cpp : Defines the functions for the static library.
//
#include "pch.h"
#include "framework.h"
unsigned char* UnPCKFile(const char* file, size_t* len, bool nocrypt)
{
FileIO File(file);
if (!File.startRead()) return NULL;
size_t size;
unsigned char* data = File.readAll(&size);
if (data) {
unsigned char* unData = UnPCKData(data, size, len, nocrypt);
delete data;
return unData;
}
return NULL;
}
unsigned char* UnPCKData(unsigned char* data, size_t datasize, size_t* len) { return UnPCKData(data, datasize, len, IsDataPCK(data, datasize)); }
unsigned char* UnPCKData(unsigned char* data, size_t datasize, size_t* len, bool nocrypt)
{
bool isPCK = IsDataPCK(data, datasize);
unsigned char* newData = data;
unsigned char* tempData = NULL;
if (nocrypt)
{
tempData = new unsigned char[datasize];
newData = tempData;
memcpy(newData, data, datasize);
unsigned char magic = newData[0] ^ 0xC8;
for (size_t i = 1; i < datasize; i++)
newData[i] ^= magic;
++newData;
--datasize;
}
// create data buffer
size_t* uncomprLenSize = (size_t*)(newData + (datasize - 4));
unsigned long uncomprLen = (unsigned long)*uncomprLenSize;
if (uncomprLen > (datasize * 100))
{
if (tempData) delete[]tempData;
*len = 0;
return NULL;
}
unsigned char* uncompr = new unsigned char[uncomprLen + 1];
if (!uncompr) {
if (tempData) delete[]tempData;
return NULL;
}
memset(uncompr, 0, sizeof(uncompr));
// find header size
unsigned char* buf = newData + PCKHEADERSIZE;
// buf = data + (6 + sizeof(time_t));
char flag = newData[3];
if (flag & GZ_FLAG_EXTRA)
{
size_t xlen = *((short int*)(buf));
buf += xlen;
}
if (flag & GZ_FLAG_FILENAME)
{
char* origname = (char*)(buf);
buf += strlen(origname) + 1;
}
if (flag & GZ_FLAG_COMMENT)
{
char* comment = (char*)(buf);
buf += strlen(comment) + 1;
}
if (flag & GZ_FLAG_HCRC)
buf += 2;
long bufSize = (long)(datasize - (buf - newData) - 8);
int err = uncompress2(uncompr, &uncomprLen, buf, bufSize);
if (err != Z_OK)
{
if (tempData) delete[]tempData;
delete uncompr;
*len = 0;
return NULL;
}
*len = uncomprLen;
uncompr[uncomprLen] = '\0';
if (tempData) delete[]tempData;
return uncompr;
}
bool IsDataPCK(const unsigned char* data, size_t size)
{
if (size >= 3)
{
unsigned char magic = data[0] ^ 0xC8;
return ((data[1] ^ magic) == 0x1F && (data[2] ^ magic) == 0x8B);
}
else
return false;
}