aboutsummaryrefslogtreecommitdiff
path: root/src/engine/EngineForApplication.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/engine/EngineForApplication.cpp')
-rw-r--r--src/engine/EngineForApplication.cpp528
1 files changed, 26 insertions, 502 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}