master
cpp 85 lines 2.44 KB
Raw
1 /*++
2
3 Copyright (c) Microsoft. All rights reserved.
4
5 Module Name:
6
7 WSLCSessionManagerFactory.cpp
8
9 Abstract:
10
11 Contains the implementation for WSLCSessionManagerFactory.
12
13 --*/
14
15 #include "precomp.h"
16
17 #include "WSLCSessionManagerFactory.h"
18 #include "WSLCSessionManager.h"
19 #include "wslpolicies.h"
20
21 using wsl::windows::service::wslc::WSLCSessionManagerFactory;
22 using wsl::windows::service::wslc::WSLCSessionManagerImpl;
23
24 CoCreatableClassWithFactory(WSLCSessionManager, WSLCSessionManagerFactory);
25
26 static std::mutex g_mutex;
27 static std::optional<WSLCSessionManagerImpl> g_sessionManagerImpl = std::make_optional<WSLCSessionManagerImpl>();
28 static Microsoft::WRL::ComPtr<WSLCSessionManager> g_sessionManager;
29
30 HRESULT WSLCSessionManagerFactory::CreateInstance(_In_ IUnknown* pUnkOuter, _In_ REFIID riid, _Out_ void** ppCreated)
31 {
32 RETURN_HR_IF_NULL(E_POINTER, ppCreated);
33 *ppCreated = nullptr;
34
35 RETURN_HR_IF(CLASS_E_NOAGGREGATION, pUnkOuter != nullptr);
36
37 WSL_LOG("WSLCSessionManagerFactory", TraceLoggingLevel(WINEVENT_LEVEL_VERBOSE));
38
39 try
40 {
41 wsl::windows::common::COMServiceExecutionContext context;
42
43 namespace policies = wsl::windows::policies;
44 THROW_HR_WITH_USER_ERROR_IF(
45 WSLC_E_CONTAINER_DISABLED,
46 wsl::shared::Localization::MessageWSLContainerDisabled(),
47 !policies::IsFeatureAllowed(policies::OpenPoliciesKey().get(), policies::c_allowWSLContainer));
48
49 std::lock_guard lock{g_mutex};
50
51 THROW_HR_IF(CO_E_SERVER_STOPPING, !g_sessionManagerImpl.has_value());
52
53 if (!g_sessionManager)
54 {
55 g_sessionManager = wil::MakeOrThrow<WSLCSessionManager>(&g_sessionManagerImpl.value());
56 }
57
58 THROW_IF_FAILED(g_sessionManager.CopyTo(riid, ppCreated));
59 }
60 catch (...)
61 {
62 const auto result = wil::ResultFromCaughtException();
63
64 // Note: S_FALSE will cause COM to retry if the service is stopping.
65 return result == CO_E_SERVER_STOPPING ? S_FALSE : result;
66 }
67
68 return S_OK;
69 }
70
71 void wsl::windows::service::wslc::ClearWslcSessionsAndBlockNewInstances()
72 {
73 std::lock_guard lock{g_mutex};
74
75 // Disconnect the COM instance from its implementation.
76 if (g_sessionManager)
77 {
78 g_sessionManager->Disconnect();
79 g_sessionManager.Reset();
80
81 // N.B. Callers might still have references to the COM instance. If that's the case, calls will all fail with RPC_E_DISCONNECTED.
82 }
83
84 g_sessionManagerImpl.reset();
85 }