Reg. ISOCHRONOUS Transfer.

Hi All,

As most of you know that I am working on a virtual BUS driver for USB
devices, right now I am trying to create a virtual webcam from the remote
system. So in this process upper-layer has issued several vendor specific
URB’s and all those URB’s were replied properly. Now the upper layer started
issuing ISOCH URB for about 24K and the virtual BUS Driver replied properly
with all the ISOPacketDescriptors filled properly with Offset, Length and
Status along with StartOfFrame and also filled the TransferBuffer memory
with the complete 24K data. Once this particular URB is replied to the
Upper-layer by completing the IRP windows is not issuing further any
commands. And strangely if I don’t trace through the driver step-by-step it
issues the 2nd ISOCH request and crashes at some other place in the driver.

So any clues would really help us in debugging this scenario. I believe
whatever the Virtual Bus Driver is filling the URB is that something wrong
or it might be missing some parameters…

Thanks in advance!!!


This message, together with any attachment(s), contains confidential and proprietary information of
ServerEngines LLC and is intended only for the designated recipient(s) named above. Any unauthorized
review, printing, retention, copying, disclosure or distribution is strictly prohibited. If you are not the
intended recipient of this message, please immediately advise the sender by reply email message and
delete all copies of this message and any attachment(s). Thank you.

Vishwanath Maram wrote:

Hi All,

As most of you know that I am working on a virtual BUS driver for USB
devices, right now I am trying to create a virtual webcam from the
remote system. So in this process upper-layer has issued several
vendor specific URB’s and all those URB’s were replied properly. Now
the upper layer started issuing ISOCH URB for about 24K and the
virtual BUS Driver replied properly with all the ISOPacketDescriptors
filled properly with Offset, Length and Status along with StartOfFrame
and also filled the TransferBuffer memory with the complete 24K data.
Once this particular URB is replied to the Upper-layer by completing
the IRP windows is not issuing further any commands. And strangely if
I don’t trace through the driver step-by-step it issues the 2^nd ISOCH
request and crashes at some other place in the driver.

So any clues would really help us in debugging this scenario. I
believe whatever the Virtual Bus Driver is filling the URB is that
something wrong or it might be missing some parameters….

Web cams are real-time devices. During all the time you are
transferring commands and buffers back and forth to your remote system,
the web camera continues to generate pixels at its constant rate,
probably overflowing its buffers, resulting in garbage data to the driver.

You are going to have to take special steps if you hope to support
devices like web cameras and USB audio devices. Your remote end will
have to start up a “continuous reader” thread to feed isochronous
packets on its own, without waiting for a request from the local side.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Hi Tim,

The Scenario is as below:

This is the very first ISOCH packet and the remote system replies with the
data to the virtual Bus Driver on windows, this driver completes the URB &
IRP with the received data. There should be another URB followed after this
but we are not getting any more commands from the upper-layer and if we
don’t debug the driver virtual bus driver is hitting the BSOD after the 2nd
command.

Thanks in Advance!!!

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Tim Roberts
Sent: Monday, December 10, 2007 12:04 PM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] Reg. ISOCHRONOUS Transfer.

Vishwanath Maram wrote:

Hi All,

As most of you know that I am working on a virtual BUS driver for USB
devices, right now I am trying to create a virtual webcam from the
remote system. So in this process upper-layer has issued several
vendor specific URB’s and all those URB’s were replied properly. Now
the upper layer started issuing ISOCH URB for about 24K and the
virtual BUS Driver replied properly with all the ISOPacketDescriptors
filled properly with Offset, Length and Status along with StartOfFrame
and also filled the TransferBuffer memory with the complete 24K data.
Once this particular URB is replied to the Upper-layer by completing
the IRP windows is not issuing further any commands. And strangely if
I don’t trace through the driver step-by-step it issues the 2^nd ISOCH
request and crashes at some other place in the driver.

So any clues would really help us in debugging this scenario. I
believe whatever the Virtual Bus Driver is filling the URB is that
something wrong or it might be missing some parameters…

Web cams are real-time devices. During all the time you are
transferring commands and buffers back and forth to your remote system,
the web camera continues to generate pixels at its constant rate,
probably overflowing its buffers, resulting in garbage data to the driver.

You are going to have to take special steps if you hope to support
devices like web cameras and USB audio devices. Your remote end will
have to start up a “continuous reader” thread to feed isochronous
packets on its own, without waiting for a request from the local side.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer


This message, together with any attachment(s), contains confidential and proprietary information of
ServerEngines LLC and is intended only for the designated recipient(s) named above. Any unauthorized
review, printing, retention, copying, disclosure or distribution is strictly prohibited. If you are not the
intended recipient of this message, please immediately advise the sender by reply email message and
delete all copies of this message and any attachment(s). Thank you.

Vishwanath Maram wrote:

Hi Tim,

The Scenario is as below:

This is the very first ISOCH packet and the remote system replies with the
data to the virtual Bus Driver on windows, this driver completes the URB &
IRP with the received data. There should be another URB followed after this
but we are not getting any more commands from the upper-layer and if we
don’t debug the driver virtual bus driver is hitting the BSOD after the 2nd
command.

All streaming isochronous consumers will issue multiple outstanding read
requests. That’s the only way to make sure you don’t drop packets. Are
you able to handle that? When you get a read request, are you blocking,
or do you queue it and mark it pending? You absolutely cannot block URBs.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Hi Tim,

