Code: Select all
EnableExplicit
CompilerIf #PB_Compiler_OS <> #PB_OS_Windows
CompilerError "Error: Windows Only"
End
CompilerEndIf
CompilerIf #PB_Compiler_Unicode = #False
CompilerError "Error: Must Compile with Unicode"
End
CompilerEndIf
If OSVersion() < #PB_OS_Windows_2000
MessageBox_(#Null, "Invalid Operating System", "Requires Windows 2000 or Later", #MB_ICONERROR)
End
EndIf
#SPDIT_COMPATDRIVER = $00000002
#CR_SUCCESS = $00000000
#DI_QUIETINSTALL = $00800000
#DI_NOFILECOPY = $01000000
#MAX_CLASS_NAME_LEN = 32
#LINE_LEN = 256 ;// Windows 9x max for displayable strings from a device INF.
Structure SP_DEVINFO_DATA Align #PB_Structure_AlignC
cbSize.l
ClassGuid.GUID
DevInst.l
*Reserved
EndStructure
Structure SP_DEVINSTALL_PARAMS Align #PB_Structure_AlignC
cbSize.l
Flags.l
FlagsEx.l
hwndParent.i
*InstallMsgHandler
*InstallMsgHandlerContext
*FileQueue
*ClassInstallReserved
Reserved.l
DriverPath.c[#MAX_PATH]
EndStructure
CompilerIf #PB_Compiler_Processor = #PB_Processor_x64
Structure SP_DRVINFO_DATA Align #PB_Structure_AlignC
cbSize.l
DriverType.l
*Reserved
Description.c[#LINE_LEN]
MfgName.c[#LINE_LEN]
ProviderName.c[#LINE_LEN]
DriverDate.FILETIME
DriverVersion.i
EndStructure
Structure SP_DRVINFO_DETAIL_DATA Align #PB_Structure_AlignC
cbSize.l
InfDate.FILETIME
CompatIDsOffset.l
CompatIDsLength.l
*Reserved
SectionName.c[#LINE_LEN]
InfFileName.c[#MAX_PATH]
DrvDescription.c[#LINE_LEN]
HardwareID.c[#ANYSIZE_ARRAY]
EndStructure
CompilerElseIf #PB_Compiler_Processor = #PB_Processor_x86
Structure SP_DRVINFO_DATA Align #PB_Structure_AlignC
cbSize.l
DriverType.l
*Reserved
Padding.l ; Why do I have to pad this for x86?
Description.c[#LINE_LEN]
MfgName.c[#LINE_LEN]
ProviderName.c[#LINE_LEN]
DriverDate.FILETIME
DriverVersion.i
EndStructure
Structure SP_DRVINFO_DETAIL_DATA; Align #PB_Structure_AlignC ; Causes failure for x86?
cbSize.l
InfDate.FILETIME
CompatIDsOffset.l
CompatIDsLength.l
*Reserved
SectionName.c[#LINE_LEN]
InfFileName.c[#MAX_PATH]
DrvDescription.c[#LINE_LEN]
HardwareID.c[#ANYSIZE_ARRAY]
EndStructure
CompilerElse
CompilerError "Error: Unsupported Processor"
End
CompilerEndIf
Prototype CM_Get_DevNode_Status(*Status, *ProblemNumber, DevInst, Flags)
; Based on ABBKlaus procedure
Procedure.s GetLastError(LastError.i)
Protected *Buffer, BufferLength.i, Flags.i, ErrorMessage$
Flags = #FORMAT_MESSAGE_ALLOCATE_BUFFER|#FORMAT_MESSAGE_FROM_SYSTEM
BufferLength = FormatMessage_(Flags, 0, LastError, GetUserDefaultLangID_(), @*Buffer, 0, 0)
If BufferLength
ErrorMessage$ = PeekS(*Buffer)
LocalFree_(*Buffer)
ErrorMessage$ = RemoveString(ErrorMessage$, Chr(13)+Chr(10))
ProcedureReturn "Error Code: " + Str(LastError) + " Error Message: " + ErrorMessage$
Else
ProcedureReturn Str(LastError)
EndIf
EndProcedure
Procedure DebugDriverInfoData_DetailStructures()
Select #PB_Compiler_Processor
Case #PB_Processor_x64
Debug "#======================================"
Debug "# Pure Basic x64 Compiler Version: "+Str(#PB_Compiler_Version)
Debug "#======================================"
Case #PB_Processor_x86
Debug "#======================================"
Debug "# Pure Basic x86 Compiler Version: "+Str(#PB_Compiler_Version)
Debug "#======================================"
EndSelect
Debug "SP_DRVINFO_DATA "+"Size: "+Str(SizeOf(SP_DRVINFO_DATA))
Debug "Alignment Boundry : "+Str(SizeOf(SP_DRVINFO_DATA)%8)
Debug "cbSize "+"Size: "+Str(SizeOf(SP_DRVINFO_DATA\cbSize))+" Offset: "+Str(OffsetOf(SP_DRVINFO_DATA\cbSize))
Debug "DriverType "+"Size: "+Str(SizeOf(SP_DRVINFO_DATA\DriverType))+" Offset: "+Str(OffsetOf(SP_DRVINFO_DATA\DriverType))
Debug "Reserved "+"Size: "+Str(SizeOf(SP_DRVINFO_DATA\Reserved))+" Offset: "+Str(OffsetOf(SP_DRVINFO_DATA\Reserved))
Debug "Description "+"Size: "+Str(SizeOf(SP_DRVINFO_DATA\Description))+" Offset: "+Str(OffsetOf(SP_DRVINFO_DATA\Description))
Debug "MfgName "+"Size: "+Str(SizeOf(SP_DRVINFO_DATA\MfgName))+" Offset: "+Str(OffsetOf(SP_DRVINFO_DATA\MfgName))
Debug "ProviderName "+"Size: "+Str(SizeOf(SP_DRVINFO_DATA\ProviderName))+" Offset: "+Str(OffsetOf(SP_DRVINFO_DATA\ProviderName))
Debug "DriverDate "+"Size: "+Str(SizeOf(SP_DRVINFO_DATA\DriverDate))+" Offset: "+Str(OffsetOf(SP_DRVINFO_DATA\DriverDate))
Debug "DriverVersion "+"Size: "+Str(SizeOf(SP_DRVINFO_DATA\DriverVersion))+" Offset: "+Str(OffsetOf(SP_DRVINFO_DATA\DriverVersion))
Debug "#======================================"
Debug ""
Debug "SP_DRVINFO_DETAIL_DATA "+"Size: "+Str(SizeOf(SP_DRVINFO_DETAIL_DATA))
Debug "Alignment Boundry : "+Str(SizeOf(SP_DRVINFO_DETAIL_DATA)%8)
Debug "cbSize "+"Size: "+Str(SizeOf(SP_DRVINFO_DETAIL_DATA\cbSize))+" Offset: "+Str(OffsetOf(SP_DRVINFO_DETAIL_DATA\cbSize))
Debug "InfDate "+"Size: "+Str(SizeOf(SP_DRVINFO_DETAIL_DATA\InfDate))+" Offset: "+Str(OffsetOf(SP_DRVINFO_DETAIL_DATA\InfDate))
Debug "CompatIDsOffset "+"Size: "+Str(SizeOf(SP_DRVINFO_DETAIL_DATA\CompatIDsOffset))+" Offset: "+Str(OffsetOf(SP_DRVINFO_DETAIL_DATA\CompatIDsOffset))
Debug "CompatIDsLength "+"Size: "+Str(SizeOf(SP_DRVINFO_DETAIL_DATA\CompatIDsLength))+" Offset: "+Str(OffsetOf(SP_DRVINFO_DETAIL_DATA\CompatIDsLength))
Debug "Reserved "+"Size: "+Str(SizeOf(SP_DRVINFO_DETAIL_DATA\Reserved))+" Offset: "+Str(OffsetOf(SP_DRVINFO_DETAIL_DATA\Reserved))
Debug "SectionName "+"Size: "+Str(SizeOf(SP_DRVINFO_DETAIL_DATA\SectionName))+" Offset: "+Str(OffsetOf(SP_DRVINFO_DETAIL_DATA\SectionName))
Debug "InfFileName "+"Size: "+Str(SizeOf(SP_DRVINFO_DETAIL_DATA\InfFileName))+" Offset: "+Str(OffsetOf(SP_DRVINFO_DETAIL_DATA\InfFileName))
Debug "DrvDescription "+"Size: "+Str(SizeOf(SP_DRVINFO_DETAIL_DATA\DrvDescription))+" Offset: "+Str(OffsetOf(SP_DRVINFO_DETAIL_DATA\DrvDescription))
Debug "HardwareID "+"Size: "+Str(SizeOf(SP_DRVINFO_DETAIL_DATA\HardwareID))+" Offset: "+Str(OffsetOf(SP_DRVINFO_DETAIL_DATA\HardwareID))
Debug "#======================================"
Debug ""
EndProcedure
Procedure GetDriverAndInfClassInfo()
Protected DeviceInfoData.SP_DEVINFO_DATA
Protected DeviceInstallParms.SP_DEVINSTALL_PARAMS
Protected DriverInfoData.SP_DRVINFO_DATA
Protected *DriverInfoDetailData.SP_DRVINFO_DETAIL_DATA
Protected.i libSetupAPI, hDevice, DeviceIndex, ConfigReturn, DriverIndex, InfPathLen, DriverInfoDetailSize, ActualDriverInfoDetailSize
Protected.i Status, Problem, Result, InstanceIdStatus, GetDriverInfoDetailStatus, DeviceInstanceIdSize
Protected SectionName$, InfFileName$, InfClassFileName$, InfPath$, DrvDescription$, HardwareID$, ClassName$, ClassGUID$, CopyFiles$, InstanceID$
Protected CM_Get_DevNode_Status_.CM_Get_DevNode_Status
Protected ClassGUID.GUID
Protected *DeviceInstanceId
DeviceInfoData\cbSize = SizeOf(SP_DEVINFO_DATA)
DeviceInstallParms\cbSize = SizeOf(SP_DEVINSTALL_PARAMS)
DriverInfoData\cbSize = SizeOf(SP_DRVINFO_DATA)
DebugDriverInfoData_DetailStructures()
ClassName$ = Space(#MAX_CLASS_NAME_LEN)
InfPath$ = GetEnvironmentVariable("SystemRoot")+"\inf"
InfPathLen = (Len(InfPath$)*SizeOf(Character))+SizeOf(Character)
libSetupAPI = OpenLibrary(#PB_Any, "setupapi.dll")
If libSetupAPI
CM_Get_DevNode_Status_ = GetFunction(libSetupAPI, "CM_Get_DevNode_Status")
If Not CM_Get_DevNode_Status_
Debug "GetFunction Error: Unable to GetFunction CM_Get_DevNode_Status"
CloseLibrary(libSetupAPI)
End
EndIf
Else
Debug "OpenLibrary Error: Unable to OpenLibrary(setupapi.dll)"
End
EndIf
hDevice = SetupDiGetClassDevs_(#Null, 0, 0, #DIGCF_ALLCLASSES|#DIGCF_PRESENT)
If hDevice = #INVALID_HANDLE_VALUE
Debug "ERROR: SetupDiGetClassDevs: "+GetLastError(GetLastError_())
ProcedureReturn GetLastError_()
EndIf
If Not SetupDiEnumDeviceInfo_(hDevice, DeviceIndex, @DeviceInfoData)
Debug "ERROR: SetupDiEnumDeviceInfo: "+GetLastError(GetLastError_())
ProcedureReturn GetLastError_()
EndIf
While GetLastError_() <> #ERROR_NO_MORE_ITEMS
Debug "================================================================================"
InstanceIdStatus = SetupDiGetDeviceInstanceId_(hDevice, @DeviceInfoData, #Null, 0, @DeviceInstanceIdSize)
If InstanceIdStatus = #False And GetLastError_() = #ERROR_INSUFFICIENT_BUFFER
DeviceInstanceIdSize = (DeviceInstanceIdSize * SizeOf(Character))
*DeviceInstanceId = AllocateMemory(DeviceInstanceIdSize + SizeOf(Character))
If *DeviceInstanceId
If SetupDiGetDeviceInstanceId_(hDevice, @DeviceInfoData, *DeviceInstanceId, DeviceInstanceIdSize, #Null)
InstanceID$ = PeekS(*DeviceInstanceId)
FreeMemory(*DeviceInstanceId)
ConfigReturn = CM_Get_DevNode_Status_(@Status, @Problem, DeviceInfoData\DevInst, 0)
If ConfigReturn = #CR_SUCCESS
If SetupDiGetDeviceInstallParams_(hDevice, @DeviceInfoData, @DeviceInstallParms)
DeviceInstallParms\Flags = #DI_QUIETINSTALL|#DI_NOFILECOPY
CopyMemory(@InfPath$, @DeviceInstallParms\DriverPath, InfPathLen)
If SetupDiSetDeviceInstallParams_(hDevice, @DeviceInfoData, @DeviceInstallParms)
If SetupDiBuildDriverInfoList_(hDevice, @DeviceInfoData, #SPDIT_COMPATDRIVER)
DriverIndex = 0
Repeat
If SetupDiEnumDriverInfo_(hDevice, @DeviceInfoData, #SPDIT_COMPATDRIVER, DriverIndex, @DriverInfoData)
GetDriverInfoDetailStatus = SetupDiGetDriverInfoDetail_(hDevice, @DeviceInfoData, @DriverInfoData, 0, 0, @DriverInfoDetailSize)
If GetDriverInfoDetailStatus = #False And GetLastError_() = #ERROR_INSUFFICIENT_BUFFER
*DriverInfoDetailData = AllocateMemory(DriverInfoDetailSize + SizeOf(Character))
If *DriverInfoDetailData
*DriverInfoDetailData\cbSize = SizeOf(SP_DRVINFO_DETAIL_DATA)
If SetupDiGetDriverInfoDetail_(hDevice, @DeviceInfoData, @DriverInfoData, *DriverInfoDetailData, DriverInfoDetailSize, @ActualDriverInfoDetailSize)
SectionName$ = PeekS(@*DriverInfoDetailData\SectionName)
InfFileName$ = PeekS(@*DriverInfoDetailData\InfFileName)
DrvDescription$ = PeekS(@*DriverInfoDetailData\DrvDescription)
HardwareID$ = PeekS(@*DriverInfoDetailData\HardwareID)
If SetupDiGetINFClass_(@InfFileName$ , @ClassGUID, @ClassName$, #MAX_CLASS_NAME_LEN, #Null)
Debug "Device Index : "+Str(DeviceIndex)
Debug "Driver Index : "+Str(DriverIndex)
Debug "DeviceInstanceID: "+InstanceID$
Debug "Hardware ID : "+HardwareID$
Debug "Drv Description : "+DrvDescription$
Debug "Inf File Name : "+InfFileName$
Debug "Section Name : "+SectionName$
Debug "Class Name : "+ClassName$
Else ;// If SetupDiGetINFClass_(@InfFileName$ , @ClassGUID, @ClassName$, #MAX_CLASS_NAME_LEN, #Null)
Debug "ERROR: SetupDiGetINFClass : "+GetLastError(GetLastError_())
EndIf ;// If SetupDiGetINFClass_(@InfFileName$ , @ClassGUID, @ClassName$, #MAX_CLASS_NAME_LEN, #Null)
Else ;// If SetupDiGetDriverInfoDetail_(hDevice, @DeviceInfoData, @DriverInfoData, *DriverInfoDetailData, DriverInfoDetailSize, @ActualDriverInfoDetailSize)
Debug "ERROR: SetupDiGetDriverInfoDetail: "+GetLastError(GetLastError_())
EndIf ;// If SetupDiGetDriverInfoDetail_(hDevice, @DeviceInfoData, @DriverInfoData, *DriverInfoDetailData, DriverInfoDetailSize, @ActualDriverInfoDetailSize)
FreeMemory(*DriverInfoDetailData)
Else ;// If *DriverInfoDetailData
Debug "ERROR: Memory Allocation SetupDiGetDriverInfoDetail"
EndIf ;// If *DriverInfoDetailData
Else ;// If GetDriverInfoDetailStatus = #False And GetLastError_() = #ERROR_INSUFFICIENT_BUFFER
Debug "ERROR: SetupDiGetDriverInfoDetail"
Debug GetLastError(GetLastError_())
EndIf ;// If GetDriverInfoDetailStatus = #False And GetLastError_() = #ERROR_INSUFFICIENT_BUFFER
ElseIf GetLastError_() = #ERROR_NO_MORE_ITEMS
Break
Else
Debug GetLastError(GetLastError_())
EndIf ;// If SetupDiEnumDriverInfo_(hDevice, @DeviceInfoData, #SPDIT_COMPATDRIVER, DriverIndex, @DriverInfoData)
DriverIndex = DriverIndex + 1
ForEver
SetupDiDestroyDriverInfoList_(hDevice, @DeviceInfoData, #SPDIT_COMPATDRIVER)
EndIf ;// If SetupDiBuildDriverInfoList_(hDevice, @DeviceInfoData, #SPDIT_COMPATDRIVER)
EndIf ;// If SetupDiSetDeviceInstallParams_(hDevice, @DeviceInfoData, @DeviceInstallParms)
EndIf ;// If SetupDiGetDeviceInstallParams_(hDevice, @DeviceInfoData, @DeviceInstallParms)
EndIf ;// If ConfigReturn = #CR_SUCCESS
EndIf ;// If SetupDiGetDeviceInstanceId_(hDevice, @DeviceInfoData, *DeviceInstanceId, DeviceInstanceIdSize, #Null)
Else ;// If *DeviceInstanceId
Debug "ERROR: Memory Allocation SetupDiGetDeviceInstanceId"
EndIf ;// If *DeviceInstanceId
Else ;// If GetDriverInfoDetailStatus = #False And GetLastError_() = #ERROR_INSUFFICIENT_BUFFER
Debug "ERROR: SetupDiGetDeviceInstanceId"
EndIf ;// If GetDriverInfoDetailStatus = #False And GetLastError_() = #ERROR_INSUFFICIENT_BUFFER
DeviceIndex = DeviceIndex + 1
SetupDiEnumDeviceInfo_(hDevice, DeviceIndex, @DeviceInfoData)
Wend ;// While GetLastError_() <> #ERROR_NO_MORE_ITEMS
SetupDiDestroyDeviceInfoList_(hDevice)
If Result = #ERROR_NO_MORE_ITEMS : Result = #True : EndIf
CloseLibrary(libSetupAPI)
ProcedureReturn Result
EndProcedure
GetDriverAndInfClassInfo()