Don't use a \\?\ prefix when resolving the distribution location (#13080)
Blue committed
Jun 10, 2025 at 11:07 UTC
63d13967149364c3e16b7bdadd08d6eacbbfe809
2 files changed
+32
-11
src/windows/common/WslClient.cpp
+7
-10
@@ -323,27 +323,27 @@ int ImportDistribution(_In_ std::wstring_view commandLine)
323
{
324
ArgumentParser parser(std::wstring{commandLine}, WSL_BINARY_NAME);
325
LPCWSTR name{};
326
- LPCWSTR installPath{};
326
+ std::optional<std::wstring> installPath{};
327
std::filesystem::path filePath;
328
ULONG flags = LXSS_IMPORT_DISTRO_FLAGS_NO_OOBE;
329
DWORD version = LXSS_WSL_VERSION_DEFAULT;
330
331
parser.AddPositionalArgument(name, 0);
332
- parser.AddPositionalArgument(installPath, 1);
332
+ parser.AddPositionalArgument(AbsolutePath(installPath), 1);
333
parser.AddPositionalArgument(filePath, 2);
334
parser.AddArgument(WslVersion(version), WSL_IMPORT_ARG_VERSION);
335
parser.AddArgument(SetFlag<ULONG, LXSS_IMPORT_DISTRO_FLAGS_VHD>{flags}, WSL_IMPORT_ARG_VHD);
336
337
parser.Parse();
338
339
- if (name == nullptr || installPath == nullptr || filePath.empty())
339
+ if (name == nullptr || !installPath.has_value() || filePath.empty())
340
{
341
THROW_HR(E_INVALIDARG);
342
}
343
344
// Ensure that the install path exists.
345
bool directoryCreated = true;
346
- if (!CreateDirectoryW(installPath, nullptr))
346
+ if (!CreateDirectoryW(installPath->c_str(), nullptr))
347
{
348
if (GetLastError() == ERROR_ALREADY_EXISTS)
349
{
@@ -355,16 +355,13 @@ int ImportDistribution(_In_ std::wstring_view commandLine)
355
}
356
}
357
358
- auto directory_cleanup = wil::scope_exit_log(WI_DIAGNOSTICS_INFO, [directoryCreated, installPath]() {
358
+ auto directory_cleanup = wil::scope_exit_log(WI_DIAGNOSTICS_INFO, [directoryCreated, &installPath]() {
359
if (directoryCreated)
360
{
361
- LOG_IF_WIN32_BOOL_FALSE(RemoveDirectory(installPath));
361
+ LOG_IF_WIN32_BOOL_FALSE(RemoveDirectory(installPath->c_str()));
362
}
363
});
364
365
- // Get the full path to the install location.
366
- const auto installFullPath(wsl::windows::common::filesystem::GetFullPath(installPath));
367
-
365
// Determine if the source of the tar file is stdin, or an on-disk file.
366
wil::unique_hfile file;
367
HANDLE fileHandle;
@@ -408,7 +405,7 @@ int ImportDistribution(_In_ std::wstring_view commandLine)
405
{
406
wsl::windows::common::HandleConsoleProgressBar progressBar(fileHandle, Localization::MessageImportProgress());
407
wsl::windows::common::SvcComm service;
411
- service.RegisterDistribution(name, version, fileHandle, installFullPath.c_str(), flags);
408
+ service.RegisterDistribution(name, version, fileHandle, installPath->c_str(), flags);
409
}
410
411
directory_cleanup.release();
test/windows/UnitTests.cpp
+25
-1
@@ -2463,7 +2463,7 @@ Error code: Wsl/InstallDistro/WSL_E_DISTRO_NOT_FOUND
2463
auto basePath = wsl::windows::common::registry::ReadString(distroKey.get(), nullptr, L"BasePath", L"");
2464
2465
// Validate that the icon is under the distribution folder.
2466
- VERIFY_IS_TRUE(iconLocation.find(basePath) != std::string::npos);
2466
+ VERIFY_IS_TRUE(iconLocation.find(basePath) == 0);
2467
}
2468
2469
return std::make_pair(json, profilePath);
@@ -3978,6 +3978,30 @@ VERSION_ID="Invalid|Format"
3978
CreateTarFromManifest(
3979
L"[shortcut]\nicon = /icon.ico\n[oobe]\ndefaultName = test-default-name", L"distro-default-name-icon.tar");
3980
3981
+ //
3982
+ // Validate that the distribution icon path is also correct when installing via wsl --import.
3983
+ //
3984
+
3985
+ {
3986
+ constexpr auto distroName = L"TestCustomLocation";
3987
+
3988
+ auto currentDirectory = std::filesystem::absolute(std::filesystem::current_path()).wstring();
3989
+ for (const auto& location : {currentDirectory, std::wstring(L".")})
3990
+ {
3991
+ auto cleanup = wil::scope_exit_log(
3992
+ WI_DIAGNOSTICS_INFO, [&]() { LxsstuLaunchWsl(std::format(L"--unregister {}", distroName)); });
3993
+
3994
+ VERIFY_ARE_EQUAL(
3995
+ LxsstuLaunchWsl(
3996
+ std::format(L"--import {} \"{}\" {}", distroName, location, "distro-default-name-icon.tar")),
3997
+ 0L);
3998
+
3999
+ auto [json, profile_path] = ValidateDistributionTerminalProfile(distroName, false);
4000
+ VERIFY_ARE_EQUAL(
4001
+ json["profiles"][1]["icon"].get<std::string>(), (std::filesystem::absolute(".") / "shortcut.ico").string());
4002
+ }
4003
+ }
4004
+
4005
InstallFromTar(L"distro-default-name-icon.tar");
4006
ValidateDistributionStarts(L"test-default-name");
4007