GCC Code Coverage Report


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