From a28015836b084bd5be993864165f6e7b33e2fdba Mon Sep 17 00:00:00 2001 From: Blue Date: Thu, 6 Nov 2025 18:57:03 -0800 Subject: [PATCH] Add stub methods --- msipackage/package.wix.in | 37 ++++++++++++- src/windows/wslaservice/exe/CMakeLists.txt | 4 ++ src/windows/wslaservice/exe/WSLAContainer.cpp | 55 +++++++++++++++++++ src/windows/wslaservice/exe/WSLAContainer.h | 38 +++++++++++++ src/windows/wslaservice/exe/WSLAProcess.cpp | 46 ++++++++++++++++ src/windows/wslaservice/exe/WSLAProcess.h | 38 +++++++++++++ src/windows/wslaservice/exe/WSLASession.cpp | 55 +++++++++++++++++++ src/windows/wslaservice/exe/WSLASession.h | 22 +++++++- .../wslaservice/exe/WSLAUserSession.cpp | 9 +++ src/windows/wslaservice/exe/WSLAUserSession.h | 4 +- src/windows/wslaservice/inc/wslaservice.idl | 12 ++-- test/windows/WSLATests.cpp | 37 +++++++++++++ 12 files changed, 347 insertions(+), 10 deletions(-) create mode 100644 src/windows/wslaservice/exe/WSLAContainer.cpp create mode 100644 src/windows/wslaservice/exe/WSLAContainer.h create mode 100644 src/windows/wslaservice/exe/WSLAProcess.cpp create mode 100644 src/windows/wslaservice/exe/WSLAProcess.h diff --git a/msipackage/package.wix.in b/msipackage/package.wix.in index 3bdfd34..f51bc8f 100644 --- a/msipackage/package.wix.in +++ b/msipackage/package.wix.in @@ -252,6 +252,18 @@ + + + + + + + + + + + + @@ -263,7 +275,6 @@ - @@ -286,6 +297,22 @@ + + + + + + + + + + + + + + + + @@ -294,6 +321,14 @@ + + + + + + + + diff --git a/src/windows/wslaservice/exe/CMakeLists.txt b/src/windows/wslaservice/exe/CMakeLists.txt index 46260d1..2795d76 100644 --- a/src/windows/wslaservice/exe/CMakeLists.txt +++ b/src/windows/wslaservice/exe/CMakeLists.txt @@ -2,6 +2,8 @@ set(SOURCES application.manifest main.rc ServiceMain.cpp + WSLAContainer.cpp + WSLAProcess.cpp WSLASession.cpp WSLAUserSession.cpp WSLAUserSessionFactory.cpp @@ -9,6 +11,8 @@ set(SOURCES ) set(HEADERS + WSLAContainer.h + WSLAProcess.h WSLASession.h WSLAUserSession.h WSLAUserSessionFactory.h diff --git a/src/windows/wslaservice/exe/WSLAContainer.cpp b/src/windows/wslaservice/exe/WSLAContainer.cpp new file mode 100644 index 0000000..1893c15 --- /dev/null +++ b/src/windows/wslaservice/exe/WSLAContainer.cpp @@ -0,0 +1,55 @@ +/*++ + +Copyright (c) Microsoft. All rights reserved. + +Module Name: + + WSLAContainer.cpp + +Abstract: + + Contains the implementation of WSLAContainer. + +--*/ + +#include "precomp.h" +#include "WSLAContainer.h" +#include "WSLAProcess.h" + +using wsl::windows::service::wsla::WSLAContainer; + +HRESULT WSLAContainer::Start() +{ + return E_NOTIMPL; +} + +HRESULT WSLAContainer::Stop(int Signal, ULONG TimeoutMs) +{ + return E_NOTIMPL; +} + +HRESULT WSLAContainer::Delete() +{ + return E_NOTIMPL; +} + +HRESULT WSLAContainer::GetState(WSLA_CONTAINER_STATE* State) +{ + return E_NOTIMPL; +} + +HRESULT WSLAContainer::GetInitProcess(IWSLAProcess** process) +{ + return E_NOTIMPL; +} + +HRESULT WSLAContainer::Exec(const WSLA_PROCESS_OPTIONS* Options, IWSLAProcess** Process) +try +{ + auto process = wil::MakeOrThrow(); + + process.CopyTo(__uuidof(IWSLAProcess), (void**)Process); + + return S_OK; +} +CATCH_RETURN(); diff --git a/src/windows/wslaservice/exe/WSLAContainer.h b/src/windows/wslaservice/exe/WSLAContainer.h new file mode 100644 index 0000000..b2ea881 --- /dev/null +++ b/src/windows/wslaservice/exe/WSLAContainer.h @@ -0,0 +1,38 @@ +/*++ + +Copyright (c) Microsoft. All rights reserved. + +Module Name: + + WSLAContainer.h + +Abstract: + + Contains the definition for WSLAContainer. + +--*/ + +#pragma once + +#include "wslaservice.h" + +namespace wsl::windows::service::wsla { + +class DECLSPEC_UUID("B1F1C4E3-C225-4CAE-AD8A-34C004DE1AE4") WSLAContainer + : public Microsoft::WRL::RuntimeClass, IWSLAContainer, IFastRundown> +{ +public: + WSLAContainer() = default; // TODO + WSLAContainer(const WSLAContainer&) = delete; + WSLAContainer& operator=(const WSLAContainer&) = delete; + + IFACEMETHOD(Start)() override; + IFACEMETHOD(Stop)(_In_ int Signal, _In_ ULONG TimeoutMs) override; + IFACEMETHOD(Delete)() override; + IFACEMETHOD(GetState)(_Out_ WSLA_CONTAINER_STATE* State) override; + IFACEMETHOD(GetInitProcess)(_Out_ IWSLAProcess** process) override; + IFACEMETHOD(Exec)(_In_ const WSLA_PROCESS_OPTIONS* Options, _Out_ IWSLAProcess** Process) override; + +private: +}; +} // namespace wsl::windows::service::wsla \ No newline at end of file diff --git a/src/windows/wslaservice/exe/WSLAProcess.cpp b/src/windows/wslaservice/exe/WSLAProcess.cpp new file mode 100644 index 0000000..6881cbe --- /dev/null +++ b/src/windows/wslaservice/exe/WSLAProcess.cpp @@ -0,0 +1,46 @@ +/*++ + +Copyright (c) Microsoft. All rights reserved. + +Module Name: + + WSLAProcess.cpp + +Abstract: + + Contains the implementation of WSLAProcess. + +--*/ + +#include "precomp.h" +#include "WSLAProcess.h" + +using wsl::windows::service::wsla::WSLAProcess; + +HRESULT WSLAProcess::Signal(int Signal) +{ + return E_NOTIMPL; +} + +HRESULT WSLAProcess::GetExitEvent(ULONG* Event) +try +{ + *Event = HandleToUlong(common::wslutil::DuplicateHandleToCallingProcess(m_exitEvent.get())); + return S_OK; +} +CATCH_RETURN(); + +HRESULT WSLAProcess::GetStdHandle(ULONG Index, ULONG* Handle) +{ + return E_NOTIMPL; +} + +HRESULT WSLAProcess::GetPid(int* Pid) +{ + return E_NOTIMPL; +} + +HRESULT WSLAProcess::GetState(WSLA_PROCESS_STATE* State, int* Code) +{ + return E_NOTIMPL; +} diff --git a/src/windows/wslaservice/exe/WSLAProcess.h b/src/windows/wslaservice/exe/WSLAProcess.h new file mode 100644 index 0000000..71d3122 --- /dev/null +++ b/src/windows/wslaservice/exe/WSLAProcess.h @@ -0,0 +1,38 @@ +/*++ + +Copyright (c) Microsoft. All rights reserved. + +Module Name: + + WSLAProcess.h + +Abstract: + + Contains the definition for WSLAProcess + +--*/ +#pragma once + +#include "wslaservice.h" + +namespace wsl::windows::service::wsla { + +class DECLSPEC_UUID("AFBEA6D6-D8A4-4F81-8FED-F947EB74B33B") WSLAProcess + : public Microsoft::WRL::RuntimeClass, IWSLAProcess, IFastRundown> +{ +public: + WSLAProcess() = default; // TODO + WSLAProcess(const WSLAProcess&) = delete; + WSLAProcess& operator=(const WSLAProcess&) = delete; + + IFACEMETHOD(Signal)(_In_ int Signal) override; + IFACEMETHOD(GetExitEvent)(_Out_ ULONG* Event) override; + IFACEMETHOD(GetStdHandle)(_In_ ULONG Index, _Out_ ULONG* Handle) override; + IFACEMETHOD(GetPid)(_Out_ int* Pid) override; + IFACEMETHOD(GetState)(_Out_ WSLA_PROCESS_STATE* State, _Out_ int* Code) override; + +private: + std::vector m_handles; + wil::unique_event m_exitEvent{wil::EventOptions::ManualReset}; +}; +} // namespace wsl::windows::service::wsla \ No newline at end of file diff --git a/src/windows/wslaservice/exe/WSLASession.cpp b/src/windows/wslaservice/exe/WSLASession.cpp index ae4b0de..ad6558f 100644 --- a/src/windows/wslaservice/exe/WSLASession.cpp +++ b/src/windows/wslaservice/exe/WSLASession.cpp @@ -12,8 +12,10 @@ Abstract: --*/ +#include "precomp.h" #include "WSLASession.h" #include "WSLAUserSession.h" +#include "WSLAContainer.h" using wsl::windows::service::wsla::WSLASession; @@ -32,8 +34,61 @@ HRESULT WSLASession::GetDisplayName(LPWSTR* DisplayName) return S_OK; } +HRESULT WSLASession::PullImage(LPCWSTR Image, const WSLA_REGISTRY_AUTHENTICATION_INFORMATION* RegistryInformation, IProgressCallback* ProgressCallback) +{ + return E_NOTIMPL; +} + +HRESULT WSLASession::ImportImage(ULONG Handle, LPCWSTR Image, IProgressCallback* ProgressCallback) +{ + return E_NOTIMPL; +} + +HRESULT WSLASession::ListImages(WSLA_IMAGE_INFORMATION** Images, ULONG* Count) +{ + return E_NOTIMPL; +} + +HRESULT WSLASession::DeleteImage(LPCWSTR Image) +{ + return E_NOTIMPL; +} + +HRESULT WSLASession::CreateContainer(const WSLA_CONTAINER_OPTIONS* Options, IWSLAContainer** Container) +try +{ + // Basic instanciation for testing. + // TODO: Implement. + + auto container = wil::MakeOrThrow(); + container.CopyTo(__uuidof(IWSLAContainer), (void**)Container); + + return S_OK; +} +CATCH_RETURN(); + +HRESULT WSLASession::OpenContainer(LPCWSTR Name, IWSLAContainer** Container) +{ + return E_NOTIMPL; +} + +HRESULT WSLASession::ListContainers(WSLA_CONTAINER** Images, ULONG* Count) +{ + return E_NOTIMPL; +} + HRESULT WSLASession::GetVirtualMachine(IWSLAVirtualMachine** VirtualMachine) { THROW_IF_FAILED(m_virtualMachine.QueryInterface(__uuidof(IWSLAVirtualMachine), (void**)VirtualMachine)); return S_OK; } + +HRESULT WSLASession::CreateRootNamespaceProcess(const WSLA_PROCESS_OPTIONS* Options, IWSLAProcess** VirtualMachine) +{ + return E_NOTIMPL; +} + +HRESULT WSLASession::FormatVirtualDisk(LPCWSTR Path) +{ + return E_NOTIMPL; +} diff --git a/src/windows/wslaservice/exe/WSLASession.h b/src/windows/wslaservice/exe/WSLASession.h index 71939ce..8eeb827 100644 --- a/src/windows/wslaservice/exe/WSLASession.h +++ b/src/windows/wslaservice/exe/WSLASession.h @@ -24,8 +24,26 @@ class DECLSPEC_UUID("4877FEFC-4977-4929-A958-9F36AA1892A4") WSLASession { public: WSLASession(const WSLA_SESSION_SETTINGS& Settings, WSLAUserSessionImpl& userSessionImpl, const VIRTUAL_MACHINE_SETTINGS& VmSettings); - IFACEMETHOD(GetDisplayName)(LPWSTR* DisplayName); - IFACEMETHOD(GetVirtualMachine)(IWSLAVirtualMachine** VirtualMachine); + + IFACEMETHOD(GetDisplayName)(LPWSTR* DisplayName) override; + + // Image management. + IFACEMETHOD(PullImage)(_In_ LPCWSTR Image, _In_ const WSLA_REGISTRY_AUTHENTICATION_INFORMATION* RegistryInformation, _In_ IProgressCallback* ProgressCallback) override; + IFACEMETHOD(ImportImage)(_In_ ULONG Handle, _In_ LPCWSTR Image, _In_ IProgressCallback* ProgressCallback) override; + IFACEMETHOD(ListImages)(_Out_ WSLA_IMAGE_INFORMATION** Images, _Out_ ULONG* Count) override; + IFACEMETHOD(DeleteImage)(_In_ LPCWSTR Image) override; + + // Container management. + IFACEMETHOD(CreateContainer)(_In_ const WSLA_CONTAINER_OPTIONS* Options, _Out_ IWSLAContainer** Container) override; + IFACEMETHOD(OpenContainer)(_In_ LPCWSTR Name, _In_ IWSLAContainer** Container) override; + IFACEMETHOD(ListContainers)(_Out_ WSLA_CONTAINER** Images, _Out_ ULONG* Count) override; + + // VM management. + IFACEMETHOD(GetVirtualMachine)(IWSLAVirtualMachine** VirtualMachine) override; + IFACEMETHOD(CreateRootNamespaceProcess)(_In_ const WSLA_PROCESS_OPTIONS* Options, _Out_ IWSLAProcess** VirtualMachine) override; + + // Disk management. + IFACEMETHOD(FormatVirtualDisk)(_In_ LPCWSTR Path) override; private: WSLA_SESSION_SETTINGS m_sessionSettings; // TODO: Revisit to see if we should have session settings as a member or not diff --git a/src/windows/wslaservice/exe/WSLAUserSession.cpp b/src/windows/wslaservice/exe/WSLAUserSession.cpp index d1c840c..63cf42c 100644 --- a/src/windows/wslaservice/exe/WSLAUserSession.cpp +++ b/src/windows/wslaservice/exe/WSLAUserSession.cpp @@ -113,3 +113,12 @@ try return session->CreateSession(Settings, VmSettings, WslaSession); } CATCH_RETURN(); + +HRESULT wsl::windows::service::wsla::WSLAUserSession::ListSessions(WSLA_SESSION_INFORMATION** Sessions, ULONG* SessionsCount) +{ + return E_NOTIMPL; +} +HRESULT wsl::windows::service::wsla::WSLAUserSession::OpenSession(ULONG Id, IWSLASession** Session) +{ + return E_NOTIMPL; +} diff --git a/src/windows/wslaservice/exe/WSLAUserSession.h b/src/windows/wslaservice/exe/WSLAUserSession.h index 7aa774f..22f610f 100644 --- a/src/windows/wslaservice/exe/WSLAUserSession.h +++ b/src/windows/wslaservice/exe/WSLAUserSession.h @@ -57,7 +57,9 @@ public: IFACEMETHOD(GetVersion)(_Out_ WSL_VERSION* Version) override; IFACEMETHOD(CreateVirtualMachine)(const VIRTUAL_MACHINE_SETTINGS* Settings, IWSLAVirtualMachine** VirtualMachine) override; // TODO: Remove virtual machine awareness from WSLAUserSession - IFACEMETHOD(CreateSession)(const WSLA_SESSION_SETTINGS* WslaSessionSettings, const VIRTUAL_MACHINE_SETTINGS* VmSettings, IWSLASession** WslaSession); + IFACEMETHOD(CreateSession)(const WSLA_SESSION_SETTINGS* WslaSessionSettings, const VIRTUAL_MACHINE_SETTINGS* VmSettings, IWSLASession** WslaSession) override; + IFACEMETHOD(ListSessions)(_Out_ WSLA_SESSION_INFORMATION** Sessions, _Out_ ULONG* SessionsCount) override; + IFACEMETHOD(OpenSession)(_In_ ULONG Id, _Out_ IWSLASession** Session) override; private: std::weak_ptr m_session; diff --git a/src/windows/wslaservice/inc/wslaservice.idl b/src/windows/wslaservice/inc/wslaservice.idl index 7db9e11..b4f6e61 100644 --- a/src/windows/wslaservice/inc/wslaservice.idl +++ b/src/windows/wslaservice/inc/wslaservice.idl @@ -159,8 +159,8 @@ struct WSLA_PORT_MAPPING struct WSLA_CONTAINER_OPTIONS { - LPCWSTR Image; - LPCWSTR Name; + LPCSTR Image; + LPCSTR Name; struct WSLA_PROCESS_OPTIONS* InitProcessOptions; [unique, size_is(VolumesCount)] struct WSLA_VOLUME* Volumes; ULONG VolumesCount; @@ -227,7 +227,7 @@ interface IWSLAContainer : IUnknown HRESULT Delete(); // TODO: Look into lifetime logic. HRESULT GetState([out] enum WSLA_CONTAINER_STATE* State); HRESULT GetInitProcess([out] IWSLAProcess** Process); - HRESULT Exec([in] struct WSLA_PROCESS_OPTIONS* Options, [out] IWSLAProcess** Process); + HRESULT Exec([in] const struct WSLA_PROCESS_OPTIONS* Options, [out] IWSLAProcess** Process); // Anonymous host port allocation (P1). //HRESULT AllocateHostPort([in] LPCSTR Name, [in] USHORT ContainerPort, [out] USHORT* AllocatedHostPort); @@ -242,18 +242,18 @@ interface IWSLAContainer : IUnknown interface IWSLASession : IUnknown { // Image management. - HRESULT PullImage([in] LPCWSTR Image, [in, unique] struct WSLA_REGISTRY_AUTHENTICATION_INFORMATION* RegistryInformation, [in, unique] IProgressCallback* ProgressCallback); + HRESULT PullImage([in] LPCWSTR Image, [in, unique] const struct WSLA_REGISTRY_AUTHENTICATION_INFORMATION* RegistryInformation, [in, unique] IProgressCallback* ProgressCallback); HRESULT ImportImage([in] ULONG Handle, [in] LPCWSTR Image, [in, unique] IProgressCallback* ProgressCallback); HRESULT ListImages([out, size_is(, *Count)] struct WSLA_IMAGE_INFORMATION** Images, [out] ULONG* Count); HRESULT DeleteImage([in] LPCWSTR Image); // Container management. - HRESULT CreateContainer([in] struct WSLA_CONTAINER_OPTIONS* Options, [out] IWSLAContainer** Container); + HRESULT CreateContainer([in] const struct WSLA_CONTAINER_OPTIONS* Options, [out] IWSLAContainer** Container); HRESULT OpenContainer([in] LPCWSTR Name, [out] IWSLAContainer** Container); HRESULT ListContainers([out, size_is(, *Count)] struct WSLA_CONTAINER** Images, [out] ULONG* Count); // Create a process at the VM level. This is meant for debugging. - HRESULT CreateRootNamespaceProcess([in] struct WSLA_PROCESS_OPTIONS* Options, [out] IWSLAProcess** Process); + HRESULT CreateRootNamespaceProcess([in] const struct WSLA_PROCESS_OPTIONS* Options, [out] IWSLAProcess** Process); // TODO: an OpenProcess() method can be added later if needed. diff --git a/test/windows/WSLATests.cpp b/test/windows/WSLATests.cpp index 6a37f43..7d11851 100644 --- a/test/windows/WSLATests.cpp +++ b/test/windows/WSLATests.cpp @@ -1131,4 +1131,41 @@ class WSLATests VERIFY_ARE_EQUAL(returnedDisplayName.get(), std::wstring(L"my-display-name")); } + + TEST_METHOD(WiringSmokeTest) + { + wil::com_ptr userSession; + VERIFY_SUCCEEDED(CoCreateInstance(__uuidof(WSLAUserSession), nullptr, CLSCTX_LOCAL_SERVER, IID_PPV_ARGS(&userSession))); + wsl::windows::common::security::ConfigureForCOMImpersonation(userSession.get()); + + WSLA_SESSION_SETTINGS settings{L"my-display-name"}; + wil::com_ptr session; + + VIRTUAL_MACHINE_SETTINGS vmSettings{}; + vmSettings.BootTimeoutMs = 30 * 1000; + vmSettings.DisplayName = L"WSLA"; + vmSettings.MemoryMb = 2048; + vmSettings.CpuCount = 4; + vmSettings.NetworkingMode = WslNetworkingModeNone; + vmSettings.EnableDebugShell = true; + + VERIFY_SUCCEEDED(userSession->CreateSession(&settings, &vmSettings, &session)); + + wil::com_ptr container; + WSLA_CONTAINER_OPTIONS containerOptions{}; + containerOptions.Image = "dummy"; + containerOptions.Name = "dummy"; + VERIFY_SUCCEEDED(session->CreateContainer(&containerOptions, &container)); + + wil::com_ptr process; + WSLA_PROCESS_OPTIONS processOptions{}; + processOptions.Executable = "dummy"; + VERIFY_SUCCEEDED(container->Exec(&processOptions, &process)); + + wil::unique_handle exitEvent; + VERIFY_SUCCEEDED(process->GetExitEvent(reinterpret_cast(exitEvent.addressof()))); + + // Verify that the event handle is valid. + VERIFY_ARE_EQUAL(WaitForSingleObject(exitEvent.get(), 0), WAIT_TIMEOUT); + } }; \ No newline at end of file