Closed nikola-matic closed 7 years ago
Hi @nikola-matic,
From what I understand you are using the function "UsbDk_ReadPipe" and getting "INVALID_HANDLE (0x6)", I think it may be an issue with the devicehandle that you are providing for the function, are you sure it is valid?
In order to debug the issue please run DebugView and reproduce the issue, an error should show up there. Just open DebugView without any additional settings, reproduce the issue and post the error here so I can help you further investigate the issue. You can download DebugView from Microsoft here: https://docs.microsoft.com/en-us/sysinternals/downloads/debugview.
I'd be happy to do a pull request and write some examples - perhaps by extending the UsbDkController class. Thanks.
That would be great, please send a pull request once it is ready.
Hi @sameehj,
Yes, I'm using UsbDk_ReadPipe. I'm passing it the handle I get from UsbDk_StartRedirect. Now, the redirect function works with a hitch - it disables the device on the host machine, and enables it again once UsbDk_StopRedirect is called (similar to the UsbDkController example). I'm also check the handle to make sure it's not a null pointer or INVALID_HANDLE_VALUE.
I'll run it through debugview and get to you tomorrow. Thanks for the quick reply.
I'll run it through debugview and get to you tomorrow. Thanks for the quick reply.
No problem, I'd like to further clarify that there are two tracing options for UsbDk, the one that I explained above which collects traces from User Mode components of UsbDk and there is the complete traces logs which collects traces from the UsbDk driver too. Both of these are explained in great detail here: https://github.com/daynix/UsbDk/blob/master/Documentation/Tracing.txt.
I suggest starting with the first approach and see if the logs are sufficient and can help us resolve the issue. Keep me updated =)
Just ran it through debugview, and unfortunately there is nothing of particular use. It just outputs this line:
Driver file operation error. DeviceIoControl failed (The handle is invalid. Error code = 6)
and that's it. I'll debug the driver tomorrow and report as soon as I have any new info.
@sameehj,
This is the log I got (UsbDkLogman.bat && tracefmt.exe) - usbdk.txt. The log should contain device redirection and attempted read - however, I'm not seeing anything of particular use in the logs. Perhaps you'll see something that I'm missing. Thanks.
@nikola-matic,
The log that you provided seems like a successful run, what I suspect is that you have a bug lying somewhere in your code where you mess the device handle somehow. In order to debug this I suggest that you print the value of the device handle just after you receive it from StartRedirect function and print it's value once again just before providing it to the ReadPipe function.
In case this doesn't help you solve the issue, please post the whole code somewhere (maybe github) and I'll take a look.
@sameehj,
Good news. It turns out I was allocating LPOVERLAPPED without actually assigning any values to it (even though I wanted a synchronous read). Once I set it to NULL, it started working. However, now I'm getting the same value every time I make read, no matter in which direction I move the 3D mouse. My understanding is that I should get different values depending on the direction of movement (to indicate said direction).
I'm checking the result by parsing the USB_DK_TRANSFER_REQUEST's Result field, which is of USB_DK_TRANSFER_RESULT type, which has USB_DK_GEN_TRANSFER_RESULT GenResult field in it, which in turn has a ULONG64 BytesTransferred field in it. Is the BytesTransferred field a counter indicating the number of transferred bytes, or the actual transferred bytes read from the endpoint buffer?
Good news. It turns out I was allocating LPOVERLAPPED without actually assigning any values to it (even though I wanted a synchronous read). Once I set it to NULL, it started working. However, now I'm getting the same value every time I make read, no matter in which direction I move the 3D mouse. My understanding is that I should get different values depending on the direction of movement (to indicate said direction).
Great! regarding the values, did you set the interface using "UsbDk_SetAltsetting" API function after Starting redirection and prior to executing ReadPipe? If not, this could be the reason you are getting this behaviour.
The length field contains the number of bytes that were sent. You can see that in the UsbDk driver code the structure "PWDF_REQUEST_COMPLETION_PARAMS" is used to fill the GenResult. In WritePipe scenario the CUsbDkRedirectorStrategy::WritePipe function is executed and the value of GenResult is filled in the function CompleteTransferRequest using the "Parameters.PipeWrite.Length" and "UsbdStatus" fields of usbCompletionParams.
You can read about these fields here: https://msdn.microsoft.com/en-us/library/windows/hardware/ff553049(v=vs.85).aspx
@sameehj, I did not in fact set the interface using UsbDk_Setaltsetting. What values should InterfaceIdx and AltSettingIdx be? For instance, my interface (only have one) looks like this:
Interface Descriptor:
bInterfaceNumber: 0x00
bAlternateSetting: 0x00
bNumEndpoints: 0x02
bInterfaceClass: 0x03 (HID)
bInterfaceSubClass: 0x00
bInterfaceProtocol: 0x00
iInterface: 0x00
bInterfaceNumber: 0x00 bAlternateSetting: 0x00
So set InterfaceIdx and InterfaceIdx both to zero.
@sameehj, that was the first thing I tried, unfortunately it didn't change anything. I'll fiddle around and try with another device tomorrow, and report my findings.
@sameehj, the actual buffer result I was trying to read was in PUSB_DK_TRANSFER_REQUEST (Buffer) :)
By the way, it seems setting an alternative setting is not required in order to read data.
Also, the UsbDkHelper API does not have way to get infterface/endpoint descriptors directly - i.e. this would require doing a control read on endpoint zero, right?
Also, the UsbDkHelper API does not have way to get infterface/endpoint descriptors directly - i.e. this would require doing a control read on endpoint zero, right?
You can use "UsbDk_GetConfigurationDescriptor" and "UsbDk_ReleaseConfigurationDescriptor" to accomplish that, you can find all UsbDk's API functions here: https://github.com/daynix/UsbDk/blob/master/UsbDkHelper/UsbDkHelper.h
You can use "UsbDk_GetConfigurationDescriptor" and "UsbDk_ReleaseConfigurationDescriptor" to accomplish that
Are you sure? The function only returns PUSB_CONFIGURATION_DESCRIPTOR, and from what I can see, in UsbDkCompat.h, the only defined structs are for device and configuration descriptors, which makes sense, since the API only provides functions to get device and configuration descriptors, i.e. UsbDk_GetDevicesList and UsbDk_GetConfigurationDescriptor. In any case, this still provides enough information to get the rest of the descriptors 'manually', i.e. through control endpoint reads.
Are you sure? The function only returns PUSB_CONFIGURATION_DESCRIPTOR, and from what I can see, in UsbDkCompat.h, the only defined structs are for device and configuration descriptors, which makes sense, since the API only provides functions to get device and configuration descriptors, i.e. UsbDk_GetDevicesList and UsbDk_GetConfigurationDescriptor.
True, I am sorry I apparently misread the question, there is no API functions which directly fetches the interface/endpoint descriptors.
No worries. Thanks for all the help - I'll try to make a pull request in the next couple of months to extend the UsbDkController component (or make an entirely new one) to demonstrate ReadPipe/WritePipe usage.
You're welcome =),
I suggest that you add a new standalone example project, it'll be much neater than bloating up the controller with superfluous functionality.
Thanks =)
Sounds good!
I'm trying to read data from a 3D mouse after acquiring (redirecting) the device. The device redirection is successful and disables the device, until I release it back. However, when attempting to read data, I get INVALID_HANDLE (0x6) error from GetLastError(). I've been looking through the libusb source code for example reads - however, I'm not sure I'm configuring the packets correctly. It would seem there are no read/write examples in UsbDk (controller).
This is my device endpoint descriptor:
bEndpointAddress: 0x81 IN
Transfer Type: Interrupt
wMaxPacketSize: 0x0008 (8)
bInterval: 0x0A
And this is my code:
I have to mention that I'm very new to such low level device interaction, so it may be that I'm doing something stupid, but I've been attempting to read from the device for a couple of days now without success. I'd be happy to do a pull request and write some examples - perhaps by extending the UsbDkController class. Thanks.
Edit: Note that I haven't sent a control transfer, which I'm guessing I should have?