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