mirror of
https://github.com/hakril/PythonForWindows
synced 2026-06-08 14:31:45 +00:00
Adapt lucasg winproxy code to match codebase behavvior
This commit is contained in:
@@ -24,6 +24,9 @@ if bitness() == 32:
|
||||
winstructs.PORT_MESSAGE = winstructs.PORT_MESSAGE32
|
||||
winstructs.PPORT_MESSAGE = winstructs.PPORT_MESSAGE32
|
||||
|
||||
# CFGMGR32
|
||||
winstructs.IRQ_RESOURCE = winstructs.IRQ_RESOURCE_32
|
||||
|
||||
else:
|
||||
winstructs.CONTEXT = winstructs.CONTEXT64
|
||||
winstructs.PCONTEXT = winstructs.PCONTEXT64
|
||||
@@ -41,6 +44,8 @@ else:
|
||||
winstructs.PORT_MESSAGE = winstructs.PORT_MESSAGE64
|
||||
winstructs.PPORT_MESSAGE = winstructs.PPORT_MESSAGE64
|
||||
|
||||
# CFGMGR32
|
||||
winstructs.IRQ_RESOURCE = winstructs.IRQ_RESOURCE_64
|
||||
|
||||
from . import winfuncs
|
||||
from . import windef
|
||||
|
||||
File diff suppressed because one or more lines are too long
+1105
-859
File diff suppressed because it is too large
Load Diff
+1680
-1532
File diff suppressed because it is too large
Load Diff
+2850
-2535
File diff suppressed because one or more lines are too long
@@ -3,114 +3,136 @@ from ctypes import wintypes
|
||||
import windows.generated_def as gdef
|
||||
|
||||
from ..apiproxy import ApiProxy, NeededParameter, is_implemented
|
||||
from ..error import succeed_on_zero, no_error_check
|
||||
from ..error import WinproxyError, result_is_error_code
|
||||
|
||||
CFGMGR32_ERRORS = gdef.FlagMapper(
|
||||
gdef.CR_SUCCESS,
|
||||
gdef.CR_DEFAULT,
|
||||
gdef.CR_OUT_OF_MEMORY,
|
||||
gdef.CR_INVALID_POINTER,
|
||||
gdef.CR_INVALID_FLAG,
|
||||
gdef.CR_INVALID_DEVNODE,
|
||||
gdef.CR_INVALID_DEVINST,
|
||||
gdef.CR_INVALID_RES_DES,
|
||||
gdef.CR_INVALID_LOG_CONF,
|
||||
gdef.CR_INVALID_ARBITRATOR,
|
||||
gdef.CR_INVALID_NODELIST,
|
||||
gdef.CR_DEVNODE_HAS_REQS,
|
||||
gdef.CR_DEVINST_HAS_REQS,
|
||||
gdef.CR_INVALID_RESOURCEID,
|
||||
gdef.CR_DLVXD_NOT_FOUND,
|
||||
gdef.CR_NO_SUCH_DEVNODE,
|
||||
gdef.CR_NO_SUCH_DEVINST,
|
||||
gdef.CR_NO_MORE_LOG_CONF,
|
||||
gdef.CR_NO_MORE_RES_DES,
|
||||
gdef.CR_ALREADY_SUCH_DEVNODE,
|
||||
gdef.CR_ALREADY_SUCH_DEVINST,
|
||||
gdef.CR_INVALID_RANGE_LIST,
|
||||
gdef.CR_INVALID_RANGE,
|
||||
gdef.CR_FAILURE,
|
||||
gdef.CR_NO_SUCH_LOGICAL_DEV,
|
||||
gdef.CR_CREATE_BLOCKED,
|
||||
gdef.CR_NOT_SYSTEM_VM,
|
||||
gdef.CR_REMOVE_VETOED,
|
||||
gdef.CR_APM_VETOED,
|
||||
gdef.CR_INVALID_LOAD_TYPE,
|
||||
gdef.CR_BUFFER_SMALL,
|
||||
gdef.CR_NO_ARBITRATOR,
|
||||
gdef.CR_NO_REGISTRY_HANDLE,
|
||||
gdef.CR_REGISTRY_ERROR,
|
||||
gdef.CR_INVALID_DEVICE_ID,
|
||||
gdef.CR_INVALID_DATA,
|
||||
gdef.CR_INVALID_API,
|
||||
gdef.CR_DEVLOADER_NOT_READY,
|
||||
gdef.CR_NEED_RESTART,
|
||||
gdef.CR_NO_MORE_HW_PROFILES,
|
||||
gdef.CR_DEVICE_NOT_THERE,
|
||||
gdef.CR_NO_SUCH_VALUE,
|
||||
gdef.CR_WRONG_TYPE,
|
||||
gdef.CR_INVALID_PRIORITY,
|
||||
gdef.CR_NOT_DISABLEABLE,
|
||||
gdef.CR_FREE_RESOURCES,
|
||||
gdef.CR_QUERY_VETOED,
|
||||
gdef.CR_CANT_SHARE_IRQ,
|
||||
gdef.CR_NO_DEPENDENT,
|
||||
gdef.CR_SAME_RESOURCES,
|
||||
gdef.CR_NO_SUCH_REGISTRY_KEY,
|
||||
gdef.CR_INVALID_MACHINENAME,
|
||||
gdef.CR_REMOTE_COMM_FAILURE,
|
||||
gdef.CR_MACHINE_UNAVAILABLE,
|
||||
gdef.CR_NO_CM_SERVICES,
|
||||
gdef.CR_ACCESS_DENIED,
|
||||
gdef.CR_CALL_NOT_IMPLEMENTED,
|
||||
gdef.CR_INVALID_PROPERTY,
|
||||
gdef.CR_DEVICE_INTERFACE_ACTIVE,
|
||||
gdef.CR_NO_SUCH_DEVICE_INTERFACE,
|
||||
gdef.CR_INVALID_REFERENCE_STRING,
|
||||
gdef.CR_INVALID_CONFLICT_LIST,
|
||||
gdef.CR_INVALID_INDEX,
|
||||
gdef.CR_INVALID_STRUCTURE_SIZE
|
||||
)
|
||||
|
||||
|
||||
|
||||
class CfgMgr32Error(WinproxyError):
|
||||
def __new__(cls, func_name, error_code):
|
||||
error_flag = CFGMGR32_ERRORS[error_code]
|
||||
api_error = super(WinproxyError, cls).__new__(cls)
|
||||
api_error.api_name = func_name
|
||||
api_error.winerror = error_flag
|
||||
api_error.strerror = error_flag.name
|
||||
api_error.args = (func_name, api_error.winerror, api_error.strerror)
|
||||
return api_error
|
||||
|
||||
def tst_error(func_name, result, func, args):
|
||||
if result:
|
||||
raise CfgMgr32Error(func_name, result)
|
||||
return args
|
||||
|
||||
class CfgMgr32Proxy(ApiProxy):
|
||||
APIDLL = "CfgMgr32"
|
||||
# We can make a custom error_check taht translate error code to CR_ flags if needed
|
||||
default_error_check = staticmethod(tst_error)
|
||||
|
||||
# We suppress error checks since CM_** APIs return either :
|
||||
# - CR_SUCCESS on success
|
||||
# - or a custom status, e.g. CR_NO_SUCH_VALUE on an invalid class index
|
||||
# if necessary, we can convert them to Win32 error usign CM_MapCrToWin32Err
|
||||
default_error_check = staticmethod(no_error_check)
|
||||
|
||||
|
||||
@CfgMgr32Proxy()
|
||||
def CM_Enumerate_Classes(ClassIndex, Params):
|
||||
"""
|
||||
Given a class index, either return the class GUID or None.
|
||||
"""
|
||||
|
||||
guid = gdef.GUID()
|
||||
cr_status = CM_Enumerate_Classes.ctypes_function(ClassIndex, ctypes.byref(guid), Params)
|
||||
|
||||
if cr_status != gdef.CR_SUCCESS:
|
||||
return None
|
||||
|
||||
return guid
|
||||
def CM_Enumerate_Classes(ulClassIndex, ClassGuid, ulFlags):
|
||||
return CM_Enumerate_Classes.ctypes_function(ulClassIndex, ClassGuid, ulFlags)
|
||||
|
||||
|
||||
@CfgMgr32Proxy()
|
||||
def CM_Get_First_Log_Conf(hDevInst, Flags):
|
||||
def CM_Get_First_Log_Conf(plcLogConf, dnDevInst, ulFlags):
|
||||
return CM_Get_First_Log_Conf.ctypes_function(plcLogConf, dnDevInst, ulFlags)
|
||||
|
||||
# TODO : test if process is running as wow64 on a windows >8 and raise an exception if true
|
||||
@CfgMgr32Proxy()
|
||||
def CM_Get_First_Log_Conf_Ex(plcLogConf, dnDevInst, ulFlags, hMachine):
|
||||
return CM_Get_First_Log_Conf_Ex.ctypes_function(plcLogConf, dnDevInst, ulFlags, hMachine)
|
||||
|
||||
@CfgMgr32Proxy()
|
||||
def CM_Get_Next_Log_Conf(plcLogConf, lcLogConf, ulFlags=0):
|
||||
return CM_Get_Next_Log_Conf.ctypes_function(plcLogConf, lcLogConf, ulFlags)
|
||||
|
||||
conf = wintypes.HANDLE(0)
|
||||
@CfgMgr32Proxy()
|
||||
def CM_Get_Next_Log_Conf_Ex(plcLogConf, lcLogConf, ulFlags, hMachine):
|
||||
return CM_Get_Next_Log_Conf_Ex.ctypes_function(plcLogConf, lcLogConf, ulFlags, hMachine)
|
||||
|
||||
cr_status = CM_Get_First_Log_Conf.ctypes_function(
|
||||
ctypes.byref(conf),
|
||||
hDevInst,
|
||||
Flags
|
||||
)
|
||||
|
||||
if cr_status != gdef.CR_SUCCESS:
|
||||
return None
|
||||
|
||||
return conf
|
||||
|
||||
@CfgMgr32Proxy()
|
||||
def CM_Free_Res_Des_Handle(hRes):
|
||||
return CM_Free_Res_Des_Handle.ctypes_function(hRes)
|
||||
|
||||
@CfgMgr32Proxy()
|
||||
def CM_Get_Next_Res_Des(hRes, ResourceType):
|
||||
def CM_Get_Next_Res_Des(prdResDes, rdResDes, ForResource, pResourceID, ulFlags=0):
|
||||
return CM_Get_Next_Res_Des.ctypes_function(prdResDes, rdResDes, ForResource, pResourceID, ulFlags)
|
||||
|
||||
# TODO : test if process is running as wow64 on a windows >8 and raise an exception if true
|
||||
|
||||
updated_hRes = wintypes.HANDLE(0)
|
||||
|
||||
# TODO : support ResType_All query (design change since we need to return the resource type queried)
|
||||
if not ResourceType:
|
||||
raise ValueError("ResType_All not supported")
|
||||
|
||||
if ResourceType > 7:
|
||||
raise ValueError("ResourceType %x > ResType_MAX" % ResourceType)
|
||||
|
||||
status = CM_Get_Next_Res_Des.ctypes_function(
|
||||
ctypes.byref(updated_hRes),
|
||||
hRes,
|
||||
ResourceType,
|
||||
None,
|
||||
0 # flags parameter is not used, and must always be 0
|
||||
)
|
||||
|
||||
# clean up previous hRes
|
||||
CM_Free_Res_Des_Handle(hRes)
|
||||
|
||||
if status != gdef.CR_SUCCESS:
|
||||
return None
|
||||
|
||||
return updated_hRes
|
||||
|
||||
@CfgMgr32Proxy()
|
||||
def CM_Get_Res_Des_Data_Size(hRes):
|
||||
def CM_Get_Res_Des_Data_Size(pulSize, rdResDes, ulFlags=0):
|
||||
return CM_Get_Res_Des_Data_Size.ctypes_function(pulSize, rdResDes, ulFlags)
|
||||
|
||||
resource_size = wintypes.ULONG(0)
|
||||
status = CM_Get_Res_Des_Data_Size.ctypes_function(
|
||||
ctypes.byref(resource_size),
|
||||
hRes,
|
||||
0 # flags parameter is not used, and must always be 0
|
||||
)
|
||||
|
||||
if status != gdef.CR_SUCCESS:
|
||||
return None
|
||||
|
||||
return resource_size.value
|
||||
|
||||
@CfgMgr32Proxy()
|
||||
def CM_Get_Res_Des_Data(hRes, ResourceSize):
|
||||
def CM_Get_Res_Des_Data(rdResDes, Buffer, BufferLen, ulFlags=0):
|
||||
return CM_Get_Res_Des_Data.ctypes_function(rdResDes, Buffer, BufferLen, ulFlags)
|
||||
|
||||
resource_buffer = ctypes.create_string_buffer(ResourceSize)
|
||||
result = CM_Get_Res_Des_Data.ctypes_function(
|
||||
hRes,
|
||||
ctypes.byref(resource_buffer),
|
||||
ResourceSize,
|
||||
0 # flags parameter is not used, and must always be 0
|
||||
)
|
||||
|
||||
if result != gdef.CR_SUCCESS:
|
||||
return None
|
||||
|
||||
# truncate and return data
|
||||
return bytes(resource_buffer)[0:ResourceSize]
|
||||
|
||||
@@ -16,130 +16,60 @@ class SetupApiProxy(ApiProxy):
|
||||
|
||||
|
||||
@SetupApiProxy()
|
||||
def SetupDiClassNameFromGuidA(Guid):
|
||||
"""
|
||||
def SetupDiClassNameFromGuidA(ClassGuid, ClassName, ClassNameSize=None, RequiredSize=None):
|
||||
"""
|
||||
Given a class Guid, return the name associated or raise an Exception
|
||||
"""
|
||||
if ClassNameSize is None:
|
||||
ClassNameSize = ctypes.sizeof(ClassName)
|
||||
return SetupDiClassNameFromGuidA.ctypes_function(ClassGuid, ClassName, ClassNameSize, RequiredSize)
|
||||
|
||||
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()
|
||||
def SetupDiClassNameFromGuidW(Guid):
|
||||
|
||||
"""
|
||||
"""
|
||||
Given a class Guid, return the name associated or raise an Exception
|
||||
"""
|
||||
if ClassNameSize is None:
|
||||
ClassNameSize = ctypes.sizeof(ClassName)
|
||||
return SetupDiClassNameFromGuidW.ctypes_function(ClassGuid, ClassName, ClassNameSize, RequiredSize)
|
||||
|
||||
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(error_check=result_is_handle)
|
||||
def SetupDiGetClassDevsA(Guid, Enumerator = None, hwndParent = None, Flags=0):
|
||||
"""
|
||||
def SetupDiGetClassDevsA(Guid, Enumerator=None, hwndParent=None, Flags=0):
|
||||
"""
|
||||
Given a class GUID, return a HANDLE to the device's information set or raise an Exception
|
||||
"""
|
||||
|
||||
return SetupDiGetClassDevsA.ctypes_function(
|
||||
ctypes.byref(Guid),
|
||||
Enumerator,
|
||||
hwndParent,
|
||||
Flags
|
||||
)
|
||||
return SetupDiGetClassDevsA.ctypes_function(Guid, Enumerator, hwndParent, Flags)
|
||||
|
||||
@SetupApiProxy(error_check=result_is_handle)
|
||||
def SetupDiGetClassDevsW(Guid, Enumerator = None, hwndParent = None, Flags=0):
|
||||
"""
|
||||
def SetupDiGetClassDevsW(Guid, Enumerator=None, hwndParent=None, Flags=0):
|
||||
"""
|
||||
Given a class GUID, return a HANDLE to the device's information set or raise an Exception
|
||||
"""
|
||||
|
||||
return SetupDiGetClassDevsW.ctypes_function(
|
||||
ctypes.byref(Guid),
|
||||
Enumerator,
|
||||
hwndParent,
|
||||
Flags
|
||||
)
|
||||
return SetupDiGetClassDevsW.ctypes_function(Guid, Enumerator, hwndParent, Flags)
|
||||
|
||||
@SetupApiProxy()
|
||||
def SetupDiEnumDeviceInfo(hDevInfo, MemberIndex):
|
||||
def SetupDiEnumDeviceInfo(DeviceInfoSet, MemberIndex, DeviceInfoData):
|
||||
"""
|
||||
Given a device information set, return the info associated with the index
|
||||
or raise ERROR_NO_MORE_ITEMS if there is none anymore.
|
||||
"""
|
||||
|
||||
data = gdef.winstructs.SP_DEVINFO_DATA()
|
||||
data.cbSize = ctypes.sizeof(gdef.winstructs.SP_DEVINFO_DATA)
|
||||
|
||||
success = SetupDiEnumDeviceInfo.ctypes_function(
|
||||
hDevInfo,
|
||||
MemberIndex,
|
||||
ctypes.byref(data)
|
||||
)
|
||||
|
||||
return data
|
||||
return SetupDiEnumDeviceInfo.ctypes_function(DeviceInfoSet, MemberIndex, DeviceInfoData)
|
||||
|
||||
@SetupApiProxy()
|
||||
def SetupDiGetDeviceRegistryPropertyA(hDevInfo, DevData, Property, PropertyType, PropertySize = MAX_DEV_LEN*ctypes.sizeof(wintypes.CHAR)):
|
||||
|
||||
property_buffer = ctypes.create_string_buffer(PropertySize)
|
||||
bytes_written = wintypes.DWORD(0)
|
||||
|
||||
success = SetupDiGetDeviceRegistryPropertyA.ctypes_function(
|
||||
hDevInfo,
|
||||
ctypes.byref(DevData),
|
||||
Property,
|
||||
PropertyType,
|
||||
ctypes.cast(ctypes.byref(property_buffer), gdef.winstructs.PBYTE),
|
||||
wintypes.DWORD(PropertySize),
|
||||
ctypes.byref(bytes_written),
|
||||
)
|
||||
|
||||
# Truncate read data
|
||||
registry_data = bytes(property_buffer)
|
||||
registry_data = registry_data[0:bytes_written.value]
|
||||
|
||||
return registry_data
|
||||
|
||||
def SetupDiEnumDeviceInterfaces(DeviceInfoSet, DeviceInfoData, InterfaceClassGuid, MemberIndex, DeviceInterfaceData):
|
||||
return SetupDiEnumDeviceInterfaces.ctypes_function(DeviceInfoSet, DeviceInfoData, InterfaceClassGuid, MemberIndex, DeviceInterfaceData)
|
||||
|
||||
@SetupApiProxy()
|
||||
def SetupDiGetDeviceRegistryPropertyW(hDevInfo, DevData, Property, PropertyType, PropertySize = MAX_DEV_LEN*ctypes.sizeof(wintypes.WCHAR)):
|
||||
|
||||
property_buffer = ctypes.create_unicode_buffer(PropertySize)
|
||||
bytes_written = wintypes.DWORD(0)
|
||||
|
||||
success = SetupDiGetDeviceRegistryPropertyW.ctypes_function(
|
||||
hDevInfo,
|
||||
ctypes.byref(DevData),
|
||||
Property,
|
||||
PropertyType,
|
||||
ctypes.cast(ctypes.byref(property_buffer), gdef.winstructs.PBYTE),
|
||||
wintypes.DWORD(PropertySize),
|
||||
ctypes.byref(bytes_written),
|
||||
)
|
||||
def SetupDiGetDeviceRegistryPropertyA(DeviceInfoSet, DeviceInfoData, Property, PropertyRegDataType, PropertyBuffer, PropertyBufferSize, RequiredSize):
|
||||
return SetupDiGetDeviceRegistryPropertyA.ctypes_function(DeviceInfoSet, DeviceInfoData, Property, PropertyRegDataType, PropertyBuffer, PropertyBufferSize, RequiredSize)
|
||||
|
||||
@SetupApiProxy()
|
||||
def SetupDiGetDeviceRegistryPropertyW(DeviceInfoSet, DeviceInfoData, Property, PropertyRegDataType, PropertyBuffer, PropertyBufferSize, RequiredSize):
|
||||
return SetupDiGetDeviceRegistryPropertyW.ctypes_function(DeviceInfoSet, DeviceInfoData, Property, PropertyRegDataType, PropertyBuffer, PropertyBufferSize, RequiredSize)
|
||||
|
||||
# Truncate read data
|
||||
registry_data = bytes(property_buffer)
|
||||
registry_data = registry_data[0:bytes_written.value]
|
||||
|
||||
return registry_data
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user