aboutsummaryrefslogtreecommitdiff
path: root/src/engine/payload.cpp
diff options
context:
space:
mode:
authorSean Hall <r.sean.hall@gmail.com>2018-12-29 22:12:08 -0600
committerSean Hall <r.sean.hall@gmail.com>2018-12-29 22:12:08 -0600
commit61847dddd4fd497057c780658e383c4627de19ec (patch)
treef85a845182922538ab9aa6ee85b0db3ab40c1f6e /src/engine/payload.cpp
parent8295f5f8fd28042e1a0a172d5afbba79178064c2 (diff)
downloadwix-61847dddd4fd497057c780658e383c4627de19ec.tar.gz
wix-61847dddd4fd497057c780658e383c4627de19ec.tar.bz2
wix-61847dddd4fd497057c780658e383c4627de19ec.zip
Import code from old v4 repo
Diffstat (limited to 'src/engine/payload.cpp')
-rw-r--r--src/engine/payload.cpp367
1 files changed, 367 insertions, 0 deletions
diff --git a/src/engine/payload.cpp b/src/engine/payload.cpp
new file mode 100644
index 00000000..6833288f
--- /dev/null
+++ b/src/engine/payload.cpp
@@ -0,0 +1,367 @@
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// internal function declarations
7
8static HRESULT FindEmbeddedBySourcePath(
9 __in BURN_PAYLOADS* pPayloads,
10 __in_opt BURN_CONTAINER* pContainer,
11 __in_z LPCWSTR wzStreamName,
12 __out BURN_PAYLOAD** ppPayload
13 );
14
15
16// function definitions
17
18extern "C" HRESULT PayloadsParseFromXml(
19 __in BURN_PAYLOADS* pPayloads,
20 __in_opt BURN_CONTAINERS* pContainers,
21 __in_opt BURN_CATALOGS* pCatalogs,
22 __in IXMLDOMNode* pixnBundle
23 )
24{
25 HRESULT hr = S_OK;
26 IXMLDOMNodeList* pixnNodes = NULL;
27 IXMLDOMNode* pixnNode = NULL;
28 DWORD cNodes = 0;
29 LPWSTR scz = NULL;
30
31 // select payload nodes
32 hr = XmlSelectNodes(pixnBundle, L"Payload", &pixnNodes);
33 ExitOnFailure(hr, "Failed to select payload nodes.");
34
35 // get payload node count
36 hr = pixnNodes->get_length((long*)&cNodes);
37 ExitOnFailure(hr, "Failed to get payload node count.");
38
39 if (!cNodes)
40 {
41 ExitFunction();
42 }
43
44 // allocate memory for payloads
45 pPayloads->rgPayloads = (BURN_PAYLOAD*)MemAlloc(sizeof(BURN_PAYLOAD) * cNodes, TRUE);
46 ExitOnNull(pPayloads->rgPayloads, hr, E_OUTOFMEMORY, "Failed to allocate memory for payload structs.");
47
48 pPayloads->cPayloads = cNodes;
49
50 // parse search elements
51 for (DWORD i = 0; i < cNodes; ++i)
52 {
53 BURN_PAYLOAD* pPayload = &pPayloads->rgPayloads[i];
54
55 hr = XmlNextElement(pixnNodes, &pixnNode, NULL);
56 ExitOnFailure(hr, "Failed to get next node.");
57
58 // @Id
59 hr = XmlGetAttributeEx(pixnNode, L"Id", &pPayload->sczKey);
60 ExitOnFailure(hr, "Failed to get @Id.");
61
62 // @FilePath
63 hr = XmlGetAttributeEx(pixnNode, L"FilePath", &pPayload->sczFilePath);
64 ExitOnFailure(hr, "Failed to get @FilePath.");
65
66 // @Packaging
67 hr = XmlGetAttributeEx(pixnNode, L"Packaging", &scz);
68 ExitOnFailure(hr, "Failed to get @Packaging.");
69
70 if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"download", -1))
71 {
72 pPayload->packaging = BURN_PAYLOAD_PACKAGING_DOWNLOAD;
73 }
74 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"embedded", -1))
75 {
76 pPayload->packaging = BURN_PAYLOAD_PACKAGING_EMBEDDED;
77 }
78 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"external", -1))
79 {
80 pPayload->packaging = BURN_PAYLOAD_PACKAGING_EXTERNAL;
81 }
82 else
83 {
84 hr = E_INVALIDARG;
85 ExitOnFailure(hr, "Invalid value for @Packaging: %ls", scz);
86 }
87
88 // @Container
89 if (pContainers)
90 {
91 hr = XmlGetAttributeEx(pixnNode, L"Container", &scz);
92 if (E_NOTFOUND != hr || BURN_PAYLOAD_PACKAGING_EMBEDDED == pPayload->packaging)
93 {
94 ExitOnFailure(hr, "Failed to get @Container.");
95
96 // find container
97 hr = ContainerFindById(pContainers, scz, &pPayload->pContainer);
98 ExitOnFailure(hr, "Failed to to find container: %ls", scz);
99 }
100 }
101
102 // @LayoutOnly
103 hr = XmlGetYesNoAttribute(pixnNode, L"LayoutOnly", &pPayload->fLayoutOnly);
104 if (E_NOTFOUND != hr)
105 {
106 ExitOnFailure(hr, "Failed to get @LayoutOnly.");
107 }
108
109 // @SourcePath
110 hr = XmlGetAttributeEx(pixnNode, L"SourcePath", &pPayload->sczSourcePath);
111 if (E_NOTFOUND != hr || BURN_PAYLOAD_PACKAGING_DOWNLOAD != pPayload->packaging)
112 {
113 ExitOnFailure(hr, "Failed to get @SourcePath.");
114 }
115
116 // @DownloadUrl
117 hr = XmlGetAttributeEx(pixnNode, L"DownloadUrl", &pPayload->downloadSource.sczUrl);
118 if (E_NOTFOUND != hr || BURN_PAYLOAD_PACKAGING_DOWNLOAD == pPayload->packaging)
119 {
120 ExitOnFailure(hr, "Failed to get @DownloadUrl.");
121 }
122
123 // @FileSize
124 hr = XmlGetAttributeEx(pixnNode, L"FileSize", &scz);
125 if (E_NOTFOUND != hr)
126 {
127 ExitOnFailure(hr, "Failed to get @FileSize.");
128
129 hr = StrStringToUInt64(scz, 0, &pPayload->qwFileSize);
130 ExitOnFailure(hr, "Failed to parse @FileSize.");
131 }
132
133 // @CertificateAuthorityKeyIdentifier
134 hr = XmlGetAttributeEx(pixnNode, L"CertificateRootPublicKeyIdentifier", &scz);
135 if (E_NOTFOUND != hr)
136 {
137 ExitOnFailure(hr, "Failed to get @CertificateRootPublicKeyIdentifier.");
138
139 hr = StrAllocHexDecode(scz, &pPayload->pbCertificateRootPublicKeyIdentifier, &pPayload->cbCertificateRootPublicKeyIdentifier);
140 ExitOnFailure(hr, "Failed to hex decode @CertificateRootPublicKeyIdentifier.");
141 }
142
143 // @CertificateThumbprint
144 hr = XmlGetAttributeEx(pixnNode, L"CertificateRootThumbprint", &scz);
145 if (E_NOTFOUND != hr)
146 {
147 ExitOnFailure(hr, "Failed to get @CertificateRootThumbprint.");
148
149 hr = StrAllocHexDecode(scz, &pPayload->pbCertificateRootThumbprint, &pPayload->cbCertificateRootThumbprint);
150 ExitOnFailure(hr, "Failed to hex decode @CertificateRootThumbprint.");
151 }
152
153 // @Hash
154 hr = XmlGetAttributeEx(pixnNode, L"Hash", &scz);
155 ExitOnFailure(hr, "Failed to get @Hash.");
156
157 hr = StrAllocHexDecode(scz, &pPayload->pbHash, &pPayload->cbHash);
158 ExitOnFailure(hr, "Failed to hex decode the Payload/@Hash.");
159
160 // @Catalog
161 hr = XmlGetAttributeEx(pixnNode, L"Catalog", &scz);
162 if (E_NOTFOUND != hr)
163 {
164 ExitOnFailure(hr, "Failed to get @Catalog.");
165
166 hr = CatalogFindById(pCatalogs, scz, &pPayload->pCatalog);
167 ExitOnFailure(hr, "Failed to find catalog.");
168 }
169
170 // prepare next iteration
171 ReleaseNullObject(pixnNode);
172 }
173
174 hr = S_OK;
175
176LExit:
177 ReleaseObject(pixnNodes);
178 ReleaseObject(pixnNode);
179 ReleaseStr(scz);
180
181 return hr;
182}
183
184extern "C" void PayloadsUninitialize(
185 __in BURN_PAYLOADS* pPayloads
186 )
187{
188 if (pPayloads->rgPayloads)
189 {
190 for (DWORD i = 0; i < pPayloads->cPayloads; ++i)
191 {
192 BURN_PAYLOAD* pPayload = &pPayloads->rgPayloads[i];
193
194 ReleaseStr(pPayload->sczKey);
195 ReleaseStr(pPayload->sczFilePath);
196 ReleaseMem(pPayload->pbHash);
197 ReleaseMem(pPayload->pbCertificateRootThumbprint);
198 ReleaseMem(pPayload->pbCertificateRootPublicKeyIdentifier);
199 ReleaseStr(pPayload->sczSourcePath);
200 ReleaseStr(pPayload->sczLocalFilePath);
201 ReleaseStr(pPayload->downloadSource.sczUrl);
202 ReleaseStr(pPayload->downloadSource.sczUser);
203 ReleaseStr(pPayload->downloadSource.sczPassword);
204 }
205 MemFree(pPayloads->rgPayloads);
206 }
207
208 // clear struct
209 memset(pPayloads, 0, sizeof(BURN_PAYLOADS));
210}
211
212extern "C" HRESULT PayloadExtractFromContainer(
213 __in BURN_PAYLOADS* pPayloads,
214 __in_opt BURN_CONTAINER* pContainer,
215 __in BURN_CONTAINER_CONTEXT* pContainerContext,
216 __in_z LPCWSTR wzTargetDir
217 )
218{
219 HRESULT hr = S_OK;
220 LPWSTR sczStreamName = NULL;
221 LPWSTR sczDirectory = NULL;
222 BURN_PAYLOAD* pPayload = NULL;
223
224 // extract all payloads
225 for (;;)
226 {
227 // get next stream
228 hr = ContainerNextStream(pContainerContext, &sczStreamName);
229 if (E_NOMOREITEMS == hr)
230 {
231 hr = S_OK;
232 break;
233 }
234 ExitOnFailure(hr, "Failed to get next stream.");
235
236 // find payload by stream name
237 hr = FindEmbeddedBySourcePath(pPayloads, pContainer, sczStreamName, &pPayload);
238 ExitOnFailure(hr, "Failed to find embedded payload: %ls", sczStreamName);
239
240 // make file path
241 hr = PathConcat(wzTargetDir, pPayload->sczFilePath, &pPayload->sczLocalFilePath);
242 ExitOnFailure(hr, "Failed to concat file paths.");
243
244 // extract file
245 hr = PathGetDirectory(pPayload->sczLocalFilePath, &sczDirectory);
246 ExitOnFailure(hr, "Failed to get directory portion of local file path");
247
248 hr = DirEnsureExists(sczDirectory, NULL);
249 ExitOnFailure(hr, "Failed to ensure directory exists");
250
251 hr = ContainerStreamToFile(pContainerContext, pPayload->sczLocalFilePath);
252 ExitOnFailure(hr, "Failed to extract file.");
253
254 // flag that the payload has been acquired
255 pPayload->state = BURN_PAYLOAD_STATE_ACQUIRED;
256 }
257
258 // locate any payloads that were not extracted
259 for (DWORD i = 0; i < pPayloads->cPayloads; ++i)
260 {
261 pPayload = &pPayloads->rgPayloads[i];
262
263 // if the payload is part of the container
264 if (!pContainer || pPayload->pContainer == pContainer)
265 {
266 // if the payload has not been acquired
267 if (BURN_PAYLOAD_STATE_ACQUIRED > pPayload->state)
268 {
269 hr = E_INVALIDDATA;
270 ExitOnRootFailure(hr, "Payload was not found in container: %ls", pPayload->sczKey);
271 }
272 }
273 }
274
275LExit:
276 ReleaseStr(sczStreamName);
277 ReleaseStr(sczDirectory);
278
279 return hr;
280}
281
282extern "C" HRESULT PayloadFindById(
283 __in BURN_PAYLOADS* pPayloads,
284 __in_z LPCWSTR wzId,
285 __out BURN_PAYLOAD** ppPayload
286 )
287{
288 HRESULT hr = S_OK;
289 BURN_PAYLOAD* pPayload = NULL;
290
291 for (DWORD i = 0; i < pPayloads->cPayloads; ++i)
292 {
293 pPayload = &pPayloads->rgPayloads[i];
294
295 if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, pPayload->sczKey, -1, wzId, -1))
296 {
297 *ppPayload = pPayload;
298 ExitFunction1(hr = S_OK);
299 }
300 }
301
302 hr = E_NOTFOUND;
303
304LExit:
305 return hr;
306}
307
308extern "C" HRESULT PayloadFindEmbeddedBySourcePath(
309 __in BURN_PAYLOADS* pPayloads,
310 __in_z LPCWSTR wzStreamName,
311 __out BURN_PAYLOAD** ppPayload
312 )
313{
314 HRESULT hr = S_OK;
315 BURN_PAYLOAD* pPayload = NULL;
316
317 for (DWORD i = 0; i < pPayloads->cPayloads; ++i)
318 {
319 pPayload = &pPayloads->rgPayloads[i];
320
321 if (BURN_PAYLOAD_PACKAGING_EMBEDDED == pPayload->packaging)
322 {
323 if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, pPayload->sczSourcePath, -1, wzStreamName, -1))
324 {
325 *ppPayload = pPayload;
326 ExitFunction1(hr = S_OK);
327 }
328 }
329 }
330
331 hr = E_NOTFOUND;
332
333LExit:
334 return hr;
335}
336
337
338// internal function definitions
339
340static HRESULT FindEmbeddedBySourcePath(
341 __in BURN_PAYLOADS* pPayloads,
342 __in_opt BURN_CONTAINER* pContainer,
343 __in_z LPCWSTR wzStreamName,
344 __out BURN_PAYLOAD** ppPayload
345 )
346{
347 HRESULT hr = S_OK;
348
349 for (DWORD i = 0; i < pPayloads->cPayloads; ++i)
350 {
351 BURN_PAYLOAD* pPayload = &pPayloads->rgPayloads[i];
352
353 if (BURN_PAYLOAD_PACKAGING_EMBEDDED == pPayload->packaging && (!pContainer || pPayload->pContainer == pContainer))
354 {
355 if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, pPayload->sczSourcePath, -1, wzStreamName, -1))
356 {
357 *ppPayload = pPayload;
358 ExitFunction1(hr = S_OK);
359 }
360 }
361 }
362
363 hr = E_NOTFOUND;
364
365LExit:
366 return hr;
367}