diff --git a/src/cascadia/TerminalApp/AppLogic.cpp b/src/cascadia/TerminalApp/AppLogic.cpp index b1b94bc5b..26d7cdb8a 100644 --- a/src/cascadia/TerminalApp/AppLogic.cpp +++ b/src/cascadia/TerminalApp/AppLogic.cpp @@ -10,6 +10,7 @@ #include #include +#include using namespace winrt::Windows::ApplicationModel; using namespace winrt::Windows::ApplicationModel::DataTransfer; @@ -131,17 +132,28 @@ static Documents::Run _BuildErrorRun(const winrt::hstring& text, const ResourceD // Method Description: // - Returns whether the user is either a member of the Administrators group or // is currently elevated. +// - This will return **FALSE** if the user has UAC disabled entirely, because +// there's no separation of power between the user and an admin in that case. // Return Value: // - true if the user is an administrator static bool _isUserAdmin() noexcept try { - SID_IDENTIFIER_AUTHORITY ntAuthority{ SECURITY_NT_AUTHORITY }; - wil::unique_sid adminGroupSid{}; - THROW_IF_WIN32_BOOL_FALSE(AllocateAndInitializeSid(&ntAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &adminGroupSid)); - BOOL b; - THROW_IF_WIN32_BOOL_FALSE(CheckTokenMembership(NULL, adminGroupSid.get(), &b)); - return !!b; + wil::unique_handle processToken{ GetCurrentProcessToken() }; + const auto elevationType = wil::get_token_information(processToken.get()); + const auto elevationState = wil::get_token_information(processToken.get()); + if (elevationType == TokenElevationTypeDefault && elevationState.TokenIsElevated) + { + // In this case, the user has UAC entirely disabled. This is sort of + // weird, we treat this like the user isn't an admin at all. There's no + // separation of powers, so the things we normally want to gate on + // "having special powers" doesn't apply. + // + // See GH#7754, GH#11096 + return false; + } + + return wil::test_token_membership(nullptr, SECURITY_NT_AUTHORITY, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS); } catch (...) {