aboutsummaryrefslogtreecommitdiff
path: root/src/SFileGetFileInfo.cpp
diff options
context:
space:
mode:
authorLadislav Zezula <ladislav.zezula@avg.com>2013-12-06 15:20:47 +0100
committerLadislav Zezula <ladislav.zezula@avg.com>2013-12-06 15:20:47 +0100
commitf2a388780f83cfd95afa27b01dafe3a683b0e39c (patch)
tree34137a334e713c088a41ea2bdbdba0648df5f00b /src/SFileGetFileInfo.cpp
parentc34c37b3418f1e5ab3678ce65d46f81803dec91d (diff)
+ Bug fixes in SFileGetFileInfo, SAttrFileSaveToMpq, SListFileSaveToMpq
+ FileStream now handles files over 2GB properly + Test under Linux
Diffstat (limited to 'src/SFileGetFileInfo.cpp')
-rw-r--r--src/SFileGetFileInfo.cpp195
1 files changed, 127 insertions, 68 deletions
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)