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.
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"
43 static void parse_args(int argc
, char *argv
[], struct program_args
*pmyargs
)
51 struct poptOption long_options
[] = {
54 POPT_COMMON_CONNECTION
55 POPT_COMMON_CREDENTIALS
57 {"namespace", 0, POPT_ARG_STRING
, &pmyargs
->ns
, 0,
58 "WMI namespace, default to root\\cimv2", 0},
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);
73 argv_new
= discard_const_p(char *, poptGetArgs(pc
));
76 for (i
= 0; i
< argc
; i
++) {
77 if (argv_new
[i
] == NULL
) {
83 if (argc_new
!= 3 || argv_new
[1][0] != '/'
84 || argv_new
[1][1] != '/') {
85 poptPrintUsage(pc
, stdout
, 0);
90 pmyargs
->hostname
= argv_new
[1] + 2;
91 pmyargs
->query
= argv_new
[2];
95 #define WERR_CHECK(msg) if (!W_ERROR_IS_OK(result)) { \
96 DEBUG(0, ("ERROR: %s\n", msg)); \
99 DEBUG(1, ("OK : %s\n", msg)); \
102 #define RETURN_CVAR_ARRAY_STR(fmt, 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
)
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");
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
;
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
);
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.");
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.");
193 DEBUG(1, ("OK : Retrieved less objects than requested (it is normal).\n"));
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
);
206 for (j
= 0; j
< co
[i
]->obj_class
->__PROPERTY_COUNT
; ++j
) {
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
);
213 } while (ret
== cnt
);
217 status
= werror_to_ntstatus(result
);
218 fprintf(stderr
, "NTSTATUS: %s - %s\n", nt_errstr(status
), get_friendly_nt_error_msg(status
));