aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/FileStream.cpp18
-rw-r--r--src/SFileAttributes.cpp33
-rw-r--r--src/SFileGetFileInfo.cpp195
-rw-r--r--src/SFileListFile.cpp8
-rw-r--r--src/StormLib.h2
5 files changed, 154 insertions, 102 deletions
diff --git a/src/FileStream.cpp b/src/FileStream.cpp
index 81933fd..03a8fea 100644
--- a/src/FileStream.cpp
+++ b/src/FileStream.cpp
@@ -182,7 +182,7 @@ static bool BaseFile_Read(
// we have to update the file position
if(ByteOffset != pStream->Base.File.FilePos)
{
- lseek((intptr_t)pStream->Base.File.hFile, (off_t)(ByteOffset), SEEK_SET);
+ lseek64((intptr_t)pStream->Base.File.hFile, (__off64_t)(ByteOffset), SEEK_SET);
pStream->Base.File.FilePos = ByteOffset;
}
@@ -271,7 +271,7 @@ static bool BaseFile_Write(TFileStream * pStream, ULONGLONG * pByteOffset, const
// we have to update the file position
if(ByteOffset != pStream->Base.File.FilePos)
{
- lseek((intptr_t)pStream->Base.File.hFile, (off_t)(ByteOffset), SEEK_SET);
+ lseek64((intptr_t)pStream->Base.File.hFile, (__off64_t)(ByteOffset), SEEK_SET);
pStream->Base.File.FilePos = ByteOffset;
}
@@ -346,7 +346,7 @@ static bool BaseFile_SetSize(TFileStream * pStream, ULONGLONG NewFileSize)
#if defined(PLATFORM_MAC) || defined(PLATFORM_LINUX)
{
- if(ftruncate((intptr_t)pStream->Base.File.hFile, (off_t)NewFileSize) == -1)
+ if(ftruncate64((intptr_t)pStream->Base.File.hFile, (__off64_t)NewFileSize) == -1)
{
nLastError = errno;
return false;
@@ -429,7 +429,7 @@ static bool BaseFile_Create(
{
intptr_t handle;
- handle = open(szFileName, O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
+ handle = open(szFileName, O_RDWR | O_CREAT | O_TRUNC | O_LARGEFILE, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
if(handle == -1)
{
nLastError = errno;
@@ -489,12 +489,12 @@ static bool BaseFile_Open(
#if defined(PLATFORM_MAC) || defined(PLATFORM_LINUX)
{
- struct stat fileinfo;
+ struct stat64 fileinfo;
int oflag = (dwStreamFlags & STREAM_FLAG_READ_ONLY) ? O_RDONLY : O_RDWR;
intptr_t handle;
// Open the file
- handle = open(szFileName, oflag);
+ handle = open(szFileName, oflag | O_LARGEFILE);
if(handle == -1)
{
nLastError = errno;
@@ -502,7 +502,7 @@ static bool BaseFile_Open(
}
// Get the file size
- if(fstat(handle, &fileinfo) == -1)
+ if(fstat64(handle, &fileinfo) == -1)
{
nLastError = errno;
return false;
@@ -650,7 +650,7 @@ static bool BaseMap_Open(
#endif
#if defined(PLATFORM_MAC) || defined(PLATFORM_LINUX)
- struct stat fileinfo;
+ struct stat64 fileinfo;
intptr_t handle;
bool bResult = false;
@@ -659,7 +659,7 @@ static bool BaseMap_Open(
if(handle != -1)
{
// Get the file size
- if(fstat(handle, &fileinfo) != -1)
+ if(fstat64(handle, &fileinfo) != -1)
{
pStream->Base.Map.pbFile = (LPBYTE)mmap(NULL, (size_t)fileinfo.st_size, PROT_READ, MAP_PRIVATE, handle, 0);
if(pStream->Base.Map.pbFile != NULL)
diff --git a/src/SFileAttributes.cpp b/src/SFileAttributes.cpp
index bca1f66..7f12028 100644
--- a/src/SFileAttributes.cpp
+++ b/src/SFileAttributes.cpp
@@ -41,8 +41,10 @@ static DWORD GetSizeOfAttributesFile(DWORD dwAttrFlags, DWORD dwFileTableSize)
if(dwAttrFlags & MPQ_ATTRIBUTE_MD5)
cbAttrFile += dwFileTableSize * MD5_DIGEST_SIZE;
- // Weird: When there's 1 extra bit in the patch bit array, it's ignored
- // wow-update-13164.MPQ: BlockTableSize = 0x62E1, but there's only 0xC5C bytes
+ // The bit array has been create without the last bit belonging to (attributes)
+ // When the number of files is a multiplier of 8 plus one, then the size of (attributes)
+ // if 1 byte less than expected.
+ // Example: wow-update-13164.MPQ: BlockTableSize = 0x62E1, but there's only 0xC5C bytes
if(dwAttrFlags & MPQ_ATTRIBUTE_PATCH_BIT)
cbAttrFile += (dwFileTableSize + 6) / 8;
@@ -165,7 +167,7 @@ static LPBYTE CreateAttributesFile(TMPQArchive * ha, DWORD * pcbAttrFile)
LPBYTE pbAttrFile;
LPBYTE pbAttrPtr;
size_t cbAttrFile;
- DWORD dwFinalEntries = ha->dwFileTableSize + ha->dwReservedFiles;
+ DWORD dwFinalEntries = ha->dwFileTableSize + ha->dwReservedFiles + 1;
// Check if we need patch bits in the (attributes) file
for(pFileEntry = ha->pFileTable; pFileEntry < pFileTableEnd; pFileEntry++)
@@ -202,7 +204,7 @@ static LPBYTE CreateAttributesFile(TMPQArchive * ha, DWORD * pcbAttrFile)
*pArrayCRC32++ = BSWAP_INT32_UNSIGNED(pFileEntry->dwCrc32);
// Skip the reserved entries
- pbAttrPtr = (LPBYTE)(pArrayCRC32 + ha->dwReservedFiles);
+ pbAttrPtr = (LPBYTE)(pArrayCRC32 + ha->dwReservedFiles + 1);
}
// Write the array of file time
@@ -215,7 +217,7 @@ static LPBYTE CreateAttributesFile(TMPQArchive * ha, DWORD * pcbAttrFile)
*pArrayFileTime++ = BSWAP_INT64_UNSIGNED(pFileEntry->FileTime);
// Skip the reserved entries
- pbAttrPtr = (LPBYTE)(pArrayFileTime + ha->dwReservedFiles);
+ pbAttrPtr = (LPBYTE)(pArrayFileTime + ha->dwReservedFiles + 1);
}
// Write the array of MD5s
@@ -231,16 +233,15 @@ static LPBYTE CreateAttributesFile(TMPQArchive * ha, DWORD * pcbAttrFile)
}
// Skip the reserved items
- pbAttrPtr = pbArrayMD5 + (ha->dwReservedFiles * MD5_DIGEST_SIZE);
+ pbAttrPtr = pbArrayMD5 + ((ha->dwReservedFiles + 1) * MD5_DIGEST_SIZE);
}
// Write the array of patch bits
if(ha->dwAttrFlags & MPQ_ATTRIBUTE_PATCH_BIT)
{
LPBYTE pbBitArray = pbAttrPtr;
- DWORD dwByteSize = (dwFinalEntries + 7) / 8;
DWORD dwByteIndex = 0;
- DWORD dwBitMask = 0x80;
+ BYTE dwBitMask = 0x80;
// Copy from file table
for(pFileEntry = ha->pFileTable; pFileEntry < pFileTableEnd; pFileEntry++)
@@ -254,14 +255,18 @@ static LPBYTE CreateAttributesFile(TMPQArchive * ha, DWORD * pcbAttrFile)
dwBitMask = (dwBitMask << 0x07) | (dwBitMask >> 0x01);
}
+ // Note: Do not increment the array by the last bit that belongs to (attributes).
+ // This might create the array one byte less (if the number of files a multiplier of 8).
+ // Blizzard MPQs have the same feature.
+
// Move past the bit array
- pbAttrPtr = (pbBitArray + dwByteSize);
+ pbAttrPtr = (pbBitArray + dwByteIndex) + ((dwBitMask & 0x7F) ? 1 : 0);
}
// Now we expect that current position matches the estimated size
// Note that if there is 1 extra bit above the byte size,
// the table is actually 1 byte shorted in Blizzard MPQs. See GetSizeOfAttributesFile
- assert((size_t)(pbAttrPtr - pbAttrFile) == cbAttrFile + ((dwFinalEntries & 0x07) == 1) ? 1 : 0);
+ assert((size_t)(pbAttrPtr - pbAttrFile) == cbAttrFile);
}
// Give away the attributes file
@@ -329,18 +334,12 @@ int SAttrFileSaveToMpq(TMPQArchive * ha)
// We expect at least one reserved entry to be there
assert(ha->dwReservedFiles >= 1);
+ ha->dwReservedFiles--;
// Create the raw data that is to be written to (attributes)
// Note: Blizzard MPQs have entries for (listfile) and (attributes),
// but they are filled empty
pbAttrFile = CreateAttributesFile(ha, &cbAttrFile);
-
- // Now we decrement the number of reserved files.
- // This frees one slot in the file table, so the subsequent file create operation should succeed
- // This must happen even if CreateAttributesFile failed
- ha->dwReservedFiles--;
-
- // If we created something, write the attributes to the MPQ
if(pbAttrFile != NULL)
{
// We expect it to be nonzero size
diff --git a/src/SFileGetFileInfo.cpp b/src/SFileGetFileInfo.cpp
index 06c8d6a..a8083dc 100644
--- a/src/SFileGetFileInfo.cpp
+++ b/src/SFileGetFileInfo.cpp
@@ -16,12 +16,13 @@
// Local defines
// Information types for SFileGetFileInfo
-#define SFILE_INFO_TYPE_UNKNOWN 0
-#define SFILE_INFO_TYPE_DIRECT_POINTER 1
-#define SFILE_INFO_TYPE_ALLOCATED 2
-#define SFILE_INFO_TYPE_READ_FROM_FILE 3
-#define SFILE_INFO_TYPE_TABLE_POINTER 4
-#define SFILE_INFO_TYPE_FILE_ENTRY 5
+#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
@@ -146,8 +147,8 @@ bool WINAPI SFileGetFileInfo(
void * pvSrcFileInfo = NULL;
DWORD cbSrcFileInfo = 0;
DWORD dwInt32Value = 0;
- int nInfoType = SFILE_INFO_TYPE_UNKNOWN;
- int nError = ERROR_INVALID_PARAMETER;
+ int nInfoType = SFILE_INFO_TYPE_INVALID_HANDLE;
+ int nError = ERROR_SUCCESS;
switch(InfoClass)
{
@@ -163,31 +164,43 @@ bool WINAPI SFileGetFileInfo(
case SFileMpqUserDataOffset:
ha = IsValidMpqHandle(hMpqOrFile);
- if(ha != NULL && ha->pUserData != NULL)
+ if(ha != NULL)
{
- pvSrcFileInfo = &ha->UserDataPos;
- cbSrcFileInfo = sizeof(ULONGLONG);
- nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
+ nInfoType = SFILE_INFO_TYPE_NOT_FOUND;
+ if(ha->pUserData != NULL)
+ {
+ pvSrcFileInfo = &ha->UserDataPos;
+ cbSrcFileInfo = sizeof(ULONGLONG);
+ nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
+ }
}
break;
case SFileMpqUserDataHeader:
ha = IsValidMpqHandle(hMpqOrFile);
- if(ha != NULL && ha->pUserData != NULL)
+ if(ha != NULL)
{
- ByteOffset = ha->UserDataPos;
- cbSrcFileInfo = sizeof(TMPQUserData);
- nInfoType = SFILE_INFO_TYPE_READ_FROM_FILE;
+ nInfoType = SFILE_INFO_TYPE_NOT_FOUND;
+ if(ha->pUserData != NULL)
+ {
+ ByteOffset = ha->UserDataPos;
+ cbSrcFileInfo = sizeof(TMPQUserData);
+ nInfoType = SFILE_INFO_TYPE_READ_FROM_FILE;
+ }
}
break;
case SFileMpqUserData:
ha = IsValidMpqHandle(hMpqOrFile);
- if(ha != NULL && ha->pUserData != NULL)
+ if(ha != NULL)
{
- ByteOffset = ha->UserDataPos + sizeof(TMPQUserData);
- cbSrcFileInfo = ha->pUserData->dwHeaderOffs - sizeof(TMPQUserData);
- nInfoType = SFILE_INFO_TYPE_READ_FROM_FILE;
+ 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;
@@ -245,9 +258,13 @@ bool WINAPI SFileGetFileInfo(
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);
- cbSrcFileInfo = sizeof(TMPQHetHeader);
- nInfoType = SFILE_INFO_TYPE_ALLOCATED;
+ if(pvSrcFileInfo != NULL)
+ {
+ cbSrcFileInfo = sizeof(TMPQHetHeader);
+ nInfoType = SFILE_INFO_TYPE_ALLOCATED;
+ }
}
break;
@@ -255,9 +272,13 @@ bool WINAPI SFileGetFileInfo(
ha = IsValidMpqHandle(hMpqOrFile);
if(ha != NULL)
{
+ nInfoType = SFILE_INFO_TYPE_NOT_FOUND;
pvSrcFileInfo = LoadHetTable(ha);
- cbSrcFileInfo = sizeof(void *);
- nInfoType = SFILE_INFO_TYPE_TABLE_POINTER;
+ if(pvSrcFileInfo != NULL)
+ {
+ cbSrcFileInfo = sizeof(void *);
+ nInfoType = SFILE_INFO_TYPE_TABLE_POINTER;
+ }
}
break;
@@ -285,6 +306,7 @@ bool WINAPI SFileGetFileInfo(
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)
{
@@ -301,9 +323,13 @@ bool WINAPI SFileGetFileInfo(
ha = IsValidMpqHandle(hMpqOrFile);
if(ha != NULL)
{
+ nInfoType = SFILE_INFO_TYPE_NOT_FOUND;
pvSrcFileInfo = LoadBetTable(ha);
- cbSrcFileInfo = sizeof(void *);
- nInfoType = SFILE_INFO_TYPE_TABLE_POINTER;
+ if(pvSrcFileInfo != NULL)
+ {
+ cbSrcFileInfo = sizeof(void *);
+ nInfoType = SFILE_INFO_TYPE_TABLE_POINTER;
+ }
}
break;
@@ -342,9 +368,13 @@ bool WINAPI SFileGetFileInfo(
ha = IsValidMpqHandle(hMpqOrFile);
if(ha != NULL)
{
- cbSrcFileInfo = ha->pHeader->dwHashTableSize * sizeof(TMPQHash);
- pvSrcFileInfo = ha->pHashTable;
- nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
+ nInfoType = SFILE_INFO_TYPE_NOT_FOUND;
+ if(ha->pHashTable != NULL)
+ {
+ pvSrcFileInfo = ha->pHashTable;
+ cbSrcFileInfo = ha->pHeader->dwHashTableSize * sizeof(TMPQHash);
+ nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
+ }
}
break;
@@ -383,10 +413,14 @@ bool WINAPI SFileGetFileInfo(
ha = IsValidMpqHandle(hMpqOrFile);
if(ha != NULL)
{
- cbSrcFileInfo = ha->pHeader->dwBlockTableSize * sizeof(TMPQBlock);
- if(cbFileInfo >= cbSrcFileInfo)
- pvSrcFileInfo = LoadBlockTable(ha, true);
- nInfoType = SFILE_INFO_TYPE_ALLOCATED;
+ nInfoType = SFILE_INFO_TYPE_NOT_FOUND;
+ if(MAKE_OFFSET64(ha->pHeader->wBlockTablePosHi, ha->pHeader->dwBlockTablePos) != 0)
+ {
+ cbSrcFileInfo = ha->pHeader->dwBlockTableSize * sizeof(TMPQBlock);
+ if(cbFileInfo >= cbSrcFileInfo)
+ pvSrcFileInfo = LoadBlockTable(ha, true);
+ nInfoType = SFILE_INFO_TYPE_ALLOCATED;
+ }
}
break;
@@ -411,7 +445,15 @@ bool WINAPI SFileGetFileInfo(
break;
case SFileMpqHiBlockTable:
- assert(false);
+ ha = IsValidMpqHandle(hMpqOrFile);
+ if(ha != NULL)
+ {
+ nInfoType = SFILE_INFO_TYPE_NOT_FOUND;
+ if(ha->pHeader->HiBlockTablePos64 && ha->pHeader->HiBlockTableSize64)
+ {
+ assert(false);
+ }
+ }
break;
case SFileMpqSignatures:
@@ -426,10 +468,10 @@ bool WINAPI SFileGetFileInfo(
case SFileMpqStrongSignatureOffset:
ha = IsValidMpqHandle(hMpqOrFile);
- if(ha != NULL && QueryMpqSignatureInfo(ha, &SignatureInfo))
+ if(ha != NULL)
{
- // Is a strong signature present?
- if(SignatureInfo.SignatureTypes & SIGNATURE_TYPE_STRONG)
+ nInfoType = SFILE_INFO_TYPE_NOT_FOUND;
+ if(QueryMpqSignatureInfo(ha, &SignatureInfo) && (SignatureInfo.SignatureTypes & SIGNATURE_TYPE_STRONG))
{
pvSrcFileInfo = &SignatureInfo.EndMpqData;
cbSrcFileInfo = sizeof(ULONGLONG);
@@ -440,10 +482,10 @@ bool WINAPI SFileGetFileInfo(
case SFileMpqStrongSignatureSize:
ha = IsValidMpqHandle(hMpqOrFile);
- if(ha != NULL && QueryMpqSignatureInfo(ha, &SignatureInfo))
+ if(ha != NULL)
{
- // Is a strong signature present?
- if(SignatureInfo.SignatureTypes & SIGNATURE_TYPE_STRONG)
+ nInfoType = SFILE_INFO_TYPE_NOT_FOUND;
+ if(QueryMpqSignatureInfo(ha, &SignatureInfo) && (SignatureInfo.SignatureTypes & SIGNATURE_TYPE_STRONG))
{
dwInt32Value = MPQ_STRONG_SIGNATURE_SIZE + 4;
pvSrcFileInfo = &dwInt32Value;
@@ -455,10 +497,10 @@ bool WINAPI SFileGetFileInfo(
case SFileMpqStrongSignature:
ha = IsValidMpqHandle(hMpqOrFile);
- if(ha != NULL && QueryMpqSignatureInfo(ha, &SignatureInfo))
+ if(ha != NULL)
{
- // Is a strong signature present?
- if(SignatureInfo.SignatureTypes & SIGNATURE_TYPE_STRONG)
+ nInfoType = SFILE_INFO_TYPE_NOT_FOUND;
+ if(QueryMpqSignatureInfo(ha, &SignatureInfo) && (SignatureInfo.SignatureTypes & SIGNATURE_TYPE_STRONG))
{
pvSrcFileInfo = SignatureInfo.Signature;
cbSrcFileInfo = MPQ_STRONG_SIGNATURE_SIZE + 4;
@@ -469,22 +511,30 @@ bool WINAPI SFileGetFileInfo(
case SFileMpqBitmapOffset:
ha = IsValidMpqHandle(hMpqOrFile);
- if(ha != NULL && ha->pBitmap != NULL)
+ if(ha != NULL)
{
- Int64Value = MAKE_OFFSET64(ha->pBitmap->dwMapOffsetHi, ha->pBitmap->dwMapOffsetLo);
- pvSrcFileInfo = &Int64Value;
- cbSrcFileInfo = sizeof(ULONGLONG);
- nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
+ nInfoType = SFILE_INFO_TYPE_NOT_FOUND;
+ if(ha->pBitmap != NULL)
+ {
+ Int64Value = MAKE_OFFSET64(ha->pBitmap->dwMapOffsetHi, ha->pBitmap->dwMapOffsetLo);
+ pvSrcFileInfo = &Int64Value;
+ cbSrcFileInfo = sizeof(ULONGLONG);
+ nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
+ }
}
break;
case SFileMpqBitmapSize:
ha = IsValidMpqHandle(hMpqOrFile);
- if(ha != NULL && ha->pBitmap != NULL)
+ if(ha != NULL)
{
- pvSrcFileInfo = &ha->dwBitmapSize;
- cbSrcFileInfo = sizeof(DWORD);
- nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
+ nInfoType = SFILE_INFO_TYPE_NOT_FOUND;
+ if(ha->pBitmap != NULL)
+ {
+ pvSrcFileInfo = &ha->dwBitmapSize;
+ cbSrcFileInfo = sizeof(DWORD);
+ nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
+ }
}
break;
@@ -492,9 +542,13 @@ bool WINAPI SFileGetFileInfo(
ha = IsValidMpqHandle(hMpqOrFile);
if(ha != NULL)
{
- pvSrcFileInfo = ha->pBitmap;
- cbSrcFileInfo = ha->dwBitmapSize;
- nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
+ nInfoType = SFILE_INFO_TYPE_NOT_FOUND;
+ if(ha->pBitmap != NULL)
+ {
+ pvSrcFileInfo = ha->pBitmap;
+ cbSrcFileInfo = ha->dwBitmapSize;
+ nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
+ }
}
break;
@@ -563,9 +617,13 @@ bool WINAPI SFileGetFileInfo(
ha = IsValidMpqHandle(hMpqOrFile);
if(ha != NULL)
{
- pvSrcFileInfo = &ha->pHeader->dwRawChunkSize;
- cbSrcFileInfo = sizeof(DWORD);
- nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
+ 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;
@@ -760,7 +818,7 @@ bool WINAPI SFileGetFileInfo(
}
// If we validated the handle and info class, give as much info as possible
- if(nInfoType != SFILE_INFO_TYPE_UNKNOWN)
+ if(nInfoType >= SFILE_INFO_TYPE_DIRECT_POINTER)
{
// Give the length needed, if wanted
if(pcbLengthNeeded != NULL)
@@ -777,24 +835,21 @@ bool WINAPI SFileGetFileInfo(
case SFILE_INFO_TYPE_DIRECT_POINTER:
case SFILE_INFO_TYPE_ALLOCATED:
memcpy(pvFileInfo, pvSrcFileInfo, cbSrcFileInfo);
- nError = ERROR_SUCCESS;
break;
case SFILE_INFO_TYPE_READ_FROM_FILE:
- if(FileStream_Read(ha->pStream, &ByteOffset, pvFileInfo, cbSrcFileInfo))
- nError = ERROR_SUCCESS;
+ if(!FileStream_Read(ha->pStream, &ByteOffset, pvFileInfo, cbSrcFileInfo))
+ nError = GetLastError();
break;
case SFILE_INFO_TYPE_TABLE_POINTER:
*(void **)pvFileInfo = pvSrcFileInfo;
pvSrcFileInfo = NULL;
- nError = ERROR_SUCCESS;
break;
case SFILE_INFO_TYPE_FILE_ENTRY:
assert(pFileEntry != NULL);
ConvertFileEntryToSelfRelative((TFileEntry *)pvFileInfo, pFileEntry);
- nError = ERROR_SUCCESS;
break;
}
}
@@ -803,10 +858,6 @@ bool WINAPI SFileGetFileInfo(
nError = ERROR_INSUFFICIENT_BUFFER;
}
}
- else
- {
- nError = ERROR_SUCCESS;
- }
// Free the file info if needed
if(nInfoType == SFILE_INFO_TYPE_ALLOCATED && pvSrcFileInfo != NULL)
@@ -814,6 +865,14 @@ bool WINAPI SFileGetFileInfo(
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;
+ }
// Set the last error value, if needed
if(nError != ERROR_SUCCESS)
diff --git a/src/SFileListFile.cpp b/src/SFileListFile.cpp
index f98c92b..896b341 100644
--- a/src/SFileListFile.cpp
+++ b/src/SFileListFile.cpp
@@ -382,19 +382,13 @@ int SListFileSaveToMpq(TMPQArchive * ha)
// At this point, we expect to have at least one reserved entry in the file table
assert(ha->dwReservedFiles >= 1);
+ ha->dwReservedFiles--;
// Create the raw data that is to be written to (listfile)
// Note: Creating the raw data before the (listfile) has been created in the MPQ
// causes that the name of the listfile will not be included in the listfile itself.
// That is OK, because (listfile) in Blizzard MPQs does not contain it either.
pbListFile = CreateListFile(ha, &cbListFile);
-
- // Now we decrement the number of reserved files.
- // This frees one slot in the file table, so the subsequent file create operation should succeed
- // This must happen even if the listfile cannot be created
- ha->dwReservedFiles--;
-
- // If the listfile create succeeded, we write it to the MPQ
if(pbListFile != NULL)
{
// We expect it to be nonzero size
diff --git a/src/StormLib.h b/src/StormLib.h
index ce65f7f..3659c23 100644
--- a/src/StormLib.h
+++ b/src/StormLib.h
@@ -413,7 +413,7 @@ typedef enum _SFileInfoClass
SFileInfoNameHash2, // The second name hash in the hash table (DWORD)
SFileInfoNameHash3, // 64-bit file name hash for the HET/BET tables (ULONGLONG)
SFileInfoLocale, // File locale (DWORD)
- SFileInfoFileIndex, // Block index (DWORD)
+ SFileInfoFileIndex, // Block index (DWORD)
SFileInfoByteOffset, // File position in the archive (ULONGLONG)
SFileInfoFileTime, // File time (ULONGLONG)
SFileInfoFileSize, // Size of the file (DWORD)