aboutsummaryrefslogtreecommitdiff
path: root/src/engine/plan.cpp
diff options
context:
space:
mode:
authorSean Hall <r.sean.hall@gmail.com>2021-04-16 10:09:26 -0500
committerSean Hall <r.sean.hall@gmail.com>2021-04-19 23:12:55 -0500
commit90cdf39e6e6b7d676ca33bee031fa2b865bb5fbd (patch)
tree901feb035d5ea9a13f306582cedd6668b539953f /src/engine/plan.cpp
parentc88806b89293f5bb92c42e90230e48be6b79b7f4 (diff)
downloadwix-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.cpp893
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(
15static void UninitializeCacheAction( 15static void UninitializeCacheAction(
16 __in BURN_CACHE_ACTION* pCacheAction 16 __in BURN_CACHE_ACTION* pCacheAction
17 ); 17 );
18static void ResetPlannedContainerState(
19 __in BURN_CONTAINER* pContainer
20 );
21static void ResetPlannedPayloadsState(
22 __in BURN_PAYLOADS* pPayloads
23 );
24static void ResetPlannedPayloadGroupState(
25 __in BURN_PAYLOAD_GROUP* pPayloadGroup
26 );
18static void ResetPlannedPackageState( 27static 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 );
36static HRESULT InitializePackage( 44static 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 );
102static HRESULT AppendLayoutContainerAction( 109static 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 );
110static 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 );
118static 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 );
127static 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 );
135static 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 );
141static 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 );
147static BURN_CACHE_ACTION* ProcessSharedPayload(
148 __in BURN_PLAN* pPlan,
149 __in BURN_PAYLOAD* pPayload
150 ); 112 );
151static void RemoveUnnecessaryActions( 113static 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 );
178static HRESULT CreateContainerProgress(
179 __in BURN_PLAN* pPlan,
180 __in BURN_CONTAINER* pContainer,
181 __out BURN_CACHE_CONTAINER_PROGRESS** ppContainerProgress
182 );
183static 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
191extern "C" void PlanReset( 143extern "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
485LExit: 438LExit:
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
788LExit: 739LExit:
@@ -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
808LExit: 759LExit:
@@ -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
1038extern "C" HRESULT PlanLayoutPackage( 987extern "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. 1030LExit:
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; 1034extern "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: 1821static 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: 1828static 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
1841static void ResetPlannedPayloadGroupState(
1842 __in BURN_PAYLOAD_GROUP* /*pPayloadGroup*/
1843 )
1844{
1845}
1846
1880static void ResetPlannedPackageState( 1847static 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
1936static void ResetPlannedRollbackBoundaryState( 1905static 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
2287static HRESULT AppendLayoutContainerAction( 2211static 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
2342LExit:
2343 ReleaseNullStr(sczContainerWorkingPath);
2344
2345 return hr;
2346}
2347
2348static 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
2479LExit:
2480 ReleaseStr(sczPayloadWorkingPath);
2481
2482 return hr;
2483}
2484
2485static 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
2527static 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
2618LExit:
2619 ReleaseStr(sczContainerWorkingPath);
2620
2621 return hr;
2622}
2623
2624static 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
2661LExit: 2240LExit:
2662 ReleaseStr(sczContainerWorkingPath);
2663
2664 return hr;
2665}
2666
2667static 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
2688LExit:
2689 return hr; 2241 return hr;
2690} 2242}
2691 2243
2692static 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
2741static void RemoveUnnecessaryActions( 2244static 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
2987static 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
3023LExit:
3024 return hr;
3025}
3026
3027static 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
3063LExit:
3064 return hr;
3065}
3066
3067static void CacheActionLog( 2490static 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)