@joebigelow / wix / commits / fdd47bab

Consolidate the code for the BA and bext engines.

Sean Hall committed Nov 17, 2020 at 18:53 UTC fdd47bab30235f62a8bcc7a5a88c6d69267046aa
6 files changed +956 -685
src/engine/EngineForApplication.cpp
+26 -502
@@ -3,12 +3,6 @@
3 #include "precomp.h"
4
5
6 -static HRESULT CopyStringToBA(
7 - __in LPWSTR wzValue,
8 - __in_opt LPWSTR wzBuffer,
9 - __inout DWORD* pcchBuffer
10 - );
11 -
6 static HRESULT BAEngineGetPackageCount(
7 __in BOOTSTRAPPER_ENGINE_CONTEXT* pContext,
8 __in const LPVOID pvArgs,
@@ -18,9 +12,8 @@ static HRESULT BAEngineGetPackageCount(
12 HRESULT hr = S_OK;
13 ValidateMessageArgs(hr, pvArgs, BAENGINE_GETPACKAGECOUNT_ARGS, pArgs);
14 ValidateMessageResults(hr, pvResults, BAENGINE_GETPACKAGECOUNT_RESULTS, pResults);
21 - DWORD* pcPackages = &pResults->cPackages;
15
23 - *pcPackages = pContext->pEngineState->packages.cPackages;
16 + ExternalEngineGetPackageCount(pContext->pEngineState, &pResults->cPackages);
17
18 LExit:
19 return hr;
@@ -35,17 +28,8 @@ static HRESULT BAEngineGetVariableNumeric(
28 HRESULT hr = S_OK;
29 ValidateMessageArgs(hr, pvArgs, BAENGINE_GETVARIABLENUMERIC_ARGS, pArgs);
30 ValidateMessageResults(hr, pvResults, BAENGINE_GETVARIABLENUMERIC_RESULTS, pResults);
38 - LPCWSTR wzVariable = pArgs->wzVariable;
39 - LONGLONG* pllValue = &pResults->llValue;
31
41 - if (wzVariable && *wzVariable)
42 - {
43 - hr = VariableGetNumeric(&pContext->pEngineState->variables, wzVariable, pllValue);
44 - }
45 - else
46 - {
47 - hr = E_INVALIDARG;
48 - }
32 + hr = ExternalEngineGetVariableNumeric(pContext->pEngineState, pArgs->wzVariable, &pResults->llValue);
33
34 LExit:
35 return hr;
@@ -58,28 +42,12 @@ static HRESULT BAEngineGetVariableString(
42 )
43 {
44 HRESULT hr = S_OK;
61 - LPWSTR sczValue = NULL;
45 ValidateMessageArgs(hr, pvArgs, BAENGINE_GETVARIABLESTRING_ARGS, pArgs);
46 ValidateMessageResults(hr, pvResults, BAENGINE_GETVARIABLESTRING_RESULTS, pResults);
64 - LPCWSTR wzVariable = pArgs->wzVariable;
65 - LPWSTR wzValue = pResults->wzValue;
66 - DWORD* pcchValue = &pResults->cchValue;
47
68 - if (wzVariable && *wzVariable)
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 - }
48 + hr = ExternalEngineGetVariableString(pContext->pEngineState, pArgs->wzVariable, pResults->wzValue, &pResults->cchValue);
49
50 LExit:
82 - StrSecureZeroFreeString(sczValue);
51 return hr;
52 }
53
@@ -90,29 +58,12 @@ static HRESULT BAEngineGetVariableVersion(
58 )
59 {
60 HRESULT hr = S_OK;
93 - VERUTIL_VERSION* pVersion = NULL;
61 ValidateMessageArgs(hr, pvArgs, BAENGINE_GETVARIABLEVERSION_ARGS, pArgs);
62 ValidateMessageResults(hr, pvResults, BAENGINE_GETVARIABLEVERSION_RESULTS, pResults);
96 - LPCWSTR wzVariable = pArgs->wzVariable;
97 - LPWSTR wzValue = pResults->wzValue;
98 - DWORD* pcchValue = &pResults->cchValue;
63
100 - if (wzVariable && *wzVariable)
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 - }
64 + hr = ExternalEngineGetVariableVersion(pContext->pEngineState, pArgs->wzVariable, pResults->wzValue, &pResults->cchValue);
65
66 LExit:
114 - ReleaseVerutilVersion(pVersion);
115 -
67 return hr;
68 }
69
@@ -123,28 +74,12 @@ static HRESULT BAEngineFormatString(
74 )
75 {
76 HRESULT hr = S_OK;
126 - LPWSTR sczValue = NULL;
77 ValidateMessageArgs(hr, pvArgs, BAENGINE_FORMATSTRING_ARGS, pArgs);
78 ValidateMessageResults(hr, pvResults, BAENGINE_FORMATSTRING_RESULTS, pResults);
129 - LPCWSTR wzIn = pArgs->wzIn;
130 - LPWSTR wzOut = pResults->wzOut;
131 - DWORD* pcchOut = &pResults->cchOut;
79
133 - if (wzIn && *wzIn)
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 - }
80 + hr = ExternalEngineFormatString(pContext->pEngineState, pArgs->wzIn, pResults->wzOut, &pResults->cchOut);
81
82 LExit:
147 - StrSecureZeroFreeString(sczValue);
83 return hr;
84 }
85
@@ -155,28 +90,12 @@ static HRESULT BAEngineEscapeString(
90 )
91 {
92 HRESULT hr = S_OK;
158 - LPWSTR sczValue = NULL;
93 ValidateMessageArgs(hr, pvArgs, BAENGINE_ESCAPESTRING_ARGS, pArgs);
94 ValidateMessageResults(hr, pvResults, BAENGINE_ESCAPESTRING_RESULTS, pResults);
161 - LPCWSTR wzIn = pArgs->wzIn;
162 - LPWSTR wzOut = pResults->wzOut;
163 - DWORD* pcchOut = &pResults->cchOut;
95
165 - if (wzIn && *wzIn)
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 - }
96 + hr = ExternalEngineEscapeString(pArgs->wzIn, pResults->wzOut, &pResults->cchOut);
97
98 LExit:
179 - StrSecureZeroFreeString(sczValue);
99 return hr;
100 }
101
@@ -189,17 +108,8 @@ static HRESULT BAEngineEvaluateCondition(
108 HRESULT hr = S_OK;
109 ValidateMessageArgs(hr, pvArgs, BAENGINE_EVALUATECONDITION_ARGS, pArgs);
110 ValidateMessageResults(hr, pvResults, BAENGINE_EVALUATECONDITION_RESULTS, pResults);
192 - LPCWSTR wzCondition = pArgs->wzCondition;
193 - BOOL* pf = &pResults->f;
111
195 - if (wzCondition && *wzCondition)
196 - {
197 - hr = ConditionEvaluate(&pContext->pEngineState->variables, wzCondition, pf);
198 - }
199 - else
200 - {
201 - hr = E_INVALIDARG;
202 - }
112 + hr = ExternalEngineEvaluateCondition(pContext->pEngineState, pArgs->wzCondition, &pResults->f);
113
114 LExit:
115 return hr;
@@ -212,13 +122,11 @@ static HRESULT BAEngineLog(
122 )
123 {
124 HRESULT hr = S_OK;
125 + REPORT_LEVEL rl = REPORT_NONE;
126 ValidateMessageArgs(hr, pvArgs, BAENGINE_LOG_ARGS, pArgs);
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;
128
221 - switch (level)
129 + switch (pArgs->level)
130 {
131 case BOOTSTRAPPER_LOG_LEVEL_STANDARD:
132 rl = REPORT_STANDARD;
@@ -240,7 +148,7 @@ static HRESULT BAEngineLog(
148 ExitFunction1(hr = E_INVALIDARG);
149 }
150
243 - hr = LogStringLine(rl, "%ls", wzMessage);
151 + hr = ExternalEngineLog(rl, pArgs->wzMessage);
152 ExitOnFailure(hr, "Failed to log BA message.");
153
154 LExit:
@@ -254,38 +162,12 @@ static HRESULT BAEngineSendEmbeddedError(
162 )
163 {
164 HRESULT hr = S_OK;
257 - BYTE* pbData = NULL;
258 - DWORD cbData = 0;
259 - DWORD dwResult = 0;
165 ValidateMessageArgs(hr, pvArgs, BAENGINE_SENDEMBEDDEDERROR_ARGS, pArgs);
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.");
167
276 - hr = BuffWriteString(&pbData, &cbData, wzMessage ? wzMessage : L"");
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);
168 + hr = ExternalEngineSendEmbeddedError(pContext->pEngineState, pArgs->dwErrorCode, pArgs->wzMessage, pArgs->dwUIHint, &pResults->nResult);
169
170 LExit:
288 - ReleaseBuffer(pbData);
171 return hr;
172 }
173
@@ -296,34 +178,12 @@ static HRESULT BAEngineSendEmbeddedProgress(
178 )
179 {
180 HRESULT hr = S_OK;
299 - BYTE* pbData = NULL;
300 - DWORD cbData = 0;
301 - DWORD dwResult = 0;
181 ValidateMessageArgs(hr, pvArgs, BAENGINE_SENDEMBEDDEDPROGRESS_ARGS, pArgs);
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.");
183
323 - *pnResult = static_cast<int>(dwResult);
184 + hr = ExternalEngineSendEmbeddedProgress(pContext->pEngineState, pArgs->dwProgressPercentage, pArgs->dwOverallProgressPercentage, &pResults->nResult);
185
186 LExit:
326 - ReleaseBuffer(pbData);
187 return hr;
188 }
189
@@ -334,81 +194,12 @@ static HRESULT BAEngineSetUpdate(
194 )
195 {
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;
197 ValidateMessageArgs(hr, pvArgs, BAENGINE_SETUPDATE_ARGS, pArgs);
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;
199
352 - ::EnterCriticalSection(&pContext->pEngineState->csActive);
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 - }
200 + hr = ExternalEngineSetUpdate(pContext->pEngineState, pArgs->wzLocalSource, pArgs->wzDownloadSource, pArgs->qwSize, pArgs->hashType, pArgs->rgbHash, pArgs->cbHash);
201
202 LExit:
408 - ::LeaveCriticalSection(&pContext->pEngineState->csActive);
409 -
410 - ReleaseStr(sczCommandline);
411 - ReleaseStr(sczLocalSource);
203 return hr;
204 }
205
@@ -419,51 +210,12 @@ static HRESULT BAEngineSetLocalSource(
210 )
211 {
212 HRESULT hr = S_OK;
422 - BURN_CONTAINER* pContainer = NULL;
423 - BURN_PAYLOAD* pPayload = NULL;
213 ValidateMessageArgs(hr, pvArgs, BAENGINE_SETLOCALSOURCE_ARGS, pArgs);
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 - }
215
449 - hr = StrAllocString(&pPayload->sczSourcePath, wzPath, 0);
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 - }
216 + hr = ExternalEngineSetLocalSource(pContext->pEngineState, pArgs->wzPackageOrContainerId, pArgs->wzPayloadId, pArgs->wzPath);
217
218 LExit:
466 - ::LeaveCriticalSection(&pContext->pEngineState->csActive);
219 return hr;
220 }
221
@@ -474,82 +226,12 @@ static HRESULT BAEngineSetDownloadSource(
226 )
227 {
228 HRESULT hr = S_OK;
477 - BURN_CONTAINER* pContainer = NULL;
478 - BURN_PAYLOAD* pPayload = NULL;
479 - DOWNLOAD_SOURCE* pDownloadSource = NULL;
229 ValidateMessageArgs(hr, pvArgs, BAENGINE_SETDOWNLOADSOURCE_ARGS, pArgs);
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;
231
488 - ::EnterCriticalSection(&pContext->pEngineState->csActive);
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 - }
232 + hr = ExternalEngineSetDownloadSource(pContext->pEngineState, pArgs->wzPackageOrContainerId, pArgs->wzPayloadId, pArgs->wzUrl, pArgs->wzUser, pArgs->wzPassword);
233
234 LExit:
552 - ::LeaveCriticalSection(&pContext->pEngineState->csActive);
235 return hr;
236 }
237
@@ -562,19 +244,8 @@ static HRESULT BAEngineSetVariableNumeric(
244 HRESULT hr = S_OK;
245 ValidateMessageArgs(hr, pvArgs, BAENGINE_SETVARIABLENUMERIC_ARGS, pArgs);
246 ValidateMessageResults(hr, pvResults, BAENGINE_SETVARIABLENUMERIC_RESULTS, pResults);
565 - LPCWSTR wzVariable = pArgs->wzVariable;
566 - LONGLONG llValue = pArgs->llValue;
247
568 - if (wzVariable && *wzVariable)
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 - }
248 + hr = ExternalEngineSetVariableNumeric(pContext->pEngineState, pArgs->wzVariable, pArgs->llValue);
249
250 LExit:
251 return hr;
@@ -589,19 +260,8 @@ static HRESULT BAEngineSetVariableString(
260 HRESULT hr = S_OK;
261 ValidateMessageArgs(hr, pvArgs, BAENGINE_SETVARIABLESTRING_ARGS, pArgs);
262 ValidateMessageResults(hr, pvResults, BAENGINE_SETVARIABLESTRING_RESULTS, pResults);
592 - LPCWSTR wzVariable = pArgs->wzVariable;
593 - LPCWSTR wzValue = pArgs->wzValue;
263
595 - if (wzVariable && *wzVariable)
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 - }
264 + hr = ExternalEngineSetVariableString(pContext->pEngineState, pArgs->wzVariable, pArgs->wzValue, pArgs->fFormatted);
265
266 LExit:
267 return hr;
@@ -614,32 +274,12 @@ static HRESULT BAEngineSetVariableVersion(
274 )
275 {
276 HRESULT hr = S_OK;
617 - VERUTIL_VERSION* pVersion = NULL;
277 ValidateMessageArgs(hr, pvArgs, BAENGINE_SETVARIABLEVERSION_ARGS, pArgs);
278 ValidateMessageResults(hr, pvResults, BAENGINE_SETVARIABLEVERSION_RESULTS, pResults);
620 - LPCWSTR wzVariable = pArgs->wzVariable;
621 - LPCWSTR wzValue = pArgs->wzValue;
279
623 - if (wzVariable && *wzVariable)
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 - }
280 + hr = ExternalEngineSetVariableVersion(pContext->pEngineState, pArgs->wzVariable, pArgs->wzValue);
281
282 LExit:
641 - ReleaseVerutilVersion(pVersion);
642 -
283 return hr;
284 }
285
@@ -653,11 +293,7 @@ static HRESULT BAEngineCloseSplashScreen(
293 ValidateMessageArgs(hr, pvArgs, BAENGINE_CLOSESPLASHSCREEN_ARGS, pArgs);
294 ValidateMessageResults(hr, pvResults, BAENGINE_CLOSESPLASHSCREEN_RESULTS, pResults);
295
656 - // If the splash screen is still around, close it.
657 - if (::IsWindow(pContext->pEngineState->command.hwndSplashScreen))
658 - {
659 - ::PostMessageW(pContext->pEngineState->command.hwndSplashScreen, WM_CLOSE, 0, 0);
660 - }
296 + ExternalEngineCloseSplashScreen(pContext->pEngineState);
297
298 LExit:
299 return hr;
@@ -672,11 +308,8 @@ static HRESULT BAEngineCompareVersions(
308 HRESULT hr = S_OK;
309 ValidateMessageArgs(hr, pvArgs, BAENGINE_COMPAREVERSIONS_ARGS, pArgs);
310 ValidateMessageResults(hr, pvResults, BAENGINE_COMPAREVERSIONS_RESULTS, pResults);
675 - LPCWSTR wzVersion1 = pArgs->wzVersion1;
676 - LPCWSTR wzVersion2 = pArgs->wzVersion2;
677 - int* pnResult = &pResults->nResult;
311
679 - hr = VerCompareStringVersions(wzVersion1, wzVersion2, FALSE, pnResult);
312 + hr = ExternalEngineCompareVersions(pArgs->wzVersion1, pArgs->wzVersion2, &pResults->nResult);
313
314 LExit:
315 return hr;
@@ -692,10 +325,7 @@ static HRESULT BAEngineDetect(
325 ValidateMessageArgs(hr, pvArgs, BAENGINE_DETECT_ARGS, pArgs);
326 ValidateMessageResults(hr, pvResults, BAENGINE_DETECT_RESULTS, pResults);
327
695 - if (!::PostThreadMessageW(pContext->dwThreadId, WM_BURN_DETECT, 0, reinterpret_cast<LPARAM>(pArgs->hwndParent)))
696 - {
697 - ExitWithLastError(hr, "Failed to post detect message.");
698 - }
328 + hr = ExternalEngineDetect(pContext->dwThreadId, pArgs->hwndParent);
329
330 LExit:
331 return hr;
@@ -710,12 +340,8 @@ static HRESULT BAEnginePlan(
340 HRESULT hr = S_OK;
341 ValidateMessageArgs(hr, pvArgs, BAENGINE_PLAN_ARGS, pArgs);
342 ValidateMessageResults(hr, pvResults, BAENGINE_PLAN_RESULTS, pResults);
713 - BOOTSTRAPPER_ACTION action = pArgs->action;
343
715 - if (!::PostThreadMessageW(pContext->dwThreadId, WM_BURN_PLAN, 0, action))
716 - {
717 - ExitWithLastError(hr, "Failed to post plan message.");
718 - }
344 + hr = ExternalEnginePlan(pContext->dwThreadId, pArgs->action);
345
346 LExit:
347 return hr;
@@ -731,14 +357,7 @@ static HRESULT BAEngineElevate(
357 ValidateMessageArgs(hr, pvArgs, BAENGINE_ELEVATE_ARGS, pArgs);
358 ValidateMessageResults(hr, pvResults, BAENGINE_ELEVATE_RESULTS, pResults);
359
734 - if (INVALID_HANDLE_VALUE != pContext->pEngineState->companionConnection.hPipe)
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 - }
360 + hr = ExternalEngineElevate(pContext->pEngineState, pContext->dwThreadId, pArgs->hwndParent);
361
362 LExit:
363 return hr;
@@ -754,16 +373,7 @@ static HRESULT BAEngineApply(
373 ValidateMessageArgs(hr, pvArgs, BAENGINE_APPLY_ARGS, pArgs);
374 ValidateMessageResults(hr, pvResults, BAENGINE_APPLY_RESULTS, pResults);
375
757 - ExitOnNull(pArgs->hwndParent, hr, E_INVALIDARG, "BA passed NULL hwndParent to Apply.");
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 - }
376 + hr = ExternalEngineApply(pContext->dwThreadId, pArgs->hwndParent);
377
378 LExit:
379 return hr;
@@ -779,10 +389,7 @@ static HRESULT BAEngineQuit(
389 ValidateMessageArgs(hr, pvArgs, BAENGINE_QUIT_ARGS, pArgs);
390 ValidateMessageResults(hr, pvResults, BAENGINE_QUIT_RESULTS, pResults);
391
782 - if (!::PostThreadMessageW(pContext->dwThreadId, WM_BURN_QUIT, static_cast<WPARAM>(pArgs->dwExitCode), 0))
783 - {
784 - ExitWithLastError(hr, "Failed to post shutdown message.");
785 - }
392 + hr = ExternalEngineQuit(pContext->dwThreadId, pArgs->dwExitCode);
393
394 LExit:
395 return hr;
@@ -795,64 +402,12 @@ static HRESULT BAEngineLaunchApprovedExe(
402 )
403 {
404 HRESULT hr = S_OK;
798 - BURN_APPROVED_EXE* pApprovedExe = NULL;
799 - BOOL fLeaveCriticalSection = FALSE;
800 - BURN_LAUNCH_APPROVED_EXE* pLaunchApprovedExe = NULL;
405 ValidateMessageArgs(hr, pvArgs, BAENGINE_LAUNCHAPPROVEDEXE_ARGS, pArgs);
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;
407
808 - pLaunchApprovedExe = (BURN_LAUNCH_APPROVED_EXE*)MemAlloc(sizeof(BURN_LAUNCH_APPROVED_EXE), TRUE);
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 - }
408 + hr = ExternalEngineLaunchApprovedExe(pContext->pEngineState, pContext->dwThreadId, pArgs->hwndParent, pArgs->wzApprovedExeForElevationId, pArgs->wzArguments, pArgs->dwWaitForInputIdleTimeout);
409
410 LExit:
846 - if (fLeaveCriticalSection)
847 - {
848 - ::LeaveCriticalSection(&pContext->pEngineState->csActive);
849 - }
850 -
851 - if (FAILED(hr))
852 - {
853 - ApprovedExesUninitializeLaunch(pLaunchApprovedExe);
854 - }
855 -
411 return hr;
412 }
413
@@ -953,34 +508,3 @@ HRESULT WINAPI EngineForApplicationProc(
508 LExit:
509 return hr;
510 }
956 -
957 -static 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 -}
src/engine/EngineForExtension.cpp
+12 -179
@@ -3,12 +3,6 @@
3 #include "precomp.h"
4
5
6 -static HRESULT CopyStringToBE(
7 - __in LPWSTR wzValue,
8 - __in LPWSTR wzBuffer,
9 - __inout DWORD* pcchBuffer
10 - );
11 -
6 static HRESULT BEEngineEscapeString(
7 __in BURN_EXTENSION_ENGINE_CONTEXT* /*pContext*/,
8 __in const LPVOID pvArgs,
@@ -16,28 +10,12 @@ static HRESULT BEEngineEscapeString(
10 )
11 {
12 HRESULT hr = S_OK;
19 - LPWSTR sczValue = NULL;
13 ValidateMessageArgs(hr, pvArgs, BUNDLE_EXTENSION_ENGINE_ESCAPESTRING_ARGS, pArgs);
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;
15
26 - if (wzIn && *wzIn)
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 - }
16 + hr = ExternalEngineEscapeString(pArgs->wzIn, pResults->wzOut, &pResults->cchOut);
17
18 LExit:
40 - StrSecureZeroFreeString(sczValue);
19 return hr;
20 }
21
@@ -50,17 +28,8 @@ static HRESULT BEEngineEvaluateCondition(
28 HRESULT hr = S_OK;
29 ValidateMessageArgs(hr, pvArgs, BUNDLE_EXTENSION_ENGINE_EVALUATECONDITION_ARGS, pArgs);
30 ValidateMessageResults(hr, pvResults, BUNDLE_EXTENSION_ENGINE_EVALUATECONDITION_RESULTS, pResults);
53 - LPCWSTR wzCondition = pArgs->wzCondition;
54 - BOOL* pf = &pResults->f;
31
56 - if (wzCondition && *wzCondition)
57 - {
58 - hr = ConditionEvaluate(&pContext->pEngineState->variables, wzCondition, pf);
59 - }
60 - else
61 - {
62 - hr = E_INVALIDARG;
63 - }
32 + hr = ExternalEngineEvaluateCondition(pContext->pEngineState, pArgs->wzCondition, &pResults->f);
33
34 LExit:
35 return hr;
@@ -73,28 +42,12 @@ static HRESULT BEEngineFormatString(
42 )
43 {
44 HRESULT hr = S_OK;
76 - LPWSTR sczValue = NULL;
45 ValidateMessageArgs(hr, pvArgs, BUNDLE_EXTENSION_ENGINE_FORMATSTRING_ARGS, pArgs);
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;
47
83 - if (wzIn && *wzIn)
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 - }
48 + hr = ExternalEngineFormatString(pContext->pEngineState, pArgs->wzIn, pResults->wzOut, &pResults->cchOut);
49
50 LExit:
97 - StrSecureZeroFreeString(sczValue);
51 return hr;
52 }
53
@@ -107,17 +60,8 @@ static HRESULT BEEngineGetVariableNumeric(
60 HRESULT hr = S_OK;
61 ValidateMessageArgs(hr, pvArgs, BUNDLE_EXTENSION_ENGINE_GETVARIABLENUMERIC_ARGS, pArgs);
62 ValidateMessageResults(hr, pvResults, BUNDLE_EXTENSION_ENGINE_GETVARIABLENUMERIC_RESULTS, pResults);
110 - LPCWSTR wzVariable = pArgs->wzVariable;
111 - LONGLONG* pllValue = &pResults->llValue;
63
113 - if (wzVariable && *wzVariable)
114 - {
115 - hr = VariableGetNumeric(&pContext->pEngineState->variables, wzVariable, pllValue);
116 - }
117 - else
118 - {
119 - hr = E_INVALIDARG;
120 - }
64 + hr = ExternalEngineGetVariableNumeric(pContext->pEngineState, pArgs->wzVariable, &pResults->llValue);
65
66 LExit:
67 return hr;
@@ -130,28 +74,12 @@ static HRESULT BEEngineGetVariableString(
74 )
75 {
76 HRESULT hr = S_OK;
133 - LPWSTR sczValue = NULL;
77 ValidateMessageArgs(hr, pvArgs, BUNDLE_EXTENSION_ENGINE_GETVARIABLESTRING_ARGS, pArgs);
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;
79
140 - if (wzVariable && *wzVariable)
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 - }
80 + hr = ExternalEngineGetVariableString(pContext->pEngineState, pArgs->wzVariable, pResults->wzValue, &pResults->cchValue);
81
82 LExit:
154 - StrSecureZeroFreeString(sczValue);
83 return hr;
84 }
85
@@ -162,29 +90,12 @@ static HRESULT BEEngineGetVariableVersion(
90 )
91 {
92 HRESULT hr = S_OK;
165 - VERUTIL_VERSION* pVersion = NULL;
93 ValidateMessageArgs(hr, pvArgs, BUNDLE_EXTENSION_ENGINE_GETVARIABLEVERSION_ARGS, pArgs);
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;
95
172 - if (wzVariable && *wzVariable)
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 - }
96 + hr = ExternalEngineGetVariableVersion(pContext->pEngineState, pArgs->wzVariable, pResults->wzValue, &pResults->cchValue);
97
98 LExit:
186 - ReleaseVerutilVersion(pVersion);
187 -
99 return hr;
100 }
101
@@ -198,10 +109,8 @@ static HRESULT BEEngineLog(
109 REPORT_LEVEL rl = REPORT_NONE;
110 ValidateMessageArgs(hr, pvArgs, BUNDLE_EXTENSION_ENGINE_LOG_ARGS, pArgs);
111 ValidateMessageResults(hr, pvResults, BUNDLE_EXTENSION_ENGINE_LOG_RESULTS, pResults);
201 - BUNDLE_EXTENSION_LOG_LEVEL level = pArgs->level;
202 - LPCWSTR wzMessage = pArgs->wzMessage;
112
204 - switch (level)
113 + switch (pArgs->level)
114 {
115 case BUNDLE_EXTENSION_LOG_LEVEL_STANDARD:
116 rl = REPORT_STANDARD;
@@ -223,7 +132,7 @@ static HRESULT BEEngineLog(
132 ExitFunction1(hr = E_INVALIDARG);
133 }
134
226 - hr = LogStringLine(rl, "%ls", wzMessage);
135 + hr = ExternalEngineLog(rl, pArgs->wzMessage);
136 ExitOnFailure(hr, "Failed to log Bundle Extension message.");
137
138 LExit:
@@ -239,19 +148,8 @@ static HRESULT BEEngineSetVariableNumeric(
148 HRESULT hr = S_OK;
149 ValidateMessageArgs(hr, pvArgs, BUNDLE_EXTENSION_ENGINE_SETVARIABLENUMERIC_ARGS, pArgs);
150 ValidateMessageResults(hr, pvResults, BUNDLE_EXTENSION_ENGINE_SETVARIABLENUMERIC_RESULTS, pResults);
242 - LPCWSTR wzVariable = pArgs->wzVariable;
243 - LONGLONG llValue = pArgs->llValue;
151
245 - if (wzVariable && *wzVariable)
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 - }
152 + hr = ExternalEngineSetVariableNumeric(pContext->pEngineState, pArgs->wzVariable, pArgs->llValue);
153
154 LExit:
155 return hr;
@@ -266,19 +164,8 @@ static HRESULT BEEngineSetVariableString(
164 HRESULT hr = S_OK;
165 ValidateMessageArgs(hr, pvArgs, BUNDLE_EXTENSION_ENGINE_SETVARIABLESTRING_ARGS, pArgs);
166 ValidateMessageResults(hr, pvResults, BUNDLE_EXTENSION_ENGINE_SETVARIABLESTRING_RESULTS, pResults);
269 - LPCWSTR wzVariable = pArgs->wzVariable;
270 - LPCWSTR wzValue = pArgs->wzValue;
167
272 - if (wzVariable && *wzVariable)
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 - }
168 + hr = ExternalEngineSetVariableString(pContext->pEngineState, pArgs->wzVariable, pArgs->wzValue, pArgs->fFormatted);
169
170 LExit:
171 return hr;
@@ -291,32 +178,12 @@ static HRESULT BEEngineSetVariableVersion(
178 )
179 {
180 HRESULT hr = S_OK;
294 - VERUTIL_VERSION* pVersion = NULL;
181 ValidateMessageArgs(hr, pvArgs, BUNDLE_EXTENSION_ENGINE_SETVARIABLEVERSION_ARGS, pArgs);
182 ValidateMessageResults(hr, pvResults, BUNDLE_EXTENSION_ENGINE_SETVARIABLEVERSION_RESULTS, pResults);
297 - LPCWSTR wzVariable = pArgs->wzVariable;
298 - LPCWSTR wzValue = pArgs->wzValue;
183
300 - if (wzVariable && *wzVariable)
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 - }
184 + hr = ExternalEngineSetVariableVersion(pContext->pEngineState, pArgs->wzVariable, pArgs->wzValue);
185
186 LExit:
318 - ReleaseVerutilVersion(pVersion);
319 -
187 return hr;
188 }
189
@@ -329,11 +196,8 @@ static HRESULT BEEngineCompareVersions(
196 HRESULT hr = S_OK;
197 ValidateMessageArgs(hr, pvArgs, BUNDLE_EXTENSION_ENGINE_COMPAREVERSIONS_ARGS, pArgs);
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;
199
336 - hr = VerCompareStringVersions(wzVersion1, wzVersion2, FALSE, pnResult);
200 + hr = ExternalEngineCompareVersions(pArgs->wzVersion1, pArgs->wzVersion2, &pResults->nResult);
201
202 LExit:
203 return hr;
@@ -397,34 +261,3 @@ HRESULT WINAPI EngineForExtensionProc(
261 LExit:
262 return hr;
263 }
400 -
401 -static 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 -}
src/engine/externalengine.cpp
+760
@@ -3,8 +3,737 @@
3 #include "precomp.h"
4
5
6 +static HRESULT CopyStringToExternal(
7 + __in_z LPWSTR wzValue,
8 + __in_z_opt LPWSTR wzBuffer,
9 + __inout DWORD* pcchBuffer
10 + );
11 +
12 // function definitions
13
14 +void ExternalEngineGetPackageCount(
15 + __in BURN_ENGINE_STATE* pEngineState,
16 + __out DWORD* pcPackages
17 + )
18 +{
19 + *pcPackages = pEngineState->packages.cPackages;
20 +}
21 +
22 +HRESULT 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 +
43 +HRESULT 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 +
71 +HRESULT 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 +
99 +HRESULT 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 +
127 +HRESULT 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 +
154 +HRESULT 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 +
175 +HRESULT 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 +
187 +HRESULT 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 +
220 +LExit:
221 + ReleaseBuffer(pbData);
222 +
223 + return hr;
224 +}
225 +
226 +HRESULT 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 +
255 +LExit:
256 + ReleaseBuffer(pbData);
257 +
258 + return hr;
259 +}
260 +
261 +HRESULT 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 +
334 +LExit:
335 + ::LeaveCriticalSection(&pEngineState->csActive);
336 +
337 + ReleaseStr(sczCommandline);
338 + ReleaseStr(sczLocalSource);
339 +
340 + return hr;
341 +}
342 +
343 +HRESULT 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 +
389 +LExit:
390 + ::LeaveCriticalSection(&pEngineState->csActive);
391 +
392 + return hr;
393 +}
394 +
395 +HRESULT 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 +
472 +LExit:
473 + ::LeaveCriticalSection(&pEngineState->csActive);
474 +
475 + return hr;
476 +}
477 +
478 +HRESULT 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 +
497 +LExit:
498 + return hr;
499 +}
500 +
501 +HRESULT 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 +
521 +LExit:
522 + return hr;
523 +}
524 +
525 +HRESULT 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 +
551 +LExit:
552 + ReleaseVerutilVersion(pVersion);
553 +
554 + return hr;
555 +}
556 +
557 +void 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 +
568 +HRESULT 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 +
581 +HRESULT 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 +
593 +LExit:
594 + return hr;
595 +}
596 +
597 +HRESULT 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 +
609 +LExit:
610 + return hr;
611 +}
612 +
613 +HRESULT 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 +
630 +LExit:
631 + return hr;
632 +}
633 +
634 +HRESULT 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 +
652 +LExit:
653 + return hr;
654 +}
655 +
656 +HRESULT 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 +
668 +LExit:
669 + return hr;
670 +}
671 +
672 +HRESULT 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 +
723 +LExit:
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 +
737 // TODO: callers need to provide the original size (at the time of first public release) of the struct instead of the current size.
738 HRESULT WINAPI ExternalEngineValidateMessageParameter(
739 __in_opt const LPVOID pv,
@@ -28,3 +757,34 @@ HRESULT WINAPI ExternalEngineValidateMessageParameter(
757 LExit:
758 return hr;
759 }
760 +
761 +static 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 +}
src/engine/externalengine.h
+154
@@ -11,6 +11,160 @@
11 extern "C" {
12 #endif
13
14 +void ExternalEngineGetPackageCount(
15 + __in BURN_ENGINE_STATE* pEngineState,
16 + __out DWORD* pcPackages
17 + );
18 +
19 +HRESULT ExternalEngineGetVariableNumeric(
20 + __in BURN_ENGINE_STATE* pEngineState,
21 + __in_z LPCWSTR wzVariable,
22 + __out LONGLONG* pllValue
23 + );
24 +
25 +HRESULT 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 +
32 +HRESULT 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 +
39 +HRESULT 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 +
46 +HRESULT ExternalEngineEscapeString(
47 + __in_z LPCWSTR wzIn,
48 + __out_ecount_opt(*pcchOut) LPWSTR wzOut,
49 + __inout DWORD* pcchOut
50 + );
51 +
52 +HRESULT ExternalEngineEvaluateCondition(
53 + __in BURN_ENGINE_STATE* pEngineState,
54 + __in_z LPCWSTR wzCondition,
55 + __out BOOL* pf
56 + );
57 +
58 +HRESULT ExternalEngineLog(
59 + __in REPORT_LEVEL rl,
60 + __in_z LPCWSTR wzMessage
61 + );
62 +
63 +HRESULT 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 +
71 +HRESULT ExternalEngineSendEmbeddedProgress(
72 + __in BURN_ENGINE_STATE* pEngineState,
73 + __in const DWORD dwProgressPercentage,
74 + __in const DWORD dwOverallProgressPercentage,
75 + __out int* pnResult
76 + );
77 +
78 +HRESULT 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 +
88 +HRESULT 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 +
95 +HRESULT 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 +
104 +HRESULT ExternalEngineSetVariableNumeric(
105 + __in BURN_ENGINE_STATE* pEngineState,
106 + __in_z LPCWSTR wzVariable,
107 + __in const LONGLONG llValue
108 + );
109 +
110 +HRESULT 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 +
117 +HRESULT ExternalEngineSetVariableVersion(
118 + __in BURN_ENGINE_STATE* pEngineState,
119 + __in_z LPCWSTR wzVariable,
120 + __in_z_opt LPCWSTR wzValue
121 + );
122 +
123 +void ExternalEngineCloseSplashScreen(
124 + __in BURN_ENGINE_STATE* pEngineState
125 + );
126 +
127 +HRESULT ExternalEngineCompareVersions(
128 + __in_z LPCWSTR wzVersion1,
129 + __in_z LPCWSTR wzVersion2,
130 + __out int* pnResult
131 + );
132 +
133 +HRESULT ExternalEngineDetect(
134 + __in const DWORD dwThreadId,
135 + __in_opt const HWND hwndParent
136 + );
137 +
138 +HRESULT ExternalEnginePlan(
139 + __in const DWORD dwThreadId,
140 + __in const BOOTSTRAPPER_ACTION action
141 + );
142 +
143 +HRESULT ExternalEngineElevate(
144 + __in BURN_ENGINE_STATE* pEngineState,
145 + __in const DWORD dwThreadId,
146 + __in_opt const HWND hwndParent
147 + );
148 +
149 +HRESULT ExternalEngineApply(
150 + __in const DWORD dwThreadId,
151 + __in_opt const HWND hwndParent
152 + );
153 +
154 +HRESULT ExternalEngineQuit(
155 + __in const DWORD dwThreadId,
156 + __in const DWORD dwExitCode
157 + );
158 +
159 +HRESULT 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 +
168 HRESULT WINAPI ExternalEngineValidateMessageParameter(
169 __in_opt const LPVOID pv,
170 __in SIZE_T cbSizeOffset,
src/engine/pseudobundle.cpp
+2 -2
@@ -19,8 +19,8 @@ extern "C" HRESULT PseudoBundleInitialize(
19 __in_z_opt LPCWSTR wzRepairArguments,
20 __in_z_opt LPCWSTR wzUninstallArguments,
21 __in_opt BURN_DEPENDENCY_PROVIDER* pDependencyProvider,
22 - __in_opt BYTE* pbHash,
23 - __in DWORD cbHash
22 + __in_opt const BYTE* pbHash,
23 + __in const DWORD cbHash
24 )
25 {
26 HRESULT hr = S_OK;
src/engine/pseudobundle.h
+2 -2
@@ -22,8 +22,8 @@ HRESULT PseudoBundleInitialize(
22 __in_z_opt LPCWSTR wzRepairArguments,
23 __in_z_opt LPCWSTR wzUninstallArguments,
24 __in_opt BURN_DEPENDENCY_PROVIDER* pDependencyProvider,
25 - __in_opt BYTE* pbHash,
26 - __in DWORD cbHash
25 + __in_opt const BYTE* pbHash,
26 + __in const DWORD cbHash
27 );
28 HRESULT PseudoBundleInitializePassthrough(
29 __in BURN_PACKAGE* pPassthroughPackage,