mirror of
https://github.com/mangosfour/server.git
synced 2025-12-12 19:37:03 +00:00
[Build] Larger build system update
FIXED: Core now builds under cmake for Windows TODO: Map and mmap gen currently does not build TODO: More sync work is required for Eluna, thus Eluna is temporarily disabled This has only been tested under Windows with CMAKE and VS
This commit is contained in:
parent
c2f9316581
commit
13292befd6
640 changed files with 100354 additions and 29918 deletions
|
|
@ -37,12 +37,14 @@ struct TMPQSearch
|
|||
//-----------------------------------------------------------------------------
|
||||
// Local functions
|
||||
|
||||
static bool IsValidSearchHandle(TMPQSearch * hs)
|
||||
static TMPQSearch * IsValidSearchHandle(HANDLE hFind)
|
||||
{
|
||||
if(hs == NULL)
|
||||
return false;
|
||||
TMPQSearch * hs = (TMPQSearch *)hFind;
|
||||
|
||||
return IsValidMpqHandle(hs->ha);
|
||||
if(hs != NULL && IsValidMpqHandle(hs->ha))
|
||||
return hs;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool CheckWildCard(const char * szString, const char * szWildCard)
|
||||
|
|
@ -69,7 +71,7 @@ bool CheckWildCard(const char * szString, const char * szWildCard)
|
|||
szString++;
|
||||
}
|
||||
|
||||
// If there is '*', means zero or more chars. We have to
|
||||
// If there is '*', means zero or more chars. We have to
|
||||
// find the sequence after '*'
|
||||
if(*szWildCard == '*')
|
||||
{
|
||||
|
|
@ -95,7 +97,7 @@ bool CheckWildCard(const char * szString, const char * szWildCard)
|
|||
// Calculate match count
|
||||
while(nMatchCount < nSubStringLength)
|
||||
{
|
||||
if(toupper(szString[nMatchCount]) != toupper(szWildCard[nMatchCount]))
|
||||
if(AsciiToUpperTable[(BYTE)szString[nMatchCount]] != AsciiToUpperTable[(BYTE)szWildCard[nMatchCount]])
|
||||
break;
|
||||
if(szString[nMatchCount] == 0)
|
||||
break;
|
||||
|
|
@ -118,7 +120,7 @@ bool CheckWildCard(const char * szString, const char * szWildCard)
|
|||
else
|
||||
{
|
||||
// If we came to the end of the string, compare it to the wildcard
|
||||
if(toupper(*szString) != toupper(*szWildCard))
|
||||
if(AsciiToUpperTable[(BYTE)*szString] != AsciiToUpperTable[(BYTE)*szWildCard])
|
||||
return false;
|
||||
|
||||
// If we arrived to the end of the string, it's a match
|
||||
|
|
@ -140,7 +142,7 @@ static DWORD GetSearchTableItems(TMPQArchive * ha)
|
|||
while(ha != NULL)
|
||||
{
|
||||
// Append the number of files
|
||||
dwMergeItems += (ha->pHetTable != NULL) ? ha->pHetTable->dwMaxFileCount
|
||||
dwMergeItems += (ha->pHetTable != NULL) ? ha->pHetTable->dwEntryCount
|
||||
: ha->pHeader->dwBlockTableSize;
|
||||
// Move to the patched archive
|
||||
ha = ha->haPatch;
|
||||
|
|
@ -151,9 +153,9 @@ static DWORD GetSearchTableItems(TMPQArchive * ha)
|
|||
}
|
||||
|
||||
static bool FileWasFoundBefore(
|
||||
TMPQArchive * ha,
|
||||
TMPQSearch * hs,
|
||||
TFileEntry * pFileEntry)
|
||||
TMPQArchive * ha,
|
||||
TMPQSearch * hs,
|
||||
TFileEntry * pFileEntry)
|
||||
{
|
||||
TFileEntry * pEntry;
|
||||
char * szRealFileName = pFileEntry->szFileName;
|
||||
|
|
@ -165,14 +167,14 @@ static bool FileWasFoundBefore(
|
|||
{
|
||||
// If we are in patch MPQ, we check if patch prefix matches
|
||||
// and then trim the patch prefix
|
||||
if(ha->cchPatchPrefix != 0)
|
||||
if(ha->pPatchPrefix != NULL)
|
||||
{
|
||||
// If the patch prefix doesn't fit, we pretend that the file
|
||||
// was there before and it will be skipped
|
||||
if(_strnicmp(szRealFileName, ha->szPatchPrefix, ha->cchPatchPrefix))
|
||||
if(_strnicmp(szRealFileName, ha->pPatchPrefix->szPatchPrefix, ha->pPatchPrefix->nLength))
|
||||
return true;
|
||||
|
||||
szRealFileName += ha->cchPatchPrefix;
|
||||
szRealFileName += ha->pPatchPrefix->nLength;
|
||||
}
|
||||
|
||||
// Calculate the hash to the table
|
||||
|
|
@ -211,6 +213,14 @@ static bool FileWasFoundBefore(
|
|||
return false;
|
||||
}
|
||||
|
||||
static inline bool FileEntryIsInvalid(
|
||||
TMPQArchive * ha,
|
||||
TFileEntry * pFileEntry)
|
||||
{
|
||||
// Spazzler3 protector: Some files are clearly wrong
|
||||
return ((ha->dwFlags & MPQ_FLAG_MALFORMED) && (pFileEntry->dwCmpSize & 0xFFFF0000) >= 0x7FFF0000);
|
||||
}
|
||||
|
||||
static TFileEntry * FindPatchEntry(TMPQArchive * ha, TFileEntry * pFileEntry)
|
||||
{
|
||||
TFileEntry * pPatchEntry = NULL;
|
||||
|
|
@ -223,9 +233,11 @@ static TFileEntry * FindPatchEntry(TMPQArchive * ha, TFileEntry * pFileEntry)
|
|||
{
|
||||
// Move to the patch archive
|
||||
ha = ha->haPatch;
|
||||
szFileName[0] = 0;
|
||||
|
||||
// Prepare the prefix for the file name
|
||||
strcpy(szFileName, ha->szPatchPrefix);
|
||||
if(ha->pPatchPrefix != NULL)
|
||||
strcpy(szFileName, ha->pPatchPrefix->szPatchPrefix);
|
||||
strcat(szFileName, pFileEntry->szFileName);
|
||||
|
||||
// Try to find the file there
|
||||
|
|
@ -259,7 +271,7 @@ static int DoMPQSearch(TMPQSearch * hs, SFILE_FIND_DATA * lpFindFileData)
|
|||
pFileEntry = ha->pFileTable + hs->dwNextIndex;
|
||||
|
||||
// Get the length of the patch prefix (0 if none)
|
||||
nPrefixLength = strlen(ha->szPatchPrefix);
|
||||
nPrefixLength = (ha->pPatchPrefix != NULL) ? ha->pPatchPrefix->nLength : 0;
|
||||
|
||||
// Parse the file table
|
||||
while(pFileEntry < pFileTableEnd)
|
||||
|
|
@ -267,61 +279,77 @@ static int DoMPQSearch(TMPQSearch * hs, SFILE_FIND_DATA * lpFindFileData)
|
|||
// Increment the next index for subsequent search
|
||||
hs->dwNextIndex++;
|
||||
|
||||
// Is it a file and not a patch file?
|
||||
// Is it a file but not a patch file?
|
||||
if((pFileEntry->dwFlags & hs->dwFlagMask) == MPQ_FILE_EXISTS)
|
||||
{
|
||||
// Now we have to check if this file was not enumerated before
|
||||
if(!FileWasFoundBefore(ha, hs, pFileEntry))
|
||||
{
|
||||
// Find a patch to this file
|
||||
pPatchEntry = FindPatchEntry(ha, pFileEntry);
|
||||
if(pPatchEntry == NULL)
|
||||
pPatchEntry = pFileEntry;
|
||||
|
||||
// Prepare the block index
|
||||
dwBlockIndex = (DWORD)(pFileEntry - ha->pFileTable);
|
||||
|
||||
// Get the file name. If it's not known, we will create pseudo-name
|
||||
szFileName = pFileEntry->szFileName;
|
||||
if(szFileName == NULL)
|
||||
// Spazzler3 protector: Some files are clearly wrong
|
||||
if(!FileEntryIsInvalid(ha, pFileEntry))
|
||||
{
|
||||
// Now we have to check if this file was not enumerated before
|
||||
if(!FileWasFoundBefore(ha, hs, pFileEntry))
|
||||
{
|
||||
// Open the file by its pseudo-name.
|
||||
// This also generates the file name with a proper extension
|
||||
sprintf(szPseudoName, "File%08u.xxx", dwBlockIndex);
|
||||
if(SFileOpenFileEx((HANDLE)hs->ha, szPseudoName, SFILE_OPEN_FROM_MPQ, &hFile))
|
||||
// if(pFileEntry != NULL && !_stricmp(pFileEntry->szFileName, "TriggerLibs\\NativeLib.galaxy"))
|
||||
// DebugBreak();
|
||||
|
||||
// Find a patch to this file
|
||||
pPatchEntry = FindPatchEntry(ha, pFileEntry);
|
||||
if(pPatchEntry == NULL)
|
||||
pPatchEntry = pFileEntry;
|
||||
|
||||
// Prepare the block index
|
||||
dwBlockIndex = (DWORD)(pFileEntry - ha->pFileTable);
|
||||
|
||||
// Get the file name. If it's not known, we will create pseudo-name
|
||||
szFileName = pFileEntry->szFileName;
|
||||
if(szFileName == NULL)
|
||||
{
|
||||
szFileName = (pFileEntry->szFileName != NULL) ? pFileEntry->szFileName : szPseudoName;
|
||||
SFileCloseFile(hFile);
|
||||
// Open the file by its pseudo-name.
|
||||
// This also generates the file name with a proper extension
|
||||
sprintf(szPseudoName, "File%08u.xxx", (unsigned int)dwBlockIndex);
|
||||
if(SFileOpenFileEx((HANDLE)hs->ha, szPseudoName, SFILE_OPEN_BASE_FILE, &hFile))
|
||||
{
|
||||
szFileName = (pFileEntry->szFileName != NULL) ? pFileEntry->szFileName : szPseudoName;
|
||||
SFileCloseFile(hFile);
|
||||
}
|
||||
}
|
||||
|
||||
// If the file name is still NULL, we cannot include the file to search results
|
||||
if(szFileName != NULL)
|
||||
{
|
||||
// Check the file name against the wildcard
|
||||
if(CheckWildCard(szFileName + nPrefixLength, hs->szSearchMask))
|
||||
{
|
||||
// Fill the found entry. hash entry and block index are taken from the base MPQ
|
||||
lpFindFileData->dwHashIndex = pFileEntry->dwHashIndex;
|
||||
lpFindFileData->dwBlockIndex = dwBlockIndex;
|
||||
lpFindFileData->dwFileSize = pPatchEntry->dwFileSize;
|
||||
lpFindFileData->dwFileFlags = pPatchEntry->dwFlags;
|
||||
lpFindFileData->dwCompSize = pPatchEntry->dwCmpSize;
|
||||
lpFindFileData->lcLocale = pPatchEntry->lcLocale;
|
||||
|
||||
// Fill the filetime
|
||||
lpFindFileData->dwFileTimeHi = (DWORD)(pPatchEntry->FileTime >> 32);
|
||||
lpFindFileData->dwFileTimeLo = (DWORD)(pPatchEntry->FileTime);
|
||||
|
||||
// Fill the file name and plain file name
|
||||
strcpy(lpFindFileData->cFileName, szFileName + nPrefixLength);
|
||||
lpFindFileData->szPlainName = (char *)GetPlainFileName(lpFindFileData->cFileName);
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check the file name against the wildcard
|
||||
if(CheckWildCard(szFileName + nPrefixLength, hs->szSearchMask))
|
||||
{
|
||||
// Fill the found entry
|
||||
lpFindFileData->dwHashIndex = pPatchEntry->dwHashIndex;
|
||||
lpFindFileData->dwBlockIndex = dwBlockIndex;
|
||||
lpFindFileData->dwFileSize = pPatchEntry->dwFileSize;
|
||||
lpFindFileData->dwFileFlags = pPatchEntry->dwFlags;
|
||||
lpFindFileData->dwCompSize = pPatchEntry->dwCmpSize;
|
||||
lpFindFileData->lcLocale = pPatchEntry->lcLocale;
|
||||
|
||||
// Fill the filetime
|
||||
lpFindFileData->dwFileTimeHi = (DWORD)(pPatchEntry->FileTime >> 32);
|
||||
lpFindFileData->dwFileTimeLo = (DWORD)(pPatchEntry->FileTime);
|
||||
|
||||
// Fill the file name and plain file name
|
||||
strcpy(lpFindFileData->cFileName, szFileName + nPrefixLength);
|
||||
lpFindFileData->szPlainName = (char *)GetPlainFileNameA(lpFindFileData->cFileName);
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
pFileEntry++;
|
||||
}
|
||||
|
||||
// If there is no more patches in the chain, stop it.
|
||||
// This also keeps hs->ha non-NULL, which is required
|
||||
// for freeing the handle later
|
||||
if(ha->haPatch == NULL)
|
||||
break;
|
||||
|
||||
// Move to the next patch in the patch chain
|
||||
hs->ha = ha = ha->haPatch;
|
||||
hs->dwNextIndex = 0;
|
||||
|
|
@ -353,7 +381,7 @@ HANDLE WINAPI SFileFindFirstFile(HANDLE hMpq, const char * szMask, SFILE_FIND_DA
|
|||
int nError = ERROR_SUCCESS;
|
||||
|
||||
// Check for the valid parameters
|
||||
if(!IsValidMpqHandle(ha))
|
||||
if(!IsValidMpqHandle(hMpq))
|
||||
nError = ERROR_INVALID_HANDLE;
|
||||
if(szMask == NULL || lpFindFileData == NULL)
|
||||
nError = ERROR_INVALID_PARAMETER;
|
||||
|
|
@ -406,18 +434,18 @@ HANDLE WINAPI SFileFindFirstFile(HANDLE hMpq, const char * szMask, SFILE_FIND_DA
|
|||
FreeMPQSearch(hs);
|
||||
SetLastError(nError);
|
||||
}
|
||||
|
||||
|
||||
// Return the result value
|
||||
return (HANDLE)hs;
|
||||
}
|
||||
|
||||
bool WINAPI SFileFindNextFile(HANDLE hFind, SFILE_FIND_DATA * lpFindFileData)
|
||||
{
|
||||
TMPQSearch * hs = (TMPQSearch *)hFind;
|
||||
TMPQSearch * hs = IsValidSearchHandle(hFind);
|
||||
int nError = ERROR_SUCCESS;
|
||||
|
||||
// Check the parameters
|
||||
if(!IsValidSearchHandle(hs))
|
||||
if(hs == NULL)
|
||||
nError = ERROR_INVALID_HANDLE;
|
||||
if(lpFindFileData == NULL)
|
||||
nError = ERROR_INVALID_PARAMETER;
|
||||
|
|
@ -432,10 +460,10 @@ bool WINAPI SFileFindNextFile(HANDLE hFind, SFILE_FIND_DATA * lpFindFileData)
|
|||
|
||||
bool WINAPI SFileFindClose(HANDLE hFind)
|
||||
{
|
||||
TMPQSearch * hs = (TMPQSearch *)hFind;
|
||||
TMPQSearch * hs = IsValidSearchHandle(hFind);
|
||||
|
||||
// Check the parameters
|
||||
if(!IsValidSearchHandle(hs))
|
||||
if(hs == NULL)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_HANDLE);
|
||||
return false;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue