Clean up synchronization between the engine and the BA.
Sean Hall committed
Feb 2, 2021 at 16:56 UTC
bb7d4bdc09d0b52a65b8cf3b5ae629f385fc8011
10 files changed
+80
-109
src/engine/apply.cpp
+1
-4
@@ -366,7 +366,7 @@ extern "C" HRESULT ApplyRegister(
366
hr = CoreSaveEngineState(pEngineState);
367
if (FAILED(hr))
368
{
369
- LogErrorId(hr, MSG_STATE_NOT_SAVED, NULL, NULL, NULL);
369
+ LogErrorId(hr, MSG_STATE_NOT_SAVED);
370
hr = S_OK;
371
}
372
@@ -1348,8 +1348,6 @@ static HRESULT PromptForSource(
1348
HRESULT hr = S_OK;
1349
BOOTSTRAPPER_RESOLVESOURCE_ACTION action = BOOTSTRAPPER_RESOLVESOURCE_ACTION_NONE;
1350
1351
- UserExperienceDeactivateEngine(pUX);
1352
-
1351
hr = UserExperienceOnResolveSource(pUX, wzPackageOrContainerId, wzPayloadId, wzLocalSource, wzDownloadSource, &action);
1352
if (FAILED(hr))
1353
{
@@ -1376,7 +1374,6 @@ static HRESULT PromptForSource(
1374
}
1375
1376
LExit:
1379
- UserExperienceActivateEngine(pUX, NULL);
1377
return hr;
1378
}
1379
src/engine/core.cpp
+8
-39
@@ -236,16 +236,12 @@ extern "C" HRESULT CoreDetect(
236
)
237
{
238
HRESULT hr = S_OK;
239
- BOOL fActivated = FALSE;
239
BOOL fDetectBegan = FALSE;
240
BURN_PACKAGE* pPackage = NULL;
241
HRESULT hrFirstPackageFailure = S_OK;
242
243
LogId(REPORT_STANDARD, MSG_DETECT_BEGIN, pEngineState->packages.cPackages);
244
246
- hr = UserExperienceActivateEngine(&pEngineState->userExperience, &fActivated);
247
- ExitOnFailure(hr, "Engine cannot start detect because it is busy with another action.");
248
-
245
// Detect if bundle installed state has changed since start up. This
246
// only happens if Apply() changed the state of bundle (installed or
247
// uninstalled). In that case, Detect() can be used here to reset
@@ -369,11 +365,6 @@ LExit:
365
hr = hrFirstPackageFailure;
366
}
367
372
- if (fActivated)
373
- {
374
- UserExperienceDeactivateEngine(&pEngineState->userExperience);
375
- }
376
-
368
if (fDetectBegan)
369
{
370
UserExperienceOnDetectComplete(&pEngineState->userExperience, hr);
@@ -392,7 +383,6 @@ extern "C" HRESULT CorePlan(
383
)
384
{
385
HRESULT hr = S_OK;
395
- BOOL fActivated = FALSE;
386
BOOL fPlanBegan = FALSE;
387
LPWSTR sczLayoutDirectory = NULL;
388
HANDLE hSyncpointEvent = NULL;
@@ -401,9 +391,6 @@ extern "C" HRESULT CorePlan(
391
392
LogId(REPORT_STANDARD, MSG_PLAN_BEGIN, pEngineState->packages.cPackages, LoggingBurnActionToString(action));
393
404
- hr = UserExperienceActivateEngine(&pEngineState->userExperience, &fActivated);
405
- ExitOnFailure(hr, "Engine cannot start plan because it is busy with another action.");
406
-
394
fPlanBegan = TRUE;
395
hr = UserExperienceOnPlanBegin(&pEngineState->userExperience, pEngineState->packages.cPackages);
396
ExitOnRootFailure(hr, "BA aborted plan begin.");
@@ -496,11 +483,6 @@ extern "C" HRESULT CorePlan(
483
PlanDump(&pEngineState->plan);
484
485
LExit:
499
- if (fActivated)
500
- {
501
- UserExperienceDeactivateEngine(&pEngineState->userExperience);
502
- }
503
-
486
if (fPlanBegan)
487
{
488
UserExperienceOnPlanComplete(&pEngineState->userExperience, hr);
@@ -551,10 +533,10 @@ extern "C" HRESULT CoreApply(
533
)
534
{
535
HRESULT hr = S_OK;
554
- BOOL fActivated = FALSE;
536
HANDLE hLock = NULL;
537
DWORD cOverallProgressTicks = 0;
538
HANDLE hCacheThread = NULL;
539
+ BOOL fApplyInitialize = FALSE;
540
BOOL fElevated = FALSE;
541
BOOL fRegistered = FALSE;
542
BOOL fKeepRegistration = pEngineState->plan.fKeepRegistrationDefault;
@@ -567,9 +549,6 @@ extern "C" HRESULT CoreApply(
549
550
LogId(REPORT_STANDARD, MSG_APPLY_BEGIN);
551
570
- hr = UserExperienceActivateEngine(&pEngineState->userExperience, &fActivated);
571
- ExitOnFailure(hr, "Engine cannot start apply because it is busy with another action.");
572
-
552
// Ensure any previous attempts to execute are reset.
553
ApplyReset(&pEngineState->userExperience, &pEngineState->packages);
554
@@ -599,6 +578,7 @@ extern "C" HRESULT CoreApply(
578
ExitOnFailure(hr, "Another per-user setup is already executing.");
579
580
// Initialize only after getting a lock.
581
+ fApplyInitialize = TRUE;
582
ApplyInitialize();
583
584
pEngineState->userExperience.hwndApply = hwndParent;
@@ -627,7 +607,7 @@ extern "C" HRESULT CoreApply(
607
ExitOnFailure(hr, "Failed to elevate.");
608
609
hr = ElevationApplyInitialize(pEngineState->companionConnection.hPipe, &pEngineState->userExperience, &pEngineState->variables, pEngineState->plan.action, pEngineState->automaticUpdates, !pEngineState->fDisableSystemRestore);
630
- ExitOnFailure(hr, "Another per-machine setup is already executing.");
610
+ ExitOnFailure(hr, "Failed to initialize apply in elevated process.");
611
612
fElevated = TRUE;
613
}
@@ -704,7 +684,10 @@ LExit:
684
685
pEngineState->userExperience.hwndApply = NULL;
686
707
- ApplyUninitialize();
687
+ if (fApplyInitialize)
688
+ {
689
+ ApplyUninitialize();
690
+ }
691
692
if (hLock)
693
{
@@ -712,11 +695,6 @@ LExit:
695
::CloseHandle(hLock);
696
}
697
715
- if (fActivated)
716
- {
717
- UserExperienceDeactivateEngine(&pEngineState->userExperience);
718
- }
719
-
698
ReleaseHandle(hCacheThread);
699
700
UserExperienceOnApplyComplete(&pEngineState->userExperience, hr, restart, &applyCompleteAction);
@@ -736,14 +714,10 @@ extern "C" HRESULT CoreLaunchApprovedExe(
714
)
715
{
716
HRESULT hr = S_OK;
739
- BOOL fActivated = FALSE;
717
DWORD dwProcessId = 0;
718
719
LogId(REPORT_STANDARD, MSG_LAUNCH_APPROVED_EXE_BEGIN, pLaunchApprovedExe->sczId);
720
744
- hr = UserExperienceActivateEngine(&pEngineState->userExperience, &fActivated);
745
- ExitOnFailure(hr, "Engine cannot start LaunchApprovedExe because it is busy with another action.");
746
-
721
hr = UserExperienceOnLaunchApprovedExeBegin(&pEngineState->userExperience);
722
ExitOnRootFailure(hr, "BA aborted LaunchApprovedExe begin.");
723
@@ -755,11 +729,6 @@ extern "C" HRESULT CoreLaunchApprovedExe(
729
hr = ElevationLaunchApprovedExe(pEngineState->companionConnection.hPipe, pLaunchApprovedExe, &dwProcessId);
730
731
LExit:
758
- if (fActivated)
759
- {
760
- UserExperienceDeactivateEngine(&pEngineState->userExperience);
761
- }
762
-
732
UserExperienceOnLaunchApprovedExeComplete(&pEngineState->userExperience, hr, dwProcessId);
733
734
LogId(REPORT_STANDARD, MSG_LAUNCH_APPROVED_EXE_COMPLETE, hr, dwProcessId);
@@ -782,7 +751,7 @@ extern "C" HRESULT CoreQuit(
751
hr = CoreSaveEngineState(pEngineState);
752
if (FAILED(hr))
753
{
785
- LogErrorId(hr, MSG_STATE_NOT_SAVED, NULL, NULL, NULL);
754
+ LogErrorId(hr, MSG_STATE_NOT_SAVED);
755
hr = S_OK;
756
}
757
}
src/engine/core.h
-5
@@ -77,11 +77,6 @@ enum BURN_AU_PAUSE_ACTION
77
78
typedef struct _BURN_ENGINE_STATE
79
{
80
- // synchronization
81
- CRITICAL_SECTION csActive; // Any call from the UX that reads or alters the engine state
82
- // needs to be syncronized through this critical section.
83
- // Note: The engine must never do a UX callback while in this critical section.
84
-
80
// UX flow control
81
//BOOL fSuspend; // Is TRUE when UX made Suspend() call on core.
82
//BOOL fForcedReboot; // Is TRUE when UX made Reboot() call on core.
src/engine/detect.cpp
+2
-2
@@ -9,7 +9,7 @@ typedef struct _DETECT_AUTHENTICATION_REQUIRED_DATA
9
} DETECT_AUTHENTICATION_REQUIRED_DATA;
10
11
// internal function definitions
12
-static HRESULT AuthenticationRequired(
12
+static HRESULT WINAPI AuthenticationRequired(
13
__in LPVOID pData,
14
__in HINTERNET hUrl,
15
__in long lHttpCode,
@@ -288,7 +288,7 @@ LExit:
288
return hr;
289
}
290
291
-static HRESULT AuthenticationRequired(
291
+static HRESULT WINAPI AuthenticationRequired(
292
__in LPVOID pData,
293
__in HINTERNET hUrl,
294
__in long lHttpCode,
src/engine/engine.cpp
+4
-3
@@ -330,7 +330,6 @@ static HRESULT InitializeEngineState(
330
331
pEngineState->automaticUpdates = BURN_AU_PAUSE_ACTION_IFELEVATED;
332
pEngineState->dwElevatedLoggingTlsId = TLS_OUT_OF_INDEXES;
333
- ::InitializeCriticalSection(&pEngineState->csActive);
333
::InitializeCriticalSection(&pEngineState->userExperience.csEngineActive);
334
PipeConnectionInitialize(&pEngineState->companionConnection);
335
PipeConnectionInitialize(&pEngineState->embeddedConnection);
@@ -418,8 +417,6 @@ static void UninitializeEngineState(
417
::TlsFree(pEngineState->dwElevatedLoggingTlsId);
418
}
419
421
- ::DeleteCriticalSection(&pEngineState->csActive);
422
-
420
// clear struct
421
memset(pEngineState, 0, sizeof(BURN_ENGINE_STATE));
422
}
@@ -805,6 +802,8 @@ static HRESULT ProcessMessage(
802
{
803
HRESULT hr = S_OK;
804
805
+ UserExperienceActivateEngine(&pEngineState->userExperience);
806
+
807
switch (pmsg->message)
808
{
809
case WM_BURN_DETECT:
@@ -832,6 +831,8 @@ static HRESULT ProcessMessage(
831
break;
832
}
833
834
+ UserExperienceDeactivateEngine(&pEngineState->userExperience);
835
+
836
return hr;
837
}
838
src/engine/engine.mc
+1
-1
@@ -938,7 +938,7 @@ MessageId=501
938
Severity=Warning
939
SymbolicName=MSG_STATE_NOT_SAVED
940
Language=English
941
-The state file could not be saved, error: 0x%1!x!. Continuing...
941
+The state file could not be saved. Continuing...
942
.
943
944
MessageId=600
src/engine/externalengine.cpp
+10
-11
@@ -276,7 +276,9 @@ HRESULT ExternalEngineSetUpdate(
276
WCHAR wzGuid[39];
277
RPC_STATUS rs = RPC_S_OK;
278
279
- ::EnterCriticalSection(&pEngineState->csActive);
279
+ ::EnterCriticalSection(&pEngineState->userExperience.csEngineActive);
280
+ hr = UserExperienceEnsureEngineInactive(&pEngineState->userExperience);
281
+ ExitOnFailure(hr, "Engine is active, cannot change engine state.");
282
283
if ((!wzLocalSource || !*wzLocalSource) && (!wzDownloadSource || !*wzDownloadSource))
284
{
@@ -332,7 +334,7 @@ HRESULT ExternalEngineSetUpdate(
334
}
335
336
LExit:
335
- ::LeaveCriticalSection(&pEngineState->csActive);
337
+ ::LeaveCriticalSection(&pEngineState->userExperience.csEngineActive);
338
339
ReleaseStr(sczCommandline);
340
ReleaseStr(sczLocalSource);
@@ -351,7 +353,7 @@ HRESULT ExternalEngineSetLocalSource(
353
BURN_CONTAINER* pContainer = NULL;
354
BURN_PAYLOAD* pPayload = NULL;
355
354
- ::EnterCriticalSection(&pEngineState->csActive);
356
+ ::EnterCriticalSection(&pEngineState->userExperience.csEngineActive);
357
hr = UserExperienceEnsureEngineInactive(&pEngineState->userExperience);
358
ExitOnFailure(hr, "Engine is active, cannot change engine state.");
359
@@ -387,7 +389,7 @@ HRESULT ExternalEngineSetLocalSource(
389
}
390
391
LExit:
390
- ::LeaveCriticalSection(&pEngineState->csActive);
392
+ ::LeaveCriticalSection(&pEngineState->userExperience.csEngineActive);
393
394
return hr;
395
}
@@ -406,7 +408,7 @@ HRESULT ExternalEngineSetDownloadSource(
408
BURN_PAYLOAD* pPayload = NULL;
409
DOWNLOAD_SOURCE* pDownloadSource = NULL;
410
409
- ::EnterCriticalSection(&pEngineState->csActive);
411
+ ::EnterCriticalSection(&pEngineState->userExperience.csEngineActive);
412
hr = UserExperienceEnsureEngineInactive(&pEngineState->userExperience);
413
ExitOnFailure(hr, "Engine is active, cannot change engine state.");
414
@@ -470,7 +472,7 @@ HRESULT ExternalEngineSetDownloadSource(
472
}
473
474
LExit:
473
- ::LeaveCriticalSection(&pEngineState->csActive);
475
+ ::LeaveCriticalSection(&pEngineState->userExperience.csEngineActive);
476
477
return hr;
478
}
@@ -686,7 +688,7 @@ HRESULT ExternalEngineLaunchApprovedExe(
688
pLaunchApprovedExe = (BURN_LAUNCH_APPROVED_EXE*)MemAlloc(sizeof(BURN_LAUNCH_APPROVED_EXE), TRUE);
689
ExitOnNull(pLaunchApprovedExe, hr, E_OUTOFMEMORY, "Failed to alloc BURN_LAUNCH_APPROVED_EXE");
690
689
- ::EnterCriticalSection(&pEngineState->csActive);
691
+ ::EnterCriticalSection(&pEngineState->userExperience.csEngineActive);
692
fLeaveCriticalSection = TRUE;
693
hr = UserExperienceEnsureEngineInactive(&pEngineState->userExperience);
694
ExitOnFailure(hr, "Engine is active, cannot change engine state.");
@@ -699,9 +701,6 @@ HRESULT ExternalEngineLaunchApprovedExe(
701
hr = ApprovedExesFindById(&pEngineState->approvedExes, wzApprovedExeForElevationId, &pApprovedExe);
702
ExitOnFailure(hr, "BA requested unknown approved exe with id: %ls", wzApprovedExeForElevationId);
703
702
- ::LeaveCriticalSection(&pEngineState->csActive);
703
- fLeaveCriticalSection = FALSE;
704
-
704
hr = StrAllocString(&pLaunchApprovedExe->sczId, wzApprovedExeForElevationId, NULL);
705
ExitOnFailure(hr, "Failed to copy the id.");
706
@@ -723,7 +722,7 @@ HRESULT ExternalEngineLaunchApprovedExe(
722
LExit:
723
if (fLeaveCriticalSection)
724
{
726
- ::LeaveCriticalSection(&pEngineState->csActive);
725
+ ::LeaveCriticalSection(&pEngineState->userExperience.csEngineActive);
726
}
727
728
if (FAILED(hr))
src/engine/userexperience.cpp
+44
-39
@@ -24,6 +24,13 @@ static HRESULT SendBAMessage(
24
__inout LPVOID pvResults
25
);
26
27
+static HRESULT SendBAMessageFromInactiveEngine(
28
+ __in BURN_USER_EXPERIENCE* pUserExperience,
29
+ __in BOOTSTRAPPER_APPLICATION_MESSAGE message,
30
+ __in const LPVOID pvArgs,
31
+ __inout LPVOID pvResults
32
+ );
33
+
34
35
// function definitions
36
@@ -230,51 +237,31 @@ extern "C" int UserExperienceSendError(
237
return nResult;
238
}
239
233
-extern "C" HRESULT UserExperienceActivateEngine(
234
- __in BURN_USER_EXPERIENCE* pUserExperience,
235
- __out_opt BOOL* pfActivated
240
+extern "C" void UserExperienceActivateEngine(
241
+ __in BURN_USER_EXPERIENCE* pUserExperience
242
)
243
{
238
- HRESULT hr = S_OK;
239
- BOOL fActivated;
240
-
244
::EnterCriticalSection(&pUserExperience->csEngineActive);
242
- if (InterlockedCompareExchange(reinterpret_cast<LONG*>(&pUserExperience->fEngineActive), TRUE, FALSE))
243
- {
244
- AssertSz(FALSE, "Engine should have been deactivated before activating it.");
245
-
246
- fActivated = FALSE;
247
- hr = HRESULT_FROM_WIN32(ERROR_INVALID_STATE);
248
- }
249
- else
250
- {
251
- fActivated = TRUE;
252
- }
245
+ AssertSz(!pUserExperience->fEngineActive, "Engine should have been deactivated before activating it.");
246
+ pUserExperience->fEngineActive = TRUE;
247
::LeaveCriticalSection(&pUserExperience->csEngineActive);
254
-
255
- if (pfActivated)
256
- {
257
- *pfActivated = fActivated;
258
- }
259
- ExitOnRootFailure(hr, "Engine active cannot be changed because it was already in that state.");
260
-
261
-LExit:
262
- return hr;
248
}
249
250
extern "C" void UserExperienceDeactivateEngine(
251
__in BURN_USER_EXPERIENCE* pUserExperience
252
)
253
{
269
- BOOL fActive = InterlockedExchange(reinterpret_cast<LONG*>(&pUserExperience->fEngineActive), FALSE);
270
- fActive = fActive; // prevents warning in "ship" build.
271
- AssertSz(fActive, "Engine should have be active before deactivating it.");
254
+ ::EnterCriticalSection(&pUserExperience->csEngineActive);
255
+ AssertSz(pUserExperience->fEngineActive, "Engine should have been active before deactivating it.");
256
+ pUserExperience->fEngineActive = FALSE;
257
+ ::LeaveCriticalSection(&pUserExperience->csEngineActive);
258
}
259
260
extern "C" HRESULT UserExperienceEnsureEngineInactive(
261
__in BURN_USER_EXPERIENCE* pUserExperience
262
)
263
{
264
+ // Make a slight optimization here by ignoring the critical section, because all callers should have needed to enter it for their operation anyway.
265
HRESULT hr = pUserExperience->fEngineActive ? HRESULT_FROM_WIN32(ERROR_BUSY) : S_OK;
266
ExitOnRootFailure(hr, "Engine is active, cannot proceed.");
267
@@ -346,7 +333,7 @@ EXTERN_C BAAPI UserExperienceOnApplyComplete(
333
results.cbSize = sizeof(results);
334
results.action = *pAction;
335
349
- hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONAPPLYCOMPLETE, &args, &results);
336
+ hr = SendBAMessageFromInactiveEngine(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONAPPLYCOMPLETE, &args, &results);
337
ExitOnFailure(hr, "BA OnApplyComplete failed.");
338
339
*pAction = results.action;
@@ -761,7 +748,7 @@ EXTERN_C BAAPI UserExperienceOnDetectComplete(
748
749
results.cbSize = sizeof(results);
750
764
- hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTCOMPLETE, &args, &results);
751
+ hr = SendBAMessageFromInactiveEngine(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTCOMPLETE, &args, &results);
752
ExitOnFailure(hr, "BA OnDetectComplete failed.");
753
754
LExit:
@@ -990,7 +977,7 @@ LExit:
977
978
EXTERN_C BAAPI UserExperienceOnDetectUpdate(
979
__in BURN_USER_EXPERIENCE* pUserExperience,
993
- __in_z LPCWSTR wzUpdateLocation,
980
+ __in_z_opt LPCWSTR wzUpdateLocation,
981
__in DWORD64 dw64Size,
982
__in VERUTIL_VERSION* pVersion,
983
__in_z_opt LPCWSTR wzTitle,
@@ -1016,7 +1003,7 @@ EXTERN_C BAAPI UserExperienceOnDetectUpdate(
1003
results.cbSize = sizeof(results);
1004
results.fStopProcessingUpdates = *pfStopProcessingUpdates;
1005
1019
- hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTUPDATE, &args, &results);
1006
+ hr = SendBAMessageFromInactiveEngine(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTUPDATE, &args, &results);
1007
ExitOnFailure(hr, "BA OnDetectUpdate failed.");
1008
1009
if (results.fCancel)
@@ -1045,7 +1032,7 @@ EXTERN_C BAAPI UserExperienceOnDetectUpdateBegin(
1032
results.cbSize = sizeof(results);
1033
results.fSkip = *pfSkip;
1034
1048
- hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTUPDATEBEGIN, &args, &results);
1035
+ hr = SendBAMessageFromInactiveEngine(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTUPDATEBEGIN, &args, &results);
1036
ExitOnFailure(hr, "BA OnDetectUpdateBegin failed.");
1037
1038
if (results.fCancel)
@@ -1074,7 +1061,7 @@ EXTERN_C BAAPI UserExperienceOnDetectUpdateComplete(
1061
results.cbSize = sizeof(results);
1062
results.fIgnoreError = *pfIgnoreError;
1063
1077
- hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTUPDATECOMPLETE, &args, &results);
1064
+ hr = SendBAMessageFromInactiveEngine(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTUPDATECOMPLETE, &args, &results);
1065
ExitOnFailure(hr, "BA OnDetectUpdateComplete failed.");
1066
1067
if (FAILED(hrStatus))
@@ -1124,7 +1111,7 @@ EXTERN_C BAAPI UserExperienceOnElevateComplete(
1111
1112
results.cbSize = sizeof(results);
1113
1127
- hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONELEVATECOMPLETE, &args, &results);
1114
+ hr = SendBAMessageFromInactiveEngine(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONELEVATECOMPLETE, &args, &results);
1115
ExitOnFailure(hr, "BA OnElevateComplete failed.");
1116
1117
LExit:
@@ -1452,7 +1439,7 @@ EXTERN_C BAAPI UserExperienceOnLaunchApprovedExeComplete(
1439
1440
results.cbSize = sizeof(results);
1441
1455
- hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONLAUNCHAPPROVEDEXECOMPLETE, &args, &results);
1442
+ hr = SendBAMessageFromInactiveEngine(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONLAUNCHAPPROVEDEXECOMPLETE, &args, &results);
1443
ExitOnFailure(hr, "BA OnLaunchApprovedExeComplete failed.");
1444
1445
LExit:
@@ -1571,7 +1558,7 @@ EXTERN_C BAAPI UserExperienceOnPlanComplete(
1558
1559
results.cbSize = sizeof(results);
1560
1574
- hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANCOMPLETE, &args, &results);
1561
+ hr = SendBAMessageFromInactiveEngine(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANCOMPLETE, &args, &results);
1562
ExitOnFailure(hr, "BA OnPlanComplete failed.");
1563
1564
LExit:
@@ -1831,7 +1818,7 @@ EXTERN_C BAAPI UserExperienceOnResolveSource(
1818
results.cbSize = sizeof(results);
1819
results.action = *pAction;
1820
1834
- hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONRESOLVESOURCE, &args, &results);
1821
+ hr = SendBAMessageFromInactiveEngine(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONRESOLVESOURCE, &args, &results);
1822
ExitOnFailure(hr, "BA OnResolveSource failed.");
1823
1824
if (results.fCancel)
@@ -2317,3 +2304,21 @@ static HRESULT SendBAMessage(
2304
2305
return hr;
2306
}
2307
+
2308
+static HRESULT SendBAMessageFromInactiveEngine(
2309
+ __in BURN_USER_EXPERIENCE* pUserExperience,
2310
+ __in BOOTSTRAPPER_APPLICATION_MESSAGE message,
2311
+ __in const LPVOID pvArgs,
2312
+ __inout LPVOID pvResults
2313
+ )
2314
+{
2315
+ HRESULT hr = S_OK;
2316
+
2317
+ UserExperienceDeactivateEngine(pUserExperience);
2318
+
2319
+ hr = SendBAMessage(pUserExperience, message, pvArgs, pvResults);
2320
+
2321
+ UserExperienceActivateEngine(pUserExperience);
2322
+
2323
+ return hr;
2324
+}
src/engine/userexperience.h
+8
-4
@@ -82,13 +82,17 @@ int UserExperienceSendError(
82
__in DWORD uiFlags,
83
__in int nRecommendation
84
);
85
-HRESULT UserExperienceActivateEngine(
86
- __in BURN_USER_EXPERIENCE* pUserExperience,
87
- __out_opt BOOL* pfActivated
85
+void UserExperienceActivateEngine(
86
+ __in BURN_USER_EXPERIENCE* pUserExperience
87
);
88
void UserExperienceDeactivateEngine(
89
__in BURN_USER_EXPERIENCE* pUserExperience
90
);
91
+/********************************************************************
92
+ UserExperienceEnsureEngineInactive - Verifies the engine is inactive.
93
+ The caller MUST enter the csActive critical section before calling.
94
+
95
+*********************************************************************/
96
HRESULT UserExperienceEnsureEngineInactive(
97
__in BURN_USER_EXPERIENCE* pUserExperience
98
);
@@ -240,7 +244,7 @@ BAAPI UserExperienceOnDetectTargetMsiPackage(
244
);
245
BAAPI UserExperienceOnDetectUpdate(
246
__in BURN_USER_EXPERIENCE* pUserExperience,
243
- __in_z LPCWSTR wzUpdateLocation,
247
+ __in_z_opt LPCWSTR wzUpdateLocation,
248
__in DWORD64 dw64Size,
249
__in VERUTIL_VERSION* pVersion,
250
__in_z_opt LPCWSTR wzTitle,
src/test/BurnUnitTest/PlanTest.cpp
+2
-1
@@ -529,7 +529,6 @@ namespace Bootstrapper
529
HRESULT hr = S_OK;
530
LPWSTR sczFilePath = NULL;
531
532
- ::InitializeCriticalSection(&pEngineState->csActive);
532
::InitializeCriticalSection(&pEngineState->userExperience.csEngineActive);
533
534
hr = VariableInitialize(&pEngineState->variables);
@@ -567,6 +566,8 @@ namespace Bootstrapper
566
567
hr = DepDependencyArrayAlloc(&pRegistration->rgIgnoredDependencies, &pRegistration->cIgnoredDependencies, pRegistration->sczProviderKey, NULL);
568
NativeAssert::Succeeded(hr, "Failed to add the bundle provider key to the list of dependencies to ignore.");
569
+
570
+ pEngineState->userExperience.fEngineActive = TRUE;
571
}
572
573
void DetectAttachedContainerAsAttached(BURN_ENGINE_STATE* pEngineState)