From c485da28162e04e77cd3ac4f89fd7b37465549fb Mon Sep 17 00:00:00 2001 From: Andrey Nekrasov Date: Tue, 10 May 2022 19:13:56 +0300 Subject: [PATCH] [Settings]Don't launch if explorer is running elevated (#18124) --- src/common/utils/elevation.h | 31 ++++++- .../fancyzones/FancyZonesLib/WindowUtils.cpp | 28 +----- src/runner/Resources.resx | 3 + src/runner/settings_window.cpp | 86 ++++--------------- 4 files changed, 54 insertions(+), 94 deletions(-) diff --git a/src/common/utils/elevation.h b/src/common/utils/elevation.h index 0f443a078a..c8aa88995a 100644 --- a/src/common/utils/elevation.h +++ b/src/common/utils/elevation.h @@ -83,7 +83,7 @@ namespace inline bool GetDesktopAutomationObject(REFIID riid, void** ppv) { CComPtr spsv; - + // Desktop may not be available on startup auto attempts = 5; for (auto i = 1; i <= attempts; i++) @@ -492,4 +492,31 @@ inline bool check_user_is_admin() freeMemory(pSID, pGroupInfo); return false; -} \ No newline at end of file +} + +inline bool is_process_of_window_elevated(HWND window) +{ + DWORD pid = 0; + GetWindowThreadProcessId(window, &pid); + if (!pid) + { + return false; + } + + wil::unique_handle hProcess{ OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, + FALSE, + pid) }; + + wil::unique_handle token; + + if (OpenProcessToken(hProcess.get(), TOKEN_QUERY, &token)) + { + TOKEN_ELEVATION elevation; + DWORD size; + if (GetTokenInformation(token.get(), TokenElevation, &elevation, sizeof(elevation), &size)) + { + return elevation.TokenIsElevated != 0; + } + } + return false; +} diff --git a/src/modules/fancyzones/FancyZonesLib/WindowUtils.cpp b/src/modules/fancyzones/FancyZonesLib/WindowUtils.cpp index d9fa6e00e3..0c4345c9e8 100644 --- a/src/modules/fancyzones/FancyZonesLib/WindowUtils.cpp +++ b/src/modules/fancyzones/FancyZonesLib/WindowUtils.cpp @@ -3,10 +3,11 @@ #include #include +#include +#include #include #include #include -#include #include #include @@ -245,30 +246,7 @@ bool FancyZonesWindowUtils::IsCandidateForZoning(HWND window) bool FancyZonesWindowUtils::IsProcessOfWindowElevated(HWND window) { - DWORD pid = 0; - GetWindowThreadProcessId(window, &pid); - if (!pid) - { - return false; - } - - wil::unique_handle hProcess{ OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, - FALSE, - pid) }; - - wil::unique_handle token; - bool elevated = false; - - if (OpenProcessToken(hProcess.get(), TOKEN_QUERY, &token)) - { - TOKEN_ELEVATION elevation; - DWORD size; - if (GetTokenInformation(token.get(), TokenElevation, &elevation, sizeof(elevation), &size)) - { - return elevation.TokenIsElevated != 0; - } - } - return false; + return is_process_of_window_elevated(window); } bool FancyZonesWindowUtils::IsExcludedByUser(const std::wstring& processPath) noexcept diff --git a/src/runner/Resources.resx b/src/runner/Resources.resx index 2f5198b2d1..9ac1b8da2f 100644 --- a/src/runner/Resources.resx +++ b/src/runner/Resources.resx @@ -122,4 +122,7 @@ Bug report .zip file has been created on your Desktop. + + Cannot start PowerToys.Settings process non-elevated, because explorer.exe process is elevated. Consider enabling UAC. + diff --git a/src/runner/settings_window.cpp b/src/runner/settings_window.cpp index 5d84d6847d..678a88fdbd 100644 --- a/src/runner/settings_window.cpp +++ b/src/runner/settings_window.cpp @@ -11,6 +11,7 @@ #include "restart_elevated.h" #include "UpdateUtils.h" #include "centralized_kb_hook.h" +#include "Generated Files/resource.h" #include #include @@ -20,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -197,67 +199,6 @@ void receive_json_send_to_main_thread(const std::wstring& msg) dispatch_run_on_main_ui_thread(dispatch_received_json_callback, copy); } -// Try to run the Settings process with non-elevated privileges. -BOOL run_settings_non_elevated(LPCWSTR executable_path, LPWSTR executable_args, PROCESS_INFORMATION* process_info) -{ - HWND hwnd = GetShellWindow(); - if (!hwnd) - { - return false; - } - - DWORD pid; - GetWindowThreadProcessId(hwnd, &pid); - - winrt::handle process{ OpenProcess(PROCESS_CREATE_PROCESS, FALSE, pid) }; - if (!process) - { - return false; - } - - SIZE_T size = 0; - InitializeProcThreadAttributeList(nullptr, 1, 0, &size); - auto pproc_buffer = std::unique_ptr{ new (std::nothrow) char[size] }; - auto pptal = reinterpret_cast(pproc_buffer.get()); - if (!pptal) - { - return false; - } - - if (!InitializeProcThreadAttributeList(pptal, 1, 0, &size)) - { - return false; - } - - if (!UpdateProcThreadAttribute(pptal, - 0, - PROC_THREAD_ATTRIBUTE_PARENT_PROCESS, - &process, - sizeof(process), - nullptr, - nullptr)) - { - return false; - } - - STARTUPINFOEX siex = { 0 }; - siex.lpAttributeList = pptal; - siex.StartupInfo.cb = sizeof(siex); - - BOOL process_created = CreateProcessW(executable_path, - executable_args, - nullptr, - nullptr, - FALSE, - EXTENDED_STARTUPINFO_PRESENT, - nullptr, - nullptr, - &siex.StartupInfo, - process_info); - g_isLaunchInProgress = false; - return process_created; -} - DWORD g_settings_process_id = 0; void run_settings_window(bool show_oobe_window, bool show_scoobe_window, std::optional settings_window) @@ -355,13 +296,24 @@ void run_settings_window(bool show_oobe_window, bool show_scoobe_window, std::op if (is_process_elevated()) { - auto res = RunNonElevatedFailsafe(executable_path, executable_args, get_module_folderpath()); - process_created = res.has_value(); - if (process_created) + const bool explorer_is_elevated = is_process_of_window_elevated(GetShellWindow()); + if (explorer_is_elevated) { - process_info.dwProcessId = res->processID; - process_info.hProcess = res->processHandle.release(); - g_isLaunchInProgress = false; + MessageBoxW(nullptr, + GET_RESOURCE_STRING(IDS_CANNOT_LAUNCH_SETTINGS_NONELEVATED).c_str(), + L"PowerToys", + MB_OK | MB_ICONERROR); + } + else + { + auto res = RunNonElevatedFailsafe(executable_path, executable_args, get_module_folderpath()); + process_created = res.has_value(); + if (process_created) + { + process_info.dwProcessId = res->processID; + process_info.hProcess = res->processHandle.release(); + g_isLaunchInProgress = false; + } } }