Code: Alles auswählen
EnableExplicit
Prototype.i CM_Get_First_Log_Conf_(plcLogConf.i, dnDevInst.l, ulFlags.l)
Prototype.i CM_Get_Next_Res_Des_(prdResDes.i, rdResDes.i, ForResource.l, pResourceID.i, ulFlags.i)
Prototype.i CM_Free_Res_Des_Handle_(rdResDes.i)
Prototype.i CM_Get_Res_Des_Data_Size_(pulSize.i, rdResDes.i, ulFlags.i)
Prototype.i CM_Get_Res_Des_Data_(rdResDes.i, *Buffer, BufferLen.i, ulFlags.i)
Prototype.i CM_Get_Device_ID_(dnDevInst.i, *Buffer, BufferLen.i, ulFlags.i)
Global CM_Get_First_Log_Conf.CM_Get_First_Log_Conf_
Global CM_Get_Next_Res_Des.CM_Get_Next_Res_Des_
Global CM_Free_Res_Des_Handle.CM_Free_Res_Des_Handle_
Global CM_Get_Res_Des_Data_Size.CM_Get_Res_Des_Data_Size_
Global CM_Get_Res_Des_Data.CM_Get_Res_Des_Data_
Global CM_Get_Device_ID.CM_Get_Device_ID_
Global Cfgmgr32
Cfgmgr32 = OpenLibrary(#PB_Any, "cfgmgr32.dll")
If Cfgmgr32
CM_Get_First_Log_Conf = GetFunction(Cfgmgr32, "CM_Get_First_Log_Conf")
CM_Get_Next_Res_Des = GetFunction(Cfgmgr32, "CM_Get_Next_Res_Des")
CM_Free_Res_Des_Handle = GetFunction(Cfgmgr32, "CM_Free_Res_Des_Handle")
CM_Get_Res_Des_Data_Size = GetFunction(Cfgmgr32, "CM_Get_Res_Des_Data_Size")
CM_Get_Res_Des_Data = GetFunction(Cfgmgr32, "CM_Get_Res_Des_Data")
CM_Get_Device_ID = GetFunction(Cfgmgr32, "CM_Get_Device_IDA")
EndIf
Structure SP_DEVINFO_DATA
cbSize.l
ClassGuid.GUID
DevInst.l
Reserved.i ; ULONG_PTR
EndStructure
Structure IO_DES
IOD_Count.l
IOD_Type.l
IOD_Alloc_Base.q
IOD_Alloc_End.q
IOD_DesFlags.l
EndStructure
Structure IO_RANGE
IOR_Align.q
IOR_nPorts.l
IOR_Min.q
IOR_Max.q
IOR_RangeFlags.l
IOR_Alias.q
EndStructure
#SPDRP_CLASS = $00000007
#SPDRP_FRIENDLYNAME = $0000000C
#SPDIT_COMPATDRIVER = 2
#ALLOC_LOG_CONF = $00000002
#BOOT_LOG_CONF = $00000003
#CR_SUCCESS = $00000000
#ResType_All = $00000000
#ResType_None = $00000000
#ResType_Mem = $00000001
#ResType_IO = $00000002
#ResType_DMA = $00000003
#ResType_IRQ = $00000004
#ResType_DoNotUse = $00000005
#ResType_BusNumber = $00000006
#ResType_MAX = $00000006
#ResType_Ignored_Bit = $00008000
#ResType_ClassSpecific = $0000FFFF
#ResType_Reserved = $00008000
#ResType_DevicePrivate = $00008001
#ResType_PcCardConfig = $00008002
#ResType_MfCardConfig = $00008003
#MAX_PORTRANGES = 256
Structure SPORTRANGE
RangeBegin.i
RangeEnd.i
EndStructure
Structure SDEVICEINFO
Class.s
ClassDescription.s
Name.s
IOPortRangesCount.i
IOPortRanges.SPORTRANGE[#MAX_PORTRANGES]
EndStructure
Global DevInfo
Procedure ExamineDevices()
DevInfo = SetupDiGetClassDevs_(0, 0, 0, #DIGCF_PRESENT | #DIGCF_ALLCLASSES | #DIGCF_PROFILE)
EndProcedure
Procedure FinishDevices()
SetupDiDestroyDeviceInfoList_(DevInfo)
DevInfo = 0
EndProcedure
Procedure GetDeviceInformation(Index, *DeviceInformation.SDEVICEINFO)
Protected *Buffer.IO_DES
Protected RealSize.i
Protected Result.i
Protected CMResult.i
Protected FirstLogConf.i, NextResDes.i, PrevResDes.i
Protected DevInfoData.SP_DEVINFO_DATA
Result = 0
If *DeviceInformation And DevInfo
*DeviceInformation\IOPortRangesCount = 0
*Buffer = AllocateMemory(2048)
If *Buffer
DevInfoData\cbSize = SizeOf(SP_DEVINFO_DATA)
If SetupDiEnumDeviceInfo_(DevInfo, Index, @DevInfoData)
If SetupDiGetDeviceRegistryProperty_(DevInfo, @DevInfoData, #SPDRP_CLASS, 0, *Buffer, 2048, 0)
*DeviceInformation\Class = PeekS(*Buffer)
If SetupDiGetClassDescription_(@DevInfoData\ClassGuid, *Buffer, #MAX_PATH, @RealSize)
*DeviceInformation\ClassDescription = PeekS(*Buffer)
If SetupDiGetDeviceRegistryProperty_(DevInfo, @DevInfoData, #SPDRP_FRIENDLYNAME, 0, *Buffer, 2048, 0)
*DeviceInformation\Name = PeekS(*Buffer)
CMResult = CM_Get_First_Log_Conf(@FirstLogConf, DevInfoData\DevInst, #ALLOC_LOG_CONF)
If CMResult <> #CR_SUCCESS
CMResult = CM_Get_First_Log_Conf(@FirstLogConf, DevInfoData\DevInst, #BOOT_LOG_CONF)
EndIf
If CMResult = #CR_SUCCESS
If CM_Get_Next_Res_Des(@NextResDes, FirstLogConf, #ResType_IO, 0, 0) = #CR_SUCCESS
Repeat
If CM_Get_Res_Des_Data_Size(@RealSize, NextResDes, 0) = #CR_SUCCESS
If RealSize > MemorySize(*Buffer)
*Buffer = ReAllocateMemory(*Buffer, RealSize)
EndIf
If *Buffer
CM_Get_Res_Des_Data(NextResDes, *Buffer, RealSize, 0)
If *Buffer\IOD_Count = 0
*DeviceInformation\IOPortRanges[*DeviceInformation\IOPortRangesCount]\RangeBegin = *Buffer\IOD_Alloc_Base
*DeviceInformation\IOPortRanges[*DeviceInformation\IOPortRangesCount]\RangeEnd = *Buffer\IOD_Alloc_End
*DeviceInformation\IOPortRangesCount + 1
Else
; I don't know if this would ever happen,
; but then you'd have to read the buffer
; in some special way as there's a whole
; list of IO_RANGEs
EndIf
EndIf
EndIf
PrevResDes = NextResDes
CMResult = CM_Get_Next_Res_Des(@NextResDes, PrevResDes, #ResType_IO, 0, 0)
CM_Free_Res_Des_Handle(PrevResDes)
Until CMResult <> #CR_SUCCESS
EndIf
CM_Free_Res_Des_Handle(FirstLogConf)
EndIf
EndIf
EndIf
EndIf
Result = 1
SetupDiDestroyDriverInfoList_(DevInfo, @DevInfoData, #SPDIT_COMPATDRIVER)
EndIf
If *Buffer
FreeMemory(*Buffer)
EndIf
EndIf
EndIf
ProcedureReturn Result
EndProcedure
; ------------------------------ EXAMPLE CODE ---------------------------------------------------
Define Index
Define k
Define Text.s
Define DeviceInformation.SDEVICEINFO
ExamineDevices()
For Index = 0 To $7FFF
If GetDeviceInformation(Index, @DeviceInformation)
If DeviceInformation\Class = "Ports" And FindString(DeviceInformation\Name, "LPT", 1)
Text = "(" + DeviceInformation\Class + ") " + DeviceInformation\Name
For k = 0 To DeviceInformation\IOPortRangesCount - 1
Text + " ["
Text + RSet(Hex(DeviceInformation\IOPortRanges[k]\RangeBegin, #PB_Integer), SizeOf(Integer), "0")
Text + " - "
Text + RSet(Hex(DeviceInformation\IOPortRanges[k]\RangeEnd , #PB_Integer), SizeOf(Integer), "0")
Text + "] "
Next k
Debug Text
EndIf
EndIf
Next Index
FinishDevices()
Debug ""
Debug "Finished"
If Cfgmgr32
CloseLibrary(Cfgmgr32)
EndIf