mirror of
https://github.com/microsoft/WSL.git
synced 2025-12-10 00:44:55 -06:00
cleanup: VirtioNetworking refactoring to be more portable (#13783)
* cleanup: VirtioNetworking refactoring to be more portable * more refactoring * make m_guestDeviceManager private --------- Co-authored-by: Ben Hillis <benhill@ntdev.microsoft.com>
This commit is contained in:
parent
b0df225c51
commit
4207cc80bd
@ -63,10 +63,10 @@ set(HEADERS
|
|||||||
disk.hpp
|
disk.hpp
|
||||||
Distribution.h
|
Distribution.h
|
||||||
filesystem.hpp
|
filesystem.hpp
|
||||||
|
HandleConsoleProgressBar.h
|
||||||
hcs.hpp
|
hcs.hpp
|
||||||
hcs_schema.h
|
hcs_schema.h
|
||||||
helpers.hpp
|
helpers.hpp
|
||||||
HandleConsoleProgressBar.h
|
|
||||||
interop.hpp
|
interop.hpp
|
||||||
ExecutionContext.h
|
ExecutionContext.h
|
||||||
socket.hpp
|
socket.hpp
|
||||||
|
|||||||
@ -78,6 +78,22 @@ void CoInitializeSecurity();
|
|||||||
|
|
||||||
void ConfigureCrt();
|
void ConfigureCrt();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a COM server with user impersonation.
|
||||||
|
/// </summary>
|
||||||
|
template <typename Interface>
|
||||||
|
wil::com_ptr_t<Interface> CreateComServerAsUser(_In_ REFCLSID RefClsId, _In_ HANDLE UserToken)
|
||||||
|
{
|
||||||
|
auto revert = wil::impersonate_token(UserToken);
|
||||||
|
return wil::CoCreateInstance<Interface>(RefClsId, (CLSCTX_LOCAL_SERVER | CLSCTX_ENABLE_CLOAKING | CLSCTX_ENABLE_AAA));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Class, typename Interface>
|
||||||
|
wil::com_ptr_t<Interface> CreateComServerAsUser(_In_ HANDLE UserToken)
|
||||||
|
{
|
||||||
|
return CreateComServerAsUser<Interface>(__uuidof(Class), UserToken);
|
||||||
|
}
|
||||||
|
|
||||||
std::wstring ConstructPipePath(_In_ std::wstring_view PipeName);
|
std::wstring ConstructPipePath(_In_ std::wstring_view PipeName);
|
||||||
|
|
||||||
GUID CreateV5Uuid(const GUID& namespaceGuid, const std::span<const std::byte> name);
|
GUID CreateV5Uuid(const GUID& namespaceGuid, const std::span<const std::byte> name);
|
||||||
|
|||||||
@ -17,6 +17,7 @@ set(SOURCES
|
|||||||
GnsChannel.cpp
|
GnsChannel.cpp
|
||||||
GnsPortTrackerChannel.cpp
|
GnsPortTrackerChannel.cpp
|
||||||
GnsRpcServer.cpp
|
GnsRpcServer.cpp
|
||||||
|
GuestDeviceManager.cpp
|
||||||
GuestTelemetryLogger.cpp
|
GuestTelemetryLogger.cpp
|
||||||
Lifetime.cpp
|
Lifetime.cpp
|
||||||
LxssConsoleManager.cpp
|
LxssConsoleManager.cpp
|
||||||
@ -56,6 +57,7 @@ set(HEADERS
|
|||||||
GnsChannel.h
|
GnsChannel.h
|
||||||
GnsPortTrackerChannel.h
|
GnsPortTrackerChannel.h
|
||||||
GnsRpcServer.h
|
GnsRpcServer.h
|
||||||
|
GuestDeviceManager.h
|
||||||
GuestTelemetryLogger.h
|
GuestTelemetryLogger.h
|
||||||
INetworkingEngine.h
|
INetworkingEngine.h
|
||||||
IMirroredNetworkManager.h
|
IMirroredNetworkManager.h
|
||||||
|
|||||||
149
src/windows/service/exe/GuestDeviceManager.cpp
Normal file
149
src/windows/service/exe/GuestDeviceManager.cpp
Normal file
@ -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<DeviceHostProxy>(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<IPlan9FileSystem> 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<IPlan9FileSystem>(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<IPlan9FileSystem>& 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<IPlan9FileSystem>& 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/<VM ID>/<Relative Path>
|
||||||
|
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<wil::unique_handle> 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<PWCH>(nextDir.data());
|
||||||
|
ntPath.Length = sizeof(WCHAR) * gsl::narrow_cast<USHORT>(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<IPlan9FileSystem> 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()
|
||||||
72
src/windows/service/exe/GuestDeviceManager.h
Normal file
72
src/windows/service/exe/GuestDeviceManager.h
Normal file
@ -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<IPlan9FileSystem>& server, _In_ PCWSTR tag);
|
||||||
|
|
||||||
|
void AddRemoteFileSystem(_In_ REFCLSID clsid, _In_ PCWSTR tag, _In_ const wil::com_ptr<IPlan9FileSystem>& server);
|
||||||
|
|
||||||
|
void AddSharedMemoryDevice(_In_ const GUID& ImplementationClsid, _In_ PCWSTR Tag, _In_ PCWSTR Path, _In_ UINT32 SizeMb, _In_ HANDLE UserToken);
|
||||||
|
|
||||||
|
wil::com_ptr<IPlan9FileSystem> 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<wil::unique_handle> HierarchyLifetimes;
|
||||||
|
};
|
||||||
|
|
||||||
|
DirectoryObjectLifetime CreateSectionObjectRoot(_In_ std::wstring_view RelativeRootPath, _In_ HANDLE UserToken) const;
|
||||||
|
|
||||||
|
wil::srwlock m_lock;
|
||||||
|
std::wstring m_machineId;
|
||||||
|
wil::com_ptr<DeviceHostProxy> m_deviceHostSupport;
|
||||||
|
_Guarded_by_(m_lock) std::vector<DirectoryObjectLifetime> m_objectDirectories;
|
||||||
|
};
|
||||||
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include "precomp.h"
|
#include "precomp.h"
|
||||||
#include "VirtioNetworking.h"
|
#include "VirtioNetworking.h"
|
||||||
|
#include "GuestDeviceManager.h"
|
||||||
#include "Stringify.h"
|
#include "Stringify.h"
|
||||||
#include "stringshared.h"
|
#include "stringshared.h"
|
||||||
|
|
||||||
@ -13,15 +14,10 @@ using wsl::core::VirtioNetworking;
|
|||||||
static constexpr auto c_loopbackDeviceName = TEXT(LX_INIT_LOOPBACK_DEVICE_NAME);
|
static constexpr auto c_loopbackDeviceName = TEXT(LX_INIT_LOOPBACK_DEVICE_NAME);
|
||||||
|
|
||||||
VirtioNetworking::VirtioNetworking(
|
VirtioNetworking::VirtioNetworking(
|
||||||
GnsChannel&& gnsChannel,
|
GnsChannel&& gnsChannel, bool enableLocalhostRelay, std::shared_ptr<GuestDeviceManager> guestDeviceManager, wil::shared_handle userToken) :
|
||||||
bool enableLocalhostRelay,
|
m_guestDeviceManager(std::move(guestDeviceManager)),
|
||||||
AddGuestDeviceCallback addGuestDeviceCallback,
|
m_userToken(std::move(userToken)),
|
||||||
ModifyOpenPortsCallback modifyOpenPortsCallback,
|
|
||||||
GuestInterfaceStateChangeCallback guestInterfaceStateChangeCallback) :
|
|
||||||
m_addGuestDeviceCallback(std::move(addGuestDeviceCallback)),
|
|
||||||
m_gnsChannel(std::move(gnsChannel)),
|
m_gnsChannel(std::move(gnsChannel)),
|
||||||
m_modifyOpenPortsCallback(std::move(modifyOpenPortsCallback)),
|
|
||||||
m_guestInterfaceStateChangeCallback(std::move(guestInterfaceStateChangeCallback)),
|
|
||||||
m_enableLocalhostRelay(enableLocalhostRelay)
|
m_enableLocalhostRelay(enableLocalhostRelay)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -72,11 +68,12 @@ try
|
|||||||
device_options << L"nameservers=" << dns_servers;
|
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();
|
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;
|
hns::HNSEndpoint endpointProperties;
|
||||||
endpointProperties.ID = m_adapterId;
|
endpointProperties.ID = m_adapterId;
|
||||||
endpointProperties.IPAddress = m_networkSettings->PreferredIpAddress.AddressString;
|
endpointProperties.IPAddress = m_networkSettings->PreferredIpAddress.AddressString;
|
||||||
@ -121,8 +118,14 @@ CATCH_LOG()
|
|||||||
|
|
||||||
void VirtioNetworking::SetupLoopbackDevice()
|
void VirtioNetworking::SetupLoopbackDevice()
|
||||||
{
|
{
|
||||||
m_localhostAdapterId = m_addGuestDeviceCallback(
|
m_localhostAdapterId = m_guestDeviceManager->AddGuestDevice(
|
||||||
c_virtioNetworkClsid, c_virtioNetworkDeviceId, c_loopbackDeviceName, L"client_ip=127.0.0.1;client_mac=00:11:22:33:44:55");
|
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;
|
hns::HNSEndpoint endpointProperties;
|
||||||
endpointProperties.ID = m_localhostAdapterId;
|
endpointProperties.ID = m_localhostAdapterId;
|
||||||
@ -151,7 +154,7 @@ void VirtioNetworking::StartPortTracker(wil::unique_socket&& socket)
|
|||||||
m_gnsPortTrackerChannel.emplace(
|
m_gnsPortTrackerChannel.emplace(
|
||||||
std::move(socket),
|
std::move(socket),
|
||||||
[&](const SOCKADDR_INET& addr, int protocol, bool allocate) { return HandlePortNotification(addr, protocol, allocate); },
|
[&](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
|
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;
|
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);
|
LOG_HR_IF_MSG(E_FAIL, result != S_OK, "Failure adding localhost relay port %d", localAddr.Ipv4.sin_port);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!loopback)
|
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);
|
LOG_HR_IF_MSG(E_FAIL, localResult != S_OK, "Failure adding relay port %d", addr.Ipv4.sin_port);
|
||||||
if (result == 0)
|
if (result == 0)
|
||||||
{
|
{
|
||||||
result = localResult;
|
result = localResult;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
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)
|
void NETIOAPI_API_ VirtioNetworking::OnNetworkConnectivityChange(PVOID context, NL_NETWORK_CONNECTIVITY_HINT hint)
|
||||||
{
|
{
|
||||||
static_cast<VirtioNetworking*>(context)->RefreshGuestConnection(hint);
|
static_cast<VirtioNetworking*>(context)->RefreshGuestConnection(hint);
|
||||||
|
|||||||
@ -6,22 +6,14 @@
|
|||||||
#include "GnsChannel.h"
|
#include "GnsChannel.h"
|
||||||
#include "WslCoreHostDnsInfo.h"
|
#include "WslCoreHostDnsInfo.h"
|
||||||
#include "GnsPortTrackerChannel.h"
|
#include "GnsPortTrackerChannel.h"
|
||||||
|
#include "GuestDeviceManager.h"
|
||||||
|
|
||||||
namespace wsl::core {
|
namespace wsl::core {
|
||||||
|
|
||||||
using AddGuestDeviceCallback = std::function<GUID(const GUID& clsid, const GUID& deviceId, PCWSTR tag, PCWSTR options)>;
|
|
||||||
using ModifyOpenPortsCallback = std::function<int(const GUID& clsid, PCWSTR tag, const SOCKADDR_INET& addr, int protocol, bool isOpen)>;
|
|
||||||
using GuestInterfaceStateChangeCallback = std::function<void(const std::string& name, bool isUp)>;
|
|
||||||
|
|
||||||
class VirtioNetworking : public INetworkingEngine
|
class VirtioNetworking : public INetworkingEngine
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
VirtioNetworking(
|
VirtioNetworking(GnsChannel&& gnsChannel, bool enableLocalhostRelay, std::shared_ptr<GuestDeviceManager> guestDeviceManager, wil::shared_handle userToken);
|
||||||
GnsChannel&& gnsChannel,
|
|
||||||
bool enableLocalhostRelay,
|
|
||||||
AddGuestDeviceCallback addGuestDeviceCallback,
|
|
||||||
ModifyOpenPortsCallback modifyOpenPortsCallback,
|
|
||||||
GuestInterfaceStateChangeCallback guestInterfaceStateChangeCallback);
|
|
||||||
~VirtioNetworking() = default;
|
~VirtioNetworking() = default;
|
||||||
|
|
||||||
// Note: This class cannot be moved because m_networkNotifyHandle captures a 'this' pointer.
|
// Note: This class cannot be moved because m_networkNotifyHandle captures a 'this' pointer.
|
||||||
@ -43,6 +35,7 @@ private:
|
|||||||
static std::optional<ULONGLONG> FindVirtioInterfaceLuid(const SOCKADDR_INET& virtioAddress, const NL_NETWORK_CONNECTIVITY_HINT& currentConnectivityHint);
|
static std::optional<ULONGLONG> FindVirtioInterfaceLuid(const SOCKADDR_INET& virtioAddress, const NL_NETWORK_CONNECTIVITY_HINT& currentConnectivityHint);
|
||||||
|
|
||||||
HRESULT HandlePortNotification(const SOCKADDR_INET& addr, int protocol, bool allocate) const noexcept;
|
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 RefreshGuestConnection(NL_NETWORK_CONNECTIVITY_HINT hint) noexcept;
|
||||||
void SetupLoopbackDevice();
|
void SetupLoopbackDevice();
|
||||||
void UpdateDns(wsl::shared::hns::DNS&& dnsSettings);
|
void UpdateDns(wsl::shared::hns::DNS&& dnsSettings);
|
||||||
@ -50,17 +43,14 @@ private:
|
|||||||
|
|
||||||
mutable wil::srwlock m_lock;
|
mutable wil::srwlock m_lock;
|
||||||
|
|
||||||
AddGuestDeviceCallback m_addGuestDeviceCallback;
|
std::shared_ptr<GuestDeviceManager> m_guestDeviceManager;
|
||||||
|
wil::shared_handle m_userToken;
|
||||||
GnsChannel m_gnsChannel;
|
GnsChannel m_gnsChannel;
|
||||||
std::optional<GnsPortTrackerChannel> m_gnsPortTrackerChannel;
|
std::optional<GnsPortTrackerChannel> m_gnsPortTrackerChannel;
|
||||||
std::shared_ptr<networking::NetworkSettings> m_networkSettings;
|
std::shared_ptr<networking::NetworkSettings> m_networkSettings;
|
||||||
bool m_enableLocalhostRelay;
|
bool m_enableLocalhostRelay;
|
||||||
GUID m_localhostAdapterId;
|
GUID m_localhostAdapterId;
|
||||||
GUID m_adapterId;
|
GUID m_adapterId;
|
||||||
std::optional<NL_NETWORK_CONNECTIVITY_LEVEL_HINT> m_connectivityLevel;
|
|
||||||
std::optional<NL_NETWORK_CONNECTIVITY_COST_HINT> m_connectivityCost;
|
|
||||||
ModifyOpenPortsCallback m_modifyOpenPortsCallback;
|
|
||||||
GuestInterfaceStateChangeCallback m_guestInterfaceStateChangeCallback;
|
|
||||||
|
|
||||||
std::optional<ULONGLONG> m_interfaceLuid;
|
std::optional<ULONGLONG> m_interfaceLuid;
|
||||||
ULONG m_networkMtu = 0;
|
ULONG m_networkMtu = 0;
|
||||||
|
|||||||
@ -39,18 +39,10 @@ using namespace std::string_literals;
|
|||||||
// Start of unaddressable memory if guest only supports the minimum 36-bit addressing.
|
// Start of unaddressable memory if guest only supports the minimum 36-bit addressing.
|
||||||
#define MAX_36_BIT_PAGE_IN_MB (0x1000000000 / _1MB)
|
#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.
|
// This device type is implemented by the external virtio-pmem vdev.
|
||||||
// {EDBB24BB-5E19-40F4-8A0F-8224313064FD}
|
// {EDBB24BB-5E19-40F4-8A0F-8224313064FD}
|
||||||
DEFINE_GUID(VIRTIO_PMEM_DEVICE_ID, 0xEDBB24BB, 0x5E19, 0x40F4, 0x8A, 0x0F, 0x82, 0x24, 0x31, 0x30, 0x64, 0xFD);
|
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.
|
// Version numbers for various functionality that was backported.
|
||||||
#define NICKEL_BUILD_FLOOR 22350
|
#define NICKEL_BUILD_FLOOR 22350
|
||||||
#define VIRTIO_SERIAL_CONSOLE_COBALT_RELEASE_UBR 40
|
#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 auto c_localDevicesKey = L"SOFTWARE\\Microsoft\\Terminal Server Client\\LocalDevices";
|
||||||
static constexpr std::pair<uint32_t, uint32_t> c_schemaVersionNickel{2, 7};
|
static constexpr std::pair<uint32_t, uint32_t> 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))
|
#define LXSS_ENABLE_GUI_APPS() (m_vmConfig.EnableGuiApps && (m_systemDistroDeviceId != ULONG_MAX))
|
||||||
|
|
||||||
using namespace wsl::windows::common;
|
using namespace wsl::windows::common;
|
||||||
@ -78,8 +67,6 @@ using wsl::shared::Localization;
|
|||||||
using wsl::windows::common::Context;
|
using wsl::windows::common::Context;
|
||||||
using wsl::windows::common::ExecutionContext;
|
using wsl::windows::common::ExecutionContext;
|
||||||
|
|
||||||
const std::wstring WslCoreVm::c_defaultTag = L"default"s;
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
INT64
|
INT64
|
||||||
RequiredExtraMmioSpaceForPmemFileInMb(_In_ PCWSTR FilePath)
|
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());
|
m_runtimeId = wsl::windows::common::hcs::GetRuntimeId(m_system.get());
|
||||||
WI_ASSERT(IsEqualGUID(VmId, m_runtimeId));
|
WI_ASSERT(IsEqualGUID(VmId, m_runtimeId));
|
||||||
|
|
||||||
m_deviceHostSupport = wil::MakeOrThrow<DeviceHostProxy>(m_machineId, m_runtimeId);
|
// Initialize the guest device manager.
|
||||||
|
m_guestDeviceManager = std::make_shared<GuestDeviceManager>(m_machineId, m_runtimeId);
|
||||||
|
|
||||||
// Create a socket listening for connections from mini_init.
|
// Create a socket listening for connections from mini_init.
|
||||||
m_listenSocket = wsl::windows::common::hvsocket::Listen(m_runtimeId, LX_INIT_UTILITY_VM_INIT_PORT);
|
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;
|
break;
|
||||||
|
|
||||||
case LxMiniInitMountDeviceTypePmem:
|
case LxMiniInitMountDeviceTypePmem:
|
||||||
m_systemDistroDeviceId = MountFileAsPersistentMemory(c_pmemClassId, m_vmConfig.SystemDistroPath.c_str(), true);
|
m_systemDistroDeviceId = MountFileAsPersistentMemory(m_vmConfig.SystemDistroPath.c_str(), true);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -608,15 +596,7 @@ void WslCoreVm::Initialize(const GUID& VmId, const wil::shared_handle& UserToken
|
|||||||
else if (m_vmConfig.NetworkingMode == NetworkingMode::VirtioProxy)
|
else if (m_vmConfig.NetworkingMode == NetworkingMode::VirtioProxy)
|
||||||
{
|
{
|
||||||
m_networkingEngine = std::make_unique<wsl::core::VirtioNetworking>(
|
m_networkingEngine = std::make_unique<wsl::core::VirtioNetworking>(
|
||||||
std::move(gnsChannel),
|
std::move(gnsChannel), m_vmConfig.EnableLocalhostRelay, m_guestDeviceManager, m_userToken);
|
||||||
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) {});
|
|
||||||
}
|
}
|
||||||
else if (m_vmConfig.NetworkingMode == NetworkingMode::Bridged)
|
else if (m_vmConfig.NetworkingMode == NetworkingMode::Bridged)
|
||||||
{
|
{
|
||||||
@ -799,9 +779,9 @@ WslCoreVm::~WslCoreVm() noexcept
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Shutdown virtio device hosts.
|
// 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
|
// Call RevokeVmAccess on each VHD that was added to the utility VM. This
|
||||||
@ -955,7 +935,7 @@ void WslCoreVm::AddPlan9Share(
|
|||||||
|
|
||||||
if (m_vmConfig.EnableVirtio9p)
|
if (m_vmConfig.EnableVirtio9p)
|
||||||
{
|
{
|
||||||
server = m_deviceHostSupport->GetRemoteFileSystem(__uuidof(p9fs::Plan9FileSystem), VirtIoTag);
|
server = m_guestDeviceManager->GetRemoteFileSystem(__uuidof(p9fs::Plan9FileSystem), VirtIoTag);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -968,10 +948,10 @@ void WslCoreVm::AddPlan9Share(
|
|||||||
|
|
||||||
if (!server)
|
if (!server)
|
||||||
{
|
{
|
||||||
server = CreateComServerAsUser<p9fs::Plan9FileSystem, IPlan9FileSystem>(UserToken);
|
server = wsl::windows::common::wslutil::CreateComServerAsUser<p9fs::Plan9FileSystem, IPlan9FileSystem>(UserToken);
|
||||||
if (m_vmConfig.EnableVirtio9p)
|
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
|
// Start with one device to handle the first mount request. After
|
||||||
// each mount, the Plan9 file-system will request additional
|
// each mount, the Plan9 file-system will request additional
|
||||||
@ -999,66 +979,10 @@ void WslCoreVm::AddPlan9Share(
|
|||||||
if (addNewDevice)
|
if (addNewDevice)
|
||||||
{
|
{
|
||||||
// This requires more privileges than the user may have, so impersonation is disabled.
|
// 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/<VM ID>/<Relative Path>
|
|
||||||
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<wil::unique_handle> 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<PWCH>(nextDir.data());
|
|
||||||
ntPath.Length = sizeof(WCHAR) * gsl::narrow_cast<USHORT>(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<ULONG> Lun, _In_ bool IsUserDisk, _In_ HANDLE UserToken)
|
ULONG WslCoreVm::AttachDisk(_In_ PCWSTR Disk, _In_ DiskType Type, _In_ std::optional<ULONG> Lun, _In_ bool IsUserDisk, _In_ HANDLE UserToken)
|
||||||
{
|
{
|
||||||
auto lock = m_lock.lock_exclusive();
|
auto lock = m_lock.lock_exclusive();
|
||||||
@ -1867,7 +1791,8 @@ void WslCoreVm::InitializeGuest()
|
|||||||
{
|
{
|
||||||
try
|
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);
|
m_sharedMemoryRoot = std::format(L"WSL\\{}\\wslg", m_machineId);
|
||||||
}
|
}
|
||||||
CATCH_LOG()
|
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
|
// Before checking whether DrvFs is already initialized, make sure any existing Plan 9 servers
|
||||||
// are usable.
|
// are usable.
|
||||||
VerifyDrvFsServers();
|
VerifyPlan9Servers();
|
||||||
|
|
||||||
const auto elevated = wsl::windows::common::security::IsTokenElevated(UserToken);
|
const auto elevated = wsl::windows::common::security::IsTokenElevated(UserToken);
|
||||||
if (elevated)
|
if (elevated)
|
||||||
@ -2004,53 +1929,6 @@ bool WslCoreVm::IsVhdAttached(_In_ PCWSTR VhdPath)
|
|||||||
return m_attachedDisks.contains({DiskType::VHD, 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(
|
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)
|
_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);
|
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
|
ULONG
|
||||||
WslCoreVm::MountFileAsPersistentMemory(_In_ const GUID& ImplementationClsid, _In_ PCWSTR FilePath, _In_ bool ReadOnly)
|
WslCoreVm::MountFileAsPersistentMemory(_In_ PCWSTR FilePath, _In_ bool ReadOnly)
|
||||||
{
|
{
|
||||||
hcs::Plan9ShareFlags flags{};
|
hcs::Plan9ShareFlags flags{};
|
||||||
|
|
||||||
@ -2198,7 +2051,7 @@ WslCoreVm::MountFileAsPersistentMemory(_In_ const GUID& ImplementationClsid, _In
|
|||||||
// a symlink that points to a path like:
|
// a symlink that points to a path like:
|
||||||
// /sys/devices/LNXSYSTM:00/LNXSYBUS:00/ACPI0004:00/VMBUS:00/<GUID>/pcicceb:00//cceb:00:00.0/virtio1/ndbus0/region0/namespace0.0/block/pmem0
|
// /sys/devices/LNXSYSTM:00/LNXSYBUS:00/ACPI0004:00/VMBUS:00/<GUID>/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
|
// 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.
|
// eventually /dev/pmemX will appear in the guest.
|
||||||
auto persistentMemoryLock = m_persistentMemoryLock.lock_exclusive();
|
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
|
// 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).
|
// (in which case there's no need to remove the device).
|
||||||
{
|
{
|
||||||
auto guestDeviceLock = m_guestDeviceLock.lock_exclusive();
|
(void)m_guestDeviceManager->AddGuestDevice(
|
||||||
(void)AddHdvShare(VIRTIO_PMEM_DEVICE_ID, ImplementationClsid, L"", FilePath, static_cast<UINT32>(flags), m_userToken.get());
|
VIRTIO_PMEM_DEVICE_ID, VIRTIO_PMEM_CLASS_ID, L"", nullptr, FilePath, static_cast<UINT32>(flags), m_userToken.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait for the pmem device to appear in the VM at /dev/pmemX. Guess the value of X given the
|
// 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<IPlan9FileSystem> 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<IPlan9FileSystem>(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)
|
_Requires_lock_held_(m_guestDeviceLock)
|
||||||
std::wstring WslCoreVm::AddVirtioFsShare(_In_ bool Admin, _In_ PCWSTR Path, _In_ PCWSTR Options, _In_opt_ HANDLE UserToken)
|
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());
|
tag += std::to_wstring(m_virtioFsShares.size());
|
||||||
WI_ASSERT(!FindVirtioFsShare(tag.c_str(), Admin));
|
WI_ASSERT(!FindVirtioFsShare(tag.c_str(), Admin));
|
||||||
|
|
||||||
(void)AddHdvShareWithOptions(
|
(void)m_guestDeviceManager->AddGuestDevice(
|
||||||
VIRTIO_VIRTIOFS_DEVICE_ID, Admin ? c_virtiofsAdminClassId : c_virtiofsClassId, tag, key.OptionsString(), sharePath, VIRTIO_FS_FLAGS_TYPE_FILES, UserToken);
|
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);
|
m_virtioFsShares.emplace(std::move(key), tag);
|
||||||
created = true;
|
created = true;
|
||||||
@ -2690,7 +2499,7 @@ std::pair<int, LX_MINI_MOUNT_STEP> WslCoreVm::UnmountVolume(_In_ const AttachedD
|
|||||||
}
|
}
|
||||||
|
|
||||||
_Requires_lock_held_(m_guestDeviceLock)
|
_Requires_lock_held_(m_guestDeviceLock)
|
||||||
void WslCoreVm::VerifyDrvFsServers()
|
void WslCoreVm::VerifyPlan9Servers()
|
||||||
{
|
{
|
||||||
for (auto it = m_plan9Servers.begin(); it != m_plan9Servers.end();)
|
for (auto it = m_plan9Servers.begin(); it != m_plan9Servers.end();)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -29,6 +29,7 @@ Abstract:
|
|||||||
#include "INetworkingEngine.h"
|
#include "INetworkingEngine.h"
|
||||||
#include "SocketChannel.h"
|
#include "SocketChannel.h"
|
||||||
#include "DeviceHostProxy.h"
|
#include "DeviceHostProxy.h"
|
||||||
|
#include "GuestDeviceManager.h"
|
||||||
|
|
||||||
#define UTILITY_VM_SHUTDOWN_TIMEOUT (30 * 1000)
|
#define UTILITY_VM_SHUTDOWN_TIMEOUT (30 * 1000)
|
||||||
#define UTILITY_VM_TERMINATE_TIMEOUT (30 * 1000)
|
#define UTILITY_VM_TERMINATE_TIMEOUT (30 * 1000)
|
||||||
@ -107,10 +108,6 @@ public:
|
|||||||
|
|
||||||
bool IsVhdAttached(_In_ PCWSTR VhdPath);
|
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(
|
DiskMountResult MountDisk(
|
||||||
_In_ PCWSTR Disk, _In_ DiskType MountDiskType, _In_ ULONG PartitionIndex, _In_opt_ PCWSTR Name, _In_opt_ PCWSTR Type, _In_opt_ PCWSTR Options);
|
_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
|
ReadOnly = 0x1
|
||||||
};
|
};
|
||||||
|
|
||||||
void MountSharedMemoryDevice(_In_ const GUID& ImplementationClsid, _In_ PCWSTR Tag, _In_ PCWSTR Path, _In_ UINT32 SizeMb);
|
|
||||||
|
|
||||||
ULONG
|
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);
|
void MountRootNamespaceFolder(_In_ LPCWSTR HostPath, _In_ LPCWSTR GuestPath, _In_ bool ReadOnly, _In_ LPCWSTR Name);
|
||||||
|
|
||||||
@ -135,7 +130,7 @@ public:
|
|||||||
void SaveAttachedDisksState();
|
void SaveAttachedDisksState();
|
||||||
|
|
||||||
_Requires_lock_held_(m_guestDeviceLock)
|
_Requires_lock_held_(m_guestDeviceLock)
|
||||||
void VerifyDrvFsServers();
|
void VerifyPlan9Servers();
|
||||||
|
|
||||||
enum DiskStateFlags
|
enum DiskStateFlags
|
||||||
{
|
{
|
||||||
@ -172,14 +167,6 @@ private:
|
|||||||
DiskStateFlags Flags;
|
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<wil::unique_handle> HierarchyLifetimes;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct VirtioFsShare
|
struct VirtioFsShare
|
||||||
{
|
{
|
||||||
VirtioFsShare(PCWSTR Path, PCWSTR Options, bool Admin);
|
VirtioFsShare(PCWSTR Path, PCWSTR Options, bool Admin);
|
||||||
@ -202,19 +189,6 @@ private:
|
|||||||
_Requires_lock_held_(m_guestDeviceLock)
|
_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);
|
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)
|
_Requires_lock_held_(m_guestDeviceLock)
|
||||||
std::wstring AddVirtioFsShare(_In_ bool Admin, _In_ PCWSTR Path, _In_ PCWSTR Options, _In_opt_ HANDLE UserToken = nullptr);
|
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;
|
void CollectCrashDumps(wil::unique_socket&& socket) const;
|
||||||
|
|
||||||
template <typename Interface>
|
|
||||||
wil::com_ptr_t<Interface> CreateComServerAsUser(_In_ REFCLSID RefClsId, _In_ HANDLE UserToken)
|
|
||||||
{
|
|
||||||
auto revert = wil::impersonate_token(UserToken);
|
|
||||||
return wil::CoCreateInstance<Interface>(RefClsId, (CLSCTX_LOCAL_SERVER | CLSCTX_ENABLE_CLOAKING | CLSCTX_ENABLE_AAA));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Class, typename Interface>
|
|
||||||
wil::com_ptr_t<Interface> CreateComServerAsUser(_In_ HANDLE UserToken)
|
|
||||||
{
|
|
||||||
return CreateComServerAsUser<Interface>(__uuidof(Class), UserToken);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr<LxssRunningInstance> CreateInstanceInternal(
|
std::shared_ptr<LxssRunningInstance> CreateInstanceInternal(
|
||||||
_In_ const GUID& InstanceId,
|
_In_ const GUID& InstanceId,
|
||||||
_In_ const LXSS_DISTRO_CONFIGURATION& Configuration,
|
_In_ const LXSS_DISTRO_CONFIGURATION& Configuration,
|
||||||
@ -245,8 +206,6 @@ private:
|
|||||||
_In_ bool LaunchSystemDistro = false,
|
_In_ bool LaunchSystemDistro = false,
|
||||||
_Out_opt_ ULONG* ConnectPort = nullptr);
|
_Out_opt_ ULONG* ConnectPort = nullptr);
|
||||||
|
|
||||||
DirectoryObjectLifetime CreateSectionObjectRoot(_In_ std::wstring_view RelativeRootPath, _In_ HANDLE UserToken) const;
|
|
||||||
|
|
||||||
_Requires_lock_held_(m_lock)
|
_Requires_lock_held_(m_lock)
|
||||||
void EjectVhdLockHeld(_In_ PCWSTR VhdPath);
|
void EjectVhdLockHeld(_In_ PCWSTR VhdPath);
|
||||||
|
|
||||||
@ -281,9 +240,6 @@ private:
|
|||||||
DiskMountResult MountDiskLockHeld(
|
DiskMountResult MountDiskLockHeld(
|
||||||
_In_ PCWSTR Disk, _In_ DiskType MountDiskType, _In_ ULONG PartitionIndex, _In_opt_ PCWSTR Name, _In_opt_ PCWSTR Type, _In_opt_ PCWSTR Options);
|
_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 WaitForPmemDeviceInVm(_In_ ULONG PmemId);
|
||||||
|
|
||||||
void OnCrash(_In_ LPCWSTR Details);
|
void OnCrash(_In_ LPCWSTR Details);
|
||||||
@ -314,12 +270,14 @@ private:
|
|||||||
|
|
||||||
static void CALLBACK s_OnExit(_In_ HCS_EVENT* Event, _In_opt_ void* Context);
|
static void CALLBACK s_OnExit(_In_ HCS_EVENT* Event, _In_opt_ void* Context);
|
||||||
|
|
||||||
wil::srwlock m_lock;
|
|
||||||
wil::srwlock m_guestDeviceLock;
|
wil::srwlock m_guestDeviceLock;
|
||||||
|
std::shared_ptr<GuestDeviceManager> m_guestDeviceManager;
|
||||||
_Guarded_by_(m_guestDeviceLock) std::future<bool> m_drvfsInitialResult;
|
_Guarded_by_(m_guestDeviceLock) std::future<bool> m_drvfsInitialResult;
|
||||||
_Guarded_by_(m_guestDeviceLock) wil::unique_handle m_drvfsToken;
|
_Guarded_by_(m_guestDeviceLock) wil::unique_handle m_drvfsToken;
|
||||||
_Guarded_by_(m_guestDeviceLock) wil::unique_handle m_adminDrvfsToken;
|
_Guarded_by_(m_guestDeviceLock) wil::unique_handle m_adminDrvfsToken;
|
||||||
_Guarded_by_(m_guestDeviceLock) std::map<VirtioFsShare, std::wstring> m_virtioFsShares;
|
_Guarded_by_(m_guestDeviceLock) std::map<VirtioFsShare, std::wstring> m_virtioFsShares;
|
||||||
|
_Guarded_by_(m_guestDeviceLock) std::map<UINT32, wil::com_ptr<IPlan9FileSystem>> 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_terminatingEvent { wil::EventOptions::ManualReset };
|
||||||
_Guarded_by_(m_lock) wil::unique_event m_vmExitEvent { wil::EventOptions::ManualReset };
|
_Guarded_by_(m_lock) wil::unique_event m_vmExitEvent { wil::EventOptions::ManualReset };
|
||||||
wil::unique_event m_vmCrashEvent{wil::EventOptions::ManualReset};
|
wil::unique_event m_vmCrashEvent{wil::EventOptions::ManualReset};
|
||||||
@ -351,12 +309,9 @@ private:
|
|||||||
wsl::shared::SocketChannel m_miniInitChannel;
|
wsl::shared::SocketChannel m_miniInitChannel;
|
||||||
wil::unique_socket m_notifyChannel;
|
wil::unique_socket m_notifyChannel;
|
||||||
SE_SID m_userSid;
|
SE_SID m_userSid;
|
||||||
wil::com_ptr<DeviceHostProxy> m_deviceHostSupport;
|
|
||||||
std::shared_ptr<LxssRunningInstance> m_systemDistro;
|
std::shared_ptr<LxssRunningInstance> m_systemDistro;
|
||||||
_Guarded_by_(m_lock) std::bitset<MAX_VHD_COUNT> m_lunBitmap;
|
_Guarded_by_(m_lock) std::bitset<MAX_VHD_COUNT> m_lunBitmap;
|
||||||
_Guarded_by_(m_lock) std::map<AttachedDisk, DiskState> m_attachedDisks;
|
_Guarded_by_(m_lock) std::map<AttachedDisk, DiskState> m_attachedDisks;
|
||||||
_Guarded_by_(m_guestDeviceLock) std::map<UINT32, wil::com_ptr<IPlan9FileSystem>> m_plan9Servers;
|
|
||||||
_Guarded_by_(m_guestDeviceLock) std::vector<DirectoryObjectLifetime> m_objectDirectories;
|
|
||||||
std::tuple<std::uint32_t, std::uint32_t, std::uint32_t> m_kernelVersion;
|
std::tuple<std::uint32_t, std::uint32_t, std::uint32_t> m_kernelVersion;
|
||||||
std::wstring m_kernelVersionString;
|
std::wstring m_kernelVersionString;
|
||||||
bool m_seccompAvailable;
|
bool m_seccompAvailable;
|
||||||
@ -375,8 +330,6 @@ private:
|
|||||||
_Guarded_by_(m_persistentMemoryLock) ULONG m_nextPersistentMemoryId = 0;
|
_Guarded_by_(m_persistentMemoryLock) ULONG m_nextPersistentMemoryId = 0;
|
||||||
|
|
||||||
std::unique_ptr<wsl::core::INetworkingEngine> m_networkingEngine;
|
std::unique_ptr<wsl::core::INetworkingEngine> m_networkingEngine;
|
||||||
|
|
||||||
static const std::wstring c_defaultTag;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
DEFINE_ENUM_FLAG_OPERATORS(WslCoreVm::DiskStateFlags);
|
DEFINE_ENUM_FLAG_OPERATORS(WslCoreVm::DiskStateFlags);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user