diff --git a/src/windows/common/CMakeLists.txt b/src/windows/common/CMakeLists.txt
index 90c50d0..a254469 100644
--- a/src/windows/common/CMakeLists.txt
+++ b/src/windows/common/CMakeLists.txt
@@ -63,10 +63,10 @@ set(HEADERS
disk.hpp
Distribution.h
filesystem.hpp
+ HandleConsoleProgressBar.h
hcs.hpp
hcs_schema.h
helpers.hpp
- HandleConsoleProgressBar.h
interop.hpp
ExecutionContext.h
socket.hpp
diff --git a/src/windows/common/wslutil.h b/src/windows/common/wslutil.h
index 41d4b7c..fab4c98 100644
--- a/src/windows/common/wslutil.h
+++ b/src/windows/common/wslutil.h
@@ -78,6 +78,22 @@ void CoInitializeSecurity();
void ConfigureCrt();
+///
+/// Creates a COM server with user impersonation.
+///
+template
+wil::com_ptr_t CreateComServerAsUser(_In_ REFCLSID RefClsId, _In_ HANDLE UserToken)
+{
+ auto revert = wil::impersonate_token(UserToken);
+ return wil::CoCreateInstance(RefClsId, (CLSCTX_LOCAL_SERVER | CLSCTX_ENABLE_CLOAKING | CLSCTX_ENABLE_AAA));
+}
+
+template
+wil::com_ptr_t CreateComServerAsUser(_In_ HANDLE UserToken)
+{
+ return CreateComServerAsUser(__uuidof(Class), UserToken);
+}
+
std::wstring ConstructPipePath(_In_ std::wstring_view PipeName);
GUID CreateV5Uuid(const GUID& namespaceGuid, const std::span name);
diff --git a/src/windows/service/exe/CMakeLists.txt b/src/windows/service/exe/CMakeLists.txt
index f6962b8..c1e49a2 100644
--- a/src/windows/service/exe/CMakeLists.txt
+++ b/src/windows/service/exe/CMakeLists.txt
@@ -17,6 +17,7 @@ set(SOURCES
GnsChannel.cpp
GnsPortTrackerChannel.cpp
GnsRpcServer.cpp
+ GuestDeviceManager.cpp
GuestTelemetryLogger.cpp
Lifetime.cpp
LxssConsoleManager.cpp
@@ -56,6 +57,7 @@ set(HEADERS
GnsChannel.h
GnsPortTrackerChannel.h
GnsRpcServer.h
+ GuestDeviceManager.h
GuestTelemetryLogger.h
INetworkingEngine.h
IMirroredNetworkManager.h
diff --git a/src/windows/service/exe/GuestDeviceManager.cpp b/src/windows/service/exe/GuestDeviceManager.cpp
new file mode 100644
index 0000000..73426ab
--- /dev/null
+++ b/src/windows/service/exe/GuestDeviceManager.cpp
@@ -0,0 +1,149 @@
+// Copyright (C) Microsoft Corporation. All rights reserved.
+
+#include "precomp.h"
+#include "GuestDeviceManager.h"
+#include "DeviceHostProxy.h"
+
+GuestDeviceManager::GuestDeviceManager(_In_ const std::wstring& machineId, _In_ const GUID& runtimeId) :
+ m_machineId(machineId), m_deviceHostSupport(wil::MakeOrThrow(machineId, runtimeId))
+{
+}
+
+_Requires_lock_not_held_(m_lock)
+GUID GuestDeviceManager::AddGuestDevice(
+ _In_ const GUID& DeviceId, _In_ const GUID& ImplementationClsid, _In_ PCWSTR AccessName, _In_opt_ PCWSTR Options, _In_ PCWSTR Path, _In_ UINT32 Flags, _In_ HANDLE UserToken)
+{
+ auto guestDeviceLock = m_lock.lock_exclusive();
+ return AddHdvShareWithOptions(DeviceId, ImplementationClsid, AccessName, Options, Path, Flags, UserToken);
+}
+
+_Requires_lock_held_(m_lock)
+GUID GuestDeviceManager::AddHdvShareWithOptions(
+ _In_ const GUID& DeviceId, _In_ const GUID& ImplementationClsid, _In_ PCWSTR AccessName, _In_opt_ PCWSTR Options, _In_ PCWSTR Path, _In_ UINT32 Flags, _In_ HANDLE UserToken)
+{
+ wil::com_ptr server;
+
+ // Options are appended to the name with a semi-colon separator.
+ // "name;key1=value1;key2=value2"
+ // The AddSharePath implementation is responsible for separating them out and interpreting them.
+ std::wstring nameWithOptions{AccessName};
+ if (ARGUMENT_PRESENT(Options))
+ {
+ nameWithOptions += L";";
+ nameWithOptions += Options;
+ }
+
+ {
+ auto revert = wil::impersonate_token(UserToken);
+
+ server = GetRemoteFileSystem(ImplementationClsid, c_defaultDeviceTag);
+ if (!server)
+ {
+ server = wil::CoCreateInstance(ImplementationClsid, (CLSCTX_LOCAL_SERVER | CLSCTX_ENABLE_CLOAKING | CLSCTX_ENABLE_AAA));
+ AddRemoteFileSystem(ImplementationClsid, c_defaultDeviceTag.c_str(), server);
+ }
+
+ THROW_IF_FAILED(server->AddSharePath(nameWithOptions.c_str(), Path, Flags));
+ }
+
+ // This requires more privileges than the user may have, so impersonation is disabled.
+ return AddNewDevice(DeviceId, server, AccessName);
+}
+
+GUID GuestDeviceManager::AddNewDevice(_In_ const GUID& deviceId, _In_ const wil::com_ptr& server, _In_ PCWSTR tag)
+{
+ THROW_HR_IF(E_NOT_VALID_STATE, !m_deviceHostSupport);
+ return m_deviceHostSupport->AddNewDevice(deviceId, server, tag);
+}
+
+void GuestDeviceManager::AddRemoteFileSystem(_In_ REFCLSID clsid, _In_ PCWSTR tag, _In_ const wil::com_ptr& server)
+{
+ THROW_HR_IF(E_NOT_VALID_STATE, !m_deviceHostSupport);
+ m_deviceHostSupport->AddRemoteFileSystem(clsid, tag, server);
+}
+
+void GuestDeviceManager::AddSharedMemoryDevice(_In_ const GUID& ImplementationClsid, _In_ PCWSTR Tag, _In_ PCWSTR Path, _In_ UINT32 SizeMb, _In_ HANDLE UserToken)
+{
+ auto guestDeviceLock = m_lock.lock_exclusive();
+ auto objectLifetime = CreateSectionObjectRoot(Path, UserToken);
+
+ // For virtiofs hdv, the flags parameter has been overloaded. Flags are placed in the lower
+ // 16 bits, while the shared memory size in megabytes are placed in the upper 16 bits.
+ static constexpr auto VIRTIO_FS_FLAGS_SHMEM_SIZE_SHIFT = 16;
+ UINT32 flags = (SizeMb << VIRTIO_FS_FLAGS_SHMEM_SIZE_SHIFT);
+ WI_SetFlag(flags, VIRTIO_FS_FLAGS_TYPE_SECTIONS);
+ (void)AddHdvShareWithOptions(VIRTIO_VIRTIOFS_DEVICE_ID, ImplementationClsid, Tag, {}, objectLifetime.Path.c_str(), flags, UserToken);
+ m_objectDirectories.emplace_back(std::move(objectLifetime));
+}
+
+GuestDeviceManager::DirectoryObjectLifetime GuestDeviceManager::CreateSectionObjectRoot(_In_ std::wstring_view RelativeRootPath, _In_ HANDLE UserToken) const
+{
+ auto revert = wil::impersonate_token(UserToken);
+ DWORD sessionId;
+ DWORD bytesWritten;
+ THROW_LAST_ERROR_IF(!GetTokenInformation(GetCurrentThreadToken(), TokenSessionId, &sessionId, sizeof(sessionId), &bytesWritten));
+
+ // /Sessions/1/BaseNamedObjects/WSL//
+ std::wstringstream sectionPathBuilder;
+ sectionPathBuilder << L"\\Sessions\\" << sessionId << L"\\BaseNamedObjects" << L"\\WSL\\" << m_machineId << L"\\" << RelativeRootPath;
+ auto sectionPath = sectionPathBuilder.str();
+
+ UNICODE_STRING ntPath{};
+ OBJECT_ATTRIBUTES attributes{};
+ attributes.Length = sizeof(OBJECT_ATTRIBUTES);
+ attributes.ObjectName = &ntPath;
+ std::vector directoryHierarchy;
+ auto remainingPath = std::wstring_view(sectionPath.data(), sectionPath.length());
+ while (remainingPath.length() > 0)
+ {
+ // Find the next path substring, ignoring the root path backslash.
+ auto nextDir = remainingPath;
+ const auto separatorPos = nextDir.find(L"\\", remainingPath[0] == L'\\' ? 1 : 0);
+ if (separatorPos != std::wstring_view::npos)
+ {
+ nextDir = nextDir.substr(0, separatorPos);
+ remainingPath = remainingPath.substr(separatorPos + 1, std::wstring_view::npos);
+
+ // Skip concurrent backslashes.
+ while (remainingPath.length() > 0 && remainingPath[0] == L'\\')
+ {
+ remainingPath = remainingPath.substr(1, std::wstring_view::npos);
+ }
+ }
+ else
+ {
+ remainingPath = remainingPath.substr(remainingPath.length(), std::wstring_view::npos);
+ }
+
+ attributes.RootDirectory = directoryHierarchy.size() > 0 ? directoryHierarchy.back().get() : nullptr;
+ ntPath.Buffer = const_cast(nextDir.data());
+ ntPath.Length = sizeof(WCHAR) * gsl::narrow_cast(nextDir.length());
+ ntPath.MaximumLength = ntPath.Length;
+ wil::unique_handle nextHandle;
+ NTSTATUS status = ZwCreateDirectoryObject(&nextHandle, DIRECTORY_ALL_ACCESS, &attributes);
+ if (status == STATUS_OBJECT_NAME_COLLISION)
+ {
+ status = NtOpenDirectoryObject(&nextHandle, MAXIMUM_ALLOWED, &attributes);
+ }
+ THROW_IF_NTSTATUS_FAILED(status);
+ directoryHierarchy.emplace_back(std::move(nextHandle));
+ }
+
+ return {std::move(sectionPath), std::move(directoryHierarchy)};
+}
+
+wil::com_ptr GuestDeviceManager::GetRemoteFileSystem(_In_ REFCLSID clsid, _In_ std::wstring_view tag)
+{
+ THROW_HR_IF(E_NOT_VALID_STATE, !m_deviceHostSupport);
+ return m_deviceHostSupport->GetRemoteFileSystem(clsid, tag);
+}
+
+void GuestDeviceManager::Shutdown()
+try
+{
+ if (m_deviceHostSupport)
+ {
+ m_deviceHostSupport->Shutdown();
+ }
+}
+CATCH_LOG()
diff --git a/src/windows/service/exe/GuestDeviceManager.h b/src/windows/service/exe/GuestDeviceManager.h
new file mode 100644
index 0000000..f1afa99
--- /dev/null
+++ b/src/windows/service/exe/GuestDeviceManager.h
@@ -0,0 +1,72 @@
+// Copyright (C) Microsoft Corporation. All rights reserved.
+
+#pragma once
+
+#include "DeviceHostProxy.h"
+
+// Flags for virtiofs vdev device creation.
+#define VIRTIO_FS_FLAGS_TYPE_FILES 0x8000
+#define VIRTIO_FS_FLAGS_TYPE_SECTIONS 0x4000
+
+// {872270E1-A899-4AF6-B454-7193634435AD}
+DEFINE_GUID(VIRTIO_VIRTIOFS_DEVICE_ID, 0x872270E1, 0xA899, 0x4AF6, 0xB4, 0x54, 0x71, 0x93, 0x63, 0x44, 0x35, 0xAD);
+
+// {ABB755FC-1B86-4255-83E2-E5787ABCF6C2}
+DEFINE_GUID(VIRTIO_PMEM_CLASS_ID, 0xABB755FC, 0x1B86, 0x4255, 0x83, 0xe2, 0xe5, 0x78, 0x7a, 0xbc, 0xf6, 0xc2);
+
+inline const std::wstring c_defaultDeviceTag = L"default";
+
+//
+// Provides synchronized access to guest device operations.
+//
+class GuestDeviceManager
+{
+public:
+ GuestDeviceManager(_In_ const std::wstring& machineId, _In_ const GUID& runtimeId);
+
+ _Requires_lock_not_held_(m_lock)
+ GUID AddGuestDevice(
+ _In_ const GUID& DeviceId,
+ _In_ const GUID& ImplementationClsid,
+ _In_ PCWSTR AccessName,
+ _In_opt_ PCWSTR Options,
+ _In_ PCWSTR Path,
+ _In_ UINT32 Flags,
+ _In_ HANDLE UserToken);
+
+ GUID AddNewDevice(_In_ const GUID& deviceId, _In_ const wil::com_ptr& server, _In_ PCWSTR tag);
+
+ void AddRemoteFileSystem(_In_ REFCLSID clsid, _In_ PCWSTR tag, _In_ const wil::com_ptr& server);
+
+ void AddSharedMemoryDevice(_In_ const GUID& ImplementationClsid, _In_ PCWSTR Tag, _In_ PCWSTR Path, _In_ UINT32 SizeMb, _In_ HANDLE UserToken);
+
+ wil::com_ptr GetRemoteFileSystem(_In_ REFCLSID clsid, _In_ std::wstring_view tag);
+
+ void Shutdown();
+
+private:
+ _Requires_lock_held_(m_lock)
+ GUID AddHdvShareWithOptions(
+ _In_ const GUID& DeviceId,
+ _In_ const GUID& ImplementationClsid,
+ _In_ PCWSTR AccessName,
+ _In_opt_ PCWSTR Options,
+ _In_ PCWSTR Path,
+ _In_ UINT32 Flags,
+ _In_ HANDLE UserToken);
+
+ struct DirectoryObjectLifetime
+ {
+ std::wstring Path;
+ // Directory objects are temporary, even if they have children, so need to keep
+ // any created handles open in order for the directory to remain accessible.
+ std::vector HierarchyLifetimes;
+ };
+
+ DirectoryObjectLifetime CreateSectionObjectRoot(_In_ std::wstring_view RelativeRootPath, _In_ HANDLE UserToken) const;
+
+ wil::srwlock m_lock;
+ std::wstring m_machineId;
+ wil::com_ptr m_deviceHostSupport;
+ _Guarded_by_(m_lock) std::vector m_objectDirectories;
+};
diff --git a/src/windows/service/exe/VirtioNetworking.cpp b/src/windows/service/exe/VirtioNetworking.cpp
index 1d48b03..cb69244 100644
--- a/src/windows/service/exe/VirtioNetworking.cpp
+++ b/src/windows/service/exe/VirtioNetworking.cpp
@@ -2,6 +2,7 @@
#include "precomp.h"
#include "VirtioNetworking.h"
+#include "GuestDeviceManager.h"
#include "Stringify.h"
#include "stringshared.h"
@@ -13,15 +14,10 @@ using wsl::core::VirtioNetworking;
static constexpr auto c_loopbackDeviceName = TEXT(LX_INIT_LOOPBACK_DEVICE_NAME);
VirtioNetworking::VirtioNetworking(
- GnsChannel&& gnsChannel,
- bool enableLocalhostRelay,
- AddGuestDeviceCallback addGuestDeviceCallback,
- ModifyOpenPortsCallback modifyOpenPortsCallback,
- GuestInterfaceStateChangeCallback guestInterfaceStateChangeCallback) :
- m_addGuestDeviceCallback(std::move(addGuestDeviceCallback)),
+ GnsChannel&& gnsChannel, bool enableLocalhostRelay, std::shared_ptr guestDeviceManager, wil::shared_handle userToken) :
+ m_guestDeviceManager(std::move(guestDeviceManager)),
+ m_userToken(std::move(userToken)),
m_gnsChannel(std::move(gnsChannel)),
- m_modifyOpenPortsCallback(std::move(modifyOpenPortsCallback)),
- m_guestInterfaceStateChangeCallback(std::move(guestInterfaceStateChangeCallback)),
m_enableLocalhostRelay(enableLocalhostRelay)
{
}
@@ -72,11 +68,12 @@ try
device_options << L"nameservers=" << dns_servers;
}
- // Add virtio net adapter to guest
- m_adapterId = m_addGuestDeviceCallback(c_virtioNetworkClsid, c_virtioNetworkDeviceId, L"eth0", device_options.str().c_str());
-
auto lock = m_lock.lock_exclusive();
+ // Add virtio net adapter to guest
+ m_adapterId = m_guestDeviceManager->AddGuestDevice(
+ c_virtioNetworkDeviceId, c_virtioNetworkClsid, L"eth0", nullptr, device_options.str().c_str(), 0, m_userToken.get());
+
hns::HNSEndpoint endpointProperties;
endpointProperties.ID = m_adapterId;
endpointProperties.IPAddress = m_networkSettings->PreferredIpAddress.AddressString;
@@ -121,8 +118,14 @@ CATCH_LOG()
void VirtioNetworking::SetupLoopbackDevice()
{
- m_localhostAdapterId = m_addGuestDeviceCallback(
- c_virtioNetworkClsid, c_virtioNetworkDeviceId, c_loopbackDeviceName, L"client_ip=127.0.0.1;client_mac=00:11:22:33:44:55");
+ m_localhostAdapterId = m_guestDeviceManager->AddGuestDevice(
+ c_virtioNetworkDeviceId,
+ c_virtioNetworkClsid,
+ c_loopbackDeviceName,
+ nullptr,
+ L"client_ip=127.0.0.1;client_mac=00:11:22:33:44:55",
+ 0,
+ m_userToken.get());
hns::HNSEndpoint endpointProperties;
endpointProperties.ID = m_localhostAdapterId;
@@ -151,7 +154,7 @@ void VirtioNetworking::StartPortTracker(wil::unique_socket&& socket)
m_gnsPortTrackerChannel.emplace(
std::move(socket),
[&](const SOCKADDR_INET& addr, int protocol, bool allocate) { return HandlePortNotification(addr, protocol, allocate); },
- [&](_In_ const std::string& interfaceName, _In_ bool up) { m_guestInterfaceStateChangeCallback(interfaceName, up); });
+ [](const std::string&, bool) {}); // TODO: reconsider if InterfaceStateCallback is needed.
}
HRESULT VirtioNetworking::HandlePortNotification(const SOCKADDR_INET& addr, int protocol, bool allocate) const noexcept
@@ -185,21 +188,65 @@ HRESULT VirtioNetworking::HandlePortNotification(const SOCKADDR_INET& addr, int
localAddr.Ipv6.sin6_port = addr.Ipv6.sin6_port;
}
}
- result = m_modifyOpenPortsCallback(c_virtioNetworkClsid, c_loopbackDeviceName, localAddr, protocol, allocate);
+ result = ModifyOpenPorts(c_virtioNetworkClsid, c_loopbackDeviceName, localAddr, protocol, allocate);
LOG_HR_IF_MSG(E_FAIL, result != S_OK, "Failure adding localhost relay port %d", localAddr.Ipv4.sin_port);
}
+
if (!loopback)
{
- const int localResult = m_modifyOpenPortsCallback(c_virtioNetworkClsid, L"eth0", addr, protocol, allocate);
+ const int localResult = ModifyOpenPorts(c_virtioNetworkClsid, L"eth0", addr, protocol, allocate);
LOG_HR_IF_MSG(E_FAIL, localResult != S_OK, "Failure adding relay port %d", addr.Ipv4.sin_port);
if (result == 0)
{
result = localResult;
}
}
+
return result;
}
+int VirtioNetworking::ModifyOpenPorts(_In_ const GUID& clsid, _In_ PCWSTR tag, _In_ const SOCKADDR_INET& addr, _In_ int protocol, _In_ bool isOpen) const
+{
+ if (protocol != IPPROTO_TCP && protocol != IPPROTO_UDP)
+ {
+ LOG_HR_MSG(HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED), "Unsupported bind protocol %d", protocol);
+ return 0;
+ }
+ else if (addr.si_family == AF_INET6)
+ {
+ // The virtio net adapter does not yet support IPv6 packets, so any traffic would arrive via
+ // IPv4. If the caller wants IPv4 they will also likely listen on an IPv4 address, which will
+ // be handled as a separate callback to this same code.
+ return 0;
+ }
+
+ auto lock = m_lock.lock_exclusive();
+ const auto server = m_guestDeviceManager->GetRemoteFileSystem(clsid, c_defaultDeviceTag);
+ if (server)
+ {
+ std::wstring portString = std::format(L"tag={};port_number={}", tag, addr.Ipv4.sin_port);
+ if (protocol == IPPROTO_UDP)
+ {
+ portString += L";udp";
+ }
+
+ if (!isOpen)
+ {
+ portString += L";allocate=false";
+ }
+ else
+ {
+ wchar_t addrStr[16]; // "000.000.000.000" + null terminator
+ RtlIpv4AddressToStringW(&addr.Ipv4.sin_addr, addrStr);
+ portString += std::format(L";listen_addr={}", addrStr);
+ }
+
+ LOG_IF_FAILED(server->AddShare(portString.c_str(), nullptr, 0));
+ }
+
+ return 0;
+}
+
void NETIOAPI_API_ VirtioNetworking::OnNetworkConnectivityChange(PVOID context, NL_NETWORK_CONNECTIVITY_HINT hint)
{
static_cast(context)->RefreshGuestConnection(hint);
diff --git a/src/windows/service/exe/VirtioNetworking.h b/src/windows/service/exe/VirtioNetworking.h
index decae80..629afb2 100644
--- a/src/windows/service/exe/VirtioNetworking.h
+++ b/src/windows/service/exe/VirtioNetworking.h
@@ -6,22 +6,14 @@
#include "GnsChannel.h"
#include "WslCoreHostDnsInfo.h"
#include "GnsPortTrackerChannel.h"
+#include "GuestDeviceManager.h"
namespace wsl::core {
-using AddGuestDeviceCallback = std::function;
-using ModifyOpenPortsCallback = std::function;
-using GuestInterfaceStateChangeCallback = std::function;
-
class VirtioNetworking : public INetworkingEngine
{
public:
- VirtioNetworking(
- GnsChannel&& gnsChannel,
- bool enableLocalhostRelay,
- AddGuestDeviceCallback addGuestDeviceCallback,
- ModifyOpenPortsCallback modifyOpenPortsCallback,
- GuestInterfaceStateChangeCallback guestInterfaceStateChangeCallback);
+ VirtioNetworking(GnsChannel&& gnsChannel, bool enableLocalhostRelay, std::shared_ptr guestDeviceManager, wil::shared_handle userToken);
~VirtioNetworking() = default;
// Note: This class cannot be moved because m_networkNotifyHandle captures a 'this' pointer.
@@ -43,6 +35,7 @@ private:
static std::optional FindVirtioInterfaceLuid(const SOCKADDR_INET& virtioAddress, const NL_NETWORK_CONNECTIVITY_HINT& currentConnectivityHint);
HRESULT HandlePortNotification(const SOCKADDR_INET& addr, int protocol, bool allocate) const noexcept;
+ int ModifyOpenPorts(_In_ const GUID& clsid, _In_ PCWSTR tag, _In_ const SOCKADDR_INET& addr, _In_ int protocol, _In_ bool isOpen) const;
void RefreshGuestConnection(NL_NETWORK_CONNECTIVITY_HINT hint) noexcept;
void SetupLoopbackDevice();
void UpdateDns(wsl::shared::hns::DNS&& dnsSettings);
@@ -50,17 +43,14 @@ private:
mutable wil::srwlock m_lock;
- AddGuestDeviceCallback m_addGuestDeviceCallback;
+ std::shared_ptr m_guestDeviceManager;
+ wil::shared_handle m_userToken;
GnsChannel m_gnsChannel;
std::optional m_gnsPortTrackerChannel;
std::shared_ptr m_networkSettings;
bool m_enableLocalhostRelay;
GUID m_localhostAdapterId;
GUID m_adapterId;
- std::optional m_connectivityLevel;
- std::optional m_connectivityCost;
- ModifyOpenPortsCallback m_modifyOpenPortsCallback;
- GuestInterfaceStateChangeCallback m_guestInterfaceStateChangeCallback;
std::optional m_interfaceLuid;
ULONG m_networkMtu = 0;
diff --git a/src/windows/service/exe/WslCoreVm.cpp b/src/windows/service/exe/WslCoreVm.cpp
index f9a401c..343b818 100644
--- a/src/windows/service/exe/WslCoreVm.cpp
+++ b/src/windows/service/exe/WslCoreVm.cpp
@@ -39,18 +39,10 @@ using namespace std::string_literals;
// Start of unaddressable memory if guest only supports the minimum 36-bit addressing.
#define MAX_36_BIT_PAGE_IN_MB (0x1000000000 / _1MB)
-// This device type is implemented by the external virtiofs vdev.
-// {872270E1-A899-4AF6-B454-7193634435AD}
-DEFINE_GUID(VIRTIO_VIRTIOFS_DEVICE_ID, 0x872270E1, 0xA899, 0x4AF6, 0xB4, 0x54, 0x71, 0x93, 0x63, 0x44, 0x35, 0xAD);
-
// This device type is implemented by the external virtio-pmem vdev.
// {EDBB24BB-5E19-40F4-8A0F-8224313064FD}
DEFINE_GUID(VIRTIO_PMEM_DEVICE_ID, 0xEDBB24BB, 0x5E19, 0x40F4, 0x8A, 0x0F, 0x82, 0x24, 0x31, 0x30, 0x64, 0xFD);
-// Flags for virtiofs vdev device creation.
-#define VIRTIO_FS_FLAGS_TYPE_FILES 0x8000
-#define VIRTIO_FS_FLAGS_TYPE_SECTIONS 0x4000
-
// Version numbers for various functionality that was backported.
#define NICKEL_BUILD_FLOOR 22350
#define VIRTIO_SERIAL_CONSOLE_COBALT_RELEASE_UBR 40
@@ -65,9 +57,6 @@ static constexpr size_t c_bootEntropy = 0x1000;
static constexpr auto c_localDevicesKey = L"SOFTWARE\\Microsoft\\Terminal Server Client\\LocalDevices";
static constexpr std::pair c_schemaVersionNickel{2, 7};
-// {ABB755FC-1B86-4255-83E2-E5787ABCF6C2}
-static constexpr GUID c_pmemClassId = {0xABB755FC, 0x1B86, 0x4255, {0x83, 0xe2, 0xe5, 0x78, 0x7a, 0xbc, 0xf6, 0xc2}};
-
#define LXSS_ENABLE_GUI_APPS() (m_vmConfig.EnableGuiApps && (m_systemDistroDeviceId != ULONG_MAX))
using namespace wsl::windows::common;
@@ -78,8 +67,6 @@ using wsl::shared::Localization;
using wsl::windows::common::Context;
using wsl::windows::common::ExecutionContext;
-const std::wstring WslCoreVm::c_defaultTag = L"default"s;
-
namespace {
INT64
RequiredExtraMmioSpaceForPmemFileInMb(_In_ PCWSTR FilePath)
@@ -342,7 +329,8 @@ void WslCoreVm::Initialize(const GUID& VmId, const wil::shared_handle& UserToken
m_runtimeId = wsl::windows::common::hcs::GetRuntimeId(m_system.get());
WI_ASSERT(IsEqualGUID(VmId, m_runtimeId));
- m_deviceHostSupport = wil::MakeOrThrow(m_machineId, m_runtimeId);
+ // Initialize the guest device manager.
+ m_guestDeviceManager = std::make_shared(m_machineId, m_runtimeId);
// Create a socket listening for connections from mini_init.
m_listenSocket = wsl::windows::common::hvsocket::Listen(m_runtimeId, LX_INIT_UTILITY_VM_INIT_PORT);
@@ -469,7 +457,7 @@ void WslCoreVm::Initialize(const GUID& VmId, const wil::shared_handle& UserToken
break;
case LxMiniInitMountDeviceTypePmem:
- m_systemDistroDeviceId = MountFileAsPersistentMemory(c_pmemClassId, m_vmConfig.SystemDistroPath.c_str(), true);
+ m_systemDistroDeviceId = MountFileAsPersistentMemory(m_vmConfig.SystemDistroPath.c_str(), true);
break;
default:
@@ -608,15 +596,7 @@ void WslCoreVm::Initialize(const GUID& VmId, const wil::shared_handle& UserToken
else if (m_vmConfig.NetworkingMode == NetworkingMode::VirtioProxy)
{
m_networkingEngine = std::make_unique(
- std::move(gnsChannel),
- m_vmConfig.EnableLocalhostRelay,
- [this](const GUID& Clsid, const GUID& DeviceId, PCWSTR Tag, PCWSTR Options) {
- return HandleVirtioAddGuestDevice(Clsid, DeviceId, Tag, Options);
- },
- [this](const GUID& Clsid, PCWSTR Tag, const SOCKADDR_INET& Addr, int Protocol, bool IsOpen) {
- return HandleVirtioModifyOpenPorts(Clsid, Tag, Addr, Protocol, IsOpen);
- },
- [](const std::string&, bool) {});
+ std::move(gnsChannel), m_vmConfig.EnableLocalhostRelay, m_guestDeviceManager, m_userToken);
}
else if (m_vmConfig.NetworkingMode == NetworkingMode::Bridged)
{
@@ -799,9 +779,9 @@ WslCoreVm::~WslCoreVm() noexcept
}
// Shutdown virtio device hosts.
- if (m_deviceHostSupport)
+ if (m_guestDeviceManager)
{
- m_deviceHostSupport->Shutdown();
+ m_guestDeviceManager->Shutdown();
}
// Call RevokeVmAccess on each VHD that was added to the utility VM. This
@@ -955,7 +935,7 @@ void WslCoreVm::AddPlan9Share(
if (m_vmConfig.EnableVirtio9p)
{
- server = m_deviceHostSupport->GetRemoteFileSystem(__uuidof(p9fs::Plan9FileSystem), VirtIoTag);
+ server = m_guestDeviceManager->GetRemoteFileSystem(__uuidof(p9fs::Plan9FileSystem), VirtIoTag);
}
else
{
@@ -968,10 +948,10 @@ void WslCoreVm::AddPlan9Share(
if (!server)
{
- server = CreateComServerAsUser(UserToken);
+ server = wsl::windows::common::wslutil::CreateComServerAsUser(UserToken);
if (m_vmConfig.EnableVirtio9p)
{
- m_deviceHostSupport->AddRemoteFileSystem(__uuidof(p9fs::Plan9FileSystem), VirtIoTag, server);
+ m_guestDeviceManager->AddRemoteFileSystem(__uuidof(p9fs::Plan9FileSystem), VirtIoTag, server);
// Start with one device to handle the first mount request. After
// each mount, the Plan9 file-system will request additional
@@ -999,66 +979,10 @@ void WslCoreVm::AddPlan9Share(
if (addNewDevice)
{
// This requires more privileges than the user may have, so impersonation is disabled.
- (void)m_deviceHostSupport->AddNewDevice(VIRTIO_PLAN9_DEVICE_ID, server, VirtIoTag);
+ (void)m_guestDeviceManager->AddNewDevice(VIRTIO_PLAN9_DEVICE_ID, server, VirtIoTag);
}
}
-WslCoreVm::DirectoryObjectLifetime WslCoreVm::CreateSectionObjectRoot(_In_ std::wstring_view RelativeRootPath, _In_ HANDLE UserToken) const
-{
- auto revert = wil::impersonate_token(UserToken);
- DWORD sessionId;
- DWORD bytesWritten;
- THROW_LAST_ERROR_IF(!GetTokenInformation(GetCurrentThreadToken(), TokenSessionId, &sessionId, sizeof(sessionId), &bytesWritten));
-
- // /Sessions/1/BaseNamedObjects/WSL//
- std::wstringstream sectionPathBuilder;
- sectionPathBuilder << L"\\Sessions\\" << sessionId << L"\\BaseNamedObjects" << L"\\WSL\\" << m_machineId << L"\\" << RelativeRootPath;
- auto sectionPath = sectionPathBuilder.str();
-
- UNICODE_STRING ntPath{};
- OBJECT_ATTRIBUTES attributes{};
- attributes.Length = sizeof(OBJECT_ATTRIBUTES);
- attributes.ObjectName = &ntPath;
- std::vector directoryHierarchy;
- auto remainingPath = std::wstring_view(sectionPath.data(), sectionPath.length());
- while (remainingPath.length() > 0)
- {
- // Find the next path substring, ignoring the root path backslash.
- auto nextDir = remainingPath;
- const auto separatorPos = nextDir.find(L"\\", remainingPath[0] == L'\\' ? 1 : 0);
- if (separatorPos != std::wstring_view::npos)
- {
- nextDir = nextDir.substr(0, separatorPos);
- remainingPath = remainingPath.substr(separatorPos + 1, std::wstring_view::npos);
-
- // Skip concurrent backslashes.
- while (remainingPath.length() > 0 && remainingPath[0] == L'\\')
- {
- remainingPath = remainingPath.substr(1, std::wstring_view::npos);
- }
- }
- else
- {
- remainingPath = remainingPath.substr(remainingPath.length(), std::wstring_view::npos);
- }
-
- attributes.RootDirectory = directoryHierarchy.size() > 0 ? directoryHierarchy.back().get() : nullptr;
- ntPath.Buffer = const_cast(nextDir.data());
- ntPath.Length = sizeof(WCHAR) * gsl::narrow_cast(nextDir.length());
- ntPath.MaximumLength = ntPath.Length;
- wil::unique_handle nextHandle;
- NTSTATUS status = ZwCreateDirectoryObject(&nextHandle, DIRECTORY_ALL_ACCESS, &attributes);
- if (status == STATUS_OBJECT_NAME_COLLISION)
- {
- status = NtOpenDirectoryObject(&nextHandle, MAXIMUM_ALLOWED, &attributes);
- }
- THROW_IF_NTSTATUS_FAILED(status);
- directoryHierarchy.emplace_back(std::move(nextHandle));
- }
-
- return {std::move(sectionPath), std::move(directoryHierarchy)};
-}
-
ULONG WslCoreVm::AttachDisk(_In_ PCWSTR Disk, _In_ DiskType Type, _In_ std::optional Lun, _In_ bool IsUserDisk, _In_ HANDLE UserToken)
{
auto lock = m_lock.lock_exclusive();
@@ -1867,7 +1791,8 @@ void WslCoreVm::InitializeGuest()
{
try
{
- MountSharedMemoryDevice(c_virtiofsClassId, L"wslg", L"wslg", WSLG_SHARED_MEMORY_SIZE_MB);
+ m_guestDeviceManager->AddSharedMemoryDevice(
+ c_virtiofsClassId, L"wslg", L"wslg", WSLG_SHARED_MEMORY_SIZE_MB, m_userToken.get());
m_sharedMemoryRoot = std::format(L"WSL\\{}\\wslg", m_machineId);
}
CATCH_LOG()
@@ -1966,7 +1891,7 @@ bool WslCoreVm::InitializeDrvFsLockHeld(_In_ HANDLE UserToken)
{
// Before checking whether DrvFs is already initialized, make sure any existing Plan 9 servers
// are usable.
- VerifyDrvFsServers();
+ VerifyPlan9Servers();
const auto elevated = wsl::windows::common::security::IsTokenElevated(UserToken);
if (elevated)
@@ -2004,53 +1929,6 @@ bool WslCoreVm::IsVhdAttached(_In_ PCWSTR VhdPath)
return m_attachedDisks.contains({DiskType::VHD, VhdPath});
}
-GUID WslCoreVm::HandleVirtioAddGuestDevice(_In_ const GUID& Clsid, _In_ const GUID& DeviceId, _In_ PCWSTR Tag, _In_ PCWSTR Options)
-{
- auto guestDeviceLock = m_guestDeviceLock.lock_exclusive();
- return AddHdvShareWithOptions(DeviceId, Clsid, Tag, {}, Options, 0, m_userToken.get());
-}
-
-int WslCoreVm::HandleVirtioModifyOpenPorts(_In_ const GUID& Clsid, _In_ PCWSTR Tag, _In_ const SOCKADDR_INET& Addr, _In_ int Protocol, _In_ bool IsOpen)
-{
- if (Protocol != IPPROTO_TCP && Protocol != IPPROTO_UDP)
- {
- LOG_HR_MSG(HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED), "Unsupported bind protocol %d", Protocol);
- return 0;
- }
- else if (Addr.si_family == AF_INET6)
- {
- // The virtio net adapter does not yet support IPv6 packets, so any traffic would arrive via
- // IPv4. If the caller wants IPv4 they will also likely listen on an IPv4 address, which will
- // be handled as a separate callback to this same code.
- return 0;
- }
-
- auto guestDeviceLock = m_guestDeviceLock.lock_exclusive();
- const auto server = m_deviceHostSupport->GetRemoteFileSystem(Clsid, c_defaultTag);
- if (server)
- {
- std::wstring portString = std::format(L"tag={};port_number={}", Tag, Addr.Ipv4.sin_port);
- if (Protocol == IPPROTO_UDP)
- {
- portString += L";udp";
- }
-
- if (!IsOpen)
- {
- portString += L";allocate=false";
- }
- else
- {
- wchar_t addrStr[16]; // "000.000.000.000" + null terminator
- RtlIpv4AddressToStringW(&Addr.Ipv4.sin_addr, addrStr);
- portString += std::format(L";listen_addr={}", addrStr);
- }
-
- LOG_IF_FAILED(server->AddShare(portString.c_str(), nullptr, 0));
- }
- return 0;
-}
-
WslCoreVm::DiskMountResult WslCoreVm::MountDisk(
_In_ PCWSTR Disk, _In_ DiskType MountDiskType, _In_ ULONG PartitionIndex, _In_opt_ PCWSTR Name, _In_opt_ PCWSTR Type, _In_opt_ PCWSTR Options)
{
@@ -2150,33 +2028,8 @@ void WslCoreVm::MountRootNamespaceFolder(_In_ LPCWSTR HostPath, _In_ LPCWSTR Gue
ResultMessage.Result);
}
-void WslCoreVm::MountSharedMemoryDevice(_In_ const GUID& ImplementationClsid, _In_ PCWSTR Tag, _In_ PCWSTR Path, _In_ UINT32 SizeMb)
-{
- if (!m_vmConfig.EnableVirtio)
- {
- return;
- }
-
- auto guestDeviceLock = m_guestDeviceLock.lock_exclusive();
- MountSharedMemoryDeviceLockHeld(ImplementationClsid, Tag, Path, SizeMb);
-}
-
-_Requires_lock_held_(m_guestDeviceLock)
-void WslCoreVm::MountSharedMemoryDeviceLockHeld(_In_ const GUID& ImplementationClsid, _In_ PCWSTR Tag, _In_ PCWSTR Path, _In_ UINT32 SizeMb)
-{
- auto objectLifetime = CreateSectionObjectRoot(Path, m_userToken.get());
-
- // For virtiofs hdv, the flags parameter has been overloaded. Flags are placed in the lower
- // 16 bits, while the shared memory size in megabytes are placed in the upper 16 bits.
- static constexpr auto VIRTIO_FS_FLAGS_SHMEM_SIZE_SHIFT = 16;
- UINT32 flags = (SizeMb << VIRTIO_FS_FLAGS_SHMEM_SIZE_SHIFT);
- WI_SetFlag(flags, VIRTIO_FS_FLAGS_TYPE_SECTIONS);
- (void)AddHdvShare(VIRTIO_VIRTIOFS_DEVICE_ID, ImplementationClsid, Tag, objectLifetime.Path.c_str(), flags, m_userToken.get());
- m_objectDirectories.emplace_back(std::move(objectLifetime));
-}
-
ULONG
-WslCoreVm::MountFileAsPersistentMemory(_In_ const GUID& ImplementationClsid, _In_ PCWSTR FilePath, _In_ bool ReadOnly)
+WslCoreVm::MountFileAsPersistentMemory(_In_ PCWSTR FilePath, _In_ bool ReadOnly)
{
hcs::Plan9ShareFlags flags{};
@@ -2198,7 +2051,7 @@ WslCoreVm::MountFileAsPersistentMemory(_In_ const GUID& ImplementationClsid, _In
// a symlink that points to a path like:
// /sys/devices/LNXSYSTM:00/LNXSYBUS:00/ACPI0004:00/VMBUS:00//pcicceb:00//cceb:00:00.0/virtio1/ndbus0/region0/namespace0.0/block/pmem0
// Notice the GUID in the middle of that path. That GUID is the instance ID, which is randomly
- // generated by AddHdvShare. So once we find a path with the instance ID, we know that
+ // generated by AddGuestDevice. So once we find a path with the instance ID, we know that
// eventually /dev/pmemX will appear in the guest.
auto persistentMemoryLock = m_persistentMemoryLock.lock_exclusive();
@@ -2209,8 +2062,8 @@ WslCoreVm::MountFileAsPersistentMemory(_In_ const GUID& ImplementationClsid, _In
// added as part of VM creation and therefore any failure will result in VM termination
// (in which case there's no need to remove the device).
{
- auto guestDeviceLock = m_guestDeviceLock.lock_exclusive();
- (void)AddHdvShare(VIRTIO_PMEM_DEVICE_ID, ImplementationClsid, L"", FilePath, static_cast(flags), m_userToken.get());
+ (void)m_guestDeviceManager->AddGuestDevice(
+ VIRTIO_PMEM_DEVICE_ID, VIRTIO_PMEM_CLASS_ID, L"", nullptr, FilePath, static_cast(flags), m_userToken.get());
}
// Wait for the pmem device to appear in the VM at /dev/pmemX. Guess the value of X given the
@@ -2259,56 +2112,6 @@ void WslCoreVm::WaitForPmemDeviceInVm(_In_ ULONG PmemId)
}
}
-_Requires_lock_held_(m_guestDeviceLock)
-GUID WslCoreVm::AddHdvShareWithOptions(
- _In_ const GUID& DeviceId,
- _In_ const GUID& ImplementationClsid,
- _In_ std::wstring_view AccessName,
- _In_ std::wstring_view Options,
- _In_ std::wstring_view Path,
- _In_ UINT32 Flags,
- _In_ HANDLE UserToken)
-{
- wil::com_ptr server;
-
- THROW_HR_IF(E_NOTIMPL, !m_vmConfig.EnableVirtio);
-
- // Options are appended to the name with a semi-colon separator.
- // "name;key1=value1;key2=value2"
- // The AddSharePath implementation is responsible for separating them out and interpreting them.
- std::wstring nameWithOptions{AccessName};
- if (!Options.empty())
- {
- nameWithOptions += L";";
- nameWithOptions += Options;
- }
-
- {
- auto revert = wil::impersonate_token(UserToken);
-
- server = m_deviceHostSupport->GetRemoteFileSystem(ImplementationClsid, c_defaultTag);
- if (!server)
- {
- server = CreateComServerAsUser(ImplementationClsid, UserToken);
- m_deviceHostSupport->AddRemoteFileSystem(ImplementationClsid, c_defaultTag, server);
- }
-
- const std::wstring SharePath(Path);
- THROW_IF_FAILED(server->AddSharePath(nameWithOptions.c_str(), SharePath.c_str(), Flags));
- }
-
- // This requires more privileges than the user may have, so impersonation is disabled.
- const std::wstring VirtioTag(AccessName);
- return m_deviceHostSupport->AddNewDevice(DeviceId, server, VirtioTag.c_str());
-}
-
-_Requires_lock_held_(m_guestDeviceLock)
-GUID WslCoreVm::AddHdvShare(
- _In_ const GUID& DeviceId, _In_ const GUID& ImplementationClsid, _In_ PCWSTR AccessName, _In_ PCWSTR Path, _In_ UINT32 Flags, _In_ HANDLE UserToken)
-{
- return AddHdvShareWithOptions(DeviceId, ImplementationClsid, AccessName, {}, Path, Flags, UserToken);
-}
-
_Requires_lock_held_(m_guestDeviceLock)
std::wstring WslCoreVm::AddVirtioFsShare(_In_ bool Admin, _In_ PCWSTR Path, _In_ PCWSTR Options, _In_opt_ HANDLE UserToken)
{
@@ -2341,8 +2144,14 @@ std::wstring WslCoreVm::AddVirtioFsShare(_In_ bool Admin, _In_ PCWSTR Path, _In_
tag += std::to_wstring(m_virtioFsShares.size());
WI_ASSERT(!FindVirtioFsShare(tag.c_str(), Admin));
- (void)AddHdvShareWithOptions(
- VIRTIO_VIRTIOFS_DEVICE_ID, Admin ? c_virtiofsAdminClassId : c_virtiofsClassId, tag, key.OptionsString(), sharePath, VIRTIO_FS_FLAGS_TYPE_FILES, UserToken);
+ (void)m_guestDeviceManager->AddGuestDevice(
+ VIRTIO_VIRTIOFS_DEVICE_ID,
+ Admin ? c_virtiofsAdminClassId : c_virtiofsClassId,
+ tag.c_str(),
+ key.OptionsString().c_str(),
+ sharePath.c_str(),
+ VIRTIO_FS_FLAGS_TYPE_FILES,
+ UserToken);
m_virtioFsShares.emplace(std::move(key), tag);
created = true;
@@ -2690,7 +2499,7 @@ std::pair WslCoreVm::UnmountVolume(_In_ const AttachedD
}
_Requires_lock_held_(m_guestDeviceLock)
-void WslCoreVm::VerifyDrvFsServers()
+void WslCoreVm::VerifyPlan9Servers()
{
for (auto it = m_plan9Servers.begin(); it != m_plan9Servers.end();)
{
diff --git a/src/windows/service/exe/WslCoreVm.h b/src/windows/service/exe/WslCoreVm.h
index c2e2e37..496ae6e 100644
--- a/src/windows/service/exe/WslCoreVm.h
+++ b/src/windows/service/exe/WslCoreVm.h
@@ -29,6 +29,7 @@ Abstract:
#include "INetworkingEngine.h"
#include "SocketChannel.h"
#include "DeviceHostProxy.h"
+#include "GuestDeviceManager.h"
#define UTILITY_VM_SHUTDOWN_TIMEOUT (30 * 1000)
#define UTILITY_VM_TERMINATE_TIMEOUT (30 * 1000)
@@ -107,10 +108,6 @@ public:
bool IsVhdAttached(_In_ PCWSTR VhdPath);
- GUID HandleVirtioAddGuestDevice(_In_ const GUID& Clsid, _In_ const GUID& DeviceId, _In_ PCWSTR Tag, _In_ PCWSTR Options);
-
- int HandleVirtioModifyOpenPorts(_In_ const GUID& Clsid, _In_ PCWSTR Tag, _In_ const SOCKADDR_INET& Addr, _In_ int Protocol, _In_ bool IsOpen);
-
DiskMountResult MountDisk(
_In_ PCWSTR Disk, _In_ DiskType MountDiskType, _In_ ULONG PartitionIndex, _In_opt_ PCWSTR Name, _In_opt_ PCWSTR Type, _In_opt_ PCWSTR Options);
@@ -120,10 +117,8 @@ public:
ReadOnly = 0x1
};
- void MountSharedMemoryDevice(_In_ const GUID& ImplementationClsid, _In_ PCWSTR Tag, _In_ PCWSTR Path, _In_ UINT32 SizeMb);
-
ULONG
- MountFileAsPersistentMemory(_In_ const GUID& ImplementationClsid, _In_ PCWSTR FilePath, _In_ bool ReadOnly);
+ MountFileAsPersistentMemory(_In_ PCWSTR FilePath, _In_ bool ReadOnly);
void MountRootNamespaceFolder(_In_ LPCWSTR HostPath, _In_ LPCWSTR GuestPath, _In_ bool ReadOnly, _In_ LPCWSTR Name);
@@ -135,7 +130,7 @@ public:
void SaveAttachedDisksState();
_Requires_lock_held_(m_guestDeviceLock)
- void VerifyDrvFsServers();
+ void VerifyPlan9Servers();
enum DiskStateFlags
{
@@ -172,14 +167,6 @@ private:
DiskStateFlags Flags;
};
- struct DirectoryObjectLifetime
- {
- std::wstring Path;
- // Directory objects are temporary, even if they have children, so need to keep
- // any created handles open in order for the directory to remain accessible.
- std::vector HierarchyLifetimes;
- };
-
struct VirtioFsShare
{
VirtioFsShare(PCWSTR Path, PCWSTR Options, bool Admin);
@@ -202,19 +189,6 @@ private:
_Requires_lock_held_(m_guestDeviceLock)
void AddPlan9Share(_In_ PCWSTR AccessName, _In_ PCWSTR Path, _In_ UINT32 Port, _In_ wsl::windows::common::hcs::Plan9ShareFlags Flags, _In_ HANDLE UserToken, _In_ PCWSTR VirtIoTag);
- _Requires_lock_held_(m_guestDeviceLock)
- GUID AddHdvShare(_In_ const GUID& DeviceId, _In_ const GUID& ImplementationClsid, _In_ PCWSTR AccessName, _In_opt_ PCWSTR Path, _In_ UINT32 Flags, _In_ HANDLE UserToken);
-
- _Requires_lock_held_(m_guestDeviceLock)
- GUID AddHdvShareWithOptions(
- _In_ const GUID& DeviceId,
- _In_ const GUID& ImplementationClsid,
- _In_ std::wstring_view AccessName,
- _In_ std::wstring_view Options,
- _In_ std::wstring_view Path,
- _In_ UINT32 Flags,
- _In_ HANDLE UserToken);
-
_Requires_lock_held_(m_guestDeviceLock)
std::wstring AddVirtioFsShare(_In_ bool Admin, _In_ PCWSTR Path, _In_ PCWSTR Options, _In_opt_ HANDLE UserToken = nullptr);
@@ -223,19 +197,6 @@ private:
void CollectCrashDumps(wil::unique_socket&& socket) const;
- template
- wil::com_ptr_t CreateComServerAsUser(_In_ REFCLSID RefClsId, _In_ HANDLE UserToken)
- {
- auto revert = wil::impersonate_token(UserToken);
- return wil::CoCreateInstance(RefClsId, (CLSCTX_LOCAL_SERVER | CLSCTX_ENABLE_CLOAKING | CLSCTX_ENABLE_AAA));
- }
-
- template
- wil::com_ptr_t CreateComServerAsUser(_In_ HANDLE UserToken)
- {
- return CreateComServerAsUser(__uuidof(Class), UserToken);
- }
-
std::shared_ptr CreateInstanceInternal(
_In_ const GUID& InstanceId,
_In_ const LXSS_DISTRO_CONFIGURATION& Configuration,
@@ -245,8 +206,6 @@ private:
_In_ bool LaunchSystemDistro = false,
_Out_opt_ ULONG* ConnectPort = nullptr);
- DirectoryObjectLifetime CreateSectionObjectRoot(_In_ std::wstring_view RelativeRootPath, _In_ HANDLE UserToken) const;
-
_Requires_lock_held_(m_lock)
void EjectVhdLockHeld(_In_ PCWSTR VhdPath);
@@ -281,9 +240,6 @@ private:
DiskMountResult MountDiskLockHeld(
_In_ PCWSTR Disk, _In_ DiskType MountDiskType, _In_ ULONG PartitionIndex, _In_opt_ PCWSTR Name, _In_opt_ PCWSTR Type, _In_opt_ PCWSTR Options);
- _Requires_lock_held_(m_guestDeviceLock)
- void MountSharedMemoryDeviceLockHeld(_In_ const GUID& ImplementationClsid, _In_ PCWSTR Tag, _In_ PCWSTR Path, _In_ UINT32 SizeMb);
-
void WaitForPmemDeviceInVm(_In_ ULONG PmemId);
void OnCrash(_In_ LPCWSTR Details);
@@ -314,12 +270,14 @@ private:
static void CALLBACK s_OnExit(_In_ HCS_EVENT* Event, _In_opt_ void* Context);
- wil::srwlock m_lock;
wil::srwlock m_guestDeviceLock;
+ std::shared_ptr m_guestDeviceManager;
_Guarded_by_(m_guestDeviceLock) std::future m_drvfsInitialResult;
_Guarded_by_(m_guestDeviceLock) wil::unique_handle m_drvfsToken;
_Guarded_by_(m_guestDeviceLock) wil::unique_handle m_adminDrvfsToken;
_Guarded_by_(m_guestDeviceLock) std::map m_virtioFsShares;
+ _Guarded_by_(m_guestDeviceLock) std::map> m_plan9Servers;
+ wil::srwlock m_lock;
_Guarded_by_(m_lock) wil::unique_event m_terminatingEvent { wil::EventOptions::ManualReset };
_Guarded_by_(m_lock) wil::unique_event m_vmExitEvent { wil::EventOptions::ManualReset };
wil::unique_event m_vmCrashEvent{wil::EventOptions::ManualReset};
@@ -351,12 +309,9 @@ private:
wsl::shared::SocketChannel m_miniInitChannel;
wil::unique_socket m_notifyChannel;
SE_SID m_userSid;
- wil::com_ptr m_deviceHostSupport;
std::shared_ptr m_systemDistro;
_Guarded_by_(m_lock) std::bitset m_lunBitmap;
_Guarded_by_(m_lock) std::map m_attachedDisks;
- _Guarded_by_(m_guestDeviceLock) std::map> m_plan9Servers;
- _Guarded_by_(m_guestDeviceLock) std::vector m_objectDirectories;
std::tuple m_kernelVersion;
std::wstring m_kernelVersionString;
bool m_seccompAvailable;
@@ -375,8 +330,6 @@ private:
_Guarded_by_(m_persistentMemoryLock) ULONG m_nextPersistentMemoryId = 0;
std::unique_ptr m_networkingEngine;
-
- static const std::wstring c_defaultTag;
};
DEFINE_ENUM_FLAG_OPERATORS(WslCoreVm::DiskStateFlags);