Как я могу вызвать метод WinUsb_WritePipe в C # без проблем - PullRequest
0 голосов
/ 18 февраля 2019

У меня проблема при вызове метода WinUsb_WritePipe.

Сначала я начинаю с вызова метода CreateFile, который предоставляет мне дескриптор.Затем я вызываю метод «WinUsb_Initialize», чтобы получить WinUsbHandle.

После этого я получаю некоторую информацию о своем USB-устройстве, вызывая «WinUsb_QueryDeviceInformation», «WinUsb_QueryInterfaceSettings» и «WinUsb_QueryPipe» без каких-либо проблем.1006 * Моя проблема добавляется, когда мне приходится вызывать метод WinUsb_WritePipe.В первой библиотеке, которую я сделал на языке Си, она работает правильно.Но я должен переключиться с C на C # для моей новой библиотеки, и метод возвращает False, и последняя ошибка, которую я получаю, - INVALID_PARAMETER.

Похоже, что это происходит из-за перекрывающегося параметра.Я не могу передать NULL этому параметру, как указано в спецификации.

Я не вижу, что я делаю неправильно.

Я уже пробовал:

  • Я уже пытаюсь изменить тип параметра Overlapped с IntPtr, на Int, чтобы поставить 0, как для вызова языка Си.

  • Я пытался изменить IntPtr структурой NativeOverlapped.В первый раз со структурой NULL, но у меня та же проблема.

  • Если я дал инициализированную структуру, я пытаюсь вызвать метод GetOverlappedResult, но он просто возвращает INVALID_PARAMETER, поэтому проблема всегда присутствует.

  • IЯ пытался использовать небезопасный для управления методом как вызов C, но проблема все еще здесь.

Вы можете найти мой код ниже:

[DllImport("winusb.dll", SetLastError = true)]
internal static extern Boolean WinUsb_WritePipe(IntPtr InterfaceHandle, Byte PipeId, Byte[] Buffer, UInt32 BufferLength, ref UInt32 LengthTransferred,  IntPtr Overlapped);


Byte[] SendBuffer = new Byte[3];

SendBuffer[0] = 0x01;

SendBuffer[1] = 0x0D;

SendBuffer[2] = 0x00;

UInt32 BytesToWrite = Convert.ToUInt32(SendBuffer.Length);

UInt32 BytesWritten=0;

IntPtr Handle = DeviceUSB.GetHandle(); //corresponding to the WinUsbHandle

Byte Pipe = DeviceUSB.GetPipe(DeviceUSB.GetSelectedMode()).PipeOutId; // 0x04

Success = WinUsbApiCalls.WinUsb_WritePipe(Handle, Pipe, SendBuffer, SizeToSend, ref SizeSent, IntPtr.Zero);

Я ожидаювозвращаемое значение установлено в true, а SizeSent равно 3., но в действительности возвращается false, а lastError установлено в INVALID_PARAMETER, а SizeSent равно 0.

Ответы [ 2 ]

0 голосов
/ 20 февраля 2019

Я попытался снова с моим первым объявлением DllImport с UInt32 вместо UInt64.Существует не исключение дисбаланса стека, а просто ошибка, полученная последняя ошибка INVALID_PARAMETER.Я думаю, что есть проблема с перекрывающимся параметром, а не с типами параметров размера.Похоже, что метод writepipe не поддерживает метод IntPtr.Zero для перекрытия этого параметра.

0 голосов
/ 18 февраля 2019

Если вы используете этот API https://docs.microsoft.com/en-us/windows/desktop/api/winusb/nf-winusb-winusb_writepipe, вам нужно изменить параметры BufferLength и LengthTransferred с UInt32 на UInt64

C++
BOOL WinUsb_WritePipe(
  WINUSB_INTERFACE_HANDLE InterfaceHandle,
  UCHAR                   PipeID,
  PUCHAR                  Buffer,
  ULONG                   BufferLength,
  PULONG                  LengthTransferred,
  LPOVERLAPPED            Overlapped
);

C#
internal static extern Boolean WinUsb_WritePipe(
    IntPtr InterfaceHandle, 
    Byte PipeId, 
    Byte[] Buffer, 
    UInt64 BufferLength, 
    ref UInt64 LengthTransferred, 
    IntPtr Overlapped);
...