Hi Oliver,
good to see that someone got it (http://www.jps.net/~koma) to work ;-)
Future revisions should have some more interpretation, this version is
essentially just a dump of all URBs going down and coming up. As a
starter, I'll try to explain a few things. If you'd ever programmed
drivers for USB devices under Windows, things would make much more
sense. If you have never programmed it, here are a few pointers:
- MS has their DDKs online available for free download, or you can read
the docs while you're online. http://www.microsoft.com/ddk/ has all the
stuff; either the Win98 or the Win2K DDK will do.
- The programming model for USB devices on Windows is very similar
(though somewhat more complicated) to the one on Linux. USB transfers
are put into URBs (USB Request Blocks), and those are submitted to USBD.
The filter looks at all I/O requests (IRP_...), and decodes the ones
which are IRP_INTERNAL_IOCTL with the code SUBMIT_URB. All the rest just
gets logged as "this got called".
- In Windows, when a USB device plug-in gets detected, the system looks
up the driver which should handle this, and loads it. Its up to the
driver to do anything with the device - including get device descriptor,
select configuration, ... - all of this traffic gets logged by the
snooper.
- The filter labels the URBs; in general, pretty much everything is
asynchronous (just like in Linux); the driver can decide to wait for an
URB to be completed, or it can fire-and-forget, or it can attach a
completion routine to be called when the request completes. The filter
shows the direction "URB going down" or "URB coming back", along with
its sequence number and decoded contents.
[log snipped]
> I might be missing something fundamental about the way Windows uses
USB.
I doubt you are. However, if you have a vendor-specific device, be
prepared for some weirdness. There's a reason that people put their
class as vendor-specific...
One thing which looked weird (and probably is a bug in the driver you
are using - it's quite common, because it's tolerated by USBD), is that
BULK OUT transfers are being sent to a BULK IN endpoint. The filter
judges by the flags set whether it prints or doesn't print the
information in the user buffer. If you do an IN, it makes no sense to
print the garbage that is in the buffer before the device fills it in.
However, since the filter does *not* keep any state information about
which endpoint is IN or OUT, it will rely on the flags. Maybe I should
make it remember the endpoint information, and print a warning when data
gets sent to an IN endpoint.
In essence,
-------- Step 1: Inquiry in URB 5
> Here it is becoming relevant.
> Looks like a SCSI command written to pipe 0.
> 00000282 79.85785440 >>>>>>> URB 5 going down...
> 00000290 79.85806080 12 00 00 00 60 00
Or endpoint 1, the only OUT endpoint.
> Seems like INQUIRY with 96 bytes requested.
Agreed. My SCSI knowledge is limited, but that looks right.
-------- Step 2a: Fetch the result of the Inquiry by sending a read
request in URB 6
00000303 79.86020480 >>>>>>> URB 6 going down...
00000304 79.86024640 -- URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER:
00000305 79.86027680 PipeHandle = c14c594c
00000306 79.86032800 TransferFlags = 00000000
(USBD_TRANSFER_DIRECTION_OUT, ~USBD_SHORT_TRANSFER_OK)
Don't believe the flags. They have probably just been zeroed, the
programmer thinking "don't care == 0". The filter *does* print the
garbage data in the user buffer, though, since it looks at the Flags.
You as an intelligent being (and future versions of the snooper) should
look at the PipeHandle, which points to an Bulk IN pipe. (the buffer
contains in ASCII "USB\02 3 4 5 6" - looks like some re-used buffer)
> ^ What is that ???
Garbage. Disregard.
-------- Step 2a: Fetch the result of the Inquiry when URB 6 completes
> 00000316 79.86212800 <<<<<<< URB 6 coming back...
> 00000317 79.86217440 -- URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER:
> 00000318 79.86220560 PipeHandle = c14c594c
> 00000319 79.86225680 TransferFlags = 00000001
(USBD_TRANSFER_DIRECTION_IN, ~USBD_SHORT_TRANSFER_OK)
The USB subsystem has now set the flags properly (direction in).
> It seems commands are written to Pipe 0 and answers are read from Pipe
1.
Most likely. Query->Response model. Wonder why they didn't use control
transfers rather than two bulk pipes? And then? The third bulk pipe
could be for the real data, no? It has a larger MaxPacketSize than the
first bulk in pipe...
-------- Step 3: Finish command sequence?
>
> This is most strange.
>
> 00000384 79.86680240 >>>>>>> URB 9 going down...
> 00000385 79.86684640 -- URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER:
> 00000387 79.86692880 TransferFlags = 00000000
(USBD_TRANSFER_DIRECTION_OUT, ~USBD_SHORT_TRANSFER_OK)
Again, since it is pipe 1, which is input, you don't want to trust the
user data that is printed on submission of the URB.
> 00000395 79.86782640 <<<<<<< URB 9 coming back...
> 00000399 79.86798000 TransferBufferLength = 00000001
> 00000402 79.86805680 0000: 00
"End of packet?" "I'm done?" "No more responses left?"
----- more steps:
> A SCSI read, reading scanner attributes (31 bytes).
> Again going to Pipe 0.
OK. Sounds good.
> URB 11 reads 31 bytes from Pipe 1 as expected.
Also fine ;-)
> Again strange. TEST_UNIT_READY ?
> But why Pipe 1 ?
Again, it might be a "end of transfer" signal. It only *reads* -
remember, don't trust the direction flags as they are going down.
> 00000455 79.87389120 >>>>>>> URB 12 going down...
> 00000466 79.87451600 <<<<<<< URB 12 coming back...
> 00000473 79.87475600 0000: 00
Does that make sense?
..tom
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]