master
cpp 222 lines 5.56 KB
Raw
1 /*++
2
3 Copyright (c) Microsoft. All rights reserved.
4
5 Module Name:
6
7 SessionSettings.cpp
8
9 Abstract:
10
11 This file contains the implementation of the WinRT wrapper for the WSLC SDK SessionSettings class.
12
13 --*/
14
15 #include "precomp.h"
16 #include "SessionSettings.h"
17 #include "Microsoft.WSL.Containers.SessionSettings.g.cpp"
18 #include "Session.h"
19
20 using namespace winrt::Windows::Foundation;
21
22 namespace winrt::Microsoft::WSL::Containers::implementation {
23 SessionSettings::SessionSettings(hstring const& name, hstring const& storagePath) : m_name(name), m_storagePath(storagePath)
24 {
25 if (name.empty())
26 {
27 throw winrt::hresult_invalid_argument(L"Session name cannot be empty");
28 }
29
30 if (storagePath.empty())
31 {
32 throw winrt::hresult_invalid_argument(L"Storage path cannot be empty");
33 }
34 }
35
36 hstring SessionSettings::Name()
37 {
38 return hstring(m_name);
39 }
40
41 void SessionSettings::Name(hstring const& value)
42 {
43 if (m_sessionSettings)
44 {
45 throw hresult_illegal_state_change(L"Cannot change session name after session has been initialized");
46 }
47
48 if (value.empty())
49 {
50 throw winrt::hresult_invalid_argument(L"Session name cannot be empty");
51 }
52
53 m_name = value;
54 }
55
56 hstring SessionSettings::StoragePath()
57 {
58 return hstring(m_storagePath);
59 }
60
61 void SessionSettings::StoragePath(hstring const& value)
62 {
63 if (m_sessionSettings)
64 {
65 throw hresult_illegal_state_change(L"Cannot change storage path after session has been initialized");
66 }
67
68 if (value.empty())
69 {
70 throw winrt::hresult_invalid_argument(L"Storage path cannot be empty");
71 }
72
73 m_storagePath = value;
74 }
75
76 IReference<uint32_t> SessionSettings::CpuCount()
77 {
78 return m_cpuCount;
79 }
80
81 void SessionSettings::CpuCount(IReference<uint32_t> const& value)
82 {
83 if (m_sessionSettings)
84 {
85 throw hresult_illegal_state_change(L"Cannot change CPU count after session has been initialized");
86 }
87
88 if (value && value.Value() == 0)
89 {
90 throw hresult_invalid_argument(L"CPU count cannot be 0");
91 }
92
93 m_cpuCount = value;
94 }
95
96 IReference<uint32_t> SessionSettings::MemorySizeInMB()
97 {
98 return m_memorySizeInMB;
99 }
100
101 void SessionSettings::MemorySizeInMB(IReference<uint32_t> const& value)
102 {
103 if (m_sessionSettings)
104 {
105 throw hresult_illegal_state_change(L"Cannot change memory size after session has been initialized");
106 }
107
108 if (value && value.Value() == 0)
109 {
110 throw hresult_invalid_argument(L"Memory size cannot be 0");
111 }
112
113 m_memorySizeInMB = value;
114 }
115
116 IReference<TimeSpan> SessionSettings::Timeout()
117 {
118 return m_timeout;
119 }
120
121 void SessionSettings::Timeout(IReference<TimeSpan> const& value)
122 {
123 if (m_sessionSettings)
124 {
125 throw hresult_illegal_state_change(L"Cannot change timeout after session has been initialized");
126 }
127
128 if (value)
129 {
130 if (value.Value() == TimeSpan::zero())
131 {
132 throw hresult_invalid_argument(L"Timeout cannot be 0");
133 }
134
135 // The C API takes the timeout in milliseconds as a uint32_t, so we need to validate that the value is within range.
136 auto timeoutMS = std::chrono::duration_cast<std::chrono::milliseconds>(value.Value()).count();
137 if (timeoutMS > std::numeric_limits<uint32_t>::max())
138 {
139 throw hresult_invalid_argument(L"Timeout exceeds the allowed limit");
140 }
141
142 if (timeoutMS < 0)
143 {
144 throw hresult_invalid_argument(L"Timeout cannot be negative");
145 }
146 }
147
148 m_timeout = value;
149 }
150
151 winrt::Microsoft::WSL::Containers::VhdOptions SessionSettings::VhdRequirements()
152 {
153 return m_vhdRequirements;
154 }
155
156 void SessionSettings::VhdRequirements(winrt::Microsoft::WSL::Containers::VhdOptions const& value)
157 {
158 if (m_sessionSettings)
159 {
160 throw hresult_illegal_state_change(L"Cannot change VHD requirements after session has been initialized");
161 }
162
163 if (!value)
164 {
165 throw winrt::hresult_error(E_POINTER, L"VHD requirements cannot be null");
166 }
167
168 m_vhdRequirements = value;
169 }
170
171 bool SessionSettings::EnableGpu()
172 {
173 return WI_IsFlagSet(m_featureFlags, WSLC_SESSION_FEATURE_FLAG_ENABLE_GPU);
174 }
175
176 void SessionSettings::EnableGpu(bool value)
177 {
178 if (m_sessionSettings)
179 {
180 throw hresult_illegal_state_change(L"Cannot change GPU setting after session has been initialized");
181 }
182
183 WI_UpdateFlag(m_featureFlags, WSLC_SESSION_FEATURE_FLAG_ENABLE_GPU, value);
184 }
185
186 WslcSessionSettings* SessionSettings::ToStructPointer()
187 {
188 if (m_sessionSettings)
189 {
190 return m_sessionSettings.get();
191 }
192
193 m_sessionSettings = std::make_unique<WslcSessionSettings>();
194 winrt::check_hresult(WslcInitSessionSettings(m_name.c_str(), m_storagePath.c_str(), m_sessionSettings.get()));
195
196 if (m_cpuCount)
197 {
198 winrt::check_hresult(WslcSetSessionSettingsCpuCount(m_sessionSettings.get(), m_cpuCount.Value()));
199 }
200
201 if (m_memorySizeInMB)
202 {
203 winrt::check_hresult(WslcSetSessionSettingsMemory(m_sessionSettings.get(), m_memorySizeInMB.Value()));
204 }
205
206 if (m_timeout)
207 {
208 auto timeoutMS = std::chrono::duration_cast<std::chrono::milliseconds>(m_timeout.Value()).count();
209 winrt::check_hresult(WslcSetSessionSettingsTimeout(m_sessionSettings.get(), static_cast<uint32_t>(timeoutMS)));
210 }
211
212 if (m_vhdRequirements)
213 {
214 winrt::check_hresult(WslcSetSessionSettingsVhd(m_sessionSettings.get(), GetStructPointer(m_vhdRequirements)));
215 }
216
217 winrt::check_hresult(WslcSetSessionSettingsFeatureFlags(m_sessionSettings.get(), m_featureFlags));
218
219 return m_sessionSettings.get();
220 }
221
222 } // namespace winrt::Microsoft::WSL::Containers::implementation