Update Burn to handle ExePackages that don't support uninstalling.
Partial fix for #6459
Sean Hall committed
Jan 16, 2022 at 12:17 UTC
f5d880cc70ad7350b0da1ea825141f95cbdb4c7b
4 files changed
+43
-20
src/burn/engine/exeengine.cpp
+24
-20
@@ -11,36 +11,43 @@ extern "C" HRESULT ExeEngineParsePackageFromXml(
11
)
12
{
13
HRESULT hr = S_OK;
14
+ BOOL fFoundXml = FALSE;
15
IXMLDOMNodeList* pixnNodes = NULL;
16
IXMLDOMNode* pixnNode = NULL;
17
LPWSTR scz = NULL;
18
19
// @DetectCondition
20
hr = XmlGetAttributeEx(pixnExePackage, L"DetectCondition", &pPackage->Exe.sczDetectCondition);
20
- ExitOnFailure(hr, "Failed to get @DetectCondition.");
21
+ ExitOnOptionalXmlQueryFailure(hr, fFoundXml, "Failed to get @DetectCondition.");
22
23
// @InstallArguments
24
hr = XmlGetAttributeEx(pixnExePackage, L"InstallArguments", &pPackage->Exe.sczInstallArguments);
24
- ExitOnFailure(hr, "Failed to get @InstallArguments.");
25
+ ExitOnOptionalXmlQueryFailure(hr, fFoundXml, "Failed to get @InstallArguments.");
26
27
// @UninstallArguments
28
hr = XmlGetAttributeEx(pixnExePackage, L"UninstallArguments", &pPackage->Exe.sczUninstallArguments);
28
- ExitOnFailure(hr, "Failed to get @UninstallArguments.");
29
+ ExitOnOptionalXmlQueryFailure(hr, fFoundXml, "Failed to get @UninstallArguments.");
30
31
// @RepairArguments
32
hr = XmlGetAttributeEx(pixnExePackage, L"RepairArguments", &pPackage->Exe.sczRepairArguments);
32
- ExitOnFailure(hr, "Failed to get @RepairArguments.");
33
+ ExitOnOptionalXmlQueryFailure(hr, fFoundXml, "Failed to get @RepairArguments.");
34
35
// @Repairable
36
hr = XmlGetYesNoAttribute(pixnExePackage, L"Repairable", &pPackage->Exe.fRepairable);
36
- if (E_NOTFOUND != hr)
37
- {
38
- ExitOnFailure(hr, "Failed to get @Repairable.");
39
- }
37
+ ExitOnOptionalXmlQueryFailure(hr, fFoundXml, "Failed to get @Repairable.");
38
+
39
+ // @Uninstallable
40
+ pPackage->Exe.fUninstallable = TRUE; // TODO: https://github.com/wixtoolset/issues/issues/6459
41
+ /*
42
+ hr = XmlGetYesNoAttribute(pixnNode, L"Uninstallable", &pPackage->Exe.fUninstallable);
43
+ ExitOnOptionalXmlQueryFailure(hr, fFoundXml, "Failed to get @Uninstallable.");
44
+ */
45
46
// @Protocol
47
hr = XmlGetAttributeEx(pixnExePackage, L"Protocol", &scz);
43
- if (SUCCEEDED(hr))
48
+ ExitOnOptionalXmlQueryFailure(hr, fFoundXml, "Failed to get @Protocol.");
49
+
50
+ if (fFoundXml)
51
{
52
if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"burn", -1))
53
{
@@ -60,10 +67,6 @@ extern "C" HRESULT ExeEngineParsePackageFromXml(
67
ExitOnFailure(hr, "Invalid protocol type: %ls", scz);
68
}
69
}
63
- else if (E_NOTFOUND != hr)
64
- {
65
- ExitOnFailure(hr, "Failed to get @Protocol.");
66
- }
70
71
hr = ExeEngineParseExitCodesFromXml(pixnExePackage, &pPackage->Exe.rgExitCodes, &pPackage->Exe.cExitCodes);
72
ExitOnFailure(hr, "Failed to parse exit codes.");
@@ -172,7 +175,7 @@ extern "C" HRESULT ExeEnginePlanCalculatePackage(
175
execute = !pPackage->fPermanent ? BOOTSTRAPPER_ACTION_STATE_UNINSTALL : BOOTSTRAPPER_ACTION_STATE_NONE;
176
break;
177
case BOOTSTRAPPER_REQUEST_STATE_FORCE_ABSENT:
175
- execute = BOOTSTRAPPER_ACTION_STATE_UNINSTALL;
178
+ execute = pPackage->Exe.fUninstallable ? BOOTSTRAPPER_ACTION_STATE_UNINSTALL : BOOTSTRAPPER_ACTION_STATE_NONE;
179
break;
180
default:
181
execute = BOOTSTRAPPER_ACTION_STATE_NONE;
@@ -552,11 +555,11 @@ extern "C" HRESULT ExeEngineParseExitCodesFromXml(
555
556
// @Type
557
hr = XmlGetAttributeNumber(pixnNode, L"Type", (DWORD*)&pExitCode->type);
555
- ExitOnFailure(hr, "Failed to get @Type.");
558
+ ExitOnRequiredXmlQueryFailure(hr, "Failed to get @Type.");
559
560
// @Code
561
hr = XmlGetAttributeEx(pixnNode, L"Code", &scz);
559
- ExitOnFailure(hr, "Failed to get @Code.");
562
+ ExitOnRequiredXmlQueryFailure(hr, "Failed to get @Code.");
563
564
if (L'*' == scz[0])
565
{
@@ -614,25 +617,26 @@ extern "C" HRESULT ExeEngineParseCommandLineArgumentsFromXml(
617
for (DWORD i = 0; i < cNodes; ++i)
618
{
619
BURN_EXE_COMMAND_LINE_ARGUMENT* pCommandLineArgument = *prgCommandLineArguments + i;
620
+ BOOL fFoundXml = FALSE;
621
622
hr = XmlNextElement(pixnNodes, &pixnNode, NULL);
623
ExitOnFailure(hr, "Failed to get next command-line argument node.");
624
625
// @InstallArgument
626
hr = XmlGetAttributeEx(pixnNode, L"InstallArgument", &pCommandLineArgument->sczInstallArgument);
623
- ExitOnFailure(hr, "Failed to get @InstallArgument.");
627
+ ExitOnOptionalXmlQueryFailure(hr, fFoundXml, "Failed to get @InstallArgument.");
628
629
// @UninstallArgument
630
hr = XmlGetAttributeEx(pixnNode, L"UninstallArgument", &pCommandLineArgument->sczUninstallArgument);
627
- ExitOnFailure(hr, "Failed to get @UninstallArgument.");
631
+ ExitOnOptionalXmlQueryFailure(hr, fFoundXml, "Failed to get @UninstallArgument.");
632
633
// @RepairArgument
634
hr = XmlGetAttributeEx(pixnNode, L"RepairArgument", &pCommandLineArgument->sczRepairArgument);
631
- ExitOnFailure(hr, "Failed to get @RepairArgument.");
635
+ ExitOnOptionalXmlQueryFailure(hr, fFoundXml, "Failed to get @RepairArgument.");
636
637
// @Condition
638
hr = XmlGetAttributeEx(pixnNode, L"Condition", &pCommandLineArgument->sczCondition);
635
- ExitOnFailure(hr, "Failed to get @Condition.");
639
+ ExitOnRequiredXmlQueryFailure(hr, "Failed to get @Condition.");
640
641
// Prepare next iteration.
642
ReleaseNullObject(pixnNode);
src/burn/engine/package.cpp
+17
@@ -235,6 +235,23 @@ extern "C" HRESULT PackagesParseFromXml(
235
// ignore other package types for now
236
}
237
238
+ if (!pPackage->fPermanent)
239
+ {
240
+ BOOL fUninstallable = TRUE;
241
+
242
+ switch (pPackage->type)
243
+ {
244
+ case BURN_PACKAGE_TYPE_EXE:
245
+ fUninstallable = pPackage->Exe.fUninstallable;
246
+ break;
247
+ }
248
+
249
+ if (!fUninstallable)
250
+ {
251
+ ExitWithRootFailure(hr, E_INVALIDDATA, "Non-permanent packages must be uninstallable.");
252
+ }
253
+ }
254
+
255
// parse payload references
256
hr = ParsePayloadRefsFromXml(pPackage, pPayloads, pixnNode);
257
ExitOnFailure(hr, "Failed to parse payload references.");
src/burn/engine/package.h
+1
@@ -323,6 +323,7 @@ typedef struct _BURN_PACKAGE
323
BOOL fPseudoBundle;
324
BOOL fFireAndForget;
325
BOOL fRepairable;
326
+ BOOL fUninstallable;
327
BURN_EXE_PROTOCOL_TYPE protocol;
328
329
BURN_EXE_EXIT_CODE* rgExitCodes;
src/burn/engine/pseudobundle.cpp
+1
@@ -115,6 +115,7 @@ extern "C" HRESULT PseudoBundleInitializePassthrough(
115
pPassthroughPackage->fPermanent = TRUE;
116
117
pPassthroughPackage->Exe.fPseudoBundle = TRUE;
118
+ pPassthroughPackage->Exe.fUninstallable = FALSE;
119
pPassthroughPackage->Exe.protocol = pPackage->Bundle.fSupportsBurnProtocol ? BURN_EXE_PROTOCOL_TYPE_BURN : BURN_EXE_PROTOCOL_TYPE_NONE;
120
121
hr = StrAllocString(&pPassthroughPackage->sczId, pPackage->sczId, 0);