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]

Reply via email to