diff options
author | Sean Hall <r.sean.hall@gmail.com> | 2022-01-16 12:17:27 -0600 |
---|---|---|
committer | Sean Hall <r.sean.hall@gmail.com> | 2022-01-16 22:59:50 -0600 |
commit | f5d880cc70ad7350b0da1ea825141f95cbdb4c7b (patch) | |
tree | 32a16f0d57fc17e8de83eb5d35783a1ef6fa7ab5 | |
parent | 934cacdc8fc7c35c94d3b1eee6cc8ab5c8a8ce4d (diff) | |
download | wix-f5d880cc70ad7350b0da1ea825141f95cbdb4c7b.tar.gz wix-f5d880cc70ad7350b0da1ea825141f95cbdb4c7b.tar.bz2 wix-f5d880cc70ad7350b0da1ea825141f95cbdb4c7b.zip |
Update Burn to handle ExePackages that don't support uninstalling.
Partial fix for #6459
-rw-r--r-- | src/burn/engine/exeengine.cpp | 44 | ||||
-rw-r--r-- | src/burn/engine/package.cpp | 17 | ||||
-rw-r--r-- | src/burn/engine/package.h | 1 | ||||
-rw-r--r-- | src/burn/engine/pseudobundle.cpp | 1 |
4 files changed, 43 insertions, 20 deletions
diff --git a/src/burn/engine/exeengine.cpp b/src/burn/engine/exeengine.cpp index 7a36f882..cf10448f 100644 --- a/src/burn/engine/exeengine.cpp +++ b/src/burn/engine/exeengine.cpp | |||
@@ -11,36 +11,43 @@ extern "C" HRESULT ExeEngineParsePackageFromXml( | |||
11 | ) | 11 | ) |
12 | { | 12 | { |
13 | HRESULT hr = S_OK; | 13 | HRESULT hr = S_OK; |
14 | BOOL fFoundXml = FALSE; | ||
14 | IXMLDOMNodeList* pixnNodes = NULL; | 15 | IXMLDOMNodeList* pixnNodes = NULL; |
15 | IXMLDOMNode* pixnNode = NULL; | 16 | IXMLDOMNode* pixnNode = NULL; |
16 | LPWSTR scz = NULL; | 17 | LPWSTR scz = NULL; |
17 | 18 | ||
18 | // @DetectCondition | 19 | // @DetectCondition |
19 | hr = XmlGetAttributeEx(pixnExePackage, L"DetectCondition", &pPackage->Exe.sczDetectCondition); | 20 | hr = XmlGetAttributeEx(pixnExePackage, L"DetectCondition", &pPackage->Exe.sczDetectCondition); |
20 | ExitOnFailure(hr, "Failed to get @DetectCondition."); | 21 | ExitOnOptionalXmlQueryFailure(hr, fFoundXml, "Failed to get @DetectCondition."); |
21 | 22 | ||
22 | // @InstallArguments | 23 | // @InstallArguments |
23 | hr = XmlGetAttributeEx(pixnExePackage, L"InstallArguments", &pPackage->Exe.sczInstallArguments); | 24 | hr = XmlGetAttributeEx(pixnExePackage, L"InstallArguments", &pPackage->Exe.sczInstallArguments); |
24 | ExitOnFailure(hr, "Failed to get @InstallArguments."); | 25 | ExitOnOptionalXmlQueryFailure(hr, fFoundXml, "Failed to get @InstallArguments."); |
25 | 26 | ||
26 | // @UninstallArguments | 27 | // @UninstallArguments |
27 | hr = XmlGetAttributeEx(pixnExePackage, L"UninstallArguments", &pPackage->Exe.sczUninstallArguments); | 28 | hr = XmlGetAttributeEx(pixnExePackage, L"UninstallArguments", &pPackage->Exe.sczUninstallArguments); |
28 | ExitOnFailure(hr, "Failed to get @UninstallArguments."); | 29 | ExitOnOptionalXmlQueryFailure(hr, fFoundXml, "Failed to get @UninstallArguments."); |
29 | 30 | ||
30 | // @RepairArguments | 31 | // @RepairArguments |
31 | hr = XmlGetAttributeEx(pixnExePackage, L"RepairArguments", &pPackage->Exe.sczRepairArguments); | 32 | hr = XmlGetAttributeEx(pixnExePackage, L"RepairArguments", &pPackage->Exe.sczRepairArguments); |
32 | ExitOnFailure(hr, "Failed to get @RepairArguments."); | 33 | ExitOnOptionalXmlQueryFailure(hr, fFoundXml, "Failed to get @RepairArguments."); |
33 | 34 | ||
34 | // @Repairable | 35 | // @Repairable |
35 | hr = XmlGetYesNoAttribute(pixnExePackage, L"Repairable", &pPackage->Exe.fRepairable); | 36 | hr = XmlGetYesNoAttribute(pixnExePackage, L"Repairable", &pPackage->Exe.fRepairable); |
36 | if (E_NOTFOUND != hr) | 37 | ExitOnOptionalXmlQueryFailure(hr, fFoundXml, "Failed to get @Repairable."); |
37 | { | 38 | |
38 | ExitOnFailure(hr, "Failed to get @Repairable."); | 39 | // @Uninstallable |
39 | } | 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 | */ | ||
40 | 45 | ||
41 | // @Protocol | 46 | // @Protocol |
42 | hr = XmlGetAttributeEx(pixnExePackage, L"Protocol", &scz); | 47 | hr = XmlGetAttributeEx(pixnExePackage, L"Protocol", &scz); |
43 | if (SUCCEEDED(hr)) | 48 | ExitOnOptionalXmlQueryFailure(hr, fFoundXml, "Failed to get @Protocol."); |
49 | |||
50 | if (fFoundXml) | ||
44 | { | 51 | { |
45 | if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"burn", -1)) | 52 | if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"burn", -1)) |
46 | { | 53 | { |
@@ -60,10 +67,6 @@ extern "C" HRESULT ExeEngineParsePackageFromXml( | |||
60 | ExitOnFailure(hr, "Invalid protocol type: %ls", scz); | 67 | ExitOnFailure(hr, "Invalid protocol type: %ls", scz); |
61 | } | 68 | } |
62 | } | 69 | } |
63 | else if (E_NOTFOUND != hr) | ||
64 | { | ||
65 | ExitOnFailure(hr, "Failed to get @Protocol."); | ||
66 | } | ||
67 | 70 | ||
68 | hr = ExeEngineParseExitCodesFromXml(pixnExePackage, &pPackage->Exe.rgExitCodes, &pPackage->Exe.cExitCodes); | 71 | hr = ExeEngineParseExitCodesFromXml(pixnExePackage, &pPackage->Exe.rgExitCodes, &pPackage->Exe.cExitCodes); |
69 | ExitOnFailure(hr, "Failed to parse exit codes."); | 72 | ExitOnFailure(hr, "Failed to parse exit codes."); |
@@ -172,7 +175,7 @@ extern "C" HRESULT ExeEnginePlanCalculatePackage( | |||
172 | execute = !pPackage->fPermanent ? BOOTSTRAPPER_ACTION_STATE_UNINSTALL : BOOTSTRAPPER_ACTION_STATE_NONE; | 175 | execute = !pPackage->fPermanent ? BOOTSTRAPPER_ACTION_STATE_UNINSTALL : BOOTSTRAPPER_ACTION_STATE_NONE; |
173 | break; | 176 | break; |
174 | case BOOTSTRAPPER_REQUEST_STATE_FORCE_ABSENT: | 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; |
176 | break; | 179 | break; |
177 | default: | 180 | default: |
178 | execute = BOOTSTRAPPER_ACTION_STATE_NONE; | 181 | execute = BOOTSTRAPPER_ACTION_STATE_NONE; |
@@ -552,11 +555,11 @@ extern "C" HRESULT ExeEngineParseExitCodesFromXml( | |||
552 | 555 | ||
553 | // @Type | 556 | // @Type |
554 | hr = XmlGetAttributeNumber(pixnNode, L"Type", (DWORD*)&pExitCode->type); | 557 | hr = XmlGetAttributeNumber(pixnNode, L"Type", (DWORD*)&pExitCode->type); |
555 | ExitOnFailure(hr, "Failed to get @Type."); | 558 | ExitOnRequiredXmlQueryFailure(hr, "Failed to get @Type."); |
556 | 559 | ||
557 | // @Code | 560 | // @Code |
558 | hr = XmlGetAttributeEx(pixnNode, L"Code", &scz); | 561 | hr = XmlGetAttributeEx(pixnNode, L"Code", &scz); |
559 | ExitOnFailure(hr, "Failed to get @Code."); | 562 | ExitOnRequiredXmlQueryFailure(hr, "Failed to get @Code."); |
560 | 563 | ||
561 | if (L'*' == scz[0]) | 564 | if (L'*' == scz[0]) |
562 | { | 565 | { |
@@ -614,25 +617,26 @@ extern "C" HRESULT ExeEngineParseCommandLineArgumentsFromXml( | |||
614 | for (DWORD i = 0; i < cNodes; ++i) | 617 | for (DWORD i = 0; i < cNodes; ++i) |
615 | { | 618 | { |
616 | BURN_EXE_COMMAND_LINE_ARGUMENT* pCommandLineArgument = *prgCommandLineArguments + i; | 619 | BURN_EXE_COMMAND_LINE_ARGUMENT* pCommandLineArgument = *prgCommandLineArguments + i; |
620 | BOOL fFoundXml = FALSE; | ||
617 | 621 | ||
618 | hr = XmlNextElement(pixnNodes, &pixnNode, NULL); | 622 | hr = XmlNextElement(pixnNodes, &pixnNode, NULL); |
619 | ExitOnFailure(hr, "Failed to get next command-line argument node."); | 623 | ExitOnFailure(hr, "Failed to get next command-line argument node."); |
620 | 624 | ||
621 | // @InstallArgument | 625 | // @InstallArgument |
622 | hr = XmlGetAttributeEx(pixnNode, L"InstallArgument", &pCommandLineArgument->sczInstallArgument); | 626 | hr = XmlGetAttributeEx(pixnNode, L"InstallArgument", &pCommandLineArgument->sczInstallArgument); |
623 | ExitOnFailure(hr, "Failed to get @InstallArgument."); | 627 | ExitOnOptionalXmlQueryFailure(hr, fFoundXml, "Failed to get @InstallArgument."); |
624 | 628 | ||
625 | // @UninstallArgument | 629 | // @UninstallArgument |
626 | hr = XmlGetAttributeEx(pixnNode, L"UninstallArgument", &pCommandLineArgument->sczUninstallArgument); | 630 | hr = XmlGetAttributeEx(pixnNode, L"UninstallArgument", &pCommandLineArgument->sczUninstallArgument); |
627 | ExitOnFailure(hr, "Failed to get @UninstallArgument."); | 631 | ExitOnOptionalXmlQueryFailure(hr, fFoundXml, "Failed to get @UninstallArgument."); |
628 | 632 | ||
629 | // @RepairArgument | 633 | // @RepairArgument |
630 | hr = XmlGetAttributeEx(pixnNode, L"RepairArgument", &pCommandLineArgument->sczRepairArgument); | 634 | hr = XmlGetAttributeEx(pixnNode, L"RepairArgument", &pCommandLineArgument->sczRepairArgument); |
631 | ExitOnFailure(hr, "Failed to get @RepairArgument."); | 635 | ExitOnOptionalXmlQueryFailure(hr, fFoundXml, "Failed to get @RepairArgument."); |
632 | 636 | ||
633 | // @Condition | 637 | // @Condition |
634 | hr = XmlGetAttributeEx(pixnNode, L"Condition", &pCommandLineArgument->sczCondition); | 638 | hr = XmlGetAttributeEx(pixnNode, L"Condition", &pCommandLineArgument->sczCondition); |
635 | ExitOnFailure(hr, "Failed to get @Condition."); | 639 | ExitOnRequiredXmlQueryFailure(hr, "Failed to get @Condition."); |
636 | 640 | ||
637 | // Prepare next iteration. | 641 | // Prepare next iteration. |
638 | ReleaseNullObject(pixnNode); | 642 | ReleaseNullObject(pixnNode); |
diff --git a/src/burn/engine/package.cpp b/src/burn/engine/package.cpp index 20b728f4..72da817f 100644 --- a/src/burn/engine/package.cpp +++ b/src/burn/engine/package.cpp | |||
@@ -235,6 +235,23 @@ extern "C" HRESULT PackagesParseFromXml( | |||
235 | // ignore other package types for now | 235 | // ignore other package types for now |
236 | } | 236 | } |
237 | 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 | |||
238 | // parse payload references | 255 | // parse payload references |
239 | hr = ParsePayloadRefsFromXml(pPackage, pPayloads, pixnNode); | 256 | hr = ParsePayloadRefsFromXml(pPackage, pPayloads, pixnNode); |
240 | ExitOnFailure(hr, "Failed to parse payload references."); | 257 | ExitOnFailure(hr, "Failed to parse payload references."); |
diff --git a/src/burn/engine/package.h b/src/burn/engine/package.h index 5a7aefa3..91bad1bc 100644 --- a/src/burn/engine/package.h +++ b/src/burn/engine/package.h | |||
@@ -323,6 +323,7 @@ typedef struct _BURN_PACKAGE | |||
323 | BOOL fPseudoBundle; | 323 | BOOL fPseudoBundle; |
324 | BOOL fFireAndForget; | 324 | BOOL fFireAndForget; |
325 | BOOL fRepairable; | 325 | BOOL fRepairable; |
326 | BOOL fUninstallable; | ||
326 | BURN_EXE_PROTOCOL_TYPE protocol; | 327 | BURN_EXE_PROTOCOL_TYPE protocol; |
327 | 328 | ||
328 | BURN_EXE_EXIT_CODE* rgExitCodes; | 329 | BURN_EXE_EXIT_CODE* rgExitCodes; |
diff --git a/src/burn/engine/pseudobundle.cpp b/src/burn/engine/pseudobundle.cpp index b343f810..153d76e6 100644 --- a/src/burn/engine/pseudobundle.cpp +++ b/src/burn/engine/pseudobundle.cpp | |||
@@ -115,6 +115,7 @@ extern "C" HRESULT PseudoBundleInitializePassthrough( | |||
115 | pPassthroughPackage->fPermanent = TRUE; | 115 | pPassthroughPackage->fPermanent = TRUE; |
116 | 116 | ||
117 | pPassthroughPackage->Exe.fPseudoBundle = TRUE; | 117 | pPassthroughPackage->Exe.fPseudoBundle = TRUE; |
118 | pPassthroughPackage->Exe.fUninstallable = FALSE; | ||
118 | pPassthroughPackage->Exe.protocol = pPackage->Bundle.fSupportsBurnProtocol ? BURN_EXE_PROTOCOL_TYPE_BURN : BURN_EXE_PROTOCOL_TYPE_NONE; | 119 | pPassthroughPackage->Exe.protocol = pPackage->Bundle.fSupportsBurnProtocol ? BURN_EXE_PROTOCOL_TYPE_BURN : BURN_EXE_PROTOCOL_TYPE_NONE; |
119 | 120 | ||
120 | hr = StrAllocString(&pPassthroughPackage->sczId, pPackage->sczId, 0); | 121 | hr = StrAllocString(&pPassthroughPackage->sczId, pPackage->sczId, 0); |