Skip to content
Open
Show file tree
Hide file tree
Changes from all 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>Administrator protection is enabled, and your distributions might be registered with a different account.
Sign in with the account that registered them, and try again. To learn more, go to aka.ms/apdevguide.</value>
<comment>{Locked="Administrator 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)();
}

} // anonymous namespace

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