mirror of
https://github.com/thunderbrewhq/thunderbrew
synced 2025-10-29 23:36:02 +03:00
chore(build): update StormLib
This commit is contained in:
parent
1e5f4fb542
commit
6c4f278065
1
vendor/stormlib-9/CMakeLists.txt
vendored
1
vendor/stormlib-9/CMakeLists.txt
vendored
@ -40,6 +40,7 @@ set(TOMCRYPT_FILES
|
||||
src/libtomcrypt/src/hashes/hash_memory.c
|
||||
src/libtomcrypt/src/hashes/md5.c
|
||||
src/libtomcrypt/src/hashes/sha1.c
|
||||
src/libtomcrypt/src/hashes/sha256.c
|
||||
src/libtomcrypt/src/math/ltm_desc.c
|
||||
src/libtomcrypt/src/math/multi.c
|
||||
src/libtomcrypt/src/math/rand_prime.c
|
||||
|
||||
24
vendor/stormlib-9/src/DllMain.rc
vendored
24
vendor/stormlib-9/src/DllMain.rc
vendored
@ -16,10 +16,8 @@
|
||||
// Neutral resources
|
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEU)
|
||||
#ifdef _WIN32
|
||||
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
|
||||
#pragma code_page(1250)
|
||||
#endif //_WIN32
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
@ -27,8 +25,8 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 9,22,0,3
|
||||
PRODUCTVERSION 9,22,0,3
|
||||
FILEVERSION 9,25,0,3
|
||||
PRODUCTVERSION 9,25,0,3
|
||||
FILEFLAGSMASK 0x17L
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
@ -45,12 +43,12 @@ BEGIN
|
||||
BEGIN
|
||||
VALUE "Comments", "http://www.zezula.net/mpq.html"
|
||||
VALUE "FileDescription", "StormLib library for reading Blizzard MPQ archives"
|
||||
VALUE "FileVersion", "9, 22, 0, 3\0"
|
||||
VALUE "FileVersion", "9.25.0.3"
|
||||
VALUE "InternalName", "StormLib"
|
||||
VALUE "LegalCopyright", "Copyright (c) 2014 - 2020 Ladislav Zezula"
|
||||
VALUE "LegalCopyright", "Copyright (c) 2014 - 2023 Ladislav Zezula"
|
||||
VALUE "OriginalFilename", "StormLib.dll"
|
||||
VALUE "ProductName", "StormLib"
|
||||
VALUE "ProductVersion", "9, 22, 0, 3\0"
|
||||
VALUE "ProductVersion", "9.25.0.3"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
@ -64,13 +62,11 @@ END
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Czech resources
|
||||
// Czech (Czech Republic) resources
|
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CSY)
|
||||
#ifdef _WIN32
|
||||
LANGUAGE LANG_CZECH, SUBLANG_DEFAULT
|
||||
#pragma code_page(1250)
|
||||
#endif //_WIN32
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
@ -78,26 +74,26 @@ LANGUAGE LANG_CZECH, SUBLANG_DEFAULT
|
||||
// TEXTINCLUDE
|
||||
//
|
||||
|
||||
2 TEXTINCLUDE
|
||||
2 TEXTINCLUDE
|
||||
BEGIN
|
||||
"#include ""afxres.h""\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
3 TEXTINCLUDE
|
||||
3 TEXTINCLUDE
|
||||
BEGIN
|
||||
"\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
1 TEXTINCLUDE
|
||||
1 TEXTINCLUDE
|
||||
BEGIN
|
||||
"resource.h\0"
|
||||
END
|
||||
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
#endif // Czech resources
|
||||
#endif // Czech (Czech Republic) resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
1
vendor/stormlib-9/src/LibTomCrypt.c
vendored
1
vendor/stormlib-9/src/LibTomCrypt.c
vendored
@ -8,6 +8,7 @@
|
||||
#include "libtomcrypt/src/hashes/hash_memory.c"
|
||||
#include "libtomcrypt/src/hashes/md5.c"
|
||||
#include "libtomcrypt/src/hashes/sha1.c"
|
||||
#include "libtomcrypt/src/hashes/sha256.c"
|
||||
#include "libtomcrypt/src/math/multi.c"
|
||||
#include "libtomcrypt/src/math/rand_prime.c"
|
||||
#include "libtomcrypt/src/misc/base64_decode.c"
|
||||
|
||||
112
vendor/stormlib-9/src/SBaseCommon.cpp
vendored
112
vendor/stormlib-9/src/SBaseCommon.cpp
vendored
@ -15,7 +15,7 @@
|
||||
#include "StormLib.h"
|
||||
#include "StormCommon.h"
|
||||
|
||||
char StormLibCopyright[] = "StormLib v " STORMLIB_VERSION_STRING " Copyright Ladislav Zezula 1998-2014";
|
||||
char StormLibCopyright[] = "StormLib v " STORMLIB_VERSION_STRING " Copyright Ladislav Zezula 1998-2023";
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Local variables
|
||||
@ -244,8 +244,8 @@ void InitializeMpqCryptography()
|
||||
}
|
||||
|
||||
// Also register both MD5 and SHA1 hash algorithms
|
||||
register_hash(&md5_desc);
|
||||
register_hash(&sha1_desc);
|
||||
register_hash(&md5_desc);
|
||||
|
||||
// Use LibTomMath as support math library for LibTomCrypt
|
||||
ltc_mp = ltm_desc;
|
||||
@ -403,7 +403,7 @@ DWORD GetDefaultSpecialFileFlags(DWORD dwFileSize, USHORT wFormatVersion)
|
||||
{
|
||||
// Fixed for format 1.0
|
||||
if(wFormatVersion == MPQ_FORMAT_VERSION_1)
|
||||
return MPQ_FILE_COMPRESS | MPQ_FILE_ENCRYPTED | MPQ_FILE_FIX_KEY;
|
||||
return MPQ_FILE_COMPRESS | MPQ_FILE_ENCRYPTED | MPQ_FILE_KEY_V2;
|
||||
|
||||
// Size-dependent for formats 2.0-4.0
|
||||
return (dwFileSize > 0x4000) ? (MPQ_FILE_COMPRESS | MPQ_FILE_SECTOR_CRC) : (MPQ_FILE_COMPRESS | MPQ_FILE_SINGLE_UNIT);
|
||||
@ -696,7 +696,7 @@ DWORD DecryptFileKey(
|
||||
dwFileKey = HashString(szFileName, MPQ_HASH_FILE_KEY);
|
||||
|
||||
// Fix the key, if needed
|
||||
if(dwFlags & MPQ_FILE_FIX_KEY)
|
||||
if(dwFlags & MPQ_FILE_KEY_V2)
|
||||
dwFileKey = (dwFileKey + dwMpqPos) ^ dwFileSize;
|
||||
|
||||
// Return the key
|
||||
@ -999,18 +999,20 @@ void * LoadMpqTable(
|
||||
LPBYTE pbCompressed = NULL;
|
||||
LPBYTE pbMpqTable;
|
||||
LPBYTE pbToRead;
|
||||
DWORD dwBytesToRead = dwCompressedSize;
|
||||
DWORD dwBytesToRead = dwTableSize;
|
||||
DWORD dwErrCode = ERROR_SUCCESS;
|
||||
|
||||
// Allocate the MPQ table
|
||||
pbMpqTable = pbToRead = STORM_ALLOC(BYTE, dwTableSize);
|
||||
if(pbMpqTable != NULL)
|
||||
{
|
||||
// Check if the MPQ table is encrypted
|
||||
// Check if the MPQ table is compressed
|
||||
if(dwCompressedSize < dwTableSize)
|
||||
{
|
||||
// Allocate temporary buffer for holding compressed data
|
||||
pbCompressed = pbToRead = STORM_ALLOC(BYTE, dwCompressedSize);
|
||||
dwBytesToRead = dwCompressedSize;
|
||||
|
||||
if(pbCompressed == NULL)
|
||||
{
|
||||
STORM_FREE(pbMpqTable);
|
||||
@ -1152,6 +1154,7 @@ DWORD AllocateSectorBuffer(TMPQFile * hf)
|
||||
DWORD AllocatePatchInfo(TMPQFile * hf, bool bLoadFromFile)
|
||||
{
|
||||
TMPQArchive * ha = hf->ha;
|
||||
TPatchInfo * pPatchInfo;
|
||||
DWORD dwLength = sizeof(TPatchInfo);
|
||||
|
||||
// The following conditions must be true
|
||||
@ -1162,35 +1165,39 @@ __AllocateAndLoadPatchInfo:
|
||||
|
||||
// Allocate space for patch header. Start with default size,
|
||||
// and if its size if bigger, then we reload them
|
||||
hf->pPatchInfo = STORM_ALLOC(TPatchInfo, 1);
|
||||
if(hf->pPatchInfo == NULL)
|
||||
pPatchInfo = (TPatchInfo *)(STORM_ALLOC(BYTE, dwLength));
|
||||
if(pPatchInfo == NULL)
|
||||
return ERROR_NOT_ENOUGH_MEMORY;
|
||||
|
||||
// Do we have to load the patch header from the file ?
|
||||
if(bLoadFromFile)
|
||||
{
|
||||
// Load the patch header
|
||||
if(!FileStream_Read(ha->pStream, &hf->RawFilePos, hf->pPatchInfo, dwLength))
|
||||
if(!FileStream_Read(ha->pStream, &hf->RawFilePos, pPatchInfo, dwLength))
|
||||
{
|
||||
// Free the patch info
|
||||
STORM_FREE(hf->pPatchInfo);
|
||||
hf->pPatchInfo = NULL;
|
||||
STORM_FREE(pPatchInfo);
|
||||
return GetLastError();
|
||||
}
|
||||
|
||||
// Perform necessary swapping
|
||||
hf->pPatchInfo->dwLength = BSWAP_INT32_UNSIGNED(hf->pPatchInfo->dwLength);
|
||||
hf->pPatchInfo->dwFlags = BSWAP_INT32_UNSIGNED(hf->pPatchInfo->dwFlags);
|
||||
hf->pPatchInfo->dwDataSize = BSWAP_INT32_UNSIGNED(hf->pPatchInfo->dwDataSize);
|
||||
pPatchInfo->dwLength = BSWAP_INT32_UNSIGNED(pPatchInfo->dwLength);
|
||||
pPatchInfo->dwFlags = BSWAP_INT32_UNSIGNED(pPatchInfo->dwFlags);
|
||||
pPatchInfo->dwDataSize = BSWAP_INT32_UNSIGNED(pPatchInfo->dwDataSize);
|
||||
|
||||
// Do nothing if the patch info is not valid
|
||||
if(!(pPatchInfo->dwFlags & MPQ_PATCH_INFO_VALID))
|
||||
{
|
||||
STORM_FREE(pPatchInfo);
|
||||
return ERROR_FILE_CORRUPT;
|
||||
}
|
||||
|
||||
// Verify the size of the patch header
|
||||
// If it's not default size, we have to reload them
|
||||
if(hf->pPatchInfo->dwLength > dwLength)
|
||||
if(pPatchInfo->dwLength > dwLength)
|
||||
{
|
||||
// Free the patch info
|
||||
dwLength = hf->pPatchInfo->dwLength;
|
||||
STORM_FREE(hf->pPatchInfo);
|
||||
hf->pPatchInfo = NULL;
|
||||
dwLength = pPatchInfo->dwLength;
|
||||
STORM_FREE(pPatchInfo);
|
||||
|
||||
// If the length is out of all possible ranges, fail the operation
|
||||
if(dwLength > 0x400)
|
||||
@ -1199,16 +1206,17 @@ __AllocateAndLoadPatchInfo:
|
||||
}
|
||||
|
||||
// Patch file data size according to the patch header
|
||||
hf->dwDataSize = hf->pPatchInfo->dwDataSize;
|
||||
hf->dwDataSize = pPatchInfo->dwDataSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(hf->pPatchInfo, 0, dwLength);
|
||||
memset(pPatchInfo, 0, dwLength);
|
||||
pPatchInfo->dwLength = dwLength;
|
||||
pPatchInfo->dwFlags = MPQ_PATCH_INFO_VALID;
|
||||
}
|
||||
|
||||
// Save the final length to the patch header
|
||||
hf->pPatchInfo->dwLength = dwLength;
|
||||
hf->pPatchInfo->dwFlags = 0x80000000;
|
||||
hf->pPatchInfo = pPatchInfo;
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
@ -1888,10 +1896,10 @@ void ConvertUInt16Buffer(void * ptr, size_t length)
|
||||
uint32_t nElements = (uint32_t)(length / sizeof(uint16_t));
|
||||
|
||||
while(nElements-- > 0)
|
||||
{
|
||||
*buffer = SwapUInt16(*buffer);
|
||||
buffer++;
|
||||
}
|
||||
{
|
||||
*buffer = SwapUInt16(*buffer);
|
||||
buffer++;
|
||||
}
|
||||
}
|
||||
|
||||
// Swaps array of unsigned 32-bit integers
|
||||
@ -1900,11 +1908,11 @@ void ConvertUInt32Buffer(void * ptr, size_t length)
|
||||
uint32_t * buffer = (uint32_t *)ptr;
|
||||
uint32_t nElements = (uint32_t)(length / sizeof(uint32_t));
|
||||
|
||||
while(nElements-- > 0)
|
||||
{
|
||||
*buffer = SwapUInt32(*buffer);
|
||||
buffer++;
|
||||
}
|
||||
while(nElements-- > 0)
|
||||
{
|
||||
*buffer = SwapUInt32(*buffer);
|
||||
buffer++;
|
||||
}
|
||||
}
|
||||
|
||||
// Swaps array of unsigned 64-bit integers
|
||||
@ -1913,37 +1921,37 @@ void ConvertUInt64Buffer(void * ptr, size_t length)
|
||||
uint64_t * buffer = (uint64_t *)ptr;
|
||||
uint32_t nElements = (uint32_t)(length / sizeof(uint64_t));
|
||||
|
||||
while(nElements-- > 0)
|
||||
{
|
||||
*buffer = SwapUInt64(*buffer);
|
||||
buffer++;
|
||||
}
|
||||
while(nElements-- > 0)
|
||||
{
|
||||
*buffer = SwapUInt64(*buffer);
|
||||
buffer++;
|
||||
}
|
||||
}
|
||||
|
||||
// Swaps the TMPQHeader structure
|
||||
void ConvertTMPQHeader(void *header, uint16_t version)
|
||||
{
|
||||
TMPQHeader * theHeader = (TMPQHeader *)header;
|
||||
TMPQHeader * theHeader = (TMPQHeader *)header;
|
||||
|
||||
// Swap header part version 1
|
||||
if(version >= MPQ_FORMAT_VERSION_1)
|
||||
{
|
||||
theHeader->dwID = SwapUInt32(theHeader->dwID);
|
||||
theHeader->dwHeaderSize = SwapUInt32(theHeader->dwHeaderSize);
|
||||
theHeader->dwArchiveSize = SwapUInt32(theHeader->dwArchiveSize);
|
||||
theHeader->wFormatVersion = SwapUInt16(theHeader->wFormatVersion);
|
||||
theHeader->wSectorSize = SwapUInt16(theHeader->wSectorSize);
|
||||
theHeader->dwHashTablePos = SwapUInt32(theHeader->dwHashTablePos);
|
||||
theHeader->dwBlockTablePos = SwapUInt32(theHeader->dwBlockTablePos);
|
||||
theHeader->dwHashTableSize = SwapUInt32(theHeader->dwHashTableSize);
|
||||
theHeader->dwBlockTableSize = SwapUInt32(theHeader->dwBlockTableSize);
|
||||
theHeader->dwID = SwapUInt32(theHeader->dwID);
|
||||
theHeader->dwHeaderSize = SwapUInt32(theHeader->dwHeaderSize);
|
||||
theHeader->dwArchiveSize = SwapUInt32(theHeader->dwArchiveSize);
|
||||
theHeader->wFormatVersion = SwapUInt16(theHeader->wFormatVersion);
|
||||
theHeader->wSectorSize = SwapUInt16(theHeader->wSectorSize);
|
||||
theHeader->dwHashTablePos = SwapUInt32(theHeader->dwHashTablePos);
|
||||
theHeader->dwBlockTablePos = SwapUInt32(theHeader->dwBlockTablePos);
|
||||
theHeader->dwHashTableSize = SwapUInt32(theHeader->dwHashTableSize);
|
||||
theHeader->dwBlockTableSize = SwapUInt32(theHeader->dwBlockTableSize);
|
||||
}
|
||||
|
||||
if(version >= MPQ_FORMAT_VERSION_2)
|
||||
{
|
||||
theHeader->HiBlockTablePos64 = SwapUInt64(theHeader->HiBlockTablePos64);
|
||||
if(version >= MPQ_FORMAT_VERSION_2)
|
||||
{
|
||||
theHeader->HiBlockTablePos64 = SwapUInt64(theHeader->HiBlockTablePos64);
|
||||
theHeader->wHashTablePosHi = SwapUInt16(theHeader->wHashTablePosHi);
|
||||
theHeader->wBlockTablePosHi = SwapUInt16(theHeader->wBlockTablePosHi);
|
||||
theHeader->wBlockTablePosHi = SwapUInt16(theHeader->wBlockTablePosHi);
|
||||
}
|
||||
|
||||
if(version >= MPQ_FORMAT_VERSION_3)
|
||||
@ -1954,7 +1962,7 @@ void ConvertTMPQHeader(void *header, uint16_t version)
|
||||
}
|
||||
|
||||
if(version >= MPQ_FORMAT_VERSION_4)
|
||||
{
|
||||
{
|
||||
theHeader->HashTableSize64 = SwapUInt64(theHeader->HashTableSize64);
|
||||
theHeader->BlockTableSize64 = SwapUInt64(theHeader->BlockTableSize64);
|
||||
theHeader->HiBlockTableSize64 = SwapUInt64(theHeader->HiBlockTableSize64);
|
||||
|
||||
135
vendor/stormlib-9/src/SBaseFileTable.cpp
vendored
135
vendor/stormlib-9/src/SBaseFileTable.cpp
vendored
@ -312,34 +312,38 @@ static ULONGLONG DetermineArchiveSize_V1(
|
||||
return (EndOfMpq - MpqOffset);
|
||||
}
|
||||
|
||||
static ULONGLONG DetermineArchiveSize_V2(
|
||||
TMPQHeader * pHeader,
|
||||
ULONGLONG MpqOffset,
|
||||
ULONGLONG FileSize)
|
||||
static ULONGLONG DetermineBlockTableSize_V2(TMPQHeader * pHeader, ULONGLONG MpqHeaderPos, ULONGLONG FileSize)
|
||||
{
|
||||
ULONGLONG EndOfMpq = FileSize;
|
||||
DWORD dwArchiveSize32;
|
||||
ULONGLONG BlockTablePos = MAKE_OFFSET64(pHeader->wBlockTablePosHi, pHeader->dwBlockTablePos);
|
||||
ULONGLONG ArchiveSize = FileSize - MpqHeaderPos;
|
||||
|
||||
// This could only be called for MPQs version 2.0
|
||||
assert(pHeader->wFormatVersion == MPQ_FORMAT_VERSION_2);
|
||||
|
||||
// Check if we can rely on the archive size in the header
|
||||
if((FileSize >> 0x20) == 0)
|
||||
// If there is a hi-block table and it is beyond the block table,
|
||||
// we can determine the block table size from it
|
||||
if(pHeader->HiBlockTablePos64 != 0)
|
||||
{
|
||||
if(pHeader->dwBlockTablePos < pHeader->dwArchiveSize)
|
||||
if(pHeader->HiBlockTablePos64 > BlockTablePos)
|
||||
{
|
||||
if((pHeader->dwArchiveSize - pHeader->dwBlockTablePos) <= (pHeader->dwBlockTableSize * sizeof(TMPQBlock)))
|
||||
return pHeader->dwArchiveSize;
|
||||
|
||||
// If the archive size in the header is less than real file size
|
||||
dwArchiveSize32 = (DWORD)(FileSize - MpqOffset);
|
||||
if(pHeader->dwArchiveSize <= dwArchiveSize32)
|
||||
return pHeader->dwArchiveSize;
|
||||
return (pHeader->HiBlockTablePos64 - BlockTablePos);
|
||||
}
|
||||
}
|
||||
|
||||
// Return the calculated archive size
|
||||
return (EndOfMpq - MpqOffset);
|
||||
// If we have valid archive size, we can determine the block table size from the archive size
|
||||
else
|
||||
{
|
||||
if((BlockTablePos >> 0x20) == 0 && (ArchiveSize >> 0x20) == 0)
|
||||
{
|
||||
DWORD dwBlockTablePos32 = (DWORD)(BlockTablePos);
|
||||
DWORD dwArchiveSize32 = (DWORD)(ArchiveSize);
|
||||
|
||||
if(pHeader->dwArchiveSize == dwArchiveSize32)
|
||||
{
|
||||
return (dwArchiveSize32 - dwBlockTablePos32);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Default is the block table size from MPQ header
|
||||
return (ULONGLONG)(pHeader->dwBlockTableSize) * sizeof(TMPQBlock);
|
||||
}
|
||||
|
||||
static ULONGLONG DetermineArchiveSize_V4(
|
||||
@ -381,20 +385,39 @@ static ULONGLONG DetermineArchiveSize_V4(
|
||||
return ArchiveSize;
|
||||
}
|
||||
|
||||
ULONGLONG GetFileOffsetMask(TMPQArchive * ha)
|
||||
{
|
||||
ULONGLONG FileOffsetMask = (ULONGLONG)(-1);
|
||||
|
||||
// Sanity checks
|
||||
assert(ha != NULL);
|
||||
assert(ha->pHeader != NULL);
|
||||
|
||||
// MPQs of format 1 are 32-bit only
|
||||
if(ha->pHeader->wFormatVersion == MPQ_FORMAT_VERSION_1)
|
||||
FileOffsetMask = (ULONGLONG)(DWORD)(-1);
|
||||
return FileOffsetMask;
|
||||
}
|
||||
|
||||
ULONGLONG FileOffsetFromMpqOffset(TMPQArchive * ha, ULONGLONG MpqOffset)
|
||||
{
|
||||
if(ha->pHeader->wFormatVersion == MPQ_FORMAT_VERSION_1)
|
||||
{
|
||||
// For MPQ archive v1, any file offset is only 32-bit
|
||||
return (ULONGLONG)((DWORD)ha->MpqPos + (DWORD)MpqOffset);
|
||||
}
|
||||
else
|
||||
{
|
||||
// For MPQ archive v2+, file offsets are full 64-bit
|
||||
return ha->MpqPos + MpqOffset;
|
||||
}
|
||||
return (ha->MpqPos + MpqOffset) & ha->FileOffsetMask;
|
||||
}
|
||||
|
||||
//ULONGLONG FileOffsetFromMpqOffset(TMPQArchive * ha, ULONGLONG MpqOffset)
|
||||
//{
|
||||
// if(ha->pHeader->wFormatVersion == MPQ_FORMAT_VERSION_1)
|
||||
// {
|
||||
// // For MPQ archive v1, any file offset is only 32-bit
|
||||
// return (ULONGLONG)((DWORD)ha->MpqPos + (DWORD)MpqOffset);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// // For MPQ archive v2+, file offsets are full 64-bit
|
||||
// return ha->MpqPos + MpqOffset;
|
||||
// }
|
||||
//}
|
||||
|
||||
ULONGLONG CalculateRawSectorOffset(
|
||||
TMPQFile * hf,
|
||||
DWORD dwSectorOffset)
|
||||
@ -414,9 +437,7 @@ ULONGLONG CalculateRawSectorOffset(
|
||||
// For MPQs version 1.0, the offset is purely 32-bit
|
||||
//
|
||||
|
||||
RawFilePos = hf->RawFilePos + dwSectorOffset;
|
||||
if(hf->ha->pHeader->wFormatVersion == MPQ_FORMAT_VERSION_1)
|
||||
RawFilePos = (DWORD)hf->ha->MpqPos + (DWORD)hf->pFileEntry->ByteOffset + dwSectorOffset;
|
||||
RawFilePos = (hf->RawFilePos + dwSectorOffset) & hf->ha->FileOffsetMask;
|
||||
|
||||
// We also have to add patch header size, if patch header is present
|
||||
if(hf->pPatchInfo != NULL)
|
||||
@ -541,34 +562,14 @@ DWORD ConvertMpqHeaderToFormat4(
|
||||
// We require the block table to follow hash table
|
||||
if(BlockTablePos64 >= HashTablePos64)
|
||||
{
|
||||
// HashTableSize64 may be less than TblSize * sizeof(TMPQHash).
|
||||
// That means that the hash table is compressed.
|
||||
// Determine whether the hash table is compressed. This can be detected
|
||||
// by subtracting hash table position from the block table position.
|
||||
pHeader->HashTableSize64 = BlockTablePos64 - HashTablePos64;
|
||||
|
||||
// Calculate the compressed block table size
|
||||
if(pHeader->HiBlockTablePos64 != 0)
|
||||
{
|
||||
// BlockTableSize64 may be less than TblSize * sizeof(TMPQBlock).
|
||||
// That means that the block table is compressed.
|
||||
pHeader->BlockTableSize64 = pHeader->HiBlockTablePos64 - BlockTablePos64;
|
||||
assert(pHeader->BlockTableSize64 <= (pHeader->dwBlockTableSize * sizeof(TMPQBlock)));
|
||||
|
||||
// Determine real archive size
|
||||
pHeader->ArchiveSize64 = DetermineArchiveSize_V2(pHeader, ByteOffset, FileSize);
|
||||
|
||||
// Calculate the size of the hi-block table
|
||||
pHeader->HiBlockTableSize64 = pHeader->ArchiveSize64 - pHeader->HiBlockTablePos64;
|
||||
assert(pHeader->HiBlockTableSize64 == (pHeader->dwBlockTableSize * sizeof(USHORT)));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Determine real archive size
|
||||
pHeader->ArchiveSize64 = DetermineArchiveSize_V2(pHeader, ByteOffset, FileSize);
|
||||
|
||||
// Calculate size of the block table
|
||||
pHeader->BlockTableSize64 = pHeader->ArchiveSize64 - BlockTablePos64;
|
||||
assert(pHeader->BlockTableSize64 <= (pHeader->dwBlockTableSize * sizeof(TMPQBlock)));
|
||||
}
|
||||
// Also, block table may be compressed. We check whether the HiBlockTable is there.
|
||||
// If not, we try to use the archive size. Note that ArchiveSize may have
|
||||
// an arbitrary value, because it is not tested by Blizzard games anymore
|
||||
pHeader->BlockTableSize64 = DetermineBlockTableSize_V2(pHeader, ByteOffset, FileSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -2816,17 +2817,17 @@ DWORD DefragmentFileTable(TMPQArchive * ha)
|
||||
{
|
||||
TMPQHash * pHashTableEnd = ha->pHashTable + ha->pHeader->dwHashTableSize;
|
||||
TMPQHash * pHash;
|
||||
DWORD dwNewBlockIndex;
|
||||
DWORD dwNewBlockIndex;
|
||||
|
||||
for(pHash = ha->pHashTable; pHash < pHashTableEnd; pHash++)
|
||||
{
|
||||
if(MPQ_BLOCK_INDEX(pHash) < ha->dwFileTableSize)
|
||||
{
|
||||
// If that block entry is there, set it to the hash entry
|
||||
// If not, set it as DELETED
|
||||
dwNewBlockIndex = DefragmentTable[MPQ_BLOCK_INDEX(pHash)];
|
||||
pHash->dwBlockIndex = (dwNewBlockIndex != HASH_ENTRY_FREE) ? dwNewBlockIndex : HASH_ENTRY_DELETED;
|
||||
}
|
||||
{
|
||||
// If that block entry is there, set it to the hash entry
|
||||
// If not, set it as DELETED
|
||||
dwNewBlockIndex = DefragmentTable[MPQ_BLOCK_INDEX(pHash)];
|
||||
pHash->dwBlockIndex = (dwNewBlockIndex != HASH_ENTRY_FREE) ? dwNewBlockIndex : HASH_ENTRY_DELETED;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
109
vendor/stormlib-9/src/SCompression.cpp
vendored
109
vendor/stormlib-9/src/SCompression.cpp
vendored
@ -176,7 +176,7 @@ int Decompress_ZLIB(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, i
|
||||
inflateEnd(&z);
|
||||
}
|
||||
|
||||
return (nResult >= Z_OK);
|
||||
return (nResult >= Z_OK);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
@ -279,27 +279,27 @@ static void Compress_PKLIB(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBu
|
||||
static int Decompress_PKLIB(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, int cbInBuffer)
|
||||
{
|
||||
TDataInfo Info; // Data information
|
||||
char * work_buf;
|
||||
int nResult = 0;
|
||||
char * work_buf;
|
||||
int nResult = 0;
|
||||
|
||||
// Allocate Pklib's work buffer
|
||||
if((work_buf = STORM_ALLOC(char, EXP_BUFFER_SIZE)) != NULL)
|
||||
{
|
||||
// Fill data information structure
|
||||
memset(work_buf, 0, EXP_BUFFER_SIZE);
|
||||
Info.pbInBuff = (unsigned char *)pvInBuffer;
|
||||
Info.pbInBuffEnd = (unsigned char *)pvInBuffer + cbInBuffer;
|
||||
Info.pbOutBuff = (unsigned char *)pvOutBuffer;
|
||||
Info.pbOutBuffEnd = (unsigned char *)pvOutBuffer + *pcbOutBuffer;
|
||||
|
||||
// Do the decompression
|
||||
if(explode(ReadInputData, WriteOutputData, work_buf, &Info) == CMP_NO_ERROR)
|
||||
nResult = 1;
|
||||
|
||||
// Give away the number of decompressed bytes
|
||||
*pcbOutBuffer = (int)(Info.pbOutBuff - (unsigned char *)pvOutBuffer);
|
||||
STORM_FREE(work_buf);
|
||||
}
|
||||
{
|
||||
// Fill data information structure
|
||||
memset(work_buf, 0, EXP_BUFFER_SIZE);
|
||||
Info.pbInBuff = (unsigned char *)pvInBuffer;
|
||||
Info.pbInBuffEnd = (unsigned char *)pvInBuffer + cbInBuffer;
|
||||
Info.pbOutBuff = (unsigned char *)pvOutBuffer;
|
||||
Info.pbOutBuffEnd = (unsigned char *)pvOutBuffer + *pcbOutBuffer;
|
||||
|
||||
// Do the decompression
|
||||
if(explode(ReadInputData, WriteOutputData, work_buf, &Info) == CMP_NO_ERROR)
|
||||
nResult = 1;
|
||||
|
||||
// Give away the number of decompressed bytes
|
||||
*pcbOutBuffer = (int)(Info.pbOutBuff - (unsigned char *)pvOutBuffer);
|
||||
STORM_FREE(work_buf);
|
||||
}
|
||||
|
||||
return nResult;
|
||||
}
|
||||
@ -374,7 +374,7 @@ static int Decompress_BZIP2(void * pvOutBuffer, int * pcbOutBuffer, void * pvInB
|
||||
BZ2_bzDecompressEnd(&strm);
|
||||
}
|
||||
|
||||
return (nResult >= BZ_OK);
|
||||
return (nResult >= BZ_OK);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
@ -895,6 +895,16 @@ int WINAPI SCompCompress(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuff
|
||||
/* */
|
||||
/*****************************************************************************/
|
||||
|
||||
// Decompression table specific for Starcraft I BETA
|
||||
// WAVE files are compressed by different ADPCM compression
|
||||
static TDecompressTable dcmp_table_sc_beta[] =
|
||||
{
|
||||
{MPQ_COMPRESSION_PKWARE, Decompress_PKLIB}, // Decompression with Pkware Data Compression Library
|
||||
{MPQ_COMPRESSION_HUFFMANN, Decompress_huff}, // Huffmann decompression
|
||||
{0x10, Decompress_ADPCM1_sc1b}, // IMA ADPCM mono decompression
|
||||
{0x20, Decompress_ADPCM2_sc1b}, // IMA ADPCM stereo decompression
|
||||
};
|
||||
|
||||
// This table contains decompress functions which can be applied to
|
||||
// uncompressed data. The compression mask is stored in the first byte
|
||||
// of compressed data
|
||||
@ -909,25 +919,22 @@ static TDecompressTable dcmp_table[] =
|
||||
{MPQ_COMPRESSION_SPARSE, Decompress_SPARSE} // Sparse decompression
|
||||
};
|
||||
|
||||
// Decompression table specific for Starcraft I BETA
|
||||
// WAVE files are compressed by different ADPCM compression
|
||||
static TDecompressTable dcmp_table_sc1b[] =
|
||||
{
|
||||
{MPQ_COMPRESSION_PKWARE, Decompress_PKLIB}, // Decompression with Pkware Data Compression Library
|
||||
{MPQ_COMPRESSION_HUFFMANN, Decompress_huff}, // Huffmann decompression
|
||||
{0x10, Decompress_ADPCM1_sc1b}, // IMA ADPCM mono decompression
|
||||
{0x20, Decompress_ADPCM2_sc1b}, // IMA ADPCM stereo decompression
|
||||
};
|
||||
|
||||
static int SCompDecompressInternal(TDecompressTable * table, size_t table_length, void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, int cbInBuffer)
|
||||
static int SCompDecompressInternal(
|
||||
TDecompressTable * table,
|
||||
size_t table_length,
|
||||
void * pvOutBuffer,
|
||||
int * pcbOutBuffer,
|
||||
void * pvInBuffer,
|
||||
int cbInBuffer,
|
||||
unsigned uValidMask = 0xFF)
|
||||
{
|
||||
unsigned char * pbWorkBuffer = NULL;
|
||||
unsigned char * pbOutBuffer = (unsigned char *)pvOutBuffer;
|
||||
unsigned char * pbInBuffer = (unsigned char *)pvInBuffer;
|
||||
unsigned char * pbOutput = (unsigned char *)pvOutBuffer;
|
||||
unsigned char * pbInput;
|
||||
unsigned uCompressionMask; // Decompressions applied to the data
|
||||
unsigned uCompressionCopy; // Decompressions applied to the data
|
||||
unsigned uCompressionMask1; // Decompressions applied to the data
|
||||
unsigned uCompressionMask2; // Decompressions applied to the data
|
||||
int cbOutBuffer = *pcbOutBuffer; // Current size of the output buffer
|
||||
int cbInLength; // Current size of the input buffer
|
||||
int nCompressCount = 0; // Number of compressions to be applied
|
||||
@ -948,7 +955,8 @@ static int SCompDecompressInternal(TDecompressTable * table, size_t table_length
|
||||
}
|
||||
|
||||
// Get applied compression types and decrement data length
|
||||
uCompressionMask = uCompressionCopy = (unsigned char)(*pbInBuffer++);
|
||||
uCompressionMask1 = ((unsigned char)(*pbInBuffer++) & (uValidMask));
|
||||
uCompressionMask2 = uCompressionMask1;
|
||||
cbInBuffer--;
|
||||
|
||||
// Get current compressed data and length of it
|
||||
@ -956,21 +964,21 @@ static int SCompDecompressInternal(TDecompressTable * table, size_t table_length
|
||||
cbInLength = cbInBuffer;
|
||||
|
||||
// This compression function doesn't support LZMA
|
||||
assert(uCompressionMask != MPQ_COMPRESSION_LZMA);
|
||||
assert(uCompressionMask1 != MPQ_COMPRESSION_LZMA);
|
||||
|
||||
// Parse the compression mask
|
||||
for(size_t i = 0; i < table_length; i++)
|
||||
{
|
||||
// If the mask agrees, insert the compression function to the array
|
||||
if(uCompressionMask & table[i].uMask)
|
||||
if(uCompressionMask1 & table[i].uMask)
|
||||
{
|
||||
uCompressionCopy &= ~table[i].uMask;
|
||||
uCompressionMask2 &= ~table[i].uMask;
|
||||
nCompressCount++;
|
||||
}
|
||||
}
|
||||
|
||||
// If at least one of the compressions remaing unknown, return an error
|
||||
if(nCompressCount == 0 || uCompressionCopy != 0)
|
||||
if(nCompressCount == 0 || uCompressionMask2 != 0)
|
||||
{
|
||||
SetLastError(ERROR_NOT_SUPPORTED);
|
||||
return 0;
|
||||
@ -994,7 +1002,7 @@ static int SCompDecompressInternal(TDecompressTable * table, size_t table_length
|
||||
for(size_t i = 0; i < table_length; i++)
|
||||
{
|
||||
// Perform the (next) decompression
|
||||
if(uCompressionMask & table[i].uMask)
|
||||
if(uCompressionMask1 & table[i].uMask)
|
||||
{
|
||||
// Get the correct output buffer
|
||||
pbOutput = (nCompressIndex & 1) ? pbWorkBuffer : pbOutBuffer;
|
||||
@ -1030,11 +1038,6 @@ int WINAPI SCompDecompress(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBu
|
||||
return SCompDecompressInternal(dcmp_table, _countof(dcmp_table), pvOutBuffer, pcbOutBuffer, pvInBuffer, cbInBuffer);
|
||||
}
|
||||
|
||||
int WINAPI SCompDecompress_SC1B(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, int cbInBuffer)
|
||||
{
|
||||
return SCompDecompressInternal(dcmp_table_sc1b, _countof(dcmp_table_sc1b), pvOutBuffer, pcbOutBuffer, pvInBuffer, cbInBuffer);
|
||||
}
|
||||
|
||||
int WINAPI SCompDecompress2(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, int cbInBuffer)
|
||||
{
|
||||
DECOMPRESS pfnDecompress1 = NULL;
|
||||
@ -1149,6 +1152,24 @@ int WINAPI SCompDecompress2(void * pvOutBuffer, int * pcbOutBuffer, void * pvInB
|
||||
return nResult;
|
||||
}
|
||||
|
||||
int WINAPI SCompDecompressX(TMPQArchive * ha, void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, int cbInBuffer)
|
||||
{
|
||||
// MPQs version 2 use their own fixed list of compression flags.
|
||||
if(ha->pHeader->wFormatVersion >= MPQ_FORMAT_VERSION_2)
|
||||
{
|
||||
return SCompDecompress2(pvOutBuffer, pcbOutBuffer, pvInBuffer, cbInBuffer);
|
||||
}
|
||||
|
||||
// Starcraft BETA has specific decompression table.
|
||||
if(ha->dwFlags & MPQ_FLAG_STARCRAFT_BETA)
|
||||
{
|
||||
return SCompDecompressInternal(dcmp_table_sc_beta, _countof(dcmp_table_sc_beta), pvOutBuffer, pcbOutBuffer, pvInBuffer, cbInBuffer);
|
||||
}
|
||||
|
||||
// Default: Use the common MPQ v1 decompression routine
|
||||
return SCompDecompressInternal(dcmp_table, _countof(dcmp_table), pvOutBuffer, pcbOutBuffer, pvInBuffer, cbInBuffer);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* File decompression for MPK archives */
|
||||
|
||||
12
vendor/stormlib-9/src/SFileAddFile.cpp
vendored
12
vendor/stormlib-9/src/SFileAddFile.cpp
vendored
@ -246,6 +246,14 @@ static DWORD WriteDataToMpqFile(
|
||||
BSWAP_ARRAY32_UNSIGNED(pbToWrite, dwBytesInSector);
|
||||
}
|
||||
|
||||
// Do not allow Warcraft III maps to go over 2GB.
|
||||
// https://github.com/ladislav-zezula/StormLib/issues/306
|
||||
if((ha->dwFlags & MPQ_FLAG_WAR3_MAP) && (ByteOffset + dwBytesInSector) > 0x7FFFFFFF)
|
||||
{
|
||||
dwErrCode = ERROR_DISK_FULL;
|
||||
break;
|
||||
}
|
||||
|
||||
// Write the file sector
|
||||
if(!FileStream_Write(ha->pStream, &ByteOffset, pbToWrite, dwBytesInSector))
|
||||
{
|
||||
@ -425,7 +433,7 @@ DWORD SFileAddFile_Init(
|
||||
|
||||
// Fix Key is not allowed if the file is not encrypted
|
||||
if(!(dwFlags & MPQ_FILE_ENCRYPTED))
|
||||
dwFlags &= ~MPQ_FILE_FIX_KEY;
|
||||
dwFlags &= ~MPQ_FILE_KEY_V2;
|
||||
|
||||
// If the MPQ is of version 3.0 or higher, we ignore file locale.
|
||||
// This is because HET and BET tables have no known support for it
|
||||
@ -1295,7 +1303,7 @@ bool WINAPI SFileSetFileLocale(HANDLE hFile, LCID lcNewLocale)
|
||||
}
|
||||
|
||||
// We have to check if the file+locale is not already there
|
||||
pFileEntry = GetFileEntryLocale(ha, hf->pFileEntry->szFileName, lcNewLocale, NULL);
|
||||
pFileEntry = GetFileEntryExact(ha, hf->pFileEntry->szFileName, lcNewLocale, NULL);
|
||||
if(pFileEntry != NULL)
|
||||
{
|
||||
SetLastError(ERROR_ALREADY_EXISTS);
|
||||
|
||||
5
vendor/stormlib-9/src/SFileAttributes.cpp
vendored
5
vendor/stormlib-9/src/SFileAttributes.cpp
vendored
@ -391,7 +391,10 @@ DWORD SAttrLoadAttributes(TMPQArchive * ha)
|
||||
pbAttrFile[cbAttrFile] = 0;
|
||||
|
||||
// Load the entire file to memory
|
||||
SFileReadFile(hFile, pbAttrFile, cbAttrFile, &dwBytesRead, NULL);
|
||||
if(!SFileReadFile(hFile, pbAttrFile, cbAttrFile, &dwBytesRead, NULL))
|
||||
ha->dwFlags |= (GetLastError() == ERROR_FILE_CORRUPT) ? MPQ_FLAG_MALFORMED : 0;
|
||||
|
||||
// Parse the (attributes)
|
||||
if(dwBytesRead == cbAttrFile)
|
||||
dwErrCode = LoadAttributesFile(ha, pbAttrFile, cbAttrFile);
|
||||
|
||||
|
||||
@ -163,7 +163,7 @@ static DWORD CopyMpqFileSectors(
|
||||
if(dwErrCode == ERROR_SUCCESS && (pFileEntry->dwFlags & MPQ_FILE_ENCRYPTED))
|
||||
{
|
||||
dwFileKey2 = dwFileKey1 = hf->dwFileKey;
|
||||
if(pFileEntry->dwFlags & MPQ_FILE_FIX_KEY)
|
||||
if(pFileEntry->dwFlags & MPQ_FILE_KEY_V2)
|
||||
{
|
||||
dwFileKey2 = (dwFileKey1 ^ pFileEntry->dwFileSize) - (DWORD)pFileEntry->ByteOffset;
|
||||
dwFileKey2 = (dwFileKey2 + (DWORD)MpqFilePos) ^ pFileEntry->dwFileSize;
|
||||
|
||||
3
vendor/stormlib-9/src/SFileCreateArchive.cpp
vendored
3
vendor/stormlib-9/src/SFileCreateArchive.cpp
vendored
@ -238,6 +238,9 @@ bool WINAPI SFileCreateArchive2(const TCHAR * szMpqName, PSFILE_CREATE_MPQ pCrea
|
||||
pHeader->dwBlockTablePos = pHeader->dwHashTablePos + dwHashTableSize * sizeof(TMPQHash);
|
||||
pHeader->dwBlockTableSize = dwBlockTableSize;
|
||||
|
||||
// Set the mask for MPQ byte offset
|
||||
ha->FileOffsetMask = GetFileOffsetMask(ha);
|
||||
|
||||
// For MPQs version 4 and higher, we set the size of raw data block
|
||||
// for calculating MD5
|
||||
if(pCreateInfo->dwMpqVersion >= MPQ_FORMAT_VERSION_4)
|
||||
|
||||
20
vendor/stormlib-9/src/SFileGetFileInfo.cpp
vendored
20
vendor/stormlib-9/src/SFileGetFileInfo.cpp
vendored
@ -68,6 +68,10 @@ static bool GetInfo_BufferCheck(void * pvFileInfo, DWORD cbFileInfo, DWORD cbDat
|
||||
|
||||
static bool GetInfo(void * pvFileInfo, DWORD cbFileInfo, const void * pvData, DWORD cbData, LPDWORD pcbLengthNeeded)
|
||||
{
|
||||
// Verify the input parameter
|
||||
if(pvData == NULL)
|
||||
return GetInfo_ReturnError(ERROR_INVALID_PARAMETER);
|
||||
|
||||
// Verify buffer pointer and buffer size
|
||||
if(!GetInfo_BufferCheck(pvFileInfo, cbFileInfo, cbData, pcbLengthNeeded))
|
||||
return false;
|
||||
@ -81,6 +85,10 @@ static bool GetInfo_Allocated(void * pvFileInfo, DWORD cbFileInfo, void * pvData
|
||||
{
|
||||
bool bResult;
|
||||
|
||||
// Verify the input parameter
|
||||
if(pvData == NULL)
|
||||
return GetInfo_ReturnError(ERROR_INVALID_PARAMETER);
|
||||
|
||||
// Verify buffer pointer and buffer size
|
||||
if((bResult = GetInfo_BufferCheck(pvFileInfo, cbFileInfo, cbData, pcbLengthNeeded)) != false)
|
||||
memcpy(pvFileInfo, pvData, cbData);
|
||||
@ -401,15 +409,21 @@ bool WINAPI SFileGetFileInfo(
|
||||
return GetInfo(pvFileInfo, cbFileInfo, &hf->dwHashIndex, sizeof(DWORD), pcbLengthNeeded);
|
||||
|
||||
case SFileInfoNameHash1:
|
||||
if(hf->pHashEntry == NULL)
|
||||
return GetInfo_ReturnError(ERROR_INVALID_PARAMETER);
|
||||
return GetInfo(pvFileInfo, cbFileInfo, &hf->pHashEntry->dwName1, sizeof(DWORD), pcbLengthNeeded);
|
||||
|
||||
case SFileInfoNameHash2:
|
||||
if(hf->pHashEntry == NULL)
|
||||
return GetInfo_ReturnError(ERROR_INVALID_PARAMETER);
|
||||
return GetInfo(pvFileInfo, cbFileInfo, &hf->pHashEntry->dwName2, sizeof(DWORD), pcbLengthNeeded);
|
||||
|
||||
case SFileInfoNameHash3:
|
||||
return GetInfo(pvFileInfo, cbFileInfo, &pFileEntry->FileNameHash, sizeof(ULONGLONG), pcbLengthNeeded);
|
||||
|
||||
case SFileInfoLocale:
|
||||
if(hf->pHashEntry == NULL)
|
||||
return GetInfo_ReturnError(ERROR_INVALID_PARAMETER);
|
||||
dwInt32Value = SFILE_MAKE_LCID(hf->pHashEntry->Locale, hf->pHashEntry->Platform);
|
||||
return GetInfo(pvFileInfo, cbFileInfo, &dwInt32Value, sizeof(DWORD), pcbLengthNeeded);
|
||||
|
||||
@ -437,7 +451,7 @@ bool WINAPI SFileGetFileInfo(
|
||||
|
||||
case SFileInfoEncryptionKeyRaw:
|
||||
dwInt32Value = hf->dwFileKey;
|
||||
if(pFileEntry->dwFlags & MPQ_FILE_FIX_KEY)
|
||||
if(pFileEntry->dwFlags & MPQ_FILE_KEY_V2)
|
||||
dwInt32Value = (dwInt32Value ^ pFileEntry->dwFileSize) - (DWORD)hf->MpqFilePos;
|
||||
return GetInfo(pvFileInfo, cbFileInfo, &dwInt32Value, sizeof(DWORD), pcbLengthNeeded);
|
||||
|
||||
@ -564,11 +578,11 @@ static DWORD CreatePseudoFileName(HANDLE hFile, TFileEntry * pFileEntry, char *
|
||||
|
||||
bool WINAPI SFileGetFileName(HANDLE hFile, char * szFileName)
|
||||
{
|
||||
TMPQFile * hf = (TMPQFile *)hFile; // MPQ File handle
|
||||
TMPQFile * hf;
|
||||
DWORD dwErrCode = ERROR_INVALID_HANDLE;
|
||||
|
||||
// Check valid parameters
|
||||
if(IsValidFileHandle(hFile))
|
||||
if((hf = IsValidFileHandle(hFile)) != NULL)
|
||||
{
|
||||
TFileEntry * pFileEntry = hf->pFileEntry;
|
||||
|
||||
|
||||
47
vendor/stormlib-9/src/SFileListFile.cpp
vendored
47
vendor/stormlib-9/src/SFileListFile.cpp
vendored
@ -558,6 +558,27 @@ static DWORD SFileAddArbitraryListFile(
|
||||
return (pCache != NULL) ? ERROR_SUCCESS : ERROR_FILE_CORRUPT;
|
||||
}
|
||||
|
||||
static DWORD SFileAddArbitraryListFile(
|
||||
TMPQArchive * ha,
|
||||
const char ** listFileEntries,
|
||||
DWORD dwEntryCount)
|
||||
{
|
||||
if(listFileEntries != NULL && dwEntryCount > 0)
|
||||
{
|
||||
// Get the next line
|
||||
for(DWORD dwListFileNum = 0; dwListFileNum < dwEntryCount; dwListFileNum++)
|
||||
{
|
||||
const char * listFileEntry = listFileEntries[dwListFileNum];
|
||||
if(listFileEntry != NULL)
|
||||
{
|
||||
SListFileCreateNodeForAllLocales(ha, listFileEntry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (listFileEntries != NULL && dwEntryCount > 0) ? ERROR_SUCCESS : ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
static DWORD SFileAddInternalListFile(
|
||||
TMPQArchive * ha,
|
||||
HANDLE hMpq)
|
||||
@ -662,6 +683,32 @@ DWORD WINAPI SFileAddListFile(HANDLE hMpq, const TCHAR * szListFile)
|
||||
return dwErrCode;
|
||||
}
|
||||
|
||||
DWORD WINAPI SFileAddListFileEntries(HANDLE hMpq, const char ** listFileEntries, DWORD dwEntryCount)
|
||||
{
|
||||
TMPQArchive * ha = (TMPQArchive *)hMpq;
|
||||
DWORD dwErrCode = ERROR_SUCCESS;
|
||||
|
||||
// Add the listfile for each MPQ in the patch chain
|
||||
while(ha != NULL)
|
||||
{
|
||||
if(listFileEntries != NULL && dwEntryCount > 0)
|
||||
dwErrCode = SFileAddArbitraryListFile(ha, listFileEntries, dwEntryCount);
|
||||
else
|
||||
dwErrCode = SFileAddInternalListFile(ha, hMpq);
|
||||
|
||||
// Also, add three special files to the listfile:
|
||||
// (listfile) itself, (attributes) and (signature)
|
||||
SListFileCreateNodeForAllLocales(ha, LISTFILE_NAME);
|
||||
SListFileCreateNodeForAllLocales(ha, SIGNATURE_NAME);
|
||||
SListFileCreateNodeForAllLocales(ha, ATTRIBUTES_NAME);
|
||||
|
||||
// Move to the next archive in the chain
|
||||
ha = ha->haPatch;
|
||||
}
|
||||
|
||||
return dwErrCode;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Enumerating files in listfile
|
||||
|
||||
|
||||
28
vendor/stormlib-9/src/SFileOpenArchive.cpp
vendored
28
vendor/stormlib-9/src/SFileOpenArchive.cpp
vendored
@ -387,7 +387,7 @@ bool WINAPI SFileOpenArchive(
|
||||
}
|
||||
|
||||
// Check for MPK archives (Longwu Online - MPQ fork)
|
||||
if(MapType == MapTypeNotRecognized && dwHeaderID == ID_MPK)
|
||||
if(MapType == MapTypeNotRecognized && (dwFlags & MPQ_OPEN_FORCE_MPQ_V1) == 0 && dwHeaderID == ID_MPK)
|
||||
{
|
||||
// Now convert the MPK header to MPQ Header version 4
|
||||
dwErrCode = ConvertMpkHeaderToFormat4(ha, FileSize, dwFlags);
|
||||
@ -463,16 +463,24 @@ bool WINAPI SFileOpenArchive(
|
||||
if(IsStarcraftBetaArchive(ha->pHeader))
|
||||
ha->dwFlags |= MPQ_FLAG_STARCRAFT_BETA;
|
||||
|
||||
// Remember whether whis is a map for Warcraft III
|
||||
if(MapType == MapTypeWarcraft3)
|
||||
{
|
||||
ha->dwValidFileFlags = MPQ_FILE_VALID_FLAGS_W3X;
|
||||
ha->dwFlags |= MPQ_FLAG_WAR3_MAP;
|
||||
}
|
||||
// Set the mask for the file offset. In MPQs version 1,
|
||||
// all offsets are 32-bit and overflow is allowed.
|
||||
// For MPQs v2+, file offset if 64-bit.
|
||||
ha->FileOffsetMask = GetFileOffsetMask(ha);
|
||||
|
||||
// If this is starcraft map, set the flag mask
|
||||
if(MapType == MapTypeStarcraft)
|
||||
ha->dwValidFileFlags = MPQ_FILE_VALID_FLAGS_SCX;
|
||||
// Maps from StarCraft and Warcraft III need special treatment
|
||||
switch(MapType)
|
||||
{
|
||||
case MapTypeStarcraft:
|
||||
ha->dwValidFileFlags = MPQ_FILE_VALID_FLAGS_SCX;
|
||||
ha->dwFlags |= MPQ_FLAG_STARCRAFT;
|
||||
break;
|
||||
|
||||
case MapTypeWarcraft3:
|
||||
ha->dwValidFileFlags = MPQ_FILE_VALID_FLAGS_W3X;
|
||||
ha->dwFlags |= MPQ_FLAG_WAR3_MAP;
|
||||
break;
|
||||
}
|
||||
|
||||
// Set the size of file sector
|
||||
ha->dwSectorSize = (0x200 << ha->pHeader->wSectorSize);
|
||||
|
||||
29
vendor/stormlib-9/src/SFileOpenFileEx.cpp
vendored
29
vendor/stormlib-9/src/SFileOpenFileEx.cpp
vendored
@ -16,11 +16,13 @@
|
||||
/* Local functions */
|
||||
/*****************************************************************************/
|
||||
|
||||
// Finds hash index of the entry that was open by pseudo-name
|
||||
static DWORD FindHashIndex(TMPQArchive * ha, DWORD dwFileIndex)
|
||||
{
|
||||
TMPQHash * pHashTableEnd;
|
||||
TMPQHash * pHash;
|
||||
DWORD dwFirstIndex = HASH_ENTRY_FREE;
|
||||
DWORD dwHashIndex = HASH_ENTRY_FREE;
|
||||
DWORD dwCount = 0;
|
||||
|
||||
// Should only be called if the archive has hash table
|
||||
assert(ha->pHashTable != NULL);
|
||||
@ -32,15 +34,18 @@ static DWORD FindHashIndex(TMPQArchive * ha, DWORD dwFileIndex)
|
||||
{
|
||||
if(MPQ_BLOCK_INDEX(pHash) == dwFileIndex)
|
||||
{
|
||||
// Duplicate hash entry found
|
||||
if(dwFirstIndex != HASH_ENTRY_FREE)
|
||||
// Example: MPQ_2023_v1_Lusin2Rpg1.28.w3x, file index 24483
|
||||
// ReplaceableTextures\CommandButtons\BTNHaboss79.blp
|
||||
// Hash Table Index #1 = 18
|
||||
// Hash Table Index #2 = 8446
|
||||
if(dwCount++ > 0)
|
||||
return HASH_ENTRY_FREE;
|
||||
dwFirstIndex = (DWORD)(pHash - ha->pHashTable);
|
||||
dwHashIndex = (DWORD)(pHash - ha->pHashTable);
|
||||
}
|
||||
}
|
||||
|
||||
// Return the hash table entry index
|
||||
return dwFirstIndex;
|
||||
// Return the found hash index, if there are no duplicities
|
||||
return dwHashIndex;
|
||||
}
|
||||
|
||||
static const char * GetPatchFileName(TMPQArchive * ha, const char * szFileName, char * szBuffer)
|
||||
@ -298,32 +303,32 @@ bool WINAPI SFileOpenFileEx(HANDLE hMpq, const char * szFileName, DWORD dwSearch
|
||||
if(dwErrCode == ERROR_SUCCESS)
|
||||
{
|
||||
// If we didn't find the file, try to open it using pseudo file name ("File
|
||||
if (pFileEntry == NULL || (pFileEntry->dwFlags & MPQ_FILE_EXISTS) == 0)
|
||||
if(pFileEntry == NULL || (pFileEntry->dwFlags & MPQ_FILE_EXISTS) == 0)
|
||||
{
|
||||
// Check the pseudo-file name ("File00000001.ext")
|
||||
if ((bOpenByIndex = IsPseudoFileName(szFileName, &dwFileIndex)) == true)
|
||||
if((bOpenByIndex = IsPseudoFileName(szFileName, &dwFileIndex)) == true)
|
||||
{
|
||||
// Get the file entry for the file
|
||||
if (dwFileIndex < ha->dwFileTableSize)
|
||||
if(dwFileIndex < ha->dwFileTableSize)
|
||||
{
|
||||
pFileEntry = ha->pFileTable + dwFileIndex;
|
||||
}
|
||||
}
|
||||
|
||||
// Still not found?
|
||||
if (pFileEntry == NULL)
|
||||
if(pFileEntry == NULL || (pFileEntry->dwFlags & MPQ_FILE_EXISTS) == 0)
|
||||
{
|
||||
dwErrCode = ERROR_FILE_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
|
||||
// Perform some checks of invalid files
|
||||
if (pFileEntry != NULL)
|
||||
if(pFileEntry != NULL)
|
||||
{
|
||||
// MPQ protectors use insanely amount of fake files, often with very high size.
|
||||
// We won't open any files whose compressed size is bigger than archive size
|
||||
// If the file is not compressed, its size cannot be bigger than archive size
|
||||
if ((pFileEntry->dwFlags & MPQ_FILE_COMPRESS_MASK) == 0 && (pFileEntry->dwFileSize > ha->FileSize))
|
||||
if((pFileEntry->dwFlags & MPQ_FILE_COMPRESS_MASK) == 0 && (pFileEntry->dwFileSize > ha->FileSize))
|
||||
{
|
||||
dwErrCode = ERROR_FILE_CORRUPT;
|
||||
pFileEntry = NULL;
|
||||
|
||||
21
vendor/stormlib-9/src/SFileReadFile.cpp
vendored
21
vendor/stormlib-9/src/SFileReadFile.cpp
vendored
@ -13,6 +13,11 @@
|
||||
#include "StormLib.h"
|
||||
#include "StormCommon.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// External references (not public functions)
|
||||
|
||||
int WINAPI SCompDecompressX(TMPQArchive * ha, void * pvOutBuffer, int * pcbOutBuffer, void * pbInBuffer, int cbInBuffer);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Local functions
|
||||
|
||||
@ -171,18 +176,10 @@ static DWORD ReadMpqSectors(TMPQFile * hf, LPBYTE pbBuffer, DWORD dwByteOffset,
|
||||
// Remember the last used compression
|
||||
hf->dwCompression0 = pbInSector[0];
|
||||
|
||||
// Decompress the data
|
||||
if(ha->pHeader->wFormatVersion >= MPQ_FORMAT_VERSION_2)
|
||||
{
|
||||
nResult = SCompDecompress2(pbOutSector, &cbOutSector, pbInSector, cbInSector);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(ha->dwFlags & MPQ_FLAG_STARCRAFT_BETA)
|
||||
nResult = SCompDecompress_SC1B(pbOutSector, &cbOutSector, pbInSector, cbInSector);
|
||||
else
|
||||
nResult = SCompDecompress(pbOutSector, &cbOutSector, pbInSector, cbInSector);
|
||||
}
|
||||
// Decompress the data. We need to perform MPQ-specific decompression,
|
||||
// as multiple Blizzard games may have their own decompression tables
|
||||
// and even decompression methods.
|
||||
nResult = SCompDecompressX(ha, pbOutSector, &cbOutSector, pbInSector, cbInSector);
|
||||
}
|
||||
|
||||
// Is the file compressed by PKWARE Data Compression Library ?
|
||||
|
||||
2
vendor/stormlib-9/src/SFileVerify.cpp
vendored
2
vendor/stormlib-9/src/SFileVerify.cpp
vendored
@ -863,7 +863,7 @@ DWORD SSignFileFinish(TMPQArchive * ha)
|
||||
// Sign the hash
|
||||
memset(WeakSignature, 0, sizeof(WeakSignature));
|
||||
rsa_sign_hash_ex(Md5Digest, sizeof(Md5Digest), WeakSignature + 8, &signature_len, LTC_LTC_PKCS_1_V1_5, 0, 0, hash_idx, 0, &key);
|
||||
memrev(WeakSignature + 8, MPQ_WEAK_SIGNATURE_SIZE);
|
||||
memrev(WeakSignature + 8, MPQ_WEAK_SIGNATURE_SIZE);
|
||||
rsa_free(&key);
|
||||
|
||||
// Write the signature to the MPQ. Don't use SFile* functions, but write the hash directly
|
||||
|
||||
3
vendor/stormlib-9/src/StormCommon.h
vendored
3
vendor/stormlib-9/src/StormCommon.h
vendored
@ -82,7 +82,7 @@
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// MTYPE definition - specifies what kind of MPQ is the map type
|
||||
// MTYPE definition - specifies what kind of MPQ is the file
|
||||
|
||||
typedef enum _MTYPE
|
||||
{
|
||||
@ -251,6 +251,7 @@ TMPQFile * IsValidFileHandle(HANDLE hFile);
|
||||
//-----------------------------------------------------------------------------
|
||||
// Support for MPQ file tables
|
||||
|
||||
ULONGLONG GetFileOffsetMask(TMPQArchive * ha);
|
||||
ULONGLONG FileOffsetFromMpqOffset(TMPQArchive * ha, ULONGLONG MpqOffset);
|
||||
ULONGLONG CalculateRawSectorOffset(TMPQFile * hf, DWORD dwSectorOffset);
|
||||
|
||||
|
||||
47
vendor/stormlib-9/src/StormLib.h
vendored
47
vendor/stormlib-9/src/StormLib.h
vendored
@ -143,8 +143,8 @@ extern "C" {
|
||||
//-----------------------------------------------------------------------------
|
||||
// Defines
|
||||
|
||||
#define STORMLIB_VERSION 0x0918 // Current version of StormLib (9.24)
|
||||
#define STORMLIB_VERSION_STRING "9.24" // String version of StormLib version
|
||||
#define STORMLIB_VERSION 0x0919 // Current version of StormLib
|
||||
#define STORMLIB_VERSION_STRING "9.25" // Current version of StormLib as string
|
||||
|
||||
#define ID_MPQ 0x1A51504D // MPQ archive header ID ('MPQ\x1A')
|
||||
#define ID_MPQ_USERDATA 0x1B51504D // MPQ userdata entry ('MPQ\x1B')
|
||||
@ -194,15 +194,16 @@ extern "C" {
|
||||
#define MPQ_FLAG_CHECK_SECTOR_CRC 0x00000020 // Checking sector CRC when reading files
|
||||
#define MPQ_FLAG_SAVING_TABLES 0x00000040 // If set, we are saving MPQ internal files and MPQ tables
|
||||
#define MPQ_FLAG_PATCH 0x00000080 // If set, this MPQ is a patch archive
|
||||
#define MPQ_FLAG_WAR3_MAP 0x00000100 // If set, this MPQ is a Warcraft III map
|
||||
#define MPQ_FLAG_STARCRAFT_BETA 0x00000200 // If set, this MPQ is StarDat.mpq from Starcraft I BETA
|
||||
#define MPQ_FLAG_LISTFILE_NONE 0x00000400 // Set when no (listfile) was found in InvalidateInternalFiles
|
||||
#define MPQ_FLAG_LISTFILE_NEW 0x00000800 // Set when (listfile) invalidated by InvalidateInternalFiles
|
||||
#define MPQ_FLAG_LISTFILE_FORCE 0x00001000 // Save updated listfile on exit
|
||||
#define MPQ_FLAG_ATTRIBUTES_NONE 0x00002000 // Set when no (attributes) was found in InvalidateInternalFiles
|
||||
#define MPQ_FLAG_ATTRIBUTES_NEW 0x00004000 // Set when (attributes) invalidated by InvalidateInternalFiles
|
||||
#define MPQ_FLAG_SIGNATURE_NONE 0x00008000 // Set when no (signature) was found in InvalidateInternalFiles
|
||||
#define MPQ_FLAG_SIGNATURE_NEW 0x00010000 // Set when (signature) invalidated by InvalidateInternalFiles
|
||||
#define MPQ_FLAG_STARCRAFT_BETA 0x00000100 // If set, this MPQ is from Starcraft I BETA
|
||||
#define MPQ_FLAG_STARCRAFT 0x00000200 // If set, this MPQ is from Starcraft I
|
||||
#define MPQ_FLAG_WAR3_MAP 0x00000400 // If set, this MPQ is a Warcraft III map
|
||||
#define MPQ_FLAG_LISTFILE_NONE 0x00000800 // Set when no (listfile) was found in InvalidateInternalFiles
|
||||
#define MPQ_FLAG_LISTFILE_NEW 0x00001000 // Set when (listfile) invalidated by InvalidateInternalFiles
|
||||
#define MPQ_FLAG_LISTFILE_FORCE 0x00002000 // Save updated listfile on exit
|
||||
#define MPQ_FLAG_ATTRIBUTES_NONE 0x00004000 // Set when no (attributes) was found in InvalidateInternalFiles
|
||||
#define MPQ_FLAG_ATTRIBUTES_NEW 0x00008000 // Set when (attributes) invalidated by InvalidateInternalFiles
|
||||
#define MPQ_FLAG_SIGNATURE_NONE 0x00010000 // Set when no (signature) was found in InvalidateInternalFiles
|
||||
#define MPQ_FLAG_SIGNATURE_NEW 0x00020000 // Set when (signature) invalidated by InvalidateInternalFiles
|
||||
|
||||
// Values for TMPQArchive::dwSubType
|
||||
#define MPQ_SUBTYPE_MPQ 0x00000000 // The file is a MPQ file (Blizzard games)
|
||||
@ -214,11 +215,11 @@ extern "C" {
|
||||
#define SFILE_INVALID_POS 0xFFFFFFFF
|
||||
#define SFILE_INVALID_ATTRIBUTES 0xFFFFFFFF
|
||||
|
||||
// Flags for SFileAddFile
|
||||
// Flags for TMPQBlock::dwFlags
|
||||
#define MPQ_FILE_IMPLODE 0x00000100 // Implode method (By PKWARE Data Compression Library)
|
||||
#define MPQ_FILE_COMPRESS 0x00000200 // Compress methods (By multiple methods)
|
||||
#define MPQ_FILE_ENCRYPTED 0x00010000 // Indicates whether file is encrypted
|
||||
#define MPQ_FILE_FIX_KEY 0x00020000 // File decryption key has to be fixed
|
||||
#define MPQ_FILE_ENCRYPTED 0x00010000 // Indicates an encrypted file
|
||||
#define MPQ_FILE_KEY_V2 0x00020000 // Indicates an encrypted file with key v2
|
||||
#define MPQ_FILE_PATCH_FILE 0x00100000 // The file is a patch file. Raw file data begin with TPatchInfo structure
|
||||
#define MPQ_FILE_SINGLE_UNIT 0x01000000 // File is stored as a single unit, rather than split into sectors (Thx, Quantam)
|
||||
#define MPQ_FILE_DELETE_MARKER 0x02000000 // File is a deletion marker. Used in MPQ patches, indicating that the file no longer exists.
|
||||
@ -232,10 +233,12 @@ extern "C" {
|
||||
|
||||
#define MPQ_FILE_DEFAULT_INTERNAL 0xFFFFFFFF // Use default flags for internal files
|
||||
|
||||
#define MPQ_FILE_FIX_KEY 0x00020000 // Obsolete, do not use
|
||||
|
||||
#define MPQ_FILE_VALID_FLAGS (MPQ_FILE_IMPLODE | \
|
||||
MPQ_FILE_COMPRESS | \
|
||||
MPQ_FILE_ENCRYPTED | \
|
||||
MPQ_FILE_FIX_KEY | \
|
||||
MPQ_FILE_KEY_V2 | \
|
||||
MPQ_FILE_PATCH_FILE | \
|
||||
MPQ_FILE_SINGLE_UNIT | \
|
||||
MPQ_FILE_DELETE_MARKER | \
|
||||
@ -246,7 +249,7 @@ extern "C" {
|
||||
#define MPQ_FILE_VALID_FLAGS_W3X (MPQ_FILE_IMPLODE | \
|
||||
MPQ_FILE_COMPRESS | \
|
||||
MPQ_FILE_ENCRYPTED | \
|
||||
MPQ_FILE_FIX_KEY | \
|
||||
MPQ_FILE_KEY_V2 | \
|
||||
MPQ_FILE_DELETE_MARKER | \
|
||||
MPQ_FILE_SECTOR_CRC | \
|
||||
MPQ_FILE_SIGNATURE | \
|
||||
@ -255,9 +258,12 @@ extern "C" {
|
||||
#define MPQ_FILE_VALID_FLAGS_SCX (MPQ_FILE_IMPLODE | \
|
||||
MPQ_FILE_COMPRESS | \
|
||||
MPQ_FILE_ENCRYPTED | \
|
||||
MPQ_FILE_FIX_KEY | \
|
||||
MPQ_FILE_KEY_V2 | \
|
||||
MPQ_FILE_EXISTS)
|
||||
|
||||
// Flags for TPatchInfo::dwFlags
|
||||
#define MPQ_PATCH_INFO_VALID 0x80000000 // Set if the patch info is valid
|
||||
|
||||
// We need to mask out the upper 4 bits of the block table index.
|
||||
// This is because it gets shifted out when calculating block table offset
|
||||
// BlockTableOffset = pHash->dwBlockIndex << 0x04
|
||||
@ -471,6 +477,8 @@ typedef enum _SFileInfoClass
|
||||
SFileInfoEncryptionKey, // File encryption key
|
||||
SFileInfoEncryptionKeyRaw, // Unfixed value of the file key
|
||||
SFileInfoCRC32, // CRC32 of the file
|
||||
|
||||
SFileInfoInvalid = 0xFFF, // Invalid file info class
|
||||
} SFileInfoClass;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -675,7 +683,7 @@ typedef struct _TMPQBlock
|
||||
typedef struct _TPatchInfo
|
||||
{
|
||||
DWORD dwLength; // Length of patch info header, in bytes
|
||||
DWORD dwFlags; // Flags. 0x80000000 = MD5 (?)
|
||||
DWORD dwFlags; // Flags. 0x80000000 = valid (?)
|
||||
DWORD dwDataSize; // Uncompressed size of the patch file
|
||||
BYTE md5[0x10]; // MD5 of the entire patch file after decompression
|
||||
|
||||
@ -822,6 +830,7 @@ typedef struct _TMPQArchive
|
||||
ULONGLONG UserDataPos; // Position of user data (relative to the begin of the file)
|
||||
ULONGLONG MpqPos; // MPQ header offset (relative to the begin of the file)
|
||||
ULONGLONG FileSize; // Size of the file at the moment of file open
|
||||
ULONGLONG FileOffsetMask; // 0xFFFFFFFF for MPQ v 1, otherwise 0xFFFFFFFFFFFFFFFFull
|
||||
|
||||
struct _TMPQArchive * haPatch; // Pointer to patch archive, if any
|
||||
struct _TMPQArchive * haBase; // Pointer to base ("previous version") archive, if any
|
||||
@ -1025,6 +1034,7 @@ bool WINAPI SFileCloseArchive(HANDLE hMpq);
|
||||
// so you can use this API to combining more listfiles.
|
||||
// Note that this function is internally called by SFileFindFirstFile
|
||||
DWORD WINAPI SFileAddListFile(HANDLE hMpq, const TCHAR * szListFile);
|
||||
DWORD WINAPI SFileAddListFileEntries(HANDLE hMpq, const char ** listFileEntries, DWORD dwEntryCount);
|
||||
|
||||
// Archive compacting
|
||||
bool WINAPI SFileSetCompactCallback(HANDLE hMpq, SFILE_COMPACT_CALLBACK CompactCB, void * pvUserData);
|
||||
@ -1120,7 +1130,6 @@ int WINAPI SCompExplode (void * pvOutBuffer, int * pcbOutBuffer, void * pv
|
||||
int WINAPI SCompCompress (void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, int cbInBuffer, unsigned uCompressionMask, int nCmpType, int nCmpLevel);
|
||||
int WINAPI SCompDecompress (void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, int cbInBuffer);
|
||||
int WINAPI SCompDecompress2(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, int cbInBuffer);
|
||||
int WINAPI SCompDecompress_SC1B(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, int cbInBuffer);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Non-Windows support for SetLastError/GetLastError
|
||||
|
||||
2
vendor/stormlib-9/src/StormPort.h
vendored
2
vendor/stormlib-9/src/StormPort.h
vendored
@ -20,7 +20,7 @@
|
||||
/* 12.11.03 1.02 Dan Macintosh compatibility */
|
||||
/* 24.07.04 1.03 Sam Mac OS X compatibility */
|
||||
/* 22.11.06 1.04 Sam Mac OS X compatibility (for StormLib 6.0) */
|
||||
/* 31.12.06 1.05 XPinguin Full GNU/Linux compatibility */
|
||||
/* 31.12.06 1.05 XPinguin Full GNU/Linux compatibility */
|
||||
/* 17.10.12 1.05 Lad Moved error codes so they don't overlap with errno.h */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
59
vendor/stormlib-9/src/huffman/huff.cpp
vendored
59
vendor/stormlib-9/src/huffman/huff.cpp
vendored
@ -269,24 +269,6 @@ TInputStream::TInputStream(void * pvInBuffer, size_t cbInBuffer)
|
||||
BitCount = 0;
|
||||
}
|
||||
|
||||
// Gets 7 bits from the stream. DOES NOT remove the bits from input stream
|
||||
unsigned int TInputStream::Peek7Bits()
|
||||
{
|
||||
unsigned int dwReloadByte = 0;
|
||||
|
||||
// If there is not enough bits to get the value,
|
||||
// we have to add 8 more bits from the input buffer
|
||||
if(BitCount < 7)
|
||||
{
|
||||
dwReloadByte = *pbInBuffer++;
|
||||
BitBuffer |= dwReloadByte << BitCount;
|
||||
BitCount += 8;
|
||||
}
|
||||
|
||||
// Return the first available 7 bits. DO NOT remove them from the input stream
|
||||
return (BitBuffer & 0x7F);
|
||||
}
|
||||
|
||||
// Gets one bit from input stream
|
||||
unsigned int TInputStream::Get1Bit()
|
||||
{
|
||||
@ -330,6 +312,30 @@ unsigned int TInputStream::Get8Bits()
|
||||
return dwOneByte;
|
||||
}
|
||||
|
||||
// Gets 7 bits from the stream. DOES NOT remove the bits from input stream
|
||||
bool TInputStream::Peek7Bits(unsigned int & Value)
|
||||
{
|
||||
unsigned int Value8Bits = 0;
|
||||
|
||||
// If there is not enough bits to get the value,
|
||||
// we have to add 8 more bits from the input buffer
|
||||
if(BitCount < 7)
|
||||
{
|
||||
// Load additional 8 bits. Be careful if we have no more data
|
||||
if(pbInBuffer >= pbInBufferEnd)
|
||||
return false;
|
||||
Value8Bits = *pbInBuffer++;
|
||||
|
||||
// Add these 8 bits to the bit buffer
|
||||
BitBuffer |= Value8Bits << BitCount;
|
||||
BitCount += 8;
|
||||
}
|
||||
|
||||
// Return 7 bits of data. DO NOT remove them from the input stream
|
||||
Value = (BitBuffer & 0x7F);
|
||||
return true;
|
||||
}
|
||||
|
||||
void TInputStream::SkipBits(unsigned int dwBitsToSkip)
|
||||
{
|
||||
unsigned int dwReloadByte = 0;
|
||||
@ -696,16 +702,13 @@ unsigned int THuffmannTree::DecodeOneByte(TInputStream * is)
|
||||
THTreeItem * pItem;
|
||||
unsigned int ItemLinkIndex;
|
||||
unsigned int BitCount = 0;
|
||||
bool bHasItemLinkIndex;
|
||||
|
||||
// Check for the end of the input stream
|
||||
if(is->pbInBuffer >= is->pbInBufferEnd && is->BitCount < 7)
|
||||
return 0x1FF;
|
||||
|
||||
// Get the eventual quick-link index
|
||||
ItemLinkIndex = is->Peek7Bits();
|
||||
// Try to retrieve quick link index
|
||||
bHasItemLinkIndex = is->Peek7Bits(ItemLinkIndex);
|
||||
|
||||
// Is the quick-link item valid?
|
||||
if(QuickLinks[ItemLinkIndex].ValidValue > MinValidValue)
|
||||
if(bHasItemLinkIndex && QuickLinks[ItemLinkIndex].ValidValue > MinValidValue)
|
||||
{
|
||||
// If that item needs less than 7 bits, we can get decompressed value directly
|
||||
if(QuickLinks[ItemLinkIndex].ValidBits <= 7)
|
||||
@ -745,7 +748,7 @@ unsigned int THuffmannTree::DecodeOneByte(TInputStream * is)
|
||||
|
||||
// If we didn't get the item from the quick-link array,
|
||||
// set the entry in it
|
||||
if(QuickLinks[ItemLinkIndex].ValidValue < MinValidValue)
|
||||
if(bHasItemLinkIndex && QuickLinks[ItemLinkIndex].ValidValue < MinValidValue)
|
||||
{
|
||||
// If the current compressed byte was more than 7 bits,
|
||||
// set a quick-link item with pointer to tree item
|
||||
@ -876,10 +879,10 @@ unsigned int THuffmannTree::Decompress(void * pvOutBuffer, unsigned int cbOutLen
|
||||
IncWeightsAndRebalance(ItemsByByte[DecompressedValue]);
|
||||
}
|
||||
|
||||
// A byte successfully decoded - store it in the output stream
|
||||
*pbOutBuffer++ = (unsigned char)DecompressedValue;
|
||||
// Store the byte to the output stream
|
||||
if(pbOutBuffer >= pbOutBufferEnd)
|
||||
break;
|
||||
*pbOutBuffer++ = (unsigned char)DecompressedValue;
|
||||
|
||||
if(bIsCmp0)
|
||||
{
|
||||
|
||||
2
vendor/stormlib-9/src/huffman/huff.h
vendored
2
vendor/stormlib-9/src/huffman/huff.h
vendored
@ -29,8 +29,8 @@ class TInputStream
|
||||
|
||||
TInputStream(void * pvInBuffer, size_t cbInBuffer);
|
||||
unsigned int Get1Bit();
|
||||
unsigned int Peek7Bits();
|
||||
unsigned int Get8Bits();
|
||||
bool Peek7Bits(unsigned int & Value);
|
||||
void SkipBits(unsigned int BitCount);
|
||||
|
||||
unsigned char * pbInBufferEnd; // End position in the the input buffer
|
||||
|
||||
340
vendor/stormlib-9/src/libtomcrypt/src/hashes/sha256.c
vendored
Normal file
340
vendor/stormlib-9/src/libtomcrypt/src/hashes/sha256.c
vendored
Normal file
@ -0,0 +1,340 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
|
||||
*
|
||||
* LibTomCrypt is a library that provides various cryptographic
|
||||
* algorithms in a highly modular and flexible manner.
|
||||
*
|
||||
* The library is free for all purposes without any express
|
||||
* guarantee it works.
|
||||
*
|
||||
* Tom St Denis, tomstdenis@gmail.com, http://libtom.org
|
||||
*/
|
||||
#include "../headers/tomcrypt.h"
|
||||
|
||||
/**
|
||||
@file sha256.c
|
||||
LTC_SHA256 by Tom St Denis
|
||||
*/
|
||||
|
||||
#ifdef LTC_SHA256
|
||||
|
||||
const struct ltc_hash_descriptor sha256_desc =
|
||||
{
|
||||
"sha256",
|
||||
0,
|
||||
32,
|
||||
64,
|
||||
|
||||
/* OID */
|
||||
{ 2, 16, 840, 1, 101, 3, 4, 2, 1, },
|
||||
9,
|
||||
|
||||
&sha256_init,
|
||||
&sha256_process,
|
||||
&sha256_done,
|
||||
&sha256_test,
|
||||
NULL
|
||||
};
|
||||
|
||||
#ifdef LTC_SMALL_CODE
|
||||
/* the K array */
|
||||
static const ulong32 K[64] = {
|
||||
0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL,
|
||||
0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL,
|
||||
0x243185beUL, 0x550c7dc3UL, 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL,
|
||||
0xc19bf174UL, 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
|
||||
0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 0x983e5152UL,
|
||||
0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL,
|
||||
0x06ca6351UL, 0x14292967UL, 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL,
|
||||
0x53380d13UL, 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
|
||||
0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL,
|
||||
0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 0x19a4c116UL, 0x1e376c08UL,
|
||||
0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL,
|
||||
0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
|
||||
0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
|
||||
};
|
||||
#endif
|
||||
|
||||
/* Various logical functions */
|
||||
#define Ch(x,y,z) (z ^ (x & (y ^ z)))
|
||||
#define Maj(x,y,z) (((x | y) & z) | (x & y))
|
||||
#define S(x, n) RORc((x),(n))
|
||||
#define R(x, n) (((x)&0xFFFFFFFFUL)>>(n))
|
||||
#define Sigma0(x) (S(x, 2) ^ S(x, 13) ^ S(x, 22))
|
||||
#define Sigma1(x) (S(x, 6) ^ S(x, 11) ^ S(x, 25))
|
||||
#define Gamma0(x) (S(x, 7) ^ S(x, 18) ^ R(x, 3))
|
||||
#define Gamma1(x) (S(x, 17) ^ S(x, 19) ^ R(x, 10))
|
||||
|
||||
/* compress 512-bits */
|
||||
#ifdef LTC_CLEAN_STACK
|
||||
static int _sha256_compress(hash_state * md, unsigned char *buf)
|
||||
#else
|
||||
static int sha256_compress(hash_state * md, unsigned char *buf)
|
||||
#endif
|
||||
{
|
||||
ulong32 S[8], W[64], t0, t1;
|
||||
#ifdef LTC_SMALL_CODE
|
||||
ulong32 t;
|
||||
#endif
|
||||
int i;
|
||||
|
||||
/* copy state into S */
|
||||
for (i = 0; i < 8; i++) {
|
||||
S[i] = md->sha256.state[i];
|
||||
}
|
||||
|
||||
/* copy the state into 512-bits into W[0..15] */
|
||||
for (i = 0; i < 16; i++) {
|
||||
LOAD32H(W[i], buf + (4*i));
|
||||
}
|
||||
|
||||
/* fill W[16..63] */
|
||||
for (i = 16; i < 64; i++) {
|
||||
W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16];
|
||||
}
|
||||
|
||||
/* Compress */
|
||||
#ifdef LTC_SMALL_CODE
|
||||
#define RND(a,b,c,d,e,f,g,h,i) \
|
||||
t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \
|
||||
t1 = Sigma0(a) + Maj(a, b, c); \
|
||||
d += t0; \
|
||||
h = t0 + t1;
|
||||
|
||||
for (i = 0; i < 64; ++i) {
|
||||
RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],i);
|
||||
t = S[7]; S[7] = S[6]; S[6] = S[5]; S[5] = S[4];
|
||||
S[4] = S[3]; S[3] = S[2]; S[2] = S[1]; S[1] = S[0]; S[0] = t;
|
||||
}
|
||||
#else
|
||||
#define RND(a,b,c,d,e,f,g,h,i,ki) \
|
||||
t0 = h + Sigma1(e) + Ch(e, f, g) + ki + W[i]; \
|
||||
t1 = Sigma0(a) + Maj(a, b, c); \
|
||||
d += t0; \
|
||||
h = t0 + t1;
|
||||
|
||||
RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],0,0x428a2f98);
|
||||
RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],1,0x71374491);
|
||||
RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],2,0xb5c0fbcf);
|
||||
RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],3,0xe9b5dba5);
|
||||
RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],4,0x3956c25b);
|
||||
RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],5,0x59f111f1);
|
||||
RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],6,0x923f82a4);
|
||||
RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],7,0xab1c5ed5);
|
||||
RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],8,0xd807aa98);
|
||||
RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],9,0x12835b01);
|
||||
RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],10,0x243185be);
|
||||
RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],11,0x550c7dc3);
|
||||
RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],12,0x72be5d74);
|
||||
RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],13,0x80deb1fe);
|
||||
RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],14,0x9bdc06a7);
|
||||
RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],15,0xc19bf174);
|
||||
RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],16,0xe49b69c1);
|
||||
RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],17,0xefbe4786);
|
||||
RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],18,0x0fc19dc6);
|
||||
RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],19,0x240ca1cc);
|
||||
RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],20,0x2de92c6f);
|
||||
RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],21,0x4a7484aa);
|
||||
RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],22,0x5cb0a9dc);
|
||||
RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],23,0x76f988da);
|
||||
RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],24,0x983e5152);
|
||||
RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],25,0xa831c66d);
|
||||
RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],26,0xb00327c8);
|
||||
RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],27,0xbf597fc7);
|
||||
RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],28,0xc6e00bf3);
|
||||
RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],29,0xd5a79147);
|
||||
RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],30,0x06ca6351);
|
||||
RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],31,0x14292967);
|
||||
RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],32,0x27b70a85);
|
||||
RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],33,0x2e1b2138);
|
||||
RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],34,0x4d2c6dfc);
|
||||
RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],35,0x53380d13);
|
||||
RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],36,0x650a7354);
|
||||
RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],37,0x766a0abb);
|
||||
RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],38,0x81c2c92e);
|
||||
RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],39,0x92722c85);
|
||||
RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],40,0xa2bfe8a1);
|
||||
RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],41,0xa81a664b);
|
||||
RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],42,0xc24b8b70);
|
||||
RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],43,0xc76c51a3);
|
||||
RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],44,0xd192e819);
|
||||
RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],45,0xd6990624);
|
||||
RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],46,0xf40e3585);
|
||||
RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],47,0x106aa070);
|
||||
RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],48,0x19a4c116);
|
||||
RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],49,0x1e376c08);
|
||||
RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],50,0x2748774c);
|
||||
RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],51,0x34b0bcb5);
|
||||
RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],52,0x391c0cb3);
|
||||
RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],53,0x4ed8aa4a);
|
||||
RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],54,0x5b9cca4f);
|
||||
RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],55,0x682e6ff3);
|
||||
RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],56,0x748f82ee);
|
||||
RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],57,0x78a5636f);
|
||||
RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],58,0x84c87814);
|
||||
RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],59,0x8cc70208);
|
||||
RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],60,0x90befffa);
|
||||
RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],61,0xa4506ceb);
|
||||
RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],62,0xbef9a3f7);
|
||||
RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],63,0xc67178f2);
|
||||
|
||||
#undef RND
|
||||
|
||||
#endif
|
||||
|
||||
/* feedback */
|
||||
for (i = 0; i < 8; i++) {
|
||||
md->sha256.state[i] = md->sha256.state[i] + S[i];
|
||||
}
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#ifdef LTC_CLEAN_STACK
|
||||
static int sha256_compress(hash_state * md, unsigned char *buf)
|
||||
{
|
||||
int err;
|
||||
err = _sha256_compress(md, buf);
|
||||
burn_stack(sizeof(ulong32) * 74);
|
||||
return err;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
Initialize the hash state
|
||||
@param md The hash state you wish to initialize
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int sha256_init(hash_state * md)
|
||||
{
|
||||
LTC_ARGCHK(md != NULL);
|
||||
|
||||
md->sha256.curlen = 0;
|
||||
md->sha256.length = 0;
|
||||
md->sha256.state[0] = 0x6A09E667UL;
|
||||
md->sha256.state[1] = 0xBB67AE85UL;
|
||||
md->sha256.state[2] = 0x3C6EF372UL;
|
||||
md->sha256.state[3] = 0xA54FF53AUL;
|
||||
md->sha256.state[4] = 0x510E527FUL;
|
||||
md->sha256.state[5] = 0x9B05688CUL;
|
||||
md->sha256.state[6] = 0x1F83D9ABUL;
|
||||
md->sha256.state[7] = 0x5BE0CD19UL;
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
Process a block of memory though the hash
|
||||
@param md The hash state
|
||||
@param in The data to hash
|
||||
@param inlen The length of the data (octets)
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
HASH_PROCESS(sha256_process, sha256_compress, sha256, 64)
|
||||
|
||||
/**
|
||||
Terminate the hash to get the digest
|
||||
@param md The hash state
|
||||
@param out [out] The destination of the hash (32 bytes)
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int sha256_done(hash_state * md, unsigned char *out)
|
||||
{
|
||||
int i;
|
||||
|
||||
LTC_ARGCHK(md != NULL);
|
||||
LTC_ARGCHK(out != NULL);
|
||||
|
||||
if (md->sha256.curlen >= sizeof(md->sha256.buf)) {
|
||||
return CRYPT_INVALID_ARG;
|
||||
}
|
||||
|
||||
|
||||
/* increase the length of the message */
|
||||
md->sha256.length += md->sha256.curlen * 8;
|
||||
|
||||
/* append the '1' bit */
|
||||
md->sha256.buf[md->sha256.curlen++] = (unsigned char)0x80;
|
||||
|
||||
/* if the length is currently above 56 bytes we append zeros
|
||||
* then compress. Then we can fall back to padding zeros and length
|
||||
* encoding like normal.
|
||||
*/
|
||||
if (md->sha256.curlen > 56) {
|
||||
while (md->sha256.curlen < 64) {
|
||||
md->sha256.buf[md->sha256.curlen++] = (unsigned char)0;
|
||||
}
|
||||
sha256_compress(md, md->sha256.buf);
|
||||
md->sha256.curlen = 0;
|
||||
}
|
||||
|
||||
/* pad upto 56 bytes of zeroes */
|
||||
while (md->sha256.curlen < 56) {
|
||||
md->sha256.buf[md->sha256.curlen++] = (unsigned char)0;
|
||||
}
|
||||
|
||||
/* store length */
|
||||
STORE64H(md->sha256.length, md->sha256.buf+56);
|
||||
sha256_compress(md, md->sha256.buf);
|
||||
|
||||
/* copy output */
|
||||
for (i = 0; i < 8; i++) {
|
||||
STORE32H(md->sha256.state[i], out+(4*i));
|
||||
}
|
||||
#ifdef LTC_CLEAN_STACK
|
||||
zeromem(md, sizeof(hash_state));
|
||||
#endif
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
Self-test the hash
|
||||
@return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
|
||||
*/
|
||||
int sha256_test(void)
|
||||
{
|
||||
#ifndef LTC_TEST
|
||||
return CRYPT_NOP;
|
||||
#else
|
||||
static const struct {
|
||||
char *msg;
|
||||
unsigned char hash[32];
|
||||
} tests[] = {
|
||||
{ "abc",
|
||||
{ 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea,
|
||||
0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23,
|
||||
0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
|
||||
0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad }
|
||||
},
|
||||
{ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
|
||||
{ 0x24, 0x8d, 0x6a, 0x61, 0xd2, 0x06, 0x38, 0xb8,
|
||||
0xe5, 0xc0, 0x26, 0x93, 0x0c, 0x3e, 0x60, 0x39,
|
||||
0xa3, 0x3c, 0xe4, 0x59, 0x64, 0xff, 0x21, 0x67,
|
||||
0xf6, 0xec, 0xed, 0xd4, 0x19, 0xdb, 0x06, 0xc1 }
|
||||
},
|
||||
};
|
||||
|
||||
int i;
|
||||
unsigned char tmp[32];
|
||||
hash_state md;
|
||||
|
||||
for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) {
|
||||
sha256_init(&md);
|
||||
sha256_process(&md, (unsigned char*)tests[i].msg, (unsigned long)strlen(tests[i].msg));
|
||||
sha256_done(&md, tmp);
|
||||
if (XMEMCMP(tmp, tests[i].hash, 32) != 0) {
|
||||
return CRYPT_FAIL_TESTVECTOR;
|
||||
}
|
||||
}
|
||||
return CRYPT_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef LTC_SHA224
|
||||
#include "sha224.c"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* $Source: /cvs/libtom/libtomcrypt/src/hashes/sha2/sha256.c,v $ */
|
||||
/* $Revision: 1.11 $ */
|
||||
/* $Date: 2007/05/12 14:25:28 $ */
|
||||
@ -11,29 +11,29 @@
|
||||
#define LTC_NO_ROLC
|
||||
|
||||
#define LTC_SOURCE
|
||||
#define LTC_SHA256
|
||||
#define LTC_SHA1
|
||||
#define LTC_MD5
|
||||
#define LTC_DER
|
||||
#define LTC_RC4
|
||||
|
||||
#define USE_LTM
|
||||
#define LTM_DESC
|
||||
#define USE_LTM
|
||||
|
||||
/* macros for various libc functions you can change for embedded targets */
|
||||
#ifndef XMALLOC
|
||||
#ifdef malloc
|
||||
#ifdef malloc
|
||||
#define LTC_NO_PROTOTYPES
|
||||
#endif
|
||||
#define XMALLOC LibTomMalloc
|
||||
#endif
|
||||
#ifndef XREALLOC
|
||||
#ifdef realloc
|
||||
#ifdef realloc
|
||||
#define LTC_NO_PROTOTYPES
|
||||
#endif
|
||||
#define XREALLOC LibTomRealloc
|
||||
#endif
|
||||
#ifndef XCALLOC
|
||||
#ifdef calloc
|
||||
#ifdef calloc
|
||||
#define LTC_NO_PROTOTYPES
|
||||
#endif
|
||||
#define XCALLOC LibTomCalloc
|
||||
@ -58,7 +58,7 @@
|
||||
#define XMEMCPY memcpy
|
||||
#endif
|
||||
#ifndef XMEMCMP
|
||||
#ifdef memcmp
|
||||
#ifdef memcmp
|
||||
#define LTC_NO_PROTOTYPES_MEMCMP
|
||||
#endif
|
||||
#define XMEMCMP memcmp
|
||||
@ -91,19 +91,19 @@
|
||||
#define LTC_BLOWFISH
|
||||
#define LTC_DES
|
||||
#define LTC_CAST5
|
||||
|
||||
|
||||
#define LTC_NO_MODES
|
||||
#define LTC_ECB_MODE
|
||||
#define LTC_CBC_MODE
|
||||
#define LTC_CTR_MODE
|
||||
|
||||
|
||||
#define LTC_NO_HASHES
|
||||
#define LTC_SHA1
|
||||
#define LTC_SHA512
|
||||
#define LTC_SHA384
|
||||
#define LTC_SHA256
|
||||
#define LTC_SHA224
|
||||
|
||||
|
||||
#define LTC_NO_MACS
|
||||
#define LTC_HMAC
|
||||
#define LTC_OMAC
|
||||
@ -114,11 +114,11 @@
|
||||
#define LTC_YARROW
|
||||
#define LTC_DEVRANDOM
|
||||
#define TRY_URANDOM_FIRST
|
||||
|
||||
|
||||
#define LTC_NO_PK
|
||||
#define LTC_MRSA
|
||||
#define LTC_MECC
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Use small code where possible */
|
||||
/* #define LTC_SMALL_CODE */
|
||||
@ -194,7 +194,7 @@
|
||||
#define LTC_LRW_MODE
|
||||
#ifndef LTC_NO_TABLES
|
||||
/* like GCM mode this will enable 16 8x128 tables [64KB] that make
|
||||
* seeking very fast.
|
||||
* seeking very fast.
|
||||
*/
|
||||
#define LRW_TABLES
|
||||
#endif
|
||||
@ -205,7 +205,7 @@
|
||||
#endif /* LTC_NO_MODES */
|
||||
|
||||
/* ---> One-Way Hash Functions <--- */
|
||||
#ifndef LTC_NO_HASHES
|
||||
#ifndef LTC_NO_HASHES
|
||||
|
||||
#define LTC_CHC_HASH
|
||||
#define LTC_WHIRLPOOL
|
||||
@ -252,7 +252,7 @@
|
||||
|
||||
/* Use 64KiB tables */
|
||||
#ifndef LTC_NO_TABLES
|
||||
#define LTC_GCM_TABLES
|
||||
#define LTC_GCM_TABLES
|
||||
#endif
|
||||
|
||||
/* USE SSE2? requires GCC works on x86_32 and x86_64*/
|
||||
@ -319,7 +319,7 @@
|
||||
#define LTC_MRSA
|
||||
|
||||
/* Include Katja (a Rabin variant like RSA) */
|
||||
/* #define MKAT */
|
||||
/* #define MKAT */
|
||||
|
||||
/* Digital Signature Algorithm */
|
||||
#define LTC_MDSA
|
||||
@ -332,7 +332,7 @@
|
||||
|
||||
#if defined(TFM_LTC_DESC) && defined(LTC_MECC)
|
||||
#define LTC_MECC_ACCEL
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* do we want fixed point ECC */
|
||||
/* #define LTC_MECC_FP */
|
||||
@ -376,9 +376,9 @@
|
||||
|
||||
#ifdef LTC_MRSA
|
||||
#define LTC_PKCS_1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(LTC_DER) && !defined(MPI)
|
||||
#if defined(LTC_DER) && !defined(MPI)
|
||||
#error ASN.1 DER requires MPI functionality
|
||||
#endif
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user