NEITHER IO

in my IRP_MJ_WRITE dispatch I want to do some kind of shadow writes to a file when a certain file get the request.
As I’ve seen most FS devices support NEITHER IO
In neither IO the user buffer is active, but it is avalaible only in the requestor’s thread context
I allocate an irp and a mdl describing the pages of the irp->UserBuffer.
i use probe and lock pages to lock the buffer in system space
I associate the mdl with the irp , pass it down the stack. I free the irp and mdl in the completion routine.
after this I pass down the initial irp.
this seems to work until my driver unloads, this is when I get blue screen
the output is correct to both of the files

Do you get a blue screen when nothing has been filtered?

i.e. you load the driver and unload it right away.

Btw you don’t need to allocate a new Irp for this, you can reuse the Irp
you were given.

Le Tue, 18 Sep 2007 04:46:04 -0400 (EDT), xxxxx@gmail.com a ecrit:

in my IRP_MJ_WRITE dispatch I want to do some kind of shadow writes to a
file when a certain file get the request.
As I’ve seen most FS devices support NEITHER IO
In neither IO the user buffer is active, but it is avalaible only in the
requestor’s thread context
I allocate an irp and a mdl describing the pages of the irp->UserBuffer.
i use probe and lock pages to lock the buffer in system space
I associate the mdl with the irp , pass it down the stack. I free the
irp
and mdl in the completion routine.
after this I pass down the initial irp.
this seems to work until my driver unloads, this is when I get blue
screen
the output is correct to both of the files

EA

>> I allocate an irp and a mdl describing the pages of the irp->UserBuffer.

Then what is the benifit of using NEITHER method? Why don’t you use DIRECT method? It may not be the case, but BSOD is possibly for failing to probe/check/validate the buffer.

I use __try {probefor write () } __ except to probe the validity of the buffet

I will try reusing and tell you the result.
thank you for the suggestion. can u also suggest some documentation on this (NEITHER IO and reusing )

if I load and unload right away I don’t get the BSOD

I don’t think reusing the IRP is a good idea because then it will processed in arbitrary thread context and that user buffer is only available in the context of the calling process.
probably I am doing the reusing in a wrong manner.
this is how I do it:
this is somewhere in the IRP_MJ_WRITE at PASSIVE_LEVEL

RtlInitUnicodeString(&DummyFileName,
L"\Device\HarddiskVolume1\dummy.txt");

GetFileObjectFromPath uses IoCreateFileSpecifyDeviceObjectHint and the ObReferenceObjectByHandle() to get the file_object for the dummy, i don’t know any other way

Status = GetFileObjectFromPathEx(
devExt->NLExtHeader.AttachedToDeviceObject,
&DummyFileName,
&DummyFileObject,
&hFile,
GENERIC_WRITE|GENERIC_READ);

if (!NT_SUCCESS(Status))
{
IoSkipCurrentIrpStackLocation(Irp);
return IoCallDriver(devExt->NLExtHeader.AttachedToDeviceObject,Irp);
}

KeInitializeEvent(
&WriteEvent,
NotificationEvent,
FALSE);

IoCopyCurrentIrpStackLocationToNext(Irp);

//all the completion routine does is set the event and return STATUS_MORE_PROCESSING_REQUIRED

IoSetCompletionRoutine(
Irp,
IoWriteRequestCompletion,
&WriteEvent,
TRUE,
TRUE,
TRUE);

Status = IoCallDriver(
devExt->NLExtHeader.AttachedToDeviceObject,
Irp);

if (Status == STATUS_PENDING)
KeWaitForSingleObject(
&WriteEvent,
Executive,
KernelMode,
FALSE,
NULL);

localStatus = Irp->IoStatus.Status;
DbgPrint(“Wrote to file: 0x%x\n”,localStatus);

//debuged the code and until here everthing is ok

IoReuseIrp(Irp,STATUS_SUCCESS);

irpSp = IoGetCurrentIrpStackLocation(Irp);

devExt = (PSFILTER_DEVICE_EXTENSION)DeviceObject->DeviceExtension;

irpSp->FileObject = DummyFileObject;

KeInitializeEvent(
&WriteEvent,
NotificationEvent,
FALSE);

IoCopyCurrentIrpStackLocationToNext(Irp);

IoSetCompletionRoutine(
Irp,
IoWriteRequestCompletion,
&Write~Event,
TRUE,
TRUE,
TRUE);

//this is where it crashes with status_access_violation
//when calling IoCallDriver
Status = IoCallDriver(
devExt->NLExtHeader.AttachedToDeviceObject,
Irp);

if (Status == STATUS_PENDING)
KeWaitForSingleObject(
&WriteWorkItemEvent,
Executive,
KernelMode,
FALSE,
NULL);

IoCompleteRequest(Irp,IO_NO_INCREMENT);

ObDereferenceObject(DummyFileObject);