static int ApplyFilePatch( TMPQFile * hfBase, // The file in the base MPQ TMPQFile * hfPrev, // The file in the previous MPQ TMPQFile * hf) { TPatchHeader * pPatchHeader = hf->pPatchHeader; TMPQFile * hfFrom = NULL; int nError = ERROR_SUCCESS; // Sanity checks assert(hf->pbFileData == NULL); // Either take the base version or the previous version if(!memcmp(hfBase->FileDataMD5, pPatchHeader->md5_before_patch, MD5_DIGEST_SIZE)) hfFrom = hfBase; if(!memcmp(hfPrev->FileDataMD5, pPatchHeader->md5_before_patch, MD5_DIGEST_SIZE)) hfFrom = hfPrev; if(hfFrom == NULL) return ERROR_FILE_CORRUPT; // Allocate the buffer for patched file content hf->pbFileData = STORM_ALLOC(BYTE, pPatchHeader->dwSizeAfterPatch); hf->cbFileData = pPatchHeader->dwSizeAfterPatch; if(hf->pbFileData == NULL) return ERROR_NOT_ENOUGH_MEMORY; // Apply the patch if(nError == ERROR_SUCCESS) { switch(pPatchHeader->dwPatchType) { case 0x59504f43: // 'COPY' nError = ApplyFilePatch_COPY(hfFrom, hf, pPatchHeader); break; case 0x30445342: // 'BSD0' nError = ApplyFilePatch_BSD0(hfFrom, hf, pPatchHeader); break; default: nError = ERROR_FILE_CORRUPT; break; } } // Verify MD5 after patch if(nError == ERROR_SUCCESS && pPatchHeader->dwSizeAfterPatch != 0) { // Verify the patched file if(!VerifyDataBlockHash(hf->pbFileData, hf->cbFileData, pPatchHeader->md5_after_patch)) nError = ERROR_FILE_CORRUPT; // Copy the MD5 of the new block memcpy(hf->FileDataMD5, pPatchHeader->md5_after_patch, MD5_DIGEST_SIZE); } return nError; }
static int ApplyFilePatch( TMPQPatcher * pPatcher, PMPQ_PATCH_HEADER pFullPatch) { LPBYTE pbSource = (pPatcher->nCounter & 0x1) ? pPatcher->pbFileData2 : pPatcher->pbFileData1; LPBYTE pbTarget = (pPatcher->nCounter & 0x1) ? pPatcher->pbFileData1 : pPatcher->pbFileData2; int nError; // Sanity checks assert(pFullPatch->dwSizeAfterPatch <= pPatcher->cbMaxFileData); // Apply the patch according to the type switch(pFullPatch->dwPatchType) { case 0x59504f43: // 'COPY' nError = ApplyFilePatch_COPY(pPatcher, pFullPatch, pbTarget, pbSource); break; case 0x30445342: // 'BSD0' nError = ApplyFilePatch_BSD0(pPatcher, pFullPatch, pbTarget, pbSource); break; default: nError = ERROR_FILE_CORRUPT; break; } // Verify MD5 after patch if(nError == ERROR_SUCCESS && pFullPatch->dwSizeAfterPatch != 0) { // Verify the patched file if(!VerifyDataBlockHash(pbTarget, pFullPatch->dwSizeAfterPatch, pFullPatch->md5_after_patch)) nError = ERROR_FILE_CORRUPT; // Copy the MD5 of the new block memcpy(pPatcher->this_md5, pFullPatch->md5_after_patch, MD5_DIGEST_SIZE); } return nError; }