probably at the beach
probably at the beach

Reputation: 15217

c# USB parsing of a _URB_BULK_OR_INTERRUPT_TRANSFER packet

I'm parsing a _URB_BULK_OR_INTERRUPT_TRANSFER packet as defined in http://msdn.microsoft.com/en-us/library/windows/hardware/ff540352(v=vs.85).aspx using the following code:

            //parse URB Packet
            /*
            _URB_HEADER {
            USHORT      Length;
            USHORT      Function;
            USBD_STATUS Status;
            PVOID       UsbdDeviceHandle;
            ULONG       UsbdFlags;
            }*/

            //start header parse
            UInt16 urb_length = rdr.ReadUInt16();
            UInt16 urb_function = rdr.ReadUInt16();
            UInt32 urb_status = rdr.ReadUInt32();
            rdr.ReadBytes(System.IntPtr.Size);
            UInt32 UsbdFlags = rdr.ReadUInt32();
            //end header parse

            //.. skip code to check if it a _URB_BULK_OR_INTERRUPT_TRANSFER 
            // but assuming it is parse it

            /*struct _URB_BULK_OR_INTERRUPT_TRANSFER {
            struct URB_HEADER  Hdr;//covered above
            USBD_PIPE_HANDLE    PipeHandle;
            ULONG               TransferFlags;
            ULONG               TransferBufferLength;
            PVOID               TransferBuffer;
            PMDL                TransferBufferMDL;
            struct URB  *UrbLink;
            struct URB_HCD_AREA  hca;
            }*/

            rdr.ReadBytes(System.IntPtr.Size);
            UInt32 TransferFlags = rdr.ReadUInt32();
            UInt32 TransferBufferLength = rdr.ReadUInt32();
            byte[] ptr_bytes = rdr.ReadBytes(System.IntPtr.Size);
            System.IntPtr ptr_transfer_buffer = new System.IntPtr(BitConverter.ToUInt32(ptr_bytes, 0));
            ptr_bytes = rdr.ReadBytes(System.IntPtr.Size);
            System.IntPtr mdl_transfer_buffer = new System.IntPtr(BitConverter.ToUInt32(ptr_bytes, 0))

Inspecting all the values as they are being read in, most seem sensible until the PMDL void pointer. This ends up being a large negative number instead of 0 (NULL) or a valid address. Can anyone point me in the right direction as to why this might be happening? Thanks.

Upvotes: 0

Views: 1066

Answers (2)

Christopher
Christopher

Reputation: 8992

MDL objects are memory descriptors only usable in kernel mode. Due to the user/kernel-mode split, virtual addresses over 2 GB on x86 systems (without the 3GB switch) are in the kernel virtual address space.

Upvotes: 1

whosrdaddy
whosrdaddy

Reputation: 11860

I don't quite understand your question... TransferBufferMDL is used in DirectIO cases whereas TransferBuffer is for Buffered IO.

So one of those two will always be void.

Hope this helps!

Upvotes: 1

Related Questions