223
ArgumentParser parser(std::wstring{commandLine}, WSL_BINARY_NAME);
224
std::filesystem::path filePath;
225
LPCWSTR name{};
226
+ int tarFormatSet = 0;
227
227
- auto parseFormat = [&flags](LPCWSTR Value) {
228
+ auto parseFormat = [&flags, &tarFormatSet](LPCWSTR Value) {
229
if (Value == nullptr)
230
{
231
return -1;
243
{
244
WI_SetFlag(flags, LXSS_EXPORT_DISTRO_FLAGS_VHD);
245
}
245
- else if (!wsl::shared::string::IsEqual(L"tar", Value))
246
+ else if (wsl::shared::string::IsEqual(L"tar", Value))
247
+ {
248
+ tarFormatSet = 1;
249
+ }
250
+ else
251
{
252
THROW_HR(E_INVALIDARG);
253
}
261
parser.AddArgument(parseFormat, WSL_EXPORT_ARG_FORMAT_OPTION);
262
parser.Parse();
263
259
- THROW_HR_IF(
260
- WSL_E_INVALID_USAGE,
261
- filePath.empty() || (WI_IsFlagSet(flags, LXSS_EXPORT_DISTRO_FLAGS_GZIP) && WI_IsFlagSet(flags, LXSS_EXPORT_DISTRO_FLAGS_VHD)));
264
+ constexpr ULONG c_exportFormatFlags = LXSS_EXPORT_DISTRO_FLAGS_VHD | LXSS_EXPORT_DISTRO_FLAGS_GZIP | LXSS_EXPORT_DISTRO_FLAGS_XZIP;
265
+ THROW_HR_IF(WSL_E_INVALID_USAGE, filePath.empty() || std::popcount(flags & c_exportFormatFlags) + tarFormatSet > 1);
266
267
// Determine if the target is stdout, or an on-disk file.
268
wil::unique_hfile file;
930
else if (defaultUser)
931
{
932
auto wslExe = wil::GetModuleFileNameW<std::wstring>(wil::GetModuleInstanceHandle());
929
-
930
- auto commandLine = std::format(
931
- L"\"{}\" {} -u root /usr/bin/id -u -- '{}'",
932
- wslExe,
933
- wsl::shared::string::GuidToString<wchar_t>(distroGuid),
934
- defaultUser.value());
933
+ const auto distroGuidString = wsl::shared::string::GuidToString<wchar_t>(distroGuid);
934
+ const std::array<std::wstring_view, 9> arguments{
935
+ wslExe, distroGuidString, WSL_USER_ARG, L"root", WSL_EXEC_ARG, L"/usr/bin/id", L"-u", L"--", defaultUser.value()};
936
+ const auto commandLine = wil::ArgvToCommandLine(arguments);
937
938
wsl::windows::common::SubProcess process{wslExe.c_str(), commandLine.c_str()};
939