About Irp->UserBuffer

Hello everyone!

I am writing a file system filter driver and dispatch functions for IRP_MJ_READ and IRP_MJ_WRITE.

Here is the code for IRP_MJ_READ:

NTSTATUS
MyRead ( PDEVICE_OBJECT DeviceObject, PIRP Irp )
{
PIO_STACK_LOCATION pIoStackLocation;
PVOID pBuffer;
ULONG Length;

pIoStackLocation = IoGetCurrentIrpStackLocation( Irp );

Length = pIoStackLocation->Parameters.Read.Length;
pBuffer = ExAllocatePoolWithTag( NonPagedPool, Length, ‘cuL’ );
if ( NULL == pBuffer )
{
DbgPrint( “\npBuffer = ExAllocatePoolWithTag Error” );
DbgBreakPoint();
}
RtlFillMemory( pBuffer, Length, 65 );

try
{
if ( Irp->RequestorMode == UserMode )
{

ProbeForWrite( Irp->UserBuffer, Length, TYPE_ALIGNMENT( WCHAR ) );
RtlCopyMemory( Irp->UserBuffer, pBuffer, Length );
}
}
except ( EXCEPTION_EXECUTE_HANDLER )
{
DbgPrint( “\nMyRead: EXCEPTION_EXECUTE_HANDLER” );
ExFreePoolWithTag( pBuffer, ‘cuL’ );
Irp->IoStatus.Status = STATUS_ACCESS_DENIED;
Irp->IoStatus.Information = 0;
IoCompleteRequest( Irp, IO_NO_INCREMENT );
return STATUS_ACCESS_DENIED;
}
ExFreePoolWithTag( pBuffer, ‘cuL’ );

Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = Length;
IoCompleteRequest( Irp, IO_NO_INCREMENT );
return STATUS_SUCCESS;
}

This is not the original and all code. I want to complete this IRP with a buffer filled with “A”.

I know that Irp->UserBuffer is valid only in the context of the calling thread. The problem is that I want to mark the IRP pending, queue it and process it in a separate thread. Obviously I won’t be able to use this pointer Irp->UserBuffer to copy data to it from my created thread.
I know that if Irp->RequestorMode is UserMode, the Irp->MdlAddress is NULL. Is it possible to use IoAllocateMdl() and passing the Irp->UserBuffer as the input VirtualAddress of this function? Theb call MmProbeAndLockPages(). Then set Irp->MdlAddress to point to my allocated MDL. Then later from my thread may I use this MDL to write data to that buffer?

PMDL
IoAllocateMdl(
IN PVOID VirtualAddress,
IN ULONG Length,
IN BOOLEAN SecondaryBuffer,
IN BOOLEAN ChargeQuota,
IN OUT PIRP Irp OPTIONAL
);

Can VirtualAddress be a pointer from user-mode?
I don’t understand the meaning of ChargeQuota.

Thank you!

Can anyone help?

You may find this article helpful:

http://www.osronline.com/article.cfm?article=423

It explains how to pin a user buffer and map it to a SystemVA

wrote news:xxxxx@ntfsd…
> Hello everyone!
>
> I am writing a file system filter driver and dispatch functions for
> IRP_MJ_READ and IRP_MJ_WRITE.
>
> Here is the code for IRP_MJ_READ:
>
> NTSTATUS
> MyRead ( PDEVICE_OBJECT DeviceObject, PIRP Irp )
> {
> PIO_STACK_LOCATION pIoStackLocation;
> PVOID pBuffer;
> ULONG Length;
>
>
> pIoStackLocation = IoGetCurrentIrpStackLocation( Irp );
>
> Length = pIoStackLocation->Parameters.Read.Length;
> pBuffer = ExAllocatePoolWithTag( NonPagedPool, Length, ‘cuL’ );
> if ( NULL == pBuffer )
> {
> DbgPrint( “\npBuffer = ExAllocatePoolWithTag Error” );
> DbgBreakPoint();
> }
> RtlFillMemory( pBuffer, Length, 65 );
>
> try
> {
> if ( Irp->RequestorMode == UserMode )
> {
>
> ProbeForWrite( Irp->UserBuffer, Length, TYPE_ALIGNMENT( WCHAR ) );
> RtlCopyMemory( Irp->UserBuffer, pBuffer, Length );
> }
> }
> except ( EXCEPTION_EXECUTE_HANDLER )
> {
> DbgPrint( “\nMyRead: EXCEPTION_EXECUTE_HANDLER” );
> ExFreePoolWithTag( pBuffer, ‘cuL’ );
> Irp->IoStatus.Status = STATUS_ACCESS_DENIED;
> Irp->IoStatus.Information = 0;
> IoCompleteRequest( Irp, IO_NO_INCREMENT );
> return STATUS_ACCESS_DENIED;
> }
> ExFreePoolWithTag( pBuffer, ‘cuL’ );
>
> Irp->IoStatus.Status = STATUS_SUCCESS;
> Irp->IoStatus.Information = Length;
> IoCompleteRequest( Irp, IO_NO_INCREMENT );
> return STATUS_SUCCESS;
> }
>
> This is not the original and all code. I want to complete this IRP with a
> buffer filled with “A”.
>
> I know that Irp->UserBuffer is valid only in the context of the calling
> thread. The problem is that I want to mark the IRP pending, queue it and
> process it in a separate thread. Obviously I won’t be able to use this
> pointer Irp->UserBuffer to copy data to it from my created thread.
> I know that if Irp->RequestorMode is UserMode, the Irp->MdlAddress is
> NULL. Is it possible to use IoAllocateMdl() and passing the
> Irp->UserBuffer as the input VirtualAddress of this function? Theb call
> MmProbeAndLockPages(). Then set Irp->MdlAddress to point to my allocated
> MDL. Then later from my thread may I use this MDL to write data to that
> buffer?
>
> PMDL
> IoAllocateMdl(
> IN PVOID VirtualAddress,
> IN ULONG Length,
> IN BOOLEAN SecondaryBuffer,
> IN BOOLEAN ChargeQuota,
> IN OUT PIRP Irp OPTIONAL
> );
>
> Can VirtualAddress be a pointer from user-mode?
> I don’t understand the meaning of ChargeQuota.
>
> Thank you!
>

Thank you Frank, but I already read this article. Yes it is very useful and I am already trying to solve my problem using my own MDLs… I hope I am going in the right way.