From a47bb0d0dc8670d91cc25a1fd8eb16f39e0093d5 Mon Sep 17 00:00:00 2001 From: "Dustin L. Howett" Date: Tue, 5 Jul 2022 15:47:20 -0500 Subject: [PATCH] Remove the fallback to wsl.exe when HKCU\...\Lxss doesn't exist (#13436) The main result of this fallback is that we attempt to launch wsl.exe when the user hasn't installed or interacted with WSL. On our test machines, that results in the creation of a wsl.exe process that tells us precisely nothing; on WDAC managed machines it results in an Event Log entry about spawning another (possibly blocked) process. The registry is more reliable, and if the "API" it provides changes we can just rev terminal. Closes #11716 (cherry picked from commit f025c53dbab37a5a55ac23a51aba03e36467315f) Service-Card-Id: 83892843 Service-Version: 1.14 --- .../WslDistroGenerator.cpp | 109 +----------------- 1 file changed, 3 insertions(+), 106 deletions(-) diff --git a/src/cascadia/TerminalSettingsModel/WslDistroGenerator.cpp b/src/cascadia/TerminalSettingsModel/WslDistroGenerator.cpp index a40a7f853be..840835cf1f3 100644 --- a/src/cascadia/TerminalSettingsModel/WslDistroGenerator.cpp +++ b/src/cascadia/TerminalSettingsModel/WslDistroGenerator.cpp @@ -7,8 +7,6 @@ #include "LegacyProfileGeneratorNamespaces.h" #include "../../inc/DefaultSettings.h" -#include -#include #include "DynamicProfileUtils.h" static constexpr std::wstring_view WslHomeDirectory{ L"~" }; @@ -68,105 +66,6 @@ static winrt::com_ptr makeProfile(const std::wstring& d return WSLDistro; } -// Method Description: -// - Enumerates all the installed WSL distros to create profiles for them. -// Arguments: -// - -// Return Value: -// - a vector with all distros for all the installed WSL distros -static void legacyGenerate(std::vector>& profiles) -{ - wil::unique_handle readPipe; - wil::unique_handle writePipe; - SECURITY_ATTRIBUTES sa{ sizeof(sa), nullptr, true }; - THROW_IF_WIN32_BOOL_FALSE(CreatePipe(&readPipe, &writePipe, &sa, 0)); - STARTUPINFO si{ 0 }; - si.cb = sizeof(si); - si.dwFlags = STARTF_USESTDHANDLES; - si.hStdOutput = writePipe.get(); - si.hStdError = writePipe.get(); - wil::unique_process_information pi; - wil::unique_cotaskmem_string systemPath; - THROW_IF_FAILED(wil::GetSystemDirectoryW(systemPath)); - std::wstring command(systemPath.get()); - command += L"\\wsl.exe --list"; - - THROW_IF_WIN32_BOOL_FALSE(CreateProcessW(nullptr, - const_cast(command.c_str()), - nullptr, - nullptr, - TRUE, - CREATE_NO_WINDOW, - nullptr, - nullptr, - &si, - &pi)); - switch (WaitForSingleObject(pi.hProcess, 2000)) - { - case WAIT_OBJECT_0: - break; - case WAIT_ABANDONED: - case WAIT_TIMEOUT: - return; - case WAIT_FAILED: - THROW_LAST_ERROR(); - default: - THROW_HR(ERROR_UNHANDLED_EXCEPTION); - } - DWORD exitCode; - if (!GetExitCodeProcess(pi.hProcess, &exitCode)) - { - THROW_HR(E_INVALIDARG); - } - else if (exitCode != 0) - { - return; - } - DWORD bytesAvailable; - THROW_IF_WIN32_BOOL_FALSE(PeekNamedPipe(readPipe.get(), nullptr, NULL, nullptr, &bytesAvailable, nullptr)); - // "The _open_osfhandle call transfers ownership of the Win32 file handle to the file descriptor." - // (https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/open-osfhandle?view=vs-2019) - // so, we detach_from_smart_pointer it -- but... - // "File descriptors passed into _fdopen are owned by the returned FILE * stream. - // If _fdopen is successful, do not call _close on the file descriptor. - // Calling fclose on the returned FILE * also closes the file descriptor." - // https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/fdopen-wfdopen?view=vs-2019 - auto stdioPipeHandle = _wfdopen(_open_osfhandle((intptr_t)wil::detach_from_smart_pointer(readPipe), _O_WTEXT | _O_RDONLY), L"r"); - auto closeFile = wil::scope_exit([&]() { fclose(stdioPipeHandle); }); - - std::wfstream pipe{ stdioPipeHandle }; - - std::wstring wline; - std::getline(pipe, wline); // remove the header from the output. - while (pipe.tellp() < bytesAvailable) - { - std::getline(pipe, wline); - std::wstringstream wlinestream(wline); - if (wlinestream) - { - std::wstring distName; - std::getline(wlinestream, distName, L'\r'); - - if (til::starts_with(distName, DockerDistributionPrefix)) - { - // Docker for Windows creates some utility distributions to handle Docker commands. - // Pursuant to GH#3556, because they are _not_ user-facing we want to hide them. - continue; - } - - const auto firstChar = distName.find_first_of(L"( "); - // Some localizations don't have a space between the name and "(Default)" - // https://github.com/microsoft/terminal/issues/1168#issuecomment-500187109 - if (firstChar < distName.size()) - { - distName.resize(firstChar); - } - - profiles.emplace_back(makeProfile(distName)); - } - } -} - // Function Description: // - Create a list of Profiles for each distro listed in names. // - Skips distros that are utility distros for docker (see GH#3556) @@ -310,9 +209,9 @@ static bool getWslNames(const wil::unique_hkey& wslRootKey, // Method Description: // - Generate a list of profiles for each on the installed WSL distros. This // will first try to read the installed distros from the registry. If that -// fails, we'll fall back to the legacy way of launching WSL.exe to read the -// distros from the commandline. Reading the registry is slightly more stable -// (see GH#7199, GH#9905), but it is certainly BODGY +// fails, we'll assume there are no WSL distributions installed. +// Reading the registry is slightly more stable (see GH#7199, GH#9905), +// but it is certainly BODGY // Arguments: // - // Return Value: @@ -333,6 +232,4 @@ void WslDistroGenerator::GenerateProfiles(std::vector