Skip to content
Merged
7 changes: 4 additions & 3 deletions localization/strings/en-US/Resources.resw
Original file line number Diff line number Diff line change
Expand Up @@ -217,9 +217,6 @@ Install using 'wsl.exe {} <Distro>'.
To get a list of valid distributions, use 'wsl.exe --list --online'.</value>
<comment>{FixedPlaceholder="{}"}{Locked="--list "}{Locked="--online'"}Command line arguments, file names and string inserts should not be translated</comment>
</data>
<data name="MessageInstanceTerminated" xml:space="preserve">
<value>The Windows Subsystem for Linux instance has terminated.</value>
</data>
<data name="MessageInvalidCommandLine" xml:space="preserve">
<value>Invalid command line argument: {}
Please use '{} --help' to get a list of supported arguments.</value>
Expand Down Expand Up @@ -853,6 +850,10 @@ For information please visit https://aka.ms/wslinstall</value>
<value>Failed to create the swap disk in '{}': {}</value>
<comment>{FixedPlaceholder="{}"}Command line arguments, file names and string inserts should not be translated</comment>
</data>
<data name="MessageFailedToCreateDisk" xml:space="preserve">
<value>Failed to create disk '{}': {}</value>
<comment>{FixedPlaceholder="{}"}Command line arguments, file names and string inserts should not be translated</comment>
</data>
<data name="MessageNestedVirtualizationNotSupported" xml:space="preserve">
<value>Nested virtualization is not supported on this machine.</value>
</data>
Expand Down
12 changes: 8 additions & 4 deletions src/windows/common/WslCoreFilesystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,15 @@ void wsl::core::filesystem::CreateVhd(_In_ LPCWSTR target, _In_ ULONGLONG maximu
// N.B. This ensures that HcsGrantVmAccess is able to add the required ACL
// to the VHD because the operation is done while impersonating the user.
auto sd = windows::common::security::CreateSecurityDescriptor(userSid);

wil::unique_hfile vhd{};
THROW_IF_WIN32_ERROR_MSG(
::CreateVirtualDisk(&storageType, target, VIRTUAL_DISK_ACCESS_NONE, &sd, flags, 0, &createVhdParameters, nullptr, &vhd),
"Path: %ls",
target);
auto result = HRESULT_FROM_WIN32(
::CreateVirtualDisk(&storageType, target, VIRTUAL_DISK_ACCESS_NONE, &sd, flags, 0, &createVhdParameters, nullptr, &vhd));
if (FAILED(result))
{
THROW_HR_WITH_USER_ERROR(
result, shared::Localization::MessagedFailedToCreateDisk(target, windows::common::wslutil::GetErrorString(result)));
}
}

wil::unique_handle wsl::core::filesystem::OpenVhd(_In_ LPCWSTR Path, _In_ VIRTUAL_DISK_ACCESS_MASK Mask)
Expand Down
10 changes: 0 additions & 10 deletions src/windows/common/wslutil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -636,22 +636,12 @@ std::wstring wsl::windows::common::wslutil::GetErrorString(HRESULT result)
case WSL_E_DEFAULT_DISTRO_NOT_FOUND:
return Localization::MessageNoDefaultDistro();

case HRESULT_FROM_WIN32(WSAECONNABORTED):
case HRESULT_FROM_WIN32(ERROR_SHUTDOWN_IN_PROGRESS):
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Open to feedback on this: I chose to remove this because it can be misleading since a closed socket isn't necessarily a sign that the distro is terminating.

return Localization::MessageInstanceTerminated();

case WSL_E_DISTRO_NOT_FOUND:
return Localization::MessageDistroNotFound();

case HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS):
return Localization::MessageDistroNameAlreadyExists();

case WSL_E_DISTRIBUTION_NAME_NEEDED:
return Localization::MessageDistributionNameNeeded();

case HRESULT_FROM_WIN32(ERROR_FILE_EXISTS):
return Localization::MessageDistroInstallPathAlreadyExists();

case WSL_E_TOO_MANY_DISKS_ATTACHED:
return Localization::MessageTooManyDisks();

Expand Down
14 changes: 8 additions & 6 deletions src/windows/service/exe/LxssUserSession.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3787,11 +3787,12 @@ void LxssUserSessionImpl::_ValidateDistributionNameAndPathNotInUse(

if (Name != nullptr && wsl::shared::string::IsEqual(Name, configuration.Name, true))
{
THROW_HR_MSG(
(configuration.State == LxssDistributionStateInstalled) ? HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS) : E_ILLEGAL_STATE_CHANGE,
"%ls already registered (state = %d)",
Name,
configuration.State);
THROW_HR_WITH_USER_ERROR_IF(
HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS),
wsl::shared::Localization::MessageDistroNameAlreadyExists(),
configuration.State == LxssDistributionStateInstalled);

