Merge branch 'master' of ssh://git.samba.org/data/git/samba into wmi
[abartlet/samba.git/.git] / source4 / lib / wmi / wmi.i
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 %}