IRP_MJ_READ, buffer size and sector size on a USB key.

Hi all,

I am testing my filter driver with a USB key and I found a problem with a
IRP_MJ_READ/IRP_MJ_WRITE
The same issues does not occur on a hard disk.

In my driver I need to read a file content using IRP. The handle comes from
the user mode.
I use the IoBuildSynchronousFsdRequest to build the IRP and I then set the
flags

IRP_NO_CACHE and IRP_IRP_SYNCHRONOUS_API.

The buffer size is 0x2000, while the sector on the disk is 0x200.

When I read or write I get the fatal error as follows. The strange thing is
that it works
if the buffer size is like the sector size. Any ideas?

Thanks in advance.
Francesco


static
NTSTATUS SendSyncIrp(PDEVICE_OBJECT DeviceObject, ULONG MajorFunction,
PFILE_OBJECT FileObject, ULONG IrpFlags,
PIO_STATUS_BLOCK IoStatusBlock, PVOID Buffer, ULONG
BufferLength, PLARGE_INTEGER Offset) {
PIRP Irp;
KEVENT Event;
NTSTATUS Status;
PIO_STACK_LOCATION IrpStack = NULL;

KeInitializeEvent( &Event, NotificationEvent, FALSE );

Irp = IoBuildSynchronousFsdRequest(MajorFunction, DeviceObject, Buffer,
BufferLength, Offset,
&Event, IoStatusBlock);
if (!Irp) {
KDERROR(“IRP(%p): cannot create sync IRP\n”, FileObject);
return STATUS_INSUFFICIENT_RESOURCES;
}
Irp->Flags |= IrpFlags;

IrpStack = IoGetNextIrpStackLocation( Irp );
IrpStack->FileObject = FileObject;

Status = IoCallDriver(DeviceObject, Irp);

if ( Status == STATUS_PENDING ) {
KeWaitForSingleObject( &Event, Executive, KernelMode, FALSE, NULL );
Status = IoStatusBlock->Status;
}

// IoFreeIrp( Irp );

return Status;
}


BugCheck D1, {8b08468b, 2, 1, fc7adf2d}

Probably caused by : usbuhci.sys ( usbuhci!UhciProcessDoneAsyncTd+dd )

Followup: MachineOwner

nt!RtlpBreakWithStatusInstruction:
804e3b25 cc int 3
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: 8b08468b, memory referenced
Arg2: 00000002, IRQL
Arg3: 00000001, value 0 = read operation, 1 = write operation
Arg4: fc7adf2d, address which referenced memory

Debugging Details:

WRITE_ADDRESS: 8b08468b Nonpaged pool

CURRENT_IRQL: 2

FAULTING_IP:
usbuhci!UhciProcessDoneAsyncTd+dd
fc7adf2d f3a5 rep movsd

DEFAULT_BUCKET_ID: DRIVER_FAULT

BUGCHECK_STR: 0xD1

LAST_CONTROL_TRANSFER: from fc7ae47a to fc7adf2d

TRAP_FRAME: 8055071c – (.trap ffffffff8055071c)
ErrCode = 00000002
eax=810d5040 ebx=81162a18 ecx=3ac00011 edx=eb000047 esi=810d5040
edi=8b08468b
eip=fc7adf2d esp=80550790 ebp=805507ac iopl=0 nv up ei pl nz na po
cy
cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000
efl=00010207
usbuhci!UhciProcessDoneAsyncTd+0xdd:
fc7adf2d f3a5 rep movsd
Resetting default scope

STACK_TEXT:
805507ac fc7ae47a 810f69dc 810d5c20 ffaa0f70
usbuhci!UhciProcessDoneAsyncTd+0xdd
805507cc fc7abded 810f69dc 810d5000 805507fc
usbuhci!UhciPollAsyncEndpoint+0x450
805507dc fc1a22ba 810f69dc ffaa0f70 804e3579 usbuhci!UhciPollEndpoint+0x1f
805507fc fc1a3578 026c6f50 810f60e0 ffaa0df8
USBPORT!USBPORT_PollEndpoint+0xe8
80550824 fc1a6ed0 810f6028 50457270 804e3579
USBPORT!USBPORT_CoreEndpointWorker+0x2be
80550854 fc1b4fb0 810f6028 804e3579 810f6028 USBPORT!USBPORT_DpcWorker+0x18a
80550890 fc1b5128 810f6028 00000001 80559580
USBPORT!USBPORT_IsrDpcWorker+0x37e
805508ac 804dc179 810f664c 6b755044 00000000 USBPORT!USBPORT_IsrDpc+0x166

