diff --git a/dev/AppLifecycle/AppInstance.cpp b/dev/AppLifecycle/AppInstance.cpp index f99409acc9..7c4d3cbfe8 100644 --- a/dev/AppLifecycle/AppInstance.cpp +++ b/dev/AppLifecycle/AppInstance.cpp @@ -15,6 +15,11 @@ #include "PushNotificationManager.h" #include "AppNotificationManager.h" +#include + +// 63876312: Prevent AppInstance::GetInstances from registering an invalid process handle. +#define WINAPPSDK_CHANGEID_63876312 63876312 + using namespace winrt; using namespace winrt::Windows::Foundation; using namespace winrt::Windows::Foundation::Collections; @@ -96,7 +101,13 @@ namespace winrt::Microsoft::Windows::AppLifecycle::implementation return { kind, data }; } - AppInstance::AppInstance(uint32_t processId) + AppInstance::AppInstance() : + AppInstance(GetCurrentProcessId(), {}) + { + } + + AppInstance::AppInstance(uint32_t processId, wil::unique_handle processHandle) : + m_instanceHandle(std::move(processHandle)) { m_processId = processId; m_isCurrent = (GetCurrentProcessId() == processId); @@ -146,7 +157,15 @@ namespace winrt::Microsoft::Windows::AppLifecycle::implementation } else { - m_instanceHandle.reset(OpenProcess(SYNCHRONIZE, FALSE, processId)); + if (!m_instanceHandle) + { + m_instanceHandle.reset(OpenProcess(SYNCHRONIZE, FALSE, processId)); + } + + if (WinAppSdk::Containment::IsChangeEnabled()) + { + THROW_HR_IF(E_INVALIDARG, !m_instanceHandle); + } // Create a monitor thread to handle cleaning up this instance if the backing process terminates. auto onInstanceTerminated = [](_In_ void* context, _In_ BOOLEAN /*reason*/) -> void @@ -277,7 +296,7 @@ namespace winrt::Microsoft::Windows::AppLifecycle::implementation { auto initInstance = [] { - s_current = winrt::make_self(GetCurrentProcessId()); + s_current = winrt::make_self(); }; wil::init_once(s_initOnce, initInstance); @@ -290,6 +309,9 @@ namespace winrt::Microsoft::Windows::AppLifecycle::implementation // Force the singleton init. GetCurrent(); + const bool processHandleFixEnabled{ + WinAppSdk::Containment::IsChangeEnabled() }; + IVector instances{ winrt::single_threaded_vector() }; // Grab the list of processes while under the lock, and then drop it since we'll be calling out to other code. @@ -318,10 +340,18 @@ namespace winrt::Microsoft::Windows::AppLifecycle::implementation } else { - wil::unique_handle process(::OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, pid)); + const DWORD desiredAccess{ + processHandleFixEnabled ? static_cast(SYNCHRONIZE) : + static_cast(PROCESS_QUERY_LIMITED_INFORMATION) }; + wil::unique_handle process(::OpenProcess(desiredAccess, FALSE, pid)); if (process != nullptr) { - instances.Append(make(pid)); + wil::unique_handle instanceHandle; + if (processHandleFixEnabled) + { + instanceHandle = std::move(process); + } + instances.Append(make(pid, std::move(instanceHandle))); } else { diff --git a/dev/AppLifecycle/AppInstance.h b/dev/AppLifecycle/AppInstance.h index f1c7771a8a..beb02af484 100644 --- a/dev/AppLifecycle/AppInstance.h +++ b/dev/AppLifecycle/AppInstance.h @@ -18,7 +18,8 @@ namespace winrt::Microsoft::Windows::AppLifecycle::implementation struct AppInstance : AppInstanceT { // No interface public methods. - AppInstance(uint32_t processId); + AppInstance(); + AppInstance(uint32_t processId, wil::unique_handle processHandle); ~AppInstance() { if (m_terminationWatcherWaitHandle)