Jan-Cornelius Molnar
8/7/2007 9:29:00 PM
Hi,
I'm porting my libusb-win32 device to WinUsb. It is completely controlled
via the Control Pipe so all I want to do is sending control messages to the
device which IMHO can be done via WinUsb_ControlTransfer.
I've already managed getting the WinUsb handle and querying the interface
but unfortunatelly every call to WinUsb_ControlTransfer fails with
ERROR_INVALID_HANDLE :(
maybe you could give me a hint ...
this is my interop api:
[DllImport("winusb.dll")]
public static extern bool WinUsb_Initialize(IntPtr DeviceHandle,
out IntPtr InterfaceHandle);
[DllImport("winusb.dll")]
public static extern bool WinUsb_QueryInterfaceSettings(IntPtr
InterfaceHandle,
byte AlternateSettingNumber,
ref USB_INTERFACE_DESCRIPTOR UsbAltInterfaceDescriptor);
[DllImport("winusb.dll")]
public static unsafe extern bool WinUsb_ControlTransfer(IntPtr
InterfaceHandle,
WINUSB_SETUP_PACKET SetupPacket,
byte[] Buffer,
ulong BufferLength,
out ulong LengthTransferred,
NativeOverlapped* Overlapped);
[DllImport("winusb.dll")]
public static extern bool WinUsb_Free(IntPtr InterfaceHandle);
[StructLayout(LayoutKind.Sequential)]
public struct WINUSB_SETUP_PACKET
{
public byte RequestType;
public byte Request;
public ushort Value;
public ushort Index;
public ushort Length;
}
this is my code:
string path;
IntPtr dHandle;
IntPtr iHandle;
bool success;
// get the device path ...
path = (new SetupApiLayer()).GetDevicePath();
if (String.IsNullOrEmpty(path)) { Console.WriteLine("no
device"); return; }
// create device handle
dHandle = Win32Api.CreateFile(path,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
IntPtr.Zero,
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
IntPtr.Zero);
if (dHandle.ToInt32() == -1) { Win32Api.PrintWin32Error();
return; }
// get winusb handle
success = Win32Api.WinUsb_Initialize(dHandle, out iHandle);
if (!success) { Win32Api.PrintWin32Error(); return; }
try
{
Console.WriteLine("Dev/WinUsb: {0}/{1}", dHandle, iHandle);
// query interface
USB_INTERFACE_DESCRIPTOR desc = new
USB_INTERFACE_DESCRIPTOR();
success = Win32Api.WinUsb_QueryInterfaceSettings(iHandle, 0,
ref desc);
if (!success) { Win32Api.PrintWin32Error(); return; }
Console.WriteLine("Interface Info / Endpoints: {0}",
desc.bNumEndpoints);
// build setup packet
WINUSB_SETUP_PACKET pack = new WINUSB_SETUP_PACKET();
pack.RequestType = USB_TYPE_VENDOR | USB_RECIP_DEVICE |
USB_READ;
pack.Request = (byte)LCD_COMMANDS.Echo;
pack.Value = 123;
pack.Index = 0;
pack.Length = (ushort)Marshal.SizeOf(pack);
byte[] buffer = null;
ulong bytesTransfered;
// create overlapped handle for async i/o
Overlapped ov = new System.Threading.Overlapped();
NativeOverlapped* nov = ov.Pack(new
System.Threading.IOCompletionCallback(OnCallback), buffer);
// send control message
success = Win32Api.WinUsb_ControlTransfer(iHandle, pack,
null, 0, out bytesTransfered, nov);
Console.WriteLine("Bytes Transfered: {0}", bytesTransfered);
if (!success) { Win32Api.PrintWin32Error(); return; }
}
finally
{
// clean up
success = Win32Api.WinUsb_Free(iHandle);
if (!success) { Win32Api.PrintWin32Error(); return; }
}