@joebigelow / wix-1 / commits / 0d873d28

Add plan tests.

Sean Hall committed Nov 15, 2020 at 19:54 UTC 0d873d28c2dd18444afa08b748e91f495ed1cf5c
15 files changed +1125 -34
src/engine/container.cpp
+27 -9
@@ -17,7 +17,6 @@ static HRESULT GetAttachedContainerInfo(
17 // function definitions
18
19 extern "C" HRESULT ContainersParseFromXml(
20 - __in BURN_SECTION* pSection,
20 __in BURN_CONTAINERS* pContainers,
21 __in IXMLDOMNode* pixnBundle
22 )
@@ -128,14 +127,6 @@ extern "C" HRESULT ContainersParseFromXml(
127 ExitOnFailure(hr, "Failed to get @Hash.");
128 }
129
131 - // If the container is attached, make sure the information in the section matches what the
132 - // manifest contained and get the offset to the container.
133 - if (pContainer->fAttached)
134 - {
135 - hr = SectionGetAttachedContainerInfo(pSection, pContainer->dwAttachedIndex, pContainer->type, &pContainer->qwAttachedOffset, &pContainer->qwFileSize, &pContainer->fActuallyAttached);
136 - ExitOnFailure(hr, "Failed to get attached container information.");
137 - }
138 -
130 // prepare next iteration
131 ReleaseNullObject(pixnNode);
132 }
@@ -150,6 +141,33 @@ LExit:
141 return hr;
142 }
143
144 +extern "C" HRESULT ContainersInitialize(
145 + __in BURN_CONTAINERS* pContainers,
146 + __in BURN_SECTION* pSection
147 + )
148 +{
149 + HRESULT hr = S_OK;
150 +
151 + if (pContainers->rgContainers)
152 + {
153 + for (DWORD i = 0; i < pContainers->cContainers; ++i)
154 + {
155 + BURN_CONTAINER* pContainer = &pContainers->rgContainers[i];
156 +
157 + // If the container is attached, make sure the information in the section matches what the
158 + // manifest contained and get the offset to the container.
159 + if (pContainer->fAttached)
160 + {
161 + hr = SectionGetAttachedContainerInfo(pSection, pContainer->dwAttachedIndex, pContainer->type, &pContainer->qwAttachedOffset, &pContainer->qwFileSize, &pContainer->fActuallyAttached);
162 + ExitOnFailure(hr, "Failed to get attached container information.");
163 + }
164 + }
165 + }
166 +
167 +LExit:
168 + return hr;
169 +}
170 +
171 extern "C" void ContainersUninitialize(
172 __in BURN_CONTAINERS* pContainers
173 )
src/engine/container.h
+4 -1
@@ -135,10 +135,13 @@ typedef struct _BURN_CONTAINER_CONTEXT
135 // functions
136
137 HRESULT ContainersParseFromXml(
138 - __in BURN_SECTION* pSection,
138 __in BURN_CONTAINERS* pContainers,
139 __in IXMLDOMNode* pixnBundle
140 );
141 +HRESULT ContainersInitialize(
142 + __in BURN_CONTAINERS* pContainers,
143 + __in BURN_SECTION* pSection
144 + );
145 void ContainersUninitialize(
146 __in BURN_CONTAINERS* pContainers
147 );
src/engine/core.cpp
+4
@@ -96,6 +96,9 @@ extern "C" HRESULT CoreInitialize(
96 hr = ManifestLoadXmlFromBuffer(pbBuffer, cbBuffer, pEngineState);
97 ExitOnFailure(hr, "Failed to load manifest.");
98
99 + hr = ContainersInitialize(&pEngineState->containers, &pEngineState->section);
100 + ExitOnFailure(hr, "Failed to intialize containers.");
101 +
102 // Parse command line.
103 hr = ParseCommandLine(pEngineState->argc, pEngineState->argv, &pEngineState->command, &pEngineState->companionConnection, &pEngineState->embeddedConnection, &pEngineState->variables, &pEngineState->mode, &pEngineState->automaticUpdates, &pEngineState->fDisableSystemRestore, &sczSourceProcessPath, &sczOriginalSource, &pEngineState->fDisableUnelevate, &pEngineState->log.dwAttributes, &pEngineState->log.sczPath, &pEngineState->registration.sczActiveParent, &pEngineState->sczIgnoreDependencies, &pEngineState->registration.sczAncestors, &sczSanitizedCommandLine);
104 ExitOnFailure(hr, "Failed to parse command line.");
@@ -411,6 +414,7 @@ extern "C" HRESULT CorePlan(
414 pEngineState->plan.action = action;
415 pEngineState->plan.wzBundleId = pEngineState->registration.sczId;
416 pEngineState->plan.wzBundleProviderKey = pEngineState->registration.sczId;
417 + pEngineState->plan.fDisableRollback = pEngineState->fDisableRollback;
418
419 hr = PlanSetVariables(action, &pEngineState->variables);
420 ExitOnFailure(hr, "Failed to update action.");
src/engine/logging.cpp
+21
@@ -468,6 +468,27 @@ extern "C" LPCSTR LoggingMsiInstallContext(
468 }
469 }
470
471 +extern "C" LPCWSTR LoggingBurnMsiPropertyToString(
472 + __in BURN_MSI_PROPERTY burnMsiProperty
473 + )
474 +{
475 + switch (burnMsiProperty)
476 + {
477 + case BURN_MSI_PROPERTY_INSTALL:
478 + return BURNMSIINSTALL_PROPERTY_NAME;
479 + case BURN_MSI_PROPERTY_MODIFY:
480 + return BURNMSIMODIFY_PROPERTY_NAME;
481 + case BURN_MSI_PROPERTY_NONE:
482 + return L"(none)";
483 + case BURN_MSI_PROPERTY_REPAIR:
484 + return BURNMSIREPAIR_PROPERTY_NAME;
485 + case BURN_MSI_PROPERTY_UNINSTALL:
486 + return BURNMSIUNINSTALL_PROPERTY_NAME;
487 + default:
488 + return L"Invalid";
489 + }
490 +}
491 +
492 extern "C" LPCSTR LoggingPerMachineToString(
493 __in BOOL fPerMachine
494 )
src/engine/logging.h
+4
@@ -101,6 +101,10 @@ LPCSTR LoggingMsiInstallContext(
101 __in MSIINSTALLCONTEXT context
102 );
103
104 +LPCWSTR LoggingBurnMsiPropertyToString(
105 + __in BURN_MSI_PROPERTY burnMsiProperty
106 + );
107 +
108 LPCSTR LoggingPerMachineToString(
109 __in BOOL fPerMachine
110 );
src/engine/manifest.cpp
+44 -5
@@ -3,8 +3,33 @@
3 #include "precomp.h"
4
5
6 +static HRESULT ParseFromXml(
7 + __in IXMLDOMDocument* pixdDocument,
8 + __in BURN_ENGINE_STATE* pEngineState
9 + );
10 +
11 // function definitions
12
13 +extern "C" HRESULT ManifestLoadXml(
14 + __in LPCWSTR wzDocument,
15 + __in BURN_ENGINE_STATE* pEngineState
16 + )
17 +{
18 + HRESULT hr = S_OK;
19 + IXMLDOMDocument* pixdDocument = NULL;
20 +
21 + // load xml document
22 + hr = XmlLoadDocument(wzDocument, &pixdDocument);
23 + ExitOnFailure(hr, "Failed to load manifest as XML document.");
24 +
25 + hr = ParseFromXml(pixdDocument, pEngineState);
26 +
27 +LExit:
28 + ReleaseObject(pixdDocument);
29 +
30 + return hr;
31 +}
32 +
33 extern "C" HRESULT ManifestLoadXmlFromBuffer(
34 __in_bcount(cbBuffer) BYTE* pbBuffer,
35 __in SIZE_T cbBuffer,
@@ -13,14 +38,29 @@ extern "C" HRESULT ManifestLoadXmlFromBuffer(
38 {
39 HRESULT hr = S_OK;
40 IXMLDOMDocument* pixdDocument = NULL;
16 - IXMLDOMElement* pixeBundle = NULL;
17 - IXMLDOMNode* pixnLog = NULL;
18 - IXMLDOMNode* pixnChain = NULL;
41
42 // load xml document
43 hr = XmlLoadDocumentFromBuffer(pbBuffer, cbBuffer, &pixdDocument);
44 ExitOnFailure(hr, "Failed to load manifest as XML document.");
45
46 + hr = ParseFromXml(pixdDocument, pEngineState);
47 +
48 +LExit:
49 + ReleaseObject(pixdDocument);
50 +
51 + return hr;
52 +}
53 +
54 +static HRESULT ParseFromXml(
55 + __in IXMLDOMDocument* pixdDocument,
56 + __in BURN_ENGINE_STATE* pEngineState
57 + )
58 +{
59 + HRESULT hr = S_OK;
60 + IXMLDOMElement* pixeBundle = NULL;
61 + IXMLDOMNode* pixnLog = NULL;
62 + IXMLDOMNode* pixnChain = NULL;
63 +
64 // get bundle element
65 hr = pixdDocument->get_documentElement(&pixeBundle);
66 ExitOnFailure(hr, "Failed to get bundle element.");
@@ -105,7 +145,7 @@ extern "C" HRESULT ManifestLoadXmlFromBuffer(
145 ExitOnFailure(hr, "Failed to parse update.");
146
147 // parse containers
108 - hr = ContainersParseFromXml(&pEngineState->section, &pEngineState->containers, pixeBundle);
148 + hr = ContainersParseFromXml(&pEngineState->containers, pixeBundle);
149 ExitOnFailure(hr, "Failed to parse containers.");
150
151 // parse payloads
@@ -124,6 +164,5 @@ LExit:
164 ReleaseObject(pixnChain);
165 ReleaseObject(pixnLog);
166 ReleaseObject(pixeBundle);
127 - ReleaseObject(pixdDocument);
167 return hr;
168 }
src/engine/manifest.h
+5
@@ -11,6 +11,11 @@ extern "C" {
11
12 // function declarations
13
14 +HRESULT ManifestLoadXml(
15 + __in LPCWSTR wzDocument,
16 + __in BURN_ENGINE_STATE* pEngineState
17 + );
18 +
19 HRESULT ManifestLoadXmlFromBuffer(
20 __in_bcount(cbBuffer) BYTE* pbBuffer,
21 __in SIZE_T cbBuffer,
src/engine/msiengine.cpp
+1 -4
@@ -4,10 +4,7 @@
4
5
6 // constants
7 -#define BURNMSIINSTALL_PROPERTY_NAME L"BURNMSIINSTALL"
8 -#define BURNMSIMODIFY_PROPERTY_NAME L"BURNMSIMODIFY"
9 -#define BURNMSIREPAIR_PROPERTY_NAME L"BURNMSIREPAIR"
10 -#define BURNMSIUNINSTALL_PROPERTY_NAME L"BURNMSIUNINSTALL"
7 +
8
9 // structs
10
src/engine/msiengine.h
+6
@@ -1,6 +1,12 @@
1 #pragma once
2 // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
3
4 +// constants
5 +#define BURNMSIINSTALL_PROPERTY_NAME L"BURNMSIINSTALL"
6 +#define BURNMSIMODIFY_PROPERTY_NAME L"BURNMSIMODIFY"
7 +#define BURNMSIREPAIR_PROPERTY_NAME L"BURNMSIREPAIR"
8 +#define BURNMSIUNINSTALL_PROPERTY_NAME L"BURNMSIUNINSTALL"
9 +
10
11 #if defined(__cplusplus)
12 extern "C" {
src/engine/plan.cpp
+19 -15
@@ -74,7 +74,9 @@ static BOOL AlreadyPlannedCachePackage(
74 __in_z LPCWSTR wzPackageId,
75 __out HANDLE* phSyncpointEvent
76 );
77 -static DWORD GetNextCheckpointId();
77 +static DWORD GetNextCheckpointId(
78 + __in BURN_PLAN* pPlan
79 + );
80 static HRESULT AppendCacheAction(
81 __in BURN_PLAN* pPlan,
82 __out BURN_CACHE_ACTION** ppCacheAction
@@ -1621,7 +1623,7 @@ extern "C" HRESULT PlanExecuteCheckpoint(
1623 {
1624 HRESULT hr = S_OK;
1625 BURN_EXECUTE_ACTION* pAction = NULL;
1624 - DWORD dwCheckpointId = GetNextCheckpointId();
1626 + DWORD dwCheckpointId = GetNextCheckpointId(pPlan);
1627
1628 // execute checkpoint
1629 hr = PlanAppendExecuteAction(pPlan, &pAction);
@@ -1808,7 +1810,7 @@ extern "C" HRESULT PlanRollbackBoundaryComplete(
1810 DWORD dwCheckpointId = 0;
1811
1812 // Add checkpoints.
1811 - dwCheckpointId = GetNextCheckpointId();
1813 + dwCheckpointId = GetNextCheckpointId(pPlan);
1814
1815 hr = PlanAppendExecuteAction(pPlan, &pExecuteAction);
1816 ExitOnFailure(hr, "Failed to append execute action.");
@@ -2095,7 +2097,7 @@ static HRESULT AddCachePackageHelper(
2097 // Cache checkpoints happen before the package is cached because downloading packages'
2098 // payloads will not roll themselves back the way installation packages rollback on
2099 // failure automatically.
2098 - dwCheckpoint = GetNextCheckpointId();
2100 + dwCheckpoint = GetNextCheckpointId(pPlan);
2101
2102 hr = AppendCacheAction(pPlan, &pCacheAction);
2103 ExitOnFailure(hr, "Failed to append package start action.");
@@ -2234,10 +2236,11 @@ static BOOL AlreadyPlannedCachePackage(
2236 return fPlanned;
2237 }
2238
2237 -static DWORD GetNextCheckpointId()
2239 +static DWORD GetNextCheckpointId(
2240 + __in BURN_PLAN* pPlan
2241 + )
2242 {
2239 - static DWORD dwCounter = 0;
2240 - return ++dwCounter;
2243 + return ++pPlan->dwNextCheckpointId;
2244 }
2245
2246 static HRESULT AppendCacheAction(
@@ -3039,11 +3042,11 @@ static void CacheActionLog(
3042 break;
3043
3044 case BURN_CACHE_ACTION_TYPE_SIGNAL_SYNCPOINT:
3042 - LogStringLine(REPORT_STANDARD, "%ls action[%u]: SIGNAL_SYNCPOINT event handle: 0x%x, skip until retried: %hs", wzBase, iAction, pAction->syncpoint.hEvent, LoggingBoolToString(pAction->fSkipUntilRetried));
3045 + LogStringLine(REPORT_STANDARD, "%ls action[%u]: SIGNAL_SYNCPOINT event handle: 0x%p, skip until retried: %hs", wzBase, iAction, pAction->syncpoint.hEvent, LoggingBoolToString(pAction->fSkipUntilRetried));
3046 break;
3047
3048 case BURN_CACHE_ACTION_TYPE_TRANSACTION_BOUNDARY:
3046 - LogStringLine(REPORT_STANDARD, "%ls action[%u]: TRANSACTION_BOUNDARY id: %ls, event handle: 0x%x, vital: %ls, transaction: %ls", wzBase, iAction, pAction->rollbackBoundary.pRollbackBoundary->sczId, pAction->rollbackBoundary.hEvent, pAction->rollbackBoundary.pRollbackBoundary->fVital ? L"yes" : L"no", pAction->rollbackBoundary.pRollbackBoundary->fTransaction ? L"yes" : L"no");
3049 + LogStringLine(REPORT_STANDARD, "%ls action[%u]: TRANSACTION_BOUNDARY id: %ls, event handle: 0x%p, vital: %ls, transaction: %ls", wzBase, iAction, pAction->rollbackBoundary.pRollbackBoundary->sczId, pAction->rollbackBoundary.hEvent, pAction->rollbackBoundary.pRollbackBoundary->fVital ? L"yes" : L"no", pAction->rollbackBoundary.pRollbackBoundary->fTransaction ? L"yes" : L"no");
3050 break;
3051
3052 default:
@@ -3066,11 +3069,11 @@ static void ExecuteActionLog(
3069 break;
3070
3071 case BURN_EXECUTE_ACTION_TYPE_PACKAGE_PROVIDER:
3069 - LogStringLine(REPORT_STANDARD, "%ls action[%u]: PACKAGE_PROVIDER package id: %ls, action: %u", wzBase, iAction, pAction->packageProvider.pPackage->sczId, pAction->packageProvider.action);
3072 + LogStringLine(REPORT_STANDARD, "%ls action[%u]: PACKAGE_PROVIDER package id: %ls, action: %hs", wzBase, iAction, pAction->packageProvider.pPackage->sczId, LoggingDependencyActionToString(pAction->packageProvider.action));
3073 break;
3074
3075 case BURN_EXECUTE_ACTION_TYPE_PACKAGE_DEPENDENCY:
3073 - LogStringLine(REPORT_STANDARD, "%ls action[%u]: PACKAGE_DEPENDENCY package id: %ls, bundle provider key: %ls, action: %u", wzBase, iAction, pAction->packageDependency.pPackage->sczId, pAction->packageDependency.sczBundleProviderKey, pAction->packageDependency.action);
3076 + LogStringLine(REPORT_STANDARD, "%ls action[%u]: PACKAGE_DEPENDENCY package id: %ls, bundle provider key: %ls, action: %hs", wzBase, iAction, pAction->packageDependency.pPackage->sczId, pAction->packageDependency.sczBundleProviderKey, LoggingDependencyActionToString(pAction->packageDependency.action));
3077 break;
3078
3079 case BURN_EXECUTE_ACTION_TYPE_EXE_PACKAGE:
@@ -3078,15 +3081,15 @@ static void ExecuteActionLog(
3081 break;
3082
3083 case BURN_EXECUTE_ACTION_TYPE_MSI_PACKAGE:
3081 - LogStringLine(REPORT_STANDARD, "%ls action[%u]: MSI_PACKAGE package id: %ls, action: %hs, action msi property: %u, ui level: %u, disable externaluihandler: %ls, log path: %ls, logging attrib: %u", wzBase, iAction, pAction->msiPackage.pPackage->sczId, LoggingActionStateToString(pAction->msiPackage.action), pAction->msiPackage.actionMsiProperty, pAction->msiPackage.uiLevel, pAction->msiPackage.fDisableExternalUiHandler ? L"yes" : L"no", pAction->msiPackage.sczLogPath, pAction->msiPackage.dwLoggingAttributes);
3084 + LogStringLine(REPORT_STANDARD, "%ls action[%u]: MSI_PACKAGE package id: %ls, action: %hs, action msi property: %ls, ui level: %u, disable externaluihandler: %ls, log path: %ls, logging attrib: %u", wzBase, iAction, pAction->msiPackage.pPackage->sczId, LoggingActionStateToString(pAction->msiPackage.action), LoggingBurnMsiPropertyToString(pAction->msiPackage.actionMsiProperty), pAction->msiPackage.uiLevel, pAction->msiPackage.fDisableExternalUiHandler ? L"yes" : L"no", pAction->msiPackage.sczLogPath, pAction->msiPackage.dwLoggingAttributes);
3085 for (DWORD j = 0; j < pAction->msiPackage.cPatches; ++j)
3086 {
3084 - LogStringLine(REPORT_STANDARD, " Patch[%u]: order: %u, msp package id: %ls", j, pAction->msiPackage.rgOrderedPatches->dwOrder, pAction->msiPackage.rgOrderedPatches[j].dwOrder, pAction->msiPackage.rgOrderedPatches[j].pPackage->sczId);
3087 + LogStringLine(REPORT_STANDARD, " Patch[%u]: order: %u, msp package id: %ls", j, pAction->msiPackage.rgOrderedPatches[j].dwOrder, pAction->msiPackage.rgOrderedPatches[j].pPackage->sczId);
3088 }
3089 break;
3090
3091 case BURN_EXECUTE_ACTION_TYPE_MSP_TARGET:
3089 - LogStringLine(REPORT_STANDARD, "%ls action[%u]: MSP_TARGET package id: %ls, action: %hs, target product code: %ls, target per-machine: %ls, action msi property: %u, ui level: %u, disable externaluihandler: %ls, log path: %ls", wzBase, iAction, pAction->mspTarget.pPackage->sczId, LoggingActionStateToString(pAction->mspTarget.action), pAction->mspTarget.sczTargetProductCode, pAction->mspTarget.fPerMachineTarget ? L"yes" : L"no", pAction->mspTarget.actionMsiProperty, pAction->mspTarget.uiLevel, pAction->mspTarget.fDisableExternalUiHandler ? L"yes" : L"no", pAction->mspTarget.sczLogPath);
3092 + LogStringLine(REPORT_STANDARD, "%ls action[%u]: MSP_TARGET package id: %ls, action: %hs, target product code: %ls, target per-machine: %ls, action msi property: %ls, ui level: %u, disable externaluihandler: %ls, log path: %ls", wzBase, iAction, pAction->mspTarget.pPackage->sczId, LoggingActionStateToString(pAction->mspTarget.action), pAction->mspTarget.sczTargetProductCode, pAction->mspTarget.fPerMachineTarget ? L"yes" : L"no", LoggingBurnMsiPropertyToString(pAction->mspTarget.actionMsiProperty), pAction->mspTarget.uiLevel, pAction->mspTarget.fDisableExternalUiHandler ? L"yes" : L"no", pAction->mspTarget.sczLogPath);
3093 for (DWORD j = 0; j < pAction->mspTarget.cOrderedPatches; ++j)
3094 {
3095 LogStringLine(REPORT_STANDARD, " Patch[%u]: order: %u, msp package id: %ls", j, pAction->mspTarget.rgOrderedPatches[j].dwOrder, pAction->mspTarget.rgOrderedPatches[j].pPackage->sczId);
@@ -3106,7 +3109,7 @@ static void ExecuteActionLog(
3109 break;
3110
3111 case BURN_EXECUTE_ACTION_TYPE_WAIT_SYNCPOINT:
3109 - LogStringLine(REPORT_STANDARD, "%ls action[%u]: WAIT_SYNCPOINT event handle: 0x%x", wzBase, iAction, pAction->syncpoint.hEvent);
3112 + LogStringLine(REPORT_STANDARD, "%ls action[%u]: WAIT_SYNCPOINT event handle: 0x%p", wzBase, iAction, pAction->syncpoint.hEvent);
3113 break;
3114
3115 case BURN_EXECUTE_ACTION_TYPE_UNCACHE_PACKAGE:
@@ -3131,6 +3134,7 @@ extern "C" void PlanDump(
3134
3135 LogStringLine(REPORT_STANDARD, "Plan action: %hs", LoggingBurnActionToString(pPlan->action));
3136 LogStringLine(REPORT_STANDARD, " per-machine: %hs", LoggingTrueFalseToString(pPlan->fPerMachine));
3137 + LogStringLine(REPORT_STANDARD, " disable-rollback: %hs", LoggingTrueFalseToString(pPlan->fDisableRollback));
3138 LogStringLine(REPORT_STANDARD, " keep registration by default: %hs", LoggingTrueFalseToString(pPlan->fKeepRegistrationDefault));
3139 LogStringLine(REPORT_STANDARD, " estimated size: %llu", pPlan->qwEstimatedSize);
3140
src/engine/plan.h
+3
@@ -325,6 +325,7 @@ typedef struct _BURN_PLAN
325 DWORD dwRegistrationOperations;
326 BOOL fKeepRegistrationDefault;
327 BOOL fDisallowRemoval;
328 + BOOL fDisableRollback;
329
330 DWORD64 qwCacheSizeTotal;
331
@@ -366,6 +367,8 @@ typedef struct _BURN_PLAN
367 BURN_CACHE_PAYLOAD_PROGRESS* rgPayloadProgress;
368 DWORD cPayloadProgress;
369 STRINGDICT_HANDLE shPayloadProgress;
370 +
371 + DWORD dwNextCheckpointId;
372 } BURN_PLAN;
373
374
src/test/BurnUnitTest/BurnUnitTest.vcxproj
+1
@@ -36,6 +36,7 @@
36 <ClCompile Include="ElevationTest.cpp" />
37 <ClCompile Include="ManifestHelpers.cpp" />
38 <ClCompile Include="ManifestTest.cpp" />
39 + <ClCompile Include="PlanTest.cpp" />
40 <ClCompile Include="precomp.cpp">
41 <PrecompiledHeader>Create</PrecompiledHeader>
42 <!-- Warnings from referencing netstandard dlls -->
src/test/BurnUnitTest/BurnUnitTest.vcxproj.filters
+3
@@ -30,6 +30,9 @@
30 <ClCompile Include="ManifestTest.cpp">
31 <Filter>Source Files</Filter>
32 </ClCompile>
33 + <ClCompile Include="PlanTest.cpp">
34 + <Filter>Source Files</Filter>
35 + </ClCompile>
36 <ClCompile Include="precomp.cpp">
37 <Filter>Source Files</Filter>
38 </ClCompile>
src/test/BurnUnitTest/PlanTest.cpp new
+982
@@ -0,0 +1,982 @@
1 +// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2 +
3 +#include "precomp.h"
4 +
5 +static HRESULT WINAPI PlanTestBAProc(
6 + __in BOOTSTRAPPER_APPLICATION_MESSAGE message,
7 + __in const LPVOID pvArgs,
8 + __inout LPVOID pvResults,
9 + __in_opt LPVOID pvContext
10 + );
11 +
12 +static LPCWSTR wzMsiTransactionManifest =
13 + L"<Bundle>"
14 + L" <Log PathVariable='WixBundleLog' Prefix='~manual_BundleA' Extension='log' />"
15 + L" <RelatedBundle Id='{90ED10D5-B187-4470-B498-05D80DAB729A}' Action='Upgrade' />"
16 + L" <Variable Id='TestName' Value='MsiTransaction' Type='string' Hidden='no' Persisted='no' />"
17 + L" <Variable Id='WixBundleName' Hidden='no' Persisted='yes' />"
18 + L" <Variable Id='WixBundleOriginalSource' Hidden='no' Persisted='yes' />"
19 + L" <Variable Id='WixBundleOriginalSourceFolder' Hidden='no' Persisted='yes' />"
20 + L" <Variable Id='WixBundleLastUsedSource' Hidden='no' Persisted='yes' />"
21 + L" <UX>"
22 + L" <Payload Id='WixStandardBootstrapperApplication.RtfLicense' FilePath='wixstdba.dll' FileSize='1312768' Hash='B331BC5C819F019981D2524C48CC370DE2BFE9F8' Packaging='embedded' SourcePath='u0' />"
23 + L" <Payload Id='payF3wjO.aj6M8ftq9wrfYB1N4aw4g' FilePath='thm.xml' FileSize='8048' Hash='A712A9E1427A4EE1D0B68343A54019A3FC9967CB' Packaging='embedded' SourcePath='u1' />"
24 + L" <Payload Id='payViPRdlZD7MPIBgwmX2Hv5C6oKt4' FilePath='thm.wxl' FileSize='3926' Hash='B88FAB9B6C2B52FBE017F91B0915781C6B76058E' Packaging='embedded' SourcePath='u2' />"
25 + L" <Payload Id='payjqSD44latbvJnf4vAQuVMUST73A' FilePath='logo.png' FileSize='852' Hash='239F10674BF6022854C1F1BF7C91955BDE34D3E4' Packaging='embedded' SourcePath='u3' />"
26 + L" <Payload Id='pay60yHh1x6HODo4M_38Pud7jhl2Ig' FilePath='license.rtf' FileSize='4908' Hash='383034848F8CC4F3C8E795CC0F4D716A285E9465' Packaging='embedded' SourcePath='u4' />"
27 + L" <Payload Id='uxTxMXPVMXwQrPTMIGa5WGt93w0Ns' FilePath='BootstrapperApplicationData.xml' FileSize='6870' Hash='5302818DB5BD565463715D3C7099FE5123474476' Packaging='embedded' SourcePath='u5' />"
28 + L" </UX>"
29 + L" <Container Id='WixAttachedContainer' FileSize='9198' Hash='D932DEBC15B7EC41B3EB64DD075A1C7148C2BD6D' FilePath='BundleA.exe' AttachedIndex='1' Attached='yes' Primary='yes' />"
30 + L" <Payload Id='PackageA' FilePath='~manual_PackageA.msi' FileSize='32768' Hash='4011C700186B4C162B2A50D981C895108AD67EBB' Packaging='embedded' SourcePath='a0' Container='WixAttachedContainer' />"
31 + L" <Payload Id='PackageB' FilePath='~manual_PackageB.msi' FileSize='32768' Hash='0DA2766C6B5D2253A37675D89E6F15A70EDD18EB' Packaging='embedded' SourcePath='a1' Container='WixAttachedContainer' />"
32 + L" <Payload Id='PackageC' FilePath='~manual_PackageC.msi' FileSize='32768' Hash='B5E1B37DCF08B7D88F2EB45D063513BDE052E5E4' Packaging='embedded' SourcePath='a2' Container='WixAttachedContainer' />"
33 + L" <Payload Id='cab1QmlL013Hqv_44W64R0cvnHn_2c' FilePath='cab1.cab' FileSize='973' Hash='7A51FCEDBCD0A697A94F0C47A89BDD5EFCC0CB4B' Packaging='embedded' SourcePath='a3' Container='WixAttachedContainer' />"
34 + L" <Payload Id='cabQH1Sgh7w2K8tLIftUaaWVhMWt0s' FilePath='cab1.cab' FileSize='985' Hash='32EFE9983CB1FF0905A3725B901D0BBD5334E616' Packaging='embedded' SourcePath='a4' Container='WixAttachedContainer' />"
35 + L" <Payload Id='cabRT8kdm93olnEAQB2GSO3u0400VI' FilePath='cab1.cab' FileSize='971' Hash='1D20203378E2AEC4AD728F7849A5CC7F6E7D094D' Packaging='embedded' SourcePath='a5' Container='WixAttachedContainer' />"
36 + L" <RollbackBoundary Id='WixDefaultBoundary' Vital='yes' Transaction='no' />"
37 + L" <RollbackBoundary Id='rbaOCA08D8ky7uBOK71_6FWz1K3TuQ' Vital='yes' Transaction='yes' />"
38 + L" <Registration Id='{c096190a-8bf3-4342-a1d2-94ea9cb853d6}' ExecutableName='BundleA.exe' PerMachine='yes' Tag='' Version='1.0.0.0' ProviderKey='{c096190a-8bf3-4342-a1d2-94ea9cb853d6}'>"
39 + L" <Arp Register='yes' DisplayName='~manual - Bundle A' DisplayVersion='1.0.0.0' />"
40 + L" </Registration>"
41 + L" <Chain>"
42 + L" <MsiPackage Id='PackageA' Cache='yes' CacheId='{196E43EA-EF92-4FF8-B9AC-A0FD0D225BB4}v1.0.0.0' InstallSize='1634' Size='33741' PerMachine='yes' Permanent='no' Vital='yes' RollbackBoundaryForward='WixDefaultBoundary' RollbackBoundaryBackward='WixDefaultBoundary' LogPathVariable='WixBundleLog_PackageA' RollbackLogPathVariable='WixBundleRollbackLog_PackageA' ProductCode='{196E43EA-EF92-4FF8-B9AC-A0FD0D225BB4}' Language='1033' Version='1.0.0.0' UpgradeCode='{5B6AB1CF-5DD5-4BB1-851A-9C7E789BCDC7}'>"
43 + L" <MsiProperty Id='ARPSYSTEMCOMPONENT' Value='1' />"
44 + L" <MsiProperty Id='MSIFASTINSTALL' Value='7' />"
45 + L" <Provides Key='{196E43EA-EF92-4FF8-B9AC-A0FD0D225BB4}' DisplayName='~manual - A' />"
46 + L" <RelatedPackage Id='{5B6AB1CF-5DD5-4BB1-851A-9C7E789BCDC7}' MaxVersion='1.0.0.0' MaxInclusive='no' OnlyDetect='no' LangInclusive='yes'>"
47 + L" <Language Id='1033' />"
48 + L" </RelatedPackage>"
49 + L" <RelatedPackage Id='{5B6AB1CF-5DD5-4BB1-851A-9C7E789BCDC7}' MinVersion='1.0.0.0' MinInclusive='no' OnlyDetect='yes' LangInclusive='yes'>"
50 + L" <Language Id='1033' />"
51 + L" </RelatedPackage>"
52 + L" <PayloadRef Id='PackageA' />"
53 + L" <PayloadRef Id='cab1QmlL013Hqv_44W64R0cvnHn_2c' />"
54 + L" </MsiPackage>"
55 + L" <MsiPackage Id='PackageB' Cache='yes' CacheId='{388E4963-13AD-4EE7-B907-AA8888F50E54}v1.0.0.0' InstallSize='1665' Size='33753' PerMachine='yes' Permanent='no' Vital='yes' RollbackBoundaryForward='rbaOCA08D8ky7uBOK71_6FWz1K3TuQ' LogPathVariable='WixBundleLog_PackageB' RollbackLogPathVariable='WixBundleRollbackLog_PackageB' ProductCode='{388E4963-13AD-4EE7-B907-AA8888F50E54}' Language='1033' Version='1.0.0.0' UpgradeCode='{04ABCDBB-2C66-4338-9B1D-DE2AC9B0D1C2}'>"
56 + L" <MsiProperty Id='ARPSYSTEMCOMPONENT' Value='1' />"
57 + L" <MsiProperty Id='MSIFASTINSTALL' Value='7' />"
58 + L" <Provides Key='{388E4963-13AD-4EE7-B907-AA8888F50E54}' DisplayName='~manual - B' />"
59 + L" <RelatedPackage Id='{04ABCDBB-2C66-4338-9B1D-DE2AC9B0D1C2}' MaxVersion='1.0.0.0' MaxInclusive='yes' OnlyDetect='no' LangInclusive='yes'>"
60 + L" <Language Id='1033' />"
61 + L" </RelatedPackage>"
62 + L" <RelatedPackage Id='{04ABCDBB-2C66-4338-9B1D-DE2AC9B0D1C2}' MinVersion='1.0.0.0' MinInclusive='no' OnlyDetect='yes' LangInclusive='yes'>"
63 + L" <Language Id='1033' />"
64 + L" </RelatedPackage>"
65 + L" <PayloadRef Id='PackageB' />"
66 + L" <PayloadRef Id='cabQH1Sgh7w2K8tLIftUaaWVhMWt0s' />"
67 + L" </MsiPackage>"
68 + L" <MsiPackage Id='PackageC' Cache='yes' CacheId='{BE27CF2B-9E5F-4500-BAE3-5E0E522FB962}v1.0.0.0' InstallSize='1634' Size='33739' PerMachine='yes' Permanent='no' Vital='yes' RollbackBoundaryBackward='rbaOCA08D8ky7uBOK71_6FWz1K3TuQ' LogPathVariable='WixBundleLog_PackageC' RollbackLogPathVariable='WixBundleRollbackLog_PackageC' ProductCode='{BE27CF2B-9E5F-4500-BAE3-5E0E522FB962}' Language='1033' Version='1.0.0.0' UpgradeCode='{3F8C1522-741D-499E-9137-7E192405E01A}'>"
69 + L" <MsiProperty Id='ARPSYSTEMCOMPONENT' Value='1' />"
70 + L" <MsiProperty Id='MSIFASTINSTALL' Value='7' />"
71 + L" <Provides Key='{BE27CF2B-9E5F-4500-BAE3-5E0E522FB962}' DisplayName='~manual - C' />"
72 + L" <RelatedPackage Id='{3F8C1522-741D-499E-9137-7E192405E01A}' MaxVersion='1.0.0.0' MaxInclusive='no' OnlyDetect='no' LangInclusive='yes'>"
73 + L" <Language Id='1033' />"
74 + L" </RelatedPackage>"
75 + L" <RelatedPackage Id='{3F8C1522-741D-499E-9137-7E192405E01A}' MinVersion='1.0.0.0' MinInclusive='no' OnlyDetect='yes' LangInclusive='yes'>"
76 + L" <Language Id='1033' />"
77 + L" </RelatedPackage>"
78 + L" <PayloadRef Id='PackageC' />"
79 + L" <PayloadRef Id='cabRT8kdm93olnEAQB2GSO3u0400VI' />"
80 + L" </MsiPackage>"
81 + L" </Chain>"
82 + L"</Bundle>";
83 +
84 +static LPCWSTR wzSingleMsiManifest =
85 + L"<Bundle>"
86 + L" <Log PathVariable='WixBundleLog' Prefix='~manual_BundleB' Extension='log' />"
87 + L" <RelatedBundle Id='{CAAD4202-2097-4065-82BB-83F9F3FF61CE}' Action='Upgrade' />"
88 + L" <Variable Id='TestName' Value='SingleMsi' Type='string' Hidden='no' Persisted='no' />"
89 + L" <Variable Id='WixBundleName' Hidden='no' Persisted='yes' />"
90 + L" <Variable Id='WixBundleOriginalSource' Hidden='no' Persisted='yes' />"
91 + L" <Variable Id='WixBundleOriginalSourceFolder' Hidden='no' Persisted='yes' />"
92 + L" <Variable Id='WixBundleLastUsedSource' Hidden='no' Persisted='yes' />"
93 + L" <UX>"
94 + L" <Payload Id='WixStandardBootstrapperApplication.RtfLicense' FilePath='wixstdba.dll' FileSize='1312768' Hash='B331BC5C819F019981D2524C48CC370DE2BFE9F8' Packaging='embedded' SourcePath='u0' />"
95 + L" <Payload Id='payF3wjO.aj6M8ftq9wrfYB1N4aw4g' FilePath='thm.xml' FileSize='8048' Hash='A712A9E1427A4EE1D0B68343A54019A3FC9967CB' Packaging='embedded' SourcePath='u1' />"
96 + L" <Payload Id='payViPRdlZD7MPIBgwmX2Hv5C6oKt4' FilePath='thm.wxl' FileSize='3926' Hash='B88FAB9B6C2B52FBE017F91B0915781C6B76058E' Packaging='embedded' SourcePath='u2' />"
97 + L" <Payload Id='payjqSD44latbvJnf4vAQuVMUST73A' FilePath='logo.png' FileSize='852' Hash='239F10674BF6022854C1F1BF7C91955BDE34D3E4' Packaging='embedded' SourcePath='u3' />"
98 + L" <Payload Id='pay60yHh1x6HODo4M_38Pud7jhl2Ig' FilePath='license.rtf' FileSize='4908' Hash='383034848F8CC4F3C8E795CC0F4D716A285E9465' Packaging='embedded' SourcePath='u4' />"
99 + L" <Payload Id='uxTxMXPVMXwQrPTMIGa5WGt93w0Ns' FilePath='BootstrapperApplicationData.xml' FileSize='3854' Hash='2807D2AB42585125D18B7DCE49DB6454A1AFC367' Packaging='embedded' SourcePath='u5' />"
100 + L" </UX>"
101 + L" <Container Id='WixAttachedContainer' FileSize='6486' Hash='944E8702BD8DCDB1E41C47033115B690CED42033' FilePath='BundleC.exe' AttachedIndex='1' Attached='yes' Primary='yes' />"
102 + L" <Payload Id='PackageE' FilePath='~manual_PackageE.msi' FileSize='32768' Hash='EB5B931CFCD724391A014A93A9B41037AEE57EC5' Packaging='embedded' SourcePath='a0' Container='WixAttachedContainer' />"
103 + L" <Payload Id='cabkAPka1fWa1PyiVdoVPuoB6Qvs3k' FilePath='cab1.cab' FileSize='973' Hash='A0D42DE329CFCF0AF60D5FFA902C7E53DD5F3B4F' Packaging='embedded' SourcePath='a1' Container='WixAttachedContainer' />"
104 + L" <RollbackBoundary Id='WixDefaultBoundary' Vital='yes' Transaction='no' />"
105 + L" <Registration Id='{4a04385a-0081-44ba-acd1-9e4e95cfc97f}' ExecutableName='BundleC.exe' PerMachine='yes' Tag='' Version='1.0.0.0' ProviderKey='{4a04385a-0081-44ba-acd1-9e4e95cfc97f}'>"
106 + L" <Arp Register='yes' DisplayName='~manual - Bundle B' DisplayVersion='1.0.0.0' />"
107 + L" </Registration>"
108 + L" <Chain>"
109 + L" <MsiPackage Id='PackageE' Cache='yes' CacheId='{284F56B6-B6C7-404A-B9B5-78F63BF79494}v1.0.0.0' InstallSize='1640' Size='33741' PerMachine='yes' Permanent='no' Vital='yes' RollbackBoundaryForward='WixDefaultBoundary' RollbackBoundaryBackward='WixDefaultBoundary' LogPathVariable='WixBundleLog_PackageE' RollbackLogPathVariable='WixBundleRollbackLog_PackageE' ProductCode='{284F56B6-B6C7-404A-B9B5-78F63BF79494}' Language='1033' Version='1.0.0.0' UpgradeCode='{04ABCDBB-2C66-4338-9B1D-DE2AC9B0D1C2}'>"
110 + L" <MsiProperty Id='ARPSYSTEMCOMPONENT' Value='1' />"
111 + L" <MsiProperty Id='MSIFASTINSTALL' Value='7' />"
112 + L" <Provides Key='{284F56B6-B6C7-404A-B9B5-78F63BF79494}' DisplayName='~manual - E' />"
113 + L" <RelatedPackage Id='{04ABCDBB-2C66-4338-9B1D-DE2AC9B0D1C2}' MaxVersion='1.0.0.0' MaxInclusive='no' OnlyDetect='no' LangInclusive='yes'>"
114 + L" <Language Id='1033' />"
115 + L" </RelatedPackage>"
116 + L" <RelatedPackage Id='{04ABCDBB-2C66-4338-9B1D-DE2AC9B0D1C2}' MinVersion='1.0.0.0' MinInclusive='no' OnlyDetect='yes' LangInclusive='yes'>"
117 + L" <Language Id='1033' />"
118 + L" </RelatedPackage>"
119 + L" <PayloadRef Id='PackageE' />"
120 + L" <PayloadRef Id='cabkAPka1fWa1PyiVdoVPuoB6Qvs3k' />"
121 + L" </MsiPackage>"
122 + L" </Chain>"
123 + L"</Bundle>";
124 +
125 +namespace Microsoft
126 +{
127 +namespace Tools
128 +{
129 +namespace WindowsInstallerXml
130 +{
131 +namespace Test
132 +{
133 +namespace Bootstrapper
134 +{
135 + using namespace System;
136 + using namespace Xunit;
137 +
138 + public ref class PlanTest : BurnUnitTest
139 + {
140 + public:
141 + PlanTest(BurnTestFixture^ fixture) : BurnUnitTest(fixture)
142 + {
143 + }
144 +
145 + [Fact]
146 + void MsiTransactionInstallTest()
147 + {
148 + HRESULT hr = S_OK;
149 + BURN_ENGINE_STATE engineState = { };
150 + BURN_ENGINE_STATE* pEngineState = &engineState;
151 + BURN_PLAN* pPlan = &engineState.plan;
152 +
153 + InitializeEngineStateForCorePlan(wzMsiTransactionManifest, pEngineState);
154 + DetectPackagesAsAbsent(pEngineState);
155 + DetectUpgradeBundle(pEngineState, L"{FD9920AD-DBCA-4C6C-8CD5-B47431CE8D21}", L"1.0.0.0");
156 +
157 + hr = CorePlan(pEngineState, BOOTSTRAPPER_ACTION_INSTALL);
158 + NativeAssert::Succeeded(hr, "CorePlan failed");
159 +
160 + Assert::Equal<DWORD>(BOOTSTRAPPER_ACTION_INSTALL, pPlan->action);
161 + Assert::Equal<BOOL>(TRUE, pPlan->fPerMachine);
162 + Assert::Equal<BOOL>(FALSE, pPlan->fDisableRollback);
163 + Assert::Equal<BOOL>(FALSE, pPlan->fKeepRegistrationDefault);
164 +
165 + BOOL fRollback = FALSE;
166 + DWORD dwIndex = 0;
167 + DWORD dwPackageStart = 0;
168 + ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 1);
169 + dwPackageStart = ValidateCachePackageStart(pPlan, fRollback, dwIndex++, L"PackageA", 6, 2, 33741, FALSE);
170 + ValidateCacheAcquireContainer(pPlan, fRollback, dwIndex++, L"WixAttachedContainer", FALSE);
171 + ValidateCacheExtractContainer(pPlan, fRollback, dwIndex++, L"WixAttachedContainer", FALSE, dwPackageStart, 6);
172 + ValidateCacheCachePayload(pPlan, fRollback, dwIndex++, L"PackageA", L"PackageA", TRUE, FALSE, dwPackageStart);
173 + ValidateCacheCachePayload(pPlan, fRollback, dwIndex++, L"PackageA", L"cab1QmlL013Hqv_44W64R0cvnHn_2c", TRUE, FALSE, dwPackageStart);
174 + ValidateCachePackageStop(pPlan, fRollback, dwIndex++, L"PackageA", FALSE);
175 + ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++, FALSE);
176 + ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 8);
177 + dwPackageStart = ValidateCachePackageStart(pPlan, fRollback, dwIndex++, L"PackageB", 14, 2, 33753, FALSE);
178 + ValidateCacheAcquireContainer(pPlan, fRollback, dwIndex++, L"WixAttachedContainer", TRUE);
179 + ValidateCacheExtractContainer(pPlan, fRollback, dwIndex++, L"WixAttachedContainer", FALSE, dwPackageStart, 2);
180 + ValidateCacheCachePayload(pPlan, fRollback, dwIndex++, L"PackageB", L"PackageB", TRUE, FALSE, dwPackageStart);
181 + ValidateCacheCachePayload(pPlan, fRollback, dwIndex++, L"PackageB", L"cabQH1Sgh7w2K8tLIftUaaWVhMWt0s", TRUE, FALSE, dwPackageStart);
182 + ValidateCachePackageStop(pPlan, fRollback, dwIndex++, L"PackageB", FALSE);
183 + ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++, FALSE);
184 + ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 14);
185 + dwPackageStart = ValidateCachePackageStart(pPlan, fRollback, dwIndex++, L"PackageC", 22, 2, 33739, FALSE);
186 + ValidateCacheAcquireContainer(pPlan, fRollback, dwIndex++, L"WixAttachedContainer", TRUE);
187 + ValidateCacheExtractContainer(pPlan, fRollback, dwIndex++, L"WixAttachedContainer", FALSE, dwPackageStart, 2);
188 + ValidateCacheCachePayload(pPlan, fRollback, dwIndex++, L"PackageC", L"PackageC", TRUE, FALSE, dwPackageStart);
189 + ValidateCacheCachePayload(pPlan, fRollback, dwIndex++, L"PackageC", L"cabRT8kdm93olnEAQB2GSO3u0400VI", TRUE, FALSE, dwPackageStart);
190 + ValidateCachePackageStop(pPlan, fRollback, dwIndex++, L"PackageC", FALSE);
191 + ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++, FALSE);
192 + Assert::Equal(24ul, pPlan->cCacheActions);
193 +
194 + fRollback = TRUE;
195 + dwIndex = 0;
196 + ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 1);
197 + ValidateCacheRollbackPackage(pPlan, fRollback, dwIndex++, L"PackageA", FALSE);
198 + ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 8);
199 + ValidateCacheRollbackPackage(pPlan, fRollback, dwIndex++, L"PackageB", FALSE);
200 + ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 14);
201 + ValidateCacheRollbackPackage(pPlan, fRollback, dwIndex++, L"PackageC", FALSE);
202 + Assert::Equal(dwIndex, pPlan->cRollbackCacheActions);
203 +
204 + Assert::Equal(106166ull, pPlan->qwEstimatedSize);
205 + Assert::Equal(101233ull, pPlan->qwCacheSizeTotal);
206 +
207 + fRollback = FALSE;
208 + dwIndex = 0;
209 + DWORD dwExecuteCheckpointId = 2;
210 + ValidateExecuteRollbackBoundary(pPlan, fRollback, dwIndex++, L"WixDefaultBoundary", TRUE, FALSE);
211 + ValidateExecuteWaitSyncpoint(pPlan, fRollback, dwIndex++, pPlan->rgCacheActions[7].syncpoint.hEvent);
212 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
213 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
214 + ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageA", BURN_DEPENDENCY_ACTION_REGISTER);
215 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
216 + ValidateExecuteMsiPackage(pPlan, fRollback, dwIndex++, L"PackageA", BOOTSTRAPPER_ACTION_STATE_INSTALL, BURN_MSI_PROPERTY_INSTALL, INSTALLUILEVEL_NONE, FALSE, 0);
217 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
218 + ValidateExecuteRegistration(pPlan, fRollback, dwIndex++, TRUE);
219 + ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageA", L"{c096190a-8bf3-4342-a1d2-94ea9cb853d6}", BURN_DEPENDENCY_ACTION_REGISTER);
220 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
221 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
222 + ValidateExecuteRollbackBoundary(pPlan, fRollback, dwIndex++, L"rbaOCA08D8ky7uBOK71_6FWz1K3TuQ", TRUE, TRUE);
223 + ValidateExecuteWaitSyncpoint(pPlan, fRollback, dwIndex++, pPlan->rgCacheActions[15].syncpoint.hEvent);
224 + dwExecuteCheckpointId = 9;
225 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
226 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
227 + ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageB", BURN_DEPENDENCY_ACTION_REGISTER);
228 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
229 + ValidateExecuteMsiPackage(pPlan, fRollback, dwIndex++, L"PackageB", BOOTSTRAPPER_ACTION_STATE_INSTALL, BURN_MSI_PROPERTY_INSTALL, INSTALLUILEVEL_NONE, FALSE, 0);
230 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
231 + ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageB", L"{c096190a-8bf3-4342-a1d2-94ea9cb853d6}", BURN_DEPENDENCY_ACTION_REGISTER);
232 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
233 + ValidateExecuteWaitSyncpoint(pPlan, fRollback, dwIndex++, pPlan->rgCacheActions[23].syncpoint.hEvent);
234 + dwExecuteCheckpointId = 15;
235 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
236 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
237 + ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageC", BURN_DEPENDENCY_ACTION_REGISTER);
238 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
239 + ValidateExecuteMsiPackage(pPlan, fRollback, dwIndex++, L"PackageC", BOOTSTRAPPER_ACTION_STATE_INSTALL, BURN_MSI_PROPERTY_INSTALL, INSTALLUILEVEL_NONE, FALSE, 0);
240 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
241 + ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageC", L"{c096190a-8bf3-4342-a1d2-94ea9cb853d6}", BURN_DEPENDENCY_ACTION_REGISTER);
242 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
243 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
244 + ValidateExecuteWaitSyncpoint(pPlan, fRollback, dwIndex++, pPlan->rgCacheActions[23].syncpoint.hEvent);
245 + ValidateExecuteExePackage(pPlan, fRollback, dwIndex++, L"{FD9920AD-DBCA-4C6C-8CD5-B47431CE8D21}", BOOTSTRAPPER_ACTION_STATE_UNINSTALL, NULL);
246 + Assert::Equal(34ul, pPlan->cExecuteActions);
247 +
248 + fRollback = TRUE;
249 + dwIndex = 0;
250 + dwExecuteCheckpointId = 2;
251 + ValidateExecuteRollbackBoundary(pPlan, fRollback, dwIndex++, L"WixDefaultBoundary", TRUE, FALSE);
252 + ValidateExecuteRegistration(pPlan, fRollback, dwIndex++, FALSE);
253 + ValidateExecuteUncachePackage(pPlan, fRollback, dwIndex++, L"PackageA");
254 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
255 + ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageA", BURN_DEPENDENCY_ACTION_UNREGISTER);
256 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
257 + ValidateExecuteMsiPackage(pPlan, fRollback, dwIndex++, L"PackageA", BOOTSTRAPPER_ACTION_STATE_UNINSTALL, BURN_MSI_PROPERTY_UNINSTALL, INSTALLUILEVEL_NONE, FALSE, 0);
258 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
259 + ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageA", L"{c096190a-8bf3-4342-a1d2-94ea9cb853d6}", BURN_DEPENDENCY_ACTION_UNREGISTER);
260 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
261 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
262 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
263 + ValidateExecuteRollbackBoundary(pPlan, fRollback, dwIndex++, L"rbaOCA08D8ky7uBOK71_6FWz1K3TuQ", TRUE, TRUE);
264 + ValidateExecuteUncachePackage(pPlan, fRollback, dwIndex++, L"PackageB");
265 + dwExecuteCheckpointId = 9;
266 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
267 + ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageB", BURN_DEPENDENCY_ACTION_UNREGISTER);
268 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
269 + ValidateExecuteMsiPackage(pPlan, fRollback, dwIndex++, L"PackageB", BOOTSTRAPPER_ACTION_STATE_UNINSTALL, BURN_MSI_PROPERTY_UNINSTALL, INSTALLUILEVEL_NONE, FALSE, 0);
270 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
271 + ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageB", L"{c096190a-8bf3-4342-a1d2-94ea9cb853d6}", BURN_DEPENDENCY_ACTION_UNREGISTER);
272 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
273 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
274 + ValidateExecuteUncachePackage(pPlan, fRollback, dwIndex++, L"PackageC");
275 + dwExecuteCheckpointId = 15;
276 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
277 + ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageC", BURN_DEPENDENCY_ACTION_UNREGISTER);
278 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
279 + ValidateExecuteMsiPackage(pPlan, fRollback, dwIndex++, L"PackageC", BOOTSTRAPPER_ACTION_STATE_UNINSTALL, BURN_MSI_PROPERTY_UNINSTALL, INSTALLUILEVEL_NONE, FALSE, 0);
280 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
281 + ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageC", L"{c096190a-8bf3-4342-a1d2-94ea9cb853d6}", BURN_DEPENDENCY_ACTION_UNREGISTER);
282 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
283 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
284 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
285 + ValidateExecuteExePackage(pPlan, fRollback, dwIndex++, L"{FD9920AD-DBCA-4C6C-8CD5-B47431CE8D21}", BOOTSTRAPPER_ACTION_STATE_INSTALL, NULL);
286 + Assert::Equal(33ul, pPlan->cRollbackActions);
287 +
288 + Assert::Equal(4ul, pPlan->cExecutePackagesTotal);
289 + Assert::Equal(7ul, pPlan->cOverallProgressTicksTotal);
290 +
291 + dwIndex = 0;
292 + Assert::Equal(dwIndex, pPlan->cCleanActions);
293 +
294 + UINT uIndex = 0;
295 + ValidatePlannedProvider(pPlan, uIndex++, L"{c096190a-8bf3-4342-a1d2-94ea9cb853d6}", NULL);
296 + Assert::Equal(uIndex, pPlan->cPlannedProviders);
297 + }
298 +
299 + [Fact]
300 + void MsiTransactionUninstallTest()
301 + {
302 + HRESULT hr = S_OK;
303 + BURN_ENGINE_STATE engineState = { };
304 + BURN_ENGINE_STATE* pEngineState = &engineState;
305 + BURN_PLAN* pPlan = &engineState.plan;
306 +
307 + InitializeEngineStateForCorePlan(wzMsiTransactionManifest, pEngineState);
308 + DetectPackagesAsPresentAndCached(pEngineState);
309 +
310 + hr = CorePlan(pEngineState, BOOTSTRAPPER_ACTION_UNINSTALL);
311 + NativeAssert::Succeeded(hr, "CorePlan failed");
312 +
313 + Assert::Equal<DWORD>(BOOTSTRAPPER_ACTION_UNINSTALL, pPlan->action);
314 + Assert::Equal<BOOL>(TRUE, pPlan->fPerMachine);
315 + Assert::Equal<BOOL>(FALSE, pPlan->fDisableRollback);
316 + Assert::Equal<BOOL>(TRUE, pPlan->fKeepRegistrationDefault);
317 +
318 + BOOL fRollback = FALSE;
319 + DWORD dwIndex = 0;
320 + Assert::Equal(dwIndex, pPlan->cCacheActions);
321 +
322 + fRollback = TRUE;
323 + dwIndex = 0;
324 + Assert::Equal(dwIndex, pPlan->cRollbackCacheActions);
325 +
326 + Assert::Equal(0ull, pPlan->qwEstimatedSize);
327 + Assert::Equal(0ull, pPlan->qwCacheSizeTotal);
328 +
329 + fRollback = FALSE;
330 + dwIndex = 0;
331 + DWORD dwExecuteCheckpointId = 1;
332 + ValidateExecuteRollbackBoundary(pPlan, fRollback, dwIndex++, L"rbaOCA08D8ky7uBOK71_6FWz1K3TuQ", TRUE, TRUE);
333 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
334 + ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageC", L"{c096190a-8bf3-4342-a1d2-94ea9cb853d6}", BURN_DEPENDENCY_ACTION_UNREGISTER);
335 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
336 + ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageC", BURN_DEPENDENCY_ACTION_UNREGISTER);
337 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
338 + ValidateExecuteMsiPackage(pPlan, fRollback, dwIndex++, L"PackageC", BOOTSTRAPPER_ACTION_STATE_UNINSTALL, BURN_MSI_PROPERTY_UNINSTALL, INSTALLUILEVEL_NONE, FALSE, 0);
339 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
340 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
341 + ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageB", L"{c096190a-8bf3-4342-a1d2-94ea9cb853d6}", BURN_DEPENDENCY_ACTION_UNREGISTER);
342 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
343 + ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageB", BURN_DEPENDENCY_ACTION_UNREGISTER);
344 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
345 + ValidateExecuteMsiPackage(pPlan, fRollback, dwIndex++, L"PackageB", BOOTSTRAPPER_ACTION_STATE_UNINSTALL, BURN_MSI_PROPERTY_UNINSTALL, INSTALLUILEVEL_NONE, FALSE, 0);
346 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
347 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
348 + ValidateExecuteRollbackBoundary(pPlan, fRollback, dwIndex++, L"WixDefaultBoundary", TRUE, FALSE);
349 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
350 + ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageA", L"{c096190a-8bf3-4342-a1d2-94ea9cb853d6}", BURN_DEPENDENCY_ACTION_UNREGISTER);
351 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
352 + ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageA", BURN_DEPENDENCY_ACTION_UNREGISTER);
353 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
354 + ValidateExecuteMsiPackage(pPlan, fRollback, dwIndex++, L"PackageA", BOOTSTRAPPER_ACTION_STATE_UNINSTALL, BURN_MSI_PROPERTY_UNINSTALL, INSTALLUILEVEL_NONE, FALSE, 0);
355 + ValidateExecuteRegistration(pPlan, fRollback, dwIndex++, FALSE);
356 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
357 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
358 + Assert::Equal(dwIndex, pPlan->cExecuteActions);
359 +
360 + fRollback = TRUE;
361 + dwIndex = 0;
362 + dwExecuteCheckpointId = 1;
363 + ValidateExecuteRollbackBoundary(pPlan, fRollback, dwIndex++, L"rbaOCA08D8ky7uBOK71_6FWz1K3TuQ", TRUE, TRUE);
364 + ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageC", L"{c096190a-8bf3-4342-a1d2-94ea9cb853d6}", BURN_DEPENDENCY_ACTION_REGISTER);
365 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
366 + ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageC", BURN_DEPENDENCY_ACTION_REGISTER);
367 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
368 + ValidateExecuteMsiPackage(pPlan, fRollback, dwIndex++, L"PackageC", BOOTSTRAPPER_ACTION_STATE_INSTALL, BURN_MSI_PROPERTY_INSTALL, INSTALLUILEVEL_NONE, FALSE, 0);
369 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
370 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
371 + ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageB", L"{c096190a-8bf3-4342-a1d2-94ea9cb853d6}", BURN_DEPENDENCY_ACTION_REGISTER);
372 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
373 + ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageB", BURN_DEPENDENCY_ACTION_REGISTER);
374 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
375 + ValidateExecuteMsiPackage(pPlan, fRollback, dwIndex++, L"PackageB", BOOTSTRAPPER_ACTION_STATE_INSTALL, BURN_MSI_PROPERTY_INSTALL, INSTALLUILEVEL_NONE, FALSE, 0);
376 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
377 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
378 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
379 + ValidateExecuteRollbackBoundary(pPlan, fRollback, dwIndex++, L"WixDefaultBoundary", TRUE, FALSE);
380 + ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageA", L"{c096190a-8bf3-4342-a1d2-94ea9cb853d6}", BURN_DEPENDENCY_ACTION_REGISTER);
381 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
382 + ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageA", BURN_DEPENDENCY_ACTION_REGISTER);
383 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
384 + ValidateExecuteMsiPackage(pPlan, fRollback, dwIndex++, L"PackageA", BOOTSTRAPPER_ACTION_STATE_INSTALL, BURN_MSI_PROPERTY_INSTALL, INSTALLUILEVEL_NONE, FALSE, 0);
385 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
386 + ValidateExecuteRegistration(pPlan, fRollback, dwIndex++, TRUE);
387 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
388 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
389 + Assert::Equal(dwIndex, pPlan->cRollbackActions);
390 +
391 + Assert::Equal(3ul, pPlan->cExecutePackagesTotal);
392 + Assert::Equal(3ul, pPlan->cOverallProgressTicksTotal);
393 +
394 + dwIndex = 0;
395 + ValidateCleanAction(pPlan, dwIndex++, L"PackageC");
396 + ValidateCleanAction(pPlan, dwIndex++, L"PackageB");
397 + ValidateCleanAction(pPlan, dwIndex++, L"PackageA");
398 + Assert::Equal(dwIndex, pPlan->cCleanActions);
399 +
400 + UINT uIndex = 0;
401 + ValidatePlannedProvider(pPlan, uIndex++, L"{c096190a-8bf3-4342-a1d2-94ea9cb853d6}", NULL);
402 + ValidatePlannedProvider(pPlan, uIndex++, L"{BE27CF2B-9E5F-4500-BAE3-5E0E522FB962}", NULL);
403 + ValidatePlannedProvider(pPlan, uIndex++, L"{388E4963-13AD-4EE7-B907-AA8888F50E54}", NULL);
404 + ValidatePlannedProvider(pPlan, uIndex++, L"{196E43EA-EF92-4FF8-B9AC-A0FD0D225BB4}", NULL);
405 + Assert::Equal(uIndex, pPlan->cPlannedProviders);
406 + }
407 +
408 + [Fact]
409 + void SingleMsiInstallTest()
410 + {
411 + HRESULT hr = S_OK;
412 + BURN_ENGINE_STATE engineState = { };
413 + BURN_ENGINE_STATE* pEngineState = &engineState;
414 + BURN_PLAN* pPlan = &engineState.plan;
415 +
416 + InitializeEngineStateForCorePlan(wzSingleMsiManifest, pEngineState);
417 + DetectAttachedContainerAsAttached(pEngineState);
418 + DetectPackagesAsAbsent(pEngineState);
419 + DetectUpgradeBundle(pEngineState, L"{FD9920AD-DBCA-4C6C-8CD5-B47431CE8D21}", L"0.9.0.0");
420 +
421 + hr = CorePlan(pEngineState, BOOTSTRAPPER_ACTION_INSTALL);
422 + NativeAssert::Succeeded(hr, "CorePlan failed");
423 +
424 + Assert::Equal<DWORD>(BOOTSTRAPPER_ACTION_INSTALL, pPlan->action);
425 + Assert::Equal<BOOL>(TRUE, pPlan->fPerMachine);
426 + Assert::Equal<BOOL>(FALSE, pPlan->fDisableRollback);
427 + Assert::Equal<BOOL>(FALSE, pPlan->fKeepRegistrationDefault);
428 +
429 + BOOL fRollback = FALSE;
430 + DWORD dwIndex = 0;
431 + DWORD dwPackageStart = 0;
432 + ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 1);
433 + dwPackageStart = ValidateCachePackageStart(pPlan, fRollback, dwIndex++, L"PackageE", 5, 2, 33741, FALSE);
434 + ValidateCacheExtractContainer(pPlan, fRollback, dwIndex++, L"WixAttachedContainer", FALSE, BURN_PLAN_INVALID_ACTION_INDEX, 2);
435 + ValidateCacheCachePayload(pPlan, fRollback, dwIndex++, L"PackageE", L"PackageE", TRUE, FALSE, dwPackageStart);
436 + ValidateCacheCachePayload(pPlan, fRollback, dwIndex++, L"PackageE", L"cabkAPka1fWa1PyiVdoVPuoB6Qvs3k", TRUE, FALSE, dwPackageStart);
437 + ValidateCachePackageStop(pPlan, fRollback, dwIndex++, L"PackageE", FALSE);
438 + ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++, FALSE);
439 + Assert::Equal(dwIndex, pPlan->cCacheActions);
440 +
441 + fRollback = TRUE;
442 + dwIndex = 0;
443 + ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 1);
444 + ValidateCacheRollbackPackage(pPlan, fRollback, dwIndex++, L"PackageE", FALSE);
445 + Assert::Equal(dwIndex, pPlan->cRollbackCacheActions);
446 +
447 + Assert::Equal(35381ull, pPlan->qwEstimatedSize);
448 + Assert::Equal(33741ull, pPlan->qwCacheSizeTotal);
449 +
450 + fRollback = FALSE;
451 + dwIndex = 0;
452 + DWORD dwExecuteCheckpointId = 2;
453 + ValidateExecuteRollbackBoundary(pPlan, fRollback, dwIndex++, L"WixDefaultBoundary", TRUE, FALSE);
454 + ValidateExecuteWaitSyncpoint(pPlan, fRollback, dwIndex++, pPlan->rgCacheActions[6].syncpoint.hEvent);
455 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
456 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
457 + ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageE", BURN_DEPENDENCY_ACTION_REGISTER);
458 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
459 + ValidateExecuteMsiPackage(pPlan, fRollback, dwIndex++, L"PackageE", BOOTSTRAPPER_ACTION_STATE_INSTALL, BURN_MSI_PROPERTY_INSTALL, INSTALLUILEVEL_NONE, FALSE, 0);
460 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
461 + ValidateExecuteRegistration(pPlan, fRollback, dwIndex++, TRUE);
462 + ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageE", L"{4a04385a-0081-44ba-acd1-9e4e95cfc97f}", BURN_DEPENDENCY_ACTION_REGISTER);
463 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
464 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
465 + ValidateExecuteWaitSyncpoint(pPlan, fRollback, dwIndex++, pPlan->rgCacheActions[6].syncpoint.hEvent);
466 + ValidateExecuteExePackage(pPlan, fRollback, dwIndex++, L"{FD9920AD-DBCA-4C6C-8CD5-B47431CE8D21}", BOOTSTRAPPER_ACTION_STATE_UNINSTALL, NULL);
467 + Assert::Equal(dwIndex, pPlan->cExecuteActions);
468 +
469 + fRollback = TRUE;
470 + dwIndex = 0;
471 + dwExecuteCheckpointId = 2;
472 + ValidateExecuteRollbackBoundary(pPlan, fRollback, dwIndex++, L"WixDefaultBoundary", TRUE, FALSE);
473 + ValidateExecuteRegistration(pPlan, fRollback, dwIndex++, FALSE);
474 + ValidateExecuteUncachePackage(pPlan, fRollback, dwIndex++, L"PackageE");
475 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
476 + ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageE", BURN_DEPENDENCY_ACTION_UNREGISTER);
477 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
478 + ValidateExecuteMsiPackage(pPlan, fRollback, dwIndex++, L"PackageE", BOOTSTRAPPER_ACTION_STATE_UNINSTALL, BURN_MSI_PROPERTY_UNINSTALL, INSTALLUILEVEL_NONE, FALSE, 0);
479 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
480 + ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageE", L"{4a04385a-0081-44ba-acd1-9e4e95cfc97f}", BURN_DEPENDENCY_ACTION_UNREGISTER);
481 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
482 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
483 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
484 + ValidateExecuteExePackage(pPlan, fRollback, dwIndex++, L"{FD9920AD-DBCA-4C6C-8CD5-B47431CE8D21}", BOOTSTRAPPER_ACTION_STATE_INSTALL, NULL);
485 + Assert::Equal(dwIndex, pPlan->cRollbackActions);
486 +
487 + Assert::Equal(2ul, pPlan->cExecutePackagesTotal);
488 + Assert::Equal(3ul, pPlan->cOverallProgressTicksTotal);
489 +
490 + dwIndex = 0;
491 + Assert::Equal(dwIndex, pPlan->cCleanActions);
492 +
493 + UINT uIndex = 0;
494 + ValidatePlannedProvider(pPlan, uIndex++, L"{4a04385a-0081-44ba-acd1-9e4e95cfc97f}", NULL);
495 + Assert::Equal(uIndex, pPlan->cPlannedProviders);
496 + }
497 +
498 + [Fact]
499 + void SingleMsiUninstallTest()
500 + {
501 + HRESULT hr = S_OK;
502 + BURN_ENGINE_STATE engineState = { };
503 + BURN_ENGINE_STATE* pEngineState = &engineState;
504 + BURN_PLAN* pPlan = &engineState.plan;
505 +
506 + InitializeEngineStateForCorePlan(wzSingleMsiManifest, pEngineState);
507 + DetectPackagesAsPresentAndCached(pEngineState);
508 +
509 + hr = CorePlan(pEngineState, BOOTSTRAPPER_ACTION_UNINSTALL);
510 + NativeAssert::Succeeded(hr, "CorePlan failed");
511 +
512 + Assert::Equal<DWORD>(BOOTSTRAPPER_ACTION_UNINSTALL, pPlan->action);
513 + Assert::Equal<BOOL>(TRUE, pPlan->fPerMachine);
514 + Assert::Equal<BOOL>(FALSE, pPlan->fDisableRollback);
515 + Assert::Equal<BOOL>(TRUE, pPlan->fKeepRegistrationDefault);
516 +
517 + BOOL fRollback = FALSE;
518 + DWORD dwIndex = 0;
519 + Assert::Equal(dwIndex, pPlan->cCacheActions);
520 +
521 + fRollback = TRUE;
522 + dwIndex = 0;
523 + Assert::Equal(dwIndex, pPlan->cRollbackCacheActions);
524 +
525 + Assert::Equal(0ull, pPlan->qwEstimatedSize);
526 + Assert::Equal(0ull, pPlan->qwCacheSizeTotal);
527 +
528 + fRollback = FALSE;
529 + dwIndex = 0;
530 + DWORD dwExecuteCheckpointId = 1;
531 + ValidateExecuteRollbackBoundary(pPlan, fRollback, dwIndex++, L"WixDefaultBoundary", TRUE, FALSE);
532 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
533 + ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageE", L"{4a04385a-0081-44ba-acd1-9e4e95cfc97f}", BURN_DEPENDENCY_ACTION_UNREGISTER);
534 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
535 + ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageE", BURN_DEPENDENCY_ACTION_UNREGISTER);
536 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
537 + ValidateExecuteMsiPackage(pPlan, fRollback, dwIndex++, L"PackageE", BOOTSTRAPPER_ACTION_STATE_UNINSTALL, BURN_MSI_PROPERTY_UNINSTALL, INSTALLUILEVEL_NONE, FALSE, 0);
538 + ValidateExecuteRegistration(pPlan, fRollback, dwIndex++, FALSE);
539 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
540 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
541 + Assert::Equal(dwIndex, pPlan->cExecuteActions);
542 +
543 + fRollback = TRUE;
544 + dwIndex = 0;
545 + dwExecuteCheckpointId = 1;
546 + ValidateExecuteRollbackBoundary(pPlan, fRollback, dwIndex++, L"WixDefaultBoundary", TRUE, FALSE);
547 + ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageE", L"{4a04385a-0081-44ba-acd1-9e4e95cfc97f}", BURN_DEPENDENCY_ACTION_REGISTER);
548 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
549 + ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageE", BURN_DEPENDENCY_ACTION_REGISTER);
550 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
551 + ValidateExecuteMsiPackage(pPlan, fRollback, dwIndex++, L"PackageE", BOOTSTRAPPER_ACTION_STATE_INSTALL, BURN_MSI_PROPERTY_INSTALL, INSTALLUILEVEL_NONE, FALSE, 0);
552 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
553 + ValidateExecuteRegistration(pPlan, fRollback, dwIndex++, TRUE);
554 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
555 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
556 + Assert::Equal(dwIndex, pPlan->cRollbackActions);
557 +
558 + Assert::Equal(1ul, pPlan->cExecutePackagesTotal);
559 + Assert::Equal(1ul, pPlan->cOverallProgressTicksTotal);
560 +
561 + dwIndex = 0;
562 + ValidateCleanAction(pPlan, dwIndex++, L"PackageE");
563 + Assert::Equal(dwIndex, pPlan->cCleanActions);
564 +
565 + UINT uIndex = 0;
566 + ValidatePlannedProvider(pPlan, uIndex++, L"{4a04385a-0081-44ba-acd1-9e4e95cfc97f}", NULL);
567 + ValidatePlannedProvider(pPlan, uIndex++, L"{284F56B6-B6C7-404A-B9B5-78F63BF79494}", NULL);
568 + Assert::Equal(uIndex, pPlan->cPlannedProviders);
569 + }
570 +
571 + private:
572 + // This doesn't initialize everything, just enough for CorePlan to work.
573 + void InitializeEngineStateForCorePlan(LPCWSTR wzManifest, BURN_ENGINE_STATE* pEngineState)
574 + {
575 + HRESULT hr = S_OK;
576 +
577 + ::InitializeCriticalSection(&pEngineState->csActive);
578 + ::InitializeCriticalSection(&pEngineState->userExperience.csEngineActive);
579 +
580 + hr = VariableInitialize(&pEngineState->variables);
581 + NativeAssert::Succeeded(hr, "Failed to initialize variables.");
582 +
583 + hr = ManifestLoadXml(wzManifest, pEngineState);
584 + NativeAssert::Succeeded(hr, "Failed to load manifest.");
585 +
586 + pEngineState->userExperience.pfnBAProc = PlanTestBAProc;
587 + }
588 +
589 + void DetectAttachedContainerAsAttached(BURN_ENGINE_STATE* pEngineState)
590 + {
591 + for (DWORD i = 0; i < pEngineState->containers.cContainers; ++i)
592 + {
593 + BURN_CONTAINER* pContainer = pEngineState->containers.rgContainers + i;
594 + if (pContainer->fAttached)
595 + {
596 + pContainer->fActuallyAttached = TRUE;
597 + }
598 + }
599 + }
600 +
601 + void DetectPackagesAsAbsent(BURN_ENGINE_STATE* pEngineState)
602 + {
603 + DetectReset(&pEngineState->registration, &pEngineState->packages);
604 + PlanReset(&pEngineState->plan, &pEngineState->packages);
605 +
606 + for (DWORD i = 0; i < pEngineState->packages.cPackages; ++i)
607 + {
608 + BURN_PACKAGE* pPackage = pEngineState->packages.rgPackages + i;
609 + pPackage->currentState = BOOTSTRAPPER_PACKAGE_STATE_ABSENT;
610 + }
611 + }
612 +
613 + void DetectPackagesAsPresentAndCached(BURN_ENGINE_STATE* pEngineState)
614 + {
615 + DetectReset(&pEngineState->registration, &pEngineState->packages);
616 + PlanReset(&pEngineState->plan, &pEngineState->packages);
617 +
618 + pEngineState->registration.fInstalled = TRUE;
619 +
620 + for (DWORD i = 0; i < pEngineState->packages.cPackages; ++i)
621 + {
622 + BURN_PACKAGE* pPackage = pEngineState->packages.rgPackages + i;
623 + pPackage->currentState = BOOTSTRAPPER_PACKAGE_STATE_PRESENT;
624 + pPackage->cache = BURN_CACHE_STATE_COMPLETE;
625 +
626 + for (DWORD j = 0; j < pPackage->cPayloads; ++j)
627 + {
628 + pPackage->rgPayloads[j].fCached = TRUE;
629 + }
630 + }
631 + }
632 +
633 + HRESULT DetectUpgradeBundle(
634 + __in BURN_ENGINE_STATE* pEngineState,
635 + __in LPCWSTR wzId,
636 + __in LPCWSTR wzVersion
637 + )
638 + {
639 + HRESULT hr = S_OK;
640 + BURN_RELATED_BUNDLES* pRelatedBundles = &pEngineState->registration.relatedBundles;
641 + BURN_DEPENDENCY_PROVIDER dependencyProvider = { };
642 +
643 + hr = StrAllocString(&dependencyProvider.sczKey, wzId, 0);
644 + ExitOnFailure(hr, "Failed to copy provider key");
645 +
646 + dependencyProvider.fImported = TRUE;
647 +
648 + hr = StrAllocString(&dependencyProvider.sczVersion, wzVersion, 0);
649 + ExitOnFailure(hr, "Failed to copy version");
650 +
651 + hr = MemEnsureArraySize(reinterpret_cast<LPVOID*>(&pRelatedBundles->rgRelatedBundles), pRelatedBundles->cRelatedBundles + 1, sizeof(BURN_RELATED_BUNDLE), 5);
652 + ExitOnFailure(hr, "Failed to ensure there is space for related bundles.");
653 +
654 + BURN_RELATED_BUNDLE* pRelatedBundle = pRelatedBundles->rgRelatedBundles + pRelatedBundles->cRelatedBundles;
655 +
656 + hr = VerParseVersion(wzVersion, 0, FALSE, &pRelatedBundle->pVersion);
657 + ExitOnFailure(hr, "Failed to parse pseudo bundle version: %ls", wzVersion);
658 +
659 + pRelatedBundle->relationType = BOOTSTRAPPER_RELATION_UPGRADE;
660 +
661 + hr = PseudoBundleInitialize(0, &pRelatedBundle->package, TRUE, wzId, pRelatedBundle->relationType, BOOTSTRAPPER_PACKAGE_STATE_PRESENT, NULL, NULL, NULL, 0, FALSE, L"-quiet", L"-repair -quiet", L"-uninstall -quiet", &dependencyProvider, NULL, 0);
662 + ExitOnFailure(hr, "Failed to initialize related bundle to represent bundle: %ls", wzId);
663 +
664 + ++pRelatedBundles->cRelatedBundles;
665 +
666 + LExit:
667 + return hr;
668 + }
669 +
670 + void ValidateCacheAcquireContainer(
671 + __in BURN_PLAN* pPlan,
672 + __in BOOL fRollback,
673 + __in DWORD dwIndex,
674 + __in LPCWSTR wzContainerId,
675 + __in BOOL fSkipUntilRetried
676 + )
677 + {
678 + BURN_CACHE_ACTION* pAction = ValidateCacheActionExists(pPlan, fRollback, dwIndex);
679 + Assert::Equal<DWORD>(BURN_CACHE_ACTION_TYPE_ACQUIRE_CONTAINER, pAction->type);
680 + NativeAssert::StringEqual(wzContainerId, pAction->extractContainer.pContainer->sczId);
681 + Assert::Equal<BOOL>(fSkipUntilRetried, pAction->fSkipUntilRetried);
682 + }
683 +
684 + BURN_CACHE_ACTION* ValidateCacheActionExists(BURN_PLAN* pPlan, BOOL fRollback, DWORD dwIndex)
685 + {
686 + Assert::InRange(dwIndex + 1ul, 1ul, (fRollback ? pPlan->cRollbackCacheActions : pPlan->cCacheActions));
687 + return (fRollback ? pPlan->rgRollbackCacheActions : pPlan->rgCacheActions) + dwIndex;
688 + }
689 +
690 + void ValidateCacheCachePayload(
691 + __in BURN_PLAN* pPlan,
692 + __in BOOL fRollback,
693 + __in DWORD dwIndex,
694 + __in LPCWSTR wzPackageId,
695 + __in LPCWSTR wzPayloadId,
696 + __in BOOL fMove,
697 + __in BOOL fSkipUntilRetried,
698 + __in DWORD iTryAgainAction
699 + )
700 + {
701 + BURN_CACHE_ACTION* pAction = ValidateCacheActionExists(pPlan, fRollback, dwIndex);
702 + Assert::Equal<DWORD>(BURN_CACHE_ACTION_TYPE_CACHE_PAYLOAD, pAction->type);
703 + NativeAssert::StringEqual(wzPackageId, pAction->cachePayload.pPackage->sczId);
704 + NativeAssert::StringEqual(wzPayloadId, pAction->cachePayload.pPayload->sczKey);
705 + Assert::Equal<BOOL>(fMove, pAction->cachePayload.fMove);
706 + Assert::Equal<BOOL>(fSkipUntilRetried, pAction->fSkipUntilRetried);
707 + Assert::Equal(iTryAgainAction, pAction->cachePayload.iTryAgainAction);
708 + }
709 +
710 + void ValidateCacheCheckpoint(
711 + __in BURN_PLAN* pPlan,
712 + __in BOOL fRollback,
713 + __in DWORD dwIndex,
714 + __in DWORD dwId
715 + )
716 + {
717 + BURN_CACHE_ACTION* pAction = ValidateCacheActionExists(pPlan, fRollback, dwIndex);
718 + Assert::Equal<DWORD>(BURN_CACHE_ACTION_TYPE_CHECKPOINT, pAction->type);
719 + Assert::Equal(dwId, pAction->checkpoint.dwId);
720 + }
721 +
722 + void ValidateCacheExtractContainer(
723 + __in BURN_PLAN* pPlan,
724 + __in BOOL fRollback,
725 + __in DWORD dwIndex,
726 + __in LPCWSTR wzContainerId,
727 + __in BOOL fSkipUntilRetried,
728 + __in DWORD iSkipUntilAcquiredByAction,
729 + __in DWORD cPayloads
730 + )
731 + {
732 + BURN_CACHE_ACTION* pAction = ValidateCacheActionExists(pPlan, fRollback, dwIndex);
733 + Assert::Equal<DWORD>(BURN_CACHE_ACTION_TYPE_EXTRACT_CONTAINER, pAction->type);
734 + NativeAssert::StringEqual(wzContainerId, pAction->extractContainer.pContainer->sczId);
735 + Assert::Equal<BOOL>(fSkipUntilRetried, pAction->fSkipUntilRetried);
736 + Assert::Equal(iSkipUntilAcquiredByAction, pAction->extractContainer.iSkipUntilAcquiredByAction);
737 + Assert::Equal(cPayloads, pAction->extractContainer.cPayloads);
738 + }
739 +
740 + DWORD ValidateCachePackageStart(
741 + __in BURN_PLAN* pPlan,
742 + __in BOOL fRollback,
743 + __in DWORD dwIndex,
744 + __in LPCWSTR wzPackageId,
745 + __in DWORD iPackageCompleteAction,
746 + __in DWORD cCachePayloads,
747 + __in DWORD64 qwCachePayloadSizeTotal,
748 + __in BOOL fSkipUntilRetried
749 + )
750 + {
751 + BURN_CACHE_ACTION* pAction = ValidateCacheActionExists(pPlan, fRollback, dwIndex);
752 + Assert::Equal<DWORD>(BURN_CACHE_ACTION_TYPE_PACKAGE_START, pAction->type);
753 + NativeAssert::StringEqual(wzPackageId, pAction->packageStart.pPackage->sczId);
754 + Assert::Equal(iPackageCompleteAction, pAction->packageStart.iPackageCompleteAction);
755 + Assert::Equal(cCachePayloads, pAction->packageStart.cCachePayloads);
756 + Assert::Equal(qwCachePayloadSizeTotal, pAction->packageStart.qwCachePayloadSizeTotal);
757 + Assert::Equal<BOOL>(fSkipUntilRetried, pAction->fSkipUntilRetried);
758 + return dwIndex + 1;
759 + }
760 +
761 + void ValidateCachePackageStop(
762 + __in BURN_PLAN* pPlan,
763 + __in BOOL fRollback,
764 + __in DWORD dwIndex,
765 + __in LPCWSTR wzPackageId,
766 + __in BOOL fSkipUntilRetried
767 + )
768 + {
769 + BURN_CACHE_ACTION* pAction = ValidateCacheActionExists(pPlan, fRollback, dwIndex);
770 + Assert::Equal<DWORD>(BURN_CACHE_ACTION_TYPE_PACKAGE_STOP, pAction->type);
771 + NativeAssert::StringEqual(wzPackageId, pAction->packageStop.pPackage->sczId);
772 + Assert::Equal<BOOL>(fSkipUntilRetried, pAction->fSkipUntilRetried);
773 + }
774 +
775 + void ValidateCacheRollbackPackage(
776 + __in BURN_PLAN* pPlan,
777 + __in BOOL fRollback,
778 + __in DWORD dwIndex,
779 + __in LPCWSTR wzPackageId,
780 + __in BOOL fSkipUntilRetried
781 + )
782 + {
783 + BURN_CACHE_ACTION* pAction = ValidateCacheActionExists(pPlan, fRollback, dwIndex);
784 + Assert::Equal<DWORD>(BURN_CACHE_ACTION_TYPE_ROLLBACK_PACKAGE, pAction->type);
785 + NativeAssert::StringEqual(wzPackageId, pAction->rollbackPackage.pPackage->sczId);
786 + Assert::Equal<BOOL>(fSkipUntilRetried, pAction->fSkipUntilRetried);
787 + }
788 +
789 + void ValidateCacheSignalSyncpoint(
790 + __in BURN_PLAN* pPlan,
791 + __in BOOL fRollback,
792 + __in DWORD dwIndex,
793 + __in BOOL fSkipUntilRetried
794 + )
795 + {
796 + BURN_CACHE_ACTION* pAction = ValidateCacheActionExists(pPlan, fRollback, dwIndex);
797 + Assert::Equal<DWORD>(BURN_CACHE_ACTION_TYPE_SIGNAL_SYNCPOINT, pAction->type);
798 + Assert::NotEqual((DWORD_PTR)NULL, (DWORD_PTR)pAction->syncpoint.hEvent);
799 + Assert::Equal<BOOL>(fSkipUntilRetried, pAction->fSkipUntilRetried);
800 + }
801 +
802 + void ValidateCleanAction(
803 + __in BURN_PLAN* pPlan,
804 + __in DWORD dwIndex,
805 + __in LPCWSTR wzPackageId
806 + )
807 + {
808 + Assert::InRange(dwIndex + 1ul, 1ul, pPlan->cCleanActions);
809 +
810 + BURN_CLEAN_ACTION* pCleanAction = pPlan->rgCleanActions + dwIndex;
811 + Assert::NotEqual((DWORD_PTR)0, (DWORD_PTR)pCleanAction->pPackage);
812 + NativeAssert::StringEqual(wzPackageId, pCleanAction->pPackage->sczId);
813 + }
814 +
815 + BURN_EXECUTE_ACTION* ValidateExecuteActionExists(BURN_PLAN* pPlan, BOOL fRollback, DWORD dwIndex)
816 + {
817 + Assert::InRange(dwIndex + 1ul, 1ul, (fRollback ? pPlan->cRollbackActions : pPlan->cExecuteActions));
818 + return (fRollback ? pPlan->rgRollbackActions : pPlan->rgExecuteActions) + dwIndex;
819 + }
820 +
821 + void ValidateExecuteCheckpoint(
822 + __in BURN_PLAN* pPlan,
823 + __in BOOL fRollback,
824 + __in DWORD dwIndex,
825 + __in DWORD dwId
826 + )
827 + {
828 + BURN_EXECUTE_ACTION* pAction = ValidateExecuteActionExists(pPlan, fRollback, dwIndex);
829 + Assert::Equal<DWORD>(BURN_EXECUTE_ACTION_TYPE_CHECKPOINT, pAction->type);
830 + Assert::Equal(dwId, pAction->checkpoint.dwId);
831 + }
832 +
833 + void ValidateExecuteExePackage(
834 + __in BURN_PLAN* pPlan,
835 + __in BOOL fRollback,
836 + __in DWORD dwIndex,
837 + __in LPCWSTR wzPackageId,
838 + __in BOOTSTRAPPER_ACTION_STATE action,
839 + __in LPCWSTR wzIgnoreDependencies
840 + )
841 + {
842 + BURN_EXECUTE_ACTION* pAction = ValidateExecuteActionExists(pPlan, fRollback, dwIndex);
843 + Assert::Equal<DWORD>(BURN_EXECUTE_ACTION_TYPE_EXE_PACKAGE, pAction->type);
844 + NativeAssert::StringEqual(wzPackageId, pAction->exePackage.pPackage->sczId);
845 + Assert::Equal<DWORD>(action, pAction->exePackage.action);
846 + NativeAssert::StringEqual(wzIgnoreDependencies, pAction->exePackage.sczIgnoreDependencies);
847 + }
848 +
849 + void ValidateExecuteMsiPackage(
850 + __in BURN_PLAN* pPlan,
851 + __in BOOL fRollback,
852 + __in DWORD dwIndex,
853 + __in LPCWSTR wzPackageId,
854 + __in BOOTSTRAPPER_ACTION_STATE action,
855 + __in BURN_MSI_PROPERTY actionMsiProperty,
856 + __in DWORD uiLevel,
857 + __in BOOL fDisableExternalUiHandler,
858 + __in DWORD dwLoggingAttributes
859 + )
860 + {
861 + BURN_EXECUTE_ACTION* pAction = ValidateExecuteActionExists(pPlan, fRollback, dwIndex);
862 + Assert::Equal<DWORD>(BURN_EXECUTE_ACTION_TYPE_MSI_PACKAGE, pAction->type);
863 + NativeAssert::StringEqual(wzPackageId, pAction->msiPackage.pPackage->sczId);
864 + Assert::Equal<DWORD>(action, pAction->msiPackage.action);
865 + Assert::Equal<DWORD>(actionMsiProperty, pAction->msiPackage.actionMsiProperty);
866 + Assert::Equal<DWORD>(uiLevel, pAction->msiPackage.uiLevel);
867 + Assert::Equal<BOOL>(fDisableExternalUiHandler, pAction->msiPackage.fDisableExternalUiHandler);
868 + NativeAssert::NotNull(pAction->msiPackage.sczLogPath);
869 + Assert::Equal<DWORD>(dwLoggingAttributes, pAction->msiPackage.dwLoggingAttributes);
870 + }
871 +
872 + void ValidateExecutePackageDependency(
873 + __in BURN_PLAN* pPlan,
874 + __in BOOL fRollback,
875 + __in DWORD dwIndex,
876 + __in LPCWSTR wzPackageId,
877 + __in LPCWSTR wzBundleProviderKey,
878 + __in BURN_DEPENDENCY_ACTION action
879 + )
880 + {
881 + BURN_EXECUTE_ACTION* pAction = ValidateExecuteActionExists(pPlan, fRollback, dwIndex);
882 + Assert::Equal<DWORD>(BURN_EXECUTE_ACTION_TYPE_PACKAGE_DEPENDENCY, pAction->type);
883 + NativeAssert::StringEqual(wzPackageId, pAction->packageDependency.pPackage->sczId);
884 + NativeAssert::StringEqual(wzBundleProviderKey, pAction->packageDependency.sczBundleProviderKey);
885 + Assert::Equal<DWORD>(action, pAction->packageDependency.action);
886 + }
887 +
888 + void ValidateExecutePackageProvider(
889 + __in BURN_PLAN* pPlan,
890 + __in BOOL fRollback,
891 + __in DWORD dwIndex,
892 + __in LPCWSTR wzPackageId,
893 + __in BURN_DEPENDENCY_ACTION action
894 + )
895 + {
896 + BURN_EXECUTE_ACTION* pAction = ValidateExecuteActionExists(pPlan, fRollback, dwIndex);
897 + Assert::Equal<DWORD>(BURN_EXECUTE_ACTION_TYPE_PACKAGE_PROVIDER, pAction->type);
898 + NativeAssert::StringEqual(wzPackageId, pAction->packageProvider.pPackage->sczId);
899 + Assert::Equal<DWORD>(action, pAction->packageProvider.action);
900 + }
901 +
902 + void ValidateExecuteRegistration(
903 + __in BURN_PLAN* pPlan,
904 + __in BOOL fRollback,
905 + __in DWORD dwIndex,
906 + __in BOOL fKeep
907 + )
908 + {
909 + BURN_EXECUTE_ACTION* pAction = ValidateExecuteActionExists(pPlan, fRollback, dwIndex);
910 + Assert::Equal<DWORD>(BURN_EXECUTE_ACTION_TYPE_REGISTRATION, pAction->type);
911 + Assert::Equal<BOOL>(fKeep, pAction->registration.fKeep);
912 + }
913 +
914 + void ValidateExecuteRollbackBoundary(
915 + __in BURN_PLAN* pPlan,
916 + __in BOOL fRollback,
917 + __in DWORD dwIndex,
918 + __in LPCWSTR wzId,
919 + __in BOOL fVital,
920 + __in BOOL fTransaction
921 + )
922 + {
923 + BURN_EXECUTE_ACTION* pAction = ValidateExecuteActionExists(pPlan, fRollback, dwIndex);
924 + Assert::Equal<DWORD>(BURN_EXECUTE_ACTION_TYPE_ROLLBACK_BOUNDARY, pAction->type);
925 + NativeAssert::StringEqual(wzId, pAction->rollbackBoundary.pRollbackBoundary->sczId);
926 + Assert::Equal<BOOL>(fVital, pAction->rollbackBoundary.pRollbackBoundary->fVital);
927 + Assert::Equal<BOOL>(fTransaction, pAction->rollbackBoundary.pRollbackBoundary->fTransaction);
928 + }
929 +
930 + void ValidateExecuteUncachePackage(
931 + __in BURN_PLAN* pPlan,
932 + __in BOOL fRollback,
933 + __in DWORD dwIndex,
934 + __in LPCWSTR wzPackageId
935 + )
936 + {
937 + BURN_EXECUTE_ACTION* pAction = ValidateExecuteActionExists(pPlan, fRollback, dwIndex);
938 + Assert::Equal<DWORD>(BURN_EXECUTE_ACTION_TYPE_UNCACHE_PACKAGE, pAction->type);
939 + NativeAssert::StringEqual(wzPackageId, pAction->uncachePackage.pPackage->sczId);
940 + }
941 +
942 + void ValidateExecuteWaitSyncpoint(
943 + __in BURN_PLAN* pPlan,
944 + __in BOOL fRollback,
945 + __in DWORD dwIndex,
946 + __in HANDLE hEvent
947 + )
948 + {
949 + BURN_EXECUTE_ACTION* pAction = ValidateExecuteActionExists(pPlan, fRollback, dwIndex);
950 + Assert::Equal<DWORD>(BURN_EXECUTE_ACTION_TYPE_WAIT_SYNCPOINT, pAction->type);
951 + Assert::Equal((DWORD_PTR)hEvent, (DWORD_PTR)pAction->syncpoint.hEvent);
952 + }
953 +
954 + void ValidatePlannedProvider(
955 + __in BURN_PLAN* pPlan,
956 + __in UINT uIndex,
957 + __in LPCWSTR wzKey,
958 + __in LPCWSTR wzName
959 + )
960 + {
961 + Assert::InRange(uIndex + 1u, 1u, pPlan->cPlannedProviders);
962 +
963 + DEPENDENCY* pProvider = pPlan->rgPlannedProviders + uIndex;
964 + NativeAssert::StringEqual(wzKey, pProvider->sczKey);
965 + NativeAssert::StringEqual(wzName, pProvider->sczName);
966 + }
967 + };
968 +}
969 +}
970 +}
971 +}
972 +}
973 +
974 +static HRESULT WINAPI PlanTestBAProc(
975 + __in BOOTSTRAPPER_APPLICATION_MESSAGE /*message*/,
976 + __in const LPVOID /*pvArgs*/,
977 + __inout LPVOID /*pvResults*/,
978 + __in_opt LPVOID /*pvContext*/
979 + )
980 +{
981 + return S_OK;
982 +}
src/test/BurnUnitTest/precomp.h
+1
@@ -69,6 +69,7 @@
69 #include "manifest.h"
70 #include "splashscreen.h"
71 #include "bitsengine.h"
72 +#include "detect.h"
73
74 #pragma managed
75 #include <vcclr.h>