A basic doubt on this structure:

typedef struct _USBD_ISO_PACKET_DESCRIPTOR {
ULONG Offset; // INPUT Offset of the packet from the begining of
the
// buffer.

ULONG Length; // OUTPUT length of data received (for in).
// OUTPUT 0 for OUT.
USBD_STATUS Status; // status code for this packet.
} USBD_ISO_PACKET_DESCRIPTOR, *PUSBD_ISO_PACKET_DESCRIPTOR;

struct _URB_ISOCH_TRANSFER {
//
// This block is the same as CommonTransfer
//
struct _URB_HEADER Hdr; // function code indicates get
set.
USBD_PIPE_HANDLE PipeHandle;
ULONG TransferFlags;
ULONG TransferBufferLength;
PVOID TransferBuffer;
PMDL TransferBufferMDL; // *optional*
struct _URB *UrbLink; // *optional* link to next urb
request
// if this is a chain of commands
struct _URB_HCD_AREA hca; // fields for HCD use

//
// this block contains transfer fields
// specific to isochronous transfers
//

// 32 bit frame number to begin this transfer on, must be within 1000
// frames of the current USB frame or an error is returned.

// START_ISO_TRANSFER_ASAP flag in transferFlags:
// If this flag is set and no transfers have been submitted
// for the pipe then the transfer will begin on the next frame
// and StartFrame will be updated with the frame number the transfer
// was started on.
// If this flag is set and the pipe has active transfers then
// the transfer will be queued to begin on the frame after the
// last transfer queued is completed.
//
ULONG StartFrame;
// number of packets that make up this request
ULONG NumberOfPackets;
// number of packets that completed with errors
ULONG ErrorCount;
USBD_ISO_PACKET_DESCRIPTOR IsoPacket[1];
};

The Virtual bus driver always gets the TransferBuffer as a valid pointer and
TransferBufferLength set to 24K with a particular WEBCAM, is this
TransferBuffer is a pointer to a single virtually contiguous buffer of 24K
which the upper-layer asks for in TransferBufferLength??? How about
TransferBufferMDL??? Whether this virtual Bus Driver has to allocate and
assign it to this pointer and if so how can the virtual bus driver
de-allocate this buffer??? Once this driver calls IoCompleteRequest() then
this driver will not have any control of releasing of this buffer right
until there is some acknowledgement for this IRP from upper layer??? So can
anyone help me out in better understanding this structure???

Thanks in advance!!!

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Tim Roberts
Sent: Monday, December 10, 2007 4:03 PM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] Reg. ISOCHRONOUS Transfer.

Vishwanath Maram wrote:

Hi Tim,

The Scenario is as below:

This is the very first ISOCH packet and the remote system replies with the
data to the virtual Bus Driver on windows, this driver completes the URB &
IRP with the received data. There should be another URB followed after
this
but we are not getting any more commands from the upper-layer and if we
don’t debug the driver virtual bus driver is hitting the BSOD after the
2nd
command.

All streaming isochronous consumers will issue multiple outstanding read
requests. That’s the only way to make sure you don’t drop packets. Are
you able to handle that? When you get a read request, are you blocking,
or do you queue it and mark it pending? You absolutely cannot block URBs.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer


This message, together with any attachment(s), contains confidential and proprietary information of
ServerEngines LLC and is intended only for the designated recipient(s) named above. Any unauthorized
review, printing, retention, copying, disclosure or distribution is strictly prohibited. If you are not the
intended recipient of this message, please immediately advise the sender by reply email message and
delete all copies of this message and any attachment(s). Thank you.

Vishwanath Maram wrote:

The Virtual bus driver always gets the TransferBuffer as a valid pointer and
TransferBufferLength set to 24K with a particular WEBCAM, is this
TransferBuffer is a pointer to a single virtually contiguous buffer of 24K
which the upper-layer asks for in TransferBufferLength???

Probably. The IsoPacket array contains the offsets to the start of each
packet within the TransferBuffer. If a webcam wants to get 8 packets of
3072 bytes (meaning a full frame at the maximum packet size), the most
sensible way to do that is to allocate 24k and set the offsets in units
of 3k. Theoretically, the packets don’t have to be contiguous in the
TransferBuffer, but only the most obnoxious driver writer would do that.

How about TransferBufferMDL??? Whether this virtual Bus Driver has to allocate and
assign it to this pointer and if so how can the virtual bus driver
de-allocate this buffer???

Either TransferBuffer or TransferBufferMDL will be valid. It depends on
what the caller used. If TransferBuffer was supplied, then you can use
it. If not, then you have to get a virtual address from the MDL. You
(as the bus driver) do not set those fields; those are provided by the
caller to describe the caller’s buffer.

Once this driver calls IoCompleteRequest() then
this driver will not have any control of releasing of this buffer right
until there is some acknowledgement for this IRP from upper layer???

The buffer does not belong to you, so you can’t release it. It belongs
to the calling driver. You just copy data into it, fill in the
IsoPacket fields, and complete the request.

So can anyone help me out in better understanding this structure???

There’s really not that much to it. Have you never traced through a
driver that did isochronous requests? I can’t imagine trying to write a
virtual USB bus driver without being fully conversant in URB handling.

Are you seeing requests with UrbLink set? I didn’t think that was used.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Tim Roberts wrote:

I can’t imagine trying to write a virtual USB bus driver without being
fully conversant in URB handling.