Francesco

For non cache read (a) offset must be sector aligned in file (b) length must
be exact multiple of sector size (c) buffer address must be sector aligned
in memory.

These conditions are not always enforced however if you violate the
conditions the system behaviour is not defined.

Cheers
Lyndon

“francesco garelli” wrote in message
news:xxxxx@ntfsd…
Hi all,

I am testing my filter driver with a USB key and I found a problem with a
IRP_MJ_READ/IRP_MJ_WRITE
The same issues does not occur on a hard disk.

In my driver I need to read a file content using IRP. The handle comes from
the user mode.
I use the IoBuildSynchronousFsdRequest to build the IRP and I then set the
flags

IRP_NO_CACHE and IRP_IRP_SYNCHRONOUS_API.

The buffer size is 0x2000, while the sector on the disk is 0x200.

When I read or write I get the fatal error as follows. The strange thing is
that it works
if the buffer size is like the sector size. Any ideas?

Thanks in advance.
Francesco

-------------------------------------------------------------------------------------------------------------------------------------

static
NTSTATUS SendSyncIrp(PDEVICE_OBJECT DeviceObject, ULONG MajorFunction,
PFILE_OBJECT FileObject, ULONG IrpFlags,
PIO_STATUS_BLOCK IoStatusBlock, PVOID Buffer, ULONG
BufferLength, PLARGE_INTEGER Offset) {
PIRP Irp;
KEVENT Event;
NTSTATUS Status;
PIO_STACK_LOCATION IrpStack = NULL;

KeInitializeEvent( &Event, NotificationEvent, FALSE );

Irp = IoBuildSynchronousFsdRequest(MajorFunction, DeviceObject, Buffer,
BufferLength, Offset,
&Event, IoStatusBlock);
if (!Irp) {
KDERROR(“IRP(%p): cannot create sync IRP\n”, FileObject);
return STATUS_INSUFFICIENT_RESOURCES;
}
Irp->Flags |= IrpFlags;

IrpStack = IoGetNextIrpStackLocation( Irp );
IrpStack->FileObject = FileObject;

Status = IoCallDriver(DeviceObject, Irp);

if ( Status == STATUS_PENDING ) {
KeWaitForSingleObject( &Event, Executive, KernelMode, FALSE, NULL );
Status = IoStatusBlock->Status;
}

// IoFreeIrp( Irp );

return Status;
}

--------------------------------------------------------------------------------------------------------------------------------

BugCheck D1, {8b08468b, 2, 1, fc7adf2d}

Probably caused by : usbuhci.sys ( usbuhci!UhciProcessDoneAsyncTd+dd )

Followup: MachineOwner
---------

nt!RtlpBreakWithStatusInstruction:
804e3b25 cc int 3
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: 8b08468b, memory referenced
Arg2: 00000002, IRQL
Arg3: 00000001, value 0 = read operation, 1 = write operation
Arg4: fc7adf2d, address which referenced memory

Debugging Details:
------------------

WRITE_ADDRESS: 8b08468b Nonpaged pool

CURRENT_IRQL: 2

FAULTING_IP:
usbuhci!UhciProcessDoneAsyncTd+dd
fc7adf2d f3a5 rep movsd

DEFAULT_BUCKET_ID: DRIVER_FAULT

BUGCHECK_STR: 0xD1

LAST_CONTROL_TRANSFER: from fc7ae47a to fc7adf2d

TRAP_FRAME: 8055071c – (.trap ffffffff8055071c)
ErrCode = 00000002
eax=810d5040 ebx=81162a18 ecx=3ac00011 edx=eb000047 esi=810d5040
edi=8b08468b
eip=fc7adf2d esp=80550790 ebp=805507ac iopl=0 nv up ei pl nz na po
cy
cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000
efl=00010207
usbuhci!UhciProcessDoneAsyncTd+0xdd:
fc7adf2d f3a5 rep movsd
Resetting default scope

