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,