示例#1
0
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;
                }
            }
        }
示例#2
0
// 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++;
        }