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