I can’t imagine trying to write a virtual USB bus driver without understanding how usbccgp works either, but he’s asked about that also.

Chris,

I have asked about usbccgp long back and was able to make the Composite
printers work for me with out any issues…But I am right now working on
composite devices for webcam where in I am seeing problems with ISOCH
transfer and also some problem with the audio interface…the drivers for
audio device won’t get installed properly…these drivers stop and show up
with “Code 10” in the device manager…So I am stuck with 2-different
issues all together…

Thanks…

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of
xxxxx@gmail.com
Sent: Thursday, December 13, 2007 3:22 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Reg. ISOCHRONOUS Transfer.

Tim Roberts wrote:

I can’t imagine trying to write a virtual USB bus driver without being
fully conversant in URB handling.

I can’t imagine trying to write a virtual USB bus driver without
understanding how usbccgp works either, but he’s asked about that also.


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer


This message, together with any attachment(s), contains confidential and proprietary information of
ServerEngines LLC and is intended only for the designated recipient(s) named above. Any unauthorized
review, printing, retention, copying, disclosure or distribution is strictly prohibited. If you are not the
intended recipient of this message, please immediately advise the sender by reply email message and
delete all copies of this message and any attachment(s). Thank you.

Hi Tim,

As I was discussing with you earlier that the upper layer vendor drivers are
crashing as soon as we reply with the initial ISOCH requests, still
debugging the same. We are now faking sending just ZEROS for all the 24k…

So any idea what exactly might be happening or what those upper layer
drivers expect in general…

Thanks in advance!!!

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Tim Roberts
Sent: Thursday, December 13, 2007 12:26 PM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] Reg. ISOCHRONOUS Transfer.

Vishwanath Maram wrote:

The Virtual bus driver always gets the TransferBuffer as a valid pointer
and
TransferBufferLength set to 24K with a particular WEBCAM, is this
TransferBuffer is a pointer to a single virtually contiguous buffer of 24K
which the upper-layer asks for in TransferBufferLength???

Probably. The IsoPacket array contains the offsets to the start of each
packet within the TransferBuffer. If a webcam wants to get 8 packets of
3072 bytes (meaning a full frame at the maximum packet size), the most
sensible way to do that is to allocate 24k and set the offsets in units
of 3k. Theoretically, the packets don’t have to be contiguous in the
TransferBuffer, but only the most obnoxious driver writer would do that.

How about TransferBufferMDL??? Whether this virtual Bus Driver has to
allocate and
assign it to this pointer and if so how can the virtual bus driver
de-allocate this buffer???

Either TransferBuffer or TransferBufferMDL will be valid. It depends on
what the caller used. If TransferBuffer was supplied, then you can use
it. If not, then you have to get a virtual address from the MDL. You
(as the bus driver) do not set those fields; those are provided by the
caller to describe the caller’s buffer.

Once this driver calls IoCompleteRequest() then
this driver will not have any control of releasing of this buffer right
until there is some acknowledgement for this IRP from upper layer???

The buffer does not belong to you, so you can’t release it. It belongs
to the calling driver. You just copy data into it, fill in the
IsoPacket fields, and complete the request.

So can anyone help me out in better understanding this structure???

There’s really not that much to it. Have you never traced through a
driver that did isochronous requests? I can’t imagine trying to write a
virtual USB bus driver without being fully conversant in URB handling.

Are you seeing requests with UrbLink set? I didn’t think that was used.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer


This message, together with any attachment(s), contains confidential and proprietary information of
ServerEngines LLC and is intended only for the designated recipient(s) named above. Any unauthorized
review, printing, retention, copying, disclosure or distribution is strictly prohibited. If you are not the
intended recipient of this message, please immediately advise the sender by reply email message and
delete all copies of this message and any attachment(s). Thank you.

Vishwanath Maram wrote:

As I was discussing with you earlier that the upper layer vendor drivers are
crashing as soon as we reply with the initial ISOCH requests, still
debugging the same. We are now faking sending just ZEROS for all the 24k…

So any idea what exactly might be happening or what those upper layer
drivers expect in general…

My USB capture drivers usually look something like this:
for( i = 0; i < urb->NumberOfPackets; i++ )
{
if( urb->IsoPacket[i].Length )
ProcessPacket(
urb->TransferBuffer + urb->IsoPacket[i].Offset,
urb->IsoPacket[i].Length
);
else
KdPrint(( “Whoops, isoch error %08x in packet %d\n”,
urb->IsoPacket[i].Status, i
));
}

You may have to disassemble backwards from the crash a bit to find out
what they don’t like.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Tim,

Code snippet of what I am doing… In this part of faking code I am just
sending the same captured data for the first 4-packets and then all
ZERO’s…

