Source code for windows.winobject.wmi

import windows
import ctypes
import struct
import functools

from ctypes.wintypes import *

import windows.com
from windows.generated_def.winstructs import *
from windows.generated_def.interfaces import IWbemLocator, IWbemServices, IEnumWbemClassObject, IWbemClassObject


[docs]class WmiRequester(object): r"""An object to perform wmi request to ``root\cimv2``""" INSTANCE = None # def __new__(cls, *args, **kwargs): # if cls.INSTANCE is not None: # return cls.INSTANCE # cls.INSTANCE = super(cls, cls).__new__(cls, *args, **kwargs) # return cls.INSTANCE def __init__(self, target="root\\cimv2", user=None, password=None): locator = IWbemLocator() service = IWbemServices() #CLSID_WbemAdministrativeLocator_IID = windows.com.IID.from_string('CB8555CC-9128-11D1-AD9B-00C04FD8FDFF') WbemLocator_CLSID = windows.com.IID.from_string('4590F811-1D3A-11D0-891F-00AA004B2E24') windows.com.init() windows.com.create_instance(WbemLocator_CLSID, locator) locator.ConnectServer(target, user, password , None, 0x80, None, None, ctypes.byref(service)) self.service = service
[docs] def select(self, frm, attrs="*"): """Select ``attrs`` from ``frm`` :rtype: list of dict """ enumerator = IEnumWbemClassObject() try: self.service.ExecQuery("WQL", "select * from {0}".format(frm), 0x20, 0, ctypes.byref(enumerator)) except WindowsError as e: if (e.winerror & 0xffffffff) == WBEM_E_INVALID_CLASS: raise WindowsError(e.winerror, 'WBEM_E_INVALID_CLASS <Invalid WMI class "{0}">'.format(frm)) elif (e.winerror & 0xffffffff) in WBEMSTATUS.values: raise WindowsError(e.winerror, WBEMSTATUS(e.winerror & 0xffffffff).value) raise count = ctypes.c_ulong(0) processor = IWbemClassObject() res = [] enumerator.Next(0xffffffff, 1, ctypes.byref(processor), ctypes.byref(count)) while count.value: current_res = {} variant_res = windows.com.ImprovedVariant() if attrs == "*": attrs = [x for x in self.get_names(processor) if not x.startswith("__")] for name in attrs: processor.Get(name, 0, ctypes.byref(variant_res), None, None) # TODO: something clean and generic if variant_res.vt & VT_ARRAY: if variant_res.vt & VT_TYPEMASK == VT_BSTR: current_res[name] = variant_res.asarray.to_list(BSTR) if variant_res.vt & VT_TYPEMASK == VT_I4: current_res[name] = variant_res.asarray.to_list(LONG) elif variant_res.vt in [VT_EMPTY, VT_NULL]: current_res[name] = None elif variant_res.vt == VT_BSTR: current_res[name] = variant_res.asbstr elif variant_res.vt == VT_I4: current_res[name] = variant_res.aslong elif variant_res.vt == VT_BOOL: current_res[name] = variant_res.asbool elif variant_res.vt == VT_I2: current_res[name] = variant_res.asshort elif variant_res.vt == VT_UI1: current_res[name] = variant_res.asbyte else: print("[WARN] WMI Ignore variant of type {0}".format(hex(variant_res.vt))) res.append(current_res) enumerator.Next(0xffffffff, 1, ctypes.byref(processor), ctypes.byref(count)) return res
def get_names(self, processor): res = POINTER(SAFEARRAY)() processor.GetNames(None, 0, None, byref(res)) safe_array = ctypes.cast(res, POINTER(windows.com.ImprovedSAFEARRAY))[0] safe_array.elt_type = BSTR return safe_array.to_list()