Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions localization/strings/en-US/Resources.resw
Original file line number Diff line number Diff line change
Expand Up @@ -744,6 +744,11 @@ For information please visit https://aka.ms/wslinstall</value>
<data name="MessageAdministratorAccessRequiredForDebugShell" xml:space="preserve">
<value>Running the debug shell requires running wsl.exe as Administrator.</value>
</data>
<data name="MessageAdminProtectionEnabled" xml:space="preserve">
<value>Windows Admin Protection is enabled and your distributions may be registered under a different account.
For more information on Admin Protection, please visit https://aka.ms/apdevguide</value>
<comment>{Locked="Windows Admin Protection"}{Locked="Admin Protection"}{Locked="https://aka.ms/apdevguide"}Command line arguments, file names and string inserts should not be translated</comment>
</data>
<data name="MessageInstallProcessFailed" xml:space="preserve">
<value>The installation process for distribution '{}' failed with exit code: {}.</value>
<comment>{FixedPlaceholder="{}"}Command line arguments, file names and string inserts should not be translated</comment>
Expand Down
57 changes: 54 additions & 3 deletions src/windows/common/wslutil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -522,10 +522,40 @@ wsl::windows::common::wslutil::GetDefaultVersion(void)
return version;
}

namespace {

// Returns true if the current process is running as a shadow admin under
// Windows Admin Protection. Caches the DLL lookup on first call.
bool IsAdminProtectionEnabled()
{
const auto token = wil::open_current_access_token();
if (!wsl::windows::common::security::IsTokenElevated(token.get()))
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@OneBlue - Perhaps we should return this error in both cases? (even non-admin)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would only apply in the case where the user is elevated right ? If the other was not found and the user was non-elevated, then we know for sure that it's a user error, so probably best not to display this imo

{
return false;
}

using ShadowAdminEnabledFn = BOOL(WINAPI)();
static std::optional<LxssDynamicFunction<ShadowAdminEnabledFn>> s_fn;
static std::once_flag s_initFlag;

std::call_once(s_initFlag, []() {
LxssDynamicFunction<ShadowAdminEnabledFn> fn{DynamicFunctionErrorLogs::None};
if (SUCCEEDED(fn.load(L"SecurityHealthUdk.dll", "Shield_LUAIsShadowAdminEnabled")))
{
s_fn.emplace(std::move(fn));
}
});

return s_fn.has_value() && (*s_fn)();
}
Comment thread
benhillis marked this conversation as resolved.

} // anonymous namespace

Comment thread
benhillis marked this conversation as resolved.
std::wstring wsl::windows::common::wslutil::GetErrorString(HRESULT result)
{
ULONG buildNumber = 0;
std::wstring kbUrl;
std::wstring errorString;

switch (result)
{
Expand All @@ -545,14 +575,16 @@ std::wstring wsl::windows::common::wslutil::GetErrorString(HRESULT result)
return Localization::MessageHigherIntegrity();

case WSL_E_DEFAULT_DISTRO_NOT_FOUND:
return Localization::MessageNoDefaultDistro();
errorString = Localization::MessageNoDefaultDistro();
break;

case HRESULT_FROM_WIN32(WSAECONNABORTED):
case HRESULT_FROM_WIN32(ERROR_SHUTDOWN_IN_PROGRESS):
return Localization::MessageInstanceTerminated();

case WSL_E_DISTRO_NOT_FOUND:
return Localization::MessageDistroNotFound();
errorString = Localization::MessageDistroNotFound();
break;

case HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS):
return Localization::MessageDistroNameAlreadyExists();
Expand Down Expand Up @@ -695,7 +727,26 @@ std::wstring wsl::windows::common::wslutil::GetErrorString(HRESULT result)
}
}

return GetSystemErrorString(result);
if (errorString.empty())
{
return GetSystemErrorString(result);
}

// If Admin Protection is enabled, prepend an informational message for
// errors that may be caused by the shadow admin's separate registry hive.
try
{
if (IsAdminProtectionEnabled())
{
auto message = Localization::MessageAdminProtectionEnabled();
message += L"\n\n";
message += errorString;
return message;
}
}
CATCH_LOG()

return errorString;
}

std::optional<std::pair<std::wstring, GitHubReleaseAsset>> wsl::windows::common::wslutil::GetGitHubAssetFromRelease(const GitHubRelease& Release)
Expand Down
Loading