mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-12-16 11:48:06 +01:00
"Always run as administrator" and "Restart as ..." only for administrator account (#1318)
This commit is contained in:
committed by
GitHub
parent
e177c5c94c
commit
607a297c4a
@@ -6,6 +6,8 @@
|
|||||||
#include <sddl.h>
|
#include <sddl.h>
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
|
|
||||||
|
#pragma comment(lib, "advapi32.lib")
|
||||||
|
|
||||||
namespace localized_strings
|
namespace localized_strings
|
||||||
{
|
{
|
||||||
const wchar_t LAST_ERROR_FORMAT_STRING[] = L"%s failed with error %d: %s";
|
const wchar_t LAST_ERROR_FORMAT_STRING[] = L"%s failed with error %d: %s";
|
||||||
@@ -539,3 +541,72 @@ std::wstring get_module_folderpath(HMODULE mod)
|
|||||||
PathRemoveFileSpecW(buffer);
|
PathRemoveFileSpecW(buffer);
|
||||||
return { buffer, (UINT)lstrlenW(buffer) };
|
return { buffer, (UINT)lstrlenW(buffer) };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// The function returns true in case of error since we want to return false
|
||||||
|
// only in case of a positive verification that the user is not an admin.
|
||||||
|
bool check_user_is_admin()
|
||||||
|
{
|
||||||
|
auto freeMemory = [](PSID pSID, PTOKEN_GROUPS pGroupInfo) {
|
||||||
|
if (pSID)
|
||||||
|
{
|
||||||
|
FreeSid(pSID);
|
||||||
|
}
|
||||||
|
if (pGroupInfo)
|
||||||
|
{
|
||||||
|
GlobalFree(pGroupInfo);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
HANDLE hToken;
|
||||||
|
DWORD dwSize = 0, dwResult = 0;
|
||||||
|
PTOKEN_GROUPS pGroupInfo;
|
||||||
|
SID_IDENTIFIER_AUTHORITY SIDAuth = SECURITY_NT_AUTHORITY;
|
||||||
|
PSID pSID = NULL;
|
||||||
|
|
||||||
|
// Open a handle to the access token for the calling process.
|
||||||
|
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Call GetTokenInformation to get the buffer size.
|
||||||
|
if (!GetTokenInformation(hToken, TokenGroups, NULL, dwSize, &dwSize))
|
||||||
|
{
|
||||||
|
dwResult = GetLastError();
|
||||||
|
if (dwResult != ERROR_INSUFFICIENT_BUFFER)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Allocate the buffer.
|
||||||
|
pGroupInfo = (PTOKEN_GROUPS)GlobalAlloc(GPTR, dwSize);
|
||||||
|
|
||||||
|
// Call GetTokenInformation again to get the group information.
|
||||||
|
if (!GetTokenInformation(hToken, TokenGroups, pGroupInfo, dwSize, &dwSize))
|
||||||
|
{
|
||||||
|
freeMemory(pSID, pGroupInfo);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a SID for the BUILTIN\Administrators group.
|
||||||
|
if (!AllocateAndInitializeSid(&SIDAuth, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &pSID))
|
||||||
|
{
|
||||||
|
freeMemory(pSID, pGroupInfo);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Loop through the group SIDs looking for the administrator SID.
|
||||||
|
for (DWORD i = 0; i < pGroupInfo->GroupCount; ++i)
|
||||||
|
{
|
||||||
|
if (EqualSid(pSID, pGroupInfo->Groups[i].Sid))
|
||||||
|
{
|
||||||
|
freeMemory(pSID, pGroupInfo);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
freeMemory(pSID, pGroupInfo);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|||||||
@@ -71,6 +71,9 @@ bool run_non_elevated(const std::wstring& file, const std::wstring& params);
|
|||||||
// Run command with the same elevation, returns true if succedded
|
// Run command with the same elevation, returns true if succedded
|
||||||
bool run_same_elevation(const std::wstring& file, const std::wstring& params);
|
bool run_same_elevation(const std::wstring& file, const std::wstring& params);
|
||||||
|
|
||||||
|
// Returns true if the current process is running from administrator account
|
||||||
|
bool check_user_is_admin();
|
||||||
|
|
||||||
// Get the executable path or module name for modern apps
|
// Get the executable path or module name for modern apps
|
||||||
std::wstring get_process_path(DWORD pid) noexcept;
|
std::wstring get_process_path(DWORD pid) noexcept;
|
||||||
// Get the executable path or module name for modern apps
|
// Get the executable path or module name for modern apps
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ json::JsonObject GeneralSettings::to_json()
|
|||||||
|
|
||||||
result.SetNamedValue(L"is_elevated", json::value(isElevated));
|
result.SetNamedValue(L"is_elevated", json::value(isElevated));
|
||||||
result.SetNamedValue(L"run_elevated", json::value(isRunElevated));
|
result.SetNamedValue(L"run_elevated", json::value(isRunElevated));
|
||||||
|
result.SetNamedValue(L"is_admin", json::value(isAdmin));
|
||||||
result.SetNamedValue(L"theme", json::value(theme));
|
result.SetNamedValue(L"theme", json::value(theme));
|
||||||
result.SetNamedValue(L"system_theme", json::value(systemTheme));
|
result.SetNamedValue(L"system_theme", json::value(systemTheme));
|
||||||
result.SetNamedValue(L"powertoys_version", json::value(powerToysVersion));
|
result.SetNamedValue(L"powertoys_version", json::value(powerToysVersion));
|
||||||
@@ -65,6 +66,7 @@ GeneralSettings get_settings()
|
|||||||
.isPackaged = winstore::running_as_packaged(),
|
.isPackaged = winstore::running_as_packaged(),
|
||||||
.isElevated = is_process_elevated(),
|
.isElevated = is_process_elevated(),
|
||||||
.isRunElevated = run_as_elevated,
|
.isRunElevated = run_as_elevated,
|
||||||
|
.isAdmin = check_user_is_admin(),
|
||||||
.theme = settings_theme,
|
.theme = settings_theme,
|
||||||
.systemTheme = WindowsColors::is_dark_mode() ? L"dark" : L"light",
|
.systemTheme = WindowsColors::is_dark_mode() ? L"dark" : L"light",
|
||||||
.powerToysVersion = get_product_version(),
|
.powerToysVersion = get_product_version(),
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ struct GeneralSettings
|
|||||||
std::unordered_map<std::wstring, bool> isModulesEnabledMap;
|
std::unordered_map<std::wstring, bool> isModulesEnabledMap;
|
||||||
bool isElevated;
|
bool isElevated;
|
||||||
bool isRunElevated;
|
bool isRunElevated;
|
||||||
|
bool isAdmin;
|
||||||
std::wstring theme;
|
std::wstring theme;
|
||||||
std::wstring systemTheme;
|
std::wstring systemTheme;
|
||||||
std::wstring powerToysVersion;
|
std::wstring powerToysVersion;
|
||||||
|
|||||||
@@ -133,12 +133,15 @@ export class GeneralSettings extends React.Component <any, any> {
|
|||||||
ref={(input) => {this.startup_reference=input;}}
|
ref={(input) => {this.startup_reference=input;}}
|
||||||
/>
|
/>
|
||||||
</Stack>
|
</Stack>
|
||||||
<BoolToggleSettingsControl
|
{this.state.settings.general.is_admin &&
|
||||||
|
(<BoolToggleSettingsControl
|
||||||
setting={{display_name: 'Always run as administrator', value: this.state.settings.general.run_elevated}}
|
setting={{display_name: 'Always run as administrator', value: this.state.settings.general.run_elevated}}
|
||||||
on_change={this.parent_on_change}
|
on_change={this.parent_on_change}
|
||||||
ref={(input) => {this.elevated_reference=input;}}
|
ref={(input) => {this.elevated_reference=input;}}
|
||||||
/>
|
/>)
|
||||||
<CustomActionSettingsControl
|
}
|
||||||
|
{this.state.settings.general.is_admin &&
|
||||||
|
(<CustomActionSettingsControl
|
||||||
setting={{
|
setting={{
|
||||||
display_name: '',
|
display_name: '',
|
||||||
value: this.state.settings.general.is_elevated ?
|
value: this.state.settings.general.is_elevated ?
|
||||||
@@ -160,7 +163,8 @@ export class GeneralSettings extends React.Component <any, any> {
|
|||||||
}));
|
}));
|
||||||
}}
|
}}
|
||||||
ref={(input) => {this.restart_reference=input;}}
|
ref={(input) => {this.restart_reference=input;}}
|
||||||
/>
|
/>)
|
||||||
|
}
|
||||||
<ChoiceGroupSettingsControl
|
<ChoiceGroupSettingsControl
|
||||||
setting={{display_name: 'Chose Settings color',
|
setting={{display_name: 'Chose Settings color',
|
||||||
value: this.state.settings.general.theme,
|
value: this.state.settings.general.theme,
|
||||||
|
|||||||
2
src/settings/settings-html/dist/bundle.js
vendored
2
src/settings/settings-html/dist/bundle.js
vendored
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user