none
WinUSB WritePipe method failure RRS feed

  • Question

  • Hi all, 

    I am facing some issues when I try to send data on bulk pipe.

    I am able to get the handle after calling CreateFile() method.

    IntPtr handleDevice = Kernel32ApiCalls.CreateFile(devicePath, GENERIC_READ | GENERIC_WRITE, 0, IntPtr.Zero, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, IntPtr.Zero);

    Then I am able to get the WinUSB handle by calling WinUsb_Initialize() method.

    WinUsbApiCalls.WinUsb_Initialize(handleDevice, out handle);

    I haven't yet tested ReadPipe() and ControlTransfer() methods, but I am able to call all others WinUsb methods except WritePipe() method.

    It is declared as follow in my code.

    [DllImport("winusb.dll", SetLastError = true, CallingConvention = CallingConvention.Cdecl)]
    internal static extern bool WinUsb_WritePipe(IntPtr InterfaceHandle, uint PipeID, byte[] Buffer, uint BufferLength, ref uint LengthTransferred, IntPtr Overlapped);

    And I call it as follow :

    bool success = WinUsbApiCalls.WinUsb_WritePipe(handle, pipe, sendBuffer, sizeToSend, ref lengthTransferred, IntPtr.Zero);

    where:

    - sendBuffer is defined as new byte[] {0x01, 0x0D, 0x00}

    - sizeToSend is equal to 3

    - lengthTransferred is initialized to 0

    When I test it, I encountered 'PInvokeStackImbalance' exception.

    Few years ago, I have made a shared library which managed WinUsb methods correctly.

    So I have tested to compile a C dll which manages only WinUsb methods call without any intelligency.

    [DllImport("usb.dll", CallingConvention = CallingConvention.Cdecl, SetLastError = true)]
    internal static extern int usbWrite(IntPtr InterfaceHandle, uint PipeID, byte[] Buffer, uint BufferLength);
    int success = UsbApiCalls.usbWrite(handle, pipe, sendBuffer, sizeToSend);

    and on the dll side it works like that:

    - header file:

    typedef int (__stdcall *winusb_writepipe)    (WINUSB_INTERFACE_HANDLE, unsigned char, unsigned char*, unsigned long, unsigned long*, LPOVERLAPPED);
    extern winusb_writepipe  _wusb_write;

    - source file:

    winusb_writepipe _wusb_write;
    
    HINSTANCE dllLib = LoadLibrary("path\\winusb"); 
    if (dllLib != NULL)
    {
       _wusb_write = (winusb_writepipe) GetProcAddress(dllLib,"WinUsb_WritePipe");
    }
    
    DLLEXPORT int usbWrite(PWINUSB_INTERFACE_HANDLE handle, unsigned char pipe, unsigned char* buffer, unsigned long size){
       FILE * fp = fopen ("USB.txt", "w+");
       unsigned long lpBytesWritten=0;
       int err = _wusb_write(handle, pipe, buffer, size, &lpBytesWritten, NULL);
       if(err == 1){
    	if(lpBytesWritten != size){
    	    fprintf(fp, "Size sent incorrect.\n");
    	    return 0;
    	}
       } else {
    	fprintf(fp, "\nLast error : %d\n", (int) GetLastError());
       }
       fclose(fp);
       return err;
    }

    And then I obtain an INVALID_PARAMETER error.

    I did not see what is wrong, because for me, in both cases I respect the WritePipe() method requirements.

    I provide all parameters and I specify "Null" for Overlapped structure to force synchronous communication with USB port.

    It seems that there is a problem to call WritePipe method without specifying an Overlapped structure.

    Can someone help me about this issue ?

    Thursday, May 9, 2019 3:00 PM

All replies

  • Your first pinvoke should not use bool as the return type, as that is a one byte value compared to the Windows BOOL type, which is a 4 byte value. This may explain the imbalance exception, please read https://blogs.msdn.microsoft.com/jaredpar/2008/10/14/pinvoke-and-bool-or-should-i-say-bool/

    WinUsb_WritePipe can only INVALID_PARAMETER  from an API call in its implementation, I would hazard a strong guess that this is being returned by DevceIoControl.


    d -- This posting is provided "AS IS" with no warranties, and confers no rights.

    Thursday, May 9, 2019 9:31 PM
  • When I test it, I encountered 'PInvokeStackImbalance' exception.

    In your C DLL you define calling convention of WinUsb_WritePipe (properly) as stdcall , but in .NET variant you declare it as cdecl.

    -- pa



    • Edited by Pavel A Thursday, May 9, 2019 9:52 PM
    Thursday, May 9, 2019 9:48 PM
  • WinUSB works perfectly well when lpOverlapped is null.  Are you quite sure you're specifying the correct pipe ID from your descriptors?

    Tim Roberts | Driver MVP Emeritus | Providenza & Boekelheide, Inc.

    Friday, May 10, 2019 12:55 AM
  • Yes I'm sure that my PipeId is correct because the device is developed by collegues and it corresponds to the output pipe.

    I have already try to send on other PipeId of the same interface but it does not work either.

    Friday, May 10, 2019 6:39 AM
  • I have tested to use stdcall in .NET but it does not work either.

    But the 'PInvokeStackImbalance' exception does not appear anymore.

    Friday, May 10, 2019 6:39 AM
  • I have tried to change from bool to int return value but the result is the same in my .NET code.

    But the fact to change from Cdecl to StdCall the CallingConvention removed the exception.

    Invalid parameter appears only when I call a sub dll function.

    In .NET library I try to get last error with Kernel32 dll but result is always 0.

    Finally I have always the problem false return value and lengthTrasnferred is still equal to 0.


    Friday, May 10, 2019 6:44 AM
  • WinUSB works perfectly well when lpOverlapped is null.  Are you quite sure you're specifying the correct pipe ID from your descriptors?

    Tim Roberts | Driver MVP Emeritus | Providenza & Boekelheide, Inc.

    I agree with you but when I compiled my dll with Windows 7 all was fine and since I compile my dll under Windows 10, it does not work anymore.

    I have seen that with Windows 10, there are some trouble with the overlapped structure.


    Friday, May 10, 2019 11:56 AM
  • > when I compiled my dll with Windows 7 all was fine and
    > since I compile my dll under Windows 10

    I can't tell what that sentence means.  Are you saying you ran the compiler under Windows 7, or are you saying you compiled it with a target of Windows 7, or are you saying the program runs differently when run on Windows 7 and 10?


    Tim Roberts | Driver MVP Emeritus | Providenza & Boekelheide, Inc.

    Sunday, May 12, 2019 7:41 AM

  • I can't tell what that sentence means.  Are you saying you ran the compiler under Windows 7, or are you saying you compiled it with a target of Windows 7, or are you saying the program runs differently when run on Windows 7 and 10?

    I want say that the program compile differently when run on Windows 7 and  10.

    I compiled it with Windows 7 few years ago, and the dll runs perfectly under Windows 7 and 10.

    But I try to compile again with the same way to call, WinUsb functions with Windows 10 and I am not able to communicate with devices.

    I can only retrieve device details like endpoints in/out, speed, etc... 

    Monday, May 13, 2019 6:56 AM