if( urb->UrbHeader.Function ==
URB_FUNCTION_ISOCH_TRANSFER ) {

ULONG i,Address;

isoch++;
DebugPrint((0,“Received ISOCH Packet - 0x%x
\n”,isoch));

DebugPrint((0,“urb->UrbIsochronousTransfer.PipeHandle - 0x%x
\n”,urb->UrbIsochronousTransfer.PipeHandle));

DebugPrint((0,“urb->UrbIsochronousTransfer.TransferFlags - 0x%x
\n”,urb->UrbIsochronousTransfer.TransferFlags));

DebugPrint((0,“urb->UrbIsochronousTransfer.TransferBufferLength - 0x%x
\n”,urb->UrbIsochronousTransfer.TransferBufferLength));

DebugPrint((0,“urb->UrbIsochronousTransfer.TransferBuffer - 0x%x
\n”,urb->UrbIsochronousTransfer.TransferBuffer));

DebugPrint((0,“urb->UrbIsochronousTransfer.StartFrame - 0x%x
\n”,urb->UrbIsochronousTransfer.StartFrame));

DebugPrint((0,“urb->UrbIsochronousTransfer.NumberOfPackets - 0x%x
\n”,urb->UrbIsochronousTransfer.NumberOfPackets));

DebugPrint((0,“urb->UrbIsochronousTransfer.ErrorCount - 0x%x
\n”,urb->UrbIsochronousTransfer.ErrorCount));
urb->UrbHeader.Status = 0;

urb->UrbIsochronousTransfer.TransferFlags =
0x5;
urb->UrbIsochronousTransfer.PipeHandle =
(USBD_PIPE_HANDLE) 0x81;
urb->UrbHeader.Status = 0;

if (isoch == 1)

urb->UrbIsochronousTransfer.StartFrame = FrameNumber + 5*isoch;
else

urb->UrbIsochronousTransfer.StartFrame = FrameNumber + 20*isoch;

urb->UrbIsochronousTransfer.ErrorCount = 0;
Address =
(ULONG)urb->UrbIsochronousTransfer.TransferBuffer;

if
(urb->UrbIsochronousTransfer.TransferBuffer){

//RtlFillMemory(urb->UrbIsochronousTransfer.TransferBuffer,
urb->UrbIsochronousTransfer.TransferBufferLength, 0x00);
switch (isoch)
{
case 1:

RtlCopyMemory(urb->UrbIsochronousTransfer.TransferBuffer, isoch_data,
urb->UrbIsochronousTransfer.TransferBufferLength);
break;
case 2:

RtlCopyMemory(urb->UrbIsochronousTransfer.TransferBuffer, isoch1_data,
urb->UrbIsochronousTransfer.TransferBufferLength);
break;
case 3:

RtlCopyMemory(urb->UrbIsochronousTransfer.TransferBuffer, isoch2_data,
urb->UrbIsochronousTransfer.TransferBufferLength);
break;
case 4:

RtlCopyMemory(urb->UrbIsochronousTransfer.TransferBuffer, isoch3_data,
urb->UrbIsochronousTransfer.TransferBufferLength);
break;
default:

RtlFillMemory(urb->UrbIsochronousTransfer.TransferBuffer,
urb->UrbIsochronousTransfer.TransferBufferLength, 0x00);
break;
}
}else{
DebugPrint((0,“&&&&& Transfer Buffer
MDL &&&&&\n”));
}

for(i=0;i <
urb->UrbIsochronousTransfer.NumberOfPackets;i++){

urb->UrbIsochronousTransfer.IsoPacket[i].Offset = i*768;

urb->UrbIsochronousTransfer.IsoPacket[i].Length = 0x300;

urb->UrbIsochronousTransfer.IsoPacket[i].Status = 0;

Address =
(ULONG)urb->UrbIsochronousTransfer.TransferBuffer + i*768;

if (isoch > 5)

RtlFillMemory((PVOID)Address, 1, 0xFF);
}

Irp->IoStatus.Information =
urb->UrbIsochronousTransfer.TransferBufferLength;
Irp->IoStatus.Status =
STATUS_SUCCESS;

//
// Complete it.
//
IoCompleteRequest(Irp, IO_NO_INCREMENT);

DebugPrint((0,“****** Completed the ISOCH
IRP ******\n”));
return STATUS_SUCCESS
This is the debug trace for the crash…
kd> !analyze -v
****************************************************************************
***
*
*
* Bugcheck Analysis
*
*
*
****************************************************************************
***

DRIVER_IRQL_NOT_LESS_OR_EQUAL (d1)
An attempt was made to access a pageable (or completely invalid) address at
an
interrupt request level (IRQL) that is too high. This is usually
caused by drivers using improper addresses.
If kernel debugger is available get stack backtrace.
Arguments:
Arg1: 04400008, memory referenced
Arg2: 00000002, IRQL
Arg3: 00000001, value 0 = read operation, 1 = write operation
Arg4: 5acf2126, address which referenced memory

Debugging Details:

WRITE_ADDRESS: 04400008

CURRENT_IRQL: 2

FAULTING_IP:
vfwwdm32+2126
5acf2126 895e08 mov dword ptr [esi+8],ebx

PROCESS_NAME: PhotoStudio.exe

DEFAULT_BUCKET_ID: DRIVER_FAULT

BUGCHECK_STR: 0xD1

TRAP_FRAME: eefb33f4 – (.trap 0xffffffffeefb33f4)
ErrCode = 00000006
eax=04400000 ebx=00000000 ecx=7c809ab9 edx=7c90eb94 esi=04400000
edi=00000000
eip=5acf2126 esp=0012e7c0 ebp=0012e7e0 iopl=0 nv up ei pl nz na pe
nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000
efl=00010206
vfwwdm32+0x2126:
001b:5acf2126 895e08 mov dword ptr [esi+8],ebx
ds:0023:04400008=???
Resetting default scope

LAST_CONTROL_TRANSFER: from 80532487 to 804e3592

