0

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;    
}
BenMorel
  • 34,448
  • 50
  • 182
  • 322
Nick3
  • 639
  • 1
  • 14
  • 40

1 Answers1

1

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;
}
master131
  • 431
  • 3
  • 4
  • Thanks! I tryed this now, and got "1784: The supplied user buffer is not valid for the requested operation". But I'm still not sure how to fix this, do you have any idea why this error occures? – Nick3 Nov 19 '13 at 12:21
  • 1
    My guess is that your "DeviceInterfaceData" structure is not marshalled correctly (Marshal.SizeOf is returning the wrong size). Check my edited post. – master131 Nov 21 '13 at 07:47