Win32Api USB SetupDiGetDeviceInterfaceDetail fail - PullRequest
2 голосов
/ 12 февраля 2012

Я пытаюсь подключиться к устройству USB GPS.Я могу успешно подключиться к устройству, если я вручную создаю файл через CreateFile WinApi (используя путь, указанный в диспетчере устройств).

Однако, когда я пытаюсь выбрать устройство с помощью перечисления, мне не удается выполнить @ вызов SetupDiGetDeviceInterfaceDetail.

У меня есть код на C, который работает правильно, но мой перевод на C # не работает должным образом.Я перепробовал много вариантов с практически одинаковыми результатами.

C Код, который работает

// Get enumerator handle for the specified ClassGuid
HDEVINFO theDevInfo = SetupDiGetClassDevs((GUID*)&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*)&GUID_DEVINTERFACE_GRMNUSB, 0, &theInterfaceData) &&
    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, &theInterfaceData, NULL, 0, &theBytesReturned, NULL);
// theBytesReturned = 83
theDevDetailData =
(PSP_INTERFACE_DEVICE_DETAIL_DATA)malloc(theBytesReturned);
theDevDetailData->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA);

bool initialized = SetupDiGetDeviceInterfaceDetail(theDevInfo, &theInterfaceData, theDevDetailData, theBytesReturned, NULL, &theDevInfoData);

C #

[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

Ответы [ 2 ]

4 голосов
/ 12 февраля 2012

Поздравляю, это работает. Вы получите строку Unicode, она вдвое длиннее. И ЛОЖНЫЙ возврат верен. Вам просто нужно вызвать Marshal.GetLastWin32Error () и убедиться, что вы получили ERROR_INSUFFICIENT_BUFFER. Ваш код C не работает, возможно, потому что вы забыли инициализировать theBytesReturned в ноль.

2 голосов
/ 12 февраля 2012

Мне кажется, я нашел проблему.

Пройдя по pinvoke.net, я обнаружил следующее

// 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

Изменение этого в моем коде позволяет мне правильно получить DevicePath.

Справочник для заинтересованных.

http://pinvoke.net/default.aspx/setupapi.SetupDiGetDeviceInterfaceDetail

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...