librpc: Shorten dcerpc_binding_handle_call a bit
[Samba/gebeck_regimport.git] / source4 / lib / wmi / tools / wmic.c
blobbbfe5ed3341a1c7c582baa40724ec7ce41cf2b28
1 /*
2 WMI Sample client
3 Copyright (C) 2006 Andrzej Hajda <andrzej.hajda@wp.pl>
4 Copyright (C) 2008 Jelmer Vernooij <jelmer@samba.org>
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 #include "includes.h"
22 #include "lib/cmdline/popt_common.h"
23 #include "librpc/rpc/dcerpc.h"
24 #include "librpc/gen_ndr/ndr_oxidresolver.h"
25 #include "librpc/gen_ndr/ndr_oxidresolver_c.h"
26 #include "librpc/gen_ndr/ndr_dcom.h"
27 #include "librpc/gen_ndr/ndr_dcom_c.h"
28 #include "librpc/gen_ndr/ndr_remact_c.h"
29 #include "librpc/gen_ndr/ndr_epmapper_c.h"
30 #include "librpc/gen_ndr/com_dcom.h"
32 #include "lib/com/dcom/dcom.h"
33 #include "lib/com/com.h"
35 #include "lib/wmi/wmi.h"
37 struct program_args {
38 char *hostname;
39 char *query;
40 char *ns;
43 static void parse_args(int argc, char *argv[], struct program_args *pmyargs)
45 poptContext pc;
46 int opt, i;
48 int argc_new;
49 char **argv_new;
51 struct poptOption long_options[] = {
52 POPT_AUTOHELP
53 POPT_COMMON_SAMBA
54 POPT_COMMON_CONNECTION
55 POPT_COMMON_CREDENTIALS
56 POPT_COMMON_VERSION
57 {"namespace", 0, POPT_ARG_STRING, &pmyargs->ns, 0,
58 "WMI namespace, default to root\\cimv2", 0},
59 POPT_TABLEEND
62 pc = poptGetContext("wmi", argc, (const char **) argv,
63 long_options, POPT_CONTEXT_KEEP_FIRST);
65 poptSetOtherOptionHelp(pc, "//host query\n\nExample: wmic -U [domain/]adminuser%password //host \"select * from Win32_ComputerSystem\"");
67 while ((opt = poptGetNextOpt(pc)) != -1) {
68 poptPrintUsage(pc, stdout, 0);
69 poptFreeContext(pc);
70 exit(1);
73 argv_new = discard_const_p(char *, poptGetArgs(pc));
75 argc_new = argc;
76 for (i = 0; i < argc; i++) {
77 if (argv_new[i] == NULL) {
78 argc_new = i;
79 break;
83 if (argc_new != 3 || argv_new[1][0] != '/'
84 || argv_new[1][1] != '/') {
85 poptPrintUsage(pc, stdout, 0);
86 poptFreeContext(pc);
87 exit(1);
90 pmyargs->hostname = argv_new[1] + 2;
91 pmyargs->query = argv_new[2];
92 poptFreeContext(pc);
95 #define WERR_CHECK(msg) if (!W_ERROR_IS_OK(result)) { \
96 DEBUG(0, ("ERROR: %s\n", msg)); \
97 goto error; \
98 } else { \
99 DEBUG(1, ("OK : %s\n", msg)); \
102 #define RETURN_CVAR_ARRAY_STR(fmt, arr) {\
103 uint32_t i;\
104 char *r;\
106 if (!arr) {\
107 return talloc_strdup(mem_ctx, "NULL");\
109 r = talloc_strdup(mem_ctx, "(");\
110 for (i = 0; i < arr->count; ++i) {\
111 r = talloc_asprintf_append(r, fmt "%s", arr->item[i], (i+1 == arr->count)?"":",");\
113 return talloc_asprintf_append(r, ")");\
116 char *string_CIMVAR(TALLOC_CTX *mem_ctx, union CIMVAR *v, enum CIMTYPE_ENUMERATION cimtype)
118 switch (cimtype) {
119 case CIM_SINT8: return talloc_asprintf(mem_ctx, "%d", v->v_sint8);
120 case CIM_UINT8: return talloc_asprintf(mem_ctx, "%u", v->v_uint8);
121 case CIM_SINT16: return talloc_asprintf(mem_ctx, "%d", v->v_sint16);
122 case CIM_UINT16: return talloc_asprintf(mem_ctx, "%u", v->v_uint16);
123 case CIM_SINT32: return talloc_asprintf(mem_ctx, "%d", v->v_sint32);
124 case CIM_UINT32: return talloc_asprintf(mem_ctx, "%u", v->v_uint32);
125 case CIM_SINT64: return talloc_asprintf(mem_ctx, "%lld", v->v_sint64);
126 case CIM_UINT64: return talloc_asprintf(mem_ctx, "%llu", v->v_sint64);
127 case CIM_REAL32: return talloc_asprintf(mem_ctx, "%f", (double)v->v_uint32);
128 case CIM_REAL64: return talloc_asprintf(mem_ctx, "%f", (double)v->v_uint64);
129 case CIM_BOOLEAN: return talloc_asprintf(mem_ctx, "%s", v->v_boolean?"True":"False");
130 case CIM_STRING:
131 case CIM_DATETIME:
132 case CIM_REFERENCE: return talloc_asprintf(mem_ctx, "%s", v->v_string);
133 case CIM_CHAR16: return talloc_asprintf(mem_ctx, "Unsupported");
134 case CIM_OBJECT: return talloc_asprintf(mem_ctx, "Unsupported");
135 case CIM_ARR_SINT8: RETURN_CVAR_ARRAY_STR("%d", v->a_sint8);
136 case CIM_ARR_UINT8: RETURN_CVAR_ARRAY_STR("%u", v->a_uint8);
137 case CIM_ARR_SINT16: RETURN_CVAR_ARRAY_STR("%d", v->a_sint16);
138 case CIM_ARR_UINT16: RETURN_CVAR_ARRAY_STR("%u", v->a_uint16);
139 case CIM_ARR_SINT32: RETURN_CVAR_ARRAY_STR("%d", v->a_sint32);
140 case CIM_ARR_UINT32: RETURN_CVAR_ARRAY_STR("%u", v->a_uint32);
141 case CIM_ARR_SINT64: RETURN_CVAR_ARRAY_STR("%lld", v->a_sint64);
142 case CIM_ARR_UINT64: RETURN_CVAR_ARRAY_STR("%llu", v->a_uint64);
143 case CIM_ARR_REAL32: RETURN_CVAR_ARRAY_STR("%f", v->a_real32);
144 case CIM_ARR_REAL64: RETURN_CVAR_ARRAY_STR("%f", v->a_real64);
145 case CIM_ARR_BOOLEAN: RETURN_CVAR_ARRAY_STR("%d", v->a_boolean);
146 case CIM_ARR_STRING: RETURN_CVAR_ARRAY_STR("%s", v->a_string);
147 case CIM_ARR_DATETIME: RETURN_CVAR_ARRAY_STR("%s", v->a_datetime);
148 case CIM_ARR_REFERENCE: RETURN_CVAR_ARRAY_STR("%s", v->a_reference);
149 default: return talloc_asprintf(mem_ctx, "Unsupported");
153 #undef RETURN_CVAR_ARRAY_STR
155 int main(int argc, char **argv)
157 struct program_args args = {};
158 uint32_t cnt = 5, ret;
159 char *class_name = NULL;
160 WERROR result;
161 NTSTATUS status;
162 struct IWbemServices *pWS = NULL;
163 struct BSTR queryLanguage, query;
164 struct IEnumWbemClassObject *pEnum = NULL;
165 struct com_context *ctx = NULL;
167 parse_args(argc, argv, &args);
169 wmi_init(&ctx, cmdline_credentials);
171 if (!args.ns)
172 args.ns = "root\\cimv2";
173 result = WBEM_ConnectServer(ctx, args.hostname, args.ns, 0, 0, 0, 0, 0, 0, &pWS);
174 WERR_CHECK("Login to remote object.");
176 queryLanguage.data = "WQL";
177 query.data = args.query;
178 result = IWbemServices_ExecQuery(pWS, ctx, queryLanguage, query, WBEM_FLAG_RETURN_IMMEDIATELY | WBEM_FLAG_ENSURE_LOCATABLE, NULL, &pEnum);
179 WERR_CHECK("WMI query execute.");
181 IEnumWbemClassObject_Reset(pEnum, ctx);
182 WERR_CHECK("Reset result of WMI query.");
184 do {
185 uint32_t i, j;
186 struct WbemClassObject *co[cnt];
188 result = IEnumWbemClassObject_SmartNext(pEnum, ctx, 0xFFFFFFFF, cnt, co, &ret);
189 /* WERR_BADFUNC is OK, it means only that there is less returned objects than requested */
190 if (!W_ERROR_EQUAL(result, WERR_BADFUNC)) {
191 WERR_CHECK("Retrieve result data.");
192 } else {
193 DEBUG(1, ("OK : Retrieved less objects than requested (it is normal).\n"));
195 if (!ret) break;
197 for (i = 0; i < ret; ++i) {
198 if (!class_name || strcmp(co[i]->obj_class->__CLASS, class_name)) {
199 if (class_name) talloc_free(class_name);
200 class_name = talloc_strdup(ctx, co[i]->obj_class->__CLASS);
201 printf("CLASS: %s\n", class_name);
202 for (j = 0; j < co[i]->obj_class->__PROPERTY_COUNT; ++j)
203 printf("%s%s", j?"|":"", co[i]->obj_class->properties[j].property.name);
204 printf("\n");
206 for (j = 0; j < co[i]->obj_class->__PROPERTY_COUNT; ++j) {
207 char *s;
208 s = string_CIMVAR(ctx, &co[i]->instance->data[j], co[i]->obj_class->properties[j].property.desc->cimtype & CIM_TYPEMASK);
209 printf("%s%s", j?"|":"", s);
211 printf("\n");
213 } while (ret == cnt);
214 talloc_free(ctx);
215 return 0;
216 error:
217 status = werror_to_ntstatus(result);
218 fprintf(stderr, "NTSTATUS: %s - %s\n", nt_errstr(status), get_friendly_nt_error_msg(status));
219 talloc_free(ctx);
220 return 1;