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/burn/engine/externalengine.cpp | |
| 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/burn/engine/externalengine.cpp')
| -rw-r--r-- | src/burn/engine/externalengine.cpp | 166 |
1 files changed, 115 insertions, 51 deletions
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 | } | ||
