M
Morice Yohan
Guest
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 ?
Continue reading...
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 ?
Continue reading...