GCC Code Coverage Report


Directory: src/gate/
File: src/gate/tech/virtualization.c
Date: 2026-10-19 17:06:30
Exec Total Coverage
Lines: 18 207 8.7%
Functions: 3 27 11.1%
Branches: 6 84 7.1%

Line Branch Exec Source
1 /* GATE PROJECT LICENSE:
2 +----------------------------------------------------------------------------+
3 | Copyright(c) 2018-2026, Stefan Meislinger |
4 | All rights reserved. |
5 | |
6 | Redistribution and use in source and binary forms, with or without |
7 | modification, are permitted provided that the following conditions are met:|
8 | |
9 | 1. Redistributions of source code must retain the above copyright notice, |
10 | this list of conditions and the following disclaimer. |
11 | 2. Redistributions in binary form must reproduce the above copyright |
12 | notice, this list of conditions and the following disclaimer in the |
13 | documentation and/or other materials provided with the distribution. |
14 | |
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"|
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
18 | ARE DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
25 | THE POSSIBILITY OF SUCH DAMAGE. |
26 +----------------------------------------------------------------------------+
27 */
28
29 #include "gate/tech/virtualization.h"
30
31 #include "gate/results.h"
32
33
34 static gate_string_t const virtprov_name_lxc = GATE_STRING_INIT_STATIC("lxc");
35 static gate_string_t const virtprov_descr_lxc = GATE_STRING_INIT_STATIC("Linux-Containers");
36
37 static gate_string_t const virtprov_name_docker = GATE_STRING_INIT_STATIC("docker");
38 static gate_string_t const virtprov_descr_docker = GATE_STRING_INIT_STATIC("Docker");
39
40 #if defined(GATE_SYS_LINUX)
41 # define GATE_TECH_VIRTUALIZATION_LXC 1
42 #endif
43
44 #if defined(GATE_SYS_WIN) && !defined(GATE_SYS_WINCE) && !defined(GATE_SYS_WIN16)
45 # define GATE_TECH_VIRTUALIZATION_HYPERV2 1
46 # define GATE_TECH_VIRTUALIZATION_WSL 1
47 #endif
48
49 #define GATE_TECH_VIRTUALIZATION_DOCKER 1
50
51
52
53
54 #if defined(GATE_TECH_VIRTUALIZATION_LXC)
55
56 #include <stdlib.h>
57
58 #include "gate/tech/platform/gate_lxc.h"
59 #include "gate/utilities.h"
60 #include "gate/debugging.h"
61
62 static gate_lxc_functions_t lxc_code;
63 static gate_bool_t lxc_code_init;
64
65 1 static gate_result_t gate_lxc_init()
66 {
67 1 gate_result_t ret = GATE_RESULT_OK;
68
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (!lxc_code_init)
69 {
70 1 ret = gate_load_lxc_functions(&lxc_code);
71
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (GATE_SUCCEEDED(ret))
72 {
73 ✗ lxc_code_init = true;
74 }
75 }
76 1 return ret;
77 }
78
79 ✗ static void free_lxc_array(void** array, int count)
80 {
81 ✗ while(count-- > 0)
82 {
83 ✗ free(*array);
84 ✗ ++array;
85 }
86 ✗ }
87
88 /* LXC sandbox interface methods */
89
90 typedef struct lxcsbox_class
91 {
92 GATE_INTERFACE_VTBL(gate_virtualization_sandbox) const* vtbl;
93
94 gate_atomic_int_t ref_counter;
95 gate_string_t name;
96 gate_property_t settings;
97 } lxcsbox_t;
98
99 ✗ static void lxcsbox_destroy(lxcsbox_t* self)
100 {
101 ✗ gate_string_release(&self->name);
102 ✗ gate_property_destroy(&self->settings);
103 ✗ gate_mem_dealloc(self);
104 ✗ }
105
106 ✗ static char const* lxcsbox_get_interface_name(void* thisptr)
107 {
108 GATE_UNUSED_ARG(thisptr);
109 ✗ return GATE_INTERFACE_NAME_VIRTUALIZATION_SANDBOX;
110 }
111
112 ✗ static void lxcsbox_release(void* thisptr)
113 {
114 ✗ lxcsbox_t* const self = (lxcsbox_t*)thisptr;
115 ✗ if (gate_atomic_int_dec(&self->ref_counter) == 0)
116 {
117 ✗ lxcsbox_destroy(self);
118 }
119 ✗ }
120
121 ✗ static int lxcsbox_retain(void* thisptr)
122 {
123 ✗ lxcsbox_t* const self = (lxcsbox_t*)thisptr;
124 ✗ return gate_atomic_int_inc(&self->ref_counter);
125 }
126
127 ✗ static gate_result_t get_lxc_container_from_sandbox(lxcsbox_t* self, struct lxc_container** ptr_container)
128 {
129 gate_result_t ret;
130 ✗ gate_cstrbuffer_t buffer = GATE_INIT_EMPTY;
131 ✗ struct lxc_container* container = NULL;
132 do
133 {
134 ✗ if (NULL == gate_cstrbuffer_create_string(&buffer, &self->name, false))
135 {
136 ✗ GATE_DEBUG_TRACE("gate_cstrbuffer_create_string() failed");
137 ✗ ret = GATE_RESULT_OUTOFMEMORY;
138 ✗ break;
139 }
140 ✗ container = lxc_code.lxc_container_new(gate_cstrbuffer_get(&buffer), NULL);
141 ✗ if (NULL == container)
142 {
143 ✗ GATE_DEBUG_TRACE("lxc_container_new() failed");
144 ✗ ret = GATE_RESULT_FAILED;
145 ✗ break;
146 }
147 ✗ ret = GATE_RESULT_OK;
148 } while (0);
149 ✗ gate_cstrbuffer_destroy(&buffer);
150 ✗ *ptr_container = container;
151 ✗ return ret;
152 }
153
154 ✗ static void release_container(struct lxc_container** ptr_container)
155 {
156 ✗ GATE_DEBUG_ASSERT(ptr_container != NULL);
157 ✗ if (NULL != *ptr_container)
158 {
159 ✗ lxc_code.lxc_container_put(*ptr_container);
160 ✗ *ptr_container = NULL;
161 }
162 ✗ }
163
164 ✗ static gate_result_t lxcsbox_start(void* thisptr)
165 {
166 ✗ lxcsbox_t* const self = (lxcsbox_t*)thisptr;
167 ✗ gate_result_t ret = GATE_RESULT_NOTIMPLEMENTED;
168 ✗ struct lxc_container* ptr_container = NULL;
169 do
170 {
171 ✗ ret = get_lxc_container_from_sandbox(self, &ptr_container);
172 ✗ GATE_BREAK_IF_FAILED(ret);
173
174 ✗ if (!ptr_container->is_defined(ptr_container))
175 {
176 /* container not defined/existing */
177 ✗ ret = GATE_RESULT_NOTAVAILABLE;
178 ✗ break;
179 }
180
181 ✗ if (ptr_container->is_running(ptr_container))
182 {
183 /* container is already started -> start not supported */
184 ✗ ret = GATE_RESULT_INVALIDSTATE;
185 ✗ break;
186 }
187
188 ✗ if (!ptr_container->start(ptr_container, 0, NULL))
189 {
190 /* failed to start container */
191 ✗ ret = GATE_RESULT_FAILED;
192 ✗ break;
193 }
194
195 /* success case */
196 ✗ ret = GATE_RESULT_OK;
197 } while (0);
198
199 ✗ release_container(&ptr_container);
200 ✗ return ret;
201 }
202
203 ✗ static gate_result_t lxcsbox_stop(void* thisptr)
204 {
205 ✗ lxcsbox_t* const self = (lxcsbox_t*)thisptr;
206 ✗ gate_result_t ret = GATE_RESULT_NOTIMPLEMENTED;
207 ✗ struct lxc_container* ptr_container = NULL;
208 do
209 {
210 ✗ ret = get_lxc_container_from_sandbox(self, &ptr_container);
211 ✗ GATE_BREAK_IF_FAILED(ret);
212
213 ✗ if (!ptr_container->is_defined(ptr_container))
214 {
215 /* container not defined/existing */
216 ✗ ret = GATE_RESULT_NOTAVAILABLE;
217 ✗ break;
218 }
219
220 ✗ if (!ptr_container->is_running(ptr_container))
221 {
222 /* conainter is not running, stop not supported */
223 ✗ ret = GATE_RESULT_INVALIDSTATE;
224 ✗ break;
225 }
226
227 ✗ if (!ptr_container->stop(ptr_container))
228 {
229 /* failed to stop container */
230 ✗ ret = GATE_RESULT_FAILED;
231 ✗ break;
232 }
233
234 /* success case */
235 ✗ ret = GATE_RESULT_OK;
236 } while (0);
237
238 ✗ release_container(&ptr_container);
239 ✗ return ret;
240 }
241
242 ✗ static gate_enumint_t lxcsbox_get_status(void* thisptr)
243 {
244 ✗ lxcsbox_t* const self = (lxcsbox_t*)thisptr;
245 ✗ gate_enumint_t ret = GATE_VIRTUALIZATION_SANDBOX_STATUS_UNKNOWN;
246 ✗ struct lxc_container* ptr_container = NULL;
247 do
248 {
249 ✗ gate_result_t result = get_lxc_container_from_sandbox(self, &ptr_container);
250 ✗ GATE_BREAK_IF_FAILED(result);
251
252 ✗ if (!ptr_container->is_defined(ptr_container))
253 {
254 /* container not defined/existing */
255 ✗ ret = GATE_VIRTUALIZATION_SANDBOX_STATUS_UNKNOWN;
256 }
257 else
258 {
259 /* evaluate running state */
260 ✗ ret = ptr_container->is_running(ptr_container)
261 ? GATE_VIRTUALIZATION_SANDBOX_STATUS_ONLINE
262 ✗ : GATE_VIRTUALIZATION_SANDBOX_STATUS_OFFLINE
263 ;
264 }
265 } while (0);
266 ✗ release_container(&ptr_container);
267 ✗ return ret;
268 }
269
270 ✗ static gate_result_t lxcsbox_get_id(void* thisptr, gate_string_t* id)
271 {
272 ✗ lxcsbox_t* const self = (lxcsbox_t*)thisptr;
273 ✗ if (id)
274 {
275 ✗ gate_string_clone(id, &self->name);
276 }
277 ✗ return GATE_RESULT_OK;
278 }
279
280 ✗ static gate_result_t lxcsbox_get_name(void* thisptr, gate_string_t* name)
281 {
282 ✗ lxcsbox_t* const self = (lxcsbox_t*)thisptr;
283 ✗ if (name)
284 {
285 ✗ gate_string_clone(name, &self->name);
286 }
287 ✗ return GATE_RESULT_OK;
288 }
289
290 ✗ static gate_result_t lxcsbox_get_settings(void* thisptr, gate_property_t* settings)
291 {
292 ✗ lxcsbox_t* const self = (lxcsbox_t*)thisptr;
293 ✗ if (settings)
294 {
295 ✗ if (NULL == gate_property_copy(settings, &self->settings))
296 {
297 ✗ return GATE_RESULT_OUTOFMEMORY;
298 }
299 }
300 ✗ return GATE_RESULT_OK;
301 }
302
303 ✗ static gate_result_t lxcsbox_update_settings(void* thisptr, gate_property_t const* settings)
304 {
305 ✗ lxcsbox_t* const self = (lxcsbox_t*)thisptr;
306 ✗ gate_result_t ret = GATE_RESULT_NOTIMPLEMENTED;
307 (void)self;
308 /* TODO */
309 ✗ return ret;
310 }
311
312 ✗ static GATE_INTERFACE_VTBL(gate_virtualization_sandbox) const* lxcsbox_vtbl_init()
313 {
314 static GATE_INTERFACE_VTBL(gate_virtualization_sandbox) lxcsbox_vtbl;
315 ✗ if (lxcsbox_vtbl.get_interface_name == NULL)
316 {
317 GATE_INTERFACE_VTBL(gate_virtualization_sandbox) const vtbl = {
318 &lxcsbox_get_interface_name,
319 &lxcsbox_release,
320 &lxcsbox_retain,
321
322 &lxcsbox_start,
323 &lxcsbox_stop,
324 &lxcsbox_get_status,
325
326 &lxcsbox_get_id,
327 &lxcsbox_get_name,
328 &lxcsbox_get_settings,
329 &lxcsbox_update_settings
330 };
331 ✗ lxcsbox_vtbl = vtbl;
332 }
333 ✗ return &lxcsbox_vtbl;
334 }
335
336 ✗ static gate_result_t lxcsbox_create(gate_string_t const* name, lxcsbox_t** ptr_lxcsbox)
337 {
338 ✗ lxcsbox_t* ptr = (lxcsbox_t*)gate_mem_alloc(sizeof(lxcsbox_t));
339 ✗ if (NULL == ptr)
340 {
341 ✗ return GATE_RESULT_OUTOFMEMORY;
342 }
343 ✗ gate_mem_clear(ptr, sizeof(lxcsbox_t));
344 ✗ ptr->vtbl = lxcsbox_vtbl_init();
345 ✗ gate_atomic_int_init(&ptr->ref_counter, 1);
346 ✗ gate_string_clone(&ptr->name, name);
347 ✗ gate_property_create_object(&ptr->settings);
348 ✗ *ptr_lxcsbox = ptr;
349 ✗ return GATE_RESULT_OK;
350 }
351
352
353
354 /* LXC provider interface methods */
355
356 ✗ static char const* lxcprov_get_interface_name(void* obj)
357 {
358 GATE_UNUSED_ARG(obj);
359 ✗ return GATE_INTERFACE_NAME_VIRTUALIZATION_PROVIDER;
360 }
361 ✗ static void lxcprov_release(void* obj)
362 {
363 GATE_UNUSED_ARG(obj);
364 ✗ }
365 ✗ static int lxcprov_retain(void* obj)
366 {
367 GATE_UNUSED_ARG(obj);
368 ✗ return 1;
369 }
370 ✗ static gate_result_t lxcprov_get_name(void* obj, gate_string_t* name)
371 {
372 GATE_UNUSED_ARG(obj);
373 ✗ gate_string_create_static_len(name, "LXC", 3);
374 ✗ return GATE_RESULT_OK;
375 }
376 ✗ static gate_result_t lxcprov_get_settings(void* obj, gate_property_t* settings)
377 {
378 GATE_UNUSED_ARG(obj);
379 ✗ gate_property_create_object(settings);
380 ✗ return GATE_RESULT_OK;
381 }
382 ✗ static gate_result_t lxcprov_list_sandbox_ids(void* obj, gate_array_t* sandbox_ids)
383 {
384 GATE_UNUSED_ARG(obj);
385 ✗ gate_result_t ret = GATE_RESULT_FAILED;
386 ✗ char** names = NULL;
387 int found_containers;
388 ✗ gate_arraylist_t arr = GATE_INIT_EMPTY;
389
390 do
391 {
392 gate_size_t ndx;
393 ✗ char const* const lxcpath = NULL;
394 ✗ found_containers = lxc_code.list_all_containers(lxcpath, &names, NULL);
395 ✗ if (found_containers < 0)
396 {
397 ✗ ret = GATE_RESULT_FAILED;
398 ✗ break;
399 }
400
401 ✗ arr = gate_util_stringarray_create();
402 ✗ if (gate_arraylist_is_null(arr))
403 {
404 ✗ ret = GATE_RESULT_OUTOFMEMORY;
405 ✗ break;
406 }
407
408 ✗ for (ndx = 0; ndx < found_containers; ++ndx)
409 {
410 ✗ char const* name = names[ndx];
411 ✗ gate_util_stringarray_add_str(arr, name);
412 }
413
414 ✗ ret = GATE_RESULT_OK;
415 ✗ if (sandbox_ids)
416 {
417 ✗ if (NULL == gate_array_create(sandbox_ids, arr))
418 {
419 ✗ ret = GATE_RESULT_OUTOFMEMORY;
420 }
421 }
422 } while (0);
423
424 ✗ gate_arraylist_release(&arr);
425 ✗ if (names)
426 {
427 ✗ free_lxc_array((void**)names, found_containers);
428 }
429
430 ✗ return ret;
431 }
432
433 ✗ static gate_result_t lxcprov_get_sandbox(void* obj, gate_string_t const* sandbox_id, gate_virtualization_sandbox_t** ptr_sandbox)
434 {
435 ✗ lxcsbox_t* ptr = NULL;
436 ✗ gate_result_t result = lxcsbox_create(sandbox_id, &ptr);
437 ✗ if (GATE_SUCCEEDED(result))
438 {
439 ✗ if (ptr_sandbox)
440 {
441 ✗ *ptr_sandbox = (gate_virtualization_sandbox_t*)ptr;
442 }
443 else
444 {
445 ✗ gate_object_release(ptr);
446 }
447 }
448 ✗ return result;
449 }
450
451
452 ✗ static gate_virtualization_provider_t* init_global_lxc_provider()
453 {
454 static gate_virtualization_provider_t lxc_prov;
455 static GATE_INTERFACE_VTBL(gate_virtualization_provider) lxc_prov_vtbl;
456
457 ✗ if (lxc_prov.vtbl == NULL)
458 {
459 GATE_INTERFACE_VTBL(gate_virtualization_provider) const vtbl = {
460 &lxcprov_get_interface_name,
461 &lxcprov_release,
462 &lxcprov_retain,
463
464 &lxcprov_get_name,
465 &lxcprov_get_settings,
466
467 &lxcprov_list_sandbox_ids,
468 &lxcprov_get_sandbox
469 };
470 ✗ lxc_prov_vtbl = vtbl;
471 ✗ lxc_prov.vtbl = &lxc_prov_vtbl;
472 }
473 ✗ return &lxc_prov;
474 }
475
476 #endif /* GATE_TECH_VIRTUALIZATION_LXC */
477
478
479
480 #if defined(GATE_TECH_VIRTUALIZATION_HYPERV2)
481
482 #include "gate/system/management.h"
483 #include "gate/utilities.h"
484
485 static gate_string_t const virtprov_name_hyperv2 = GATE_STRING_INIT_STATIC("mshyperv2");
486 static gate_string_t const virtprov_descr_hyperv2 = GATE_STRING_INIT_STATIC("Microsoft Hyper-V v2");
487
488 static gate_string_t const wmi_default_host = GATE_STRING_INIT_STATIC(".");
489 static gate_string_t const wmi_default_namespace = GATE_STRING_INIT_STATIC("ROOT\\virtualization\\v2");
490 static gate_string_t const wmi_search_path = GATE_STRING_INIT_STATIC("\\\\.\\ROOT\\virtualization\\v2");
491
492
493 typedef struct mshv2sbox_class
494 {
495 GATE_INTERFACE_VTBL(gate_virtualization_sandbox) const* vtbl;
496
497 gate_atomic_int_t ref_counter;
498 gate_management_t mgmt;
499 gate_string_t vm_path;
500 } mshv2sbox_t;
501
502 static void mshv2sbox_destroy(mshv2sbox_t* self)
503 {
504 if (self->mgmt)
505 {
506 gate_management_close(self->mgmt);
507 }
508 gate_string_release(&self->vm_path);
509
510 gate_mem_clear(self, sizeof(mshv2sbox_t));
511 gate_mem_dealloc(self);
512 }
513
514 static char const* mshv2sbox_get_interface_name(void* thisptr)
515 {
516 mshv2sbox_t* const self = (mshv2sbox_t*)thisptr;
517 return GATE_INTERFACE_NAME_VIRTUALIZATION_SANDBOX;
518 }
519 static void mshv2sbox_release(void* thisptr)
520 {
521 mshv2sbox_t* const self = (mshv2sbox_t*)thisptr;
522 if (gate_atomic_int_dec(&self->ref_counter) == 0)
523 {
524 mshv2sbox_destroy(self);
525 }
526 }
527 static int mshv2sbox_retain(void* thisptr)
528 {
529 mshv2sbox_t* const self = (mshv2sbox_t*)thisptr;
530 return gate_atomic_int_inc(&self->ref_counter);
531 }
532
533
534 static gate_result_t mshv2sbox_change_state(mshv2sbox_t* self, gate_int32_t new_state)
535 {
536 gate_result_t ret;
537 gate_map_t input_args = GATE_INIT_EMPTY;
538 gate_map_t output_args = GATE_INIT_EMPTY;
539 do
540 {
541 static gate_string_t const methodname = GATE_STRING_INIT_STATIC("RequestStateChange");
542 static gate_string_t const param_requestedstate = GATE_STRING_INIT_STATIC("RequestedState");
543 static gate_string_t const param_returnvalue = GATE_STRING_INIT_STATIC("ReturnValue");
544 gate_value_t const* ptr_retval = NULL;
545
546 if (NULL == gate_util_stringvaluemap_create_ex(&input_args, true, true))
547 {
548 ret = GATE_RESULT_OUTOFMEMORY;
549 break;
550 }
551 gate_util_stringvaluemap_add_string(&input_args, &param_requestedstate, GATE_TYPE_I32, &new_state);
552
553 ret = gate_management_invoke(self->mgmt, &self->vm_path, &methodname, &input_args, &output_args);
554 GATE_BREAK_IF_FAILED(ret);
555
556 ptr_retval = gate_util_stringvaluemap_get_string(&output_args, &param_returnvalue);
557 if (ptr_retval)
558 {
559 /* evaluate WMI return value */
560 gate_int32_t const* ptr_intretval = (gate_int32_t const*)gate_value_get_ptr(ptr_retval);
561 if (ptr_intretval)
562 {
563 gate_int32_t const rv = *ptr_intretval;
564 if ((rv == 0) || (rv == 4096))
565 {
566 ret = GATE_RESULT_OK;
567 }
568 else
569 {
570 ret = GATE_RESULT_EXECUTIONFAILED;
571 }
572 }
573 }
574 } while (0);
575
576 gate_map_destroy(&input_args);
577 gate_map_destroy(&output_args);
578 return ret;
579 }
580
581 static gate_result_t mshv2sbox_start(void* thisptr)
582 {
583 mshv2sbox_t* const self = (mshv2sbox_t*)thisptr;
584 static int const state_enabled = 2;
585 return mshv2sbox_change_state(self, state_enabled);
586 }
587 static gate_result_t mshv2sbox_stop(void* thisptr)
588 {
589 mshv2sbox_t* const self = (mshv2sbox_t*)thisptr;
590 static int const state_disabled = 3;
591 return mshv2sbox_change_state(self, state_disabled);
592 }
593
594 #define MSHV2SBOX_STATE_UNKNOWN 0
595 #define MSHV2SBOX_STATE_OTHER 1
596 #define MSHV2SBOX_STATE_ENABLED 2
597 #define MSHV2SBOX_STATE_DISABLED 3
598 #define MSHV2SBOX_STATE_SHUTDOWN 4
599 #define MSHV2SBOX_STATE_NOTAPPLICABLE 5
600 #define MSHV2SBOX_STATE_OFFLINE 6
601 #define MSHV2SBOX_STATE_TEST 7
602 #define MSHV2SBOX_STATE_DEFERRED 8
603 #define MSHV2SBOX_STATE_QUIESCE 9
604 #define MSHV2SBOX_STATE_STARTING 10
605
606 static gate_enumint_t mshv2sbox_get_status(void* thisptr)
607 {
608 mshv2sbox_t* const self = (mshv2sbox_t*)thisptr;
609 gate_management_object_t obj = GATE_INIT_EMPTY;
610 gate_enumint_t ret = GATE_VIRTUALIZATION_SANDBOX_STATUS_UNKNOWN;
611
612 do
613 {
614 static gate_string_t const keyEnabledState = GATE_STRING_INIT_STATIC("EnabledState");
615 gate_map_iterator_t iter;
616 gate_result_t result = gate_management_get_object(self->mgmt, &self->vm_path, &obj);
617 GATE_BREAK_IF_FAILED(result);
618
619 iter = gate_map_get(&obj.properties, &keyEnabledState);
620 if (!gate_map_iterator_valid(iter))
621 {
622 ret = GATE_VIRTUALIZATION_SANDBOX_STATUS_UNKNOWN;
623 break;
624 }
625 else
626 {
627 gate_value_t const* ptr_value = (gate_value_t const*)gate_map_iterator_value(iter);
628 gate_int32_t const* ptr_state;
629 if (gate_value_type(ptr_value) != GATE_TYPE_I32)
630 {
631 break;
632 }
633 ptr_state = (gate_int32_t const*)gate_value_get_ptr(ptr_value);
634 switch (*ptr_state)
635 {
636 case MSHV2SBOX_STATE_UNKNOWN:
637 case MSHV2SBOX_STATE_OTHER:
638 ret = GATE_VIRTUALIZATION_SANDBOX_STATUS_UNKNOWN;
639 break;
640 case MSHV2SBOX_STATE_ENABLED:
641 case MSHV2SBOX_STATE_QUIESCE:
642 case MSHV2SBOX_STATE_OFFLINE:
643 ret = GATE_VIRTUALIZATION_SANDBOX_STATUS_ONLINE;
644 break;
645 case MSHV2SBOX_STATE_DISABLED:
646 ret = GATE_VIRTUALIZATION_SANDBOX_STATUS_OFFLINE;
647 break;
648 case MSHV2SBOX_STATE_SHUTDOWN:
649 case MSHV2SBOX_STATE_NOTAPPLICABLE:
650 case MSHV2SBOX_STATE_TEST:
651 case MSHV2SBOX_STATE_DEFERRED:
652 case MSHV2SBOX_STATE_STARTING:
653 ret = GATE_VIRTUALIZATION_SANDBOX_STATUS_BUSY;
654 break;
655 }
656 }
657 } while (0);
658
659 gate_management_object_release(&obj);
660 return ret;
661 }
662
663 static gate_result_t mshv2sbox_get_id(void* thisptr, gate_string_t* id)
664 {
665 mshv2sbox_t* const self = (mshv2sbox_t*)thisptr;
666 gate_result_t ret;
667 gate_management_object_t obj = GATE_INIT_EMPTY;
668
669 do
670 {
671 static gate_string_t const keyName = GATE_STRING_INIT_STATIC("Name");
672 gate_map_iterator_t iter;
673 gate_value_t const* value;
674 gate_string_t const* strvalue;
675
676 ret = gate_management_get_object(self->mgmt, &self->vm_path, &obj);
677 GATE_BREAK_IF_FAILED(ret);
678
679 iter = gate_map_get(&obj.properties, &keyName);
680 if (!gate_map_iterator_valid(iter))
681 {
682 ret = GATE_RESULT_NOTAVAILABLE;
683 break;
684 }
685 value = (gate_value_t const*)gate_map_iterator_value(iter);
686 if (gate_value_type(value) != GATE_TYPE_STRING)
687 {
688 ret = GATE_RESULT_INCORRECTTYPE;
689 break;
690 }
691 strvalue = (gate_string_t const*)gate_value_get_ptr(value);
692 if (NULL == gate_string_clone(id, strvalue))
693 {
694 ret = GATE_RESULT_OUTOFMEMORY;
695 break;
696 }
697 ret = GATE_RESULT_OK;
698 } while (0);
699 gate_management_object_release(&obj);
700 return ret;
701 }
702 static gate_result_t mshv2sbox_get_name(void* thisptr, gate_string_t* name)
703 {
704 mshv2sbox_t* const self = (mshv2sbox_t*)thisptr;
705 gate_result_t ret;
706 gate_management_object_t obj = GATE_INIT_EMPTY;
707
708 do
709 {
710 static gate_string_t const keyName = GATE_STRING_INIT_STATIC("ElementName");
711 gate_map_iterator_t iter;
712 gate_value_t const* value;
713 gate_string_t const* strvalue;
714
715 ret = gate_management_get_object(self->mgmt, &self->vm_path, &obj);
716 GATE_BREAK_IF_FAILED(ret);
717
718 iter = gate_map_get(&obj.properties, &keyName);
719 if (!gate_map_iterator_valid(iter))
720 {
721 ret = GATE_RESULT_NOTAVAILABLE;
722 break;
723 }
724 value = (gate_value_t const*)gate_map_iterator_value(iter);
725 if (gate_value_type(value) != GATE_TYPE_STRING)
726 {
727 ret = GATE_RESULT_INCORRECTTYPE;
728 break;
729 }
730 strvalue = (gate_string_t const*)gate_value_get_ptr(value);
731 if (NULL == gate_string_clone(name, strvalue))
732 {
733 ret = GATE_RESULT_OUTOFMEMORY;
734 break;
735 }
736 ret = GATE_RESULT_OK;
737 } while (0);
738 gate_management_object_release(&obj);
739 return ret;
740 }
741 static gate_result_t mshv2sbox_get_settings(void* thisptr, gate_property_t* settings)
742 {
743 mshv2sbox_t* const self = (mshv2sbox_t*)thisptr;
744 gate_result_t ret;
745 do
746 {
747 if (NULL == gate_property_create_object(settings))
748 {
749 ret = GATE_RESULT_OUTOFMEMORY;
750 break;
751 }
752 /* TODO */
753 ret = GATE_RESULT_OK;
754 } while (0);
755 return ret;
756 }
757 static gate_result_t mshv2sbox_update_settings(void* thisptr, gate_property_t const* settings)
758 {
759 mshv2sbox_t* const self = (mshv2sbox_t*)thisptr;
760 gate_result_t ret;
761 do
762 {
763 /* TODO */
764 ret = GATE_RESULT_NOTSUPPORTED;
765 } while (0);
766 return ret;
767 }
768
769 static GATE_INTERFACE_VTBL(gate_virtualization_sandbox)* mshv2sbox_vtbl_init()
770 {
771 static GATE_INTERFACE_VTBL(gate_virtualization_sandbox) vtbl;
772 if (vtbl.get_interface_name == NULL)
773 {
774 GATE_INTERFACE_VTBL(gate_virtualization_sandbox) v =
775 {
776 &mshv2sbox_get_interface_name,
777 &mshv2sbox_release,
778 &mshv2sbox_retain,
779
780 &mshv2sbox_start,
781 &mshv2sbox_stop,
782 &mshv2sbox_get_status,
783
784 &mshv2sbox_get_id,
785 &mshv2sbox_get_name,
786 &mshv2sbox_get_settings,
787 &mshv2sbox_update_settings
788 };
789 vtbl = v;
790 }
791 return &vtbl;
792 }
793
794
795 static gate_result_t mshv2sbox_create(gate_string_t const* path, mshv2sbox_t** ptr_obj)
796 {
797 gate_result_t ret;
798 gate_management_t mgmt;
799 mshv2sbox_t* sbox = NULL;
800
801 do
802 {
803 sbox = (mshv2sbox_t*)gate_mem_alloc(sizeof(mshv2sbox_t));
804 if (sbox == NULL)
805 {
806 ret = GATE_RESULT_OUTOFMEMORY;
807 break;
808 }
809
810 gate_mem_clear(sbox, sizeof(mshv2sbox_t));
811 sbox->vtbl = mshv2sbox_vtbl_init();
812 gate_atomic_int_init(&sbox->ref_counter, 1);
813
814 gate_string_clone(&sbox->vm_path, path);
815 ret = gate_management_open(&wmi_default_host, NULL, &wmi_default_namespace, 0, &sbox->mgmt);
816 GATE_BREAK_IF_FAILED(ret);
817
818 *ptr_obj = sbox;
819 sbox = NULL;
820 ret = GATE_RESULT_OK;
821 } while (0);
822
823 if (sbox != NULL)
824 {
825 mshv2sbox_destroy(sbox);
826 }
827
828 return ret;
829 }
830
831
832 typedef struct mshv2prov_class
833 {
834 GATE_INTERFACE_VTBL(gate_virtualization_provider) const* vtbl;
835
836 gate_atomic_int_t ref_counter;
837 gate_management_t mgmt;
838 } mshv2prov_t;
839
840 static void mshv2prov_destroy(mshv2prov_t* self)
841 {
842 if (NULL != self->mgmt)
843 {
844 gate_management_close(self->mgmt);
845 }
846 gate_mem_clear(self, sizeof(mshv2prov_t));
847 gate_mem_dealloc(self);
848 }
849
850 static char const* mshv2prov_get_interface_name(void* thisptr)
851 {
852 mshv2prov_t* self = (mshv2prov_t*)thisptr;
853 return GATE_INTERFACE_NAME_VIRTUALIZATION_PROVIDER;
854 }
855
856 static void mshv2prov_release(void* thisptr)
857 {
858 mshv2prov_t* const self = (mshv2prov_t*)thisptr;
859 if (0 == gate_atomic_int_dec(&self->ref_counter))
860 {
861 mshv2prov_destroy(self);
862 }
863 }
864
865 static int mshv2prov_retain(void* thisptr)
866 {
867 mshv2prov_t* const self = (mshv2prov_t*)thisptr;
868 return gate_atomic_int_inc(&self->ref_counter);
869 }
870
871 static gate_result_t mshv2prov_get_name(void* thisptr, gate_string_t* name)
872 {
873 mshv2prov_t* const self = (mshv2prov_t*)thisptr;
874 gate_string_duplicate(name, &virtprov_name_hyperv2);
875 return GATE_RESULT_OK;
876 }
877
878 static gate_result_t mshv2prov_get_settings(void* thisptr, gate_property_t* settings)
879 {
880 mshv2prov_t* const self = (mshv2prov_t*)thisptr;
881 if (NULL == gate_property_create_object(settings))
882 {
883 return GATE_RESULT_OUTOFMEMORY;
884 }
885 return GATE_RESULT_OK;
886 }
887
888 static gate_bool_t GATE_CALL mshv2prov_list_callback(gate_management_object_t const* mgmt_obj, void* user_param)
889 {
890 gate_arraylist_t* lst = (gate_arraylist_t*)user_param;
891 static gate_string_t const keyInstallDate = GATE_STRING_INIT_STATIC("InstallDate");
892 static gate_string_t const keyName = GATE_STRING_INIT_STATIC("Name");
893 gate_map_iterator_t iterDate = gate_map_get(&mgmt_obj->properties, &keyInstallDate);
894 gate_map_iterator_t iterName = gate_map_get(&mgmt_obj->properties, &keyName);
895 if (gate_map_iterator_valid(iterDate) && gate_map_iterator_valid(iterName))
896 {
897 gate_value_t const* val_name = gate_map_iterator_value(iterName);
898 if (val_name && (gate_value_type(val_name) == GATE_TYPE_STRING))
899 {
900 gate_string_t const* name = (gate_string_t const*)gate_value_get_ptr(val_name);
901 gate_arraylist_add(*lst, name);
902 }
903 }
904 return true;
905 }
906
907 static gate_string_t const search_query = GATE_STRING_INIT_STATIC("SELECT * FROM Msvm_ComputerSystem");
908
909 static gate_result_t mshv2prov_list_sandbox_ids(void* thisptr, gate_array_t* sandbox_ids)
910 {
911 mshv2prov_t* const self = (mshv2prov_t*)thisptr;
912 gate_result_t ret;
913 gate_arraylist_t lst = gate_util_stringarray_create();
914
915 do
916 {
917 if (gate_arraylist_is_null(lst))
918 {
919 ret = GATE_RESULT_OUTOFMEMORY;
920 break;
921 }
922
923 ret = gate_management_query(self->mgmt, &wmi_search_path, &search_query, &mshv2prov_list_callback, &lst);
924 GATE_BREAK_IF_FAILED(ret);
925
926 if (NULL == gate_array_create(sandbox_ids, lst))
927 {
928 ret = GATE_RESULT_OUTOFMEMORY;
929 break;
930 }
931
932 ret = GATE_RESULT_OK;
933 } while (0);
934
935 gate_arraylist_release(&lst);
936 return ret;
937 }
938
939 static gate_bool_t GATE_CALL mshv2prov_sandbox_callback(gate_management_object_t const* mgmt_obj, void* user_param)
940 {
941 gate_string_t* path = (gate_string_t*)user_param;
942 gate_string_clone(path, &mgmt_obj->path);
943 return false;
944 }
945
946 static gate_result_t mshv2prov_get_sandbox(void* thisptr, gate_string_t const* sandbox_id, gate_virtualization_sandbox_t** ptr_sandbox)
947 {
948 mshv2prov_t* const self = (mshv2prov_t*)thisptr;
949 mshv2sbox_t* mshv2sbox = NULL;
950 gate_result_t result;
951 gate_strbuilder_t builder;
952 gate_string_t query = GATE_STRING_INIT_EMPTY;
953 gate_string_t found_path = GATE_STRING_INIT_EMPTY;
954 char buffer[1024];
955
956 do
957 {
958 gate_strbuilder_create_static(&builder, buffer, sizeof(buffer), 0);
959
960 gate_strbuilder_append_string(&builder, &search_query);
961 gate_strbuilder_append_cstr(&builder, " WHERE Name=\"");
962 gate_strbuilder_append_string(&builder, sandbox_id);
963 gate_strbuilder_append_cstr(&builder, "\"");
964
965 if (NULL == gate_strbuilder_to_string(&builder, &query))
966 {
967 result = GATE_RESULT_OUTOFMEMORY;
968 break;
969 }
970
971 result = gate_management_query(self->mgmt, &wmi_search_path, &query, &mshv2prov_sandbox_callback, &found_path);
972 GATE_BREAK_IF_FAILED(result);
973
974 if (gate_string_is_empty(&found_path))
975 {
976 result = GATE_RESULT_NOMATCH;
977 break;
978 }
979
980 result = mshv2sbox_create(&found_path, &mshv2sbox);
981 if (GATE_SUCCEEDED(result))
982 {
983 if (ptr_sandbox)
984 {
985 *ptr_sandbox = (gate_virtualization_sandbox_t*)mshv2sbox;
986 }
987 else
988 {
989 gate_object_release(mshv2sbox);
990 }
991 }
992 } while (0);
993
994 gate_string_release(&found_path);
995 gate_string_release(&query);
996 gate_strbuilder_release(&builder);
997
998 return result;
999 }
1000
1001 static GATE_INTERFACE_VTBL(gate_virtualization_provider) const* init_virutalization_provider_vtbl()
1002 {
1003 static GATE_INTERFACE_VTBL(gate_virtualization_provider) vtbl;
1004 if (vtbl.get_interface_name == NULL)
1005 {
1006 GATE_INTERFACE_VTBL(gate_virtualization_provider) v =
1007 {
1008 &mshv2prov_get_interface_name,
1009 &mshv2prov_release,
1010 &mshv2prov_retain,
1011
1012 &mshv2prov_get_name,
1013 &mshv2prov_get_settings,
1014
1015 &mshv2prov_list_sandbox_ids,
1016 &mshv2prov_get_sandbox
1017 };
1018 vtbl = v;
1019 }
1020 return &vtbl;
1021 }
1022
1023 static gate_result_t mshv2prov_create(gate_string_t const* host, gate_virtualization_provider_t** ptr)
1024 {
1025 gate_result_t ret;
1026 mshv2prov_t* mshv2prov = NULL;
1027
1028 do
1029 {
1030 mshv2prov = (mshv2prov_t*)gate_mem_alloc(sizeof(mshv2prov_t));
1031 if (NULL == mshv2prov)
1032 {
1033 ret = GATE_RESULT_OUTOFMEMORY;
1034 break;
1035 }
1036 gate_mem_clear(mshv2prov, sizeof(mshv2prov_t));
1037 mshv2prov->vtbl = init_virutalization_provider_vtbl();
1038 gate_atomic_int_init(&mshv2prov->ref_counter, 1);
1039
1040 if (gate_string_is_empty(host))
1041 {
1042 host = &wmi_default_host;
1043 }
1044
1045 ret = gate_management_open(host, NULL, &wmi_default_namespace, 0, &mshv2prov->mgmt);
1046 GATE_BREAK_IF_FAILED(ret);
1047
1048 if (ptr != NULL)
1049 {
1050 *ptr = (gate_virtualization_provider_t*)mshv2prov;
1051 mshv2prov = NULL;
1052 }
1053 ret = GATE_RESULT_OK;
1054 } while (0);
1055
1056 if (NULL != mshv2prov)
1057 {
1058 gate_mem_dealloc(mshv2prov);
1059 }
1060 return ret;
1061 }
1062
1063 #endif /* GATE_TECH_VIRTUALIZATION_HYPERV2 */
1064
1065
1066
1067 #if defined(GATE_TECH_VIRTUALIZATION_WSL)
1068
1069 #include "gate/tech/platform/gate_wsl.h"
1070
1071 static gate_string_t const virtprov_name_wsl = GATE_STRING_INIT_STATIC("wsl");
1072 static gate_string_t const virtprov_descr_wsl = GATE_STRING_INIT_STATIC("Windows Subsystem for Linux");
1073
1074 typedef struct wsl_virtualization_provider_class
1075 {
1076 GATE_INTERFACE_VTBL(gate_virtualization_provider) const* vtbl;
1077
1078 gate_atomic_int_t ref_counter;
1079 } wsl_virtualization_provider_t;
1080
1081 static char const* wsl_get_interface_name(void* thisptr)
1082 {
1083 GATE_UNUSED_ARG(thisptr);
1084 return GATE_INTERFACE_NAME_VIRTUALIZATION_PROVIDER;
1085 }
1086 static void wsl_destroy(wsl_virtualization_provider_t* self)
1087 {
1088 gate_mem_dealloc(self);
1089 }
1090 static void wsl_release(void* thisptr)
1091 {
1092 wsl_virtualization_provider_t* self = (wsl_virtualization_provider_t*)thisptr;
1093 if (gate_atomic_int_dec(&self->ref_counter) == 0)
1094 {
1095 wsl_destroy(self);
1096 }
1097 }
1098 static int wsl_retain(void* thisptr)
1099 {
1100 wsl_virtualization_provider_t* self = (wsl_virtualization_provider_t*)thisptr;
1101 return gate_atomic_int_inc(&self->ref_counter);
1102 }
1103
1104 static gate_result_t wsl_get_name(void* thisptr, gate_string_t* name)
1105 {
1106 wsl_virtualization_provider_t* self = (wsl_virtualization_provider_t*)thisptr;
1107 gate_string_duplicate(name, &virtprov_name_wsl);
1108 return GATE_RESULT_OK;
1109 }
1110 static gate_result_t wsl_get_settings(void* thisptr, gate_property_t* settings)
1111 {
1112 wsl_virtualization_provider_t* self = (wsl_virtualization_provider_t*)thisptr;
1113 gate_property_create_empty(settings);
1114 return GATE_RESULT_OK;
1115 }
1116 static gate_result_t wsl_list_sandbox_ids(void* thisptr, gate_array_t* sandbox_ids)
1117 {
1118 wsl_virtualization_provider_t* self = (wsl_virtualization_provider_t*)thisptr;
1119 /* TODO */
1120 /* HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Lxss */
1121 return GATE_RESULT_NOTIMPLEMENTED;
1122 }
1123 static gate_result_t wsl_get_sandbox(void* thisptr, gate_string_t const* sandbox_id, gate_virtualization_sandbox_t** ptr_sandbox)
1124 {
1125 wsl_virtualization_provider_t* self = (wsl_virtualization_provider_t*)thisptr;
1126 /* TODO */
1127 return GATE_RESULT_NOTIMPLEMENTED;
1128 }
1129
1130 static GATE_INTERFACE_VTBL(gate_virtualization_provider) const* wsl_provider_vtbl_init()
1131 {
1132 static GATE_INTERFACE_VTBL(gate_virtualization_provider) vtbl;
1133 if (vtbl.get_interface_name == NULL)
1134 {
1135 GATE_INTERFACE_VTBL(gate_virtualization_provider) v = {
1136 &wsl_get_interface_name,
1137 &wsl_release,
1138 &wsl_retain,
1139
1140 &wsl_get_name,
1141 &wsl_get_settings,
1142 &wsl_list_sandbox_ids,
1143 &wsl_get_sandbox
1144 };
1145 vtbl = v;
1146 }
1147 return &vtbl;
1148 }
1149
1150 static gate_result_t wsl_provider_create(gate_virtualization_provider_t** ptr_provider)
1151 {
1152 gate_result_t ret = GATE_RESULT_FAILED;
1153 wsl_virtualization_provider_t* wsl_prov = NULL;
1154 do
1155 {
1156 GATE_INTERFACE_VTBL(gate_virtualization_provider) const* vtbl = wsl_provider_vtbl_init();
1157 wsl_api_t* wsl = load_wsl_functions();
1158
1159 if (wsl == NULL)
1160 {
1161 ret = GATE_RESULT_NOTAVAILABLE;
1162 }
1163
1164 wsl_prov = (wsl_virtualization_provider_t*)gate_mem_alloc(sizeof(wsl_virtualization_provider_t));
1165 if (wsl_prov == NULL)
1166 {
1167 ret = GATE_RESULT_OUTOFMEMORY;
1168 break;
1169 }
1170
1171 wsl_prov->vtbl = vtbl;
1172 gate_atomic_int_init(&wsl_prov->ref_counter, 1);
1173
1174 /* success case reached: */
1175 *ptr_provider = (gate_virtualization_provider_t*)wsl_prov;
1176 wsl_prov = NULL;
1177 ret = GATE_RESULT_OK;
1178 } while (0);
1179
1180 if (wsl_prov)
1181 {
1182 wsl_release(wsl_prov);
1183 }
1184 return ret;
1185 }
1186
1187 #endif /* GATE_TECH_VIRTUALIZATION_WSL */
1188
1189
1190
1191 1 gate_result_t gate_tech_virtualization_providers_enum(gate_tech_virtualization_providers_callback_t callback, void* param)
1192 {
1193 1 gate_result_t ret = GATE_RESULT_OK;
1194
1195 do
1196 {
1197 #if defined(GATE_TECH_VIRTUALIZATION_LXC)
1198 /* lxc support */
1199
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 if (GATE_SUCCEEDED(gate_lxc_init()))
1200 {
1201 ✗ if (!callback(&virtprov_name_lxc, &virtprov_descr_lxc, param))
1202 {
1203 ✗ break;
1204 }
1205 }
1206 #endif /* GATE_TECH_VIRTUALIZATION_LXC */
1207
1208 #if defined(GATE_TECH_VIRTUALIZATION_HYPERV2)
1209 /* MS hyper-v wmi access */
1210 if (!callback(&virtprov_name_hyperv2, &virtprov_descr_hyperv2, param))
1211 {
1212 break;
1213 }
1214 #endif /* GATE_TECH_VIRTUALIZATION_HYPERV2 */
1215
1216 #if defined(GATE_TECH_VIRTUALIZATION_WSL)
1217 if (!callback(&virtprov_name_wsl, &virtprov_descr_wsl, param))
1218 {
1219 break;
1220 }
1221 #endif /* GATE_TECH_VIRTUALIZATION_WSL */
1222
1223 #if defined(GATE_TECH_VIRTUALIZATION_DOCKER)
1224 /* docker support */
1225
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 if (!callback(&virtprov_name_docker, &virtprov_descr_docker, param))
1226 {
1227 ✗ break;
1228 }
1229 #endif /* GATE_TECH_VIRTUALIZATION_DOCKER */
1230
1231 } while (0);
1232
1233 1 return ret;
1234 }
1235
1236
1237 1 gate_result_t gate_tech_virtualization_provider_create(gate_string_t const* name, gate_virtualization_provider_t** ptr_provider)
1238 {
1239 1 gate_result_t ret = GATE_RESULT_NOMATCH;
1240
1241 do
1242 {
1243 #if defined(GATE_TECH_VIRTUALIZATION_LXC)
1244
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 if (gate_string_equals(name, &virtprov_name_lxc))
1245 {
1246 ✗ ret = gate_lxc_init();
1247 ✗ GATE_BREAK_IF_FAILED(ret);
1248
1249 ✗ if (ptr_provider)
1250 {
1251 ✗ gate_virtualization_provider_t* prov = init_global_lxc_provider();
1252 ✗ if (!prov)
1253 {
1254 ✗ ret = GATE_RESULT_FAILED;
1255 ✗ break;
1256 }
1257 ✗ *ptr_provider = prov;
1258 }
1259 ✗ ret = GATE_RESULT_OK;
1260 ✗ break;
1261 }
1262 #endif /* GATE_TECH_VIRTUALIZATION_LXC */
1263
1264 #if defined(GATE_TECH_VIRTUALIZATION_HYPERV2)
1265 if (gate_string_equals(name, &virtprov_name_hyperv2))
1266 {
1267 ret = mshv2prov_create(NULL, ptr_provider);
1268 return ret;
1269 }
1270 #endif /* GATE_TECH_VIRTUALIZATION_HYPERV2 */
1271
1272 #if defined(GATE_TECH_VIRTUALIZATION_WSL)
1273 if (gate_string_equals(name, &virtprov_name_wsl))
1274 {
1275 ret = wsl_provider_create(ptr_provider);
1276 return ret;
1277 }
1278 #endif /* GATE_TECH_VIRTUALIZATION_WSL */
1279
1280 #if defined(GATE_TECH_VIRTUALIZATION_DOCKER)
1281
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 if (gate_string_equals(name, &virtprov_name_docker))
1282 {
1283 /* TODO */
1284 1 ret = GATE_RESULT_FAILED;
1285 1 break;
1286 }
1287 #endif /* GATE_TECH_VIRTUALIZATION_DOCKER */
1288
1289 ✗ ret = GATE_RESULT_NOMATCH;
1290 } while (0);
1291
1292 1 return ret;
1293 }
1294