aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSean Hall <r.sean.hall@gmail.com>2021-08-03 15:41:18 -0500
committerSean Hall <r.sean.hall@gmail.com>2021-08-04 10:03:57 -0500
commit6d7a275edafb3ae0f3cff94d66503a82dafb71f7 (patch)
treefae8f75e2cd1d7b179b0ed93e15625d68ba7c441 /src
parented57d171f6fb6bb4e180696cc12caa568599566a (diff)
downloadwix-6d7a275edafb3ae0f3cff94d66503a82dafb71f7.tar.gz
wix-6d7a275edafb3ae0f3cff94d66503a82dafb71f7.tar.bz2
wix-6d7a275edafb3ae0f3cff94d66503a82dafb71f7.zip
Replace static cache internals with a struct.
Initialize them explicitly to make it clearer when that happens.
Diffstat (limited to 'src')
-rw-r--r--src/burn/engine/apply.cpp34
-rw-r--r--src/burn/engine/approvedexe.cpp3
-rw-r--r--src/burn/engine/approvedexe.h6
-rw-r--r--src/burn/engine/cache.cpp505
-rw-r--r--src/burn/engine/cache.h57
-rw-r--r--src/burn/engine/core.cpp23
-rw-r--r--src/burn/engine/core.h2
-rw-r--r--src/burn/engine/elevation.cpp74
-rw-r--r--src/burn/engine/elevation.h1
-rw-r--r--src/burn/engine/engine.cpp18
-rw-r--r--src/burn/engine/exeengine.cpp3
-rw-r--r--src/burn/engine/exeengine.h1
-rw-r--r--src/burn/engine/manifest.cpp2
-rw-r--r--src/burn/engine/msiengine.cpp11
-rw-r--r--src/burn/engine/msiengine.h1
-rw-r--r--src/burn/engine/mspengine.cpp3
-rw-r--r--src/burn/engine/mspengine.h1
-rw-r--r--src/burn/engine/msuengine.cpp3
-rw-r--r--src/burn/engine/msuengine.h1
-rw-r--r--src/burn/engine/plan.cpp8
-rw-r--r--src/burn/engine/plan.h3
-rw-r--r--src/burn/engine/precomp.h2
-rw-r--r--src/burn/engine/registration.cpp17
-rw-r--r--src/burn/engine/registration.h3
-rw-r--r--src/burn/engine/uithread.cpp12
-rw-r--r--src/burn/engine/userexperience.cpp4
-rw-r--r--src/burn/engine/userexperience.h4
-rw-r--r--src/burn/test/BurnUnitTest/CacheTest.cpp7
-rw-r--r--src/burn/test/BurnUnitTest/ManifestTest.cpp3
-rw-r--r--src/burn/test/BurnUnitTest/PlanTest.cpp6
-rw-r--r--src/burn/test/BurnUnitTest/RegistrationTest.cpp78
-rw-r--r--src/burn/test/BurnUnitTest/precomp.h2
32 files changed, 526 insertions, 372 deletions
diff --git a/src/burn/engine/apply.cpp b/src/burn/engine/apply.cpp
index c126d63c..002158b6 100644
--- a/src/burn/engine/apply.cpp
+++ b/src/burn/engine/apply.cpp
@@ -26,6 +26,7 @@ enum BURN_CACHE_PROGRESS_TYPE
26 26
27typedef struct _BURN_CACHE_CONTEXT 27typedef struct _BURN_CACHE_CONTEXT
28{ 28{
29 BURN_CACHE* pCache;
29 BURN_USER_EXPERIENCE* pUX; 30 BURN_USER_EXPERIENCE* pUX;
30 BURN_VARIABLES* pVariables; 31 BURN_VARIABLES* pVariables;
31 BURN_PAYLOADS* pPayloads; 32 BURN_PAYLOADS* pPayloads;
@@ -55,6 +56,7 @@ typedef struct _BURN_CACHE_PROGRESS_CONTEXT
55 56
56typedef struct _BURN_EXECUTE_CONTEXT 57typedef struct _BURN_EXECUTE_CONTEXT
57{ 58{
59 BURN_CACHE* pCache;
58 BURN_USER_EXPERIENCE* pUX; 60 BURN_USER_EXPERIENCE* pUX;
59 BURN_APPLY_CONTEXT* pApplyContext; 61 BURN_APPLY_CONTEXT* pApplyContext;
60 BOOL fRollback; 62 BOOL fRollback;
@@ -269,6 +271,7 @@ static void ResetTransactionRegistrationState(
269 __in BOOL fCommit 271 __in BOOL fCommit
270 ); 272 );
271static HRESULT CleanPackage( 273static HRESULT CleanPackage(
274 __in BURN_CACHE* pCache,
272 __in HANDLE hElevatedPipe, 275 __in HANDLE hElevatedPipe,
273 __in BURN_PACKAGE* pPackage 276 __in BURN_PACKAGE* pPackage
274 ); 277 );
@@ -401,7 +404,7 @@ extern "C" HRESULT ApplyRegister(
401 } 404 }
402 else // need to complete registration on the machine. 405 else // need to complete registration on the machine.
403 { 406 {
404 hr = CacheCalculateBundleWorkingPath(pEngineState->registration.sczId, pEngineState->registration.sczExecutableName, &sczEngineWorkingPath); 407 hr = CacheCalculateBundleWorkingPath(pEngineState->plan.pCache, pEngineState->registration.sczExecutableName, &sczEngineWorkingPath);
405 ExitOnFailure(hr, "Failed to calculate working path for engine."); 408 ExitOnFailure(hr, "Failed to calculate working path for engine.");
406 409
407 // begin new session 410 // begin new session
@@ -412,7 +415,7 @@ extern "C" HRESULT ApplyRegister(
412 } 415 }
413 else 416 else
414 { 417 {
415 hr = RegistrationSessionBegin(sczEngineWorkingPath, &pEngineState->registration, &pEngineState->variables, pEngineState->plan.dwRegistrationOperations, pEngineState->plan.dependencyRegistrationAction, pEngineState->plan.qwEstimatedSize, registrationType); 418 hr = RegistrationSessionBegin(sczEngineWorkingPath, &pEngineState->registration, &pEngineState->cache, &pEngineState->variables, pEngineState->plan.dwRegistrationOperations, pEngineState->plan.dependencyRegistrationAction, pEngineState->plan.qwEstimatedSize, registrationType);
416 ExitOnFailure(hr, "Failed to begin registration session."); 419 ExitOnFailure(hr, "Failed to begin registration session.");
417 } 420 }
418 } 421 }
@@ -501,7 +504,7 @@ extern "C" HRESULT ApplyUnregister(
501 } 504 }
502 else 505 else
503 { 506 {
504 hr = RegistrationSessionEnd(&pEngineState->registration, &pEngineState->variables, &pEngineState->packages, resumeMode, restart, pEngineState->plan.dependencyRegistrationAction, registrationType); 507 hr = RegistrationSessionEnd(&pEngineState->registration, &pEngineState->cache, &pEngineState->variables, &pEngineState->packages, resumeMode, restart, pEngineState->plan.dependencyRegistrationAction, registrationType);
505 ExitOnFailure(hr, "Failed to end session in per-user process."); 508 ExitOnFailure(hr, "Failed to end session in per-user process.");
506 } 509 }
507 510
@@ -531,6 +534,7 @@ extern "C" HRESULT ApplyCache(
531 ExitOnRootFailure(hr, "BA aborted cache."); 534 ExitOnRootFailure(hr, "BA aborted cache.");
532 535
533 cacheContext.hSourceEngineFile = hSourceEngineFile; 536 cacheContext.hSourceEngineFile = hSourceEngineFile;
537 cacheContext.pCache = pPlan->pCache;
534 cacheContext.pPayloads = pPlan->pPayloads; 538 cacheContext.pPayloads = pPlan->pPayloads;
535 cacheContext.pUX = pUX; 539 cacheContext.pUX = pUX;
536 cacheContext.pVariables = pVariables; 540 cacheContext.pVariables = pVariables;
@@ -568,7 +572,7 @@ extern "C" HRESULT ApplyCache(
568 { 572 {
569 if (!pPackage->fPerMachine || INVALID_HANDLE_VALUE == cacheContext.hPipe) 573 if (!pPackage->fPerMachine || INVALID_HANDLE_VALUE == cacheContext.hPipe)
570 { 574 {
571 hr = CachePreparePackage(pPackage); 575 hr = CachePreparePackage(pPlan->pCache, pPackage);
572 576
573 cacheContext.hPipe = INVALID_HANDLE_VALUE; 577 cacheContext.hPipe = INVALID_HANDLE_VALUE;
574 } 578 }
@@ -616,7 +620,7 @@ LExit:
616 ElevationCacheCleanup(hPipe); 620 ElevationCacheCleanup(hPipe);
617 } 621 }
618 622
619 CacheCleanup(FALSE, pPlan->wzBundleId); 623 CacheCleanup(FALSE, pPlan->pCache);
620 624
621 for (DWORD i = 0; i < cacheContext.cSearchPathsMax; ++i) 625 for (DWORD i = 0; i < cacheContext.cSearchPathsMax; ++i)
622 { 626 {
@@ -653,6 +657,7 @@ extern "C" HRESULT ApplyExecute(
653 BURN_ROLLBACK_BOUNDARY* pRollbackBoundary = NULL; 657 BURN_ROLLBACK_BOUNDARY* pRollbackBoundary = NULL;
654 BOOL fSeekNextRollbackBoundary = FALSE; 658 BOOL fSeekNextRollbackBoundary = FALSE;
655 659
660 context.pCache = pEngineState->plan.pCache;
656 context.pUX = &pEngineState->userExperience; 661 context.pUX = &pEngineState->userExperience;
657 context.pApplyContext = pApplyContext; 662 context.pApplyContext = pApplyContext;
658 context.cExecutePackagesTotal = pEngineState->plan.cExecutePackagesTotal; 663 context.cExecutePackagesTotal = pEngineState->plan.cExecutePackagesTotal;
@@ -762,7 +767,7 @@ extern "C" void ApplyClean(
762 BURN_CLEAN_ACTION* pCleanAction = pPlan->rgCleanActions + i; 767 BURN_CLEAN_ACTION* pCleanAction = pPlan->rgCleanActions + i;
763 BURN_PACKAGE* pPackage = pCleanAction->pPackage; 768 BURN_PACKAGE* pPackage = pCleanAction->pPackage;
764 769
765 hr = CleanPackage(hPipe, pPackage); 770 hr = CleanPackage(pPlan->pCache, hPipe, pPackage);
766 } 771 }
767} 772}
768 773
@@ -1479,7 +1484,7 @@ static HRESULT AcquireContainerOrPayload(
1479 dwChosenSearchPath = 0; 1484 dwChosenSearchPath = 0;
1480 dwDestinationSearchPath = 0; 1485 dwDestinationSearchPath = 0;
1481 1486
1482 hr = CacheGetLocalSourcePaths(wzRelativePath, *pwzSourcePath, wzDestinationPath, pContext->wzLayoutDirectory, pContext->pVariables, &pContext->rgSearchPaths, &pContext->cSearchPaths, &dwChosenSearchPath, &dwDestinationSearchPath); 1487 hr = CacheGetLocalSourcePaths(wzRelativePath, *pwzSourcePath, wzDestinationPath, pContext->wzLayoutDirectory, pContext->pCache, pContext->pVariables, &pContext->rgSearchPaths, &pContext->cSearchPaths, &dwChosenSearchPath, &dwDestinationSearchPath);
1483 ExitOnFailure(hr, "Failed to search local source."); 1488 ExitOnFailure(hr, "Failed to search local source.");
1484 1489
1485 if (wzPayloadContainerId) 1490 if (wzPayloadContainerId)
@@ -1710,7 +1715,7 @@ static HRESULT LayoutOrCacheContainerOrPayload(
1710 } 1715 }
1711 else // complete the payload. 1716 else // complete the payload.
1712 { 1717 {
1713 hr = CacheCompletePayload(pPackage->fPerMachine, pPayload, pPackage->sczCacheId, wzUnverifiedPath, fMove, CacheMessageHandler, CacheProgressRoutine, &progress); 1718 hr = CacheCompletePayload(pContext->pCache, pPackage->fPerMachine, pPayload, pPackage->sczCacheId, wzUnverifiedPath, fMove, CacheMessageHandler, CacheProgressRoutine, &progress);
1714 } 1719 }
1715 } 1720 }
1716 1721
@@ -2174,7 +2179,7 @@ static void DoRollbackCache(
2174 { 2179 {
2175 if (dwLastCheckpoint <= dwCheckpoint) // only rollback when it was attempted to be cached. 2180 if (dwLastCheckpoint <= dwCheckpoint) // only rollback when it was attempted to be cached.
2176 { 2181 {
2177 hr = CleanPackage(hPipe, pPackage); 2182 hr = CleanPackage(pPlan->pCache, hPipe, pPackage);
2178 } 2183 }
2179 } 2184 }
2180 else if (pPackage->fCanAffectRegistration) 2185 else if (pPackage->fCanAffectRegistration)
@@ -2401,7 +2406,7 @@ static HRESULT DoRollbackActions(
2401 case BURN_EXECUTE_ACTION_TYPE_UNCACHE_PACKAGE: 2406 case BURN_EXECUTE_ACTION_TYPE_UNCACHE_PACKAGE:
2402 if (!pRollbackAction->uncachePackage.pPackage->fCached) // only rollback when it wasn't already cached. 2407 if (!pRollbackAction->uncachePackage.pPackage->fCached) // only rollback when it wasn't already cached.
2403 { 2408 {
2404 hr = CleanPackage(pEngineState->companionConnection.hPipe, pRollbackAction->uncachePackage.pPackage); 2409 hr = CleanPackage(pEngineState->plan.pCache, pEngineState->companionConnection.hPipe, pRollbackAction->uncachePackage.pPackage);
2405 IgnoreRollbackError(hr, "Failed to uncache package for rollback."); 2410 IgnoreRollbackError(hr, "Failed to uncache package for rollback.");
2406 } 2411 }
2407 else if (pRollbackAction->uncachePackage.pPackage->fCanAffectRegistration) 2412 else if (pRollbackAction->uncachePackage.pPackage->fCanAffectRegistration)
@@ -2477,7 +2482,7 @@ static HRESULT ExecuteExePackage(
2477 } 2482 }
2478 else 2483 else
2479 { 2484 {
2480 hrExecute = ExeEngineExecutePackage(pExecuteAction, &pEngineState->variables, fRollback, GenericExecuteMessageHandler, pContext, pRestart); 2485 hrExecute = ExeEngineExecutePackage(pExecuteAction, pContext->pCache, &pEngineState->variables, fRollback, GenericExecuteMessageHandler, pContext, pRestart);
2481 ExitOnFailure(hrExecute, "Failed to configure per-user EXE package."); 2486 ExitOnFailure(hrExecute, "Failed to configure per-user EXE package.");
2482 } 2487 }
2483 2488
@@ -2548,7 +2553,7 @@ static HRESULT ExecuteMsiPackage(
2548 } 2553 }
2549 else 2554 else
2550 { 2555 {
2551 hrExecute = MsiEngineExecutePackage(pEngineState->userExperience.hwndApply, pExecuteAction, &pEngineState->variables, fRollback, MsiExecuteMessageHandler, pContext, pRestart); 2556 hrExecute = MsiEngineExecutePackage(pEngineState->userExperience.hwndApply, pExecuteAction, pContext->pCache, &pEngineState->variables, fRollback, MsiExecuteMessageHandler, pContext, pRestart);
2552 ExitOnFailure(hrExecute, "Failed to configure per-user MSI package."); 2557 ExitOnFailure(hrExecute, "Failed to configure per-user MSI package.");
2553 } 2558 }
2554 2559
@@ -2621,7 +2626,7 @@ static HRESULT ExecuteMspPackage(
2621 } 2626 }
2622 else 2627 else
2623 { 2628 {
2624 hrExecute = MspEngineExecutePackage(pEngineState->userExperience.hwndApply, pExecuteAction, &pEngineState->variables, fRollback, MsiExecuteMessageHandler, pContext, pRestart); 2629 hrExecute = MspEngineExecutePackage(pEngineState->userExperience.hwndApply, pExecuteAction, pContext->pCache, &pEngineState->variables, fRollback, MsiExecuteMessageHandler, pContext, pRestart);
2625 ExitOnFailure(hrExecute, "Failed to configure per-user MSP package."); 2630 ExitOnFailure(hrExecute, "Failed to configure per-user MSP package.");
2626 } 2631 }
2627 2632
@@ -2983,6 +2988,7 @@ static void ResetTransactionRegistrationState(
2983} 2988}
2984 2989
2985static HRESULT CleanPackage( 2990static HRESULT CleanPackage(
2991 __in BURN_CACHE* pCache,
2986 __in HANDLE hElevatedPipe, 2992 __in HANDLE hElevatedPipe,
2987 __in BURN_PACKAGE* pPackage 2993 __in BURN_PACKAGE* pPackage
2988 ) 2994 )
@@ -2995,7 +3001,7 @@ static HRESULT CleanPackage(
2995 } 3001 }
2996 else 3002 else
2997 { 3003 {
2998 hr = CacheRemovePackage(FALSE, pPackage->sczId, pPackage->sczCacheId); 3004 hr = CacheRemovePackage(pCache, FALSE, pPackage->sczId, pPackage->sczCacheId);
2999 } 3005 }
3000 3006
3001 if (pPackage->fCanAffectRegistration) 3007 if (pPackage->fCanAffectRegistration)
diff --git a/src/burn/engine/approvedexe.cpp b/src/burn/engine/approvedexe.cpp
index e3d51a47..b9efd624 100644
--- a/src/burn/engine/approvedexe.cpp
+++ b/src/burn/engine/approvedexe.cpp
@@ -211,6 +211,7 @@ LExit:
211} 211}
212 212
213extern "C" HRESULT ApprovedExesVerifySecureLocation( 213extern "C" HRESULT ApprovedExesVerifySecureLocation(
214 __in BURN_CACHE* pCache,
214 __in BURN_VARIABLES* pVariables, 215 __in BURN_VARIABLES* pVariables,
215 __in BURN_LAUNCH_APPROVED_EXE* pLaunchApprovedExe 216 __in BURN_LAUNCH_APPROVED_EXE* pLaunchApprovedExe
216 ) 217 )
@@ -245,7 +246,7 @@ extern "C" HRESULT ApprovedExesVerifySecureLocation(
245 246
246 // The problem with using a Variable for the root package cache folder is that it might not have been secured yet. 247 // The problem with using a Variable for the root package cache folder is that it might not have been secured yet.
247 // Getting it through CacheGetPerMachineRootCompletedPath makes sure it has been secured. 248 // Getting it through CacheGetPerMachineRootCompletedPath makes sure it has been secured.
248 hr = CacheGetPerMachineRootCompletedPath(&scz, &sczSecondary); 249 hr = CacheGetPerMachineRootCompletedPath(pCache, &scz, &sczSecondary);
249 ExitOnFailure(hr, "Failed to get the root package cache folder."); 250 ExitOnFailure(hr, "Failed to get the root package cache folder.");
250 251
251 // If the package cache is redirected, hr is S_FALSE. 252 // If the package cache is redirected, hr is S_FALSE.
diff --git a/src/burn/engine/approvedexe.h b/src/burn/engine/approvedexe.h
index 23f3b1bb..076d86c4 100644
--- a/src/burn/engine/approvedexe.h
+++ b/src/burn/engine/approvedexe.h
@@ -6,6 +6,11 @@
6extern "C" { 6extern "C" {
7#endif 7#endif
8 8
9// forward declare
10
11typedef struct _BOOTSTRAPPER_ENGINE_CONTEXT BOOTSTRAPPER_ENGINE_CONTEXT;
12typedef struct _BURN_CACHE BURN_CACHE;
13typedef struct _BURN_ENGINE_COMMAND BURN_ENGINE_COMMAND;
9 14
10// structs 15// structs
11 16
@@ -57,6 +62,7 @@ HRESULT ApprovedExesLaunch(
57 __out DWORD* pdwProcessId 62 __out DWORD* pdwProcessId
58 ); 63 );
59HRESULT ApprovedExesVerifySecureLocation( 64HRESULT ApprovedExesVerifySecureLocation(
65 __in BURN_CACHE* pCache,
60 __in BURN_VARIABLES* pVariables, 66 __in BURN_VARIABLES* pVariables,
61 __in BURN_LAUNCH_APPROVED_EXE* pLaunchApprovedExe 67 __in BURN_LAUNCH_APPROVED_EXE* pLaunchApprovedExe
62 ); 68 );
diff --git a/src/burn/engine/cache.cpp b/src/burn/engine/cache.cpp
index a35b83bc..54328091 100644
--- a/src/burn/engine/cache.cpp
+++ b/src/burn/engine/cache.cpp
@@ -9,40 +9,37 @@ static const LPCWSTR PACKAGE_CACHE_FOLDER_NAME = L"Package Cache";
9static const DWORD FILE_OPERATION_RETRY_COUNT = 3; 9static const DWORD FILE_OPERATION_RETRY_COUNT = 3;
10static const DWORD FILE_OPERATION_RETRY_WAIT = 2000; 10static const DWORD FILE_OPERATION_RETRY_WAIT = 2000;
11 11
12static BOOL vfInitializedCache = FALSE;
13static BOOL vfRunningFromCache = FALSE;
14static LPWSTR vsczSourceProcessFolder = NULL;
15static LPWSTR vsczWorkingFolder = NULL;
16static LPWSTR vsczDefaultUserPackageCache = NULL;
17static LPWSTR vsczDefaultMachinePackageCache = NULL;
18static LPWSTR vsczCurrentMachinePackageCache = NULL;
19
20static HRESULT CacheVerifyPayloadSignature( 12static HRESULT CacheVerifyPayloadSignature(
21 __in BURN_PAYLOAD* pPayload, 13 __in BURN_PAYLOAD* pPayload,
22 __in_z LPCWSTR wzUnverifiedPayloadPath, 14 __in_z LPCWSTR wzUnverifiedPayloadPath,
23 __in HANDLE hFile 15 __in HANDLE hFile
24 ); 16 );
25static HRESULT CalculateWorkingFolder( 17static HRESULT CalculateWorkingFolder(
26 __in_z LPCWSTR wzBundleId, 18 __in BURN_CACHE* pCache,
27 __deref_out_z LPWSTR* psczWorkingFolder 19 __in BURN_ENGINE_COMMAND* pInternalCommand
28 ); 20 );
29static HRESULT GetLastUsedSourceFolder( 21static HRESULT GetLastUsedSourceFolder(
30 __in BURN_VARIABLES* pVariables, 22 __in BURN_VARIABLES* pVariables,
31 __out_z LPWSTR* psczLastSource 23 __out_z LPWSTR* psczLastSource
32 ); 24 );
33static HRESULT SecurePerMachineCacheRoot(); 25static HRESULT SecurePerMachineCacheRoot(
26 __in BURN_CACHE* pCache
27 );
34static HRESULT CreateCompletedPath( 28static HRESULT CreateCompletedPath(
29 __in BURN_CACHE* pCache,
35 __in BOOL fPerMachine, 30 __in BOOL fPerMachine,
36 __in LPCWSTR wzCacheId, 31 __in LPCWSTR wzCacheId,
37 __in LPCWSTR wzFilePath, 32 __in LPCWSTR wzFilePath,
38 __out_z LPWSTR* psczCachePath 33 __out_z LPWSTR* psczCachePath
39 ); 34 );
40static HRESULT CreateUnverifiedPath( 35static HRESULT CreateUnverifiedPath(
36 __in BURN_CACHE* pCache,
41 __in BOOL fPerMachine, 37 __in BOOL fPerMachine,
42 __in_z LPCWSTR wzPayloadId, 38 __in_z LPCWSTR wzPayloadId,
43 __out_z LPWSTR* psczUnverifiedPayloadPath 39 __out_z LPWSTR* psczUnverifiedPayloadPath
44 ); 40 );
45static HRESULT GetRootPath( 41static HRESULT GetRootPath(
42 __in BURN_CACHE* pCache,
46 __in BOOL fPerMachine, 43 __in BOOL fPerMachine,
47 __in BOOL fAllowRedirect, 44 __in BOOL fAllowRedirect,
48 __deref_out_z LPWSTR* psczRootPath 45 __deref_out_z LPWSTR* psczRootPath
@@ -101,6 +98,7 @@ static HRESULT SecurePath(
101 __in LPCWSTR wzPath 98 __in LPCWSTR wzPath
102 ); 99 );
103static HRESULT CopyEngineToWorkingFolder( 100static HRESULT CopyEngineToWorkingFolder(
101 __in BURN_CACHE* pCache,
104 __in_z LPCWSTR wzSourcePath, 102 __in_z LPCWSTR wzSourcePath,
105 __in_z LPCWSTR wzWorkingFolderName, 103 __in_z LPCWSTR wzWorkingFolderName,
106 __in_z LPCWSTR wzExecutableName, 104 __in_z LPCWSTR wzExecutableName,
@@ -114,6 +112,7 @@ static HRESULT CopyEngineWithSignatureFixup(
114 __in BURN_SECTION* pSection 112 __in BURN_SECTION* pSection
115 ); 113 );
116static HRESULT RemoveBundleOrPackage( 114static HRESULT RemoveBundleOrPackage(
115 __in BURN_CACHE* pCache,
117 __in BOOL fBundle, 116 __in BOOL fBundle,
118 __in BOOL fPerMachine, 117 __in BOOL fPerMachine,
119 __in_z LPCWSTR wzBundleOrPackageId, 118 __in_z LPCWSTR wzBundleOrPackageId,
@@ -158,11 +157,79 @@ static HRESULT SendCacheCompleteMessage(
158 157
159 158
160extern "C" HRESULT CacheInitialize( 159extern "C" HRESULT CacheInitialize(
160 __in BURN_CACHE* pCache,
161 __in BURN_ENGINE_COMMAND* pInternalCommand
162 )
163{
164 Assert(!pCache->fInitializedCache);
165
166 HRESULT hr = S_OK;
167 LPWSTR sczAppData = NULL;
168 int nCompare = 0;
169
170 // Cache paths are initialized once so they cannot be changed while the engine is caching payloads.
171 // Always construct the default machine package cache path so we can determine if we're redirected.
172 hr = PathGetKnownFolder(CSIDL_COMMON_APPDATA, &sczAppData);
173 ExitOnFailure(hr, "Failed to find local %hs appdata directory.", "per-machine");
174
175 hr = PathConcat(sczAppData, PACKAGE_CACHE_FOLDER_NAME, &pCache->sczDefaultMachinePackageCache);
176 ExitOnFailure(hr, "Failed to construct %hs package cache directory name.", "per-machine");
177
178 hr = PathBackslashTerminate(&pCache->sczDefaultMachinePackageCache);
179 ExitOnFailure(hr, "Failed to backslash terminate default %hs package cache directory name.", "per-machine");
180
181
182 // The machine package cache can be redirected through policy.
183 hr = PolcReadString(POLICY_BURN_REGISTRY_PATH, L"PackageCache", NULL, &pCache->sczCurrentMachinePackageCache);
184 ExitOnFailure(hr, "Failed to read PackageCache policy directory.");
185
186 if (pCache->sczCurrentMachinePackageCache)
187 {
188 hr = PathBackslashTerminate(&pCache->sczCurrentMachinePackageCache);
189 ExitOnFailure(hr, "Failed to backslash terminate redirected per-machine package cache directory name.");
190 }
191 else
192 {
193 hr = StrAllocString(&pCache->sczCurrentMachinePackageCache, pCache->sczDefaultMachinePackageCache, 0);
194 ExitOnFailure(hr, "Failed to copy default package cache directory to current package cache directory.");
195 }
196
197 hr = PathCompare(pCache->sczDefaultMachinePackageCache, pCache->sczCurrentMachinePackageCache, &nCompare);
198 ExitOnFailure(hr, "Failed to compare default and current package cache directories.");
199
200 pCache->fCustomMachinePackageCache = CSTR_EQUAL != nCompare;
201
202
203 hr = PathGetKnownFolder(CSIDL_LOCAL_APPDATA, &sczAppData);
204 ExitOnFailure(hr, "Failed to find local %hs appdata directory.", "per-user");
205
206 hr = PathConcat(sczAppData, PACKAGE_CACHE_FOLDER_NAME, &pCache->sczDefaultUserPackageCache);
207 ExitOnFailure(hr, "Failed to construct %hs package cache directory name.", "per-user");
208
209 hr = PathBackslashTerminate(&pCache->sczDefaultUserPackageCache);
210 ExitOnFailure(hr, "Failed to backslash terminate default %hs package cache directory name.", "per-user");
211
212
213 hr = CalculateWorkingFolder(pCache, pInternalCommand);
214
215 pCache->fInitializedCache = TRUE;
216
217LExit:
218 ReleaseStr(sczAppData);
219
220 return hr;
221}
222
223
224extern "C" HRESULT CacheInitializeSources(
225 __in BURN_CACHE* pCache,
161 __in BURN_REGISTRATION* pRegistration, 226 __in BURN_REGISTRATION* pRegistration,
162 __in BURN_VARIABLES* pVariables, 227 __in BURN_VARIABLES* pVariables,
163 __in_z_opt LPCWSTR wzSourceProcessPath 228 __in BURN_ENGINE_COMMAND* pInternalCommand
164 ) 229 )
165{ 230{
231 Assert(!pCache->fInitializedCacheSources);
232
166 HRESULT hr = S_OK; 233 HRESULT hr = S_OK;
167 LPWSTR sczCurrentPath = NULL; 234 LPWSTR sczCurrentPath = NULL;
168 LPWSTR sczCompletedFolder = NULL; 235 LPWSTR sczCompletedFolder = NULL;
@@ -170,66 +237,64 @@ extern "C" HRESULT CacheInitialize(
170 LPWSTR sczOriginalSource = NULL; 237 LPWSTR sczOriginalSource = NULL;
171 LPWSTR sczOriginalSourceFolder = NULL; 238 LPWSTR sczOriginalSourceFolder = NULL;
172 int nCompare = 0; 239 int nCompare = 0;
240 LPCWSTR wzSourceProcessPath = pInternalCommand->sczSourceProcessPath;
173 241
174 if (!vfInitializedCache) 242 hr = PathForCurrentProcess(&sczCurrentPath, NULL);
175 { 243 ExitOnFailure(hr, "Failed to get current process path.");
176 hr = PathForCurrentProcess(&sczCurrentPath, NULL);
177 ExitOnFailure(hr, "Failed to get current process path.");
178 244
179 // Determine if we are running from the package cache or not. 245 // Determine if we are running from the package cache or not.
180 hr = CacheGetCompletedPath(pRegistration->fPerMachine, pRegistration->sczId, &sczCompletedFolder); 246 hr = CacheGetCompletedPath(pCache, pRegistration->fPerMachine, pRegistration->sczId, &sczCompletedFolder);
181 ExitOnFailure(hr, "Failed to get completed path for bundle."); 247 ExitOnFailure(hr, "Failed to get completed path for bundle.");
182 248
183 hr = PathConcat(sczCompletedFolder, pRegistration->sczExecutableName, &sczCompletedPath); 249 hr = PathConcat(sczCompletedFolder, pRegistration->sczExecutableName, &sczCompletedPath);
184 ExitOnFailure(hr, "Failed to combine working path with engine file name."); 250 ExitOnFailure(hr, "Failed to combine working path with engine file name.");
185 251
186 hr = PathCompare(sczCurrentPath, sczCompletedPath, &nCompare); 252 hr = PathCompare(sczCurrentPath, sczCompletedPath, &nCompare);
187 ExitOnFailure(hr, "Failed to compare current path for bundle: %ls", sczCurrentPath); 253 ExitOnFailure(hr, "Failed to compare current path for bundle: %ls", sczCurrentPath);
188 254
189 vfRunningFromCache = (CSTR_EQUAL == nCompare); 255 pCache->fRunningFromCache = (CSTR_EQUAL == nCompare);
190 256
191 // If a source process path was not provided (e.g. we are not being 257 // If a source process path was not provided (e.g. we are not being
192 // run in a clean room) then use the current process path as the 258 // run in a clean room) then use the current process path as the
193 // source process path. 259 // source process path.
194 if (!wzSourceProcessPath) 260 if (!wzSourceProcessPath)
195 { 261 {
196 wzSourceProcessPath = sczCurrentPath; 262 wzSourceProcessPath = sczCurrentPath;
197 } 263 }
198 264
199 hr = PathGetDirectory(wzSourceProcessPath, &vsczSourceProcessFolder); 265 hr = PathGetDirectory(wzSourceProcessPath, &pCache->sczSourceProcessFolder);
200 ExitOnFailure(hr, "Failed to initialize cache source folder."); 266 ExitOnFailure(hr, "Failed to initialize cache source folder.");
201 267
202 // If we're not running from the cache, ensure the original source is set. 268 // If we're not running from the cache, ensure the original source is set.
203 if (!vfRunningFromCache) 269 if (!pCache->fRunningFromCache)
270 {
271 // If the original source has not been set already then set it where the bundle is
272 // running from right now. This value will be persisted and we'll use it when launched
273 // from the clean room or package cache since none of our packages will be relative to
274 // those locations.
275 hr = VariableGetString(pVariables, BURN_BUNDLE_ORIGINAL_SOURCE, &sczOriginalSource);
276 if (E_NOTFOUND == hr)
204 { 277 {
205 // If the original source has not been set already then set it where the bundle is 278 hr = VariableSetString(pVariables, BURN_BUNDLE_ORIGINAL_SOURCE, wzSourceProcessPath, FALSE, FALSE);
206 // running from right now. This value will be persisted and we'll use it when launched 279 ExitOnFailure(hr, "Failed to set original source variable.");
207 // from the clean room or package cache since none of our packages will be relative to
208 // those locations.
209 hr = VariableGetString(pVariables, BURN_BUNDLE_ORIGINAL_SOURCE, &sczOriginalSource);
210 if (E_NOTFOUND == hr)
211 {
212 hr = VariableSetString(pVariables, BURN_BUNDLE_ORIGINAL_SOURCE, wzSourceProcessPath, FALSE, FALSE);
213 ExitOnFailure(hr, "Failed to set original source variable.");
214 280
215 hr = StrAllocString(&sczOriginalSource, wzSourceProcessPath, 0); 281 hr = StrAllocString(&sczOriginalSource, wzSourceProcessPath, 0);
216 ExitOnFailure(hr, "Failed to copy current path to original source."); 282 ExitOnFailure(hr, "Failed to copy current path to original source.");
217 } 283 }
218 284
219 hr = VariableGetString(pVariables, BURN_BUNDLE_ORIGINAL_SOURCE_FOLDER, &sczOriginalSourceFolder); 285 hr = VariableGetString(pVariables, BURN_BUNDLE_ORIGINAL_SOURCE_FOLDER, &sczOriginalSourceFolder);
220 if (E_NOTFOUND == hr) 286 if (E_NOTFOUND == hr)
221 { 287 {
222 hr = PathGetDirectory(sczOriginalSource, &sczOriginalSourceFolder); 288 hr = PathGetDirectory(sczOriginalSource, &sczOriginalSourceFolder);
223 ExitOnFailure(hr, "Failed to get directory from original source path."); 289 ExitOnFailure(hr, "Failed to get directory from original source path.");
224 290
225 hr = VariableSetString(pVariables, BURN_BUNDLE_ORIGINAL_SOURCE_FOLDER, sczOriginalSourceFolder, FALSE, FALSE); 291 hr = VariableSetString(pVariables, BURN_BUNDLE_ORIGINAL_SOURCE_FOLDER, sczOriginalSourceFolder, FALSE, FALSE);
226 ExitOnFailure(hr, "Failed to set original source directory variable."); 292 ExitOnFailure(hr, "Failed to set original source directory variable.");
227 }
228 } 293 }
229
230 vfInitializedCache = TRUE;
231 } 294 }
232 295
296 pCache->fInitializedCacheSources = TRUE;
297
233LExit: 298LExit:
234 ReleaseStr(sczCurrentPath); 299 ReleaseStr(sczCurrentPath);
235 ReleaseStr(sczCompletedFolder); 300 ReleaseStr(sczCompletedFolder);
@@ -241,99 +306,85 @@ LExit:
241} 306}
242 307
243extern "C" HRESULT CacheEnsureWorkingFolder( 308extern "C" HRESULT CacheEnsureWorkingFolder(
244 __in_z_opt LPCWSTR wzBundleId, 309 __in BURN_CACHE* pCache,
245 __deref_out_z_opt LPWSTR* psczWorkingFolder 310 __deref_out_z_opt LPWSTR* psczWorkingFolder
246 ) 311 )
247{ 312{
248 HRESULT hr = S_OK; 313 Assert(pCache->fInitializedCache);
249 LPWSTR sczWorkingFolder = NULL;
250 314
251 hr = CalculateWorkingFolder(wzBundleId, &sczWorkingFolder); 315 HRESULT hr = S_OK;
252 ExitOnFailure(hr, "Failed to calculate working folder to ensure it exists.");
253 316
254 hr = DirEnsureExists(sczWorkingFolder, NULL); 317 hr = DirEnsureExists(pCache->sczWorkingFolder, NULL);
255 ExitOnFailure(hr, "Failed create working folder."); 318 ExitOnFailure(hr, "Failed create working folder.");
256 319
257 // Best effort to ensure our working folder is not encrypted. 320 // Best effort to ensure our working folder is not encrypted.
258 ::DecryptFileW(sczWorkingFolder, 0); 321 ::DecryptFileW(pCache->sczWorkingFolder, 0);
259 322
260 if (psczWorkingFolder) 323 if (psczWorkingFolder)
261 { 324 {
262 hr = StrAllocString(psczWorkingFolder, sczWorkingFolder, 0); 325 hr = StrAllocString(psczWorkingFolder, pCache->sczWorkingFolder, 0);
263 ExitOnFailure(hr, "Failed to copy working folder."); 326 ExitOnFailure(hr, "Failed to copy working folder.");
264 } 327 }
265 328
266LExit: 329LExit:
267 ReleaseStr(sczWorkingFolder);
268
269 return hr; 330 return hr;
270} 331}
271 332
272extern "C" HRESULT CacheCalculateBundleWorkingPath( 333extern "C" HRESULT CacheCalculateBundleWorkingPath(
273 __in_z LPCWSTR wzBundleId, 334 __in BURN_CACHE* pCache,
274 __in LPCWSTR wzExecutableName, 335 __in LPCWSTR wzExecutableName,
275 __deref_out_z LPWSTR* psczWorkingPath 336 __deref_out_z LPWSTR* psczWorkingPath
276 ) 337 )
277{ 338{
278 Assert(vfInitializedCache); 339 Assert(pCache->fInitializedCache);
279 340
280 HRESULT hr = S_OK; 341 HRESULT hr = S_OK;
281 LPWSTR sczWorkingFolder = NULL;
282 342
283 // If the bundle is running out of the package cache then we use that as the 343 // If the bundle is running out of the package cache then we use that as the
284 // working folder since we feel safe in the package cache. 344 // working folder since we feel safe in the package cache.
285 if (vfRunningFromCache) 345 if (CacheBundleRunningFromCache(pCache))
286 { 346 {
287 hr = PathForCurrentProcess(psczWorkingPath, NULL); 347 hr = PathForCurrentProcess(psczWorkingPath, NULL);
288 ExitOnFailure(hr, "Failed to get current process path."); 348 ExitOnFailure(hr, "Failed to get current process path.");
289 } 349 }
290 else // Otherwise, use the real working folder. 350 else // Otherwise, use the real working folder.
291 { 351 {
292 hr = CalculateWorkingFolder(wzBundleId, &sczWorkingFolder); 352 hr = StrAllocFormatted(psczWorkingPath, L"%ls%ls\\%ls", pCache->sczWorkingFolder, BUNDLE_WORKING_FOLDER_NAME, wzExecutableName);
293 ExitOnFailure(hr, "Failed to get working folder for bundle.");
294
295 hr = StrAllocFormatted(psczWorkingPath, L"%ls%ls\\%ls", sczWorkingFolder, BUNDLE_WORKING_FOLDER_NAME, wzExecutableName);
296 ExitOnFailure(hr, "Failed to calculate the bundle working path."); 353 ExitOnFailure(hr, "Failed to calculate the bundle working path.");
297 } 354 }
298 355
299LExit: 356LExit:
300 ReleaseStr(sczWorkingFolder);
301
302 return hr; 357 return hr;
303} 358}
304 359
305extern "C" HRESULT CacheCalculateBundleLayoutWorkingPath( 360extern "C" HRESULT CacheCalculateBundleLayoutWorkingPath(
361 __in BURN_CACHE* pCache,
306 __in_z LPCWSTR wzBundleId, 362 __in_z LPCWSTR wzBundleId,
307 __deref_out_z LPWSTR* psczWorkingPath 363 __deref_out_z LPWSTR* psczWorkingPath
308 ) 364 )
309{ 365{
310 HRESULT hr = S_OK; 366 Assert(pCache->fInitializedCache);
311 LPWSTR sczWorkingFolder = NULL;
312 367
313 hr = CalculateWorkingFolder(wzBundleId, psczWorkingPath); 368 HRESULT hr = S_OK;
314 ExitOnFailure(hr, "Failed to get working folder for bundle layout.");
315 369
316 hr = StrAllocConcat(psczWorkingPath, wzBundleId, 0); 370 hr = PathConcat(pCache->sczWorkingFolder, wzBundleId, psczWorkingPath);
317 ExitOnFailure(hr, "Failed to append bundle id for bundle layout working path."); 371 ExitOnFailure(hr, "Failed to append bundle id for bundle layout working path.");
318 372
319LExit: 373LExit:
320 ReleaseStr(sczWorkingFolder);
321
322 return hr; 374 return hr;
323} 375}
324 376
325extern "C" HRESULT CacheCalculatePayloadWorkingPath( 377extern "C" HRESULT CacheCalculatePayloadWorkingPath(
326 __in_z LPCWSTR wzBundleId, 378 __in BURN_CACHE* pCache,
327 __in BURN_PAYLOAD* pPayload, 379 __in BURN_PAYLOAD* pPayload,
328 __deref_out_z LPWSTR* psczWorkingPath 380 __deref_out_z LPWSTR* psczWorkingPath
329 ) 381 )
330{ 382{
331 HRESULT hr = S_OK; 383 Assert(pCache->fInitializedCache);
332 384
333 hr = CalculateWorkingFolder(wzBundleId, psczWorkingPath); 385 HRESULT hr = S_OK;
334 ExitOnFailure(hr, "Failed to get working folder for payload.");
335 386
336 hr = StrAllocConcat(psczWorkingPath, pPayload->sczKey, 0); 387 hr = PathConcat(pCache->sczWorkingFolder, pPayload->sczKey, psczWorkingPath);
337 ExitOnFailure(hr, "Failed to append Id as payload unverified path."); 388 ExitOnFailure(hr, "Failed to append Id as payload unverified path.");
338 389
339LExit: 390LExit:
@@ -341,17 +392,16 @@ LExit:
341} 392}
342 393
343extern "C" HRESULT CacheCalculateContainerWorkingPath( 394extern "C" HRESULT CacheCalculateContainerWorkingPath(
344 __in_z LPCWSTR wzBundleId, 395 __in BURN_CACHE* pCache,
345 __in BURN_CONTAINER* pContainer, 396 __in BURN_CONTAINER* pContainer,
346 __deref_out_z LPWSTR* psczWorkingPath 397 __deref_out_z LPWSTR* psczWorkingPath
347 ) 398 )
348{ 399{
349 HRESULT hr = S_OK; 400 Assert(pCache->fInitializedCache);
350 401
351 hr = CalculateWorkingFolder(wzBundleId, psczWorkingPath); 402 HRESULT hr = S_OK;
352 ExitOnFailure(hr, "Failed to get working folder for container.");
353 403
354 hr = StrAllocConcat(psczWorkingPath, pContainer->sczHash, 0); 404 hr = PathConcat(pCache->sczWorkingFolder, pContainer->sczHash, psczWorkingPath);
355 ExitOnFailure(hr, "Failed to append hash as container unverified path."); 405 ExitOnFailure(hr, "Failed to append hash as container unverified path.");
356 406
357LExit: 407LExit:
@@ -359,6 +409,7 @@ LExit:
359} 409}
360 410
361extern "C" HRESULT CacheGetPerMachineRootCompletedPath( 411extern "C" HRESULT CacheGetPerMachineRootCompletedPath(
412 __in BURN_CACHE* pCache,
362 __out_z LPWSTR* psczCurrentRootCompletedPath, 413 __out_z LPWSTR* psczCurrentRootCompletedPath,
363 __out_z LPWSTR* psczDefaultRootCompletedPath 414 __out_z LPWSTR* psczDefaultRootCompletedPath
364 ) 415 )
@@ -368,15 +419,15 @@ extern "C" HRESULT CacheGetPerMachineRootCompletedPath(
368 *psczCurrentRootCompletedPath = NULL; 419 *psczCurrentRootCompletedPath = NULL;
369 *psczDefaultRootCompletedPath = NULL; 420 *psczDefaultRootCompletedPath = NULL;
370 421
371 hr = SecurePerMachineCacheRoot(); 422 hr = SecurePerMachineCacheRoot(pCache);
372 ExitOnFailure(hr, "Failed to secure per-machine cache root."); 423 ExitOnFailure(hr, "Failed to secure per-machine cache root.");
373 424
374 hr = GetRootPath(TRUE, TRUE, psczCurrentRootCompletedPath); 425 hr = GetRootPath(pCache, TRUE, TRUE, psczCurrentRootCompletedPath);
375 ExitOnFailure(hr, "Failed to get per-machine cache root."); 426 ExitOnFailure(hr, "Failed to get per-machine cache root.");
376 427
377 if (S_FALSE == hr) 428 if (S_FALSE == hr)
378 { 429 {
379 hr = GetRootPath(TRUE, FALSE, psczDefaultRootCompletedPath); 430 hr = GetRootPath(pCache, TRUE, FALSE, psczDefaultRootCompletedPath);
380 ExitOnFailure(hr, "Failed to get default per-machine cache root."); 431 ExitOnFailure(hr, "Failed to get default per-machine cache root.");
381 432
382 hr = S_FALSE; 433 hr = S_FALSE;
@@ -387,6 +438,7 @@ LExit:
387} 438}
388 439
389extern "C" HRESULT CacheGetCompletedPath( 440extern "C" HRESULT CacheGetCompletedPath(
441 __in BURN_CACHE* pCache,
390 __in BOOL fPerMachine, 442 __in BOOL fPerMachine,
391 __in_z LPCWSTR wzCacheId, 443 __in_z LPCWSTR wzCacheId,
392 __deref_out_z LPWSTR* psczCompletedPath 444 __deref_out_z LPWSTR* psczCompletedPath
@@ -398,7 +450,7 @@ extern "C" HRESULT CacheGetCompletedPath(
398 LPWSTR sczCurrentCompletedPath = NULL; 450 LPWSTR sczCurrentCompletedPath = NULL;
399 LPWSTR sczDefaultCompletedPath = NULL; 451 LPWSTR sczDefaultCompletedPath = NULL;
400 452
401 hr = GetRootPath(fPerMachine, TRUE, &sczRootPath); 453 hr = GetRootPath(pCache, fPerMachine, TRUE, &sczRootPath);
402 ExitOnFailure(hr, "Failed to get %hs package cache root directory.", fPerMachine ? "per-machine" : "per-user"); 454 ExitOnFailure(hr, "Failed to get %hs package cache root directory.", fPerMachine ? "per-machine" : "per-user");
403 455
404 // GetRootPath returns S_FALSE if the package cache is redirected elsewhere. 456 // GetRootPath returns S_FALSE if the package cache is redirected elsewhere.
@@ -414,7 +466,7 @@ extern "C" HRESULT CacheGetCompletedPath(
414 // If neither package cache directory exists return the (possibly) redirected package cache directory. 466 // If neither package cache directory exists return the (possibly) redirected package cache directory.
415 if (fRedirected && !DirExists(sczCurrentCompletedPath, NULL)) 467 if (fRedirected && !DirExists(sczCurrentCompletedPath, NULL))
416 { 468 {
417 hr = GetRootPath(fPerMachine, FALSE, &sczRootPath); 469 hr = GetRootPath(pCache, fPerMachine, FALSE, &sczRootPath);
418 ExitOnFailure(hr, "Failed to get old %hs package cache root directory.", fPerMachine ? "per-machine" : "per-user"); 470 ExitOnFailure(hr, "Failed to get old %hs package cache root directory.", fPerMachine ? "per-machine" : "per-user");
419 471
420 hr = PathConcat(sczRootPath, wzCacheId, &sczDefaultCompletedPath); 472 hr = PathConcat(sczRootPath, wzCacheId, &sczDefaultCompletedPath);
@@ -462,6 +514,7 @@ extern "C" HRESULT CacheGetLocalSourcePaths(
462 __in_z LPCWSTR wzSourcePath, 514 __in_z LPCWSTR wzSourcePath,
463 __in_z LPCWSTR wzDestinationPath, 515 __in_z LPCWSTR wzDestinationPath,
464 __in_z_opt LPCWSTR wzLayoutDirectory, 516 __in_z_opt LPCWSTR wzLayoutDirectory,
517 __in BURN_CACHE* pCache,
465 __in BURN_VARIABLES* pVariables, 518 __in BURN_VARIABLES* pVariables,
466 __inout LPWSTR** prgSearchPaths, 519 __inout LPWSTR** prgSearchPaths,
467 __out DWORD* pcSearchPaths, 520 __out DWORD* pcSearchPaths,
@@ -469,6 +522,8 @@ extern "C" HRESULT CacheGetLocalSourcePaths(
469 __out DWORD* pdwDestinationSearchPath 522 __out DWORD* pdwDestinationSearchPath
470 ) 523 )
471{ 524{
525 AssertSz(pCache->fInitializedCacheSources, "Cache sources weren't initialized");
526
472 HRESULT hr = S_OK; 527 HRESULT hr = S_OK;
473 LPWSTR sczCurrentPath = NULL; 528 LPWSTR sczCurrentPath = NULL;
474 LPWSTR sczLastSourceFolder = NULL; 529 LPWSTR sczLastSourceFolder = NULL;
@@ -481,11 +536,9 @@ extern "C" HRESULT CacheGetLocalSourcePaths(
481 DWORD dwLikelySearchPath = 0; 536 DWORD dwLikelySearchPath = 0;
482 DWORD dwDestinationSearchPath = 0; 537 DWORD dwDestinationSearchPath = 0;
483 538
484 AssertSz(vfInitializedCache, "Cache wasn't initialized");
485
486 hr = GetLastUsedSourceFolder(pVariables, &sczLastSourceFolder); 539 hr = GetLastUsedSourceFolder(pVariables, &sczLastSourceFolder);
487 fPreferSourcePathLocation = !vfRunningFromCache || FAILED(hr); 540 fPreferSourcePathLocation = !pCache->fRunningFromCache || FAILED(hr);
488 fTryLastFolder = SUCCEEDED(hr) && sczLastSourceFolder && *sczLastSourceFolder && CSTR_EQUAL != ::CompareStringW(LOCALE_NEUTRAL, NORM_IGNORECASE, vsczSourceProcessFolder, -1, sczLastSourceFolder, -1); 541 fTryLastFolder = SUCCEEDED(hr) && sczLastSourceFolder && *sczLastSourceFolder && CSTR_EQUAL != ::CompareStringW(LOCALE_NEUTRAL, NORM_IGNORECASE, pCache->sczSourceProcessFolder, -1, sczLastSourceFolder, -1);
489 fTryRelativePath = CSTR_EQUAL != ::CompareStringW(LOCALE_NEUTRAL, NORM_IGNORECASE, wzSourcePath, -1, wzRelativePath, -1); 542 fTryRelativePath = CSTR_EQUAL != ::CompareStringW(LOCALE_NEUTRAL, NORM_IGNORECASE, wzSourcePath, -1, wzRelativePath, -1);
490 fSourceIsAbsolute = PathIsAbsolute(wzSourcePath); 543 fSourceIsAbsolute = PathIsAbsolute(wzSourcePath);
491 544
@@ -528,7 +581,7 @@ extern "C" HRESULT CacheGetLocalSourcePaths(
528 hr = MemEnsureArraySize(reinterpret_cast<LPVOID*>(prgSearchPaths), cSearchPaths + 1, sizeof(LPWSTR), BURN_CACHE_MAX_SEARCH_PATHS); 581 hr = MemEnsureArraySize(reinterpret_cast<LPVOID*>(prgSearchPaths), cSearchPaths + 1, sizeof(LPWSTR), BURN_CACHE_MAX_SEARCH_PATHS);
529 ExitOnFailure(hr, "Failed to ensure size for search paths array."); 582 ExitOnFailure(hr, "Failed to ensure size for search paths array.");
530 583
531 hr = PathConcat(vsczSourceProcessFolder, wzSourcePath, &sczCurrentPath); 584 hr = PathConcat(pCache->sczSourceProcessFolder, wzSourcePath, &sczCurrentPath);
532 ExitOnFailure(hr, "Failed to combine source process folder with source."); 585 ExitOnFailure(hr, "Failed to combine source process folder with source.");
533 586
534 // If we're not running from cache or we couldn't get the last source, 587 // If we're not running from cache or we couldn't get the last source,
@@ -580,7 +633,7 @@ extern "C" HRESULT CacheGetLocalSourcePaths(
580 hr = MemEnsureArraySize(reinterpret_cast<LPVOID*>(prgSearchPaths), cSearchPaths + 1, sizeof(LPWSTR), BURN_CACHE_MAX_SEARCH_PATHS); 633 hr = MemEnsureArraySize(reinterpret_cast<LPVOID*>(prgSearchPaths), cSearchPaths + 1, sizeof(LPWSTR), BURN_CACHE_MAX_SEARCH_PATHS);
581 ExitOnFailure(hr, "Failed to ensure size for search paths array."); 634 ExitOnFailure(hr, "Failed to ensure size for search paths array.");
582 635
583 hr = PathConcat(vsczSourceProcessFolder, wzRelativePath, &sczCurrentPath); 636 hr = PathConcat(pCache->sczSourceProcessFolder, wzRelativePath, &sczCurrentPath);
584 ExitOnFailure(hr, "Failed to combine source process folder with relative."); 637 ExitOnFailure(hr, "Failed to combine source process folder with relative.");
585 638
586 if (fPreferSourcePathLocation) 639 if (fPreferSourcePathLocation)
@@ -761,12 +814,17 @@ extern "C" void CacheSendErrorCallback(
761 } 814 }
762} 815}
763 816
764extern "C" BOOL CacheBundleRunningFromCache() 817extern "C" BOOL CacheBundleRunningFromCache(
818 __in BURN_CACHE* pCache
819 )
765{ 820{
766 return vfRunningFromCache; 821 AssertSz(pCache->fInitializedCacheSources, "Cache sources weren't initialized");
822
823 return pCache->fRunningFromCache;
767} 824}
768 825
769HRESULT CachePreparePackage( 826extern "C" HRESULT CachePreparePackage(
827 __in BURN_CACHE* pCache,
770 __in BURN_PACKAGE* pPackage 828 __in BURN_PACKAGE* pPackage
771 ) 829 )
772{ 830{
@@ -774,13 +832,14 @@ HRESULT CachePreparePackage(
774 832
775 if (!pPackage->sczCacheFolder) 833 if (!pPackage->sczCacheFolder)
776 { 834 {
777 hr = CreateCompletedPath(pPackage->fPerMachine, pPackage->sczCacheId, NULL, &pPackage->sczCacheFolder); 835 hr = CreateCompletedPath(pCache, pPackage->fPerMachine, pPackage->sczCacheId, NULL, &pPackage->sczCacheFolder);
778 } 836 }
779 837
780 return hr; 838 return hr;
781} 839}
782 840
783extern "C" HRESULT CacheBundleToCleanRoom( 841extern "C" HRESULT CacheBundleToCleanRoom(
842 __in BURN_CACHE* pCache,
784 __in BURN_SECTION* pSection, 843 __in BURN_SECTION* pSection,
785 __deref_out_z_opt LPWSTR* psczCleanRoomBundlePath 844 __deref_out_z_opt LPWSTR* psczCleanRoomBundlePath
786 ) 845 )
@@ -794,7 +853,7 @@ extern "C" HRESULT CacheBundleToCleanRoom(
794 853
795 wzExecutableName = PathFile(sczSourcePath); 854 wzExecutableName = PathFile(sczSourcePath);
796 855
797 hr = CopyEngineToWorkingFolder(sczSourcePath, BUNDLE_CLEAN_ROOM_WORKING_FOLDER_NAME, wzExecutableName, pSection, psczCleanRoomBundlePath); 856 hr = CopyEngineToWorkingFolder(pCache, sczSourcePath, BUNDLE_CLEAN_ROOM_WORKING_FOLDER_NAME, wzExecutableName, pSection, psczCleanRoomBundlePath);
798 ExitOnFailure(hr, "Failed to cache bundle to clean room."); 857 ExitOnFailure(hr, "Failed to cache bundle to clean room.");
799 858
800LExit: 859LExit:
@@ -804,13 +863,13 @@ LExit:
804} 863}
805 864
806extern "C" HRESULT CacheBundleToWorkingDirectory( 865extern "C" HRESULT CacheBundleToWorkingDirectory(
807 __in_z LPCWSTR /*wzBundleId*/, 866 __in BURN_CACHE* pCache,
808 __in_z LPCWSTR wzExecutableName, 867 __in_z LPCWSTR wzExecutableName,
809 __in BURN_SECTION* pSection, 868 __in BURN_SECTION* pSection,
810 __deref_out_z_opt LPWSTR* psczEngineWorkingPath 869 __deref_out_z_opt LPWSTR* psczEngineWorkingPath
811 ) 870 )
812{ 871{
813 Assert(vfInitializedCache); 872 Assert(pCache->fInitializedCache);
814 873
815 HRESULT hr = S_OK; 874 HRESULT hr = S_OK;
816 LPWSTR sczSourcePath = NULL; 875 LPWSTR sczSourcePath = NULL;
@@ -821,14 +880,14 @@ extern "C" HRESULT CacheBundleToWorkingDirectory(
821 880
822 // If the bundle is running out of the package cache then we don't need to copy it to 881 // If the bundle is running out of the package cache then we don't need to copy it to
823 // the working folder since we feel safe in the package cache and will run from there. 882 // the working folder since we feel safe in the package cache and will run from there.
824 if (vfRunningFromCache) 883 if (CacheBundleRunningFromCache(pCache))
825 { 884 {
826 hr = StrAllocString(psczEngineWorkingPath, sczSourcePath, 0); 885 hr = StrAllocString(psczEngineWorkingPath, sczSourcePath, 0);
827 ExitOnFailure(hr, "Failed to use current process path as target path."); 886 ExitOnFailure(hr, "Failed to use current process path as target path.");
828 } 887 }
829 else // otherwise, carry on putting the bundle in the working folder. 888 else // otherwise, carry on putting the bundle in the working folder.
830 { 889 {
831 hr = CopyEngineToWorkingFolder(sczSourcePath, BUNDLE_WORKING_FOLDER_NAME, wzExecutableName, pSection, psczEngineWorkingPath); 890 hr = CopyEngineToWorkingFolder(pCache, sczSourcePath, BUNDLE_WORKING_FOLDER_NAME, wzExecutableName, pSection, psczEngineWorkingPath);
832 ExitOnFailure(hr, "Failed to copy engine to working folder."); 891 ExitOnFailure(hr, "Failed to copy engine to working folder.");
833 } 892 }
834 893
@@ -866,6 +925,7 @@ LExit:
866} 925}
867 926
868extern "C" HRESULT CacheCompleteBundle( 927extern "C" HRESULT CacheCompleteBundle(
928 __in BURN_CACHE* pCache,
869 __in BOOL fPerMachine, 929 __in BOOL fPerMachine,
870 __in_z LPCWSTR wzExecutableName, 930 __in_z LPCWSTR wzExecutableName,
871 __in_z LPCWSTR wzBundleId, 931 __in_z LPCWSTR wzBundleId,
@@ -882,7 +942,7 @@ extern "C" HRESULT CacheCompleteBundle(
882 LPWSTR sczSourceDirectory = NULL; 942 LPWSTR sczSourceDirectory = NULL;
883 LPWSTR sczPayloadSourcePath = NULL; 943 LPWSTR sczPayloadSourcePath = NULL;
884 944
885 hr = CreateCompletedPath(fPerMachine, wzBundleId, NULL, &sczTargetDirectory); 945 hr = CreateCompletedPath(pCache, fPerMachine, wzBundleId, NULL, &sczTargetDirectory);
886 ExitOnFailure(hr, "Failed to create completed cache path for bundle."); 946 ExitOnFailure(hr, "Failed to create completed cache path for bundle.");
887 947
888 hr = PathConcat(sczTargetDirectory, wzExecutableName, &sczTargetPath); 948 hr = PathConcat(sczTargetDirectory, wzExecutableName, &sczTargetPath);
@@ -976,6 +1036,7 @@ LExit:
976} 1036}
977 1037
978extern "C" HRESULT CacheCompletePayload( 1038extern "C" HRESULT CacheCompletePayload(
1039 __in BURN_CACHE* pCache,
979 __in BOOL fPerMachine, 1040 __in BOOL fPerMachine,
980 __in BURN_PAYLOAD* pPayload, 1041 __in BURN_PAYLOAD* pPayload,
981 __in_z LPCWSTR wzCacheId, 1042 __in_z LPCWSTR wzCacheId,
@@ -990,7 +1051,7 @@ extern "C" HRESULT CacheCompletePayload(
990 LPWSTR sczCachedPath = NULL; 1051 LPWSTR sczCachedPath = NULL;
991 LPWSTR sczUnverifiedPayloadPath = NULL; 1052 LPWSTR sczUnverifiedPayloadPath = NULL;
992 1053
993 hr = CreateCompletedPath(fPerMachine, wzCacheId, pPayload->sczFilePath, &sczCachedPath); 1054 hr = CreateCompletedPath(pCache, fPerMachine, wzCacheId, pPayload->sczFilePath, &sczCachedPath);
994 ExitOnFailure(hr, "Failed to get cached path for package with cache id: %ls", wzCacheId); 1055 ExitOnFailure(hr, "Failed to get cached path for package with cache id: %ls", wzCacheId);
995 1056
996 // If the cached file matches what we expected, we're good. 1057 // If the cached file matches what we expected, we're good.
@@ -1000,7 +1061,7 @@ extern "C" HRESULT CacheCompletePayload(
1000 ExitFunction(); 1061 ExitFunction();
1001 } 1062 }
1002 1063
1003 hr = CreateUnverifiedPath(fPerMachine, pPayload->sczKey, &sczUnverifiedPayloadPath); 1064 hr = CreateUnverifiedPath(pCache, fPerMachine, pPayload->sczKey, &sczUnverifiedPayloadPath);
1004 ExitOnFailure(hr, "Failed to create unverified path."); 1065 ExitOnFailure(hr, "Failed to create unverified path.");
1005 1066
1006 // If the working path exists, let's get it into the unverified path so we can reset the ACLs and verify the file. 1067 // If the working path exists, let's get it into the unverified path so we can reset the ACLs and verify the file.
@@ -1091,36 +1152,30 @@ LExit:
1091} 1152}
1092 1153
1093extern "C" HRESULT CacheRemoveWorkingFolder( 1154extern "C" HRESULT CacheRemoveWorkingFolder(
1094 __in_z_opt LPCWSTR wzBundleId 1155 __in BURN_CACHE* pCache
1095 ) 1156 )
1096{ 1157{
1097 HRESULT hr = S_OK; 1158 HRESULT hr = S_OK;
1098 LPWSTR sczWorkingFolder = NULL;
1099 1159
1100 if (vfInitializedCache) 1160 if (pCache->fInitializedCacheSources)
1101 { 1161 {
1102 hr = CalculateWorkingFolder(wzBundleId, &sczWorkingFolder);
1103 ExitOnFailure(hr, "Failed to calculate the working folder to remove it.");
1104
1105 // Try to clean out everything in the working folder. 1162 // Try to clean out everything in the working folder.
1106 hr = DirEnsureDeleteEx(sczWorkingFolder, DIR_DELETE_FILES | DIR_DELETE_RECURSE | DIR_DELETE_SCHEDULE); 1163 hr = DirEnsureDeleteEx(pCache->sczWorkingFolder, DIR_DELETE_FILES | DIR_DELETE_RECURSE | DIR_DELETE_SCHEDULE);
1107 TraceError(hr, "Could not delete bundle engine working folder."); 1164 TraceError(hr, "Could not delete bundle engine working folder.");
1108 } 1165 }
1109 1166
1110LExit:
1111 ReleaseStr(sczWorkingFolder);
1112
1113 return hr; 1167 return hr;
1114} 1168}
1115 1169
1116extern "C" HRESULT CacheRemoveBundle( 1170extern "C" HRESULT CacheRemoveBundle(
1171 __in BURN_CACHE* pCache,
1117 __in BOOL fPerMachine, 1172 __in BOOL fPerMachine,
1118 __in_z LPCWSTR wzBundleId 1173 __in_z LPCWSTR wzBundleId
1119 ) 1174 )
1120{ 1175{
1121 HRESULT hr = S_OK; 1176 HRESULT hr = S_OK;
1122 1177
1123 hr = RemoveBundleOrPackage(TRUE, fPerMachine, wzBundleId, wzBundleId); 1178 hr = RemoveBundleOrPackage(pCache, TRUE, fPerMachine, wzBundleId, wzBundleId);
1124 ExitOnFailure(hr, "Failed to remove bundle id: %ls.", wzBundleId); 1179 ExitOnFailure(hr, "Failed to remove bundle id: %ls.", wzBundleId);
1125 1180
1126LExit: 1181LExit:
@@ -1128,6 +1183,7 @@ LExit:
1128} 1183}
1129 1184
1130extern "C" HRESULT CacheRemovePackage( 1185extern "C" HRESULT CacheRemovePackage(
1186 __in BURN_CACHE* pCache,
1131 __in BOOL fPerMachine, 1187 __in BOOL fPerMachine,
1132 __in_z LPCWSTR wzPackageId, 1188 __in_z LPCWSTR wzPackageId,
1133 __in_z LPCWSTR wzCacheId 1189 __in_z LPCWSTR wzCacheId
@@ -1135,7 +1191,7 @@ extern "C" HRESULT CacheRemovePackage(
1135{ 1191{
1136 HRESULT hr = S_OK; 1192 HRESULT hr = S_OK;
1137 1193
1138 hr = RemoveBundleOrPackage(FALSE, fPerMachine, wzPackageId, wzCacheId); 1194 hr = RemoveBundleOrPackage(pCache, FALSE, fPerMachine, wzPackageId, wzCacheId);
1139 ExitOnFailure(hr, "Failed to remove package id: %ls.", wzPackageId); 1195 ExitOnFailure(hr, "Failed to remove package id: %ls.", wzPackageId);
1140 1196
1141LExit: 1197LExit:
@@ -1194,9 +1250,11 @@ LExit:
1194 1250
1195extern "C" void CacheCleanup( 1251extern "C" void CacheCleanup(
1196 __in BOOL fPerMachine, 1252 __in BOOL fPerMachine,
1197 __in_z LPCWSTR wzBundleId 1253 __in BURN_CACHE* pCache
1198 ) 1254 )
1199{ 1255{
1256 Assert(pCache->fInitializedCache);
1257
1200 HRESULT hr = S_OK; 1258 HRESULT hr = S_OK;
1201 LPWSTR sczFolder = NULL; 1259 LPWSTR sczFolder = NULL;
1202 LPWSTR sczFiles = NULL; 1260 LPWSTR sczFiles = NULL;
@@ -1205,7 +1263,7 @@ extern "C" void CacheCleanup(
1205 WIN32_FIND_DATAW wfd = { }; 1263 WIN32_FIND_DATAW wfd = { };
1206 size_t cchFileName = 0; 1264 size_t cchFileName = 0;
1207 1265
1208 hr = CacheGetCompletedPath(fPerMachine, UNVERIFIED_CACHE_FOLDER_NAME, &sczFolder); 1266 hr = CacheGetCompletedPath(pCache, fPerMachine, UNVERIFIED_CACHE_FOLDER_NAME, &sczFolder);
1209 if (SUCCEEDED(hr)) 1267 if (SUCCEEDED(hr))
1210 { 1268 {
1211 hr = DirEnsureDeleteEx(sczFolder, DIR_DELETE_FILES | DIR_DELETE_RECURSE | DIR_DELETE_SCHEDULE); 1269 hr = DirEnsureDeleteEx(sczFolder, DIR_DELETE_FILES | DIR_DELETE_RECURSE | DIR_DELETE_SCHEDULE);
@@ -1213,10 +1271,9 @@ extern "C" void CacheCleanup(
1213 1271
1214 if (!fPerMachine) 1272 if (!fPerMachine)
1215 { 1273 {
1216 hr = CalculateWorkingFolder(wzBundleId, &sczFolder); 1274 if (pCache->sczWorkingFolder)
1217 if (SUCCEEDED(hr))
1218 { 1275 {
1219 hr = PathConcat(sczFolder, L"*.*", &sczFiles); 1276 hr = PathConcat(pCache->sczWorkingFolder, L"*.*", &sczFiles);
1220 if (SUCCEEDED(hr)) 1277 if (SUCCEEDED(hr))
1221 { 1278 {
1222 hFind = ::FindFirstFileW(sczFiles, &wfd); 1279 hFind = ::FindFirstFileW(sczFiles, &wfd);
@@ -1238,7 +1295,7 @@ extern "C" void CacheCleanup(
1238 continue; 1295 continue;
1239 } 1296 }
1240 1297
1241 hr = PathConcatCch(sczFolder, 0, wfd.cFileName, cchFileName, &sczDelete); 1298 hr = PathConcatCch(pCache->sczWorkingFolder, 0, wfd.cFileName, cchFileName, &sczDelete);
1242 if (SUCCEEDED(hr)) 1299 if (SUCCEEDED(hr))
1243 { 1300 {
1244 hr = FileEnsureDelete(sczDelete); 1301 hr = FileEnsureDelete(sczDelete);
@@ -1259,63 +1316,61 @@ extern "C" void CacheCleanup(
1259 ReleaseStr(sczFolder); 1316 ReleaseStr(sczFolder);
1260} 1317}
1261 1318
1262extern "C" void CacheUninitialize() 1319extern "C" void CacheUninitialize(
1320 __in BURN_CACHE* pCache
1321 )
1263{ 1322{
1264 ReleaseNullStr(vsczCurrentMachinePackageCache); 1323 ReleaseNullStr(pCache->sczCurrentMachinePackageCache);
1265 ReleaseNullStr(vsczDefaultMachinePackageCache); 1324 ReleaseNullStr(pCache->sczDefaultMachinePackageCache);
1266 ReleaseNullStr(vsczDefaultUserPackageCache); 1325 ReleaseNullStr(pCache->sczDefaultUserPackageCache);
1267 ReleaseNullStr(vsczWorkingFolder); 1326 ReleaseNullStr(pCache->sczWorkingFolder);
1268 ReleaseNullStr(vsczSourceProcessFolder); 1327 ReleaseNullStr(pCache->sczSourceProcessFolder);
1269 1328
1270 vfRunningFromCache = FALSE; 1329 pCache->fRunningFromCache = FALSE;
1271 vfInitializedCache = FALSE; 1330 pCache->fInitializedCache = FALSE;
1331 pCache->fInitializedCacheSources = FALSE;
1332 pCache->fPerMachineCacheRootVerified = FALSE;
1333 pCache->fOriginalPerMachineCacheRootVerified = FALSE;
1334 pCache->fUnverifiedCacheFolderCreated = FALSE;
1335 pCache->fCustomMachinePackageCache = FALSE;
1272} 1336}
1273 1337
1274// Internal functions. 1338// Internal functions.
1275 1339
1276static HRESULT CalculateWorkingFolder( 1340static HRESULT CalculateWorkingFolder(
1277 __in_z_opt LPCWSTR /*wzBundleId*/, 1341 __in BURN_CACHE* pCache,
1278 __deref_out_z LPWSTR* psczWorkingFolder 1342 __in BURN_ENGINE_COMMAND* pInternalCommand
1279 ) 1343 )
1280{ 1344{
1281 HRESULT hr = S_OK; 1345 HRESULT hr = S_OK;
1282 RPC_STATUS rs = RPC_S_OK; 1346 RPC_STATUS rs = RPC_S_OK;
1283 BOOL fElevated = FALSE;
1284 LPWSTR sczTempPath = NULL; 1347 LPWSTR sczTempPath = NULL;
1285 UUID guid = {}; 1348 UUID guid = {};
1286 WCHAR wzGuid[39]; 1349 WCHAR wzGuid[39];
1287 1350
1288 if (!vsczWorkingFolder) 1351 if (pInternalCommand->fInitiallyElevated)
1289 { 1352 {
1290 ProcElevated(::GetCurrentProcess(), &fElevated); 1353 hr = PathGetSystemTempPath(&sczTempPath);
1291 1354 ExitOnFailure(hr, "Failed to get system temp folder path for working folder.");
1292 if (fElevated) 1355 }
1293 { 1356 else
1294 hr = PathGetSystemTempPath(&sczTempPath); 1357 {
1295 ExitOnFailure(hr, "Failed to get system temp folder path for working folder."); 1358 hr = PathGetTempPath(&sczTempPath);
1296 } 1359 ExitOnFailure(hr, "Failed to get temp folder path for working folder.");
1297 else 1360 }
1298 {
1299 hr = PathGetTempPath(&sczTempPath);
1300 ExitOnFailure(hr, "Failed to get temp folder path for working folder.");
1301 }
1302
1303 rs = ::UuidCreate(&guid);
1304 hr = HRESULT_FROM_RPC(rs);
1305 ExitOnFailure(hr, "Failed to create working folder guid.");
1306 1361
1307 if (!::StringFromGUID2(guid, wzGuid, countof(wzGuid))) 1362 rs = ::UuidCreate(&guid);
1308 { 1363 hr = HRESULT_FROM_RPC(rs);
1309 hr = E_OUTOFMEMORY; 1364 ExitOnFailure(hr, "Failed to create working folder guid.");
1310 ExitOnRootFailure(hr, "Failed to convert working folder guid into string.");
1311 }
1312 1365
1313 hr = StrAllocFormatted(&vsczWorkingFolder, L"%ls%ls\\", sczTempPath, wzGuid); 1366 if (!::StringFromGUID2(guid, wzGuid, countof(wzGuid)))
1314 ExitOnFailure(hr, "Failed to append bundle id on to temp path for working folder."); 1367 {
1368 hr = E_OUTOFMEMORY;
1369 ExitOnRootFailure(hr, "Failed to convert working folder guid into string.");
1315 } 1370 }
1316 1371
1317 hr = StrAllocString(psczWorkingFolder, vsczWorkingFolder, 0); 1372 hr = StrAllocFormatted(&pCache->sczWorkingFolder, L"%ls%ls\\", sczTempPath, wzGuid);
1318 ExitOnFailure(hr, "Failed to copy working folder path."); 1373 ExitOnFailure(hr, "Failed to append random guid on to temp path for working folder.");
1319 1374
1320LExit: 1375LExit:
1321 ReleaseStr(sczTempPath); 1376 ReleaseStr(sczTempPath);
@@ -1324,78 +1379,33 @@ LExit:
1324} 1379}
1325 1380
1326static HRESULT GetRootPath( 1381static HRESULT GetRootPath(
1382 __in BURN_CACHE* pCache,
1327 __in BOOL fPerMachine, 1383 __in BOOL fPerMachine,
1328 __in BOOL fAllowRedirect, 1384 __in BOOL fAllowRedirect,
1329 __deref_out_z LPWSTR* psczRootPath 1385 __deref_out_z LPWSTR* psczRootPath
1330 ) 1386 )
1331{ 1387{
1388 Assert(pCache->fInitializedCache);
1389
1332 HRESULT hr = S_OK; 1390 HRESULT hr = S_OK;
1333 LPWSTR sczAppData = NULL;
1334 int nCompare = 0;
1335 1391
1336 // Cache paths are initialized once so they cannot be changed while the engine is caching payloads.
1337 if (fPerMachine) 1392 if (fPerMachine)
1338 { 1393 {
1339 // Always construct the default machine package cache path so we can determine if we're redirected. 1394 BOOL fRedirect = fAllowRedirect && pCache->fCustomMachinePackageCache;
1340 if (!vsczDefaultMachinePackageCache)
1341 {
1342 hr = PathGetKnownFolder(CSIDL_COMMON_APPDATA, &sczAppData);
1343 ExitOnFailure(hr, "Failed to find local %hs appdata directory.", "per-machine");
1344
1345 hr = PathConcat(sczAppData, PACKAGE_CACHE_FOLDER_NAME, &vsczDefaultMachinePackageCache);
1346 ExitOnFailure(hr, "Failed to construct %hs package cache directory name.", "per-machine");
1347
1348 hr = PathBackslashTerminate(&vsczDefaultMachinePackageCache);
1349 ExitOnFailure(hr, "Failed to backslash terminate default %hs package cache directory name.", "per-machine");
1350 }
1351 1395
1352 if (!vsczCurrentMachinePackageCache) 1396 hr = StrAllocString(psczRootPath, fRedirect ? pCache->sczCurrentMachinePackageCache : pCache->sczDefaultMachinePackageCache, 0);
1353 {
1354 hr = PolcReadString(POLICY_BURN_REGISTRY_PATH, L"PackageCache", NULL, &vsczCurrentMachinePackageCache);
1355 ExitOnFailure(hr, "Failed to read PackageCache policy directory.");
1356
1357 if (vsczCurrentMachinePackageCache)
1358 {
1359 hr = PathBackslashTerminate(&vsczCurrentMachinePackageCache);
1360 ExitOnFailure(hr, "Failed to backslash terminate redirected per-machine package cache directory name.");
1361 }
1362 else
1363 {
1364 hr = StrAllocString(&vsczCurrentMachinePackageCache, vsczDefaultMachinePackageCache, 0);
1365 ExitOnFailure(hr, "Failed to copy default package cache directory to current package cache directory.");
1366 }
1367 }
1368
1369 hr = StrAllocString(psczRootPath, fAllowRedirect ? vsczCurrentMachinePackageCache : vsczDefaultMachinePackageCache, 0);
1370 ExitOnFailure(hr, "Failed to copy %hs package cache root directory.", "per-machine"); 1397 ExitOnFailure(hr, "Failed to copy %hs package cache root directory.", "per-machine");
1371 1398
1372 hr = PathCompare(vsczDefaultMachinePackageCache, *psczRootPath, &nCompare);
1373 ExitOnFailure(hr, "Failed to compare default and current package cache directories.");
1374
1375 // Return S_FALSE if the current location is not the default location (redirected). 1399 // Return S_FALSE if the current location is not the default location (redirected).
1376 hr = CSTR_EQUAL == nCompare ? S_OK : S_FALSE; 1400 hr = fRedirect ? S_FALSE : S_OK;
1377 } 1401 }
1378 else 1402 else
1379 { 1403 {
1380 if (!vsczDefaultUserPackageCache) 1404 hr = StrAllocString(psczRootPath, pCache->sczDefaultUserPackageCache, 0);
1381 {
1382 hr = PathGetKnownFolder(CSIDL_LOCAL_APPDATA, &sczAppData);
1383 ExitOnFailure(hr, "Failed to find local %hs appdata directory.", "per-user");
1384
1385 hr = PathConcat(sczAppData, PACKAGE_CACHE_FOLDER_NAME, &vsczDefaultUserPackageCache);
1386 ExitOnFailure(hr, "Failed to construct %hs package cache directory name.", "per-user");
1387
1388 hr = PathBackslashTerminate(&vsczDefaultUserPackageCache);
1389 ExitOnFailure(hr, "Failed to backslash terminate default %hs package cache directory name.", "per-user");
1390 }
1391
1392 hr = StrAllocString(psczRootPath, vsczDefaultUserPackageCache, 0);
1393 ExitOnFailure(hr, "Failed to copy %hs package cache root directory.", "per-user"); 1405 ExitOnFailure(hr, "Failed to copy %hs package cache root directory.", "per-user");
1394 } 1406 }
1395 1407
1396LExit: 1408LExit:
1397 ReleaseStr(sczAppData);
1398
1399 return hr; 1409 return hr;
1400} 1410}
1401 1411
@@ -1416,20 +1426,19 @@ static HRESULT GetLastUsedSourceFolder(
1416 return hr; 1426 return hr;
1417} 1427}
1418 1428
1419static HRESULT SecurePerMachineCacheRoot() 1429static HRESULT SecurePerMachineCacheRoot(
1430 __in BURN_CACHE* pCache
1431 )
1420{ 1432{
1421 static BOOL fPerMachineCacheRootVerified = FALSE;
1422 static BOOL fOriginalPerMachineCacheRootVerified = FALSE;
1423
1424 HRESULT hr = S_OK; 1433 HRESULT hr = S_OK;
1425 BOOL fRedirected = FALSE; 1434 BOOL fRedirected = FALSE;
1426 LPWSTR sczCacheDirectory = NULL; 1435 LPWSTR sczCacheDirectory = NULL;
1427 1436
1428 if (!fPerMachineCacheRootVerified) 1437 if (!pCache->fPerMachineCacheRootVerified)
1429 { 1438 {
1430 // If we are doing a permachine install but have not yet verified that the root cache folder 1439 // If we are doing a permachine install but have not yet verified that the root cache folder
1431 // was created with the correct ACLs yet, do that now. 1440 // was created with the correct ACLs yet, do that now.
1432 hr = GetRootPath(TRUE, TRUE, &sczCacheDirectory); 1441 hr = GetRootPath(pCache, TRUE, TRUE, &sczCacheDirectory);
1433 ExitOnFailure(hr, "Failed to get cache directory."); 1442 ExitOnFailure(hr, "Failed to get cache directory.");
1434 1443
1435 fRedirected = S_FALSE == hr; 1444 fRedirected = S_FALSE == hr;
@@ -1440,19 +1449,19 @@ static HRESULT SecurePerMachineCacheRoot()
1440 hr = SecurePath(sczCacheDirectory); 1449 hr = SecurePath(sczCacheDirectory);
1441 ExitOnFailure(hr, "Failed to secure cache directory: %ls", sczCacheDirectory); 1450 ExitOnFailure(hr, "Failed to secure cache directory: %ls", sczCacheDirectory);
1442 1451
1443 fPerMachineCacheRootVerified = TRUE; 1452 pCache->fPerMachineCacheRootVerified = TRUE;
1444 1453
1445 if (!fRedirected) 1454 if (!fRedirected)
1446 { 1455 {
1447 fOriginalPerMachineCacheRootVerified = TRUE; 1456 pCache->fOriginalPerMachineCacheRootVerified = TRUE;
1448 } 1457 }
1449 } 1458 }
1450 1459
1451 if (!fOriginalPerMachineCacheRootVerified) 1460 if (!pCache->fOriginalPerMachineCacheRootVerified)
1452 { 1461 {
1453 // If we are doing a permachine install but have not yet verified that the original root cache folder 1462 // If we are doing a permachine install but have not yet verified that the original root cache folder
1454 // was created with the correct ACLs yet, do that now. 1463 // was created with the correct ACLs yet, do that now.
1455 hr = GetRootPath(TRUE, FALSE, &sczCacheDirectory); 1464 hr = GetRootPath(pCache, TRUE, FALSE, &sczCacheDirectory);
1456 ExitOnFailure(hr, "Failed to get original cache directory."); 1465 ExitOnFailure(hr, "Failed to get original cache directory.");
1457 1466
1458 hr = DirEnsureExists(sczCacheDirectory, NULL); 1467 hr = DirEnsureExists(sczCacheDirectory, NULL);
@@ -1461,7 +1470,7 @@ static HRESULT SecurePerMachineCacheRoot()
1461 hr = SecurePath(sczCacheDirectory); 1470 hr = SecurePath(sczCacheDirectory);
1462 ExitOnFailure(hr, "Failed to secure original cache directory: %ls", sczCacheDirectory); 1471 ExitOnFailure(hr, "Failed to secure original cache directory: %ls", sczCacheDirectory);
1463 1472
1464 fOriginalPerMachineCacheRootVerified = TRUE; 1473 pCache->fOriginalPerMachineCacheRootVerified = TRUE;
1465 } 1474 }
1466 1475
1467LExit: 1476LExit:
@@ -1471,6 +1480,7 @@ LExit:
1471} 1480}
1472 1481
1473static HRESULT CreateCompletedPath( 1482static HRESULT CreateCompletedPath(
1483 __in BURN_CACHE* pCache,
1474 __in BOOL fPerMachine, 1484 __in BOOL fPerMachine,
1475 __in LPCWSTR wzId, 1485 __in LPCWSTR wzId,
1476 __in LPCWSTR wzFilePath, 1486 __in LPCWSTR wzFilePath,
@@ -1483,12 +1493,12 @@ static HRESULT CreateCompletedPath(
1483 1493
1484 if (fPerMachine) 1494 if (fPerMachine)
1485 { 1495 {
1486 hr = SecurePerMachineCacheRoot(); 1496 hr = SecurePerMachineCacheRoot(pCache);
1487 ExitOnFailure(hr, "Failed to secure per-machine cache root."); 1497 ExitOnFailure(hr, "Failed to secure per-machine cache root.");
1488 } 1498 }
1489 1499
1490 // Get the cache completed path. 1500 // Get the cache completed path.
1491 hr = CacheGetCompletedPath(fPerMachine, wzId, &sczCacheDirectory); 1501 hr = CacheGetCompletedPath(pCache, fPerMachine, wzId, &sczCacheDirectory);
1492 ExitOnFailure(hr, "Failed to get cache directory."); 1502 ExitOnFailure(hr, "Failed to get cache directory.");
1493 1503
1494 // Ensure it exists. 1504 // Ensure it exists.
@@ -1523,25 +1533,26 @@ LExit:
1523} 1533}
1524 1534
1525static HRESULT CreateUnverifiedPath( 1535static HRESULT CreateUnverifiedPath(
1536 __in BURN_CACHE* pCache,
1526 __in BOOL fPerMachine, 1537 __in BOOL fPerMachine,
1527 __in_z LPCWSTR wzPayloadId, 1538 __in_z LPCWSTR wzPayloadId,
1528 __out_z LPWSTR* psczUnverifiedPayloadPath 1539 __out_z LPWSTR* psczUnverifiedPayloadPath
1529 ) 1540 )
1530{ 1541{
1531 static BOOL fUnverifiedCacheFolderCreated = FALSE;
1532
1533 HRESULT hr = S_OK; 1542 HRESULT hr = S_OK;
1534 LPWSTR sczUnverifiedCacheFolder = NULL; 1543 LPWSTR sczUnverifiedCacheFolder = NULL;
1535 1544
1536 hr = CacheGetCompletedPath(fPerMachine, UNVERIFIED_CACHE_FOLDER_NAME, &sczUnverifiedCacheFolder); 1545 hr = CacheGetCompletedPath(pCache, fPerMachine, UNVERIFIED_CACHE_FOLDER_NAME, &sczUnverifiedCacheFolder);
1537 ExitOnFailure(hr, "Failed to get cache directory."); 1546 ExitOnFailure(hr, "Failed to get cache directory.");
1538 1547
1539 if (!fUnverifiedCacheFolderCreated) 1548 if (!pCache->fUnverifiedCacheFolderCreated)
1540 { 1549 {
1541 hr = DirEnsureExists(sczUnverifiedCacheFolder, NULL); 1550 hr = DirEnsureExists(sczUnverifiedCacheFolder, NULL);
1542 ExitOnFailure(hr, "Failed to create unverified cache directory: %ls", sczUnverifiedCacheFolder); 1551 ExitOnFailure(hr, "Failed to create unverified cache directory: %ls", sczUnverifiedCacheFolder);
1543 1552
1544 ResetPathPermissions(fPerMachine, sczUnverifiedCacheFolder); 1553 ResetPathPermissions(fPerMachine, sczUnverifiedCacheFolder);
1554
1555 pCache->fUnverifiedCacheFolderCreated = TRUE;
1545 } 1556 }
1546 1557
1547 hr = PathConcat(sczUnverifiedCacheFolder, wzPayloadId, psczUnverifiedPayloadPath); 1558 hr = PathConcat(sczUnverifiedCacheFolder, wzPayloadId, psczUnverifiedPayloadPath);
@@ -1946,6 +1957,7 @@ LExit:
1946 1957
1947 1958
1948static HRESULT CopyEngineToWorkingFolder( 1959static HRESULT CopyEngineToWorkingFolder(
1960 __in BURN_CACHE* pCache,
1949 __in_z LPCWSTR wzSourcePath, 1961 __in_z LPCWSTR wzSourcePath,
1950 __in_z LPCWSTR wzWorkingFolderName, 1962 __in_z LPCWSTR wzWorkingFolderName,
1951 __in_z LPCWSTR wzExecutableName, 1963 __in_z LPCWSTR wzExecutableName,
@@ -1961,7 +1973,7 @@ static HRESULT CopyEngineToWorkingFolder(
1961 LPWSTR sczPayloadSourcePath = NULL; 1973 LPWSTR sczPayloadSourcePath = NULL;
1962 LPWSTR sczPayloadTargetPath = NULL; 1974 LPWSTR sczPayloadTargetPath = NULL;
1963 1975
1964 hr = CacheEnsureWorkingFolder(NULL, &sczWorkingFolder); 1976 hr = CacheEnsureWorkingFolder(pCache, &sczWorkingFolder);
1965 ExitOnFailure(hr, "Failed to create working path to copy engine."); 1977 ExitOnFailure(hr, "Failed to create working path to copy engine.");
1966 1978
1967 hr = PathConcat(sczWorkingFolder, wzWorkingFolderName, &sczTargetDirectory); 1979 hr = PathConcat(sczWorkingFolder, wzWorkingFolderName, &sczTargetDirectory);
@@ -2064,6 +2076,7 @@ LExit:
2064 2076
2065 2077
2066static HRESULT RemoveBundleOrPackage( 2078static HRESULT RemoveBundleOrPackage(
2079 __in BURN_CACHE* pCache,
2067 __in BOOL fBundle, 2080 __in BOOL fBundle,
2068 __in BOOL fPerMachine, 2081 __in BOOL fPerMachine,
2069 __in_z LPCWSTR wzBundleOrPackageId, 2082 __in_z LPCWSTR wzBundleOrPackageId,
@@ -2074,7 +2087,7 @@ static HRESULT RemoveBundleOrPackage(
2074 LPWSTR sczRootCacheDirectory = NULL; 2087 LPWSTR sczRootCacheDirectory = NULL;
2075 LPWSTR sczDirectory = NULL; 2088 LPWSTR sczDirectory = NULL;
2076 2089
2077 hr = CacheGetCompletedPath(fPerMachine, wzCacheId, &sczDirectory); 2090 hr = CacheGetCompletedPath(pCache, fPerMachine, wzCacheId, &sczDirectory);
2078 ExitOnFailure(hr, "Failed to calculate cache path."); 2091 ExitOnFailure(hr, "Failed to calculate cache path.");
2079 2092
2080 LogId(REPORT_STANDARD, fBundle ? MSG_UNCACHE_BUNDLE : MSG_UNCACHE_PACKAGE, wzBundleOrPackageId, sczDirectory); 2093 LogId(REPORT_STANDARD, fBundle ? MSG_UNCACHE_BUNDLE : MSG_UNCACHE_PACKAGE, wzBundleOrPackageId, sczDirectory);
@@ -2103,14 +2116,14 @@ static HRESULT RemoveBundleOrPackage(
2103 else 2116 else
2104 { 2117 {
2105 // Try to remove root package cache in the off chance it is now empty. 2118 // Try to remove root package cache in the off chance it is now empty.
2106 hr = GetRootPath(fPerMachine, TRUE, &sczRootCacheDirectory); 2119 hr = GetRootPath(pCache, fPerMachine, TRUE, &sczRootCacheDirectory);
2107 ExitOnFailure(hr, "Failed to get %hs package cache root directory.", fPerMachine ? "per-machine" : "per-user"); 2120 ExitOnFailure(hr, "Failed to get %hs package cache root directory.", fPerMachine ? "per-machine" : "per-user");
2108 DirEnsureDeleteEx(sczRootCacheDirectory, DIR_DELETE_SCHEDULE); 2121 DirEnsureDeleteEx(sczRootCacheDirectory, DIR_DELETE_SCHEDULE);
2109 2122
2110 // GetRootPath returns S_FALSE if the package cache is redirected elsewhere. 2123 // GetRootPath returns S_FALSE if the package cache is redirected elsewhere.
2111 if (S_FALSE == hr) 2124 if (S_FALSE == hr)
2112 { 2125 {
2113 hr = GetRootPath(fPerMachine, FALSE, &sczRootCacheDirectory); 2126 hr = GetRootPath(pCache, fPerMachine, FALSE, &sczRootCacheDirectory);
2114 ExitOnFailure(hr, "Failed to get old %hs package cache root directory.", fPerMachine ? "per-machine" : "per-user"); 2127 ExitOnFailure(hr, "Failed to get old %hs package cache root directory.", fPerMachine ? "per-machine" : "per-user");
2115 DirEnsureDeleteEx(sczRootCacheDirectory, DIR_DELETE_SCHEDULE); 2128 DirEnsureDeleteEx(sczRootCacheDirectory, DIR_DELETE_SCHEDULE);
2116 } 2129 }
diff --git a/src/burn/engine/cache.h b/src/burn/engine/cache.h
index dfb4f69f..69d82639 100644
--- a/src/burn/engine/cache.h
+++ b/src/burn/engine/cache.h
@@ -24,6 +24,24 @@ enum BURN_CACHE_STEP
24 BURN_CACHE_STEP_FINALIZE, 24 BURN_CACHE_STEP_FINALIZE,
25}; 25};
26 26
27typedef struct _BURN_CACHE
28{
29 BOOL fInitializedCache;
30 BOOL fPerMachineCacheRootVerified;
31 BOOL fOriginalPerMachineCacheRootVerified;
32 BOOL fUnverifiedCacheFolderCreated;
33 BOOL fCustomMachinePackageCache;
34 LPWSTR sczDefaultUserPackageCache;
35 LPWSTR sczDefaultMachinePackageCache;
36 LPWSTR sczCurrentMachinePackageCache;
37
38 // Only valid after CacheInitializeSources
39 BOOL fInitializedCacheSources;
40 BOOL fRunningFromCache;
41 LPWSTR sczSourceProcessFolder;
42 LPWSTR sczWorkingFolder;
43} BURN_CACHE;
44
27typedef struct _BURN_CACHE_MESSAGE 45typedef struct _BURN_CACHE_MESSAGE
28{ 46{
29 BURN_CACHE_MESSAGE_TYPE type; 47 BURN_CACHE_MESSAGE_TYPE type;
@@ -53,38 +71,46 @@ typedef HRESULT(CALLBACK* PFN_BURNCACHEMESSAGEHANDLER)(
53// functions 71// functions
54 72
55HRESULT CacheInitialize( 73HRESULT CacheInitialize(
74 __in BURN_CACHE* pCache,
75 __in BURN_ENGINE_COMMAND* pInternalCommand
76 );
77HRESULT CacheInitializeSources(
78 __in BURN_CACHE* pCache,
56 __in BURN_REGISTRATION* pRegistration, 79 __in BURN_REGISTRATION* pRegistration,
57 __in BURN_VARIABLES* pVariables, 80 __in BURN_VARIABLES* pVariables,
58 __in_z_opt LPCWSTR wzSourceProcessPath 81 __in BURN_ENGINE_COMMAND* pInternalCommand
59 ); 82 );
60HRESULT CacheEnsureWorkingFolder( 83HRESULT CacheEnsureWorkingFolder(
61 __in_z_opt LPCWSTR wzBundleId, 84 __in BURN_CACHE* pCache,
62 __deref_out_z_opt LPWSTR* psczWorkingFolder 85 __deref_out_z_opt LPWSTR* psczWorkingFolder
63 ); 86 );
64HRESULT CacheCalculateBundleWorkingPath( 87HRESULT CacheCalculateBundleWorkingPath(
65 __in_z LPCWSTR wzBundleId, 88 __in BURN_CACHE* pCache,
66 __in LPCWSTR wzExecutableName, 89 __in LPCWSTR wzExecutableName,
67 __deref_out_z LPWSTR* psczWorkingPath 90 __deref_out_z LPWSTR* psczWorkingPath
68 ); 91 );
69HRESULT CacheCalculateBundleLayoutWorkingPath( 92HRESULT CacheCalculateBundleLayoutWorkingPath(
93 __in BURN_CACHE* pCache,
70 __in_z LPCWSTR wzBundleId, 94 __in_z LPCWSTR wzBundleId,
71 __deref_out_z LPWSTR* psczWorkingPath 95 __deref_out_z LPWSTR* psczWorkingPath
72 ); 96 );
73HRESULT CacheCalculatePayloadWorkingPath( 97HRESULT CacheCalculatePayloadWorkingPath(
74 __in_z LPCWSTR wzBundleId, 98 __in BURN_CACHE* pCache,
75 __in BURN_PAYLOAD* pPayload, 99 __in BURN_PAYLOAD* pPayload,
76 __deref_out_z LPWSTR* psczWorkingPath 100 __deref_out_z LPWSTR* psczWorkingPath
77 ); 101 );
78HRESULT CacheCalculateContainerWorkingPath( 102HRESULT CacheCalculateContainerWorkingPath(
79 __in_z LPCWSTR wzBundleId, 103 __in BURN_CACHE* pCache,
80 __in BURN_CONTAINER* pContainer, 104 __in BURN_CONTAINER* pContainer,
81 __deref_out_z LPWSTR* psczWorkingPath 105 __deref_out_z LPWSTR* psczWorkingPath
82 ); 106 );
83HRESULT CacheGetPerMachineRootCompletedPath( 107HRESULT CacheGetPerMachineRootCompletedPath(
108 __in BURN_CACHE* pCache,
84 __out_z LPWSTR* psczCurrentRootCompletedPath, 109 __out_z LPWSTR* psczCurrentRootCompletedPath,
85 __out_z LPWSTR* psczDefaultRootCompletedPath 110 __out_z LPWSTR* psczDefaultRootCompletedPath
86 ); 111 );
87HRESULT CacheGetCompletedPath( 112HRESULT CacheGetCompletedPath(
113 __in BURN_CACHE* pCache,
88 __in BOOL fPerMachine, 114 __in BOOL fPerMachine,
89 __in_z LPCWSTR wzCacheId, 115 __in_z LPCWSTR wzCacheId,
90 __deref_out_z LPWSTR* psczCompletedPath 116 __deref_out_z LPWSTR* psczCompletedPath
@@ -98,6 +124,7 @@ HRESULT CacheGetLocalSourcePaths(
98 __in_z LPCWSTR wzSourcePath, 124 __in_z LPCWSTR wzSourcePath,
99 __in_z LPCWSTR wzDestinationPath, 125 __in_z LPCWSTR wzDestinationPath,
100 __in_z_opt LPCWSTR wzLayoutDirectory, 126 __in_z_opt LPCWSTR wzLayoutDirectory,
127 __in BURN_CACHE* pCache,
101 __in BURN_VARIABLES* pVariables, 128 __in BURN_VARIABLES* pVariables,
102 __inout LPWSTR** prgSearchPaths, 129 __inout LPWSTR** prgSearchPaths,
103 __out DWORD* pcSearchPaths, 130 __out DWORD* pcSearchPaths,
@@ -121,16 +148,20 @@ void CacheSendErrorCallback(
121 __in_z_opt LPCWSTR wzError, 148 __in_z_opt LPCWSTR wzError,
122 __out_opt BOOL* pfRetry 149 __out_opt BOOL* pfRetry
123 ); 150 );
124BOOL CacheBundleRunningFromCache(); 151BOOL CacheBundleRunningFromCache(
152 __in BURN_CACHE* pCache
153 );
125HRESULT CachePreparePackage( 154HRESULT CachePreparePackage(
155 __in BURN_CACHE* pCache,
126 __in BURN_PACKAGE* pPackage 156 __in BURN_PACKAGE* pPackage
127 ); 157 );
128HRESULT CacheBundleToCleanRoom( 158HRESULT CacheBundleToCleanRoom(
159 __in BURN_CACHE* pCache,
129 __in BURN_SECTION* pSection, 160 __in BURN_SECTION* pSection,
130 __deref_out_z_opt LPWSTR* psczCleanRoomBundlePath 161 __deref_out_z_opt LPWSTR* psczCleanRoomBundlePath
131 ); 162 );
132HRESULT CacheBundleToWorkingDirectory( 163HRESULT CacheBundleToWorkingDirectory(
133 __in_z LPCWSTR wzBundleId, 164 __in BURN_CACHE* pCache,
134 __in_z LPCWSTR wzExecutableName, 165 __in_z LPCWSTR wzExecutableName,
135 __in BURN_SECTION* pSection, 166 __in BURN_SECTION* pSection,
136 __deref_out_z_opt LPWSTR* psczEngineWorkingPath 167 __deref_out_z_opt LPWSTR* psczEngineWorkingPath
@@ -145,6 +176,7 @@ HRESULT CacheLayoutBundle(
145 __in LPVOID pContext 176 __in LPVOID pContext
146 ); 177 );
147HRESULT CacheCompleteBundle( 178HRESULT CacheCompleteBundle(
179 __in BURN_CACHE* pCache,
148 __in BOOL fPerMachine, 180 __in BOOL fPerMachine,
149 __in_z LPCWSTR wzExecutableName, 181 __in_z LPCWSTR wzExecutableName,
150 __in_z LPCWSTR wzBundleId, 182 __in_z LPCWSTR wzBundleId,
@@ -172,6 +204,7 @@ HRESULT CacheLayoutPayload(
172 __in LPVOID pContext 204 __in LPVOID pContext
173 ); 205 );
174HRESULT CacheCompletePayload( 206HRESULT CacheCompletePayload(
207 __in BURN_CACHE* pCache,
175 __in BOOL fPerMachine, 208 __in BOOL fPerMachine,
176 __in BURN_PAYLOAD* pPayload, 209 __in BURN_PAYLOAD* pPayload,
177 __in_z LPCWSTR wzCacheId, 210 __in_z LPCWSTR wzCacheId,
@@ -196,22 +229,26 @@ HRESULT CacheVerifyPayload(
196 __in LPVOID pContext 229 __in LPVOID pContext
197 ); 230 );
198HRESULT CacheRemoveWorkingFolder( 231HRESULT CacheRemoveWorkingFolder(
199 __in_z_opt LPCWSTR wzBundleId 232 __in BURN_CACHE* pCache
200 ); 233 );
201HRESULT CacheRemoveBundle( 234HRESULT CacheRemoveBundle(
235 __in BURN_CACHE* pCache,
202 __in BOOL fPerMachine, 236 __in BOOL fPerMachine,
203 __in_z LPCWSTR wzPackageId 237 __in_z LPCWSTR wzPackageId
204 ); 238 );
205HRESULT CacheRemovePackage( 239HRESULT CacheRemovePackage(
240 __in BURN_CACHE* pCache,
206 __in BOOL fPerMachine, 241 __in BOOL fPerMachine,
207 __in_z LPCWSTR wzPackageId, 242 __in_z LPCWSTR wzPackageId,
208 __in_z LPCWSTR wzCacheId 243 __in_z LPCWSTR wzCacheId
209 ); 244 );
210void CacheCleanup( 245void CacheCleanup(
211 __in BOOL fPerMachine, 246 __in BOOL fPerMachine,
212 __in_z LPCWSTR wzBundleId 247 __in BURN_CACHE* pCache
248 );
249void CacheUninitialize(
250 __in BURN_CACHE* pCache
213 ); 251 );
214void CacheUninitialize();
215 252
216#ifdef __cplusplus 253#ifdef __cplusplus
217} 254}
diff --git a/src/burn/engine/core.cpp b/src/burn/engine/core.cpp
index 0468d406..8985ab27 100644
--- a/src/burn/engine/core.cpp
+++ b/src/burn/engine/core.cpp
@@ -32,6 +32,7 @@ static HRESULT DetectPackage(
32 __in BURN_PACKAGE* pPackage 32 __in BURN_PACKAGE* pPackage
33 ); 33 );
34static HRESULT DetectPackagePayloadsCached( 34static HRESULT DetectPackagePayloadsCached(
35 __in BURN_CACHE* pCache,
35 __in BURN_PACKAGE* pPackage 36 __in BURN_PACKAGE* pPackage
36 ); 37 );
37static DWORD WINAPI CacheThreadProc( 38static DWORD WINAPI CacheThreadProc(
@@ -65,7 +66,6 @@ extern "C" HRESULT CoreInitialize(
65 BYTE* pbBuffer = NULL; 66 BYTE* pbBuffer = NULL;
66 SIZE_T cbBuffer = 0; 67 SIZE_T cbBuffer = 0;
67 BURN_CONTAINER_CONTEXT containerContext = { }; 68 BURN_CONTAINER_CONTEXT containerContext = { };
68 BOOL fElevated = FALSE;
69 LPWSTR sczSourceProcessFolder = NULL; 69 LPWSTR sczSourceProcessFolder = NULL;
70 70
71 // Initialize variables. 71 // Initialize variables.
@@ -105,10 +105,7 @@ extern "C" HRESULT CoreInitialize(
105 hr = CoreInitializeConstants(pEngineState); 105 hr = CoreInitializeConstants(pEngineState);
106 ExitOnFailure(hr, "Failed to initialize contants."); 106 ExitOnFailure(hr, "Failed to initialize contants.");
107 107
108 // Retain whether bundle was initially run elevated. 108 hr = VariableSetNumeric(&pEngineState->variables, BURN_BUNDLE_ELEVATED, pEngineState->internalCommand.fInitiallyElevated, TRUE);
109 ProcElevated(::GetCurrentProcess(), &fElevated);
110
111 hr = VariableSetNumeric(&pEngineState->variables, BURN_BUNDLE_ELEVATED, fElevated, TRUE);
112 ExitOnFailure(hr, "Failed to overwrite the %ls built-in variable.", BURN_BUNDLE_ELEVATED); 109 ExitOnFailure(hr, "Failed to overwrite the %ls built-in variable.", BURN_BUNDLE_ELEVATED);
113 110
114 hr = VariableSetNumeric(&pEngineState->variables, BURN_BUNDLE_UILEVEL, pEngineState->command.display, TRUE); 111 hr = VariableSetNumeric(&pEngineState->variables, BURN_BUNDLE_UILEVEL, pEngineState->command.display, TRUE);
@@ -136,8 +133,8 @@ extern "C" HRESULT CoreInitialize(
136 133
137 if (BURN_MODE_UNTRUSTED == pEngineState->mode || BURN_MODE_NORMAL == pEngineState->mode || BURN_MODE_EMBEDDED == pEngineState->mode) 134 if (BURN_MODE_UNTRUSTED == pEngineState->mode || BURN_MODE_NORMAL == pEngineState->mode || BURN_MODE_EMBEDDED == pEngineState->mode)
138 { 135 {
139 hr = CacheInitialize(&pEngineState->registration, &pEngineState->variables, pEngineState->internalCommand.sczSourceProcessPath); 136 hr = CacheInitializeSources(&pEngineState->cache, &pEngineState->registration, &pEngineState->variables, &pEngineState->internalCommand);
140 ExitOnFailure(hr, "Failed to initialize internal cache functionality."); 137 ExitOnFailure(hr, "Failed to initialize internal cache source functionality.");
141 } 138 }
142 139
143 // If we're not elevated then we'll be loading the bootstrapper application, so extract 140 // If we're not elevated then we'll be loading the bootstrapper application, so extract
@@ -145,7 +142,7 @@ extern "C" HRESULT CoreInitialize(
145 if (BURN_MODE_NORMAL == pEngineState->mode || BURN_MODE_EMBEDDED == pEngineState->mode) 142 if (BURN_MODE_NORMAL == pEngineState->mode || BURN_MODE_EMBEDDED == pEngineState->mode)
146 { 143 {
147 // Extract all UX payloads to working folder. 144 // Extract all UX payloads to working folder.
148 hr = UserExperienceEnsureWorkingFolder(pEngineState->registration.sczId, &pEngineState->userExperience.sczTempDirectory); 145 hr = UserExperienceEnsureWorkingFolder(&pEngineState->cache, &pEngineState->userExperience.sczTempDirectory);
149 ExitOnFailure(hr, "Failed to get unique temporary folder for bootstrapper application."); 146 ExitOnFailure(hr, "Failed to get unique temporary folder for bootstrapper application.");
150 147
151 hr = PayloadExtractUXContainer(&pEngineState->userExperience.payloads, &containerContext, pEngineState->userExperience.sczTempDirectory); 148 hr = PayloadExtractUXContainer(&pEngineState->userExperience.payloads, &containerContext, pEngineState->userExperience.sczTempDirectory);
@@ -455,6 +452,7 @@ extern "C" HRESULT CorePlan(
455 // Remember the overall action state in the plan since it shapes the changes 452 // Remember the overall action state in the plan since it shapes the changes
456 // we make everywhere. 453 // we make everywhere.
457 pEngineState->plan.action = action; 454 pEngineState->plan.action = action;
455 pEngineState->plan.pCache = &pEngineState->cache;
458 pEngineState->plan.pPayloads = &pEngineState->payloads; 456 pEngineState->plan.pPayloads = &pEngineState->payloads;
459 pEngineState->plan.wzBundleId = pEngineState->registration.sczId; 457 pEngineState->plan.wzBundleId = pEngineState->registration.sczId;
460 pEngineState->plan.wzBundleProviderKey = pEngineState->registration.sczId; 458 pEngineState->plan.wzBundleProviderKey = pEngineState->registration.sczId;
@@ -571,7 +569,7 @@ extern "C" HRESULT CoreElevate(
571 // If the elevated companion pipe isn't created yet, let's make that happen. 569 // If the elevated companion pipe isn't created yet, let's make that happen.
572 if (!pEngineState->sczBundleEngineWorkingPath) 570 if (!pEngineState->sczBundleEngineWorkingPath)
573 { 571 {
574 hr = CacheBundleToWorkingDirectory(pEngineState->registration.sczId, pEngineState->registration.sczExecutableName, &pEngineState->section, &pEngineState->sczBundleEngineWorkingPath); 572 hr = CacheBundleToWorkingDirectory(&pEngineState->cache, pEngineState->registration.sczExecutableName, &pEngineState->section, &pEngineState->sczBundleEngineWorkingPath);
575 ExitOnFailure(hr, "Failed to cache engine to working directory."); 573 ExitOnFailure(hr, "Failed to cache engine to working directory.");
576 } 574 }
577 575
@@ -673,7 +671,7 @@ extern "C" HRESULT CoreApply(
673 // Ensure the engine is cached to the working path. 671 // Ensure the engine is cached to the working path.
674 if (!pEngineState->sczBundleEngineWorkingPath) 672 if (!pEngineState->sczBundleEngineWorkingPath)
675 { 673 {
676 hr = CacheBundleToWorkingDirectory(pEngineState->registration.sczId, pEngineState->registration.sczExecutableName, &pEngineState->section, &pEngineState->sczBundleEngineWorkingPath); 674 hr = CacheBundleToWorkingDirectory(&pEngineState->cache, pEngineState->registration.sczExecutableName, &pEngineState->section, &pEngineState->sczBundleEngineWorkingPath);
677 ExitOnFailure(hr, "Failed to cache engine to working directory."); 675 ExitOnFailure(hr, "Failed to cache engine to working directory.");
678 } 676 }
679 677
@@ -1740,7 +1738,7 @@ static HRESULT DetectPackage(
1740 ExitOnRootFailure(hr, "BA aborted detect package begin."); 1738 ExitOnRootFailure(hr, "BA aborted detect package begin.");
1741 1739
1742 // Detect the cache state of the package. 1740 // Detect the cache state of the package.
1743 hr = DetectPackagePayloadsCached(pPackage); 1741 hr = DetectPackagePayloadsCached(&pEngineState->cache, pPackage);
1744 ExitOnFailure(hr, "Failed to detect if payloads are all cached for package: %ls", pPackage->sczId); 1742 ExitOnFailure(hr, "Failed to detect if payloads are all cached for package: %ls", pPackage->sczId);
1745 1743
1746 // Use the correct engine to detect the package. 1744 // Use the correct engine to detect the package.
@@ -1782,6 +1780,7 @@ LExit:
1782} 1780}
1783 1781
1784static HRESULT DetectPackagePayloadsCached( 1782static HRESULT DetectPackagePayloadsCached(
1783 __in BURN_CACHE* pCache,
1785 __in BURN_PACKAGE* pPackage 1784 __in BURN_PACKAGE* pPackage
1786 ) 1785 )
1787{ 1786{
@@ -1792,7 +1791,7 @@ static HRESULT DetectPackagePayloadsCached(
1792 1791
1793 if (pPackage->sczCacheId && *pPackage->sczCacheId) 1792 if (pPackage->sczCacheId && *pPackage->sczCacheId)
1794 { 1793 {
1795 hr = CacheGetCompletedPath(pPackage->fPerMachine, pPackage->sczCacheId, &sczCachePath); 1794 hr = CacheGetCompletedPath(pCache, pPackage->fPerMachine, pPackage->sczCacheId, &sczCachePath);
1796 ExitOnFailure(hr, "Failed to get completed cache path."); 1795 ExitOnFailure(hr, "Failed to get completed cache path.");
1797 1796
1798 // If the cached directory exists, we have something. 1797 // If the cached directory exists, we have something.
diff --git a/src/burn/engine/core.h b/src/burn/engine/core.h
index 3fa1f04a..9bb06147 100644
--- a/src/burn/engine/core.h
+++ b/src/burn/engine/core.h
@@ -80,6 +80,7 @@ enum BURN_AU_PAUSE_ACTION
80 80
81typedef struct _BURN_ENGINE_COMMAND 81typedef struct _BURN_ENGINE_COMMAND
82{ 82{
83 BOOL fInitiallyElevated;
83 LPWSTR sczSourceProcessPath; 84 LPWSTR sczSourceProcessPath;
84 LPWSTR sczOriginalSource; 85 LPWSTR sczOriginalSource;
85} BURN_ENGINE_COMMAND; 86} BURN_ENGINE_COMMAND;
@@ -109,6 +110,7 @@ typedef struct _BURN_ENGINE_STATE
109 BURN_PACKAGES packages; 110 BURN_PACKAGES packages;
110 BURN_UPDATE update; 111 BURN_UPDATE update;
111 BURN_APPROVED_EXES approvedExes; 112 BURN_APPROVED_EXES approvedExes;
113 BURN_CACHE cache;
112 BURN_EXTENSIONS extensions; 114 BURN_EXTENSIONS extensions;
113 115
114 HWND hMessageWindow; 116 HWND hMessageWindow;
diff --git a/src/burn/engine/elevation.cpp b/src/burn/engine/elevation.cpp
index db2a82a6..a0ad6685 100644
--- a/src/burn/engine/elevation.cpp
+++ b/src/burn/engine/elevation.cpp
@@ -88,6 +88,7 @@ typedef struct _BURN_ELEVATION_CHILD_MESSAGE_CONTEXT
88 HANDLE* phLock; 88 HANDLE* phLock;
89 BOOL* pfDisabledAutomaticUpdates; 89 BOOL* pfDisabledAutomaticUpdates;
90 BURN_APPROVED_EXES* pApprovedExes; 90 BURN_APPROVED_EXES* pApprovedExes;
91 BURN_CACHE* pCache;
91 BURN_CONTAINERS* pContainers; 92 BURN_CONTAINERS* pContainers;
92 BURN_PACKAGES* pPackages; 93 BURN_PACKAGES* pPackages;
93 BURN_PAYLOADS* pPayloads; 94 BURN_PAYLOADS* pPayloads;
@@ -164,6 +165,7 @@ static HRESULT OnApplyUninitialize(
164 __in HANDLE* phLock 165 __in HANDLE* phLock
165 ); 166 );
166static HRESULT OnSessionBegin( 167static HRESULT OnSessionBegin(
168 __in BURN_CACHE* pCache,
167 __in BURN_REGISTRATION* pRegistration, 169 __in BURN_REGISTRATION* pRegistration,
168 __in BURN_VARIABLES* pVariables, 170 __in BURN_VARIABLES* pVariables,
169 __in BYTE* pbData, 171 __in BYTE* pbData,
@@ -176,6 +178,7 @@ static HRESULT OnSessionResume(
176 __in SIZE_T cbData 178 __in SIZE_T cbData
177 ); 179 );
178static HRESULT OnSessionEnd( 180static HRESULT OnSessionEnd(
181 __in BURN_CACHE* pCache,
179 __in BURN_PACKAGES* pPackages, 182 __in BURN_PACKAGES* pPackages,
180 __in BURN_REGISTRATION* pRegistration, 183 __in BURN_REGISTRATION* pRegistration,
181 __in BURN_VARIABLES* pVariables, 184 __in BURN_VARIABLES* pVariables,
@@ -188,12 +191,14 @@ static HRESULT OnSaveState(
188 __in SIZE_T cbData 191 __in SIZE_T cbData
189 ); 192 );
190static HRESULT OnCachePreparePackage( 193static HRESULT OnCachePreparePackage(
194 __in BURN_CACHE* pCache,
191 __in BURN_PACKAGES* pPackages, 195 __in BURN_PACKAGES* pPackages,
192 __in BYTE* pbData, 196 __in BYTE* pbData,
193 __in SIZE_T cbData 197 __in SIZE_T cbData
194 ); 198 );
195static HRESULT OnCacheCompletePayload( 199static HRESULT OnCacheCompletePayload(
196 __in HANDLE hPipe, 200 __in HANDLE hPipe,
201 __in BURN_CACHE* pCache,
197 __in BURN_PACKAGES* pPackages, 202 __in BURN_PACKAGES* pPackages,
198 __in BURN_PAYLOADS* pPayloads, 203 __in BURN_PAYLOADS* pPayloads,
199 __in BYTE* pbData, 204 __in BYTE* pbData,
@@ -207,7 +212,7 @@ static HRESULT OnCacheVerifyPayload(
207 __in SIZE_T cbData 212 __in SIZE_T cbData
208 ); 213 );
209static void OnCacheCleanup( 214static void OnCacheCleanup(
210 __in_z LPCWSTR wzBundleId 215 __in BURN_CACHE* pCache
211 ); 216 );
212static HRESULT OnProcessDependentRegistration( 217static HRESULT OnProcessDependentRegistration(
213 __in const BURN_REGISTRATION* pRegistration, 218 __in const BURN_REGISTRATION* pRegistration,
@@ -216,6 +221,7 @@ static HRESULT OnProcessDependentRegistration(
216 ); 221 );
217static HRESULT OnExecuteExePackage( 222static HRESULT OnExecuteExePackage(
218 __in HANDLE hPipe, 223 __in HANDLE hPipe,
224 __in BURN_CACHE* pCache,
219 __in BURN_PACKAGES* pPackages, 225 __in BURN_PACKAGES* pPackages,
220 __in BURN_RELATED_BUNDLES* pRelatedBundles, 226 __in BURN_RELATED_BUNDLES* pRelatedBundles,
221 __in BURN_VARIABLES* pVariables, 227 __in BURN_VARIABLES* pVariables,
@@ -224,6 +230,7 @@ static HRESULT OnExecuteExePackage(
224 ); 230 );
225static HRESULT OnExecuteMsiPackage( 231static HRESULT OnExecuteMsiPackage(
226 __in HANDLE hPipe, 232 __in HANDLE hPipe,
233 __in BURN_CACHE* pCache,
227 __in BURN_PACKAGES* pPackages, 234 __in BURN_PACKAGES* pPackages,
228 __in BURN_VARIABLES* pVariables, 235 __in BURN_VARIABLES* pVariables,
229 __in BYTE* pbData, 236 __in BYTE* pbData,
@@ -231,6 +238,7 @@ static HRESULT OnExecuteMsiPackage(
231 ); 238 );
232static HRESULT OnExecuteMspPackage( 239static HRESULT OnExecuteMspPackage(
233 __in HANDLE hPipe, 240 __in HANDLE hPipe,
241 __in BURN_CACHE* pCache,
234 __in BURN_PACKAGES* pPackages, 242 __in BURN_PACKAGES* pPackages,
235 __in BURN_VARIABLES* pVariables, 243 __in BURN_VARIABLES* pVariables,
236 __in BYTE* pbData, 244 __in BYTE* pbData,
@@ -238,6 +246,7 @@ static HRESULT OnExecuteMspPackage(
238 ); 246 );
239static HRESULT OnExecuteMsuPackage( 247static HRESULT OnExecuteMsuPackage(
240 __in HANDLE hPipe, 248 __in HANDLE hPipe,
249 __in BURN_CACHE* pCache,
241 __in BURN_PACKAGES* pPackages, 250 __in BURN_PACKAGES* pPackages,
242 __in BURN_VARIABLES* pVariables, 251 __in BURN_VARIABLES* pVariables,
243 __in BYTE* pbData, 252 __in BYTE* pbData,
@@ -279,6 +288,7 @@ static int MsiExecuteMessageHandler(
279 __in_opt LPVOID pvContext 288 __in_opt LPVOID pvContext
280 ); 289 );
281static HRESULT OnCleanPackage( 290static HRESULT OnCleanPackage(
291 __in BURN_CACHE* pCache,
282 __in BURN_PACKAGES* pPackages, 292 __in BURN_PACKAGES* pPackages,
283 __in BYTE* pbData, 293 __in BYTE* pbData,
284 __in SIZE_T cbData 294 __in SIZE_T cbData
@@ -286,6 +296,7 @@ static HRESULT OnCleanPackage(
286static HRESULT OnLaunchApprovedExe( 296static HRESULT OnLaunchApprovedExe(
287 __in HANDLE hPipe, 297 __in HANDLE hPipe,
288 __in BURN_APPROVED_EXES* pApprovedExes, 298 __in BURN_APPROVED_EXES* pApprovedExes,
299 __in BURN_CACHE* pCache,
289 __in BURN_VARIABLES* pVariables, 300 __in BURN_VARIABLES* pVariables,
290 __in BYTE* pbData, 301 __in BYTE* pbData,
291 __in SIZE_T cbData 302 __in SIZE_T cbData
@@ -1284,6 +1295,7 @@ extern "C" HRESULT ElevationChildPumpMessages(
1284 __in HANDLE hPipe, 1295 __in HANDLE hPipe,
1285 __in HANDLE hCachePipe, 1296 __in HANDLE hCachePipe,
1286 __in BURN_APPROVED_EXES* pApprovedExes, 1297 __in BURN_APPROVED_EXES* pApprovedExes,
1298 __in BURN_CACHE* pCache,
1287 __in BURN_CONTAINERS* pContainers, 1299 __in BURN_CONTAINERS* pContainers,
1288 __in BURN_PACKAGES* pPackages, 1300 __in BURN_PACKAGES* pPackages,
1289 __in BURN_PAYLOADS* pPayloads, 1301 __in BURN_PAYLOADS* pPayloads,
@@ -1304,6 +1316,7 @@ extern "C" HRESULT ElevationChildPumpMessages(
1304 1316
1305 cacheContext.dwLoggingTlsId = dwLoggingTlsId; 1317 cacheContext.dwLoggingTlsId = dwLoggingTlsId;
1306 cacheContext.hPipe = hCachePipe; 1318 cacheContext.hPipe = hCachePipe;
1319 cacheContext.pCache = pCache;
1307 cacheContext.pContainers = pContainers; 1320 cacheContext.pContainers = pContainers;
1308 cacheContext.pPackages = pPackages; 1321 cacheContext.pPackages = pPackages;
1309 cacheContext.pPayloads = pPayloads; 1322 cacheContext.pPayloads = pPayloads;
@@ -1316,6 +1329,7 @@ extern "C" HRESULT ElevationChildPumpMessages(
1316 context.phLock = phLock; 1329 context.phLock = phLock;
1317 context.pfDisabledAutomaticUpdates = pfDisabledAutomaticUpdates; 1330 context.pfDisabledAutomaticUpdates = pfDisabledAutomaticUpdates;
1318 context.pApprovedExes = pApprovedExes; 1331 context.pApprovedExes = pApprovedExes;
1332 context.pCache = pCache;
1319 context.pContainers = pContainers; 1333 context.pContainers = pContainers;
1320 context.pPackages = pPackages; 1334 context.pPackages = pPackages;
1321 context.pPayloads = pPayloads; 1335 context.pPayloads = pPayloads;
@@ -1826,7 +1840,7 @@ static HRESULT ProcessElevatedChildMessage(
1826 break; 1840 break;
1827 1841
1828 case BURN_ELEVATION_MESSAGE_TYPE_SESSION_BEGIN: 1842 case BURN_ELEVATION_MESSAGE_TYPE_SESSION_BEGIN:
1829 hrResult = OnSessionBegin(pContext->pRegistration, pContext->pVariables, (BYTE*)pMsg->pvData, pMsg->cbData); 1843 hrResult = OnSessionBegin(pContext->pCache, pContext->pRegistration, pContext->pVariables, (BYTE*)pMsg->pvData, pMsg->cbData);
1830 break; 1844 break;
1831 1845
1832 case BURN_ELEVATION_MESSAGE_TYPE_SESSION_RESUME: 1846 case BURN_ELEVATION_MESSAGE_TYPE_SESSION_RESUME:
@@ -1834,7 +1848,7 @@ static HRESULT ProcessElevatedChildMessage(
1834 break; 1848 break;
1835 1849
1836 case BURN_ELEVATION_MESSAGE_TYPE_SESSION_END: 1850 case BURN_ELEVATION_MESSAGE_TYPE_SESSION_END:
1837 hrResult = OnSessionEnd(pContext->pPackages, pContext->pRegistration, pContext->pVariables, (BYTE*)pMsg->pvData, pMsg->cbData); 1851 hrResult = OnSessionEnd(pContext->pCache, pContext->pPackages, pContext->pRegistration, pContext->pVariables, (BYTE*)pMsg->pvData, pMsg->cbData);
1838 break; 1852 break;
1839 1853
1840 case BURN_ELEVATION_MESSAGE_TYPE_SAVE_STATE: 1854 case BURN_ELEVATION_MESSAGE_TYPE_SAVE_STATE:
@@ -1846,19 +1860,19 @@ static HRESULT ProcessElevatedChildMessage(
1846 break; 1860 break;
1847 1861
1848 case BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_EXE_PACKAGE: 1862 case BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_EXE_PACKAGE:
1849 hrResult = OnExecuteExePackage(pContext->hPipe, pContext->pPackages, &pContext->pRegistration->relatedBundles, pContext->pVariables, (BYTE*)pMsg->pvData, pMsg->cbData); 1863 hrResult = OnExecuteExePackage(pContext->hPipe, pContext->pCache, pContext->pPackages, &pContext->pRegistration->relatedBundles, pContext->pVariables, (BYTE*)pMsg->pvData, pMsg->cbData);
1850 break; 1864 break;
1851 1865
1852 case BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_MSI_PACKAGE: 1866 case BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_MSI_PACKAGE:
1853 hrResult = OnExecuteMsiPackage(pContext->hPipe, pContext->pPackages, pContext->pVariables, (BYTE*)pMsg->pvData, pMsg->cbData); 1867 hrResult = OnExecuteMsiPackage(pContext->hPipe, pContext->pCache, pContext->pPackages, pContext->pVariables, (BYTE*)pMsg->pvData, pMsg->cbData);
1854 break; 1868 break;
1855 1869
1856 case BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_MSP_PACKAGE: 1870 case BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_MSP_PACKAGE:
1857 hrResult = OnExecuteMspPackage(pContext->hPipe, pContext->pPackages, pContext->pVariables, (BYTE*)pMsg->pvData, pMsg->cbData); 1871 hrResult = OnExecuteMspPackage(pContext->hPipe, pContext->pCache, pContext->pPackages, pContext->pVariables, (BYTE*)pMsg->pvData, pMsg->cbData);
1858 break; 1872 break;
1859 1873
1860 case BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_MSU_PACKAGE: 1874 case BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_MSU_PACKAGE:
1861 hrResult = OnExecuteMsuPackage(pContext->hPipe, pContext->pPackages, pContext->pVariables, (BYTE*)pMsg->pvData, pMsg->cbData); 1875 hrResult = OnExecuteMsuPackage(pContext->hPipe, pContext->pCache, pContext->pPackages, pContext->pVariables, (BYTE*)pMsg->pvData, pMsg->cbData);
1862 break; 1876 break;
1863 1877
1864 case BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_PACKAGE_PROVIDER: 1878 case BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_PACKAGE_PROVIDER:
@@ -1870,11 +1884,11 @@ static HRESULT ProcessElevatedChildMessage(
1870 break; 1884 break;
1871 1885
1872 case BURN_ELEVATION_MESSAGE_TYPE_CLEAN_PACKAGE: 1886 case BURN_ELEVATION_MESSAGE_TYPE_CLEAN_PACKAGE:
1873 hrResult = OnCleanPackage(pContext->pPackages, (BYTE*)pMsg->pvData, pMsg->cbData); 1887 hrResult = OnCleanPackage(pContext->pCache, pContext->pPackages, (BYTE*)pMsg->pvData, pMsg->cbData);
1874 break; 1888 break;
1875 1889
1876 case BURN_ELEVATION_MESSAGE_TYPE_LAUNCH_APPROVED_EXE: 1890 case BURN_ELEVATION_MESSAGE_TYPE_LAUNCH_APPROVED_EXE:
1877 hrResult = OnLaunchApprovedExe(pContext->hPipe, pContext->pApprovedExes, pContext->pVariables, (BYTE*)pMsg->pvData, pMsg->cbData); 1891 hrResult = OnLaunchApprovedExe(pContext->hPipe, pContext->pApprovedExes, pContext->pCache, pContext->pVariables, (BYTE*)pMsg->pvData, pMsg->cbData);
1878 break; 1892 break;
1879 1893
1880 default: 1894 default:
@@ -1901,11 +1915,11 @@ static HRESULT ProcessElevatedChildCacheMessage(
1901 switch (pMsg->dwMessage) 1915 switch (pMsg->dwMessage)
1902 { 1916 {
1903 case BURN_ELEVATION_MESSAGE_TYPE_CACHE_PREPARE_PACKAGE: 1917 case BURN_ELEVATION_MESSAGE_TYPE_CACHE_PREPARE_PACKAGE:
1904 hrResult = OnCachePreparePackage(pContext->pPackages, (BYTE*)pMsg->pvData, pMsg->cbData); 1918 hrResult = OnCachePreparePackage(pContext->pCache, pContext->pPackages, (BYTE*)pMsg->pvData, pMsg->cbData);
1905 break; 1919 break;
1906 1920
1907 case BURN_ELEVATION_MESSAGE_TYPE_CACHE_COMPLETE_PAYLOAD: 1921 case BURN_ELEVATION_MESSAGE_TYPE_CACHE_COMPLETE_PAYLOAD:
1908 hrResult = OnCacheCompletePayload(pContext->hPipe, pContext->pPackages, pContext->pPayloads, (BYTE*)pMsg->pvData, pMsg->cbData); 1922 hrResult = OnCacheCompletePayload(pContext->hPipe, pContext->pCache, pContext->pPackages, pContext->pPayloads, (BYTE*)pMsg->pvData, pMsg->cbData);
1909 break; 1923 break;
1910 1924
1911 case BURN_ELEVATION_MESSAGE_TYPE_CACHE_VERIFY_PAYLOAD: 1925 case BURN_ELEVATION_MESSAGE_TYPE_CACHE_VERIFY_PAYLOAD:
@@ -1913,12 +1927,12 @@ static HRESULT ProcessElevatedChildCacheMessage(
1913 break; 1927 break;
1914 1928
1915 case BURN_ELEVATION_MESSAGE_TYPE_CACHE_CLEANUP: 1929 case BURN_ELEVATION_MESSAGE_TYPE_CACHE_CLEANUP:
1916 OnCacheCleanup(pContext->pRegistration->sczId); 1930 OnCacheCleanup(pContext->pCache);
1917 hrResult = S_OK; 1931 hrResult = S_OK;
1918 break; 1932 break;
1919 1933
1920 case BURN_ELEVATION_MESSAGE_TYPE_CLEAN_PACKAGE: 1934 case BURN_ELEVATION_MESSAGE_TYPE_CLEAN_PACKAGE:
1921 hrResult = OnCleanPackage(pContext->pPackages, (BYTE*)pMsg->pvData, pMsg->cbData); 1935 hrResult = OnCleanPackage(pContext->pCache, pContext->pPackages, (BYTE*)pMsg->pvData, pMsg->cbData);
1922 break; 1936 break;
1923 1937
1924 default: 1938 default:
@@ -2080,6 +2094,7 @@ static HRESULT OnApplyUninitialize(
2080} 2094}
2081 2095
2082static HRESULT OnSessionBegin( 2096static HRESULT OnSessionBegin(
2097 __in BURN_CACHE* pCache,
2083 __in BURN_REGISTRATION* pRegistration, 2098 __in BURN_REGISTRATION* pRegistration,
2084 __in BURN_VARIABLES* pVariables, 2099 __in BURN_VARIABLES* pVariables,
2085 __in BYTE* pbData, 2100 __in BYTE* pbData,
@@ -2120,7 +2135,7 @@ static HRESULT OnSessionBegin(
2120 ExitOnFailure(hr, "Failed to read variables."); 2135 ExitOnFailure(hr, "Failed to read variables.");
2121 2136
2122 // Begin session in per-machine process. 2137 // Begin session in per-machine process.
2123 hr = RegistrationSessionBegin(sczEngineWorkingPath, pRegistration, pVariables, dwRegistrationOperations, (BURN_DEPENDENCY_REGISTRATION_ACTION)dwDependencyRegistrationAction, qwEstimatedSize, (BOOTSTRAPPER_REGISTRATION_TYPE)dwRegistrationType); 2138 hr = RegistrationSessionBegin(sczEngineWorkingPath, pRegistration, pCache, pVariables, dwRegistrationOperations, (BURN_DEPENDENCY_REGISTRATION_ACTION)dwDependencyRegistrationAction, qwEstimatedSize, (BOOTSTRAPPER_REGISTRATION_TYPE)dwRegistrationType);
2124 ExitOnFailure(hr, "Failed to begin registration session."); 2139 ExitOnFailure(hr, "Failed to begin registration session.");
2125 2140
2126LExit: 2141LExit:
@@ -2162,6 +2177,7 @@ LExit:
2162} 2177}
2163 2178
2164static HRESULT OnSessionEnd( 2179static HRESULT OnSessionEnd(
2180 __in BURN_CACHE* pCache,
2165 __in BURN_PACKAGES* pPackages, 2181 __in BURN_PACKAGES* pPackages,
2166 __in BURN_REGISTRATION* pRegistration, 2182 __in BURN_REGISTRATION* pRegistration,
2167 __in BURN_VARIABLES* pVariables, 2183 __in BURN_VARIABLES* pVariables,
@@ -2190,7 +2206,7 @@ static HRESULT OnSessionEnd(
2190 ExitOnFailure(hr, "Failed to read dependency registration action."); 2206 ExitOnFailure(hr, "Failed to read dependency registration action.");
2191 2207
2192 // suspend session in per-machine process 2208 // suspend session in per-machine process
2193 hr = RegistrationSessionEnd(pRegistration, pVariables, pPackages, (BURN_RESUME_MODE)dwResumeMode, (BOOTSTRAPPER_APPLY_RESTART)dwRestart, (BURN_DEPENDENCY_REGISTRATION_ACTION)dwDependencyRegistrationAction, (BOOTSTRAPPER_REGISTRATION_TYPE)dwRegistrationType); 2209 hr = RegistrationSessionEnd(pRegistration, pCache, pVariables, pPackages, (BURN_RESUME_MODE)dwResumeMode, (BOOTSTRAPPER_APPLY_RESTART)dwRestart, (BURN_DEPENDENCY_REGISTRATION_ACTION)dwDependencyRegistrationAction, (BOOTSTRAPPER_REGISTRATION_TYPE)dwRegistrationType);
2194 ExitOnFailure(hr, "Failed to suspend registration session."); 2210 ExitOnFailure(hr, "Failed to suspend registration session.");
2195 2211
2196LExit: 2212LExit:
@@ -2214,6 +2230,7 @@ LExit:
2214} 2230}
2215 2231
2216static HRESULT OnCachePreparePackage( 2232static HRESULT OnCachePreparePackage(
2233 __in BURN_CACHE* pCache,
2217 __in BURN_PACKAGES* pPackages, 2234 __in BURN_PACKAGES* pPackages,
2218 __in BYTE* pbData, 2235 __in BYTE* pbData,
2219 __in SIZE_T cbData 2236 __in SIZE_T cbData
@@ -2239,7 +2256,7 @@ static HRESULT OnCachePreparePackage(
2239 ExitOnRootFailure(hr, "Invalid data passed to cache prepare package."); 2256 ExitOnRootFailure(hr, "Invalid data passed to cache prepare package.");
2240 } 2257 }
2241 2258
2242 hr = CachePreparePackage(pPackage); 2259 hr = CachePreparePackage(pCache, pPackage);
2243 ExitOnFailure(hr, "Failed to prepare cache package."); 2260 ExitOnFailure(hr, "Failed to prepare cache package.");
2244 2261
2245LExit: 2262LExit:
@@ -2250,6 +2267,7 @@ LExit:
2250 2267
2251static HRESULT OnCacheCompletePayload( 2268static HRESULT OnCacheCompletePayload(
2252 __in HANDLE hPipe, 2269 __in HANDLE hPipe,
2270 __in BURN_CACHE* pCache,
2253 __in BURN_PACKAGES* pPackages, 2271 __in BURN_PACKAGES* pPackages,
2254 __in BURN_PAYLOADS* pPayloads, 2272 __in BURN_PAYLOADS* pPayloads,
2255 __in BYTE* pbData, 2273 __in BYTE* pbData,
@@ -2291,7 +2309,7 @@ static HRESULT OnCacheCompletePayload(
2291 2309
2292 if (pPackage && pPayload) // complete payload. 2310 if (pPackage && pPayload) // complete payload.
2293 { 2311 {
2294 hr = CacheCompletePayload(pPackage->fPerMachine, pPayload, pPackage->sczCacheId, sczUnverifiedPath, fMove, BurnCacheMessageHandler, ElevatedProgressRoutine, hPipe); 2312 hr = CacheCompletePayload(pCache, pPackage->fPerMachine, pPayload, pPackage->sczCacheId, sczUnverifiedPath, fMove, BurnCacheMessageHandler, ElevatedProgressRoutine, hPipe);
2295 ExitOnFailure(hr, "Failed to cache payload: %ls", pPayload->sczKey); 2313 ExitOnFailure(hr, "Failed to cache payload: %ls", pPayload->sczKey);
2296 } 2314 }
2297 else 2315 else
@@ -2364,10 +2382,10 @@ LExit:
2364} 2382}
2365 2383
2366static void OnCacheCleanup( 2384static void OnCacheCleanup(
2367 __in_z LPCWSTR wzBundleId 2385 __in BURN_CACHE* pCache
2368 ) 2386 )
2369{ 2387{
2370 CacheCleanup(TRUE, wzBundleId); 2388 CacheCleanup(TRUE, pCache);
2371} 2389}
2372 2390
2373static HRESULT OnProcessDependentRegistration( 2391static HRESULT OnProcessDependentRegistration(
@@ -2405,6 +2423,7 @@ LExit:
2405 2423
2406static HRESULT OnExecuteExePackage( 2424static HRESULT OnExecuteExePackage(
2407 __in HANDLE hPipe, 2425 __in HANDLE hPipe,
2426 __in BURN_CACHE* pCache,
2408 __in BURN_PACKAGES* pPackages, 2427 __in BURN_PACKAGES* pPackages,
2409 __in BURN_RELATED_BUNDLES* pRelatedBundles, 2428 __in BURN_RELATED_BUNDLES* pRelatedBundles,
2410 __in BURN_VARIABLES* pVariables, 2429 __in BURN_VARIABLES* pVariables,
@@ -2464,7 +2483,7 @@ static HRESULT OnExecuteExePackage(
2464 } 2483 }
2465 2484
2466 // Execute EXE package. 2485 // Execute EXE package.
2467 hr = ExeEngineExecutePackage(&executeAction, pVariables, static_cast<BOOL>(dwRollback), GenericExecuteMessageHandler, hPipe, &exeRestart); 2486 hr = ExeEngineExecutePackage(&executeAction, pCache, pVariables, static_cast<BOOL>(dwRollback), GenericExecuteMessageHandler, hPipe, &exeRestart);
2468 ExitOnFailure(hr, "Failed to execute EXE package."); 2487 ExitOnFailure(hr, "Failed to execute EXE package.");
2469 2488
2470LExit: 2489LExit:
@@ -2490,6 +2509,7 @@ LExit:
2490 2509
2491static HRESULT OnExecuteMsiPackage( 2510static HRESULT OnExecuteMsiPackage(
2492 __in HANDLE hPipe, 2511 __in HANDLE hPipe,
2512 __in BURN_CACHE* pCache,
2493 __in BURN_PACKAGES* pPackages, 2513 __in BURN_PACKAGES* pPackages,
2494 __in BURN_VARIABLES* pVariables, 2514 __in BURN_VARIABLES* pVariables,
2495 __in BYTE* pbData, 2515 __in BYTE* pbData,
@@ -2563,7 +2583,7 @@ static HRESULT OnExecuteMsiPackage(
2563 ExitOnFailure(hr, "Failed to read variables."); 2583 ExitOnFailure(hr, "Failed to read variables.");
2564 2584
2565 // Execute MSI package. 2585 // Execute MSI package.
2566 hr = MsiEngineExecutePackage(hwndParent, &executeAction, pVariables, fRollback, MsiExecuteMessageHandler, hPipe, &msiRestart); 2586 hr = MsiEngineExecutePackage(hwndParent, &executeAction, pCache, pVariables, fRollback, MsiExecuteMessageHandler, hPipe, &msiRestart);
2567 ExitOnFailure(hr, "Failed to execute MSI package."); 2587 ExitOnFailure(hr, "Failed to execute MSI package.");
2568 2588
2569LExit: 2589LExit:
@@ -2587,6 +2607,7 @@ LExit:
2587 2607
2588static HRESULT OnExecuteMspPackage( 2608static HRESULT OnExecuteMspPackage(
2589 __in HANDLE hPipe, 2609 __in HANDLE hPipe,
2610 __in BURN_CACHE* pCache,
2590 __in BURN_PACKAGES* pPackages, 2611 __in BURN_PACKAGES* pPackages,
2591 __in BURN_VARIABLES* pVariables, 2612 __in BURN_VARIABLES* pVariables,
2592 __in BYTE* pbData, 2613 __in BYTE* pbData,
@@ -2658,7 +2679,7 @@ static HRESULT OnExecuteMspPackage(
2658 ExitOnFailure(hr, "Failed to read rollback flag."); 2679 ExitOnFailure(hr, "Failed to read rollback flag.");
2659 2680
2660 // Execute MSP package. 2681 // Execute MSP package.
2661 hr = MspEngineExecutePackage(hwndParent, &executeAction, pVariables, fRollback, MsiExecuteMessageHandler, hPipe, &restart); 2682 hr = MspEngineExecutePackage(hwndParent, &executeAction, pCache, pVariables, fRollback, MsiExecuteMessageHandler, hPipe, &restart);
2662 ExitOnFailure(hr, "Failed to execute MSP package."); 2683 ExitOnFailure(hr, "Failed to execute MSP package.");
2663 2684
2664LExit: 2685LExit:
@@ -2682,6 +2703,7 @@ LExit:
2682 2703
2683static HRESULT OnExecuteMsuPackage( 2704static HRESULT OnExecuteMsuPackage(
2684 __in HANDLE hPipe, 2705 __in HANDLE hPipe,
2706 __in BURN_CACHE* pCache,
2685 __in BURN_PACKAGES* pPackages, 2707 __in BURN_PACKAGES* pPackages,
2686 __in BURN_VARIABLES* pVariables, 2708 __in BURN_VARIABLES* pVariables,
2687 __in BYTE* pbData, 2709 __in BYTE* pbData,
@@ -2718,7 +2740,7 @@ static HRESULT OnExecuteMsuPackage(
2718 ExitOnFailure(hr, "Failed to find package: %ls", sczPackage); 2740 ExitOnFailure(hr, "Failed to find package: %ls", sczPackage);
2719 2741
2720 // execute MSU package 2742 // execute MSU package
2721 hr = MsuEngineExecutePackage(&executeAction, pVariables, static_cast<BOOL>(dwRollback), static_cast<BOOL>(dwStopWusaService), GenericExecuteMessageHandler, hPipe, &restart); 2743 hr = MsuEngineExecutePackage(&executeAction, pCache, pVariables, static_cast<BOOL>(dwRollback), static_cast<BOOL>(dwStopWusaService), GenericExecuteMessageHandler, hPipe, &restart);
2722 ExitOnFailure(hr, "Failed to execute MSU package."); 2744 ExitOnFailure(hr, "Failed to execute MSU package.");
2723 2745
2724LExit: 2746LExit:
@@ -3051,6 +3073,7 @@ LExit:
3051} 3073}
3052 3074
3053static HRESULT OnCleanPackage( 3075static HRESULT OnCleanPackage(
3076 __in BURN_CACHE* pCache,
3054 __in BURN_PACKAGES* pPackages, 3077 __in BURN_PACKAGES* pPackages,
3055 __in BYTE* pbData, 3078 __in BYTE* pbData,
3056 __in SIZE_T cbData 3079 __in SIZE_T cbData
@@ -3069,7 +3092,7 @@ static HRESULT OnCleanPackage(
3069 ExitOnFailure(hr, "Failed to find package: %ls", sczPackage); 3092 ExitOnFailure(hr, "Failed to find package: %ls", sczPackage);
3070 3093
3071 // Remove the package from the cache. 3094 // Remove the package from the cache.
3072 hr = CacheRemovePackage(TRUE, pPackage->sczId, pPackage->sczCacheId); 3095 hr = CacheRemovePackage(pCache, TRUE, pPackage->sczId, pPackage->sczCacheId);
3073 ExitOnFailure(hr, "Failed to remove from cache package: %ls", pPackage->sczId); 3096 ExitOnFailure(hr, "Failed to remove from cache package: %ls", pPackage->sczId);
3074 3097
3075LExit: 3098LExit:
@@ -3080,6 +3103,7 @@ LExit:
3080static HRESULT OnLaunchApprovedExe( 3103static HRESULT OnLaunchApprovedExe(
3081 __in HANDLE hPipe, 3104 __in HANDLE hPipe,
3082 __in BURN_APPROVED_EXES* pApprovedExes, 3105 __in BURN_APPROVED_EXES* pApprovedExes,
3106 __in BURN_CACHE* pCache,
3083 __in BURN_VARIABLES* pVariables, 3107 __in BURN_VARIABLES* pVariables,
3084 __in BYTE* pbData, 3108 __in BYTE* pbData,
3085 __in SIZE_T cbData 3109 __in SIZE_T cbData
@@ -3124,7 +3148,7 @@ static HRESULT OnLaunchApprovedExe(
3124 hr = RegReadString(hKey, pApprovedExe->sczValueName, &pLaunchApprovedExe->sczExecutablePath); 3148 hr = RegReadString(hKey, pApprovedExe->sczValueName, &pLaunchApprovedExe->sczExecutablePath);
3125 ExitOnFailure(hr, "Failed to read the value for the approved exe path."); 3149 ExitOnFailure(hr, "Failed to read the value for the approved exe path.");
3126 3150
3127 hr = ApprovedExesVerifySecureLocation(pVariables, pLaunchApprovedExe); 3151 hr = ApprovedExesVerifySecureLocation(pCache, pVariables, pLaunchApprovedExe);
3128 ExitOnFailure(hr, "Failed to verify the executable path is in a secure location: %ls", pLaunchApprovedExe->sczExecutablePath); 3152 ExitOnFailure(hr, "Failed to verify the executable path is in a secure location: %ls", pLaunchApprovedExe->sczExecutablePath);
3129 if (S_FALSE == hr) 3153 if (S_FALSE == hr)
3130 { 3154 {
diff --git a/src/burn/engine/elevation.h b/src/burn/engine/elevation.h
index 00dca8dc..fb2e9cb4 100644
--- a/src/burn/engine/elevation.h
+++ b/src/burn/engine/elevation.h
@@ -151,6 +151,7 @@ HRESULT ElevationChildPumpMessages(
151 __in HANDLE hPipe, 151 __in HANDLE hPipe,
152 __in HANDLE hCachePipe, 152 __in HANDLE hCachePipe,
153 __in BURN_APPROVED_EXES* pApprovedExes, 153 __in BURN_APPROVED_EXES* pApprovedExes,
154 __in BURN_CACHE* pCache,
154 __in BURN_CONTAINERS* pContainers, 155 __in BURN_CONTAINERS* pContainers,
155 __in BURN_PACKAGES* pPackages, 156 __in BURN_PACKAGES* pPackages,
156 __in BURN_PAYLOADS* pPayloads, 157 __in BURN_PAYLOADS* pPayloads,
diff --git a/src/burn/engine/engine.cpp b/src/burn/engine/engine.cpp
index e6cb1708..0c2c8dc5 100644
--- a/src/burn/engine/engine.cpp
+++ b/src/burn/engine/engine.cpp
@@ -244,8 +244,8 @@ LExit:
244 244
245 UserExperienceRemove(&engineState.userExperience); 245 UserExperienceRemove(&engineState.userExperience);
246 246
247 CacheRemoveWorkingFolder(engineState.registration.sczId); 247 CacheRemoveWorkingFolder(&engineState.cache);
248 CacheUninitialize(); 248 CacheUninitialize(&engineState.cache);
249 249
250 // If this is a related bundle (but not an update) suppress restart and return the standard restart error code. 250 // If this is a related bundle (but not an update) suppress restart and return the standard restart error code.
251 if (fRestart && BOOTSTRAPPER_RELATION_NONE != engineState.command.relationType && BOOTSTRAPPER_RELATION_UPDATE != engineState.command.relationType) 251 if (fRestart && BOOTSTRAPPER_RELATION_NONE != engineState.command.relationType && BOOTSTRAPPER_RELATION_UPDATE != engineState.command.relationType)
@@ -334,6 +334,9 @@ static HRESULT InitializeEngineState(
334 PipeConnectionInitialize(&pEngineState->companionConnection); 334 PipeConnectionInitialize(&pEngineState->companionConnection);
335 PipeConnectionInitialize(&pEngineState->embeddedConnection); 335 PipeConnectionInitialize(&pEngineState->embeddedConnection);
336 336
337 // Retain whether bundle was initially run elevated.
338 ProcElevated(::GetCurrentProcess(), &pEngineState->internalCommand.fInitiallyElevated);
339
337 // Parse command line. 340 // Parse command line.
338 hr = CoreParseCommandLine(pEngineState->argc, pEngineState->argv, &pEngineState->command, &pEngineState->companionConnection, &pEngineState->embeddedConnection, &pEngineState->mode, &pEngineState->automaticUpdates, &pEngineState->fDisableSystemRestore, &pEngineState->internalCommand.sczSourceProcessPath, &pEngineState->internalCommand.sczOriginalSource, &hSectionFile, &hSourceEngineFile, &pEngineState->fDisableUnelevate, &pEngineState->log.dwAttributes, &pEngineState->log.sczPath, &pEngineState->registration.sczActiveParent, &pEngineState->sczIgnoreDependencies, &pEngineState->registration.sczAncestors, &pEngineState->fInvalidCommandLine, &pEngineState->cUnknownArgs, &pEngineState->rgUnknownArgs); 341 hr = CoreParseCommandLine(pEngineState->argc, pEngineState->argv, &pEngineState->command, &pEngineState->companionConnection, &pEngineState->embeddedConnection, &pEngineState->mode, &pEngineState->automaticUpdates, &pEngineState->fDisableSystemRestore, &pEngineState->internalCommand.sczSourceProcessPath, &pEngineState->internalCommand.sczOriginalSource, &hSectionFile, &hSourceEngineFile, &pEngineState->fDisableUnelevate, &pEngineState->log.dwAttributes, &pEngineState->log.sczPath, &pEngineState->registration.sczActiveParent, &pEngineState->sczIgnoreDependencies, &pEngineState->registration.sczAncestors, &pEngineState->fInvalidCommandLine, &pEngineState->cUnknownArgs, &pEngineState->rgUnknownArgs);
339 ExitOnFailure(hr, "Fatal error while parsing command line."); 342 ExitOnFailure(hr, "Fatal error while parsing command line.");
@@ -341,6 +344,9 @@ static HRESULT InitializeEngineState(
341 hr = SectionInitialize(&pEngineState->section, hSectionFile, hSourceEngineFile); 344 hr = SectionInitialize(&pEngineState->section, hSectionFile, hSourceEngineFile);
342 ExitOnFailure(hr, "Failed to initialize engine section."); 345 ExitOnFailure(hr, "Failed to initialize engine section.");
343 346
347 hr = CacheInitialize(&pEngineState->cache, &pEngineState->internalCommand);
348 ExitOnFailure(hr, "Failed to initialize internal cache functionality.");
349
344LExit: 350LExit:
345 return hr; 351 return hr;
346} 352}
@@ -421,8 +427,6 @@ static HRESULT RunUntrusted(
421 hr = PathForCurrentProcess(&sczCurrentProcessPath, NULL); 427 hr = PathForCurrentProcess(&sczCurrentProcessPath, NULL);
422 ExitOnFailure(hr, "Failed to get path for current process."); 428 ExitOnFailure(hr, "Failed to get path for current process.");
423 429
424 BOOL fRunningFromCache = CacheBundleRunningFromCache();
425
426 // If we're running from the package cache, we're in a secure 430 // If we're running from the package cache, we're in a secure
427 // folder (DLLs cannot be inserted here for hijacking purposes) 431 // folder (DLLs cannot be inserted here for hijacking purposes)
428 // so just launch the current process's path as the clean room 432 // so just launch the current process's path as the clean room
@@ -431,13 +435,13 @@ static HRESULT RunUntrusted(
431 // a secure folder) but it makes the code that only wants to run 435 // a secure folder) but it makes the code that only wants to run
432 // in clean room more complicated if we don't launch an explicit 436 // in clean room more complicated if we don't launch an explicit
433 // clean room process. 437 // clean room process.
434 if (fRunningFromCache) 438 if (CacheBundleRunningFromCache(&pEngineState->cache))
435 { 439 {
436 wzCleanRoomBundlePath = sczCurrentProcessPath; 440 wzCleanRoomBundlePath = sczCurrentProcessPath;
437 } 441 }
438 else 442 else
439 { 443 {
440 hr = CacheBundleToCleanRoom(&pEngineState->section, &sczCachedCleanRoomBundlePath); 444 hr = CacheBundleToCleanRoom(&pEngineState->cache, &pEngineState->section, &sczCachedCleanRoomBundlePath);
441 ExitOnFailure(hr, "Failed to cache to clean room."); 445 ExitOnFailure(hr, "Failed to cache to clean room.");
442 446
443 wzCleanRoomBundlePath = sczCachedCleanRoomBundlePath; 447 wzCleanRoomBundlePath = sczCachedCleanRoomBundlePath;
@@ -658,7 +662,7 @@ static HRESULT RunElevated(
658 SrpInitialize(TRUE); 662 SrpInitialize(TRUE);
659 663
660 // Pump messages from parent process. 664 // Pump messages from parent process.
661 hr = ElevationChildPumpMessages(pEngineState->dwElevatedLoggingTlsId, pEngineState->companionConnection.hPipe, pEngineState->companionConnection.hCachePipe, &pEngineState->approvedExes, &pEngineState->containers, &pEngineState->packages, &pEngineState->payloads, &pEngineState->variables, &pEngineState->registration, &pEngineState->userExperience, &hLock, &fDisabledAutomaticUpdates, &pEngineState->userExperience.dwExitCode, &pEngineState->fRestart); 665 hr = ElevationChildPumpMessages(pEngineState->dwElevatedLoggingTlsId, pEngineState->companionConnection.hPipe, pEngineState->companionConnection.hCachePipe, &pEngineState->approvedExes, &pEngineState->cache, &pEngineState->containers, &pEngineState->packages, &pEngineState->payloads, &pEngineState->variables, &pEngineState->registration, &pEngineState->userExperience, &hLock, &fDisabledAutomaticUpdates, &pEngineState->userExperience.dwExitCode, &pEngineState->fRestart);
662 LogRedirect(NULL, NULL); // reset logging so the next failure gets written to "log buffer" for the failure log. 666 LogRedirect(NULL, NULL); // reset logging so the next failure gets written to "log buffer" for the failure log.
663 ExitOnFailure(hr, "Failed to pump messages from parent process."); 667 ExitOnFailure(hr, "Failed to pump messages from parent process.");
664 668
diff --git a/src/burn/engine/exeengine.cpp b/src/burn/engine/exeengine.cpp
index d8ffbdb0..9eea4960 100644
--- a/src/burn/engine/exeengine.cpp
+++ b/src/burn/engine/exeengine.cpp
@@ -342,6 +342,7 @@ LExit:
342 342
343extern "C" HRESULT ExeEngineExecutePackage( 343extern "C" HRESULT ExeEngineExecutePackage(
344 __in BURN_EXECUTE_ACTION* pExecuteAction, 344 __in BURN_EXECUTE_ACTION* pExecuteAction,
345 __in BURN_CACHE* pCache,
345 __in BURN_VARIABLES* pVariables, 346 __in BURN_VARIABLES* pVariables,
346 __in BOOL fRollback, 347 __in BOOL fRollback,
347 __in PFN_GENERICMESSAGEHANDLER pfnGenericMessageHandler, 348 __in PFN_GENERICMESSAGEHANDLER pfnGenericMessageHandler,
@@ -368,7 +369,7 @@ extern "C" HRESULT ExeEngineExecutePackage(
368 BURN_PAYLOAD* pPackagePayload = pPackage->payloads.rgItems[0].pPayload; 369 BURN_PAYLOAD* pPackagePayload = pPackage->payloads.rgItems[0].pPayload;
369 370
370 // get cached executable path 371 // get cached executable path
371 hr = CacheGetCompletedPath(pPackage->fPerMachine, pPackage->sczCacheId, &sczCachedDirectory); 372 hr = CacheGetCompletedPath(pCache, pPackage->fPerMachine, pPackage->sczCacheId, &sczCachedDirectory);
372 ExitOnFailure(hr, "Failed to get cached path for package: %ls", pPackage->sczId); 373 ExitOnFailure(hr, "Failed to get cached path for package: %ls", pPackage->sczId);
373 374
374 // Best effort to set the execute package cache folder and action variables. 375 // Best effort to set the execute package cache folder and action variables.
diff --git a/src/burn/engine/exeengine.h b/src/burn/engine/exeengine.h
index 4fec2dd9..877968cd 100644
--- a/src/burn/engine/exeengine.h
+++ b/src/burn/engine/exeengine.h
@@ -32,6 +32,7 @@ HRESULT ExeEnginePlanAddPackage(
32 ); 32 );
33HRESULT ExeEngineExecutePackage( 33HRESULT ExeEngineExecutePackage(
34 __in BURN_EXECUTE_ACTION* pExecuteAction, 34 __in BURN_EXECUTE_ACTION* pExecuteAction,
35 __in BURN_CACHE* pCache,
35 __in BURN_VARIABLES* pVariables, 36 __in BURN_VARIABLES* pVariables,
36 __in BOOL fRollback, 37 __in BOOL fRollback,
37 __in PFN_GENERICMESSAGEHANDLER pfnGenericExecuteProgress, 38 __in PFN_GENERICMESSAGEHANDLER pfnGenericExecuteProgress,
diff --git a/src/burn/engine/manifest.cpp b/src/burn/engine/manifest.cpp
index b1740083..1ef8e610 100644
--- a/src/burn/engine/manifest.cpp
+++ b/src/burn/engine/manifest.cpp
@@ -133,7 +133,7 @@ static HRESULT ParseFromXml(
133 ExitOnFailure(hr, "Failed to parse searches."); 133 ExitOnFailure(hr, "Failed to parse searches.");
134 134
135 // parse registration 135 // parse registration
136 hr = RegistrationParseFromXml(&pEngineState->registration, pixeBundle); 136 hr = RegistrationParseFromXml(&pEngineState->registration, &pEngineState->cache, pixeBundle);
137 ExitOnFailure(hr, "Failed to parse registration."); 137 ExitOnFailure(hr, "Failed to parse registration.");
138 138
139 // parse update 139 // parse update
diff --git a/src/burn/engine/msiengine.cpp b/src/burn/engine/msiengine.cpp
index 4ff129fd..c80fd79f 100644
--- a/src/burn/engine/msiengine.cpp
+++ b/src/burn/engine/msiengine.cpp
@@ -41,6 +41,7 @@ static HRESULT ConcatFeatureActionProperties(
41 __inout_z LPWSTR* psczArguments 41 __inout_z LPWSTR* psczArguments
42 ); 42 );
43static HRESULT ConcatPatchProperty( 43static HRESULT ConcatPatchProperty(
44 __in BURN_CACHE* pCache,
44 __in BURN_PACKAGE* pPackage, 45 __in BURN_PACKAGE* pPackage,
45 __in BOOL fRollback, 46 __in BOOL fRollback,
46 __inout_z LPWSTR* psczArguments 47 __inout_z LPWSTR* psczArguments
@@ -1059,6 +1060,7 @@ LExit:
1059extern "C" HRESULT MsiEngineExecutePackage( 1060extern "C" HRESULT MsiEngineExecutePackage(
1060 __in_opt HWND hwndParent, 1061 __in_opt HWND hwndParent,
1061 __in BURN_EXECUTE_ACTION* pExecuteAction, 1062 __in BURN_EXECUTE_ACTION* pExecuteAction,
1063 __in BURN_CACHE* pCache,
1062 __in BURN_VARIABLES* pVariables, 1064 __in BURN_VARIABLES* pVariables,
1063 __in BOOL fRollback, 1065 __in BOOL fRollback,
1064 __in PFN_MSIEXECUTEMESSAGEHANDLER pfnMessageHandler, 1066 __in PFN_MSIEXECUTEMESSAGEHANDLER pfnMessageHandler,
@@ -1119,7 +1121,7 @@ extern "C" HRESULT MsiEngineExecutePackage(
1119 if (BOOTSTRAPPER_ACTION_STATE_UNINSTALL != pExecuteAction->msiPackage.action) 1121 if (BOOTSTRAPPER_ACTION_STATE_UNINSTALL != pExecuteAction->msiPackage.action)
1120 { 1122 {
1121 // get cached MSI path 1123 // get cached MSI path
1122 hr = CacheGetCompletedPath(pPackage->fPerMachine, pPackage->sczCacheId, &sczCachedDirectory); 1124 hr = CacheGetCompletedPath(pCache, pPackage->fPerMachine, pPackage->sczCacheId, &sczCachedDirectory);
1123 ExitOnFailure(hr, "Failed to get cached path for package: %ls", pPackage->sczId); 1125 ExitOnFailure(hr, "Failed to get cached path for package: %ls", pPackage->sczId);
1124 1126
1125 // Best effort to set the execute package cache folder variable. 1127 // Best effort to set the execute package cache folder variable.
@@ -1165,10 +1167,10 @@ extern "C" HRESULT MsiEngineExecutePackage(
1165 ExitOnFailure(hr, "Failed to add feature action properties to obfuscated argument string."); 1167 ExitOnFailure(hr, "Failed to add feature action properties to obfuscated argument string.");
1166 1168
1167 // add slipstream patch properties 1169 // add slipstream patch properties
1168 hr = ConcatPatchProperty(pPackage, fRollback, &sczProperties); 1170 hr = ConcatPatchProperty(pCache, pPackage, fRollback, &sczProperties);
1169 ExitOnFailure(hr, "Failed to add patch properties to argument string."); 1171 ExitOnFailure(hr, "Failed to add patch properties to argument string.");
1170 1172
1171 hr = ConcatPatchProperty(pPackage, fRollback, &sczObfuscatedProperties); 1173 hr = ConcatPatchProperty(pCache, pPackage, fRollback, &sczObfuscatedProperties);
1172 ExitOnFailure(hr, "Failed to add patch properties to obfuscated argument string."); 1174 ExitOnFailure(hr, "Failed to add patch properties to obfuscated argument string.");
1173 1175
1174 hr = MsiEngineConcatActionProperty(pExecuteAction->msiPackage.actionMsiProperty, &sczProperties); 1176 hr = MsiEngineConcatActionProperty(pExecuteAction->msiPackage.actionMsiProperty, &sczProperties);
@@ -1940,6 +1942,7 @@ LExit:
1940} 1942}
1941 1943
1942static HRESULT ConcatPatchProperty( 1944static HRESULT ConcatPatchProperty(
1945 __in BURN_CACHE* pCache,
1943 __in BURN_PACKAGE* pPackage, 1946 __in BURN_PACKAGE* pPackage,
1944 __in BOOL fRollback, 1947 __in BOOL fRollback,
1945 __inout_z LPWSTR* psczArguments 1948 __inout_z LPWSTR* psczArguments
@@ -1962,7 +1965,7 @@ static HRESULT ConcatPatchProperty(
1962 1965
1963 if (BOOTSTRAPPER_ACTION_STATE_UNINSTALL < patchExecuteAction) 1966 if (BOOTSTRAPPER_ACTION_STATE_UNINSTALL < patchExecuteAction)
1964 { 1967 {
1965 hr = CacheGetCompletedPath(pMspPackage->fPerMachine, pMspPackage->sczCacheId, &sczCachedDirectory); 1968 hr = CacheGetCompletedPath(pCache, pMspPackage->fPerMachine, pMspPackage->sczCacheId, &sczCachedDirectory);
1966 ExitOnFailure(hr, "Failed to get cached path for MSP package: %ls", pMspPackage->sczId); 1969 ExitOnFailure(hr, "Failed to get cached path for MSP package: %ls", pMspPackage->sczId);
1967 1970
1968 hr = PathConcat(sczCachedDirectory, pMspPackagePayload->sczFilePath, &sczMspPath); 1971 hr = PathConcat(sczCachedDirectory, pMspPackagePayload->sczFilePath, &sczMspPath);
diff --git a/src/burn/engine/msiengine.h b/src/burn/engine/msiengine.h
index e4155a62..87f47f7c 100644
--- a/src/burn/engine/msiengine.h
+++ b/src/burn/engine/msiengine.h
@@ -63,6 +63,7 @@ HRESULT MsiEngineRollbackTransaction(
63HRESULT MsiEngineExecutePackage( 63HRESULT MsiEngineExecutePackage(
64 __in_opt HWND hwndParent, 64 __in_opt HWND hwndParent,
65 __in BURN_EXECUTE_ACTION* pExecuteAction, 65 __in BURN_EXECUTE_ACTION* pExecuteAction,
66 __in BURN_CACHE* pCache,
66 __in BURN_VARIABLES* pVariables, 67 __in BURN_VARIABLES* pVariables,
67 __in BOOL fRollback, 68 __in BOOL fRollback,
68 __in PFN_MSIEXECUTEMESSAGEHANDLER pfnMessageHandler, 69 __in PFN_MSIEXECUTEMESSAGEHANDLER pfnMessageHandler,
diff --git a/src/burn/engine/mspengine.cpp b/src/burn/engine/mspengine.cpp
index d547b130..3d7b5517 100644
--- a/src/burn/engine/mspengine.cpp
+++ b/src/burn/engine/mspengine.cpp
@@ -544,6 +544,7 @@ LExit:
544extern "C" HRESULT MspEngineExecutePackage( 544extern "C" HRESULT MspEngineExecutePackage(
545 __in_opt HWND hwndParent, 545 __in_opt HWND hwndParent,
546 __in BURN_EXECUTE_ACTION* pExecuteAction, 546 __in BURN_EXECUTE_ACTION* pExecuteAction,
547 __in BURN_CACHE* pCache,
547 __in BURN_VARIABLES* pVariables, 548 __in BURN_VARIABLES* pVariables,
548 __in BOOL fRollback, 549 __in BOOL fRollback,
549 __in PFN_MSIEXECUTEMESSAGEHANDLER pfnMessageHandler, 550 __in PFN_MSIEXECUTEMESSAGEHANDLER pfnMessageHandler,
@@ -574,7 +575,7 @@ extern "C" HRESULT MspEngineExecutePackage(
574 575
575 if (BOOTSTRAPPER_ACTION_STATE_INSTALL == pExecuteAction->mspTarget.action) 576 if (BOOTSTRAPPER_ACTION_STATE_INSTALL == pExecuteAction->mspTarget.action)
576 { 577 {
577 hr = CacheGetCompletedPath(pMspPackage->fPerMachine, pMspPackage->sczCacheId, &sczCachedDirectory); 578 hr = CacheGetCompletedPath(pCache, pMspPackage->fPerMachine, pMspPackage->sczCacheId, &sczCachedDirectory);
578 ExitOnFailure(hr, "Failed to get cached path for MSP package: %ls", pMspPackage->sczId); 579 ExitOnFailure(hr, "Failed to get cached path for MSP package: %ls", pMspPackage->sczId);
579 580
580 // TODO: Figure out if this makes sense -- the variable is set to the last patch's path only 581 // TODO: Figure out if this makes sense -- the variable is set to the last patch's path only
diff --git a/src/burn/engine/mspengine.h b/src/burn/engine/mspengine.h
index a8835d7b..d17d731d 100644
--- a/src/burn/engine/mspengine.h
+++ b/src/burn/engine/mspengine.h
@@ -62,6 +62,7 @@ HRESULT MspEnginePlanAddPackage(
62HRESULT MspEngineExecutePackage( 62HRESULT MspEngineExecutePackage(
63 __in_opt HWND hwndParent, 63 __in_opt HWND hwndParent,
64 __in BURN_EXECUTE_ACTION* pExecuteAction, 64 __in BURN_EXECUTE_ACTION* pExecuteAction,
65 __in BURN_CACHE* pCache,
65 __in BURN_VARIABLES* pVariables, 66 __in BURN_VARIABLES* pVariables,
66 __in BOOL fRollback, 67 __in BOOL fRollback,
67 __in PFN_MSIEXECUTEMESSAGEHANDLER pfnMessageHandler, 68 __in PFN_MSIEXECUTEMESSAGEHANDLER pfnMessageHandler,
diff --git a/src/burn/engine/msuengine.cpp b/src/burn/engine/msuengine.cpp
index d6722bbf..1ce2dd11 100644
--- a/src/burn/engine/msuengine.cpp
+++ b/src/burn/engine/msuengine.cpp
@@ -233,6 +233,7 @@ LExit:
233 233
234extern "C" HRESULT MsuEngineExecutePackage( 234extern "C" HRESULT MsuEngineExecutePackage(
235 __in BURN_EXECUTE_ACTION* pExecuteAction, 235 __in BURN_EXECUTE_ACTION* pExecuteAction,
236 __in BURN_CACHE* pCache,
236 __in BURN_VARIABLES* pVariables, 237 __in BURN_VARIABLES* pVariables,
237 __in BOOL fRollback, 238 __in BOOL fRollback,
238 __in BOOL fStopWusaService, 239 __in BOOL fStopWusaService,
@@ -289,7 +290,7 @@ extern "C" HRESULT MsuEngineExecutePackage(
289 { 290 {
290 case BOOTSTRAPPER_ACTION_STATE_INSTALL: 291 case BOOTSTRAPPER_ACTION_STATE_INSTALL:
291 // get cached MSU path 292 // get cached MSU path
292 hr = CacheGetCompletedPath(TRUE, pPackage->sczCacheId, &sczCachedDirectory); 293 hr = CacheGetCompletedPath(pCache, TRUE, pPackage->sczCacheId, &sczCachedDirectory);
293 ExitOnFailure(hr, "Failed to get cached path for package: %ls", pPackage->sczId); 294 ExitOnFailure(hr, "Failed to get cached path for package: %ls", pPackage->sczId);
294 295
295 // Best effort to set the execute package cache folder variable. 296 // Best effort to set the execute package cache folder variable.
diff --git a/src/burn/engine/msuengine.h b/src/burn/engine/msuengine.h
index 23dd5301..0d2563e2 100644
--- a/src/burn/engine/msuengine.h
+++ b/src/burn/engine/msuengine.h
@@ -31,6 +31,7 @@ HRESULT MsuEnginePlanAddPackage(
31 ); 31 );
32HRESULT MsuEngineExecutePackage( 32HRESULT MsuEngineExecutePackage(
33 __in BURN_EXECUTE_ACTION* pExecuteAction, 33 __in BURN_EXECUTE_ACTION* pExecuteAction,
34 __in BURN_CACHE* pCache,
34 __in BURN_VARIABLES* pVariables, 35 __in BURN_VARIABLES* pVariables,
35 __in BOOL fRollback, 36 __in BOOL fRollback,
36 __in BOOL fStopWusaService, 37 __in BOOL fStopWusaService,
diff --git a/src/burn/engine/plan.cpp b/src/burn/engine/plan.cpp
index 3d6fc65f..79b7c98f 100644
--- a/src/burn/engine/plan.cpp
+++ b/src/burn/engine/plan.cpp
@@ -409,7 +409,7 @@ extern "C" HRESULT PlanLayoutBundle(
409 hr = StrAllocString(&pCacheAction->bundleLayout.sczExecutableName, wzExecutableName, 0); 409 hr = StrAllocString(&pCacheAction->bundleLayout.sczExecutableName, wzExecutableName, 0);
410 ExitOnFailure(hr, "Failed to to copy executable name for bundle."); 410 ExitOnFailure(hr, "Failed to to copy executable name for bundle.");
411 411
412 hr = CacheCalculateBundleLayoutWorkingPath(pPlan->wzBundleId, &pCacheAction->bundleLayout.sczUnverifiedPath); 412 hr = CacheCalculateBundleLayoutWorkingPath(pPlan->pCache, pPlan->wzBundleId, &pCacheAction->bundleLayout.sczUnverifiedPath);
413 ExitOnFailure(hr, "Failed to calculate bundle layout working path."); 413 ExitOnFailure(hr, "Failed to calculate bundle layout working path.");
414 414
415 pCacheAction->bundleLayout.qwBundleSize = qwBundleSize; 415 pCacheAction->bundleLayout.qwBundleSize = qwBundleSize;
@@ -526,7 +526,7 @@ extern "C" HRESULT PlanRegistration(
526 pPlan->fIgnoreAllDependents = pRegistration->fIgnoreAllDependents; 526 pPlan->fIgnoreAllDependents = pRegistration->fIgnoreAllDependents;
527 527
528 // Ensure the bundle is cached if not running from the cache. 528 // Ensure the bundle is cached if not running from the cache.
529 if (!CacheBundleRunningFromCache()) 529 if (!CacheBundleRunningFromCache(pPlan->pCache))
530 { 530 {
531 pPlan->dwRegistrationOperations |= BURN_REGISTRATION_ACTION_OPERATIONS_CACHE_BUNDLE; 531 pPlan->dwRegistrationOperations |= BURN_REGISTRATION_ACTION_OPERATIONS_CACHE_BUNDLE;
532 } 532 }
@@ -1021,7 +1021,7 @@ extern "C" HRESULT PlanLayoutContainer(
1021 } 1021 }
1022 else 1022 else
1023 { 1023 {
1024 hr = CacheCalculateContainerWorkingPath(pPlan->wzBundleId, pContainer, &pContainer->sczUnverifiedPath); 1024 hr = CacheCalculateContainerWorkingPath(pPlan->pCache, pContainer, &pContainer->sczUnverifiedPath);
1025 ExitOnFailure(hr, "Failed to calculate unverified path for container."); 1025 ExitOnFailure(hr, "Failed to calculate unverified path for container.");
1026 } 1026 }
1027 } 1027 }
@@ -2235,7 +2235,7 @@ static HRESULT ProcessPayloadGroup(
2235 2235
2236 if (!pPayload->sczUnverifiedPath) 2236 if (!pPayload->sczUnverifiedPath)
2237 { 2237 {
2238 hr = CacheCalculatePayloadWorkingPath(pPlan->wzBundleId, pPayload, &pPayload->sczUnverifiedPath); 2238 hr = CacheCalculatePayloadWorkingPath(pPlan->pCache, pPayload, &pPayload->sczUnverifiedPath);
2239 ExitOnFailure(hr, "Failed to calculate unverified path for payload."); 2239 ExitOnFailure(hr, "Failed to calculate unverified path for payload.");
2240 } 2240 }
2241 } 2241 }
diff --git a/src/burn/engine/plan.h b/src/burn/engine/plan.h
index 6db464e1..28fc1639 100644
--- a/src/burn/engine/plan.h
+++ b/src/burn/engine/plan.h
@@ -229,7 +229,8 @@ typedef struct _BURN_CLEAN_ACTION
229typedef struct _BURN_PLAN 229typedef struct _BURN_PLAN
230{ 230{
231 BOOTSTRAPPER_ACTION action; 231 BOOTSTRAPPER_ACTION action;
232 BURN_PAYLOADS* pPayloads; // points directly into parent the ENGINE_STATE. 232 BURN_CACHE* pCache;
233 BURN_PAYLOADS* pPayloads;
233 LPWSTR wzBundleId; // points directly into parent the ENGINE_STATE. 234 LPWSTR wzBundleId; // points directly into parent the ENGINE_STATE.
234 LPWSTR wzBundleProviderKey; // points directly into parent the ENGINE_STATE. 235 LPWSTR wzBundleProviderKey; // points directly into parent the ENGINE_STATE.
235 BOOL fPerMachine; 236 BOOL fPerMachine;
diff --git a/src/burn/engine/precomp.h b/src/burn/engine/precomp.h
index c1822381..647a3b33 100644
--- a/src/burn/engine/precomp.h
+++ b/src/burn/engine/precomp.h
@@ -82,8 +82,8 @@
82#include "plan.h" 82#include "plan.h"
83#include "logging.h" 83#include "logging.h"
84#include "pipe.h" 84#include "pipe.h"
85#include "core.h"
86#include "cache.h" 85#include "cache.h"
86#include "core.h"
87#include "apply.h" 87#include "apply.h"
88#include "exeengine.h" 88#include "exeengine.h"
89#include "msiengine.h" 89#include "msiengine.h"
diff --git a/src/burn/engine/registration.cpp b/src/burn/engine/registration.cpp
index 0a8fb602..d1c32b3e 100644
--- a/src/burn/engine/registration.cpp
+++ b/src/burn/engine/registration.cpp
@@ -42,7 +42,8 @@ static HRESULT ParseSoftwareTagsFromXml(
42 __out DWORD* pcSoftwareTags 42 __out DWORD* pcSoftwareTags
43 ); 43 );
44static HRESULT SetPaths( 44static HRESULT SetPaths(
45 __in BURN_REGISTRATION* pRegistration 45 __in BURN_REGISTRATION* pRegistration,
46 __in BURN_CACHE* pCache
46 ); 47 );
47static HRESULT GetBundleManufacturer( 48static HRESULT GetBundleManufacturer(
48 __in BURN_REGISTRATION* pRegistration, 49 __in BURN_REGISTRATION* pRegistration,
@@ -120,6 +121,7 @@ static BOOL IsRegistryRebootPending();
120*******************************************************************/ 121*******************************************************************/
121extern "C" HRESULT RegistrationParseFromXml( 122extern "C" HRESULT RegistrationParseFromXml(
122 __in BURN_REGISTRATION* pRegistration, 123 __in BURN_REGISTRATION* pRegistration,
124 __in BURN_CACHE* pCache,
123 __in IXMLDOMNode* pixnBundle 125 __in IXMLDOMNode* pixnBundle
124 ) 126 )
125{ 127{
@@ -335,7 +337,7 @@ extern "C" HRESULT RegistrationParseFromXml(
335 ExitOnFailure(hr, "Failed to get @Classification."); 337 ExitOnFailure(hr, "Failed to get @Classification.");
336 } 338 }
337 339
338 hr = SetPaths(pRegistration); 340 hr = SetPaths(pRegistration, pCache);
339 ExitOnFailure(hr, "Failed to set registration paths."); 341 ExitOnFailure(hr, "Failed to set registration paths.");
340 342
341LExit: 343LExit:
@@ -614,6 +616,7 @@ LExit:
614extern "C" HRESULT RegistrationSessionBegin( 616extern "C" HRESULT RegistrationSessionBegin(
615 __in_z LPCWSTR wzEngineWorkingPath, 617 __in_z LPCWSTR wzEngineWorkingPath,
616 __in BURN_REGISTRATION* pRegistration, 618 __in BURN_REGISTRATION* pRegistration,
619 __in BURN_CACHE* pCache,
617 __in BURN_VARIABLES* pVariables, 620 __in BURN_VARIABLES* pVariables,
618 __in DWORD dwRegistrationOptions, 621 __in DWORD dwRegistrationOptions,
619 __in BURN_DEPENDENCY_REGISTRATION_ACTION dependencyRegistrationAction, 622 __in BURN_DEPENDENCY_REGISTRATION_ACTION dependencyRegistrationAction,
@@ -633,7 +636,7 @@ extern "C" HRESULT RegistrationSessionBegin(
633 // Cache bundle executable. 636 // Cache bundle executable.
634 if (dwRegistrationOptions & BURN_REGISTRATION_ACTION_OPERATIONS_CACHE_BUNDLE) 637 if (dwRegistrationOptions & BURN_REGISTRATION_ACTION_OPERATIONS_CACHE_BUNDLE)
635 { 638 {
636 hr = CacheCompleteBundle(pRegistration->fPerMachine, pRegistration->sczExecutableName, pRegistration->sczId, wzEngineWorkingPath 639 hr = CacheCompleteBundle(pCache, pRegistration->fPerMachine, pRegistration->sczExecutableName, pRegistration->sczId, wzEngineWorkingPath
637#ifdef DEBUG 640#ifdef DEBUG
638 , pRegistration->sczCacheExecutablePath 641 , pRegistration->sczCacheExecutablePath
639#endif 642#endif
@@ -900,6 +903,7 @@ LExit:
900 *******************************************************************/ 903 *******************************************************************/
901extern "C" HRESULT RegistrationSessionEnd( 904extern "C" HRESULT RegistrationSessionEnd(
902 __in BURN_REGISTRATION* pRegistration, 905 __in BURN_REGISTRATION* pRegistration,
906 __in BURN_CACHE* pCache,
903 __in BURN_VARIABLES* pVariables, 907 __in BURN_VARIABLES* pVariables,
904 __in BURN_PACKAGES* pPackages, 908 __in BURN_PACKAGES* pPackages,
905 __in BURN_RESUME_MODE resumeMode, 909 __in BURN_RESUME_MODE resumeMode,
@@ -964,7 +968,7 @@ extern "C" HRESULT RegistrationSessionEnd(
964 ExitOnFailure(hr, "Failed to delete registration key: %ls", pRegistration->sczRegistrationKey); 968 ExitOnFailure(hr, "Failed to delete registration key: %ls", pRegistration->sczRegistrationKey);
965 } 969 }
966 970
967 CacheRemoveBundle(pRegistration->fPerMachine, pRegistration->sczId); 971 CacheRemoveBundle(pCache, pRegistration->fPerMachine, pRegistration->sczId);
968 } 972 }
969 else // the mode needs to be updated so open the registration key. 973 else // the mode needs to be updated so open the registration key.
970 { 974 {
@@ -1213,7 +1217,8 @@ LExit:
1213} 1217}
1214 1218
1215static HRESULT SetPaths( 1219static HRESULT SetPaths(
1216 __in BURN_REGISTRATION* pRegistration 1220 __in BURN_REGISTRATION* pRegistration,
1221 __in BURN_CACHE* pCache
1217 ) 1222 )
1218{ 1223{
1219 HRESULT hr = S_OK; 1224 HRESULT hr = S_OK;
@@ -1227,7 +1232,7 @@ static HRESULT SetPaths(
1227 ExitOnFailure(hr, "Failed to build uninstall registry key path."); 1232 ExitOnFailure(hr, "Failed to build uninstall registry key path.");
1228 1233
1229 // build cache directory 1234 // build cache directory
1230 hr = CacheGetCompletedPath(pRegistration->fPerMachine, pRegistration->sczId, &sczCacheDirectory); 1235 hr = CacheGetCompletedPath(pCache, pRegistration->fPerMachine, pRegistration->sczId, &sczCacheDirectory);
1231 ExitOnFailure(hr, "Failed to build cache directory."); 1236 ExitOnFailure(hr, "Failed to build cache directory.");
1232 1237
1233 // build cached executable path 1238 // build cached executable path
diff --git a/src/burn/engine/registration.h b/src/burn/engine/registration.h
index 936e5966..aa5bf842 100644
--- a/src/burn/engine/registration.h
+++ b/src/burn/engine/registration.h
@@ -166,6 +166,7 @@ typedef struct _BURN_REGISTRATION
166 166
167HRESULT RegistrationParseFromXml( 167HRESULT RegistrationParseFromXml(
168 __in BURN_REGISTRATION* pRegistration, 168 __in BURN_REGISTRATION* pRegistration,
169 __in BURN_CACHE* pCache,
169 __in IXMLDOMNode* pixnBundle 170 __in IXMLDOMNode* pixnBundle
170 ); 171 );
171void RegistrationUninitialize( 172void RegistrationUninitialize(
@@ -188,6 +189,7 @@ HRESULT RegistrationDetectRelatedBundles(
188HRESULT RegistrationSessionBegin( 189HRESULT RegistrationSessionBegin(
189 __in_z LPCWSTR wzEngineWorkingPath, 190 __in_z LPCWSTR wzEngineWorkingPath,
190 __in BURN_REGISTRATION* pRegistration, 191 __in BURN_REGISTRATION* pRegistration,
192 __in BURN_CACHE* pCache,
191 __in BURN_VARIABLES* pVariables, 193 __in BURN_VARIABLES* pVariables,
192 __in DWORD dwRegistrationOptions, 194 __in DWORD dwRegistrationOptions,
193 __in BURN_DEPENDENCY_REGISTRATION_ACTION dependencyRegistrationAction, 195 __in BURN_DEPENDENCY_REGISTRATION_ACTION dependencyRegistrationAction,
@@ -201,6 +203,7 @@ HRESULT RegistrationSessionResume(
201 ); 203 );
202HRESULT RegistrationSessionEnd( 204HRESULT RegistrationSessionEnd(
203 __in BURN_REGISTRATION* pRegistration, 205 __in BURN_REGISTRATION* pRegistration,
206 __in BURN_CACHE* pCache,
204 __in BURN_VARIABLES* pVariables, 207 __in BURN_VARIABLES* pVariables,
205 __in BURN_PACKAGES* pPackages, 208 __in BURN_PACKAGES* pPackages,
206 __in BURN_RESUME_MODE resumeMode, 209 __in BURN_RESUME_MODE resumeMode,
diff --git a/src/burn/engine/uithread.cpp b/src/burn/engine/uithread.cpp
index 433cb171..986342b2 100644
--- a/src/burn/engine/uithread.cpp
+++ b/src/burn/engine/uithread.cpp
@@ -16,7 +16,7 @@ struct UITHREAD_CONTEXT
16 16
17struct UITHREAD_INFO 17struct UITHREAD_INFO
18{ 18{
19 BOOL fElevated; 19 BOOL fElevatedEngine;
20 BURN_USER_EXPERIENCE* pUserExperience; 20 BURN_USER_EXPERIENCE* pUserExperience;
21}; 21};
22 22
@@ -105,10 +105,10 @@ static DWORD WINAPI ThreadProc(
105 MSG msg = { }; 105 MSG msg = { };
106 106
107 BURN_ENGINE_STATE* pEngineState = pContext->pEngineState; 107 BURN_ENGINE_STATE* pEngineState = pContext->pEngineState;
108 BOOL fElevated = BURN_MODE_ELEVATED == pContext->pEngineState->mode; 108 BOOL fElevatedEngine = BURN_MODE_ELEVATED == pContext->pEngineState->mode;
109 109
110 // If elevated, set up the thread local storage to store the correct pipe to communicate logging. 110 // If elevated, set up the thread local storage to store the correct pipe to communicate logging.
111 if (fElevated) 111 if (fElevatedEngine)
112 { 112 {
113 Assert(TLS_OUT_OF_INDEXES != pEngineState->dwElevatedLoggingTlsId); 113 Assert(TLS_OUT_OF_INDEXES != pEngineState->dwElevatedLoggingTlsId);
114 114
@@ -130,7 +130,7 @@ static DWORD WINAPI ThreadProc(
130 130
131 fRegistered = TRUE; 131 fRegistered = TRUE;
132 132
133 info.fElevated = fElevated; 133 info.fElevatedEngine = fElevatedEngine;
134 info.pUserExperience = &pEngineState->userExperience; 134 info.pUserExperience = &pEngineState->userExperience;
135 135
136 // Create the window to handle reboots without activating it. 136 // Create the window to handle reboots without activating it.
@@ -199,7 +199,7 @@ static LRESULT CALLBACK WndProc(
199 199
200 // Always block shutdown in the elevated process, but ask the BA in the non-elevated. 200 // Always block shutdown in the elevated process, but ask the BA in the non-elevated.
201 UITHREAD_INFO* pInfo = reinterpret_cast<UITHREAD_INFO*>(::GetWindowLongPtrW(hWnd, GWLP_USERDATA)); 201 UITHREAD_INFO* pInfo = reinterpret_cast<UITHREAD_INFO*>(::GetWindowLongPtrW(hWnd, GWLP_USERDATA));
202 if (!pInfo->fElevated) 202 if (!pInfo->fElevatedEngine)
203 { 203 {
204 // TODO: instead of recommending canceling all non-critical shutdowns, maybe we should only recommend cancel 204 // TODO: instead of recommending canceling all non-critical shutdowns, maybe we should only recommend cancel
205 // when the engine is doing work? 205 // when the engine is doing work?
@@ -209,7 +209,7 @@ static LRESULT CALLBACK WndProc(
209 } 209 }
210 210
211 fRet = !fCancel; 211 fRet = !fCancel;
212 LogId(REPORT_STANDARD, MSG_SYSTEM_SHUTDOWN, LoggingBoolToString(fCritical), LoggingBoolToString(pInfo->fElevated), LoggingBoolToString(fRet)); 212 LogId(REPORT_STANDARD, MSG_SYSTEM_SHUTDOWN, LoggingBoolToString(fCritical), LoggingBoolToString(pInfo->fElevatedEngine), LoggingBoolToString(fRet));
213 return fRet; 213 return fRet;
214 } 214 }
215 215
diff --git a/src/burn/engine/userexperience.cpp b/src/burn/engine/userexperience.cpp
index 88655774..69ec6347 100644
--- a/src/burn/engine/userexperience.cpp
+++ b/src/burn/engine/userexperience.cpp
@@ -161,14 +161,14 @@ extern "C" HRESULT UserExperienceUnload(
161} 161}
162 162
163extern "C" HRESULT UserExperienceEnsureWorkingFolder( 163extern "C" HRESULT UserExperienceEnsureWorkingFolder(
164 __in LPCWSTR wzBundleId, 164 __in BURN_CACHE* pCache,
165 __deref_out_z LPWSTR* psczUserExperienceWorkingFolder 165 __deref_out_z LPWSTR* psczUserExperienceWorkingFolder
166 ) 166 )
167{ 167{
168 HRESULT hr = S_OK; 168 HRESULT hr = S_OK;
169 LPWSTR sczWorkingFolder = NULL; 169 LPWSTR sczWorkingFolder = NULL;
170 170
171 hr = CacheEnsureWorkingFolder(wzBundleId, &sczWorkingFolder); 171 hr = CacheEnsureWorkingFolder(pCache, &sczWorkingFolder);
172 ExitOnFailure(hr, "Failed to create working folder."); 172 ExitOnFailure(hr, "Failed to create working folder.");
173 173
174 hr = StrAllocFormatted(psczUserExperienceWorkingFolder, L"%ls%ls\\", sczWorkingFolder, L".ba"); 174 hr = StrAllocFormatted(psczUserExperienceWorkingFolder, L"%ls%ls\\", sczWorkingFolder, L".ba");
diff --git a/src/burn/engine/userexperience.h b/src/burn/engine/userexperience.h
index 584bef14..aaf69083 100644
--- a/src/burn/engine/userexperience.h
+++ b/src/burn/engine/userexperience.h
@@ -15,8 +15,6 @@ const DWORD MB_RETRYTRYAGAIN = 0xF;
15 15
16// structs 16// structs
17 17
18typedef struct _BOOTSTRAPPER_ENGINE_CONTEXT BOOTSTRAPPER_ENGINE_CONTEXT; // forward declare
19
20typedef struct _BURN_USER_EXPERIENCE 18typedef struct _BURN_USER_EXPERIENCE
21{ 19{
22 BURN_PAYLOADS payloads; 20 BURN_PAYLOADS payloads;
@@ -66,7 +64,7 @@ HRESULT UserExperienceUnload(
66 __in BURN_USER_EXPERIENCE* pUserExperience 64 __in BURN_USER_EXPERIENCE* pUserExperience
67 ); 65 );
68HRESULT UserExperienceEnsureWorkingFolder( 66HRESULT UserExperienceEnsureWorkingFolder(
69 __in LPCWSTR wzBundleId, 67 __in BURN_CACHE* pCache,
70 __deref_out_z LPWSTR* psczUserExperienceWorkingFolder 68 __deref_out_z LPWSTR* psczUserExperienceWorkingFolder
71 ); 69 );
72HRESULT UserExperienceRemove( 70HRESULT UserExperienceRemove(
diff --git a/src/burn/test/BurnUnitTest/CacheTest.cpp b/src/burn/test/BurnUnitTest/CacheTest.cpp
index e9ad555b..6979ec1a 100644
--- a/src/burn/test/BurnUnitTest/CacheTest.cpp
+++ b/src/burn/test/BurnUnitTest/CacheTest.cpp
@@ -48,6 +48,8 @@ namespace Bootstrapper
48 void CacheSignatureTest() 48 void CacheSignatureTest()
49 { 49 {
50 HRESULT hr = S_OK; 50 HRESULT hr = S_OK;
51 BURN_CACHE cache = { };
52 BURN_ENGINE_COMMAND internalCommand = { };
51 BURN_PACKAGE package = { }; 53 BURN_PACKAGE package = { };
52 BURN_PAYLOAD payload = { }; 54 BURN_PAYLOAD payload = { };
53 LPWSTR sczPayloadPath = NULL; 55 LPWSTR sczPayloadPath = NULL;
@@ -74,7 +76,10 @@ namespace Bootstrapper
74 payload.qwFileSize = 27; 76 payload.qwFileSize = 27;
75 payload.verification = BURN_PAYLOAD_VERIFICATION_HASH; 77 payload.verification = BURN_PAYLOAD_VERIFICATION_HASH;
76 78
77 hr = CacheCompletePayload(package.fPerMachine, &payload, package.sczCacheId, sczPayloadPath, FALSE, CacheTestEventRoutine, CacheTestProgressRoutine, &context); 79 hr = CacheInitialize(&cache, &internalCommand);
80 TestThrowOnFailure(hr, L"Failed initialize cache.");
81
82 hr = CacheCompletePayload(&cache, package.fPerMachine, &payload, package.sczCacheId, sczPayloadPath, FALSE, CacheTestEventRoutine, CacheTestProgressRoutine, &context);
78 Assert::Equal(S_OK, hr); 83 Assert::Equal(S_OK, hr);
79 } 84 }
80 finally 85 finally
diff --git a/src/burn/test/BurnUnitTest/ManifestTest.cpp b/src/burn/test/BurnUnitTest/ManifestTest.cpp
index 345ddfd9..6973c772 100644
--- a/src/burn/test/BurnUnitTest/ManifestTest.cpp
+++ b/src/burn/test/BurnUnitTest/ManifestTest.cpp
@@ -40,6 +40,9 @@ namespace Bootstrapper
40 " <CommandLine Variables='upperCase' />" 40 " <CommandLine Variables='upperCase' />"
41 "</Bundle>"; 41 "</Bundle>";
42 42
43 hr = CacheInitialize(&engineState.cache, &engineState.internalCommand);
44 TestThrowOnFailure(hr, L"Failed initialize cache.");
45
43 hr = VariableInitialize(&engineState.variables); 46 hr = VariableInitialize(&engineState.variables);
44 TestThrowOnFailure(hr, L"Failed to initialize variables."); 47 TestThrowOnFailure(hr, L"Failed to initialize variables.");
45 48
diff --git a/src/burn/test/BurnUnitTest/PlanTest.cpp b/src/burn/test/BurnUnitTest/PlanTest.cpp
index 7909d747..2e3b1092 100644
--- a/src/burn/test/BurnUnitTest/PlanTest.cpp
+++ b/src/burn/test/BurnUnitTest/PlanTest.cpp
@@ -925,6 +925,9 @@ namespace Bootstrapper
925 925
926 ::InitializeCriticalSection(&pEngineState->userExperience.csEngineActive); 926 ::InitializeCriticalSection(&pEngineState->userExperience.csEngineActive);
927 927
928 hr = CacheInitialize(&pEngineState->cache, &pEngineState->internalCommand);
929 NativeAssert::Succeeded(hr, "Failed to initialize cache.");
930
928 hr = VariableInitialize(&pEngineState->variables); 931 hr = VariableInitialize(&pEngineState->variables);
929 NativeAssert::Succeeded(hr, "Failed to initialize variables."); 932 NativeAssert::Succeeded(hr, "Failed to initialize variables.");
930 933
@@ -948,6 +951,9 @@ namespace Bootstrapper
948 hr = CoreInitializeConstants(pEngineState); 951 hr = CoreInitializeConstants(pEngineState);
949 NativeAssert::Succeeded(hr, "Failed to initialize core constants"); 952 NativeAssert::Succeeded(hr, "Failed to initialize core constants");
950 953
954 hr = CacheInitializeSources(&pEngineState->cache, &pEngineState->registration, &pEngineState->variables, &pEngineState->internalCommand);
955 NativeAssert::Succeeded(hr, "Failed to initialize cache sources.");
956
951 pEngineState->userExperience.pfnBAProc = PlanTestBAProc; 957 pEngineState->userExperience.pfnBAProc = PlanTestBAProc;
952 } 958 }
953 959
diff --git a/src/burn/test/BurnUnitTest/RegistrationTest.cpp b/src/burn/test/BurnUnitTest/RegistrationTest.cpp
index b1c911f7..7c0dde5a 100644
--- a/src/burn/test/BurnUnitTest/RegistrationTest.cpp
+++ b/src/burn/test/BurnUnitTest/RegistrationTest.cpp
@@ -75,6 +75,8 @@ namespace Bootstrapper
75 BURN_REGISTRATION registration = { }; 75 BURN_REGISTRATION registration = { };
76 BURN_LOGGING logging = { }; 76 BURN_LOGGING logging = { };
77 BURN_PACKAGES packages = { }; 77 BURN_PACKAGES packages = { };
78 BURN_CACHE cache = { };
79 BURN_ENGINE_COMMAND internalCommand = { };
78 String^ cacheDirectory = Path::Combine(Path::Combine(Environment::GetFolderPath(Environment::SpecialFolder::LocalApplicationData), gcnew String(L"Package Cache")), gcnew String(TEST_BUNDLE_ID)); 80 String^ cacheDirectory = Path::Combine(Path::Combine(Environment::GetFolderPath(Environment::SpecialFolder::LocalApplicationData), gcnew String(L"Package Cache")), gcnew String(TEST_BUNDLE_ID));
79 81
80 try 82 try
@@ -99,13 +101,16 @@ namespace Bootstrapper
99 // load XML document 101 // load XML document
100 LoadBundleXmlHelper(wzDocument, &pixeBundle); 102 LoadBundleXmlHelper(wzDocument, &pixeBundle);
101 103
104 hr = CacheInitialize(&cache, &internalCommand);
105 TestThrowOnFailure(hr, L"Failed initialize cache.");
106
102 hr = VariableInitialize(&variables); 107 hr = VariableInitialize(&variables);
103 TestThrowOnFailure(hr, L"Failed to initialize variables."); 108 TestThrowOnFailure(hr, L"Failed to initialize variables.");
104 109
105 hr = UserExperienceParseFromXml(&userExperience, pixeBundle); 110 hr = UserExperienceParseFromXml(&userExperience, pixeBundle);
106 TestThrowOnFailure(hr, L"Failed to parse UX from XML."); 111 TestThrowOnFailure(hr, L"Failed to parse UX from XML.");
107 112
108 hr = RegistrationParseFromXml(&registration, pixeBundle); 113 hr = RegistrationParseFromXml(&registration, &cache, pixeBundle);
109 TestThrowOnFailure(hr, L"Failed to parse registration from XML."); 114 TestThrowOnFailure(hr, L"Failed to parse registration from XML.");
110 115
111 hr = PlanSetResumeCommand(&registration, BOOTSTRAPPER_ACTION_INSTALL, &command, &logging); 116 hr = PlanSetResumeCommand(&registration, BOOTSTRAPPER_ACTION_INSTALL, &command, &logging);
@@ -115,7 +120,7 @@ namespace Bootstrapper
115 TestThrowOnFailure(hr, L"Failed to get current process path."); 120 TestThrowOnFailure(hr, L"Failed to get current process path.");
116 121
117 // write registration 122 // write registration
118 hr = RegistrationSessionBegin(sczCurrentProcess, &registration, &variables, BURN_REGISTRATION_ACTION_OPERATIONS_CACHE_BUNDLE | BURN_REGISTRATION_ACTION_OPERATIONS_WRITE_REGISTRATION, BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER, 0, BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS); 123 hr = RegistrationSessionBegin(sczCurrentProcess, &registration, &cache, &variables, BURN_REGISTRATION_ACTION_OPERATIONS_CACHE_BUNDLE | BURN_REGISTRATION_ACTION_OPERATIONS_WRITE_REGISTRATION, BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER, 0, BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS);
119 TestThrowOnFailure(hr, L"Failed to register bundle."); 124 TestThrowOnFailure(hr, L"Failed to register bundle.");
120 125
121 // verify that registration was created 126 // verify that registration was created
@@ -126,7 +131,7 @@ namespace Bootstrapper
126 Assert::Equal<String^>(String::Concat(L"\"", Path::Combine(cacheDirectory, gcnew String(L"setup.exe")), L"\" /burn.runonce"), (String^)(Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(TEST_BUNDLE_ID), nullptr))); 131 Assert::Equal<String^>(String::Concat(L"\"", Path::Combine(cacheDirectory, gcnew String(L"setup.exe")), L"\" /burn.runonce"), (String^)(Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(TEST_BUNDLE_ID), nullptr)));
127 132
128 // end session 133 // end session
129 hr = RegistrationSessionEnd(&registration, &variables, &packages, BURN_RESUME_MODE_NONE, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_UNREGISTER, BOOTSTRAPPER_REGISTRATION_TYPE_NONE); 134 hr = RegistrationSessionEnd(&registration, &cache, &variables, &packages, BURN_RESUME_MODE_NONE, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_UNREGISTER, BOOTSTRAPPER_REGISTRATION_TYPE_NONE);
130 TestThrowOnFailure(hr, L"Failed to unregister bundle."); 135 TestThrowOnFailure(hr, L"Failed to unregister bundle.");
131 136
132 // verify that registration was removed 137 // verify that registration was removed
@@ -165,6 +170,8 @@ namespace Bootstrapper
165 BURN_REGISTRATION registration = { }; 170 BURN_REGISTRATION registration = { };
166 BURN_LOGGING logging = { }; 171 BURN_LOGGING logging = { };
167 BURN_PACKAGES packages = { }; 172 BURN_PACKAGES packages = { };
173 BURN_CACHE cache = { };
174 BURN_ENGINE_COMMAND internalCommand = { };
168 String^ cacheDirectory = Path::Combine(Path::Combine(Environment::GetFolderPath(Environment::SpecialFolder::LocalApplicationData), gcnew String(L"Package Cache")), gcnew String(TEST_BUNDLE_ID)); 175 String^ cacheDirectory = Path::Combine(Path::Combine(Environment::GetFolderPath(Environment::SpecialFolder::LocalApplicationData), gcnew String(L"Package Cache")), gcnew String(TEST_BUNDLE_ID));
169 try 176 try
170 { 177 {
@@ -188,13 +195,16 @@ namespace Bootstrapper
188 // load XML document 195 // load XML document
189 LoadBundleXmlHelper(wzDocument, &pixeBundle); 196 LoadBundleXmlHelper(wzDocument, &pixeBundle);
190 197
198 hr = CacheInitialize(&cache, &internalCommand);
199 TestThrowOnFailure(hr, L"Failed initialize cache.");
200
191 hr = VariableInitialize(&variables); 201 hr = VariableInitialize(&variables);
192 TestThrowOnFailure(hr, L"Failed to initialize variables."); 202 TestThrowOnFailure(hr, L"Failed to initialize variables.");
193 203
194 hr = UserExperienceParseFromXml(&userExperience, pixeBundle); 204 hr = UserExperienceParseFromXml(&userExperience, pixeBundle);
195 TestThrowOnFailure(hr, L"Failed to parse UX from XML."); 205 TestThrowOnFailure(hr, L"Failed to parse UX from XML.");
196 206
197 hr = RegistrationParseFromXml(&registration, pixeBundle); 207 hr = RegistrationParseFromXml(&registration, &cache, pixeBundle);
198 TestThrowOnFailure(hr, L"Failed to parse registration from XML."); 208 TestThrowOnFailure(hr, L"Failed to parse registration from XML.");
199 209
200 hr = PlanSetResumeCommand(&registration, BOOTSTRAPPER_ACTION_INSTALL, &command, &logging); 210 hr = PlanSetResumeCommand(&registration, BOOTSTRAPPER_ACTION_INSTALL, &command, &logging);
@@ -208,7 +218,7 @@ namespace Bootstrapper
208 // 218 //
209 219
210 // write registration 220 // write registration
211 hr = RegistrationSessionBegin(sczCurrentProcess, &registration, &variables, BURN_REGISTRATION_ACTION_OPERATIONS_WRITE_REGISTRATION, BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER, 0, BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS); 221 hr = RegistrationSessionBegin(sczCurrentProcess, &registration, &cache, &variables, BURN_REGISTRATION_ACTION_OPERATIONS_WRITE_REGISTRATION, BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER, 0, BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS);
212 TestThrowOnFailure(hr, L"Failed to register bundle."); 222 TestThrowOnFailure(hr, L"Failed to register bundle.");
213 223
214 // verify that registration was created 224 // verify that registration was created
@@ -217,7 +227,7 @@ namespace Bootstrapper
217 Assert::Equal<String^>(String::Concat(L"\"", Path::Combine(cacheDirectory, gcnew String(L"setup.exe")), L"\" /burn.runonce"), (String^)Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(TEST_BUNDLE_ID), nullptr)); 227 Assert::Equal<String^>(String::Concat(L"\"", Path::Combine(cacheDirectory, gcnew String(L"setup.exe")), L"\" /burn.runonce"), (String^)Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(TEST_BUNDLE_ID), nullptr));
218 228
219 // complete registration 229 // complete registration
220 hr = RegistrationSessionEnd(&registration, &variables, &packages, BURN_RESUME_MODE_ARP, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER, BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS); 230 hr = RegistrationSessionEnd(&registration, &cache, &variables, &packages, BURN_RESUME_MODE_ARP, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER, BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS);
221 TestThrowOnFailure(hr, L"Failed to unregister bundle."); 231 TestThrowOnFailure(hr, L"Failed to unregister bundle.");
222 232
223 // verify that registration was updated 233 // verify that registration was updated
@@ -230,7 +240,7 @@ namespace Bootstrapper
230 // 240 //
231 241
232 // write registration 242 // write registration
233 hr = RegistrationSessionBegin(sczCurrentProcess, &registration, &variables, BURN_REGISTRATION_ACTION_OPERATIONS_WRITE_REGISTRATION, BURN_DEPENDENCY_REGISTRATION_ACTION_UNREGISTER, 0, BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS); 243 hr = RegistrationSessionBegin(sczCurrentProcess, &registration, &cache, &variables, BURN_REGISTRATION_ACTION_OPERATIONS_WRITE_REGISTRATION, BURN_DEPENDENCY_REGISTRATION_ACTION_UNREGISTER, 0, BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS);
234 TestThrowOnFailure(hr, L"Failed to register bundle."); 244 TestThrowOnFailure(hr, L"Failed to register bundle.");
235 245
236 // verify that registration was updated 246 // verify that registration was updated
@@ -239,7 +249,7 @@ namespace Bootstrapper
239 Assert::Equal<String^>(String::Concat(L"\"", Path::Combine(cacheDirectory, gcnew String(L"setup.exe")), L"\" /burn.runonce"), (String^)Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(TEST_BUNDLE_ID), nullptr)); 249 Assert::Equal<String^>(String::Concat(L"\"", Path::Combine(cacheDirectory, gcnew String(L"setup.exe")), L"\" /burn.runonce"), (String^)Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(TEST_BUNDLE_ID), nullptr));
240 250
241 // delete registration 251 // delete registration
242 hr = RegistrationSessionEnd(&registration, &variables, &packages, BURN_RESUME_MODE_NONE, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_UNREGISTER, BOOTSTRAPPER_REGISTRATION_TYPE_NONE); 252 hr = RegistrationSessionEnd(&registration, &cache, &variables, &packages, BURN_RESUME_MODE_NONE, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_UNREGISTER, BOOTSTRAPPER_REGISTRATION_TYPE_NONE);
243 TestThrowOnFailure(hr, L"Failed to unregister bundle."); 253 TestThrowOnFailure(hr, L"Failed to unregister bundle.");
244 254
245 // verify that registration was removed 255 // verify that registration was removed
@@ -277,6 +287,8 @@ namespace Bootstrapper
277 BURN_REGISTRATION registration = { }; 287 BURN_REGISTRATION registration = { };
278 BURN_LOGGING logging = { }; 288 BURN_LOGGING logging = { };
279 BURN_PACKAGES packages = { }; 289 BURN_PACKAGES packages = { };
290 BURN_CACHE cache = { };
291 BURN_ENGINE_COMMAND internalCommand = { };
280 String^ cacheDirectory = Path::Combine(Path::Combine(Environment::GetFolderPath(Environment::SpecialFolder::LocalApplicationData), gcnew String(L"Package Cache")), gcnew String(TEST_BUNDLE_ID)); 292 String^ cacheDirectory = Path::Combine(Path::Combine(Environment::GetFolderPath(Environment::SpecialFolder::LocalApplicationData), gcnew String(L"Package Cache")), gcnew String(TEST_BUNDLE_ID));
281 try 293 try
282 { 294 {
@@ -300,13 +312,16 @@ namespace Bootstrapper
300 // load XML document 312 // load XML document
301 LoadBundleXmlHelper(wzDocument, &pixeBundle); 313 LoadBundleXmlHelper(wzDocument, &pixeBundle);
302 314
315 hr = CacheInitialize(&cache, &internalCommand);
316 TestThrowOnFailure(hr, L"Failed initialize cache.");
317
303 hr = VariableInitialize(&variables); 318 hr = VariableInitialize(&variables);
304 TestThrowOnFailure(hr, L"Failed to initialize variables."); 319 TestThrowOnFailure(hr, L"Failed to initialize variables.");
305 320
306 hr = UserExperienceParseFromXml(&userExperience, pixeBundle); 321 hr = UserExperienceParseFromXml(&userExperience, pixeBundle);
307 TestThrowOnFailure(hr, L"Failed to parse UX from XML."); 322 TestThrowOnFailure(hr, L"Failed to parse UX from XML.");
308 323
309 hr = RegistrationParseFromXml(&registration, pixeBundle); 324 hr = RegistrationParseFromXml(&registration, &cache, pixeBundle);
310 TestThrowOnFailure(hr, L"Failed to parse registration from XML."); 325 TestThrowOnFailure(hr, L"Failed to parse registration from XML.");
311 326
312 hr = PlanSetResumeCommand(&registration, BOOTSTRAPPER_ACTION_INSTALL, &command, &logging); 327 hr = PlanSetResumeCommand(&registration, BOOTSTRAPPER_ACTION_INSTALL, &command, &logging);
@@ -320,7 +335,7 @@ namespace Bootstrapper
320 // 335 //
321 336
322 // write registration 337 // write registration
323 hr = RegistrationSessionBegin(sczCurrentProcess, &registration, &variables, BURN_REGISTRATION_ACTION_OPERATIONS_WRITE_REGISTRATION, BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER, 0, BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS); 338 hr = RegistrationSessionBegin(sczCurrentProcess, &registration, &cache, &variables, BURN_REGISTRATION_ACTION_OPERATIONS_WRITE_REGISTRATION, BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER, 0, BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS);
324 TestThrowOnFailure(hr, L"Failed to register bundle."); 339 TestThrowOnFailure(hr, L"Failed to register bundle.");
325 340
326 // verify that registration was created 341 // verify that registration was created
@@ -328,7 +343,7 @@ namespace Bootstrapper
328 Assert::Equal<String^>(String::Concat(L"\"", Path::Combine(cacheDirectory, gcnew String(L"setup.exe")), L"\" /burn.runonce"), (String^)Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(TEST_BUNDLE_ID), nullptr)); 343 Assert::Equal<String^>(String::Concat(L"\"", Path::Combine(cacheDirectory, gcnew String(L"setup.exe")), L"\" /burn.runonce"), (String^)Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(TEST_BUNDLE_ID), nullptr));
329 344
330 // complete registration 345 // complete registration
331 hr = RegistrationSessionEnd(&registration, &variables, &packages, BURN_RESUME_MODE_ARP, BOOTSTRAPPER_APPLY_RESTART_REQUIRED, BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER, BOOTSTRAPPER_REGISTRATION_TYPE_FULL); 346 hr = RegistrationSessionEnd(&registration, &cache, &variables, &packages, BURN_RESUME_MODE_ARP, BOOTSTRAPPER_APPLY_RESTART_REQUIRED, BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER, BOOTSTRAPPER_REGISTRATION_TYPE_FULL);
332 TestThrowOnFailure(hr, L"Failed to unregister bundle."); 347 TestThrowOnFailure(hr, L"Failed to unregister bundle.");
333 348
334 // verify that registration variables were updated 349 // verify that registration variables were updated
@@ -349,7 +364,7 @@ namespace Bootstrapper
349 // 364 //
350 365
351 // delete registration 366 // delete registration
352 hr = RegistrationSessionEnd(&registration, &variables, &packages, BURN_RESUME_MODE_NONE, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_UNREGISTER, BOOTSTRAPPER_REGISTRATION_TYPE_NONE); 367 hr = RegistrationSessionEnd(&registration, &cache, &variables, &packages, BURN_RESUME_MODE_NONE, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_UNREGISTER, BOOTSTRAPPER_REGISTRATION_TYPE_NONE);
353 TestThrowOnFailure(hr, L"Failed to unregister bundle."); 368 TestThrowOnFailure(hr, L"Failed to unregister bundle.");
354 369
355 // verify that registration was removed 370 // verify that registration was removed
@@ -387,6 +402,8 @@ namespace Bootstrapper
387 BURN_REGISTRATION registration = { }; 402 BURN_REGISTRATION registration = { };
388 BURN_LOGGING logging = { }; 403 BURN_LOGGING logging = { };
389 BURN_PACKAGES packages = { }; 404 BURN_PACKAGES packages = { };
405 BURN_CACHE cache = { };
406 BURN_ENGINE_COMMAND internalCommand = { };
390 String^ cacheDirectory = Path::Combine(Path::Combine(Environment::GetFolderPath(Environment::SpecialFolder::LocalApplicationData), gcnew String(L"Package Cache")), gcnew String(TEST_BUNDLE_ID)); 407 String^ cacheDirectory = Path::Combine(Path::Combine(Environment::GetFolderPath(Environment::SpecialFolder::LocalApplicationData), gcnew String(L"Package Cache")), gcnew String(TEST_BUNDLE_ID));
391 try 408 try
392 { 409 {
@@ -412,13 +429,16 @@ namespace Bootstrapper
412 // load XML document 429 // load XML document
413 LoadBundleXmlHelper(wzDocument, &pixeBundle); 430 LoadBundleXmlHelper(wzDocument, &pixeBundle);
414 431
432 hr = CacheInitialize(&cache, &internalCommand);
433 TestThrowOnFailure(hr, L"Failed initialize cache.");
434
415 hr = VariableInitialize(&variables); 435 hr = VariableInitialize(&variables);
416 TestThrowOnFailure(hr, L"Failed to initialize variables."); 436 TestThrowOnFailure(hr, L"Failed to initialize variables.");
417 437
418 hr = UserExperienceParseFromXml(&userExperience, pixeBundle); 438 hr = UserExperienceParseFromXml(&userExperience, pixeBundle);
419 TestThrowOnFailure(hr, L"Failed to parse UX from XML."); 439 TestThrowOnFailure(hr, L"Failed to parse UX from XML.");
420 440
421 hr = RegistrationParseFromXml(&registration, pixeBundle); 441 hr = RegistrationParseFromXml(&registration, &cache, pixeBundle);
422 TestThrowOnFailure(hr, L"Failed to parse registration from XML."); 442 TestThrowOnFailure(hr, L"Failed to parse registration from XML.");
423 443
424 hr = PlanSetResumeCommand(&registration, BOOTSTRAPPER_ACTION_INSTALL, &command, &logging); 444 hr = PlanSetResumeCommand(&registration, BOOTSTRAPPER_ACTION_INSTALL, &command, &logging);
@@ -432,7 +452,7 @@ namespace Bootstrapper
432 // 452 //
433 453
434 // write registration 454 // write registration
435 hr = RegistrationSessionBegin(sczCurrentProcess, &registration, &variables, BURN_REGISTRATION_ACTION_OPERATIONS_WRITE_REGISTRATION, BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER, 0, BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS); 455 hr = RegistrationSessionBegin(sczCurrentProcess, &registration, &cache, &variables, BURN_REGISTRATION_ACTION_OPERATIONS_WRITE_REGISTRATION, BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER, 0, BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS);
436 TestThrowOnFailure(hr, L"Failed to register bundle."); 456 TestThrowOnFailure(hr, L"Failed to register bundle.");
437 457
438 // verify that registration was created 458 // verify that registration was created
@@ -440,7 +460,7 @@ namespace Bootstrapper
440 Assert::Equal<String^>(String::Concat(L"\"", Path::Combine(cacheDirectory, gcnew String(L"setup.exe")), L"\" /burn.runonce"), (String^)Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(TEST_BUNDLE_ID), nullptr)); 460 Assert::Equal<String^>(String::Concat(L"\"", Path::Combine(cacheDirectory, gcnew String(L"setup.exe")), L"\" /burn.runonce"), (String^)Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(TEST_BUNDLE_ID), nullptr));
441 461
442 // finish registration 462 // finish registration
443 hr = RegistrationSessionEnd(&registration, &variables, &packages, BURN_RESUME_MODE_ARP, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER, BOOTSTRAPPER_REGISTRATION_TYPE_FULL); 463 hr = RegistrationSessionEnd(&registration, &cache, &variables, &packages, BURN_RESUME_MODE_ARP, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER, BOOTSTRAPPER_REGISTRATION_TYPE_FULL);
444 TestThrowOnFailure(hr, L"Failed to register bundle."); 464 TestThrowOnFailure(hr, L"Failed to register bundle.");
445 465
446 // verify that registration was updated 466 // verify that registration was updated
@@ -465,7 +485,7 @@ namespace Bootstrapper
465 // 485 //
466 486
467 // write registration 487 // write registration
468 hr = RegistrationSessionBegin(sczCurrentProcess, &registration, &variables, BURN_REGISTRATION_ACTION_OPERATIONS_WRITE_REGISTRATION, BURN_DEPENDENCY_REGISTRATION_ACTION_UNREGISTER, 0, BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS); 488 hr = RegistrationSessionBegin(sczCurrentProcess, &registration, &cache, &variables, BURN_REGISTRATION_ACTION_OPERATIONS_WRITE_REGISTRATION, BURN_DEPENDENCY_REGISTRATION_ACTION_UNREGISTER, 0, BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS);
469 TestThrowOnFailure(hr, L"Failed to register bundle."); 489 TestThrowOnFailure(hr, L"Failed to register bundle.");
470 490
471 // verify that registration was updated 491 // verify that registration was updated
@@ -473,7 +493,7 @@ namespace Bootstrapper
473 Assert::Equal<String^>(String::Concat(L"\"", Path::Combine(cacheDirectory, gcnew String(L"setup.exe")), L"\" /burn.runonce"), (String^)Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(TEST_BUNDLE_ID), nullptr)); 493 Assert::Equal<String^>(String::Concat(L"\"", Path::Combine(cacheDirectory, gcnew String(L"setup.exe")), L"\" /burn.runonce"), (String^)Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(TEST_BUNDLE_ID), nullptr));
474 494
475 // delete registration 495 // delete registration
476 hr = RegistrationSessionEnd(&registration, &variables, &packages, BURN_RESUME_MODE_NONE, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_UNREGISTER, BOOTSTRAPPER_REGISTRATION_TYPE_NONE); 496 hr = RegistrationSessionEnd(&registration, &cache, &variables, &packages, BURN_RESUME_MODE_NONE, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_UNREGISTER, BOOTSTRAPPER_REGISTRATION_TYPE_NONE);
477 TestThrowOnFailure(hr, L"Failed to unregister bundle."); 497 TestThrowOnFailure(hr, L"Failed to unregister bundle.");
478 498
479 // verify that registration was removed 499 // verify that registration was removed
@@ -514,6 +534,8 @@ namespace Bootstrapper
514 BURN_REGISTRATION registration = { }; 534 BURN_REGISTRATION registration = { };
515 BURN_LOGGING logging = { }; 535 BURN_LOGGING logging = { };
516 BURN_PACKAGES packages = { }; 536 BURN_PACKAGES packages = { };
537 BURN_CACHE cache = { };
538 BURN_ENGINE_COMMAND internalCommand = { };
517 BYTE* pbBuffer = NULL; 539 BYTE* pbBuffer = NULL;
518 SIZE_T cbBuffer = 0; 540 SIZE_T cbBuffer = 0;
519 541
@@ -546,6 +568,9 @@ namespace Bootstrapper
546 // load XML document 568 // load XML document
547 LoadBundleXmlHelper(wzDocument, &pixeBundle); 569 LoadBundleXmlHelper(wzDocument, &pixeBundle);
548 570
571 hr = CacheInitialize(&cache, &internalCommand);
572 TestThrowOnFailure(hr, L"Failed initialize cache.");
573
549 hr = VariableInitialize(&variables); 574 hr = VariableInitialize(&variables);
550 TestThrowOnFailure(hr, L"Failed to initialize variables."); 575 TestThrowOnFailure(hr, L"Failed to initialize variables.");
551 576
@@ -555,7 +580,7 @@ namespace Bootstrapper
555 hr = UserExperienceParseFromXml(&userExperience, pixeBundle); 580 hr = UserExperienceParseFromXml(&userExperience, pixeBundle);
556 TestThrowOnFailure(hr, L"Failed to parse UX from XML."); 581 TestThrowOnFailure(hr, L"Failed to parse UX from XML.");
557 582
558 hr = RegistrationParseFromXml(&registration, pixeBundle); 583 hr = RegistrationParseFromXml(&registration, &cache, pixeBundle);
559 TestThrowOnFailure(hr, L"Failed to parse registration from XML."); 584 TestThrowOnFailure(hr, L"Failed to parse registration from XML.");
560 585
561 hr = PlanSetResumeCommand(&registration, BOOTSTRAPPER_ACTION_INSTALL, &command, &logging); 586 hr = PlanSetResumeCommand(&registration, BOOTSTRAPPER_ACTION_INSTALL, &command, &logging);
@@ -565,7 +590,7 @@ namespace Bootstrapper
565 TestThrowOnFailure(hr, L"Failed to get current process path."); 590 TestThrowOnFailure(hr, L"Failed to get current process path.");
566 591
567 // begin session 592 // begin session
568 hr = RegistrationSessionBegin(sczCurrentProcess, &registration, &variables, BURN_REGISTRATION_ACTION_OPERATIONS_WRITE_REGISTRATION, BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER, 0, BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS); 593 hr = RegistrationSessionBegin(sczCurrentProcess, &registration, &cache, &variables, BURN_REGISTRATION_ACTION_OPERATIONS_WRITE_REGISTRATION, BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER, 0, BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS);
569 TestThrowOnFailure(hr, L"Failed to register bundle."); 594 TestThrowOnFailure(hr, L"Failed to register bundle.");
570 595
571 VariableSetNumericHelper(&variables, L"MyBurnVariable1", 42); 596 VariableSetNumericHelper(&variables, L"MyBurnVariable1", 42);
@@ -608,7 +633,7 @@ namespace Bootstrapper
608 NativeAssert::StringEqual(L"42", sczValue); 633 NativeAssert::StringEqual(L"42", sczValue);
609 634
610 // end session 635 // end session
611 hr = RegistrationSessionEnd(&registration, &variables, &packages, BURN_RESUME_MODE_NONE, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_UNREGISTER, BOOTSTRAPPER_REGISTRATION_TYPE_NONE); 636 hr = RegistrationSessionEnd(&registration, &cache, &variables, &packages, BURN_RESUME_MODE_NONE, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_UNREGISTER, BOOTSTRAPPER_REGISTRATION_TYPE_NONE);
612 TestThrowOnFailure(hr, L"Failed to unregister bundle."); 637 TestThrowOnFailure(hr, L"Failed to unregister bundle.");
613 } 638 }
614 finally 639 finally
@@ -643,6 +668,8 @@ namespace Bootstrapper
643 BURN_REGISTRATION registration = { }; 668 BURN_REGISTRATION registration = { };
644 BURN_LOGGING logging = { }; 669 BURN_LOGGING logging = { };
645 BURN_PACKAGES packages = { }; 670 BURN_PACKAGES packages = { };
671 BURN_CACHE cache = { };
672 BURN_ENGINE_COMMAND internalCommand = { };
646 BOOTSTRAPPER_RESUME_TYPE resumeType = BOOTSTRAPPER_RESUME_TYPE_NONE; 673 BOOTSTRAPPER_RESUME_TYPE resumeType = BOOTSTRAPPER_RESUME_TYPE_NONE;
647 BYTE* pbBuffer = NULL; 674 BYTE* pbBuffer = NULL;
648 SIZE_T cbBuffer = 0; 675 SIZE_T cbBuffer = 0;
@@ -674,6 +701,9 @@ namespace Bootstrapper
674 // load XML document 701 // load XML document
675 LoadBundleXmlHelper(wzDocument, &pixeBundle); 702 LoadBundleXmlHelper(wzDocument, &pixeBundle);
676 703
704 hr = CacheInitialize(&cache, &internalCommand);
705 TestThrowOnFailure(hr, L"Failed initialize cache.");
706
677 hr = VariableInitialize(&variables); 707 hr = VariableInitialize(&variables);
678 TestThrowOnFailure(hr, L"Failed to initialize variables."); 708 TestThrowOnFailure(hr, L"Failed to initialize variables.");
679 709
@@ -683,7 +713,7 @@ namespace Bootstrapper
683 hr = UserExperienceParseFromXml(&userExperience, pixeBundle); 713 hr = UserExperienceParseFromXml(&userExperience, pixeBundle);
684 TestThrowOnFailure(hr, L"Failed to parse UX from XML."); 714 TestThrowOnFailure(hr, L"Failed to parse UX from XML.");
685 715
686 hr = RegistrationParseFromXml(&registration, pixeBundle); 716 hr = RegistrationParseFromXml(&registration, &cache, pixeBundle);
687 TestThrowOnFailure(hr, L"Failed to parse registration from XML."); 717 TestThrowOnFailure(hr, L"Failed to parse registration from XML.");
688 718
689 hr = PlanSetResumeCommand(&registration, BOOTSTRAPPER_ACTION_INSTALL, &command, &logging); 719 hr = PlanSetResumeCommand(&registration, BOOTSTRAPPER_ACTION_INSTALL, &command, &logging);
@@ -699,7 +729,7 @@ namespace Bootstrapper
699 Assert::Equal((int)BOOTSTRAPPER_RESUME_TYPE_NONE, (int)resumeType); 729 Assert::Equal((int)BOOTSTRAPPER_RESUME_TYPE_NONE, (int)resumeType);
700 730
701 // begin session 731 // begin session
702 hr = RegistrationSessionBegin(sczCurrentProcess, &registration, &variables, BURN_REGISTRATION_ACTION_OPERATIONS_WRITE_REGISTRATION, BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER, 0, BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS); 732 hr = RegistrationSessionBegin(sczCurrentProcess, &registration, &cache, &variables, BURN_REGISTRATION_ACTION_OPERATIONS_WRITE_REGISTRATION, BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER, 0, BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS);
703 TestThrowOnFailure(hr, L"Failed to register bundle."); 733 TestThrowOnFailure(hr, L"Failed to register bundle.");
704 734
705 VariableSetNumericHelper(&variables, L"MyBurnVariable1", 42); 735 VariableSetNumericHelper(&variables, L"MyBurnVariable1", 42);
@@ -738,7 +768,7 @@ namespace Bootstrapper
738 Assert::Equal((int)BOOTSTRAPPER_RESUME_TYPE_INTERRUPTED, (int)resumeType); 768 Assert::Equal((int)BOOTSTRAPPER_RESUME_TYPE_INTERRUPTED, (int)resumeType);
739 769
740 // suspend session 770 // suspend session
741 hr = RegistrationSessionEnd(&registration, &variables, &packages, BURN_RESUME_MODE_SUSPEND, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER, BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS); 771 hr = RegistrationSessionEnd(&registration, &cache, &variables, &packages, BURN_RESUME_MODE_SUSPEND, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER, BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS);
742 TestThrowOnFailure(hr, L"Failed to suspend session."); 772 TestThrowOnFailure(hr, L"Failed to suspend session.");
743 773
744 // verify that run key was removed 774 // verify that run key was removed
@@ -765,7 +795,7 @@ namespace Bootstrapper
765 Assert::NotEqual((Object^)nullptr, Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(TEST_BUNDLE_ID), nullptr)); 795 Assert::NotEqual((Object^)nullptr, Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(TEST_BUNDLE_ID), nullptr));
766 796
767 // end session 797 // end session
768 hr = RegistrationSessionEnd(&registration, &variables, &packages, BURN_RESUME_MODE_NONE, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_UNREGISTER, BOOTSTRAPPER_REGISTRATION_TYPE_NONE); 798 hr = RegistrationSessionEnd(&registration, &cache, &variables, &packages, BURN_RESUME_MODE_NONE, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_UNREGISTER, BOOTSTRAPPER_REGISTRATION_TYPE_NONE);
769 TestThrowOnFailure(hr, L"Failed to unregister bundle."); 799 TestThrowOnFailure(hr, L"Failed to unregister bundle.");
770 800
771 // read resume type after session 801 // read resume type after session
diff --git a/src/burn/test/BurnUnitTest/precomp.h b/src/burn/test/BurnUnitTest/precomp.h
index 78c44d39..a77dfe32 100644
--- a/src/burn/test/BurnUnitTest/precomp.h
+++ b/src/burn/test/BurnUnitTest/precomp.h
@@ -56,8 +56,8 @@
56#include "plan.h" 56#include "plan.h"
57#include "pipe.h" 57#include "pipe.h"
58#include "logging.h" 58#include "logging.h"
59#include "core.h"
60#include "cache.h" 59#include "cache.h"
60#include "core.h"
61#include "apply.h" 61#include "apply.h"
62#include "exeengine.h" 62#include "exeengine.h"
63#include "msiengine.h" 63#include "msiengine.h"