コード例 #1
0
static bool FindPatchPrefix_SC2(TMPQArchive * haBase, TMPQArchive * haPatch)
{
    TFileEntry * pFileTableEnd;
    TFileEntry * pFileEntry;
    TFileEntry * pBaseEntry;
    const char * szPlainName;
    char * szLstFileName;
    size_t cchWorkBuffer = 0x400;
    size_t cchBaseName;
    size_t cchDirName;
    bool bResult = false;

    // Find a *-md5.lst file in the base archive
    pBaseEntry = FindMd5ListFile(haBase);
    if(pBaseEntry == NULL)
        return false;
    cchBaseName = strlen(pBaseEntry->szFileName) + 1;

    // Allocate working buffer for merging LST file
    szLstFileName = STORM_ALLOC(char, cchWorkBuffer);
    if(szLstFileName != NULL)
    {
        // Find that file in the patch MPQ
        pFileTableEnd = haPatch->pFileTable + haPatch->dwFileTableSize;
        for(pFileEntry = haPatch->pFileTable; pFileEntry < pFileTableEnd; pFileEntry++)
        {
            // Find the "(patch_metadata)" file within that folder
            // Note that the file is always relatively small and contains the patch prefix
            // Checking for file size greatly speeds up the search process
            if(pFileEntry->szFileName && !(pFileEntry->dwFlags & MPQ_FILE_PATCH_FILE) && (0 < pFileEntry->dwFileSize && pFileEntry->dwFileSize < 0x40))
            {
                // If the plain file name matches, we need to check its MD5
                szPlainName = GetPlainFileName(pFileEntry->szFileName);
                cchDirName = (size_t)(szPlainName - pFileEntry->szFileName);

                // The file name must not too long and must be PATCH_METADATA_NAME
                if((cchDirName + cchBaseName) < cchWorkBuffer && _stricmp(szPlainName, PATCH_METADATA_NAME) == 0)
                {
                    // Construct the name of the eventuall LST file
                    memcpy(szLstFileName, pFileEntry->szFileName, cchDirName);
                    memcpy(szLstFileName + cchDirName, pBaseEntry->szFileName, cchBaseName);

                    // If there is the "*-md5.lst" file in that directory, we check its MD5
                    if(IsMatchingPatchFile(haPatch, szLstFileName, pBaseEntry->md5))
                    {
                        bResult = CreatePatchPrefix(haPatch, pFileEntry->szFileName, szPlainName);
                        break;
                    }
                }
            }
        }

        // Free the work buffer
        STORM_FREE(szLstFileName);
    }

    return bResult;
}
コード例 #2
0
static bool FindPatchPrefix_SC2(TMPQArchive * haBase, TMPQArchive * haPatch)
{
    TMPQNamePrefix * pPatchPrefix;
    TFileEntry * pBaseEntry;
    char * szLstFileName;
    char * szPlainName;
    size_t cchWorkBuffer = 0x400;
    bool bResult = false;

    // First-level patches: Find the same file within the patch archive
    // and verify by MD5-before-patch
    if(haBase->haPatch == NULL)
    {
        TFileEntry * pFileTableEnd = haPatch->pFileTable + haPatch->dwFileTableSize;
        TFileEntry * pFileEntry;

        // Allocate working buffer for merging LST file
        szLstFileName = STORM_ALLOC(char, cchWorkBuffer);
        if(szLstFileName != NULL)
        {
            // Find a *-md5.lst file in the base archive
            pBaseEntry = FindBaseLstFile(haBase);
            if(pBaseEntry == NULL)
            {
                STORM_FREE(szLstFileName);
                return false;
            }

            // Parse the entire file table
            for(pFileEntry = haPatch->pFileTable; pFileEntry < pFileTableEnd; pFileEntry++)
            {
                // Look for "patch_metadata" file
                if(IsPatchMetadataFile(pFileEntry))
                {
                    // Construct the name of the MD5 file
                    strcpy(szLstFileName, pFileEntry->szFileName);
                    szPlainName = (char *)GetPlainFileName(szLstFileName);
                    strcpy(szPlainName, pBaseEntry->szFileName);

                    // Check for matching MD5 file
                    if(IsMatchingPatchFile(haPatch, szLstFileName, pBaseEntry->md5))
                    {
                        bResult = CreatePatchPrefix(haPatch, szLstFileName, (size_t)(szPlainName - szLstFileName));
                        break;
                    }
                }
            }

            // Delete the merge buffer
            STORM_FREE(szLstFileName);
        }
    }