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; }
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); } }