Adapted device manager samples & small API improvements

This commit is contained in:
hakril
2020-05-10 20:25:20 +02:00
parent 78c205d248
commit 0ec8ae2fa6
5 changed files with 157 additions and 43 deletions
-40
View File
@@ -1,40 +0,0 @@
import windows
import windows.generated_def as gdef
manager = windows.system.device_manager
print(manager)
for devcls in manager.classes:
print("- {0!r}".format(devcls))
for device in devcls.devices:
print(u" - [{dev.name}] <{dev.description}> ({dev.device_object_name})".format(dev=device))
# Je sais pas trop quoi faire comme API sur ce truc
# Apparement on peut avoir plusieurs logical_configuration par type
# - Je sais meme pas si c'est possible en vrai meme si <CM_Get_Next_Log_Conf> existe
# Idées:
# * get_allocated_conf + get_boot_conf & co
# * logical_configurations() qui retourne la liste complete
# * Je sais pas trop
#
devconf = device.get_first_logical_configuration(gdef.ALLOC_LOG_CONF)
if devconf:
# import pdb;pdb.set_trace()
# print(devconf)
print(" <config:>")
for resource in devconf.resources:
print(" - {0}".format(resource))
# print(dev.description)
# print(dev.device_object_name)
# # x = dev.get_first_logical_configuration(gdef.ALLOC_LOG_CONF)
# x = dev.get_first_logical_configuration(gdef.BOOT_LOG_CONF)
# if x:
# print(x)
# for res in x.resources:
# print(res)
# # print(repr(res.rawdata))
# print(res.header)
# assert not res.data
# # import pdb;pdb.set_trace()
# import pdb;pdb.set_trace()
# print("BYE")
+51
View File
@@ -0,0 +1,51 @@
import sys
import os.path
sys.path.append(os.path.abspath(__file__ + "\..\.."))
import windows
import windows.generated_def as gdef
devmgr = windows.system.device_manager
print("Device manager is {0}".format(devmgr))
print("Enumerating the first 3 device classes")
for cls in devmgr.classes[:3]:
print(" * {0}".format(cls))
print("Finding device class 'System'")
# Allow devmgr.classes["name"] ?
system_cls = [cls for cls in devmgr.classes if cls.name == "System"][0]
print(" * {0}".format(system_cls))
print(" Enumerating some devices of 'System'")
devices = system_cls.devices.all()
for devinst in (devices[0], devices[25], devices[35]): # Some "random" devices to have interesting ones
print(" * {0}".format(devinst))
devconf = devinst.allocated_configuration
if not devconf:
continue
print(" Enumerating allocated resources:")
for resource in devconf.resources:
print(" * {0}".format(resource))
# python64 samples\device\device_manager.py
# Device manager is <windows.winobject.device_manager.DeviceManager object at 0x0000000003669908>
# Enumerating the first 3 device classes
# * <DeviceClass name="XboxComposite" guid=05F5CFE2-4733-4950-A6BB-07AAD01A3A84>
# * <DeviceClass name="DXGKrnl" guid=1264760F-A5C8-4BFE-B314-D56A7B44A362>
# * <DeviceClass name="RemotePosDevice" guid=13E42DFA-85D9-424D-8646-28A70F864F9C>
# Finding device class 'System'
# * <DeviceClass name="System" guid=4D36E97D-E325-11CE-BFC1-08002BE10318>
# Enumerating some devices of 'System'
# * <DeviceInstance "Motherboard resources" (id=1)>
# * <DeviceInstance "Microsoft ACPI-Compliant Embedded Controller" (id=26)>
# Enumerating allocated resources:
# * <IoResource : [0x00000000000062-0x00000000000062]>
# * <IoResource : [0x00000000000066-0x00000000000066]>
# * <DeviceInstance "High Definition Audio Controller" (id=36)>
# Enumerating allocated resources:
# * <MemoryResource : [0x000000f7080000-0x000000f7083fff]>
# * <DevicePrivateResource type=ResType_DevicePrivate(0x8001)>
# * <IrqResource : [0x00000000000011]>
+48
View File
@@ -0,0 +1,48 @@
import argparse
import windows
import windows.generated_def as gdef
devmgr = windows.system.device_manager
def class_generator(filter=None):
for cls in devmgr.classes:
if filter and cls.name != filter:
continue
yield cls
def main(clsfilter, enumerate_devices, print_devinst_resources):
for devcls in class_generator(clsfilter):
print(devcls)
if not enumerate_devices:
continue
# Enumerate devices
for devinst in devcls.devices:
print(" * {0}".format(devinst))
if not print_devinst_resources:
continue
# Device resources
devconf = devinst.allocated_configuration
if not devconf:
# No allocated configuration
# Check boot conf ?
continue
for resource in devconf.resources:
print(" * {0}".format(resource))
if __name__ == "__main__":
parser = argparse.ArgumentParser(prog=__file__, formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument("--class", dest="clsfilter", default=None, help="The classe to list: default all")
parser.add_argument("--no-print-devices", action="store_true", help="Prevent the listing of devices in the matching classes")
parser.add_argument("--print-resources", action="store_true", help="Print the resources allocated to the device instance")
args = parser.parse_args()
print(args)
main(args.clsfilter,
enumerate_devices=not args.no_print_devices,
print_devinst_resources=args.print_resources)
+54 -3
View File
@@ -11,6 +11,9 @@ from windows.utils import fixedproperty
class DeviceManager(object):
@property
def classes(self):
return list(self._classes_generator())
def _classes_generator(self):
for index in itertools.count():
try:
yield self._enumerate_classes(index, 0)
@@ -55,7 +58,7 @@ class DeviceClass(gdef.GUID):
def __repr__(self):
guid_cls = self.to_string()
return """<{0} {2} name="{1}">""".format(type(self).__name__, self.name, guid_cls)
return """<{0} name="{1}" guid={2}>""".format(type(self).__name__, self.name, guid_cls)
__str__ = __repr__ # Overwrite default GUID str
@@ -80,6 +83,9 @@ class DeviceInformationSet(gdef.HDEVINFO):
def enum_device_interface(self, index):
raise NotImplementedError("enum_device_interface")
def all(self):
return list(self)
class DeviceInstance(gdef.SP_DEVINFO_DATA):
def __init__(self, information_set=None):
@@ -148,6 +154,9 @@ class DeviceInstance(gdef.SP_DEVINFO_DATA):
raise
# https://docs.microsoft.com/en-us/windows-hardware/drivers/kernel/hardware-resources
# Explanation of types:
# - https://docs.microsoft.com/en-us/windows-hardware/drivers/kernel/hardware-resources#logical-configuration-types-for-resource-requirements-lists
def get_first_logical_configuration(self, type):
res = LogicalConfiguration()
try:
@@ -163,6 +172,49 @@ class DeviceInstance(gdef.SP_DEVINFO_DATA):
winproxy.CM_Get_Next_Log_Conf(res, logconf)
return res
def _logical_configuration_generator(self, type):
x = self.get_first_logical_configuration(type)
while x:
yield x
try:
x = self.get_next_logical_configuration(x)
except WindowsError as e:
if e.winerror == gdef.CR_NO_MORE_LOG_CONF:
return
raise
def get_logical_configuration(self, type):
return list(self._logical_configuration_generator(type))
# Allocated Configuration
# From https://docs.microsoft.com/en-us/windows-hardware/drivers/kernel/hardware-resources#logical-configuration-types-for-resource-lists
# A resource list identifying resources currently in use by a device instance.
# !!! Only one allocated configuration can exist for each device instance.
@property
def allocated_configuration(self):
allocconfs = self.get_logical_configuration(gdef.ALLOC_LOG_CONF)
if not allocconfs:
return allocconfs
assert len(allocconfs) == 1 # Only one allocated configuration can exist for each device instance.
return allocconfs[0]
# Boot Configuration
# From https://docs.microsoft.com/en-us/windows-hardware/drivers/kernel/hardware-resources#logical-configuration-types-for-resource-lists
# A resource list identifying the resources assigned to a device instance when the system is booted
# Only one boot configuration can exist for each device instance.
@property
def boot_configuration(self):
bootconfs = self.get_logical_configuration(gdef.BOOT_LOG_CONF)
if not bootconfs:
return bootconfs
assert len(bootconfs) == 1 # Only one boot configuration can exist for each device instance.
return bootconfs[0]
# Make properties for Each type of logical configuration ?
# 'advanced' attributes extrapolated from properties
@property
@@ -170,7 +222,7 @@ class DeviceInstance(gdef.SP_DEVINFO_DATA):
return SecurityDescriptor.from_binary(self.raw_security_descriptor)
def __repr__(self):
return """<{0} {1}>""".format(type(self).__name__, self.DevInst)
return """<{0} "{1}" (id={2})>""".format(type(self).__name__, self.description, self.DevInst)
class LogicalConfiguration(gdef.HANDLE):
@@ -305,7 +357,6 @@ class DmaResource(ResourceDescriptorWithHeaderAndRanges):
DATA_TYPE = gdef.DMA_RESOURCE
def __str__(self):
import pdb;pdb.set_trace()
return "<{0} : [{1:#016x}]>".format(type(self).__name__, self.header.DD_Alloc_Chan)
+4
View File
@@ -136,3 +136,7 @@ def CM_Get_Res_Des_Data_Size(pulSize, rdResDes, ulFlags=0):
def CM_Get_Res_Des_Data(rdResDes, Buffer, BufferLen, ulFlags=0):
return CM_Get_Res_Des_Data.ctypes_function(rdResDes, Buffer, BufferLen, ulFlags)
@CfgMgr32Proxy()
def CM_Get_Parent(pdnDevInst, dnDevInst, ulFlags=0):
return CM_Get_Parent.ctypes_function(pdnDevInst, dnDevInst, ulFlags)