From 0ee191c98185ea909a20220e1dadfa213455bfd3 Mon Sep 17 00:00:00 2001 From: lucasg Date: Sun, 12 Apr 2020 18:55:05 +0200 Subject: [PATCH] [Device] Add setupapi SetupDiClassNameFromGuid winproxy --- samples/device/device_manager.py | 2 +- windows/generated_def/winfuncs.py | 8 +++++ windows/winobject/device.py | 56 +++++++++++++++++++++++++++++-- windows/winproxy/apis/setupapi.py | 47 ++++++++++++++++++++++---- 4 files changed, 103 insertions(+), 10 deletions(-) diff --git a/samples/device/device_manager.py b/samples/device/device_manager.py index 006623e..d4d1ed1 100644 --- a/samples/device/device_manager.py +++ b/samples/device/device_manager.py @@ -4,7 +4,7 @@ from windows.winobject.device import DeviceManager def main(): for device_class in DeviceManager.enumerate_active_class(): - print("-Class : %s" % (device_class)) + print("-[%s] Class %s" % (device_class.guid, device_class.name)) # for device in device_class.devices: # print(" -Device : %s" % (device.name)) diff --git a/windows/generated_def/winfuncs.py b/windows/generated_def/winfuncs.py index ef4c18b..a9eb61a 100644 --- a/windows/generated_def/winfuncs.py +++ b/windows/generated_def/winfuncs.py @@ -3158,3 +3158,11 @@ FindCloseParams = ((1, 'hFindFile'),) CM_Enumerate_ClassesPrototype = WINFUNCTYPE(CR_STATUS, DWORD, POINTER(GUID), DWORD) CM_Enumerate_ClassesParams = ((1, 'ClassIndex'), (1, 'pGUID'), (1,'Params'),) + + + +SetupDiClassNameFromGuidAPrototype = WINFUNCTYPE(BOOL, POINTER(GUID), LPCSTR, DWORD , POINTER(DWORD)) +SetupDiClassNameFromGuidAParams = ((1, 'ClassGuid'),(1, 'ClassName'),(1, 'ClassNameSize'),(1, 'RequiredSize')) + +SetupDiClassNameFromGuidWPrototype = WINFUNCTYPE(BOOL, POINTER(GUID), LPCWSTR, DWORD , POINTER(DWORD)) +SetupDiClassNameFromGuidWParams = ((1, 'ClassGuid'),(1, 'ClassName'),(1, 'ClassNameSize'),(1, 'RequiredSize')) diff --git a/windows/winobject/device.py b/windows/winobject/device.py index 131bf38..fd271da 100644 --- a/windows/winobject/device.py +++ b/windows/winobject/device.py @@ -4,6 +4,59 @@ from windows.generated_def import windef import windows.generated_def as gdef +class DeviceClass(object): + + def __init__(self, guid): + + self._guid = guid + + self._name = None + + # self._devices = None + # self._h_devs = None + + @property + def name(self): + if not self._name: + self._name = self._get_class_name() + + return self._name + + @property + def guid(self): + return self._guid + + # @property + # def devices(self): + # if not self._devices: + + # with OpenDeviceClass(self): + # self._devices = list(do for do in self._get_devices()) + + # return self._devices + + # def _get_devices(self): + + # if not self._h_devs: + # return + + # device_index = 0 + + # while True: + + # device_data = winproxy.SetupDiEnumDeviceInfo(self._h_devs, device_index) + # if not device_data: + # return # stop iterating + + + # device_index+=1 + # yield DeviceObject.from_device_info(self._h_devs, device_data) + + + def _get_class_name(self): + return winproxy.SetupDiClassNameFromGuidW(self.guid) + + class DeviceManager(object): @staticmethod @@ -28,8 +81,7 @@ class DeviceManager(object): if not class_guid: return # stop iterating - #yield DeviceClass(class_guid) - yield class_guid + yield DeviceClass(class_guid) diff --git a/windows/winproxy/apis/setupapi.py b/windows/winproxy/apis/setupapi.py index 93745b3..f7fb039 100644 --- a/windows/winproxy/apis/setupapi.py +++ b/windows/winproxy/apis/setupapi.py @@ -1,21 +1,54 @@ import ctypes +from ctypes import wintypes import windows.generated_def as gdef from ..apiproxy import ApiProxy, NeededParameter, is_implemented -from ..error import succeed_on_zero +from ..error import succeed_on_zero, fail_on_zero + + +MAX_CLASS_NAME_LEN = 32 class SetupApiProxy(ApiProxy): APIDLL = "SetupApi" default_error_check = staticmethod(succeed_on_zero) -# @SetupApiProxy() -# def SetupDiClassNameFromGuidA(Guid): -# return SetupDiClassNameFromGuidA.ctypes_function() +@SetupApiProxy() +def SetupDiClassNameFromGuidA(Guid): + """ + Given a class Guid, return the name associated or raise an Exception + """ -# @SetupApiProxy() -# def SetupDiClassNameFromGuidW(Guid): -# return SetupDiClassNameFromGuidW.ctypes_function() + class_name = ctypes.create_string_buffer(MAX_CLASS_NAME_LEN) + + success = SetupDiClassNameFromGuidA.ctypes_function( + ctypes.byref(Guid), + ctypes.cast(ctypes.byref(class_name), wintypes.LPCSTR), + MAX_CLASS_NAME_LEN, + None + ) + + raw_class_name = bytes(class_name) + return raw_class_name.decode("utf-8").rstrip("\x00") + +@SetupApiProxy(error_check=fail_on_zero) +def SetupDiClassNameFromGuidW(Guid): + + """ + Given a class Guid, return the name associated or raise an Exception + """ + + class_name = ctypes.create_unicode_buffer(MAX_CLASS_NAME_LEN) + + success = SetupDiClassNameFromGuidW.ctypes_function( + ctypes.byref(Guid), + ctypes.cast(ctypes.byref(class_name), wintypes.LPCWSTR), + MAX_CLASS_NAME_LEN, + None + ) + + raw_class_name = bytes(class_name) + return raw_class_name.decode("utf-16-le").rstrip("\x00") # @SetupApiProxy() # def SetupDiGetClassDevsA(Guid):