[Settings]Don't launch if explorer is running elevated (#18124)

This commit is contained in:
Andrey Nekrasov 2022-05-10 19:13:56 +03:00 committed by GitHub
parent 741457ffa5
commit c485da2816
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 54 additions and 94 deletions

View File

@ -83,7 +83,7 @@ namespace
inline bool GetDesktopAutomationObject(REFIID riid, void** ppv)
{
CComPtr<IShellView> 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;
}
}
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;
}

View File

@ -3,10 +3,11 @@
#include <common/display/dpi_aware.h>
#include <common/logger/logger.h>
#include <common/utils/elevation.h>
#include <common/utils/excluded_apps.h>
#include <common/utils/process_path.h>
#include <common/utils/winapi_error.h>
#include <common/utils/window.h>
#include <common/utils/excluded_apps.h>
#include <FancyZonesLib/FancyZonesWindowProperties.h>
#include <FancyZonesLib/Settings.h>
@ -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

View File

@ -122,4 +122,7 @@
<data name="BUGREPORT_SUCCESS" xml:space="preserve">
<value>Bug report .zip file has been created on your Desktop.</value>
</data>
<data name="CANNOT_LAUNCH_SETTINGS_NONELEVATED" xml:space="preserve">
<value>Cannot start PowerToys.Settings process non-elevated, because explorer.exe process is elevated. Consider enabling UAC.</value>
</data>
</root>

View File

@ -11,6 +11,7 @@
#include "restart_elevated.h"
#include "UpdateUtils.h"
#include "centralized_kb_hook.h"
#include "Generated Files/resource.h"
#include <common/utils/json.h>
#include <common/SettingsAPI/settings_helpers.cpp>
@ -20,6 +21,7 @@
#include <common/utils/elevation.h>
#include <common/utils/process_path.h>
#include <common/utils/timeutil.h>
#include <common/utils/resources.h>
#include <common/utils/winapi_error.h>
#include <common/updating/updateState.h>
#include <common/themes/windows_colors.h>
@ -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<char[]>{ new (std::nothrow) char[size] };
auto pptal = reinterpret_cast<PPROC_THREAD_ATTRIBUTE_LIST>(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<std::wstring> 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;
}
}
}