main
cpp 221 lines 5.28 KB
Raw
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 IBootstrapperExtensionEngine* vpEngine = NULL;
6
7 // prototypes
8
9 DAPI_(void) BextInitialize(
10 __in IBootstrapperExtensionEngine* pEngine
11 )
12 {
13 pEngine->AddRef();
14
15 ReleaseObject(vpEngine);
16 vpEngine = pEngine;
17 }
18
19 DAPI_(HRESULT) BextInitializeFromCreateArgs(
20 __in const BOOTSTRAPPER_EXTENSION_CREATE_ARGS* pArgs,
21 __out_opt IBootstrapperExtensionEngine** ppEngine
22 )
23 {
24 HRESULT hr = S_OK;
25 IBootstrapperExtensionEngine* pEngine = NULL;
26
27 hr = BextBootstrapperExtensionEngineCreate(pArgs->pfnBootstrapperExtensionEngineProc, pArgs->pvBootstrapperExtensionEngineProcContext, &pEngine);
28 ExitOnFailure(hr, "Failed to create BextBootstrapperExtensionEngine.");
29
30 BextInitialize(pEngine);
31
32 if (ppEngine)
33 {
34 *ppEngine = pEngine;
35 }
36 pEngine = NULL;
37
38 LExit:
39 ReleaseObject(pEngine);
40
41 return hr;
42 }
43
44
45 DAPI_(void) BextUninitialize()
46 {
47 ReleaseNullObject(vpEngine);
48 }
49
50 DAPI_(HRESULT) BextGetBootstrapperExtensionDataNode(
51 __in IXMLDOMDocument* pixdManifest,
52 __in LPCWSTR wzExtensionId,
53 __out IXMLDOMNode** ppixnBootstrapperExtension
54 )
55 {
56 HRESULT hr = S_OK;
57 IXMLDOMElement* pixeBootstrapperExtensionData = NULL;
58 IXMLDOMNodeList* pixnNodes = NULL;
59 IXMLDOMNode* pixnNode = NULL;
60 DWORD cNodes = 0;
61 LPWSTR sczId = NULL;
62
63 // Get BootstrapperExtensionData element.
64 hr = pixdManifest->get_documentElement(&pixeBootstrapperExtensionData);
65 ExitOnFailure(hr, "Failed to get BootstrapperExtensionData element.");
66
67 // Select BootstrapperExtension nodes.
68 hr = XmlSelectNodes(pixeBootstrapperExtensionData, L"BootstrapperExtension", &pixnNodes);
69 ExitOnFailure(hr, "Failed to select BootstrapperExtension nodes.");
70
71 // Get BootstrapperExtension node count.
72 hr = pixnNodes->get_length((long*)&cNodes);
73 ExitOnFailure(hr, "Failed to get BootstrapperExtension node count.");
74
75 if (!cNodes)
76 {
77 ExitFunction();
78 }
79
80 // Find requested extension.
81 for (DWORD i = 0; i < cNodes; ++i)
82 {
83 hr = XmlNextElement(pixnNodes, &pixnNode, NULL);
84 ExitOnFailure(hr, "Failed to get next node.");
85
86 // @Id
87 hr = XmlGetAttributeEx(pixnNode, L"Id", &sczId);
88 ExitOnRequiredXmlQueryFailure(hr, "Failed to get @Id.");
89
90 if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, sczId, -1, wzExtensionId, -1))
91 {
92 *ppixnBootstrapperExtension = pixnNode;
93 pixnNode = NULL;
94
95 ExitFunction1(hr = S_OK);
96 }
97
98 // Prepare next iteration.
99 ReleaseNullObject(pixnNode);
100 }
101
102 hr = E_NOTFOUND;
103
104 LExit:
105 ReleaseStr(sczId);
106 ReleaseObject(pixnNode);
107 ReleaseObject(pixnNodes);
108 ReleaseObject(pixeBootstrapperExtensionData);
109
110 return hr;
111 }
112
113
114 DAPIV_(HRESULT) BextLog(
115 __in BOOTSTRAPPER_EXTENSION_LOG_LEVEL level,
116 __in_z __format_string LPCSTR szFormat,
117 ...
118 )
119 {
120 HRESULT hr = S_OK;
121 va_list args;
122
123 if (!vpEngine)
124 {
125 hr = E_POINTER;
126 ExitOnRootFailure(hr, "BextInitialize() must be called first.");
127 }
128
129 va_start(args, szFormat);
130 hr = BextLogArgs(level, szFormat, args);
131 va_end(args);
132
133 LExit:
134 return hr;
135 }
136
137
138 DAPI_(HRESULT) BextLogArgs(
139 __in BOOTSTRAPPER_EXTENSION_LOG_LEVEL level,
140 __in_z __format_string LPCSTR szFormat,
141 __in va_list args
142 )
143 {
144 HRESULT hr = S_OK;
145 LPSTR sczFormattedAnsi = NULL;
146 LPWSTR sczMessage = NULL;
147
148 if (!vpEngine)
149 {
150 hr = E_POINTER;
151 ExitOnRootFailure(hr, "BextInitialize() must be called first.");
152 }
153
154 hr = StrAnsiAllocFormattedArgs(&sczFormattedAnsi, szFormat, args);
155 ExitOnFailure(hr, "Failed to format log string.");
156
157 hr = StrAllocStringAnsi(&sczMessage, sczFormattedAnsi, 0, CP_UTF8);
158 ExitOnFailure(hr, "Failed to convert log string to Unicode.");
159
160 hr = vpEngine->Log(level, sczMessage);
161
162 LExit:
163 ReleaseStr(sczMessage);
164 ReleaseStr(sczFormattedAnsi);
165 return hr;
166 }
167
168
169 DAPIV_(HRESULT) BextLogError(
170 __in HRESULT hrError,
171 __in_z __format_string LPCSTR szFormat,
172 ...
173 )
174 {
175 HRESULT hr = S_OK;
176 va_list args;
177
178 if (!vpEngine)
179 {
180 hr = E_POINTER;
181 ExitOnRootFailure(hr, "BextInitialize() must be called first.");
182 }
183
184 va_start(args, szFormat);
185 hr = BextLogErrorArgs(hrError, szFormat, args);
186 va_end(args);
187
188 LExit:
189 return hr;
190 }
191
192
193 DAPI_(HRESULT) BextLogErrorArgs(
194 __in HRESULT hrError,
195 __in_z __format_string LPCSTR szFormat,
196 __in va_list args
197 )
198 {
199 HRESULT hr = S_OK;
200 LPSTR sczFormattedAnsi = NULL;
201 LPWSTR sczMessage = NULL;
202
203 if (!vpEngine)
204 {
205 hr = E_POINTER;
206 ExitOnRootFailure(hr, "BextInitialize() must be called first.");
207 }
208
209 hr = StrAnsiAllocFormattedArgs(&sczFormattedAnsi, szFormat, args);
210 ExitOnFailure(hr, "Failed to format error log string.");
211
212 hr = StrAllocFormatted(&sczMessage, L"Error 0x%08x: %S", hrError, sczFormattedAnsi);
213 ExitOnFailure(hr, "Failed to prepend error number to error log string.");
214
215 hr = vpEngine->Log(BOOTSTRAPPER_EXTENSION_LOG_LEVEL_ERROR, sczMessage);
216
217 LExit:
218 ReleaseStr(sczMessage);
219 ReleaseStr(sczFormattedAnsi);
220 return hr;
221 }