THROW_HR_MSG(E_ILLEGAL_STATE_CHANGE, "%ls already registered (state = %d)", Name, configuration.State);
}

if (Path != nullptr)
Expand All @@ -3803,8 +3804,9 @@ void LxssUserSessionImpl::_ValidateDistributionNameAndPathNotInUse(
}

// Ensure another distribution by a different name is not already registered to the same location.
THROW_HR_IF(
THROW_HR_WITH_USER_ERROR_IF(
HRESULT_FROM_WIN32(ERROR_FILE_EXISTS),
wsl::shared::Localization::MessageDistroInstallPathAlreadyExists(),
wsl::windows::common::string::IsPathComponentEqual(error ? configuration.BasePath.native() : canonicalDistroPath.native(), Path));
}
}
Expand Down
31 changes: 26 additions & 5 deletions test/windows/UnitTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -960,7 +960,7 @@ class UnitTests
VERIFY_IS_FALSE(!vhdFile);
}

auto validateOutput = [](LPCWSTR commandLine, LPCWSTR expectedOutput, DWORD expectedExitCode = -1) {
auto validateOutput = [](LPCWSTR commandLine, const std::wstring& expectedOutput, DWORD expectedExitCode = -1) {
auto [out, err] = LxsstuLaunchWslAndCaptureOutput(commandLine, expectedExitCode);
VERIFY_ARE_EQUAL(expectedOutput, out);
VERIFY_ARE_EQUAL(L"", err);
Expand All @@ -970,8 +970,10 @@ class UnitTests
auto commandLine = std::format(L"--import dummy {} {} --version {}", LXSST_IMPORT_DISTRO_TEST_DIR, tarFileName, version);
validateOutput(
commandLine.c_str(),
L"The supplied install location is already in use.\r\n"
L"Error code: Wsl/Service/RegisterDistro/ERROR_FILE_EXISTS\r\n");
std::format(
L"Failed to create disk '{}ext4.vhdx': The file exists. \r\n"
L"Error code: Wsl/Service/RegisterDistro/ERROR_FILE_EXISTS\r\n",
LXSST_IMPORT_DISTRO_TEST_DIR));

commandLine = std::format(L"--import dummy {} {} --version {}", LXSST_IMPORT_DISTRO_TEST_DIR, vhdFileName, version);
validateOutput(commandLine.c_str(), L"This looks like a VHD file. Use --vhd to import a VHD instead of a tar.\r\n");
Expand All @@ -985,6 +987,25 @@ class UnitTests
L"Error code: Wsl/Service/RegisterDistro/WSL_E_WSL2_NEEDED\r\n");
}

//
// Verify that importing a distribution with a different name into the same path as an
// already registered distribution (test_distro) returns the path-already-exists error.
//

{
const auto distroKey = OpenDistributionKey(LXSS_DISTRO_NAME_TEST_L);
VERIFY_IS_TRUE(!!distroKey);

auto basePath = wsl::windows::common::registry::ReadString(distroKey.get(), nullptr, L"BasePath", L"");
VERIFY_IS_FALSE(basePath.empty());

commandLine = std::format(L"--import path-conflict-distro \"{}\" \"{}\" --version {}", basePath, tarFileName, version);
validateOutput(
commandLine.c_str(),
L"The supplied install location is already in use.\r\n"
L"Error code: Wsl/Service/RegisterDistro/ERROR_FILE_EXISTS\r\n");
}

//
// Create and import a new distro that where /bin/sh is an absolute symlink.
//
Expand Down Expand Up @@ -5361,7 +5382,7 @@ Error code: Wsl/InstallDistro/WSL_E_DISTRO_NOT_FOUND\r\n",

VERIFY_ARE_EQUAL(
out,
L"A distribution with the supplied name already exists. Use --name to chose a different name.\r\n"
L"Cannot create a file when that file already exists. \r\n"
L"Error code: Wsl/InstallDistro/ERROR_ALREADY_EXISTS\r\n");

VERIFY_ARE_EQUAL(err, L"");
Expand All @@ -5372,7 +5393,7 @@ Error code: Wsl/InstallDistro/WSL_E_DISTRO_NOT_FOUND\r\n",

VERIFY_ARE_EQUAL(
out,
L"A distribution with the supplied name already exists. Use --name to chose a different name.\r\n"
L"Cannot create a file when that file already exists. \r\n"
L"Error code: Wsl/InstallDistro/ERROR_ALREADY_EXISTS\r\n");

VERIFY_ARE_EQUAL(err, L"");
Expand Down
Loading