aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSean Hall <r.sean.hall@gmail.com>2020-11-17 18:53:13 -0600
committerSean Hall <r.sean.hall@gmail.com>2020-11-17 19:06:00 -0600
commitfdd47bab30235f62a8bcc7a5a88c6d69267046aa (patch)
tree2d105633f6dfca8d853688bb0912753eeb524eaf
parent643293e48d176ff78282670512f45b4cf889b0a5 (diff)
downloadwix-fdd47bab30235f62a8bcc7a5a88c6d69267046aa.tar.gz
wix-fdd47bab30235f62a8bcc7a5a88c6d69267046aa.tar.bz2
wix-fdd47bab30235f62a8bcc7a5a88c6d69267046aa.zip
Consolidate the code for the BA and bext engines.
-rw-r--r--src/engine/EngineForApplication.cpp528
-rw-r--r--src/engine/EngineForExtension.cpp191
-rw-r--r--src/engine/externalengine.cpp760
-rw-r--r--src/engine/externalengine.h154
-rw-r--r--src/engine/pseudobundle.cpp4
-rw-r--r--src/engine/pseudobundle.h4
6 files changed, 956 insertions, 685 deletions
diff --git a/src/engine/EngineForApplication.cpp b/src/engine/EngineForApplication.cpp
index e3ce7670..361e0f4e 100644
--- a/src/engine/EngineForApplication.cpp
+++ b/src/engine/EngineForApplication.cpp
@@ -3,12 +3,6 @@
3#include "precomp.h" 3#include "precomp.h"
4 4
5 5
6static HRESULT CopyStringToBA(
7 __in LPWSTR wzValue,
8 __in_opt LPWSTR wzBuffer,
9 __inout DWORD* pcchBuffer
10 );
11
12static HRESULT BAEngineGetPackageCount( 6static HRESULT BAEngineGetPackageCount(
13 __in BOOTSTRAPPER_ENGINE_CONTEXT* pContext, 7 __in BOOTSTRAPPER_ENGINE_CONTEXT* pContext,
14 __in const LPVOID pvArgs, 8 __in const LPVOID pvArgs,
@@ -18,9 +12,8 @@ static HRESULT BAEngineGetPackageCount(
18 HRESULT hr = S_OK; 12 HRESULT hr = S_OK;
19 ValidateMessageArgs(hr, pvArgs, BAENGINE_GETPACKAGECOUNT_ARGS, pArgs); 13 ValidateMessageArgs(hr, pvArgs, BAENGINE_GETPACKAGECOUNT_ARGS, pArgs);
20 ValidateMessageResults(hr, pvResults, BAENGINE_GETPACKAGECOUNT_RESULTS, pResults); 14 ValidateMessageResults(hr, pvResults, BAENGINE_GETPACKAGECOUNT_RESULTS, pResults);
21 DWORD* pcPackages = &pResults->cPackages;
22 15
23 *pcPackages = pContext->pEngineState->packages.cPackages; 16 ExternalEngineGetPackageCount(pContext->pEngineState, &pResults->cPackages);
24 17
25LExit: 18LExit:
26 return hr; 19 return hr;
@@ -35,17 +28,8 @@ static HRESULT BAEngineGetVariableNumeric(
35 HRESULT hr = S_OK; 28 HRESULT hr = S_OK;
36 ValidateMessageArgs(hr, pvArgs, BAENGINE_GETVARIABLENUMERIC_ARGS, pArgs); 29 ValidateMessageArgs(hr, pvArgs, BAENGINE_GETVARIABLENUMERIC_ARGS, pArgs);
37 ValidateMessageResults(hr, pvResults, BAENGINE_GETVARIABLENUMERIC_RESULTS, pResults); 30 ValidateMessageResults(hr, pvResults, BAENGINE_GETVARIABLENUMERIC_RESULTS, pResults);
38 LPCWSTR wzVariable = pArgs->wzVariable;
39 LONGLONG* pllValue = &pResults->llValue;
40 31
41 if (wzVariable && *wzVariable) 32 hr = ExternalEngineGetVariableNumeric(pContext->pEngineState, pArgs->wzVariable, &pResults->llValue);
42 {
43 hr = VariableGetNumeric(&pContext->pEngineState->variables, wzVariable, pllValue);
44 }
45 else
46 {
47 hr = E_INVALIDARG;
48 }
49 33
50LExit: 34LExit:
51 return hr; 35 return hr;
@@ -58,28 +42,12 @@ static HRESULT BAEngineGetVariableString(
58 ) 42 )
59{ 43{
60 HRESULT hr = S_OK; 44 HRESULT hr = S_OK;
61 LPWSTR sczValue = NULL;
62 ValidateMessageArgs(hr, pvArgs, BAENGINE_GETVARIABLESTRING_ARGS, pArgs); 45 ValidateMessageArgs(hr, pvArgs, BAENGINE_GETVARIABLESTRING_ARGS, pArgs);
63 ValidateMessageResults(hr, pvResults, BAENGINE_GETVARIABLESTRING_RESULTS, pResults); 46 ValidateMessageResults(hr, pvResults, BAENGINE_GETVARIABLESTRING_RESULTS, pResults);
64 LPCWSTR wzVariable = pArgs->wzVariable;
65 LPWSTR wzValue = pResults->wzValue;
66 DWORD* pcchValue = &pResults->cchValue;
67 47
68 if (wzVariable && *wzVariable) 48 hr = ExternalEngineGetVariableString(pContext->pEngineState, pArgs->wzVariable, pResults->wzValue, &pResults->cchValue);
69 {
70 hr = VariableGetString(&pContext->pEngineState->variables, wzVariable, &sczValue);
71 if (SUCCEEDED(hr))
72 {
73 hr = CopyStringToBA(sczValue, wzValue, pcchValue);
74 }
75 }
76 else
77 {
78 hr = E_INVALIDARG;
79 }
80 49
81LExit: 50LExit:
82 StrSecureZeroFreeString(sczValue);
83 return hr; 51 return hr;
84} 52}
85 53
@@ -90,29 +58,12 @@ static HRESULT BAEngineGetVariableVersion(
90 ) 58 )
91{ 59{
92 HRESULT hr = S_OK; 60 HRESULT hr = S_OK;
93 VERUTIL_VERSION* pVersion = NULL;
94 ValidateMessageArgs(hr, pvArgs, BAENGINE_GETVARIABLEVERSION_ARGS, pArgs); 61 ValidateMessageArgs(hr, pvArgs, BAENGINE_GETVARIABLEVERSION_ARGS, pArgs);
95 ValidateMessageResults(hr, pvResults, BAENGINE_GETVARIABLEVERSION_RESULTS, pResults); 62 ValidateMessageResults(hr, pvResults, BAENGINE_GETVARIABLEVERSION_RESULTS, pResults);
96 LPCWSTR wzVariable = pArgs->wzVariable;
97 LPWSTR wzValue = pResults->wzValue;
98 DWORD* pcchValue = &pResults->cchValue;
99 63
100 if (wzVariable && *wzVariable) 64 hr = ExternalEngineGetVariableVersion(pContext->pEngineState, pArgs->wzVariable, pResults->wzValue, &pResults->cchValue);
101 {
102 hr = VariableGetVersion(&pContext->pEngineState->variables, wzVariable, &pVersion);
103 if (SUCCEEDED(hr))
104 {
105 hr = CopyStringToBA(pVersion->sczVersion, wzValue, pcchValue);
106 }
107 }
108 else
109 {
110 hr = E_INVALIDARG;
111 }
112 65
113LExit: 66LExit:
114 ReleaseVerutilVersion(pVersion);
115
116 return hr; 67 return hr;
117} 68}
118 69
@@ -123,28 +74,12 @@ static HRESULT BAEngineFormatString(
123 ) 74 )
124{ 75{
125 HRESULT hr = S_OK; 76 HRESULT hr = S_OK;
126 LPWSTR sczValue = NULL;
127 ValidateMessageArgs(hr, pvArgs, BAENGINE_FORMATSTRING_ARGS, pArgs); 77 ValidateMessageArgs(hr, pvArgs, BAENGINE_FORMATSTRING_ARGS, pArgs);
128 ValidateMessageResults(hr, pvResults, BAENGINE_FORMATSTRING_RESULTS, pResults); 78 ValidateMessageResults(hr, pvResults, BAENGINE_FORMATSTRING_RESULTS, pResults);
129 LPCWSTR wzIn = pArgs->wzIn;
130 LPWSTR wzOut = pResults->wzOut;
131 DWORD* pcchOut = &pResults->cchOut;
132 79
133 if (wzIn && *wzIn) 80 hr = ExternalEngineFormatString(pContext->pEngineState, pArgs->wzIn, pResults->wzOut, &pResults->cchOut);
134 {
135 hr = VariableFormatString(&pContext->pEngineState->variables, wzIn, &sczValue, NULL);
136 if (SUCCEEDED(hr))
137 {
138 hr = CopyStringToBA(sczValue, wzOut, pcchOut);
139 }
140 }
141 else
142 {
143 hr = E_INVALIDARG;
144 }
145 81
146LExit: 82LExit:
147 StrSecureZeroFreeString(sczValue);
148 return hr; 83 return hr;
149} 84}
150 85
@@ -155,28 +90,12 @@ static HRESULT BAEngineEscapeString(
155 ) 90 )
156{ 91{
157 HRESULT hr = S_OK; 92 HRESULT hr = S_OK;
158 LPWSTR sczValue = NULL;
159 ValidateMessageArgs(hr, pvArgs, BAENGINE_ESCAPESTRING_ARGS, pArgs); 93 ValidateMessageArgs(hr, pvArgs, BAENGINE_ESCAPESTRING_ARGS, pArgs);
160 ValidateMessageResults(hr, pvResults, BAENGINE_ESCAPESTRING_RESULTS, pResults); 94 ValidateMessageResults(hr, pvResults, BAENGINE_ESCAPESTRING_RESULTS, pResults);
161 LPCWSTR wzIn = pArgs->wzIn;
162 LPWSTR wzOut = pResults->wzOut;
163 DWORD* pcchOut = &pResults->cchOut;
164 95
165 if (wzIn && *wzIn) 96 hr = ExternalEngineEscapeString(pArgs->wzIn, pResults->wzOut, &pResults->cchOut);
166 {
167 hr = VariableEscapeString(wzIn, &sczValue);
168 if (SUCCEEDED(hr))
169 {
170 hr = CopyStringToBA(sczValue, wzOut, pcchOut);
171 }
172 }
173 else
174 {
175 hr = E_INVALIDARG;
176 }
177 97
178LExit: 98LExit:
179 StrSecureZeroFreeString(sczValue);
180 return hr; 99 return hr;
181} 100}
182 101
@@ -189,17 +108,8 @@ static HRESULT BAEngineEvaluateCondition(
189 HRESULT hr = S_OK; 108 HRESULT hr = S_OK;
190 ValidateMessageArgs(hr, pvArgs, BAENGINE_EVALUATECONDITION_ARGS, pArgs); 109 ValidateMessageArgs(hr, pvArgs, BAENGINE_EVALUATECONDITION_ARGS, pArgs);
191 ValidateMessageResults(hr, pvResults, BAENGINE_EVALUATECONDITION_RESULTS, pResults); 110 ValidateMessageResults(hr, pvResults, BAENGINE_EVALUATECONDITION_RESULTS, pResults);
192 LPCWSTR wzCondition = pArgs->wzCondition;
193 BOOL* pf = &pResults->f;
194 111
195 if (wzCondition && *wzCondition) 112 hr = ExternalEngineEvaluateCondition(pContext->pEngineState, pArgs->wzCondition, &pResults->f);
196 {
197 hr = ConditionEvaluate(&pContext->pEngineState->variables, wzCondition, pf);
198 }
199 else
200 {
201 hr = E_INVALIDARG;
202 }
203 113
204LExit: 114LExit:
205 return hr; 115 return hr;
@@ -212,13 +122,11 @@ static HRESULT BAEngineLog(
212 ) 122 )
213{ 123{
214 HRESULT hr = S_OK; 124 HRESULT hr = S_OK;
125 REPORT_LEVEL rl = REPORT_NONE;
215 ValidateMessageArgs(hr, pvArgs, BAENGINE_LOG_ARGS, pArgs); 126 ValidateMessageArgs(hr, pvArgs, BAENGINE_LOG_ARGS, pArgs);
216 ValidateMessageResults(hr, pvResults, BAENGINE_LOG_RESULTS, pResults); 127 ValidateMessageResults(hr, pvResults, BAENGINE_LOG_RESULTS, pResults);
217 REPORT_LEVEL rl = REPORT_NONE;
218 BOOTSTRAPPER_LOG_LEVEL level = pArgs->level;
219 LPCWSTR wzMessage = pArgs->wzMessage;
220 128
221 switch (level) 129 switch (pArgs->level)
222 { 130 {
223 case BOOTSTRAPPER_LOG_LEVEL_STANDARD: 131 case BOOTSTRAPPER_LOG_LEVEL_STANDARD:
224 rl = REPORT_STANDARD; 132 rl = REPORT_STANDARD;
@@ -240,7 +148,7 @@ static HRESULT BAEngineLog(
240 ExitFunction1(hr = E_INVALIDARG); 148 ExitFunction1(hr = E_INVALIDARG);
241 } 149 }
242 150
243 hr = LogStringLine(rl, "%ls", wzMessage); 151 hr = ExternalEngineLog(rl, pArgs->wzMessage);
244 ExitOnFailure(hr, "Failed to log BA message."); 152 ExitOnFailure(hr, "Failed to log BA message.");
245 153
246LExit: 154LExit:
@@ -254,38 +162,12 @@ static HRESULT BAEngineSendEmbeddedError(
254 ) 162 )
255{ 163{
256 HRESULT hr = S_OK; 164 HRESULT hr = S_OK;
257 BYTE* pbData = NULL;
258 DWORD cbData = 0;
259 DWORD dwResult = 0;
260 ValidateMessageArgs(hr, pvArgs, BAENGINE_SENDEMBEDDEDERROR_ARGS, pArgs); 165 ValidateMessageArgs(hr, pvArgs, BAENGINE_SENDEMBEDDEDERROR_ARGS, pArgs);
261 ValidateMessageResults(hr, pvResults, BAENGINE_SENDEMBEDDEDERROR_RESULTS, pResults); 166 ValidateMessageResults(hr, pvResults, BAENGINE_SENDEMBEDDEDERROR_RESULTS, pResults);
262 DWORD dwErrorCode = pArgs->dwErrorCode;
263 LPCWSTR wzMessage = pArgs->wzMessage;
264 DWORD dwUIHint = pArgs->dwUIHint;
265 int* pnResult = &pResults->nResult;
266
267 if (BURN_MODE_EMBEDDED != pContext->pEngineState->mode)
268 {
269 hr = HRESULT_FROM_WIN32(ERROR_INVALID_STATE);
270 ExitOnRootFailure(hr, "BA requested to send embedded message when not in embedded mode.");
271 }
272
273 hr = BuffWriteNumber(&pbData, &cbData, dwErrorCode);
274 ExitOnFailure(hr, "Failed to write error code to message buffer.");
275 167
276 hr = BuffWriteString(&pbData, &cbData, wzMessage ? wzMessage : L""); 168 hr = ExternalEngineSendEmbeddedError(pContext->pEngineState, pArgs->dwErrorCode, pArgs->wzMessage, pArgs->dwUIHint, &pResults->nResult);
277 ExitOnFailure(hr, "Failed to write message string to message buffer.");
278
279 hr = BuffWriteNumber(&pbData, &cbData, dwUIHint);
280 ExitOnFailure(hr, "Failed to write UI hint to message buffer.");
281
282 hr = PipeSendMessage(pContext->pEngineState->embeddedConnection.hPipe, BURN_EMBEDDED_MESSAGE_TYPE_ERROR, pbData, cbData, NULL, NULL, &dwResult);
283 ExitOnFailure(hr, "Failed to send embedded message over pipe.");
284
285 *pnResult = static_cast<int>(dwResult);
286 169
287LExit: 170LExit:
288 ReleaseBuffer(pbData);
289 return hr; 171 return hr;
290} 172}
291 173
@@ -296,34 +178,12 @@ static HRESULT BAEngineSendEmbeddedProgress(
296 ) 178 )
297{ 179{
298 HRESULT hr = S_OK; 180 HRESULT hr = S_OK;
299 BYTE* pbData = NULL;
300 DWORD cbData = 0;
301 DWORD dwResult = 0;
302 ValidateMessageArgs(hr, pvArgs, BAENGINE_SENDEMBEDDEDPROGRESS_ARGS, pArgs); 181 ValidateMessageArgs(hr, pvArgs, BAENGINE_SENDEMBEDDEDPROGRESS_ARGS, pArgs);
303 ValidateMessageResults(hr, pvResults, BAENGINE_SENDEMBEDDEDPROGRESS_RESULTS, pResults); 182 ValidateMessageResults(hr, pvResults, BAENGINE_SENDEMBEDDEDPROGRESS_RESULTS, pResults);
304 DWORD dwProgressPercentage = pArgs->dwProgressPercentage;
305 DWORD dwOverallProgressPercentage = pArgs->dwOverallProgressPercentage;
306 int* pnResult = &pResults->nResult;
307
308 if (BURN_MODE_EMBEDDED != pContext->pEngineState->mode)
309 {
310 hr = HRESULT_FROM_WIN32(ERROR_INVALID_STATE);
311 ExitOnRootFailure(hr, "BA requested to send embedded progress message when not in embedded mode.");
312 }
313
314 hr = BuffWriteNumber(&pbData, &cbData, dwProgressPercentage);
315 ExitOnFailure(hr, "Failed to write progress percentage to message buffer.");
316
317 hr = BuffWriteNumber(&pbData, &cbData, dwOverallProgressPercentage);
318 ExitOnFailure(hr, "Failed to write overall progress percentage to message buffer.");
319
320 hr = PipeSendMessage(pContext->pEngineState->embeddedConnection.hPipe, BURN_EMBEDDED_MESSAGE_TYPE_PROGRESS, pbData, cbData, NULL, NULL, &dwResult);
321 ExitOnFailure(hr, "Failed to send embedded progress message over pipe.");
322 183
323 *pnResult = static_cast<int>(dwResult); 184 hr = ExternalEngineSendEmbeddedProgress(pContext->pEngineState, pArgs->dwProgressPercentage, pArgs->dwOverallProgressPercentage, &pResults->nResult);
324 185
325LExit: 186LExit:
326 ReleaseBuffer(pbData);
327 return hr; 187 return hr;
328} 188}
329 189
@@ -334,81 +194,12 @@ static HRESULT BAEngineSetUpdate(
334 ) 194 )
335{ 195{
336 HRESULT hr = S_OK; 196 HRESULT hr = S_OK;
337 LPCWSTR sczId = NULL;
338 LPWSTR sczLocalSource = NULL;
339 LPWSTR sczCommandline = NULL;
340 UUID guid = { };
341 WCHAR wzGuid[39];
342 RPC_STATUS rs = RPC_S_OK;
343 ValidateMessageArgs(hr, pvArgs, BAENGINE_SETUPDATE_ARGS, pArgs); 197 ValidateMessageArgs(hr, pvArgs, BAENGINE_SETUPDATE_ARGS, pArgs);
344 ValidateMessageResults(hr, pvResults, BAENGINE_SETUPDATE_RESULTS, pResults); 198 ValidateMessageResults(hr, pvResults, BAENGINE_SETUPDATE_RESULTS, pResults);
345 LPCWSTR wzLocalSource = pArgs->wzLocalSource;
346 LPCWSTR wzDownloadSource = pArgs->wzDownloadSource;
347 DWORD64 qwSize = pArgs->qwSize;
348 BOOTSTRAPPER_UPDATE_HASH_TYPE hashType = pArgs->hashType;
349 BYTE* rgbHash = pArgs->rgbHash;
350 DWORD cbHash = pArgs->cbHash;
351 199
352 ::EnterCriticalSection(&pContext->pEngineState->csActive); 200 hr = ExternalEngineSetUpdate(pContext->pEngineState, pArgs->wzLocalSource, pArgs->wzDownloadSource, pArgs->qwSize, pArgs->hashType, pArgs->rgbHash, pArgs->cbHash);
353
354 if ((!wzLocalSource || !*wzLocalSource) && (!wzDownloadSource || !*wzDownloadSource))
355 {
356 UpdateUninitialize(&pContext->pEngineState->update);
357 }
358 else if (BOOTSTRAPPER_UPDATE_HASH_TYPE_NONE == hashType && (0 != cbHash || rgbHash))
359 {
360 hr = E_INVALIDARG;
361 }
362 else if (BOOTSTRAPPER_UPDATE_HASH_TYPE_SHA1 == hashType && (SHA1_HASH_LEN != cbHash || !rgbHash))
363 {
364 hr = E_INVALIDARG;
365 }
366 else
367 {
368 UpdateUninitialize(&pContext->pEngineState->update);
369
370 if (!wzLocalSource || !*wzLocalSource)
371 {
372 hr = StrAllocFormatted(&sczLocalSource, L"update\\%ls", pContext->pEngineState->registration.sczExecutableName);
373 ExitOnFailure(hr, "Failed to default local update source");
374 }
375
376 hr = CoreRecreateCommandLine(&sczCommandline, BOOTSTRAPPER_ACTION_INSTALL, pContext->pEngineState->command.display, pContext->pEngineState->command.restart, BOOTSTRAPPER_RELATION_NONE, FALSE, pContext->pEngineState->registration.sczActiveParent, pContext->pEngineState->registration.sczAncestors, NULL, pContext->pEngineState->command.wzCommandLine);
377 ExitOnFailure(hr, "Failed to recreate command-line for update bundle.");
378
379 // Per-user bundles would fail to use the downloaded update bundle, as the existing install would already be cached
380 // at the registration id's location. Here I am generating a random guid, but in the future it would be nice if the
381 // feed would provide the ID of the update.
382 if (!pContext->pEngineState->registration.fPerMachine)
383 {
384 rs = ::UuidCreate(&guid);
385 hr = HRESULT_FROM_RPC(rs);
386 ExitOnFailure(hr, "Failed to create bundle update guid.");
387
388 if (!::StringFromGUID2(guid, wzGuid, countof(wzGuid)))
389 {
390 hr = E_OUTOFMEMORY;
391 ExitOnRootFailure(hr, "Failed to convert bundle update guid into string.");
392 }
393
394 sczId = wzGuid;
395 }
396 else
397 {
398 sczId = pContext->pEngineState->registration.sczId;
399 }
400
401 hr = PseudoBundleInitialize(FILEMAKEVERSION(rmj, rmm, rup, rpr), &pContext->pEngineState->update.package, FALSE, sczId, BOOTSTRAPPER_RELATION_UPDATE, BOOTSTRAPPER_PACKAGE_STATE_ABSENT, pContext->pEngineState->registration.sczExecutableName, sczLocalSource ? sczLocalSource : wzLocalSource, wzDownloadSource, qwSize, TRUE, sczCommandline, NULL, NULL, NULL, rgbHash, cbHash);
402 ExitOnFailure(hr, "Failed to set update bundle.");
403
404 pContext->pEngineState->update.fUpdateAvailable = TRUE;
405 }
406 201
407LExit: 202LExit:
408 ::LeaveCriticalSection(&pContext->pEngineState->csActive);
409
410 ReleaseStr(sczCommandline);
411 ReleaseStr(sczLocalSource);
412 return hr; 203 return hr;
413} 204}
414 205
@@ -419,51 +210,12 @@ static HRESULT BAEngineSetLocalSource(
419 ) 210 )
420{ 211{
421 HRESULT hr = S_OK; 212 HRESULT hr = S_OK;
422 BURN_CONTAINER* pContainer = NULL;
423 BURN_PAYLOAD* pPayload = NULL;
424 ValidateMessageArgs(hr, pvArgs, BAENGINE_SETLOCALSOURCE_ARGS, pArgs); 213 ValidateMessageArgs(hr, pvArgs, BAENGINE_SETLOCALSOURCE_ARGS, pArgs);
425 ValidateMessageResults(hr, pvResults, BAENGINE_SETLOCALSOURCE_RESULTS, pResults); 214 ValidateMessageResults(hr, pvResults, BAENGINE_SETLOCALSOURCE_RESULTS, pResults);
426 LPCWSTR wzPackageOrContainerId = pArgs->wzPackageOrContainerId;
427 LPCWSTR wzPayloadId = pArgs->wzPayloadId;
428 LPCWSTR wzPath = pArgs->wzPath;
429
430 ::EnterCriticalSection(&pContext->pEngineState->csActive);
431 hr = UserExperienceEnsureEngineInactive(&pContext->pEngineState->userExperience);
432 ExitOnFailure(hr, "Engine is active, cannot change engine state.");
433
434 if (!wzPath || !*wzPath)
435 {
436 hr = E_INVALIDARG;
437 }
438 else if (wzPayloadId && * wzPayloadId)
439 {
440 hr = PayloadFindById(&pContext->pEngineState->payloads, wzPayloadId, &pPayload);
441 ExitOnFailure(hr, "BA requested unknown payload with id: %ls", wzPayloadId);
442
443 if (BURN_PAYLOAD_PACKAGING_EMBEDDED == pPayload->packaging)
444 {
445 hr = HRESULT_FROM_WIN32(ERROR_INVALID_OPERATION);
446 ExitOnFailure(hr, "BA denied while trying to set source on embedded payload: %ls", wzPayloadId);
447 }
448 215
449 hr = StrAllocString(&pPayload->sczSourcePath, wzPath, 0); 216 hr = ExternalEngineSetLocalSource(pContext->pEngineState, pArgs->wzPackageOrContainerId, pArgs->wzPayloadId, pArgs->wzPath);
450 ExitOnFailure(hr, "Failed to set source path for payload.");
451 }
452 else if (wzPackageOrContainerId && *wzPackageOrContainerId)
453 {
454 hr = ContainerFindById(&pContext->pEngineState->containers, wzPackageOrContainerId, &pContainer);
455 ExitOnFailure(hr, "BA requested unknown container with id: %ls", wzPackageOrContainerId);
456
457 hr = StrAllocString(&pContainer->sczSourcePath, wzPath, 0);
458 ExitOnFailure(hr, "Failed to set source path for container.");
459 }
460 else
461 {
462 hr = E_INVALIDARG;
463 }
464 217
465LExit: 218LExit:
466 ::LeaveCriticalSection(&pContext->pEngineState->csActive);
467 return hr; 219 return hr;
468} 220}
469 221
@@ -474,82 +226,12 @@ static HRESULT BAEngineSetDownloadSource(
474 ) 226 )
475{ 227{
476 HRESULT hr = S_OK; 228 HRESULT hr = S_OK;
477 BURN_CONTAINER* pContainer = NULL;
478 BURN_PAYLOAD* pPayload = NULL;
479 DOWNLOAD_SOURCE* pDownloadSource = NULL;
480 ValidateMessageArgs(hr, pvArgs, BAENGINE_SETDOWNLOADSOURCE_ARGS, pArgs); 229 ValidateMessageArgs(hr, pvArgs, BAENGINE_SETDOWNLOADSOURCE_ARGS, pArgs);
481 ValidateMessageResults(hr, pvResults, BAENGINE_SETDOWNLOADSOURCE_RESULTS, pResults); 230 ValidateMessageResults(hr, pvResults, BAENGINE_SETDOWNLOADSOURCE_RESULTS, pResults);
482 LPCWSTR wzPackageOrContainerId = pArgs->wzPackageOrContainerId;
483 LPCWSTR wzPayloadId = pArgs->wzPayloadId;
484 LPCWSTR wzUrl = pArgs->wzUrl;
485 LPCWSTR wzUser = pArgs->wzUser;
486 LPCWSTR wzPassword = pArgs->wzPassword;
487 231
488 ::EnterCriticalSection(&pContext->pEngineState->csActive); 232 hr = ExternalEngineSetDownloadSource(pContext->pEngineState, pArgs->wzPackageOrContainerId, pArgs->wzPayloadId, pArgs->wzUrl, pArgs->wzUser, pArgs->wzPassword);
489 hr = UserExperienceEnsureEngineInactive(&pContext->pEngineState->userExperience);
490 ExitOnFailure(hr, "Engine is active, cannot change engine state.");
491
492 if (wzPayloadId && *wzPayloadId)
493 {
494 hr = PayloadFindById(&pContext->pEngineState->payloads, wzPayloadId, &pPayload);
495 ExitOnFailure(hr, "BA requested unknown payload with id: %ls", wzPayloadId);
496
497 if (BURN_PAYLOAD_PACKAGING_EMBEDDED == pPayload->packaging)
498 {
499 hr = HRESULT_FROM_WIN32(ERROR_INVALID_OPERATION);
500 ExitOnFailure(hr, "BA denied while trying to set download URL on embedded payload: %ls", wzPayloadId);
501 }
502
503 pDownloadSource = &pPayload->downloadSource;
504 }
505 else if (wzPackageOrContainerId && *wzPackageOrContainerId)
506 {
507 hr = ContainerFindById(&pContext->pEngineState->containers, wzPackageOrContainerId, &pContainer);
508 ExitOnFailure(hr, "BA requested unknown container with id: %ls", wzPackageOrContainerId);
509
510 pDownloadSource = &pContainer->downloadSource;
511 }
512 else
513 {
514 hr = E_INVALIDARG;
515 ExitOnFailure(hr, "BA did not provide container or payload id.");
516 }
517
518 if (wzUrl && *wzUrl)
519 {
520 hr = StrAllocString(&pDownloadSource->sczUrl, wzUrl, 0);
521 ExitOnFailure(hr, "Failed to set download URL.");
522
523 if (wzUser && *wzUser)
524 {
525 hr = StrAllocString(&pDownloadSource->sczUser, wzUser, 0);
526 ExitOnFailure(hr, "Failed to set download user.");
527
528 if (wzPassword && *wzPassword)
529 {
530 hr = StrAllocString(&pDownloadSource->sczPassword, wzPassword, 0);
531 ExitOnFailure(hr, "Failed to set download password.");
532 }
533 else // no password.
534 {
535 ReleaseNullStr(pDownloadSource->sczPassword);
536 }
537 }
538 else // no user means no password either.
539 {
540 ReleaseNullStr(pDownloadSource->sczUser);
541 ReleaseNullStr(pDownloadSource->sczPassword);
542 }
543 }
544 else // no URL provided means clear out the whole download source.
545 {
546 ReleaseNullStr(pDownloadSource->sczUrl);
547 ReleaseNullStr(pDownloadSource->sczUser);
548 ReleaseNullStr(pDownloadSource->sczPassword);
549 }
550 233
551LExit: 234LExit:
552 ::LeaveCriticalSection(&pContext->pEngineState->csActive);
553 return hr; 235 return hr;
554} 236}
555 237
@@ -562,19 +244,8 @@ static HRESULT BAEngineSetVariableNumeric(
562 HRESULT hr = S_OK; 244 HRESULT hr = S_OK;
563 ValidateMessageArgs(hr, pvArgs, BAENGINE_SETVARIABLENUMERIC_ARGS, pArgs); 245 ValidateMessageArgs(hr, pvArgs, BAENGINE_SETVARIABLENUMERIC_ARGS, pArgs);
564 ValidateMessageResults(hr, pvResults, BAENGINE_SETVARIABLENUMERIC_RESULTS, pResults); 246 ValidateMessageResults(hr, pvResults, BAENGINE_SETVARIABLENUMERIC_RESULTS, pResults);
565 LPCWSTR wzVariable = pArgs->wzVariable;
566 LONGLONG llValue = pArgs->llValue;
567 247
568 if (wzVariable && *wzVariable) 248 hr = ExternalEngineSetVariableNumeric(pContext->pEngineState, pArgs->wzVariable, pArgs->llValue);
569 {
570 hr = VariableSetNumeric(&pContext->pEngineState->variables, wzVariable, llValue, FALSE);
571 ExitOnFailure(hr, "Failed to set numeric variable.");
572 }
573 else
574 {
575 hr = E_INVALIDARG;
576 ExitOnFailure(hr, "BA did not provide variable name.");
577 }
578 249
579LExit: 250LExit:
580 return hr; 251 return hr;
@@ -589,19 +260,8 @@ static HRESULT BAEngineSetVariableString(
589 HRESULT hr = S_OK; 260 HRESULT hr = S_OK;
590 ValidateMessageArgs(hr, pvArgs, BAENGINE_SETVARIABLESTRING_ARGS, pArgs); 261 ValidateMessageArgs(hr, pvArgs, BAENGINE_SETVARIABLESTRING_ARGS, pArgs);
591 ValidateMessageResults(hr, pvResults, BAENGINE_SETVARIABLESTRING_RESULTS, pResults); 262 ValidateMessageResults(hr, pvResults, BAENGINE_SETVARIABLESTRING_RESULTS, pResults);
592 LPCWSTR wzVariable = pArgs->wzVariable;
593 LPCWSTR wzValue = pArgs->wzValue;
594 263
595 if (wzVariable && *wzVariable) 264 hr = ExternalEngineSetVariableString(pContext->pEngineState, pArgs->wzVariable, pArgs->wzValue, pArgs->fFormatted);
596 {
597 hr = VariableSetString(&pContext->pEngineState->variables, wzVariable, wzValue, FALSE, pArgs->fFormatted);
598 ExitOnFailure(hr, "Failed to set string variable.");
599 }
600 else
601 {
602 hr = E_INVALIDARG;
603 ExitOnFailure(hr, "BA did not provide variable name.");
604 }
605 265
606LExit: 266LExit:
607 return hr; 267 return hr;
@@ -614,32 +274,12 @@ static HRESULT BAEngineSetVariableVersion(
614 ) 274 )
615{ 275{
616 HRESULT hr = S_OK; 276 HRESULT hr = S_OK;
617 VERUTIL_VERSION* pVersion = NULL;
618 ValidateMessageArgs(hr, pvArgs, BAENGINE_SETVARIABLEVERSION_ARGS, pArgs); 277 ValidateMessageArgs(hr, pvArgs, BAENGINE_SETVARIABLEVERSION_ARGS, pArgs);
619 ValidateMessageResults(hr, pvResults, BAENGINE_SETVARIABLEVERSION_RESULTS, pResults); 278 ValidateMessageResults(hr, pvResults, BAENGINE_SETVARIABLEVERSION_RESULTS, pResults);
620 LPCWSTR wzVariable = pArgs->wzVariable;
621 LPCWSTR wzValue = pArgs->wzValue;
622 279
623 if (wzVariable && *wzVariable) 280 hr = ExternalEngineSetVariableVersion(pContext->pEngineState, pArgs->wzVariable, pArgs->wzValue);
624 {
625 if (wzValue)
626 {
627 hr = VerParseVersion(wzValue, 0, FALSE, &pVersion);
628 ExitOnFailure(hr, "Failed to parse new version value.");
629 }
630
631 hr = VariableSetVersion(&pContext->pEngineState->variables, wzVariable, pVersion, FALSE);
632 ExitOnFailure(hr, "Failed to set version variable.");
633 }
634 else
635 {
636 hr = E_INVALIDARG;
637 ExitOnFailure(hr, "BA did not provide variable name.");
638 }
639 281
640LExit: 282LExit:
641 ReleaseVerutilVersion(pVersion);
642
643 return hr; 283 return hr;
644} 284}
645 285
@@ -653,11 +293,7 @@ static HRESULT BAEngineCloseSplashScreen(
653 ValidateMessageArgs(hr, pvArgs, BAENGINE_CLOSESPLASHSCREEN_ARGS, pArgs); 293 ValidateMessageArgs(hr, pvArgs, BAENGINE_CLOSESPLASHSCREEN_ARGS, pArgs);
654 ValidateMessageResults(hr, pvResults, BAENGINE_CLOSESPLASHSCREEN_RESULTS, pResults); 294 ValidateMessageResults(hr, pvResults, BAENGINE_CLOSESPLASHSCREEN_RESULTS, pResults);
655 295
656 // If the splash screen is still around, close it. 296 ExternalEngineCloseSplashScreen(pContext->pEngineState);
657 if (::IsWindow(pContext->pEngineState->command.hwndSplashScreen))
658 {
659 ::PostMessageW(pContext->pEngineState->command.hwndSplashScreen, WM_CLOSE, 0, 0);
660 }
661 297
662LExit: 298LExit:
663 return hr; 299 return hr;
@@ -672,11 +308,8 @@ static HRESULT BAEngineCompareVersions(
672 HRESULT hr = S_OK; 308 HRESULT hr = S_OK;
673 ValidateMessageArgs(hr, pvArgs, BAENGINE_COMPAREVERSIONS_ARGS, pArgs); 309 ValidateMessageArgs(hr, pvArgs, BAENGINE_COMPAREVERSIONS_ARGS, pArgs);
674 ValidateMessageResults(hr, pvResults, BAENGINE_COMPAREVERSIONS_RESULTS, pResults); 310 ValidateMessageResults(hr, pvResults, BAENGINE_COMPAREVERSIONS_RESULTS, pResults);
675 LPCWSTR wzVersion1 = pArgs->wzVersion1;
676 LPCWSTR wzVersion2 = pArgs->wzVersion2;
677 int* pnResult = &pResults->nResult;
678 311
679 hr = VerCompareStringVersions(wzVersion1, wzVersion2, FALSE, pnResult); 312 hr = ExternalEngineCompareVersions(pArgs->wzVersion1, pArgs->wzVersion2, &pResults->nResult);
680 313
681LExit: 314LExit:
682 return hr; 315 return hr;
@@ -692,10 +325,7 @@ static HRESULT BAEngineDetect(
692 ValidateMessageArgs(hr, pvArgs, BAENGINE_DETECT_ARGS, pArgs); 325 ValidateMessageArgs(hr, pvArgs, BAENGINE_DETECT_ARGS, pArgs);
693 ValidateMessageResults(hr, pvResults, BAENGINE_DETECT_RESULTS, pResults); 326 ValidateMessageResults(hr, pvResults, BAENGINE_DETECT_RESULTS, pResults);
694 327
695 if (!::PostThreadMessageW(pContext->dwThreadId, WM_BURN_DETECT, 0, reinterpret_cast<LPARAM>(pArgs->hwndParent))) 328 hr = ExternalEngineDetect(pContext->dwThreadId, pArgs->hwndParent);
696 {
697 ExitWithLastError(hr, "Failed to post detect message.");
698 }
699 329
700LExit: 330LExit:
701 return hr; 331 return hr;
@@ -710,12 +340,8 @@ static HRESULT BAEnginePlan(
710 HRESULT hr = S_OK; 340 HRESULT hr = S_OK;
711 ValidateMessageArgs(hr, pvArgs, BAENGINE_PLAN_ARGS, pArgs); 341 ValidateMessageArgs(hr, pvArgs, BAENGINE_PLAN_ARGS, pArgs);
712 ValidateMessageResults(hr, pvResults, BAENGINE_PLAN_RESULTS, pResults); 342 ValidateMessageResults(hr, pvResults, BAENGINE_PLAN_RESULTS, pResults);
713 BOOTSTRAPPER_ACTION action = pArgs->action;
714 343
715 if (!::PostThreadMessageW(pContext->dwThreadId, WM_BURN_PLAN, 0, action)) 344 hr = ExternalEnginePlan(pContext->dwThreadId, pArgs->action);
716 {
717 ExitWithLastError(hr, "Failed to post plan message.");
718 }
719 345
720LExit: 346LExit:
721 return hr; 347 return hr;
@@ -731,14 +357,7 @@ static HRESULT BAEngineElevate(
731 ValidateMessageArgs(hr, pvArgs, BAENGINE_ELEVATE_ARGS, pArgs); 357 ValidateMessageArgs(hr, pvArgs, BAENGINE_ELEVATE_ARGS, pArgs);
732 ValidateMessageResults(hr, pvResults, BAENGINE_ELEVATE_RESULTS, pResults); 358 ValidateMessageResults(hr, pvResults, BAENGINE_ELEVATE_RESULTS, pResults);
733 359
734 if (INVALID_HANDLE_VALUE != pContext->pEngineState->companionConnection.hPipe) 360 hr = ExternalEngineElevate(pContext->pEngineState, pContext->dwThreadId, pArgs->hwndParent);
735 {
736 hr = HRESULT_FROM_WIN32(ERROR_ALREADY_INITIALIZED);
737 }
738 else if (!::PostThreadMessageW(pContext->dwThreadId, WM_BURN_ELEVATE, 0, reinterpret_cast<LPARAM>(pArgs->hwndParent)))
739 {
740 ExitWithLastError(hr, "Failed to post elevate message.");
741 }
742 361
743LExit: 362LExit:
744 return hr; 363 return hr;
@@ -754,16 +373,7 @@ static HRESULT BAEngineApply(
754 ValidateMessageArgs(hr, pvArgs, BAENGINE_APPLY_ARGS, pArgs); 373 ValidateMessageArgs(hr, pvArgs, BAENGINE_APPLY_ARGS, pArgs);
755 ValidateMessageResults(hr, pvResults, BAENGINE_APPLY_RESULTS, pResults); 374 ValidateMessageResults(hr, pvResults, BAENGINE_APPLY_RESULTS, pResults);
756 375
757 ExitOnNull(pArgs->hwndParent, hr, E_INVALIDARG, "BA passed NULL hwndParent to Apply."); 376 hr = ExternalEngineApply(pContext->dwThreadId, pArgs->hwndParent);
758 if (!::IsWindow(pArgs->hwndParent))
759 {
760 ExitOnFailure(hr = E_INVALIDARG, "BA passed invalid hwndParent to Apply.");
761 }
762
763 if (!::PostThreadMessageW(pContext->dwThreadId, WM_BURN_APPLY, 0, reinterpret_cast<LPARAM>(pArgs->hwndParent)))
764 {
765 ExitWithLastError(hr, "Failed to post apply message.");
766 }
767 377
768LExit: 378LExit:
769 return hr; 379 return hr;
@@ -779,10 +389,7 @@ static HRESULT BAEngineQuit(
779 ValidateMessageArgs(hr, pvArgs, BAENGINE_QUIT_ARGS, pArgs); 389 ValidateMessageArgs(hr, pvArgs, BAENGINE_QUIT_ARGS, pArgs);
780 ValidateMessageResults(hr, pvResults, BAENGINE_QUIT_RESULTS, pResults); 390 ValidateMessageResults(hr, pvResults, BAENGINE_QUIT_RESULTS, pResults);
781 391
782 if (!::PostThreadMessageW(pContext->dwThreadId, WM_BURN_QUIT, static_cast<WPARAM>(pArgs->dwExitCode), 0)) 392 hr = ExternalEngineQuit(pContext->dwThreadId, pArgs->dwExitCode);
783 {
784 ExitWithLastError(hr, "Failed to post shutdown message.");
785 }
786 393
787LExit: 394LExit:
788 return hr; 395 return hr;
@@ -795,64 +402,12 @@ static HRESULT BAEngineLaunchApprovedExe(
795 ) 402 )
796{ 403{
797 HRESULT hr = S_OK; 404 HRESULT hr = S_OK;
798 BURN_APPROVED_EXE* pApprovedExe = NULL;
799 BOOL fLeaveCriticalSection = FALSE;
800 BURN_LAUNCH_APPROVED_EXE* pLaunchApprovedExe = NULL;
801 ValidateMessageArgs(hr, pvArgs, BAENGINE_LAUNCHAPPROVEDEXE_ARGS, pArgs); 405 ValidateMessageArgs(hr, pvArgs, BAENGINE_LAUNCHAPPROVEDEXE_ARGS, pArgs);
802 ValidateMessageResults(hr, pvResults, BAENGINE_LAUNCHAPPROVEDEXE_RESULTS, pResults); 406 ValidateMessageResults(hr, pvResults, BAENGINE_LAUNCHAPPROVEDEXE_RESULTS, pResults);
803 HWND hwndParent = pArgs->hwndParent;
804 LPCWSTR wzApprovedExeForElevationId = pArgs->wzApprovedExeForElevationId;
805 LPCWSTR wzArguments = pArgs->wzArguments;
806 DWORD dwWaitForInputIdleTimeout = pArgs->dwWaitForInputIdleTimeout;
807 407
808 pLaunchApprovedExe = (BURN_LAUNCH_APPROVED_EXE*)MemAlloc(sizeof(BURN_LAUNCH_APPROVED_EXE), TRUE); 408 hr = ExternalEngineLaunchApprovedExe(pContext->pEngineState, pContext->dwThreadId, pArgs->hwndParent, pArgs->wzApprovedExeForElevationId, pArgs->wzArguments, pArgs->dwWaitForInputIdleTimeout);
809 ExitOnNull(pLaunchApprovedExe, hr, E_OUTOFMEMORY, "Failed to alloc BURN_LAUNCH_APPROVED_EXE");
810
811 ::EnterCriticalSection(&pContext->pEngineState->csActive);
812 fLeaveCriticalSection = TRUE;
813 hr = UserExperienceEnsureEngineInactive(&pContext->pEngineState->userExperience);
814 ExitOnFailure(hr, "Engine is active, cannot change engine state.");
815
816 if (!wzApprovedExeForElevationId || !*wzApprovedExeForElevationId)
817 {
818 ExitFunction1(hr = E_INVALIDARG);
819 }
820
821 hr = ApprovedExesFindById(&pContext->pEngineState->approvedExes, wzApprovedExeForElevationId, &pApprovedExe);
822 ExitOnFailure(hr, "BA requested unknown approved exe with id: %ls", wzApprovedExeForElevationId);
823
824 ::LeaveCriticalSection(&pContext->pEngineState->csActive);
825 fLeaveCriticalSection = FALSE;
826
827 hr = StrAllocString(&pLaunchApprovedExe->sczId, wzApprovedExeForElevationId, NULL);
828 ExitOnFailure(hr, "Failed to copy the id.");
829
830 if (wzArguments)
831 {
832 hr = StrAllocString(&pLaunchApprovedExe->sczArguments, wzArguments, NULL);
833 ExitOnFailure(hr, "Failed to copy the arguments.");
834 }
835
836 pLaunchApprovedExe->dwWaitForInputIdleTimeout = dwWaitForInputIdleTimeout;
837
838 pLaunchApprovedExe->hwndParent = hwndParent;
839
840 if (!::PostThreadMessageW(pContext->dwThreadId, WM_BURN_LAUNCH_APPROVED_EXE, 0, reinterpret_cast<LPARAM>(pLaunchApprovedExe)))
841 {
842 ExitWithLastError(hr, "Failed to post launch approved exe message.");
843 }
844 409
845LExit: 410LExit:
846 if (fLeaveCriticalSection)
847 {
848 ::LeaveCriticalSection(&pContext->pEngineState->csActive);
849 }
850
851 if (FAILED(hr))
852 {
853 ApprovedExesUninitializeLaunch(pLaunchApprovedExe);
854 }
855
856 return hr; 411 return hr;
857} 412}
858 413
@@ -953,34 +508,3 @@ HRESULT WINAPI EngineForApplicationProc(
953LExit: 508LExit:
954 return hr; 509 return hr;
955} 510}
956
957static HRESULT CopyStringToBA(
958 __in LPWSTR wzValue,
959 __in_opt LPWSTR wzBuffer,
960 __inout DWORD* pcchBuffer
961 )
962{
963 HRESULT hr = S_OK;
964 BOOL fTooSmall = !wzBuffer;
965
966 if (!fTooSmall)
967 {
968 hr = ::StringCchCopyExW(wzBuffer, *pcchBuffer, wzValue, NULL, NULL, STRSAFE_FILL_BEHIND_NULL);
969 if (STRSAFE_E_INSUFFICIENT_BUFFER == hr)
970 {
971 fTooSmall = TRUE;
972 }
973 }
974
975 if (fTooSmall)
976 {
977 hr = ::StringCchLengthW(wzValue, STRSAFE_MAX_CCH, reinterpret_cast<size_t*>(pcchBuffer));
978 if (SUCCEEDED(hr))
979 {
980 hr = E_MOREDATA;
981 *pcchBuffer += 1; // null terminator.
982 }
983 }
984
985 return hr;
986}
diff --git a/src/engine/EngineForExtension.cpp b/src/engine/EngineForExtension.cpp
index 29b6a6b3..2e1c98fd 100644
--- a/src/engine/EngineForExtension.cpp
+++ b/src/engine/EngineForExtension.cpp
@@ -3,12 +3,6 @@
3#include "precomp.h" 3#include "precomp.h"
4 4
5 5
6static HRESULT CopyStringToBE(
7 __in LPWSTR wzValue,
8 __in LPWSTR wzBuffer,
9 __inout DWORD* pcchBuffer
10 );
11
12static HRESULT BEEngineEscapeString( 6static HRESULT BEEngineEscapeString(
13 __in BURN_EXTENSION_ENGINE_CONTEXT* /*pContext*/, 7 __in BURN_EXTENSION_ENGINE_CONTEXT* /*pContext*/,
14 __in const LPVOID pvArgs, 8 __in const LPVOID pvArgs,
@@ -16,28 +10,12 @@ static HRESULT BEEngineEscapeString(
16 ) 10 )
17{ 11{
18 HRESULT hr = S_OK; 12 HRESULT hr = S_OK;
19 LPWSTR sczValue = NULL;
20 ValidateMessageArgs(hr, pvArgs, BUNDLE_EXTENSION_ENGINE_ESCAPESTRING_ARGS, pArgs); 13 ValidateMessageArgs(hr, pvArgs, BUNDLE_EXTENSION_ENGINE_ESCAPESTRING_ARGS, pArgs);
21 ValidateMessageResults(hr, pvResults, BUNDLE_EXTENSION_ENGINE_ESCAPESTRING_RESULTS, pResults); 14 ValidateMessageResults(hr, pvResults, BUNDLE_EXTENSION_ENGINE_ESCAPESTRING_RESULTS, pResults);
22 LPCWSTR wzIn = pArgs->wzIn;
23 LPWSTR wzOut = pResults->wzOut;
24 DWORD* pcchOut = &pResults->cchOut;
25 15
26 if (wzIn && *wzIn) 16 hr = ExternalEngineEscapeString(pArgs->wzIn, pResults->wzOut, &pResults->cchOut);
27 {
28 hr = VariableEscapeString(wzIn, &sczValue);
29 if (SUCCEEDED(hr))
30 {
31 hr = CopyStringToBE(sczValue, wzOut, pcchOut);
32 }
33 }
34 else
35 {
36 hr = E_INVALIDARG;
37 }
38 17
39LExit: 18LExit:
40 StrSecureZeroFreeString(sczValue);
41 return hr; 19 return hr;
42} 20}
43 21
@@ -50,17 +28,8 @@ static HRESULT BEEngineEvaluateCondition(
50 HRESULT hr = S_OK; 28 HRESULT hr = S_OK;
51 ValidateMessageArgs(hr, pvArgs, BUNDLE_EXTENSION_ENGINE_EVALUATECONDITION_ARGS, pArgs); 29 ValidateMessageArgs(hr, pvArgs, BUNDLE_EXTENSION_ENGINE_EVALUATECONDITION_ARGS, pArgs);
52 ValidateMessageResults(hr, pvResults, BUNDLE_EXTENSION_ENGINE_EVALUATECONDITION_RESULTS, pResults); 30 ValidateMessageResults(hr, pvResults, BUNDLE_EXTENSION_ENGINE_EVALUATECONDITION_RESULTS, pResults);
53 LPCWSTR wzCondition = pArgs->wzCondition;
54 BOOL* pf = &pResults->f;
55 31
56 if (wzCondition && *wzCondition) 32 hr = ExternalEngineEvaluateCondition(pContext->pEngineState, pArgs->wzCondition, &pResults->f);
57 {
58 hr = ConditionEvaluate(&pContext->pEngineState->variables, wzCondition, pf);
59 }
60 else
61 {
62 hr = E_INVALIDARG;
63 }
64 33
65LExit: 34LExit:
66 return hr; 35 return hr;
@@ -73,28 +42,12 @@ static HRESULT BEEngineFormatString(
73 ) 42 )
74{ 43{
75 HRESULT hr = S_OK; 44 HRESULT hr = S_OK;
76 LPWSTR sczValue = NULL;
77 ValidateMessageArgs(hr, pvArgs, BUNDLE_EXTENSION_ENGINE_FORMATSTRING_ARGS, pArgs); 45 ValidateMessageArgs(hr, pvArgs, BUNDLE_EXTENSION_ENGINE_FORMATSTRING_ARGS, pArgs);
78 ValidateMessageResults(hr, pvResults, BUNDLE_EXTENSION_ENGINE_FORMATSTRING_RESULTS, pResults); 46 ValidateMessageResults(hr, pvResults, BUNDLE_EXTENSION_ENGINE_FORMATSTRING_RESULTS, pResults);
79 LPCWSTR wzIn = pArgs->wzIn;
80 LPWSTR wzOut = pResults->wzOut;
81 DWORD* pcchOut = &pResults->cchOut;
82 47
83 if (wzIn && *wzIn) 48 hr = ExternalEngineFormatString(pContext->pEngineState, pArgs->wzIn, pResults->wzOut, &pResults->cchOut);
84 {
85 hr = VariableFormatString(&pContext->pEngineState->variables, wzIn, &sczValue, NULL);
86 if (SUCCEEDED(hr))
87 {
88 hr = CopyStringToBE(sczValue, wzOut, pcchOut);
89 }
90 }
91 else
92 {
93 hr = E_INVALIDARG;
94 }
95 49
96LExit: 50LExit:
97 StrSecureZeroFreeString(sczValue);
98 return hr; 51 return hr;
99} 52}
100 53
@@ -107,17 +60,8 @@ static HRESULT BEEngineGetVariableNumeric(
107 HRESULT hr = S_OK; 60 HRESULT hr = S_OK;
108 ValidateMessageArgs(hr, pvArgs, BUNDLE_EXTENSION_ENGINE_GETVARIABLENUMERIC_ARGS, pArgs); 61 ValidateMessageArgs(hr, pvArgs, BUNDLE_EXTENSION_ENGINE_GETVARIABLENUMERIC_ARGS, pArgs);
109 ValidateMessageResults(hr, pvResults, BUNDLE_EXTENSION_ENGINE_GETVARIABLENUMERIC_RESULTS, pResults); 62 ValidateMessageResults(hr, pvResults, BUNDLE_EXTENSION_ENGINE_GETVARIABLENUMERIC_RESULTS, pResults);
110 LPCWSTR wzVariable = pArgs->wzVariable;
111 LONGLONG* pllValue = &pResults->llValue;
112 63
113 if (wzVariable && *wzVariable) 64 hr = ExternalEngineGetVariableNumeric(pContext->pEngineState, pArgs->wzVariable, &pResults->llValue);
114 {
115 hr = VariableGetNumeric(&pContext->pEngineState->variables, wzVariable, pllValue);
116 }
117 else
118 {
119 hr = E_INVALIDARG;
120 }
121 65
122LExit: 66LExit:
123 return hr; 67 return hr;
@@ -130,28 +74,12 @@ static HRESULT BEEngineGetVariableString(
130 ) 74 )
131{ 75{
132 HRESULT hr = S_OK; 76 HRESULT hr = S_OK;
133 LPWSTR sczValue = NULL;
134 ValidateMessageArgs(hr, pvArgs, BUNDLE_EXTENSION_ENGINE_GETVARIABLESTRING_ARGS, pArgs); 77 ValidateMessageArgs(hr, pvArgs, BUNDLE_EXTENSION_ENGINE_GETVARIABLESTRING_ARGS, pArgs);
135 ValidateMessageResults(hr, pvResults, BUNDLE_EXTENSION_ENGINE_GETVARIABLESTRING_RESULTS, pResults); 78 ValidateMessageResults(hr, pvResults, BUNDLE_EXTENSION_ENGINE_GETVARIABLESTRING_RESULTS, pResults);
136 LPCWSTR wzVariable = pArgs->wzVariable;
137 LPWSTR wzValue = pResults->wzValue;
138 DWORD* pcchValue = &pResults->cchValue;
139 79
140 if (wzVariable && *wzVariable) 80 hr = ExternalEngineGetVariableString(pContext->pEngineState, pArgs->wzVariable, pResults->wzValue, &pResults->cchValue);
141 {
142 hr = VariableGetString(&pContext->pEngineState->variables, wzVariable, &sczValue);
143 if (SUCCEEDED(hr))
144 {
145 hr = CopyStringToBE(sczValue, wzValue, pcchValue);
146 }
147 }
148 else
149 {
150 hr = E_INVALIDARG;
151 }
152 81
153LExit: 82LExit:
154 StrSecureZeroFreeString(sczValue);
155 return hr; 83 return hr;
156} 84}
157 85
@@ -162,29 +90,12 @@ static HRESULT BEEngineGetVariableVersion(
162 ) 90 )
163{ 91{
164 HRESULT hr = S_OK; 92 HRESULT hr = S_OK;
165 VERUTIL_VERSION* pVersion = NULL;
166 ValidateMessageArgs(hr, pvArgs, BUNDLE_EXTENSION_ENGINE_GETVARIABLEVERSION_ARGS, pArgs); 93 ValidateMessageArgs(hr, pvArgs, BUNDLE_EXTENSION_ENGINE_GETVARIABLEVERSION_ARGS, pArgs);
167 ValidateMessageResults(hr, pvResults, BUNDLE_EXTENSION_ENGINE_GETVARIABLEVERSION_RESULTS, pResults); 94 ValidateMessageResults(hr, pvResults, BUNDLE_EXTENSION_ENGINE_GETVARIABLEVERSION_RESULTS, pResults);
168 LPCWSTR wzVariable = pArgs->wzVariable;
169 LPWSTR wzValue = pResults->wzValue;
170 DWORD* pcchValue = &pResults->cchValue;
171 95
172 if (wzVariable && *wzVariable) 96 hr = ExternalEngineGetVariableVersion(pContext->pEngineState, pArgs->wzVariable, pResults->wzValue, &pResults->cchValue);
173 {
174 hr = VariableGetVersion(&pContext->pEngineState->variables, wzVariable, &pVersion);
175 if (SUCCEEDED(hr))
176 {
177 hr = CopyStringToBE(pVersion->sczVersion, wzValue, pcchValue);
178 }
179 }
180 else
181 {
182 hr = E_INVALIDARG;
183 }
184 97
185LExit: 98LExit:
186 ReleaseVerutilVersion(pVersion);
187
188 return hr; 99 return hr;
189} 100}
190 101
@@ -198,10 +109,8 @@ static HRESULT BEEngineLog(
198 REPORT_LEVEL rl = REPORT_NONE; 109 REPORT_LEVEL rl = REPORT_NONE;
199 ValidateMessageArgs(hr, pvArgs, BUNDLE_EXTENSION_ENGINE_LOG_ARGS, pArgs); 110 ValidateMessageArgs(hr, pvArgs, BUNDLE_EXTENSION_ENGINE_LOG_ARGS, pArgs);
200 ValidateMessageResults(hr, pvResults, BUNDLE_EXTENSION_ENGINE_LOG_RESULTS, pResults); 111 ValidateMessageResults(hr, pvResults, BUNDLE_EXTENSION_ENGINE_LOG_RESULTS, pResults);
201 BUNDLE_EXTENSION_LOG_LEVEL level = pArgs->level;
202 LPCWSTR wzMessage = pArgs->wzMessage;
203 112
204 switch (level) 113 switch (pArgs->level)
205 { 114 {
206 case BUNDLE_EXTENSION_LOG_LEVEL_STANDARD: 115 case BUNDLE_EXTENSION_LOG_LEVEL_STANDARD:
207 rl = REPORT_STANDARD; 116 rl = REPORT_STANDARD;
@@ -223,7 +132,7 @@ static HRESULT BEEngineLog(
223 ExitFunction1(hr = E_INVALIDARG); 132 ExitFunction1(hr = E_INVALIDARG);
224 } 133 }
225 134
226 hr = LogStringLine(rl, "%ls", wzMessage); 135 hr = ExternalEngineLog(rl, pArgs->wzMessage);
227 ExitOnFailure(hr, "Failed to log Bundle Extension message."); 136 ExitOnFailure(hr, "Failed to log Bundle Extension message.");
228 137
229LExit: 138LExit:
@@ -239,19 +148,8 @@ static HRESULT BEEngineSetVariableNumeric(
239 HRESULT hr = S_OK; 148 HRESULT hr = S_OK;
240 ValidateMessageArgs(hr, pvArgs, BUNDLE_EXTENSION_ENGINE_SETVARIABLENUMERIC_ARGS, pArgs); 149 ValidateMessageArgs(hr, pvArgs, BUNDLE_EXTENSION_ENGINE_SETVARIABLENUMERIC_ARGS, pArgs);
241 ValidateMessageResults(hr, pvResults, BUNDLE_EXTENSION_ENGINE_SETVARIABLENUMERIC_RESULTS, pResults); 150 ValidateMessageResults(hr, pvResults, BUNDLE_EXTENSION_ENGINE_SETVARIABLENUMERIC_RESULTS, pResults);
242 LPCWSTR wzVariable = pArgs->wzVariable;
243 LONGLONG llValue = pArgs->llValue;
244 151
245 if (wzVariable && *wzVariable) 152 hr = ExternalEngineSetVariableNumeric(pContext->pEngineState, pArgs->wzVariable, pArgs->llValue);
246 {
247 hr = VariableSetNumeric(&pContext->pEngineState->variables, wzVariable, llValue, FALSE);
248 ExitOnFailure(hr, "Failed to set numeric variable.");
249 }
250 else
251 {
252 hr = E_INVALIDARG;
253 ExitOnFailure(hr, "Bundle Extension did not provide variable name.");
254 }
255 153
256LExit: 154LExit:
257 return hr; 155 return hr;
@@ -266,19 +164,8 @@ static HRESULT BEEngineSetVariableString(
266 HRESULT hr = S_OK; 164 HRESULT hr = S_OK;
267 ValidateMessageArgs(hr, pvArgs, BUNDLE_EXTENSION_ENGINE_SETVARIABLESTRING_ARGS, pArgs); 165 ValidateMessageArgs(hr, pvArgs, BUNDLE_EXTENSION_ENGINE_SETVARIABLESTRING_ARGS, pArgs);
268 ValidateMessageResults(hr, pvResults, BUNDLE_EXTENSION_ENGINE_SETVARIABLESTRING_RESULTS, pResults); 166 ValidateMessageResults(hr, pvResults, BUNDLE_EXTENSION_ENGINE_SETVARIABLESTRING_RESULTS, pResults);
269 LPCWSTR wzVariable = pArgs->wzVariable;
270 LPCWSTR wzValue = pArgs->wzValue;
271 167
272 if (wzVariable && *wzVariable) 168 hr = ExternalEngineSetVariableString(pContext->pEngineState, pArgs->wzVariable, pArgs->wzValue, pArgs->fFormatted);
273 {
274 hr = VariableSetString(&pContext->pEngineState->variables, wzVariable, wzValue, FALSE, pArgs->fFormatted);
275 ExitOnFailure(hr, "Failed to set string variable.");
276 }
277 else
278 {
279 hr = E_INVALIDARG;
280 ExitOnFailure(hr, "Bundle Extension did not provide variable name.");
281 }
282 169
283LExit: 170LExit:
284 return hr; 171 return hr;
@@ -291,32 +178,12 @@ static HRESULT BEEngineSetVariableVersion(
291 ) 178 )
292{ 179{
293 HRESULT hr = S_OK; 180 HRESULT hr = S_OK;
294 VERUTIL_VERSION* pVersion = NULL;
295 ValidateMessageArgs(hr, pvArgs, BUNDLE_EXTENSION_ENGINE_SETVARIABLEVERSION_ARGS, pArgs); 181 ValidateMessageArgs(hr, pvArgs, BUNDLE_EXTENSION_ENGINE_SETVARIABLEVERSION_ARGS, pArgs);
296 ValidateMessageResults(hr, pvResults, BUNDLE_EXTENSION_ENGINE_SETVARIABLEVERSION_RESULTS, pResults); 182 ValidateMessageResults(hr, pvResults, BUNDLE_EXTENSION_ENGINE_SETVARIABLEVERSION_RESULTS, pResults);
297 LPCWSTR wzVariable = pArgs->wzVariable;
298 LPCWSTR wzValue = pArgs->wzValue;
299 183
300 if (wzVariable && *wzVariable) 184 hr = ExternalEngineSetVariableVersion(pContext->pEngineState, pArgs->wzVariable, pArgs->wzValue);
301 {
302 if (wzValue)
303 {
304 hr = VerParseVersion(wzValue, 0, FALSE, &pVersion);
305 ExitOnFailure(hr, "Failed to parse new version value.");
306 }
307
308 hr = VariableSetVersion(&pContext->pEngineState->variables, wzVariable, pVersion, FALSE);
309 ExitOnFailure(hr, "Failed to set version variable.");
310 }
311 else
312 {
313 hr = E_INVALIDARG;
314 ExitOnFailure(hr, "Bundle Extension did not provide variable name.");
315 }
316 185
317LExit: 186LExit:
318 ReleaseVerutilVersion(pVersion);
319
320 return hr; 187 return hr;
321} 188}
322 189
@@ -329,11 +196,8 @@ static HRESULT BEEngineCompareVersions(
329 HRESULT hr = S_OK; 196 HRESULT hr = S_OK;
330 ValidateMessageArgs(hr, pvArgs, BUNDLE_EXTENSION_ENGINE_COMPAREVERSIONS_ARGS, pArgs); 197 ValidateMessageArgs(hr, pvArgs, BUNDLE_EXTENSION_ENGINE_COMPAREVERSIONS_ARGS, pArgs);
331 ValidateMessageResults(hr, pvResults, BUNDLE_EXTENSION_ENGINE_COMPAREVERSIONS_RESULTS, pResults); 198 ValidateMessageResults(hr, pvResults, BUNDLE_EXTENSION_ENGINE_COMPAREVERSIONS_RESULTS, pResults);
332 LPCWSTR wzVersion1 = pArgs->wzVersion1;
333 LPCWSTR wzVersion2 = pArgs->wzVersion2;
334 int* pnResult = &pResults->nResult;
335 199
336 hr = VerCompareStringVersions(wzVersion1, wzVersion2, FALSE, pnResult); 200 hr = ExternalEngineCompareVersions(pArgs->wzVersion1, pArgs->wzVersion2, &pResults->nResult);
337 201
338LExit: 202LExit:
339 return hr; 203 return hr;
@@ -397,34 +261,3 @@ HRESULT WINAPI EngineForExtensionProc(
397LExit: 261LExit:
398 return hr; 262 return hr;
399} 263}
400
401static HRESULT CopyStringToBE(
402 __in LPWSTR wzValue,
403 __in LPWSTR wzBuffer,
404 __inout DWORD* pcchBuffer
405 )
406{
407 HRESULT hr = S_OK;
408 BOOL fTooSmall = !wzBuffer;
409
410 if (!fTooSmall)
411 {
412 hr = ::StringCchCopyExW(wzBuffer, *pcchBuffer, wzValue, NULL, NULL, STRSAFE_FILL_BEHIND_NULL);
413 if (STRSAFE_E_INSUFFICIENT_BUFFER == hr)
414 {
415 fTooSmall = TRUE;
416 }
417 }
418
419 if (fTooSmall)
420 {
421 hr = ::StringCchLengthW(wzValue, STRSAFE_MAX_CCH, reinterpret_cast<size_t*>(pcchBuffer));
422 if (SUCCEEDED(hr))
423 {
424 hr = E_MOREDATA;
425 *pcchBuffer += 1; // null terminator.
426 }
427 }
428
429 return hr;
430}
diff --git a/src/engine/externalengine.cpp b/src/engine/externalengine.cpp
index ef4f931d..3d5b3696 100644
--- a/src/engine/externalengine.cpp
+++ b/src/engine/externalengine.cpp
@@ -3,8 +3,737 @@
3#include "precomp.h" 3#include "precomp.h"
4 4
5 5
6static HRESULT CopyStringToExternal(
7 __in_z LPWSTR wzValue,
8 __in_z_opt LPWSTR wzBuffer,
9 __inout DWORD* pcchBuffer
10 );
11
6// function definitions 12// function definitions
7 13
14void ExternalEngineGetPackageCount(
15 __in BURN_ENGINE_STATE* pEngineState,
16 __out DWORD* pcPackages
17 )
18{
19 *pcPackages = pEngineState->packages.cPackages;
20}
21
22HRESULT ExternalEngineGetVariableNumeric(
23 __in BURN_ENGINE_STATE* pEngineState,
24 __in_z LPCWSTR wzVariable,
25 __out LONGLONG* pllValue
26 )
27{
28 HRESULT hr = S_OK;
29
30 if (wzVariable && *wzVariable)
31 {
32 hr = VariableGetNumeric(&pEngineState->variables, wzVariable, pllValue);
33 }
34 else
35 {
36 *pllValue = 0;
37 hr = E_INVALIDARG;
38 }
39
40 return hr;
41}
42
43HRESULT ExternalEngineGetVariableString(
44 __in BURN_ENGINE_STATE* pEngineState,
45 __in_z LPCWSTR wzVariable,
46 __out_ecount_opt(*pcchValue) LPWSTR wzValue,
47 __inout DWORD* pcchValue
48 )
49{
50 HRESULT hr = S_OK;
51 LPWSTR sczValue = NULL;
52
53 if (wzVariable && *wzVariable)
54 {
55 hr = VariableGetString(&pEngineState->variables, wzVariable, &sczValue);
56 if (SUCCEEDED(hr))
57 {
58 hr = CopyStringToExternal(sczValue, wzValue, pcchValue);
59 }
60 }
61 else
62 {
63 hr = E_INVALIDARG;
64 }
65
66 StrSecureZeroFreeString(sczValue);
67
68 return hr;
69}
70
71HRESULT ExternalEngineGetVariableVersion(
72 __in BURN_ENGINE_STATE* pEngineState,
73 __in_z LPCWSTR wzVariable,
74 __out_ecount_opt(*pcchValue) LPWSTR wzValue,
75 __inout DWORD* pcchValue
76 )
77{
78 HRESULT hr = S_OK;
79 VERUTIL_VERSION* pVersion = NULL;
80
81 if (wzVariable && *wzVariable)
82 {
83 hr = VariableGetVersion(&pEngineState->variables, wzVariable, &pVersion);
84 if (SUCCEEDED(hr))
85 {
86 hr = CopyStringToExternal(pVersion->sczVersion, wzValue, pcchValue);
87 }
88 }
89 else
90 {
91 hr = E_INVALIDARG;
92 }
93
94 ReleaseVerutilVersion(pVersion);
95
96 return hr;
97}
98
99HRESULT ExternalEngineFormatString(
100 __in BURN_ENGINE_STATE* pEngineState,
101 __in_z LPCWSTR wzIn,
102 __out_ecount_opt(*pcchOut) LPWSTR wzOut,
103 __inout DWORD* pcchOut
104 )
105{
106 HRESULT hr = S_OK;
107 LPWSTR sczValue = NULL;
108
109 if (wzIn && *wzIn)
110 {
111 hr = VariableFormatString(&pEngineState->variables, wzIn, &sczValue, NULL);
112 if (SUCCEEDED(hr))
113 {
114 hr = CopyStringToExternal(sczValue, wzOut, pcchOut);
115 }
116 }
117 else
118 {
119 hr = E_INVALIDARG;
120 }
121
122 StrSecureZeroFreeString(sczValue);
123
124 return hr;
125}
126
127HRESULT ExternalEngineEscapeString(
128 __in_z LPCWSTR wzIn,
129 __out_ecount_opt(*pcchOut) LPWSTR wzOut,
130 __inout DWORD* pcchOut
131 )
132{
133 HRESULT hr = S_OK;
134 LPWSTR sczValue = NULL;
135
136 if (wzIn && *wzIn)
137 {
138 hr = VariableEscapeString(wzIn, &sczValue);
139 if (SUCCEEDED(hr))
140 {
141 hr = CopyStringToExternal(sczValue, wzOut, pcchOut);
142 }
143 }
144 else
145 {
146 hr = E_INVALIDARG;
147 }
148
149 StrSecureZeroFreeString(sczValue);
150
151 return hr;
152}
153
154HRESULT ExternalEngineEvaluateCondition(
155 __in BURN_ENGINE_STATE* pEngineState,
156 __in_z LPCWSTR wzCondition,
157 __out BOOL* pf
158 )
159{
160 HRESULT hr = S_OK;
161
162 if (wzCondition && *wzCondition)
163 {
164 hr = ConditionEvaluate(&pEngineState->variables, wzCondition, pf);
165 }
166 else
167 {
168 *pf = FALSE;
169 hr = E_INVALIDARG;
170 }
171
172 return hr;
173}
174
175HRESULT ExternalEngineLog(
176 __in REPORT_LEVEL rl,
177 __in_z LPCWSTR wzMessage
178 )
179{
180 HRESULT hr = S_OK;
181
182 hr = LogStringLine(rl, "%ls", wzMessage);
183
184 return hr;
185}
186
187HRESULT ExternalEngineSendEmbeddedError(
188 __in BURN_ENGINE_STATE* pEngineState,
189 __in const DWORD dwErrorCode,
190 __in_z LPCWSTR wzMessage,
191 __in const DWORD dwUIHint,
192 __out int* pnResult
193 )
194{
195 HRESULT hr = S_OK;
196 BYTE* pbData = NULL;
197 DWORD cbData = 0;
198 DWORD dwResult = *pnResult = 0;
199
200 if (BURN_MODE_EMBEDDED != pEngineState->mode)
201 {
202 hr = HRESULT_FROM_WIN32(ERROR_INVALID_STATE);
203 ExitOnRootFailure(hr, "BA requested to send embedded message when not in embedded mode.");
204 }
205
206 hr = BuffWriteNumber(&pbData, &cbData, dwErrorCode);
207 ExitOnFailure(hr, "Failed to write error code to message buffer.");
208
209 hr = BuffWriteString(&pbData, &cbData, wzMessage ? wzMessage : L"");
210 ExitOnFailure(hr, "Failed to write message string to message buffer.");
211
212 hr = BuffWriteNumber(&pbData, &cbData, dwUIHint);
213 ExitOnFailure(hr, "Failed to write UI hint to message buffer.");
214
215 hr = PipeSendMessage(pEngineState->embeddedConnection.hPipe, BURN_EMBEDDED_MESSAGE_TYPE_ERROR, pbData, cbData, NULL, NULL, &dwResult);
216 ExitOnFailure(hr, "Failed to send embedded message over pipe.");
217
218 *pnResult = static_cast<int>(dwResult);
219
220LExit:
221 ReleaseBuffer(pbData);
222
223 return hr;
224}
225
226HRESULT ExternalEngineSendEmbeddedProgress(
227 __in BURN_ENGINE_STATE* pEngineState,
228 __in const DWORD dwProgressPercentage,
229 __in const DWORD dwOverallProgressPercentage,
230 __out int* pnResult
231 )
232{
233 HRESULT hr = S_OK;
234 BYTE* pbData = NULL;
235 DWORD cbData = 0;
236 DWORD dwResult = *pnResult = 0;
237
238 if (BURN_MODE_EMBEDDED != pEngineState->mode)
239 {
240 hr = HRESULT_FROM_WIN32(ERROR_INVALID_STATE);
241 ExitOnRootFailure(hr, "BA requested to send embedded progress message when not in embedded mode.");
242 }
243
244 hr = BuffWriteNumber(&pbData, &cbData, dwProgressPercentage);
245 ExitOnFailure(hr, "Failed to write progress percentage to message buffer.");
246
247 hr = BuffWriteNumber(&pbData, &cbData, dwOverallProgressPercentage);
248 ExitOnFailure(hr, "Failed to write overall progress percentage to message buffer.");
249
250 hr = PipeSendMessage(pEngineState->embeddedConnection.hPipe, BURN_EMBEDDED_MESSAGE_TYPE_PROGRESS, pbData, cbData, NULL, NULL, &dwResult);
251 ExitOnFailure(hr, "Failed to send embedded progress message over pipe.");
252
253 *pnResult = static_cast<int>(dwResult);
254
255LExit:
256 ReleaseBuffer(pbData);
257
258 return hr;
259}
260
261HRESULT ExternalEngineSetUpdate(
262 __in BURN_ENGINE_STATE* pEngineState,
263 __in_z_opt LPCWSTR wzLocalSource,
264 __in_z_opt LPCWSTR wzDownloadSource,
265 __in const DWORD64 qwSize,
266 __in const BOOTSTRAPPER_UPDATE_HASH_TYPE hashType,
267 __in_opt const BYTE* rgbHash,
268 __in const DWORD cbHash
269 )
270{
271 HRESULT hr = S_OK;
272 LPCWSTR sczId = NULL;
273 LPWSTR sczLocalSource = NULL;
274 LPWSTR sczCommandline = NULL;
275 UUID guid = { };
276 WCHAR wzGuid[39];
277 RPC_STATUS rs = RPC_S_OK;
278
279 ::EnterCriticalSection(&pEngineState->csActive);
280
281 if ((!wzLocalSource || !*wzLocalSource) && (!wzDownloadSource || !*wzDownloadSource))
282 {
283 UpdateUninitialize(&pEngineState->update);
284 }
285 else if (BOOTSTRAPPER_UPDATE_HASH_TYPE_NONE == hashType && (0 != cbHash || rgbHash))
286 {
287 hr = E_INVALIDARG;
288 }
289 else if (BOOTSTRAPPER_UPDATE_HASH_TYPE_SHA1 == hashType && (SHA1_HASH_LEN != cbHash || !rgbHash))
290 {
291 hr = E_INVALIDARG;
292 }
293 else
294 {
295 UpdateUninitialize(&pEngineState->update);
296
297 if (!wzLocalSource || !*wzLocalSource)
298 {
299 hr = StrAllocFormatted(&sczLocalSource, L"update\\%ls", pEngineState->registration.sczExecutableName);
300 ExitOnFailure(hr, "Failed to default local update source");
301 }
302
303 hr = CoreRecreateCommandLine(&sczCommandline, BOOTSTRAPPER_ACTION_INSTALL, pEngineState->command.display, pEngineState->command.restart, BOOTSTRAPPER_RELATION_NONE, FALSE, pEngineState->registration.sczActiveParent, pEngineState->registration.sczAncestors, NULL, pEngineState->command.wzCommandLine);
304 ExitOnFailure(hr, "Failed to recreate command-line for update bundle.");
305
306 // Per-user bundles would fail to use the downloaded update bundle, as the existing install would already be cached
307 // at the registration id's location. Here I am generating a random guid, but in the future it would be nice if the
308 // feed would provide the ID of the update.
309 if (!pEngineState->registration.fPerMachine)
310 {
311 rs = ::UuidCreate(&guid);
312 hr = HRESULT_FROM_RPC(rs);
313 ExitOnFailure(hr, "Failed to create bundle update guid.");
314
315 if (!::StringFromGUID2(guid, wzGuid, countof(wzGuid)))
316 {
317 hr = E_OUTOFMEMORY;
318 ExitOnRootFailure(hr, "Failed to convert bundle update guid into string.");
319 }
320
321 sczId = wzGuid;
322 }
323 else
324 {
325 sczId = pEngineState->registration.sczId;
326 }
327
328 hr = PseudoBundleInitialize(FILEMAKEVERSION(rmj, rmm, rup, rpr), &pEngineState->update.package, FALSE, sczId, BOOTSTRAPPER_RELATION_UPDATE, BOOTSTRAPPER_PACKAGE_STATE_ABSENT, pEngineState->registration.sczExecutableName, sczLocalSource ? sczLocalSource : wzLocalSource, wzDownloadSource, qwSize, TRUE, sczCommandline, NULL, NULL, NULL, rgbHash, cbHash);
329 ExitOnFailure(hr, "Failed to set update bundle.");
330
331 pEngineState->update.fUpdateAvailable = TRUE;
332 }
333
334LExit:
335 ::LeaveCriticalSection(&pEngineState->csActive);
336
337 ReleaseStr(sczCommandline);
338 ReleaseStr(sczLocalSource);
339
340 return hr;
341}
342
343HRESULT ExternalEngineSetLocalSource(
344 __in BURN_ENGINE_STATE* pEngineState,
345 __in_z_opt LPCWSTR wzPackageOrContainerId,
346 __in_z_opt LPCWSTR wzPayloadId,
347 __in_z LPCWSTR wzPath
348 )
349{
350 HRESULT hr = S_OK;
351 BURN_CONTAINER* pContainer = NULL;
352 BURN_PAYLOAD* pPayload = NULL;
353
354 ::EnterCriticalSection(&pEngineState->csActive);
355 hr = UserExperienceEnsureEngineInactive(&pEngineState->userExperience);
356 ExitOnFailure(hr, "Engine is active, cannot change engine state.");
357
358 if (!wzPath || !*wzPath)
359 {
360 hr = E_INVALIDARG;
361 }
362 else if (wzPayloadId && *wzPayloadId)
363 {
364 hr = PayloadFindById(&pEngineState->payloads, wzPayloadId, &pPayload);
365 ExitOnFailure(hr, "BA requested unknown payload with id: %ls", wzPayloadId);
366
367 if (BURN_PAYLOAD_PACKAGING_EMBEDDED == pPayload->packaging)
368 {
369 hr = HRESULT_FROM_WIN32(ERROR_INVALID_OPERATION);
370 ExitOnFailure(hr, "BA denied while trying to set source on embedded payload: %ls", wzPayloadId);
371 }
372
373 hr = StrAllocString(&pPayload->sczSourcePath, wzPath, 0);
374 ExitOnFailure(hr, "Failed to set source path for payload.");
375 }
376 else if (wzPackageOrContainerId && *wzPackageOrContainerId)
377 {
378 hr = ContainerFindById(&pEngineState->containers, wzPackageOrContainerId, &pContainer);
379 ExitOnFailure(hr, "BA requested unknown container with id: %ls", wzPackageOrContainerId);
380
381 hr = StrAllocString(&pContainer->sczSourcePath, wzPath, 0);
382 ExitOnFailure(hr, "Failed to set source path for container.");
383 }
384 else
385 {
386 hr = E_INVALIDARG;
387 }
388
389LExit:
390 ::LeaveCriticalSection(&pEngineState->csActive);
391
392 return hr;
393}
394
395HRESULT ExternalEngineSetDownloadSource(
396 __in BURN_ENGINE_STATE* pEngineState,
397 __in_z_opt LPCWSTR wzPackageOrContainerId,
398 __in_z_opt LPCWSTR wzPayloadId,
399 __in_z_opt LPCWSTR wzUrl,
400 __in_z_opt LPCWSTR wzUser,
401 __in_z_opt LPCWSTR wzPassword
402 )
403{
404 HRESULT hr = S_OK;
405 BURN_CONTAINER* pContainer = NULL;
406 BURN_PAYLOAD* pPayload = NULL;
407 DOWNLOAD_SOURCE* pDownloadSource = NULL;
408
409 ::EnterCriticalSection(&pEngineState->csActive);
410 hr = UserExperienceEnsureEngineInactive(&pEngineState->userExperience);
411 ExitOnFailure(hr, "Engine is active, cannot change engine state.");
412
413 if (wzPayloadId && *wzPayloadId)
414 {
415 hr = PayloadFindById(&pEngineState->payloads, wzPayloadId, &pPayload);
416 ExitOnFailure(hr, "BA requested unknown payload with id: %ls", wzPayloadId);
417
418 if (BURN_PAYLOAD_PACKAGING_EMBEDDED == pPayload->packaging)
419 {
420 hr = HRESULT_FROM_WIN32(ERROR_INVALID_OPERATION);
421 ExitOnFailure(hr, "BA denied while trying to set download URL on embedded payload: %ls", wzPayloadId);
422 }
423
424 pDownloadSource = &pPayload->downloadSource;
425 }
426 else if (wzPackageOrContainerId && *wzPackageOrContainerId)
427 {
428 hr = ContainerFindById(&pEngineState->containers, wzPackageOrContainerId, &pContainer);
429 ExitOnFailure(hr, "BA requested unknown container with id: %ls", wzPackageOrContainerId);
430
431 pDownloadSource = &pContainer->downloadSource;
432 }
433 else
434 {
435 hr = E_INVALIDARG;
436 ExitOnFailure(hr, "BA did not provide container or payload id.");
437 }
438
439 if (wzUrl && *wzUrl)
440 {
441 hr = StrAllocString(&pDownloadSource->sczUrl, wzUrl, 0);
442 ExitOnFailure(hr, "Failed to set download URL.");
443
444 if (wzUser && *wzUser)
445 {
446 hr = StrAllocString(&pDownloadSource->sczUser, wzUser, 0);
447 ExitOnFailure(hr, "Failed to set download user.");
448
449 if (wzPassword && *wzPassword)
450 {
451 hr = StrAllocString(&pDownloadSource->sczPassword, wzPassword, 0);
452 ExitOnFailure(hr, "Failed to set download password.");
453 }
454 else // no password.
455 {
456 ReleaseNullStr(pDownloadSource->sczPassword);
457 }
458 }
459 else // no user means no password either.
460 {
461 ReleaseNullStr(pDownloadSource->sczUser);
462 ReleaseNullStr(pDownloadSource->sczPassword);
463 }
464 }
465 else // no URL provided means clear out the whole download source.
466 {
467 ReleaseNullStr(pDownloadSource->sczUrl);
468 ReleaseNullStr(pDownloadSource->sczUser);
469 ReleaseNullStr(pDownloadSource->sczPassword);
470 }
471
472LExit:
473 ::LeaveCriticalSection(&pEngineState->csActive);
474
475 return hr;
476}
477
478HRESULT ExternalEngineSetVariableNumeric(
479 __in BURN_ENGINE_STATE* pEngineState,
480 __in_z LPCWSTR wzVariable,
481 __in const LONGLONG llValue
482 )
483{
484 HRESULT hr = S_OK;
485
486 if (wzVariable && *wzVariable)
487 {
488 hr = VariableSetNumeric(&pEngineState->variables, wzVariable, llValue, FALSE);
489 ExitOnFailure(hr, "Failed to set numeric variable.");
490 }
491 else
492 {
493 hr = E_INVALIDARG;
494 ExitOnFailure(hr, "SetVariableNumeric did not provide variable name.");
495 }
496
497LExit:
498 return hr;
499}
500
501HRESULT ExternalEngineSetVariableString(
502 __in BURN_ENGINE_STATE* pEngineState,
503 __in_z LPCWSTR wzVariable,
504 __in_z_opt LPCWSTR wzValue,
505 __in const BOOL fFormatted
506 )
507{
508 HRESULT hr = S_OK;
509
510 if (wzVariable && *wzVariable)
511 {
512 hr = VariableSetString(&pEngineState->variables, wzVariable, wzValue, FALSE, fFormatted);
513 ExitOnFailure(hr, "Failed to set string variable.");
514 }
515 else
516 {
517 hr = E_INVALIDARG;
518 ExitOnFailure(hr, "SetVariableString did not provide variable name.");
519 }
520
521LExit:
522 return hr;
523}
524
525HRESULT ExternalEngineSetVariableVersion(
526 __in BURN_ENGINE_STATE* pEngineState,
527 __in_z LPCWSTR wzVariable,
528 __in_z_opt LPCWSTR wzValue
529 )
530{
531 HRESULT hr = S_OK;
532 VERUTIL_VERSION* pVersion = NULL;
533
534 if (wzVariable && *wzVariable)
535 {
536 if (wzValue)
537 {
538 hr = VerParseVersion(wzValue, 0, FALSE, &pVersion);
539 ExitOnFailure(hr, "Failed to parse new version value.");
540 }
541
542 hr = VariableSetVersion(&pEngineState->variables, wzVariable, pVersion, FALSE);
543 ExitOnFailure(hr, "Failed to set version variable.");
544 }
545 else
546 {
547 hr = E_INVALIDARG;
548 ExitOnFailure(hr, "SetVariableVersion did not provide variable name.");
549 }
550
551LExit:
552 ReleaseVerutilVersion(pVersion);
553
554 return hr;
555}
556
557void ExternalEngineCloseSplashScreen(
558 __in BURN_ENGINE_STATE* pEngineState
559 )
560{
561 // If the splash screen is still around, close it.
562 if (::IsWindow(pEngineState->command.hwndSplashScreen))
563 {
564 ::PostMessageW(pEngineState->command.hwndSplashScreen, WM_CLOSE, 0, 0);
565 }
566}
567
568HRESULT ExternalEngineCompareVersions(
569 __in_z LPCWSTR wzVersion1,
570 __in_z LPCWSTR wzVersion2,
571 __out int* pnResult
572 )
573{
574 HRESULT hr = S_OK;
575
576 hr = VerCompareStringVersions(wzVersion1, wzVersion2, FALSE, pnResult);
577
578 return hr;
579}
580
581HRESULT ExternalEngineDetect(
582 __in const DWORD dwThreadId,
583 __in_opt const HWND hwndParent
584 )
585{
586 HRESULT hr = S_OK;
587
588 if (!::PostThreadMessageW(dwThreadId, WM_BURN_DETECT, 0, reinterpret_cast<LPARAM>(hwndParent)))
589 {
590 ExitWithLastError(hr, "Failed to post detect message.");
591 }
592
593LExit:
594 return hr;
595}
596
597HRESULT ExternalEnginePlan(
598 __in const DWORD dwThreadId,
599 __in const BOOTSTRAPPER_ACTION action
600 )
601{
602 HRESULT hr = S_OK;
603
604 if (!::PostThreadMessageW(dwThreadId, WM_BURN_PLAN, 0, action))
605 {
606 ExitWithLastError(hr, "Failed to post plan message.");
607 }
608
609LExit:
610 return hr;
611}
612
613HRESULT ExternalEngineElevate(
614 __in BURN_ENGINE_STATE* pEngineState,
615 __in const DWORD dwThreadId,
616 __in_opt const HWND hwndParent
617 )
618{
619 HRESULT hr = S_OK;
620
621 if (INVALID_HANDLE_VALUE != pEngineState->companionConnection.hPipe)
622 {
623 hr = HRESULT_FROM_WIN32(ERROR_ALREADY_INITIALIZED);
624 }
625 else if (!::PostThreadMessageW(dwThreadId, WM_BURN_ELEVATE, 0, reinterpret_cast<LPARAM>(hwndParent)))
626 {
627 ExitWithLastError(hr, "Failed to post elevate message.");
628 }
629
630LExit:
631 return hr;
632}
633
634HRESULT ExternalEngineApply(
635 __in const DWORD dwThreadId,
636 __in_opt const HWND hwndParent
637 )
638{
639 HRESULT hr = S_OK;
640
641 ExitOnNull(hwndParent, hr, E_INVALIDARG, "BA passed NULL hwndParent to Apply.");
642 if (!::IsWindow(hwndParent))
643 {
644 ExitOnFailure(hr = E_INVALIDARG, "BA passed invalid hwndParent to Apply.");
645 }
646
647 if (!::PostThreadMessageW(dwThreadId, WM_BURN_APPLY, 0, reinterpret_cast<LPARAM>(hwndParent)))
648 {
649 ExitWithLastError(hr, "Failed to post apply message.");
650 }
651
652LExit:
653 return hr;
654}
655
656HRESULT ExternalEngineQuit(
657 __in const DWORD dwThreadId,
658 __in const DWORD dwExitCode
659 )
660{
661 HRESULT hr = S_OK;
662
663 if (!::PostThreadMessageW(dwThreadId, WM_BURN_QUIT, static_cast<WPARAM>(dwExitCode), 0))
664 {
665 ExitWithLastError(hr, "Failed to post shutdown message.");
666 }
667
668LExit:
669 return hr;
670}
671
672HRESULT ExternalEngineLaunchApprovedExe(
673 __in BURN_ENGINE_STATE* pEngineState,
674 __in const DWORD dwThreadId,
675 __in_opt const HWND hwndParent,
676 __in_z LPCWSTR wzApprovedExeForElevationId,
677 __in_z_opt LPCWSTR wzArguments,
678 __in const DWORD dwWaitForInputIdleTimeout
679 )
680{
681 HRESULT hr = S_OK;
682 BURN_APPROVED_EXE* pApprovedExe = NULL;
683 BOOL fLeaveCriticalSection = FALSE;
684 BURN_LAUNCH_APPROVED_EXE* pLaunchApprovedExe = NULL;
685
686 pLaunchApprovedExe = (BURN_LAUNCH_APPROVED_EXE*)MemAlloc(sizeof(BURN_LAUNCH_APPROVED_EXE), TRUE);
687 ExitOnNull(pLaunchApprovedExe, hr, E_OUTOFMEMORY, "Failed to alloc BURN_LAUNCH_APPROVED_EXE");
688
689 ::EnterCriticalSection(&pEngineState->csActive);
690 fLeaveCriticalSection = TRUE;
691 hr = UserExperienceEnsureEngineInactive(&pEngineState->userExperience);
692 ExitOnFailure(hr, "Engine is active, cannot change engine state.");
693
694 if (!wzApprovedExeForElevationId || !*wzApprovedExeForElevationId)
695 {
696 ExitFunction1(hr = E_INVALIDARG);
697 }
698
699 hr = ApprovedExesFindById(&pEngineState->approvedExes, wzApprovedExeForElevationId, &pApprovedExe);
700 ExitOnFailure(hr, "BA requested unknown approved exe with id: %ls", wzApprovedExeForElevationId);
701
702 ::LeaveCriticalSection(&pEngineState->csActive);
703 fLeaveCriticalSection = FALSE;
704
705 hr = StrAllocString(&pLaunchApprovedExe->sczId, wzApprovedExeForElevationId, NULL);
706 ExitOnFailure(hr, "Failed to copy the id.");
707
708 if (wzArguments)
709 {
710 hr = StrAllocString(&pLaunchApprovedExe->sczArguments, wzArguments, NULL);
711 ExitOnFailure(hr, "Failed to copy the arguments.");
712 }
713
714 pLaunchApprovedExe->dwWaitForInputIdleTimeout = dwWaitForInputIdleTimeout;
715
716 pLaunchApprovedExe->hwndParent = hwndParent;
717
718 if (!::PostThreadMessageW(dwThreadId, WM_BURN_LAUNCH_APPROVED_EXE, 0, reinterpret_cast<LPARAM>(pLaunchApprovedExe)))
719 {
720 ExitWithLastError(hr, "Failed to post launch approved exe message.");
721 }
722
723LExit:
724 if (fLeaveCriticalSection)
725 {
726 ::LeaveCriticalSection(&pEngineState->csActive);
727 }
728
729 if (FAILED(hr))
730 {
731 ApprovedExesUninitializeLaunch(pLaunchApprovedExe);
732 }
733
734 return hr;
735}
736
8// TODO: callers need to provide the original size (at the time of first public release) of the struct instead of the current size. 737// TODO: callers need to provide the original size (at the time of first public release) of the struct instead of the current size.
9HRESULT WINAPI ExternalEngineValidateMessageParameter( 738HRESULT WINAPI ExternalEngineValidateMessageParameter(
10 __in_opt const LPVOID pv, 739 __in_opt const LPVOID pv,
@@ -28,3 +757,34 @@ HRESULT WINAPI ExternalEngineValidateMessageParameter(
28LExit: 757LExit:
29 return hr; 758 return hr;
30} 759}
760
761static HRESULT CopyStringToExternal(
762 __in_z LPWSTR wzValue,
763 __in_z_opt LPWSTR wzBuffer,
764 __inout DWORD* pcchBuffer
765 )
766{
767 HRESULT hr = S_OK;
768 BOOL fTooSmall = !wzBuffer;
769
770 if (!fTooSmall)
771 {
772 hr = ::StringCchCopyExW(wzBuffer, *pcchBuffer, wzValue, NULL, NULL, STRSAFE_FILL_BEHIND_NULL);
773 if (STRSAFE_E_INSUFFICIENT_BUFFER == hr)
774 {
775 fTooSmall = TRUE;
776 }
777 }
778
779 if (fTooSmall)
780 {
781 hr = ::StringCchLengthW(wzValue, STRSAFE_MAX_CCH, reinterpret_cast<size_t*>(pcchBuffer));
782 if (SUCCEEDED(hr))
783 {
784 hr = E_MOREDATA;
785 *pcchBuffer += 1; // null terminator.
786 }
787 }
788
789 return hr;
790}
diff --git a/src/engine/externalengine.h b/src/engine/externalengine.h
index 7910b224..3f7bc8c8 100644
--- a/src/engine/externalengine.h
+++ b/src/engine/externalengine.h
@@ -11,6 +11,160 @@
11extern "C" { 11extern "C" {
12#endif 12#endif
13 13
14void ExternalEngineGetPackageCount(
15 __in BURN_ENGINE_STATE* pEngineState,
16 __out DWORD* pcPackages
17 );
18
19HRESULT ExternalEngineGetVariableNumeric(
20 __in BURN_ENGINE_STATE* pEngineState,
21 __in_z LPCWSTR wzVariable,
22 __out LONGLONG* pllValue
23 );
24
25HRESULT ExternalEngineGetVariableString(
26 __in BURN_ENGINE_STATE* pEngineState,
27 __in_z LPCWSTR wzVariable,
28 __out_ecount_opt(*pcchValue) LPWSTR wzValue,
29 __inout DWORD* pcchValue
30 );
31
32HRESULT ExternalEngineGetVariableVersion(
33 __in BURN_ENGINE_STATE* pEngineState,
34 __in_z LPCWSTR wzVariable,
35 __out_ecount_opt(*pcchValue) LPWSTR wzValue,
36 __inout DWORD* pcchValue
37 );
38
39HRESULT ExternalEngineFormatString(
40 __in BURN_ENGINE_STATE* pEngineState,
41 __in_z LPCWSTR wzIn,
42 __out_ecount_opt(*pcchOut) LPWSTR wzOut,
43 __inout DWORD* pcchOut
44 );
45
46HRESULT ExternalEngineEscapeString(
47 __in_z LPCWSTR wzIn,
48 __out_ecount_opt(*pcchOut) LPWSTR wzOut,
49 __inout DWORD* pcchOut
50 );
51
52HRESULT ExternalEngineEvaluateCondition(
53 __in BURN_ENGINE_STATE* pEngineState,
54 __in_z LPCWSTR wzCondition,
55 __out BOOL* pf
56 );
57
58HRESULT ExternalEngineLog(
59 __in REPORT_LEVEL rl,
60 __in_z LPCWSTR wzMessage
61 );
62
63HRESULT ExternalEngineSendEmbeddedError(
64 __in BURN_ENGINE_STATE* pEngineState,
65 __in const DWORD dwErrorCode,
66 __in_z LPCWSTR wzMessage,
67 __in const DWORD dwUIHint,
68 __out int* pnResult
69 );
70
71HRESULT ExternalEngineSendEmbeddedProgress(
72 __in BURN_ENGINE_STATE* pEngineState,
73 __in const DWORD dwProgressPercentage,
74 __in const DWORD dwOverallProgressPercentage,
75 __out int* pnResult
76 );
77
78HRESULT ExternalEngineSetUpdate(
79 __in BURN_ENGINE_STATE* pEngineState,
80 __in_z_opt LPCWSTR wzLocalSource,
81 __in_z_opt LPCWSTR wzDownloadSource,
82 __in const DWORD64 qwSize,
83 __in const BOOTSTRAPPER_UPDATE_HASH_TYPE hashType,
84 __in_opt const BYTE* rgbHash,
85 __in const DWORD cbHash
86 );
87
88HRESULT ExternalEngineSetLocalSource(
89 __in BURN_ENGINE_STATE* pEngineState,
90 __in_z_opt LPCWSTR wzPackageOrContainerId,
91 __in_z_opt LPCWSTR wzPayloadId,
92 __in_z LPCWSTR wzPath
93 );
94
95HRESULT ExternalEngineSetDownloadSource(
96 __in BURN_ENGINE_STATE* pEngineState,
97 __in_z_opt LPCWSTR wzPackageOrContainerId,
98 __in_z_opt LPCWSTR wzPayloadId,
99 __in_z_opt LPCWSTR wzUrl,
100 __in_z_opt LPCWSTR wzUser,
101 __in_z_opt LPCWSTR wzPassword
102 );
103
104HRESULT ExternalEngineSetVariableNumeric(
105 __in BURN_ENGINE_STATE* pEngineState,
106 __in_z LPCWSTR wzVariable,
107 __in const LONGLONG llValue
108 );
109
110HRESULT ExternalEngineSetVariableString(
111 __in BURN_ENGINE_STATE* pEngineState,
112 __in_z LPCWSTR wzVariable,
113 __in_z_opt LPCWSTR wzValue,
114 __in const BOOL fFormatted
115 );
116
117HRESULT ExternalEngineSetVariableVersion(
118 __in BURN_ENGINE_STATE* pEngineState,
119 __in_z LPCWSTR wzVariable,
120 __in_z_opt LPCWSTR wzValue
121 );
122
123void ExternalEngineCloseSplashScreen(
124 __in BURN_ENGINE_STATE* pEngineState
125 );
126
127HRESULT ExternalEngineCompareVersions(
128 __in_z LPCWSTR wzVersion1,
129 __in_z LPCWSTR wzVersion2,
130 __out int* pnResult
131 );
132
133HRESULT ExternalEngineDetect(
134 __in const DWORD dwThreadId,
135 __in_opt const HWND hwndParent
136 );
137
138HRESULT ExternalEnginePlan(
139 __in const DWORD dwThreadId,
140 __in const BOOTSTRAPPER_ACTION action
141 );
142
143HRESULT ExternalEngineElevate(
144 __in BURN_ENGINE_STATE* pEngineState,
145 __in const DWORD dwThreadId,
146 __in_opt const HWND hwndParent
147 );
148
149HRESULT ExternalEngineApply(
150 __in const DWORD dwThreadId,
151 __in_opt const HWND hwndParent
152 );
153
154HRESULT ExternalEngineQuit(
155 __in const DWORD dwThreadId,
156 __in const DWORD dwExitCode
157 );
158
159HRESULT ExternalEngineLaunchApprovedExe(
160 __in BURN_ENGINE_STATE* pEngineState,
161 __in const DWORD dwThreadId,
162 __in_opt const HWND hwndParent,
163 __in_z LPCWSTR wzApprovedExeForElevationId,
164 __in_z_opt LPCWSTR wzArguments,
165 __in const DWORD dwWaitForInputIdleTimeout
166 );
167
14HRESULT WINAPI ExternalEngineValidateMessageParameter( 168HRESULT WINAPI ExternalEngineValidateMessageParameter(
15 __in_opt const LPVOID pv, 169 __in_opt const LPVOID pv,
16 __in SIZE_T cbSizeOffset, 170 __in SIZE_T cbSizeOffset,
diff --git a/src/engine/pseudobundle.cpp b/src/engine/pseudobundle.cpp
index 70f93701..0864be3a 100644
--- a/src/engine/pseudobundle.cpp
+++ b/src/engine/pseudobundle.cpp
@@ -19,8 +19,8 @@ extern "C" HRESULT PseudoBundleInitialize(
19 __in_z_opt LPCWSTR wzRepairArguments, 19 __in_z_opt LPCWSTR wzRepairArguments,
20 __in_z_opt LPCWSTR wzUninstallArguments, 20 __in_z_opt LPCWSTR wzUninstallArguments,
21 __in_opt BURN_DEPENDENCY_PROVIDER* pDependencyProvider, 21 __in_opt BURN_DEPENDENCY_PROVIDER* pDependencyProvider,
22 __in_opt BYTE* pbHash, 22 __in_opt const BYTE* pbHash,
23 __in DWORD cbHash 23 __in const DWORD cbHash
24 ) 24 )
25{ 25{
26 HRESULT hr = S_OK; 26 HRESULT hr = S_OK;
diff --git a/src/engine/pseudobundle.h b/src/engine/pseudobundle.h
index 144f6880..4d3d3052 100644
--- a/src/engine/pseudobundle.h
+++ b/src/engine/pseudobundle.h
@@ -22,8 +22,8 @@ HRESULT PseudoBundleInitialize(
22 __in_z_opt LPCWSTR wzRepairArguments, 22 __in_z_opt LPCWSTR wzRepairArguments,
23 __in_z_opt LPCWSTR wzUninstallArguments, 23 __in_z_opt LPCWSTR wzUninstallArguments,
24 __in_opt BURN_DEPENDENCY_PROVIDER* pDependencyProvider, 24 __in_opt BURN_DEPENDENCY_PROVIDER* pDependencyProvider,
25 __in_opt BYTE* pbHash, 25 __in_opt const BYTE* pbHash,
26 __in DWORD cbHash 26 __in const DWORD cbHash
27 ); 27 );
28HRESULT PseudoBundleInitializePassthrough( 28HRESULT PseudoBundleInitializePassthrough(
29 __in BURN_PACKAGE* pPassthroughPackage, 29 __in BURN_PACKAGE* pPassthroughPackage,