diff options
author | Sean Hall <r.sean.hall@gmail.com> | 2022-10-19 15:44:40 -0500 |
---|---|---|
committer | Sean Hall <r.sean.hall@gmail.com> | 2022-10-25 15:13:06 -0500 |
commit | 98080672cdbbde00ea40a96c1ce38e8a52f24fee (patch) | |
tree | 9c0b859f147d55d5c4caadccfd764ca84ed7e648 /src | |
parent | 28e9c7c14d2a156b55476f6b8e39e13f17aa87b6 (diff) | |
download | wix-98080672cdbbde00ea40a96c1ce38e8a52f24fee.tar.gz wix-98080672cdbbde00ea40a96c1ce38e8a52f24fee.tar.bz2 wix-98080672cdbbde00ea40a96c1ce38e8a52f24fee.zip |
Add queutil so Burn can manage its own queue of BA requested actions.
Fixes 6349
Diffstat (limited to 'src')
-rw-r--r-- | src/burn/engine/EngineForApplication.cpp | 12 | ||||
-rw-r--r-- | src/burn/engine/EngineForApplication.h | 33 | ||||
-rw-r--r-- | src/burn/engine/approvedexe.cpp | 1 | ||||
-rw-r--r-- | src/burn/engine/core.cpp | 31 | ||||
-rw-r--r-- | src/burn/engine/core.h | 9 | ||||
-rw-r--r-- | src/burn/engine/elevation.cpp | 5 | ||||
-rw-r--r-- | src/burn/engine/engine.cpp | 95 | ||||
-rw-r--r-- | src/burn/engine/externalengine.cpp | 166 | ||||
-rw-r--r-- | src/burn/engine/externalengine.h | 14 | ||||
-rw-r--r-- | src/burn/engine/platform.h | 1 | ||||
-rw-r--r-- | src/burn/engine/precomp.h | 1 | ||||
-rw-r--r-- | src/libs/dutil/WixToolset.DUtil/dutil.vcxproj | 2 | ||||
-rw-r--r-- | src/libs/dutil/WixToolset.DUtil/dutil.vcxproj.filters | 6 | ||||
-rw-r--r-- | src/libs/dutil/WixToolset.DUtil/inc/dutilsources.h | 1 | ||||
-rw-r--r-- | src/libs/dutil/WixToolset.DUtil/inc/queutil.h | 52 | ||||
-rw-r--r-- | src/libs/dutil/WixToolset.DUtil/precomp.h | 1 | ||||
-rw-r--r-- | src/libs/dutil/WixToolset.DUtil/queutil.cpp | 144 | ||||
-rw-r--r-- | src/test/burn/WixToolsetTest.BurnE2E/ElevationTests.cs | 2 |
18 files changed, 451 insertions, 125 deletions
diff --git a/src/burn/engine/EngineForApplication.cpp b/src/burn/engine/EngineForApplication.cpp index 27f815c6..45bfaf83 100644 --- a/src/burn/engine/EngineForApplication.cpp +++ b/src/burn/engine/EngineForApplication.cpp | |||
@@ -325,7 +325,7 @@ static HRESULT BAEngineDetect( | |||
325 | ValidateMessageArgs(hr, pvArgs, BAENGINE_DETECT_ARGS, pArgs); | 325 | ValidateMessageArgs(hr, pvArgs, BAENGINE_DETECT_ARGS, pArgs); |
326 | ValidateMessageResults(hr, pvResults, BAENGINE_DETECT_RESULTS, pResults); | 326 | ValidateMessageResults(hr, pvResults, BAENGINE_DETECT_RESULTS, pResults); |
327 | 327 | ||
328 | hr = ExternalEngineDetect(pContext->dwThreadId, pArgs->hwndParent); | 328 | hr = ExternalEngineDetect(pContext, pArgs->hwndParent); |
329 | 329 | ||
330 | LExit: | 330 | LExit: |
331 | return hr; | 331 | return hr; |
@@ -341,7 +341,7 @@ static HRESULT BAEnginePlan( | |||
341 | ValidateMessageArgs(hr, pvArgs, BAENGINE_PLAN_ARGS, pArgs); | 341 | ValidateMessageArgs(hr, pvArgs, BAENGINE_PLAN_ARGS, pArgs); |
342 | ValidateMessageResults(hr, pvResults, BAENGINE_PLAN_RESULTS, pResults); | 342 | ValidateMessageResults(hr, pvResults, BAENGINE_PLAN_RESULTS, pResults); |
343 | 343 | ||
344 | hr = ExternalEnginePlan(pContext->dwThreadId, pArgs->action); | 344 | hr = ExternalEnginePlan(pContext, pArgs->action); |
345 | 345 | ||
346 | LExit: | 346 | LExit: |
347 | return hr; | 347 | return hr; |
@@ -357,7 +357,7 @@ static HRESULT BAEngineElevate( | |||
357 | ValidateMessageArgs(hr, pvArgs, BAENGINE_ELEVATE_ARGS, pArgs); | 357 | ValidateMessageArgs(hr, pvArgs, BAENGINE_ELEVATE_ARGS, pArgs); |
358 | ValidateMessageResults(hr, pvResults, BAENGINE_ELEVATE_RESULTS, pResults); | 358 | ValidateMessageResults(hr, pvResults, BAENGINE_ELEVATE_RESULTS, pResults); |
359 | 359 | ||
360 | hr = ExternalEngineElevate(pContext->pEngineState, pContext->dwThreadId, pArgs->hwndParent); | 360 | hr = ExternalEngineElevate(pContext, pArgs->hwndParent); |
361 | 361 | ||
362 | LExit: | 362 | LExit: |
363 | return hr; | 363 | return hr; |
@@ -373,7 +373,7 @@ static HRESULT BAEngineApply( | |||
373 | ValidateMessageArgs(hr, pvArgs, BAENGINE_APPLY_ARGS, pArgs); | 373 | ValidateMessageArgs(hr, pvArgs, BAENGINE_APPLY_ARGS, pArgs); |
374 | ValidateMessageResults(hr, pvResults, BAENGINE_APPLY_RESULTS, pResults); | 374 | ValidateMessageResults(hr, pvResults, BAENGINE_APPLY_RESULTS, pResults); |
375 | 375 | ||
376 | hr = ExternalEngineApply(pContext->dwThreadId, pArgs->hwndParent); | 376 | hr = ExternalEngineApply(pContext, pArgs->hwndParent); |
377 | 377 | ||
378 | LExit: | 378 | LExit: |
379 | return hr; | 379 | return hr; |
@@ -389,7 +389,7 @@ static HRESULT BAEngineQuit( | |||
389 | ValidateMessageArgs(hr, pvArgs, BAENGINE_QUIT_ARGS, pArgs); | 389 | ValidateMessageArgs(hr, pvArgs, BAENGINE_QUIT_ARGS, pArgs); |
390 | ValidateMessageResults(hr, pvResults, BAENGINE_QUIT_RESULTS, pResults); | 390 | ValidateMessageResults(hr, pvResults, BAENGINE_QUIT_RESULTS, pResults); |
391 | 391 | ||
392 | hr = ExternalEngineQuit(pContext->dwThreadId, pArgs->dwExitCode); | 392 | hr = ExternalEngineQuit(pContext, pArgs->dwExitCode); |
393 | 393 | ||
394 | LExit: | 394 | LExit: |
395 | return hr; | 395 | return hr; |
@@ -405,7 +405,7 @@ static HRESULT BAEngineLaunchApprovedExe( | |||
405 | ValidateMessageArgs(hr, pvArgs, BAENGINE_LAUNCHAPPROVEDEXE_ARGS, pArgs); | 405 | ValidateMessageArgs(hr, pvArgs, BAENGINE_LAUNCHAPPROVEDEXE_ARGS, pArgs); |
406 | ValidateMessageResults(hr, pvResults, BAENGINE_LAUNCHAPPROVEDEXE_RESULTS, pResults); | 406 | ValidateMessageResults(hr, pvResults, BAENGINE_LAUNCHAPPROVEDEXE_RESULTS, pResults); |
407 | 407 | ||
408 | hr = ExternalEngineLaunchApprovedExe(pContext->pEngineState, pContext->dwThreadId, pArgs->hwndParent, pArgs->wzApprovedExeForElevationId, pArgs->wzArguments, pArgs->dwWaitForInputIdleTimeout); | 408 | hr = ExternalEngineLaunchApprovedExe(pContext, pArgs->hwndParent, pArgs->wzApprovedExeForElevationId, pArgs->wzArguments, pArgs->dwWaitForInputIdleTimeout); |
409 | 409 | ||
410 | LExit: | 410 | LExit: |
411 | return hr; | 411 | return hr; |
diff --git a/src/burn/engine/EngineForApplication.h b/src/burn/engine/EngineForApplication.h index d25a7e51..bf86b7ee 100644 --- a/src/burn/engine/EngineForApplication.h +++ b/src/burn/engine/EngineForApplication.h | |||
@@ -11,9 +11,40 @@ extern "C" { | |||
11 | typedef struct _BOOTSTRAPPER_ENGINE_CONTEXT | 11 | typedef struct _BOOTSTRAPPER_ENGINE_CONTEXT |
12 | { | 12 | { |
13 | BURN_ENGINE_STATE* pEngineState; | 13 | BURN_ENGINE_STATE* pEngineState; |
14 | DWORD dwThreadId; | 14 | QUEUTIL_QUEUE_HANDLE hQueue; |
15 | HANDLE hQueueSemaphore; | ||
16 | CRITICAL_SECTION csQueue; | ||
15 | } BOOTSTRAPPER_ENGINE_CONTEXT; | 17 | } BOOTSTRAPPER_ENGINE_CONTEXT; |
16 | 18 | ||
19 | typedef struct _BOOTSTRAPPER_ENGINE_ACTION | ||
20 | { | ||
21 | WM_BURN dwMessage; | ||
22 | union | ||
23 | { | ||
24 | struct | ||
25 | { | ||
26 | HWND hwndParent; | ||
27 | } detect; | ||
28 | struct | ||
29 | { | ||
30 | BOOTSTRAPPER_ACTION action; | ||
31 | } plan; | ||
32 | struct | ||
33 | { | ||
34 | HWND hwndParent; | ||
35 | } elevate; | ||
36 | struct | ||
37 | { | ||
38 | HWND hwndParent; | ||
39 | } apply; | ||
40 | BURN_LAUNCH_APPROVED_EXE launchApprovedExe; | ||
41 | struct | ||
42 | { | ||
43 | DWORD dwExitCode; | ||
44 | } quit; | ||
45 | }; | ||
46 | } BOOTSTRAPPER_ENGINE_ACTION; | ||
47 | |||
17 | // function declarations | 48 | // function declarations |
18 | 49 | ||
19 | HRESULT WINAPI EngineForApplicationProc( | 50 | HRESULT WINAPI EngineForApplicationProc( |
diff --git a/src/burn/engine/approvedexe.cpp b/src/burn/engine/approvedexe.cpp index d8bd956b..28b26d6d 100644 --- a/src/burn/engine/approvedexe.cpp +++ b/src/burn/engine/approvedexe.cpp | |||
@@ -106,7 +106,6 @@ extern "C" void ApprovedExesUninitializeLaunch( | |||
106 | ReleaseStr(pLaunchApprovedExe->sczArguments); | 106 | ReleaseStr(pLaunchApprovedExe->sczArguments); |
107 | ReleaseStr(pLaunchApprovedExe->sczExecutablePath); | 107 | ReleaseStr(pLaunchApprovedExe->sczExecutablePath); |
108 | ReleaseStr(pLaunchApprovedExe->sczId); | 108 | ReleaseStr(pLaunchApprovedExe->sczId); |
109 | MemFree(pLaunchApprovedExe); | ||
110 | } | 109 | } |
111 | } | 110 | } |
112 | 111 | ||
diff --git a/src/burn/engine/core.cpp b/src/burn/engine/core.cpp index c443e0c8..8903b5b2 100644 --- a/src/burn/engine/core.cpp +++ b/src/burn/engine/core.cpp | |||
@@ -884,17 +884,16 @@ LExit: | |||
884 | 884 | ||
885 | LogId(REPORT_STANDARD, MSG_LAUNCH_APPROVED_EXE_COMPLETE, hr, dwProcessId); | 885 | LogId(REPORT_STANDARD, MSG_LAUNCH_APPROVED_EXE_COMPLETE, hr, dwProcessId); |
886 | 886 | ||
887 | ApprovedExesUninitializeLaunch(pLaunchApprovedExe); | ||
888 | |||
889 | return hr; | 887 | return hr; |
890 | } | 888 | } |
891 | 889 | ||
892 | extern "C" HRESULT CoreQuit( | 890 | extern "C" void CoreQuit( |
893 | __in BURN_ENGINE_STATE* pEngineState, | 891 | __in BOOTSTRAPPER_ENGINE_CONTEXT* pEngineContext, |
894 | __in int nExitCode | 892 | __in DWORD dwExitCode |
895 | ) | 893 | ) |
896 | { | 894 | { |
897 | HRESULT hr = S_OK; | 895 | HRESULT hr = S_OK; |
896 | BURN_ENGINE_STATE* pEngineState = pEngineContext->pEngineState; | ||
898 | 897 | ||
899 | // Save engine state if resume mode is unequal to "none". | 898 | // Save engine state if resume mode is unequal to "none". |
900 | if (BURN_RESUME_MODE_NONE != pEngineState->resumeMode) | 899 | if (BURN_RESUME_MODE_NONE != pEngineState->resumeMode) |
@@ -907,13 +906,15 @@ extern "C" HRESULT CoreQuit( | |||
907 | } | 906 | } |
908 | } | 907 | } |
909 | 908 | ||
910 | LogId(REPORT_STANDARD, MSG_QUIT, nExitCode); | 909 | LogId(REPORT_STANDARD, MSG_QUIT, dwExitCode); |
911 | 910 | ||
912 | pEngineState->fQuit = TRUE; | 911 | pEngineState->userExperience.dwExitCode = dwExitCode; |
913 | 912 | ||
914 | ::PostQuitMessage(nExitCode); // go bye-bye. | 913 | ::EnterCriticalSection(&pEngineContext->csQueue); |
915 | 914 | ||
916 | return hr; | 915 | pEngineState->fQuit = TRUE; |
916 | |||
917 | ::LeaveCriticalSection(&pEngineContext->csQueue); | ||
917 | } | 918 | } |
918 | 919 | ||
919 | extern "C" HRESULT CoreSaveEngineState( | 920 | extern "C" HRESULT CoreSaveEngineState( |
@@ -2071,6 +2072,18 @@ LExit: | |||
2071 | return hr; | 2072 | return hr; |
2072 | } | 2073 | } |
2073 | 2074 | ||
2075 | extern "C" void DAPI CoreBootstrapperEngineActionUninitialize( | ||
2076 | __in BOOTSTRAPPER_ENGINE_ACTION* pAction | ||
2077 | ) | ||
2078 | { | ||
2079 | switch (pAction->dwMessage) | ||
2080 | { | ||
2081 | case WM_BURN_LAUNCH_APPROVED_EXE: | ||
2082 | ApprovedExesUninitializeLaunch(&pAction->launchApprovedExe); | ||
2083 | break; | ||
2084 | } | ||
2085 | } | ||
2086 | |||
2074 | // internal helper functions | 2087 | // internal helper functions |
2075 | 2088 | ||
2076 | static HRESULT AppendEscapedArgumentToCommandLine( | 2089 | static HRESULT AppendEscapedArgumentToCommandLine( |
diff --git a/src/burn/engine/core.h b/src/burn/engine/core.h index 3e636640..186b49ca 100644 --- a/src/burn/engine/core.h +++ b/src/burn/engine/core.h | |||
@@ -262,9 +262,9 @@ HRESULT CoreLaunchApprovedExe( | |||
262 | __in BURN_ENGINE_STATE* pEngineState, | 262 | __in BURN_ENGINE_STATE* pEngineState, |
263 | __in BURN_LAUNCH_APPROVED_EXE* pLaunchApprovedExe | 263 | __in BURN_LAUNCH_APPROVED_EXE* pLaunchApprovedExe |
264 | ); | 264 | ); |
265 | HRESULT CoreQuit( | 265 | void CoreQuit( |
266 | __in BURN_ENGINE_STATE* pEngineState, | 266 | __in BOOTSTRAPPER_ENGINE_CONTEXT* pEngineContext, |
267 | __in int nExitCode | 267 | __in DWORD dwExitCode |
268 | ); | 268 | ); |
269 | HRESULT CoreSaveEngineState( | 269 | HRESULT CoreSaveEngineState( |
270 | __in BURN_ENGINE_STATE* pEngineState | 270 | __in BURN_ENGINE_STATE* pEngineState |
@@ -354,6 +354,9 @@ HRESULT DAPI CoreCloseElevatedLoggingThread( | |||
354 | HRESULT DAPI CoreWaitForUnelevatedLoggingThread( | 354 | HRESULT DAPI CoreWaitForUnelevatedLoggingThread( |
355 | __in HANDLE hUnelevatedLoggingThread | 355 | __in HANDLE hUnelevatedLoggingThread |
356 | ); | 356 | ); |
357 | void DAPI CoreBootstrapperEngineActionUninitialize( | ||
358 | __in BOOTSTRAPPER_ENGINE_ACTION* pAction | ||
359 | ); | ||
357 | 360 | ||
358 | #if defined(__cplusplus) | 361 | #if defined(__cplusplus) |
359 | } | 362 | } |
diff --git a/src/burn/engine/elevation.cpp b/src/burn/engine/elevation.cpp index 7fd372b0..154c407d 100644 --- a/src/burn/engine/elevation.cpp +++ b/src/burn/engine/elevation.cpp | |||
@@ -3824,7 +3824,8 @@ static HRESULT OnLaunchApprovedExe( | |||
3824 | { | 3824 | { |
3825 | HRESULT hr = S_OK; | 3825 | HRESULT hr = S_OK; |
3826 | SIZE_T iData = 0; | 3826 | SIZE_T iData = 0; |
3827 | BURN_LAUNCH_APPROVED_EXE* pLaunchApprovedExe = NULL; | 3827 | BURN_LAUNCH_APPROVED_EXE launchApprovedExe = { }; |
3828 | BURN_LAUNCH_APPROVED_EXE* pLaunchApprovedExe = &launchApprovedExe; | ||
3828 | BURN_APPROVED_EXE* pApprovedExe = NULL; | 3829 | BURN_APPROVED_EXE* pApprovedExe = NULL; |
3829 | HKEY hKey = NULL; | 3830 | HKEY hKey = NULL; |
3830 | DWORD dwProcessId = 0; | 3831 | DWORD dwProcessId = 0; |
@@ -3832,8 +3833,6 @@ static HRESULT OnLaunchApprovedExe( | |||
3832 | SIZE_T cbSendData = 0; | 3833 | SIZE_T cbSendData = 0; |
3833 | DWORD dwResult = 0; | 3834 | DWORD dwResult = 0; |
3834 | 3835 | ||
3835 | pLaunchApprovedExe = (BURN_LAUNCH_APPROVED_EXE*)MemAlloc(sizeof(BURN_LAUNCH_APPROVED_EXE), TRUE); | ||
3836 | |||
3837 | // Deserialize message data. | 3836 | // Deserialize message data. |
3838 | hr = BuffReadString(pbData, cbData, &iData, &pLaunchApprovedExe->sczId); | 3837 | hr = BuffReadString(pbData, cbData, &iData, &pLaunchApprovedExe->sczId); |
3839 | ExitOnFailure(hr, "Failed to read approved exe id."); | 3838 | ExitOnFailure(hr, "Failed to read approved exe id."); |
diff --git a/src/burn/engine/engine.cpp b/src/burn/engine/engine.cpp index 48196655..c9d2bdcd 100644 --- a/src/burn/engine/engine.cpp +++ b/src/burn/engine/engine.cpp | |||
@@ -42,8 +42,8 @@ static HRESULT RunApplication( | |||
42 | __out BOOL* pfSkipCleanup | 42 | __out BOOL* pfSkipCleanup |
43 | ); | 43 | ); |
44 | static HRESULT ProcessMessage( | 44 | static HRESULT ProcessMessage( |
45 | __in BURN_ENGINE_STATE* pEngineState, | 45 | __in BOOTSTRAPPER_ENGINE_CONTEXT* pEngineContext, |
46 | __in const MSG* pmsg | 46 | __in BOOTSTRAPPER_ENGINE_ACTION* pAction |
47 | ); | 47 | ); |
48 | static HRESULT DAPI RedirectLoggingOverPipe( | 48 | static HRESULT DAPI RedirectLoggingOverPipe( |
49 | __in_z LPCSTR szString, | 49 | __in_z LPCSTR szString, |
@@ -790,6 +790,19 @@ LExit: | |||
790 | return hr; | 790 | return hr; |
791 | } | 791 | } |
792 | 792 | ||
793 | static void CALLBACK FreeQueueItem( | ||
794 | __in void* pvValue, | ||
795 | __in void* /*pvContext*/ | ||
796 | ) | ||
797 | { | ||
798 | BOOTSTRAPPER_ENGINE_ACTION* pAction = reinterpret_cast<BOOTSTRAPPER_ENGINE_ACTION*>(pvValue); | ||
799 | |||
800 | LogId(REPORT_WARNING, MSG_IGNORE_OPERATION_AFTER_QUIT, LoggingBurnMessageToString(pAction->dwMessage)); | ||
801 | |||
802 | CoreBootstrapperEngineActionUninitialize(pAction); | ||
803 | MemFree(pAction); | ||
804 | } | ||
805 | |||
793 | static HRESULT RunApplication( | 806 | static HRESULT RunApplication( |
794 | __in BURN_ENGINE_STATE* pEngineState, | 807 | __in BURN_ENGINE_STATE* pEngineState, |
795 | __out BOOL* pfReloadApp, | 808 | __out BOOL* pfReloadApp, |
@@ -799,16 +812,20 @@ static HRESULT RunApplication( | |||
799 | HRESULT hr = S_OK; | 812 | HRESULT hr = S_OK; |
800 | BOOTSTRAPPER_ENGINE_CONTEXT engineContext = { }; | 813 | BOOTSTRAPPER_ENGINE_CONTEXT engineContext = { }; |
801 | BOOL fStartupCalled = FALSE; | 814 | BOOL fStartupCalled = FALSE; |
802 | BOOL fRet = FALSE; | ||
803 | MSG msg = { }; | ||
804 | BOOTSTRAPPER_SHUTDOWN_ACTION shutdownAction = BOOTSTRAPPER_SHUTDOWN_ACTION_NONE; | 815 | BOOTSTRAPPER_SHUTDOWN_ACTION shutdownAction = BOOTSTRAPPER_SHUTDOWN_ACTION_NONE; |
805 | 816 | BOOTSTRAPPER_ENGINE_ACTION* pAction = NULL; | |
806 | ::PeekMessageW(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE); | ||
807 | 817 | ||
808 | // Setup the bootstrapper engine. | 818 | // Setup the bootstrapper engine. |
809 | engineContext.dwThreadId = ::GetCurrentThreadId(); | ||
810 | engineContext.pEngineState = pEngineState; | 819 | engineContext.pEngineState = pEngineState; |
811 | 820 | ||
821 | ::InitializeCriticalSection(&engineContext.csQueue); | ||
822 | |||
823 | engineContext.hQueueSemaphore = ::CreateSemaphoreW(NULL, 0, LONG_MAX, NULL); | ||
824 | ExitOnNullWithLastError(engineContext.hQueueSemaphore, hr, "Failed to create semaphore for queue."); | ||
825 | |||
826 | hr = QueCreate(&engineContext.hQueue); | ||
827 | ExitOnFailure(hr, "Failed to create queue for bootstrapper engine."); | ||
828 | |||
812 | // Load the bootstrapper application. | 829 | // Load the bootstrapper application. |
813 | hr = UserExperienceLoad(&pEngineState->userExperience, &engineContext, &pEngineState->command); | 830 | hr = UserExperienceLoad(&pEngineState->userExperience, &engineContext, &pEngineState->command); |
814 | ExitOnFailure(hr, "Failed to load BA."); | 831 | ExitOnFailure(hr, "Failed to load BA."); |
@@ -817,28 +834,24 @@ static HRESULT RunApplication( | |||
817 | hr = UserExperienceOnStartup(&pEngineState->userExperience); | 834 | hr = UserExperienceOnStartup(&pEngineState->userExperience); |
818 | ExitOnFailure(hr, "Failed to start bootstrapper application."); | 835 | ExitOnFailure(hr, "Failed to start bootstrapper application."); |
819 | 836 | ||
820 | // Enter the message pump. | 837 | while (!pEngineState->fQuit) |
821 | while (0 != (fRet = ::GetMessageW(&msg, NULL, 0, 0))) | ||
822 | { | 838 | { |
823 | if (-1 == fRet) | 839 | hr = AppWaitForSingleObject(engineContext.hQueueSemaphore, INFINITE); |
824 | { | 840 | ExitOnFailure(hr, "Failed to wait on queue event."); |
825 | hr = E_UNEXPECTED; | ||
826 | ExitOnRootFailure(hr, "Unexpected return value from message pump."); | ||
827 | } | ||
828 | else | ||
829 | { | ||
830 | // When the BA makes a request from its own thread, it's common for the PostThreadMessage in externalengine.cpp | ||
831 | // to block until this thread waits on something. It's also common for Detect and Plan to never wait on something. | ||
832 | // In the extreme case, the engine could be elevating in Apply before the Detect call returned to the BA. | ||
833 | // This helps to avoid that situation, which could be blocking a UI thread. | ||
834 | ::Sleep(0); | ||
835 | 841 | ||
836 | ProcessMessage(pEngineState, &msg); | 842 | ::EnterCriticalSection(&engineContext.csQueue); |
837 | } | 843 | |
838 | } | 844 | hr = QueDequeue(engineContext.hQueue, reinterpret_cast<void**>(&pAction)); |
845 | |||
846 | ::LeaveCriticalSection(&engineContext.csQueue); | ||
839 | 847 | ||
840 | // Get exit code. | 848 | ExitOnFailure(hr, "Failed to dequeue action."); |
841 | pEngineState->userExperience.dwExitCode = (DWORD)msg.wParam; | 849 | |
850 | ProcessMessage(&engineContext, pAction); | ||
851 | |||
852 | CoreBootstrapperEngineActionUninitialize(pAction); | ||
853 | MemFree(pAction); | ||
854 | } | ||
842 | 855 | ||
843 | LExit: | 856 | LExit: |
844 | if (fStartupCalled) | 857 | if (fStartupCalled) |
@@ -864,52 +877,50 @@ LExit: | |||
864 | // Unload BA. | 877 | // Unload BA. |
865 | UserExperienceUnload(&pEngineState->userExperience, *pfReloadApp); | 878 | UserExperienceUnload(&pEngineState->userExperience, *pfReloadApp); |
866 | 879 | ||
880 | ::DeleteCriticalSection(&engineContext.csQueue); | ||
881 | ReleaseHandle(engineContext.hQueueSemaphore); | ||
882 | ReleaseQueue(engineContext.hQueue, FreeQueueItem, &engineContext); | ||
883 | |||
867 | return hr; | 884 | return hr; |
868 | } | 885 | } |
869 | 886 | ||
870 | static HRESULT ProcessMessage( | 887 | static HRESULT ProcessMessage( |
871 | __in BURN_ENGINE_STATE* pEngineState, | 888 | __in BOOTSTRAPPER_ENGINE_CONTEXT* pEngineContext, |
872 | __in const MSG* pmsg | 889 | __in BOOTSTRAPPER_ENGINE_ACTION* pAction |
873 | ) | 890 | ) |
874 | { | 891 | { |
875 | HRESULT hr = S_OK; | 892 | HRESULT hr = S_OK; |
893 | BURN_ENGINE_STATE* pEngineState = pEngineContext->pEngineState; | ||
876 | 894 | ||
877 | UserExperienceActivateEngine(&pEngineState->userExperience); | 895 | UserExperienceActivateEngine(&pEngineState->userExperience); |
878 | 896 | ||
879 | if (pEngineState->fQuit) | 897 | switch (pAction->dwMessage) |
880 | { | ||
881 | LogId(REPORT_WARNING, MSG_IGNORE_OPERATION_AFTER_QUIT, LoggingBurnMessageToString(pmsg->message)); | ||
882 | ExitFunction1(hr = E_INVALIDSTATE); | ||
883 | } | ||
884 | |||
885 | switch (pmsg->message) | ||
886 | { | 898 | { |
887 | case WM_BURN_DETECT: | 899 | case WM_BURN_DETECT: |
888 | hr = CoreDetect(pEngineState, reinterpret_cast<HWND>(pmsg->lParam)); | 900 | hr = CoreDetect(pEngineState, pAction->detect.hwndParent); |
889 | break; | 901 | break; |
890 | 902 | ||
891 | case WM_BURN_PLAN: | 903 | case WM_BURN_PLAN: |
892 | hr = CorePlan(pEngineState, static_cast<BOOTSTRAPPER_ACTION>(pmsg->lParam)); | 904 | hr = CorePlan(pEngineState, pAction->plan.action); |
893 | break; | 905 | break; |
894 | 906 | ||
895 | case WM_BURN_ELEVATE: | 907 | case WM_BURN_ELEVATE: |
896 | hr = CoreElevate(pEngineState, WM_BURN_ELEVATE, reinterpret_cast<HWND>(pmsg->lParam)); | 908 | hr = CoreElevate(pEngineState, WM_BURN_ELEVATE, pAction->elevate.hwndParent); |
897 | break; | 909 | break; |
898 | 910 | ||
899 | case WM_BURN_APPLY: | 911 | case WM_BURN_APPLY: |
900 | hr = CoreApply(pEngineState, reinterpret_cast<HWND>(pmsg->lParam)); | 912 | hr = CoreApply(pEngineState, pAction->apply.hwndParent); |
901 | break; | 913 | break; |
902 | 914 | ||
903 | case WM_BURN_LAUNCH_APPROVED_EXE: | 915 | case WM_BURN_LAUNCH_APPROVED_EXE: |
904 | hr = CoreLaunchApprovedExe(pEngineState, reinterpret_cast<BURN_LAUNCH_APPROVED_EXE*>(pmsg->lParam)); | 916 | hr = CoreLaunchApprovedExe(pEngineState, &pAction->launchApprovedExe); |
905 | break; | 917 | break; |
906 | 918 | ||
907 | case WM_BURN_QUIT: | 919 | case WM_BURN_QUIT: |
908 | hr = CoreQuit(pEngineState, static_cast<int>(pmsg->wParam)); | 920 | CoreQuit(pEngineContext, pAction->quit.dwExitCode); |
909 | break; | 921 | break; |
910 | } | 922 | } |
911 | 923 | ||
912 | LExit: | ||
913 | UserExperienceDeactivateEngine(&pEngineState->userExperience); | 924 | UserExperienceDeactivateEngine(&pEngineState->userExperience); |
914 | 925 | ||
915 | return hr; | 926 | return hr; |
diff --git a/src/burn/engine/externalengine.cpp b/src/burn/engine/externalengine.cpp index 5e540c2a..262bb1a9 100644 --- a/src/burn/engine/externalengine.cpp +++ b/src/burn/engine/externalengine.cpp | |||
@@ -13,6 +13,10 @@ static HRESULT ProcessUnknownEmbeddedMessages( | |||
13 | __in_opt LPVOID /*pvContext*/, | 13 | __in_opt LPVOID /*pvContext*/, |
14 | __out DWORD* pdwResult | 14 | __out DWORD* pdwResult |
15 | ); | 15 | ); |
16 | static HRESULT EnqueueAction( | ||
17 | __in BOOTSTRAPPER_ENGINE_CONTEXT* pEngineContext, | ||
18 | __inout BOOTSTRAPPER_ENGINE_ACTION** ppAction | ||
19 | ); | ||
16 | 20 | ||
17 | // function definitions | 21 | // function definitions |
18 | 22 | ||
@@ -582,69 +586,91 @@ HRESULT ExternalEngineCompareVersions( | |||
582 | } | 586 | } |
583 | 587 | ||
584 | HRESULT ExternalEngineDetect( | 588 | HRESULT ExternalEngineDetect( |
585 | __in const DWORD dwThreadId, | 589 | __in BOOTSTRAPPER_ENGINE_CONTEXT* pEngineContext, |
586 | __in_opt const HWND hwndParent | 590 | __in_opt const HWND hwndParent |
587 | ) | 591 | ) |
588 | { | 592 | { |
589 | HRESULT hr = S_OK; | 593 | HRESULT hr = S_OK; |
594 | BOOTSTRAPPER_ENGINE_ACTION* pAction = NULL; | ||
590 | 595 | ||
591 | if (!::PostThreadMessageW(dwThreadId, WM_BURN_DETECT, 0, reinterpret_cast<LPARAM>(hwndParent))) | 596 | pAction = (BOOTSTRAPPER_ENGINE_ACTION*)MemAlloc(sizeof(BOOTSTRAPPER_ENGINE_ACTION), TRUE); |
592 | { | 597 | ExitOnNull(pAction, hr, E_OUTOFMEMORY, "Failed to alloc BOOTSTRAPPER_ENGINE_ACTION"); |
593 | ExitWithLastError(hr, "Failed to post detect message."); | 598 | |
594 | } | 599 | pAction->dwMessage = WM_BURN_DETECT; |
600 | pAction->detect.hwndParent = hwndParent; | ||
601 | |||
602 | hr = EnqueueAction(pEngineContext, &pAction); | ||
603 | ExitOnFailure(hr, "Failed to enqueue detect action."); | ||
595 | 604 | ||
596 | LExit: | 605 | LExit: |
606 | ReleaseMem(pAction); | ||
607 | |||
597 | return hr; | 608 | return hr; |
598 | } | 609 | } |
599 | 610 | ||
600 | HRESULT ExternalEnginePlan( | 611 | HRESULT ExternalEnginePlan( |
601 | __in const DWORD dwThreadId, | 612 | __in BOOTSTRAPPER_ENGINE_CONTEXT* pEngineContext, |
602 | __in const BOOTSTRAPPER_ACTION action | 613 | __in const BOOTSTRAPPER_ACTION action |
603 | ) | 614 | ) |
604 | { | 615 | { |
605 | HRESULT hr = S_OK; | 616 | HRESULT hr = S_OK; |
617 | BOOTSTRAPPER_ENGINE_ACTION* pAction = NULL; | ||
606 | 618 | ||
607 | if (BOOTSTRAPPER_ACTION_LAYOUT > action || BOOTSTRAPPER_ACTION_UPDATE_REPLACE_EMBEDDED < action) | 619 | if (BOOTSTRAPPER_ACTION_LAYOUT > action || BOOTSTRAPPER_ACTION_UPDATE_REPLACE_EMBEDDED < action) |
608 | { | 620 | { |
609 | ExitOnRootFailure(hr = E_INVALIDARG, "BA passed invalid action to Plan: %u.", action); | 621 | ExitOnRootFailure(hr = E_INVALIDARG, "BA passed invalid action to Plan: %u.", action); |
610 | } | 622 | } |
611 | 623 | ||
612 | if (!::PostThreadMessageW(dwThreadId, WM_BURN_PLAN, 0, action)) | 624 | pAction = (BOOTSTRAPPER_ENGINE_ACTION*)MemAlloc(sizeof(BOOTSTRAPPER_ENGINE_ACTION), TRUE); |
613 | { | 625 | ExitOnNull(pAction, hr, E_OUTOFMEMORY, "Failed to alloc BOOTSTRAPPER_ENGINE_ACTION"); |
614 | ExitWithLastError(hr, "Failed to post plan message."); | 626 | |
615 | } | 627 | pAction->dwMessage = WM_BURN_PLAN; |
628 | pAction->plan.action = action; | ||
629 | |||
630 | hr = EnqueueAction(pEngineContext, &pAction); | ||
631 | ExitOnFailure(hr, "Failed to enqueue plan action."); | ||
616 | 632 | ||
617 | LExit: | 633 | LExit: |
634 | ReleaseMem(pAction); | ||
635 | |||
618 | return hr; | 636 | return hr; |
619 | } | 637 | } |
620 | 638 | ||
621 | HRESULT ExternalEngineElevate( | 639 | HRESULT ExternalEngineElevate( |
622 | __in BURN_ENGINE_STATE* pEngineState, | 640 | __in BOOTSTRAPPER_ENGINE_CONTEXT* pEngineContext, |
623 | __in const DWORD dwThreadId, | ||
624 | __in_opt const HWND hwndParent | 641 | __in_opt const HWND hwndParent |
625 | ) | 642 | ) |
626 | { | 643 | { |
627 | HRESULT hr = S_OK; | 644 | HRESULT hr = S_OK; |
645 | BOOTSTRAPPER_ENGINE_ACTION* pAction = NULL; | ||
628 | 646 | ||
629 | if (INVALID_HANDLE_VALUE != pEngineState->companionConnection.hPipe) | 647 | if (INVALID_HANDLE_VALUE != pEngineContext->pEngineState->companionConnection.hPipe) |
630 | { | ||
631 | hr = HRESULT_FROM_WIN32(ERROR_ALREADY_INITIALIZED); | ||
632 | } | ||
633 | else if (!::PostThreadMessageW(dwThreadId, WM_BURN_ELEVATE, 0, reinterpret_cast<LPARAM>(hwndParent))) | ||
634 | { | 648 | { |
635 | ExitWithLastError(hr, "Failed to post elevate message."); | 649 | ExitFunction1(hr = HRESULT_FROM_WIN32(ERROR_ALREADY_INITIALIZED)); |
636 | } | 650 | } |
637 | 651 | ||
652 | pAction = (BOOTSTRAPPER_ENGINE_ACTION*)MemAlloc(sizeof(BOOTSTRAPPER_ENGINE_ACTION), TRUE); | ||
653 | ExitOnNull(pAction, hr, E_OUTOFMEMORY, "Failed to alloc BOOTSTRAPPER_ENGINE_ACTION"); | ||
654 | |||
655 | pAction->dwMessage = WM_BURN_ELEVATE; | ||
656 | pAction->elevate.hwndParent = hwndParent; | ||
657 | |||
658 | hr = EnqueueAction(pEngineContext, &pAction); | ||
659 | ExitOnFailure(hr, "Failed to enqueue elevate action."); | ||
660 | |||
638 | LExit: | 661 | LExit: |
662 | ReleaseMem(pAction); | ||
663 | |||
639 | return hr; | 664 | return hr; |
640 | } | 665 | } |
641 | 666 | ||
642 | HRESULT ExternalEngineApply( | 667 | HRESULT ExternalEngineApply( |
643 | __in const DWORD dwThreadId, | 668 | __in BOOTSTRAPPER_ENGINE_CONTEXT* pEngineContext, |
644 | __in_opt const HWND hwndParent | 669 | __in_opt const HWND hwndParent |
645 | ) | 670 | ) |
646 | { | 671 | { |
647 | HRESULT hr = S_OK; | 672 | HRESULT hr = S_OK; |
673 | BOOTSTRAPPER_ENGINE_ACTION* pAction = NULL; | ||
648 | 674 | ||
649 | ExitOnNull(hwndParent, hr, E_INVALIDARG, "BA passed NULL hwndParent to Apply."); | 675 | ExitOnNull(hwndParent, hr, E_INVALIDARG, "BA passed NULL hwndParent to Apply."); |
650 | if (!::IsWindow(hwndParent)) | 676 | if (!::IsWindow(hwndParent)) |
@@ -652,34 +678,46 @@ HRESULT ExternalEngineApply( | |||
652 | ExitOnRootFailure(hr = E_INVALIDARG, "BA passed invalid hwndParent to Apply."); | 678 | ExitOnRootFailure(hr = E_INVALIDARG, "BA passed invalid hwndParent to Apply."); |
653 | } | 679 | } |
654 | 680 | ||
655 | if (!::PostThreadMessageW(dwThreadId, WM_BURN_APPLY, 0, reinterpret_cast<LPARAM>(hwndParent))) | 681 | pAction = (BOOTSTRAPPER_ENGINE_ACTION*)MemAlloc(sizeof(BOOTSTRAPPER_ENGINE_ACTION), TRUE); |
656 | { | 682 | ExitOnNull(pAction, hr, E_OUTOFMEMORY, "Failed to alloc BOOTSTRAPPER_ENGINE_ACTION"); |
657 | ExitWithLastError(hr, "Failed to post apply message."); | 683 | |
658 | } | 684 | pAction->dwMessage = WM_BURN_APPLY; |
685 | pAction->apply.hwndParent = hwndParent; | ||
686 | |||
687 | hr = EnqueueAction(pEngineContext, &pAction); | ||
688 | ExitOnFailure(hr, "Failed to enqueue apply action."); | ||
659 | 689 | ||
660 | LExit: | 690 | LExit: |
691 | ReleaseMem(pAction); | ||
692 | |||
661 | return hr; | 693 | return hr; |
662 | } | 694 | } |
663 | 695 | ||
664 | HRESULT ExternalEngineQuit( | 696 | HRESULT ExternalEngineQuit( |
665 | __in const DWORD dwThreadId, | 697 | __in BOOTSTRAPPER_ENGINE_CONTEXT* pEngineContext, |
666 | __in const DWORD dwExitCode | 698 | __in const DWORD dwExitCode |
667 | ) | 699 | ) |
668 | { | 700 | { |
669 | HRESULT hr = S_OK; | 701 | HRESULT hr = S_OK; |
702 | BOOTSTRAPPER_ENGINE_ACTION* pAction = NULL; | ||
670 | 703 | ||
671 | if (!::PostThreadMessageW(dwThreadId, WM_BURN_QUIT, static_cast<WPARAM>(dwExitCode), 0)) | 704 | pAction = (BOOTSTRAPPER_ENGINE_ACTION*)MemAlloc(sizeof(BOOTSTRAPPER_ENGINE_ACTION), TRUE); |
672 | { | 705 | ExitOnNull(pAction, hr, E_OUTOFMEMORY, "Failed to alloc BOOTSTRAPPER_ENGINE_ACTION"); |
673 | ExitWithLastError(hr, "Failed to post shutdown message."); | 706 | |
674 | } | 707 | pAction->dwMessage = WM_BURN_QUIT; |
708 | pAction->quit.dwExitCode = dwExitCode; | ||
709 | |||
710 | hr = EnqueueAction(pEngineContext, &pAction); | ||
711 | ExitOnFailure(hr, "Failed to enqueue shutdown action."); | ||
675 | 712 | ||
676 | LExit: | 713 | LExit: |
714 | ReleaseMem(pAction); | ||
715 | |||
677 | return hr; | 716 | return hr; |
678 | } | 717 | } |
679 | 718 | ||
680 | HRESULT ExternalEngineLaunchApprovedExe( | 719 | HRESULT ExternalEngineLaunchApprovedExe( |
681 | __in BURN_ENGINE_STATE* pEngineState, | 720 | __in BOOTSTRAPPER_ENGINE_CONTEXT* pEngineContext, |
682 | __in const DWORD dwThreadId, | ||
683 | __in_opt const HWND hwndParent, | 721 | __in_opt const HWND hwndParent, |
684 | __in_z LPCWSTR wzApprovedExeForElevationId, | 722 | __in_z LPCWSTR wzApprovedExeForElevationId, |
685 | __in_z_opt LPCWSTR wzArguments, | 723 | __in_z_opt LPCWSTR wzArguments, |
@@ -688,25 +726,23 @@ HRESULT ExternalEngineLaunchApprovedExe( | |||
688 | { | 726 | { |
689 | HRESULT hr = S_OK; | 727 | HRESULT hr = S_OK; |
690 | BURN_APPROVED_EXE* pApprovedExe = NULL; | 728 | BURN_APPROVED_EXE* pApprovedExe = NULL; |
691 | BOOL fLeaveCriticalSection = FALSE; | ||
692 | BURN_LAUNCH_APPROVED_EXE* pLaunchApprovedExe = NULL; | 729 | BURN_LAUNCH_APPROVED_EXE* pLaunchApprovedExe = NULL; |
693 | 730 | BOOTSTRAPPER_ENGINE_ACTION* pAction = NULL; | |
694 | pLaunchApprovedExe = (BURN_LAUNCH_APPROVED_EXE*)MemAlloc(sizeof(BURN_LAUNCH_APPROVED_EXE), TRUE); | ||
695 | ExitOnNull(pLaunchApprovedExe, hr, E_OUTOFMEMORY, "Failed to alloc BURN_LAUNCH_APPROVED_EXE"); | ||
696 | |||
697 | ::EnterCriticalSection(&pEngineState->userExperience.csEngineActive); | ||
698 | fLeaveCriticalSection = TRUE; | ||
699 | hr = UserExperienceEnsureEngineInactive(&pEngineState->userExperience); | ||
700 | ExitOnFailure(hr, "Engine is active, cannot change engine state."); | ||
701 | 731 | ||
702 | if (!wzApprovedExeForElevationId || !*wzApprovedExeForElevationId) | 732 | if (!wzApprovedExeForElevationId || !*wzApprovedExeForElevationId) |
703 | { | 733 | { |
704 | ExitFunction1(hr = E_INVALIDARG); | 734 | ExitFunction1(hr = E_INVALIDARG); |
705 | } | 735 | } |
706 | 736 | ||
707 | hr = ApprovedExesFindById(&pEngineState->approvedExes, wzApprovedExeForElevationId, &pApprovedExe); | 737 | hr = ApprovedExesFindById(&pEngineContext->pEngineState->approvedExes, wzApprovedExeForElevationId, &pApprovedExe); |
708 | ExitOnFailure(hr, "BA requested unknown approved exe with id: %ls", wzApprovedExeForElevationId); | 738 | ExitOnFailure(hr, "BA requested unknown approved exe with id: %ls", wzApprovedExeForElevationId); |
709 | 739 | ||
740 | pAction = (BOOTSTRAPPER_ENGINE_ACTION*)MemAlloc(sizeof(BOOTSTRAPPER_ENGINE_ACTION), TRUE); | ||
741 | ExitOnNull(pAction, hr, E_OUTOFMEMORY, "Failed to alloc BOOTSTRAPPER_ENGINE_ACTION"); | ||
742 | |||
743 | pAction->dwMessage = WM_BURN_LAUNCH_APPROVED_EXE; | ||
744 | pLaunchApprovedExe = &pAction->launchApprovedExe; | ||
745 | |||
710 | hr = StrAllocString(&pLaunchApprovedExe->sczId, wzApprovedExeForElevationId, NULL); | 746 | hr = StrAllocString(&pLaunchApprovedExe->sczId, wzApprovedExeForElevationId, NULL); |
711 | ExitOnFailure(hr, "Failed to copy the id."); | 747 | ExitOnFailure(hr, "Failed to copy the id."); |
712 | 748 | ||
@@ -720,20 +756,14 @@ HRESULT ExternalEngineLaunchApprovedExe( | |||
720 | 756 | ||
721 | pLaunchApprovedExe->hwndParent = hwndParent; | 757 | pLaunchApprovedExe->hwndParent = hwndParent; |
722 | 758 | ||
723 | if (!::PostThreadMessageW(dwThreadId, WM_BURN_LAUNCH_APPROVED_EXE, 0, reinterpret_cast<LPARAM>(pLaunchApprovedExe))) | 759 | hr = EnqueueAction(pEngineContext, &pAction); |
724 | { | 760 | ExitOnFailure(hr, "Failed to enqueue launch approved exe action."); |
725 | ExitWithLastError(hr, "Failed to post launch approved exe message."); | ||
726 | } | ||
727 | 761 | ||
728 | LExit: | 762 | LExit: |
729 | if (fLeaveCriticalSection) | 763 | if (pAction) |
730 | { | 764 | { |
731 | ::LeaveCriticalSection(&pEngineState->userExperience.csEngineActive); | 765 | CoreBootstrapperEngineActionUninitialize(pAction); |
732 | } | 766 | MemFree(pAction); |
733 | |||
734 | if (FAILED(hr)) | ||
735 | { | ||
736 | ApprovedExesUninitializeLaunch(pLaunchApprovedExe); | ||
737 | } | 767 | } |
738 | 768 | ||
739 | return hr; | 769 | return hr; |
@@ -836,3 +866,37 @@ static HRESULT ProcessUnknownEmbeddedMessages( | |||
836 | 866 | ||
837 | return S_OK; | 867 | return S_OK; |
838 | } | 868 | } |
869 | |||
870 | static HRESULT EnqueueAction( | ||
871 | __in BOOTSTRAPPER_ENGINE_CONTEXT* pEngineContext, | ||
872 | __inout BOOTSTRAPPER_ENGINE_ACTION** ppAction | ||
873 | ) | ||
874 | { | ||
875 | HRESULT hr = S_OK; | ||
876 | |||
877 | ::EnterCriticalSection(&pEngineContext->csQueue); | ||
878 | |||
879 | if (pEngineContext->pEngineState->fQuit) | ||
880 | { | ||
881 | LogId(REPORT_WARNING, MSG_IGNORE_OPERATION_AFTER_QUIT, LoggingBurnMessageToString((*ppAction)->dwMessage)); | ||
882 | hr = E_INVALIDSTATE; | ||
883 | } | ||
884 | else | ||
885 | { | ||
886 | hr = QueEnqueue(pEngineContext->hQueue, *ppAction); | ||
887 | } | ||
888 | |||
889 | ::LeaveCriticalSection(&pEngineContext->csQueue); | ||
890 | |||
891 | ExitOnFailure(hr, "Failed to enqueue action."); | ||
892 | |||
893 | *ppAction = NULL; | ||
894 | |||
895 | if (!::ReleaseSemaphore(pEngineContext->hQueueSemaphore, 1, NULL)) | ||
896 | { | ||
897 | ExitWithLastError(hr, "Failed to signal queue semaphore."); | ||
898 | } | ||
899 | |||
900 | LExit: | ||
901 | return hr; | ||
902 | } | ||
diff --git a/src/burn/engine/externalengine.h b/src/burn/engine/externalengine.h index f28971cd..9322234a 100644 --- a/src/burn/engine/externalengine.h +++ b/src/burn/engine/externalengine.h | |||
@@ -130,34 +130,32 @@ HRESULT ExternalEngineCompareVersions( | |||
130 | ); | 130 | ); |
131 | 131 | ||
132 | HRESULT ExternalEngineDetect( | 132 | HRESULT ExternalEngineDetect( |
133 | __in const DWORD dwThreadId, | 133 | __in BOOTSTRAPPER_ENGINE_CONTEXT* pEngineContext, |
134 | __in_opt const HWND hwndParent | 134 | __in_opt const HWND hwndParent |
135 | ); | 135 | ); |
136 | 136 | ||
137 | HRESULT ExternalEnginePlan( | 137 | HRESULT ExternalEnginePlan( |
138 | __in const DWORD dwThreadId, | 138 | __in BOOTSTRAPPER_ENGINE_CONTEXT* pEngineContext, |
139 | __in const BOOTSTRAPPER_ACTION action | 139 | __in const BOOTSTRAPPER_ACTION action |
140 | ); | 140 | ); |
141 | 141 | ||
142 | HRESULT ExternalEngineElevate( | 142 | HRESULT ExternalEngineElevate( |
143 | __in BURN_ENGINE_STATE* pEngineState, | 143 | __in BOOTSTRAPPER_ENGINE_CONTEXT* pEngineContext, |
144 | __in const DWORD dwThreadId, | ||
145 | __in_opt const HWND hwndParent | 144 | __in_opt const HWND hwndParent |
146 | ); | 145 | ); |
147 | 146 | ||
148 | HRESULT ExternalEngineApply( | 147 | HRESULT ExternalEngineApply( |
149 | __in const DWORD dwThreadId, | 148 | __in BOOTSTRAPPER_ENGINE_CONTEXT* pEngineContext, |
150 | __in_opt const HWND hwndParent | 149 | __in_opt const HWND hwndParent |
151 | ); | 150 | ); |
152 | 151 | ||
153 | HRESULT ExternalEngineQuit( | 152 | HRESULT ExternalEngineQuit( |
154 | __in const DWORD dwThreadId, | 153 | __in BOOTSTRAPPER_ENGINE_CONTEXT* pEngineContext, |
155 | __in const DWORD dwExitCode | 154 | __in const DWORD dwExitCode |
156 | ); | 155 | ); |
157 | 156 | ||
158 | HRESULT ExternalEngineLaunchApprovedExe( | 157 | HRESULT ExternalEngineLaunchApprovedExe( |
159 | __in BURN_ENGINE_STATE* pEngineState, | 158 | __in BOOTSTRAPPER_ENGINE_CONTEXT* pEngineContext, |
160 | __in const DWORD dwThreadId, | ||
161 | __in_opt const HWND hwndParent, | 159 | __in_opt const HWND hwndParent, |
162 | __in_z LPCWSTR wzApprovedExeForElevationId, | 160 | __in_z LPCWSTR wzApprovedExeForElevationId, |
163 | __in_z_opt LPCWSTR wzArguments, | 161 | __in_z_opt LPCWSTR wzArguments, |
diff --git a/src/burn/engine/platform.h b/src/burn/engine/platform.h index 60184c23..5896a5ca 100644 --- a/src/burn/engine/platform.h +++ b/src/burn/engine/platform.h | |||
@@ -28,6 +28,7 @@ enum WM_BURN | |||
28 | 28 | ||
29 | enum BURN_MODE; | 29 | enum BURN_MODE; |
30 | typedef struct _BOOTSTRAPPER_ENGINE_CONTEXT BOOTSTRAPPER_ENGINE_CONTEXT; | 30 | typedef struct _BOOTSTRAPPER_ENGINE_CONTEXT BOOTSTRAPPER_ENGINE_CONTEXT; |
31 | typedef struct _BOOTSTRAPPER_ENGINE_ACTION BOOTSTRAPPER_ENGINE_ACTION; | ||
31 | typedef struct _BURN_CACHE BURN_CACHE; | 32 | typedef struct _BURN_CACHE BURN_CACHE; |
32 | typedef struct _BURN_DEPENDENCIES BURN_DEPENDENCIES; | 33 | typedef struct _BURN_DEPENDENCIES BURN_DEPENDENCIES; |
33 | typedef struct _BURN_ENGINE_COMMAND BURN_ENGINE_COMMAND; | 34 | typedef struct _BURN_ENGINE_COMMAND BURN_ENGINE_COMMAND; |
diff --git a/src/burn/engine/precomp.h b/src/burn/engine/precomp.h index e2d1b5cd..a64ce474 100644 --- a/src/burn/engine/precomp.h +++ b/src/burn/engine/precomp.h | |||
@@ -40,6 +40,7 @@ | |||
40 | #include <pathutil.h> | 40 | #include <pathutil.h> |
41 | #include <polcutil.h> | 41 | #include <polcutil.h> |
42 | #include <procutil.h> | 42 | #include <procutil.h> |
43 | #include <queutil.h> | ||
43 | #include <regutil.h> | 44 | #include <regutil.h> |
44 | #include <resrutil.h> | 45 | #include <resrutil.h> |
45 | #include <shelutil.h> | 46 | #include <shelutil.h> |
diff --git a/src/libs/dutil/WixToolset.DUtil/dutil.vcxproj b/src/libs/dutil/WixToolset.DUtil/dutil.vcxproj index c84b98fe..dc6b913f 100644 --- a/src/libs/dutil/WixToolset.DUtil/dutil.vcxproj +++ b/src/libs/dutil/WixToolset.DUtil/dutil.vcxproj | |||
@@ -91,6 +91,7 @@ | |||
91 | <ClCompile Include="proc2utl.cpp" /> | 91 | <ClCompile Include="proc2utl.cpp" /> |
92 | <ClCompile Include="proc3utl.cpp" /> | 92 | <ClCompile Include="proc3utl.cpp" /> |
93 | <ClCompile Include="procutil.cpp" /> | 93 | <ClCompile Include="procutil.cpp" /> |
94 | <ClCompile Include="queutil.cpp" /> | ||
94 | <ClCompile Include="regutil.cpp" /> | 95 | <ClCompile Include="regutil.cpp" /> |
95 | <ClCompile Include="resrutil.cpp" /> | 96 | <ClCompile Include="resrutil.cpp" /> |
96 | <ClCompile Include="reswutil.cpp" /> | 97 | <ClCompile Include="reswutil.cpp" /> |
@@ -153,6 +154,7 @@ | |||
153 | <ClInclude Include="inc\perfutil.h" /> | 154 | <ClInclude Include="inc\perfutil.h" /> |
154 | <ClInclude Include="inc\polcutil.h" /> | 155 | <ClInclude Include="inc\polcutil.h" /> |
155 | <ClInclude Include="inc\procutil.h" /> | 156 | <ClInclude Include="inc\procutil.h" /> |
157 | <ClInclude Include="inc\queutil.h" /> | ||
156 | <ClInclude Include="inc\regutil.h" /> | 158 | <ClInclude Include="inc\regutil.h" /> |
157 | <ClInclude Include="inc\resrutil.h" /> | 159 | <ClInclude Include="inc\resrutil.h" /> |
158 | <ClInclude Include="inc\reswutil.h" /> | 160 | <ClInclude Include="inc\reswutil.h" /> |
diff --git a/src/libs/dutil/WixToolset.DUtil/dutil.vcxproj.filters b/src/libs/dutil/WixToolset.DUtil/dutil.vcxproj.filters index efadef6f..c1095651 100644 --- a/src/libs/dutil/WixToolset.DUtil/dutil.vcxproj.filters +++ b/src/libs/dutil/WixToolset.DUtil/dutil.vcxproj.filters | |||
@@ -135,6 +135,9 @@ | |||
135 | <ClCompile Include="procutil.cpp"> | 135 | <ClCompile Include="procutil.cpp"> |
136 | <Filter>Source Files</Filter> | 136 | <Filter>Source Files</Filter> |
137 | </ClCompile> | 137 | </ClCompile> |
138 | <ClCompile Include="queutil.cpp"> | ||
139 | <Filter>Source Files</Filter> | ||
140 | </ClCompile> | ||
138 | <ClCompile Include="resrutil.cpp"> | 141 | <ClCompile Include="resrutil.cpp"> |
139 | <Filter>Source Files</Filter> | 142 | <Filter>Source Files</Filter> |
140 | </ClCompile> | 143 | </ClCompile> |
@@ -314,6 +317,9 @@ | |||
314 | <ClInclude Include="inc\procutil.h"> | 317 | <ClInclude Include="inc\procutil.h"> |
315 | <Filter>Header Files</Filter> | 318 | <Filter>Header Files</Filter> |
316 | </ClInclude> | 319 | </ClInclude> |
320 | <ClInclude Include="inc\queutil.h"> | ||
321 | <Filter>Header Files</Filter> | ||
322 | </ClInclude> | ||
317 | <ClInclude Include="inc\regutil.h"> | 323 | <ClInclude Include="inc\regutil.h"> |
318 | <Filter>Header Files</Filter> | 324 | <Filter>Header Files</Filter> |
319 | </ClInclude> | 325 | </ClInclude> |
diff --git a/src/libs/dutil/WixToolset.DUtil/inc/dutilsources.h b/src/libs/dutil/WixToolset.DUtil/inc/dutilsources.h index 664c21e5..cf10f910 100644 --- a/src/libs/dutil/WixToolset.DUtil/inc/dutilsources.h +++ b/src/libs/dutil/WixToolset.DUtil/inc/dutilsources.h | |||
@@ -64,6 +64,7 @@ typedef enum DUTIL_SOURCE | |||
64 | DUTIL_SOURCE_WNDUTIL, | 64 | DUTIL_SOURCE_WNDUTIL, |
65 | DUTIL_SOURCE_ENVUTIL, | 65 | DUTIL_SOURCE_ENVUTIL, |
66 | DUTIL_SOURCE_THRDUTIL, | 66 | DUTIL_SOURCE_THRDUTIL, |
67 | DUTIL_SOURCE_QUEUTIL, | ||
67 | 68 | ||
68 | DUTIL_SOURCE_EXTERNAL = 256, | 69 | DUTIL_SOURCE_EXTERNAL = 256, |
69 | } DUTIL_SOURCE; | 70 | } DUTIL_SOURCE; |
diff --git a/src/libs/dutil/WixToolset.DUtil/inc/queutil.h b/src/libs/dutil/WixToolset.DUtil/inc/queutil.h new file mode 100644 index 00000000..3b88825e --- /dev/null +++ b/src/libs/dutil/WixToolset.DUtil/inc/queutil.h | |||
@@ -0,0 +1,52 @@ | |||
1 | #pragma once | ||
2 | // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. | ||
3 | |||
4 | |||
5 | #ifdef __cplusplus | ||
6 | extern "C" { | ||
7 | #endif | ||
8 | |||
9 | #define ReleaseQueue(qh, pfn, pv) if (qh) { QueDestroy(qh, pfn, pv); } | ||
10 | #define ReleaseNullQue(qh, pfv, pv) if (qh) { QueDestroy(qh, pfn, pv); qh = NULL; } | ||
11 | |||
12 | typedef void* QUEUTIL_QUEUE_HANDLE; | ||
13 | |||
14 | typedef void(CALLBACK* PFNQUEUTIL_QUEUE_RELEASE_VALUE)( | ||
15 | __in void* pvValue, | ||
16 | __in void* pvContext | ||
17 | ); | ||
18 | |||
19 | extern const int QUEUTIL_QUEUE_HANDLE_BYTES; | ||
20 | |||
21 | /******************************************************************** | ||
22 | QueCreate - Creates a simple queue. It is not thread safe. | ||
23 | |||
24 | ********************************************************************/ | ||
25 | HRESULT DAPI QueCreate( | ||
26 | __out_bcount(QUEUTIL_QUEUE_HANDLE_BYTES) QUEUTIL_QUEUE_HANDLE* phQueue | ||
27 | ); | ||
28 | |||
29 | HRESULT DAPI QueEnqueue( | ||
30 | __in_bcount(QUEUTIL_QUEUE_HANDLE_BYTES) QUEUTIL_QUEUE_HANDLE hQueue, | ||
31 | __in void* pvValue | ||
32 | ); | ||
33 | |||
34 | /******************************************************************** | ||
35 | QueDequeue - Returns the value from the beginning of the queue, | ||
36 | or E_NOMOREITEMS if the queue is empty. | ||
37 | |||
38 | ********************************************************************/ | ||
39 | HRESULT DAPI QueDequeue( | ||
40 | __in_bcount(QUEUTIL_QUEUE_HANDLE_BYTES) QUEUTIL_QUEUE_HANDLE hQueue, | ||
41 | __out void** ppvValue | ||
42 | ); | ||
43 | |||
44 | void DAPI QueDestroy( | ||
45 | __in_bcount(QUEUTIL_QUEUE_HANDLE_BYTES) QUEUTIL_QUEUE_HANDLE hQueue, | ||
46 | __in_opt PFNQUEUTIL_QUEUE_RELEASE_VALUE pfnReleaseValue, | ||
47 | __in_opt void* pvContext | ||
48 | ); | ||
49 | |||
50 | #ifdef __cplusplus | ||
51 | } | ||
52 | #endif | ||
diff --git a/src/libs/dutil/WixToolset.DUtil/precomp.h b/src/libs/dutil/WixToolset.DUtil/precomp.h index b628d271..607f7ce6 100644 --- a/src/libs/dutil/WixToolset.DUtil/precomp.h +++ b/src/libs/dutil/WixToolset.DUtil/precomp.h | |||
@@ -75,6 +75,7 @@ | |||
75 | #include "perfutil.h" | 75 | #include "perfutil.h" |
76 | #include "polcutil.h" | 76 | #include "polcutil.h" |
77 | #include "procutil.h" | 77 | #include "procutil.h" |
78 | #include "queutil.h" | ||
78 | #include "regutil.h" | 79 | #include "regutil.h" |
79 | #include "butil.h" // NOTE: Butil must come after Regutil. | 80 | #include "butil.h" // NOTE: Butil must come after Regutil. |
80 | #include "resrutil.h" | 81 | #include "resrutil.h" |
diff --git a/src/libs/dutil/WixToolset.DUtil/queutil.cpp b/src/libs/dutil/WixToolset.DUtil/queutil.cpp new file mode 100644 index 00000000..c5d2d736 --- /dev/null +++ b/src/libs/dutil/WixToolset.DUtil/queutil.cpp | |||
@@ -0,0 +1,144 @@ | |||
1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. | ||
2 | |||
3 | #include "precomp.h" | ||
4 | |||
5 | |||
6 | // Exit macros | ||
7 | #define QueExitOnLastError(x, s, ...) ExitOnLastErrorSource(DUTIL_SOURCE_QUEUTIL, x, s, __VA_ARGS__) | ||
8 | #define QueExitOnLastErrorDebugTrace(x, s, ...) ExitOnLastErrorDebugTraceSource(DUTIL_SOURCE_QUEUTIL, x, s, __VA_ARGS__) | ||
9 | #define QueExitWithLastError(x, s, ...) ExitWithLastErrorSource(DUTIL_SOURCE_QUEUTIL, x, s, __VA_ARGS__) | ||
10 | #define QueExitOnFailure(x, s, ...) ExitOnFailureSource(DUTIL_SOURCE_QUEUTIL, x, s, __VA_ARGS__) | ||
11 | #define QueExitOnRootFailure(x, s, ...) ExitOnRootFailureSource(DUTIL_SOURCE_QUEUTIL, x, s, __VA_ARGS__) | ||
12 | #define QueExitOnFailureDebugTrace(x, s, ...) ExitOnFailureDebugTraceSource(DUTIL_SOURCE_QUEUTIL, x, s, __VA_ARGS__) | ||
13 | #define QueExitOnNull(p, x, e, s, ...) ExitOnNullSource(DUTIL_SOURCE_QUEUTIL, p, x, e, s, __VA_ARGS__) | ||
14 | #define QueExitOnNullWithLastError(p, x, s, ...) ExitOnNullWithLastErrorSource(DUTIL_SOURCE_QUEUTIL, p, x, s, __VA_ARGS__) | ||
15 | #define QueExitOnNullDebugTrace(p, x, e, s, ...) ExitOnNullDebugTraceSource(DUTIL_SOURCE_QUEUTIL, p, x, e, s, __VA_ARGS__) | ||
16 | #define QueExitOnInvalidHandleWithLastError(p, x, s, ...) ExitOnInvalidHandleWithLastErrorSource(DUTIL_SOURCE_QUEUTIL, p, x, s, __VA_ARGS__) | ||
17 | #define QueExitOnWin32Error(e, x, s, ...) ExitOnWin32ErrorSource(DUTIL_SOURCE_QUEUTIL, e, x, s, __VA_ARGS__) | ||
18 | #define QueExitOnGdipFailure(g, x, s, ...) ExitOnGdipFailureSource(DUTIL_SOURCE_QUEUTIL, g, x, s, __VA_ARGS__) | ||
19 | |||
20 | |||
21 | struct QUEUTIL_QUEUE_ITEM | ||
22 | { | ||
23 | QUEUTIL_QUEUE_ITEM* pNext; | ||
24 | void* pvValue; | ||
25 | }; | ||
26 | |||
27 | struct QUEUTIL_QUEUE_STRUCT | ||
28 | { | ||
29 | QUEUTIL_QUEUE_ITEM* pFirst; | ||
30 | QUEUTIL_QUEUE_ITEM* pLast; | ||
31 | }; | ||
32 | |||
33 | const int QUEUTIL_QUEUE_HANDLE_BYTES = sizeof(QUEUTIL_QUEUE_STRUCT); | ||
34 | |||
35 | extern "C" HRESULT DAPI QueCreate( | ||
36 | __out_bcount(QUEUTIL_QUEUE_HANDLE_BYTES) QUEUTIL_QUEUE_HANDLE* phQueue | ||
37 | ) | ||
38 | { | ||
39 | HRESULT hr = S_OK; | ||
40 | |||
41 | QueExitOnNull(phQueue, hr, E_INVALIDARG, "Handle not specified while creating queue."); | ||
42 | |||
43 | *phQueue = reinterpret_cast<QUEUTIL_QUEUE_HANDLE>(MemAlloc(QUEUTIL_QUEUE_HANDLE_BYTES, TRUE)); | ||
44 | QueExitOnNull(*phQueue, hr, E_OUTOFMEMORY, "Failed to allocate queue object."); | ||
45 | |||
46 | LExit: | ||
47 | return hr; | ||
48 | } | ||
49 | |||
50 | extern "C" HRESULT DAPI QueEnqueue( | ||
51 | __in_bcount(QUEUTIL_QUEUE_HANDLE_BYTES) QUEUTIL_QUEUE_HANDLE hQueue, | ||
52 | __in void* pvValue | ||
53 | ) | ||
54 | { | ||
55 | HRESULT hr = S_OK; | ||
56 | QUEUTIL_QUEUE_ITEM* pItem = NULL; | ||
57 | QUEUTIL_QUEUE_STRUCT* pQueue = reinterpret_cast<QUEUTIL_QUEUE_STRUCT*>(hQueue); | ||
58 | |||
59 | QueExitOnNull(pQueue, hr, E_INVALIDARG, "Handle not specified while enqueing value."); | ||
60 | |||
61 | pItem = reinterpret_cast<QUEUTIL_QUEUE_ITEM*>(MemAlloc(sizeof(QUEUTIL_QUEUE_ITEM), TRUE)); | ||
62 | QueExitOnNull(pItem, hr, E_OUTOFMEMORY, "Failed to allocate queue item."); | ||
63 | |||
64 | pItem->pvValue = pvValue; | ||
65 | |||
66 | if (!pQueue->pLast) | ||
67 | { | ||
68 | pQueue->pFirst = pItem; | ||
69 | } | ||
70 | else | ||
71 | { | ||
72 | pQueue->pLast->pNext = pItem; | ||
73 | } | ||
74 | |||
75 | pQueue->pLast = pItem; | ||
76 | |||
77 | pItem = NULL; | ||
78 | |||
79 | LExit: | ||
80 | ReleaseMem(pItem); | ||
81 | |||
82 | return hr; | ||
83 | } | ||
84 | |||
85 | extern "C" HRESULT DAPI QueDequeue( | ||
86 | __in_bcount(QUEUTIL_QUEUE_HANDLE_BYTES) QUEUTIL_QUEUE_HANDLE hQueue, | ||
87 | __out void** ppvValue | ||
88 | ) | ||
89 | { | ||
90 | HRESULT hr = S_OK; | ||
91 | QUEUTIL_QUEUE_ITEM* pItem = NULL; | ||
92 | QUEUTIL_QUEUE_STRUCT* pQueue = reinterpret_cast<QUEUTIL_QUEUE_STRUCT*>(hQueue); | ||
93 | |||
94 | QueExitOnNull(pQueue, hr, E_INVALIDARG, "Handle not specified while dequeing value."); | ||
95 | |||
96 | if (!pQueue->pFirst) | ||
97 | { | ||
98 | *ppvValue = NULL; | ||
99 | ExitFunction1(hr = E_NOMOREITEMS); | ||
100 | } | ||
101 | |||
102 | pItem = pQueue->pFirst; | ||
103 | |||
104 | if (!pItem->pNext) | ||
105 | { | ||
106 | pQueue->pFirst = NULL; | ||
107 | pQueue->pLast = NULL; | ||
108 | } | ||
109 | else | ||
110 | { | ||
111 | pQueue->pFirst = pItem->pNext; | ||
112 | } | ||
113 | |||
114 | *ppvValue = pItem->pvValue; | ||
115 | |||
116 | LExit: | ||
117 | ReleaseMem(pItem); | ||
118 | |||
119 | return hr; | ||
120 | } | ||
121 | |||
122 | extern "C" void DAPI QueDestroy( | ||
123 | __in_bcount(QUEUTIL_QUEUE_HANDLE_BYTES) QUEUTIL_QUEUE_HANDLE hQueue, | ||
124 | __in_opt PFNQUEUTIL_QUEUE_RELEASE_VALUE pfnReleaseValue, | ||
125 | __in_opt void* pvContext | ||
126 | ) | ||
127 | { | ||
128 | HRESULT hr = S_OK; | ||
129 | void* pvValue = NULL; | ||
130 | |||
131 | hr = hQueue ? QueDequeue(hQueue, &pvValue) : E_NOMOREITEMS; | ||
132 | |||
133 | while (SUCCEEDED(hr)) | ||
134 | { | ||
135 | if (pfnReleaseValue) | ||
136 | { | ||
137 | pfnReleaseValue(pvValue, pvContext); | ||
138 | } | ||
139 | |||
140 | hr = QueDequeue(hQueue, &pvValue); | ||
141 | } | ||
142 | |||
143 | ReleaseMem(hQueue); | ||
144 | } | ||
diff --git a/src/test/burn/WixToolsetTest.BurnE2E/ElevationTests.cs b/src/test/burn/WixToolsetTest.BurnE2E/ElevationTests.cs index 8f141e5d..f040905d 100644 --- a/src/test/burn/WixToolsetTest.BurnE2E/ElevationTests.cs +++ b/src/test/burn/WixToolsetTest.BurnE2E/ElevationTests.cs | |||
@@ -13,7 +13,7 @@ namespace WixToolsetTest.BurnE2E | |||
13 | /// This test calls Elevate after Detect, and then calls Plan in OnElevateBegin. | 13 | /// This test calls Elevate after Detect, and then calls Plan in OnElevateBegin. |
14 | /// After calling Plan, it pumps some messages to simulate UI like the UAC callback. | 14 | /// After calling Plan, it pumps some messages to simulate UI like the UAC callback. |
15 | /// </summary> | 15 | /// </summary> |
16 | [RuntimeFact(Skip = "https://github.com/wixtoolset/issues/issues/6349")] // CAUTION: this test currently hangs because the Plan request gets dropped. | 16 | [RuntimeFact] |
17 | public void CanExplicitlyElevateAndPlanFromOnElevateBegin() | 17 | public void CanExplicitlyElevateAndPlanFromOnElevateBegin() |
18 | { | 18 | { |
19 | var packageA = this.CreatePackageInstaller("PackageA"); | 19 | var packageA = this.CreatePackageInstaller("PackageA"); |