Irp->UserBuffer question

Hi, everybody!

I’m trying to do the simplest thing, and I cannot !

I have a driver, and I want to copy data from the driver to
my application.

I issue a CreateFile, and it succeeds.
Then I do a ReadFile, and gives it the buffer I want to fill.

In the driver itself, I do a simple memcpy to Irp->UserBuffer,
and fill the Irp ->IoStatus.Status with STATUS_SUCCESS,
and Irp ->IoStatus.Informatrion with the length of data.

Then, I complete the IRP.

The problem is that my application receives an empty buffer
(all zeros) !!!.

I also tried to fill the buffer with some data before the ReadFile(),
and print it using DbgPrint() in the driver - and it worked !

What am I doing wrong? is it something in the CreateFile?
Is it the driver? Am I allowed to do such things? Do I have
to lock something in memory before filling the buffer?

thanks in advance,

  • Barak

Barak Mandelovich xxxxx@mercury.co.il
Mercury Interactive ltd.

It depends on your DeviceObject’s flags.
You can use Irp->UserBuffer only and only if the
DeviceObject->Flags contain neither DO_BUFFERED_IO
nor DO_DIRECT_IO.
Else you should use either Irp->AssociatedIrp.SystemBuffer
or Irp->MdlAddress.

Paul

-----P?vodn? zpr?va-----
Od: Barak Mandelovich [SMTP:xxxxx@mercury.co.il]
Odesl?no: Wednesday, August 30, 2000 2:13 PM
Komu: NT Developers Interest List
P?edm?t: [ntdev] Irp->UserBuffer question

Hi, everybody!

I’m trying to do the simplest thing, and I cannot !

I have a driver, and I want to copy data from the driver to
my application.

I issue a CreateFile, and it succeeds.
Then I do a ReadFile, and gives it the buffer I want to fill.

In the driver itself, I do a simple memcpy to Irp->UserBuffer,
and fill the Irp ->IoStatus.Status with STATUS_SUCCESS,
and Irp ->IoStatus.Informatrion with the length of data.

Then, I complete the IRP.

The problem is that my application receives an empty buffer
(all zeros) !!!.

I also tried to fill the buffer with some data before the ReadFile(),
and print it using DbgPrint() in the driver - and it worked !

What am I doing wrong? is it something in the CreateFile?
Is it the driver? Am I allowed to do such things? Do I have
to lock something in memory before filling the buffer?

thanks in advance,

  • Barak

Barak Mandelovich xxxxx@mercury.co.il
Mercury Interactive ltd.


You are currently subscribed to ntdev as: xxxxx@sodatsw.cz
To unsubscribe send a blank email to $subst(‘Email.Unsub’)

> In the driver itself, I do a simple memcpy to Irp->UserBuffer,

Don’t forget to do this under try/catch block and to do ProbeForWrite
before.
(otherwise, anybody will be able to pass the kernel pointer to ReadFile and
crash the OS).

What am I doing wrong? is it something in the CreateFile?
Is it the driver?

If you use Irp->UserBuffer, you must not specify neither DO_BUFFERED_IO nor
DO_DIRECT_IO flags.

Max

ProbeForWrite()?

it’s not documented in the DDK!
I only found its declaration in ntddk.h,
but no explanation there…

Can someone please advise?

best regards,

  • Barak

Barak Mandelovich xxxxx@mercury.co.il
Mercury Interactive ltd. 19 Shabazi St.
Tel: +972-3-5399286 Yehud, 56100
Fax: +972-3-5331617 Israel

-----Original Message-----
From: Maxim S. Shatskih [mailto:xxxxx@storagecraft.com]
Sent: Wednesday, August 30, 2000 3:34 PM
To: NT Developers Interest List
Subject: [ntdev] Re: Irp->UserBuffer question

In the driver itself, I do a simple memcpy to Irp->UserBuffer,

Don’t forget to do this under try/catch block and to do ProbeForWrite
before.
(otherwise, anybody will be able to pass the kernel pointer to ReadFile and
crash the OS).

What am I doing wrong? is it something in the CreateFile?
Is it the driver?

If you use Irp->UserBuffer, you must not specify neither DO_BUFFERED_IO nor
DO_DIRECT_IO flags.

