title: Win32Api USB SetupDiGetDeviceInterfaceDetail fail
body: <p>I am attempting to connect to a USB GPS device.  I can successfully connect to the device if I manually create a file via CreateFile WinApi (using the path specified in Device Manager).</p>
  
  <p>However, when I try to select the device through enumeration I fail @ the SetupDiGetDeviceInterfaceDetail call.</p>
  
  <p>I have C code that works correctly, but my C# translation does not appear to work correctly.  I have tried many variations with essentially the same results.</p>
  
  <p><strong>C Code that works</strong></p>
  
  <pre><code>// Get enumerator handle for the specified ClassGuid
  HDEVINFO theDevInfo = SetupDiGetClassDevs((GUID*)&amp;GUID_DEVINTERFACE_GRMNUSB, NULL, NULL,
      DIGCF_PRESENT | DIGCF_INTERFACEDEVICE);
  
  SP_DEVICE_INTERFACE_DATA theInterfaceData;
  theInterfaceData.cbSize = sizeof(theInterfaceData);
  
  // populate theInterfaceData which contains device class information
  if (!SetupDiEnumDeviceInterfaces(theDevInfo, NULL, (GUID*)&amp;GUID_DEVINTERFACE_GRMNUSB, 0, &amp;theInterfaceData) &amp;&amp;
      GetLastError() == ERROR_NO_MORE_ITEMS)
  {
    gHandle = 0;
    return;
  }
  // This is normally used to obtain the device path information using theInterfaceData obtained above
  bool initialized = SetupDiGetDeviceInterfaceDetail(theDevInfo, &amp;theInterfaceData, NULL, 0, &amp;theBytesReturned, NULL);
  // theBytesReturned = 83
  theDevDetailData =
  (PSP_INTERFACE_DEVICE_DETAIL_DATA)malloc(theBytesReturned);
  theDevDetailData-&gt;cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA);
  
  bool initialized = SetupDiGetDeviceInterfaceDetail(theDevInfo, &amp;theInterfaceData, theDevDetailData, theBytesReturned, NULL, &amp;theDevInfoData);
  </code></pre>
  
  <hr>
  
  <p><strong>C#</strong></p>
  
  <pre><code>[DllImport(@"setupapi.dll", CharSet = CharSet.Auto, SetLastError = true)]
  public static extern Boolean SetupDiGetDeviceInterfaceDetail(
      IntPtr hDevInfo,
      ref SP_DEVICE_INTERFACE_DATA deviceInterfaceData,
      IntPtr deviceInterfaceDetailData,
      UInt32 deviceInterfaceDetailDataSize,
      out UInt32 requiredSize,
      IntPtr deviceInfoData
      );
  
  [StructLayout(LayoutKind.Sequential)]
  public struct SP_DEVICE_INTERFACE_DATA
  {
      public Int32 cbSize;
      public Guid interfaceClassGuid;
      public Int32 flags;
      private UIntPtr reserved;
  }
  
  
  // Get enumerator handle for the specified ClassGuid
  IntPtr theDevInfo = SetupDiGetClassDevs(ref ClassGuid, (DiGetClassFlags.DIGCF_PRESENT | DiGetClassFlags.DIGCF_DEVICEINTERFACE));
  
  SP_DEVICE_INTERFACE_DATA DevInterfaceData = new SP_DEVICE_INTERFACE_DATA();
  DevInterfaceData.cbSize = Marshal.SizeOf(DevInterfaceData);
  
  initialized = SetupDiEnumDeviceInterfaces(theDevInfo, IntPtr.Zero, ref ClassGuid, 0,
          ref DevInterfaceData); 
  // I assume The DevInterfaceData is populated correctly as it matches the C Code
  // And I've compared the values in memory and they match
  
  uint bytesReturned = 0;
  initialized = SetupDiGetDeviceInterfaceDetail(theDevInfo, ref DevInterfaceData, IntPtr.Zero, 0, out bytesReturned, IntPtr.Zero);
  // I expect bytesReturned = 83 and initialized = true which is the value that is returned in the C Code
  // Instead the value 162 is returned
  </code></pre>