static int ApplyMpqPatch( TMPQFile * hf, TPatchHeader * pPatchHeader) { unsigned char md5_digest[MD5_DIGEST_SIZE]; hash_state md5_state; int nError = ERROR_SUCCESS; // Verify the original file before patching if(pPatchHeader->dwSizeBeforePatch != 0) { md5_init(&md5_state); md5_process(&md5_state, hf->pbFileData, hf->cbFileData); md5_done(&md5_state, md5_digest); if(memcmp(pPatchHeader->md5_before_patch, md5_digest, MD5_DIGEST_SIZE)) nError = ERROR_FILE_CORRUPT; } // Apply the patch if(nError == ERROR_SUCCESS) { switch(pPatchHeader->dwPatchType) { case 0x59504f43: // 'COPY' nError = ApplyMpqPatch_COPY(hf, pPatchHeader); break; case 0x30445342: // 'BSD0' nError = ApplyMpqPatch_BSD0(hf, pPatchHeader); break; default: nError = ERROR_FILE_CORRUPT; break; } } // Verify MD5 after patch if(nError == ERROR_SUCCESS && pPatchHeader->dwSizeAfterPatch != 0) { // Verify the patched file md5_init(&md5_state); md5_process(&md5_state, hf->pbFileData, hf->cbFileData); md5_done(&md5_state, md5_digest); if(memcmp(pPatchHeader->md5_after_patch, md5_digest, MD5_DIGEST_SIZE)) nError = ERROR_FILE_CORRUPT; } return nError; }
static int ApplyMpqPatch( TMPQFile * hf, TPatchHeader * pPatchHeader) { int nError = ERROR_SUCCESS; // Verify the original file before patching if(pPatchHeader->dwSizeBeforePatch != 0) { if(!VerifyDataBlockHash(hf->pbFileData, hf->cbFileData, pPatchHeader->md5_before_patch)) nError = ERROR_FILE_CORRUPT; } // Apply the patch if(nError == ERROR_SUCCESS) { switch(pPatchHeader->dwPatchType) { case 0x59504f43: // 'COPY' nError = ApplyMpqPatch_COPY(hf, pPatchHeader); break; case 0x30445342: // 'BSD0' nError = ApplyMpqPatch_BSD0(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; } return nError; }