STACK_TEXT:
eefb2fa8 80532487 00000003 eefb3304 00000000
nt!RtlpBreakWithStatusInstruction
eefb2ff4 80532f5e 00000003 04400008 5acf2126 nt!KiBugCheckDebugBreak+0x19
eefb33d4 804e187f 0000000a 04400008 00000002 nt!KeBugCheck2+0x574
eefb33d4 5acf2126 0000000a 04400008 00000002 nt!KiTrap0E+0x233
WARNING: Stack unwind information not available. Following frames may be
wrong.
0012e7e0 5acf4aa0 0000037c 002f4017 0012e810 vfwwdm32+0x2126
0012e880 5acf72c6 043b0008 00000001 001e4150 vfwwdm32!DriverProc+0x2394
0012e8a4 5acf73ca 03b80000 001e4148 00000028 vfwwdm32!VfwWdm+0x26fb
0012e8bc 5acf2799 03b80000 000040c8 001e4148 vfwwdm32!VfwWdm+0x27ff
0012e8d4 76b431f1 03b80000 00000014 000040c8 vfwwdm32!DriverProc+0x8d
0012e900 76b43140 00000130 000040c8 001e4148 WINMM!SendDriverMessage+0xc9
0012e91c 73b8bc47 00000014 000040c8 001e4148 WINMM!SendDriverMessage+0x18
0012e934 73b84449 00000014 001e4148 001e3fe8
AVICAP32!capCreateCaptureWindowA+0x9e0c

0012e974 73b8741e 00000000 00000000 001e3fe8
AVICAP32!capCreateCaptureWindowA+0x260e

0012e990 73b87ffb 001e3fe8 0000040a 00000000
AVICAP32!capCreateCaptureWindowA+0x55e3

0012ea10 7e418734 00030200 0000040a 00000000
AVICAP32!capCreateCaptureWindowA+0x61c0

0012ea3c 7e418816 73b87fc5 00030200 0000040a USER32!GetDC+0x6d
0012eaa4 7e41b4c0 00000000 73b87fc5 00030200 USER32!GetDC+0x14f
0012eaf8 7e41b50c 00a73c90 0000040a 00000000 USER32!DefWindowProcW+0x184
0012eb20 7c90eae3 0012eb30 00000018 00a73c90 USER32!DefWindowProcW+0x1d0
0012eb80 7e42f3cc 00a73c90 0000040a 00000000
ntdll!KiUserCallbackDispatcher+0x13
0012eba0 0321b045 00030200 0000040a 00000000 USER32!SendMessageA+0x49
0012eba4 00030200 0000040a 00000000 00000000 TWD207!DS_Entry+0x6fc5
0012eba8 00000000 00000000 00000000 dc9c4608 0x30200

STACK_COMMAND: kb

FOLLOWUP_IP:
nt!KiTrap0E+233
804e187f f7457000000200 test dword ptr [ebp+70h],20000h

SYMBOL_STACK_INDEX: 3

SYMBOL_NAME: nt!KiTrap0E+233

FOLLOWUP_NAME: MachineOwner

MODULE_NAME: nt

IMAGE_NAME: ntoskrnl.exe

DEBUG_FLR_IMAGE_TIMESTAMP: 45e54711

FAILURE_BUCKET_ID: 0xD1_W_nt!KiTrap0E+233

BUCKET_ID: 0xD1_W_nt!KiTrap0E+233

Followup: MachineOwner

Thanks in advance…

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Tim Roberts
Sent: Tuesday, December 18, 2007 1:49 PM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] Reg. ISOCHRONOUS Transfer.

Vishwanath Maram wrote:

As I was discussing with you earlier that the upper layer vendor drivers
are
crashing as soon as we reply with the initial ISOCH requests, still
debugging the same. We are now faking sending just ZEROS for all the
24k…

So any idea what exactly might be happening or what those upper layer
drivers expect in general…

My USB capture drivers usually look something like this:
for( i = 0; i < urb->NumberOfPackets; i++ )
{
if( urb->IsoPacket[i].Length )
ProcessPacket(
urb->TransferBuffer + urb->IsoPacket[i].Offset,
urb->IsoPacket[i].Length
);
else
KdPrint(( “Whoops, isoch error %08x in packet %d\n”,
urb->IsoPacket[i].Status, i
));
}

You may have to disassemble backwards from the crash a bit to find out
what they don’t like.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer


This message, together with any attachment(s), contains confidential and proprietary information of
ServerEngines LLC and is intended only for the designated recipient(s) named above. Any unauthorized
review, printing, retention, copying, disclosure or distribution is strictly prohibited. If you are not the
intended recipient of this message, please immediately advise the sender by reply email message and
delete all copies of this message and any attachment(s). Thank you.

Vishwanath Maram wrote:

Code snippet of what I am doing… In this part of faking code I am just
sending the same captured data for the first 4-packets and then all
ZERO’s…

There are some serious problems here.

Also note that you aren’t sending captured data for the first 4 PACKETS;
you are sending captured data for the first 4 TRANSFERS. Each transfer
consists of multiple packets.

urb->UrbHeader.Status = 0;
urb->UrbIsochronousTransfer.TransferFlags = 0x5;

TransferFlags is an INPUT parameter. You, as the bus, are not allowed
to change it.

urb->UrbIsochronousTransfer.PipeHandle = (USBD_PIPE_HANDLE) 0x81;

