Esempio n. 1
0
static bool CheckConfigFileVariable(
    TCascStorage * hs,                  // Pointer to storage structure
    const char * szLinePtr,             // Pointer to the begin of the line
    const char * szLineEnd,             // Pointer to the end of the line
    const char * szVarName,             // Pointer to the variable to check
    PARSE_VARIABLE PfnParseProc,        // Pointer to the parsing function
    void * pvParseParam)                // Pointer to the parameter passed to parsing function
{
    char szVariableName[MAX_VAR_NAME];

    // Capture the variable from the line
    szLinePtr = CaptureSingleString(szLinePtr, szLineEnd, szVariableName, sizeof(szVariableName));
    if (szLinePtr == NULL)
        return false;

    // Verify whether this is the variable
    if (!CheckWildCard(szVariableName, szVarName))
        return false;

    // Skip the spaces and '='
    while (szLinePtr < szLineEnd && (IsWhiteSpace(szLinePtr) || szLinePtr[0] == '='))
        szLinePtr++;

    // Call the parsing function only if there is some data
    if (szLinePtr >= szLineEnd)
        return false;

    return (PfnParseProc(hs, szVariableName, szLinePtr, szLineEnd, pvParseParam) == ERROR_SUCCESS);
}
Esempio n. 2
0
size_t ListFile_GetNext(void * pvListFile, const char * szMask, char * szBuffer, size_t nMaxChars)
{
    TListFileCache * pCache = (TListFileCache *)pvListFile;
    size_t nLength = 0;
    int nError = ERROR_INVALID_PARAMETER;

    // Check for parameters
    if(pCache != NULL)
    {
        for(;;)
        {
            // Read the (next) line
            nLength = ReadListFileLine(pCache, szBuffer, nMaxChars);
            if(nLength == 0)
            {
                nError = ERROR_NO_MORE_FILES;
                break;
            }

            // If some mask entered, check it
            if(CheckWildCard(szBuffer, szMask))
            {
                nError = ERROR_SUCCESS;
                break;
            }
        }
    }

    if (nError != ERROR_SUCCESS)
        SetLastError((DWORD)nError);
    return nLength;
}
Esempio n. 3
0
bool WINAPI SListFileFindNextFile(HANDLE hFind, SFILE_FIND_DATA * lpFindFileData)
{
    TListFileCache * pCache = (TListFileCache *)hFind;
    size_t nLength;
    bool bResult = false;
    int nError = ERROR_SUCCESS;

    for(;;)
    {
        // Read the (next) line
        nLength = ReadListFileLine(pCache, lpFindFileData->cFileName, sizeof(lpFindFileData->cFileName));
        if(nLength == 0)
        {
            nError = ERROR_NO_MORE_FILES;
            break;
        }

        // If some mask entered, check it
        if(CheckWildCard(lpFindFileData->cFileName, pCache->szMask))
        {
            bResult = true;
            break;
        }
    }

    if(nError != ERROR_SUCCESS)
        SetLastError(nError);
    return bResult;
}
Esempio n. 4
0
size_t ListFile_GetNext(void * pvListFile, const char * szMask, char * szBuffer, size_t nMaxChars)
{
    size_t nLength = 0;
    int nError = ERROR_SUCCESS;

    // Check for parameters
    for(;;)
    {
        // Read the (next) line
        nLength = ListFile_GetNextLine(pvListFile, szBuffer, nMaxChars);
        if(nLength == 0)
        {
            nError = ERROR_NO_MORE_FILES;
            break;
        }

        // If some mask entered, check it
        if(CheckWildCard(szBuffer, szMask))
        {
            nError = ERROR_SUCCESS;
            break;
        }
    }

    if(nError != ERROR_SUCCESS)
        SetLastError(nError);
    return nLength;
}
Esempio n. 5
0
bool CheckWildCard(const char * szString, const char * szWildCard)
{
    const char * szWildCardPtr;

    for(;;)
    {
        // If there is '?' in the wildcard, we skip one char
        while(szWildCard[0] == '?')
        {
            if(szString[0] == 0)
                return false;

            szWildCard++;
            szString++;
        }

        // Handle '*'
        szWildCardPtr = szWildCard;
        if(szWildCardPtr[0] != 0)
        {
            if(szWildCardPtr[0] == '*')
            {
                szWildCardPtr++;

                if(szWildCardPtr[0] == '*')
                    continue;

                if(szWildCardPtr[0] == 0)
                    return true;

                if(AsciiToUpperTable[szWildCardPtr[0]] == AsciiToUpperTable[szString[0]])
                {
                    if(CheckWildCard(szString, szWildCardPtr))
                        return true;
                }
            }
            else
            {
                if(AsciiToUpperTable[szWildCardPtr[0]] != AsciiToUpperTable[szString[0]])
                    return false;

                szWildCard = szWildCardPtr + 1;
            }

            if(szString[0] == 0)
                return false;
            szString++;
        }
        else
        {
            return (szString[0] == 0) ? true : false;
        }
    }
}
Esempio n. 6
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;
                }
            }
        }
Esempio n. 7
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++;
        }
