aboutsummaryrefslogtreecommitdiff
path: root/src/api/burn/balutil/balcondition.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/api/burn/balutil/balcondition.cpp')
-rw-r--r--src/api/burn/balutil/balcondition.cpp124
1 files changed, 124 insertions, 0 deletions
diff --git a/src/api/burn/balutil/balcondition.cpp b/src/api/burn/balutil/balcondition.cpp
new file mode 100644
index 00000000..8b05508f
--- /dev/null
+++ b/src/api/burn/balutil/balcondition.cpp
@@ -0,0 +1,124 @@
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// prototypes
6
7
8DAPI_(HRESULT) BalConditionsParseFromXml(
9 __in BAL_CONDITIONS* pConditions,
10 __in IXMLDOMDocument* pixdManifest,
11 __in_opt WIX_LOCALIZATION* pWixLoc
12 )
13{
14 HRESULT hr = S_OK;
15 IXMLDOMNodeList* pNodeList = NULL;
16 IXMLDOMNode* pNode = NULL;
17 BAL_CONDITION* prgConditions = NULL;
18 DWORD cConditions = 0;
19
20 hr = XmlSelectNodes(pixdManifest, L"/BootstrapperApplicationData/WixBalCondition", &pNodeList);
21 ExitOnFailure(hr, "Failed to select all conditions.");
22
23 hr = pNodeList->get_length(reinterpret_cast<long*>(&cConditions));
24 ExitOnFailure(hr, "Failed to get the condition count.");
25
26 if (!cConditions)
27 {
28 ExitFunction();
29 }
30
31 prgConditions = static_cast<BAL_CONDITION*>(MemAlloc(sizeof(BAL_CONDITION) * cConditions, TRUE));
32 ExitOnNull(prgConditions, hr, E_OUTOFMEMORY, "Failed to allocate memory for conditions.");
33
34 DWORD iCondition = 0;
35 while (S_OK == (hr = XmlNextElement(pNodeList, &pNode, NULL)))
36 {
37 hr = XmlGetAttributeEx(pNode, L"Condition", &prgConditions[iCondition].sczCondition);
38 ExitOnFailure(hr, "Failed to get condition for condition.");
39
40 hr = XmlGetAttributeEx(pNode, L"Message", &prgConditions[iCondition].sczMessage);
41 ExitOnFailure(hr, "Failed to get message for condition.");
42
43 if (pWixLoc && prgConditions[iCondition].sczMessage && *prgConditions[iCondition].sczMessage)
44 {
45 hr = LocLocalizeString(pWixLoc, &prgConditions[iCondition].sczMessage);
46 ExitOnFailure(hr, "Failed to localize condition message.");
47 }
48
49 ++iCondition;
50 ReleaseNullObject(pNode);
51 }
52 ExitOnFailure(hr, "Failed to parse all condition elements.");
53
54 if (S_FALSE == hr)
55 {
56 hr = S_OK;
57 }
58
59 pConditions->cConditions = cConditions;
60 pConditions->rgConditions = prgConditions;
61 prgConditions = NULL;
62
63LExit:
64 ReleaseMem(prgConditions);
65 ReleaseObject(pNode);
66 ReleaseObject(pNodeList);
67
68 return hr;
69}
70
71
72//the contents of psczMessage may be sensitive, should keep encrypted and SecureZeroFree
73DAPI_(HRESULT) BalConditionEvaluate(
74 __in BAL_CONDITION* pCondition,
75 __in IBootstrapperEngine* pEngine,
76 __out BOOL* pfResult,
77 __out_z_opt LPWSTR* psczMessage
78 )
79{
80 HRESULT hr = S_OK;
81 SIZE_T cchMessage = 0;
82
83 hr = pEngine->EvaluateCondition(pCondition->sczCondition, pfResult);
84 ExitOnFailure(hr, "Failed to evaluate condition with bootstrapper engine.");
85
86 if (psczMessage)
87 {
88 if (*psczMessage)
89 {
90 hr = StrMaxLength(*psczMessage, &cchMessage);
91 ExitOnFailure(hr, "Failed to get length of message.");
92 }
93
94 hr = pEngine->FormatString(pCondition->sczMessage, *psczMessage, &cchMessage);
95 if (E_MOREDATA == hr)
96 {
97 ++cchMessage;
98
99 hr = StrAllocSecure(psczMessage, cchMessage);
100 ExitOnFailure(hr, "Failed to allocate string for condition's formatted message.");
101
102 hr = pEngine->FormatString(pCondition->sczMessage, *psczMessage, &cchMessage);
103 }
104 ExitOnFailure(hr, "Failed to format condition's message.");
105 }
106
107LExit:
108 return hr;
109}
110
111
112DAPI_(void) BalConditionsUninitialize(
113 __in BAL_CONDITIONS* pConditions
114 )
115{
116 for (DWORD i = 0; i < pConditions->cConditions; ++i)
117 {
118 ReleaseStr(pConditions->rgConditions[i].sczMessage);
119 ReleaseStr(pConditions->rgConditions[i].sczCondition);
120 }
121
122 ReleaseMem(pConditions->rgConditions);
123 memset(pConditions, 0, sizeof(BAL_CONDITIONS));
124}