diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/SBaseDumpData.cpp | 50 | ||||
-rw-r--r-- | src/SBaseFileTable.cpp | 6 | ||||
-rw-r--r-- | src/SFileAddFile.cpp | 20 | ||||
-rw-r--r-- | src/SFileFindFile.cpp | 2 | ||||
-rw-r--r-- | src/SFileGetFileInfo.cpp | 887 | ||||
-rw-r--r-- | src/SFileListFile.cpp | 8 | ||||
-rw-r--r-- | src/SFileOpenArchive.cpp | 2 | ||||
-rw-r--r-- | src/SFileReadFile.cpp | 2 | ||||
-rw-r--r-- | src/StormLib.h | 4 | ||||
-rw-r--r-- | src/huffman/huff.cpp | 61 | ||||
-rw-r--r-- | src/huffman/huff.h | 2 |
11 files changed, 328 insertions, 716 deletions
diff --git a/src/SBaseDumpData.cpp b/src/SBaseDumpData.cpp index 334561b..2454f22 100644 --- a/src/SBaseDumpData.cpp +++ b/src/SBaseDumpData.cpp @@ -111,39 +111,33 @@ void DumpHetAndBetTable(TMPQHetTable * pHetTable, TMPQBetTable * pBetTable) DWORD dwFlags = 0; DWORD dwBetIndex = 0; - GetBits(pHetTable->pBetIndexes, i * pHetTable->dwIndexSizeTotal, - pHetTable->dwIndexSize, - &dwBetIndex, - 4); + GetMPQBits(pHetTable->pBetIndexes, i * pHetTable->dwIndexSizeTotal, + pHetTable->dwIndexSize, + &dwBetIndex, 4); if(dwBetIndex < pHetTable->dwTotalCount) { DWORD dwEntryIndex = pBetTable->dwTableEntrySize * dwBetIndex; - GetBits(pBetTable->pNameHashes, dwBetIndex * pBetTable->dwBitTotal_NameHash2, - pBetTable->dwBitCount_NameHash2, - &BetHash, - 8); - - GetBits(pBetTable->pFileTable, dwEntryIndex + pBetTable->dwBitIndex_FilePos, - pBetTable->dwBitCount_FilePos, - &ByteOffset, - 8); - - GetBits(pBetTable->pFileTable, dwEntryIndex + pBetTable->dwBitIndex_FileSize, - pBetTable->dwBitCount_FileSize, - &dwFileSize, - 4); - - GetBits(pBetTable->pFileTable, dwEntryIndex + pBetTable->dwBitIndex_CmpSize, - pBetTable->dwBitCount_CmpSize, - &dwCmpSize, - 4); - - GetBits(pBetTable->pFileTable, dwEntryIndex + pBetTable->dwBitIndex_FlagIndex, - pBetTable->dwBitCount_FlagIndex, - &dwFlagIndex, - 4); + GetMPQBits(pBetTable->pNameHashes, dwBetIndex * pBetTable->dwBitTotal_NameHash2, + pBetTable->dwBitCount_NameHash2, + &BetHash, 8); + + GetMPQBits(pBetTable->pFileTable, dwEntryIndex + pBetTable->dwBitIndex_FilePos, + pBetTable->dwBitCount_FilePos, + &ByteOffset, 8); + + GetMPQBits(pBetTable->pFileTable, dwEntryIndex + pBetTable->dwBitIndex_FileSize, + pBetTable->dwBitCount_FileSize, + &dwFileSize, 4); + + GetMPQBits(pBetTable->pFileTable, dwEntryIndex + pBetTable->dwBitIndex_CmpSize, + pBetTable->dwBitCount_CmpSize, + &dwCmpSize, 4); + + GetMPQBits(pBetTable->pFileTable, dwEntryIndex + pBetTable->dwBitIndex_FlagIndex, + pBetTable->dwBitCount_FlagIndex, + &dwFlagIndex, 4); dwFlags = pBetTable->pFileFlags[dwFlagIndex]; } diff --git a/src/SBaseFileTable.cpp b/src/SBaseFileTable.cpp index af8d290..7fe1042 100644 --- a/src/SBaseFileTable.cpp +++ b/src/SBaseFileTable.cpp @@ -432,9 +432,9 @@ int ConvertMpqHeaderToFormat4( // If version 1.0 is forced, then the format version is forced to be 1.0
// Reason: Storm.dll in Warcraft III ignores format version value
- if((dwFlags & MPQ_OPEN_FORCE_MPQ_V1) || (MapType == MapTypeWarcraft3))
+ if((MapType == MapTypeWarcraft3) || (dwFlags & MPQ_OPEN_FORCE_MPQ_V1))
wFormatVersion = MPQ_FORMAT_VERSION_1;
- if(MapType == MapTypeStarcraft2)
+ if((MapType == MapTypeStarcraft2) && (pHeader->wFormatVersion > MPQ_FORMAT_VERSION_4))
wFormatVersion = MPQ_FORMAT_VERSION_4;
// Format-specific fixes
@@ -647,7 +647,7 @@ int ConvertMpqHeaderToFormat4( return ERROR_FAKE_MPQ_HEADER;
// Check for malformed MPQs
- if(pHeader->wFormatVersion != MPQ_FORMAT_VERSION_4 || (ha->MpqPos + pHeader->ArchiveSize64) != FileSize || (ha->MpqPos + pHeader->HiBlockTablePos64) >= FileSize)
+ if(pHeader->wFormatVersion != MPQ_FORMAT_VERSION_4 || (MpqOffset + pHeader->ArchiveSize64) != FileSize || (MpqOffset + pHeader->HiBlockTablePos64) >= FileSize)
{
pHeader->wFormatVersion = MPQ_FORMAT_VERSION_4;
pHeader->dwHeaderSize = MPQ_HEADER_SIZE_V4;
diff --git a/src/SFileAddFile.cpp b/src/SFileAddFile.cpp index 7dd583f..e756781 100644 --- a/src/SFileAddFile.cpp +++ b/src/SFileAddFile.cpp @@ -236,7 +236,7 @@ static int WriteDataToMpqFile( // We have to calculate sector CRC, if enabled
if(hf->SectorChksums != NULL)
hf->SectorChksums[dwSectorIndex] = adler32(0, pbCompressed, nOutBuffer);
- }
+ }
// Encrypt the sector, if necessary
if(pFileEntry->dwFlags & MPQ_FILE_ENCRYPTED)
@@ -592,7 +592,7 @@ int SFileAddFile_Write(TMPQFile * hf, const void * pvData, DWORD dwSize, DWORD d if(hf->pPatchInfo == NULL && IsIncrementalPatchFile(pvData, dwSize, &hf->dwPatchedFileSize))
{
// Set the MPQ_FILE_PATCH_FILE flag
- hf->pFileEntry->dwFlags |= MPQ_FILE_PATCH_FILE;
+ pFileEntry->dwFlags |= MPQ_FILE_PATCH_FILE;
// Allocate the patch info
hf->nAddFileError = nError = AllocatePatchInfo(hf, false);
@@ -659,10 +659,10 @@ int SFileAddFile_Write(TMPQFile * hf, const void * pvData, DWORD dwSize, DWORD d if(hf->dwFilePos >= pFileEntry->dwFileSize)
{
// Finish calculating CRC32
- hf->pFileEntry->dwCrc32 = hf->dwCrc32;
+ pFileEntry->dwCrc32 = hf->dwCrc32;
// Finish calculating MD5
- md5_done((hash_state *)hf->hctx, hf->pFileEntry->md5);
+ md5_done((hash_state *)hf->hctx, pFileEntry->md5);
// If we also have sector checksums, write them to the file
if(hf->SectorChksums != NULL)
@@ -673,9 +673,9 @@ int SFileAddFile_Write(TMPQFile * hf, const void * pvData, DWORD dwSize, DWORD d // Now write patch info
if(hf->pPatchInfo != NULL)
{
- memcpy(hf->pPatchInfo->md5, hf->pFileEntry->md5, MD5_DIGEST_SIZE);
- hf->pPatchInfo->dwDataSize = hf->pFileEntry->dwFileSize;
- hf->pFileEntry->dwFileSize = hf->dwPatchedFileSize;
+ memcpy(hf->pPatchInfo->md5, pFileEntry->md5, MD5_DIGEST_SIZE);
+ hf->pPatchInfo->dwDataSize = pFileEntry->dwFileSize;
+ pFileEntry->dwFileSize = hf->dwPatchedFileSize;
nError = WritePatchInfo(hf);
}
@@ -689,13 +689,17 @@ int SFileAddFile_Write(TMPQFile * hf, const void * pvData, DWORD dwSize, DWORD d if(ha->pHeader->dwRawChunkSize != 0)
{
nError = WriteMpqDataMD5(ha->pStream,
- ha->MpqPos + hf->pFileEntry->ByteOffset,
+ ha->MpqPos + pFileEntry->ByteOffset,
hf->pFileEntry->dwCmpSize,
ha->pHeader->dwRawChunkSize);
}
}
}
+ // Update the archive size
+ if((ha->MpqPos + pFileEntry->ByteOffset + pFileEntry->dwCmpSize) > ha->FileSize)
+ ha->FileSize = ha->MpqPos + pFileEntry->ByteOffset + pFileEntry->dwCmpSize;
+
// Store the error code from the Write File operation
hf->nAddFileError = nError;
return nError;
diff --git a/src/SFileFindFile.cpp b/src/SFileFindFile.cpp index 7e8502b..6a4cecd 100644 --- a/src/SFileFindFile.cpp +++ b/src/SFileFindFile.cpp @@ -238,6 +238,8 @@ static bool DoMPQSearch_FileEntry( // Prepare the block index
dwBlockIndex = (DWORD)(pFileEntry - ha->pFileTable);
+ if(dwBlockIndex == 569)
+ szNameBuff[0] = 'F';
// Get the file name. If it's not known, we will create pseudo-name
szFileName = pFileEntry->szFileName;
diff --git a/src/SFileGetFileInfo.cpp b/src/SFileGetFileInfo.cpp index c57b3b7..4ec05e2 100644 --- a/src/SFileGetFileInfo.cpp +++ b/src/SFileGetFileInfo.cpp @@ -13,35 +13,8 @@ #include "StormCommon.h"
//-----------------------------------------------------------------------------
-// Local defines
-
-// Information types for SFileGetFileInfo
-#define SFILE_INFO_TYPE_INVALID_HANDLE 0
-#define SFILE_INFO_TYPE_NOT_FOUND 1
-#define SFILE_INFO_TYPE_DIRECT_POINTER 2
-#define SFILE_INFO_TYPE_ALLOCATED 3
-#define SFILE_INFO_TYPE_READ_FROM_FILE 4
-#define SFILE_INFO_TYPE_TABLE_POINTER 5
-#define SFILE_INFO_TYPE_FILE_ENTRY 6
-
-//-----------------------------------------------------------------------------
// Local functions
-static void ConvertFileEntryToSelfRelative(TFileEntry * pFileEntry, TFileEntry * pSrcFileEntry)
-{
- // Copy the file entry itself
- memcpy(pFileEntry, pSrcFileEntry, sizeof(TFileEntry));
-
- // If source is NULL, leave it NULL
- if(pSrcFileEntry->szFileName != NULL)
- {
- // Set the file name pointer after the file entry
- pFileEntry->szFileName = (char *)(pFileEntry + 1);
- strcpy(pFileEntry->szFileName, pSrcFileEntry->szFileName);
- }
-}
-
-
static DWORD GetMpqFileCount(TMPQArchive * ha)
{
TFileEntry * pFileTableEnd;
@@ -69,56 +42,138 @@ static DWORD GetMpqFileCount(TMPQArchive * ha) return dwFileCount;
}
-static bool GetFilePatchChain(TMPQFile * hf, void * pvFileInfo, DWORD cbFileInfo, DWORD * pcbLengthNeeded)
+static bool GetInfo_ReturnError(DWORD dwErrCode)
+{
+ SetLastError(dwErrCode);
+ return false;
+}
+
+static bool GetInfo_BufferCheck(void * pvFileInfo, DWORD cbFileInfo, DWORD cbData, LPDWORD pcbLengthNeeded)
+{
+ // Give the length needed to store the info
+ if(pcbLengthNeeded != NULL)
+ pcbLengthNeeded[0] = cbData;
+
+ // Check for sufficient buffer
+ if(cbData > cbFileInfo)
+ return GetInfo_ReturnError(ERROR_INSUFFICIENT_BUFFER);
+
+ // If the buffer size is sufficient, check for valid user buffer
+ if(pvFileInfo == NULL)
+ return GetInfo_ReturnError(ERROR_INVALID_PARAMETER);
+
+ // Buffers and sizes are OK, we are ready to proceed file copying
+ return true;
+}
+
+static bool GetInfo(void * pvFileInfo, DWORD cbFileInfo, const void * pvData, DWORD cbData, LPDWORD pcbLengthNeeded)
+{
+ // Verify buffer pointer and buffer size
+ if(!GetInfo_BufferCheck(pvFileInfo, cbFileInfo, cbData, pcbLengthNeeded))
+ return false;
+
+ // Copy the data to the caller-supplied buffer
+ memcpy(pvFileInfo, pvData, cbData);
+ return true;
+}
+
+static bool GetInfo_Allocated(void * pvFileInfo, DWORD cbFileInfo, void * pvData, DWORD cbData, LPDWORD pcbLengthNeeded)
+{
+ bool bResult;
+
+ // Verify buffer pointer and buffer size
+ if((bResult = GetInfo_BufferCheck(pvFileInfo, cbFileInfo, cbData, pcbLengthNeeded)) != false)
+ memcpy(pvFileInfo, pvData, cbData);
+
+ // Copy the data to the user buffer
+ STORM_FREE(pvData);
+ return bResult;
+}
+
+static bool GetInfo_TablePointer(void * pvFileInfo, DWORD cbFileInfo, void * pvTablePointer, SFileInfoClass InfoClass, LPDWORD pcbLengthNeeded)
+{
+ // Verify buffer pointer and buffer size
+ if(!GetInfo_BufferCheck(pvFileInfo, cbFileInfo, sizeof(void *), pcbLengthNeeded))
+ {
+ SFileFreeFileInfo(pvTablePointer, InfoClass);
+ return false;
+ }
+
+ // The user buffer receives pointer to the table.
+ // When done, the caller needs to call SFileFreeFileInfo on it
+ *(void **)pvFileInfo = pvTablePointer;
+ return true;
+}
+
+static bool GetInfo_ReadFromFile(void * pvFileInfo, DWORD cbFileInfo, TFileStream * pStream, ULONGLONG ByteOffset, DWORD cbData, LPDWORD pcbLengthNeeded)
+{
+ // Verify buffer pointer and buffer size
+ if(!GetInfo_BufferCheck(pvFileInfo, cbFileInfo, cbData, pcbLengthNeeded))
+ return false;
+
+ return FileStream_Read(pStream, &ByteOffset, pvFileInfo, cbData);
+}
+
+static bool GetInfo_FileEntry(void * pvFileInfo, DWORD cbFileInfo, TFileEntry * pFileEntry, LPDWORD pcbLengthNeeded)
+{
+ LPBYTE pbFileInfo = (LPBYTE)pvFileInfo;
+ DWORD cbSrcFileInfo = sizeof(TFileEntry);
+ DWORD cbFileName = 1;
+
+ // The file name belongs to the file entry
+ if(pFileEntry->szFileName)
+ cbFileName = (DWORD)strlen(pFileEntry->szFileName) + 1;
+ cbSrcFileInfo += cbFileName;
+
+ // Verify buffer pointer and buffer size
+ if(!GetInfo_BufferCheck(pvFileInfo, cbFileInfo, cbSrcFileInfo, pcbLengthNeeded))
+ return false;
+
+ // Copy the file entry
+ memcpy(pbFileInfo, pFileEntry, sizeof(TFileEntry));
+ pbFileInfo += sizeof(TFileEntry);
+ pbFileInfo[0] = 0;
+
+ // Copy the file name
+ if(pFileEntry->szFileName)
+ memcpy(pbFileInfo, pFileEntry->szFileName, cbFileName);
+ return true;
+}
+
+static bool GetInfo_PatchChain(TMPQFile * hf, void * pvFileInfo, DWORD cbFileInfo, LPDWORD pcbLengthNeeded)
{
TMPQFile * hfTemp;
- TCHAR * szFileInfo = (TCHAR *)pvFileInfo;
+ LPCTSTR szPatchName;
+ LPTSTR szFileInfo = (LPTSTR)pvFileInfo;
size_t cchCharsNeeded = 1;
- size_t cchFileInfo = (cbFileInfo / sizeof(TCHAR));
size_t nLength;
- // Patch chain is only supported on MPQ files.
+ // Patch chain is only supported on MPQ files. Local files are not supported.
if(hf->pStream != NULL)
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return false;
- }
+ return GetInfo_ReturnError(ERROR_INVALID_PARAMETER);
// Calculate the necessary length of the multi-string
for(hfTemp = hf; hfTemp != NULL; hfTemp = hfTemp->hfPatch)
cchCharsNeeded += _tcslen(FileStream_GetFileName(hfTemp->ha->pStream)) + 1;
- // Give the caller the needed length
- if(pcbLengthNeeded != NULL)
- pcbLengthNeeded[0] = (DWORD)(cchCharsNeeded * sizeof(TCHAR));
+ // Verify whether the caller gave us valid buffer with enough size
+ if(!GetInfo_BufferCheck(pvFileInfo, cbFileInfo, (DWORD)(cchCharsNeeded * sizeof(TCHAR)), pcbLengthNeeded))
+ return false;
- // If the caller gave both buffer pointer and data length,
- // try to copy the patch chain
- if(szFileInfo != NULL && cchFileInfo != 0)
+ // Copy each patch name
+ for(hfTemp = hf; hfTemp != NULL; hfTemp = hfTemp->hfPatch)
{
- // If there is enough space in the buffer, copy the patch chain
- if(cchCharsNeeded > cchFileInfo)
- {
- SetLastError(ERROR_INSUFFICIENT_BUFFER);
- return false;
- }
+ // Get the file name and its length
+ szPatchName = FileStream_GetFileName(hfTemp->ha->pStream);
+ nLength = _tcslen(szPatchName) + 1;
- // Copy each patch
- for(hfTemp = hf; hfTemp != NULL; hfTemp = hfTemp->hfPatch)
- {
- // Get the file name and its length
- const TCHAR * szFileName = FileStream_GetFileName(hfTemp->ha->pStream);
- nLength = _tcslen(szFileName) + 1;
-
- // Copy the file name
- memcpy(szFileInfo, szFileName, nLength * sizeof(TCHAR));
- szFileInfo += nLength;
- }
-
- // Make it multi-string
- szFileInfo[0] = 0;
+ // Copy the file name
+ memcpy(szFileInfo, szPatchName, nLength * sizeof(TCHAR));
+ szFileInfo += nLength;
}
+ // Make it multi-string
+ szFileInfo[0] = 0;
return true;
}
@@ -139,719 +194,253 @@ bool WINAPI SFileGetFileInfo( LPDWORD pcbLengthNeeded)
{
MPQ_SIGNATURE_INFO SignatureInfo;
+ const TCHAR * szSrcFileInfo;
TMPQArchive * ha = NULL;
TFileEntry * pFileEntry = NULL;
+ TMPQHeader * pHeader = NULL;
ULONGLONG Int64Value = 0;
- ULONGLONG ByteOffset = 0;
TMPQFile * hf = NULL;
void * pvSrcFileInfo = NULL;
DWORD cbSrcFileInfo = 0;
DWORD dwInt32Value = 0;
- int nInfoType = SFILE_INFO_TYPE_INVALID_HANDLE;
- int nError = ERROR_SUCCESS;
+ // Validate archive/file handle
+ if((int)InfoClass <= (int)SFileMpqFlags)
+ {
+ if((ha = IsValidMpqHandle(hMpqOrFile)) == NULL)
+ return GetInfo_ReturnError(ERROR_INVALID_HANDLE);
+ pHeader = ha->pHeader;
+ }
+ else
+ {
+ if((hf = IsValidFileHandle(hMpqOrFile)) == NULL)
+ return GetInfo_ReturnError(ERROR_INVALID_HANDLE);
+ pFileEntry = hf->pFileEntry;
+ }
+
+ // Return info-class-specific data
switch(InfoClass)
{
case SFileMpqFileName:
- ha = IsValidMpqHandle(hMpqOrFile);
- if(ha != NULL)
- {
- pvSrcFileInfo = (void *)FileStream_GetFileName(ha->pStream);
- cbSrcFileInfo = (DWORD)(_tcslen((TCHAR *)pvSrcFileInfo) + 1) * sizeof(TCHAR);
- nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
- }
- break;
+ szSrcFileInfo = FileStream_GetFileName(ha->pStream);
+ cbSrcFileInfo = (DWORD)((_tcslen(szSrcFileInfo) + 1) * sizeof(TCHAR));
+ return GetInfo(pvFileInfo, cbFileInfo, szSrcFileInfo, cbSrcFileInfo, pcbLengthNeeded);
case SFileMpqStreamBitmap:
- ha = IsValidMpqHandle(hMpqOrFile);
- if(ha != NULL)
- return FileStream_GetBitmap(ha->pStream, pvFileInfo, cbFileInfo, pcbLengthNeeded);
- break;
+ return FileStream_GetBitmap(ha->pStream, pvFileInfo, cbFileInfo, pcbLengthNeeded);
case SFileMpqUserDataOffset:
- ha = IsValidMpqHandle(hMpqOrFile);
- if(ha != NULL)
- {
- nInfoType = SFILE_INFO_TYPE_NOT_FOUND;
- if(ha->pUserData != NULL)
- {
- pvSrcFileInfo = &ha->UserDataPos;
- cbSrcFileInfo = sizeof(ULONGLONG);
- nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
- }
- }
- break;
+ return GetInfo(pvFileInfo, cbFileInfo, &ha->UserDataPos, sizeof(ULONGLONG), pcbLengthNeeded);
case SFileMpqUserDataHeader:
- ha = IsValidMpqHandle(hMpqOrFile);
- if(ha != NULL)
- {
- nInfoType = SFILE_INFO_TYPE_NOT_FOUND;
- if(ha->pUserData != NULL)
- {
- ByteOffset = ha->UserDataPos;
- cbSrcFileInfo = sizeof(TMPQUserData);
- nInfoType = SFILE_INFO_TYPE_READ_FROM_FILE;
- }
- }
- break;
+ return GetInfo_ReadFromFile(pvFileInfo, cbFileInfo, ha->pStream, ha->UserDataPos, sizeof(TMPQUserData), pcbLengthNeeded);
case SFileMpqUserData:
- ha = IsValidMpqHandle(hMpqOrFile);
- if(ha != NULL)
- {
- nInfoType = SFILE_INFO_TYPE_NOT_FOUND;
- if(ha->pUserData != NULL)
- {
- ByteOffset = ha->UserDataPos + sizeof(TMPQUserData);
- cbSrcFileInfo = ha->pUserData->dwHeaderOffs - sizeof(TMPQUserData);
- nInfoType = SFILE_INFO_TYPE_READ_FROM_FILE;
- }
- }
- break;
+ return GetInfo_ReadFromFile(pvFileInfo, cbFileInfo, ha->pStream, ha->UserDataPos + sizeof(TMPQUserData), ha->pUserData->dwHeaderOffs - sizeof(TMPQUserData), pcbLengthNeeded);
case SFileMpqHeaderOffset:
- ha = IsValidMpqHandle(hMpqOrFile);
- if(ha != NULL)
- {
- pvSrcFileInfo = &ha->MpqPos;
- cbSrcFileInfo = sizeof(ULONGLONG);
- nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
- }
- break;
+ return GetInfo(pvFileInfo, cbFileInfo, &ha->MpqPos, sizeof(ULONGLONG), pcbLengthNeeded);
case SFileMpqHeaderSize:
- ha = IsValidMpqHandle(hMpqOrFile);
- if(ha != NULL)
- {
- pvSrcFileInfo = &ha->pHeader->dwHeaderSize;
- cbSrcFileInfo = sizeof(DWORD);
- nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
- }
- break;
+ return GetInfo(pvFileInfo, cbFileInfo, &pHeader->dwHeaderSize, sizeof(DWORD), pcbLengthNeeded);
case SFileMpqHeader:
- ha = IsValidMpqHandle(hMpqOrFile);
- if(ha != NULL)
- {
- ByteOffset = ha->MpqPos;
- cbSrcFileInfo = ha->pHeader->dwHeaderSize;
- nInfoType = SFILE_INFO_TYPE_READ_FROM_FILE;
- }
- break;
+ return GetInfo_ReadFromFile(pvFileInfo, cbFileInfo, ha->pStream, ha->MpqPos, pHeader->dwHeaderSize, pcbLengthNeeded);
case SFileMpqHetTableOffset:
- ha = IsValidMpqHandle(hMpqOrFile);
- if(ha != NULL)
- {
- pvSrcFileInfo = &ha->pHeader->HetTablePos64;
- cbSrcFileInfo = sizeof(ULONGLONG);
- nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
- }
- break;
+ return GetInfo(pvFileInfo, cbFileInfo, &pHeader->HetTablePos64, sizeof(ULONGLONG), pcbLengthNeeded);
case SFileMpqHetTableSize:
- ha = IsValidMpqHandle(hMpqOrFile);
- if(ha != NULL)
- {
- pvSrcFileInfo = &ha->pHeader->HetTableSize64;
- cbSrcFileInfo = sizeof(ULONGLONG);
- nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
- }
- break;
+ return GetInfo(pvFileInfo, cbFileInfo, &pHeader->HetTableSize64, sizeof(ULONGLONG), pcbLengthNeeded);
case SFileMpqHetHeader:
- ha = IsValidMpqHandle(hMpqOrFile);
- if(ha != NULL)
- {
- nInfoType = SFILE_INFO_TYPE_NOT_FOUND;
- pvSrcFileInfo = LoadExtTable(ha, ha->pHeader->HetTablePos64, (size_t)ha->pHeader->HetTableSize64, HET_TABLE_SIGNATURE, MPQ_KEY_HASH_TABLE);
- if(pvSrcFileInfo != NULL)
- {
- cbSrcFileInfo = sizeof(TMPQHetHeader);
- nInfoType = SFILE_INFO_TYPE_ALLOCATED;
- }
- }
- break;
+ pvSrcFileInfo = LoadExtTable(ha, pHeader->HetTablePos64, (size_t)pHeader->HetTableSize64, HET_TABLE_SIGNATURE, MPQ_KEY_HASH_TABLE);
+ if(pvSrcFileInfo == NULL)
+ return GetInfo_ReturnError(ERROR_FILE_NOT_FOUND);
+ return GetInfo_Allocated(pvFileInfo, cbFileInfo, pvSrcFileInfo, sizeof(TMPQHetHeader), pcbLengthNeeded);
case SFileMpqHetTable:
- ha = IsValidMpqHandle(hMpqOrFile);
- if(ha != NULL)
- {
- nInfoType = SFILE_INFO_TYPE_NOT_FOUND;
- pvSrcFileInfo = LoadHetTable(ha);
- if(pvSrcFileInfo != NULL)
- {
- cbSrcFileInfo = sizeof(void *);
- nInfoType = SFILE_INFO_TYPE_TABLE_POINTER;
- }
- }
- break;
+ if((pvSrcFileInfo = LoadHetTable(ha)) == NULL)
+ return GetInfo_ReturnError(ERROR_NOT_ENOUGH_MEMORY);
+ return GetInfo_TablePointer(pvFileInfo, cbFileInfo, pvSrcFileInfo, InfoClass, pcbLengthNeeded);
case SFileMpqBetTableOffset:
- ha = IsValidMpqHandle(hMpqOrFile);
- if(ha != NULL)
- {
- pvSrcFileInfo = &ha->pHeader->BetTablePos64;
- cbSrcFileInfo = sizeof(ULONGLONG);
- nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
- }
- break;
+ return GetInfo(pvFileInfo, cbFileInfo, &pHeader->BetTablePos64, sizeof(ULONGLONG), pcbLengthNeeded);
case SFileMpqBetTableSize:
- ha = IsValidMpqHandle(hMpqOrFile);
- if(ha != NULL)
- {
- pvSrcFileInfo = &ha->pHeader->BetTableSize64;
- cbSrcFileInfo = sizeof(ULONGLONG);
- nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
- }
- break;
+ return GetInfo(pvFileInfo, cbFileInfo, &pHeader->BetTableSize64, sizeof(ULONGLONG), pcbLengthNeeded);
case SFileMpqBetHeader:
- ha = IsValidMpqHandle(hMpqOrFile);
- if(ha != NULL)
- {
- nInfoType = SFILE_INFO_TYPE_NOT_FOUND;
- pvSrcFileInfo = LoadExtTable(ha, ha->pHeader->BetTablePos64, (size_t)ha->pHeader->BetTableSize64, BET_TABLE_SIGNATURE, MPQ_KEY_BLOCK_TABLE);
- if(pvSrcFileInfo != NULL)
- {
- // It is allowed for the caller to only require BET header.
- cbSrcFileInfo = sizeof(TMPQBetHeader) + ((TMPQBetHeader *)pvSrcFileInfo)->dwFlagCount * sizeof(DWORD);
- if(cbFileInfo == sizeof(TMPQBetHeader))
- cbSrcFileInfo = sizeof(TMPQBetHeader);
- nInfoType = SFILE_INFO_TYPE_ALLOCATED;
- }
- }
- break;
+
+ // Retrieve the table and its size
+ pvSrcFileInfo = LoadExtTable(ha, pHeader->BetTablePos64, (size_t)pHeader->BetTableSize64, BET_TABLE_SIGNATURE, MPQ_KEY_BLOCK_TABLE);
+ if(pvSrcFileInfo == NULL)
+ return GetInfo_ReturnError(ERROR_FILE_NOT_FOUND);
+ cbSrcFileInfo = sizeof(TMPQBetHeader) + ((TMPQBetHeader *)pvSrcFileInfo)->dwFlagCount * sizeof(DWORD);
+
+ // It is allowed for the caller to only require BET header
+ if(cbFileInfo == sizeof(TMPQBetHeader))
+ cbSrcFileInfo = sizeof(TMPQBetHeader);
+ return GetInfo_Allocated(pvFileInfo, cbFileInfo, pvSrcFileInfo, cbSrcFileInfo, pcbLengthNeeded);
case SFileMpqBetTable:
- ha = IsValidMpqHandle(hMpqOrFile);
- if(ha != NULL)
- {
- nInfoType = SFILE_INFO_TYPE_NOT_FOUND;
- pvSrcFileInfo = LoadBetTable(ha);
- if(pvSrcFileInfo != NULL)
- {
- cbSrcFileInfo = sizeof(void *);
- nInfoType = SFILE_INFO_TYPE_TABLE_POINTER;
- }
- }
- break;
+ if((pvSrcFileInfo = LoadBetTable(ha)) == NULL)
+ return GetInfo_ReturnError(ERROR_NOT_ENOUGH_MEMORY);
+ return GetInfo_TablePointer(pvFileInfo, cbFileInfo, pvSrcFileInfo, InfoClass, pcbLengthNeeded);
case SFileMpqHashTableOffset:
- ha = IsValidMpqHandle(hMpqOrFile);
- if(ha != NULL)
- {
- Int64Value = MAKE_OFFSET64(ha->pHeader->wHashTablePosHi, ha->pHeader->dwHashTablePos);
- pvSrcFileInfo = &Int64Value;
- cbSrcFileInfo = sizeof(ULONGLONG);
- nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
- }
- break;
+ Int64Value = MAKE_OFFSET64(pHeader->wHashTablePosHi, pHeader->dwHashTablePos);
+ return GetInfo(pvFileInfo, cbFileInfo, &Int64Value, sizeof(ULONGLONG), pcbLengthNeeded);
case SFileMpqHashTableSize64:
- ha = IsValidMpqHandle(hMpqOrFile);
- if(ha != NULL)
- {
- pvSrcFileInfo = &ha->pHeader->HashTableSize64;
- cbSrcFileInfo = sizeof(ULONGLONG);
- nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
- }
- break;
+ return GetInfo(pvFileInfo, cbFileInfo, &pHeader->HashTableSize64, sizeof(ULONGLONG), pcbLengthNeeded);
case SFileMpqHashTableSize:
- ha = IsValidMpqHandle(hMpqOrFile);
- if(ha != NULL)
- {
- pvSrcFileInfo = &ha->pHeader->dwHashTableSize;
- cbSrcFileInfo = sizeof(DWORD);
- nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
- }
- break;
+ return GetInfo(pvFileInfo, cbFileInfo, &pHeader->dwHashTableSize, sizeof(DWORD), pcbLengthNeeded);
case SFileMpqHashTable:
- ha = IsValidMpqHandle(hMpqOrFile);
- if(ha != NULL && ha->pHashTable != NULL)
- {
- pvSrcFileInfo = ha->pHashTable;
- cbSrcFileInfo = ha->pHeader->dwHashTableSize * sizeof(TMPQHash);
- nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
- }
- break;
+ cbSrcFileInfo = pHeader->dwHashTableSize * sizeof(TMPQHash);
+ return GetInfo(pvFileInfo, cbFileInfo, ha->pHashTable, cbSrcFileInfo, pcbLengthNeeded);
case SFileMpqBlockTableOffset:
- ha = IsValidMpqHandle(hMpqOrFile);
- if(ha != NULL)
- {
- Int64Value = MAKE_OFFSET64(ha->pHeader->wBlockTablePosHi, ha->pHeader->dwBlockTablePos);
- pvSrcFileInfo = &Int64Value;
- cbSrcFileInfo = sizeof(ULONGLONG);
- nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
- }
- break;
+ Int64Value = MAKE_OFFSET64(pHeader->wBlockTablePosHi, pHeader->dwBlockTablePos);
+ return GetInfo(pvFileInfo, cbFileInfo, &Int64Value, sizeof(ULONGLONG), pcbLengthNeeded);
case SFileMpqBlockTableSize64:
- ha = IsValidMpqHandle(hMpqOrFile);
- if(ha != NULL)
- {
- pvSrcFileInfo = &ha->pHeader->BlockTableSize64;
- cbSrcFileInfo = sizeof(ULONGLONG);
- nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
- }
- break;
+ return GetInfo(pvFileInfo, cbFileInfo, &pHeader->BlockTableSize64, sizeof(ULONGLONG), pcbLengthNeeded);
case SFileMpqBlockTableSize:
- ha = IsValidMpqHandle(hMpqOrFile);
- if(ha != NULL)
- {
- pvSrcFileInfo = &ha->pHeader->dwBlockTableSize;
- cbSrcFileInfo = sizeof(DWORD);
- nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
- }
- break;
+ return GetInfo(pvFileInfo, cbFileInfo, &pHeader->dwBlockTableSize, sizeof(DWORD), pcbLengthNeeded);
case SFileMpqBlockTable:
- ha = IsValidMpqHandle(hMpqOrFile);
- if(ha != NULL)
- {
- nInfoType = SFILE_INFO_TYPE_NOT_FOUND;
- if(MAKE_OFFSET64(ha->pHeader->wBlockTablePosHi, ha->pHeader->dwBlockTablePos) < ha->FileSize)
- {
- cbSrcFileInfo = ha->pHeader->dwBlockTableSize * sizeof(TMPQBlock);
- if(cbFileInfo >= cbSrcFileInfo)
- pvSrcFileInfo = LoadBlockTable(ha, true);
- nInfoType = SFILE_INFO_TYPE_ALLOCATED;
- }
- }
- break;
+ if(MAKE_OFFSET64(pHeader->wBlockTablePosHi, pHeader->dwBlockTablePos) >= ha->FileSize)
+ return GetInfo_ReturnError(ERROR_FILE_NOT_FOUND);
+ cbSrcFileInfo = pHeader->dwBlockTableSize * sizeof(TMPQBlock);
+ pvSrcFileInfo = LoadBlockTable(ha, true);
+ return GetInfo_Allocated(pvFileInfo, cbFileInfo, pvSrcFileInfo, cbSrcFileInfo, pcbLengthNeeded);
case SFileMpqHiBlockTableOffset:
- ha = IsValidMpqHandle(hMpqOrFile);
- if(ha != NULL)
- {
- pvSrcFileInfo = &ha->pHeader->HiBlockTablePos64;
- cbSrcFileInfo = sizeof(ULONGLONG);
- nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
- }
- break;
+ return GetInfo(pvFileInfo, cbFileInfo, &pHeader->HiBlockTablePos64, sizeof(ULONGLONG), pcbLengthNeeded);
case SFileMpqHiBlockTableSize64:
- ha = IsValidMpqHandle(hMpqOrFile);
- if(ha != NULL)
- {
- pvSrcFileInfo = &ha->pHeader->HiBlockTableSize64;
- cbSrcFileInfo = sizeof(ULONGLONG);
- nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
- }
- break;
+ return GetInfo(pvFileInfo, cbFileInfo, &pHeader->HiBlockTableSize64, sizeof(ULONGLONG), pcbLengthNeeded);
case SFileMpqHiBlockTable:
- ha = IsValidMpqHandle(hMpqOrFile);
- if(ha != NULL)
- {
- nInfoType = SFILE_INFO_TYPE_NOT_FOUND;
- if(ha->pHeader->HiBlockTablePos64 && ha->pHeader->HiBlockTableSize64)
- {
- assert(false);
- }
- }
- break;
+ return GetInfo_ReturnError(ERROR_FILE_NOT_FOUND);
case SFileMpqSignatures:
- ha = IsValidMpqHandle(hMpqOrFile);
- if(ha != NULL && QueryMpqSignatureInfo(ha, &SignatureInfo))
- {
- pvSrcFileInfo = &SignatureInfo.SignatureTypes;
- cbSrcFileInfo = sizeof(DWORD);
- nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
- }
- break;
+ if(!QueryMpqSignatureInfo(ha, &SignatureInfo))
+ return GetInfo_ReturnError(ERROR_FILE_NOT_FOUND);
+ return GetInfo(pvFileInfo, cbFileInfo, &SignatureInfo.SignatureTypes, sizeof(DWORD), pcbLengthNeeded);
case SFileMpqStrongSignatureOffset:
- ha = IsValidMpqHandle(hMpqOrFile);
- if(ha != NULL)
- {
- nInfoType = SFILE_INFO_TYPE_NOT_FOUND;
- if(QueryMpqSignatureInfo(ha, &SignatureInfo) && (SignatureInfo.SignatureTypes & SIGNATURE_TYPE_STRONG))
- {
- pvSrcFileInfo = &SignatureInfo.EndMpqData;
- cbSrcFileInfo = sizeof(ULONGLONG);
- nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
- }
- }
- break;
+ if(QueryMpqSignatureInfo(ha, &SignatureInfo) == false || (SignatureInfo.SignatureTypes & SIGNATURE_TYPE_STRONG) == 0)
+ return GetInfo_ReturnError(ERROR_FILE_NOT_FOUND);
+ return GetInfo(pvFileInfo, cbFileInfo, &SignatureInfo.EndMpqData, sizeof(ULONGLONG), pcbLengthNeeded);
case SFileMpqStrongSignatureSize:
- ha = IsValidMpqHandle(hMpqOrFile);
- if(ha != NULL)
- {
- nInfoType = SFILE_INFO_TYPE_NOT_FOUND;
- if(QueryMpqSignatureInfo(ha, &SignatureInfo) && (SignatureInfo.SignatureTypes & SIGNATURE_TYPE_STRONG))
- {
- dwInt32Value = MPQ_STRONG_SIGNATURE_SIZE + 4;
- pvSrcFileInfo = &dwInt32Value;
- cbSrcFileInfo = sizeof(DWORD);
- nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
- }
- }
- break;
+ if(QueryMpqSignatureInfo(ha, &SignatureInfo) == false || (SignatureInfo.SignatureTypes & SIGNATURE_TYPE_STRONG) == 0)
+ return GetInfo_ReturnError(ERROR_FILE_NOT_FOUND);
+ dwInt32Value = MPQ_STRONG_SIGNATURE_SIZE + 4;
+ return GetInfo(pvFileInfo, cbFileInfo, &dwInt32Value, sizeof(DWORD), pcbLengthNeeded);
case SFileMpqStrongSignature:
- ha = IsValidMpqHandle(hMpqOrFile);
- if(ha != NULL)
- {
- nInfoType = SFILE_INFO_TYPE_NOT_FOUND;
- if(QueryMpqSignatureInfo(ha, &SignatureInfo) && (SignatureInfo.SignatureTypes & SIGNATURE_TYPE_STRONG))
- {
- pvSrcFileInfo = SignatureInfo.Signature;
- cbSrcFileInfo = MPQ_STRONG_SIGNATURE_SIZE + 4;
- nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
- }
- }
- break;
+ if(QueryMpqSignatureInfo(ha, &SignatureInfo) == false || (SignatureInfo.SignatureTypes & SIGNATURE_TYPE_STRONG) == 0)
+ return GetInfo_ReturnError(ERROR_FILE_NOT_FOUND);
+ return GetInfo(pvFileInfo, cbFileInfo, SignatureInfo.Signature, MPQ_STRONG_SIGNATURE_SIZE + 4, pcbLengthNeeded);
case SFileMpqArchiveSize64:
- ha = IsValidMpqHandle(hMpqOrFile);
- if(ha != NULL)
- {
- pvSrcFileInfo = &ha->pHeader->ArchiveSize64;
- cbSrcFileInfo = sizeof(DWORD);
- nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
- }
- break;
+ return GetInfo(pvFileInfo, cbFileInfo, &pHeader->ArchiveSize64, sizeof(ULONGLONG), pcbLengthNeeded);
case SFileMpqArchiveSize:
- ha = IsValidMpqHandle(hMpqOrFile);
- if(ha != NULL)
- {
- pvSrcFileInfo = &ha->pHeader->dwArchiveSize;
- cbSrcFileInfo = sizeof(DWORD);
- nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
- }
- break;
+ return GetInfo(pvFileInfo, cbFileInfo, &pHeader->dwArchiveSize, sizeof(DWORD), pcbLengthNeeded);
case SFileMpqMaxFileCount:
- ha = IsValidMpqHandle(hMpqOrFile);
- if(ha != NULL)
- {
- pvSrcFileInfo = &ha->dwMaxFileCount;
- cbSrcFileInfo = sizeof(DWORD);
- nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
- }
- break;
+ return GetInfo(pvFileInfo, cbFileInfo, &ha->dwMaxFileCount, sizeof(DWORD), pcbLengthNeeded);
case SFileMpqFileTableSize:
- ha = IsValidMpqHandle(hMpqOrFile);
- if(ha != NULL)
- {
- pvSrcFileInfo = &ha->dwFileTableSize;
- cbSrcFileInfo = sizeof(DWORD);
- nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
- }
- break;
+ return GetInfo(pvFileInfo, cbFileInfo, &ha->dwFileTableSize, sizeof(DWORD), pcbLengthNeeded);
case SFileMpqSectorSize:
- ha = IsValidMpqHandle(hMpqOrFile);
- if(ha != NULL)
- {
- pvSrcFileInfo = &ha->dwSectorSize;
- cbSrcFileInfo = sizeof(DWORD);
- nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
- }
- break;
+ return GetInfo(pvFileInfo, cbFileInfo, &ha->dwSectorSize, sizeof(DWORD), pcbLengthNeeded);
case SFileMpqNumberOfFiles:
- ha = IsValidMpqHandle(hMpqOrFile);
- if(ha != NULL)
- {
- pvSrcFileInfo = &dwInt32Value;
- cbSrcFileInfo = sizeof(DWORD);
- dwInt32Value = GetMpqFileCount(ha);
- nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
- }
- break;
+ dwInt32Value = GetMpqFileCount(ha);
+ return GetInfo(pvFileInfo, cbFileInfo, &dwInt32Value, sizeof(DWORD), pcbLengthNeeded);
case SFileMpqRawChunkSize:
- ha = IsValidMpqHandle(hMpqOrFile);
- if(ha != NULL)
- {
- nInfoType = SFILE_INFO_TYPE_NOT_FOUND;
- if(ha->pHeader->dwRawChunkSize != 0)
- {
- pvSrcFileInfo = &ha->pHeader->dwRawChunkSize;
- cbSrcFileInfo = sizeof(DWORD);
- nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
- }
- }
- break;
+ if(pHeader->dwRawChunkSize == 0)
+ return GetInfo_ReturnError(ERROR_FILE_NOT_FOUND);
+ return GetInfo(pvFileInfo, cbFileInfo, &pHeader->dwRawChunkSize, sizeof(DWORD), pcbLengthNeeded);
case SFileMpqStreamFlags:
- ha = IsValidMpqHandle(hMpqOrFile);
- if(ha != NULL)
- {
- FileStream_GetFlags(ha->pStream, &dwInt32Value);
- pvSrcFileInfo = &dwInt32Value;
- cbSrcFileInfo = sizeof(DWORD);
- nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
- }
- break;
+ FileStream_GetFlags(ha->pStream, &dwInt32Value);
+ return GetInfo(pvFileInfo, cbFileInfo, &dwInt32Value, sizeof(DWORD), pcbLengthNeeded);
case SFileMpqFlags:
- ha = IsValidMpqHandle(hMpqOrFile);
- if(ha != NULL)
- {
- dwInt32Value = ha->dwFlags;
- pvSrcFileInfo = &dwInt32Value;
- cbSrcFileInfo = sizeof(DWORD);
- nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
- }
- break;
+ return GetInfo(pvFileInfo, cbFileInfo, &ha->dwFlags, sizeof(DWORD), pcbLengthNeeded);
case SFileInfoPatchChain:
- hf = IsValidFileHandle(hMpqOrFile);
- if(hf != NULL)
- return GetFilePatchChain(hf, pvFileInfo, cbFileInfo, pcbLengthNeeded);
- break;
+ return GetInfo_PatchChain(hf, pvFileInfo, cbFileInfo, pcbLengthNeeded);
case SFileInfoFileEntry:
- hf = IsValidFileHandle(hMpqOrFile);
- if(hf != NULL && hf->pFileEntry != NULL)
- {
- pvSrcFileInfo = pFileEntry = hf->pFileEntry;
- cbSrcFileInfo = sizeof(TFileEntry);
- if(pFileEntry->szFileName != NULL)
- cbSrcFileInfo += (DWORD)strlen(pFileEntry->szFileName) + 1;
- nInfoType = SFILE_INFO_TYPE_FILE_ENTRY;
- }
- break;
+ if(pFileEntry == NULL)
+ return GetInfo_ReturnError(ERROR_FILE_NOT_FOUND);
+ return GetInfo_FileEntry(pvFileInfo, cbFileInfo, pFileEntry, pcbLengthNeeded);
case SFileInfoHashEntry:
- hf = IsValidFileHandle(hMpqOrFile);
- if(hf != NULL && hf->pHashEntry != NULL)
- {
- pvSrcFileInfo = hf->pHashEntry;
- cbSrcFileInfo = sizeof(TMPQHash);
- nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
- }
- break;
+ return GetInfo(pvFileInfo, cbFileInfo, hf->pHashEntry, sizeof(TMPQHash), pcbLengthNeeded);
case SFileInfoHashIndex:
- hf = IsValidFileHandle(hMpqOrFile);
- if(hf != NULL && hf->pHashEntry != NULL)
- {
- pvSrcFileInfo = &hf->dwHashIndex;
- cbSrcFileInfo = sizeof(DWORD);
- nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
- }
- break;
+ return GetInfo(pvFileInfo, cbFileInfo, &hf->dwHashIndex, sizeof(DWORD), pcbLengthNeeded);
case SFileInfoNameHash1:
- hf = IsValidFileHandle(hMpqOrFile);
- if(hf != NULL && hf->pHashEntry != NULL)
- {
- dwInt32Value = hf->pHashEntry->dwName1;
- pvSrcFileInfo = &dwInt32Value;
- cbSrcFileInfo = sizeof(DWORD);
- nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
- }
- break;
+ return GetInfo(pvFileInfo, cbFileInfo, &hf->pHashEntry->dwName1, sizeof(DWORD), pcbLengthNeeded);
case SFileInfoNameHash2:
- hf = IsValidFileHandle(hMpqOrFile);
- if(hf != NULL && hf->pHashEntry != NULL)
- {
- dwInt32Value = hf->pHashEntry->dwName2;
- pvSrcFileInfo = &dwInt32Value;
- cbSrcFileInfo = sizeof(DWORD);
- nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
- }
- break;
+ return GetInfo(pvFileInfo, cbFileInfo, &hf->pHashEntry->dwName2, sizeof(DWORD), pcbLengthNeeded);
case SFileInfoNameHash3:
- hf = IsValidFileHandle(hMpqOrFile);
- if(hf != NULL && hf->pFileEntry != NULL)
- {
- pvSrcFileInfo = &hf->pFileEntry->FileNameHash;
- cbSrcFileInfo = sizeof(ULONGLONG);
- nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
- }
- break;
+ return GetInfo(pvFileInfo, cbFileInfo, &pFileEntry->FileNameHash, sizeof(ULONGLONG), pcbLengthNeeded);
case SFileInfoLocale:
- hf = IsValidFileHandle(hMpqOrFile);
- if(hf != NULL && hf->pHashEntry != NULL)
- {
- dwInt32Value = hf->pHashEntry->lcLocale;
- pvSrcFileInfo = &dwInt32Value;
- cbSrcFileInfo = sizeof(DWORD);
- nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
- }
- break;
+ dwInt32Value = hf->pHashEntry->lcLocale;
+ return GetInfo(pvFileInfo, cbFileInfo, &dwInt32Value, sizeof(DWORD), pcbLengthNeeded);
case SFileInfoFileIndex:
- hf = IsValidFileHandle(hMpqOrFile);
- if(hf != NULL && hf->ha != NULL && hf->pFileEntry != NULL)
- {
- dwInt32Value = (DWORD)(hf->pFileEntry - hf->ha->pFileTable);
- pvSrcFileInfo = &dwInt32Value;
- cbSrcFileInfo = sizeof(DWORD);
- nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
- }
- break;
+ dwInt32Value = (DWORD)(pFileEntry - hf->ha->pFileTable);
+ return GetInfo(pvFileInfo, cbFileInfo, &dwInt32Value, sizeof(DWORD), pcbLengthNeeded);
case SFileInfoByteOffset:
- hf = IsValidFileHandle(hMpqOrFile);
- if(hf != NULL && hf->pFileEntry != NULL)
- {
- pvSrcFileInfo = &hf->pFileEntry->ByteOffset;
- cbSrcFileInfo = sizeof(ULONGLONG);
- nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
- }
- break;
+ return GetInfo(pvFileInfo, cbFileInfo, &pFileEntry->ByteOffset, sizeof(ULONGLONG), pcbLengthNeeded);
case SFileInfoFileTime:
- hf = IsValidFileHandle(hMpqOrFile);
- if(hf != NULL && hf->pFileEntry != NULL)
- {
- pvSrcFileInfo = &hf->pFileEntry->FileTime;
- cbSrcFileInfo = sizeof(ULONGLONG);
- nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
- }
- break;
+ return GetInfo(pvFileInfo, cbFileInfo, &pFileEntry->FileTime, sizeof(ULONGLONG), pcbLengthNeeded);
case SFileInfoFileSize:
- hf = IsValidFileHandle(hMpqOrFile);
- if(hf != NULL && hf->pFileEntry != NULL)
- {
- pvSrcFileInfo = &hf->pFileEntry->dwFileSize;
- cbSrcFileInfo = sizeof(DWORD);
- nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
- }
- break;
+ return GetInfo(pvFileInfo, cbFileInfo, &pFileEntry->dwFileSize, sizeof(DWORD), pcbLengthNeeded);
case SFileInfoCompressedSize:
- hf = IsValidFileHandle(hMpqOrFile);
- if(hf != NULL && hf->pFileEntry != NULL)
- {
- pvSrcFileInfo = &hf->pFileEntry->dwCmpSize;
- cbSrcFileInfo = sizeof(DWORD);
- nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
- }
- break;
+ return GetInfo(pvFileInfo, cbFileInfo, &pFileEntry->dwCmpSize, sizeof(DWORD), pcbLengthNeeded);
case SFileInfoFlags:
- hf = IsValidFileHandle(hMpqOrFile);
- if(hf != NULL && hf->pFileEntry != NULL)
- {
- pvSrcFileInfo = &hf->pFileEntry->dwFlags;
- cbSrcFileInfo = sizeof(DWORD);
- nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
- }
- break;
+ return GetInfo(pvFileInfo, cbFileInfo, &pFileEntry->dwFlags, sizeof(DWORD), pcbLengthNeeded);
case SFileInfoEncryptionKey:
- hf = IsValidFileHandle(hMpqOrFile);
- if(hf != NULL)
- {
- pvSrcFileInfo = &hf->dwFileKey;
- cbSrcFileInfo = sizeof(DWORD);
- nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
- }
- break;
+ return GetInfo(pvFileInfo, cbFileInfo, &hf->dwFileKey, sizeof(DWORD), pcbLengthNeeded);
case SFileInfoEncryptionKeyRaw:
- hf = IsValidFileHandle(hMpqOrFile);
- if(hf != NULL && hf->pFileEntry != NULL)
- {
- dwInt32Value = hf->dwFileKey;
- if(hf->pFileEntry->dwFlags & MPQ_FILE_FIX_KEY)
- dwInt32Value = (dwInt32Value ^ hf->pFileEntry->dwFileSize) - (DWORD)hf->MpqFilePos;
- pvSrcFileInfo = &dwInt32Value;
- cbSrcFileInfo = sizeof(DWORD);
- nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
- }
- break;
+ dwInt32Value = hf->dwFileKey;
+ if(pFileEntry->dwFlags & MPQ_FILE_FIX_KEY)
+ dwInt32Value = (dwInt32Value ^ pFileEntry->dwFileSize) - (DWORD)hf->MpqFilePos;
+ return GetInfo(pvFileInfo, cbFileInfo, &dwInt32Value, sizeof(DWORD), pcbLengthNeeded);
case SFileInfoCRC32:
- hf = IsValidFileHandle(hMpqOrFile);
- if(hf != NULL && hf->pFileEntry != NULL)
- {
- dwInt32Value = hf->pFileEntry->dwCrc32;
- pvSrcFileInfo = &dwInt32Value;
- cbSrcFileInfo = sizeof(DWORD);
- nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
- }
- break;
-
- default: // Invalid info class
- SetLastError(ERROR_INVALID_PARAMETER);
- return false;
- }
-
- // If we validated the handle and info class, give as much info as possible
- if(nInfoType >= SFILE_INFO_TYPE_DIRECT_POINTER)
- {
- // Give the length needed, if wanted
- if(pcbLengthNeeded != NULL)
- pcbLengthNeeded[0] = cbSrcFileInfo;
-
- // If the caller entered an output buffer, the output size must also be entered
- if(pvFileInfo != NULL && cbFileInfo != 0)
- {
- // Check if there is enough space in the output buffer
- if(cbSrcFileInfo <= cbFileInfo)
- {
- switch(nInfoType)
- {
- case SFILE_INFO_TYPE_DIRECT_POINTER:
- case SFILE_INFO_TYPE_ALLOCATED:
- assert(pvSrcFileInfo != NULL);
- memcpy(pvFileInfo, pvSrcFileInfo, cbSrcFileInfo);
- break;
-
- case SFILE_INFO_TYPE_READ_FROM_FILE:
- if(!FileStream_Read(ha->pStream, &ByteOffset, pvFileInfo, cbSrcFileInfo))
- nError = GetLastError();
- break;
-
- case SFILE_INFO_TYPE_TABLE_POINTER:
- assert(pvSrcFileInfo != NULL);
- *(void **)pvFileInfo = pvSrcFileInfo;
- pvSrcFileInfo = NULL;
- break;
-
- case SFILE_INFO_TYPE_FILE_ENTRY:
- assert(pFileEntry != NULL);
- ConvertFileEntryToSelfRelative((TFileEntry *)pvFileInfo, pFileEntry);
- break;
- }
- }
- else
- {
- nError = ERROR_INSUFFICIENT_BUFFER;
- }
- }
-
- // Free the file info if needed
- if(nInfoType == SFILE_INFO_TYPE_ALLOCATED && pvSrcFileInfo != NULL)
- STORM_FREE(pvSrcFileInfo);
- if(nInfoType == SFILE_INFO_TYPE_TABLE_POINTER && pvSrcFileInfo != NULL)
- SFileFreeFileInfo(pvSrcFileInfo, InfoClass);
- }
- else
- {
- // Handle error cases
- if(nInfoType == SFILE_INFO_TYPE_INVALID_HANDLE)
- nError = ERROR_INVALID_HANDLE;
- if(nInfoType == SFILE_INFO_TYPE_NOT_FOUND)
- nError = ERROR_FILE_NOT_FOUND;
+ return GetInfo(pvFileInfo, cbFileInfo, &hf->pFileEntry->dwCrc32, sizeof(DWORD), pcbLengthNeeded);
}
- // Set the last error value, if needed
- if(nError != ERROR_SUCCESS)
- SetLastError(nError);
- return (nError == ERROR_SUCCESS);
+ // Invalid info class
+ return GetInfo_ReturnError(ERROR_INVALID_PARAMETER);
}
bool WINAPI SFileFreeFileInfo(void * pvFileInfo, SFileInfoClass InfoClass)
diff --git a/src/SFileListFile.cpp b/src/SFileListFile.cpp index aa8969c..fe9bc69 100644 --- a/src/SFileListFile.cpp +++ b/src/SFileListFile.cpp @@ -17,7 +17,7 @@ // Listfile entry structure
#define CACHE_BUFFER_SIZE 0x1000 // Size of the cache buffer
-#define MAX_LISTFILE_SIZE 0x04000000 // Maximum accepted listfile size is about 68 MB
+#define MAX_LISTFILE_SIZE 0x8000000 // Maximum accepted listfile size is 128 MB
union TListFileHandle
{
@@ -148,6 +148,10 @@ static TListFileCache * CreateListFileCache( TListFileCache * pCache = NULL;
TListFileHandle ListHandle = {NULL};
+ // Put default value to dwMaxSize
+ if(dwMaxSize == 0)
+ dwMaxSize = MAX_LISTFILE_SIZE;
+
// Internal listfile: hMPQ must be non NULL and szListFile must be NULL.
// We load the MPQ::(listfile) file
if(hMpq != NULL && szListFile == NULL)
@@ -181,7 +185,7 @@ static TListFileCache * CreateListFileCache( {
// Verify the file size
FileStream_GetSize(ListHandle.pStream, &FileSize);
- if(0 < FileSize && FileSize < MAX_LISTFILE_SIZE)
+ if(0 < FileSize && FileSize < dwMaxSize)
{
pCache = CreateListFileCache(LoadListFile_Stream, &ListHandle, szWildCard, (DWORD)FileSize, dwMaxSize, dwFlags);
}
diff --git a/src/SFileOpenArchive.cpp b/src/SFileOpenArchive.cpp index d1cc4d6..3e333a9 100644 --- a/src/SFileOpenArchive.cpp +++ b/src/SFileOpenArchive.cpp @@ -9,7 +9,7 @@ /*---------------------------------------------------------------------------*/ /* Date Ver Who Comment */ /* -------- ---- --- ------- */ -/* xx.xx.xx 1.00 Lad The first version of SFileOpenArchive.cpp */ +/* xx.xx.xx 1.00 Lad Created */ /* 19.11.03 1.01 Dan Big endian handling */ /*****************************************************************************/ diff --git a/src/SFileReadFile.cpp b/src/SFileReadFile.cpp index a693e70..0320677 100644 --- a/src/SFileReadFile.cpp +++ b/src/SFileReadFile.cpp @@ -725,7 +725,7 @@ bool WINAPI SFileReadFile(HANDLE hFile, void * pvBuffer, DWORD dwToRead, LPDWORD // Otherwise read it as sector based MPQ file else - { + { nError = ReadMpqFileSectorFile(hf, pvBuffer, hf->dwFilePos, dwToRead, &dwBytesRead); } diff --git a/src/StormLib.h b/src/StormLib.h index d913a54..f254290 100644 --- a/src/StormLib.h +++ b/src/StormLib.h @@ -142,8 +142,8 @@ extern "C" { //----------------------------------------------------------------------------- // Defines -#define STORMLIB_VERSION 0x0916 // Current version of StormLib (9.21) -#define STORMLIB_VERSION_STRING "9.22" // String version of StormLib version +#define STORMLIB_VERSION 0x0917 // Current version of StormLib (9.23) +#define STORMLIB_VERSION_STRING "9.23" // String version of StormLib version #define ID_MPQ 0x1A51504D // MPQ archive header ID ('MPQ\x1A') #define ID_MPQ_USERDATA 0x1B51504D // MPQ userdata entry ('MPQ\x1B') diff --git a/src/huffman/huff.cpp b/src/huffman/huff.cpp index 9de5acb..fa0964d 100644 --- a/src/huffman/huff.cpp +++ b/src/huffman/huff.cpp @@ -478,19 +478,24 @@ THTreeItem * THuffmannTree::FindHigherOrEqualItem(THTreeItem * pItem, unsigned i THTreeItem * THuffmannTree::CreateNewItem(unsigned int DecompressedValue, unsigned int Weight, TInsertPoint InsertPoint) { - THTreeItem * pNewItem; + THTreeItem * pNewItem = NULL; - // Allocate new item from the item pool - pNewItem = &ItemBuffer[ItemsUsed++]; + // Don't let the item buffer run out of space + if(ItemsUsed < HUFF_ITEM_COUNT) + { + // Allocate new item from the item pool + pNewItem = &ItemBuffer[ItemsUsed++]; - // Insert this item to the top of the tree - InsertItem(pNewItem, InsertPoint, NULL); + // Insert this item to the top of the tree + InsertItem(pNewItem, InsertPoint, NULL); - // Fill the rest of the item - pNewItem->DecompressedValue = DecompressedValue; - pNewItem->Weight = Weight; - pNewItem->pParent = NULL; - pNewItem->pChildLo = NULL; + // Fill the rest of the item + pNewItem->DecompressedValue = DecompressedValue; + pNewItem->Weight = Weight; + pNewItem->pParent = NULL; + pNewItem->pChildLo = NULL; + } + return pNewItem; } @@ -567,6 +572,8 @@ bool THuffmannTree::BuildTree(unsigned int CompressionType) // Create new parent item for the children pNewItem = CreateNewItem(0, pChildHi->Weight + pChildLo->Weight, InsertAfter); + if(pNewItem == NULL) + return false; // Link both child items to their new parent pChildLo->pParent = pNewItem; @@ -631,7 +638,7 @@ void THuffmannTree::IncWeightsAndRebalance(THTreeItem * pItem) } } -void THuffmannTree::InsertNewBranchAndRebalance(unsigned int Value1, unsigned int Value2) +bool THuffmannTree::InsertNewBranchAndRebalance(unsigned int Value1, unsigned int Value2) { THTreeItem * pLastItem = pLast; THTreeItem * pChildHi; @@ -639,16 +646,26 @@ void THuffmannTree::InsertNewBranchAndRebalance(unsigned int Value1, unsigned in // Create higher-weight child pChildHi = CreateNewItem(Value1, pLastItem->Weight, InsertBefore); - pChildHi->pParent = pLastItem; - ItemsByByte[Value1] = pChildHi; + if(pChildHi != NULL) + { + pChildHi->pParent = pLastItem; + ItemsByByte[Value1] = pChildHi; - // Create lower-weight child - pChildLo = CreateNewItem(Value2, 0, InsertBefore); - pChildLo->pParent = pLastItem; - pLastItem->pChildLo = pChildLo; - ItemsByByte[Value2] = pChildLo; + // Create lower-weight child + pChildLo = CreateNewItem(Value2, 0, InsertBefore); + if(pChildLo != NULL) + { + pChildLo->pParent = pLastItem; + pLastItem->pChildLo = pChildLo; + ItemsByByte[Value2] = pChildLo; + + IncWeightsAndRebalance(pChildLo); + return true; + } + } - IncWeightsAndRebalance(pChildLo); + // No more space in the tree buffer + return false; } void THuffmannTree::EncodeOneByte(TOutputStream * os, THTreeItem * pItem) @@ -789,7 +806,8 @@ unsigned int THuffmannTree::Compress(TOutputStream * os, void * pvInBuffer, int // Store the loaded byte into output stream os->PutBits(InputByte, 8); - InsertNewBranchAndRebalance(pLast->DecompressedValue, InputByte); + if(!InsertNewBranchAndRebalance(pLast->DecompressedValue, InputByte)) + return 0; if(bIsCmp0) { @@ -851,7 +869,8 @@ unsigned int THuffmannTree::Decompress(void * pvOutBuffer, unsigned int cbOutLen // The decompressed byte is stored in the next 8 bits DecompressedValue = is->Get8Bits(); - InsertNewBranchAndRebalance(pLast->DecompressedValue, DecompressedValue); + if(!InsertNewBranchAndRebalance(pLast->DecompressedValue, DecompressedValue)) + return 0; if(bIsCmp0 == 0) IncWeightsAndRebalance(ItemsByByte[DecompressedValue]); diff --git a/src/huffman/huff.h b/src/huffman/huff.h index 89993fd..d2c3e3e 100644 --- a/src/huffman/huff.h +++ b/src/huffman/huff.h @@ -118,7 +118,7 @@ class THuffmannTree bool BuildTree(unsigned int CompressionType); void IncWeightsAndRebalance(THTreeItem * pItem); - void InsertNewBranchAndRebalance(unsigned int Value1, unsigned int Value2); + bool InsertNewBranchAndRebalance(unsigned int Value1, unsigned int Value2); void EncodeOneByte(TOutputStream * os, THTreeItem * pItem); unsigned int DecodeOneByte(TInputStream * is); |