STACK_TEXT:
805507ac fc7ae47a 810f69dc 810d5c20 ffaa0f70
usbuhci!UhciProcessDoneAsyncTd+0xdd
805507cc fc7abded 810f69dc 810d5000 805507fc
usbuhci!UhciPollAsyncEndpoint+0x450
805507dc fc1a22ba 810f69dc ffaa0f70 804e3579 usbuhci!UhciPollEndpoint+0x1f
805507fc fc1a3578 026c6f50 810f60e0 ffaa0df8
USBPORT!USBPORT_PollEndpoint+0xe8
80550824 fc1a6ed0 810f6028 50457270 804e3579
USBPORT!USBPORT_CoreEndpointWorker+0x2be
80550854 fc1b4fb0 810f6028 804e3579 810f6028 USBPORT!USBPORT_DpcWorker+0x18a
80550890 fc1b5128 810f6028 00000001 80559580
USBPORT!USBPORT_IsrDpcWorker+0x37e
805508ac 804dc179 810f664c 6b755044 00000000 USBPORT!USBPORT_IsrDpc+0x166

Lyndon,

I knew that the size and the offset are relevant in a non cache read.
Anyway the buffer size is 0x2000 bytes which is exactly 16 times the
sector size.

If it is a matter of offset in memory (how can I force the alignment
in memory?) I don’t understand why the buffer size makes the difference

Thanks
Francesco

Francesco

For non cache read (a) offset must be sector aligned in file (b)
length must be exact multiple of sector size (c) buffer address must
be sector aligned in memory.

These conditions are not always enforced however if you violate the
conditions the system behaviour is not defined.

Cheers
Lyndon

“francesco garelli” wrote in message
> news:xxxxx@ntfsd…
> Hi all,
>
> I am testing my filter driver with a USB key and I found a problem
> with a IRP_MJ_READ/IRP_MJ_WRITE
> The same issues does not occur on a hard disk.
>
> In my driver I need to read a file content using IRP. The handle comes
> from the user mode.
> I use the IoBuildSynchronousFsdRequest to build the IRP and I then set
> the flags
>
> IRP_NO_CACHE and IRP_IRP_SYNCHRONOUS_API.
>
> The buffer size is 0x2000, while the sector on the disk is 0x200.
>
>
> When I read or write I get the fatal error as follows. The strange
> thing is that it works
> if the buffer size is like the sector size. Any ideas?
>
> Thanks in advance.
> Francesco
>
> ----------------------------------------------------------------------
-
> --------------------------------------------------------------
>
> static
> NTSTATUS SendSyncIrp(PDEVICE_OBJECT DeviceObject, ULONG MajorFunction,
> PFILE_OBJECT FileObject, ULONG IrpFlags,
> PIO_STATUS_BLOCK IoStatusBlock, PVOID Buffer,
> ULONG
> BufferLength, PLARGE_INTEGER Offset) {
> PIRP Irp;
> KEVENT Event;
> NTSTATUS Status;
> PIO_STACK_LOCATION IrpStack = NULL;
>
> KeInitializeEvent( &Event, NotificationEvent, FALSE );
>
> Irp = IoBuildSynchronousFsdRequest(MajorFunction, DeviceObject,
> Buffer,
> BufferLength, Offset,
> &Event, IoStatusBlock);
> if (!Irp) {
> KDERROR(“IRP(%p): cannot create sync IRP\n”, FileObject);
> return STATUS_INSUFFICIENT_RESOURCES;
> }
> Irp->Flags |= IrpFlags;
>
> IrpStack = IoGetNextIrpStackLocation( Irp );
> IrpStack->FileObject = FileObject;
>
> Status = IoCallDriver(DeviceObject, Irp);
>
> if ( Status == STATUS_PENDING ) {
> KeWaitForSingleObject( &Event, Executive, KernelMode, FALSE,
> NULL ); Status = IoStatusBlock->Status;
> }
>
> // IoFreeIrp( Irp );
>
> return Status;
> }
>
> ----------------------------------------------------------------------
-
> ---------------------------------------------------------
>
>
> BugCheck D1, {8b08468b, 2, 1, fc7adf2d}
>
> Probably caused by : usbuhci.sys ( usbuhci!UhciProcessDoneAsyncTd+dd )
>
> Followup: MachineOwner
> ---------
>
> nt!RtlpBreakWithStatusInstruction:
> 804e3b25 cc int 3
> 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: 8b08468b, memory referenced
> Arg2: 00000002, IRQL
> Arg3: 00000001, value 0 = read operation, 1 = write operation
> Arg4: fc7adf2d, address which referenced memory
>
> Debugging Details:
> ------------------
>
>
> WRITE_ADDRESS: 8b08468b Nonpaged pool
>
> CURRENT_IRQL: 2
>
> FAULTING_IP:
> usbuhci!UhciProcessDoneAsyncTd+dd
> fc7adf2d f3a5 rep movsd
>
> DEFAULT_BUCKET_ID: DRIVER_FAULT
>
> BUGCHECK_STR: 0xD1
>
> LAST_CONTROL_TRANSFER: from fc7ae47a to fc7adf2d
>
> TRAP_FRAME: 8055071c – (.trap ffffffff8055071c)
> ErrCode = 00000002
> eax=810d5040 ebx=81162a18 ecx=3ac00011 edx=eb000047 esi=810d5040
> edi=8b08468b
> eip=fc7adf2d esp=80550790 ebp=805507ac iopl=0 nv up ei pl nz
> na po cy
> cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000
> efl=00010207
> usbuhci!UhciProcessDoneAsyncTd+0xdd:
> fc7adf2d f3a5 rep movsd
> Resetting default scope
>
> STACK_TEXT:
> 805507ac fc7ae47a 810f69dc 810d5c20 ffaa0f70
> usbuhci!UhciProcessDoneAsyncTd+0xdd
> 805507cc fc7abded 810f69dc 810d5000 805507fc
> usbuhci!UhciPollAsyncEndpoint+0x450
> 805507dc fc1a22ba 810f69dc ffaa0f70 804e3579
> usbuhci!UhciPollEndpoint+0x1f 805507fc fc1a3578 026c6f50 810f60e0
> ffaa0df8 USBPORT!USBPORT_PollEndpoint+0xe8
> 80550824 fc1a6ed0 810f6028 50457270 804e3579
> USBPORT!USBPORT_CoreEndpointWorker+0x2be
> 80550854 fc1b4fb0 810f6028 804e3579 810f6028
> USBPORT!USBPORT_DpcWorker+0x18a 80550890 fc1b5128 810f6028 00000001
> 80559580 USBPORT!USBPORT_IsrDpcWorker+0x37e
> 805508ac 804dc179 810f664c 6b755044 00000000
> USBPORT!USBPORT_IsrDpc+0x166
>
>
>

