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 %{ 29void 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 59WERROR 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); 61WERROR IEnumWbemClassObject_SmartNext(struct IEnumWbemClassObject *d, TALLOC_CTX *mem_ctx, int32_t lTimeout,uint32_t uCount, 62 struct WbemClassObject **apObjects, uint32_t *puReturned); 63 64static PyObject *PyObject_FromCVAR(uint32_t cimtype, union CIMVAR *cvar); 65static PyObject *PySWbemObject_FromWbemClassObject(struct WbemClassObject *wco); 66 67static struct com_context *com_ctx; 68static PyObject *ComError; 69static PyObject *mod_win32_client; 70static PyObject *mod_pywintypes; 71 72typedef struct IUnknown IUnknown; 73typedef struct IWbemServices IWbemServices; 74typedef struct IWbemClassObject IWbemClassObject; 75typedef 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 101static 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 121static 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 166PyObject *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; 215finish: 216 Py_DECREF(addProp); 217 Py_DECREF(properties); 218 return result; 219} 220 221static 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 263WERROR 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 276typedef 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 287typedef 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 296typedef 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 337WERROR 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%} 353