aboutsummaryrefslogtreecommitdiff
path: root/src/SFileVerify.cpp
diff options
context:
space:
mode:
authorLadislav Zezula <ladislav.zezula@avg.com>2013-12-05 15:59:00 +0100
committerLadislav Zezula <ladislav.zezula@avg.com>2013-12-05 15:59:00 +0100
commitc34c37b3418f1e5ab3678ce65d46f81803dec91d (patch)
tree4a9cf4c61634691981f9dc367b53dac4070f8d0d /src/SFileVerify.cpp
parentff0c25952a28a927c48738ab5207b9bda69e588a (diff)
+ StormLib 9.0 BETA
Diffstat (limited to 'src/SFileVerify.cpp')
-rw-r--r--src/SFileVerify.cpp162
1 files changed, 75 insertions, 87 deletions
diff --git a/src/SFileVerify.cpp b/src/SFileVerify.cpp
index 4509388..219e187 100644
--- a/src/SFileVerify.cpp
+++ b/src/SFileVerify.cpp
@@ -20,25 +20,8 @@
//-----------------------------------------------------------------------------
// Local defines
-#define SIGNATURE_TYPE_NONE 0
-#define SIGNATURE_TYPE_WEAK 1
-#define SIGNATURE_TYPE_STRONG 2
-
#define MPQ_DIGEST_UNIT_SIZE 0x10000
-typedef struct _MPQ_SIGNATURE_INFO
-{
- ULONGLONG BeginMpqData; // File offset where the hashing starts
- ULONGLONG BeginExclude; // Begin of the excluded area (used for (signature) file)
- ULONGLONG EndExclude; // End of the excluded area (used for (signature) file)
- ULONGLONG EndMpqData; // File offset where the hashing ends
- ULONGLONG EndOfFile; // Size of the entire file
- BYTE Signature[MPQ_STRONG_SIGNATURE_SIZE + 0x10];
- DWORD cbSignatureSize; // Length of the signature
- int nSignatureType; // See SIGNATURE_TYPE_XXX
-
-} MPQ_SIGNATURE_INFO, *PMPQ_SIGNATURE_INFO;
-
//-----------------------------------------------------------------------------
// Known Blizzard public keys
// Created by Jean-Francois Roy using OpenSSL
@@ -156,7 +139,7 @@ static void GetPlainAnsiFileName(
const TCHAR * szFileName,
char * szPlainName)
{
- const TCHAR * szPlainNameT = GetPlainFileNameT(szFileName);
+ const TCHAR * szPlainNameT = GetPlainFileName(szFileName);
// Convert the plain name to ANSI
while(*szPlainNameT != 0)
@@ -186,67 +169,13 @@ static void CalculateArchiveRange(
}
}
- // Get the MPQ data end. This is stored in our MPQ header,
- // and it's been already prepared by SFileOpenArchive,
+ // Get the MPQ data end. This is stored in the MPQ header
pSI->EndMpqData = ha->MpqPos + ha->pHeader->ArchiveSize64;
// Get the size of the entire file
FileStream_GetSize(ha->pStream, &pSI->EndOfFile);
}
-static bool QueryMpqSignatureInfo(
- TMPQArchive * ha,
- PMPQ_SIGNATURE_INFO pSI)
-{
- ULONGLONG ExtraBytes;
- TMPQFile * hf;
- HANDLE hFile;
- DWORD dwFileSize;
-
- // Calculate the range of the MPQ
- CalculateArchiveRange(ha, pSI);
-
- // If there is "(signature)" file in the MPQ, it has a weak signature
- if(SFileOpenFileEx((HANDLE)ha, SIGNATURE_NAME, SFILE_OPEN_BASE_FILE, &hFile))
- {
- // Get the content of the signature
- SFileReadFile(hFile, pSI->Signature, sizeof(pSI->Signature), &pSI->cbSignatureSize, NULL);
-
- // Verify the size of the signature
- hf = (TMPQFile *)hFile;
-
- // We have to exclude the signature file from the digest
- pSI->BeginExclude = ha->MpqPos + hf->pFileEntry->ByteOffset;
- pSI->EndExclude = pSI->BeginExclude + hf->pFileEntry->dwCmpSize;
- dwFileSize = hf->dwDataSize;
-
- // Close the file
- SFileCloseFile(hFile);
- pSI->nSignatureType = SIGNATURE_TYPE_WEAK;
- return (dwFileSize == (MPQ_WEAK_SIGNATURE_SIZE + 8)) ? true : false;
- }
-
- // If there is extra bytes beyond the end of the archive,
- // it's the strong signature
- ExtraBytes = pSI->EndOfFile - pSI->EndMpqData;
- if(ExtraBytes >= (MPQ_STRONG_SIGNATURE_SIZE + 4))
- {
- // Read the strong signature
- if(!FileStream_Read(ha->pStream, &pSI->EndMpqData, pSI->Signature, (MPQ_STRONG_SIGNATURE_SIZE + 4)))
- return false;
-
- // Check the signature header "NGIS"
- if(pSI->Signature[0] != 'N' || pSI->Signature[1] != 'G' || pSI->Signature[2] != 'I' || pSI->Signature[3] != 'S')
- return false;
-
- pSI->nSignatureType = SIGNATURE_TYPE_STRONG;
- return true;
- }
-
- // Succeeded, but no known signature found
- return true;
-}
-
static bool CalculateMpqHashMd5(
TMPQArchive * ha,
PMPQ_SIGNATURE_INFO pSI,
@@ -723,7 +652,7 @@ static DWORD VerifyFile(
if(dwTotalBytes == 0)
{
// Check CRC32 and MD5 only if there is no patches
- if(hf->hfPatchFile == NULL)
+ if(hf->hfPatch == NULL)
{
// Check if the CRC32 matches.
if(dwFlags & SFILE_VERIFY_FILE_CRC)
@@ -781,6 +710,63 @@ static DWORD VerifyFile(
return dwVerifyResult;
}
+// Used in SFileGetFileInfo
+bool QueryMpqSignatureInfo(
+ TMPQArchive * ha,
+ PMPQ_SIGNATURE_INFO pSI)
+{
+ ULONGLONG ExtraBytes;
+ TMPQFile * hf;
+ HANDLE hFile;
+ DWORD dwFileSize;
+
+ // Make sure it's all zeroed
+ memset(pSI, 0, sizeof(MPQ_SIGNATURE_INFO));
+
+ // Calculate the range of the MPQ
+ CalculateArchiveRange(ha, pSI);
+
+ // If there is "(signature)" file in the MPQ, it has a weak signature
+ if(SFileOpenFileEx((HANDLE)ha, SIGNATURE_NAME, SFILE_OPEN_BASE_FILE, &hFile))
+ {
+ // Get the content of the signature
+ SFileReadFile(hFile, pSI->Signature, sizeof(pSI->Signature), &pSI->cbSignatureSize, NULL);
+
+ // Verify the size of the signature
+ hf = (TMPQFile *)hFile;
+
+ // We have to exclude the signature file from the digest
+ pSI->BeginExclude = ha->MpqPos + hf->pFileEntry->ByteOffset;
+ pSI->EndExclude = pSI->BeginExclude + hf->pFileEntry->dwCmpSize;
+ dwFileSize = hf->dwDataSize;
+
+ // Close the file
+ SFileCloseFile(hFile);
+ pSI->SignatureTypes |= SIGNATURE_TYPE_WEAK;
+ return (dwFileSize == (MPQ_WEAK_SIGNATURE_SIZE + 8)) ? true : false;
+ }
+
+ // If there is extra bytes beyond the end of the archive,
+ // it's the strong signature
+ ExtraBytes = pSI->EndOfFile - pSI->EndMpqData;
+ if(ExtraBytes >= (MPQ_STRONG_SIGNATURE_SIZE + 4))
+ {
+ // Read the strong signature
+ if(!FileStream_Read(ha->pStream, &pSI->EndMpqData, pSI->Signature, (MPQ_STRONG_SIGNATURE_SIZE + 4)))
+ return false;
+
+ // Check the signature header "NGIS"
+ if(pSI->Signature[0] != 'N' || pSI->Signature[1] != 'G' || pSI->Signature[2] != 'I' || pSI->Signature[3] != 'S')
+ return false;
+
+ pSI->SignatureTypes |= SIGNATURE_TYPE_STRONG;
+ return true;
+ }
+
+ // Succeeded, but no known signature found
+ return true;
+}
+
//-----------------------------------------------------------------------------
// Public (exported) functions
@@ -828,7 +814,7 @@ int WINAPI SFileVerifyRawData(HANDLE hMpq, DWORD dwWhatToVerify, const char * sz
TMPQHeader * pHeader;
// Verify input parameters
- if(!IsValidMpqHandle(ha))
+ if(!IsValidMpqHandle(hMpq))
return ERROR_INVALID_PARAMETER;
pHeader = ha->pHeader;
@@ -900,7 +886,7 @@ DWORD WINAPI SFileVerifyArchive(HANDLE hMpq)
TMPQArchive * ha = (TMPQArchive *)hMpq;
// Verify input parameters
- if(!IsValidMpqHandle(ha))
+ if(!IsValidMpqHandle(hMpq))
return ERROR_VERIFY_FAILED;
// Get the MPQ signature and signature type
@@ -908,18 +894,20 @@ DWORD WINAPI SFileVerifyArchive(HANDLE hMpq)
if(!QueryMpqSignatureInfo(ha, &si))
return ERROR_VERIFY_FAILED;
- // Verify the signature
- switch(si.nSignatureType)
- {
- case SIGNATURE_TYPE_NONE:
- return ERROR_NO_SIGNATURE;
+ // If there is no signature
+ if(si.SignatureTypes == 0)
+ return ERROR_NO_SIGNATURE;
- case SIGNATURE_TYPE_WEAK:
- return VerifyWeakSignature(ha, &si);
+ // We haven't seen a MPQ with both signatures
+ assert(si.SignatureTypes == SIGNATURE_TYPE_WEAK || si.SignatureTypes == SIGNATURE_TYPE_STRONG);
- case SIGNATURE_TYPE_STRONG:
- return VerifyStrongSignature(ha, &si);
- }
+ // Verify the strong signature, if present
+ if(si.SignatureTypes & SIGNATURE_TYPE_STRONG)
+ return VerifyStrongSignature(ha, &si);
+
+ // Verify the weak signature, if present
+ if(si.SignatureTypes & SIGNATURE_TYPE_WEAK)
+ return VerifyWeakSignature(ha, &si);
- return ERROR_VERIFY_FAILED;
+ return ERROR_NO_SIGNATURE;
}