> If it is a matter of offset in memory (how can I force the alignment

in memory?)

From the doc for ExAllocatePoolWithTag

If NumberOfBytes is PAGE_SIZE or greater, a page-aligned buffer is
allocated. Memory allocations of PAGE_SIZE or less do not cross
page boundaries. Memory allocations of less than PAGE_SIZE are
not necessarily page-aligned but are aligned on an 8-byte boundary.

I don’t understand why the buffer size makes the difference

Nor do I, but in your position I’d take a look through the dump and see
what’s up. Questions you might want to ask yourself are: why did the
pagefault happen ? is the address complete invalid or is it just paged out?
What was the DPC doing? What was my thread up to? Does 0x8b08468b has any
meaning to me?

Sorry, I skim read, and mis-interpreted "strange thing is that it works if
the buffer size is like the sector size. " I assume then this means that
“the buffer size is equal to the sector size”?

“Francesco” wrote in message news:xxxxx@ntfsd…
> Lyndon,
>
> I knew that the size and the offset are relevant in a non cache read.
> Anyway the buffer size is 0x2000 bytes which is exactly 16 times the
> sector size.
>
> If it is a matter of offset in memory (how can I force the alignment
> in memory?) I don’t understand why the buffer size makes the difference
>
>
> Thanks
> Francesco
>
>
>> Francesco
>>
>> For non cache read (a) offset must be sector aligned in file (b)
>> length must be exact multiple of sector size (c) buffer address must
>> be sector aligned in memory.
>>
>> These conditions are not always enforced however if you violate the
>> conditions the system behaviour is not defined.
>>
>> Cheers
>> Lyndon
>>
>> “francesco garelli” wrote in message
>> news:xxxxx@ntfsd…
>> Hi all,
>>
>> I am testing my filter driver with a USB key and I found a problem
>> with a IRP_MJ_READ/IRP_MJ_WRITE
>> The same issues does not occur on a hard disk.
>>
>> In my driver I need to read a file content using IRP. The handle comes
>> from the user mode.
>> I use the IoBuildSynchronousFsdRequest to build the IRP and I then set
>> the flags
>>
>> IRP_NO_CACHE and IRP_IRP_SYNCHRONOUS_API.
>>
>> The buffer size is 0x2000, while the sector on the disk is 0x200.
>>
>>
>> When I read or write I get the fatal error as follows. The strange
>> thing is that it works
>> if the buffer size is like the sector size. Any ideas?
>>
>> Thanks in advance.
>> Francesco
>>
>> ----------------------------------------------------------------------
> -
>> --------------------------------------------------------------
>>
>> static
>> NTSTATUS SendSyncIrp(PDEVICE_OBJECT DeviceObject, ULONG MajorFunction,
>> PFILE_OBJECT FileObject, ULONG IrpFlags,
>> PIO_STATUS_BLOCK IoStatusBlock, PVOID Buffer,
>> ULONG
>> BufferLength, PLARGE_INTEGER Offset) {
>> PIRP Irp;
>> KEVENT Event;
>> NTSTATUS Status;
>> PIO_STACK_LOCATION IrpStack = NULL;
>>
>> KeInitializeEvent( &Event, NotificationEvent, FALSE );
>>
>> Irp = IoBuildSynchronousFsdRequest(MajorFunction, DeviceObject,
>> Buffer,
>> BufferLength, Offset,
>> &Event, IoStatusBlock);
>> if (!Irp) {
>> KDERROR(“IRP(%p): cannot create sync IRP\n”, FileObject);
>> return STATUS_INSUFFICIENT_RESOURCES;
>> }
>> Irp->Flags |= IrpFlags;
>>
>> IrpStack = IoGetNextIrpStackLocation( Irp );
>> IrpStack->FileObject = FileObject;
>>
>> Status = IoCallDriver(DeviceObject, Irp);
>>
>> if ( Status == STATUS_PENDING ) {
>> KeWaitForSingleObject( &Event, Executive, KernelMode, FALSE,
>> NULL ); Status = IoStatusBlock->Status;
>> }
>>
>> // IoFreeIrp( Irp );
>>
>> return Status;
>> }
>>
>> ----------------------------------------------------------------------
> -
>> ---------------------------------------------------------
>>
>>
>> BugCheck D1, {8b08468b, 2, 1, fc7adf2d}
>>
>> Probably caused by : usbuhci.sys ( usbuhci!UhciProcessDoneAsyncTd+dd )
>>
>> Followup: MachineOwner
>> ---------
>>
>> nt!RtlpBreakWithStatusInstruction:
>> 804e3b25 cc int 3
>> 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: 8b08468b, memory referenced
>> Arg2: 00000002, IRQL
>> Arg3: 00000001, value 0 = read operation, 1 = write operation
>> Arg4: fc7adf2d, address which referenced memory
>>
>> Debugging Details:
>> ------------------
>>
>>
>> WRITE_ADDRESS: 8b08468b Nonpaged pool
>>
>> CURRENT_IRQL: 2
>>
>> FAULTING_IP:
>> usbuhci!UhciProcessDoneAsyncTd+dd
>> fc7adf2d f3a5 rep movsd
>>
>> DEFAULT_BUCKET_ID: DRIVER_FAULT
>>
>> BUGCHECK_STR: 0xD1
>>
>> LAST_CONTROL_TRANSFER: from fc7ae47a to fc7adf2d
>>
>> TRAP_FRAME: 8055071c – (.trap ffffffff8055071c)
>> ErrCode = 00000002
>> eax=810d5040 ebx=81162a18 ecx=3ac00011 edx=eb000047 esi=810d5040
>> edi=8b08468b
>> eip=fc7adf2d esp=80550790 ebp=805507ac iopl=0 nv up ei pl nz
>> na po cy
>> cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000
>> efl=00010207
>> usbuhci!UhciProcessDoneAsyncTd+0xdd:
>> fc7adf2d f3a5 rep movsd
>> Resetting default scope
>>
>> STACK_TEXT:
>> 805507ac fc7ae47a 810f69dc 810d5c20 ffaa0f70
>> usbuhci!UhciProcessDoneAsyncTd+0xdd
>> 805507cc fc7abded 810f69dc 810d5000 805507fc
>> usbuhci!UhciPollAsyncEndpoint+0x450
>> 805507dc fc1a22ba 810f69dc ffaa0f70 804e3579
>> usbuhci!UhciPollEndpoint+0x1f 805507fc fc1a3578 026c6f50 810f60e0
>> ffaa0df8 USBPORT!USBPORT_PollEndpoint+0xe8
>> 80550824 fc1a6ed0 810f6028 50457270 804e3579
>> USBPORT!USBPORT_CoreEndpointWorker+0x2be
>> 80550854 fc1b4fb0 810f6028 804e3579 810f6028
>> USBPORT!USBPORT_DpcWorker+0x18a 80550890 fc1b5128 810f6028 00000001
>> 80559580 USBPORT!USBPORT_IsrDpcWorker+0x37e
>> 805508ac 804dc179 810f664c 6b755044 00000000
>> USBPORT!USBPORT_IsrDpc+0x166
>>
>>
>>
>
>