WSL/test/windows/PluginTests.cpp
WSL Team 697572d664 Initial open source commit for WSL.
Many Microsoft employees have contributed to the Windows Subsystem for Linux, this commit is the result of their work since 2016.

The entire history of the Windows Subsystem for Linux can't be shared here, but here's an overview of WSL's history after it moved to it own repository in 2021:

Number of commits on the main branch: 2930
Number of contributors: 31

Head over https://github.com/microsoft/WSL/releases for a more detailed history of the features added to WSL since 2021.
2025-05-15 12:09:45 -07:00

669 lines
No EOL
23 KiB
C++

/*++
Copyright (c) Microsoft. All rights reserved.
Module Name:
PluginTests.cpp
Abstract:
This file contains test cases for the plugin API.
--*/
#include "precomp.h"
#include "Common.h"
#include "registry.hpp"
#include "PluginTests.h"
using namespace wsl::windows::common::registry;
extern std::wstring g_testDistroPath;
class PluginTests
{
std::wstring logFile;
bool m_initialized = false;
std::wstring pluginDll;
std::optional<WslConfigChange> config;
WSL_TEST_CLASS(PluginTests)
TEST_CLASS_SETUP(TestClassSetup)
{
VERIFY_ARE_EQUAL(LxsstuInitialize(FALSE), TRUE);
m_initialized = true;
logFile = wil::GetCurrentDirectoryW<std::wstring>() + L"\\plugin-logs.txt";
const auto currentDll = std::filesystem::path(wil::GetModuleFileNameW<std::wstring>(wil::GetModuleInstanceHandle()));
const auto pluginDllPath = currentDll.parent_path() / L"testplugin.dll";
if (!std::filesystem::exists(pluginDllPath))
{
const std::wstring message = L"Plugin not found in: " + pluginDllPath.wstring();
VERIFY_FAIL(message.c_str());
return false;
}
pluginDll = pluginDllPath.wstring();
// Disable VM timeouts during the plugin tests
config.emplace(LxssGenerateTestConfig({.vmIdleTimeout = -1}));
return true;
}
TEST_CLASS_CLEANUP(TestClassCleanup)
{
auto key = OpenLxssMachineKey(KEY_ALL_ACCESS);
DeleteKey(key.get(), L"Test");
key = OpenKey(key.get(), L"Plugins", KEY_SET_VALUE);
DeleteValue(key.get(), L"TestPlugin");
RestartWslService();
std::wifstream file(logFile);
const auto fileContent = std::wstring{std::istreambuf_iterator<wchar_t>(file), {}};
LogInfo("Logfile: %ls", fileContent.c_str());
file.close();
StopWslService();
if (!DeleteFile(logFile.c_str()))
{
VERIFY_ARE_EQUAL(ERROR_FILE_NOT_FOUND, GetLastError());
}
if (m_initialized)
{
LxsstuUninitialize(FALSE);
}
return true;
}
void ConfigurePlugin(PluginTestType testCase) const
{
StopWslService();
if (!DeleteFile(logFile.c_str()))
{
VERIFY_ARE_EQUAL(ERROR_FILE_NOT_FOUND, GetLastError());
}
const auto testKey = OpenTestRegistryKey(KEY_SET_VALUE);
WriteDword(testKey.get(), nullptr, c_testType, static_cast<DWORD>(testCase));
WriteString(testKey.get(), nullptr, c_logFile, logFile.c_str());
const auto lxssKey =
CreateKey(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Lxss\\Plugins", KEY_SET_VALUE, nullptr, 0);
WriteString(lxssKey.get(), nullptr, L"TestPlugin", pluginDll.c_str());
RestartWslService();
}
static void StartWsl(int expectedExitCode, LPCWSTR ExpectedOutput = nullptr)
{
auto [output, error] = LxsstuLaunchWslAndCaptureOutput(L"echo -n OK", expectedExitCode);
if (expectedExitCode == 0)
{
VERIFY_ARE_EQUAL(output, L"OK");
}
else
{
VERIFY_ARE_EQUAL(output, ExpectedOutput);
}
}
void ValidateLogFile(LPCWSTR expected) const
{
StopWslService();
std::wifstream file(logFile);
auto fileContent = std::wstring{std::istreambuf_iterator<wchar_t>(file), {}};
LogInfo("Logfile: %ls", fileContent.c_str());
auto fileLines = wsl::shared::string::Split<wchar_t>(fileContent, '\n');
auto expectedLines = wsl::shared::string::Split<wchar_t>(expected, '\n');
for (size_t i = 0; i < std::max(fileLines.size(), expectedLines.size()); i++)
{
if (i >= fileLines.size())
{
std::wstring message = L"Line is expected but not in log file: " + expectedLines[i];
VERIFY_FAIL(message.c_str());
}
else if (i >= expectedLines.size())
{
std::wstring message = L"Line is in file but not expected: " + fileLines[i];
VERIFY_FAIL(message.c_str());
}
const auto& expected = expectedLines[i];
const auto& actual = fileLines[i];
if (!PathMatchSpec(actual.c_str(), expected.c_str()))
{
LogInfo("Plugin log: %ls", fileContent.c_str());
std::wstring message = L"Line (" + actual + L") didn't match pattern: " + expected;
VERIFY_FAIL(message.c_str());
}
}
}
TEST_METHOD(Success)
{
WSL2_TEST_ONLY();
constexpr auto ExpectedOutput =
LR"(Plugin loaded. TestMode=1
VM created (settings->CustomConfigurationFlags=0)
Folder mounted (* -> /test-plugin)
Process created
Distribution started, name=test_distro, package=, PidNs=*, InitPid=*, Flavor=debian, Version=12
Distribution Stopping, name=test_distro, package=, PidNs=*, Flavor=debian, Version=12
VM Stopping)";
ConfigurePlugin(PluginTestType::Success);
StartWsl(0);
ValidateLogFile(ExpectedOutput);
}
TEST_METHOD(CustomKernelOverridenByPolicy)
{
WSL2_TEST_ONLY();
RegistryKeyChange policy(
HKEY_LOCAL_MACHINE, wsl::windows::policies::c_registryKey, wsl::windows::policies::c_allowCustomKernelUserSetting, static_cast<DWORD>(0));
WslConfigChange config(LxssGenerateTestConfig({.kernel = L"kernel-that-doesn't-exist"}));
constexpr auto ExpectedOutput =
LR"(Plugin loaded. TestMode=1
VM created (settings->CustomConfigurationFlags=0)
Folder mounted (* -> /test-plugin)
Process created
Distribution started, name=test_distro, package=, PidNs=*, InitPid=*, Flavor=debian, Version=12
Distribution Stopping, name=test_distro, package=, PidNs=*, Flavor=debian, Version=12
VM Stopping)";
ConfigurePlugin(PluginTestType::Success);
StartWsl(0);
ValidateLogFile(ExpectedOutput);
}
TEST_METHOD(DuplicatedPlugin)
{
WSL2_TEST_ONLY();
constexpr auto ExpectedOutput =
LR"(Plugin loaded. TestMode=1
VM created (settings->CustomConfigurationFlags=0)
Folder mounted (* -> /test-plugin)
Process created
Distribution started, name=test_distro, package=, PidNs=*, InitPid=*, Flavor=debian, Version=12
Distribution Stopping, name=test_distro, package=, PidNs=*, Flavor=debian, Version=12
VM Stopping)";
ConfigurePlugin(PluginTestType::Success);
// Register the same plugin dll twice. Validate that it's only called once.
const auto key =
CreateKey(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Lxss\\Plugins", KEY_SET_VALUE, nullptr, 0);
WriteString(key.get(), nullptr, L"TestPlugin-duplicated", pluginDll.c_str());
auto cleanup = wil::scope_exit_log(WI_DIAGNOSTICS_INFO, [&]() { DeleteValue(key.get(), L"TestPlugin-duplicated"); });
RestartWslService();
StartWsl(0);
ValidateLogFile(ExpectedOutput);
}
TEST_METHOD(CustomKernel)
{
WSL2_TEST_ONLY();
constexpr auto ExpectedOutput =
LR"(Plugin loaded. TestMode=1
VM created (settings->CustomConfigurationFlags=1)
OnVmStarted: E_ACCESSDENIED
VM Stopping)";
#ifdef WSL_KERNEL_PATH
std::wstring kernelPath = WIDEN(WSL_KERNEL_PATH);
#else
auto kernelPath = wsl::windows::common::wslutil::GetMsiPackagePath().value_or(L"");
VERIFY_IS_FALSE(kernelPath.empty());
kernelPath += L"\\tools\\kernel";
#endif
WslConfigChange config(LxssGenerateTestConfig({.vmIdleTimeout = 1, .kernel = kernelPath}));
ConfigurePlugin(PluginTestType::Success);
StartWsl(
-1,
L"A fatal error was returned by plugin 'TestPlugin'\r\nError code: "
L"Wsl/Service/CreateInstance/CreateVm/Plugin/E_ACCESSDENIED\r\n");
ValidateLogFile(ExpectedOutput);
}
TEST_METHOD(CustomKernelCommandLine)
{
WSL2_TEST_ONLY();
constexpr auto ExpectedOutput =
LR"(Plugin loaded. TestMode=1
VM created (settings->CustomConfigurationFlags=2)
Folder mounted (* -> /test-plugin)
Process created
Distribution started, name=test_distro, package=, PidNs=*, InitPid=*, Flavor=debian, Version=12
Distribution Stopping, name=test_distro, package=, PidNs=*, Flavor=debian, Version=12
VM Stopping)";
WslConfigChange config(LxssGenerateTestConfig({.vmIdleTimeout = 1, .kernelCommandLine = L"custom"}));
ConfigurePlugin(PluginTestType::Success);
StartWsl(0);
ValidateLogFile(ExpectedOutput);
}
TEST_METHOD(DistroIdStaysTheSame)
{
WSL2_TEST_ONLY();
constexpr auto ExpectedOutput =
LR"(Plugin loaded. TestMode=10
VM created (settings->CustomConfigurationFlags=0)
Distribution started, name=test_distro, package=, PidNs=*, InitPid=*, Flavor=debian, Version=12
Distribution Stopping, name=test_distro, package=, PidNs=*, Flavor=debian, Version=12
VM Stopping
VM created (settings->CustomConfigurationFlags=0)
Distribution started, name=test_distro, package=, PidNs=*, InitPid=*, Flavor=debian, Version=12
OnDistroStarted: received same GUID
Distribution Stopping, name=test_distro, package=, PidNs=*, Flavor=debian, Version=12
VM Stopping)";
ConfigurePlugin(PluginTestType::SameDistroId);
StartWsl(0);
WslShutdown();
StartWsl(0);
ValidateLogFile(ExpectedOutput);
}
TEST_METHOD(InitPidIsDifferent)
{
WSL2_TEST_ONLY();
constexpr auto ExpectedOutput =
LR"(Plugin loaded. TestMode=14
VM created (settings->CustomConfigurationFlags=0)
Distribution started, name=test_distro, package=, PidNs=*, InitPid=*, Flavor=debian, Version=12
Distribution Stopping, name=test_distro, package=, PidNs=*
Distribution started, name=test_distro, package=, PidNs=*, InitPid=*, Flavor=debian, Version=12
Init's pid is different (* ! = *)
Distribution Stopping, name=test_distro, package=, PidNs=*, Flavor=debian, Version=12
VM Stopping)";
ConfigurePlugin(PluginTestType::InitPidIsDifferent);
StartWsl(0);
TerminateDistribution();
StartWsl(0);
ValidateLogFile(ExpectedOutput);
}
TEST_METHOD(PluginUpdateRequired)
{
WSL2_TEST_ONLY();
constexpr auto ExpectedOutput =
LR"(Plugin loaded. TestMode=9
OnLoad: WSL_E_PLUGINREQUIRESUPDATE)";
ConfigurePlugin(PluginTestType::PluginRequiresUpdate);
StartWsl(
-1,
L"The plugin 'TestPlugin' requires a newer version of WSL. Please run: wsl.exe --update\r\nError code: "
L"Wsl/Service/CreateInstance/CreateVm/Plugin/WSL_E_PLUGIN_REQUIRES_UPDATE\r\n");
ValidateLogFile(ExpectedOutput);
}
TEST_METHOD(APIErrors)
{
WSL2_TEST_ONLY();
constexpr auto ExpectedOutput =
LR"(Plugin loaded. TestMode=7
VM created (settings->CustomConfigurationFlags=0)
API error tests passed
Distribution started, name=test_distro, package=, PidNs=*, InitPid=*, Flavor=debian, Version=12
Distribution Stopping, name=test_distro, package=, PidNs=*, Flavor=debian, Version=12
VM Stopping)";
ConfigurePlugin(PluginTestType::ApiErrors);
StartWsl(0);
ValidateLogFile(ExpectedOutput);
}
TEST_METHOD(SuccessWSL1)
{
WSL1_TEST_ONLY();
constexpr auto ExpectedOutput = LR"(Plugin loaded. TestMode=1)";
ConfigurePlugin(PluginTestType::Success);
StartWsl(0);
ValidateLogFile(ExpectedOutput);
}
TEST_METHOD(LoadFailureFatalWSL2)
{
WSL2_TEST_ONLY();
constexpr auto ExpectedOutput =
LR"(Plugin loaded. TestMode=2
OnLoad: E_UNEXPECTED)";
ConfigurePlugin(PluginTestType::FailToLoad);
StartWsl(
-1,
L"A fatal error was returned by plugin 'TestPlugin'\r\nError code: "
L"Wsl/Service/CreateInstance/CreateVm/Plugin/E_UNEXPECTED\r\n");
ValidateLogFile(ExpectedOutput);
}
TEST_METHOD(LoadFailureNonFatalWSL1)
{
WSL1_TEST_ONLY();
constexpr auto ExpectedOutput =
LR"(Plugin loaded. TestMode=2
OnLoad: E_UNEXPECTED)";
ConfigurePlugin(PluginTestType::FailToLoad);
StartWsl(0);
ValidateLogFile(ExpectedOutput);
}
TEST_METHOD(VmStartFailure)
{
WSL2_TEST_ONLY();
constexpr auto ExpectedOutput =
LR"(Plugin loaded. TestMode=3
VM created (settings->CustomConfigurationFlags=0)
OnVmStarted: E_UNEXPECTED
VM Stopping)";
ConfigurePlugin(PluginTestType::FailToStartVm);
StartWsl(
-1,
L"A fatal error was returned by plugin 'TestPlugin'\r\nError code: "
L"Wsl/Service/CreateInstance/CreateVm/Plugin/E_UNEXPECTED\r\n");
ValidateLogFile(ExpectedOutput);
}
TEST_METHOD(VmStartFailureWithPluginErrorTwice)
{
WSL2_TEST_ONLY();
constexpr auto ExpectedOutput =
LR"(Plugin loaded. TestMode=13
VM created (settings->CustomConfigurationFlags=0)
OnVmStarted: E_UNEXPECTED
VM Stopping
VM created (settings->CustomConfigurationFlags=0)
OnVmStarted: E_UNEXPECTED
VM Stopping)";
ConfigurePlugin(PluginTestType::FailToStartVmWithPluginErrorMessage);
StartWsl(
-1,
L"A fatal error was returned by plugin 'TestPlugin'. Error message: 'Plugin error message'\r\nError code: "
L"Wsl/Service/CreateInstance/CreateVm/Plugin/E_UNEXPECTED\r\n");
StartWsl(
-1,
L"A fatal error was returned by plugin 'TestPlugin'. Error message: 'Plugin error message'\r\nError code: "
L"Wsl/Service/CreateInstance/CreateVm/Plugin/E_UNEXPECTED\r\n");
ValidateLogFile(ExpectedOutput);
}
TEST_METHOD(VmStopFailure)
{
WSL2_TEST_ONLY();
constexpr auto ExpectedOutput =
LR"(Plugin loaded. TestMode=5
VM created (settings->CustomConfigurationFlags=0)
Distribution started, name=test_distro, package=, PidNs=*, Flavor=debian, Version=12
Distribution Stopping, name=test_distro, package=, PidNs=*, Flavor=debian, Version=12
VM Stopping
OnVmStopping: E_UNEXPECTED)";
ConfigurePlugin(PluginTestType::FailToStopVm);
StartWsl(0);
ValidateLogFile(ExpectedOutput);
}
TEST_METHOD(DistributionStartFailure)
{
WSL2_TEST_ONLY();
constexpr auto ExpectedOutput =
LR"(Plugin loaded. TestMode=4
VM created (settings->CustomConfigurationFlags=0)
Distribution started, name=test_distro, package=, PidNs=*, InitPid=*, Flavor=debian, Version=12
OnDistroStarted: E_UNEXPECTED
VM Stopping)";
constexpr auto ExpectedError =
L"A fatal error was returned by plugin 'TestPlugin'\r\nError code: "
L"Wsl/Service/CreateInstance/Plugin/E_UNEXPECTED\r\n";
ConfigurePlugin(PluginTestType::FailToStartDistro);
StartWsl(-1, ExpectedError);
ValidateLogFile(ExpectedOutput);
}
TEST_METHOD(DistributionStopFailure)
{
WSL2_TEST_ONLY();
constexpr auto ExpectedOutput =
LR"(Plugin loaded. TestMode=6
VM created (settings->CustomConfigurationFlags=0)
Distribution started, name=test_distro, package=, PidNs=*, InitPid=*, Flavor=debian, Version=12
Distribution Stopping, name=test_distro, package=, PidNs=*, Flavor=debian, Version=12
OnDistroStopping: E_UNEXPECTED
VM Stopping)";
ConfigurePlugin(PluginTestType::FailToStopDistro);
StartWsl(0);
ValidateLogFile(ExpectedOutput);
}
TEST_METHOD(ErrorMessageStartVm)
{
WSL2_TEST_ONLY();
constexpr auto ExpectedOutput =
LR"(Plugin loaded. TestMode=11
VM created (settings->CustomConfigurationFlags=0)
OnVmStarted: E_FAIL
VM Stopping)";
ConfigurePlugin(PluginTestType::ErrorMessageStartVm);
StartWsl(
-1,
L"A fatal error was returned by plugin 'TestPlugin'. Error message: 'StartVm plugin error message'\r\nError code: "
L"Wsl/Service/CreateInstance/CreateVm/Plugin/E_FAIL\r\n");
ValidateLogFile(ExpectedOutput);
}
TEST_METHOD(ErrorMessageStartDistro)
{
WSL2_TEST_ONLY();
constexpr auto ExpectedOutput =
LR"(Plugin loaded. TestMode=12
VM created (settings->CustomConfigurationFlags=0)
Distribution started, name=test_distro, package=, PidNs=*, InitPid=*, Flavor=debian, Version=12
OnDistroStarted: E_FAIL
VM Stopping)";
ConfigurePlugin(PluginTestType::ErrorMessageStartDistro);
StartWsl(
-1,
L"A fatal error was returned by plugin 'TestPlugin'. Error message: 'StartDistro plugin error message'\r\nError "
L"code: "
L"Wsl/Service/CreateInstance/Plugin/E_FAIL\r\n");
ValidateLogFile(ExpectedOutput);
}
TEST_METHOD(RegisterSuccess)
{
WSL2_TEST_ONLY();
ConfigurePlugin(PluginTestType::Success);
VERIFY_ARE_EQUAL(LxsstuLaunchWsl(L"--import plugin-test-distro . \"" + g_testDistroPath + L"\" --version 2"), 0L);
VERIFY_ARE_EQUAL(LxsstuLaunchWsl(L"--unregister plugin-test-distro"), 0L);
constexpr auto ExpectedOutput =
LR"(Plugin loaded. TestMode=1
VM created (settings->CustomConfigurationFlags=0)
Folder mounted (* -> /test-plugin)
Process created
Distribution registered, name=plugin-test-distro, package=, Flavor=debian, Version=12
Distribution unregistered, name=plugin-test-distro, package=, Flavor=debian, Version=12
VM Stopping)";
ValidateLogFile(ExpectedOutput);
}
TEST_METHOD(ImportInplaceSuccess)
{
WSL2_TEST_ONLY();
ConfigurePlugin(PluginTestType::Success);
VERIFY_ARE_EQUAL(LxsstuLaunchWsl(L"--import plugin-test-distro . \"" + g_testDistroPath + L"\" --version 2"), 0L);
WslShutdown();
VERIFY_ARE_EQUAL(LxsstuLaunchWsl(L"--export plugin-test-distro plugin-test-distro.vhdx --format vhd"), 0L);
VERIFY_ARE_EQUAL(LxsstuLaunchWsl(L"--unregister plugin-test-distro"), 0L);
VERIFY_ARE_EQUAL(LxsstuLaunchWsl(L"--import-in-place plugin-test-distro-vhd plugin-test-distro.vhdx"), 0L);
VERIFY_ARE_EQUAL(LxsstuLaunchWsl(L"--unregister plugin-test-distro-vhd"), 0L);
constexpr auto ExpectedOutput =
LR"(Plugin loaded. TestMode=1
VM created (settings->CustomConfigurationFlags=0)
Folder mounted (* -> /test-plugin)
Process created
Distribution registered, name=plugin-test-distro, package=, Flavor=debian, Version=12
VM Stopping
Distribution unregistered, name=plugin-test-distro, package=, Flavor=debian, Version=12
VM created (settings->CustomConfigurationFlags=0)
Folder mounted (* -> /test-plugin)
Process created
Distribution registered, name=plugin-test-distro-vhd, package=, Flavor=debian, Version=12
Distribution unregistered, name=plugin-test-distro-vhd, package=, Flavor=debian, Version=12
VM Stopping)";
ValidateLogFile(ExpectedOutput);
}
TEST_METHOD(RegisterUnregisterFail)
{
WSL2_TEST_ONLY();
ConfigurePlugin(PluginTestType::FailToRegisterUnregisterDistro);
VERIFY_ARE_EQUAL(LxsstuLaunchWsl(L"--import plugin-test-distro . \"" + g_testDistroPath + L"\" --version 2"), 0L);
VERIFY_ARE_EQUAL(LxsstuLaunchWsl(L"--unregister plugin-test-distro"), 0L);
constexpr auto ExpectedOutput =
LR"(Plugin loaded. TestMode=15
VM created (settings->CustomConfigurationFlags=0)
Distribution registered, name=plugin-test-distro, package=, Flavor=debian, Version=12
OnDistributionRegisted: E_UNEXPECTED
Distribution unregistered, name=plugin-test-distro, package=, Flavor=debian, Version=12
OnDistributionUnregistered: E_UNEXPECTED
VM Stopping)";
ValidateLogFile(ExpectedOutput);
}
TEST_METHOD(ExecuteDistroCommand)
{
WSL2_TEST_ONLY();
ConfigurePlugin(PluginTestType::RunDistroCommand);
constexpr auto ExpectedOutput =
LR"(Plugin loaded. TestMode=16
VM created (settings->CustomConfigurationFlags=0)
Distribution started, name=test_distro, package=, PidNs=*, InitPid=*, Flavor=debian, Version=12
Process created
Failed process launch returned: -2147467259
Invalid distro launch returned: -2147220717
Distribution Stopping, name=test_distro, package=, PidNs=*, Flavor=debian, Version=12
VM Stopping)";
StartWsl(0);
ValidateLogFile(ExpectedOutput);
}
TEST_METHOD(PluginToken)
{
WSL2_TEST_ONLY();
ConfigurePlugin(PluginTestType::GetUsername);
constexpr auto ExpectedOutput =
LR"(Plugin loaded. TestMode=17
VM created (settings->CustomConfigurationFlags=0)
Username: *
Distribution started, name=test_distro, package=, PidNs=*, InitPid=*, Flavor=debian, Version=12
Distribution Stopping, name=test_distro, package=, PidNs=*, Flavor=debian, Version=12
VM Stopping)";
StartWsl(0);
ValidateLogFile(ExpectedOutput);
}
// This test must run last so it doesn't break test cases that depends on plugin signature.
TEST_METHOD(InvalidPluginSignature)
{
WSL2_TEST_ONLY();
if constexpr (!wsl::shared::OfficialBuild)
{
LogSkipped("This test only applies to signed builds");
return;
}
StopWslService();
// Append one byte at the end of the plugin dll to break its signature
wil::unique_handle plugin{CreateFile(pluginDll.c_str(), FILE_APPEND_DATA, 0, nullptr, OPEN_EXISTING, 0, nullptr)};
VERIFY_IS_TRUE(plugin.is_valid());
char c{};
VERIFY_IS_TRUE(WriteFile(plugin.get(), &c, sizeof(c), nullptr, nullptr));
plugin.reset();
ConfigurePlugin(PluginTestType::ErrorMessageStartDistro);
StartWsl(
-1,
L"A fatal error was returned by plugin 'TestPlugin'\r\nError code: "
L"Wsl/Service/CreateInstance/CreateVm/Plugin/TRUST_E_NOSIGNATURE\r\n");
}
};