diff options
author | Rob Mensching <rob@firegiant.com> | 2021-04-22 17:06:54 -0700 |
---|---|---|
committer | Rob Mensching <rob@firegiant.com> | 2021-04-29 16:36:06 -0700 |
commit | af10c45d7b3a44af0b461a557847fe03263dcc10 (patch) | |
tree | 6a5c1532304782c36ffe4200b38f3afb76789a43 /src/burn/engine/burnextension.cpp | |
parent | 9c2aed97299fb96aeee3f1471ce40225437aaecf (diff) | |
download | wix-af10c45d7b3a44af0b461a557847fe03263dcc10.tar.gz wix-af10c45d7b3a44af0b461a557847fe03263dcc10.tar.bz2 wix-af10c45d7b3a44af0b461a557847fe03263dcc10.zip |
Move burn into burn
Diffstat (limited to 'src/burn/engine/burnextension.cpp')
-rw-r--r-- | src/burn/engine/burnextension.cpp | 264 |
1 files changed, 264 insertions, 0 deletions
diff --git a/src/burn/engine/burnextension.cpp b/src/burn/engine/burnextension.cpp new file mode 100644 index 00000000..475df1c5 --- /dev/null +++ b/src/burn/engine/burnextension.cpp | |||
@@ -0,0 +1,264 @@ | |||
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 | |||
6 | static HRESULT SendRequiredBextMessage( | ||
7 | __in BURN_EXTENSION* pExtension, | ||
8 | __in BUNDLE_EXTENSION_MESSAGE message, | ||
9 | __in const LPVOID pvArgs, | ||
10 | __inout LPVOID pvResults | ||
11 | ); | ||
12 | |||
13 | // function definitions | ||
14 | |||
15 | /******************************************************************* | ||
16 | BurnExtensionParseFromXml - | ||
17 | |||
18 | *******************************************************************/ | ||
19 | EXTERN_C HRESULT BurnExtensionParseFromXml( | ||
20 | __in BURN_EXTENSIONS* pBurnExtensions, | ||
21 | __in BURN_PAYLOADS* pBaPayloads, | ||
22 | __in IXMLDOMNode* pixnBundle | ||
23 | ) | ||
24 | { | ||
25 | HRESULT hr = S_OK; | ||
26 | IXMLDOMNodeList* pixnNodes = NULL; | ||
27 | IXMLDOMNode* pixnNode = NULL; | ||
28 | DWORD cNodes = 0; | ||
29 | |||
30 | // Select BundleExtension nodes. | ||
31 | hr = XmlSelectNodes(pixnBundle, L"BundleExtension", &pixnNodes); | ||
32 | ExitOnFailure(hr, "Failed to select BundleExtension nodes."); | ||
33 | |||
34 | // Get BundleExtension node count. | ||
35 | hr = pixnNodes->get_length((long*)&cNodes); | ||
36 | ExitOnFailure(hr, "Failed to get BundleExtension node count."); | ||
37 | |||
38 | if (!cNodes) | ||
39 | { | ||
40 | ExitFunction(); | ||
41 | } | ||
42 | |||
43 | // Allocate memory for BundleExtensions. | ||
44 | pBurnExtensions->rgExtensions = (BURN_EXTENSION*)MemAlloc(sizeof(BURN_EXTENSION) * cNodes, TRUE); | ||
45 | ExitOnNull(pBurnExtensions->rgExtensions, hr, E_OUTOFMEMORY, "Failed to allocate memory for BundleExtension structs."); | ||
46 | |||
47 | pBurnExtensions->cExtensions = cNodes; | ||
48 | |||
49 | // parse search elements | ||
50 | for (DWORD i = 0; i < cNodes; ++i) | ||
51 | { | ||
52 | BURN_EXTENSION* pExtension = &pBurnExtensions->rgExtensions[i]; | ||
53 | |||
54 | hr = XmlNextElement(pixnNodes, &pixnNode, NULL); | ||
55 | ExitOnFailure(hr, "Failed to get next node."); | ||
56 | |||
57 | // @Id | ||
58 | hr = XmlGetAttributeEx(pixnNode, L"Id", &pExtension->sczId); | ||
59 | ExitOnFailure(hr, "Failed to get @Id."); | ||
60 | |||
61 | // @EntryPayloadId | ||
62 | hr = XmlGetAttributeEx(pixnNode, L"EntryPayloadId", &pExtension->sczEntryPayloadId); | ||
63 | ExitOnFailure(hr, "Failed to get @EntryPayloadId."); | ||
64 | |||
65 | hr = PayloadFindById(pBaPayloads, pExtension->sczEntryPayloadId, &pExtension->pEntryPayload); | ||
66 | ExitOnFailure(hr, "Failed to find BundleExtension EntryPayload '%ls'.", pExtension->sczEntryPayloadId); | ||
67 | |||
68 | // prepare next iteration | ||
69 | ReleaseNullObject(pixnNode); | ||
70 | } | ||
71 | |||
72 | hr = S_OK; | ||
73 | |||
74 | LExit: | ||
75 | ReleaseObject(pixnNode); | ||
76 | ReleaseObject(pixnNodes); | ||
77 | |||
78 | return hr; | ||
79 | } | ||
80 | |||
81 | /******************************************************************* | ||
82 | BurnExtensionUninitialize - | ||
83 | |||
84 | *******************************************************************/ | ||
85 | EXTERN_C void BurnExtensionUninitialize( | ||
86 | __in BURN_EXTENSIONS* pBurnExtensions | ||
87 | ) | ||
88 | { | ||
89 | if (pBurnExtensions->rgExtensions) | ||
90 | { | ||
91 | for (DWORD i = 0; i < pBurnExtensions->cExtensions; ++i) | ||
92 | { | ||
93 | BURN_EXTENSION* pExtension = &pBurnExtensions->rgExtensions[i]; | ||
94 | |||
95 | ReleaseStr(pExtension->sczEntryPayloadId); | ||
96 | ReleaseStr(pExtension->sczId); | ||
97 | } | ||
98 | MemFree(pBurnExtensions->rgExtensions); | ||
99 | } | ||
100 | |||
101 | // clear struct | ||
102 | memset(pBurnExtensions, 0, sizeof(BURN_EXTENSIONS)); | ||
103 | } | ||
104 | |||
105 | /******************************************************************* | ||
106 | BurnExtensionLoad - | ||
107 | |||
108 | *******************************************************************/ | ||
109 | EXTERN_C HRESULT BurnExtensionLoad( | ||
110 | __in BURN_EXTENSIONS * pBurnExtensions, | ||
111 | __in BURN_EXTENSION_ENGINE_CONTEXT* pEngineContext | ||
112 | ) | ||
113 | { | ||
114 | HRESULT hr = S_OK; | ||
115 | LPWSTR sczBundleExtensionDataPath = NULL; | ||
116 | BUNDLE_EXTENSION_CREATE_ARGS args = { }; | ||
117 | BUNDLE_EXTENSION_CREATE_RESULTS results = { }; | ||
118 | |||
119 | if (!pBurnExtensions->rgExtensions || !pBurnExtensions->cExtensions) | ||
120 | { | ||
121 | ExitFunction(); | ||
122 | } | ||
123 | |||
124 | hr = PathConcat(pEngineContext->pEngineState->userExperience.sczTempDirectory, L"BundleExtensionData.xml", &sczBundleExtensionDataPath); | ||
125 | ExitOnFailure(hr, "Failed to get BundleExtensionDataPath."); | ||
126 | |||
127 | for (DWORD i = 0; i < pBurnExtensions->cExtensions; ++i) | ||
128 | { | ||
129 | BURN_EXTENSION* pExtension = &pBurnExtensions->rgExtensions[i]; | ||
130 | |||
131 | memset(&args, 0, sizeof(BUNDLE_EXTENSION_CREATE_ARGS)); | ||
132 | memset(&results, 0, sizeof(BUNDLE_EXTENSION_CREATE_RESULTS)); | ||
133 | |||
134 | args.cbSize = sizeof(BUNDLE_EXTENSION_CREATE_ARGS); | ||
135 | args.pfnBundleExtensionEngineProc = EngineForExtensionProc; | ||
136 | args.pvBundleExtensionEngineProcContext = pEngineContext; | ||
137 | args.qwEngineAPIVersion = MAKEQWORDVERSION(2021, 4, 27, 0); | ||
138 | args.wzBootstrapperWorkingFolder = pEngineContext->pEngineState->userExperience.sczTempDirectory; | ||
139 | args.wzBundleExtensionDataPath = sczBundleExtensionDataPath; | ||
140 | args.wzExtensionId = pExtension->sczId; | ||
141 | |||
142 | results.cbSize = sizeof(BUNDLE_EXTENSION_CREATE_RESULTS); | ||
143 | |||
144 | // Load BundleExtension DLL. | ||
145 | pExtension->hBextModule = ::LoadLibraryExW(pExtension->pEntryPayload->sczLocalFilePath, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); | ||
146 | ExitOnNullWithLastError(pExtension->hBextModule, hr, "Failed to load BundleExtension DLL '%ls': '%ls'.", pExtension->sczId, pExtension->pEntryPayload->sczLocalFilePath); | ||
147 | |||
148 | // Get BundleExtensionCreate entry-point. | ||
149 | PFN_BUNDLE_EXTENSION_CREATE pfnCreate = (PFN_BUNDLE_EXTENSION_CREATE)::GetProcAddress(pExtension->hBextModule, "BundleExtensionCreate"); | ||
150 | ExitOnNullWithLastError(pfnCreate, hr, "Failed to get BundleExtensionCreate entry-point '%ls'.", pExtension->sczId); | ||
151 | |||
152 | // Create BundleExtension. | ||
153 | hr = pfnCreate(&args, &results); | ||
154 | ExitOnFailure(hr, "Failed to create BundleExtension '%ls'.", pExtension->sczId); | ||
155 | |||
156 | pExtension->pfnBurnExtensionProc = results.pfnBundleExtensionProc; | ||
157 | pExtension->pvBurnExtensionProcContext = results.pvBundleExtensionProcContext; | ||
158 | } | ||
159 | |||
160 | LExit: | ||
161 | ReleaseStr(sczBundleExtensionDataPath); | ||
162 | |||
163 | return hr; | ||
164 | } | ||
165 | |||
166 | /******************************************************************* | ||
167 | BurnExtensionUnload - | ||
168 | |||
169 | *******************************************************************/ | ||
170 | EXTERN_C void BurnExtensionUnload( | ||
171 | __in BURN_EXTENSIONS * pBurnExtensions | ||
172 | ) | ||
173 | { | ||
174 | HRESULT hr = S_OK; | ||
175 | |||
176 | if (pBurnExtensions->rgExtensions) | ||
177 | { | ||
178 | for (DWORD i = 0; i < pBurnExtensions->cExtensions; ++i) | ||
179 | { | ||
180 | BURN_EXTENSION* pExtension = &pBurnExtensions->rgExtensions[i]; | ||
181 | |||
182 | if (pExtension->hBextModule) | ||
183 | { | ||
184 | // Get BundleExtensionDestroy entry-point and call it if it exists. | ||
185 | PFN_BUNDLE_EXTENSION_DESTROY pfnDestroy = (PFN_BUNDLE_EXTENSION_DESTROY)::GetProcAddress(pExtension->hBextModule, "BundleExtensionDestroy"); | ||
186 | if (pfnDestroy) | ||
187 | { | ||
188 | pfnDestroy(); | ||
189 | } | ||
190 | |||
191 | // Free BundleExtension DLL. | ||
192 | if (!::FreeLibrary(pExtension->hBextModule)) | ||
193 | { | ||
194 | hr = HRESULT_FROM_WIN32(::GetLastError()); | ||
195 | TraceError(hr, "Failed to unload BundleExtension DLL."); | ||
196 | } | ||
197 | pExtension->hBextModule = NULL; | ||
198 | } | ||
199 | } | ||
200 | } | ||
201 | } | ||
202 | |||
203 | EXTERN_C HRESULT BurnExtensionFindById( | ||
204 | __in BURN_EXTENSIONS* pBurnExtensions, | ||
205 | __in_z LPCWSTR wzId, | ||
206 | __out BURN_EXTENSION** ppExtension | ||
207 | ) | ||
208 | { | ||
209 | HRESULT hr = S_OK; | ||
210 | BURN_EXTENSION* pExtension = NULL; | ||
211 | |||
212 | for (DWORD i = 0; i < pBurnExtensions->cExtensions; ++i) | ||
213 | { | ||
214 | pExtension = &pBurnExtensions->rgExtensions[i]; | ||
215 | |||
216 | if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, pExtension->sczId, -1, wzId, -1)) | ||
217 | { | ||
218 | *ppExtension = pExtension; | ||
219 | ExitFunction1(hr = S_OK); | ||
220 | } | ||
221 | } | ||
222 | |||
223 | hr = E_NOTFOUND; | ||
224 | |||
225 | LExit: | ||
226 | return hr; | ||
227 | } | ||
228 | |||
229 | EXTERN_C BEEAPI BurnExtensionPerformSearch( | ||
230 | __in BURN_EXTENSION* pExtension, | ||
231 | __in LPWSTR wzSearchId, | ||
232 | __in LPWSTR wzVariable | ||
233 | ) | ||
234 | { | ||
235 | HRESULT hr = S_OK; | ||
236 | BUNDLE_EXTENSION_SEARCH_ARGS args = { }; | ||
237 | BUNDLE_EXTENSION_SEARCH_RESULTS results = { }; | ||
238 | |||
239 | args.cbSize = sizeof(args); | ||
240 | args.wzId = wzSearchId; | ||
241 | args.wzVariable = wzVariable; | ||
242 | |||
243 | results.cbSize = sizeof(results); | ||
244 | |||
245 | hr = SendRequiredBextMessage(pExtension, BUNDLE_EXTENSION_MESSAGE_SEARCH, &args, &results); | ||
246 | ExitOnFailure(hr, "BundleExtension '%ls' Search '%ls' failed.", pExtension->sczId, wzSearchId); | ||
247 | |||
248 | LExit: | ||
249 | return hr; | ||
250 | } | ||
251 | |||
252 | static HRESULT SendRequiredBextMessage( | ||
253 | __in BURN_EXTENSION* pExtension, | ||
254 | __in BUNDLE_EXTENSION_MESSAGE message, | ||
255 | __in const LPVOID pvArgs, | ||
256 | __inout LPVOID pvResults | ||
257 | ) | ||
258 | { | ||
259 | HRESULT hr = S_OK; | ||
260 | |||
261 | hr = pExtension->pfnBurnExtensionProc(message, pvArgs, pvResults, pExtension->pvBurnExtensionProcContext); | ||
262 | |||
263 | return hr; | ||
264 | } | ||