| 1 | /*++ |
| 2 | |
| 3 | Copyright (c) Microsoft. All rights reserved. |
| 4 | |
| 5 | Module Name: |
| 6 | |
| 7 | WSLCSessionFactory.cpp |
| 8 | |
| 9 | Abstract: |
| 10 | |
| 11 | Implementation for WSLCSessionFactory. |
| 12 | |
| 13 | Creates WSLCSession objects in the per-user COM server process along with |
| 14 | their corresponding IWSLCSessionReference weak references for the SYSTEM |
| 15 | service to track session lifetime. |
| 16 | |
| 17 | --*/ |
| 18 | |
| 19 | #include "WSLCSessionFactory.h" |
| 20 | #include "WSLCSession.h" |
| 21 | #include "WSLCSessionReference.h" |
| 22 | #include "wslutil.h" |
| 23 | |
| 24 | namespace wslutil = wsl::windows::common::wslutil; |
| 25 | namespace wslc = wsl::windows::service::wslc; |
| 26 | |
| 27 | void wslc::WSLCSessionFactory::SetDestructionCallback(std::function<void()>&& callback) |
| 28 | { |
| 29 | m_destructionCallback = std::move(callback); |
| 30 | } |
| 31 | |
| 32 | HRESULT wslc::WSLCSessionFactory::CreateSession( |
| 33 | _In_ const WSLCSessionInitSettings* Settings, |
| 34 | _In_ IWSLCVirtualMachineFactory* VmFactory, |
| 35 | _In_ IWSLCPluginNotifier* PluginNotifier, |
| 36 | _In_opt_ IWarningCallback* WarningCallback, |
| 37 | _Out_ IWSLCSession** Session, |
| 38 | _Out_ IWSLCSessionReference** ServiceRef) |
| 39 | try |
| 40 | { |
| 41 | RETURN_HR_IF_NULL(E_POINTER, Session); |
| 42 | RETURN_HR_IF_NULL(E_POINTER, ServiceRef); |
| 43 | |
| 44 | *Session = nullptr; |
| 45 | *ServiceRef = nullptr; |
| 46 | |
| 47 | // Create the session object. |
| 48 | auto session = Microsoft::WRL::Make<wslc::WSLCSession>(); |
| 49 | |
| 50 | // Initialize the session with the VM factory (VMs are created on demand). |
| 51 | RETURN_IF_FAILED(session->Initialize(Settings, VmFactory, PluginNotifier, WarningCallback)); |
| 52 | |
| 53 | // Create the service session ref. It extracts metadata and a weak reference from the session. |
| 54 | auto serviceRef = Microsoft::WRL::Make<wslc::WSLCSessionReference>(session.Get()); |
| 55 | |
| 56 | // Return the session as IWSLCSession interface |
| 57 | RETURN_IF_FAILED(session->QueryInterface(IID_PPV_ARGS(Session))); |
| 58 | *ServiceRef = serviceRef.Detach(); |
| 59 | |
| 60 | // N.B. The destruction callback must be installed last, after all fallible operations. |
| 61 | // If installed earlier, an unwinding session local would fire the exit callback and race |
| 62 | // with the COM stub marshaling IErrorInfo back to the caller. |
| 63 | session->SetDestructionCallback(std::move(m_destructionCallback)); |
| 64 | |
| 65 | WSL_LOG( |
| 66 | "WSLCSessionFactoryCreatedSession", |
| 67 | TraceLoggingLevel(WINEVENT_LEVEL_INFO), |
| 68 | TraceLoggingUInt32(Settings->SessionId, "SessionId"), |
| 69 | TraceLoggingWideString(Settings->DisplayName, "DisplayName")); |
| 70 | |
| 71 | return S_OK; |
| 72 | } |
| 73 | CATCH_RETURN() |
| 74 | |
| 75 | HRESULT wslc::WSLCSessionFactory::InterfaceSupportsErrorInfo(_In_ REFIID riid) |
| 76 | { |
| 77 | return riid == __uuidof(IWSLCSessionFactory) ? S_OK : S_FALSE; |
| 78 | } |
| 79 | |
| 80 | HRESULT wslc::WSLCSessionFactory::GetProcessHandle(_Out_ HANDLE* ProcessHandle) |
| 81 | try |
| 82 | { |
| 83 | RETURN_HR_IF_NULL(E_POINTER, ProcessHandle); |
| 84 | |
| 85 | *ProcessHandle = wslutil::DuplicateHandle(GetCurrentProcess(), PROCESS_SET_QUOTA | PROCESS_TERMINATE); |
| 86 | return S_OK; |
| 87 | } |
| 88 | CATCH_RETURN() |