Same here. PipeHandle is an INPUT parameter. The driver is telling YOU
what pipe to use. In retrospect, this may be related to your problem;
USBD_PIPE_HANDLE is actually supposed to be the kernel address of a data
structure within the host controller.

Have you really never stepped through a real USB transfer from a
driver’s point of view? How can you virtualize something you have never
observed?

urb->UrbHeader.Status = 0;

This status should be non-zero if any of the packets had errors.

if (isoch == 1)
urb->UrbIsochronousTransfer.StartFrame = FrameNumber + 5*isoch;
else
7urb->UrbIsochronousTransfer.StartFrame = FrameNumber + 20*isoch;

As above, StartFrame is an INPUT parameter, not an output. The driver
tells YOU what frame number it wants. You don’t change this.

for(i=0;i <
urb->UrbIsochronousTransfer.NumberOfPackets;i++){

urb->UrbIsochronousTransfer.IsoPacket[i].Offset = i*768;

urb->UrbIsochronousTransfer.IsoPacket[i].Length = 0x300;

urb->UrbIsochronousTransfer.IsoPacket[i].Status = 0;

Once again, IsoPacket[i].Offset is an INPUT parameter. The driver tells
YOU where the packets start within its buffer, and you are not allowed
to change that. Length is both input and output. You, as the bus, are
supposed to fill in each packet with data, up to the Length field they
gave you, and then set the Length to the actual amount of data that you
copied. Note that the packets are not always full. With audio data,
they are almost never full.

I assume you know that you cannot hard code the packet sizes, like you
have done here, assuming 768 bytes per packet. You should be using the
Length that they passed you. When you’re running remotely, assuming you
can get that working, the hardware will make sure that the packet size
in the URB matches the endpoint’s packet size.

if (isoch > 5)

RtlFillMemory((PVOID)Address, 1, 0xFF);

Do you understand that this only sets one byte? This is equivalent to
*Address = 0xff;

This is the debug trace for the crash…
kd> !analyze -v
****************************************************************************
*
* Bugcheck Analysis
*
****************************************************************************

DRIVER_IRQL_NOT_LESS_OR_EQUAL (d1)
An attempt was made to access a pageable (or completely invalid) address at
an interrupt request level (IRQL) that is too high. This is usually
caused by drivers using improper addresses.
If kernel debugger is available get stack backtrace.
Arguments:
Arg1: 04400008, memory referenced
Arg2: 00000002, IRQL
Arg3: 00000001, value 0 = read operation, 1 = write operation
Arg4: 5acf2126, address which referenced memory

Debugging Details:

WRITE_ADDRESS: 04400008

CURRENT_IRQL: 2

FAULTING_IP:
vfwwdm32+2126
5acf2126 895e08 mov dword ptr [esi+8],ebx

There’s something here that I definitely do not understand. This shows
you are executing user-mode code at an IRQL of DISPATCH_LEVEL. That
shouldn’t be possible. This should have caused a page fault, but not a
blue screen.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Yes I am trying to fake first 4-transfers…I always see that the values for
OFFSET, LENGTH & STATUS are not given at least for the first transfer that’s
the reason I am setting it up…

This crash I see in the upper-layer drivers…so I don’t know how to go
about it…

With this Virtual Bus Driver all the USB memory sticks, Printers & Scanners
work fine…Now that we are trying with ISOCH transfer type of devices and
stuck here…

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Tim Roberts
Sent: Tuesday, December 18, 2007 3:48 PM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] Reg. ISOCHRONOUS Transfer.

Vishwanath Maram wrote:

Code snippet of what I am doing… In this part of faking code I am just
sending the same captured data for the first 4-packets and then all
ZERO’s…

There are some serious problems here.

Also note that you aren’t sending captured data for the first 4 PACKETS;
you are sending captured data for the first 4 TRANSFERS. Each transfer
consists of multiple packets.

urb->UrbHeader.Status = 0;
urb->UrbIsochronousTransfer.TransferFlags = 0x5;

TransferFlags is an INPUT parameter. You, as the bus, are not allowed
to change it.

urb->UrbIsochronousTransfer.PipeHandle = (USBD_PIPE_HANDLE) 0x81;

Same here. PipeHandle is an INPUT parameter. The driver is telling YOU
what pipe to use. In retrospect, this may be related to your problem;
USBD_PIPE_HANDLE is actually supposed to be the kernel address of a data
structure within the host controller.

Have you really never stepped through a real USB transfer from a
driver’s point of view? How can you virtualize something you have never
observed?

urb->UrbHeader.Status = 0;

This status should be non-zero if any of the packets had errors.

if (isoch == 1)
urb->UrbIsochronousTransfer.StartFrame = FrameNumber + 5*isoch;
else
7urb->UrbIsochronousTransfer.StartFrame = FrameNumber + 20*isoch;

As above, StartFrame is an INPUT parameter, not an output. The driver
tells YOU what frame number it wants. You don’t change this.

