Author Topic: Difficulty writing to HID device using WriteFile  (Read 14424 times)

SiberShadow

  • Member
  • ***
  • Posts: 5
Difficulty writing to HID device using WriteFile
« on: April 24, 2014, 05:24:49 pm »
Hi...  trying a basic write to an USB-attached HID device. 


//Relevant Code//

  Dim numberOfBytesWritten As Int32 = 0
  Dim outputReportBuffer() As Byte = Nothing
  Dim Success As Boolean
  Array.Resize(outputReportBuffer, Capabilities.OutputReportByteLength)

  outputReportBuffer(0) = 0
 
' Write
  Success = WriteFile(deviceHandle, outputReportBuffer, _
           outputReportBuffer.Length, numberOfBytesWritten, IntPtr.Zero)

' Test for WriteFile failure
  If (Success = 0) Then
       ErrorExit("Could not write an Output Report")
  End If


 <DllImport("kernel32.dll", SetLastError:=True)> _
    Shared Function WriteFile _
            (ByVal hFile As SafeFileHandle, _
            ByVal lpBuffer() As Byte, _
            ByVal nNumberOfBytesToWrite As Int32, _
            ByRef lpNumberOfBytesWritten As Int32, _
            ByVal lpOverlapped As IntPtr) _
    As Boolean
    End Function


(Took out the ReportID byte for the moment, because I'm just sending zeroes anyway.)



//Some things tried//

1.) Got USB Complete(4th) and perused the updated posted code.
2.) Now able to successfully CreateFile, Locate, Get Attributes, Capabilities, Handle, etc. for attached device; but cannot WriteFile to simply intialize it.
3.) Exceptions include protected memory error et al., depending on the permutations I attempt to get things to work.
4.) Just trying to write zeroes to reset the device at this point, nothing fancy.
5.) As noted, handle is valid. 
6.) During debug, "Capabilities.OutputReportByteLength" identifies as only 1 Byte, which seemed odd.


//Background//

1.) [The original source code that came with board was <= VB6.]
2.) Purchased Appleman's Win32 API book et al. including apigid32.dll, but had difficulty translating stuff to newer environment.
3.) Presently using VB via VS Express 2012, to somewhat begin fresh.



 Code above... any help is appreciated.


Jan Axelson

  • Administrator
  • Frequent Contributor
  • *****
  • Posts: 3033
    • Lakeview Research
Re: Difficulty writing to HID device using WriteFile
« Reply #1 on: April 24, 2014, 05:31:28 pm »
Capabilities.OutputReportByteLength  should match the Output report length in the report descriptor returned by the device.

What error do you get using the code you posted?

SiberShadow

  • Member
  • ***
  • Posts: 5
Re: Difficulty writing to HID device using WriteFile
« Reply #2 on: April 24, 2014, 09:08:14 pm »
Thanks for your quick reply... it helped me realize some things.  (Yes, those values match.)

I'm getting "An unhandled exception of type 'System.AccessViolationException' occurred in System.Windows.Forms.dll
Additional information: Attempted to read or write protected memory.  This is often an indication that other memory is corrupt" error." 

I suspect the basic code itself is ok, but that I messed up how it's organized.  I probably do better in a mismanaged code environment.  :-)  I need to think some about variable lifetimes and stuff.  Thanks....

SiberShadow

  • Member
  • ***
  • Posts: 5
Re: Difficulty writing to HID device using WriteFile
« Reply #3 on: April 25, 2014, 10:55:31 pm »
Read a bunch and tried some things, but no luck.

If "Capabilities.OutputReportByteLength" shows a value of only 1 Byte, and the first Byte of the WriteFile function is to be used for the ReportID... then where do I put the command?  I tried expanding the outputReportBuffer to hold 2 Bytes, but I still get a "False" return. 

(The error I mentioned before happens later, and I think may be unrelated.)

Jan Axelson

  • Administrator
  • Frequent Contributor
  • *****
  • Posts: 3033
    • Lakeview Research