Max


You are currently subscribed to ntdev as: xxxxx@mercury.co.il
To unsubscribe send a blank email to $subst(‘Email.Unsub’)

Your problem appeared to be a misunderstanding about
UserBuffer/SystemBuffer/MdlAddress - i.e. where is the user’s data - and in
your case it is unlikely that you are using neither IO, and is instead most
likely that you are using METHOD_BUFFERED and that the user’s data is in
SystemBuffer.

When you wrote data into UserBuffer that worked fine, assuming that you were
in the originating thread context and that the application gave you a valid
virtual address (which if you were using METHOD_BUFFERED then the virtual
address is valid).

However, when you completed the request the IoManager copied the contents of
SystemBuffer back into the same virtual address space that you used, that is
right back on top of UserBuffer.

If you were using METHOD_DIRECT then while the user’s data is described by
MdlAddress, unlike METHOD_BUFFERED, UserBuffer and MdlAddress are describing
the same buffer. (They may use two different virtual addresses, but these
addresses have the same backing store.) Modifications to UserBuffer would
have been observed and not overwritten on completion.

You should ignore UserBuffer and not worry about what ProbeForWrite is.

However, it is documented in the windows 2000 ddk:

Kernel-Mode Drivers: Windows 2000 DDK

ProbeForWrite
VOID
ProbeForWrite (
IN CONST VOID *Address,
IN ULONG Length,
IN ULONG Alignment
);
The ProbeForWrite support routine probes a structure for write accessibility
and ensures correct alignment of the structure. If the structure is not
accessible or has incorrect alignment, then an exception is raised.

Parameters
Address
Supplies a pointer to the structure to be probed.
Length
Length of structure.
Alignment
Supplies the required alignment of the structure expressed as the number of
bytes in the primitive datatype (e.g., 1 for char, 2 for short, 4 for long,
and 8 for quad).
Include
wdm.h or ntddk.h

Comments
Kernel-mode drivers must use ProbeForWrite to validate write access to
buffers allocated in user space. It is most commonly used during
METHOD_NEITHER I/O to valid the user buffer pointed to by Irp -> UserBuffer.

Drivers should call ProbeForWrite inside a try-except block, so that any
exceptions raised are handled properly, and the driver completes the IRP
with an error.

Callers of ProbeForWrite must be running at IRQL < APC_LEVEL.

See Also
ProbeForRead

Built on Wednesday, June 28, 2000

-----Original Message-----
From: Barak Mandelovich [mailto:xxxxx@mercury.co.il]
Sent: Wednesday, August 30, 2000 11:10 AM
To: NT Developers Interest List
Subject: [ntdev] Re: Irp->UserBuffer question

ProbeForWrite()?

it’s not documented in the DDK!
I only found its declaration in ntddk.h,
but no explanation there…

Can someone please advise?

best regards,

  • Barak


Barak Mandelovich xxxxx@mercury.co.il
Mercury Interactive ltd. 19 Shabazi St.
Tel: +972-3-5399286 Yehud, 56100
Fax: +972-3-5331617 Israel


-----Original Message-----
From: Maxim S. Shatskih [mailto:xxxxx@storagecraft.com]
Sent: Wednesday, August 30, 2000 3:34 PM
To: NT Developers Interest List
Subject: [ntdev] Re: Irp->UserBuffer question

> In the driver itself, I do a simple memcpy to Irp->UserBuffer,

Don’t forget to do this under try/catch block and to do ProbeForWrite
before.
(otherwise, anybody will be able to pass the kernel pointer
to ReadFile and
crash the OS).

> What am I doing wrong? is it something in the CreateFile?
> Is it the driver?

If you use Irp->UserBuffer, you must not specify neither
DO_BUFFERED_IO nor
DO_DIRECT_IO flags.

Max


You are currently subscribed to ntdev as: xxxxx@mercury.co.il
To unsubscribe send a blank email to $subst(‘Email.Unsub’)


You are currently subscribed to ntdev as: xxxxx@stratus.com
To unsubscribe send a blank email to $subst(‘Email.Unsub’)

ProbeForRead and ProbeForWrite are for user buffer
validation.
Must be used inside a try/except block 'cause they
can generate exceptions like STATUS_ACCESS_VIOLATION.

