diff options
| author | Sean Hall <r.sean.hall@gmail.com> | 2021-04-16 10:09:26 -0500 |
|---|---|---|
| committer | Sean Hall <r.sean.hall@gmail.com> | 2021-04-19 23:12:55 -0500 |
| commit | 90cdf39e6e6b7d676ca33bee031fa2b865bb5fbd (patch) | |
| tree | 901feb035d5ea9a13f306582cedd6668b539953f /src/engine/plan.cpp | |
| parent | c88806b89293f5bb92c42e90230e48be6b79b7f4 (diff) | |
| download | wix-90cdf39e6e6b7d676ca33bee031fa2b865bb5fbd.tar.gz wix-90cdf39e6e6b7d676ca33bee031fa2b865bb5fbd.tar.bz2 wix-90cdf39e6e6b7d676ca33bee031fa2b865bb5fbd.zip | |
Don't plan payloads.
Contributes to #3640 and #5253
Diffstat (limited to 'src/engine/plan.cpp')
| -rw-r--r-- | src/engine/plan.cpp | 893 |
1 files changed, 144 insertions, 749 deletions
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( | |||
| 15 | static void UninitializeCacheAction( | 15 | static void UninitializeCacheAction( |
| 16 | __in BURN_CACHE_ACTION* pCacheAction | 16 | __in BURN_CACHE_ACTION* pCacheAction |
| 17 | ); | 17 | ); |
| 18 | static void ResetPlannedContainerState( | ||
| 19 | __in BURN_CONTAINER* pContainer | ||
| 20 | ); | ||
| 21 | static void ResetPlannedPayloadsState( | ||
| 22 | __in BURN_PAYLOADS* pPayloads | ||
| 23 | ); | ||
| 24 | static void ResetPlannedPayloadGroupState( | ||
| 25 | __in BURN_PAYLOAD_GROUP* pPayloadGroup | ||
| 26 | ); | ||
| 18 | static void ResetPlannedPackageState( | 27 | static void ResetPlannedPackageState( |
| 19 | __in BURN_PACKAGE* pPackage | 28 | __in BURN_PACKAGE* pPackage |
| 20 | ); | 29 | ); |
| @@ -30,8 +39,7 @@ static HRESULT PlanPackagesHelper( | |||
| 30 | __in BURN_LOGGING* pLog, | 39 | __in BURN_LOGGING* pLog, |
| 31 | __in BURN_VARIABLES* pVariables, | 40 | __in BURN_VARIABLES* pVariables, |
| 32 | __in BOOTSTRAPPER_DISPLAY display, | 41 | __in BOOTSTRAPPER_DISPLAY display, |
| 33 | __in BOOTSTRAPPER_RELATION_TYPE relationType, | 42 | __in BOOTSTRAPPER_RELATION_TYPE relationType |
| 34 | __in_z_opt LPCWSTR wzLayoutDirectory | ||
| 35 | ); | 43 | ); |
| 36 | static HRESULT InitializePackage( | 44 | static HRESULT InitializePackage( |
| 37 | __in BURN_PLAN* pPlan, | 45 | __in BURN_PLAN* pPlan, |
| @@ -48,7 +56,6 @@ static HRESULT ProcessPackage( | |||
| 48 | __in BURN_LOGGING* pLog, | 56 | __in BURN_LOGGING* pLog, |
| 49 | __in BURN_VARIABLES* pVariables, | 57 | __in BURN_VARIABLES* pVariables, |
| 50 | __in BOOTSTRAPPER_DISPLAY display, | 58 | __in BOOTSTRAPPER_DISPLAY display, |
| 51 | __in_z_opt LPCWSTR wzLayoutDirectory, | ||
| 52 | __inout HANDLE* phSyncpointEvent, | 59 | __inout HANDLE* phSyncpointEvent, |
| 53 | __inout BURN_ROLLBACK_BOUNDARY** ppRollbackBoundary | 60 | __inout BURN_ROLLBACK_BOUNDARY** ppRollbackBoundary |
| 54 | ); | 61 | ); |
| @@ -99,54 +106,9 @@ static HRESULT AppendRollbackCacheAction( | |||
| 99 | __in BURN_PLAN* pPlan, | 106 | __in BURN_PLAN* pPlan, |
| 100 | __out BURN_CACHE_ACTION** ppCacheAction | 107 | __out BURN_CACHE_ACTION** ppCacheAction |
| 101 | ); | 108 | ); |
| 102 | static HRESULT AppendLayoutContainerAction( | 109 | static HRESULT ProcessPayloadGroup( |
| 103 | __in BURN_PLAN* pPlan, | ||
| 104 | __in_opt BURN_PACKAGE* pPackage, | ||
| 105 | __in DWORD iPackageStartAction, | ||
| 106 | __in BURN_CONTAINER* pContainer, | ||
| 107 | __in BOOL fContainerCached, | ||
| 108 | __in_z LPCWSTR wzLayoutDirectory | ||
| 109 | ); | ||
| 110 | static HRESULT AppendCacheOrLayoutPayloadAction( | ||
| 111 | __in BURN_PLAN* pPlan, | ||
| 112 | __in_opt BURN_PACKAGE* pPackage, | ||
| 113 | __in DWORD iPackageStartAction, | ||
| 114 | __in BURN_PAYLOAD* pPayload, | ||
| 115 | __in BOOL fPayloadCached, | ||
| 116 | __in_z_opt LPCWSTR wzLayoutDirectory | ||
| 117 | ); | ||
| 118 | static BOOL FindContainerCacheAction( | ||
| 119 | __in BURN_CACHE_ACTION_TYPE type, | ||
| 120 | __in BURN_PLAN* pPlan, | ||
| 121 | __in BURN_CONTAINER* pContainer, | ||
| 122 | __in DWORD iSearchStart, | ||
| 123 | __in DWORD iSearchEnd, | ||
| 124 | __out_opt BURN_CACHE_ACTION** ppCacheAction, | ||
| 125 | __out_opt DWORD* piCacheAction | ||
| 126 | ); | ||
| 127 | static HRESULT CreateContainerAcquireAndExtractAction( | ||
| 128 | __in BURN_PLAN* pPlan, | 110 | __in BURN_PLAN* pPlan, |
| 129 | __in BURN_CONTAINER* pContainer, | 111 | __in BURN_PAYLOAD_GROUP* pPayloadGroup |
| 130 | __in DWORD iPackageStartAction, | ||
| 131 | __in BOOL fPayloadCached, | ||
| 132 | __out BURN_CACHE_ACTION** ppContainerExtractAction, | ||
| 133 | __out DWORD* piContainerTryAgainAction | ||
| 134 | ); | ||
| 135 | static HRESULT AddAcquireContainer( | ||
| 136 | __in BURN_PLAN* pPlan, | ||
| 137 | __in BURN_CONTAINER* pContainer, | ||
| 138 | __out_opt BURN_CACHE_ACTION** ppCacheAction, | ||
| 139 | __out_opt DWORD* piCacheAction | ||
| 140 | ); | ||
| 141 | static HRESULT AddExtractPayload( | ||
| 142 | __in BURN_CACHE_ACTION* pCacheAction, | ||
| 143 | __in_opt BURN_PACKAGE* pPackage, | ||
| 144 | __in BURN_PAYLOAD* pPayload, | ||
| 145 | __in_z LPCWSTR wzPayloadWorkingPath | ||
| 146 | ); | ||
| 147 | static BURN_CACHE_ACTION* ProcessSharedPayload( | ||
| 148 | __in BURN_PLAN* pPlan, | ||
| 149 | __in BURN_PAYLOAD* pPayload | ||
| 150 | ); | 112 | ); |
| 151 | static void RemoveUnnecessaryActions( | 113 | static void RemoveUnnecessaryActions( |
| 152 | __in BOOL fExecute, | 114 | __in BOOL fExecute, |
| @@ -175,24 +137,17 @@ static BOOL NeedsCache( | |||
| 175 | __in BURN_PACKAGE* pPackage, | 137 | __in BURN_PACKAGE* pPackage, |
| 176 | __in BOOL fExecute | 138 | __in BOOL fExecute |
| 177 | ); | 139 | ); |
| 178 | static HRESULT CreateContainerProgress( | ||
| 179 | __in BURN_PLAN* pPlan, | ||
| 180 | __in BURN_CONTAINER* pContainer, | ||
| 181 | __out BURN_CACHE_CONTAINER_PROGRESS** ppContainerProgress | ||
| 182 | ); | ||
| 183 | static HRESULT CreatePayloadProgress( | ||
| 184 | __in BURN_PLAN* pPlan, | ||
| 185 | __in BURN_PAYLOAD* pPayload, | ||
| 186 | __out BURN_CACHE_PAYLOAD_PROGRESS** ppPayloadProgress | ||
| 187 | ); | ||
| 188 | 140 | ||
| 189 | // function definitions | 141 | // function definitions |
| 190 | 142 | ||
| 191 | extern "C" void PlanReset( | 143 | extern "C" void PlanReset( |
| 192 | __in BURN_PLAN* pPlan, | 144 | __in BURN_PLAN* pPlan, |
| 193 | __in BURN_PACKAGES* pPackages | 145 | __in BURN_CONTAINERS* pContainers, |
| 146 | __in BURN_PACKAGES* pPackages, | ||
| 147 | __in BURN_PAYLOAD_GROUP* pLayoutPayloads | ||
| 194 | ) | 148 | ) |
| 195 | { | 149 | { |
| 150 | ReleaseNullStr(pPlan->sczLayoutDirectory); | ||
| 196 | PackageUninitialize(&pPlan->forwardCompatibleBundle); | 151 | PackageUninitialize(&pPlan->forwardCompatibleBundle); |
| 197 | 152 | ||
| 198 | if (pPlan->rgRegistrationActions) | 153 | if (pPlan->rgRegistrationActions) |
| @@ -271,8 +226,21 @@ extern "C" void PlanReset( | |||
| 271 | ReleaseDict(pPlan->shPayloadProgress); | 226 | ReleaseDict(pPlan->shPayloadProgress); |
| 272 | } | 227 | } |
| 273 | 228 | ||
| 229 | if (pPlan->pPayloads) | ||
| 230 | { | ||
| 231 | ResetPlannedPayloadsState(pPlan->pPayloads); | ||
| 232 | } | ||
| 233 | |||
| 274 | memset(pPlan, 0, sizeof(BURN_PLAN)); | 234 | memset(pPlan, 0, sizeof(BURN_PLAN)); |
| 275 | 235 | ||
| 236 | if (pContainers->rgContainers) | ||
| 237 | { | ||
| 238 | for (DWORD i = 0; i < pContainers->cContainers; ++i) | ||
| 239 | { | ||
| 240 | ResetPlannedContainerState(&pContainers->rgContainers[i]); | ||
| 241 | } | ||
| 242 | } | ||
| 243 | |||
| 276 | // Reset the planned actions for each package. | 244 | // Reset the planned actions for each package. |
| 277 | if (pPackages->rgPackages) | 245 | if (pPackages->rgPackages) |
| 278 | { | 246 | { |
| @@ -282,6 +250,8 @@ extern "C" void PlanReset( | |||
| 282 | } | 250 | } |
| 283 | } | 251 | } |
| 284 | 252 | ||
| 253 | ResetPlannedPayloadGroupState(pLayoutPayloads); | ||
| 254 | |||
| 285 | // Reset the planned state for each rollback boundary. | 255 | // Reset the planned state for each rollback boundary. |
| 286 | if (pPackages->rgRollbackBoundaries) | 256 | if (pPackages->rgRollbackBoundaries) |
| 287 | { | 257 | { |
| @@ -417,34 +387,35 @@ extern "C" HRESULT PlanLayoutBundle( | |||
| 417 | __in_z LPCWSTR wzExecutableName, | 387 | __in_z LPCWSTR wzExecutableName, |
| 418 | __in DWORD64 qwBundleSize, | 388 | __in DWORD64 qwBundleSize, |
| 419 | __in BURN_VARIABLES* pVariables, | 389 | __in BURN_VARIABLES* pVariables, |
| 420 | __in BURN_PAYLOADS* pPayloads, | 390 | __in BURN_PAYLOAD_GROUP* pLayoutPayloads |
| 421 | __out_z LPWSTR* psczLayoutDirectory | ||
| 422 | ) | 391 | ) |
| 423 | { | 392 | { |
| 424 | HRESULT hr = S_OK; | 393 | HRESULT hr = S_OK; |
| 425 | BURN_CACHE_ACTION* pCacheAction = NULL; | 394 | BURN_CACHE_ACTION* pCacheAction = NULL; |
| 426 | LPWSTR sczExecutablePath = NULL; | 395 | LPWSTR sczExecutablePath = NULL; |
| 427 | LPWSTR sczLayoutDirectory = NULL; | ||
| 428 | 396 | ||
| 429 | // Get the layout directory. | 397 | // Get the layout directory. |
| 430 | hr = VariableGetString(pVariables, BURN_BUNDLE_LAYOUT_DIRECTORY, &sczLayoutDirectory); | 398 | hr = VariableGetString(pVariables, BURN_BUNDLE_LAYOUT_DIRECTORY, &pPlan->sczLayoutDirectory); |
| 431 | if (E_NOTFOUND == hr) // if not set, use the current directory as the layout directory. | 399 | if (E_NOTFOUND == hr) // if not set, use the current directory as the layout directory. |
| 432 | { | 400 | { |
| 433 | hr = VariableGetString(pVariables, BURN_BUNDLE_SOURCE_PROCESS_FOLDER, &sczLayoutDirectory); | 401 | hr = VariableGetString(pVariables, BURN_BUNDLE_SOURCE_PROCESS_FOLDER, &pPlan->sczLayoutDirectory); |
| 434 | if (E_NOTFOUND == hr) // if not set, use the current directory as the layout directory. | 402 | if (E_NOTFOUND == hr) // if not set, use the current directory as the layout directory. |
| 435 | { | 403 | { |
| 436 | hr = PathForCurrentProcess(&sczExecutablePath, NULL); | 404 | hr = PathForCurrentProcess(&sczExecutablePath, NULL); |
| 437 | ExitOnFailure(hr, "Failed to get path for current executing process as layout directory."); | 405 | ExitOnFailure(hr, "Failed to get path for current executing process as layout directory."); |
| 438 | 406 | ||
| 439 | hr = PathGetDirectory(sczExecutablePath, &sczLayoutDirectory); | 407 | hr = PathGetDirectory(sczExecutablePath, &pPlan->sczLayoutDirectory); |
| 440 | ExitOnFailure(hr, "Failed to get executing process as layout directory."); | 408 | ExitOnFailure(hr, "Failed to get executing process as layout directory."); |
| 441 | } | 409 | } |
| 442 | } | 410 | } |
| 443 | ExitOnFailure(hr, "Failed to get bundle layout directory property."); | 411 | ExitOnFailure(hr, "Failed to get bundle layout directory property."); |
| 444 | 412 | ||
| 445 | hr = PathBackslashTerminate(&sczLayoutDirectory); | 413 | hr = PathBackslashTerminate(&pPlan->sczLayoutDirectory); |
| 446 | ExitOnFailure(hr, "Failed to ensure layout directory is backslash terminated."); | 414 | ExitOnFailure(hr, "Failed to ensure layout directory is backslash terminated."); |
| 447 | 415 | ||
| 416 | hr = ProcessPayloadGroup(pPlan, pLayoutPayloads); | ||
| 417 | ExitOnFailure(hr, "Failed to process payload group for bundle."); | ||
| 418 | |||
| 448 | // Plan the layout of the bundle engine itself. | 419 | // Plan the layout of the bundle engine itself. |
| 449 | hr = AppendCacheAction(pPlan, &pCacheAction); | 420 | hr = AppendCacheAction(pPlan, &pCacheAction); |
| 450 | ExitOnFailure(hr, "Failed to append bundle start action."); | 421 | ExitOnFailure(hr, "Failed to append bundle start action."); |
| @@ -454,36 +425,17 @@ extern "C" HRESULT PlanLayoutBundle( | |||
| 454 | hr = StrAllocString(&pCacheAction->bundleLayout.sczExecutableName, wzExecutableName, 0); | 425 | hr = StrAllocString(&pCacheAction->bundleLayout.sczExecutableName, wzExecutableName, 0); |
| 455 | ExitOnFailure(hr, "Failed to to copy executable name for bundle."); | 426 | ExitOnFailure(hr, "Failed to to copy executable name for bundle."); |
| 456 | 427 | ||
| 457 | hr = StrAllocString(&pCacheAction->bundleLayout.sczLayoutDirectory, sczLayoutDirectory, 0); | ||
| 458 | ExitOnFailure(hr, "Failed to to copy layout directory for bundle."); | ||
| 459 | |||
| 460 | hr = CacheCalculateBundleLayoutWorkingPath(pPlan->wzBundleId, &pCacheAction->bundleLayout.sczUnverifiedPath); | 428 | hr = CacheCalculateBundleLayoutWorkingPath(pPlan->wzBundleId, &pCacheAction->bundleLayout.sczUnverifiedPath); |
| 461 | ExitOnFailure(hr, "Failed to calculate bundle layout working path."); | 429 | ExitOnFailure(hr, "Failed to calculate bundle layout working path."); |
| 462 | 430 | ||
| 463 | pCacheAction->bundleLayout.qwBundleSize = qwBundleSize; | 431 | pCacheAction->bundleLayout.qwBundleSize = qwBundleSize; |
| 432 | pCacheAction->bundleLayout.pPayloadGroup = pLayoutPayloads; | ||
| 464 | 433 | ||
| 465 | pPlan->qwCacheSizeTotal += qwBundleSize; | 434 | pPlan->qwCacheSizeTotal += 2 * qwBundleSize; |
| 466 | 435 | ||
| 467 | ++pPlan->cOverallProgressTicksTotal; | 436 | ++pPlan->cOverallProgressTicksTotal; |
| 468 | 437 | ||
| 469 | // Plan the layout of layout-only payloads. | ||
| 470 | for (DWORD i = 0; i < pPayloads->cPayloads; ++i) | ||
| 471 | { | ||
| 472 | BURN_PAYLOAD* pPayload = pPayloads->rgPayloads + i; | ||
| 473 | if (pPayload->fLayoutOnly) | ||
| 474 | { | ||
| 475 | // TODO: determine if a payload already exists in the layout and pass appropriate value fPayloadCached | ||
| 476 | // (instead of always FALSE). | ||
| 477 | hr = AppendCacheOrLayoutPayloadAction(pPlan, NULL, BURN_PLAN_INVALID_ACTION_INDEX, pPayload, FALSE, sczLayoutDirectory); | ||
| 478 | ExitOnFailure(hr, "Failed to plan layout payload."); | ||
| 479 | } | ||
| 480 | } | ||
| 481 | |||
| 482 | *psczLayoutDirectory = sczLayoutDirectory; | ||
| 483 | sczLayoutDirectory = NULL; | ||
| 484 | |||
| 485 | LExit: | 438 | LExit: |
| 486 | ReleaseStr(sczLayoutDirectory); | ||
| 487 | ReleaseStr(sczExecutablePath); | 439 | ReleaseStr(sczExecutablePath); |
| 488 | 440 | ||
| 489 | return hr; | 441 | return hr; |
| @@ -562,13 +514,12 @@ extern "C" HRESULT PlanPackages( | |||
| 562 | __in BURN_LOGGING* pLog, | 514 | __in BURN_LOGGING* pLog, |
| 563 | __in BURN_VARIABLES* pVariables, | 515 | __in BURN_VARIABLES* pVariables, |
| 564 | __in BOOTSTRAPPER_DISPLAY display, | 516 | __in BOOTSTRAPPER_DISPLAY display, |
| 565 | __in BOOTSTRAPPER_RELATION_TYPE relationType, | 517 | __in BOOTSTRAPPER_RELATION_TYPE relationType |
| 566 | __in_z_opt LPCWSTR wzLayoutDirectory | ||
| 567 | ) | 518 | ) |
| 568 | { | 519 | { |
| 569 | HRESULT hr = S_OK; | 520 | HRESULT hr = S_OK; |
| 570 | 521 | ||
| 571 | hr = PlanPackagesHelper(pPackages->rgPackages, pPackages->cPackages, TRUE, pUX, pPlan, pLog, pVariables, display, relationType, wzLayoutDirectory); | 522 | hr = PlanPackagesHelper(pPackages->rgPackages, pPackages->cPackages, TRUE, pUX, pPlan, pLog, pVariables, display, relationType); |
| 572 | 523 | ||
| 573 | return hr; | 524 | return hr; |
| 574 | } | 525 | } |
| @@ -782,7 +733,7 @@ extern "C" HRESULT PlanPassThroughBundle( | |||
| 782 | // Plan passthrough package. | 733 | // Plan passthrough package. |
| 783 | // Passthrough packages are never cleaned up by the calling bundle (they delete themselves when appropriate) | 734 | // Passthrough packages are never cleaned up by the calling bundle (they delete themselves when appropriate) |
| 784 | // so we don't need to plan clean up. | 735 | // so we don't need to plan clean up. |
| 785 | hr = PlanPackagesHelper(pPackage, 1, FALSE, pUX, pPlan, pLog, pVariables, display, relationType, NULL); | 736 | hr = PlanPackagesHelper(pPackage, 1, FALSE, pUX, pPlan, pLog, pVariables, display, relationType); |
| 786 | ExitOnFailure(hr, "Failed to process passthrough package."); | 737 | ExitOnFailure(hr, "Failed to process passthrough package."); |
| 787 | 738 | ||
| 788 | LExit: | 739 | LExit: |
| @@ -802,7 +753,7 @@ extern "C" HRESULT PlanUpdateBundle( | |||
| 802 | HRESULT hr = S_OK; | 753 | HRESULT hr = S_OK; |
| 803 | 754 | ||
| 804 | // Plan update package. | 755 | // Plan update package. |
| 805 | hr = PlanPackagesHelper(pPackage, 1, TRUE, pUX, pPlan, pLog, pVariables, display, relationType, NULL); | 756 | hr = PlanPackagesHelper(pPackage, 1, TRUE, pUX, pPlan, pLog, pVariables, display, relationType); |
| 806 | ExitOnFailure(hr, "Failed to process update package."); | 757 | ExitOnFailure(hr, "Failed to process update package."); |
| 807 | 758 | ||
| 808 | LExit: | 759 | LExit: |
| @@ -818,8 +769,7 @@ static HRESULT PlanPackagesHelper( | |||
| 818 | __in BURN_LOGGING* pLog, | 769 | __in BURN_LOGGING* pLog, |
| 819 | __in BURN_VARIABLES* pVariables, | 770 | __in BURN_VARIABLES* pVariables, |
| 820 | __in BOOTSTRAPPER_DISPLAY display, | 771 | __in BOOTSTRAPPER_DISPLAY display, |
| 821 | __in BOOTSTRAPPER_RELATION_TYPE relationType, | 772 | __in BOOTSTRAPPER_RELATION_TYPE relationType |
| 822 | __in_z_opt LPCWSTR wzLayoutDirectory | ||
| 823 | ) | 773 | ) |
| 824 | { | 774 | { |
| 825 | HRESULT hr = S_OK; | 775 | HRESULT hr = S_OK; |
| @@ -856,7 +806,7 @@ static HRESULT PlanPackagesHelper( | |||
| 856 | DWORD iPackage = (BOOTSTRAPPER_ACTION_UNINSTALL == pPlan->action) ? cPackages - 1 - i : i; | 806 | DWORD iPackage = (BOOTSTRAPPER_ACTION_UNINSTALL == pPlan->action) ? cPackages - 1 - i : i; |
| 857 | BURN_PACKAGE* pPackage = rgPackages + iPackage; | 807 | BURN_PACKAGE* pPackage = rgPackages + iPackage; |
| 858 | 808 | ||
| 859 | hr = ProcessPackage(fBundlePerMachine, pUX, pPlan, pPackage, pLog, pVariables, display, wzLayoutDirectory, &hSyncpointEvent, &pRollbackBoundary); | 809 | hr = ProcessPackage(fBundlePerMachine, pUX, pPlan, pPackage, pLog, pVariables, display, &hSyncpointEvent, &pRollbackBoundary); |
| 860 | ExitOnFailure(hr, "Failed to process package."); | 810 | ExitOnFailure(hr, "Failed to process package."); |
| 861 | } | 811 | } |
| 862 | 812 | ||
| @@ -962,7 +912,6 @@ static HRESULT ProcessPackage( | |||
| 962 | __in BURN_LOGGING* pLog, | 912 | __in BURN_LOGGING* pLog, |
| 963 | __in BURN_VARIABLES* pVariables, | 913 | __in BURN_VARIABLES* pVariables, |
| 964 | __in BOOTSTRAPPER_DISPLAY display, | 914 | __in BOOTSTRAPPER_DISPLAY display, |
| 965 | __in_z_opt LPCWSTR wzLayoutDirectory, | ||
| 966 | __inout HANDLE* phSyncpointEvent, | 915 | __inout HANDLE* phSyncpointEvent, |
| 967 | __inout BURN_ROLLBACK_BOUNDARY** ppRollbackBoundary | 916 | __inout BURN_ROLLBACK_BOUNDARY** ppRollbackBoundary |
| 968 | ) | 917 | ) |
| @@ -976,7 +925,7 @@ static HRESULT ProcessPackage( | |||
| 976 | 925 | ||
| 977 | if (BOOTSTRAPPER_ACTION_LAYOUT == pPlan->action) | 926 | if (BOOTSTRAPPER_ACTION_LAYOUT == pPlan->action) |
| 978 | { | 927 | { |
| 979 | hr = PlanLayoutPackage(pPlan, pPackage, wzLayoutDirectory); | 928 | hr = PlanLayoutPackage(pPlan, pPackage); |
| 980 | ExitOnFailure(hr, "Failed to plan layout package."); | 929 | ExitOnFailure(hr, "Failed to plan layout package."); |
| 981 | } | 930 | } |
| 982 | else | 931 | else |
| @@ -1035,59 +984,69 @@ LExit: | |||
| 1035 | return hr; | 984 | return hr; |
| 1036 | } | 985 | } |
| 1037 | 986 | ||
| 1038 | extern "C" HRESULT PlanLayoutPackage( | 987 | extern "C" HRESULT PlanLayoutContainer( |
| 1039 | __in BURN_PLAN* pPlan, | 988 | __in BURN_PLAN* pPlan, |
| 1040 | __in BURN_PACKAGE* pPackage, | 989 | __in BURN_CONTAINER* pContainer |
| 1041 | __in_z_opt LPCWSTR wzLayoutDirectory | ||
| 1042 | ) | 990 | ) |
| 1043 | { | 991 | { |
| 1044 | HRESULT hr = S_OK; | 992 | HRESULT hr = S_OK; |
| 1045 | BURN_CACHE_ACTION* pCacheAction = NULL; | 993 | BURN_CACHE_ACTION* pCacheAction = NULL; |
| 1046 | DWORD iPackageStartAction = 0; | ||
| 1047 | 994 | ||
| 1048 | hr = AppendCacheAction(pPlan, &pCacheAction); | 995 | Assert(!pContainer->fPlanned); |
| 1049 | ExitOnFailure(hr, "Failed to append package start action."); | 996 | pContainer->fPlanned = TRUE; |
| 1050 | 997 | ||
| 1051 | pCacheAction->type = BURN_CACHE_ACTION_TYPE_PACKAGE_START; | 998 | if (pPlan->sczLayoutDirectory) |
| 1052 | pCacheAction->packageStart.pPackage = pPackage; | 999 | { |
| 1000 | if (!pContainer->fAttached) | ||
| 1001 | { | ||
| 1002 | hr = AppendCacheAction(pPlan, &pCacheAction); | ||
| 1003 | ExitOnFailure(hr, "Failed to append package start action."); | ||
| 1053 | 1004 | ||
| 1054 | // Remember the index for the package start action (which is now the last in the cache | 1005 | pCacheAction->type = BURN_CACHE_ACTION_TYPE_CONTAINER; |
| 1055 | // actions array) because the array may be resized later and move around in memory. | 1006 | pCacheAction->container.pContainer = pContainer; |
| 1056 | iPackageStartAction = pPlan->cCacheActions - 1; | ||
| 1057 | 1007 | ||
| 1058 | // If any of the package payloads are not cached, add them to the plan. | 1008 | pPlan->qwCacheSizeTotal += 2 * pContainer->qwFileSize; |
| 1059 | for (DWORD i = 0; i < pPackage->cPayloads; ++i) | 1009 | } |
| 1010 | } | ||
| 1011 | else | ||
| 1060 | { | 1012 | { |
| 1061 | BURN_PACKAGE_PAYLOAD* pPackagePayload = &pPackage->rgPayloads[i]; | 1013 | pPlan->qwCacheSizeTotal += 2 * pContainer->qwFileSize; |
| 1014 | } | ||
| 1062 | 1015 | ||
| 1063 | // If doing layout and the package is in a container. | 1016 | if (!pContainer->sczUnverifiedPath) |
| 1064 | if (wzLayoutDirectory && pPackagePayload->pPayload->pContainer) | 1017 | { |
| 1018 | if (pContainer->fActuallyAttached) | ||
| 1065 | { | 1019 | { |
| 1066 | // TODO: determine if a container already exists in the layout and pass appropriate value fPayloadCached (instead of always FALSE). | 1020 | hr = PathForCurrentProcess(&pContainer->sczUnverifiedPath, NULL); |
| 1067 | hr = AppendLayoutContainerAction(pPlan, pPackage, iPackageStartAction, pPackagePayload->pPayload->pContainer, FALSE, wzLayoutDirectory); | 1021 | ExitOnFailure(hr, "Failed to get path for executing module as attached container working path."); |
| 1068 | ExitOnFailure(hr, "Failed to append layout container action."); | ||
| 1069 | } | 1022 | } |
| 1070 | else | 1023 | else |
| 1071 | { | 1024 | { |
| 1072 | // TODO: determine if a payload already exists in the layout and pass appropriate value fPayloadCached (instead of always FALSE). | 1025 | hr = CacheCalculateContainerWorkingPath(pPlan->wzBundleId, pContainer, &pContainer->sczUnverifiedPath); |
| 1073 | hr = AppendCacheOrLayoutPayloadAction(pPlan, pPackage, iPackageStartAction, pPackagePayload->pPayload, FALSE, wzLayoutDirectory); | 1026 | ExitOnFailure(hr, "Failed to calculate unverified path for container."); |
| 1074 | ExitOnFailure(hr, "Failed to append cache/layout payload action."); | ||
| 1075 | } | 1027 | } |
| 1076 | |||
| 1077 | Assert(BURN_CACHE_ACTION_TYPE_PACKAGE_START == pPlan->rgCacheActions[iPackageStartAction].type); | ||
| 1078 | ++pPlan->rgCacheActions[iPackageStartAction].packageStart.cCachePayloads; | ||
| 1079 | pPlan->rgCacheActions[iPackageStartAction].packageStart.qwCachePayloadSizeTotal += pPackagePayload->pPayload->qwFileSize; | ||
| 1080 | } | 1028 | } |
| 1081 | 1029 | ||
| 1082 | // Create package stop action. | 1030 | LExit: |
| 1083 | hr = AppendCacheAction(pPlan, &pCacheAction); | 1031 | return hr; |
| 1084 | ExitOnFailure(hr, "Failed to append cache action."); | 1032 | } |
| 1085 | 1033 | ||
| 1086 | pCacheAction->type = BURN_CACHE_ACTION_TYPE_PACKAGE_STOP; | 1034 | extern "C" HRESULT PlanLayoutPackage( |
| 1087 | pCacheAction->packageStop.pPackage = pPackage; | 1035 | __in BURN_PLAN* pPlan, |
| 1036 | __in BURN_PACKAGE* pPackage | ||
| 1037 | ) | ||
| 1038 | { | ||
| 1039 | HRESULT hr = S_OK; | ||
| 1040 | BURN_CACHE_ACTION* pCacheAction = NULL; | ||
| 1041 | |||
| 1042 | hr = ProcessPayloadGroup(pPlan, &pPackage->payloads); | ||
| 1043 | ExitOnFailure(hr, "Failed to process payload group for package: %ls.", pPackage->sczId); | ||
| 1088 | 1044 | ||
| 1089 | // Update the start action with the location of the complete action. | 1045 | hr = AppendCacheAction(pPlan, &pCacheAction); |
| 1090 | pPlan->rgCacheActions[iPackageStartAction].packageStart.iPackageCompleteAction = pPlan->cCacheActions - 1; | 1046 | ExitOnFailure(hr, "Failed to append package start action."); |
| 1047 | |||
| 1048 | pCacheAction->type = BURN_CACHE_ACTION_TYPE_PACKAGE; | ||
| 1049 | pCacheAction->package.pPackage = pPackage; | ||
| 1091 | 1050 | ||
| 1092 | ++pPlan->cOverallProgressTicksTotal; | 1051 | ++pPlan->cOverallProgressTicksTotal; |
| 1093 | 1052 | ||
| @@ -1854,29 +1813,37 @@ static void UninitializeCacheAction( | |||
| 1854 | 1813 | ||
| 1855 | case BURN_CACHE_ACTION_TYPE_LAYOUT_BUNDLE: | 1814 | case BURN_CACHE_ACTION_TYPE_LAYOUT_BUNDLE: |
| 1856 | ReleaseStr(pCacheAction->bundleLayout.sczExecutableName); | 1815 | ReleaseStr(pCacheAction->bundleLayout.sczExecutableName); |
| 1857 | ReleaseStr(pCacheAction->bundleLayout.sczLayoutDirectory); | ||
| 1858 | ReleaseStr(pCacheAction->bundleLayout.sczUnverifiedPath); | 1816 | ReleaseStr(pCacheAction->bundleLayout.sczUnverifiedPath); |
| 1859 | break; | 1817 | break; |
| 1818 | } | ||
| 1819 | } | ||
| 1860 | 1820 | ||
| 1861 | case BURN_CACHE_ACTION_TYPE_ACQUIRE_CONTAINER: | 1821 | static void ResetPlannedContainerState( |
| 1862 | ReleaseStr(pCacheAction->resolveContainer.sczUnverifiedPath); | 1822 | __in BURN_CONTAINER* pContainer |
| 1863 | break; | 1823 | ) |
| 1864 | 1824 | { | |
| 1865 | case BURN_CACHE_ACTION_TYPE_EXTRACT_CONTAINER: | 1825 | pContainer->fPlanned = FALSE; |
| 1866 | ReleaseStr(pCacheAction->extractContainer.sczContainerUnverifiedPath); | 1826 | } |
| 1867 | ReleaseMem(pCacheAction->extractContainer.rgPayloads); | ||
| 1868 | break; | ||
| 1869 | 1827 | ||
| 1870 | case BURN_CACHE_ACTION_TYPE_ACQUIRE_PAYLOAD: | 1828 | static void ResetPlannedPayloadsState( |
| 1871 | ReleaseStr(pCacheAction->resolvePayload.sczUnverifiedPath); | 1829 | __in BURN_PAYLOADS* pPayloads |
| 1872 | break; | 1830 | ) |
| 1831 | { | ||
| 1832 | for (DWORD i = 0; i < pPayloads->cPayloads; ++i) | ||
| 1833 | { | ||
| 1834 | BURN_PAYLOAD* pPayload = pPayloads->rgPayloads + i; | ||
| 1873 | 1835 | ||
| 1874 | case BURN_CACHE_ACTION_TYPE_CACHE_PAYLOAD: | 1836 | pPayload->state = BURN_PAYLOAD_STATE_NONE; |
| 1875 | ReleaseStr(pCacheAction->cachePayload.sczUnverifiedPath); | 1837 | ReleaseNullStr(pPayload->sczLocalFilePath); |
| 1876 | break; | ||
| 1877 | } | 1838 | } |
| 1878 | } | 1839 | } |
| 1879 | 1840 | ||
| 1841 | static void ResetPlannedPayloadGroupState( | ||
| 1842 | __in BURN_PAYLOAD_GROUP* /*pPayloadGroup*/ | ||
| 1843 | ) | ||
| 1844 | { | ||
| 1845 | } | ||
| 1846 | |||
| 1880 | static void ResetPlannedPackageState( | 1847 | static void ResetPlannedPackageState( |
| 1881 | __in BURN_PACKAGE* pPackage | 1848 | __in BURN_PACKAGE* pPackage |
| 1882 | ) | 1849 | ) |
| @@ -1931,6 +1898,8 @@ static void ResetPlannedPackageState( | |||
| 1931 | pTargetProduct->rollbackSkip = BURN_PATCH_SKIP_STATE_NONE; | 1898 | pTargetProduct->rollbackSkip = BURN_PATCH_SKIP_STATE_NONE; |
| 1932 | } | 1899 | } |
| 1933 | } | 1900 | } |
| 1901 | |||
| 1902 | ResetPlannedPayloadGroupState(&pPackage->payloads); | ||
| 1934 | } | 1903 | } |
| 1935 | 1904 | ||
| 1936 | static void ResetPlannedRollbackBoundaryState( | 1905 | static void ResetPlannedRollbackBoundaryState( |
| @@ -2091,7 +2060,6 @@ static HRESULT AddCachePackageHelper( | |||
| 2091 | HRESULT hr = S_OK; | 2060 | HRESULT hr = S_OK; |
| 2092 | BURN_CACHE_ACTION* pCacheAction = NULL; | 2061 | BURN_CACHE_ACTION* pCacheAction = NULL; |
| 2093 | DWORD dwCheckpoint = 0; | 2062 | DWORD dwCheckpoint = 0; |
| 2094 | DWORD iPackageStartAction = 0; | ||
| 2095 | 2063 | ||
| 2096 | BOOL fPlanned = AlreadyPlannedCachePackage(pPlan, pPackage->sczId, phSyncpointEvent); | 2064 | BOOL fPlanned = AlreadyPlannedCachePackage(pPlan, pPackage->sczId, phSyncpointEvent); |
| 2097 | if (fPlanned) | 2065 | if (fPlanned) |
| @@ -2105,7 +2073,7 @@ static HRESULT AddCachePackageHelper( | |||
| 2105 | dwCheckpoint = GetNextCheckpointId(pPlan); | 2073 | dwCheckpoint = GetNextCheckpointId(pPlan); |
| 2106 | 2074 | ||
| 2107 | hr = AppendCacheAction(pPlan, &pCacheAction); | 2075 | hr = AppendCacheAction(pPlan, &pCacheAction); |
| 2108 | ExitOnFailure(hr, "Failed to append package start action."); | 2076 | ExitOnFailure(hr, "Failed to append checkpoint before package start action."); |
| 2109 | 2077 | ||
| 2110 | pCacheAction->type = BURN_CACHE_ACTION_TYPE_CHECKPOINT; | 2078 | pCacheAction->type = BURN_CACHE_ACTION_TYPE_CHECKPOINT; |
| 2111 | pCacheAction->checkpoint.dwId = dwCheckpoint; | 2079 | pCacheAction->checkpoint.dwId = dwCheckpoint; |
| @@ -2123,50 +2091,8 @@ static HRESULT AddCachePackageHelper( | |||
| 2123 | pCacheAction->checkpoint.dwId = dwCheckpoint; | 2091 | pCacheAction->checkpoint.dwId = dwCheckpoint; |
| 2124 | } | 2092 | } |
| 2125 | 2093 | ||
| 2126 | // Plan the package start. | 2094 | hr = PlanLayoutPackage(pPlan, pPackage); |
| 2127 | hr = AppendCacheAction(pPlan, &pCacheAction); | 2095 | ExitOnFailure(hr, "Failed to plan cache for package."); |
| 2128 | ExitOnFailure(hr, "Failed to append package start action."); | ||
| 2129 | |||
| 2130 | pCacheAction->type = BURN_CACHE_ACTION_TYPE_PACKAGE_START; | ||
| 2131 | pCacheAction->packageStart.pPackage = pPackage; | ||
| 2132 | |||
| 2133 | // Remember the index for the package start action (which is now the last in the cache | ||
| 2134 | // actions array) because we have to update this action after processing all the payloads | ||
| 2135 | // and the array may be resized later which would move a pointer around in memory. | ||
| 2136 | iPackageStartAction = pPlan->cCacheActions - 1; | ||
| 2137 | |||
| 2138 | if (fPlanCacheRollback) | ||
| 2139 | { | ||
| 2140 | // Create a package cache rollback action. | ||
| 2141 | hr = AppendRollbackCacheAction(pPlan, &pCacheAction); | ||
| 2142 | ExitOnFailure(hr, "Failed to append rollback cache action."); | ||
| 2143 | |||
| 2144 | pCacheAction->type = BURN_CACHE_ACTION_TYPE_ROLLBACK_PACKAGE; | ||
| 2145 | pCacheAction->rollbackPackage.pPackage = pPackage; | ||
| 2146 | } | ||
| 2147 | |||
| 2148 | // Add all the payload cache operations to the plan for this package. | ||
| 2149 | for (DWORD i = 0; i < pPackage->cPayloads; ++i) | ||
| 2150 | { | ||
| 2151 | BURN_PACKAGE_PAYLOAD* pPackagePayload = &pPackage->rgPayloads[i]; | ||
| 2152 | |||
| 2153 | hr = AppendCacheOrLayoutPayloadAction(pPlan, pPackage, iPackageStartAction, pPackagePayload->pPayload, pPackagePayload->fCached, NULL); | ||
| 2154 | ExitOnFailure(hr, "Failed to append payload cache action."); | ||
| 2155 | |||
| 2156 | Assert(BURN_CACHE_ACTION_TYPE_PACKAGE_START == pPlan->rgCacheActions[iPackageStartAction].type); | ||
| 2157 | ++pPlan->rgCacheActions[iPackageStartAction].packageStart.cCachePayloads; | ||
| 2158 | pPlan->rgCacheActions[iPackageStartAction].packageStart.qwCachePayloadSizeTotal += pPackagePayload->pPayload->qwFileSize; | ||
| 2159 | } | ||
| 2160 | |||
| 2161 | // Create package stop action. | ||
| 2162 | hr = AppendCacheAction(pPlan, &pCacheAction); | ||
| 2163 | ExitOnFailure(hr, "Failed to append cache action."); | ||
| 2164 | |||
| 2165 | pCacheAction->type = BURN_CACHE_ACTION_TYPE_PACKAGE_STOP; | ||
| 2166 | pCacheAction->packageStop.pPackage = pPackage; | ||
| 2167 | |||
| 2168 | // Update the start action with the location of the complete action. | ||
| 2169 | pPlan->rgCacheActions[iPackageStartAction].packageStart.iPackageCompleteAction = pPlan->cCacheActions - 1; | ||
| 2170 | 2096 | ||
| 2171 | // Create syncpoint action. | 2097 | // Create syncpoint action. |
| 2172 | hr = AppendCacheAction(pPlan, &pCacheAction); | 2098 | hr = AppendCacheAction(pPlan, &pCacheAction); |
| @@ -2178,8 +2104,6 @@ static HRESULT AddCachePackageHelper( | |||
| 2178 | 2104 | ||
| 2179 | *phSyncpointEvent = pCacheAction->syncpoint.hEvent; | 2105 | *phSyncpointEvent = pCacheAction->syncpoint.hEvent; |
| 2180 | 2106 | ||
| 2181 | ++pPlan->cOverallProgressTicksTotal; | ||
| 2182 | |||
| 2183 | pPackage->fPlannedCache = TRUE; | 2107 | pPackage->fPlannedCache = TRUE; |
| 2184 | if (pPackage->fCanAffectRegistration) | 2108 | if (pPackage->fCanAffectRegistration) |
| 2185 | { | 2109 | { |
| @@ -2225,9 +2149,9 @@ static BOOL AlreadyPlannedCachePackage( | |||
| 2225 | { | 2149 | { |
| 2226 | BURN_CACHE_ACTION* pCacheAction = pPlan->rgCacheActions + iCacheAction; | 2150 | BURN_CACHE_ACTION* pCacheAction = pPlan->rgCacheActions + iCacheAction; |
| 2227 | 2151 | ||
| 2228 | if (BURN_CACHE_ACTION_TYPE_PACKAGE_STOP == pCacheAction->type) | 2152 | if (BURN_CACHE_ACTION_TYPE_PACKAGE == pCacheAction->type) |
| 2229 | { | 2153 | { |
| 2230 | if (CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, 0, pCacheAction->packageStop.pPackage->sczId, -1, wzPackageId, -1)) | 2154 | if (CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, 0, pCacheAction->package.pPackage->sczId, -1, wzPackageId, -1)) |
| 2231 | { | 2155 | { |
| 2232 | if (iCacheAction + 1 < pPlan->cCacheActions && BURN_CACHE_ACTION_TYPE_SIGNAL_SYNCPOINT == pPlan->rgCacheActions[iCacheAction + 1].type) | 2156 | if (iCacheAction + 1 < pPlan->cCacheActions && BURN_CACHE_ACTION_TYPE_SIGNAL_SYNCPOINT == pPlan->rgCacheActions[iCacheAction + 1].type) |
| 2233 | { | 2157 | { |
| @@ -2284,460 +2208,39 @@ LExit: | |||
| 2284 | return hr; | 2208 | return hr; |
| 2285 | } | 2209 | } |
| 2286 | 2210 | ||
| 2287 | static HRESULT AppendLayoutContainerAction( | 2211 | static HRESULT ProcessPayloadGroup( |
| 2288 | __in BURN_PLAN* pPlan, | ||
| 2289 | __in_opt BURN_PACKAGE* pPackage, | ||
| 2290 | __in DWORD iPackageStartAction, | ||
| 2291 | __in BURN_CONTAINER* pContainer, | ||
| 2292 | __in BOOL fContainerCached, | ||
| 2293 | __in_z LPCWSTR wzLayoutDirectory | ||
| 2294 | ) | ||
| 2295 | { | ||
| 2296 | HRESULT hr = S_OK; | ||
| 2297 | BURN_CACHE_ACTION* pAcquireAction = NULL; | ||
| 2298 | DWORD iAcquireAction = BURN_PLAN_INVALID_ACTION_INDEX; | ||
| 2299 | LPWSTR sczContainerWorkingPath = NULL; | ||
| 2300 | BURN_CACHE_ACTION* pCacheAction = NULL; | ||
| 2301 | BURN_CACHE_CONTAINER_PROGRESS* pContainerProgress = NULL; | ||
| 2302 | |||
| 2303 | // No need to do anything if the container is already cached or is attached to the bundle (since the | ||
| 2304 | // bundle itself will already have a layout action). | ||
| 2305 | if (fContainerCached || pContainer->fAttached) | ||
| 2306 | { | ||
| 2307 | ExitFunction(); | ||
| 2308 | } | ||
| 2309 | |||
| 2310 | // Ensure the container is being acquired. If it is, then some earlier package already planned the layout of this container so | ||
| 2311 | // don't do it again. Otherwise, plan away! | ||
| 2312 | if (!FindContainerCacheAction(BURN_CACHE_ACTION_TYPE_ACQUIRE_CONTAINER, pPlan, pContainer, 0, iPackageStartAction, NULL, NULL)) | ||
| 2313 | { | ||
| 2314 | hr = AddAcquireContainer(pPlan, pContainer, &pAcquireAction, &iAcquireAction); | ||
| 2315 | ExitOnFailure(hr, "Failed to append acquire container action for layout to plan."); | ||
| 2316 | |||
| 2317 | Assert(BURN_CACHE_ACTION_TYPE_ACQUIRE_CONTAINER == pAcquireAction->type); | ||
| 2318 | |||
| 2319 | // Create the layout container action. | ||
| 2320 | hr = StrAllocString(&sczContainerWorkingPath, pAcquireAction->resolveContainer.sczUnverifiedPath, 0); | ||
| 2321 | ExitOnFailure(hr, "Failed to copy container working path for layout."); | ||
| 2322 | |||
| 2323 | hr = AppendCacheAction(pPlan, &pCacheAction); | ||
| 2324 | ExitOnFailure(hr, "Failed to append cache action to cache payload."); | ||
| 2325 | |||
| 2326 | hr = CreateContainerProgress(pPlan, pContainer, &pContainerProgress); | ||
| 2327 | ExitOnFailure(hr, "Failed to create container progress."); | ||
| 2328 | |||
| 2329 | hr = StrAllocString(&pCacheAction->layoutContainer.sczLayoutDirectory, wzLayoutDirectory, 0); | ||
| 2330 | ExitOnFailure(hr, "Failed to copy layout directory into plan."); | ||
| 2331 | |||
| 2332 | pCacheAction->type = BURN_CACHE_ACTION_TYPE_LAYOUT_CONTAINER; | ||
| 2333 | pCacheAction->layoutContainer.pPackage = pPackage; | ||
| 2334 | pCacheAction->layoutContainer.pContainer = pContainer; | ||
| 2335 | pCacheAction->layoutContainer.iProgress = pContainerProgress->iIndex; | ||
| 2336 | pCacheAction->layoutContainer.fMove = TRUE; | ||
| 2337 | pCacheAction->layoutContainer.iTryAgainAction = iAcquireAction; | ||
| 2338 | pCacheAction->layoutContainer.sczUnverifiedPath = sczContainerWorkingPath; | ||
| 2339 | sczContainerWorkingPath = NULL; | ||
| 2340 | } | ||
| 2341 | |||
| 2342 | LExit: | ||
| 2343 | ReleaseNullStr(sczContainerWorkingPath); | ||
| 2344 | |||
| 2345 | return hr; | ||
| 2346 | } | ||
| 2347 | |||
| 2348 | static HRESULT AppendCacheOrLayoutPayloadAction( | ||
| 2349 | __in BURN_PLAN* pPlan, | 2212 | __in BURN_PLAN* pPlan, |
| 2350 | __in_opt BURN_PACKAGE* pPackage, | 2213 | __in BURN_PAYLOAD_GROUP* pPayloadGroup |
| 2351 | __in DWORD iPackageStartAction, | ||
| 2352 | __in BURN_PAYLOAD* pPayload, | ||
| 2353 | __in BOOL fPayloadCached, | ||
| 2354 | __in_z_opt LPCWSTR wzLayoutDirectory | ||
| 2355 | ) | 2214 | ) |
| 2356 | { | 2215 | { |
| 2357 | HRESULT hr = S_OK; | 2216 | HRESULT hr = S_OK; |
| 2358 | LPWSTR sczPayloadWorkingPath = NULL; | ||
| 2359 | BURN_CACHE_ACTION* pCacheAction = NULL; | ||
| 2360 | DWORD iTryAgainAction = BURN_PLAN_INVALID_ACTION_INDEX; | ||
| 2361 | BURN_CACHE_PAYLOAD_PROGRESS* pPayloadProgress = NULL; | ||
| 2362 | |||
| 2363 | hr = CacheCalculatePayloadWorkingPath(pPlan->wzBundleId, pPayload, &sczPayloadWorkingPath); | ||
| 2364 | ExitOnFailure(hr, "Failed to calculate unverified path for payload."); | ||
| 2365 | |||
| 2366 | // If the payload is in a container, ensure the container is being acquired | ||
| 2367 | // then add this payload to the list of payloads to extract already in the plan. | ||
| 2368 | if (pPayload->pContainer) | ||
| 2369 | { | ||
| 2370 | BURN_CACHE_ACTION* pPreviousPackageExtractAction = NULL; | ||
| 2371 | BURN_CACHE_ACTION* pThisPackageExtractAction = NULL; | ||
| 2372 | |||
| 2373 | // If the payload is not already cached, then add it to the first extract container action in the plan. Extracting | ||
| 2374 | // all the needed payloads from the container in a single pass is the most efficient way to extract files from | ||
| 2375 | // containers. If there is not an extract container action before our package, that is okay because we'll create | ||
| 2376 | // an extract container action for our package in a second anyway. | ||
| 2377 | if (!fPayloadCached) | ||
| 2378 | { | ||
| 2379 | if (FindContainerCacheAction(BURN_CACHE_ACTION_TYPE_EXTRACT_CONTAINER, pPlan, pPayload->pContainer, 0, iPackageStartAction, &pPreviousPackageExtractAction, NULL)) | ||
| 2380 | { | ||
| 2381 | hr = AddExtractPayload(pPreviousPackageExtractAction, pPackage, pPayload, sczPayloadWorkingPath); | ||
| 2382 | ExitOnFailure(hr, "Failed to add extract payload action to previous package."); | ||
| 2383 | } | ||
| 2384 | } | ||
| 2385 | |||
| 2386 | // If there is already an extract container action after our package start action then try to find an acquire action | ||
| 2387 | // that is matched with it. If there is an acquire action then that is our "try again" action, otherwise we'll use the existing | ||
| 2388 | // extract action as the "try again" action. | ||
| 2389 | if (FindContainerCacheAction(BURN_CACHE_ACTION_TYPE_EXTRACT_CONTAINER, pPlan, pPayload->pContainer, iPackageStartAction, BURN_PLAN_INVALID_ACTION_INDEX, &pThisPackageExtractAction, &iTryAgainAction)) | ||
| 2390 | { | ||
| 2391 | DWORD iAcquireAction = BURN_PLAN_INVALID_ACTION_INDEX; | ||
| 2392 | if (FindContainerCacheAction(BURN_CACHE_ACTION_TYPE_ACQUIRE_CONTAINER, pPlan, pPayload->pContainer, iPackageStartAction, iTryAgainAction, NULL, &iAcquireAction)) | ||
| 2393 | { | ||
| 2394 | iTryAgainAction = iAcquireAction; | ||
| 2395 | } | ||
| 2396 | } | ||
| 2397 | else // did not find an extract container action for our package. | ||
| 2398 | { | ||
| 2399 | // Ensure there is an extract action (and maybe an acquire action) for every package that has payloads. The | ||
| 2400 | // acquire and extract action will be skipped if the payload is already cached or was added to a previous | ||
| 2401 | // package's extract action above. | ||
| 2402 | // | ||
| 2403 | // These actions always exist (even when they are likely to be skipped) so that "try again" will not | ||
| 2404 | // jump so far back in the plan that you end up extracting payloads for other packages. With these actions | ||
| 2405 | // "try again" will only retry the extraction for payloads in this package. | ||
| 2406 | hr = CreateContainerAcquireAndExtractAction(pPlan, pPayload->pContainer, iPackageStartAction, pPreviousPackageExtractAction ? TRUE : fPayloadCached, &pThisPackageExtractAction, &iTryAgainAction); | ||
| 2407 | ExitOnFailure(hr, "Failed to create container extract action."); | ||
| 2408 | } | ||
| 2409 | ExitOnFailure(hr, "Failed while searching for package's container extract action."); | ||
| 2410 | |||
| 2411 | // We *always* add the payload to this package's extract action even though the extract action | ||
| 2412 | // is probably being skipped until retry if there was a previous package extract action. | ||
| 2413 | hr = AddExtractPayload(pThisPackageExtractAction, pPackage, pPayload, sczPayloadWorkingPath); | ||
| 2414 | ExitOnFailure(hr, "Failed to add extract payload to current package."); | ||
| 2415 | } | ||
| 2416 | else // add a payload acquire action to the plan. | ||
| 2417 | { | ||
| 2418 | // Try to find an existing acquire action for this payload. If one is not found, | ||
| 2419 | // we'll create it. At the same time we will change any cache/layout payload actions | ||
| 2420 | // that would "MOVE" the file to "COPY" so that our new cache/layout action below | ||
| 2421 | // can do the move. | ||
| 2422 | pCacheAction = ProcessSharedPayload(pPlan, pPayload); | ||
| 2423 | if (!pCacheAction) | ||
| 2424 | { | ||
| 2425 | hr = AppendCacheAction(pPlan, &pCacheAction); | ||
| 2426 | ExitOnFailure(hr, "Failed to append cache action to acquire payload."); | ||
| 2427 | |||
| 2428 | pCacheAction->type = BURN_CACHE_ACTION_TYPE_ACQUIRE_PAYLOAD; | ||
| 2429 | pCacheAction->fSkipUntilRetried = fPayloadCached; | ||
| 2430 | pCacheAction->resolvePayload.pPackage = pPackage; | ||
| 2431 | pCacheAction->resolvePayload.pPayload = pPayload; | ||
| 2432 | hr = StrAllocString(&pCacheAction->resolvePayload.sczUnverifiedPath, sczPayloadWorkingPath, 0); | ||
| 2433 | ExitOnFailure(hr, "Failed to copy unverified path for payload to acquire."); | ||
| 2434 | } | ||
| 2435 | |||
| 2436 | iTryAgainAction = static_cast<DWORD>(pCacheAction - pPlan->rgCacheActions); | ||
| 2437 | pCacheAction = NULL; | ||
| 2438 | } | ||
| 2439 | 2217 | ||
| 2440 | Assert(BURN_PLAN_INVALID_ACTION_INDEX != iTryAgainAction); | 2218 | for (DWORD i = 0; i < pPayloadGroup->cPayloads; ++i) |
| 2441 | Assert(BURN_CACHE_ACTION_TYPE_ACQUIRE_CONTAINER == pPlan->rgCacheActions[iTryAgainAction].type || | ||
| 2442 | BURN_CACHE_ACTION_TYPE_EXTRACT_CONTAINER == pPlan->rgCacheActions[iTryAgainAction].type || | ||
| 2443 | BURN_CACHE_ACTION_TYPE_ACQUIRE_PAYLOAD == pPlan->rgCacheActions[iTryAgainAction].type); | ||
| 2444 | |||
| 2445 | hr = AppendCacheAction(pPlan, &pCacheAction); | ||
| 2446 | ExitOnFailure(hr, "Failed to append cache action to cache payload."); | ||
| 2447 | |||
| 2448 | hr = CreatePayloadProgress(pPlan, pPayload, &pPayloadProgress); | ||
| 2449 | ExitOnFailure(hr, "Failed to create payload progress."); | ||
| 2450 | |||
| 2451 | if (!wzLayoutDirectory) | ||
| 2452 | { | 2219 | { |
| 2453 | pCacheAction->type = BURN_CACHE_ACTION_TYPE_CACHE_PAYLOAD; | 2220 | BURN_PAYLOAD* pPayload = pPayloadGroup->rgpPayloads[i]; |
| 2454 | pCacheAction->cachePayload.pPackage = pPackage; | ||
| 2455 | pCacheAction->cachePayload.pPayload = pPayload; | ||
| 2456 | pCacheAction->cachePayload.iProgress = pPayloadProgress->iIndex; | ||
| 2457 | pCacheAction->cachePayload.fMove = TRUE; | ||
| 2458 | pCacheAction->cachePayload.iTryAgainAction = iTryAgainAction; | ||
| 2459 | pCacheAction->cachePayload.sczUnverifiedPath = sczPayloadWorkingPath; | ||
| 2460 | sczPayloadWorkingPath = NULL; | ||
| 2461 | } | ||
| 2462 | else | ||
| 2463 | { | ||
| 2464 | hr = StrAllocString(&pCacheAction->layoutPayload.sczLayoutDirectory, wzLayoutDirectory, 0); | ||
| 2465 | ExitOnFailure(hr, "Failed to copy layout directory into plan."); | ||
| 2466 | |||
| 2467 | pCacheAction->type = BURN_CACHE_ACTION_TYPE_LAYOUT_PAYLOAD; | ||
| 2468 | pCacheAction->layoutPayload.pPackage = pPackage; | ||
| 2469 | pCacheAction->layoutPayload.pPayload = pPayload; | ||
| 2470 | pCacheAction->layoutPayload.iProgress = pPayloadProgress->iIndex; | ||
| 2471 | pCacheAction->layoutPayload.fMove = TRUE; | ||
| 2472 | pCacheAction->layoutPayload.iTryAgainAction = iTryAgainAction; | ||
| 2473 | pCacheAction->layoutPayload.sczUnverifiedPath = sczPayloadWorkingPath; | ||
| 2474 | sczPayloadWorkingPath = NULL; | ||
| 2475 | } | ||
| 2476 | |||
| 2477 | pCacheAction = NULL; | ||
| 2478 | |||
| 2479 | LExit: | ||
| 2480 | ReleaseStr(sczPayloadWorkingPath); | ||
| 2481 | |||
| 2482 | return hr; | ||
| 2483 | } | ||
| 2484 | |||
| 2485 | static BOOL FindContainerCacheAction( | ||
| 2486 | __in BURN_CACHE_ACTION_TYPE type, | ||
| 2487 | __in BURN_PLAN* pPlan, | ||
| 2488 | __in BURN_CONTAINER* pContainer, | ||
| 2489 | __in DWORD iSearchStart, | ||
| 2490 | __in DWORD iSearchEnd, | ||
| 2491 | __out_opt BURN_CACHE_ACTION** ppCacheAction, | ||
| 2492 | __out_opt DWORD* piCacheAction | ||
| 2493 | ) | ||
| 2494 | { | ||
| 2495 | BOOL fFound = FALSE; // assume we won't find what we are looking for. | ||
| 2496 | |||
| 2497 | Assert(BURN_CACHE_ACTION_TYPE_ACQUIRE_CONTAINER == type || BURN_CACHE_ACTION_TYPE_EXTRACT_CONTAINER == type); | ||
| 2498 | |||
| 2499 | iSearchStart = (BURN_PLAN_INVALID_ACTION_INDEX == iSearchStart) ? 0 : iSearchStart; | ||
| 2500 | iSearchEnd = (BURN_PLAN_INVALID_ACTION_INDEX == iSearchEnd) ? pPlan->cCacheActions : iSearchEnd; | ||
| 2501 | 2221 | ||
| 2502 | for (DWORD iSearch = iSearchStart; iSearch < iSearchEnd; ++iSearch) | 2222 | if (pPayload->pContainer && !pPayload->pContainer->fPlanned) |
| 2503 | { | ||
| 2504 | BURN_CACHE_ACTION* pCacheAction = pPlan->rgCacheActions + iSearch; | ||
| 2505 | if (pCacheAction->type == type && | ||
| 2506 | ((BURN_CACHE_ACTION_TYPE_ACQUIRE_CONTAINER == pCacheAction->type && pCacheAction->resolveContainer.pContainer == pContainer) || | ||
| 2507 | (BURN_CACHE_ACTION_TYPE_EXTRACT_CONTAINER == pCacheAction->type && pCacheAction->extractContainer.pContainer == pContainer))) | ||
| 2508 | { | 2223 | { |
| 2509 | if (ppCacheAction) | 2224 | hr = PlanLayoutContainer(pPlan, pPayload->pContainer); |
| 2510 | { | 2225 | ExitOnFailure(hr, "Failed to plan container: %ls", pPayload->pContainer->sczId); |
| 2511 | *ppCacheAction = pCacheAction; | ||
| 2512 | } | ||
| 2513 | |||
| 2514 | if (piCacheAction) | ||
| 2515 | { | ||
| 2516 | *piCacheAction = iSearch; | ||
| 2517 | } | ||
| 2518 | |||
| 2519 | fFound = TRUE; | ||
| 2520 | break; | ||
| 2521 | } | 2226 | } |
| 2522 | } | ||
| 2523 | |||
| 2524 | return fFound; | ||
| 2525 | } | ||
| 2526 | 2227 | ||
| 2527 | static HRESULT CreateContainerAcquireAndExtractAction( | 2228 | if (!pPlan->sczLayoutDirectory || !pPayload->pContainer) |
| 2528 | __in BURN_PLAN* pPlan, | ||
| 2529 | __in BURN_CONTAINER* pContainer, | ||
| 2530 | __in DWORD iPackageStartAction, | ||
| 2531 | __in BOOL fPayloadCached, | ||
| 2532 | __out BURN_CACHE_ACTION** ppContainerExtractAction, | ||
| 2533 | __out DWORD* piContainerTryAgainAction | ||
| 2534 | ) | ||
| 2535 | { | ||
| 2536 | HRESULT hr = S_OK; | ||
| 2537 | DWORD iAcquireAction = BURN_PLAN_INVALID_ACTION_INDEX; | ||
| 2538 | BURN_CACHE_ACTION* pContainerExtractAction = NULL; | ||
| 2539 | DWORD iExtractAction = BURN_PLAN_INVALID_ACTION_INDEX; | ||
| 2540 | DWORD iTryAgainAction = BURN_PLAN_INVALID_ACTION_INDEX; | ||
| 2541 | LPWSTR sczContainerWorkingPath = NULL; | ||
| 2542 | |||
| 2543 | // If the container is actually attached to the executable then we will not need an acquire | ||
| 2544 | // container action. | ||
| 2545 | if (!pContainer->fActuallyAttached) | ||
| 2546 | { | ||
| 2547 | BURN_CACHE_ACTION* pAcquireContainerAction = NULL; | ||
| 2548 | |||
| 2549 | // If there is no plan to acquire the container then add acquire action since we | ||
| 2550 | // can't extract stuff out of a container until we acquire the container. | ||
| 2551 | if (!FindContainerCacheAction(BURN_CACHE_ACTION_TYPE_ACQUIRE_CONTAINER, pPlan, pContainer, iPackageStartAction, BURN_PLAN_INVALID_ACTION_INDEX, &pAcquireContainerAction, &iAcquireAction)) | ||
| 2552 | { | 2229 | { |
| 2553 | hr = AddAcquireContainer(pPlan, pContainer, &pAcquireContainerAction, &iAcquireAction); | 2230 | pPlan->qwCacheSizeTotal += 2 * pPayload->qwFileSize; |
| 2554 | ExitOnFailure(hr, "Failed to append acquire container action to plan."); | ||
| 2555 | |||
| 2556 | pAcquireContainerAction->fSkipUntilRetried = TRUE; // we'll start by assuming the acquire is not necessary and the fPayloadCached below will set us straight if wrong. | ||
| 2557 | } | 2231 | } |
| 2558 | 2232 | ||
| 2559 | Assert(BURN_PLAN_INVALID_ACTION_INDEX != iAcquireAction); | 2233 | if (!pPayload->sczUnverifiedPath) |
| 2560 | Assert(BURN_CACHE_ACTION_TYPE_ACQUIRE_CONTAINER == pAcquireContainerAction->type); | ||
| 2561 | Assert(pContainer == pAcquireContainerAction->resolveContainer.pContainer); | ||
| 2562 | } | ||
| 2563 | |||
| 2564 | Assert((pContainer->fActuallyAttached && BURN_PLAN_INVALID_ACTION_INDEX == iAcquireAction) || | ||
| 2565 | (!pContainer->fActuallyAttached && BURN_PLAN_INVALID_ACTION_INDEX != iAcquireAction)); | ||
| 2566 | |||
| 2567 | // If we do not find an action for extracting payloads from this container, create it now. | ||
| 2568 | 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)) | ||
| 2569 | { | ||
| 2570 | // Attached containers that are actually attached use the executable path for their working path. | ||
| 2571 | if (pContainer->fActuallyAttached) | ||
| 2572 | { | 2234 | { |
| 2573 | Assert(BURN_PLAN_INVALID_ACTION_INDEX == iAcquireAction); | 2235 | hr = CacheCalculatePayloadWorkingPath(pPlan->wzBundleId, pPayload, &pPayload->sczUnverifiedPath); |
| 2574 | 2236 | ExitOnFailure(hr, "Failed to calculate unverified path for payload."); | |
| 2575 | hr = PathForCurrentProcess(&sczContainerWorkingPath, NULL); | ||
| 2576 | ExitOnFailure(hr, "Failed to get path for executing module as attached container working path."); | ||
| 2577 | } | 2237 | } |
| 2578 | else // use the acquired working path as the location of the container. | ||
| 2579 | { | ||
| 2580 | Assert(BURN_PLAN_INVALID_ACTION_INDEX != iAcquireAction); | ||
| 2581 | |||
| 2582 | hr = StrAllocString(&sczContainerWorkingPath, pPlan->rgCacheActions[iAcquireAction].resolveContainer.sczUnverifiedPath, 0); | ||
| 2583 | ExitOnFailure(hr, "Failed to copy container unverified path for cache action to extract container."); | ||
| 2584 | } | ||
| 2585 | |||
| 2586 | hr = AppendCacheAction(pPlan, &pContainerExtractAction); | ||
| 2587 | ExitOnFailure(hr, "Failed to append cache action to extract payloads from container."); | ||
| 2588 | |||
| 2589 | iExtractAction = pPlan->cCacheActions - 1; | ||
| 2590 | |||
| 2591 | pContainerExtractAction->type = BURN_CACHE_ACTION_TYPE_EXTRACT_CONTAINER; | ||
| 2592 | 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. | ||
| 2593 | pContainerExtractAction->extractContainer.pContainer = pContainer; | ||
| 2594 | pContainerExtractAction->extractContainer.iSkipUntilAcquiredByAction = iAcquireAction; | ||
| 2595 | pContainerExtractAction->extractContainer.sczContainerUnverifiedPath = sczContainerWorkingPath; | ||
| 2596 | sczContainerWorkingPath = NULL; | ||
| 2597 | } | ||
| 2598 | |||
| 2599 | Assert(BURN_CACHE_ACTION_TYPE_EXTRACT_CONTAINER == pContainerExtractAction->type); | ||
| 2600 | Assert(BURN_PLAN_INVALID_ACTION_INDEX != iExtractAction); | ||
| 2601 | |||
| 2602 | // If there is an acquire action, that is our try again action. Otherwise, we'll use the extract action. | ||
| 2603 | iTryAgainAction = (BURN_PLAN_INVALID_ACTION_INDEX != iAcquireAction) ? iAcquireAction : iExtractAction; | ||
| 2604 | |||
| 2605 | // If the try again action thinks it can be skipped but the payload is not cached, | ||
| 2606 | // ensure the action will not be skipped. | ||
| 2607 | BURN_CACHE_ACTION* pTryAgainAction = pPlan->rgCacheActions + iTryAgainAction; | ||
| 2608 | Assert((BURN_CACHE_ACTION_TYPE_ACQUIRE_CONTAINER == pTryAgainAction->type && pContainer == pTryAgainAction->resolveContainer.pContainer) || | ||
| 2609 | (BURN_CACHE_ACTION_TYPE_EXTRACT_CONTAINER == pTryAgainAction->type && pContainer == pTryAgainAction->extractContainer.pContainer)); | ||
| 2610 | if (pTryAgainAction->fSkipUntilRetried && !fPayloadCached) | ||
| 2611 | { | ||
| 2612 | pTryAgainAction->fSkipUntilRetried = FALSE; | ||
| 2613 | } | ||
| 2614 | |||
| 2615 | *ppContainerExtractAction = pContainerExtractAction; | ||
| 2616 | *piContainerTryAgainAction = iTryAgainAction; | ||
| 2617 | |||
| 2618 | LExit: | ||
| 2619 | ReleaseStr(sczContainerWorkingPath); | ||
| 2620 | |||
| 2621 | return hr; | ||
| 2622 | } | ||
| 2623 | |||
| 2624 | static HRESULT AddAcquireContainer( | ||
| 2625 | __in BURN_PLAN* pPlan, | ||
| 2626 | __in BURN_CONTAINER* pContainer, | ||
| 2627 | __out_opt BURN_CACHE_ACTION** ppCacheAction, | ||
| 2628 | __out_opt DWORD* piCacheAction | ||
| 2629 | ) | ||
| 2630 | { | ||
| 2631 | HRESULT hr = S_OK; | ||
| 2632 | LPWSTR sczContainerWorkingPath = NULL; | ||
| 2633 | BURN_CACHE_ACTION* pAcquireContainerAction = NULL; | ||
| 2634 | BURN_CACHE_CONTAINER_PROGRESS* pContainerProgress = NULL; | ||
| 2635 | |||
| 2636 | hr = CacheCalculateContainerWorkingPath(pPlan->wzBundleId, pContainer, &sczContainerWorkingPath); | ||
| 2637 | ExitOnFailure(hr, "Failed to calculate unverified path for container."); | ||
| 2638 | |||
| 2639 | hr = AppendCacheAction(pPlan, &pAcquireContainerAction); | ||
| 2640 | ExitOnFailure(hr, "Failed to append acquire container action to plan."); | ||
| 2641 | |||
| 2642 | hr = CreateContainerProgress(pPlan, pContainer, &pContainerProgress); | ||
| 2643 | ExitOnFailure(hr, "Failed to create container progress."); | ||
| 2644 | |||
| 2645 | pAcquireContainerAction->type = BURN_CACHE_ACTION_TYPE_ACQUIRE_CONTAINER; | ||
| 2646 | pAcquireContainerAction->resolveContainer.pContainer = pContainer; | ||
| 2647 | pAcquireContainerAction->resolveContainer.iProgress = pContainerProgress->iIndex; | ||
| 2648 | pAcquireContainerAction->resolveContainer.sczUnverifiedPath = sczContainerWorkingPath; | ||
| 2649 | sczContainerWorkingPath = NULL; | ||
| 2650 | |||
| 2651 | if (ppCacheAction) | ||
| 2652 | { | ||
| 2653 | *ppCacheAction = pAcquireContainerAction; | ||
| 2654 | } | ||
| 2655 | |||
| 2656 | if (piCacheAction) | ||
| 2657 | { | ||
| 2658 | *piCacheAction = pPlan->cCacheActions - 1; | ||
| 2659 | } | 2238 | } |
| 2660 | 2239 | ||
| 2661 | LExit: | 2240 | LExit: |
| 2662 | ReleaseStr(sczContainerWorkingPath); | ||
| 2663 | |||
| 2664 | return hr; | ||
| 2665 | } | ||
| 2666 | |||
| 2667 | static HRESULT AddExtractPayload( | ||
| 2668 | __in BURN_CACHE_ACTION* pCacheAction, | ||
| 2669 | __in_opt BURN_PACKAGE* pPackage, | ||
| 2670 | __in BURN_PAYLOAD* pPayload, | ||
| 2671 | __in_z LPCWSTR wzPayloadWorkingPath | ||
| 2672 | ) | ||
| 2673 | { | ||
| 2674 | HRESULT hr = S_OK; | ||
| 2675 | |||
| 2676 | Assert(BURN_CACHE_ACTION_TYPE_EXTRACT_CONTAINER == pCacheAction->type); | ||
| 2677 | |||
| 2678 | hr = MemEnsureArraySize(reinterpret_cast<LPVOID*>(&pCacheAction->extractContainer.rgPayloads), pCacheAction->extractContainer.cPayloads + 1, sizeof(BURN_EXTRACT_PAYLOAD), 5); | ||
| 2679 | ExitOnFailure(hr, "Failed to grow list of payloads to extract from container."); | ||
| 2680 | |||
| 2681 | BURN_EXTRACT_PAYLOAD* pExtractPayload = pCacheAction->extractContainer.rgPayloads + pCacheAction->extractContainer.cPayloads; | ||
| 2682 | pExtractPayload->pPackage = pPackage; | ||
| 2683 | pExtractPayload->pPayload = pPayload; | ||
| 2684 | hr = StrAllocString(&pExtractPayload->sczUnverifiedPath, wzPayloadWorkingPath, 0); | ||
| 2685 | ExitOnFailure(hr, "Failed to copy unverified path for payload to extract."); | ||
| 2686 | ++pCacheAction->extractContainer.cPayloads; | ||
| 2687 | |||
| 2688 | LExit: | ||
| 2689 | return hr; | 2241 | return hr; |
| 2690 | } | 2242 | } |
| 2691 | 2243 | ||
| 2692 | static BURN_CACHE_ACTION* ProcessSharedPayload( | ||
| 2693 | __in BURN_PLAN* pPlan, | ||
| 2694 | __in BURN_PAYLOAD* pPayload | ||
| 2695 | ) | ||
| 2696 | { | ||
| 2697 | BURN_CACHE_ACTION* pAcquireAction = NULL; | ||
| 2698 | #ifdef DEBUG | ||
| 2699 | DWORD cMove = 0; | ||
| 2700 | #endif | ||
| 2701 | |||
| 2702 | for (DWORD i = 0; i < pPlan->cCacheActions; ++i) | ||
| 2703 | { | ||
| 2704 | BURN_CACHE_ACTION* pCacheAction = pPlan->rgCacheActions + i; | ||
| 2705 | |||
| 2706 | if (BURN_CACHE_ACTION_TYPE_ACQUIRE_PAYLOAD == pCacheAction->type && | ||
| 2707 | pCacheAction->resolvePayload.pPayload == pPayload) | ||
| 2708 | { | ||
| 2709 | AssertSz(!pAcquireAction, "There should be at most one acquire cache action per payload."); | ||
| 2710 | pAcquireAction = pCacheAction; | ||
| 2711 | } | ||
| 2712 | else if (BURN_CACHE_ACTION_TYPE_CACHE_PAYLOAD == pCacheAction->type && | ||
| 2713 | pCacheAction->cachePayload.pPayload == pPayload && | ||
| 2714 | pCacheAction->cachePayload.fMove) | ||
| 2715 | { | ||
| 2716 | // Since we found a shared payload, change its operation from MOVE to COPY. | ||
| 2717 | pCacheAction->cachePayload.fMove = FALSE; | ||
| 2718 | |||
| 2719 | AssertSz(1 == ++cMove, "Shared payload should be moved once and only once."); | ||
| 2720 | #ifndef DEBUG | ||
| 2721 | break; | ||
| 2722 | #endif | ||
| 2723 | } | ||
| 2724 | else if (BURN_CACHE_ACTION_TYPE_LAYOUT_PAYLOAD == pCacheAction->type && | ||
| 2725 | pCacheAction->layoutPayload.pPayload == pPayload && | ||
| 2726 | pCacheAction->layoutPayload.fMove) | ||
| 2727 | { | ||
| 2728 | // Since we found a shared payload, change its operation from MOVE to COPY if necessary | ||
| 2729 | pCacheAction->layoutPayload.fMove = FALSE; | ||
| 2730 | |||
| 2731 | AssertSz(1 == ++cMove, "Shared payload should be moved once and only once."); | ||
| 2732 | #ifndef DEBUG | ||
| 2733 | break; | ||
| 2734 | #endif | ||
| 2735 | } | ||
| 2736 | } | ||
| 2737 | |||
| 2738 | return pAcquireAction; | ||
| 2739 | } | ||
| 2740 | |||
| 2741 | static void RemoveUnnecessaryActions( | 2244 | static void RemoveUnnecessaryActions( |
| 2742 | __in BOOL fExecute, | 2245 | __in BOOL fExecute, |
| 2743 | __in BURN_EXECUTE_ACTION* rgActions, | 2246 | __in BURN_EXECUTE_ACTION* rgActions, |
| @@ -2984,86 +2487,6 @@ static BOOL NeedsCache( | |||
| 2984 | } | 2487 | } |
| 2985 | } | 2488 | } |
| 2986 | 2489 | ||
| 2987 | static HRESULT CreateContainerProgress( | ||
| 2988 | __in BURN_PLAN* pPlan, | ||
| 2989 | __in BURN_CONTAINER* pContainer, | ||
| 2990 | __out BURN_CACHE_CONTAINER_PROGRESS** ppContainerProgress | ||
| 2991 | ) | ||
| 2992 | { | ||
| 2993 | HRESULT hr = S_OK; | ||
| 2994 | BURN_CACHE_CONTAINER_PROGRESS* pContainerProgress = NULL; | ||
| 2995 | |||
| 2996 | hr = MemEnsureArraySize(reinterpret_cast<LPVOID*>(&pPlan->rgContainerProgress), pPlan->cContainerProgress + 1, sizeof(BURN_CACHE_CONTAINER_PROGRESS), 5); | ||
| 2997 | ExitOnFailure(hr, "Failed to grow container progress list."); | ||
| 2998 | |||
| 2999 | if (!pPlan->shContainerProgress) | ||
| 3000 | { | ||
| 3001 | hr = DictCreateWithEmbeddedKey(&pPlan->shContainerProgress, 5, reinterpret_cast<void **>(&pPlan->rgContainerProgress), offsetof(BURN_CACHE_CONTAINER_PROGRESS, wzId), DICT_FLAG_NONE); | ||
| 3002 | ExitOnFailure(hr, "Failed to create container progress dictionary."); | ||
| 3003 | } | ||
| 3004 | |||
| 3005 | hr = DictGetValue(pPlan->shContainerProgress, pContainer->sczId, reinterpret_cast<void **>(&pContainerProgress)); | ||
| 3006 | if (E_NOTFOUND == hr) | ||
| 3007 | { | ||
| 3008 | pContainerProgress = &pPlan->rgContainerProgress[pPlan->cContainerProgress]; | ||
| 3009 | pContainerProgress->iIndex = pPlan->cContainerProgress; | ||
| 3010 | pContainerProgress->pContainer = pContainer; | ||
| 3011 | pContainerProgress->wzId = pContainer->sczId; | ||
| 3012 | |||
| 3013 | hr = DictAddValue(pPlan->shContainerProgress, pContainerProgress); | ||
| 3014 | ExitOnFailure(hr, "Failed to add \"%ls\" to the container progress dictionary.", pContainerProgress->wzId); | ||
| 3015 | |||
| 3016 | ++pPlan->cContainerProgress; | ||
| 3017 | pPlan->qwCacheSizeTotal += pContainer->qwFileSize; | ||
| 3018 | } | ||
| 3019 | ExitOnFailure(hr, "Failed to retrieve \"%ls\" from the container progress dictionary.", pContainer->sczId); | ||
| 3020 | |||
| 3021 | *ppContainerProgress = pContainerProgress; | ||
| 3022 | |||
| 3023 | LExit: | ||
| 3024 | return hr; | ||
| 3025 | } | ||
| 3026 | |||
| 3027 | static HRESULT CreatePayloadProgress( | ||
| 3028 | __in BURN_PLAN* pPlan, | ||
| 3029 | __in BURN_PAYLOAD* pPayload, | ||
| 3030 | __out BURN_CACHE_PAYLOAD_PROGRESS** ppPayloadProgress | ||
| 3031 | ) | ||
| 3032 | { | ||
| 3033 | HRESULT hr = S_OK; | ||
| 3034 | BURN_CACHE_PAYLOAD_PROGRESS* pPayloadProgress = NULL; | ||
| 3035 | |||
| 3036 | hr = MemEnsureArraySize(reinterpret_cast<LPVOID*>(&pPlan->rgPayloadProgress), pPlan->cPayloadProgress + 1, sizeof(BURN_CACHE_PAYLOAD_PROGRESS), 5); | ||
| 3037 | ExitOnFailure(hr, "Failed to grow payload progress list."); | ||
| 3038 | |||
| 3039 | if (!pPlan->shPayloadProgress) | ||
| 3040 | { | ||
| 3041 | hr = DictCreateWithEmbeddedKey(&pPlan->shPayloadProgress, 5, reinterpret_cast<void **>(&pPlan->rgPayloadProgress), offsetof(BURN_CACHE_PAYLOAD_PROGRESS, wzId), DICT_FLAG_NONE); | ||
| 3042 | ExitOnFailure(hr, "Failed to create payload progress dictionary."); | ||
| 3043 | } | ||
| 3044 | |||
| 3045 | hr = DictGetValue(pPlan->shPayloadProgress, pPayload->sczKey, reinterpret_cast<void **>(&pPayloadProgress)); | ||
| 3046 | if (E_NOTFOUND == hr) | ||
| 3047 | { | ||
| 3048 | pPayloadProgress = &pPlan->rgPayloadProgress[pPlan->cPayloadProgress]; | ||
| 3049 | pPayloadProgress->iIndex = pPlan->cPayloadProgress; | ||
| 3050 | pPayloadProgress->pPayload = pPayload; | ||
| 3051 | pPayloadProgress->wzId = pPayload->sczKey; | ||
| 3052 | |||
| 3053 | hr = DictAddValue(pPlan->shPayloadProgress, pPayloadProgress); | ||
| 3054 | ExitOnFailure(hr, "Failed to add \"%ls\" to the payload progress dictionary.", pPayloadProgress->wzId); | ||
| 3055 | |||
| 3056 | ++pPlan->cPayloadProgress; | ||
| 3057 | pPlan->qwCacheSizeTotal += pPayload->qwFileSize; | ||
| 3058 | } | ||
| 3059 | ExitOnFailure(hr, "Failed to retrieve \"%ls\" from the payload progress dictionary.", pPayload->sczKey); | ||
| 3060 | |||
| 3061 | *ppPayloadProgress = pPayloadProgress; | ||
| 3062 | |||
| 3063 | LExit: | ||
| 3064 | return hr; | ||
| 3065 | } | ||
| 3066 | |||
| 3067 | static void CacheActionLog( | 2490 | static void CacheActionLog( |
| 3068 | __in DWORD iAction, | 2491 | __in DWORD iAction, |
| 3069 | __in BURN_CACHE_ACTION* pAction, | 2492 | __in BURN_CACHE_ACTION* pAction, |
| @@ -3073,60 +2496,28 @@ static void CacheActionLog( | |||
| 3073 | LPCWSTR wzBase = fRollback ? L" Rollback cache" : L" Cache"; | 2496 | LPCWSTR wzBase = fRollback ? L" Rollback cache" : L" Cache"; |
| 3074 | switch (pAction->type) | 2497 | switch (pAction->type) |
| 3075 | { | 2498 | { |
| 3076 | case BURN_CACHE_ACTION_TYPE_ACQUIRE_CONTAINER: | ||
| 3077 | 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)); | ||
| 3078 | break; | ||
| 3079 | |||
| 3080 | case BURN_CACHE_ACTION_TYPE_ACQUIRE_PAYLOAD: | ||
| 3081 | 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)); | ||
| 3082 | break; | ||
| 3083 | |||
| 3084 | case BURN_CACHE_ACTION_TYPE_CACHE_PAYLOAD: | ||
| 3085 | 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); | ||
| 3086 | break; | ||
| 3087 | |||
| 3088 | case BURN_CACHE_ACTION_TYPE_CHECKPOINT: | 2499 | case BURN_CACHE_ACTION_TYPE_CHECKPOINT: |
| 3089 | LogStringLine(PlanDumpLevel, "%ls action[%u]: CHECKPOINT id: %u", wzBase, iAction, pAction->checkpoint.dwId); | 2500 | LogStringLine(PlanDumpLevel, "%ls action[%u]: CHECKPOINT id: %u", wzBase, iAction, pAction->checkpoint.dwId); |
| 3090 | break; | 2501 | break; |
| 3091 | 2502 | ||
| 3092 | case BURN_CACHE_ACTION_TYPE_EXTRACT_CONTAINER: | ||
| 3093 | 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); | ||
| 3094 | for (DWORD j = 0; j < pAction->extractContainer.cPayloads; j++) | ||
| 3095 | { | ||
| 3096 | 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); | ||
| 3097 | } | ||
| 3098 | break; | ||
| 3099 | |||
| 3100 | case BURN_CACHE_ACTION_TYPE_LAYOUT_BUNDLE: | 2503 | case BURN_CACHE_ACTION_TYPE_LAYOUT_BUNDLE: |
| 3101 | 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)); | 2504 | LogStringLine(PlanDumpLevel, "%ls action[%u]: LAYOUT_BUNDLE working path: %ls, exe name: %ls", wzBase, iAction, pAction->bundleLayout.sczUnverifiedPath, pAction->bundleLayout.sczExecutableName); |
| 3102 | break; | ||
| 3103 | |||
| 3104 | case BURN_CACHE_ACTION_TYPE_LAYOUT_CONTAINER: | ||
| 3105 | 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); | ||
| 3106 | break; | ||
| 3107 | |||
| 3108 | case BURN_CACHE_ACTION_TYPE_LAYOUT_PAYLOAD: | ||
| 3109 | 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); | ||
| 3110 | break; | 2505 | break; |
| 3111 | 2506 | ||
| 3112 | case BURN_CACHE_ACTION_TYPE_PACKAGE_START: | 2507 | case BURN_CACHE_ACTION_TYPE_CONTAINER: |
| 3113 | 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)); | 2508 | LogStringLine(PlanDumpLevel, "%ls action[%u]: CONTAINER container id: %ls, working path: %ls", wzBase, iAction, pAction->container.pContainer->sczId, pAction->container.pContainer->sczUnverifiedPath); |
| 3114 | break; | 2509 | break; |
| 3115 | 2510 | ||
| 3116 | case BURN_CACHE_ACTION_TYPE_PACKAGE_STOP: | 2511 | case BURN_CACHE_ACTION_TYPE_PACKAGE: |
| 3117 | LogStringLine(PlanDumpLevel, "%ls action[%u]: PACKAGE_STOP id: %ls, skip until retried: %hs", wzBase, iAction, pAction->packageStop.pPackage->sczId, LoggingBoolToString(pAction->fSkipUntilRetried)); | 2512 | LogStringLine(PlanDumpLevel, "%ls action[%u]: PACKAGE id: %ls", wzBase, iAction, pAction->package.pPackage->sczId); |
| 3118 | break; | 2513 | break; |
| 3119 | 2514 | ||
| 3120 | case BURN_CACHE_ACTION_TYPE_ROLLBACK_PACKAGE: | 2515 | case BURN_CACHE_ACTION_TYPE_ROLLBACK_PACKAGE: |
| 3121 | LogStringLine(PlanDumpLevel, "%ls action[%u]: ROLLBACK_PACKAGE id: %ls, skip until retried: %hs", wzBase, iAction, pAction->rollbackPackage.pPackage->sczId, LoggingBoolToString(pAction->fSkipUntilRetried)); | 2516 | LogStringLine(PlanDumpLevel, "%ls action[%u]: ROLLBACK_PACKAGE id: %ls", wzBase, iAction, pAction->rollbackPackage.pPackage->sczId); |
| 3122 | break; | 2517 | break; |
| 3123 | 2518 | ||
| 3124 | case BURN_CACHE_ACTION_TYPE_SIGNAL_SYNCPOINT: | 2519 | case BURN_CACHE_ACTION_TYPE_SIGNAL_SYNCPOINT: |
| 3125 | LogStringLine(PlanDumpLevel, "%ls action[%u]: SIGNAL_SYNCPOINT event handle: 0x%p, skip until retried: %hs", wzBase, iAction, pAction->syncpoint.hEvent, LoggingBoolToString(pAction->fSkipUntilRetried)); | 2520 | LogStringLine(PlanDumpLevel, "%ls action[%u]: SIGNAL_SYNCPOINT event handle: 0x%p", wzBase, iAction, pAction->syncpoint.hEvent); |
| 3126 | break; | ||
| 3127 | |||
| 3128 | case BURN_CACHE_ACTION_TYPE_TRANSACTION_BOUNDARY: | ||
| 3129 | 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"); | ||
| 3130 | break; | 2521 | break; |
| 3131 | 2522 | ||
| 3132 | default: | 2523 | default: |
| @@ -3222,6 +2613,10 @@ extern "C" void PlanDump( | |||
| 3222 | LogStringLine(PlanDumpLevel, " per-machine: %hs", LoggingTrueFalseToString(pPlan->fPerMachine)); | 2613 | LogStringLine(PlanDumpLevel, " per-machine: %hs", LoggingTrueFalseToString(pPlan->fPerMachine)); |
| 3223 | LogStringLine(PlanDumpLevel, " disable-rollback: %hs", LoggingTrueFalseToString(pPlan->fDisableRollback)); | 2614 | LogStringLine(PlanDumpLevel, " disable-rollback: %hs", LoggingTrueFalseToString(pPlan->fDisableRollback)); |
| 3224 | LogStringLine(PlanDumpLevel, " estimated size: %llu", pPlan->qwEstimatedSize); | 2615 | LogStringLine(PlanDumpLevel, " estimated size: %llu", pPlan->qwEstimatedSize); |
| 2616 | if (pPlan->sczLayoutDirectory) | ||
| 2617 | { | ||
| 2618 | LogStringLine(PlanDumpLevel, " layout directory: %ls", pPlan->sczLayoutDirectory); | ||
| 2619 | } | ||
| 3225 | 2620 | ||
| 3226 | LogStringLine(PlanDumpLevel, "Plan cache size: %llu", pPlan->qwCacheSizeTotal); | 2621 | LogStringLine(PlanDumpLevel, "Plan cache size: %llu", pPlan->qwCacheSizeTotal); |
| 3227 | for (DWORD i = 0; i < pPlan->cCacheActions; ++i) | 2622 | for (DWORD i = 0; i < pPlan->cCacheActions; ++i) |
