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>