aboutsummaryrefslogtreecommitdiff
path: root/src/burn/engine/burnextension.cpp
diff options
context:
space:
mode:
authorRob Mensching <rob@firegiant.com>2021-04-22 17:06:54 -0700
committerRob Mensching <rob@firegiant.com>2021-04-29 16:36:06 -0700
commitaf10c45d7b3a44af0b461a557847fe03263dcc10 (patch)
tree6a5c1532304782c36ffe4200b38f3afb76789a43 /src/burn/engine/burnextension.cpp
parent9c2aed97299fb96aeee3f1471ce40225437aaecf (diff)
downloadwix-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.cpp264
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
6static 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*******************************************************************/
19EXTERN_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
74LExit:
75 ReleaseObject(pixnNode);
76 ReleaseObject(pixnNodes);
77
78 return hr;
79}
80
81/*******************************************************************
82 BurnExtensionUninitialize -
83
84*******************************************************************/
85EXTERN_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*******************************************************************/
109EXTERN_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
160LExit:
161 ReleaseStr(sczBundleExtensionDataPath);
162
163 return hr;
164}
165
166/*******************************************************************
167 BurnExtensionUnload -
168
169*******************************************************************/
170EXTERN_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
203EXTERN_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
225LExit:
226 return hr;
227}
228
229EXTERN_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
248LExit:
249 return hr;
250}
251
252static 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}