Type a page name and press Enter. You'll jump to the page if it exists, or you can create it if it doesn't.
To create a page in a module other than setupapi, prefix the name with the module name and a period.
Public Declare Auto Function SetupDiGetDeviceInterfaceDetail2 Lib "setupapi.dll" Alias "SetupDiGetDeviceInterfaceDetailW" ( _
ByVal hDevInfo As IntPtr, _
ByRef deviceInterfaceData As SP_DEVICE_INTERFACE_DATA, _
ByRef deviceInterfaceDetailData As SP_DEVICE_INTERFACE_DETAIL_DATA, _
ByVal deviceInterfaceDetailDataSize As Int32, _
ByRef requiredSize As Int32, _
ByRef deviceInfoData As SP_DEVINFO_DATA) As Boolean
VB.net Signature
Public Declare Auto Function SetupDiGetDeviceInterfaceDetail Lib "setupapi.dll" ( _
ByVal DeviceInfoSet As IntPtr, _
ByRef DeviceInterfaceData As SP_DEVICE_INTERFACE_DATA, _
ByRef DeviceInterfaceDetailData As SP_DEVICE_INTERFACE_DETAIL_DATA, _
ByVal DeviceInterfaceDetailDataSize As UInteger, _
ByRef RequiredSize As UInteger, _
ByRef DeviceInfoData As SP_DEVINFO_DATA) As Boolean '
User-Defined Types:
[StructLayout(LayoutKind.Sequential)]
public struct SP_DEVINFO_DATA
{
public UInt32 cbSize;
public Guid ClassGuid;
public UInt32 DevInst;
public IntPtr Reserved;
}
// Device interface data
[StructLayout(LayoutKind.Sequential)]
public struct SP_DEVICE_INTERFACE_DATA
{
public UInt32 cbSize;
public Guid InterfaceClassGuid;
public UInt32 Flags;
public UIntPtr Reserved;
}
// Device interface detail data
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct SP_DEVICE_INTERFACE_DETAIL_DATA
{
public UInt32 cbSize;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
public string DevicePath;
}
VB User-Defined Types:
<StructLayout(LayoutKind.Sequential)> _
Public Structure SP_DEVICE_INTERFACE_DATA
Public cbSize As Int32
Public InterfaceClassGuid As Guid
Public Flags As Int32
Public Reserved As IntPtr
End Structure
<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)> _
Public Structure SP_DEVICE_INTERFACE_DETAIL_DATA
Public cbSize As UInt32
<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=256)> _
Public DevicePath As String
End Structure
<StructLayout(LayoutKind.Sequential)> _
Public Structure SP_DEVINFO_DATA
Public cbSize As UInteger
Public ClassGuid As Guid
Public DevInst As UInteger
Public Reserved As IntPtr
End Structure
VB.net User-Defined Types:
<StructLayout(LayoutKind.Sequential)> _
Public Structure SP_DEVICE_INTERFACE_DETAIL_DATA
Public cbSize As UInt32
<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=256)> _
Public DevicePath As String
End Structure
Public Structure SP_DEVICE_INTERFACE_DATA
Public cbSize As Int32
Public interfaceClassGuid As Guid
Public flags As Int32
Private reserved As UIntPtr
End Structure
Public Structure SP_DEVINFO_DATA
Public cbSize As Integer
Public ClassGuid As System.Guid
Public DevInst As Integer
Public Reserved As IntPtr
End Structure
Alternative Managed API:
Do you know one? Please contribute it!
Notes:
SP_DEVICE_INTERFACE_DETAIL_DATA needs a ByVal TCHAR[ANYSIZE_ARRAY] member, which could conceivably be any size. This does not bode well for determining the correct size, however DevicePath should be no longer than MAX_PATH (256).
Tips & Tricks:
On the VB side i could not get a valid result passing nulls to the optional parameters, but passing initialized structures seems to work fine.
Sample Code:
Guid DiskGUID = new Guid(GUID_DEVINTERFACE_DISK);
// We start at the "root" of the device tree and look for all
// devices that match the interface GUID of a disk
IntPtr h = SetupDiGetClassDevs(ref DiskGUID, 0, IntPtr.Zero, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
if (h.ToInt32() != INVALID_HANDLE_VALUE)
{
bool Success = true;
int i = 0;
while (Success)
{
// create a Device Interface Data structure
SP_DEVICE_INTERFACE_DATA dia = new SP_DEVICE_INTERFACE_DATA();
dia.cbSize = Marshal.SizeOf(dia);
// start the enumeration
Success = SetupDiEnumDeviceInterfaces(h, IntPtr.Zero, ref DiskGUID, i, ref dia);
if (Success)
{
// build a DevInfo Data structure
SP_DEVINFO_DATA da = new SP_DEVINFO_DATA();
da.cbSize = Marshal.SizeOf(da);
// build a Device Interface Detail Data structure
SP_DEVICE_INTERFACE_DETAIL_DATA didd = new SP_DEVICE_INTERFACE_DETAIL_DATA();
if (IntPtr.Size == 8) // for 64 bit operating systems
didd.cbSize = 8;
else
didd.cbSize = 4 + Marshal.SystemDefaultCharSize; // for 32 bit systems
// now we can get some more detailed information
int nRequiredSize = 0;
int nBytes = BUFFER_SIZE;
if (SetupDiGetDeviceInterfaceDetail(h, ref dia, ref didd, nBytes, ref nRequiredSize, ref da))
{
// current InstanceID is at the "USBSTOR" level, so we
// need up "move up" one level to get to the "USB" level
IntPtr ptrPrevious;
CM_Get_Parent(out ptrPrevious, da.DevInst, 0);
// Now we get the InstanceID of the USB level device
IntPtr ptrInstanceBuf = Marshal.AllocHGlobal(nBytes);
CM_Get_Device_ID(ptrPrevious, ptrInstanceBuf, nBytes, 0);
string InstanceID = Marshal.PtrToStringAuto(ptrInstanceBuf);
'goes through all devices matching the HID guid and finds one with a registry entry string matching the name of the desired HID device, in this case a Midi device
Public Enum Reg_Types
REG_SZ = 1
REG_BINARY = 3
REG_DWORD = 4
REG_MULTI_SZ = 7
End Enum
Function findMIDIKeyAndDescriptor() As Boolean
Dim devEnumInterfaceResult, devDetailResult, devEnumResult, destructionResult, registryPropertyResult As Boolean
Dim reqedBuffer As UInteger
Dim foundIt As Boolean
Dim startRow, searchStringPos As Integer
Dim loopSafety As Integer
Dim myGuid As Guid
Dim strTemp, errorString, ControllerDeviceDesc, ControllerDriverKey As String
Dim h, midih As IntPtr
Dim da, da2 As SP_DEVINFO_DATA
Dim dia As SP_DEVICE_INTERFACE_DATA
Dim didd As SP_DEVICE_INTERFACE_DETAIL_DATA = Nothing
Dim dwChars, errorCode As Long
Dim bufptr As IntPtr = IntPtr.Zero
Dim count, i, j As Integer
Dim MidiDevName As String
Do While devEnumResult And i < loopSafety And devEnumInterfaceResult And Not foundIt
i = i + 1
devEnumResult = SetupDiEnumDeviceInfo(h, i, da)
errorCode = Err.LastDllError
devEnumInterfaceResult = SetupDiEnumDeviceInterfaces(h, IntPtr.Zero, myGuid, i, dia)
If errorCode Then
errorString = ErrorDescriptionDLL(errorCode)
errorCode = 0
End If
If devEnumInterfaceResult And devEnumResult Then
devDetailResult = SetupDiGetDeviceInterfaceDetail(h, dia, didd, 1000, reqedBuffer, da)
'reqedBuffer turns out as 170, this will be diffent on different machines/OS,
'1000 is used as an arbitrarly large number, i found that if this was too small then I would get an error
errorCode = Err.LastDllError
Dim RegType As UInt32 = Reg_Types.REG_SZ
Dim RequiredSize As UInt32
Dim KeyName As String = ""
Dim ptrButter As IntPtr
ptrButter = Marshal.AllocHGlobal(40)
'get the right buffer size for the device description
registryPropertyResult = SetupDiGetDeviceRegistryProperty(h, da, DeviceRegistryValueNames.SPDRP_DEVICEDESC, RegType, ptrButter, 0, RequiredSize)
ptrButter = Marshal.AllocHGlobal(CInt(RequiredSize))
registryPropertyResult = SetupDiGetDeviceRegistryProperty(h, da, DeviceRegistryValueNames.SPDRP_DEVICEDESC, RegType, ptrButter, RequiredSize, RequiredSize)
If registryPropertyResult Then
ControllerDeviceDesc = Marshal.PtrToStringAuto(ptrButter, RequiredSize)
End If
'get the right buffer size for returning the driver key
registryPropertyResult = SetupDiGetDeviceRegistryProperty(h, da, DeviceRegistryValueNames.SPDRP_DRIVER, RegType, ptrButter, RequiredSize, RequiredSize)
ptrButter = Marshal.AllocHGlobal(CInt(RequiredSize))
registryPropertyResult = SetupDiGetDeviceRegistryProperty(h, da, DeviceRegistryValueNames.SPDRP_DRIVER, RegType, ptrButter, RequiredSize, RequiredSize)
If registryPropertyResult Then
ControllerDriverKey = Marshal.PtrToStringAuto(ptrButter, RequiredSize)
searchStringPos = InStr(didd.DevicePath, MidiDevName)
If searchStringPos > 0 Then
foundIt = True
End If
End If
errorCode = Err.LastDllError
Else
errorCode = Err.LastDllError
End If
If foundIt Then
findMIDIKeyAndDescriptor = True
Else
findMIDIKeyAndDescriptor = False
End If
End Function
Retrieve a device information set for the devices in a specified class.
3/24/2020 6:32:30 PM - -24.98.243.63
ByVal is a VB keyword that specifies a variable to be passed as a parameter BY VALUE. In other words, if the function or sub changes the value of the internal variable, it does not change the value of the external variable that was passed to it.
4/25/2007 3:19:55 AM - josep1er@cmich.edu-141.209.229.179
Please edit this page!
Do you have...
helpful tips or sample code to share for using this API in managed code?
corrections to the existing content?
variations of the signature you want to share?
additional languages you want to include?
Select "Edit This Page" on the right hand toolbar and edit it! Or add new pages containing supporting types needed for this API (structures, delegates, and more).