Re: Difficulty writing to HID device using WriteFile
« Reply #4 on: April 26, 2014, 05:06:57 pm »
Capabilities.OutputReportByteLength is the report length. The buffer you pass to WriteFile must have room for the report plus one byte for the report ID, which is the first byte in the buffer. If the report descriptor doesn't specify report IDs, the report ID is zero.

Use breakpoints to examine the parameters passed and returned by WriteFile. Use GetLastError to retrieve an error message. My example code shows how to do this.

A protocol analyzer can show whether the report went out on the bus.

« Last Edit: April 26, 2014, 09:23:19 pm by Jan Axelson »

SiberShadow

  • Member
  • ***
  • Posts: 5
Re: Difficulty writing to HID device using WriteFile
« Reply #5 on: April 26, 2014, 06:57:10 pm »
Hi...

Thanks for the follow-up.  Bear with me, I just downloaded the VB software a week or two ago--so I'm not that proficient.  I think I'm missing something fundamental that's simple*, but that I just don't get.  I reorganized the code: I no longer get any errors--aside from an occasional one about exceeding the outputReportBuffer array bounds--depending on how I format the array.

What I meant was... if the Capabilities.OutputReportByteLength comes back as only 1 byte, and I try to add another byte for the report ID in addition to a byte for the command itself, then I exceed the array dimensions (i.e., since the report length is the basis for the Resize).  I saw in your code comments and I thought I saw elsewhere too that arrays afforded an extra byte because of their use of zero referencing. But when I step through, I can see that the Resize results in only 1 byte, and my two Bytes (1 command and 1 report ID) exceed the bounds and cause an error.

If I arbitrarily resize the array, the "bounds" error disappears, but I always get a "False" return from the WriteFile function.  The deviceHandle is defined, valid, and open; and the outputReportBuffer and nNumberOfBytesToWrite can be made to match if I fiddle with the array size.  But as I step through it always returns Success = False.

I'll look into a protocol analyzer, etc.

Regards,

  - John

*(As an aside, even though I can't compile the older code that came with the device, I can tell that the device works because the executables files do run and the device responds with appropriate bit changes.)

Jan Axelson

  • Administrator
  • Frequent Contributor
  • *****
  • Posts: 3033
    • Lakeview Research
Re: Difficulty writing to HID device using WriteFile
« Reply #6 on: April 26, 2014, 09:28:53 pm »
Yes, Capabilities.OutputReportByteLength includes a byte for the report ID. (I've edited my previous response.)

The array begins with index zero so if the upper bound is one, the array has two elements.


SiberShadow

  • Member
  • ***
  • Posts: 5
Re: Difficulty writing to HID device using WriteFile
« Reply #7 on: April 28, 2014, 10:32:56 am »
It seems to be working now...

I kept getting "False" for the WriteFile return, even though I had eliminated all the error messages.  A protocol analyzer revealed that the WriteFile function wasn't sending anything.  I think there were two primary issues:

- I was trying to use the same handle for ReadFile and WriteFile.  To verify that there wasn't some issue with the handle, I added an additional call to CreateFile to obtain a separate handle--immediately before calling WriteFile.  When I changed the dwFlagsAndAttributes value to "0", the function returned successfully.

- The other thing was that things didn't work until I increased the nNumberOfBytesToWrite value to 9 Bytes (i.e. including space for the Report ID), regardless of the OutputReportBuffer dimensions and data.  I'm not really sure why; I'm guessing that there was something wrong with the way I was calling the OutputReportByteLength that suggested it was only 1 Byte.

Thanks for your help.

Regards,

 - John

Jan Axelson

  • Administrator
  • Frequent Contributor
  • *****
  • Posts: 3033
    • Lakeview Research
Re: Difficulty writing to HID device using WriteFile
« Reply #8 on: April 28, 2014, 12:45:59 pm »
Glad you got it working! Thanks for reporting back.