Esempio n. 8
0
HANDLE WINAPI SListFileFindFirstFile(HANDLE hMpq, const char * szListFile, const char * szMask, SFILE_FIND_DATA * lpFindFileData)
{
    TListFileCache * pCache = NULL;
    HANDLE hListFile = NULL;
    size_t nLength = 0;
    DWORD dwSearchScope = SFILE_OPEN_LOCAL_FILE;
    int nError = ERROR_SUCCESS;

    // Initialize the structure with zeros
    memset(lpFindFileData, 0, sizeof(SFILE_FIND_DATA));

    // If the szListFile is NULL, it means we have to open internal listfile
    if(szListFile == NULL)
    {
        // Use SFILE_OPEN_ANY_LOCALE for listfile. This will allow us to load
        // the listfile even if there is only non-neutral version of the listfile in the MPQ
        dwSearchScope = SFILE_OPEN_ANY_LOCALE;
        szListFile = LISTFILE_NAME;
    }

    // Open the local/internal listfile
    if(!SFileOpenFileEx(hMpq, szListFile, dwSearchScope, &hListFile))
        nError = GetLastError();

    // Load the listfile to cache
    if(nError == ERROR_SUCCESS)
    {
        pCache = CreateListFileCache(hListFile, szMask);
        if(pCache == NULL)
            nError = ERROR_FILE_CORRUPT;
    }

    // Perform file search
    if(nError == ERROR_SUCCESS)
    {
        for(;;)
        {
            // Read the (next) line
            nLength = ReadListFileLine(pCache, lpFindFileData->cFileName, sizeof(lpFindFileData->cFileName));
            if(nLength == 0)
            {
                nError = ERROR_NO_MORE_FILES;
                break;
            }

            // If some mask entered, check it
            if(CheckWildCard(lpFindFileData->cFileName, pCache->szMask))
                break;                
        }
    }

    // Cleanup & exit
    if(nError != ERROR_SUCCESS)
    {
        memset(lpFindFileData, 0, sizeof(SFILE_FIND_DATA));
        SetLastError(nError);
    }

    if(pCache != NULL)
        FreeListFileCache(pCache);
    if(hListFile != NULL)
        SFileCloseFile(hListFile);
    return (HANDLE)pCache;
}
Esempio n. 9
0
// Performs one MPQ search
static int DoMPQSearch(TMPQSearch * hs, SFILE_FIND_DATA * lpFindFileData)
{
    TMPQArchive * ha = hs->ha;
    TFileEntry * pFileTableEnd;
    TFileEntry * pFileEntry;
    const char * szFileName;
    char szPseudoName[20];
    DWORD dwBlockIndex;
    size_t nPrefixLength;

    // Do that for all files in the patch chain
    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 start and end of the hash table
        nPrefixLength = strlen(ha->szPatchPrefix);

        // Parse the file table
        while(pFileEntry < pFileTableEnd)
        {
            // Increment the next index for subsequent search
            hs->dwNextIndex++;

            // Does the block exist ?
            if(pFileEntry->dwFlags & MPQ_FILE_EXISTS)
            {
                // 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)
                {
                    HANDLE hFile;

                    // Open the file by index in order to check if the file exists
                    if(SFileOpenFileEx((HANDLE)hs->ha, (char *)(DWORD_PTR)dwBlockIndex, SFILE_OPEN_BY_INDEX, &hFile))
                        SFileCloseFile(hFile);

                    // If the name was retrieved, use that one. Otherwise, just use generic pseudo-name
                    szFileName = pFileEntry->szFileName;
                    if(szFileName == NULL)
                    {
                        sprintf(szPseudoName, "File%08u.xxx", dwBlockIndex);
                        szFileName = szPseudoName;
                    }
                }

                // If we are already in the patch MPQ, we skip all files
                // that don't have the appropriate patch prefix and are patch files
                if(ha->haBase != NULL)
                {
                    // If the file has different patch prefix, don't report it
                    if(nPrefixLength != 0 && _strnicmp(szFileName, ha->szPatchPrefix, nPrefixLength))
                        goto __SkipThisFile;

                    //
                    // We need to properly handle the following case:
                    //
                    // 1) Base MPQ file doesn't contain the desired file
                    // 2) First patch MPQ contains the file with MPQ_FILE_PATCH_FILE
                    // 3) Second patch contains full version of the file (MPQ_FILE_PATCH_FILE is not set)
                    //

                    if(IsBaseFileMissing(ha, szFileName, szFileName + nPrefixLength, pFileEntry->lcLocale))
                        goto __SkipThisFile;
                }

                // Check the file name.
                if(CheckWildCard(szFileName, hs->szSearchMask))
                {
                    // Fill the found entry
                    lpFindFileData->dwHashIndex  = pFileEntry->dwHashIndex;
                    lpFindFileData->dwBlockIndex = dwBlockIndex;
                    lpFindFileData->dwFileSize   = pFileEntry->dwFileSize;
                    lpFindFileData->dwFileFlags  = pFileEntry->dwFlags;
                    lpFindFileData->dwCompSize   = pFileEntry->dwCmpSize;
                    lpFindFileData->lcLocale     = pFileEntry->lcLocale;

                    // Fill the filetime
                    lpFindFileData->dwFileTimeHi = (DWORD)(pFileEntry->FileTime >> 32);
                    lpFindFileData->dwFileTimeLo = (DWORD)(pFileEntry->FileTime);

                    // Fill the file name and plain file name
                    strcpy(lpFindFileData->cFileName, szFileName + nPrefixLength);
                    lpFindFileData->szPlainName = (char *)GetPlainFileName(lpFindFileData->cFileName);
                    return ERROR_SUCCESS;
                }
            }

            // Move to the next file entry
__SkipThisFile:

            pFileEntry++;
        }