GCC Code Coverage Report


Directory: src/gate/
File: src/gate/system/management.c
Date: 2026-09-21 06:26:40
Exec Total Coverage
Lines: 0 48 0.0%
Functions: 0 13 0.0%
Branches: 0 14 0.0%

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/system/management.h"
30 #include "gate/results.h"
31 #include "gate/comparers.h"
32 #include "gate/debugging.h"
33 #include "gate/utilities.h"
34
35 #if defined(GATE_SYS_WIN) && !defined(GATE_SYS_WIN16)
36 # define GATE_SYSTEM_MANAGEMENT_WINAPI_IMPL
37 #else
38 # define GATE_SYSTEM_MANAGEMENT_NO_IMPL
39 #endif
40
41
42
43 gate_management_object_t* gate_management_object_copy(gate_management_object_t* dest, gate_management_object_t const* source)
44 {
45 gate_management_object_t* ret = NULL;
46 do
47 {
48 gate_mem_clear(dest, sizeof(gate_management_object_t));
49
50 if (NULL == gate_map_copy(&dest->properties, &source->properties))
51 {
52 break;
53 }
54 if (NULL == gate_string_clone(&dest->path, &source->path))
55 {
56 break;
57 }
58 if (NULL == gate_string_clone(&dest->name, &source->name))
59 {
60 break;
61 }
62 if (NULL == gate_string_clone(&dest->type, &source->type))
63 {
64 break;
65 }
66 /* success */
67 ret = dest;
68 } while (0);
69
70 if ((ret == NULL) && (dest != NULL))
71 {
72 gate_string_release(&dest->type);
73 gate_string_release(&dest->name);
74 gate_string_release(&dest->path);
75 gate_map_destroy(&dest->properties);
76 }
77 return ret;
78 }
79
80 void gate_management_object_release(gate_management_object_t* mgmt_obj)
81 {
82 if (mgmt_obj)
83 {
84 gate_string_release(&mgmt_obj->type);
85 gate_string_release(&mgmt_obj->name);
86 gate_string_release(&mgmt_obj->path);
87 gate_map_destroy(&mgmt_obj->properties);
88 gate_mem_clear(mgmt_obj, sizeof(gate_management_object_t));
89 }
90 }
91
92
93 #if defined(GATE_SYSTEM_MANAGEMENT_WINAPI_IMPL)
94
95 #include "gate/system/platform/management_wmi.h"
96
97
98 static gate_string_t const subsys_wmi = GATE_STRING_INIT_STATIC("wmi");
99
100 static gate_string_t const token_path_prefix = GATE_STRING_INIT_STATIC("\\\\");
101 static gate_string_t const token_host_separator = GATE_STRING_INIT_STATIC("\\");
102 static gate_string_t const token_default_host = GATE_STRING_INIT_STATIC(".");
103 static gate_string_t const token_ns_root = GATE_STRING_INIT_STATIC("ROOT");
104 static gate_string_t const token_default_ns = GATE_STRING_INIT_STATIC("ROOT\\CIMV2");
105 static gate_string_t const token_ns_separator = GATE_STRING_INIT_STATIC("\\");
106 static gate_string_t const token_ns_class_separator = GATE_STRING_INIT_STATIC(":");
107 static gate_string_t const token_class_instance_separator = GATE_STRING_INIT_STATIC(".");
108 static gate_string_t const token_singleton = GATE_STRING_INIT_STATIC("=@");
109
110 static gate_string_t const uid_prefix = GATE_STRING_INIT_STATIC("\\\\.\\");
111 static gate_string_t const ns_root_cimv2 = GATE_STRING_INIT_STATIC("ROOT\\CIMV2");
112
113 typedef struct gate_management_impl_class
114 {
115 gate_string_t host;
116 gate_string_t sub_system;
117 gate_string_t name_space;
118 } gate_management_impl_t;
119
120
121 #define GATE_BREAK_IF_ZERO(len_var, result_var) if(0 == (len_var)) { result_var = GATE_RESULT_OUTOFMEMORY; break; }
122
123 static gate_result_t gate_mgmt_build_path(gate_strbuilder_t* builder, gate_string_t const* host, gate_string_t const* name_space,
124 gate_string_t const* class_name, gate_string_t const* instance_name)
125 {
126 gate_result_t ret = GATE_RESULT_OK;
127 gate_size_t len = 0;
128
129 do
130 {
131 len = gate_strbuilder_append_string(builder, &token_path_prefix);
132 GATE_BREAK_IF_ZERO(len, ret);
133
134 if (gate_string_is_empty(host))
135 {
136 len = gate_strbuilder_append_string(builder, &token_default_host);
137 }
138 else
139 {
140 len = gate_strbuilder_append_string(builder, host);
141 }
142 GATE_BREAK_IF_ZERO(len, ret);
143
144 len = gate_strbuilder_append_string(builder, &token_host_separator);
145 GATE_BREAK_IF_ZERO(len, ret);
146
147 if (gate_string_is_empty(name_space))
148 {
149 len = gate_strbuilder_append_string(builder, &token_default_ns);
150 }
151 else
152 {
153 len = gate_strbuilder_append_string(builder, name_space);
154 }
155 GATE_BREAK_IF_ZERO(len, ret);
156
157 if (!gate_string_is_empty(class_name))
158 {
159 len = gate_strbuilder_append_string(builder, &token_ns_class_separator);
160 GATE_BREAK_IF_ZERO(len, ret);
161
162 len = gate_strbuilder_append_string(builder, class_name);
163 GATE_BREAK_IF_ZERO(len, ret);
164
165 if (gate_string_is_empty(instance_name))
166 {
167 len = gate_strbuilder_append_string(builder, &token_class_instance_separator);
168 GATE_BREAK_IF_ZERO(len, ret);
169 len = gate_strbuilder_append_string(builder, instance_name);
170 GATE_BREAK_IF_ZERO(len, ret);
171 }
172 }
173 } while (0);
174
175 GATE_DEBUG_TRACE_FAILED_RESULT(ret);
176 return ret;
177 }
178 #undef GATE_BREAK_IF_ZERO
179
180
181 static IWbemServices* gate_mgmt_load_wmi_service_impl(gate_string_t const* host, gate_string_t const* name_space,
182 gate_string_t const* user, gate_string_t const* password)
183 {
184 gate_result_t result;
185 IWbemServices* ret = NULL;
186 IWbemLocator* locator = NULL;
187 char path_buffer[4096];
188 gate_strbuilder_t path_builder = GATE_INIT_EMPTY;
189 gate_string_t path = GATE_STRING_INIT_EMPTY;
190 BSTR str_resource = NULL;
191 BSTR str_user = NULL;
192 BSTR str_pass = NULL;
193 HRESULT hr;
194
195 do
196 {
197 gate_strbuilder_create_static(&path_builder, path_buffer, sizeof(path_buffer), 0);
198
199 result = gate_mgmt_build_path(&path_builder, host, name_space, NULL, NULL);
200 GATE_BREAK_IF_FAILED(result);
201
202
203 if (!gate_string_is_empty(user))
204 {
205 str_user = gate_win32_bstr_create(user);
206 }
207 if (!gate_string_is_empty(password))
208 {
209 str_pass = gate_win32_bstr_create(password);
210 }
211
212
213 if (NULL == gate_strbuilder_to_string(&path_builder, &path))
214 {
215 break;
216 }
217 GATE_DEBUG_TRACE(path.str);
218
219
220 str_resource = gate_win32_bstr_create(&path);
221 gate_string_release(&path);
222
223 hr = gate_win32_com_create_instance(&CLSID_WbemLocator, &IID_IWbemLocator, (LPVOID*)&locator);
224 if (FAILED(hr))
225 {
226 GATE_DEBUG_TRACE("CoCreateInstance() failed");
227 GATE_DEBUG_TRACE_VALUE(hr);
228 break;
229 }
230
231 hr = locator->lpVtbl->ConnectServer(locator, str_resource, str_user, str_pass, NULL, 0, NULL, NULL, &ret);
232 if (FAILED(hr))
233 {
234 GATE_DEBUG_TRACE("locator->ConnectServer() failed");
235 GATE_DEBUG_TRACE(path.str);
236 GATE_DEBUG_TRACE_VALUE(hr);
237 break;
238 }
239 } while (0);
240
241 if (locator != NULL)
242 {
243 locator->lpVtbl->Release(locator);
244 }
245 if (str_resource != NULL) gate_win32_bstr_release(str_resource);
246 if (str_user != NULL) gate_win32_bstr_release(str_user);
247 if (str_pass != NULL) gate_win32_bstr_release(str_pass);
248 gate_strbuilder_release(&path_builder);
249
250 return ret;
251 }
252
253 static gate_result_t gate_mgmt_load_wmi_service(gate_string_t const* host, gate_string_t const* name_space,
254 gate_string_t const* user, gate_string_t const* password,
255 IWbemServices** services, gate_bool_t* uninit)
256 {
257 gate_result_t ret = gate_win32_com_init();
258 if (ret == GATE_RESULT_OK)
259 {
260 *uninit = true;
261 }
262 else if (ret == GATE_RESULT_OK_UNCHANGED)
263 {
264 *uninit = false;
265 }
266 else
267 {
268 *uninit = false;
269 ret = GATE_RESULT_INVALIDSTATE;
270 GATE_DEBUG_TRACE("locator->ConnectServer() failed");
271 return ret;
272 }
273
274 *services = gate_mgmt_load_wmi_service_impl(host, name_space, user, password);
275
276 gate_win32_com_pump_messages(0);
277
278 if (*services != NULL)
279 {
280 ret = GATE_RESULT_OK;
281 }
282 else
283 {
284 ret = GATE_RESULT_NOTAVAILABLE;
285 if (*uninit)
286 {
287 gate_win32_com_uninit();
288 *uninit = false;
289 }
290 }
291 GATE_DEBUG_TRACE_FAILED_RESULT(ret);
292 return ret;
293 }
294
295 static gate_result_t gate_mgmt_unload_wmi_service(IWbemServices** services, gate_bool_t* uninit)
296 {
297 if (*services)
298 {
299 (*services)->lpVtbl->Release(*services);
300 *services = NULL;
301 }
302 if (*uninit)
303 {
304 gate_win32_com_pump_messages(0);
305 gate_win32_com_uninit();
306 *uninit = false;
307 }
308 return GATE_RESULT_OK;
309 }
310
311 gate_result_t gate_management_open(gate_string_t const* host, gate_string_t const* subsystem, gate_string_t const* name_space,
312 gate_enumint_t flags, gate_management_t* handle)
313 {
314 gate_result_t ret = GATE_RESULT_FAILED;
315 gate_management_impl_t* impl = NULL;
316
317 GATE_UNUSED_ARG(flags);
318 do
319 {
320 if (gate_string_is_empty(subsystem))
321 {
322 subsystem = &subsys_wmi;
323 }
324
325 if (gate_string_is_empty(host))
326 {
327 host = &token_default_host;
328 }
329
330 if (!gate_string_equals_ic(subsystem, &subsys_wmi))
331 {
332 ret = GATE_RESULT_NOTSUPPORTED;
333 break;
334 }
335
336 impl = (gate_management_impl_t*)gate_mem_alloc(sizeof(gate_management_impl_t));
337 if (impl == NULL)
338 {
339 ret = GATE_RESULT_OUTOFMEMORY;
340 break;
341 }
342 gate_mem_clear(impl, sizeof(gate_management_impl_t));
343 gate_string_clone(&impl->host, host);
344 gate_string_clone(&impl->name_space, name_space);
345 gate_string_clone(&impl->sub_system, subsystem);
346
347 *handle = impl;
348 ret = GATE_RESULT_OK;
349 } while (0);
350
351 if (GATE_FAILED(ret))
352 {
353 if (impl)
354 {
355 gate_string_release(&impl->host);
356 gate_string_release(&impl->name_space);
357 gate_string_release(&impl->sub_system);
358 gate_mem_dealloc(impl);
359 }
360 }
361 GATE_DEBUG_TRACE_FAILED_RESULT(ret);
362 return ret;
363 }
364 gate_result_t gate_management_close(gate_management_t handle)
365 {
366 gate_management_impl_t* impl = (gate_management_impl_t*)handle;
367 gate_result_t ret = GATE_RESULT_OK;
368
369 if (impl)
370 {
371 gate_string_release(&impl->host);
372 gate_string_release(&impl->name_space);
373 gate_string_release(&impl->sub_system);
374 gate_mem_dealloc(impl);
375 }
376
377 GATE_DEBUG_TRACE_FAILED_RESULT(ret);
378 return ret;
379 }
380
381 static gate_result_t gate_mgmt_read_properties(IWbemClassObject* wmi_obj, gate_map_t* props, gate_bool_t system_only, gate_bool_t keys_only)
382 {
383 gate_result_t ret = GATE_RESULT_FAILED;
384 LONG enum_flags = system_only ? WBEM_FLAG_SYSTEM_ONLY : WBEM_FLAG_NONSYSTEM_ONLY;
385 HRESULT hr;
386 BSTR bstr_name;
387 gate_string_t str_name;
388 VARIANT var_value = GATE_INIT_EMPTY;
389 gate_value_t value;
390
391 do
392 {
393 if (gate_map_is_empty(props))
394 {
395 gate_map_create(props, &gate_compare_string,
396 sizeof(gate_string_t), &gate_string_copy_constructor, &gate_string_destructor,
397 sizeof(gate_value_t), &gate_value_copy_constructor, &gate_value_destructor);
398 }
399
400 if (keys_only)
401 {
402 enum_flags |= WBEM_FLAG_KEYS_ONLY;
403 }
404 hr = wmi_obj->lpVtbl->BeginEnumeration(wmi_obj, enum_flags);
405 if (FAILED(hr))
406 {
407 GATE_DEBUG_TRACE("wmi->BeginEnumeration() failed");
408 GATE_DEBUG_TRACE_VALUE(hr);
409 ret = GATE_RESULT_FAILED;
410 break;
411 }
412
413 for (;;)
414 {
415 bstr_name = NULL;
416 gate_win32_variant_init(&var_value);
417 hr = wmi_obj->lpVtbl->Next(wmi_obj, 0, &bstr_name, &var_value, NULL, NULL);
418 if (WBEM_S_NO_ERROR != hr)
419 {
420 break;
421 }
422
423 if (NULL == gate_win32_bstr_to_string(bstr_name, &str_name))
424 {
425
426 }
427 else
428 {
429 if (NULL == gate_win32_variant_to_value(&var_value, &value))
430 {
431 /* failed or not supported */
432 }
433 else
434 {
435 gate_map_add(props, &str_name, &value);
436 gate_value_release(&value);
437 }
438 gate_string_release(&str_name);
439 }
440 gate_win32_bstr_release(bstr_name);
441 gate_win32_variant_clear(&var_value);
442 }
443 ret = GATE_RESULT_OK;
444 } while (0);
445
446 GATE_DEBUG_TRACE_FAILED_RESULT(ret);
447 return ret;
448 }
449
450
451
452 static gate_string_t const wmi_property_path = GATE_STRING_INIT_STATIC("__PATH");
453 static gate_string_t const wmi_property_class = GATE_STRING_INIT_STATIC("__CLASS");
454
455 static gate_result_t gate_mgmt_create_object(IWbemClassObject* wmi_obj, gate_management_object_t* target)
456 {
457 gate_result_t ret = GATE_RESULT_FAILED;
458 gate_map_t sys_props = GATE_INIT_EMPTY;
459 gate_map_t key_props = GATE_INIT_EMPTY;
460 gate_value_t const* val_path = NULL;
461 gate_value_t const* val_class = NULL;
462
463 do
464 {
465 ret = gate_mgmt_read_properties(wmi_obj, &sys_props, true, false);
466 GATE_BREAK_IF_FAILED(ret);
467
468 ret = gate_mgmt_read_properties(wmi_obj, &key_props, false, true);
469 GATE_BREAK_IF_FAILED(ret);
470
471 val_path = (gate_value_t const*)gate_map_get_value(&sys_props, &wmi_property_path);
472 val_class = (gate_value_t const*)gate_map_get_value(&sys_props, &wmi_property_class);
473 if (val_path)
474 {
475 gate_value_load_string(val_path->value_type, &val_path->content.ptr_value, &target->path);
476 }
477 if (val_class)
478 {
479 gate_value_load_string(val_class->value_type, &val_class->content.ptr_value, &target->type);
480 }
481
482
483 ret = gate_mgmt_read_properties(wmi_obj, &target->properties, false, false);
484
485 } while (0);
486
487 gate_map_destroy(&sys_props);
488 gate_map_destroy(&key_props);
489
490 GATE_DEBUG_TRACE_FAILED_RESULT(ret);
491 return ret;
492 }
493
494 static gate_result_t gate_mgmt_parse_path(gate_string_t const* wmi_path, gate_string_t* host, gate_string_t* name_space,
495 gate_string_t* class_name, gate_string_t* instance)
496 {
497 gate_size_t posHostEnd;
498 gate_size_t posNsEnd;
499 gate_size_t posClassEnd;
500 //\\W900D049\root\cimv2:Win32_OperatingSystem=@
501 //\\W900D049\root\cimv2:Win32_Process.Handle="0"
502 if (!gate_string_starts_with(wmi_path, &token_path_prefix))
503 {
504 return GATE_RESULT_INVALIDINPUT;
505 }
506 posHostEnd = gate_string_pos(wmi_path, &token_host_separator, 2);
507 if (posHostEnd == GATE_STR_NPOS)
508 {
509 return GATE_RESULT_INVALIDINPUT;
510 }
511 if (host)
512 {
513 gate_string_substr(host, wmi_path, 2, posHostEnd - 2);
514 }
515
516 posNsEnd = gate_string_pos(wmi_path, &token_ns_class_separator, posHostEnd + 1);
517 if (posNsEnd == GATE_STR_NPOS)
518 {
519 gate_string_substr(name_space, wmi_path, posHostEnd + 1, GATE_STR_NPOS);
520 if (class_name)
521 {
522 gate_string_create_empty(class_name);
523 }
524 if (instance)
525 {
526 gate_string_create_empty(instance);
527 }
528 return GATE_RESULT_OK;
529 }
530 if (name_space)
531 {
532 gate_string_substr(name_space, wmi_path, posHostEnd + 1, posNsEnd - posHostEnd - 1);
533 }
534
535 posClassEnd = gate_string_pos(wmi_path, &token_class_instance_separator, posNsEnd + 1);
536 if (posClassEnd == GATE_STR_NPOS)
537 {
538 if (class_name)
539 {
540 gate_string_substr(class_name, wmi_path, posNsEnd + 1, GATE_STR_NPOS);
541 if (gate_string_ends_with(class_name, &token_singleton))
542 {
543 class_name->length -= token_singleton.length;
544 }
545 }
546 if (instance)
547 {
548 gate_string_create_empty(instance);
549 }
550 return GATE_RESULT_OK;
551 }
552 if (class_name)
553 {
554 gate_string_substr(class_name, wmi_path, posNsEnd + 1, posClassEnd - posNsEnd - 1);
555 }
556 if (instance)
557 {
558 gate_string_substr(instance, wmi_path, posClassEnd + 1, GATE_STR_NPOS);
559 }
560 return GATE_RESULT_OK;
561 }
562
563 static gate_result_t gate_mgmt_run_query(IWbemServices* services, gate_string_t const* query,
564 gate_management_callback_t callback, void* user_param)
565 {
566 gate_result_t ret = GATE_RESULT_FAILED;
567 BSTR bstr_lang = gate_win32_bstr_create_wstr(L"WQL");
568 BSTR bstr_query = gate_win32_bstr_create(query);
569 HRESULT hr;
570 IEnumWbemClassObject* ienum = NULL;
571 IWbemClassObject* wmi_obj = NULL;
572 ULONG returned;
573 gate_management_object_t mgmt_obj;
574 gate_bool_t continue_loop = true;
575
576 do
577 {
578 hr = gate_win32_com_set_proxy_blanket((IUnknown*)services, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL,
579 RPC_C_AUTHN_LEVEL_CONNECT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE);
580 if (FAILED(hr))
581 {
582 GATE_DEBUG_TRACE("CoSetProxyBlanket() failed");
583 GATE_DEBUG_TRACE_VALUE(hr);
584 ret = GATE_RESULT_INVALIDSTATE;
585 break;
586 }
587
588 hr = services->lpVtbl->ExecQuery(services, bstr_lang, bstr_query,
589 WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &ienum);
590 if (FAILED(hr))
591 {
592 GATE_DEBUG_TRACE("services->ExecQuery() failed");
593 GATE_DEBUG_TRACE(query->str);
594 GATE_DEBUG_TRACE_VALUE(hr);
595 ret = GATE_RESULT_FAILED;
596 break;
597 }
598
599 while (continue_loop && (WBEM_S_NO_ERROR == (hr = ienum->lpVtbl->Next(ienum, WBEM_INFINITE, 1, &wmi_obj, &returned))))
600 {
601 gate_mem_clear(&mgmt_obj, sizeof(mgmt_obj));
602
603 ret = gate_mgmt_create_object(wmi_obj, &mgmt_obj);
604 if (GATE_SUCCEEDED(ret))
605 {
606 continue_loop = callback(&mgmt_obj, user_param);
607 gate_management_object_release(&mgmt_obj);
608 }
609 wmi_obj->lpVtbl->Release(wmi_obj);
610 }
611 } while (0);
612
613 if (ienum) ienum->lpVtbl->Release(ienum);
614 if (bstr_query) gate_win32_bstr_release(bstr_query);
615 if (bstr_lang) gate_win32_bstr_release(bstr_lang);
616 GATE_DEBUG_TRACE_FAILED_RESULT(ret);
617 return ret;
618 }
619
620 static gate_bool_t gate_mgmt_cb_use_first(gate_management_object_t const* obj, void* user_param)
621 {
622 gate_management_object_t* dst_obj = (gate_management_object_t*)user_param;
623 gate_mem_clear(dst_obj, sizeof(gate_management_object_t));
624 if (gate_management_object_copy(dst_obj, obj))
625 {
626 return false; /* one found, cancel further iteration */
627 }
628 else
629 {
630 return true; /* continue, try next */
631 }
632 }
633
634 static gate_result_t gate_mgmt_get_object_impl(IWbemServices* services, gate_string_t const* path, gate_management_object_t* obj)
635 {
636 gate_result_t ret;
637 gate_string_t host = GATE_STRING_INIT_EMPTY;
638 gate_string_t ns = GATE_STRING_INIT_EMPTY;
639 gate_string_t class_name = GATE_STRING_INIT_EMPTY;
640 gate_string_t instance = GATE_STRING_INIT_EMPTY;
641 BSTR bstr = NULL;
642 IWbemClassObject* wmi_obj = NULL;
643 gate_strbuilder_t query_builder;
644 char query_buffer[2048];
645 gate_string_t query_string;
646 HRESULT hr;
647
648 do
649 {
650 ret = gate_mgmt_parse_path(path, &host, &ns, &class_name, &instance);
651 GATE_BREAK_IF_FAILED(ret);
652
653 if (gate_string_is_empty(&instance))
654 {
655 /* class query */
656 bstr = gate_win32_bstr_create(path);
657 hr = services->lpVtbl->GetObject(services, bstr, WBEM_FLAG_RETURN_WBEM_COMPLETE, NULL, &wmi_obj, NULL);
658 if (FAILED(hr))
659 {
660 GATE_DEBUG_TRACE("services->GetObjectW failed");
661 GATE_DEBUG_TRACE_VALUE(hr);
662 ret = GATE_RESULT_FAILED;
663 }
664 else
665 {
666 ret = gate_mgmt_create_object(wmi_obj, obj);
667 }
668 }
669 else
670 {
671 static gate_string_t const q_select = GATE_STRING_INIT_STATIC("SELECT * FROM ");
672 static gate_string_t const q_where = GATE_STRING_INIT_STATIC(" WHERE ");
673 char where_buffer[1024];
674 gate_strbuilder_t where_builder;
675 gate_string_t where_clause = GATE_STRING_INIT_EMPTY;
676
677 gate_strbuilder_create_static(&where_builder, where_buffer, sizeof(where_buffer), 0);
678 gate_strbuilder_append_string(&where_builder, &instance);
679 gate_strbuilder_replace_str(&where_builder, ",", 1, " AND ", 5, 0, GATE_STR_NPOS);
680 gate_string_create_static_len(&where_clause,
681 gate_strbuilder_ptr(&where_builder, 0),
682 gate_strbuilder_length(&where_builder)
683 );
684
685 gate_strbuilder_create_static(&query_builder, query_buffer, sizeof(query_buffer), 0);
686 gate_strbuilder_append_string(&query_builder, &q_select);
687 gate_strbuilder_append_string(&query_builder, &class_name);
688 gate_strbuilder_append_string(&query_builder, &q_where);
689 /*gate_strbuilder_append_string(&query_builder, &instance);*/
690 gate_strbuilder_append_string(&query_builder, &where_clause);
691 gate_strbuilder_to_string(&query_builder, &query_string);
692 gate_strbuilder_release(&query_builder);
693
694 ret = gate_mgmt_run_query(services, &query_string, &gate_mgmt_cb_use_first, obj);
695 gate_string_release(&query_string);
696 }
697
698 } while (0);
699
700 if (wmi_obj) wmi_obj->lpVtbl->Release(wmi_obj);
701 if (bstr) gate_win32_bstr_release(bstr);
702 gate_string_release(&instance);
703 gate_string_release(&class_name);
704 gate_string_release(&ns);
705 gate_string_release(&host);
706
707 GATE_DEBUG_TRACE_FAILED_RESULT(ret);
708 return ret;
709 }
710
711 gate_result_t gate_management_get_object(gate_management_t handle, gate_string_t const* path, gate_management_object_t* obj)
712 {
713 gate_result_t ret = GATE_RESULT_FAILED;
714 gate_management_impl_t* impl = (gate_management_impl_t*)handle;
715 IWbemServices* services = NULL;
716 gate_bool_t must_uninit = false;
717
718 ret = gate_mgmt_load_wmi_service(&impl->host, &impl->name_space, NULL, NULL, &services, &must_uninit);
719 if (GATE_SUCCEEDED(ret))
720 {
721 ret = gate_mgmt_get_object_impl(services, path, obj);
722 gate_mgmt_unload_wmi_service(&services, &must_uninit);
723 }
724 GATE_DEBUG_TRACE_FAILED_RESULT(ret);
725 return ret;
726 }
727
728 gate_result_t gate_management_query(gate_management_t handle, gate_string_t const* path, gate_string_t const* query,
729 gate_management_callback_t callback, void* userparam)
730 {
731 gate_result_t ret = GATE_RESULT_FAILED;
732 gate_management_impl_t* impl = (gate_management_impl_t*)handle;
733 IWbemServices* services = NULL;
734 gate_bool_t must_uninit = false;
735
736 ret = gate_mgmt_load_wmi_service(&impl->host, &impl->name_space, NULL, NULL, &services, &must_uninit);
737 if (GATE_SUCCEEDED(ret))
738 {
739 ret = gate_mgmt_run_query(services, query, callback, userparam);
740
741 gate_mgmt_unload_wmi_service(&services, &must_uninit);
742 }
743 GATE_DEBUG_TRACE_FAILED_RESULT(ret);
744 return ret;
745 }
746
747 static gate_string_t const wmi_query_classes = GATE_STRING_INIT_STATIC("Select * From Meta_Class");
748
749 gate_result_t gate_management_list_children(gate_management_t handle, gate_string_t const* path,
750 gate_management_callback_t callback, void* userparam)
751 {
752 gate_result_t ret = GATE_RESULT_FAILED;
753 gate_management_impl_t* impl = (gate_management_impl_t*)handle;
754 IWbemServices* services = NULL;
755 gate_bool_t must_uninit = false;
756 gate_strbuilder_t query_builder = GATE_INIT_EMPTY;
757 char query_buffer[1024];
758 gate_string_t query_string = GATE_STRING_INIT_EMPTY;
759 gate_string_t host = GATE_STRING_INIT_EMPTY;
760 gate_string_t name_space = GATE_STRING_INIT_EMPTY;
761 gate_string_t class_name = GATE_STRING_INIT_EMPTY;
762 gate_string_t instance_name = GATE_STRING_INIT_EMPTY;
763
764 ret = gate_mgmt_load_wmi_service(&impl->host, &impl->name_space, NULL, NULL, &services, &must_uninit);
765 if (GATE_SUCCEEDED(ret))
766 {
767 if (gate_string_is_empty(path))
768 {
769 ret = gate_mgmt_run_query(services, &wmi_query_classes, callback, userparam);
770 }
771 else
772 {
773 ret = gate_mgmt_parse_path(path, &host, &name_space, &class_name, &instance_name);
774 if (GATE_SUCCEEDED(ret))
775 {
776 if (gate_string_is_empty(&class_name))
777 {
778 ret = gate_mgmt_run_query(services, &wmi_query_classes, callback, userparam);
779 }
780 else
781 {
782 gate_strbuilder_create_static(&query_builder, query_buffer, sizeof(query_buffer), 0);
783
784 gate_strbuilder_to_string(&query_builder, &query_string);
785 ret = gate_mgmt_run_query(services, &query_string, callback, userparam);
786 gate_string_release(&query_string);
787 gate_strbuilder_release(&query_builder);
788 }
789 }
790
791 gate_string_release(&host);
792 gate_string_release(&name_space);
793 gate_string_release(&class_name);
794 gate_string_release(&instance_name);
795 }
796 gate_mgmt_unload_wmi_service(&services, &must_uninit);
797 }
798 GATE_DEBUG_TRACE_FAILED_RESULT(ret);
799 return ret;
800 }
801 gate_result_t gate_management_list_properties(gate_management_t handle, gate_string_t const* path, gate_map_t* properties)
802 {
803 gate_result_t ret = GATE_RESULT_NOTIMPLEMENTED;
804 gate_management_impl_t* impl = (gate_management_impl_t*)handle;
805
806 GATE_DEBUG_TRACE_FAILED_RESULT(ret);
807 return ret;
808 }
809 gate_result_t gate_management_list_methodnames(gate_management_t handle, gate_string_t const* path, gate_array_t* methodnames)
810 {
811 gate_result_t ret = GATE_RESULT_NOTIMPLEMENTED;
812 gate_management_impl_t* impl = (gate_management_impl_t*)handle;
813
814 GATE_DEBUG_TRACE_FAILED_RESULT(ret);
815 return ret;
816 }
817 gate_result_t gate_management_get_property(gate_management_t handle, gate_string_t const* path, gate_string_t const* propname, gate_value_t* value)
818 {
819 gate_result_t ret = GATE_RESULT_NOTIMPLEMENTED;
820 gate_management_impl_t* impl = (gate_management_impl_t*)handle;
821
822 GATE_DEBUG_TRACE_FAILED_RESULT(ret);
823 return ret;
824 }
825 gate_result_t gate_management_set_property(gate_management_t handle, gate_string_t const* path, gate_string_t const* propname, gate_value_t const* value)
826 {
827 gate_result_t ret = GATE_RESULT_NOTIMPLEMENTED;
828 gate_management_impl_t* impl = (gate_management_impl_t*)handle;
829
830 GATE_DEBUG_TRACE_FAILED_RESULT(ret);
831 return ret;
832 }
833
834 #define BREAK_IF_HRESULT_FAILED(hresultvar, retvar) if (FAILED(hresultvar)) { \
835 retvar = GATE_RESULT_FAILED; \
836 break; \
837 }
838
839 static gate_result_t setup_argument_values(IWbemClassObject* arg_defs, gate_map_t const* src_value_map, IWbemClassObject* dst_wmi_args)
840 {
841 gate_result_t ret = GATE_RESULT_OK;
842 HRESULT hr;
843
844 do
845 {
846 BSTR bstr_arg_name = NULL;
847 VARIANT variant_value = GATE_INIT_EMPTY;
848 CIMTYPE cim_type = 0;
849
850 hr = arg_defs->lpVtbl->BeginEnumeration(arg_defs, WBEM_FLAG_LOCAL_ONLY);
851 BREAK_IF_HRESULT_FAILED(hr, ret);
852
853 while (WBEM_S_NO_ERROR == (hr = arg_defs->lpVtbl->Next(arg_defs, 0, &bstr_arg_name, &variant_value, &cim_type, NULL)))
854 {
855 gate_string_t str_arg_name = GATE_STRING_INIT_EMPTY;
856 if (NULL != gate_win32_bstr_to_string(bstr_arg_name, &str_arg_name))
857 {
858 /* lookup parameter in input map (string->value) */
859 gate_value_t const* ptr_value = (gate_value_t const*)gate_map_get_value(src_value_map, &str_arg_name);
860 if (ptr_value)
861 {
862 do
863 {
864 /* we have a value, convert it to VARIANT */
865 VARIANT var_value = GATE_INIT_EMPTY;
866 ret = gate_win32_value_to_variant(ptr_value, &var_value);
867 GATE_BREAK_IF_FAILED(ret);
868
869 /* apply the variant on in-args object */
870 hr = dst_wmi_args->lpVtbl->Put(dst_wmi_args, bstr_arg_name, 0, &var_value, 0);
871 gate_win32_variant_clear(&var_value);
872 BREAK_IF_HRESULT_FAILED(hr, ret);
873 } while (0);
874 }
875 }
876 gate_string_release(&str_arg_name);
877 gate_win32_bstr_release(bstr_arg_name);
878 gate_win32_variant_clear(&variant_value);
879 GATE_BREAK_IF_FAILED(ret);
880 }
881 arg_defs->lpVtbl->EndEnumeration(arg_defs);
882 } while (0);
883 return ret;
884 }
885
886 static gate_result_t extract_argument_values(IWbemClassObject* wmi_args, gate_map_t* dst_value_map)
887 {
888 gate_result_t ret = GATE_RESULT_FAILED;
889 BSTR bstr_name = NULL;
890 VARIANT variant_value = GATE_INIT_EMPTY;
891 CIMTYPE cim_type = 0;
892 HRESULT hr;
893
894 do
895 {
896 hr = wmi_args->lpVtbl->BeginEnumeration(wmi_args, WBEM_FLAG_LOCAL_ONLY);
897 BREAK_IF_HRESULT_FAILED(hr, ret);
898
899 gate_map_destroy(dst_value_map);
900 if (NULL == gate_util_stringvaluemap_create(dst_value_map))
901 {
902 ret = GATE_RESULT_OUTOFMEMORY;
903 break;
904 }
905
906 while (WBEM_S_NO_ERROR == (hr = wmi_args->lpVtbl->Next(wmi_args, 0, &bstr_name, &variant_value, &cim_type, NULL)))
907 {
908 gate_value_t val = GATE_INIT_EMPTY;
909 if (NULL != gate_win32_variant_to_value(&variant_value, &val))
910 {
911 gate_string_t str_name;
912 if (NULL != gate_win32_bstr_to_string(bstr_name, &str_name))
913 {
914 gate_map_add(dst_value_map, &str_name, &val);
915 gate_string_release(&str_name);
916 }
917 gate_value_release(&val);
918 }
919 gate_win32_bstr_release(bstr_name);
920 gate_win32_variant_clear(&variant_value);
921 }
922 wmi_args->lpVtbl->EndEnumeration(wmi_args);
923 } while (0);
924
925 return ret;
926 }
927
928 gate_result_t gate_management_invoke(gate_management_t handle,
929 gate_string_t const* path, gate_string_t const* methodname,
930 gate_map_t const* input_values, gate_map_t* output_values)
931 {
932 gate_result_t ret = GATE_RESULT_FAILED;
933 gate_management_impl_t* impl = (gate_management_impl_t*)handle;
934 gate_string_t wmi_host = GATE_STRING_INIT_EMPTY;
935 gate_string_t wmi_namespace = GATE_STRING_INIT_EMPTY;
936 gate_string_t wmi_class_name = GATE_STRING_INIT_EMPTY;
937 gate_string_t wmi_instance = GATE_STRING_INIT_EMPTY;
938 IWbemServices* wmi_services = NULL;
939 IWbemClassObject* wmi_class = NULL;
940 IWbemClassObject* wmi_inparamdefs = NULL;
941 IWbemClassObject* wmi_outparamdefs = NULL;
942 IWbemClassObject* wmi_inargs = NULL;
943 IWbemClassObject* wmi_outargs = NULL;
944 gate_bool_t must_uninit = false;
945
946 BSTR bstr_class = NULL;
947 BSTR bstr_method = NULL;
948 BSTR bstr_path = NULL;
949 HRESULT hr;
950
951 do
952 {
953 ret = gate_mgmt_parse_path(path, &wmi_host, &wmi_namespace, &wmi_class_name, &wmi_instance);
954 GATE_BREAK_IF_FAILED(ret);
955
956 ret = gate_mgmt_load_wmi_service(&wmi_host, &wmi_namespace, NULL, NULL, &wmi_services, &must_uninit);
957 GATE_BREAK_IF_FAILED(ret);
958
959 bstr_class = gate_win32_bstr_create(&wmi_class_name);
960 bstr_method = gate_win32_bstr_create(methodname);
961 bstr_path = gate_win32_bstr_create(path);
962
963 /* get wmi object class */
964 hr = wmi_services->lpVtbl->GetObject(wmi_services, bstr_class, WBEM_FLAG_RETURN_WBEM_COMPLETE, NULL, &wmi_class, NULL);
965 BREAK_IF_HRESULT_FAILED(hr, ret);
966
967 /* get wmi object method parameters */
968 hr = wmi_class->lpVtbl->GetMethod(wmi_class, bstr_method, WBEM_FLAG_RETURN_WBEM_COMPLETE, &wmi_inparamdefs, &wmi_outparamdefs);
969 BREAK_IF_HRESULT_FAILED(hr, ret);
970
971 if ((wmi_inparamdefs != NULL) && (input_values != NULL))
972 {
973 /* set input parameters (from gate [name->value] map to wmi object) */
974 hr = wmi_inparamdefs->lpVtbl->SpawnInstance(wmi_inparamdefs, 0, &wmi_inargs);
975 BREAK_IF_HRESULT_FAILED(hr, ret);
976
977 ret = setup_argument_values(wmi_inparamdefs, input_values, wmi_inargs);
978 GATE_BREAK_IF_FAILED(ret);
979 }
980
981 /* execute WMI method */
982 hr = wmi_services->lpVtbl->ExecMethod(wmi_services, bstr_path, bstr_method, 0, NULL, wmi_inargs, &wmi_outargs, NULL);
983 BREAK_IF_HRESULT_FAILED(hr, ret);
984
985 if ((wmi_outargs != NULL) && (output_values != NULL))
986 {
987 extract_argument_values(wmi_outargs, output_values);
988 }
989 } while (0);
990
991 GATE_COM_RELEASE(wmi_outargs);
992 GATE_COM_RELEASE(wmi_inargs);
993 GATE_COM_RELEASE(wmi_outparamdefs);
994 GATE_COM_RELEASE(wmi_inparamdefs);
995 GATE_COM_RELEASE(wmi_class);
996
997 gate_win32_bstr_release(bstr_class);
998 gate_win32_bstr_release(bstr_method);
999 gate_win32_bstr_release(bstr_path);
1000
1001 gate_string_release(&wmi_host);
1002 gate_string_release(&wmi_namespace);
1003 gate_string_release(&wmi_class_name);
1004 gate_string_release(&wmi_instance);
1005
1006 gate_mgmt_unload_wmi_service(&wmi_services, &must_uninit);
1007
1008 GATE_DEBUG_TRACE_FAILED_RESULT(ret);
1009 return ret;
1010 }
1011
1012 #endif /* GATE_SYSTEM_MANAGEMENT_WINAPI_IMPL */
1013
1014
1015
1016
1017 #if defined(GATE_SYSTEM_MANAGEMENT_NO_IMPL)
1018
1019 gate_result_t gate_management_list_subsystems(gate_string_t const* host, gate_array_t* subsystems)
1020 {
1021 GATE_UNUSED_ARG(host);
1022 GATE_UNUSED_ARG(subsystems);
1023 return GATE_RESULT_NOTIMPLEMENTED;
1024 }
1025
1026 gate_result_t gate_management_open(gate_string_t const* host, gate_string_t const* subsystem,
1027 gate_string_t const* name_space, gate_enumint_t flags, gate_management_t* handle)
1028 {
1029 GATE_UNUSED_ARG(host);
1030 GATE_UNUSED_ARG(subsystem);
1031 GATE_UNUSED_ARG(name_space);
1032 GATE_UNUSED_ARG(flags);
1033 GATE_UNUSED_ARG(handle);
1034 return GATE_RESULT_NOTIMPLEMENTED;
1035 }
1036
1037 gate_result_t gate_management_close(gate_management_t handle)
1038 {
1039 GATE_UNUSED_ARG(handle);
1040 return GATE_RESULT_NOTIMPLEMENTED;
1041 }
1042
1043 gate_result_t gate_management_get_object(gate_management_t handle, gate_string_t const* path,
1044 gate_management_object_t* obj)
1045 {
1046 GATE_UNUSED_ARG(handle);
1047 GATE_UNUSED_ARG(path);
1048 GATE_UNUSED_ARG(obj);
1049 return GATE_RESULT_NOTIMPLEMENTED;
1050 }
1051
1052 gate_result_t gate_management_query(gate_management_t handle, gate_string_t const* path,
1053 gate_string_t const* query, gate_management_callback_t callback, void* userparam)
1054 {
1055 GATE_UNUSED_ARG(handle);
1056 GATE_UNUSED_ARG(path);
1057 GATE_UNUSED_ARG(query);
1058 GATE_UNUSED_ARG(callback);
1059 GATE_UNUSED_ARG(userparam);
1060 return GATE_RESULT_NOTIMPLEMENTED;
1061 }
1062
1063 gate_result_t gate_management_list_children(gate_management_t handle, gate_string_t const* path,
1064 gate_management_callback_t callback, void* userparam)
1065 {
1066 GATE_UNUSED_ARG(handle);
1067 GATE_UNUSED_ARG(path);
1068 GATE_UNUSED_ARG(callback);
1069 GATE_UNUSED_ARG(userparam);
1070 return GATE_RESULT_NOTIMPLEMENTED;
1071 }
1072
1073 gate_result_t gate_management_list_properties(gate_management_t handle, gate_string_t const* path, gate_map_t* properties)
1074 {
1075 GATE_UNUSED_ARG(handle);
1076 GATE_UNUSED_ARG(path);
1077 GATE_UNUSED_ARG(properties);
1078 return GATE_RESULT_NOTIMPLEMENTED;
1079 }
1080
1081 gate_result_t gate_management_list_methodnames(gate_management_t handle, gate_string_t const* path, gate_array_t* methodnames)
1082 {
1083 GATE_UNUSED_ARG(handle);
1084 GATE_UNUSED_ARG(path);
1085 GATE_UNUSED_ARG(methodnames);
1086 return GATE_RESULT_NOTIMPLEMENTED;
1087 }
1088
1089 gate_result_t gate_management_get_property(gate_management_t handle, gate_string_t const* path,
1090 gate_string_t const* propname, gate_value_t* value)
1091 {
1092 GATE_UNUSED_ARG(handle);
1093 GATE_UNUSED_ARG(path);
1094 GATE_UNUSED_ARG(propname);
1095 GATE_UNUSED_ARG(value);
1096 return GATE_RESULT_NOTIMPLEMENTED;
1097 }
1098
1099 gate_result_t gate_management_set_property(gate_management_t handle, gate_string_t const* path,
1100 gate_string_t const* propname, gate_value_t const* value)
1101 {
1102 GATE_UNUSED_ARG(handle);
1103 GATE_UNUSED_ARG(path);
1104 GATE_UNUSED_ARG(propname);
1105 GATE_UNUSED_ARG(value);
1106 return GATE_RESULT_NOTIMPLEMENTED;
1107 }
1108
1109 gate_result_t gate_management_invoke(gate_management_t handle,
1110 gate_string_t const* path, gate_string_t const* methodname,
1111 gate_map_t const* input_values, gate_map_t* output_values)
1112 {
1113 GATE_UNUSED_ARG(handle);
1114 GATE_UNUSED_ARG(path);
1115 GATE_UNUSED_ARG(methodname);
1116 GATE_UNUSED_ARG(input_values);
1117 GATE_UNUSED_ARG(output_values);
1118 return GATE_RESULT_NOTIMPLEMENTED;
1119 }
1120
1121 #endif /* GATE_SYSTEM_MANAGEMENT_NO_IMPL */
1122