From 90cdf39e6e6b7d676ca33bee031fa2b865bb5fbd Mon Sep 17 00:00:00 2001 From: Sean Hall Date: Fri, 16 Apr 2021 10:09:26 -0500 Subject: Don't plan payloads. Contributes to #3640 and #5253 --- src/engine/apply.cpp | 758 +++++++++++++++---------------- src/engine/cache.cpp | 15 +- src/engine/cache.h | 1 + src/engine/container.cpp | 12 +- src/engine/container.h | 7 +- src/engine/core.cpp | 26 +- src/engine/core.h | 2 + src/engine/detect.cpp | 5 - src/engine/engine.mc | 4 +- src/engine/exeengine.cpp | 32 +- src/engine/manifest.cpp | 2 +- src/engine/msiengine.cpp | 47 +- src/engine/mspengine.cpp | 3 +- src/engine/msuengine.cpp | 12 +- src/engine/package.cpp | 14 +- src/engine/package.h | 9 +- src/engine/payload.cpp | 41 +- src/engine/payload.h | 12 + src/engine/plan.cpp | 893 ++++++------------------------------- src/engine/plan.h | 106 +---- src/engine/pseudobundle.cpp | 75 +--- src/engine/relatedbundle.cpp | 9 +- src/engine/userexperience.cpp | 2 +- src/test/BurnUnitTest/PlanTest.cpp | 211 ++------- 24 files changed, 718 insertions(+), 1580 deletions(-) diff --git a/src/engine/apply.cpp b/src/engine/apply.cpp index b79bf934..7e03ebf9 100644 --- a/src/engine/apply.cpp +++ b/src/engine/apply.cpp @@ -13,18 +13,28 @@ const DWORD BURN_CACHE_MAX_RECOMMENDED_VERIFY_TRYAGAIN_ATTEMPTS = 2; // structs -struct BURN_CACHE_ACQUIRE_PROGRESS_CONTEXT +typedef struct _BURN_CACHE_CONTEXT { BURN_USER_EXPERIENCE* pUX; + BURN_VARIABLES* pVariables; + BURN_PAYLOADS* pPayloads; + HANDLE hPipe; + HANDLE hSourceEngineFile; + DWORD64 qwTotalCacheSize; + DWORD64 qwSuccessfulCacheProgress; + LPCWSTR wzLayoutDirectory; +} BURN_CACHE_CONTEXT; + +typedef struct _BURN_CACHE_ACQUIRE_PROGRESS_CONTEXT +{ + BURN_CACHE_CONTEXT* pCacheContext; BURN_CONTAINER* pContainer; BURN_PACKAGE* pPackage; BURN_PAYLOAD* pPayload; - DWORD64 qwCacheProgress; - DWORD64 qwTotalCacheSize; BOOL fCancel; BOOL fError; -}; +} BURN_CACHE_ACQUIRE_PROGRESS_CONTEXT; typedef struct _BURN_EXECUTE_CONTEXT { @@ -56,50 +66,49 @@ static HRESULT ExecuteDependentRegistrationActions( __in_ecount(cActions) const BURN_DEPENDENT_REGISTRATION_ACTION* rgActions, __in DWORD cActions ); -static HRESULT ExtractContainer( - __in HANDLE hSourceEngineFile, - __in BURN_CONTAINER* pContainer, - __in_z LPCWSTR wzContainerPath, - __in_ecount(cExtractPayloads) BURN_EXTRACT_PAYLOAD* rgExtractPayloads, - __in DWORD cExtractPayloads +static HRESULT ApplyCachePackage( + __in BURN_CACHE_CONTEXT* pContext, + __in BURN_PACKAGE* pPackage ); -static void UpdateCacheSuccessProgress( - __in BURN_PLAN* pPlan, - __in BURN_CACHE_ACTION* pCacheAction, - __inout DWORD64* pqwSuccessfulCachedProgress +static HRESULT ApplyExtractContainer( + __in BURN_CACHE_CONTEXT* pContext, + __in BURN_CONTAINER* pContainer + ); +static HRESULT ApplyLayoutBundle( + __in BURN_CACHE_CONTEXT* pContext, + __in BURN_PAYLOAD_GROUP* pPayloads, + __in_z LPCWSTR wzExecutableName, + __in_z LPCWSTR wzUnverifiedPath + ); +static HRESULT ApplyLayoutContainer( + __in BURN_CACHE_CONTEXT* pContext, + __in BURN_CONTAINER* pContainer + ); +static HRESULT ApplyProcessPayload( + __in BURN_CACHE_CONTEXT* pContext, + __in_opt BURN_PACKAGE* pPackage, + __in BURN_PAYLOAD* pPayload + ); +static HRESULT ExtractContainer( + __in BURN_CACHE_CONTEXT* pContext, + __in BURN_CONTAINER* pContainer ); static HRESULT LayoutBundle( - __in HANDLE hSourceEngineFile, - __in BURN_USER_EXPERIENCE* pUX, - __in BURN_VARIABLES* pVariables, - __in HANDLE hPipe, + __in BURN_CACHE_CONTEXT* pContext, __in_z LPCWSTR wzExecutableName, - __in_z LPCWSTR wzLayoutDirectory, - __in_z LPCWSTR wzUnverifiedPath, - __in DWORD64 qwSuccessfulCacheProgress, - __in DWORD64 qwTotalCacheSize + __in_z LPCWSTR wzUnverifiedPath ); static HRESULT AcquireContainerOrPayload( - __in BURN_USER_EXPERIENCE* pUX, - __in BURN_VARIABLES* pVariables, + __in BURN_CACHE_CONTEXT* pContext, __in_opt BURN_CONTAINER* pContainer, __in_opt BURN_PACKAGE* pPackage, - __in_opt BURN_PAYLOAD* pPayload, - __in LPCWSTR wzDestinationPath, - __in DWORD64 qwSuccessfulCacheProgress, - __in DWORD64 qwTotalCacheSize + __in_opt BURN_PAYLOAD* pPayload ); static HRESULT LayoutOrCacheContainerOrPayload( - __in BURN_USER_EXPERIENCE* pUX, - __in HANDLE hPipe, + __in BURN_CACHE_CONTEXT* pContext, __in_opt BURN_CONTAINER* pContainer, __in_opt BURN_PACKAGE* pPackage, __in_opt BURN_PAYLOAD* pPayload, - __in BOOL fAlreadyProvidedProgress, - __in DWORD64 qwSuccessfullyCacheProgress, - __in DWORD64 qwTotalCacheSize, - __in_z_opt LPCWSTR wzLayoutDirectory, - __in_z LPCWSTR wzUnverifiedPath, __in BOOL fMove, __in DWORD cTryAgainAttempts, __out BOOL* pfRetry @@ -461,268 +470,83 @@ extern "C" HRESULT ApplyCache( { HRESULT hr = S_OK; DWORD dwCheckpoint = 0; - BOOL fRetry = FALSE; - DWORD iRetryAction = BURN_PLAN_INVALID_ACTION_INDEX; - BURN_PACKAGE* pStartedPackage = NULL; - DWORD64 qwSuccessfulCachedProgress = 0; - - // Allow us to retry and skip packages. - DWORD iPackageStartAction = BURN_PLAN_INVALID_ACTION_INDEX; - DWORD iPackageCompleteAction = BURN_PLAN_INVALID_ACTION_INDEX; + BURN_CACHE_CONTEXT cacheContext = { }; + BURN_PACKAGE* pPackage = NULL; *pfRollback = FALSE; hr = UserExperienceOnCacheBegin(pUX); ExitOnRootFailure(hr, "BA aborted cache."); - do - { - hr = S_OK; - fRetry = FALSE; + cacheContext.hSourceEngineFile = hSourceEngineFile; + cacheContext.pPayloads = pPlan->pPayloads; + cacheContext.pUX = pUX; + cacheContext.pVariables = pVariables; + cacheContext.qwTotalCacheSize = pPlan->qwCacheSizeTotal; + cacheContext.wzLayoutDirectory = pPlan->sczLayoutDirectory; - // Allow us to retry just a container or payload. - LPCWSTR wzRetryId = NULL; - DWORD iRetryContainerOrPayloadAction = BURN_PLAN_INVALID_ACTION_INDEX; - BOOTSTRAPPER_CACHEPACKAGECOMPLETE_ACTION cachePackageCompleteAction = BOOTSTRAPPER_CACHEPACKAGECOMPLETE_ACTION_NONE; + for (DWORD i = 0; i < pPlan->cCacheActions; ++i) + { + BURN_CACHE_ACTION* pCacheAction = pPlan->rgCacheActions + i; + cacheContext.hPipe = hPipe; + pPackage = NULL; - // cache actions - for (DWORD i = (BURN_PLAN_INVALID_ACTION_INDEX == iRetryAction) ? 0 : iRetryAction; SUCCEEDED(hr) && i < pPlan->cCacheActions; ++i) + switch (pCacheAction->type) { - BURN_CACHE_ACTION* pCacheAction = pPlan->rgCacheActions + i; - BOOL fRetryContainerOrPayload = FALSE; - cachePackageCompleteAction = BOOTSTRAPPER_CACHEPACKAGECOMPLETE_ACTION_NONE; - - if (pCacheAction->fSkipUntilRetried) - { - // If this action was retried, let's make sure it will not be skipped any longer. - if (iRetryAction == i) - { - pCacheAction->fSkipUntilRetried = FALSE; - } - else // skip the action. - { - continue; - } - } - - switch (pCacheAction->type) - { - case BURN_CACHE_ACTION_TYPE_CHECKPOINT: - dwCheckpoint = pCacheAction->checkpoint.dwId; - break; - - case BURN_CACHE_ACTION_TYPE_LAYOUT_BUNDLE: - hr = LayoutBundle(hSourceEngineFile, pUX, pVariables, hPipe, pCacheAction->bundleLayout.sczExecutableName, pCacheAction->bundleLayout.sczLayoutDirectory, pCacheAction->bundleLayout.sczUnverifiedPath, qwSuccessfulCachedProgress, pPlan->qwCacheSizeTotal); - if (SUCCEEDED(hr)) - { - UpdateCacheSuccessProgress(pPlan, pCacheAction, &qwSuccessfulCachedProgress); - ++(*pcOverallProgressTicks); - - hr = ReportOverallProgressTicks(pUX, FALSE, pPlan->cOverallProgressTicksTotal, *pcOverallProgressTicks); - if (FAILED(hr)) - { - LogErrorId(hr, MSG_USER_CANCELED, L"layout bundle", NULL, NULL); - } - } - break; - - case BURN_CACHE_ACTION_TYPE_PACKAGE_START: - iPackageStartAction = i; // if we retry this package, we'll start here in the plan. - iPackageCompleteAction = pCacheAction->packageStart.iPackageCompleteAction; // if we ignore this package, we'll start after the complete action in the plan. - pStartedPackage = pCacheAction->packageStart.pPackage; - - hr = UserExperienceOnCachePackageBegin(pUX, pStartedPackage->sczId, pCacheAction->packageStart.cCachePayloads, pCacheAction->packageStart.qwCachePayloadSizeTotal); - if (FAILED(hr)) - { - LogErrorId(hr, MSG_USER_CANCELED, L"begin cache package", pStartedPackage->sczId, NULL); - } - break; - - case BURN_CACHE_ACTION_TYPE_ACQUIRE_CONTAINER: - hr = AcquireContainerOrPayload(pUX, pVariables, pCacheAction->resolveContainer.pContainer, NULL, NULL, pCacheAction->resolveContainer.sczUnverifiedPath, qwSuccessfulCachedProgress, pPlan->qwCacheSizeTotal); - if (SUCCEEDED(hr)) - { - UpdateCacheSuccessProgress(pPlan, pCacheAction, &qwSuccessfulCachedProgress); - } - else - { - LogErrorId(hr, MSG_FAILED_ACQUIRE_CONTAINER, pCacheAction->resolveContainer.pContainer->sczId, pCacheAction->resolveContainer.sczUnverifiedPath, NULL); - } - break; - - case BURN_CACHE_ACTION_TYPE_EXTRACT_CONTAINER: - // If this action is to be skipped until the acquire action is not skipped and the other - // action is still being skipped then skip this action. - if (BURN_PLAN_INVALID_ACTION_INDEX != pCacheAction->extractContainer.iSkipUntilAcquiredByAction && pPlan->rgCacheActions[pCacheAction->extractContainer.iSkipUntilAcquiredByAction].fSkipUntilRetried) - { - break; - } - - hr = ExtractContainer(hSourceEngineFile, pCacheAction->extractContainer.pContainer, pCacheAction->extractContainer.sczContainerUnverifiedPath, pCacheAction->extractContainer.rgPayloads, pCacheAction->extractContainer.cPayloads); - if (FAILED(hr)) - { - LogErrorId(hr, MSG_FAILED_EXTRACT_CONTAINER, pCacheAction->extractContainer.pContainer->sczId, pCacheAction->extractContainer.sczContainerUnverifiedPath, NULL); - } - break; - - case BURN_CACHE_ACTION_TYPE_LAYOUT_CONTAINER: - hr = LayoutOrCacheContainerOrPayload(pUX, hPipe, pCacheAction->layoutContainer.pContainer, pCacheAction->layoutContainer.pPackage, NULL, pPlan->rgContainerProgress[pCacheAction->layoutContainer.iProgress].fCachedDuringApply, qwSuccessfulCachedProgress, pPlan->qwCacheSizeTotal, pCacheAction->layoutContainer.sczLayoutDirectory, pCacheAction->layoutContainer.sczUnverifiedPath, pCacheAction->layoutContainer.fMove, pCacheAction->layoutContainer.cTryAgainAttempts, &fRetryContainerOrPayload); - if (SUCCEEDED(hr)) - { - UpdateCacheSuccessProgress(pPlan, pCacheAction, &qwSuccessfulCachedProgress); - } - else - { - LogErrorId(hr, MSG_FAILED_LAYOUT_CONTAINER, pCacheAction->layoutContainer.pContainer->sczId, pCacheAction->layoutContainer.sczLayoutDirectory, pCacheAction->layoutContainer.sczUnverifiedPath); - - if (fRetryContainerOrPayload) - { - wzRetryId = pCacheAction->layoutContainer.pContainer->sczId; - iRetryContainerOrPayloadAction = pCacheAction->layoutContainer.iTryAgainAction; - - ++pCacheAction->layoutContainer.cTryAgainAttempts; - } - } - break; - - case BURN_CACHE_ACTION_TYPE_ACQUIRE_PAYLOAD: - hr = AcquireContainerOrPayload(pUX, pVariables, NULL, pCacheAction->resolvePayload.pPackage, pCacheAction->resolvePayload.pPayload, pCacheAction->resolvePayload.sczUnverifiedPath, qwSuccessfulCachedProgress, pPlan->qwCacheSizeTotal); - if (SUCCEEDED(hr)) - { - UpdateCacheSuccessProgress(pPlan, pCacheAction, &qwSuccessfulCachedProgress); - } - else - { - LogErrorId(hr, MSG_FAILED_ACQUIRE_PAYLOAD, pCacheAction->resolvePayload.pPayload->sczKey, pCacheAction->resolvePayload.sczUnverifiedPath, NULL); - } - break; - - case BURN_CACHE_ACTION_TYPE_CACHE_PAYLOAD: - hr = LayoutOrCacheContainerOrPayload(pUX, pCacheAction->cachePayload.pPackage->fPerMachine ? hPipe : INVALID_HANDLE_VALUE, NULL, pCacheAction->cachePayload.pPackage, pCacheAction->cachePayload.pPayload, pPlan->rgPayloadProgress[pCacheAction->cachePayload.iProgress].fCachedDuringApply, qwSuccessfulCachedProgress, pPlan->qwCacheSizeTotal, NULL, pCacheAction->cachePayload.sczUnverifiedPath, pCacheAction->cachePayload.fMove, pCacheAction->cachePayload.cTryAgainAttempts, &fRetryContainerOrPayload); - if (SUCCEEDED(hr)) - { - UpdateCacheSuccessProgress(pPlan, pCacheAction, &qwSuccessfulCachedProgress); - } - else - { - LogErrorId(hr, MSG_FAILED_CACHE_PAYLOAD, pCacheAction->cachePayload.pPayload->sczKey, pCacheAction->cachePayload.sczUnverifiedPath, NULL); - - if (fRetryContainerOrPayload) - { - wzRetryId = pCacheAction->cachePayload.pPayload->sczKey; - iRetryContainerOrPayloadAction = pCacheAction->cachePayload.iTryAgainAction; - - ++pCacheAction->cachePayload.cTryAgainAttempts; - } - } - break; - - case BURN_CACHE_ACTION_TYPE_LAYOUT_PAYLOAD: - hr = LayoutOrCacheContainerOrPayload(pUX, hPipe, NULL, pCacheAction->layoutPayload.pPackage, pCacheAction->layoutPayload.pPayload, pPlan->rgPayloadProgress[pCacheAction->layoutPayload.iProgress].fCachedDuringApply, qwSuccessfulCachedProgress, pPlan->qwCacheSizeTotal, pCacheAction->layoutPayload.sczLayoutDirectory, pCacheAction->layoutPayload.sczUnverifiedPath, pCacheAction->layoutPayload.fMove, pCacheAction->layoutPayload.cTryAgainAttempts, &fRetryContainerOrPayload); - if (SUCCEEDED(hr)) - { - UpdateCacheSuccessProgress(pPlan, pCacheAction, &qwSuccessfulCachedProgress); - } - else - { - LogErrorId(hr, MSG_FAILED_LAYOUT_PAYLOAD, pCacheAction->layoutPayload.pPayload->sczKey, pCacheAction->layoutPayload.sczLayoutDirectory, pCacheAction->layoutPayload.sczUnverifiedPath); - - if (fRetryContainerOrPayload) - { - wzRetryId = pCacheAction->layoutPayload.pPayload->sczKey; - iRetryContainerOrPayloadAction = pCacheAction->layoutPayload.iTryAgainAction; - - ++pCacheAction->layoutPayload.cTryAgainAttempts; - } - } - break; - - case BURN_CACHE_ACTION_TYPE_PACKAGE_STOP: - AssertSz(pStartedPackage == pCacheAction->packageStop.pPackage, "Expected package started cached to be the same as the package checkpointed."); + case BURN_CACHE_ACTION_TYPE_CHECKPOINT: + dwCheckpoint = pCacheAction->checkpoint.dwId; + break; - hr = ReportOverallProgressTicks(pUX, FALSE, pPlan->cOverallProgressTicksTotal, *pcOverallProgressTicks + 1); - if (FAILED(hr)) - { - LogErrorId(hr, MSG_USER_CANCELED, L"end cache package", NULL, NULL); - } - else - { - ++(*pcOverallProgressTicks); + case BURN_CACHE_ACTION_TYPE_LAYOUT_BUNDLE: + hr = ApplyLayoutBundle(&cacheContext, pCacheAction->bundleLayout.pPayloadGroup, pCacheAction->bundleLayout.sczExecutableName, pCacheAction->bundleLayout.sczUnverifiedPath); + ExitOnFailure(hr, "Failed cache action: %ls", L"layout bundle"); - UserExperienceOnCachePackageComplete(pUX, pStartedPackage->sczId, hr, &cachePackageCompleteAction); + ++(*pcOverallProgressTicks); - pStartedPackage->hrCacheResult = hr; + hr = ReportOverallProgressTicks(pUX, FALSE, pPlan->cOverallProgressTicksTotal, *pcOverallProgressTicks); + LogExitOnFailure(hr, MSG_USER_CANCELED, "Cancel during cache: %ls", L"layout bundle"); - iPackageStartAction = BURN_PLAN_INVALID_ACTION_INDEX; - iPackageCompleteAction = BURN_PLAN_INVALID_ACTION_INDEX; - pStartedPackage = NULL; - } - break; + break; - case BURN_CACHE_ACTION_TYPE_SIGNAL_SYNCPOINT: - if (!::SetEvent(pCacheAction->syncpoint.hEvent)) - { - ExitWithLastError(hr, "Failed to set syncpoint event."); - } - break; + case BURN_CACHE_ACTION_TYPE_PACKAGE: + pPackage = pCacheAction->package.pPackage; - default: - AssertSz(FALSE, "Unknown cache action."); - break; + if (!pPackage->fPerMachine && !cacheContext.wzLayoutDirectory) + { + cacheContext.hPipe = INVALID_HANDLE_VALUE; } - } - - if (BURN_PLAN_INVALID_ACTION_INDEX != iRetryContainerOrPayloadAction) - { - Assert(wzRetryId); - LogErrorId(hr, MSG_APPLY_RETRYING_PAYLOAD, wzRetryId, NULL, NULL); + hr = ApplyCachePackage(&cacheContext, pPackage); + ExitOnFailure(hr, "Failed cache action: %ls", L"cache package"); - iRetryAction = iRetryContainerOrPayloadAction; - fRetry = TRUE; - } - else if (pStartedPackage) - { - Assert(BURN_PLAN_INVALID_ACTION_INDEX != iPackageStartAction); - Assert(BURN_PLAN_INVALID_ACTION_INDEX != iPackageCompleteAction); + ++(*pcOverallProgressTicks); - cachePackageCompleteAction = SUCCEEDED(hr) || pStartedPackage->fVital ? BOOTSTRAPPER_CACHEPACKAGECOMPLETE_ACTION_NONE : BOOTSTRAPPER_CACHEPACKAGECOMPLETE_ACTION_IGNORE; - UserExperienceOnCachePackageComplete(pUX, pStartedPackage->sczId, hr, &cachePackageCompleteAction); - if (BOOTSTRAPPER_CACHEPACKAGECOMPLETE_ACTION_RETRY == cachePackageCompleteAction) - { - LogErrorId(hr, MSG_APPLY_RETRYING_PACKAGE, pStartedPackage->sczId, NULL, NULL); + hr = ReportOverallProgressTicks(pUX, FALSE, pPlan->cOverallProgressTicksTotal, *pcOverallProgressTicks); + LogExitOnFailure(hr, MSG_USER_CANCELED, "Cancel during cache: %ls", L"cache package"); - iRetryAction = iPackageStartAction; - fRetry = TRUE; - } - else if (BOOTSTRAPPER_CACHEPACKAGECOMPLETE_ACTION_IGNORE == cachePackageCompleteAction && !pStartedPackage->fVital) // ignore non-vital download failures. - { - LogId(REPORT_STANDARD, MSG_APPLY_CONTINUING_NONVITAL_PACKAGE, pStartedPackage->sczId, hr); + break; - ++(*pcOverallProgressTicks); // add progress even though we didn't fully cache the package. + case BURN_CACHE_ACTION_TYPE_CONTAINER: + Assert(pPlan->sczLayoutDirectory); + hr = ApplyLayoutContainer(&cacheContext, pCacheAction->container.pContainer); + ExitOnFailure(hr, "Failed cache action: %ls", L"layout container"); + + break; - iRetryAction = iPackageCompleteAction + 1; - fRetry = TRUE; + case BURN_CACHE_ACTION_TYPE_SIGNAL_SYNCPOINT: + if (!::SetEvent(pCacheAction->syncpoint.hEvent)) + { + ExitWithLastError(hr, "Failed to set syncpoint event."); } + break; - pStartedPackage->hrCacheResult = hr; - - iPackageStartAction = BURN_PLAN_INVALID_ACTION_INDEX; - iPackageCompleteAction = BURN_PLAN_INVALID_ACTION_INDEX; - pStartedPackage = NULL; - } - else - { - Assert(BURN_PLAN_INVALID_ACTION_INDEX == iPackageStartAction); - Assert(BURN_PLAN_INVALID_ACTION_INDEX == iPackageCompleteAction); + default: + AssertSz(FALSE, "Unknown cache action."); + break; } - } while (fRetry); + } LExit: - Assert(NULL == pStartedPackage); - Assert(BURN_PLAN_INVALID_ACTION_INDEX == iPackageStartAction); - Assert(BURN_PLAN_INVALID_ACTION_INDEX == iPackageCompleteAction); - if (FAILED(hr)) { DoRollbackCache(pUX, pPlan, hPipe, dwCheckpoint); @@ -936,12 +760,216 @@ LExit: return hr; } +static HRESULT ApplyCachePackage( + __in BURN_CACHE_CONTEXT* pContext, + __in BURN_PACKAGE* pPackage + ) +{ + HRESULT hr = S_OK; + BOOTSTRAPPER_CACHEPACKAGECOMPLETE_ACTION cachePackageCompleteAction = BOOTSTRAPPER_CACHEPACKAGECOMPLETE_ACTION_NONE; + + for (;;) + { + hr = UserExperienceOnCachePackageBegin(pContext->pUX, pPackage->sczId, pPackage->payloads.cPayloads, pPackage->payloads.qwTotalSize); + LogExitOnFailure(hr, MSG_USER_CANCELED, "Cancel during cache: %ls: %ls", L"begin cache package", pPackage->sczId); + + for (DWORD i = 0; i < pPackage->payloads.cPayloads; ++i) + { + BURN_PAYLOAD* pPayload = pPackage->payloads.rgpPayloads[i]; + + hr = ApplyProcessPayload(pContext, pPackage, pPayload); + if (FAILED(hr)) + { + break; + } + } + + pPackage->hrCacheResult = hr; + cachePackageCompleteAction = SUCCEEDED(hr) || pPackage->fVital ? BOOTSTRAPPER_CACHEPACKAGECOMPLETE_ACTION_NONE : BOOTSTRAPPER_CACHEPACKAGECOMPLETE_ACTION_IGNORE; + UserExperienceOnCachePackageComplete(pContext->pUX, pPackage->sczId, hr, &cachePackageCompleteAction); + + if (SUCCEEDED(hr)) + { + break; + } + + if (BOOTSTRAPPER_CACHEPACKAGECOMPLETE_ACTION_RETRY == cachePackageCompleteAction) + { + // TODO: the progress needs to account for the payloads (potentially) being recached. + LogErrorId(hr, MSG_APPLY_RETRYING_PACKAGE, pPackage->sczId, NULL, NULL); + + continue; + } + else if (BOOTSTRAPPER_CACHEPACKAGECOMPLETE_ACTION_IGNORE == cachePackageCompleteAction && !pPackage->fVital) // ignore non-vital download failures. + { + LogId(REPORT_STANDARD, MSG_APPLY_CONTINUING_NONVITAL_PACKAGE, pPackage->sczId, hr); + hr = S_OK; + } + + break; + } + +LExit: + return hr; +} + +static HRESULT ApplyExtractContainer( + __in BURN_CACHE_CONTEXT* pContext, + __in BURN_CONTAINER* pContainer + ) +{ + HRESULT hr = S_OK; + + if (!pContainer->fActuallyAttached) + { + hr = AcquireContainerOrPayload(pContext, pContainer, NULL, NULL); + LogExitOnFailure(hr, MSG_FAILED_ACQUIRE_CONTAINER, "Failed to acquire container: %ls to working path: %ls", pContainer->sczId, pContainer->sczUnverifiedPath); + } + + pContext->qwSuccessfulCacheProgress += pContainer->qwFileSize; + + 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); + + pContext->qwSuccessfulCacheProgress += pContainer->qwFileSize; + +LExit: + return hr; +} + +static HRESULT ApplyLayoutBundle( + __in BURN_CACHE_CONTEXT* pContext, + __in BURN_PAYLOAD_GROUP* pPayloads, + __in_z LPCWSTR wzExecutableName, + __in_z LPCWSTR wzUnverifiedPath + ) +{ + HRESULT hr = S_OK; + + hr = LayoutBundle(pContext, wzExecutableName, wzUnverifiedPath); + ExitOnFailure(hr, "Failed to layout bundle."); + + for (DWORD i = 0; i < pPayloads->cPayloads; ++i) + { + BURN_PAYLOAD* pPayload = pPayloads->rgpPayloads[i]; + + hr = ApplyProcessPayload(pContext, NULL, pPayload); + ExitOnFailure(hr, "Failed to layout bundle payload: %ls", pPayload->sczKey); + } + +LExit: + return hr; +} + +static HRESULT ApplyLayoutContainer( + __in BURN_CACHE_CONTEXT* pContext, + __in BURN_CONTAINER* pContainer + ) +{ + HRESULT hr = S_OK; + DWORD cTryAgainAttempts = 0; + BOOL fRetry = FALSE; + + Assert(!pContainer->fAttached); + + for (;;) + { + fRetry = FALSE; + + hr = AcquireContainerOrPayload(pContext, pContainer, NULL, NULL); + LogExitOnFailure(hr, MSG_FAILED_ACQUIRE_CONTAINER, "Failed to acquire container: %ls to working path: %ls", pContainer->sczId, pContainer->sczUnverifiedPath); + + pContext->qwSuccessfulCacheProgress += pContainer->qwFileSize; + + hr = LayoutOrCacheContainerOrPayload(pContext, pContainer, NULL, NULL, TRUE, cTryAgainAttempts, &fRetry); + if (SUCCEEDED(hr)) + { + pContext->qwSuccessfulCacheProgress += pContainer->qwFileSize; + break; + } + else + { + LogErrorId(hr, MSG_FAILED_LAYOUT_CONTAINER, pContainer->sczId, pContext->wzLayoutDirectory, pContainer->sczUnverifiedPath); + + if (!fRetry) + { + ExitFunction(); + } + + ++cTryAgainAttempts; + pContext->qwSuccessfulCacheProgress -= pContainer->qwFileSize; + LogErrorId(hr, MSG_APPLY_RETRYING_PAYLOAD, pContainer->sczId, NULL, NULL); + } + } + +LExit: + return hr; +} + +static HRESULT ApplyProcessPayload( + __in BURN_CACHE_CONTEXT* pContext, + __in_opt BURN_PACKAGE* pPackage, + __in BURN_PAYLOAD* pPayload + ) +{ + HRESULT hr = S_OK; + DWORD cTryAgainAttempts = 0; + BOOL fRetry = FALSE; + + Assert(pContext->pPayloads || pContext->wzLayoutDirectory); + + for (;;) + { + fRetry = FALSE; + + if (pPayload->pContainer) + { + if (pContext->wzLayoutDirectory) + { + ExitFunction(); + } + + // TODO: only extract container if payload isn't already cached and isn't already extracted + hr = ApplyExtractContainer(pContext, pPayload->pContainer); + ExitOnFailure(hr, "Failed to extract container for payload: %ls", pPayload->sczKey); + } + else + { + hr = AcquireContainerOrPayload(pContext, NULL, pPackage, pPayload); + LogExitOnFailure(hr, MSG_FAILED_ACQUIRE_PAYLOAD, "Failed to acquire payload: %ls to working path: %ls", pPayload->sczKey, pPayload->sczUnverifiedPath); + } + + pContext->qwSuccessfulCacheProgress += pPayload->qwFileSize; + + // TODO: set fMove to TRUE appropriately + hr = LayoutOrCacheContainerOrPayload(pContext, NULL, pPackage, pPayload, FALSE, cTryAgainAttempts, &fRetry); + if (SUCCEEDED(hr)) + { + pContext->qwSuccessfulCacheProgress += pPayload->qwFileSize; + break; + } + else + { + LogErrorId(hr, pContext->wzLayoutDirectory ? MSG_FAILED_LAYOUT_PAYLOAD : MSG_FAILED_CACHE_PAYLOAD, pPayload->sczKey, pContext->wzLayoutDirectory, pPayload->sczUnverifiedPath); + + if (!fRetry) + { + ExitFunction(); + } + + ++cTryAgainAttempts; + pContext->qwSuccessfulCacheProgress -= pPayload->qwFileSize; + LogErrorId(hr, MSG_APPLY_RETRYING_PAYLOAD, pPayload->sczKey, NULL, NULL); + } + } + +LExit: + return hr; +} + static HRESULT ExtractContainer( - __in HANDLE hSourceEngineFile, - __in BURN_CONTAINER* pContainer, - __in_z LPCWSTR wzContainerPath, - __in_ecount(cExtractPayloads) BURN_EXTRACT_PAYLOAD* rgExtractPayloads, - __in DWORD cExtractPayloads + __in BURN_CACHE_CONTEXT* pContext, + __in BURN_CONTAINER* pContainer ) { HRESULT hr = S_OK; @@ -952,20 +980,20 @@ static HRESULT ExtractContainer( // If the container is actually attached, then it was planned to be acquired through hSourceEngineFile. if (pContainer->fActuallyAttached) { - hContainerHandle = hSourceEngineFile; + hContainerHandle = pContext->hSourceEngineFile; } - hr = ContainerOpen(&context, pContainer, hContainerHandle, wzContainerPath); + hr = ContainerOpen(&context, pContainer, hContainerHandle, pContainer->sczUnverifiedPath); ExitOnFailure(hr, "Failed to open container: %ls.", pContainer->sczId); while (S_OK == (hr = ContainerNextStream(&context, &sczExtractPayloadId))) { BOOL fExtracted = FALSE; - for (DWORD iExtract = 0; iExtract < cExtractPayloads; ++iExtract) + for (DWORD iExtract = 0; iExtract < pContext->pPayloads->cPayloads; ++iExtract) { - BURN_EXTRACT_PAYLOAD* pExtract = rgExtractPayloads + iExtract; - if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, sczExtractPayloadId, -1, pExtract->pPayload->sczSourcePath, -1)) + BURN_PAYLOAD* pExtract = pContext->pPayloads->rgPayloads + iExtract; + if (pExtract->sczUnverifiedPath && CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, sczExtractPayloadId, -1, pExtract->sczSourcePath, -1)) { // TODO: Send progress when extracting stream to file. hr = ContainerStreamToFile(&context, pExtract->sczUnverifiedPath); @@ -996,74 +1024,10 @@ LExit: return hr; } -static void UpdateCacheSuccessProgress( - __in BURN_PLAN* pPlan, - __in BURN_CACHE_ACTION* pCacheAction, - __inout DWORD64* pqwSuccessfulCachedProgress - ) -{ - switch (pCacheAction->type) - { - case BURN_CACHE_ACTION_TYPE_LAYOUT_BUNDLE: - *pqwSuccessfulCachedProgress += pCacheAction->bundleLayout.qwBundleSize; - break; - - case BURN_CACHE_ACTION_TYPE_ACQUIRE_CONTAINER: - if (!pPlan->rgContainerProgress[pCacheAction->resolveContainer.iProgress].fCachedDuringApply) - { - pPlan->rgContainerProgress[pCacheAction->resolveContainer.iProgress].fCachedDuringApply = TRUE; - *pqwSuccessfulCachedProgress += pCacheAction->resolveContainer.pContainer->qwFileSize; - } - break; - - case BURN_CACHE_ACTION_TYPE_LAYOUT_CONTAINER: - if (!pPlan->rgContainerProgress[pCacheAction->layoutContainer.iProgress].fCachedDuringApply) - { - pPlan->rgContainerProgress[pCacheAction->layoutContainer.iProgress].fCachedDuringApply = TRUE; - *pqwSuccessfulCachedProgress += pCacheAction->layoutContainer.pContainer->qwFileSize; - } - break; - - case BURN_CACHE_ACTION_TYPE_ACQUIRE_PAYLOAD: - if (!pPlan->rgPayloadProgress[pCacheAction->resolvePayload.iProgress].fCachedDuringApply) - { - pPlan->rgPayloadProgress[pCacheAction->resolvePayload.iProgress].fCachedDuringApply = TRUE; - *pqwSuccessfulCachedProgress += pCacheAction->resolvePayload.pPayload->qwFileSize; - } - break; - - case BURN_CACHE_ACTION_TYPE_CACHE_PAYLOAD: - if (!pPlan->rgPayloadProgress[pCacheAction->cachePayload.iProgress].fCachedDuringApply) - { - pPlan->rgPayloadProgress[pCacheAction->cachePayload.iProgress].fCachedDuringApply = TRUE; - *pqwSuccessfulCachedProgress += pCacheAction->cachePayload.pPayload->qwFileSize; - } - break; - - case BURN_CACHE_ACTION_TYPE_LAYOUT_PAYLOAD: - if (!pPlan->rgPayloadProgress[pCacheAction->layoutPayload.iProgress].fCachedDuringApply) - { - pPlan->rgPayloadProgress[pCacheAction->layoutPayload.iProgress].fCachedDuringApply = TRUE; - *pqwSuccessfulCachedProgress += pCacheAction->layoutPayload.pPayload->qwFileSize; - } - break; - - default: - AssertSz(FALSE, "Unexpected cache action type."); - break; - } -} - static HRESULT LayoutBundle( - __in HANDLE hSourceEngineFile, - __in BURN_USER_EXPERIENCE* pUX, - __in BURN_VARIABLES* pVariables, - __in HANDLE hPipe, + __in BURN_CACHE_CONTEXT* pContext, __in_z LPCWSTR wzExecutableName, - __in_z LPCWSTR wzLayoutDirectory, - __in_z LPCWSTR wzUnverifiedPath, - __in DWORD64 qwSuccessfulCacheProgress, - __in DWORD64 qwTotalCacheSize + __in_z LPCWSTR wzUnverifiedPath ) { HRESULT hr = S_OK; @@ -1074,7 +1038,7 @@ static HRESULT LayoutBundle( BOOL fRetry = FALSE; BOOL fRetryAcquire = FALSE; - hr = VariableGetString(pVariables, BURN_BUNDLE_SOURCE_PROCESS_PATH, &sczBundlePath); + hr = VariableGetString(pContext->pVariables, BURN_BUNDLE_SOURCE_PROCESS_PATH, &sczBundlePath); if (FAILED(hr)) { if (E_NOTFOUND != hr) @@ -1086,7 +1050,7 @@ static HRESULT LayoutBundle( ExitOnFailure(hr, "Failed to get path to bundle to layout."); } - hr = PathConcat(wzLayoutDirectory, wzExecutableName, &sczDestinationPath); + hr = PathConcat(pContext->wzLayoutDirectory, wzExecutableName, &sczDestinationPath); ExitOnFailure(hr, "Failed to concat layout path for bundle."); // If the destination path is the currently running bundle, bail. @@ -1098,9 +1062,7 @@ static HRESULT LayoutBundle( ExitFunction1(hr = S_OK); } - progress.pUX = pUX; - progress.qwCacheProgress = qwSuccessfulCacheProgress; - progress.qwTotalCacheSize = qwTotalCacheSize; + progress.pCacheContext = pContext; do { @@ -1112,13 +1074,13 @@ static HRESULT LayoutBundle( fRetryAcquire = FALSE; progress.fCancel = FALSE; - hr = UserExperienceOnCacheAcquireBegin(pUX, NULL, NULL, BOOTSTRAPPER_CACHE_OPERATION_COPY, sczBundlePath); + hr = UserExperienceOnCacheAcquireBegin(pContext->pUX, NULL, NULL, BOOTSTRAPPER_CACHE_OPERATION_COPY, sczBundlePath); ExitOnRootFailure(hr, "BA aborted cache acquire begin."); - hr = CopyPayload(&progress, hSourceEngineFile, sczBundlePath, wzUnverifiedPath); + hr = CopyPayload(&progress, pContext->hSourceEngineFile, sczBundlePath, wzUnverifiedPath); // Error handling happens after sending complete message to BA. - UserExperienceOnCacheAcquireComplete(pUX, NULL, NULL, hr, &fRetryAcquire); + UserExperienceOnCacheAcquireComplete(pContext->pUX, NULL, NULL, hr, &fRetryAcquire); if (fRetryAcquire) { continue; @@ -1130,20 +1092,20 @@ static HRESULT LayoutBundle( do { - hr = UserExperienceOnCacheVerifyBegin(pUX, NULL, NULL); + hr = UserExperienceOnCacheVerifyBegin(pContext->pUX, NULL, NULL); ExitOnRootFailure(hr, "BA aborted cache verify begin."); - if (INVALID_HANDLE_VALUE != hPipe) + if (INVALID_HANDLE_VALUE != pContext->hPipe) { - hr = ElevationLayoutBundle(hPipe, wzLayoutDirectory, wzUnverifiedPath); + hr = ElevationLayoutBundle(pContext->hPipe, pContext->wzLayoutDirectory, wzUnverifiedPath); } else { - hr = CacheLayoutBundle(wzExecutableName, wzLayoutDirectory, wzUnverifiedPath); + hr = CacheLayoutBundle(wzExecutableName, pContext->wzLayoutDirectory, wzUnverifiedPath); } BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION action = BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION_NONE; - UserExperienceOnCacheVerifyComplete(pUX, NULL, NULL, hr, &action); + UserExperienceOnCacheVerifyComplete(pContext->pUX, NULL, NULL, hr, &action); if (BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION_RETRYVERIFICATION == action) { hr = S_FALSE; // retry verify. @@ -1154,7 +1116,7 @@ static HRESULT LayoutBundle( } } while (S_FALSE == hr); } while (fRetry); - LogExitOnFailure(hr, MSG_FAILED_LAYOUT_BUNDLE, "Failed to layout bundle: %ls to layout directory: %ls", sczBundlePath, wzLayoutDirectory); + LogExitOnFailure(hr, MSG_FAILED_LAYOUT_BUNDLE, "Failed to layout bundle: %ls to layout directory: %ls", sczBundlePath, pContext->wzLayoutDirectory); LExit: ReleaseStr(sczDestinationPath); @@ -1164,14 +1126,10 @@ LExit: } static HRESULT AcquireContainerOrPayload( - __in BURN_USER_EXPERIENCE* pUX, - __in BURN_VARIABLES* pVariables, + __in BURN_CACHE_CONTEXT* pContext, __in_opt BURN_CONTAINER* pContainer, __in_opt BURN_PACKAGE* pPackage, - __in_opt BURN_PAYLOAD* pPayload, - __in LPCWSTR wzDestinationPath, - __in DWORD64 qwSuccessfulCacheProgress, - __in DWORD64 qwTotalCacheSize + __in_opt BURN_PAYLOAD* pPayload ) { AssertSz(pContainer || pPayload, "Must provide a container or a payload."); @@ -1180,17 +1138,16 @@ static HRESULT AcquireContainerOrPayload( int nEquivalentPaths = 0; LPCWSTR wzPackageOrContainerId = pContainer ? pContainer->sczId : pPackage ? pPackage->sczId : NULL; LPCWSTR wzPayloadId = pPayload ? pPayload->sczKey : NULL; + LPCWSTR wzDestinationPath = pContainer ? pContainer->sczUnverifiedPath: pPayload->sczUnverifiedPath; LPCWSTR wzRelativePath = pContainer ? pContainer->sczFilePath : pPayload->sczFilePath; LPWSTR sczSourceFullPath = NULL; BURN_CACHE_ACQUIRE_PROGRESS_CONTEXT progress = { }; BOOL fRetry = FALSE; + progress.pCacheContext = pContext; progress.pContainer = pContainer; progress.pPackage = pPackage; progress.pPayload = pPayload; - progress.pUX = pUX; - progress.qwCacheProgress = qwSuccessfulCacheProgress; - progress.qwTotalCacheSize = qwTotalCacheSize; do { @@ -1204,7 +1161,7 @@ static HRESULT AcquireContainerOrPayload( fRetry = FALSE; progress.fCancel = FALSE; - hr = CacheFindLocalSource(wzSourcePath, pVariables, &fFoundLocal, &sczSourceFullPath); + hr = CacheFindLocalSource(wzSourcePath, wzDestinationPath, pContext->pVariables, &fFoundLocal, &sczSourceFullPath); ExitOnFailure(hr, "Failed to search local source."); if (fFoundLocal) // the file exists locally, so copy it. @@ -1220,7 +1177,7 @@ static HRESULT AcquireContainerOrPayload( DWORD dwLogId = pContainer ? (wzPayloadId ? MSG_PROMPT_CONTAINER_PAYLOAD_SOURCE : MSG_PROMPT_CONTAINER_SOURCE) : pPackage ? MSG_PROMPT_PACKAGE_PAYLOAD_SOURCE : MSG_PROMPT_BUNDLE_PAYLOAD_SOURCE; LogId(REPORT_STANDARD, dwLogId, wzPackageOrContainerId ? wzPackageOrContainerId : L"", wzPayloadId ? wzPayloadId : L"", sczSourceFullPath); - hr = PromptForSource(pUX, wzPackageOrContainerId, wzPayloadId, sczSourceFullPath, wzDownloadUrl, &fRetry, &fDownload); + hr = PromptForSource(pContext->pUX, wzPackageOrContainerId, wzPayloadId, sczSourceFullPath, wzDownloadUrl, &fRetry, &fDownload); // If the BA requested download then ensure a download url is available (it may have been set // during PromptForSource so we need to check again). @@ -1239,7 +1196,7 @@ static HRESULT AcquireContainerOrPayload( if (fCopy) { - hr = UserExperienceOnCacheAcquireBegin(pUX, wzPackageOrContainerId, wzPayloadId, BOOTSTRAPPER_CACHE_OPERATION_COPY, sczSourceFullPath); + hr = UserExperienceOnCacheAcquireBegin(pContext->pUX, wzPackageOrContainerId, wzPayloadId, BOOTSTRAPPER_CACHE_OPERATION_COPY, sczSourceFullPath); ExitOnRootFailure(hr, "BA aborted cache acquire begin."); hr = CopyPayload(&progress, INVALID_HANDLE_VALUE, sczSourceFullPath, wzDestinationPath); @@ -1248,12 +1205,12 @@ static HRESULT AcquireContainerOrPayload( // We successfully copied from a source location, set that as the last used source. if (SUCCEEDED(hr)) { - CacheSetLastUsedSource(pVariables, sczSourceFullPath, wzRelativePath); + CacheSetLastUsedSource(pContext->pVariables, sczSourceFullPath, wzRelativePath); } } else if (fDownload) { - hr = UserExperienceOnCacheAcquireBegin(pUX, wzPackageOrContainerId, wzPayloadId, BOOTSTRAPPER_CACHE_OPERATION_DOWNLOAD, wzDownloadUrl); + hr = UserExperienceOnCacheAcquireBegin(pContext->pUX, wzPackageOrContainerId, wzPayloadId, BOOTSTRAPPER_CACHE_OPERATION_DOWNLOAD, wzDownloadUrl); ExitOnRootFailure(hr, "BA aborted cache download payload begin."); hr = DownloadPayload(&progress, wzDestinationPath); @@ -1262,7 +1219,7 @@ static HRESULT AcquireContainerOrPayload( if (fCopy || fDownload) { - UserExperienceOnCacheAcquireComplete(pUX, wzPackageOrContainerId, wzPayloadId, hr, &fRetry); + UserExperienceOnCacheAcquireComplete(pContext->pUX, wzPackageOrContainerId, wzPayloadId, hr, &fRetry); if (fRetry) { hr = S_OK; @@ -1279,16 +1236,10 @@ LExit: } static HRESULT LayoutOrCacheContainerOrPayload( - __in BURN_USER_EXPERIENCE* pUX, - __in HANDLE hPipe, + __in BURN_CACHE_CONTEXT* pContext, __in_opt BURN_CONTAINER* pContainer, __in_opt BURN_PACKAGE* pPackage, __in_opt BURN_PAYLOAD* pPayload, - __in BOOL fAlreadyProvidedProgress, - __in DWORD64 qwSuccessfulCachedProgress, - __in DWORD64 qwTotalCacheSize, - __in_z_opt LPCWSTR wzLayoutDirectory, - __in_z LPCWSTR wzUnverifiedPath, __in BOOL fMove, __in DWORD cTryAgainAttempts, __out BOOL* pfRetry @@ -1296,13 +1247,14 @@ static HRESULT LayoutOrCacheContainerOrPayload( { HRESULT hr = S_OK; LPCWSTR wzPackageOrContainerId = pContainer ? pContainer->sczId : pPackage ? pPackage->sczId : L""; + LPCWSTR wzUnverifiedPath = pContainer ? pContainer->sczUnverifiedPath : pPayload->sczUnverifiedPath; LPCWSTR wzPayloadId = pPayload ? pPayload->sczKey : L""; LARGE_INTEGER liContainerOrPayloadSize = { }; LARGE_INTEGER liZero = { }; BURN_CACHE_ACQUIRE_PROGRESS_CONTEXT progress = { }; BOOL fCanAffectRegistration = FALSE; - if (!wzLayoutDirectory) + if (!pContext->wzLayoutDirectory) { Assert(!pContainer); Assert(pPackage); @@ -1312,41 +1264,31 @@ static HRESULT LayoutOrCacheContainerOrPayload( liContainerOrPayloadSize.QuadPart = pContainer ? pContainer->qwFileSize : pPayload->qwFileSize; + progress.pCacheContext = pContext; progress.pContainer = pContainer; progress.pPackage = pPackage; progress.pPayload = pPayload; - progress.pUX = pUX; - progress.qwTotalCacheSize = qwTotalCacheSize; - if (fAlreadyProvidedProgress) - { - Assert(qwSuccessfulCachedProgress >= static_cast(liContainerOrPayloadSize.QuadPart)); - progress.qwCacheProgress = qwSuccessfulCachedProgress - liContainerOrPayloadSize.QuadPart; // remove the payload size, since it was marked successful thus included in the successful size already. - } - else - { - progress.qwCacheProgress = qwSuccessfulCachedProgress; - } *pfRetry = FALSE; do { - hr = UserExperienceOnCacheVerifyBegin(pUX, wzPackageOrContainerId, wzPayloadId); + hr = UserExperienceOnCacheVerifyBegin(pContext->pUX, wzPackageOrContainerId, wzPayloadId); ExitOnRootFailure(hr, "BA aborted cache verify begin."); - if (INVALID_HANDLE_VALUE != hPipe) // pass the decision off to the elevated process. + if (INVALID_HANDLE_VALUE != pContext->hPipe) // pass the decision off to the elevated process. { - hr = ElevationCacheOrLayoutContainerOrPayload(hPipe, pContainer, pPackage, pPayload, wzLayoutDirectory, wzUnverifiedPath, fMove); + hr = ElevationCacheOrLayoutContainerOrPayload(pContext->hPipe, pContainer, pPackage, pPayload, pContext->wzLayoutDirectory, wzUnverifiedPath, fMove); } - else if (wzLayoutDirectory) // layout the container or payload. + else if (pContext->wzLayoutDirectory) // layout the container or payload. { if (pContainer) { - hr = CacheLayoutContainer(pContainer, wzLayoutDirectory, wzUnverifiedPath, fMove); + hr = CacheLayoutContainer(pContainer, pContext->wzLayoutDirectory, wzUnverifiedPath, fMove); } else { - hr = CacheLayoutPayload(pPayload, wzLayoutDirectory, wzUnverifiedPath, fMove); + hr = CacheLayoutPayload(pPayload, pContext->wzLayoutDirectory, wzUnverifiedPath, fMove); } } else // complete the payload. @@ -1376,7 +1318,7 @@ static HRESULT LayoutOrCacheContainerOrPayload( } BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION action = FAILED(hr) && cTryAgainAttempts < BURN_CACHE_MAX_RECOMMENDED_VERIFY_TRYAGAIN_ATTEMPTS ? BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION_RETRYACQUISITION : BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION_NONE; - UserExperienceOnCacheVerifyComplete(pUX, wzPackageOrContainerId, wzPayloadId, hr, &action); + UserExperienceOnCacheVerifyComplete(pContext->pUX, wzPackageOrContainerId, wzPayloadId, hr, &action); if (BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION_RETRYVERIFICATION == action) { hr = S_FALSE; // retry verify. @@ -1541,7 +1483,7 @@ static HRESULT DownloadPayload( cacheCallback.pfnCancel = NULL; // TODO: set this cacheCallback.pv = pProgress; - authenticationData.pUX = pProgress->pUX; + authenticationData.pUX = pProgress->pCacheContext->pUX; authenticationData.wzPackageOrContainerId = wzPackageOrContainerId; authenticationData.wzPayloadId = wzPayloadId; authenticationCallback.pv = static_cast(&authenticationData); @@ -1630,15 +1572,15 @@ static DWORD CALLBACK CacheProgressRoutine( BURN_CACHE_ACQUIRE_PROGRESS_CONTEXT* pProgress = static_cast(lpData); LPCWSTR wzPackageOrContainerId = pProgress->pContainer ? pProgress->pContainer->sczId : pProgress->pPackage ? pProgress->pPackage->sczId : NULL; LPCWSTR wzPayloadId = pProgress->pPayload ? pProgress->pPayload->sczKey : NULL; - DWORD64 qwCacheProgress = pProgress->qwCacheProgress + TotalBytesTransferred.QuadPart; - if (qwCacheProgress > pProgress->qwTotalCacheSize) + DWORD64 qwCacheProgress = pProgress->pCacheContext->qwSuccessfulCacheProgress + TotalBytesTransferred.QuadPart; + if (qwCacheProgress > pProgress->pCacheContext->qwTotalCacheSize) { - AssertSz(FALSE, "Apply has cached more than Plan envisioned."); - qwCacheProgress = pProgress->qwTotalCacheSize; + //AssertSz(FALSE, "Apply has cached more than Plan envisioned."); + qwCacheProgress = pProgress->pCacheContext->qwTotalCacheSize; } - DWORD dwOverallPercentage = pProgress->qwTotalCacheSize ? static_cast(qwCacheProgress * 100 / pProgress->qwTotalCacheSize) : 0; + DWORD dwOverallPercentage = pProgress->pCacheContext->qwTotalCacheSize ? static_cast(qwCacheProgress * 100 / pProgress->pCacheContext->qwTotalCacheSize) : 0; - hr = UserExperienceOnCacheAcquireProgress(pProgress->pUX, wzPackageOrContainerId, wzPayloadId, TotalBytesTransferred.QuadPart, TotalFileSize.QuadPart, dwOverallPercentage); + hr = UserExperienceOnCacheAcquireProgress(pProgress->pCacheContext->pUX, wzPackageOrContainerId, wzPayloadId, TotalBytesTransferred.QuadPart, TotalFileSize.QuadPart, dwOverallPercentage); if (HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT) == hr) { dwResult = PROGRESS_CANCEL; diff --git a/src/engine/cache.cpp b/src/engine/cache.cpp index 46c2650a..6ddbfb50 100644 --- a/src/engine/cache.cpp +++ b/src/engine/cache.cpp @@ -391,6 +391,7 @@ LExit: extern "C" HRESULT CacheFindLocalSource( __in_z LPCWSTR wzSourcePath, + __in_z LPCWSTR wzDestinationPath, __in BURN_VARIABLES* pVariables, __out BOOL* pfFound, __out_z LPWSTR* psczSourceFullPath @@ -403,7 +404,7 @@ extern "C" HRESULT CacheFindLocalSource( LPWSTR sczLastSourceFolder = NULL; LPWSTR sczLayoutPath = NULL; LPWSTR sczLayoutFolder = NULL; - LPCWSTR rgwzSearchPaths[3] = { }; + LPCWSTR rgwzSearchPaths[4] = { }; DWORD cSearchPaths = 0; // If the source path provided is a full path, obviously that is where we should be looking. @@ -414,8 +415,12 @@ extern "C" HRESULT CacheFindLocalSource( } else { + // Use the destination path first. + rgwzSearchPaths[0] = wzDestinationPath; + cSearchPaths = 1; + // If we're not running from cache or we couldn't get the last source, use - // the source path location first. In the case where we are in the bundle's + // the source path location. In the case where we are in the bundle's // package cache and couldn't find a last used source we unfortunately will // be picking the package cache path which isn't likely to have what we are // looking for. @@ -428,8 +433,8 @@ extern "C" HRESULT CacheFindLocalSource( hr = PathConcat(sczSourceProcessFolder, wzSourcePath, &sczCurrentPath); ExitOnFailure(hr, "Failed to combine last source with source."); - rgwzSearchPaths[0] = sczCurrentPath; - cSearchPaths = 1; + rgwzSearchPaths[cSearchPaths] = sczCurrentPath; + ++cSearchPaths; } // If we have a last used source and it does not duplicate the existing search path, @@ -439,7 +444,7 @@ extern "C" HRESULT CacheFindLocalSource( hr = PathConcat(sczLastSourceFolder, wzSourcePath, &sczLastSourcePath); ExitOnFailure(hr, "Failed to combine last source with source."); - if (0 == cSearchPaths || CSTR_EQUAL != ::CompareStringW(LOCALE_NEUTRAL, NORM_IGNORECASE, rgwzSearchPaths[0], -1, sczLastSourcePath, -1)) + if (1 == cSearchPaths || CSTR_EQUAL != ::CompareStringW(LOCALE_NEUTRAL, NORM_IGNORECASE, rgwzSearchPaths[1], -1, sczLastSourcePath, -1)) { rgwzSearchPaths[cSearchPaths] = sczLastSourcePath; ++cSearchPaths; diff --git a/src/engine/cache.h b/src/engine/cache.h index a00c50b7..52b111e9 100644 --- a/src/engine/cache.h +++ b/src/engine/cache.h @@ -54,6 +54,7 @@ HRESULT CacheGetResumePath( ); HRESULT CacheFindLocalSource( __in_z LPCWSTR wzSourcePath, + __in_z LPCWSTR wzDestinationPath, __in BURN_VARIABLES* pVariables, __out BOOL* pfFound, __out_z LPWSTR* psczSourceFullPath diff --git a/src/engine/container.cpp b/src/engine/container.cpp index 55a16afb..2db2412c 100644 --- a/src/engine/container.cpp +++ b/src/engine/container.cpp @@ -3,17 +3,6 @@ #include "precomp.h" -// internal function declarations - -static HRESULT GetAttachedContainerInfo( - __in HANDLE hFile, - __in DWORD iContainerIndex, - __out DWORD* pdwFormat, - __out DWORD64* pqwOffset, - __out DWORD64* pqwSize - ); - - // function definitions extern "C" HRESULT ContainersParseFromXml( @@ -186,6 +175,7 @@ extern "C" void ContainersUninitialize( ReleaseStr(pContainer->downloadSource.sczUrl); ReleaseStr(pContainer->downloadSource.sczUser); ReleaseStr(pContainer->downloadSource.sczPassword); + ReleaseStr(pContainer->sczUnverifiedPath); } MemFree(pContainers->rgContainers); } diff --git a/src/engine/container.h b/src/engine/container.h index bbd9fa72..d38016cc 100644 --- a/src/engine/container.h +++ b/src/engine/container.h @@ -65,7 +65,6 @@ typedef struct _BURN_CONTAINER DWORD64 qwFileSize; LPWSTR sczHash; LPWSTR sczFilePath; // relative path to container. - LPWSTR sczSourcePath; DOWNLOAD_SOURCE downloadSource; BYTE* pbHash; @@ -73,8 +72,10 @@ typedef struct _BURN_CONTAINER DWORD64 qwAttachedOffset; BOOL fActuallyAttached; // indicates whether an attached container is attached or missing. - //LPWSTR* rgsczPayloads; - //DWORD cPayloads; + // mutable members + BOOL fPlanned; + LPWSTR sczSourcePath; + LPWSTR sczUnverifiedPath; } BURN_CONTAINER; typedef struct _BURN_CONTAINERS diff --git a/src/engine/core.cpp b/src/engine/core.cpp index 42759d3f..98aa943e 100644 --- a/src/engine/core.cpp +++ b/src/engine/core.cpp @@ -287,7 +287,7 @@ extern "C" HRESULT CoreDetect( pEngineState->fDetected = FALSE; pEngineState->fPlanned = FALSE; DetectReset(&pEngineState->registration, &pEngineState->packages); - PlanReset(&pEngineState->plan, &pEngineState->packages); + PlanReset(&pEngineState->plan, &pEngineState->containers, &pEngineState->packages, &pEngineState->layoutPayloads); // Detect if bundle installed state has changed since start up. This // only happens if Apply() changed the state of bundle (installed or @@ -438,7 +438,6 @@ extern "C" HRESULT CorePlan( { HRESULT hr = S_OK; BOOL fPlanBegan = FALSE; - LPWSTR sczLayoutDirectory = NULL; BURN_PACKAGE* pUpgradeBundlePackage = NULL; BURN_PACKAGE* pForwardCompatibleBundlePackage = NULL; BOOL fContinuePlanning = TRUE; // assume we won't skip planning due to dependencies. @@ -460,11 +459,12 @@ extern "C" HRESULT CorePlan( // Always reset the plan. pEngineState->fPlanned = FALSE; - PlanReset(&pEngineState->plan, &pEngineState->packages); + PlanReset(&pEngineState->plan, &pEngineState->containers, &pEngineState->packages, &pEngineState->layoutPayloads); // Remember the overall action state in the plan since it shapes the changes // we make everywhere. pEngineState->plan.action = action; + pEngineState->plan.pPayloads = &pEngineState->payloads; pEngineState->plan.wzBundleId = pEngineState->registration.sczId; pEngineState->plan.wzBundleProviderKey = pEngineState->registration.sczId; pEngineState->plan.fDisableRollback = pEngineState->fDisableRollback; @@ -484,11 +484,11 @@ extern "C" HRESULT CorePlan( Assert(!pEngineState->plan.fPerMachine); // Plan the bundle's layout. - hr = PlanLayoutBundle(&pEngineState->plan, pEngineState->registration.sczExecutableName, pEngineState->section.qwBundleSize, &pEngineState->variables, &pEngineState->payloads, &sczLayoutDirectory); + hr = PlanLayoutBundle(&pEngineState->plan, pEngineState->registration.sczExecutableName, pEngineState->section.qwBundleSize, &pEngineState->variables, &pEngineState->layoutPayloads); ExitOnFailure(hr, "Failed to plan the layout of the bundle."); // Plan the packages' layout. - hr = PlanPackages(&pEngineState->userExperience, &pEngineState->packages, &pEngineState->plan, &pEngineState->log, &pEngineState->variables, pEngineState->command.display, pEngineState->command.relationType, sczLayoutDirectory); + hr = PlanPackages(&pEngineState->userExperience, &pEngineState->packages, &pEngineState->plan, &pEngineState->log, &pEngineState->variables, pEngineState->command.display, pEngineState->command.relationType); ExitOnFailure(hr, "Failed to plan packages."); } else if (BOOTSTRAPPER_ACTION_UPDATE_REPLACE == action || BOOTSTRAPPER_ACTION_UPDATE_REPLACE_EMBEDDED == action) @@ -532,7 +532,7 @@ extern "C" HRESULT CorePlan( hr = PlanRelatedBundlesBegin(&pEngineState->userExperience, &pEngineState->registration, pEngineState->command.relationType, &pEngineState->plan); ExitOnFailure(hr, "Failed to plan related bundles."); - hr = PlanPackages(&pEngineState->userExperience, &pEngineState->packages, &pEngineState->plan, &pEngineState->log, &pEngineState->variables, pEngineState->command.display, pEngineState->command.relationType, NULL); + hr = PlanPackages(&pEngineState->userExperience, &pEngineState->packages, &pEngineState->plan, &pEngineState->log, &pEngineState->variables, pEngineState->command.display, pEngineState->command.relationType); ExitOnFailure(hr, "Failed to plan packages."); // Schedule the update of related bundles last. @@ -562,7 +562,6 @@ LExit: } LogId(REPORT_STANDARD, MSG_PLAN_COMPLETE, hr); - ReleaseStr(sczLayoutDirectory); return hr; } @@ -1679,23 +1678,22 @@ static HRESULT DetectPackagePayloadsCached( // If the cached directory exists, we have something. if (DirExists(sczCachePath, NULL)) { - // Check all payloads to see if they exist. - for (DWORD i = 0; i < pPackage->cPayloads; ++i) + // Check all payloads to see if any exist. + for (DWORD i = 0; i < pPackage->payloads.cPayloads; ++i) { - BURN_PACKAGE_PAYLOAD* pPackagePayload = pPackage->rgPayloads + i; + BURN_PAYLOAD* pPayload = pPackage->payloads.rgpPayloads[i]; - hr = PathConcat(sczCachePath, pPackagePayload->pPayload->sczFilePath, &sczPayloadCachePath); + hr = PathConcat(sczCachePath, pPayload->sczFilePath, &sczPayloadCachePath); ExitOnFailure(hr, "Failed to concat payload cache path."); if (FileExistsEx(sczPayloadCachePath, NULL)) { - // TODO: We shouldn't track whether the payload was cached since all we did was check whether the file exists. - pPackagePayload->fCached = TRUE; fCached = TRUE; + break; } else { - LogId(REPORT_STANDARD, MSG_DETECT_PACKAGE_NOT_FULLY_CACHED, pPackage->sczId, pPackagePayload->pPayload->sczKey); + LogId(REPORT_STANDARD, MSG_DETECT_PACKAGE_NOT_FULLY_CACHED, pPackage->sczId, pPayload->sczKey); } } } diff --git a/src/engine/core.h b/src/engine/core.h index b4e0e0d3..e96440bb 100644 --- a/src/engine/core.h +++ b/src/engine/core.h @@ -112,6 +112,8 @@ typedef struct _BURN_ENGINE_STATE BURN_LOGGING log; + BURN_PAYLOAD_GROUP layoutPayloads; + BURN_PLAN plan; BURN_MODE mode; diff --git a/src/engine/detect.cpp b/src/engine/detect.cpp index 844816ba..dc35e747 100644 --- a/src/engine/detect.cpp +++ b/src/engine/detect.cpp @@ -68,11 +68,6 @@ extern "C" void DetectReset( pPackage->installRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_UNKNOWN; pPackage->fCached = FALSE; - for (DWORD iPayload = 0; iPayload < pPackage->cPayloads; ++iPayload) - { - BURN_PACKAGE_PAYLOAD* pPayload = pPackage->rgPayloads + iPayload; - pPayload->fCached = FALSE; - } if (BURN_PACKAGE_TYPE_MSI == pPackage->type) { diff --git a/src/engine/engine.mc b/src/engine/engine.mc index 71c27cad..c8b46806 100644 --- a/src/engine/engine.mc +++ b/src/engine/engine.mc @@ -552,7 +552,7 @@ MessageId=314 Severity=Error SymbolicName=MSG_FAILED_CACHE_PAYLOAD Language=English -Failed to cache payload: %2!ls! from working path: %3!ls!, error: %1!ls!. +Failed to cache payload: %2!ls! from working path: %4!ls!, error: %1!ls!. . MessageId=315 @@ -574,7 +574,7 @@ MessageId=317 Severity=Error SymbolicName=MSG_FAILED_LAYOUT_PAYLOAD Language=English -Failed to layout payload: %2!ls! to layout directory: %3!ls!, error: %1!ls!. +Failed to layout payload: %2!ls! from working path: %4!ls! to layout directory: %3!ls!, error: %1!ls!. . MessageId=318 diff --git a/src/engine/exeengine.cpp b/src/engine/exeengine.cpp index 46905fc3..9b1b6973 100644 --- a/src/engine/exeengine.cpp +++ b/src/engine/exeengine.cpp @@ -372,31 +372,33 @@ extern "C" HRESULT ExeEngineExecutePackage( PROCESS_INFORMATION pi = { }; DWORD dwExitCode = 0; GENERIC_EXECUTE_MESSAGE message = { }; + BURN_PACKAGE* pPackage = pExecuteAction->exePackage.pPackage; + BURN_PAYLOAD* pPackagePayload = pPackage->payloads.rgpPayloads[0]; // get cached executable path - hr = CacheGetCompletedPath(pExecuteAction->exePackage.pPackage->fPerMachine, pExecuteAction->exePackage.pPackage->sczCacheId, &sczCachedDirectory); - ExitOnFailure(hr, "Failed to get cached path for package: %ls", pExecuteAction->exePackage.pPackage->sczId); + hr = CacheGetCompletedPath(pPackage->fPerMachine, pPackage->sczCacheId, &sczCachedDirectory); + ExitOnFailure(hr, "Failed to get cached path for package: %ls", pPackage->sczId); // Best effort to set the execute package cache folder and action variables. VariableSetString(pVariables, BURN_BUNDLE_EXECUTE_PACKAGE_CACHE_FOLDER, sczCachedDirectory, TRUE, FALSE); VariableSetNumeric(pVariables, BURN_BUNDLE_EXECUTE_PACKAGE_ACTION, pExecuteAction->exePackage.action, TRUE); - hr = PathConcat(sczCachedDirectory, pExecuteAction->exePackage.pPackage->rgPayloads[0].pPayload->sczFilePath, &sczExecutablePath); + hr = PathConcat(sczCachedDirectory, pPackagePayload->sczFilePath, &sczExecutablePath); ExitOnFailure(hr, "Failed to build executable path."); // pick arguments switch (pExecuteAction->exePackage.action) { case BOOTSTRAPPER_ACTION_STATE_INSTALL: - wzArguments = pExecuteAction->exePackage.pPackage->Exe.sczInstallArguments; + wzArguments = pPackage->Exe.sczInstallArguments; break; case BOOTSTRAPPER_ACTION_STATE_UNINSTALL: - wzArguments = pExecuteAction->exePackage.pPackage->Exe.sczUninstallArguments; + wzArguments = pPackage->Exe.sczUninstallArguments; break; case BOOTSTRAPPER_ACTION_STATE_REPAIR: - wzArguments = pExecuteAction->exePackage.pPackage->Exe.sczRepairArguments; + wzArguments = pPackage->Exe.sczRepairArguments; break; default: @@ -408,9 +410,9 @@ extern "C" HRESULT ExeEngineExecutePackage( hr = StrAllocString(&sczArguments, wzArguments && *wzArguments ? wzArguments : L"", 0); ExitOnFailure(hr, "Failed to copy package arguments."); - for (DWORD i = 0; i < pExecuteAction->exePackage.pPackage->Exe.cCommandLineArguments; ++i) + for (DWORD i = 0; i < pPackage->Exe.cCommandLineArguments; ++i) { - BURN_EXE_COMMAND_LINE_ARGUMENT* commandLineArgument = &pExecuteAction->exePackage.pPackage->Exe.rgCommandLineArguments[i]; + BURN_EXE_COMMAND_LINE_ARGUMENT* commandLineArgument = &pPackage->Exe.rgCommandLineArguments[i]; BOOL fCondition = FALSE; hr = ConditionEvaluate(pVariables, commandLineArgument->sczCondition, &fCondition); @@ -468,10 +470,10 @@ extern "C" HRESULT ExeEngineExecutePackage( } ExitOnFailure(hr, "Failed to create obfuscated executable command."); - if (pExecuteAction->exePackage.pPackage->Exe.fSupportsAncestors) + if (pPackage->Exe.fSupportsAncestors) { // Add the list of dependencies to ignore, if any, to the burn command line. - if (pExecuteAction->exePackage.sczIgnoreDependencies && BURN_EXE_PROTOCOL_TYPE_BURN == pExecuteAction->exePackage.pPackage->Exe.protocol) + if (pExecuteAction->exePackage.sczIgnoreDependencies && BURN_EXE_PROTOCOL_TYPE_BURN == pPackage->Exe.protocol) { hr = StrAllocFormattedSecure(&sczCommand, L"%ls -%ls=%ls", sczCommand, BURN_COMMANDLINE_SWITCH_IGNOREDEPENDENCIES, pExecuteAction->exePackage.sczIgnoreDependencies); ExitOnFailure(hr, "Failed to append the list of dependencies to ignore to the command line."); @@ -491,21 +493,21 @@ extern "C" HRESULT ExeEngineExecutePackage( } } - if (BURN_EXE_PROTOCOL_TYPE_BURN == pExecuteAction->exePackage.pPackage->Exe.protocol) + if (BURN_EXE_PROTOCOL_TYPE_BURN == pPackage->Exe.protocol) { hr = CoreAppendFileHandleSelfToCommandLine(sczExecutablePath, &hExecutableFile, &sczCommand, &sczCommandObfuscated); ExitOnFailure(hr, "Failed to append %ls", BURN_COMMANDLINE_SWITCH_FILEHANDLE_SELF); } // Log before we add the secret pipe name and client token for embedded processes. - LogId(REPORT_STANDARD, MSG_APPLYING_PACKAGE, LoggingRollbackOrExecute(fRollback), pExecuteAction->exePackage.pPackage->sczId, LoggingActionStateToString(pExecuteAction->exePackage.action), sczExecutablePath, sczCommandObfuscated); + LogId(REPORT_STANDARD, MSG_APPLYING_PACKAGE, LoggingRollbackOrExecute(fRollback), pPackage->sczId, LoggingActionStateToString(pExecuteAction->exePackage.action), sczExecutablePath, sczCommandObfuscated); - if (!pExecuteAction->exePackage.fFireAndForget && BURN_EXE_PROTOCOL_TYPE_BURN == pExecuteAction->exePackage.pPackage->Exe.protocol) + if (!pExecuteAction->exePackage.fFireAndForget && BURN_EXE_PROTOCOL_TYPE_BURN == pPackage->Exe.protocol) { hr = EmbeddedRunBundle(sczExecutablePath, sczCommand, pfnGenericMessageHandler, pvContext, &dwExitCode); ExitOnFailure(hr, "Failed to run bundle as embedded from path: %ls", sczExecutablePath); } - else if (!pExecuteAction->exePackage.fFireAndForget && BURN_EXE_PROTOCOL_TYPE_NETFX4 == pExecuteAction->exePackage.pPackage->Exe.protocol) + else if (!pExecuteAction->exePackage.fFireAndForget && BURN_EXE_PROTOCOL_TYPE_NETFX4 == pPackage->Exe.protocol) { hr = NetFxRunChainer(sczExecutablePath, sczCommand, pfnGenericMessageHandler, pvContext, &dwExitCode); ExitOnFailure(hr, "Failed to run netfx chainer: %ls", sczExecutablePath); @@ -543,7 +545,7 @@ extern "C" HRESULT ExeEngineExecutePackage( } while (HRESULT_FROM_WIN32(WAIT_TIMEOUT) == hr); } - hr = HandleExitCode(pExecuteAction->exePackage.pPackage, dwExitCode, pRestart); + hr = HandleExitCode(pPackage, dwExitCode, pRestart); ExitOnRootFailure(hr, "Process returned error: 0x%x", dwExitCode); LExit: diff --git a/src/engine/manifest.cpp b/src/engine/manifest.cpp index fa454348..b1740083 100644 --- a/src/engine/manifest.cpp +++ b/src/engine/manifest.cpp @@ -145,7 +145,7 @@ static HRESULT ParseFromXml( ExitOnFailure(hr, "Failed to parse containers."); // parse payloads - hr = PayloadsParseFromXml(&pEngineState->payloads, &pEngineState->containers, pixeBundle); + hr = PayloadsParseFromXml(&pEngineState->payloads, &pEngineState->containers, &pEngineState->layoutPayloads, pixeBundle); ExitOnFailure(hr, "Failed to parse payloads."); // parse packages diff --git a/src/engine/msiengine.cpp b/src/engine/msiengine.cpp index 35ca5c62..b081b9ca 100644 --- a/src/engine/msiengine.cpp +++ b/src/engine/msiengine.cpp @@ -1099,6 +1099,8 @@ extern "C" HRESULT MsiEngineExecutePackage( LPWSTR sczMsiPath = NULL; LPWSTR sczProperties = NULL; LPWSTR sczObfuscatedProperties = NULL; + BURN_PACKAGE* pPackage = pExecuteAction->msiPackage.pPackage; + BURN_PAYLOAD* pPackagePayload = pPackage->payloads.rgpPayloads[0]; // During rollback, if the package is already in the rollback state we expect don't // touch it again. @@ -1106,10 +1108,10 @@ extern "C" HRESULT MsiEngineExecutePackage( { if (BOOTSTRAPPER_ACTION_STATE_UNINSTALL == pExecuteAction->msiPackage.action) { - hr = WiuGetProductInfoEx(pExecuteAction->msiPackage.pPackage->Msi.sczProductCode, NULL, pExecuteAction->msiPackage.pPackage->fPerMachine ? MSIINSTALLCONTEXT_MACHINE : MSIINSTALLCONTEXT_USERUNMANAGED, INSTALLPROPERTY_VERSIONSTRING, &sczInstalledVersion); + hr = WiuGetProductInfoEx(pPackage->Msi.sczProductCode, NULL, pPackage->fPerMachine ? MSIINSTALLCONTEXT_MACHINE : MSIINSTALLCONTEXT_USERUNMANAGED, INSTALLPROPERTY_VERSIONSTRING, &sczInstalledVersion); if (FAILED(hr)) // package not present. { - LogId(REPORT_STANDARD, MSG_ROLLBACK_PACKAGE_SKIPPED, pExecuteAction->msiPackage.pPackage->sczId, LoggingActionStateToString(pExecuteAction->msiPackage.action), LoggingPackageStateToString(BOOTSTRAPPER_PACKAGE_STATE_ABSENT)); + LogId(REPORT_STANDARD, MSG_ROLLBACK_PACKAGE_SKIPPED, pPackage->sczId, LoggingActionStateToString(pExecuteAction->msiPackage.action), LoggingPackageStateToString(BOOTSTRAPPER_PACKAGE_STATE_ABSENT)); hr = S_OK; ExitFunction(); @@ -1117,10 +1119,10 @@ extern "C" HRESULT MsiEngineExecutePackage( } else if (BOOTSTRAPPER_ACTION_STATE_INSTALL == pExecuteAction->msiPackage.action) { - hr = WiuGetProductInfoEx(pExecuteAction->msiPackage.pPackage->Msi.sczProductCode, NULL, pExecuteAction->msiPackage.pPackage->fPerMachine ? MSIINSTALLCONTEXT_MACHINE : MSIINSTALLCONTEXT_USERUNMANAGED, INSTALLPROPERTY_VERSIONSTRING, &sczInstalledVersion); + hr = WiuGetProductInfoEx(pPackage->Msi.sczProductCode, NULL, pPackage->fPerMachine ? MSIINSTALLCONTEXT_MACHINE : MSIINSTALLCONTEXT_USERUNMANAGED, INSTALLPROPERTY_VERSIONSTRING, &sczInstalledVersion); if (SUCCEEDED(hr)) // package present. { - LogId(REPORT_STANDARD, MSG_ROLLBACK_PACKAGE_SKIPPED, pExecuteAction->msiPackage.pPackage->sczId, LoggingActionStateToString(pExecuteAction->msiPackage.action), LoggingPackageStateToString(BOOTSTRAPPER_PACKAGE_STATE_PRESENT)); + LogId(REPORT_STANDARD, MSG_ROLLBACK_PACKAGE_SKIPPED, pPackage->sczId, LoggingActionStateToString(pExecuteAction->msiPackage.action), LoggingPackageStateToString(BOOTSTRAPPER_PACKAGE_STATE_PRESENT)); hr = S_OK; ExitFunction(); @@ -1141,13 +1143,13 @@ extern "C" HRESULT MsiEngineExecutePackage( if (BOOTSTRAPPER_ACTION_STATE_UNINSTALL != pExecuteAction->msiPackage.action) { // get cached MSI path - hr = CacheGetCompletedPath(pExecuteAction->msiPackage.pPackage->fPerMachine, pExecuteAction->msiPackage.pPackage->sczCacheId, &sczCachedDirectory); - ExitOnFailure(hr, "Failed to get cached path for package: %ls", pExecuteAction->msiPackage.pPackage->sczId); + hr = CacheGetCompletedPath(pPackage->fPerMachine, pPackage->sczCacheId, &sczCachedDirectory); + ExitOnFailure(hr, "Failed to get cached path for package: %ls", pPackage->sczId); // Best effort to set the execute package cache folder variable. VariableSetString(pVariables, BURN_BUNDLE_EXECUTE_PACKAGE_CACHE_FOLDER, sczCachedDirectory, TRUE, FALSE); - hr = PathConcat(sczCachedDirectory, pExecuteAction->msiPackage.pPackage->rgPayloads[0].pPayload->sczFilePath, &sczMsiPath); + hr = PathConcat(sczCachedDirectory, pPackagePayload->sczFilePath, &sczMsiPath); ExitOnFailure(hr, "Failed to build MSI path."); } @@ -1169,28 +1171,28 @@ extern "C" HRESULT MsiEngineExecutePackage( if (pExecuteAction->msiPackage.sczLogPath && *pExecuteAction->msiPackage.sczLogPath) { hr = WiuEnableLog(dwLogMode, pExecuteAction->msiPackage.sczLogPath, 0); - ExitOnFailure(hr, "Failed to enable logging for package: %ls to: %ls", pExecuteAction->msiPackage.pPackage->sczId, pExecuteAction->msiPackage.sczLogPath); + ExitOnFailure(hr, "Failed to enable logging for package: %ls to: %ls", pPackage->sczId, pExecuteAction->msiPackage.sczLogPath); } // set up properties - hr = MsiEngineConcatProperties(pExecuteAction->msiPackage.pPackage->Msi.rgProperties, pExecuteAction->msiPackage.pPackage->Msi.cProperties, pVariables, fRollback, &sczProperties, FALSE); + hr = MsiEngineConcatProperties(pPackage->Msi.rgProperties, pPackage->Msi.cProperties, pVariables, fRollback, &sczProperties, FALSE); ExitOnFailure(hr, "Failed to add properties to argument string."); - hr = MsiEngineConcatProperties(pExecuteAction->msiPackage.pPackage->Msi.rgProperties, pExecuteAction->msiPackage.pPackage->Msi.cProperties, pVariables, fRollback, &sczObfuscatedProperties, TRUE); + hr = MsiEngineConcatProperties(pPackage->Msi.rgProperties, pPackage->Msi.cProperties, pVariables, fRollback, &sczObfuscatedProperties, TRUE); ExitOnFailure(hr, "Failed to add obfuscated properties to argument string."); // add feature action properties - hr = ConcatFeatureActionProperties(pExecuteAction->msiPackage.pPackage, pExecuteAction->msiPackage.rgFeatures, &sczProperties); + hr = ConcatFeatureActionProperties(pPackage, pExecuteAction->msiPackage.rgFeatures, &sczProperties); ExitOnFailure(hr, "Failed to add feature action properties to argument string."); - hr = ConcatFeatureActionProperties(pExecuteAction->msiPackage.pPackage, pExecuteAction->msiPackage.rgFeatures, &sczObfuscatedProperties); + hr = ConcatFeatureActionProperties(pPackage, pExecuteAction->msiPackage.rgFeatures, &sczObfuscatedProperties); ExitOnFailure(hr, "Failed to add feature action properties to obfuscated argument string."); // add slipstream patch properties - hr = ConcatPatchProperty(pExecuteAction->msiPackage.pPackage, fRollback, &sczProperties); + hr = ConcatPatchProperty(pPackage, fRollback, &sczProperties); ExitOnFailure(hr, "Failed to add patch properties to argument string."); - hr = ConcatPatchProperty(pExecuteAction->msiPackage.pPackage, fRollback, &sczObfuscatedProperties); + hr = ConcatPatchProperty(pPackage, fRollback, &sczObfuscatedProperties); ExitOnFailure(hr, "Failed to add patch properties to obfuscated argument string."); hr = MsiEngineConcatActionProperty(pExecuteAction->msiPackage.actionMsiProperty, &sczProperties); @@ -1199,7 +1201,7 @@ extern "C" HRESULT MsiEngineExecutePackage( hr = MsiEngineConcatActionProperty(pExecuteAction->msiPackage.actionMsiProperty, &sczObfuscatedProperties); ExitOnFailure(hr, "Failed to add action property to obfuscated argument string."); - LogId(REPORT_STANDARD, MSG_APPLYING_PACKAGE, LoggingRollbackOrExecute(fRollback), pExecuteAction->msiPackage.pPackage->sczId, LoggingActionStateToString(pExecuteAction->msiPackage.action), sczMsiPath, sczObfuscatedProperties ? sczObfuscatedProperties : L""); + LogId(REPORT_STANDARD, MSG_APPLYING_PACKAGE, LoggingRollbackOrExecute(fRollback), pPackage->sczId, LoggingActionStateToString(pExecuteAction->msiPackage.action), sczMsiPath, sczObfuscatedProperties ? sczObfuscatedProperties : L""); // // Do the actual action. @@ -1213,13 +1215,13 @@ extern "C" HRESULT MsiEngineExecutePackage( hr = WiuInstallProduct(sczMsiPath, sczProperties, &restart); ExitOnFailure(hr, "Failed to install MSI package."); - RegisterSourceDirectory(pExecuteAction->msiPackage.pPackage, sczMsiPath); + RegisterSourceDirectory(pPackage, sczMsiPath); break; case BOOTSTRAPPER_ACTION_STATE_MINOR_UPGRADE: // If feature selection is not enabled, then reinstall the existing features to ensure they get // updated. - if (0 == pExecuteAction->msiPackage.pPackage->Msi.cFeatures) + if (0 == pPackage->Msi.cFeatures) { hr = StrAllocConcatSecure(&sczProperties, L" REINSTALL=ALL", 0); ExitOnFailure(hr, "Failed to add reinstall all property on minor upgrade."); @@ -1231,7 +1233,7 @@ extern "C" HRESULT MsiEngineExecutePackage( hr = WiuInstallProduct(sczMsiPath, sczProperties, &restart); ExitOnFailure(hr, "Failed to perform minor upgrade of MSI package."); - RegisterSourceDirectory(pExecuteAction->msiPackage.pPackage, sczMsiPath); + RegisterSourceDirectory(pPackage, sczMsiPath); break; case BOOTSTRAPPER_ACTION_STATE_MODIFY: __fallthrough; @@ -1239,7 +1241,7 @@ extern "C" HRESULT MsiEngineExecutePackage( case BOOTSTRAPPER_ACTION_STATE_REPAIR: { LPCWSTR wzReinstallAll = (BOOTSTRAPPER_ACTION_STATE_MODIFY == pExecuteAction->msiPackage.action || - pExecuteAction->msiPackage.pPackage->Msi.cFeatures) ? L"" : L" REINSTALL=ALL"; + pPackage->Msi.cFeatures) ? L"" : L" REINSTALL=ALL"; LPCWSTR wzReinstallMode = (BOOTSTRAPPER_ACTION_STATE_MODIFY == pExecuteAction->msiPackage.action || BOOTSTRAPPER_ACTION_STATE_MEND == pExecuteAction->msiPackage.action) ? L"o" : L"e"; hr = StrAllocFormattedSecure(&sczProperties, L"%ls%ls REINSTALLMODE=\"cmus%ls\" REBOOT=ReallySuppress", sczProperties ? sczProperties : L"", wzReinstallAll, wzReinstallMode); @@ -1262,10 +1264,10 @@ extern "C" HRESULT MsiEngineExecutePackage( hr = StrAllocFormattedSecure(&sczProperties, L"%ls %ls=ALL", sczProperties, DEPENDENCY_IGNOREDEPENDENCIES); ExitOnFailure(hr, "Failed to add the list of dependencies to ignore to the properties."); - hr = WiuConfigureProductEx(pExecuteAction->msiPackage.pPackage->Msi.sczProductCode, INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT, sczProperties, &restart); + hr = WiuConfigureProductEx(pPackage->Msi.sczProductCode, INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT, sczProperties, &restart); if (HRESULT_FROM_WIN32(ERROR_UNKNOWN_PRODUCT) == hr) { - LogId(REPORT_STANDARD, MSG_ATTEMPTED_UNINSTALL_ABSENT_PACKAGE, pExecuteAction->msiPackage.pPackage->sczId); + LogId(REPORT_STANDARD, MSG_ATTEMPTED_UNINSTALL_ABSENT_PACKAGE, pPackage->sczId); hr = S_OK; } ExitOnFailure(hr, "Failed to uninstall MSI package."); @@ -1979,6 +1981,7 @@ static HRESULT ConcatPatchProperty( { BURN_SLIPSTREAM_MSP* pSlipstreamMsp = pPackage->Msi.rgSlipstreamMsps + i; BURN_PACKAGE* pMspPackage = pSlipstreamMsp->pMspPackage; + BURN_PAYLOAD* pMspPackagePayload = pMspPackage->payloads.rgpPayloads[0]; BOOTSTRAPPER_ACTION_STATE patchExecuteAction = fRollback ? pSlipstreamMsp->rollback : pSlipstreamMsp->execute; if (BOOTSTRAPPER_ACTION_STATE_UNINSTALL < patchExecuteAction) @@ -1986,7 +1989,7 @@ static HRESULT ConcatPatchProperty( hr = CacheGetCompletedPath(pMspPackage->fPerMachine, pMspPackage->sczCacheId, &sczCachedDirectory); ExitOnFailure(hr, "Failed to get cached path for MSP package: %ls", pMspPackage->sczId); - hr = PathConcat(sczCachedDirectory, pMspPackage->rgPayloads[0].pPayload->sczFilePath, &sczMspPath); + hr = PathConcat(sczCachedDirectory, pMspPackagePayload->sczFilePath, &sczMspPath); ExitOnFailure(hr, "Failed to build MSP path."); if (!sczPatches) diff --git a/src/engine/mspengine.cpp b/src/engine/mspengine.cpp index 5ccb6718..6addfa90 100644 --- a/src/engine/mspengine.cpp +++ b/src/engine/mspengine.cpp @@ -581,6 +581,7 @@ extern "C" HRESULT MspEngineExecutePackage( { LPCWSTR wzAppend = NULL; BURN_PACKAGE* pMspPackage = pExecuteAction->mspTarget.rgOrderedPatches[i].pPackage; + BURN_PAYLOAD* pMspPackagePayload = pMspPackage->payloads.rgpPayloads[0]; AssertSz(BURN_PACKAGE_TYPE_MSP == pMspPackage->type, "Invalid package type added to ordered patches."); if (BOOTSTRAPPER_ACTION_STATE_INSTALL == pExecuteAction->mspTarget.action) @@ -592,7 +593,7 @@ extern "C" HRESULT MspEngineExecutePackage( // Best effort to set the execute package cache folder variable. VariableSetString(pVariables, BURN_BUNDLE_EXECUTE_PACKAGE_CACHE_FOLDER, sczCachedDirectory, TRUE, FALSE); - hr = PathConcat(sczCachedDirectory, pMspPackage->rgPayloads[0].pPayload->sczFilePath, &sczMspPath); + hr = PathConcat(sczCachedDirectory, pMspPackagePayload->sczFilePath, &sczMspPath); ExitOnFailure(hr, "Failed to build MSP path."); wzAppend = sczMspPath; diff --git a/src/engine/msuengine.cpp b/src/engine/msuengine.cpp index 59f9a656..02ceb0c6 100644 --- a/src/engine/msuengine.cpp +++ b/src/engine/msuengine.cpp @@ -264,6 +264,8 @@ extern "C" HRESULT MsuEngineExecutePackage( GENERIC_EXECUTE_MESSAGE message = { }; DWORD dwExitCode = 0; BOOL fUseSysNativePath = FALSE; + BURN_PACKAGE* pPackage = pExecuteAction->msuPackage.pPackage; + BURN_PAYLOAD* pPackagePayload = pPackage->payloads.rgpPayloads[0]; #if !defined(_WIN64) hr = ProcWow64(::GetCurrentProcess(), &fUseSysNativePath); @@ -295,13 +297,13 @@ extern "C" HRESULT MsuEngineExecutePackage( { case BOOTSTRAPPER_ACTION_STATE_INSTALL: // get cached MSU path - hr = CacheGetCompletedPath(TRUE, pExecuteAction->msuPackage.pPackage->sczCacheId, &sczCachedDirectory); - ExitOnFailure(hr, "Failed to get cached path for package: %ls", pExecuteAction->msuPackage.pPackage->sczId); + hr = CacheGetCompletedPath(TRUE, pPackage->sczCacheId, &sczCachedDirectory); + ExitOnFailure(hr, "Failed to get cached path for package: %ls", pPackage->sczId); // Best effort to set the execute package cache folder variable. VariableSetString(pVariables, BURN_BUNDLE_EXECUTE_PACKAGE_CACHE_FOLDER, sczCachedDirectory, TRUE, FALSE); - hr = PathConcat(sczCachedDirectory, pExecuteAction->msuPackage.pPackage->rgPayloads[0].pPayload->sczFilePath, &sczMsuPath); + hr = PathConcat(sczCachedDirectory, pPackagePayload->sczFilePath, &sczMsuPath); ExitOnFailure(hr, "Failed to build MSU path."); // format command @@ -311,7 +313,7 @@ extern "C" HRESULT MsuEngineExecutePackage( case BOOTSTRAPPER_ACTION_STATE_UNINSTALL: // format command - hr = StrAllocFormatted(&sczCommand, L"\"%ls\" /uninstall /kb:%ls /quiet /norestart", sczWusaPath, pExecuteAction->msuPackage.pPackage->Msu.sczKB); + hr = StrAllocFormatted(&sczCommand, L"\"%ls\" /uninstall /kb:%ls /quiet /norestart", sczWusaPath, pPackage->Msu.sczKB); ExitOnFailure(hr, "Failed to format MSU uninstall command."); break; @@ -329,7 +331,7 @@ extern "C" HRESULT MsuEngineExecutePackage( ExitOnFailure(hr, "Failed to append log path to MSU command-line."); } - LogId(REPORT_STANDARD, MSG_APPLYING_PACKAGE, LoggingRollbackOrExecute(fRollback), pExecuteAction->msuPackage.pPackage->sczId, LoggingActionStateToString(pExecuteAction->msuPackage.action), sczMsuPath ? sczMsuPath : pExecuteAction->msuPackage.pPackage->Msu.sczKB, sczCommand); + LogId(REPORT_STANDARD, MSG_APPLYING_PACKAGE, LoggingRollbackOrExecute(fRollback), pPackage->sczId, LoggingActionStateToString(pExecuteAction->msuPackage.action), sczMsuPath ? sczMsuPath : pPackage->Msu.sczKB, sczCommand); hr = EnsureWUServiceEnabled(fStopWusaService, &schWu, &fWuWasDisabled); ExitOnFailure(hr, "Failed to ensure WU service was enabled to install MSU package."); diff --git a/src/engine/package.cpp b/src/engine/package.cpp index 6ff59fe4..ecf1488b 100644 --- a/src/engine/package.cpp +++ b/src/engine/package.cpp @@ -349,7 +349,7 @@ extern "C" void PackageUninitialize( MemFree(pPackage->rgDependencyProviders); } - ReleaseMem(pPackage->rgPayloads); + ReleaseMem(pPackage->payloads.rgpPayloads); switch (pPackage->type) { @@ -567,16 +567,14 @@ static HRESULT ParsePayloadRefsFromXml( } // allocate memory for payload pointers - pPackage->rgPayloads = (BURN_PACKAGE_PAYLOAD*)MemAlloc(sizeof(BURN_PACKAGE_PAYLOAD) * cNodes, TRUE); - ExitOnNull(pPackage->rgPayloads, hr, E_OUTOFMEMORY, "Failed to allocate memory for package payloads."); + pPackage->payloads.rgpPayloads = (BURN_PAYLOAD**)MemAlloc(sizeof(BURN_PAYLOAD*) * cNodes, TRUE); + ExitOnNull(pPackage->payloads.rgpPayloads, hr, E_OUTOFMEMORY, "Failed to allocate memory for package payloads."); - pPackage->cPayloads = cNodes; + pPackage->payloads.cPayloads = cNodes; // parse package elements for (DWORD i = 0; i < cNodes; ++i) { - BURN_PACKAGE_PAYLOAD* pPackagePayload = &pPackage->rgPayloads[i]; - hr = XmlNextElement(pixnNodes, &pixnNode, NULL); ExitOnFailure(hr, "Failed to get next node."); @@ -585,9 +583,11 @@ static HRESULT ParsePayloadRefsFromXml( ExitOnFailure(hr, "Failed to get Id attribute."); // find payload - hr = PayloadFindById(pPayloads, sczId, &pPackagePayload->pPayload); + hr = PayloadFindById(pPayloads, sczId, &pPackage->payloads.rgpPayloads[i]); ExitOnFailure(hr, "Failed to find payload."); + pPackage->payloads.qwTotalSize += pPackage->payloads.rgpPayloads[i]->qwFileSize; + // prepare next iteration ReleaseNullObject(pixnNode); } diff --git a/src/engine/package.h b/src/engine/package.h index 262262ab..34a3af26 100644 --- a/src/engine/package.h +++ b/src/engine/package.h @@ -184,12 +184,6 @@ typedef struct _BURN_SLIPSTREAM_MSP BOOTSTRAPPER_ACTION_STATE rollback; // only valid during Plan. } BURN_SLIPSTREAM_MSP; -typedef struct _BURN_PACKAGE_PAYLOAD -{ - BURN_PAYLOAD* pPayload; - BOOL fCached; -} BURN_PACKAGE_PAYLOAD; - typedef struct _BURN_DEPENDENCY_PROVIDER { LPWSTR sczKey; @@ -260,8 +254,7 @@ typedef struct _BURN_PACKAGE BURN_PACKAGE_REGISTRATION_STATE expectedInstallRegistrationState;// only valid after Plan. BURN_PACKAGE_REGISTRATION_STATE transactionRegistrationState; // only valid during Apply inside an MSI transaction. - BURN_PACKAGE_PAYLOAD* rgPayloads; - DWORD cPayloads; + BURN_PAYLOAD_GROUP payloads; BURN_DEPENDENCY_PROVIDER* rgDependencyProviders; DWORD cDependencyProviders; diff --git a/src/engine/payload.cpp b/src/engine/payload.cpp index 67eebe10..2be39b23 100644 --- a/src/engine/payload.cpp +++ b/src/engine/payload.cpp @@ -18,6 +18,7 @@ static HRESULT FindEmbeddedBySourcePath( extern "C" HRESULT PayloadsParseFromXml( __in BURN_PAYLOADS* pPayloads, __in_opt BURN_CONTAINERS* pContainers, + __in_opt BURN_PAYLOAD_GROUP* pLayoutPayloads, __in IXMLDOMNode* pixnBundle ) { @@ -136,6 +137,17 @@ extern "C" HRESULT PayloadsParseFromXml( hr = StrAllocHexDecode(scz, &pPayload->pbHash, &pPayload->cbHash); ExitOnFailure(hr, "Failed to hex decode the Payload/@Hash."); + if (pPayload->fLayoutOnly && pLayoutPayloads) + { + hr = MemEnsureArraySize(reinterpret_cast(&pLayoutPayloads->rgpPayloads), pLayoutPayloads->cPayloads + 1, sizeof(BURN_PAYLOAD*), 5); + ExitOnNull(pPayloads->rgPayloads, hr, E_OUTOFMEMORY, "Failed to allocate memory for layout payloads."); + + pLayoutPayloads->rgpPayloads[pLayoutPayloads->cPayloads] = pPayload; + ++pLayoutPayloads->cPayloads; + + pLayoutPayloads->qwTotalSize += pPayload->qwFileSize; + } + // prepare next iteration ReleaseNullObject(pixnNode); } @@ -150,6 +162,24 @@ LExit: return hr; } +extern "C" void PayloadUninitialize( + __in BURN_PAYLOAD* pPayload + ) +{ + if (pPayload) + { + ReleaseStr(pPayload->sczKey); + ReleaseStr(pPayload->sczFilePath); + ReleaseMem(pPayload->pbHash); + ReleaseStr(pPayload->sczSourcePath); + ReleaseStr(pPayload->sczLocalFilePath); + ReleaseStr(pPayload->downloadSource.sczUrl); + ReleaseStr(pPayload->downloadSource.sczUser); + ReleaseStr(pPayload->downloadSource.sczPassword); + ReleaseStr(pPayload->sczUnverifiedPath); + } +} + extern "C" void PayloadsUninitialize( __in BURN_PAYLOADS* pPayloads ) @@ -158,16 +188,7 @@ extern "C" void PayloadsUninitialize( { for (DWORD i = 0; i < pPayloads->cPayloads; ++i) { - BURN_PAYLOAD* pPayload = &pPayloads->rgPayloads[i]; - - ReleaseStr(pPayload->sczKey); - ReleaseStr(pPayload->sczFilePath); - ReleaseMem(pPayload->pbHash); - ReleaseStr(pPayload->sczSourcePath); - ReleaseStr(pPayload->sczLocalFilePath); - ReleaseStr(pPayload->downloadSource.sczUrl); - ReleaseStr(pPayload->downloadSource.sczUser); - ReleaseStr(pPayload->downloadSource.sczPassword); + PayloadUninitialize(pPayloads->rgPayloads + i); } MemFree(pPayloads->rgPayloads); } diff --git a/src/engine/payload.h b/src/engine/payload.h index e8639d64..ba555766 100644 --- a/src/engine/payload.h +++ b/src/engine/payload.h @@ -45,6 +45,8 @@ typedef struct _BURN_PAYLOAD // mutable members BURN_PAYLOAD_STATE state; LPWSTR sczLocalFilePath; // location of extracted or downloaded copy + + LPWSTR sczUnverifiedPath; } BURN_PAYLOAD; typedef struct _BURN_PAYLOADS @@ -53,14 +55,24 @@ typedef struct _BURN_PAYLOADS DWORD cPayloads; } BURN_PAYLOADS; +typedef struct _BURN_PAYLOAD_GROUP +{ + BURN_PAYLOAD** rgpPayloads; + DWORD cPayloads; + DWORD64 qwTotalSize; +} BURN_PAYLOAD_GROUP; // functions HRESULT PayloadsParseFromXml( __in BURN_PAYLOADS* pPayloads, __in_opt BURN_CONTAINERS* pContainers, + __in_opt BURN_PAYLOAD_GROUP* pLayoutPayloads, __in IXMLDOMNode* pixnBundle ); +void PayloadUninitialize( + __in BURN_PAYLOAD* pPayload + ); void PayloadsUninitialize( __in BURN_PAYLOADS* pPayloads ); diff --git a/src/engine/plan.cpp b/src/engine/plan.cpp index 187b1f15..ce577da5 100644 --- a/src/engine/plan.cpp +++ b/src/engine/plan.cpp @@ -15,6 +15,15 @@ static void UninitializeRegistrationAction( static void UninitializeCacheAction( __in BURN_CACHE_ACTION* pCacheAction ); +static void ResetPlannedContainerState( + __in BURN_CONTAINER* pContainer + ); +static void ResetPlannedPayloadsState( + __in BURN_PAYLOADS* pPayloads + ); +static void ResetPlannedPayloadGroupState( + __in BURN_PAYLOAD_GROUP* pPayloadGroup + ); static void ResetPlannedPackageState( __in BURN_PACKAGE* pPackage ); @@ -30,8 +39,7 @@ static HRESULT PlanPackagesHelper( __in BURN_LOGGING* pLog, __in BURN_VARIABLES* pVariables, __in BOOTSTRAPPER_DISPLAY display, - __in BOOTSTRAPPER_RELATION_TYPE relationType, - __in_z_opt LPCWSTR wzLayoutDirectory + __in BOOTSTRAPPER_RELATION_TYPE relationType ); static HRESULT InitializePackage( __in BURN_PLAN* pPlan, @@ -48,7 +56,6 @@ static HRESULT ProcessPackage( __in BURN_LOGGING* pLog, __in BURN_VARIABLES* pVariables, __in BOOTSTRAPPER_DISPLAY display, - __in_z_opt LPCWSTR wzLayoutDirectory, __inout HANDLE* phSyncpointEvent, __inout BURN_ROLLBACK_BOUNDARY** ppRollbackBoundary ); @@ -99,54 +106,9 @@ static HRESULT AppendRollbackCacheAction( __in BURN_PLAN* pPlan, __out BURN_CACHE_ACTION** ppCacheAction ); -static HRESULT AppendLayoutContainerAction( - __in BURN_PLAN* pPlan, - __in_opt BURN_PACKAGE* pPackage, - __in DWORD iPackageStartAction, - __in BURN_CONTAINER* pContainer, - __in BOOL fContainerCached, - __in_z LPCWSTR wzLayoutDirectory - ); -static HRESULT AppendCacheOrLayoutPayloadAction( - __in BURN_PLAN* pPlan, - __in_opt BURN_PACKAGE* pPackage, - __in DWORD iPackageStartAction, - __in BURN_PAYLOAD* pPayload, - __in BOOL fPayloadCached, - __in_z_opt LPCWSTR wzLayoutDirectory - ); -static BOOL FindContainerCacheAction( - __in BURN_CACHE_ACTION_TYPE type, - __in BURN_PLAN* pPlan, - __in BURN_CONTAINER* pContainer, - __in DWORD iSearchStart, - __in DWORD iSearchEnd, - __out_opt BURN_CACHE_ACTION** ppCacheAction, - __out_opt DWORD* piCacheAction - ); -static HRESULT CreateContainerAcquireAndExtractAction( +static HRESULT ProcessPayloadGroup( __in BURN_PLAN* pPlan, - __in BURN_CONTAINER* pContainer, - __in DWORD iPackageStartAction, - __in BOOL fPayloadCached, - __out BURN_CACHE_ACTION** ppContainerExtractAction, - __out DWORD* piContainerTryAgainAction - ); -static HRESULT AddAcquireContainer( - __in BURN_PLAN* pPlan, - __in BURN_CONTAINER* pContainer, - __out_opt BURN_CACHE_ACTION** ppCacheAction, - __out_opt DWORD* piCacheAction - ); -static HRESULT AddExtractPayload( - __in BURN_CACHE_ACTION* pCacheAction, - __in_opt BURN_PACKAGE* pPackage, - __in BURN_PAYLOAD* pPayload, - __in_z LPCWSTR wzPayloadWorkingPath - ); -static BURN_CACHE_ACTION* ProcessSharedPayload( - __in BURN_PLAN* pPlan, - __in BURN_PAYLOAD* pPayload + __in BURN_PAYLOAD_GROUP* pPayloadGroup ); static void RemoveUnnecessaryActions( __in BOOL fExecute, @@ -175,24 +137,17 @@ static BOOL NeedsCache( __in BURN_PACKAGE* pPackage, __in BOOL fExecute ); -static HRESULT CreateContainerProgress( - __in BURN_PLAN* pPlan, - __in BURN_CONTAINER* pContainer, - __out BURN_CACHE_CONTAINER_PROGRESS** ppContainerProgress - ); -static HRESULT CreatePayloadProgress( - __in BURN_PLAN* pPlan, - __in BURN_PAYLOAD* pPayload, - __out BURN_CACHE_PAYLOAD_PROGRESS** ppPayloadProgress - ); // function definitions extern "C" void PlanReset( __in BURN_PLAN* pPlan, - __in BURN_PACKAGES* pPackages + __in BURN_CONTAINERS* pContainers, + __in BURN_PACKAGES* pPackages, + __in BURN_PAYLOAD_GROUP* pLayoutPayloads ) { + ReleaseNullStr(pPlan->sczLayoutDirectory); PackageUninitialize(&pPlan->forwardCompatibleBundle); if (pPlan->rgRegistrationActions) @@ -271,8 +226,21 @@ extern "C" void PlanReset( ReleaseDict(pPlan->shPayloadProgress); } + if (pPlan->pPayloads) + { + ResetPlannedPayloadsState(pPlan->pPayloads); + } + memset(pPlan, 0, sizeof(BURN_PLAN)); + if (pContainers->rgContainers) + { + for (DWORD i = 0; i < pContainers->cContainers; ++i) + { + ResetPlannedContainerState(&pContainers->rgContainers[i]); + } + } + // Reset the planned actions for each package. if (pPackages->rgPackages) { @@ -282,6 +250,8 @@ extern "C" void PlanReset( } } + ResetPlannedPayloadGroupState(pLayoutPayloads); + // Reset the planned state for each rollback boundary. if (pPackages->rgRollbackBoundaries) { @@ -417,34 +387,35 @@ extern "C" HRESULT PlanLayoutBundle( __in_z LPCWSTR wzExecutableName, __in DWORD64 qwBundleSize, __in BURN_VARIABLES* pVariables, - __in BURN_PAYLOADS* pPayloads, - __out_z LPWSTR* psczLayoutDirectory + __in BURN_PAYLOAD_GROUP* pLayoutPayloads ) { HRESULT hr = S_OK; BURN_CACHE_ACTION* pCacheAction = NULL; LPWSTR sczExecutablePath = NULL; - LPWSTR sczLayoutDirectory = NULL; // Get the layout directory. - hr = VariableGetString(pVariables, BURN_BUNDLE_LAYOUT_DIRECTORY, &sczLayoutDirectory); + hr = VariableGetString(pVariables, BURN_BUNDLE_LAYOUT_DIRECTORY, &pPlan->sczLayoutDirectory); if (E_NOTFOUND == hr) // if not set, use the current directory as the layout directory. { - hr = VariableGetString(pVariables, BURN_BUNDLE_SOURCE_PROCESS_FOLDER, &sczLayoutDirectory); + hr = VariableGetString(pVariables, BURN_BUNDLE_SOURCE_PROCESS_FOLDER, &pPlan->sczLayoutDirectory); if (E_NOTFOUND == hr) // if not set, use the current directory as the layout directory. { hr = PathForCurrentProcess(&sczExecutablePath, NULL); ExitOnFailure(hr, "Failed to get path for current executing process as layout directory."); - hr = PathGetDirectory(sczExecutablePath, &sczLayoutDirectory); + hr = PathGetDirectory(sczExecutablePath, &pPlan->sczLayoutDirectory); ExitOnFailure(hr, "Failed to get executing process as layout directory."); } } ExitOnFailure(hr, "Failed to get bundle layout directory property."); - hr = PathBackslashTerminate(&sczLayoutDirectory); + hr = PathBackslashTerminate(&pPlan->sczLayoutDirectory); ExitOnFailure(hr, "Failed to ensure layout directory is backslash terminated."); + hr = ProcessPayloadGroup(pPlan, pLayoutPayloads); + ExitOnFailure(hr, "Failed to process payload group for bundle."); + // Plan the layout of the bundle engine itself. hr = AppendCacheAction(pPlan, &pCacheAction); ExitOnFailure(hr, "Failed to append bundle start action."); @@ -454,36 +425,17 @@ extern "C" HRESULT PlanLayoutBundle( hr = StrAllocString(&pCacheAction->bundleLayout.sczExecutableName, wzExecutableName, 0); ExitOnFailure(hr, "Failed to to copy executable name for bundle."); - hr = StrAllocString(&pCacheAction->bundleLayout.sczLayoutDirectory, sczLayoutDirectory, 0); - ExitOnFailure(hr, "Failed to to copy layout directory for bundle."); - hr = CacheCalculateBundleLayoutWorkingPath(pPlan->wzBundleId, &pCacheAction->bundleLayout.sczUnverifiedPath); ExitOnFailure(hr, "Failed to calculate bundle layout working path."); pCacheAction->bundleLayout.qwBundleSize = qwBundleSize; + pCacheAction->bundleLayout.pPayloadGroup = pLayoutPayloads; - pPlan->qwCacheSizeTotal += qwBundleSize; + pPlan->qwCacheSizeTotal += 2 * qwBundleSize; ++pPlan->cOverallProgressTicksTotal; - // Plan the layout of layout-only payloads. - for (DWORD i = 0; i < pPayloads->cPayloads; ++i) - { - BURN_PAYLOAD* pPayload = pPayloads->rgPayloads + i; - if (pPayload->fLayoutOnly) - { - // TODO: determine if a payload already exists in the layout and pass appropriate value fPayloadCached - // (instead of always FALSE). - hr = AppendCacheOrLayoutPayloadAction(pPlan, NULL, BURN_PLAN_INVALID_ACTION_INDEX, pPayload, FALSE, sczLayoutDirectory); - ExitOnFailure(hr, "Failed to plan layout payload."); - } - } - - *psczLayoutDirectory = sczLayoutDirectory; - sczLayoutDirectory = NULL; - LExit: - ReleaseStr(sczLayoutDirectory); ReleaseStr(sczExecutablePath); return hr; @@ -562,13 +514,12 @@ extern "C" HRESULT PlanPackages( __in BURN_LOGGING* pLog, __in BURN_VARIABLES* pVariables, __in BOOTSTRAPPER_DISPLAY display, - __in BOOTSTRAPPER_RELATION_TYPE relationType, - __in_z_opt LPCWSTR wzLayoutDirectory + __in BOOTSTRAPPER_RELATION_TYPE relationType ) { HRESULT hr = S_OK; - hr = PlanPackagesHelper(pPackages->rgPackages, pPackages->cPackages, TRUE, pUX, pPlan, pLog, pVariables, display, relationType, wzLayoutDirectory); + hr = PlanPackagesHelper(pPackages->rgPackages, pPackages->cPackages, TRUE, pUX, pPlan, pLog, pVariables, display, relationType); return hr; } @@ -782,7 +733,7 @@ extern "C" HRESULT PlanPassThroughBundle( // Plan passthrough package. // Passthrough packages are never cleaned up by the calling bundle (they delete themselves when appropriate) // so we don't need to plan clean up. - hr = PlanPackagesHelper(pPackage, 1, FALSE, pUX, pPlan, pLog, pVariables, display, relationType, NULL); + hr = PlanPackagesHelper(pPackage, 1, FALSE, pUX, pPlan, pLog, pVariables, display, relationType); ExitOnFailure(hr, "Failed to process passthrough package."); LExit: @@ -802,7 +753,7 @@ extern "C" HRESULT PlanUpdateBundle( HRESULT hr = S_OK; // Plan update package. - hr = PlanPackagesHelper(pPackage, 1, TRUE, pUX, pPlan, pLog, pVariables, display, relationType, NULL); + hr = PlanPackagesHelper(pPackage, 1, TRUE, pUX, pPlan, pLog, pVariables, display, relationType); ExitOnFailure(hr, "Failed to process update package."); LExit: @@ -818,8 +769,7 @@ static HRESULT PlanPackagesHelper( __in BURN_LOGGING* pLog, __in BURN_VARIABLES* pVariables, __in BOOTSTRAPPER_DISPLAY display, - __in BOOTSTRAPPER_RELATION_TYPE relationType, - __in_z_opt LPCWSTR wzLayoutDirectory + __in BOOTSTRAPPER_RELATION_TYPE relationType ) { HRESULT hr = S_OK; @@ -856,7 +806,7 @@ static HRESULT PlanPackagesHelper( DWORD iPackage = (BOOTSTRAPPER_ACTION_UNINSTALL == pPlan->action) ? cPackages - 1 - i : i; BURN_PACKAGE* pPackage = rgPackages + iPackage; - hr = ProcessPackage(fBundlePerMachine, pUX, pPlan, pPackage, pLog, pVariables, display, wzLayoutDirectory, &hSyncpointEvent, &pRollbackBoundary); + hr = ProcessPackage(fBundlePerMachine, pUX, pPlan, pPackage, pLog, pVariables, display, &hSyncpointEvent, &pRollbackBoundary); ExitOnFailure(hr, "Failed to process package."); } @@ -962,7 +912,6 @@ static HRESULT ProcessPackage( __in BURN_LOGGING* pLog, __in BURN_VARIABLES* pVariables, __in BOOTSTRAPPER_DISPLAY display, - __in_z_opt LPCWSTR wzLayoutDirectory, __inout HANDLE* phSyncpointEvent, __inout BURN_ROLLBACK_BOUNDARY** ppRollbackBoundary ) @@ -976,7 +925,7 @@ static HRESULT ProcessPackage( if (BOOTSTRAPPER_ACTION_LAYOUT == pPlan->action) { - hr = PlanLayoutPackage(pPlan, pPackage, wzLayoutDirectory); + hr = PlanLayoutPackage(pPlan, pPackage); ExitOnFailure(hr, "Failed to plan layout package."); } else @@ -1035,59 +984,69 @@ LExit: return hr; } -extern "C" HRESULT PlanLayoutPackage( +extern "C" HRESULT PlanLayoutContainer( __in BURN_PLAN* pPlan, - __in BURN_PACKAGE* pPackage, - __in_z_opt LPCWSTR wzLayoutDirectory + __in BURN_CONTAINER* pContainer ) { HRESULT hr = S_OK; BURN_CACHE_ACTION* pCacheAction = NULL; - DWORD iPackageStartAction = 0; - hr = AppendCacheAction(pPlan, &pCacheAction); - ExitOnFailure(hr, "Failed to append package start action."); + Assert(!pContainer->fPlanned); + pContainer->fPlanned = TRUE; - pCacheAction->type = BURN_CACHE_ACTION_TYPE_PACKAGE_START; - pCacheAction->packageStart.pPackage = pPackage; + if (pPlan->sczLayoutDirectory) + { + if (!pContainer->fAttached) + { + hr = AppendCacheAction(pPlan, &pCacheAction); + ExitOnFailure(hr, "Failed to append package start action."); - // Remember the index for the package start action (which is now the last in the cache - // actions array) because the array may be resized later and move around in memory. - iPackageStartAction = pPlan->cCacheActions - 1; + pCacheAction->type = BURN_CACHE_ACTION_TYPE_CONTAINER; + pCacheAction->container.pContainer = pContainer; - // If any of the package payloads are not cached, add them to the plan. - for (DWORD i = 0; i < pPackage->cPayloads; ++i) + pPlan->qwCacheSizeTotal += 2 * pContainer->qwFileSize; + } + } + else { - BURN_PACKAGE_PAYLOAD* pPackagePayload = &pPackage->rgPayloads[i]; + pPlan->qwCacheSizeTotal += 2 * pContainer->qwFileSize; + } - // If doing layout and the package is in a container. - if (wzLayoutDirectory && pPackagePayload->pPayload->pContainer) + if (!pContainer->sczUnverifiedPath) + { + if (pContainer->fActuallyAttached) { - // TODO: determine if a container already exists in the layout and pass appropriate value fPayloadCached (instead of always FALSE). - hr = AppendLayoutContainerAction(pPlan, pPackage, iPackageStartAction, pPackagePayload->pPayload->pContainer, FALSE, wzLayoutDirectory); - ExitOnFailure(hr, "Failed to append layout container action."); + hr = PathForCurrentProcess(&pContainer->sczUnverifiedPath, NULL); + ExitOnFailure(hr, "Failed to get path for executing module as attached container working path."); } else { - // TODO: determine if a payload already exists in the layout and pass appropriate value fPayloadCached (instead of always FALSE). - hr = AppendCacheOrLayoutPayloadAction(pPlan, pPackage, iPackageStartAction, pPackagePayload->pPayload, FALSE, wzLayoutDirectory); - ExitOnFailure(hr, "Failed to append cache/layout payload action."); + hr = CacheCalculateContainerWorkingPath(pPlan->wzBundleId, pContainer, &pContainer->sczUnverifiedPath); + ExitOnFailure(hr, "Failed to calculate unverified path for container."); } - - Assert(BURN_CACHE_ACTION_TYPE_PACKAGE_START == pPlan->rgCacheActions[iPackageStartAction].type); - ++pPlan->rgCacheActions[iPackageStartAction].packageStart.cCachePayloads; - pPlan->rgCacheActions[iPackageStartAction].packageStart.qwCachePayloadSizeTotal += pPackagePayload->pPayload->qwFileSize; } - // Create package stop action. - hr = AppendCacheAction(pPlan, &pCacheAction); - ExitOnFailure(hr, "Failed to append cache action."); +LExit: + return hr; +} - pCacheAction->type = BURN_CACHE_ACTION_TYPE_PACKAGE_STOP; - pCacheAction->packageStop.pPackage = pPackage; +extern "C" HRESULT PlanLayoutPackage( + __in BURN_PLAN* pPlan, + __in BURN_PACKAGE* pPackage + ) +{ + HRESULT hr = S_OK; + BURN_CACHE_ACTION* pCacheAction = NULL; + + hr = ProcessPayloadGroup(pPlan, &pPackage->payloads); + ExitOnFailure(hr, "Failed to process payload group for package: %ls.", pPackage->sczId); - // Update the start action with the location of the complete action. - pPlan->rgCacheActions[iPackageStartAction].packageStart.iPackageCompleteAction = pPlan->cCacheActions - 1; + hr = AppendCacheAction(pPlan, &pCacheAction); + ExitOnFailure(hr, "Failed to append package start action."); + + pCacheAction->type = BURN_CACHE_ACTION_TYPE_PACKAGE; + pCacheAction->package.pPackage = pPackage; ++pPlan->cOverallProgressTicksTotal; @@ -1854,29 +1813,37 @@ static void UninitializeCacheAction( case BURN_CACHE_ACTION_TYPE_LAYOUT_BUNDLE: ReleaseStr(pCacheAction->bundleLayout.sczExecutableName); - ReleaseStr(pCacheAction->bundleLayout.sczLayoutDirectory); ReleaseStr(pCacheAction->bundleLayout.sczUnverifiedPath); break; + } +} - case BURN_CACHE_ACTION_TYPE_ACQUIRE_CONTAINER: - ReleaseStr(pCacheAction->resolveContainer.sczUnverifiedPath); - break; - - case BURN_CACHE_ACTION_TYPE_EXTRACT_CONTAINER: - ReleaseStr(pCacheAction->extractContainer.sczContainerUnverifiedPath); - ReleaseMem(pCacheAction->extractContainer.rgPayloads); - break; +static void ResetPlannedContainerState( + __in BURN_CONTAINER* pContainer + ) +{ + pContainer->fPlanned = FALSE; +} - case BURN_CACHE_ACTION_TYPE_ACQUIRE_PAYLOAD: - ReleaseStr(pCacheAction->resolvePayload.sczUnverifiedPath); - break; +static void ResetPlannedPayloadsState( + __in BURN_PAYLOADS* pPayloads + ) +{ + for (DWORD i = 0; i < pPayloads->cPayloads; ++i) + { + BURN_PAYLOAD* pPayload = pPayloads->rgPayloads + i; - case BURN_CACHE_ACTION_TYPE_CACHE_PAYLOAD: - ReleaseStr(pCacheAction->cachePayload.sczUnverifiedPath); - break; + pPayload->state = BURN_PAYLOAD_STATE_NONE; + ReleaseNullStr(pPayload->sczLocalFilePath); } } +static void ResetPlannedPayloadGroupState( + __in BURN_PAYLOAD_GROUP* /*pPayloadGroup*/ + ) +{ +} + static void ResetPlannedPackageState( __in BURN_PACKAGE* pPackage ) @@ -1931,6 +1898,8 @@ static void ResetPlannedPackageState( pTargetProduct->rollbackSkip = BURN_PATCH_SKIP_STATE_NONE; } } + + ResetPlannedPayloadGroupState(&pPackage->payloads); } static void ResetPlannedRollbackBoundaryState( @@ -2091,7 +2060,6 @@ static HRESULT AddCachePackageHelper( HRESULT hr = S_OK; BURN_CACHE_ACTION* pCacheAction = NULL; DWORD dwCheckpoint = 0; - DWORD iPackageStartAction = 0; BOOL fPlanned = AlreadyPlannedCachePackage(pPlan, pPackage->sczId, phSyncpointEvent); if (fPlanned) @@ -2105,7 +2073,7 @@ static HRESULT AddCachePackageHelper( dwCheckpoint = GetNextCheckpointId(pPlan); hr = AppendCacheAction(pPlan, &pCacheAction); - ExitOnFailure(hr, "Failed to append package start action."); + ExitOnFailure(hr, "Failed to append checkpoint before package start action."); pCacheAction->type = BURN_CACHE_ACTION_TYPE_CHECKPOINT; pCacheAction->checkpoint.dwId = dwCheckpoint; @@ -2123,50 +2091,8 @@ static HRESULT AddCachePackageHelper( pCacheAction->checkpoint.dwId = dwCheckpoint; } - // Plan the package start. - hr = AppendCacheAction(pPlan, &pCacheAction); - ExitOnFailure(hr, "Failed to append package start action."); - - pCacheAction->type = BURN_CACHE_ACTION_TYPE_PACKAGE_START; - pCacheAction->packageStart.pPackage = pPackage; - - // Remember the index for the package start action (which is now the last in the cache - // actions array) because we have to update this action after processing all the payloads - // and the array may be resized later which would move a pointer around in memory. - iPackageStartAction = pPlan->cCacheActions - 1; - - if (fPlanCacheRollback) - { - // Create a package cache rollback action. - hr = AppendRollbackCacheAction(pPlan, &pCacheAction); - ExitOnFailure(hr, "Failed to append rollback cache action."); - - pCacheAction->type = BURN_CACHE_ACTION_TYPE_ROLLBACK_PACKAGE; - pCacheAction->rollbackPackage.pPackage = pPackage; - } - - // Add all the payload cache operations to the plan for this package. - for (DWORD i = 0; i < pPackage->cPayloads; ++i) - { - BURN_PACKAGE_PAYLOAD* pPackagePayload = &pPackage->rgPayloads[i]; - - hr = AppendCacheOrLayoutPayloadAction(pPlan, pPackage, iPackageStartAction, pPackagePayload->pPayload, pPackagePayload->fCached, NULL); - ExitOnFailure(hr, "Failed to append payload cache action."); - - Assert(BURN_CACHE_ACTION_TYPE_PACKAGE_START == pPlan->rgCacheActions[iPackageStartAction].type); - ++pPlan->rgCacheActions[iPackageStartAction].packageStart.cCachePayloads; - pPlan->rgCacheActions[iPackageStartAction].packageStart.qwCachePayloadSizeTotal += pPackagePayload->pPayload->qwFileSize; - } - - // Create package stop action. - hr = AppendCacheAction(pPlan, &pCacheAction); - ExitOnFailure(hr, "Failed to append cache action."); - - pCacheAction->type = BURN_CACHE_ACTION_TYPE_PACKAGE_STOP; - pCacheAction->packageStop.pPackage = pPackage; - - // Update the start action with the location of the complete action. - pPlan->rgCacheActions[iPackageStartAction].packageStart.iPackageCompleteAction = pPlan->cCacheActions - 1; + hr = PlanLayoutPackage(pPlan, pPackage); + ExitOnFailure(hr, "Failed to plan cache for package."); // Create syncpoint action. hr = AppendCacheAction(pPlan, &pCacheAction); @@ -2178,8 +2104,6 @@ static HRESULT AddCachePackageHelper( *phSyncpointEvent = pCacheAction->syncpoint.hEvent; - ++pPlan->cOverallProgressTicksTotal; - pPackage->fPlannedCache = TRUE; if (pPackage->fCanAffectRegistration) { @@ -2225,9 +2149,9 @@ static BOOL AlreadyPlannedCachePackage( { BURN_CACHE_ACTION* pCacheAction = pPlan->rgCacheActions + iCacheAction; - if (BURN_CACHE_ACTION_TYPE_PACKAGE_STOP == pCacheAction->type) + if (BURN_CACHE_ACTION_TYPE_PACKAGE == pCacheAction->type) { - if (CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, 0, pCacheAction->packageStop.pPackage->sczId, -1, wzPackageId, -1)) + if (CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, 0, pCacheAction->package.pPackage->sczId, -1, wzPackageId, -1)) { if (iCacheAction + 1 < pPlan->cCacheActions && BURN_CACHE_ACTION_TYPE_SIGNAL_SYNCPOINT == pPlan->rgCacheActions[iCacheAction + 1].type) { @@ -2284,460 +2208,39 @@ LExit: return hr; } -static HRESULT AppendLayoutContainerAction( - __in BURN_PLAN* pPlan, - __in_opt BURN_PACKAGE* pPackage, - __in DWORD iPackageStartAction, - __in BURN_CONTAINER* pContainer, - __in BOOL fContainerCached, - __in_z LPCWSTR wzLayoutDirectory - ) -{ - HRESULT hr = S_OK; - BURN_CACHE_ACTION* pAcquireAction = NULL; - DWORD iAcquireAction = BURN_PLAN_INVALID_ACTION_INDEX; - LPWSTR sczContainerWorkingPath = NULL; - BURN_CACHE_ACTION* pCacheAction = NULL; - BURN_CACHE_CONTAINER_PROGRESS* pContainerProgress = NULL; - - // No need to do anything if the container is already cached or is attached to the bundle (since the - // bundle itself will already have a layout action). - if (fContainerCached || pContainer->fAttached) - { - ExitFunction(); - } - - // Ensure the container is being acquired. If it is, then some earlier package already planned the layout of this container so - // don't do it again. Otherwise, plan away! - if (!FindContainerCacheAction(BURN_CACHE_ACTION_TYPE_ACQUIRE_CONTAINER, pPlan, pContainer, 0, iPackageStartAction, NULL, NULL)) - { - hr = AddAcquireContainer(pPlan, pContainer, &pAcquireAction, &iAcquireAction); - ExitOnFailure(hr, "Failed to append acquire container action for layout to plan."); - - Assert(BURN_CACHE_ACTION_TYPE_ACQUIRE_CONTAINER == pAcquireAction->type); - - // Create the layout container action. - hr = StrAllocString(&sczContainerWorkingPath, pAcquireAction->resolveContainer.sczUnverifiedPath, 0); - ExitOnFailure(hr, "Failed to copy container working path for layout."); - - hr = AppendCacheAction(pPlan, &pCacheAction); - ExitOnFailure(hr, "Failed to append cache action to cache payload."); - - hr = CreateContainerProgress(pPlan, pContainer, &pContainerProgress); - ExitOnFailure(hr, "Failed to create container progress."); - - hr = StrAllocString(&pCacheAction->layoutContainer.sczLayoutDirectory, wzLayoutDirectory, 0); - ExitOnFailure(hr, "Failed to copy layout directory into plan."); - - pCacheAction->type = BURN_CACHE_ACTION_TYPE_LAYOUT_CONTAINER; - pCacheAction->layoutContainer.pPackage = pPackage; - pCacheAction->layoutContainer.pContainer = pContainer; - pCacheAction->layoutContainer.iProgress = pContainerProgress->iIndex; - pCacheAction->layoutContainer.fMove = TRUE; - pCacheAction->layoutContainer.iTryAgainAction = iAcquireAction; - pCacheAction->layoutContainer.sczUnverifiedPath = sczContainerWorkingPath; - sczContainerWorkingPath = NULL; - } - -LExit: - ReleaseNullStr(sczContainerWorkingPath); - - return hr; -} - -static HRESULT AppendCacheOrLayoutPayloadAction( +static HRESULT ProcessPayloadGroup( __in BURN_PLAN* pPlan, - __in_opt BURN_PACKAGE* pPackage, - __in DWORD iPackageStartAction, - __in BURN_PAYLOAD* pPayload, - __in BOOL fPayloadCached, - __in_z_opt LPCWSTR wzLayoutDirectory + __in BURN_PAYLOAD_GROUP* pPayloadGroup ) { HRESULT hr = S_OK; - LPWSTR sczPayloadWorkingPath = NULL; - BURN_CACHE_ACTION* pCacheAction = NULL; - DWORD iTryAgainAction = BURN_PLAN_INVALID_ACTION_INDEX; - BURN_CACHE_PAYLOAD_PROGRESS* pPayloadProgress = NULL; - - hr = CacheCalculatePayloadWorkingPath(pPlan->wzBundleId, pPayload, &sczPayloadWorkingPath); - ExitOnFailure(hr, "Failed to calculate unverified path for payload."); - - // If the payload is in a container, ensure the container is being acquired - // then add this payload to the list of payloads to extract already in the plan. - if (pPayload->pContainer) - { - BURN_CACHE_ACTION* pPreviousPackageExtractAction = NULL; - BURN_CACHE_ACTION* pThisPackageExtractAction = NULL; - - // If the payload is not already cached, then add it to the first extract container action in the plan. Extracting - // all the needed payloads from the container in a single pass is the most efficient way to extract files from - // containers. If there is not an extract container action before our package, that is okay because we'll create - // an extract container action for our package in a second anyway. - if (!fPayloadCached) - { - if (FindContainerCacheAction(BURN_CACHE_ACTION_TYPE_EXTRACT_CONTAINER, pPlan, pPayload->pContainer, 0, iPackageStartAction, &pPreviousPackageExtractAction, NULL)) - { - hr = AddExtractPayload(pPreviousPackageExtractAction, pPackage, pPayload, sczPayloadWorkingPath); - ExitOnFailure(hr, "Failed to add extract payload action to previous package."); - } - } - - // If there is already an extract container action after our package start action then try to find an acquire action - // that is matched with it. If there is an acquire action then that is our "try again" action, otherwise we'll use the existing - // extract action as the "try again" action. - if (FindContainerCacheAction(BURN_CACHE_ACTION_TYPE_EXTRACT_CONTAINER, pPlan, pPayload->pContainer, iPackageStartAction, BURN_PLAN_INVALID_ACTION_INDEX, &pThisPackageExtractAction, &iTryAgainAction)) - { - DWORD iAcquireAction = BURN_PLAN_INVALID_ACTION_INDEX; - if (FindContainerCacheAction(BURN_CACHE_ACTION_TYPE_ACQUIRE_CONTAINER, pPlan, pPayload->pContainer, iPackageStartAction, iTryAgainAction, NULL, &iAcquireAction)) - { - iTryAgainAction = iAcquireAction; - } - } - else // did not find an extract container action for our package. - { - // Ensure there is an extract action (and maybe an acquire action) for every package that has payloads. The - // acquire and extract action will be skipped if the payload is already cached or was added to a previous - // package's extract action above. - // - // These actions always exist (even when they are likely to be skipped) so that "try again" will not - // jump so far back in the plan that you end up extracting payloads for other packages. With these actions - // "try again" will only retry the extraction for payloads in this package. - hr = CreateContainerAcquireAndExtractAction(pPlan, pPayload->pContainer, iPackageStartAction, pPreviousPackageExtractAction ? TRUE : fPayloadCached, &pThisPackageExtractAction, &iTryAgainAction); - ExitOnFailure(hr, "Failed to create container extract action."); - } - ExitOnFailure(hr, "Failed while searching for package's container extract action."); - - // We *always* add the payload to this package's extract action even though the extract action - // is probably being skipped until retry if there was a previous package extract action. - hr = AddExtractPayload(pThisPackageExtractAction, pPackage, pPayload, sczPayloadWorkingPath); - ExitOnFailure(hr, "Failed to add extract payload to current package."); - } - else // add a payload acquire action to the plan. - { - // Try to find an existing acquire action for this payload. If one is not found, - // we'll create it. At the same time we will change any cache/layout payload actions - // that would "MOVE" the file to "COPY" so that our new cache/layout action below - // can do the move. - pCacheAction = ProcessSharedPayload(pPlan, pPayload); - if (!pCacheAction) - { - hr = AppendCacheAction(pPlan, &pCacheAction); - ExitOnFailure(hr, "Failed to append cache action to acquire payload."); - - pCacheAction->type = BURN_CACHE_ACTION_TYPE_ACQUIRE_PAYLOAD; - pCacheAction->fSkipUntilRetried = fPayloadCached; - pCacheAction->resolvePayload.pPackage = pPackage; - pCacheAction->resolvePayload.pPayload = pPayload; - hr = StrAllocString(&pCacheAction->resolvePayload.sczUnverifiedPath, sczPayloadWorkingPath, 0); - ExitOnFailure(hr, "Failed to copy unverified path for payload to acquire."); - } - - iTryAgainAction = static_cast(pCacheAction - pPlan->rgCacheActions); - pCacheAction = NULL; - } - Assert(BURN_PLAN_INVALID_ACTION_INDEX != iTryAgainAction); - Assert(BURN_CACHE_ACTION_TYPE_ACQUIRE_CONTAINER == pPlan->rgCacheActions[iTryAgainAction].type || - BURN_CACHE_ACTION_TYPE_EXTRACT_CONTAINER == pPlan->rgCacheActions[iTryAgainAction].type || - BURN_CACHE_ACTION_TYPE_ACQUIRE_PAYLOAD == pPlan->rgCacheActions[iTryAgainAction].type); - - hr = AppendCacheAction(pPlan, &pCacheAction); - ExitOnFailure(hr, "Failed to append cache action to cache payload."); - - hr = CreatePayloadProgress(pPlan, pPayload, &pPayloadProgress); - ExitOnFailure(hr, "Failed to create payload progress."); - - if (!wzLayoutDirectory) + for (DWORD i = 0; i < pPayloadGroup->cPayloads; ++i) { - pCacheAction->type = BURN_CACHE_ACTION_TYPE_CACHE_PAYLOAD; - pCacheAction->cachePayload.pPackage = pPackage; - pCacheAction->cachePayload.pPayload = pPayload; - pCacheAction->cachePayload.iProgress = pPayloadProgress->iIndex; - pCacheAction->cachePayload.fMove = TRUE; - pCacheAction->cachePayload.iTryAgainAction = iTryAgainAction; - pCacheAction->cachePayload.sczUnverifiedPath = sczPayloadWorkingPath; - sczPayloadWorkingPath = NULL; - } - else - { - hr = StrAllocString(&pCacheAction->layoutPayload.sczLayoutDirectory, wzLayoutDirectory, 0); - ExitOnFailure(hr, "Failed to copy layout directory into plan."); - - pCacheAction->type = BURN_CACHE_ACTION_TYPE_LAYOUT_PAYLOAD; - pCacheAction->layoutPayload.pPackage = pPackage; - pCacheAction->layoutPayload.pPayload = pPayload; - pCacheAction->layoutPayload.iProgress = pPayloadProgress->iIndex; - pCacheAction->layoutPayload.fMove = TRUE; - pCacheAction->layoutPayload.iTryAgainAction = iTryAgainAction; - pCacheAction->layoutPayload.sczUnverifiedPath = sczPayloadWorkingPath; - sczPayloadWorkingPath = NULL; - } - - pCacheAction = NULL; - -LExit: - ReleaseStr(sczPayloadWorkingPath); - - return hr; -} - -static BOOL FindContainerCacheAction( - __in BURN_CACHE_ACTION_TYPE type, - __in BURN_PLAN* pPlan, - __in BURN_CONTAINER* pContainer, - __in DWORD iSearchStart, - __in DWORD iSearchEnd, - __out_opt BURN_CACHE_ACTION** ppCacheAction, - __out_opt DWORD* piCacheAction - ) -{ - BOOL fFound = FALSE; // assume we won't find what we are looking for. - - Assert(BURN_CACHE_ACTION_TYPE_ACQUIRE_CONTAINER == type || BURN_CACHE_ACTION_TYPE_EXTRACT_CONTAINER == type); - - iSearchStart = (BURN_PLAN_INVALID_ACTION_INDEX == iSearchStart) ? 0 : iSearchStart; - iSearchEnd = (BURN_PLAN_INVALID_ACTION_INDEX == iSearchEnd) ? pPlan->cCacheActions : iSearchEnd; + BURN_PAYLOAD* pPayload = pPayloadGroup->rgpPayloads[i]; - for (DWORD iSearch = iSearchStart; iSearch < iSearchEnd; ++iSearch) - { - BURN_CACHE_ACTION* pCacheAction = pPlan->rgCacheActions + iSearch; - if (pCacheAction->type == type && - ((BURN_CACHE_ACTION_TYPE_ACQUIRE_CONTAINER == pCacheAction->type && pCacheAction->resolveContainer.pContainer == pContainer) || - (BURN_CACHE_ACTION_TYPE_EXTRACT_CONTAINER == pCacheAction->type && pCacheAction->extractContainer.pContainer == pContainer))) + if (pPayload->pContainer && !pPayload->pContainer->fPlanned) { - if (ppCacheAction) - { - *ppCacheAction = pCacheAction; - } - - if (piCacheAction) - { - *piCacheAction = iSearch; - } - - fFound = TRUE; - break; + hr = PlanLayoutContainer(pPlan, pPayload->pContainer); + ExitOnFailure(hr, "Failed to plan container: %ls", pPayload->pContainer->sczId); } - } - - return fFound; -} -static HRESULT CreateContainerAcquireAndExtractAction( - __in BURN_PLAN* pPlan, - __in BURN_CONTAINER* pContainer, - __in DWORD iPackageStartAction, - __in BOOL fPayloadCached, - __out BURN_CACHE_ACTION** ppContainerExtractAction, - __out DWORD* piContainerTryAgainAction - ) -{ - HRESULT hr = S_OK; - DWORD iAcquireAction = BURN_PLAN_INVALID_ACTION_INDEX; - BURN_CACHE_ACTION* pContainerExtractAction = NULL; - DWORD iExtractAction = BURN_PLAN_INVALID_ACTION_INDEX; - DWORD iTryAgainAction = BURN_PLAN_INVALID_ACTION_INDEX; - LPWSTR sczContainerWorkingPath = NULL; - - // If the container is actually attached to the executable then we will not need an acquire - // container action. - if (!pContainer->fActuallyAttached) - { - BURN_CACHE_ACTION* pAcquireContainerAction = NULL; - - // If there is no plan to acquire the container then add acquire action since we - // can't extract stuff out of a container until we acquire the container. - if (!FindContainerCacheAction(BURN_CACHE_ACTION_TYPE_ACQUIRE_CONTAINER, pPlan, pContainer, iPackageStartAction, BURN_PLAN_INVALID_ACTION_INDEX, &pAcquireContainerAction, &iAcquireAction)) + if (!pPlan->sczLayoutDirectory || !pPayload->pContainer) { - hr = AddAcquireContainer(pPlan, pContainer, &pAcquireContainerAction, &iAcquireAction); - ExitOnFailure(hr, "Failed to append acquire container action to plan."); - - pAcquireContainerAction->fSkipUntilRetried = TRUE; // we'll start by assuming the acquire is not necessary and the fPayloadCached below will set us straight if wrong. + pPlan->qwCacheSizeTotal += 2 * pPayload->qwFileSize; } - Assert(BURN_PLAN_INVALID_ACTION_INDEX != iAcquireAction); - Assert(BURN_CACHE_ACTION_TYPE_ACQUIRE_CONTAINER == pAcquireContainerAction->type); - Assert(pContainer == pAcquireContainerAction->resolveContainer.pContainer); - } - - Assert((pContainer->fActuallyAttached && BURN_PLAN_INVALID_ACTION_INDEX == iAcquireAction) || - (!pContainer->fActuallyAttached && BURN_PLAN_INVALID_ACTION_INDEX != iAcquireAction)); - - // If we do not find an action for extracting payloads from this container, create it now. - if (!FindContainerCacheAction(BURN_CACHE_ACTION_TYPE_EXTRACT_CONTAINER, pPlan, pContainer, (BURN_PLAN_INVALID_ACTION_INDEX == iAcquireAction) ? iPackageStartAction : iAcquireAction, BURN_PLAN_INVALID_ACTION_INDEX, &pContainerExtractAction, &iExtractAction)) - { - // Attached containers that are actually attached use the executable path for their working path. - if (pContainer->fActuallyAttached) + if (!pPayload->sczUnverifiedPath) { - Assert(BURN_PLAN_INVALID_ACTION_INDEX == iAcquireAction); - - hr = PathForCurrentProcess(&sczContainerWorkingPath, NULL); - ExitOnFailure(hr, "Failed to get path for executing module as attached container working path."); + hr = CacheCalculatePayloadWorkingPath(pPlan->wzBundleId, pPayload, &pPayload->sczUnverifiedPath); + ExitOnFailure(hr, "Failed to calculate unverified path for payload."); } - else // use the acquired working path as the location of the container. - { - Assert(BURN_PLAN_INVALID_ACTION_INDEX != iAcquireAction); - - hr = StrAllocString(&sczContainerWorkingPath, pPlan->rgCacheActions[iAcquireAction].resolveContainer.sczUnverifiedPath, 0); - ExitOnFailure(hr, "Failed to copy container unverified path for cache action to extract container."); - } - - hr = AppendCacheAction(pPlan, &pContainerExtractAction); - ExitOnFailure(hr, "Failed to append cache action to extract payloads from container."); - - iExtractAction = pPlan->cCacheActions - 1; - - pContainerExtractAction->type = BURN_CACHE_ACTION_TYPE_EXTRACT_CONTAINER; - pContainerExtractAction->fSkipUntilRetried = pContainer->fActuallyAttached; // assume we can skip the extract engine when the container is already attached and the fPayloadCached below will set us straight if wrong. - pContainerExtractAction->extractContainer.pContainer = pContainer; - pContainerExtractAction->extractContainer.iSkipUntilAcquiredByAction = iAcquireAction; - pContainerExtractAction->extractContainer.sczContainerUnverifiedPath = sczContainerWorkingPath; - sczContainerWorkingPath = NULL; - } - - Assert(BURN_CACHE_ACTION_TYPE_EXTRACT_CONTAINER == pContainerExtractAction->type); - Assert(BURN_PLAN_INVALID_ACTION_INDEX != iExtractAction); - - // If there is an acquire action, that is our try again action. Otherwise, we'll use the extract action. - iTryAgainAction = (BURN_PLAN_INVALID_ACTION_INDEX != iAcquireAction) ? iAcquireAction : iExtractAction; - - // If the try again action thinks it can be skipped but the payload is not cached, - // ensure the action will not be skipped. - BURN_CACHE_ACTION* pTryAgainAction = pPlan->rgCacheActions + iTryAgainAction; - Assert((BURN_CACHE_ACTION_TYPE_ACQUIRE_CONTAINER == pTryAgainAction->type && pContainer == pTryAgainAction->resolveContainer.pContainer) || - (BURN_CACHE_ACTION_TYPE_EXTRACT_CONTAINER == pTryAgainAction->type && pContainer == pTryAgainAction->extractContainer.pContainer)); - if (pTryAgainAction->fSkipUntilRetried && !fPayloadCached) - { - pTryAgainAction->fSkipUntilRetried = FALSE; - } - - *ppContainerExtractAction = pContainerExtractAction; - *piContainerTryAgainAction = iTryAgainAction; - -LExit: - ReleaseStr(sczContainerWorkingPath); - - return hr; -} - -static HRESULT AddAcquireContainer( - __in BURN_PLAN* pPlan, - __in BURN_CONTAINER* pContainer, - __out_opt BURN_CACHE_ACTION** ppCacheAction, - __out_opt DWORD* piCacheAction - ) -{ - HRESULT hr = S_OK; - LPWSTR sczContainerWorkingPath = NULL; - BURN_CACHE_ACTION* pAcquireContainerAction = NULL; - BURN_CACHE_CONTAINER_PROGRESS* pContainerProgress = NULL; - - hr = CacheCalculateContainerWorkingPath(pPlan->wzBundleId, pContainer, &sczContainerWorkingPath); - ExitOnFailure(hr, "Failed to calculate unverified path for container."); - - hr = AppendCacheAction(pPlan, &pAcquireContainerAction); - ExitOnFailure(hr, "Failed to append acquire container action to plan."); - - hr = CreateContainerProgress(pPlan, pContainer, &pContainerProgress); - ExitOnFailure(hr, "Failed to create container progress."); - - pAcquireContainerAction->type = BURN_CACHE_ACTION_TYPE_ACQUIRE_CONTAINER; - pAcquireContainerAction->resolveContainer.pContainer = pContainer; - pAcquireContainerAction->resolveContainer.iProgress = pContainerProgress->iIndex; - pAcquireContainerAction->resolveContainer.sczUnverifiedPath = sczContainerWorkingPath; - sczContainerWorkingPath = NULL; - - if (ppCacheAction) - { - *ppCacheAction = pAcquireContainerAction; - } - - if (piCacheAction) - { - *piCacheAction = pPlan->cCacheActions - 1; } -LExit: - ReleaseStr(sczContainerWorkingPath); - - return hr; -} - -static HRESULT AddExtractPayload( - __in BURN_CACHE_ACTION* pCacheAction, - __in_opt BURN_PACKAGE* pPackage, - __in BURN_PAYLOAD* pPayload, - __in_z LPCWSTR wzPayloadWorkingPath - ) -{ - HRESULT hr = S_OK; - - Assert(BURN_CACHE_ACTION_TYPE_EXTRACT_CONTAINER == pCacheAction->type); - - hr = MemEnsureArraySize(reinterpret_cast(&pCacheAction->extractContainer.rgPayloads), pCacheAction->extractContainer.cPayloads + 1, sizeof(BURN_EXTRACT_PAYLOAD), 5); - ExitOnFailure(hr, "Failed to grow list of payloads to extract from container."); - - BURN_EXTRACT_PAYLOAD* pExtractPayload = pCacheAction->extractContainer.rgPayloads + pCacheAction->extractContainer.cPayloads; - pExtractPayload->pPackage = pPackage; - pExtractPayload->pPayload = pPayload; - hr = StrAllocString(&pExtractPayload->sczUnverifiedPath, wzPayloadWorkingPath, 0); - ExitOnFailure(hr, "Failed to copy unverified path for payload to extract."); - ++pCacheAction->extractContainer.cPayloads; - LExit: return hr; } -static BURN_CACHE_ACTION* ProcessSharedPayload( - __in BURN_PLAN* pPlan, - __in BURN_PAYLOAD* pPayload - ) -{ - BURN_CACHE_ACTION* pAcquireAction = NULL; -#ifdef DEBUG - DWORD cMove = 0; -#endif - - for (DWORD i = 0; i < pPlan->cCacheActions; ++i) - { - BURN_CACHE_ACTION* pCacheAction = pPlan->rgCacheActions + i; - - if (BURN_CACHE_ACTION_TYPE_ACQUIRE_PAYLOAD == pCacheAction->type && - pCacheAction->resolvePayload.pPayload == pPayload) - { - AssertSz(!pAcquireAction, "There should be at most one acquire cache action per payload."); - pAcquireAction = pCacheAction; - } - else if (BURN_CACHE_ACTION_TYPE_CACHE_PAYLOAD == pCacheAction->type && - pCacheAction->cachePayload.pPayload == pPayload && - pCacheAction->cachePayload.fMove) - { - // Since we found a shared payload, change its operation from MOVE to COPY. - pCacheAction->cachePayload.fMove = FALSE; - - AssertSz(1 == ++cMove, "Shared payload should be moved once and only once."); -#ifndef DEBUG - break; -#endif - } - else if (BURN_CACHE_ACTION_TYPE_LAYOUT_PAYLOAD == pCacheAction->type && - pCacheAction->layoutPayload.pPayload == pPayload && - pCacheAction->layoutPayload.fMove) - { - // Since we found a shared payload, change its operation from MOVE to COPY if necessary - pCacheAction->layoutPayload.fMove = FALSE; - - AssertSz(1 == ++cMove, "Shared payload should be moved once and only once."); -#ifndef DEBUG - break; -#endif - } - } - - return pAcquireAction; -} - static void RemoveUnnecessaryActions( __in BOOL fExecute, __in BURN_EXECUTE_ACTION* rgActions, @@ -2984,86 +2487,6 @@ static BOOL NeedsCache( } } -static HRESULT CreateContainerProgress( - __in BURN_PLAN* pPlan, - __in BURN_CONTAINER* pContainer, - __out BURN_CACHE_CONTAINER_PROGRESS** ppContainerProgress - ) -{ - HRESULT hr = S_OK; - BURN_CACHE_CONTAINER_PROGRESS* pContainerProgress = NULL; - - hr = MemEnsureArraySize(reinterpret_cast(&pPlan->rgContainerProgress), pPlan->cContainerProgress + 1, sizeof(BURN_CACHE_CONTAINER_PROGRESS), 5); - ExitOnFailure(hr, "Failed to grow container progress list."); - - if (!pPlan->shContainerProgress) - { - hr = DictCreateWithEmbeddedKey(&pPlan->shContainerProgress, 5, reinterpret_cast(&pPlan->rgContainerProgress), offsetof(BURN_CACHE_CONTAINER_PROGRESS, wzId), DICT_FLAG_NONE); - ExitOnFailure(hr, "Failed to create container progress dictionary."); - } - - hr = DictGetValue(pPlan->shContainerProgress, pContainer->sczId, reinterpret_cast(&pContainerProgress)); - if (E_NOTFOUND == hr) - { - pContainerProgress = &pPlan->rgContainerProgress[pPlan->cContainerProgress]; - pContainerProgress->iIndex = pPlan->cContainerProgress; - pContainerProgress->pContainer = pContainer; - pContainerProgress->wzId = pContainer->sczId; - - hr = DictAddValue(pPlan->shContainerProgress, pContainerProgress); - ExitOnFailure(hr, "Failed to add \"%ls\" to the container progress dictionary.", pContainerProgress->wzId); - - ++pPlan->cContainerProgress; - pPlan->qwCacheSizeTotal += pContainer->qwFileSize; - } - ExitOnFailure(hr, "Failed to retrieve \"%ls\" from the container progress dictionary.", pContainer->sczId); - - *ppContainerProgress = pContainerProgress; - -LExit: - return hr; -} - -static HRESULT CreatePayloadProgress( - __in BURN_PLAN* pPlan, - __in BURN_PAYLOAD* pPayload, - __out BURN_CACHE_PAYLOAD_PROGRESS** ppPayloadProgress - ) -{ - HRESULT hr = S_OK; - BURN_CACHE_PAYLOAD_PROGRESS* pPayloadProgress = NULL; - - hr = MemEnsureArraySize(reinterpret_cast(&pPlan->rgPayloadProgress), pPlan->cPayloadProgress + 1, sizeof(BURN_CACHE_PAYLOAD_PROGRESS), 5); - ExitOnFailure(hr, "Failed to grow payload progress list."); - - if (!pPlan->shPayloadProgress) - { - hr = DictCreateWithEmbeddedKey(&pPlan->shPayloadProgress, 5, reinterpret_cast(&pPlan->rgPayloadProgress), offsetof(BURN_CACHE_PAYLOAD_PROGRESS, wzId), DICT_FLAG_NONE); - ExitOnFailure(hr, "Failed to create payload progress dictionary."); - } - - hr = DictGetValue(pPlan->shPayloadProgress, pPayload->sczKey, reinterpret_cast(&pPayloadProgress)); - if (E_NOTFOUND == hr) - { - pPayloadProgress = &pPlan->rgPayloadProgress[pPlan->cPayloadProgress]; - pPayloadProgress->iIndex = pPlan->cPayloadProgress; - pPayloadProgress->pPayload = pPayload; - pPayloadProgress->wzId = pPayload->sczKey; - - hr = DictAddValue(pPlan->shPayloadProgress, pPayloadProgress); - ExitOnFailure(hr, "Failed to add \"%ls\" to the payload progress dictionary.", pPayloadProgress->wzId); - - ++pPlan->cPayloadProgress; - pPlan->qwCacheSizeTotal += pPayload->qwFileSize; - } - ExitOnFailure(hr, "Failed to retrieve \"%ls\" from the payload progress dictionary.", pPayload->sczKey); - - *ppPayloadProgress = pPayloadProgress; - -LExit: - return hr; -} - static void CacheActionLog( __in DWORD iAction, __in BURN_CACHE_ACTION* pAction, @@ -3073,60 +2496,28 @@ static void CacheActionLog( LPCWSTR wzBase = fRollback ? L" Rollback cache" : L" Cache"; switch (pAction->type) { - case BURN_CACHE_ACTION_TYPE_ACQUIRE_CONTAINER: - LogStringLine(PlanDumpLevel, "%ls action[%u]: ACQUIRE_CONTAINER id: %ls, source path: %ls, working path: %ls, skip until retried: %hs", wzBase, iAction, pAction->resolveContainer.pContainer->sczId, pAction->resolveContainer.pContainer->sczSourcePath, pAction->resolveContainer.sczUnverifiedPath, LoggingBoolToString(pAction->fSkipUntilRetried)); - break; - - case BURN_CACHE_ACTION_TYPE_ACQUIRE_PAYLOAD: - LogStringLine(PlanDumpLevel, "%ls action[%u]: ACQUIRE_PAYLOAD package id: %ls, payload id: %ls, source path: %ls, working path: %ls, skip until retried: %hs", wzBase, iAction, pAction->resolvePayload.pPackage ? pAction->resolvePayload.pPackage->sczId : L"", pAction->resolvePayload.pPayload->sczKey, pAction->resolvePayload.pPayload->sczSourcePath, pAction->resolvePayload.sczUnverifiedPath, LoggingBoolToString(pAction->fSkipUntilRetried)); - break; - - case BURN_CACHE_ACTION_TYPE_CACHE_PAYLOAD: - LogStringLine(PlanDumpLevel, "%ls action[%u]: CACHE_PAYLOAD package id: %ls, payload id: %ls, working path: %ls, operation: %ls, skip until retried: %hs, retry action: %u", wzBase, iAction, pAction->cachePayload.pPackage->sczId, pAction->cachePayload.pPayload->sczKey, pAction->cachePayload.sczUnverifiedPath, pAction->cachePayload.fMove ? L"move" : L"copy", LoggingBoolToString(pAction->fSkipUntilRetried), pAction->cachePayload.iTryAgainAction); - break; - case BURN_CACHE_ACTION_TYPE_CHECKPOINT: LogStringLine(PlanDumpLevel, "%ls action[%u]: CHECKPOINT id: %u", wzBase, iAction, pAction->checkpoint.dwId); break; - case BURN_CACHE_ACTION_TYPE_EXTRACT_CONTAINER: - LogStringLine(PlanDumpLevel, "%ls action[%u]: EXTRACT_CONTAINER id: %ls, working path: %ls, skip until retried: %hs, skip until acquired by action: %u", wzBase, iAction, pAction->extractContainer.pContainer->sczId, pAction->extractContainer.sczContainerUnverifiedPath, LoggingBoolToString(pAction->fSkipUntilRetried), pAction->extractContainer.iSkipUntilAcquiredByAction); - for (DWORD j = 0; j < pAction->extractContainer.cPayloads; j++) - { - LogStringLine(PlanDumpLevel, " extract package id: %ls, payload id: %ls, working path: %ls", pAction->extractContainer.rgPayloads[j].pPackage->sczId, pAction->extractContainer.rgPayloads[j].pPayload->sczKey, pAction->extractContainer.rgPayloads[j].sczUnverifiedPath); - } - break; - case BURN_CACHE_ACTION_TYPE_LAYOUT_BUNDLE: - LogStringLine(PlanDumpLevel, "%ls action[%u]: LAYOUT_BUNDLE working path: %ls, layout directory: %ls, exe name: %ls, skip until retried: %hs", wzBase, iAction, pAction->bundleLayout.sczUnverifiedPath, pAction->bundleLayout.sczLayoutDirectory, pAction->bundleLayout.sczExecutableName, LoggingBoolToString(pAction->fSkipUntilRetried)); - break; - - case BURN_CACHE_ACTION_TYPE_LAYOUT_CONTAINER: - LogStringLine(PlanDumpLevel, "%ls action[%u]: LAYOUT_CONTAINER package id: %ls, container id: %ls, working path: %ls, layout directory: %ls, operation: %ls, skip until retried: %hs, retry action: %u", wzBase, iAction, pAction->layoutContainer.pPackage ? pAction->layoutContainer.pPackage->sczId : L"", pAction->layoutContainer.pContainer->sczId, pAction->layoutContainer.sczUnverifiedPath, pAction->layoutContainer.sczLayoutDirectory, pAction->layoutContainer.fMove ? L"move" : L"copy", LoggingBoolToString(pAction->fSkipUntilRetried), pAction->layoutContainer.iTryAgainAction); - break; - - case BURN_CACHE_ACTION_TYPE_LAYOUT_PAYLOAD: - LogStringLine(PlanDumpLevel, "%ls action[%u]: LAYOUT_PAYLOAD package id: %ls, payload id: %ls, working path: %ls, layout directory: %ls, operation: %ls, skip until retried: %hs, retry action: %u", wzBase, iAction, pAction->layoutPayload.pPackage ? pAction->layoutPayload.pPackage->sczId : L"", pAction->layoutPayload.pPayload->sczKey, pAction->layoutPayload.sczUnverifiedPath, pAction->layoutPayload.sczLayoutDirectory, pAction->layoutPayload.fMove ? L"move" : L"copy", LoggingBoolToString(pAction->fSkipUntilRetried), pAction->layoutPayload.iTryAgainAction); + LogStringLine(PlanDumpLevel, "%ls action[%u]: LAYOUT_BUNDLE working path: %ls, exe name: %ls", wzBase, iAction, pAction->bundleLayout.sczUnverifiedPath, pAction->bundleLayout.sczExecutableName); break; - case BURN_CACHE_ACTION_TYPE_PACKAGE_START: - LogStringLine(PlanDumpLevel, "%ls action[%u]: PACKAGE_START id: %ls, plan index for skip: %u, payloads to cache: %u, bytes to cache: %llu, skip until retried: %hs", wzBase, iAction, pAction->packageStart.pPackage->sczId, pAction->packageStart.iPackageCompleteAction, pAction->packageStart.cCachePayloads, pAction->packageStart.qwCachePayloadSizeTotal, LoggingBoolToString(pAction->fSkipUntilRetried)); + case BURN_CACHE_ACTION_TYPE_CONTAINER: + LogStringLine(PlanDumpLevel, "%ls action[%u]: CONTAINER container id: %ls, working path: %ls", wzBase, iAction, pAction->container.pContainer->sczId, pAction->container.pContainer->sczUnverifiedPath); break; - case BURN_CACHE_ACTION_TYPE_PACKAGE_STOP: - LogStringLine(PlanDumpLevel, "%ls action[%u]: PACKAGE_STOP id: %ls, skip until retried: %hs", wzBase, iAction, pAction->packageStop.pPackage->sczId, LoggingBoolToString(pAction->fSkipUntilRetried)); + case BURN_CACHE_ACTION_TYPE_PACKAGE: + LogStringLine(PlanDumpLevel, "%ls action[%u]: PACKAGE id: %ls", wzBase, iAction, pAction->package.pPackage->sczId); break; case BURN_CACHE_ACTION_TYPE_ROLLBACK_PACKAGE: - LogStringLine(PlanDumpLevel, "%ls action[%u]: ROLLBACK_PACKAGE id: %ls, skip until retried: %hs", wzBase, iAction, pAction->rollbackPackage.pPackage->sczId, LoggingBoolToString(pAction->fSkipUntilRetried)); + LogStringLine(PlanDumpLevel, "%ls action[%u]: ROLLBACK_PACKAGE id: %ls", wzBase, iAction, pAction->rollbackPackage.pPackage->sczId); break; case BURN_CACHE_ACTION_TYPE_SIGNAL_SYNCPOINT: - LogStringLine(PlanDumpLevel, "%ls action[%u]: SIGNAL_SYNCPOINT event handle: 0x%p, skip until retried: %hs", wzBase, iAction, pAction->syncpoint.hEvent, LoggingBoolToString(pAction->fSkipUntilRetried)); - break; - - case BURN_CACHE_ACTION_TYPE_TRANSACTION_BOUNDARY: - LogStringLine(PlanDumpLevel, "%ls action[%u]: TRANSACTION_BOUNDARY id: %ls, event handle: 0x%p, vital: %ls, transaction: %ls", wzBase, iAction, pAction->rollbackBoundary.pRollbackBoundary->sczId, pAction->rollbackBoundary.hEvent, pAction->rollbackBoundary.pRollbackBoundary->fVital ? L"yes" : L"no", pAction->rollbackBoundary.pRollbackBoundary->fTransaction ? L"yes" : L"no"); + LogStringLine(PlanDumpLevel, "%ls action[%u]: SIGNAL_SYNCPOINT event handle: 0x%p", wzBase, iAction, pAction->syncpoint.hEvent); break; default: @@ -3222,6 +2613,10 @@ extern "C" void PlanDump( LogStringLine(PlanDumpLevel, " per-machine: %hs", LoggingTrueFalseToString(pPlan->fPerMachine)); LogStringLine(PlanDumpLevel, " disable-rollback: %hs", LoggingTrueFalseToString(pPlan->fDisableRollback)); LogStringLine(PlanDumpLevel, " estimated size: %llu", pPlan->qwEstimatedSize); + if (pPlan->sczLayoutDirectory) + { + LogStringLine(PlanDumpLevel, " layout directory: %ls", pPlan->sczLayoutDirectory); + } LogStringLine(PlanDumpLevel, "Plan cache size: %llu", pPlan->qwCacheSizeTotal); for (DWORD i = 0; i < pPlan->cCacheActions; ++i) diff --git a/src/engine/plan.h b/src/engine/plan.h index 0024b0aa..4ba2df6a 100644 --- a/src/engine/plan.h +++ b/src/engine/plan.h @@ -38,17 +38,10 @@ enum BURN_CACHE_ACTION_TYPE BURN_CACHE_ACTION_TYPE_NONE, BURN_CACHE_ACTION_TYPE_CHECKPOINT, BURN_CACHE_ACTION_TYPE_LAYOUT_BUNDLE, - BURN_CACHE_ACTION_TYPE_PACKAGE_START, - BURN_CACHE_ACTION_TYPE_PACKAGE_STOP, + BURN_CACHE_ACTION_TYPE_PACKAGE, BURN_CACHE_ACTION_TYPE_ROLLBACK_PACKAGE, BURN_CACHE_ACTION_TYPE_SIGNAL_SYNCPOINT, - BURN_CACHE_ACTION_TYPE_ACQUIRE_CONTAINER, - BURN_CACHE_ACTION_TYPE_EXTRACT_CONTAINER, - BURN_CACHE_ACTION_TYPE_LAYOUT_CONTAINER, - BURN_CACHE_ACTION_TYPE_ACQUIRE_PAYLOAD, - BURN_CACHE_ACTION_TYPE_CACHE_PAYLOAD, - BURN_CACHE_ACTION_TYPE_LAYOUT_PAYLOAD, - BURN_CACHE_ACTION_TYPE_TRANSACTION_BOUNDARY, + BURN_CACHE_ACTION_TYPE_CONTAINER, }; enum BURN_EXECUTE_ACTION_TYPE @@ -78,13 +71,6 @@ enum BURN_CLEAN_ACTION_TYPE // structs -typedef struct _BURN_EXTRACT_PAYLOAD -{ - BURN_PACKAGE* pPackage; - BURN_PAYLOAD* pPayload; - LPWSTR sczUnverifiedPath; -} BURN_EXTRACT_PAYLOAD; - typedef struct _BURN_DEPENDENT_REGISTRATION_ACTION { BURN_DEPENDENT_REGISTRATION_ACTION_TYPE type; @@ -111,7 +97,6 @@ typedef struct _BURN_CACHE_PAYLOAD_PROGRESS typedef struct _BURN_CACHE_ACTION { BURN_CACHE_ACTION_TYPE type; - BOOL fSkipUntilRetried; union { struct @@ -121,21 +106,14 @@ typedef struct _BURN_CACHE_ACTION struct { LPWSTR sczExecutableName; - LPWSTR sczLayoutDirectory; LPWSTR sczUnverifiedPath; DWORD64 qwBundleSize; + BURN_PAYLOAD_GROUP* pPayloadGroup; } bundleLayout; struct { BURN_PACKAGE* pPackage; - DWORD cCachePayloads; - DWORD64 qwCachePayloadSizeTotal; - DWORD iPackageCompleteAction; - } packageStart; - struct - { - BURN_PACKAGE* pPackage; - } packageStop; + } package; struct { BURN_PACKAGE* pPackage; @@ -147,62 +125,7 @@ typedef struct _BURN_CACHE_ACTION struct { BURN_CONTAINER* pContainer; - DWORD iProgress; - LPWSTR sczUnverifiedPath; - } resolveContainer; - struct - { - BURN_CONTAINER* pContainer; - DWORD iSkipUntilAcquiredByAction; - LPWSTR sczContainerUnverifiedPath; - - BURN_EXTRACT_PAYLOAD* rgPayloads; - DWORD cPayloads; - } extractContainer; - struct - { - BURN_PACKAGE* pPackage; - BURN_CONTAINER* pContainer; - DWORD iProgress; - DWORD iTryAgainAction; - DWORD cTryAgainAttempts; - LPWSTR sczLayoutDirectory; - LPWSTR sczUnverifiedPath; - BOOL fMove; - } layoutContainer; - struct - { - BURN_PACKAGE* pPackage; - BURN_PAYLOAD* pPayload; - DWORD iProgress; - LPWSTR sczUnverifiedPath; - } resolvePayload; - struct - { - BURN_PACKAGE* pPackage; - BURN_PAYLOAD* pPayload; - DWORD iProgress; - DWORD iTryAgainAction; - DWORD cTryAgainAttempts; - LPWSTR sczUnverifiedPath; - BOOL fMove; - } cachePayload; - struct - { - BURN_PACKAGE* pPackage; - BURN_PAYLOAD* pPayload; - DWORD iProgress; - DWORD iTryAgainAction; - DWORD cTryAgainAttempts; - LPWSTR sczLayoutDirectory; - LPWSTR sczUnverifiedPath; - BOOL fMove; - } layoutPayload; - struct - { - BURN_ROLLBACK_BOUNDARY* pRollbackBoundary; - HANDLE hEvent; - } rollbackBoundary; + } container; }; } BURN_CACHE_ACTION; @@ -306,6 +229,7 @@ typedef struct _BURN_CLEAN_ACTION typedef struct _BURN_PLAN { BOOTSTRAPPER_ACTION action; + BURN_PAYLOADS* pPayloads; // points directly into parent the ENGINE_STATE. LPWSTR wzBundleId; // points directly into parent the ENGINE_STATE. LPWSTR wzBundleProviderKey; // points directly into parent the ENGINE_STATE. BOOL fPerMachine; @@ -315,6 +239,7 @@ typedef struct _BURN_PLAN BOOL fDisableRollback; BOOL fAffectedMachineState; BOOL fIgnoreAllDependents; + LPWSTR sczLayoutDirectory; DWORD64 qwCacheSizeTotal; @@ -369,7 +294,9 @@ typedef struct _BURN_PLAN void PlanReset( __in BURN_PLAN* pPlan, - __in BURN_PACKAGES* pPackages + __in BURN_CONTAINERS* pContainers, + __in BURN_PACKAGES* pPackages, + __in BURN_PAYLOAD_GROUP* pLayoutPayloads ); void PlanUninitializeExecuteAction( __in BURN_EXECUTE_ACTION* pExecuteAction @@ -393,8 +320,7 @@ HRESULT PlanLayoutBundle( __in_z LPCWSTR wzExecutableName, __in DWORD64 qwBundleSize, __in BURN_VARIABLES* pVariables, - __in BURN_PAYLOADS* pPayloads, - __out_z LPWSTR* psczLayoutDirectory + __in BURN_PAYLOAD_GROUP* pLayoutPayloads ); HRESULT PlanForwardCompatibleBundles( __in BURN_USER_EXPERIENCE* pUX, @@ -410,8 +336,7 @@ HRESULT PlanPackages( __in BURN_LOGGING* pLog, __in BURN_VARIABLES* pVariables, __in BOOTSTRAPPER_DISPLAY display, - __in BOOTSTRAPPER_RELATION_TYPE relationType, - __in_z_opt LPCWSTR wzLayoutDirectory + __in BOOTSTRAPPER_RELATION_TYPE relationType ); HRESULT PlanRegistration( __in BURN_PLAN* pPlan, @@ -438,10 +363,13 @@ HRESULT PlanUpdateBundle( __in BOOTSTRAPPER_DISPLAY display, __in BOOTSTRAPPER_RELATION_TYPE relationType ); +HRESULT PlanLayoutContainer( + __in BURN_PLAN* pPlan, + __in BURN_CONTAINER* pContainer + ); HRESULT PlanLayoutPackage( __in BURN_PLAN* pPlan, - __in BURN_PACKAGE* pPackage, - __in_z_opt LPCWSTR wzLayoutDirectory + __in BURN_PACKAGE* pPackage ); HRESULT PlanExecutePackage( __in BOOL fPerMachine, diff --git a/src/engine/pseudobundle.cpp b/src/engine/pseudobundle.cpp index 73fbb019..db25096b 100644 --- a/src/engine/pseudobundle.cpp +++ b/src/engine/pseudobundle.cpp @@ -26,6 +26,7 @@ extern "C" HRESULT PseudoBundleInitialize( { HRESULT hr = S_OK; LPWSTR sczRelationTypeCommandLineSwitch = NULL; + BURN_PAYLOAD* pPayload = NULL; LPCWSTR wzRelationTypeCommandLine = CoreRelationTypeToCommandLineString(relationType); if (wzRelationTypeCommandLine) @@ -34,41 +35,40 @@ extern "C" HRESULT PseudoBundleInitialize( } // Initialize the single payload, and fill out all the necessary fields - pPackage->rgPayloads = (BURN_PACKAGE_PAYLOAD *)MemAlloc(sizeof(BURN_PACKAGE_PAYLOAD), TRUE); - ExitOnNull(pPackage->rgPayloads, hr, E_OUTOFMEMORY, "Failed to allocate space for burn package payload inside of related bundle struct"); - pPackage->cPayloads = 1; + pPackage->payloads.rgpPayloads = (BURN_PAYLOAD**)MemAlloc(sizeof(BURN_PAYLOAD*), TRUE); + ExitOnNull(pPackage->payloads.rgpPayloads, hr, E_OUTOFMEMORY, "Failed to allocate space for burn payload group inside of related bundle struct"); + pPackage->payloads.cPayloads = 1; - pPackage->rgPayloads->pPayload = (BURN_PAYLOAD *)MemAlloc(sizeof(BURN_PAYLOAD), TRUE); - ExitOnNull(pPackage->rgPayloads, hr, E_OUTOFMEMORY, "Failed to allocate space for burn payload inside of related bundle struct"); - pPackage->rgPayloads->pPayload->packaging = BURN_PAYLOAD_PACKAGING_EXTERNAL; - pPackage->rgPayloads->pPayload->qwFileSize = qwSize; + pPayload = (BURN_PAYLOAD*)MemAlloc(sizeof(BURN_PAYLOAD), TRUE); + ExitOnNull(pPayload, hr, E_OUTOFMEMORY, "Failed to allocate space for burn payload inside of related bundle struct"); + pPackage->payloads.rgpPayloads[0] = pPayload; + pPayload->packaging = BURN_PAYLOAD_PACKAGING_EXTERNAL; + pPayload->qwFileSize = qwSize; - hr = StrAllocString(&pPackage->rgPayloads->pPayload->sczKey, wzId, 0); + hr = StrAllocString(&pPayload->sczKey, wzId, 0); ExitOnFailure(hr, "Failed to copy key for pseudo bundle payload."); - hr = StrAllocString(&pPackage->rgPayloads->pPayload->sczFilePath, wzFilePath, 0); + hr = StrAllocString(&pPayload->sczFilePath, wzFilePath, 0); ExitOnFailure(hr, "Failed to copy filename for pseudo bundle."); - hr = StrAllocString(&pPackage->rgPayloads->pPayload->sczSourcePath, wzLocalSource, 0); + hr = StrAllocString(&pPayload->sczSourcePath, wzLocalSource, 0); ExitOnFailure(hr, "Failed to copy local source path for pseudo bundle."); if (wzDownloadSource && *wzDownloadSource) { - hr = StrAllocString(&pPackage->rgPayloads->pPayload->downloadSource.sczUrl, wzDownloadSource, 0); + hr = StrAllocString(&pPayload->downloadSource.sczUrl, wzDownloadSource, 0); ExitOnFailure(hr, "Failed to copy download source for pseudo bundle."); } if (pbHash) { - pPackage->rgPayloads->pPayload->pbHash = static_cast(MemAlloc(cbHash, FALSE)); - ExitOnNull(pPackage->rgPayloads->pPayload->pbHash, hr, E_OUTOFMEMORY, "Failed to allocate memory for pseudo bundle payload hash."); + pPayload->pbHash = static_cast(MemAlloc(cbHash, FALSE)); + ExitOnNull(pPayload->pbHash, hr, E_OUTOFMEMORY, "Failed to allocate memory for pseudo bundle payload hash."); - pPackage->rgPayloads->pPayload->cbHash = cbHash; - memcpy_s(pPackage->rgPayloads->pPayload->pbHash, pPackage->rgPayloads->pPayload->cbHash, pbHash, cbHash); + pPayload->cbHash = cbHash; + memcpy_s(pPayload->pbHash, pPayload->cbHash, pbHash, cbHash); } - pPackage->rgPayloads->fCached = fCached; - pPackage->Exe.fPseudoBundle = TRUE; pPackage->type = BURN_PACKAGE_TYPE_EXE; @@ -171,44 +171,13 @@ extern "C" HRESULT PseudoBundleInitializePassthrough( LPWSTR sczArguments = NULL; // Initialize the payloads, and copy the necessary fields. - pPassthroughPackage->rgPayloads = (BURN_PACKAGE_PAYLOAD *)MemAlloc(sizeof(BURN_PACKAGE_PAYLOAD) * pPackage->cPayloads, TRUE); - ExitOnNull(pPassthroughPackage->rgPayloads, hr, E_OUTOFMEMORY, "Failed to allocate space for burn package payload inside of passthrough bundle."); - pPassthroughPackage->cPayloads = pPackage->cPayloads; + pPassthroughPackage->payloads.rgpPayloads = (BURN_PAYLOAD**)MemAlloc(sizeof(BURN_PAYLOAD*) * pPackage->payloads.cPayloads, TRUE); + ExitOnNull(pPassthroughPackage->payloads.rgpPayloads, hr, E_OUTOFMEMORY, "Failed to allocate space for burn package payload inside of passthrough bundle."); + pPassthroughPackage->payloads.cPayloads = pPackage->payloads.cPayloads; - for (DWORD iPayload = 0; iPayload < pPackage->cPayloads; ++iPayload) + for (DWORD iPayload = 0; iPayload < pPackage->payloads.cPayloads; ++iPayload) { - BURN_PACKAGE_PAYLOAD* pPayload = pPackage->rgPayloads + iPayload; - - pPassthroughPackage->rgPayloads[iPayload].pPayload = (BURN_PAYLOAD *)MemAlloc(sizeof(BURN_PAYLOAD), TRUE); - ExitOnNull(pPassthroughPackage->rgPayloads[iPayload].pPayload, hr, E_OUTOFMEMORY, "Failed to allocate space for burn payload inside of related bundle struct"); - pPassthroughPackage->rgPayloads[iPayload].pPayload->packaging = pPayload->pPayload->packaging; - pPassthroughPackage->rgPayloads[iPayload].pPayload->qwFileSize = pPayload->pPayload->qwFileSize; - - hr = StrAllocString(&pPassthroughPackage->rgPayloads[iPayload].pPayload->sczKey, pPayload->pPayload->sczKey, 0); - ExitOnFailure(hr, "Failed to copy key for passthrough pseudo bundle payload."); - - hr = StrAllocString(&pPassthroughPackage->rgPayloads[iPayload].pPayload->sczFilePath, pPayload->pPayload->sczFilePath, 0); - ExitOnFailure(hr, "Failed to copy filename for passthrough pseudo bundle."); - - hr = StrAllocString(&pPassthroughPackage->rgPayloads[iPayload].pPayload->sczSourcePath, pPayload->pPayload->sczSourcePath, 0); - ExitOnFailure(hr, "Failed to copy local source path for passthrough pseudo bundle."); - - if (pPayload->pPayload->downloadSource.sczUrl) - { - hr = StrAllocString(&pPassthroughPackage->rgPayloads[iPayload].pPayload->downloadSource.sczUrl, pPayload->pPayload->downloadSource.sczUrl, 0); - ExitOnFailure(hr, "Failed to copy download source for passthrough pseudo bundle."); - } - - if (pPayload->pPayload->pbHash) - { - pPassthroughPackage->rgPayloads[iPayload].pPayload->pbHash = static_cast(MemAlloc(pPayload->pPayload->cbHash, FALSE)); - ExitOnNull(pPassthroughPackage->rgPayloads[iPayload].pPayload->pbHash, hr, E_OUTOFMEMORY, "Failed to allocate memory for pseudo bundle payload hash."); - - pPassthroughPackage->rgPayloads[iPayload].pPayload->cbHash = pPayload->pPayload->cbHash; - memcpy_s(pPassthroughPackage->rgPayloads[iPayload].pPayload->pbHash, pPassthroughPackage->rgPayloads[iPayload].pPayload->cbHash, pPayload->pPayload->pbHash, pPayload->pPayload->cbHash); - } - - pPassthroughPackage->rgPayloads[iPayload].fCached = pPayload->fCached; + pPassthroughPackage->payloads.rgpPayloads[iPayload] = pPackage->payloads.rgpPayloads[iPayload]; } pPassthroughPackage->Exe.fPseudoBundle = TRUE; diff --git a/src/engine/relatedbundle.cpp b/src/engine/relatedbundle.cpp index 6953c678..a79be020 100644 --- a/src/engine/relatedbundle.cpp +++ b/src/engine/relatedbundle.cpp @@ -80,7 +80,14 @@ extern "C" void RelatedBundlesUninitialize( { for (DWORD i = 0; i < pRelatedBundles->cRelatedBundles; ++i) { - PackageUninitialize(&pRelatedBundles->rgRelatedBundles[i].package); + BURN_PACKAGE* pPackage = &pRelatedBundles->rgRelatedBundles[i].package; + + for (DWORD j = 0; j < pPackage->payloads.cPayloads; ++j) + { + PayloadUninitialize(pPackage->payloads.rgpPayloads[j]); + } + + PackageUninitialize(pPackage); ReleaseStr(pRelatedBundles->rgRelatedBundles[i].sczTag); } diff --git a/src/engine/userexperience.cpp b/src/engine/userexperience.cpp index c1641675..b6bd65dc 100644 --- a/src/engine/userexperience.cpp +++ b/src/engine/userexperience.cpp @@ -62,7 +62,7 @@ extern "C" HRESULT UserExperienceParseFromXml( } // parse payloads - hr = PayloadsParseFromXml(&pUserExperience->payloads, NULL, pixnUserExperienceNode); + hr = PayloadsParseFromXml(&pUserExperience->payloads, NULL, NULL, pixnUserExperienceNode); ExitOnFailure(hr, "Failed to parse user experience payloads."); // make sure we have at least one payload diff --git a/src/test/BurnUnitTest/PlanTest.cpp b/src/test/BurnUnitTest/PlanTest.cpp index 2ebbca74..aa9deaf6 100644 --- a/src/test/BurnUnitTest/PlanTest.cpp +++ b/src/test/BurnUnitTest/PlanTest.cpp @@ -54,47 +54,30 @@ namespace Bootstrapper BOOL fRollback = FALSE; DWORD dwIndex = 0; - DWORD dwPackageStart = 0; ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 1); - dwPackageStart = ValidateCachePackageStart(pPlan, fRollback, dwIndex++, L"PackageA", 6, 2, 33743, FALSE); - ValidateCacheAcquireContainer(pPlan, fRollback, dwIndex++, L"WixAttachedContainer", FALSE); - ValidateCacheExtractContainer(pPlan, fRollback, dwIndex++, L"WixAttachedContainer", FALSE, dwPackageStart, 6); - ValidateCacheCachePayload(pPlan, fRollback, dwIndex++, L"PackageA", L"PackageA", TRUE, FALSE, dwPackageStart); - ValidateCacheCachePayload(pPlan, fRollback, dwIndex++, L"PackageA", L"cab9Ins_fTP3wNwq5Gxo41ch5VUPaQ", TRUE, FALSE, dwPackageStart); - ValidateCachePackageStop(pPlan, fRollback, dwIndex++, L"PackageA", FALSE); - ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++, FALSE); + ValidateCachePackage(pPlan, fRollback, dwIndex++, L"PackageA"); + ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++); ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 9); - dwPackageStart = ValidateCachePackageStart(pPlan, fRollback, dwIndex++, L"PackageB", 14, 2, 33743, FALSE); - ValidateCacheAcquireContainer(pPlan, fRollback, dwIndex++, L"WixAttachedContainer", TRUE); - ValidateCacheExtractContainer(pPlan, fRollback, dwIndex++, L"WixAttachedContainer", FALSE, dwPackageStart, 2); - ValidateCacheCachePayload(pPlan, fRollback, dwIndex++, L"PackageB", L"PackageB", TRUE, FALSE, dwPackageStart); - ValidateCacheCachePayload(pPlan, fRollback, dwIndex++, L"PackageB", L"cablKtJUKxAbhSMIBwQU6vJ_CDsIkE", TRUE, FALSE, dwPackageStart); - ValidateCachePackageStop(pPlan, fRollback, dwIndex++, L"PackageB", FALSE); - ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++, FALSE); + ValidateCachePackage(pPlan, fRollback, dwIndex++, L"PackageB"); + ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++); ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 14); - dwPackageStart = ValidateCachePackageStart(pPlan, fRollback, dwIndex++, L"PackageC", 22, 2, 33743, FALSE); - ValidateCacheAcquireContainer(pPlan, fRollback, dwIndex++, L"WixAttachedContainer", TRUE); - ValidateCacheExtractContainer(pPlan, fRollback, dwIndex++, L"WixAttachedContainer", FALSE, dwPackageStart, 2); - ValidateCacheCachePayload(pPlan, fRollback, dwIndex++, L"PackageC", L"PackageC", TRUE, FALSE, dwPackageStart); - ValidateCacheCachePayload(pPlan, fRollback, dwIndex++, L"PackageC", L"cab3wekki1le1R8RPDV2B8_g8jcjZc", TRUE, FALSE, dwPackageStart); - ValidateCachePackageStop(pPlan, fRollback, dwIndex++, L"PackageC", FALSE); - ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++, FALSE); - Assert::Equal(24ul, pPlan->cCacheActions); + ValidateCachePackage(pPlan, fRollback, dwIndex++, L"PackageC"); + ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++); + Assert::Equal(dwIndex, pPlan->cCacheActions); fRollback = TRUE; dwIndex = 0; ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 1); - ValidateCacheRollbackPackage(pPlan, fRollback, dwIndex++, L"PackageA", FALSE); Assert::Equal(dwIndex, pPlan->cRollbackCacheActions); Assert::Equal(107082ull, pPlan->qwEstimatedSize); - Assert::Equal(101229ull, pPlan->qwCacheSizeTotal); + Assert::Equal(202458ull, pPlan->qwCacheSizeTotal); fRollback = FALSE; dwIndex = 0; DWORD dwExecuteCheckpointId = 2; ValidateExecuteRollbackBoundary(pPlan, fRollback, dwIndex++, L"WixDefaultBoundary", TRUE, FALSE); - ValidateExecuteWaitSyncpoint(pPlan, fRollback, dwIndex++, pPlan->rgCacheActions[7].syncpoint.hEvent); + ValidateExecuteWaitSyncpoint(pPlan, fRollback, dwIndex++, pPlan->rgCacheActions[2].syncpoint.hEvent); ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageA", BURN_DEPENDENCY_ACTION_REGISTER); @@ -107,7 +90,7 @@ namespace Bootstrapper ValidateExecuteRollbackBoundary(pPlan, fRollback, dwIndex++, L"rbaOCA08D8ky7uBOK71_6FWz1K3TuQ", TRUE, TRUE); ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); ValidateExecuteBeginMsiTransaction(pPlan, fRollback, dwIndex++, L"rbaOCA08D8ky7uBOK71_6FWz1K3TuQ"); - ValidateExecuteWaitSyncpoint(pPlan, fRollback, dwIndex++, pPlan->rgCacheActions[15].syncpoint.hEvent); + ValidateExecuteWaitSyncpoint(pPlan, fRollback, dwIndex++, pPlan->rgCacheActions[5].syncpoint.hEvent); dwExecuteCheckpointId += 1; // cache checkpoints ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); @@ -116,7 +99,7 @@ namespace Bootstrapper ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageB", L"{E6469F05-BDC8-4EB8-B218-67412543EFAA}", BURN_DEPENDENCY_ACTION_REGISTER); ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); - ValidateExecuteWaitSyncpoint(pPlan, fRollback, dwIndex++, pPlan->rgCacheActions[23].syncpoint.hEvent); + ValidateExecuteWaitSyncpoint(pPlan, fRollback, dwIndex++, pPlan->rgCacheActions[8].syncpoint.hEvent); dwExecuteCheckpointId += 1; // cache checkpoints ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); @@ -314,30 +297,24 @@ namespace Bootstrapper BOOL fRollback = FALSE; DWORD dwIndex = 0; - DWORD dwPackageStart = 0; ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 1); - dwPackageStart = ValidateCachePackageStart(pPlan, fRollback, dwIndex++, L"PackageA", 5, 2, 33743, FALSE); - ValidateCacheExtractContainer(pPlan, fRollback, dwIndex++, L"WixAttachedContainer", FALSE, BURN_PLAN_INVALID_ACTION_INDEX, 2); - ValidateCacheCachePayload(pPlan, fRollback, dwIndex++, L"PackageA", L"PackageA", TRUE, FALSE, dwPackageStart); - ValidateCacheCachePayload(pPlan, fRollback, dwIndex++, L"PackageA", L"cab9Ins_fTP3wNwq5Gxo41ch5VUPaQ", TRUE, FALSE, dwPackageStart); - ValidateCachePackageStop(pPlan, fRollback, dwIndex++, L"PackageA", FALSE); - ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++, FALSE); + ValidateCachePackage(pPlan, fRollback, dwIndex++, L"PackageA"); + ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++); Assert::Equal(dwIndex, pPlan->cCacheActions); fRollback = TRUE; dwIndex = 0; ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 1); - ValidateCacheRollbackPackage(pPlan, fRollback, dwIndex++, L"PackageA", FALSE); Assert::Equal(dwIndex, pPlan->cRollbackCacheActions); Assert::Equal(35694ull, pPlan->qwEstimatedSize); - Assert::Equal(33743ull, pPlan->qwCacheSizeTotal); + Assert::Equal(67486ull, pPlan->qwCacheSizeTotal); fRollback = FALSE; dwIndex = 0; DWORD dwExecuteCheckpointId = 2; ValidateExecuteRollbackBoundary(pPlan, fRollback, dwIndex++, L"WixDefaultBoundary", TRUE, FALSE); - ValidateExecuteWaitSyncpoint(pPlan, fRollback, dwIndex++, pPlan->rgCacheActions[6].syncpoint.hEvent); + ValidateExecuteWaitSyncpoint(pPlan, fRollback, dwIndex++, pPlan->rgCacheActions[2].syncpoint.hEvent); ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageA", BURN_DEPENDENCY_ACTION_REGISTER); @@ -401,14 +378,9 @@ namespace Bootstrapper BOOL fRollback = FALSE; DWORD dwIndex = 0; - DWORD dwPackageStart = 0; ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 1); - dwPackageStart = ValidateCachePackageStart(pPlan, fRollback, dwIndex++, L"PackageA", 5, 2, 33743, FALSE); - ValidateCacheExtractContainer(pPlan, fRollback, dwIndex++, L"WixAttachedContainer", FALSE, BURN_PLAN_INVALID_ACTION_INDEX, 2); - ValidateCacheCachePayload(pPlan, fRollback, dwIndex++, L"PackageA", L"PackageA", TRUE, FALSE, dwPackageStart); - ValidateCacheCachePayload(pPlan, fRollback, dwIndex++, L"PackageA", L"cab9Ins_fTP3wNwq5Gxo41ch5VUPaQ", TRUE, FALSE, dwPackageStart); - ValidateCachePackageStop(pPlan, fRollback, dwIndex++, L"PackageA", FALSE); - ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++, FALSE); + ValidateCachePackage(pPlan, fRollback, dwIndex++, L"PackageA"); + ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++); Assert::Equal(dwIndex, pPlan->cCacheActions); fRollback = TRUE; @@ -416,13 +388,13 @@ namespace Bootstrapper Assert::Equal(dwIndex, pPlan->cRollbackCacheActions); Assert::Equal(33743ull, pPlan->qwEstimatedSize); - Assert::Equal(33743ull, pPlan->qwCacheSizeTotal); + Assert::Equal(67486ull, pPlan->qwCacheSizeTotal); fRollback = FALSE; dwIndex = 0; DWORD dwExecuteCheckpointId = 2; ValidateExecuteRollbackBoundary(pPlan, fRollback, dwIndex++, L"WixDefaultBoundary", TRUE, FALSE); - ValidateExecuteWaitSyncpoint(pPlan, fRollback, dwIndex++, pPlan->rgCacheActions[6].syncpoint.hEvent); + ValidateExecuteWaitSyncpoint(pPlan, fRollback, dwIndex++, pPlan->rgCacheActions[2].syncpoint.hEvent); ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); @@ -475,30 +447,24 @@ namespace Bootstrapper BOOL fRollback = FALSE; DWORD dwIndex = 0; - DWORD dwPackageStart = 0; ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 1); - dwPackageStart = ValidateCachePackageStart(pPlan, fRollback, dwIndex++, L"PackageA", 5, 2, 33743, FALSE); - ValidateCacheExtractContainer(pPlan, fRollback, dwIndex++, L"WixAttachedContainer", FALSE, BURN_PLAN_INVALID_ACTION_INDEX, 2); - ValidateCacheCachePayload(pPlan, fRollback, dwIndex++, L"PackageA", L"PackageA", TRUE, FALSE, dwPackageStart); - ValidateCacheCachePayload(pPlan, fRollback, dwIndex++, L"PackageA", L"cab9Ins_fTP3wNwq5Gxo41ch5VUPaQ", TRUE, FALSE, dwPackageStart); - ValidateCachePackageStop(pPlan, fRollback, dwIndex++, L"PackageA", FALSE); - ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++, FALSE); + ValidateCachePackage(pPlan, fRollback, dwIndex++, L"PackageA"); + ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++); Assert::Equal(dwIndex, pPlan->cCacheActions); fRollback = TRUE; dwIndex = 0; ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 1); - ValidateCacheRollbackPackage(pPlan, fRollback, dwIndex++, L"PackageA", FALSE); Assert::Equal(dwIndex, pPlan->cRollbackCacheActions); Assert::Equal(35694ull, pPlan->qwEstimatedSize); - Assert::Equal(33743ull, pPlan->qwCacheSizeTotal); + Assert::Equal(67486ull, pPlan->qwCacheSizeTotal); fRollback = FALSE; dwIndex = 0; DWORD dwExecuteCheckpointId = 2; ValidateExecuteRollbackBoundary(pPlan, fRollback, dwIndex++, L"WixDefaultBoundary", TRUE, FALSE); - ValidateExecuteWaitSyncpoint(pPlan, fRollback, dwIndex++, pPlan->rgCacheActions[6].syncpoint.hEvent); + ValidateExecuteWaitSyncpoint(pPlan, fRollback, dwIndex++, pPlan->rgCacheActions[2].syncpoint.hEvent); ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageA", BURN_DEPENDENCY_ACTION_REGISTER); @@ -759,36 +725,28 @@ namespace Bootstrapper BOOL fRollback = FALSE; DWORD dwIndex = 0; - DWORD dwPackageStart = 0; ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 1); - dwPackageStart = ValidateCachePackageStart(pPlan, fRollback, dwIndex++, L"PatchA", 4, 1, 20480, FALSE); - ValidateCacheAcquirePayload(pPlan, fRollback, dwIndex++, L"PatchA", L"PatchA", FALSE); - ValidateCacheCachePayload(pPlan, fRollback, dwIndex++, L"PatchA", L"PatchA", TRUE, FALSE, dwPackageStart); - ValidateCachePackageStop(pPlan, fRollback, dwIndex++, L"PatchA", FALSE); - ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++, FALSE); + ValidateCachePackage(pPlan, fRollback, dwIndex++, L"PatchA"); + ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++); ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 2); - dwPackageStart = ValidateCachePackageStart(pPlan, fRollback, dwIndex++, L"PackageA", 10, 1, 32768, FALSE); - ValidateCacheAcquirePayload(pPlan, fRollback, dwIndex++, L"PackageA", L"PackageA", FALSE); - ValidateCacheCachePayload(pPlan, fRollback, dwIndex++, L"PackageA", L"PackageA", TRUE, FALSE, dwPackageStart); - ValidateCachePackageStop(pPlan, fRollback, dwIndex++, L"PackageA", FALSE); - ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++, FALSE); + ValidateCachePackage(pPlan, fRollback, dwIndex++, L"PackageA"); + ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++); Assert::Equal(dwIndex, pPlan->cCacheActions); fRollback = TRUE; dwIndex = 0; ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 2); - ValidateCacheRollbackPackage(pPlan, fRollback, dwIndex++, L"PackageA", FALSE); Assert::Equal(dwIndex, pPlan->cRollbackCacheActions); Assert::Equal(3055111ull, pPlan->qwEstimatedSize); - Assert::Equal(53248ull, pPlan->qwCacheSizeTotal); + Assert::Equal(106496ull, pPlan->qwCacheSizeTotal); fRollback = FALSE; dwIndex = 0; DWORD dwExecuteCheckpointId = 3; BURN_EXECUTE_ACTION* pExecuteAction = NULL; ValidateExecuteRollbackBoundary(pPlan, fRollback, dwIndex++, L"WixDefaultBoundary", TRUE, FALSE); - ValidateExecuteWaitSyncpoint(pPlan, fRollback, dwIndex++, pPlan->rgCacheActions[11].syncpoint.hEvent); + ValidateExecuteWaitSyncpoint(pPlan, fRollback, dwIndex++, pPlan->rgCacheActions[5].syncpoint.hEvent); ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageA", BURN_DEPENDENCY_ACTION_REGISTER); @@ -797,7 +755,7 @@ namespace Bootstrapper ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageA", L"{22D1DDBA-284D-40A7-BD14-95EA07906F21}", BURN_DEPENDENCY_ACTION_REGISTER); ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); - ValidateExecuteWaitSyncpoint(pPlan, fRollback, dwIndex++, pPlan->rgCacheActions[5].syncpoint.hEvent); + ValidateExecuteWaitSyncpoint(pPlan, fRollback, dwIndex++, pPlan->rgCacheActions[2].syncpoint.hEvent); ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PatchA", BURN_DEPENDENCY_ACTION_REGISTER); @@ -983,7 +941,7 @@ namespace Bootstrapper BURN_REGISTRATION* pRegistration = &pEngineState->registration; DetectReset(pRegistration, &pEngineState->packages); - PlanReset(&pEngineState->plan, &pEngineState->packages); + PlanReset(&pEngineState->plan, &pEngineState->containers, &pEngineState->packages, &pEngineState->layoutPayloads); hr = DepDependencyArrayAlloc(&pRegistration->rgIgnoredDependencies, &pRegistration->cIgnoredDependencies, pRegistration->sczProviderKey, NULL); NativeAssert::Succeeded(hr, "Failed to add the bundle provider key to the list of dependencies to ignore."); @@ -1047,11 +1005,6 @@ namespace Bootstrapper pPackage->cacheRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_PRESENT; pPackage->installRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_PRESENT; } - - for (DWORD i = 0; i < pPackage->cPayloads; ++i) - { - pPackage->rgPayloads[i].fCached = TRUE; - } } void DetectPackageDependent(BURN_PACKAGE* pPackage, LPCWSTR wzId) @@ -1186,34 +1139,16 @@ namespace Bootstrapper } } - void ValidateCacheAcquireContainer( - __in BURN_PLAN* pPlan, - __in BOOL fRollback, - __in DWORD dwIndex, - __in LPCWSTR wzContainerId, - __in BOOL fSkipUntilRetried - ) - { - BURN_CACHE_ACTION* pAction = ValidateCacheActionExists(pPlan, fRollback, dwIndex); - Assert::Equal(BURN_CACHE_ACTION_TYPE_ACQUIRE_CONTAINER, pAction->type); - NativeAssert::StringEqual(wzContainerId, pAction->resolveContainer.pContainer->sczId); - Assert::Equal(fSkipUntilRetried, pAction->fSkipUntilRetried); - } - - void ValidateCacheAcquirePayload( + void ValidateCacheContainer( __in BURN_PLAN* pPlan, __in BOOL fRollback, __in DWORD dwIndex, - __in LPCWSTR wzPackageId, - __in LPCWSTR wzPayloadId, - __in BOOL fSkipUntilRetried + __in LPCWSTR wzContainerId ) { BURN_CACHE_ACTION* pAction = ValidateCacheActionExists(pPlan, fRollback, dwIndex); - Assert::Equal(BURN_CACHE_ACTION_TYPE_ACQUIRE_PAYLOAD, pAction->type); - NativeAssert::StringEqual(wzPackageId, pAction->resolvePayload.pPackage->sczId); - NativeAssert::StringEqual(wzPayloadId, pAction->resolvePayload.pPayload->sczKey); - Assert::Equal(fSkipUntilRetried, pAction->fSkipUntilRetried); + Assert::Equal(BURN_CACHE_ACTION_TYPE_CONTAINER, pAction->type); + NativeAssert::StringEqual(wzContainerId, pAction->container.pContainer->sczId); } BURN_CACHE_ACTION* ValidateCacheActionExists(BURN_PLAN* pPlan, BOOL fRollback, DWORD dwIndex) @@ -1222,26 +1157,6 @@ namespace Bootstrapper return (fRollback ? pPlan->rgRollbackCacheActions : pPlan->rgCacheActions) + dwIndex; } - void ValidateCacheCachePayload( - __in BURN_PLAN* pPlan, - __in BOOL fRollback, - __in DWORD dwIndex, - __in LPCWSTR wzPackageId, - __in LPCWSTR wzPayloadId, - __in BOOL fMove, - __in BOOL fSkipUntilRetried, - __in DWORD iTryAgainAction - ) - { - BURN_CACHE_ACTION* pAction = ValidateCacheActionExists(pPlan, fRollback, dwIndex); - Assert::Equal(BURN_CACHE_ACTION_TYPE_CACHE_PAYLOAD, pAction->type); - NativeAssert::StringEqual(wzPackageId, pAction->cachePayload.pPackage->sczId); - NativeAssert::StringEqual(wzPayloadId, pAction->cachePayload.pPayload->sczKey); - Assert::Equal(fMove, pAction->cachePayload.fMove); - Assert::Equal(fSkipUntilRetried, pAction->fSkipUntilRetried); - Assert::Equal(iTryAgainAction, pAction->cachePayload.iTryAgainAction); - } - void ValidateCacheCheckpoint( __in BURN_PLAN* pPlan, __in BOOL fRollback, @@ -1254,84 +1169,40 @@ namespace Bootstrapper Assert::Equal(dwId, pAction->checkpoint.dwId); } - void ValidateCacheExtractContainer( - __in BURN_PLAN* pPlan, - __in BOOL fRollback, - __in DWORD dwIndex, - __in LPCWSTR wzContainerId, - __in BOOL fSkipUntilRetried, - __in DWORD iSkipUntilAcquiredByAction, - __in DWORD cPayloads - ) - { - BURN_CACHE_ACTION* pAction = ValidateCacheActionExists(pPlan, fRollback, dwIndex); - Assert::Equal(BURN_CACHE_ACTION_TYPE_EXTRACT_CONTAINER, pAction->type); - NativeAssert::StringEqual(wzContainerId, pAction->extractContainer.pContainer->sczId); - Assert::Equal(fSkipUntilRetried, pAction->fSkipUntilRetried); - Assert::Equal(iSkipUntilAcquiredByAction, pAction->extractContainer.iSkipUntilAcquiredByAction); - Assert::Equal(cPayloads, pAction->extractContainer.cPayloads); - } - - DWORD ValidateCachePackageStart( + DWORD ValidateCachePackage( __in BURN_PLAN* pPlan, __in BOOL fRollback, __in DWORD dwIndex, - __in LPCWSTR wzPackageId, - __in DWORD iPackageCompleteAction, - __in DWORD cCachePayloads, - __in DWORD64 qwCachePayloadSizeTotal, - __in BOOL fSkipUntilRetried + __in LPCWSTR wzPackageId ) { BURN_CACHE_ACTION* pAction = ValidateCacheActionExists(pPlan, fRollback, dwIndex); - Assert::Equal(BURN_CACHE_ACTION_TYPE_PACKAGE_START, pAction->type); - NativeAssert::StringEqual(wzPackageId, pAction->packageStart.pPackage->sczId); - Assert::Equal(iPackageCompleteAction, pAction->packageStart.iPackageCompleteAction); - Assert::Equal(cCachePayloads, pAction->packageStart.cCachePayloads); - Assert::Equal(qwCachePayloadSizeTotal, pAction->packageStart.qwCachePayloadSizeTotal); - Assert::Equal(fSkipUntilRetried, pAction->fSkipUntilRetried); + Assert::Equal(BURN_CACHE_ACTION_TYPE_PACKAGE, pAction->type); + NativeAssert::StringEqual(wzPackageId, pAction->package.pPackage->sczId); return dwIndex + 1; } - void ValidateCachePackageStop( - __in BURN_PLAN* pPlan, - __in BOOL fRollback, - __in DWORD dwIndex, - __in LPCWSTR wzPackageId, - __in BOOL fSkipUntilRetried - ) - { - BURN_CACHE_ACTION* pAction = ValidateCacheActionExists(pPlan, fRollback, dwIndex); - Assert::Equal(BURN_CACHE_ACTION_TYPE_PACKAGE_STOP, pAction->type); - NativeAssert::StringEqual(wzPackageId, pAction->packageStop.pPackage->sczId); - Assert::Equal(fSkipUntilRetried, pAction->fSkipUntilRetried); - } - void ValidateCacheRollbackPackage( __in BURN_PLAN* pPlan, __in BOOL fRollback, __in DWORD dwIndex, - __in LPCWSTR wzPackageId, - __in BOOL fSkipUntilRetried + __in LPCWSTR wzPackageId ) { BURN_CACHE_ACTION* pAction = ValidateCacheActionExists(pPlan, fRollback, dwIndex); Assert::Equal(BURN_CACHE_ACTION_TYPE_ROLLBACK_PACKAGE, pAction->type); NativeAssert::StringEqual(wzPackageId, pAction->rollbackPackage.pPackage->sczId); - Assert::Equal(fSkipUntilRetried, pAction->fSkipUntilRetried); } void ValidateCacheSignalSyncpoint( __in BURN_PLAN* pPlan, __in BOOL fRollback, - __in DWORD dwIndex, - __in BOOL fSkipUntilRetried + __in DWORD dwIndex ) { BURN_CACHE_ACTION* pAction = ValidateCacheActionExists(pPlan, fRollback, dwIndex); Assert::Equal(BURN_CACHE_ACTION_TYPE_SIGNAL_SYNCPOINT, pAction->type); Assert::NotEqual((DWORD_PTR)NULL, (DWORD_PTR)pAction->syncpoint.hEvent); - Assert::Equal(fSkipUntilRetried, pAction->fSkipUntilRetried); } void ValidateCleanAction( -- cgit v1.2.3-55-g6feb