Question

I need to connect to a USB-device connected to the computer, I have looked around a bit and found some example projects, but cant get this to work. Everything runs nice, but I don't even get into the while-function. Since SetupDiGetClassDevs is from the setupapi.dll I can't debug this function. I do have devices connected, so that is not my problem. Also hInfoSet does get size = 8.

public static HIDDevice FindDevice(int nVid, int nPid, Type oType)
{
    string strPath = string.Empty;
    string strSearch = string.Format("vid_{0:x4}&pid_{1:x4}", nVid, nPid); // first, build the path search string
    Guid gHid;
    HidD_GetHidGuid(out gHid);  // next, get the GUID from Windows that it uses to represent the HID USB interface
    IntPtr hInfoSet = SetupDiGetClassDevs(ref gHid, null, IntPtr.Zero, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT);  // this gets a list of all HID devices currently connected to the computer (InfoSet)
    try
    {
        DeviceInterfaceData oInterface = new DeviceInterfaceData(); // build up a device interface data block
        oInterface.Size = Marshal.SizeOf(oInterface);
        // Now iterate through the InfoSet memory block assigned within Windows in the call to SetupDiGetClassDevs
        // to get device details for each device connected
        int nIndex = 0;
        while (SetupDiEnumDeviceInterfaces(hInfoSet, 0, ref gHid, (uint)nIndex, ref oInterface))    // this gets the device interface information for a device at index 'nIndex' in the memory block
        {
           string strDevicePath = GetDevicePath(hInfoSet, ref oInterface);  // get the device path (see helper method 'GetDevicePath')
            if (strDevicePath.IndexOf(strSearch) >= 0)  // do a string search, if we find the VID/PID string then we found our device!
            {
                HIDDevice oNewDevice = (HIDDevice)Activator.CreateInstance(oType);  // create an instance of the class for this device
                oNewDevice.Initialise(strDevicePath);   // initialise it with the device path
                return oNewDevice;  // and return it
            }
            nIndex++;   // if we get here, we didn't find our device. So move on to the next one.
        }
    }
    finally
    {
        // Before we go, we have to free up the InfoSet memory reserved by SetupDiGetClassDevs
        SetupDiDestroyDeviceInfoList(hInfoSet);
    }
    return null;    
}
Was it helpful?

Solution

Have you tried calling Marshal.GetLastWin32Error and printing the value after the while loop if it's not entering? Make sure to enable SetLastError on SetupDiEnumDeviceInterfaces.

Afterwards, lookup your error code here: http://msdn.microsoft.com/en-us/library/windows/desktop/ms681381%28v=vs.85%29.aspx

EDIT - After reading your comment, the structure should look something like this:

[StructLayout(LayoutKind.Sequential)]
struct GUID
{
    public int a;
    public short b;
    public short c;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst=8)]
    public byte[] d;
}

[StructLayout(LayoutKind.Sequential)]
struct SP_DEVICE_INTERFACE_DATA
{
    public uint cbSize;
    public GUID InterfaceClassGuid;
    public uint Flags;
    public IntPtr Reserved;
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top