1 | /*
|
---|
2 | WMI Implementation
|
---|
3 | Copyright (C) 2006 Andrzej Hajda <andrzej.hajda@wp.pl>
|
---|
4 | Copyright (C) 2008 Jelmer Vernooij <jelmer@samba.org>
|
---|
5 |
|
---|
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.
|
---|
10 |
|
---|
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.
|
---|
15 |
|
---|
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.
|
---|
19 | */
|
---|
20 |
|
---|
21 | %module wmi
|
---|
22 |
|
---|
23 | %include "typemaps.i"
|
---|
24 | %include "libcli/util/errors.i"
|
---|
25 | %import "stdint.i"
|
---|
26 | %import "lib/talloc/talloc.i"
|
---|
27 |
|
---|
28 | %runtime %{
|
---|
29 | void push_object(PyObject **stack, PyObject *o)
|
---|
30 | {
|
---|
31 | if ((!*stack) || (*stack == Py_None)) {
|
---|
32 | *stack = o;
|
---|
33 | } else {
|
---|
34 | PyObject *o2, *o3;
|
---|
35 | if (!PyTuple_Check(*stack)) {
|
---|
36 | o2 = *stack;
|
---|
37 | *stack = PyTuple_New(1);
|
---|
38 | PyTuple_SetItem(*stack,0,o2);
|
---|
39 | }
|
---|
40 | o3 = PyTuple_New(1);
|
---|
41 | PyTuple_SetItem(o3,0,o);
|
---|
42 | o2 = *stack;
|
---|
43 | *stack = PySequence_Concat(o2,o3);
|
---|
44 | Py_DECREF(o2);
|
---|
45 | Py_DECREF(o3);
|
---|
46 | }
|
---|
47 | }
|
---|
48 | %}
|
---|
49 |
|
---|
50 | %{
|
---|
51 | #include "includes.h"
|
---|
52 | #include "librpc/gen_ndr/misc.h"
|
---|
53 | #include "librpc/rpc/dcerpc.h"
|
---|
54 | #include "lib/com/dcom/dcom.h"
|
---|
55 | #include "librpc/gen_ndr/com_dcom.h"
|
---|
56 | #include "lib/wmi/wmi.h"
|
---|
57 |
|
---|
58 |
|
---|
59 | WERROR WBEM_ConnectServer(struct com_context *ctx, const char *server, const char *nspace, const char *user, const char *password,
|
---|
60 | const char *locale, uint32_t flags, const char *authority, struct IWbemContext* wbem_ctx, struct IWbemServices** services);
|
---|
61 | WERROR IEnumWbemClassObject_SmartNext(struct IEnumWbemClassObject *d, TALLOC_CTX *mem_ctx, int32_t lTimeout,uint32_t uCount,
|
---|
62 | struct WbemClassObject **apObjects, uint32_t *puReturned);
|
---|
63 |
|
---|
64 | static PyObject *PyObject_FromCVAR(uint32_t cimtype, union CIMVAR *cvar);
|
---|
65 | static PyObject *PySWbemObject_FromWbemClassObject(struct WbemClassObject *wco);
|
---|
66 |
|
---|
67 | static struct com_context *com_ctx;
|
---|
68 | static PyObject *ComError;
|
---|
69 | static PyObject *mod_win32_client;
|
---|
70 | static PyObject *mod_pywintypes;
|
---|
71 |
|
---|
72 | typedef struct IUnknown IUnknown;
|
---|
73 | typedef struct IWbemServices IWbemServices;
|
---|
74 | typedef struct IWbemClassObject IWbemClassObject;
|
---|
75 | typedef struct IEnumWbemClassObject IEnumWbemClassObject;
|
---|
76 | %}
|
---|
77 |
|
---|
78 | %wrapper %{
|
---|
79 |
|
---|
80 | #define RETURN_CVAR_ARRAY(fmt, arr) {\
|
---|
81 | PyObject *l, *o;\
|
---|
82 | uint32_t i;\
|
---|
83 | \
|
---|
84 | if (!arr) {\
|
---|
85 | Py_INCREF(Py_None);\
|
---|
86 | return Py_None;\
|
---|
87 | }\
|
---|
88 | l = PyList_New(arr->count);\
|
---|
89 | if (!l) return NULL;\
|
---|
90 | for (i = 0; i < arr->count; ++i) {\
|
---|
91 | o = _Py_BuildValue(fmt, arr->item[i]);\
|
---|
92 | if (!o) {\
|
---|
93 | Py_DECREF(l);\
|
---|
94 | return NULL;\
|
---|
95 | }\
|
---|
96 | PyList_SET_ITEM(l, i, o);\
|
---|
97 | }\
|
---|
98 | return l;\
|
---|
99 | }
|
---|
100 |
|
---|
101 | static PyObject *_Py_BuildValue(char *str, ...)
|
---|
102 | {
|
---|
103 | PyObject * result = NULL;
|
---|
104 | va_list lst;
|
---|
105 | va_start(lst, str);
|
---|
106 | if (str && *str == 'I') {
|
---|
107 | uint32_t value = va_arg(lst, uint32_t);
|
---|
108 | if (value & 0x80000000) {
|
---|
109 | result = Py_BuildValue("L", (long)value);
|
---|
110 | } else {
|
---|
111 | result = Py_BuildValue("i", value);
|
---|
112 | }
|
---|
113 | } else {
|
---|
114 | result = Py_VaBuildValue(str, lst);
|
---|
115 | }
|
---|
116 | va_end(lst);
|
---|
117 | return result;
|
---|
118 | }
|
---|
119 |
|
---|
120 |
|
---|
121 | static PyObject *PyObject_FromCVAR(uint32_t cimtype, union CIMVAR *cvar)
|
---|
122 | {
|
---|
123 | switch (cimtype) {
|
---|
124 | case CIM_SINT8: return Py_BuildValue("b", cvar->v_sint8);
|
---|
125 | case CIM_UINT8: return Py_BuildValue("B", cvar->v_uint8);
|
---|
126 | case CIM_SINT16: return Py_BuildValue("h", cvar->v_sint16);
|
---|
127 | case CIM_UINT16: return Py_BuildValue("H", cvar->v_uint16);
|
---|
128 | case CIM_SINT32: return Py_BuildValue("i", cvar->v_sint32);
|
---|
129 | case CIM_UINT32: return _Py_BuildValue("I", cvar->v_uint32);
|
---|
130 | case CIM_SINT64: return Py_BuildValue("L", cvar->v_sint64);
|
---|
131 | case CIM_UINT64: return Py_BuildValue("K", cvar->v_uint64);
|
---|
132 | case CIM_REAL32: return Py_BuildValue("f", cvar->v_real32);
|
---|
133 | case CIM_REAL64: return Py_BuildValue("d", cvar->v_real64);
|
---|
134 | case CIM_BOOLEAN: return Py_BuildValue("h", cvar->v_boolean);
|
---|
135 | case CIM_STRING: return Py_BuildValue("s", cvar->v_string);
|
---|
136 | case CIM_DATETIME: return Py_BuildValue("s", cvar->v_datetime);
|
---|
137 | case CIM_REFERENCE: return Py_BuildValue("s", cvar->v_reference);
|
---|
138 | case CIM_OBJECT: return PySWbemObject_FromWbemClassObject(cvar->v_object);
|
---|
139 | case CIM_ARR_SINT8: RETURN_CVAR_ARRAY("b", cvar->a_sint8);
|
---|
140 | case CIM_ARR_UINT8: RETURN_CVAR_ARRAY("B", cvar->a_uint8);
|
---|
141 | case CIM_ARR_SINT16: RETURN_CVAR_ARRAY("h", cvar->a_sint16);
|
---|
142 | case CIM_ARR_UINT16: RETURN_CVAR_ARRAY("H", cvar->a_uint16);
|
---|
143 | case CIM_ARR_SINT32: RETURN_CVAR_ARRAY("i", cvar->a_sint32);
|
---|
144 | case CIM_ARR_UINT32: RETURN_CVAR_ARRAY("I", cvar->a_uint32);
|
---|
145 | case CIM_ARR_SINT64: RETURN_CVAR_ARRAY("L", cvar->a_sint64);
|
---|
146 | case CIM_ARR_UINT64: RETURN_CVAR_ARRAY("K", cvar->a_uint64);
|
---|
147 | case CIM_ARR_REAL32: RETURN_CVAR_ARRAY("f", cvar->a_real32);
|
---|
148 | case CIM_ARR_REAL64: RETURN_CVAR_ARRAY("d", cvar->a_real64);
|
---|
149 | case CIM_ARR_BOOLEAN: RETURN_CVAR_ARRAY("h", cvar->a_boolean);
|
---|
150 | case CIM_ARR_STRING: RETURN_CVAR_ARRAY("s", cvar->a_string);
|
---|
151 | case CIM_ARR_DATETIME: RETURN_CVAR_ARRAY("s", cvar->a_datetime);
|
---|
152 | case CIM_ARR_REFERENCE: RETURN_CVAR_ARRAY("s", cvar->a_reference);
|
---|
153 | default:
|
---|
154 | {
|
---|
155 | char *str;
|
---|
156 | str = talloc_asprintf(NULL, "Unsupported CIMTYPE(0x%04X)", cimtype);
|
---|
157 | PyErr_SetString(PyExc_RuntimeError, str);
|
---|
158 | talloc_free(str);
|
---|
159 | return NULL;
|
---|
160 | }
|
---|
161 | }
|
---|
162 | }
|
---|
163 |
|
---|
164 | #undef RETURN_CVAR_ARRAY
|
---|
165 |
|
---|
166 | PyObject *PySWbemObject_InitProperites(PyObject *o, struct WbemClassObject *wco)
|
---|
167 | {
|
---|
168 | PyObject *properties;
|
---|
169 | PyObject *addProp;
|
---|
170 | uint32_t i;
|
---|
171 | int32_t r;
|
---|
172 | PyObject *result;
|
---|
173 |
|
---|
174 | result = NULL;
|
---|
175 | properties = PyObject_GetAttrString(o, "Properties_");
|
---|
176 | if (!properties) return NULL;
|
---|
177 | addProp = PyObject_GetAttrString(properties, "Add");
|
---|
178 | if (!addProp) {
|
---|
179 | Py_DECREF(properties);
|
---|
180 | return NULL;
|
---|
181 | }
|
---|
182 |
|
---|
183 | for (i = 0; i < wco->obj_class->__PROPERTY_COUNT; ++i) {
|
---|
184 | PyObject *args, *property;
|
---|
185 |
|
---|
186 | args = Py_BuildValue("(si)", wco->obj_class->properties[i].property.name, wco->obj_class->properties[i].property.desc->cimtype & CIM_TYPEMASK);
|
---|
187 | if (!args) goto finish;
|
---|
188 | property = PyObject_CallObject(addProp, args);
|
---|
189 | Py_DECREF(args);
|
---|
190 | if (!property) goto finish;
|
---|
191 | if (wco->flags & WCF_INSTANCE) {
|
---|
192 | PyObject *value;
|
---|
193 |
|
---|
194 | if (wco->instance->default_flags[i] & 1) {
|
---|
195 | value = Py_None;
|
---|
196 | Py_INCREF(Py_None);
|
---|
197 | } else
|
---|
198 | value = PyObject_FromCVAR(wco->obj_class->properties[i].property.desc->cimtype & CIM_TYPEMASK, &wco->instance->data[i]);
|
---|
199 | if (!value) {
|
---|
200 | Py_DECREF(property);
|
---|
201 | goto finish;
|
---|
202 | }
|
---|
203 | r = PyObject_SetAttrString(property, "Value", value);
|
---|
204 | Py_DECREF(value);
|
---|
205 | if (r == -1) {
|
---|
206 | PyErr_SetString(PyExc_RuntimeError, "Error setting value of property");
|
---|
207 | goto finish;
|
---|
208 | }
|
---|
209 | }
|
---|
210 | Py_DECREF(property);
|
---|
211 | }
|
---|
212 |
|
---|
213 | Py_INCREF(Py_None);
|
---|
214 | result = Py_None;
|
---|
215 | finish:
|
---|
216 | Py_DECREF(addProp);
|
---|
217 | Py_DECREF(properties);
|
---|
218 | return result;
|
---|
219 | }
|
---|
220 |
|
---|
221 | static PyObject *PySWbemObject_FromWbemClassObject(struct WbemClassObject *wco)
|
---|
222 | {
|
---|
223 | PyObject *swo_class, *swo, *args, *result;
|
---|
224 |
|
---|
225 | swo_class = PyObject_GetAttrString(mod_win32_client, "SWbemObject");
|
---|
226 | if (!swo_class) return NULL;
|
---|
227 | args = PyTuple_New(0);
|
---|
228 | if (!args) {
|
---|
229 | Py_DECREF(swo_class);
|
---|
230 | return NULL;
|
---|
231 | }
|
---|
232 | swo = PyObject_CallObject(swo_class, args);
|
---|
233 | Py_DECREF(args);
|
---|
234 | Py_DECREF(swo_class);
|
---|
235 | if (!swo) return NULL;
|
---|
236 |
|
---|
237 | result = PySWbemObject_InitProperites(swo, wco);
|
---|
238 | if (!result) {
|
---|
239 | Py_DECREF(swo);
|
---|
240 | return NULL;
|
---|
241 | }
|
---|
242 | Py_DECREF(result);
|
---|
243 |
|
---|
244 | return swo;
|
---|
245 | }
|
---|
246 |
|
---|
247 | %}
|
---|
248 |
|
---|
249 | %typemap(in, numinputs=0) struct com_context *ctx {
|
---|
250 | $1 = com_ctx;
|
---|
251 | }
|
---|
252 |
|
---|
253 | %typemap(in, numinputs=0) struct IWbemServices **services (struct IWbemServices *temp) {
|
---|
254 | $1 = &temp;
|
---|
255 | }
|
---|
256 |
|
---|
257 | %typemap(argout) struct IWbemServices **services {
|
---|
258 | PyObject *o;
|
---|
259 | o = SWIG_NewPointerObj(*$1, SWIGTYPE_p_IWbemServices, 0);
|
---|
260 | push_object(&$result, o);
|
---|
261 | }
|
---|
262 |
|
---|
263 | WERROR WBEM_ConnectServer(struct com_context *ctx, const char *server, const char *nspace, const char *user, const char *password,
|
---|
264 | const char *locale, uint32_t flags, const char *authority, struct IWbemContext* wbem_ctx, struct IWbemServices** services);
|
---|
265 |
|
---|
266 | %typemap(in, numinputs=0) struct IEnumWbemClassObject **ppEnum (struct IEnumWbemClassObject *temp) {
|
---|
267 | $1 = &temp;
|
---|
268 | }
|
---|
269 |
|
---|
270 | %typemap(argout) struct IEnumWbemClassObject **ppEnum {
|
---|
271 | PyObject *o;
|
---|
272 | o = SWIG_NewPointerObj(*$1, SWIGTYPE_p_IEnumWbemClassObject, 0);
|
---|
273 | push_object(&$result, o);
|
---|
274 | }
|
---|
275 |
|
---|
276 | typedef struct IUnknown {
|
---|
277 | %extend {
|
---|
278 | uint32_t Release(TALLOC_CTX *mem_ctx);
|
---|
279 | }
|
---|
280 | } IUnknown;
|
---|
281 |
|
---|
282 | %typemap(in) struct BSTR {
|
---|
283 | $1.data = PyString_AsString($input);
|
---|
284 | }
|
---|
285 |
|
---|
286 |
|
---|
287 | typedef struct IWbemServices {
|
---|
288 | %extend {
|
---|
289 | WERROR ExecQuery(TALLOC_CTX *mem_ctx, struct BSTR strQueryLanguage, struct BSTR strQuery, int32_t lFlags, struct IWbemContext *pCtx, struct IEnumWbemClassObject **ppEnum);
|
---|
290 | WERROR ExecNotificationQuery(TALLOC_CTX *mem_ctx, struct BSTR strQueryLanguage, struct BSTR strQuery, int32_t lFlags, struct IWbemContext *pCtx, struct IEnumWbemClassObject **ppEnum);
|
---|
291 | WERROR CreateInstanceEnum(TALLOC_CTX *mem_ctx, struct BSTR strClass,
|
---|
292 | int32_t lFlags, struct IWbemContext *pCtx, struct IEnumWbemClassObject **ppEnum);
|
---|
293 | }
|
---|
294 | } IWbemServices;
|
---|
295 |
|
---|
296 | typedef struct IEnumWbemClassObject {
|
---|
297 | %extend {
|
---|
298 | WERROR Reset(TALLOC_CTX *mem_ctx);
|
---|
299 | }
|
---|
300 | } IEnumWbemClassObject;
|
---|
301 |
|
---|
302 | %typemap(in, numinputs=1) (uint32_t uCount, struct WbemClassObject **apObjects, uint32_t *puReturned) (uint32_t uReturned) {
|
---|
303 | if (PyLong_Check($input))
|
---|
304 | $1 = PyLong_AsUnsignedLong($input);
|
---|
305 | else if (PyInt_Check($input))
|
---|
306 | $1 = PyInt_AsLong($input);
|
---|
307 | else {
|
---|
308 | PyErr_SetString(PyExc_TypeError,"Expected a long or an int");
|
---|
309 | return NULL;
|
---|
310 | }
|
---|
311 | $2 = talloc_array(NULL, struct WbemClassObject *, $1);
|
---|
312 | $3 = &uReturned;
|
---|
313 | }
|
---|
314 |
|
---|
315 | %typemap(argout) (struct WbemClassObject **apObjects, uint32_t *puReturned) {
|
---|
316 | uint32_t i;
|
---|
317 | PyObject *o;
|
---|
318 | int32_t error;
|
---|
319 |
|
---|
320 | error = 0;
|
---|
321 |
|
---|
322 | $result = PyTuple_New(*$2);
|
---|
323 | for (i = 0; i < *$2; ++i) {
|
---|
324 | if (!error) {
|
---|
325 | o = PySWbemObject_FromWbemClassObject($1[i]);
|
---|
326 | if (!o)
|
---|
327 | --error;
|
---|
328 | else
|
---|
329 | error = PyTuple_SetItem($result, i, o);
|
---|
330 | }
|
---|
331 | talloc_free($1[i]);
|
---|
332 | }
|
---|
333 | talloc_free($1);
|
---|
334 | if (error) return NULL;
|
---|
335 | }
|
---|
336 |
|
---|
337 | WERROR IEnumWbemClassObject_SmartNext(struct IEnumWbemClassObject *d, TALLOC_CTX *mem_ctx, int32_t lTimeout, uint32_t uCount,
|
---|
338 | struct WbemClassObject **apObjects, uint32_t *puReturned);
|
---|
339 |
|
---|
340 | %init %{
|
---|
341 |
|
---|
342 | mod_win32_client = PyImport_ImportModule("win32com.client");
|
---|
343 | mod_pywintypes = PyImport_ImportModule("pywintypes");
|
---|
344 | ComError = PyObject_GetAttrString(mod_pywintypes, "com_error");
|
---|
345 |
|
---|
346 | wmi_init(&com_ctx, NULL);
|
---|
347 | {
|
---|
348 | PyObject *pModule;
|
---|
349 |
|
---|
350 | pModule = PyImport_ImportModule( "win32com.client" );
|
---|
351 | }
|
---|
352 | %}
|
---|