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) |