for(i=0;i <
urb->UrbIsochronousTransfer.NumberOfPackets;i++){

urb->UrbIsochronousTransfer.IsoPacket[i].Offset = i*768;

urb->UrbIsochronousTransfer.IsoPacket[i].Length = 0x300;

urb->UrbIsochronousTransfer.IsoPacket[i].Status = 0;

Once again, IsoPacket[i].Offset is an INPUT parameter. The driver tells
YOU where the packets start within its buffer, and you are not allowed
to change that. Length is both input and output. You, as the bus, are
supposed to fill in each packet with data, up to the Length field they
gave you, and then set the Length to the actual amount of data that you
copied. Note that the packets are not always full. With audio data,
they are almost never full.

I assume you know that you cannot hard code the packet sizes, like you
have done here, assuming 768 bytes per packet. You should be using the
Length that they passed you. When you’re running remotely, assuming you
can get that working, the hardware will make sure that the packet size
in the URB matches the endpoint’s packet size.

if (isoch > 5)

RtlFillMemory((PVOID)Address, 1, 0xFF);

Do you understand that this only sets one byte? This is equivalent to
*Address = 0xff;

This is the debug trace for the crash…
kd> !analyze -v

****************************************************************************

*
* Bugcheck Analysis
*

****************************************************************************

DRIVER_IRQL_NOT_LESS_OR_EQUAL (d1)
An attempt was made to access a pageable (or completely invalid) address
at
an interrupt request level (IRQL) that is too high. This is usually
caused by drivers using improper addresses.
If kernel debugger is available get stack backtrace.
Arguments:
Arg1: 04400008, memory referenced
Arg2: 00000002, IRQL
Arg3: 00000001, value 0 = read operation, 1 = write operation
Arg4: 5acf2126, address which referenced memory

Debugging Details:

WRITE_ADDRESS: 04400008

CURRENT_IRQL: 2

FAULTING_IP:
vfwwdm32+2126
5acf2126 895e08 mov dword ptr [esi+8],ebx

There’s something here that I definitely do not understand. This shows
you are executing user-mode code at an IRQL of DISPATCH_LEVEL. That
shouldn’t be possible. This should have caused a page fault, but not a
blue screen.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer


This message, together with any attachment(s), contains confidential and proprietary information of
ServerEngines LLC and is intended only for the designated recipient(s) named above. Any unauthorized
review, printing, retention, copying, disclosure or distribution is strictly prohibited. If you are not the
intended recipient of this message, please immediately advise the sender by reply email message and
delete all copies of this message and any attachment(s). Thank you.

Vishwanath Maram wrote:

Yes I am trying to fake first 4-transfers…I always see that the values for
OFFSET, LENGTH & STATUS are not given at least for the first transfer that’s
the reason I am setting it up…

What do you mean by “not given”? For an isochronous input URB, Length
and Status should be 0, and Offset should be an increasing number. In
that case, you (the bus) set Length and Status before returning. For an
isochrononous output URB, the upper level driver sets Offset and Length.

So, if the packets are truly 768 bytes, and there were 10 packets in the
URB, the IsoPacket structure you get should look like:

00000000 00000000 00000000
00000c00 00000000 00000000
00001800 00000000 00000000
00002400 00000000 00000000
etc.
00005400 00000000 00000000
00006000 00000000 00000000
00006c00 00000000 00000000

It would be a driver bug to set Offset to 0 in every packet, but you are
not allowed to fix that bug. You have to copy one packet’s worth of
data to offset 0, and set Length to c00 (if that’s the endpoint’s packet
size).

This crash I see in the upper-layer drivers…so I don’t know how to go
about it…

The crash is NOT in an upper-layer driver. It’s in a user-mode DLL.
vfwwdm32.dll is the user-mode DLL that allows a WDM capture driver to be
used in a Video For Windows application.

With this Virtual Bus Driver all the USB memory sticks, Printers & Scanners
work fine…Now that we are trying with ISOCH transfer type of devices and
stuck here…

No doubt. I have doubts that you will ever be able to make this work
reliably. Isochronous devices are critically dependent on TIMING. The
latency you introduce will kill them.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Tim,

We are working with few other ISOCH type of devices, observing a strange
behavior like the upper-layer (user mode dll’s) are sending
BULK_OR_INTERRUPT_TRANSFER request to an endpoint and when we saw the trace
for this particular command there won’t any reply from the Host Controller
Driver or the below drivers. So we are stuck as to what we have to reply for
these kinds of commands?

Can you throw us some light on this???

Thanks,
-Vishwanath


This message, together with any attachment(s), contains confidential and proprietary information of
ServerEngines LLC and is intended only for the designated recipient(s) named above. Any unauthorized
review, printing, retention, copying, disclosure or distribution is strictly prohibited. If you are not the
intended recipient of this message, please immediately advise the sender by reply email message and
delete all copies of this message and any attachment(s). Thank you.

Vishwanath Maram wrote:

We are working with few other ISOCH type of devices, observing a
strange behavior like the upper-layer (user mode dll’s) are sending
BULK_OR_INTERRUPT_TRANSFER request to an endpoint

Sorry, DLLs don’t send BULK_OR_INTERRUPT_TRANSFER requests.

and when we saw the trace for this particular command there
won’t any reply from the Host Controller Driver or the below
drivers. So we are stuck as to what we have to reply for these
kinds of commands?

Well, let’s see. The host controller didn’t complete the URB, so what do you think you should do?

Vishwanath Maram wrote:

We are working with few other ISOCH type of devices, observing a strange
behavior like the upper-layer (user mode dll’s) are sending
BULK_OR_INTERRUPT_TRANSFER request to an endpoint and when we saw the trace
for this particular command there won’t any reply from the Host Controller
Driver or the below drivers. So we are stuck as to what we have to reply for
these kinds of commands?

Can you throw us some light on this???

It’s not so surprising, is it? Many drivers send requests that are
designed to wait for a long time. Consider, for example, a USB-to-RS232
converter, where there might not be any activity for several minutes.
The driver might just throw out a URB and return, expecting it to be
completed much later on, when the device responds. They will eventually
be completed, or else the upper-level driver will cancel them, or send a
URB_FUNCTION_ABORT_PIPE request, which causes all requests on that pipe
to be canceled.

You have to be able to handle all of that. You might have dozens –
possibly hundreds – of URBs all queued up at once waiting for action.
You’ll have to keep track of them all, and track them by pipe so you can
ship the right data to the right request.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Hi Tim,

Any idea as to how can this virtual bus driver can negotiate with the I/O
Manager about receiving the IRP’s asynchronously??? Is there is anyway that
if there is an IRP Pending the I/O Manager can still forward the IRP’s to
this Virtual Bus Driver???

Any document or url would help me in studying about this.

Thanks in advance!!!

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Tim Roberts
Sent: Wednesday, December 19, 2007 3:32 PM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] Reg. ISOCHRONOUS Transfer.