Both probes checks input address and input address + input length
for MM_USER_PROBE_ADDRESS (which is usually 0x7FEFFFFF).
If any of this two addresses is higher than allowed,
STATUS_ACCESS_VIOLATION is raised.
Next the ProbeForRead will try to read and ProbeForWrite will try
to read and write the first and last address.
This also can generate some exception.
Finally the alignment of the input address is checked and in the
case of not proper aligned buffer the STATUS_DATATYPE_MISALIGNMENT
exception is raised.

Every Native API routine uses this technique to probe addresses when
the previous mode is UserMode.

if (ExGetPreviousMode() != KernelMode)
{
try
{
ProbeForWrite(Buffer, Length, 4);
}

except(EXCEPTION_EXECUTE_HANDLER)
{
return GetExceptionCode();
}
}

Paul

-----P?vodn? zpr?va-----
Od: Barak Mandelovich [SMTP:xxxxx@mercury.co.il]
Odesl?no: Wednesday, August 30, 2000 5:10 PM
Komu: NT Developers Interest List
P?edm?t: [ntdev] Re: Irp->UserBuffer question

ProbeForWrite()?

it’s not documented in the DDK!
I only found its declaration in ntddk.h,
but no explanation there…

Can someone please advise?

best regards,

  • Barak

Barak Mandelovich xxxxx@mercury.co.il
Mercury Interactive ltd. 19 Shabazi St.
Tel: +972-3-5399286 Yehud, 56100
Fax: +972-3-5331617 Israel

-----Original Message-----
From: Maxim S. Shatskih [mailto:xxxxx@storagecraft.com]
Sent: Wednesday, August 30, 2000 3:34 PM
To: NT Developers Interest List
Subject: [ntdev] Re: Irp->UserBuffer question

> In the driver itself, I do a simple memcpy to Irp->UserBuffer,

Don’t forget to do this under try/catch block and to do ProbeForWrite
before.
(otherwise, anybody will be able to pass the kernel pointer to ReadFile
and
crash the OS).

> What am I doing wrong? is it something in the CreateFile?
> Is it the driver?

If you use Irp->UserBuffer, you must not specify neither DO_BUFFERED_IO
nor
DO_DIRECT_IO flags.

Max


You are currently subscribed to ntdev as: xxxxx@mercury.co.il
To unsubscribe send a blank email to $subst(‘Email.Unsub’)


You are currently subscribed to ntdev as: xxxxx@sodatsw.cz
To unsubscribe send a blank email to $subst(‘Email.Unsub’)

you should fill in the data in SystemBuffer and not UserBuffer.

regards
Jeseem
mailto:xxxxx@hotmail.com

----- Original Message -----
From: “Barak Mandelovich”
To: “NT Developers Interest List”
Sent: Wednesday, August 30, 2000 8:13 AM
Subject: [ntdev] Irp->UserBuffer question

> Hi, everybody!
>
> I’m trying to do the simplest thing, and I cannot !
>
> I have a driver, and I want to copy data from the driver to
> my application.
>
> I issue a CreateFile, and it succeeds.
> Then I do a ReadFile, and gives it the buffer I want to fill.
>
> In the driver itself, I do a simple memcpy to Irp->UserBuffer,
> and fill the Irp ->IoStatus.Status with STATUS_SUCCESS,
> and Irp ->IoStatus.Informatrion with the length of data.
>
> Then, I complete the IRP.
>
> The problem is that my application receives an empty buffer
> (all zeros) !!!.
>
> I also tried to fill the buffer with some data before the ReadFile(),
> and print it using DbgPrint() in the driver - and it worked !
>
> What am I doing wrong? is it something in the CreateFile?
> Is it the driver? Am I allowed to do such things? Do I have
> to lock something in memory before filling the buffer?
>
>
> thanks in advance,
>
> - Barak
>
> ------------------------------------------------------------------------
> Barak Mandelovich xxxxx@mercury.co.il
> Mercury Interactive ltd.
> ------------------------------------------------------------------------
>
>
> —
> You are currently subscribed to ntdev as: xxxxx@hotmail.com
> To unsubscribe send a blank email to $subst(‘Email.Unsub’)
>
>