From 124fef398a26bc8e139e889a2345602d2478590c Mon Sep 17 00:00:00 2001 From: Sean Hall Date: Wed, 3 Aug 2022 14:55:23 -0500 Subject: Add ability to skip a local path candidate if it failed verification. Fixes 6818 --- src/burn/engine/apply.cpp | 137 ++++++++++++++++++++++++++++++++++++------ src/burn/engine/cache.cpp | 70 ++++++++++++++++++--- src/burn/engine/cache.h | 5 ++ src/burn/engine/container.cpp | 1 + src/burn/engine/container.h | 4 +- src/burn/engine/elevation.cpp | 23 ++++++- src/burn/engine/payload.cpp | 1 + src/burn/engine/payload.h | 3 + src/burn/engine/plan.cpp | 6 +- 9 files changed, 221 insertions(+), 29 deletions(-) (limited to 'src/burn') diff --git a/src/burn/engine/apply.cpp b/src/burn/engine/apply.cpp index dd99a5cd..31d756a8 100644 --- a/src/burn/engine/apply.cpp +++ b/src/burn/engine/apply.cpp @@ -38,7 +38,7 @@ typedef struct _BURN_CACHE_CONTEXT LPWSTR* rgSearchPaths; DWORD cSearchPaths; DWORD cSearchPathsMax; - LPWSTR sczLastUsedFolderCandidate; + LPWSTR sczLocalAcquisitionSourcePath; } BURN_CACHE_CONTEXT; typedef struct _BURN_CACHE_PROGRESS_CONTEXT @@ -92,6 +92,16 @@ static HRESULT ApplyCachePackage( __in BURN_CACHE_CONTEXT* pContext, __in BURN_PACKAGE* pPackage ); +static void FinalizeContainerAcquisition( + __in BURN_CACHE_CONTEXT* pContext, + __in BURN_CONTAINER* pContainer, + __in BOOL fSuccess + ); +static void FinalizePayloadAcquisition( + __in BURN_CACHE_CONTEXT* pContext, + __in BURN_PAYLOAD* pPayload, + __in BOOL fSuccess + ); static HRESULT ApplyExtractContainer( __in BURN_CACHE_CONTEXT* pContext, __in BURN_CONTAINER* pContainer @@ -667,7 +677,7 @@ LExit: ReleaseNullStr(cacheContext.rgSearchPaths[i]); } ReleaseMem(cacheContext.rgSearchPaths); - ReleaseStr(cacheContext.sczLastUsedFolderCandidate); + ReleaseStr(cacheContext.sczLocalAcquisitionSourcePath); UserExperienceOnCacheComplete(pUX, hr); return hr; @@ -1038,6 +1048,46 @@ LExit: return hr; } +static void FinalizeContainerAcquisition( + __in BURN_CACHE_CONTEXT* pContext, + __in BURN_CONTAINER* pContainer, + __in BOOL fSuccess + ) +{ + ReleaseNullStr(pContainer->sczFailedLocalAcquisitionPath); + + if (fSuccess) + { + ReleaseNullStr(pContext->sczLocalAcquisitionSourcePath); + pContainer->fFailedVerificationFromAcquisition = FALSE; + } + else if (pContext->sczLocalAcquisitionSourcePath) + { + pContainer->sczFailedLocalAcquisitionPath = pContext->sczLocalAcquisitionSourcePath; + pContext->sczLocalAcquisitionSourcePath = NULL; + } +} + +static void FinalizePayloadAcquisition( + __in BURN_CACHE_CONTEXT* pContext, + __in BURN_PAYLOAD* pPayload, + __in BOOL fSuccess + ) +{ + ReleaseNullStr(pPayload->sczFailedLocalAcquisitionPath); + + if (fSuccess) + { + ReleaseNullStr(pContext->sczLocalAcquisitionSourcePath); + pPayload->fFailedVerificationFromAcquisition = FALSE; + } + else if (pContext->sczLocalAcquisitionSourcePath) + { + pPayload->sczFailedLocalAcquisitionPath = pContext->sczLocalAcquisitionSourcePath; + pContext->sczLocalAcquisitionSourcePath = NULL; + } +} + static HRESULT ApplyExtractContainer( __in BURN_CACHE_CONTEXT* pContext, __in BURN_CONTAINER* pContainer @@ -1066,10 +1116,11 @@ static HRESULT ApplyExtractContainer( hr = ExtractContainer(pContext, pContainer); LogExitOnFailure(hr, MSG_FAILED_EXTRACT_CONTAINER, "Failed to extract payloads from container: %ls to working path: %ls", pContainer->sczId, pContainer->sczUnverifiedPath); - if (pContext->sczLastUsedFolderCandidate) + if (pContext->sczLocalAcquisitionSourcePath) { // We successfully copied from a source location, set that as the last used source. - CacheSetLastUsedSource(pContext->pVariables, pContext->sczLastUsedFolderCandidate, pContainer->sczFilePath); + CacheSetLastUsedSource(pContext->pVariables, pContext->sczLocalAcquisitionSourcePath, pContainer->sczFilePath); + ReleaseNullStr(pContext->sczLocalAcquisitionSourcePath); } if (pContainer->qwExtractSizeTotal < pContainer->qwCommittedExtractProgress) @@ -1086,7 +1137,7 @@ static HRESULT ApplyExtractContainer( pContainer->qwCommittedExtractProgress = pContainer->qwExtractSizeTotal; LExit: - ReleaseNullStr(pContext->sczLastUsedFolderCandidate); + FinalizeContainerAcquisition(pContext, pContainer, SUCCEEDED(hr)); return hr; } @@ -1157,13 +1208,13 @@ static HRESULT ApplyLayoutContainer( ++cTryAgainAttempts; pContext->qwSuccessfulCacheProgress -= pContainer->qwCommittedCacheProgress; pContainer->qwCommittedCacheProgress = 0; - ReleaseNullStr(pContext->sczLastUsedFolderCandidate); + FinalizeContainerAcquisition(pContext, pContainer, FALSE); LogErrorId(hr, MSG_CACHE_RETRYING_CONTAINER, pContainer->sczId, NULL, NULL); } } LExit: - ReleaseNullStr(pContext->sczLastUsedFolderCandidate); + FinalizeContainerAcquisition(pContext, pContainer, SUCCEEDED(hr)); return hr; } @@ -1230,13 +1281,13 @@ static HRESULT ApplyProcessPayload( ++cTryAgainAttempts; pContext->qwSuccessfulCacheProgress -= pPayloadGroupItem->qwCommittedCacheProgress; pPayloadGroupItem->qwCommittedCacheProgress = 0; - ReleaseNullStr(pContext->sczLastUsedFolderCandidate); + FinalizePayloadAcquisition(pContext, pPayload, FALSE); LogErrorId(hr, MSG_CACHE_RETRYING_PAYLOAD, pPayload->sczKey, NULL, NULL); } } LExit: - ReleaseNullStr(pContext->sczLastUsedFolderCandidate); + FinalizePayloadAcquisition(pContext, pPayload, SUCCEEDED(hr)); return hr; } @@ -1570,6 +1621,7 @@ static HRESULT AcquireContainerOrPayload( BOOL fPreferExtract = FALSE; DWORD64 qwFileSize = 0; BOOL fMinimumFileSize = FALSE; + BOOL fEqual = FALSE; if (pContainer) { @@ -1615,21 +1667,44 @@ static HRESULT AcquireContainerOrPayload( // When a payload comes from a container, the container has the highest chance of being correct. // But we want to avoid extracting the container multiple times. // So only consider the destination path, which means the container was already extracted. - if (IsValidLocalFile(pContext->rgSearchPaths[dwDestinationSearchPath], qwFileSize, fMinimumFileSize)) + if (!pPayload->fFailedVerificationFromAcquisition && IsValidLocalFile(pContext->rgSearchPaths[dwDestinationSearchPath], qwFileSize, fMinimumFileSize)) { fFoundLocal = TRUE; dwChosenSearchPath = dwDestinationSearchPath; } - else // don't prefer the container if extracting it already failed. + else // don't prefer the container if it was already extracted. { - fPreferExtract = SUCCEEDED(pPayload->pContainer->hrExtract); + fPreferExtract = !pPayload->pContainer->fExtracted; } } if (!fFoundLocal) { + BOOL fFailedVerificationFromAcquisition = pContainer ? pContainer->fFailedVerificationFromAcquisition : pPayload->fFailedVerificationFromAcquisition; + LPCWSTR wzFailedLocalAcquisitionPath = pContainer ? pContainer->sczFailedLocalAcquisitionPath : pPayload->sczFailedLocalAcquisitionPath; + for (DWORD i = 0; i < pContext->cSearchPaths; ++i) { + // If the file failed verification from acquisition then certain paths should not be considered. + if (fFailedVerificationFromAcquisition) + { + if (i == dwDestinationSearchPath) + { + continue; + } + + if (wzFailedLocalAcquisitionPath) + { + hr = PathCompareCanonicalized(pContext->rgSearchPaths[i], wzFailedLocalAcquisitionPath, &fEqual); + ExitOnFailure(hr, "Failed to compare '%ls' to '%ls'.", pContext->rgSearchPaths[i], wzFailedLocalAcquisitionPath); + + if (fEqual) + { + continue; + } + } + } + // If the file exists locally with the correct size, choose it. if (IsValidLocalFile(pContext->rgSearchPaths[i], qwFileSize, fMinimumFileSize)) { @@ -1703,7 +1778,7 @@ static HRESULT AcquireContainerOrPayload( ExitOnFailure(hr, "Failed to copy payload: %ls", wzPayloadId); // Store the source path so it can be used as the LastUsedFolder if it passes verification. - pContext->sczLastUsedFolderCandidate = pContext->rgSearchPaths[dwChosenSearchPath]; + pContext->sczLocalAcquisitionSourcePath = pContext->rgSearchPaths[dwChosenSearchPath]; pContext->rgSearchPaths[dwChosenSearchPath] = NULL; } @@ -1731,12 +1806,14 @@ static HRESULT AcquireContainerOrPayload( LExit: if (BOOTSTRAPPER_CACHE_OPERATION_EXTRACT == cacheOperation) { - if (FAILED(hr) && SUCCEEDED(pPayload->pContainer->hrExtract) && + // If this was the first extraction attempt and it failed + // but there was a different method of acquisition available then recommend retrying. + if (FAILED(hr) && !pPayload->pContainer->fExtracted && (fFoundLocal || pPayload->downloadSource.sczUrl && *pPayload->downloadSource.sczUrl)) { *pfRetry = TRUE; } - pPayload->pContainer->hrExtract = hr; + pPayload->pContainer->fExtracted = TRUE; } UserExperienceOnCacheAcquireComplete(pContext->pUX, wzPackageOrContainerId, wzPayloadId, hr, pfRetry); @@ -2103,6 +2180,31 @@ static HRESULT CALLBACK CacheMessageHandler( hr = UserExperienceOnCacheContainerOrPayloadVerifyComplete(pProgress->pCacheContext->pUX, wzPackageOrContainerId, wzPayloadId, hr); break; } + case BURN_CACHE_MESSAGE_FAILURE: + switch (pMessage->failure.cacheStep) + { + case BURN_CACHE_STEP_HASH: + if (pProgress->pContainer) + { + LogStringLine(REPORT_DEBUG, "Verification failed on container: %ls", pProgress->pContainer->sczId); + pProgress->pContainer->fFailedVerificationFromAcquisition = TRUE; + } + else if (pProgress->pPayloadGroupItem) + { + LogStringLine(REPORT_DEBUG, "Verification failed on payload group item: %ls", pProgress->pPayloadGroupItem->pPayload->sczKey); + pProgress->pPayloadGroupItem->pPayload->fFailedVerificationFromAcquisition = TRUE; + } + else if (pProgress->pPayload) + { + LogStringLine(REPORT_DEBUG, "Verification failed on payload: %ls", pProgress->pPayload->sczKey); + pProgress->pPayload->fFailedVerificationFromAcquisition = TRUE; + } + else + { + LogStringLine(REPORT_DEBUG, "Verification failed on unknown item"); + } + break; + } } return hr; @@ -2159,10 +2261,11 @@ static HRESULT CompleteCacheProgress( pContext->pPayloadGroupItem->qwCommittedCacheProgress += qwFileSize; } - if (BURN_CACHE_PROGRESS_TYPE_FINALIZE == pContext->type && pContext->pCacheContext->sczLastUsedFolderCandidate) + if (BURN_CACHE_PROGRESS_TYPE_FINALIZE == pContext->type && pContext->pCacheContext->sczLocalAcquisitionSourcePath) { // We successfully copied from a source location, set that as the last used source. - CacheSetLastUsedSource(pContext->pCacheContext->pVariables, pContext->pCacheContext->sczLastUsedFolderCandidate, pContext->pContainer ? pContext->pContainer->sczFilePath : pContext->pPayloadGroupItem->pPayload->sczFilePath); + CacheSetLastUsedSource(pContext->pCacheContext->pVariables, pContext->pCacheContext->sczLocalAcquisitionSourcePath, pContext->pContainer ? pContext->pContainer->sczFilePath : pContext->pPayloadGroupItem->pPayload->sczFilePath); + ReleaseNullStr(pContext->pCacheContext->sczLocalAcquisitionSourcePath); } } else if (PROGRESS_CANCEL == dwResult) diff --git a/src/burn/engine/cache.cpp b/src/burn/engine/cache.cpp index eb5cc508..a23ce9ed 100644 --- a/src/burn/engine/cache.cpp +++ b/src/burn/engine/cache.cpp @@ -12,7 +12,11 @@ static const DWORD FILE_OPERATION_RETRY_WAIT = 2000; static HRESULT CacheVerifyPayloadSignature( __in BURN_PAYLOAD* pPayload, __in_z LPCWSTR wzUnverifiedPayloadPath, - __in HANDLE hFile + __in HANDLE hFile, + __in BURN_CACHE_STEP cacheStep, + __in PFN_BURNCACHEMESSAGEHANDLER pfnCacheMessageHandler, + __in LPPROGRESS_ROUTINE pfnProgress, + __in LPVOID pContext ); static HRESULT CalculatePotentialBaseWorkingFolders( __in BURN_CACHE* pCache, @@ -159,7 +163,11 @@ static HRESULT SendCacheCompleteMessage( __in LPVOID pContext, __in HRESULT hrStatus ); - +static HRESULT SendCacheFailureMessage( + __in PFN_BURNCACHEMESSAGEHANDLER pfnCacheMessageHandler, + __in LPVOID pContext, + __in BURN_CACHE_STEP cacheStep + ); extern "C" HRESULT CacheInitialize( __in BURN_CACHE* pCache, @@ -1254,11 +1262,16 @@ LExit: static HRESULT CacheVerifyPayloadSignature( __in BURN_PAYLOAD* pPayload, __in_z LPCWSTR wzUnverifiedPayloadPath, - __in HANDLE hFile + __in HANDLE hFile, + __in BURN_CACHE_STEP cacheStep, + __in PFN_BURNCACHEMESSAGEHANDLER pfnCacheMessageHandler, + __in LPPROGRESS_ROUTINE /*pfnProgress*/, + __in LPVOID pContext ) { HRESULT hr = S_OK; LONG er = ERROR_SUCCESS; + BOOL fFailedVerification = FALSE; GUID guidAuthenticode = WINTRUST_ACTION_GENERIC_VERIFY_V2; WINTRUST_FILE_INFO wfi = { }; @@ -1266,6 +1279,11 @@ static HRESULT CacheVerifyPayloadSignature( CRYPT_PROVIDER_DATA* pProviderData = NULL; CRYPT_PROVIDER_SGNR* pSigner = NULL; + hr = SendCacheBeginMessage(pfnCacheMessageHandler, pContext, cacheStep); + ExitOnFailure(hr, "Aborted cache verify payload signature begin."); + + fFailedVerification = TRUE; + // Verify the payload assuming online. wfi.cbStruct = sizeof(wfi); wfi.pcwszFilePath = wzUnverifiedPayloadPath; @@ -1297,7 +1315,19 @@ static HRESULT CacheVerifyPayloadSignature( hr = VerifyPayloadAgainstCertChain(pPayload, pSigner->pChainContext); ExitOnFailure(hr, "Failed to verify expected payload against actual certificate chain."); + fFailedVerification = FALSE; + + hr = SendCacheSuccessMessage(pfnCacheMessageHandler, pContext, pPayload->qwFileSize); + LExit: + if (fFailedVerification) + { + // Make sure the BA process marks this payload as having failed verification. + SendCacheFailureMessage(pfnCacheMessageHandler, pContext, cacheStep); + } + + SendCacheCompleteMessage(pfnCacheMessageHandler, pContext, hr); + return hr; } @@ -1744,7 +1774,7 @@ static HRESULT VerifyThenTransferPayload( switch (pPayload->verification) { case BURN_PAYLOAD_VERIFICATION_AUTHENTICODE: - hr = CacheVerifyPayloadSignature(pPayload, wzUnverifiedPayloadPath, hFile); + hr = CacheVerifyPayloadSignature(pPayload, wzUnverifiedPayloadPath, hFile, BURN_CACHE_STEP_HASH, pfnCacheMessageHandler, pfnProgress, pContext); ExitOnFailure(hr, "Failed to verify payload signature: %ls", wzCachedPath); break; case BURN_PAYLOAD_VERIFICATION_HASH: @@ -1890,7 +1920,7 @@ static HRESULT VerifyFileAgainstPayload( switch (pPayload->verification) { case BURN_PAYLOAD_VERIFICATION_AUTHENTICODE: - hr = CacheVerifyPayloadSignature(pPayload, wzVerifyPath, hFile); + hr = CacheVerifyPayloadSignature(pPayload, wzVerifyPath, hFile, cacheStep, pfnCacheMessageHandler, pfnProgress, pContext); ExitOnFailure(hr, "Failed to verify signature of payload: %ls", pPayload->sczKey); break; case BURN_PAYLOAD_VERIFICATION_HASH: @@ -2285,17 +2315,18 @@ static HRESULT VerifyHash( __in LPVOID pContext ) { - UNREFERENCED_PARAMETER(wzUnverifiedPayloadPath); - HRESULT hr = S_OK; BYTE rgbActualHash[SHA512_HASH_LEN] = { }; DWORD64 qwHashedBytes = 0; LPWSTR pszExpected = NULL; LPWSTR pszActual = NULL; + BOOL fFailedVerification = FALSE; hr = SendCacheBeginMessage(pfnCacheMessageHandler, pContext, cacheStep); ExitOnFailure(hr, "Aborted cache verify hash begin."); + fFailedVerification = TRUE; + if (fVerifyFileSize) { hr = VerifyFileSize(hFile, qwFileSize, wzUnverifiedPayloadPath); @@ -2323,9 +2354,17 @@ static HRESULT VerifyHash( } } + fFailedVerification = FALSE; + hr = SendCacheSuccessMessage(pfnCacheMessageHandler, pContext, qwFileSize); LExit: + if (fFailedVerification) + { + // Make sure the BA process marks this container or payload as having failed verification. + SendCacheFailureMessage(pfnCacheMessageHandler, pContext, cacheStep); + } + SendCacheCompleteMessage(pfnCacheMessageHandler, pContext, hr); ReleaseStr(pszActual); @@ -2448,3 +2487,20 @@ static HRESULT SendCacheCompleteMessage( return hr; } + +static HRESULT SendCacheFailureMessage( + __in PFN_BURNCACHEMESSAGEHANDLER pfnCacheMessageHandler, + __in LPVOID pContext, + __in BURN_CACHE_STEP cacheStep + ) +{ + HRESULT hr = S_OK; + BURN_CACHE_MESSAGE message = { }; + + message.type = BURN_CACHE_MESSAGE_FAILURE; + message.failure.cacheStep = cacheStep; + + hr = pfnCacheMessageHandler(&message, pContext); + + return hr; +} diff --git a/src/burn/engine/cache.h b/src/burn/engine/cache.h index 9c698b4b..cc28166e 100644 --- a/src/burn/engine/cache.h +++ b/src/burn/engine/cache.h @@ -13,6 +13,7 @@ enum BURN_CACHE_MESSAGE_TYPE BURN_CACHE_MESSAGE_BEGIN, BURN_CACHE_MESSAGE_SUCCESS, BURN_CACHE_MESSAGE_COMPLETE, + BURN_CACHE_MESSAGE_FAILURE, }; enum BURN_CACHE_STEP @@ -68,6 +69,10 @@ typedef struct _BURN_CACHE_MESSAGE { HRESULT hrStatus; } complete; + struct + { + BURN_CACHE_STEP cacheStep; + } failure; }; } BURN_CACHE_MESSAGE; diff --git a/src/burn/engine/container.cpp b/src/burn/engine/container.cpp index 2f21baa8..e6b91532 100644 --- a/src/burn/engine/container.cpp +++ b/src/burn/engine/container.cpp @@ -173,6 +173,7 @@ extern "C" void ContainersUninitialize( ReleaseStr(pContainer->downloadSource.sczUser); ReleaseStr(pContainer->downloadSource.sczPassword); ReleaseStr(pContainer->sczUnverifiedPath); + ReleaseStr(pContainer->sczFailedLocalAcquisitionPath); ReleaseDict(pContainer->sdhPayloads); } MemFree(pContainers->rgContainers); diff --git a/src/burn/engine/container.h b/src/burn/engine/container.h index f35f1da5..a38afa90 100644 --- a/src/burn/engine/container.h +++ b/src/burn/engine/container.h @@ -88,7 +88,9 @@ typedef struct _BURN_CONTAINER DWORD64 qwExtractSizeTotal; DWORD64 qwCommittedCacheProgress; DWORD64 qwCommittedExtractProgress; - HRESULT hrExtract; + BOOL fExtracted; + BOOL fFailedVerificationFromAcquisition; + LPWSTR sczFailedLocalAcquisitionPath; } BURN_CONTAINER; typedef struct _BURN_CONTAINERS diff --git a/src/burn/engine/elevation.cpp b/src/burn/engine/elevation.cpp index e165a257..ef9c6e97 100644 --- a/src/burn/engine/elevation.cpp +++ b/src/burn/engine/elevation.cpp @@ -42,6 +42,7 @@ typedef enum _BURN_ELEVATION_MESSAGE_TYPE BURN_ELEVATION_MESSAGE_TYPE_BURN_CACHE_BEGIN, BURN_ELEVATION_MESSAGE_TYPE_BURN_CACHE_COMPLETE, BURN_ELEVATION_MESSAGE_TYPE_BURN_CACHE_SUCCESS, + BURN_ELEVATION_MESSAGE_TYPE_BURN_CACHE_FAILURE, BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_PROGRESS, BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_PROCESS_CANCEL, BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_PROCESS_STARTED, @@ -1792,11 +1793,19 @@ static HRESULT ProcessBurnCacheMessages( case BURN_ELEVATION_MESSAGE_TYPE_BURN_CACHE_SUCCESS: // read message parameters hr = BuffReadNumber64((BYTE*)pMsg->pvData, pMsg->cbData, &iData, &message.success.qwFileSize); - ExitOnFailure(hr, "Failed to read begin cache step."); + ExitOnFailure(hr, "Failed to read success file size."); message.type = BURN_CACHE_MESSAGE_SUCCESS; break; + case BURN_ELEVATION_MESSAGE_TYPE_BURN_CACHE_FAILURE: + // read message parameters + hr = BuffReadNumber((BYTE*)pMsg->pvData, pMsg->cbData, &iData, reinterpret_cast(&message.failure.cacheStep)); + ExitOnFailure(hr, "Failed to read failure cache step."); + + message.type = BURN_CACHE_MESSAGE_FAILURE; + break; + case BURN_ELEVATION_MESSAGE_TYPE_PROGRESS_ROUTINE: fProgressRoutine = TRUE; break; @@ -3511,7 +3520,7 @@ static HRESULT CALLBACK BurnCacheMessageHandler( case BURN_CACHE_MESSAGE_BEGIN: // serialize message data hr = BuffWriteNumber(&pbData, &cbData, pMessage->begin.cacheStep); - ExitOnFailure(hr, "Failed to write progress percentage to message buffer."); + ExitOnFailure(hr, "Failed to write cache step to message buffer."); dwMessage = BURN_ELEVATION_MESSAGE_TYPE_BURN_CACHE_BEGIN; break; @@ -3526,10 +3535,18 @@ static HRESULT CALLBACK BurnCacheMessageHandler( case BURN_CACHE_MESSAGE_SUCCESS: hr = BuffWriteNumber64(&pbData, &cbData, pMessage->success.qwFileSize); - ExitOnFailure(hr, "Failed to count of files in use to message buffer."); + ExitOnFailure(hr, "Failed to write file size to message buffer."); dwMessage = BURN_ELEVATION_MESSAGE_TYPE_BURN_CACHE_SUCCESS; break; + + case BURN_CACHE_MESSAGE_FAILURE: + // serialize message data + hr = BuffWriteNumber(&pbData, &cbData, pMessage->failure.cacheStep); + ExitOnFailure(hr, "Failed to write cache step to message buffer."); + + dwMessage = BURN_ELEVATION_MESSAGE_TYPE_BURN_CACHE_FAILURE; + break; } // send message diff --git a/src/burn/engine/payload.cpp b/src/burn/engine/payload.cpp index a4450bf7..fe3d673e 100644 --- a/src/burn/engine/payload.cpp +++ b/src/burn/engine/payload.cpp @@ -240,6 +240,7 @@ extern "C" void PayloadUninitialize( ReleaseMem(pPayload->pbCertificateRootPublicKeyIdentifier); ReleaseStr(pPayload->sczSourcePath); ReleaseStr(pPayload->sczLocalFilePath); + ReleaseStr(pPayload->sczFailedLocalAcquisitionPath); ReleaseStr(pPayload->downloadSource.sczUrl); ReleaseStr(pPayload->downloadSource.sczUser); ReleaseStr(pPayload->downloadSource.sczPassword); diff --git a/src/burn/engine/payload.h b/src/burn/engine/payload.h index 14738506..351fd058 100644 --- a/src/burn/engine/payload.h +++ b/src/burn/engine/payload.h @@ -60,6 +60,9 @@ typedef struct _BURN_PAYLOAD LPWSTR sczUnverifiedPath; DWORD cRemainingInstances; + + BOOL fFailedVerificationFromAcquisition; + LPWSTR sczFailedLocalAcquisitionPath; } BURN_PAYLOAD; typedef struct _BURN_PAYLOADS diff --git a/src/burn/engine/plan.cpp b/src/burn/engine/plan.cpp index 5c9ebe08..e6997b64 100644 --- a/src/burn/engine/plan.cpp +++ b/src/burn/engine/plan.cpp @@ -2105,7 +2105,9 @@ static void ResetPlannedContainerState( pContainer->qwExtractSizeTotal = 0; pContainer->qwCommittedCacheProgress = 0; pContainer->qwCommittedExtractProgress = 0; - pContainer->hrExtract = S_OK; + pContainer->fExtracted = FALSE; + pContainer->fFailedVerificationFromAcquisition = FALSE; + ReleaseNullStr(pContainer->sczFailedLocalAcquisitionPath); } static void ResetPlannedPayloadsState( @@ -2118,7 +2120,9 @@ static void ResetPlannedPayloadsState( pPayload->cRemainingInstances = 0; pPayload->state = BURN_PAYLOAD_STATE_NONE; + pPayload->fFailedVerificationFromAcquisition = FALSE; ReleaseNullStr(pPayload->sczLocalFilePath); + ReleaseNullStr(pPayload->sczFailedLocalAcquisitionPath); } } -- cgit v1.2.3-55-g6feb