Vishwanath Maram wrote:

We are working with few other ISOCH type of devices, observing a strange
behavior like the upper-layer (user mode dll’s) are sending
BULK_OR_INTERRUPT_TRANSFER request to an endpoint and when we saw the
trace
for this particular command there won’t any reply from the Host Controller
Driver or the below drivers. So we are stuck as to what we have to reply
for
these kinds of commands?

Can you throw us some light on this???

It’s not so surprising, is it? Many drivers send requests that are
designed to wait for a long time. Consider, for example, a USB-to-RS232
converter, where there might not be any activity for several minutes.
The driver might just throw out a URB and return, expecting it to be
completed much later on, when the device responds. They will eventually
be completed, or else the upper-level driver will cancel them, or send a
URB_FUNCTION_ABORT_PIPE request, which causes all requests on that pipe
to be canceled.

You have to be able to handle all of that. You might have dozens –
possibly hundreds – of URBs all queued up at once waiting for action.
You’ll have to keep track of them all, and track them by pipe so you can
ship the right data to the right request.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer


This message, together with any attachment(s), contains confidential and proprietary information of
ServerEngines LLC and is intended only for the designated recipient(s) named above. Any unauthorized
review, printing, retention, copying, disclosure or distribution is strictly prohibited. If you are not the
intended recipient of this message, please immediately advise the sender by reply email message and
delete all copies of this message and any attachment(s). Thank you.

Vishwanath Maram wrote:

Any idea as to how can this virtual bus driver can negotiate with the I/O
Manager about receiving the IRP’s asynchronously??? Is there is anyway that
if there is an IRP Pending the I/O Manager can still forward the IRP’s to
this Virtual Bus Driver???

Any document or url would help me in studying about this.

IRPs are ALWAYS delivered asynchronously. There is no other option.

You will often have a long delay while you wait for a response from your
remote end. What do you do with the original request in that case? Are
you holding on to it and blocking while you wait? I already told you
many days ago that you are NOT allowed to block the URBs you get.
Unless you can satisfy the request immediately, you must put the IRP on
a queue, mark it as pending, and return to the caller. And you must be
able to handle cancellation, which means using a CSQ or switching to KMDF.

It sounds like you are a LONG way from having a workable and reliable
solution. Are you interested in contracting out the finishing of this code?


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Hi Tim,

We are working on this solution and were able to make the Memory sticks,
Scanners/printers & composite (Non-ISOCH) type of devices work without any
issues. Right now we are working on ISOCH/Interrupts transfer type of
devices and were stuck on how to go about???

Till now as soon as we get the IRP into our Virtual driver we mark it
pending and then send it across to remote wait till we get the response and
then complete it based on the status of the remote host. Right now what I am
looking is even after I send an request I am looking for another IRP to be
sent to this virtual bus driver so that we can process the requests even the
earlier request might not come back as it’s an interrupt type of request
which will be returned only when we click the buttons on HID or do a mouse
moment…

Any suggestions on this…

Will let you know if we need to get this done from you.

Thanks in advance.

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Tim Roberts
Sent: Thursday, December 20, 2007 9:57 AM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] Reg. ISOCHRONOUS Transfer.

Vishwanath Maram wrote:

Any idea as to how can this virtual bus driver can negotiate with the I/O
Manager about receiving the IRP’s asynchronously??? Is there is anyway
that
if there is an IRP Pending the I/O Manager can still forward the IRP’s to
this Virtual Bus Driver???

Any document or url would help me in studying about this.

IRPs are ALWAYS delivered asynchronously. There is no other option.

You will often have a long delay while you wait for a response from your
remote end. What do you do with the original request in that case? Are
you holding on to it and blocking while you wait? I already told you
many days ago that you are NOT allowed to block the URBs you get.
Unless you can satisfy the request immediately, you must put the IRP on
a queue, mark it as pending, and return to the caller. And you must be
able to handle cancellation, which means using a CSQ or switching to KMDF.

It sounds like you are a LONG way from having a workable and reliable
solution. Are you interested in contracting out the finishing of this code?


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer


This message, together with any attachment(s), contains confidential and proprietary information of
ServerEngines LLC and is intended only for the designated recipient(s) named above. Any unauthorized
review, printing, retention, copying, disclosure or distribution is strictly prohibited. If you are not the
intended recipient of this message, please immediately advise the sender by reply email message and
delete all copies of this message and any attachment(s). Thank you.