static bool DoMPQSearch_FileEntry( TMPQSearch * hs, SFILE_FIND_DATA * lpFindFileData, TMPQArchive * ha, TMPQHash * pHashEntry, TFileEntry * pFileEntry) { TFileEntry * pPatchEntry; HANDLE hFile = NULL; const char * szFileName; size_t nPrefixLength = (ha->pPatchPrefix != NULL) ? ha->pPatchPrefix->nLength : 0; DWORD dwBlockIndex; char szNameBuff[MAX_PATH]; // 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)) { // 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) { // Open the file by its pseudo-name. sprintf(szNameBuff, "File%08u.xxx", (unsigned int)dwBlockIndex); if(SFileOpenFileEx((HANDLE)hs->ha, szNameBuff, SFILE_OPEN_BASE_FILE, &hFile)) { SFileGetFileName(hFile, szNameBuff); szFileName = szNameBuff; 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 = HASH_ENTRY_FREE; lpFindFileData->dwBlockIndex = dwBlockIndex; lpFindFileData->dwFileSize = pPatchEntry->dwFileSize; lpFindFileData->dwFileFlags = pPatchEntry->dwFlags; lpFindFileData->dwCompSize = pPatchEntry->dwCmpSize; lpFindFileData->lcLocale = 0; // pPatchEntry->lcLocale; // Fill the filetime lpFindFileData->dwFileTimeHi = (DWORD)(pPatchEntry->FileTime >> 32); lpFindFileData->dwFileTimeLo = (DWORD)(pPatchEntry->FileTime); // Fill-in the entries from hash table entry, if given if(pHashEntry != NULL) { lpFindFileData->dwHashIndex = (DWORD)(pHashEntry - ha->pHashTable); lpFindFileData->lcLocale = pHashEntry->lcLocale; } // Fill the file name and plain file name StringCopyA(lpFindFileData->cFileName, szFileName + nPrefixLength, MAX_PATH-1); lpFindFileData->szPlainName = (char *)GetPlainFileName(lpFindFileData->cFileName); return true; } } }
// Performs one MPQ search static int DoMPQSearch(TMPQSearch * hs, SFILE_FIND_DATA * lpFindFileData) { TMPQArchive * ha = hs->ha; TFileEntry * pFileTableEnd; TFileEntry * pPatchEntry; TFileEntry * pFileEntry; const char * szFileName; HANDLE hFile; char szPseudoName[20]; DWORD dwBlockIndex; size_t nPrefixLength; // Start searching with base MPQ while(ha != NULL) { // Now parse the file entry table in order to get all files. pFileTableEnd = ha->pFileTable + ha->dwFileTableSize; pFileEntry = ha->pFileTable + hs->dwNextIndex; // Get the length of the patch prefix (0 if none) nPrefixLength = strlen(ha->szPatchPrefix); // Parse the file table while(pFileEntry < pFileTableEnd) { // Increment the next index for subsequent search hs->dwNextIndex++; // Is it a file and 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) { // 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_BASE_FILE, &hFile)) { szFileName = (pFileEntry->szFileName != NULL) ? pFileEntry->szFileName : szPseudoName; SFileCloseFile(hFile); } } // 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++; }