devilutionX/Source/encrypt.cpp
Anders Jenbo 20621a0642
add all.h and use in place of diablo.h (#2005)
Now diablo.h is treated in the same way as all other header files of
Source, as it only contains the declarations of global variables and
functions of diablo.cpp.

Besides consistency, this also enables mods to include diablo.h just
like any other header file without having to include every header file
(and without having to include C++ specific aspects of the now all.h).
2020-02-14 13:12:54 +01:00

158 lines
3.3 KiB
C++

#include "all.h"
#include "../3rdParty/PKWare/pkware.h"
DWORD hashtable[1280];
void Decrypt(void *block, DWORD size, DWORD key)
{
DWORD *castBlock;
DWORD seed, i;
castBlock = (DWORD *)block;
seed = 0xEEEEEEEE;
for (i = 0; i < (size >> 2); i++) {
seed += hashtable[0x400 + (key & 0xFF)];
*castBlock ^= seed + key;
seed += *castBlock + (seed << 5) + 3;
key = ((~key << 0x15) + 0x11111111) | (key >> 0x0B);
castBlock++;
}
}
void Encrypt(void *block, DWORD size, DWORD key)
{
DWORD *castBlock;
DWORD seed, i, ch;
castBlock = (DWORD *)block;
seed = 0xEEEEEEEE;
for (i = 0; i < (size >> 2); i++) {
ch = *castBlock;
seed += hashtable[0x400 + (key & 0xFF)];
*castBlock ^= seed + key;
seed += ch + (seed << 5) + 3;
key = ((~key << 0x15) + 0x11111111) | (key >> 0x0B);
castBlock++;
}
}
DWORD Hash(const char *s, int type)
{
char ch;
DWORD seed1, seed2;
seed1 = 0x7FED7FED;
seed2 = 0xEEEEEEEE;
while (s != NULL && *s) {
ch = *s++;
ch = toupper(ch);
seed1 = hashtable[(type << 8) + ch] ^ (seed1 + seed2);
seed2 += ch + seed1 + (seed2 << 5) + 3;
}
return seed1;
}
void InitHash()
{
DWORD seed, ch;
int i, j;
seed = 0x00100001;
for (i = 0; i < 256; i++) {
for (j = 0; j < 5; j++) {
seed = (125 * seed + 3) % 0x2AAAAB;
ch = (seed & 0xFFFF);
seed = (125 * seed + 3) % 0x2AAAAB;
hashtable[i + j * 256] = ch << 16 | (seed & 0xFFFF);
}
}
}
int PkwareCompress(void *buf, int size)
{
BYTE *srcData, *destData;
char *ptr;
unsigned int destSize, type, dsize;
TDataInfo param;
srcData = (BYTE *)buf;
ptr = (char *)DiabloAllocPtr(CMP_BUFFER_SIZE);
destSize = 2 * size;
if (destSize < 8192)
destSize = 8192;
destData = (BYTE *)DiabloAllocPtr(destSize);
param.srcData = srcData;
param.srcOffset = 0;
param.destData = destData;
param.destOffset = 0;
param.size = size;
type = 0;
dsize = 4096;
implode(PkwareBufferRead, PkwareBufferWrite, ptr, &param, &type, &dsize);
if (param.destOffset < size) {
memcpy(srcData, destData, param.destOffset);
size = param.destOffset;
}
mem_free_dbg(ptr);
mem_free_dbg(destData);
return size;
}
unsigned int __cdecl PkwareBufferRead(char *buf, unsigned int *size, void *param)
{
TDataInfo *pInfo;
DWORD sSize;
pInfo = (TDataInfo *)param;
if (*size >= pInfo->size - pInfo->srcOffset) {
sSize = pInfo->size - pInfo->srcOffset;
} else {
sSize = *size;
}
memcpy(buf, pInfo->srcData + pInfo->srcOffset, sSize);
pInfo->srcOffset += sSize;
return sSize;
}
void __cdecl PkwareBufferWrite(char *buf, unsigned int *size, void *param)
{
TDataInfo *pInfo;
pInfo = (TDataInfo *)param;
memcpy(pInfo->destData + pInfo->destOffset, buf, *size);
pInfo->destOffset += *size;
}
void PkwareDecompress(void *param, int recv_size, int dwMaxBytes)
{
char *ptr;
BYTE *pbInBuff, *pbOutBuff;
TDataInfo info;
ptr = (char *)DiabloAllocPtr(CMP_BUFFER_SIZE);
pbInBuff = (BYTE *)param;
pbOutBuff = DiabloAllocPtr(dwMaxBytes);
info.srcData = pbInBuff;
info.srcOffset = 0;
info.destData = pbOutBuff;
info.destOffset = 0;
info.size = recv_size;
explode(PkwareBufferRead, PkwareBufferWrite, ptr, &info);
memcpy(pbInBuff, pbOutBuff, info.destOffset);
mem_free_dbg(ptr);
mem_free_dbg(pbOutBuff);
}