I found an even better solution that doesn't need the unsafe code. A person named wimar created a USB HID library at the following location:
http://www.codeproject.com/KB/cs/USB_HID.aspx.
His library doesn't support interrupt transfer, but he did use a much better approach to dealing with the file stream object. He used System.IO.FileStream to communicate with the HID handle. This approach is MUCH better as it uses a native C# library instead of ReadFile/WriteFile. I simply extended what he did to use an Interrupt transfer handle as the handle for the FileStream. Basically the following is how the various handles are used:
(I didn't take the generichid_cs source quite this far, but this COULD be done)
hidHandle = FileIO.CreateFile(devicePathName[memberIndex], 0, FileIO.FILE_SHARE_READ | FileIO.FILE_SHARE_WRITE, IntPtr.Zero, FileIO.OPEN_EXISTING, 0, 0);
hidFileStream = new FileStream(hidHandle, FileAccess.Read | FileAccess.Write, MyHid.Capabilities.FeatureReportByteLength, false);
readHandle = FileIO.CreateFile(myDevicePathName, FileIO.GENERIC_READ, FileIO.FILE_SHARE_READ | FileIO.FILE_SHARE_WRITE, IntPtr.Zero, FileIO.OPEN_EXISTING, 0, 0);
readFileStream = new FileStream(readHandle, FileAccess.Read, MyHid.Capabilities.InputReportByteLength, false); //true
writeHandle = FileIO.CreateFile(myDevicePathName, FileIO.GENERIC_WRITE, FileIO.FILE_SHARE_READ | FileIO.FILE_SHARE_WRITE, IntPtr.Zero, FileIO.OPEN_EXISTING, 0, 0);
writeFileStream = new FileStream(writeHandle, FileAccess.Write, MyHid.Capabilities.OutputReportByteLength, false);
You simply then use readFileStream.Read, or .BeginRead depending on whether you want to use Synchronous or Asynchronous I/O. I haven't fully investigated it, but I believe either way, when calling CreateFile, don't specify FileIO.FILE_FLAG_OVERLAPPED as was done previously.
Anyway, this now allows the code to be compiled WITHOUT the "unsafe" option which I didn't like. (It also allows a solution for VB.NET for those interested). I've attached the updated genericHID_CS with the changes mentioned. Note that I opted for synchronous I/O since I find the code easier to follow. I simply wrap it in a thread in my own applications to prevent the main thread from blocking. (Either way, the original application was using overlapped I/O, but then blocking the thread til it completed, which basically is the same as using synchronous I/O from the perspective of the application)
Joe
[attachment deleted by admin]