write IRPs to boot disk fails upon shutdown

Upon receiving a IRP_MJ_SHUTDOWN (from a higher driver), my upper disk class filter driver holds IRP_MJ_SHUTDOWN and sends some write irps downwards to the boot disk device. Once those write irps gets completed, I send the queued IRP_MJ_SHUTDOWN irp downward to the disk device.

But I see that all of my write irps fail returning STATUS_ACCESS_DENIED. Looks like somehow (may be bypassing my filter driver) the underlying device was locked by higher drivers (filesystem?) to prevent any more writes to it. Or if my filter driver is not being bypassed then what Irp that I need to capture to get the infomartion which locks the filesystem (assuming I’m on the right track)?

Can anyone help in identifying what’s wrong I’m doing here? Or suggest any other approach of writing to the disk after receiving the IRP_MJ_SHUTDOWN. Thanks.

What is the IRQL then?

I used to do it like this
OnShutdown(…)
{
If (irql < DISPATCH)
{
Write something to disk;
}
Pass shutdown to lower drivers;
}

It works.

Regards
Haibo

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of
xxxxx@yahoo.com
Sent: Wednesday, April 15, 2009 6:31 AM
To: Windows System Software Devs Interest List
Subject: [ntdev] write IRPs to boot disk fails upon shutdown

Upon receiving a IRP_MJ_SHUTDOWN (from a higher driver), my upper disk class
filter driver holds IRP_MJ_SHUTDOWN and sends some write irps downwards to
the boot disk device. Once those write irps gets completed, I send the
queued IRP_MJ_SHUTDOWN irp downward to the disk device.

But I see that all of my write irps fail returning STATUS_ACCESS_DENIED.
Looks like somehow (may be bypassing my filter driver) the underlying device
was locked by higher drivers (filesystem?) to prevent any more writes to it.
Or if my filter driver is not being bypassed then what Irp that I need to
capture to get the infomartion which locks the filesystem (assuming I’m on
the right track)?

Can anyone help in identifying what’s wrong I’m doing here? Or suggest any
other approach of writing to the disk after receiving the IRP_MJ_SHUTDOWN.
Thanks.


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

I’m doing this:

OnShutdown (…) {

  • queue the shutdown irp;
  • IoMarkingPending (irp);
  • schedule a Worker to process the irp;
  • return STATUS_PENDING
    }

Worker (…) {

  • send some write irps to disk;
  • set an io completion routine for the queued shutdown irp
  • pass the queued shutdown irp down to lower drivers;
  • call IoCompleteRequest for the shutdown irp in the io completion routine;
    }

Is your c.r. for the shutdown irp returning status more processing required? That must be returned if you are explicitly completing the request in the c.r.

d

Sent from my phone with no t9, all spilling mistakes are not intentional.

-----Original Message-----
From: xxxxx@yahoo.com
Sent: Tuesday, April 14, 2009 11:27 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] write IRPs to boot disk fails upon shutdown

I’m doing this:

OnShutdown (…) {
- queue the shutdown irp;
- IoMarkingPending (irp);
- schedule a Worker to process the irp;
- return STATUS_PENDING
}

Worker (…) {
- send some write irps to disk;
- set an io completion routine for the queued shutdown irp
- pass the queued shutdown irp down to lower drivers;
- call IoCompleteRequest for the shutdown irp in the io completion routine;
}


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

Yes, my completion routine is returning STATUS_MORE_PROCESSING_REQUIRED. But the problem I’m facing is with the write Irps that I send downwards to lower drivers before I pass down shutdown irp.

xxxxx@yahoo.com wrote:

Yes, my completion routine is returning STATUS_MORE_PROCESSING_REQUIRED. But the problem I’m facing is with the write Irps that I send downwards to lower drivers before I pass down shutdown irp.

Question(s): Do you have previous writes, prior to receiving the
shutdown, to disk which are successful? If not, what OS are you running on?

Pete


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


Kernel Drivers
Windows File System and Device Driver Consulting
www.KernelDrivers.com
866.263.9295

What driver(s) are the writes you’re sending going to? Are you sitting above a file system, network device, scsi/fibre adapter, etc…?

-p

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@yahoo.com
Sent: Wednesday, April 15, 2009 8:33 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] write IRPs to boot disk fails upon shutdown

Yes, my completion routine is returning STATUS_MORE_PROCESSING_REQUIRED. But the problem I’m facing is with the write Irps that I send downwards to lower drivers before I pass down shutdown irp.


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

@ Peter Scott: Yes I do have writes going to the disk prior to the shutdown and they complete successfully. OS is Vista SP1.

@Peter Wieland: My driver is upper disk class filter driver and the writes that it is sending are going to the lower driver which is the one attached by driver verifier above partmgr. Here is the output from !devobj:

kd> !devobj 0x87bff320 << This is my filter device object
Device object (87bff320) is for:
\Driver\myfltr DriverObject 86bfcb10
Current Irp 00000000 RefCount 0 Type 00000007 Flags 00000010
Vpb 86bff070 DevExt 87bff3d8 DevObjExt 87bff618 Dope 87bff2a0
ExtensionFlags (0xc0000800) DOE_BOTTOM_OF_FDO_STACK, DOE_DESIGNATED_FDO
Unknown flags 0x00000800
AttachedDevice (Upper) 877fbee0 \DRIVER\VERIFIER_FILTER
AttachedTo (Lower) 87bff678 \DRIVER\VERIFIER_FILTER
Device queue is not busy.
0: kd> !devobj 87bff678
Device object (87bff678) is for:
\DRIVER\VERIFIER_FILTER DriverObject 86bff108
Current Irp 00000000 RefCount 0 Type 00000007 Flags 00000010
DevExt 87bff730 DevObjExt 87bff758
ExtensionFlags (0xc0000800) DOE_BOTTOM_OF_FDO_STACK, DOE_DESIGNATED_FDO
Unknown flags 0x00000800
AttachedDevice (Upper) 87bff320 \Driver\myfltr
AttachedTo (Lower) 87bff7b8 \Driver\partmgr
Device queue is not busy.

Drat - I was hoping this was above a file system or a ramdisk or something.

Does the behavior change if you disable the driver verifier?

-p

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@yahoo.com
Sent: Wednesday, April 15, 2009 12:00 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] write IRPs to boot disk fails upon shutdown

@ Peter Scott: Yes I do have writes going to the disk prior to the shutdown and they complete successfully. OS is Vista SP1.

@Peter Wieland: My driver is upper disk class filter driver and the writes that it is sending are going to the lower driver which is the one attached by driver verifier above partmgr. Here is the output from !devobj:

kd> !devobj 0x87bff320 << This is my filter device object
Device object (87bff320) is for:
\Driver\myfltr DriverObject 86bfcb10
Current Irp 00000000 RefCount 0 Type 00000007 Flags 00000010
Vpb 86bff070 DevExt 87bff3d8 DevObjExt 87bff618 Dope 87bff2a0
ExtensionFlags (0xc0000800) DOE_BOTTOM_OF_FDO_STACK, DOE_DESIGNATED_FDO
Unknown flags 0x00000800
AttachedDevice (Upper) 877fbee0 \DRIVER\VERIFIER_FILTER
AttachedTo (Lower) 87bff678 \DRIVER\VERIFIER_FILTER
Device queue is not busy.
0: kd> !devobj 87bff678
Device object (87bff678) is for:
\DRIVER\VERIFIER_FILTER DriverObject 86bff108
Current Irp 00000000 RefCount 0 Type 00000007 Flags 00000010
DevExt 87bff730 DevObjExt 87bff758
ExtensionFlags (0xc0000800) DOE_BOTTOM_OF_FDO_STACK, DOE_DESIGNATED_FDO
Unknown flags 0x00000800
AttachedDevice (Upper) 87bff320 \Driver\myfltr
AttachedTo (Lower) 87bff7b8 \Driver\partmgr
Device queue is not busy.


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

xxxxx@yahoo.com wrote:

@ Peter Scott: Yes I do have writes going to the disk prior to the shutdown and they complete successfully. OS is Vista SP1.

Are you sending the write requests to the driver below you or are you
sending them to the top of the stack?

Pete

@Peter Wieland: My driver is upper disk class filter driver and the writes that it is sending are going to the lower driver which is the one attached by driver verifier above partmgr. Here is the output from !devobj:

kd> !devobj 0x87bff320 << This is my filter device object
Device object (87bff320) is for:
\Driver\myfltr DriverObject 86bfcb10
Current Irp 00000000 RefCount 0 Type 00000007 Flags 00000010
Vpb 86bff070 DevExt 87bff3d8 DevObjExt 87bff618 Dope 87bff2a0
ExtensionFlags (0xc0000800) DOE_BOTTOM_OF_FDO_STACK, DOE_DESIGNATED_FDO
Unknown flags 0x00000800
AttachedDevice (Upper) 877fbee0 \DRIVER\VERIFIER_FILTER
AttachedTo (Lower) 87bff678 \DRIVER\VERIFIER_FILTER
Device queue is not busy.
0: kd> !devobj 87bff678
Device object (87bff678) is for:
\DRIVER\VERIFIER_FILTER DriverObject 86bff108
Current Irp 00000000 RefCount 0 Type 00000007 Flags 00000010
DevExt 87bff730 DevObjExt 87bff758
ExtensionFlags (0xc0000800) DOE_BOTTOM_OF_FDO_STACK, DOE_DESIGNATED_FDO
Unknown flags 0x00000800
AttachedDevice (Upper) 87bff320 \Driver\myfltr
AttachedTo (Lower) 87bff7b8 \Driver\partmgr
Device queue is not busy.


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


Kernel Drivers
Windows File System and Device Driver Consulting
www.KernelDrivers.com
866.263.9295

I’m sending them to the driver below my filter driver (deviceExtension->TargetDevcieObject).

@ Peter Wieland: No the behavior does not change if I disable the driver verifier.

> I was hoping this was above a file system or a ramdisk or something.

BTW, just for my information what could have been wrong if this was the case? THanks.

Dunno - but it’s where I would have started looking :slight_smile:

-p

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@yahoo.com
Sent: Wednesday, April 15, 2009 4:46 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] write IRPs to boot disk fails upon shutdown

@ Peter Wieland: No the behavior does not change if I disable the driver verifier.

> I was hoping this was above a file system or a ramdisk or something.

BTW, just for my information what could have been wrong if this was the case? THanks.


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

Try send the writes in shutdown thread, then return STATUS_SUCCESS from
shutdown thread.

Regards
Haibo

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of
xxxxx@yahoo.com
Sent: Wednesday, April 15, 2009 2:24 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] write IRPs to boot disk fails upon shutdown

I’m doing this:

OnShutdown (…) {

  • queue the shutdown irp;
  • IoMarkingPending (irp);
  • schedule a Worker to process the irp;
  • return STATUS_PENDING
    }

Worker (…) {

  • send some write irps to disk;
  • set an io completion routine for the queued shutdown irp
  • pass the queued shutdown irp down to lower drivers;
  • call IoCompleteRequest for the shutdown irp in the io completion routine;
    }

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

>> Try send the writes in shutdown thread, then return STATUS_SUCCESS from shutdown thread.

Did not work :frowning:

Hello. I want to implement same functionality. Have you solved this problem ?

Unfortunately not yet :frowning: I will post it on the list whenever I have an update.

I wrote a simplified version of the same code in diskperf to reproduce the problem. In total I receive 3 IRP_MJ_SHUTDOWN irps. Reads sent after receiving these shutdown irps completed successfully while first 2 writes failed with STATUS_ACCESS_DENIED and 3rd write never came back keeping the thread wait in MyFltrSendIrp (). Following is the code. Can anybody point out what is missing here? Thanks.

PIRP MyFltrBuildIrp (IN PDEVICE_OBJECT DeviceObject,

IN UCHAR ReqCode,

IN ULONG LBA,

IN ULONG Count,

PUCHAR Buffer)

{

PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;

PIRP irp;

PIO_STACK_LOCATION stack;

LARGE_INTEGER startingOffset;

ULONG numOfBytes;

startingOffset.QuadPart = (LONGLONG)LBA * 512;

numOfBytes = Count * 512;

irp = IoAllocateIrp (DeviceObject->StackSize, FALSE);

if (!irp) {

ASSERT (0);

return (NULL);

}

IoSetNextIrpStackLocation (irp);

stack = IoGetCurrentIrpStackLocation (irp);

stack->MajorFunction = ReqCode;

switch (ReqCode) {

case IRP_MJ_WRITE:

stack->Parameters.Write.Length = numOfBytes;

stack->Parameters.Write.ByteOffset = startingOffset;

break;

case IRP_MJ_READ:

stack->Parameters.Read.Length = numOfBytes;

stack->Parameters.Read.ByteOffset = startingOffset;

break;

default:

ASSERT (0);

break;

}

IoCopyCurrentIrpStackLocationToNext (irp);

irp->IoStatus.Information = 0;

ASSERT (deviceExtension->TargetDeviceObject->Flags & DO_DIRECT_IO);

irp->MdlAddress = IoAllocateMdl (Buffer,

numOfBytes,

FALSE,

FALSE,

NULL);

if (!irp->MdlAddress) {

ASSERT (0);

IoFreeIrp (irp);

return (NULL);

}

MmBuildMdlForNonPagedPool (irp->MdlAddress);

return (irp);

}

VOID MyFltrSendIrp (IN PDEVICE_OBJECT DeviceObject,

IN UCHAR ReqCode,

IN ULONG LBA,

IN ULONG Count,

IN PUCHAR Buffer)

{

PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;

PIRP irp;

KEVENT event;

NTSTATUS status;

irp = MyFltrBuildIrp (DeviceObject, ReqCode, LBA, Count, Buffer);

if (!irp) {

ASSERT (0);

return;

}

KeInitializeEvent (&event, NotificationEvent, FALSE);

IoSetCompletionRoutine (irp,

MyFltrIrpCompletion,

&event,

TRUE,

TRUE,

TRUE);

status = IoCallDriver (deviceExtension->TargetDeviceObject, irp);

if (status == STATUS_PENDING) {

KeWaitForSingleObject (&event, Executive, KernelMode, FALSE, NULL);

status = irp->IoStatus.Status;

if (!NT_SUCCESS (status)) {

switch (ReqCode) {

case IRP_MJ_WRITE:

DbgPrintEx (DPFLTR_IHVDRIVER_ID,

DPFLTR_ERROR_LEVEL,

“MyFltrSendIrp: WRITE FAILED with Status [0x%x] !!!.”

“Information = 0x%x\n”,

status,

irp->IoStatus.Information);

break;

case IRP_MJ_READ:

DbgPrintEx (DPFLTR_IHVDRIVER_ID,

DPFLTR_ERROR_LEVEL,

“MyFltrSendIrp: READ FAILED with Status [0x%x] !!!.”

“Information = 0x%x\n”,

status,

irp->IoStatus.Information);

break;

default:

ASSERT (0);

}

}

}

if (irp->MdlAddress) {

PMDL mdl, nextMdl;

for (mdl = irp->MdlAddress; mdl != NULL; mdl = nextMdl) {

nextMdl = mdl->Next;

IoFreeMdl (mdl);

}

irp->MdlAddress = NULL;

}

IoFreeIrp (irp);

}

VOID MyFltrTestSyncReadWrite (IN PDEVICE_OBJECT DeviceObject)

{

ULONG lba, cnt;

UCHAR buffer[512];

lba = 0x1600000;

cnt = 0x1;

RtlZeroMemory (buffer, 512);

// send a read

MyFltrSendIrp (DeviceObject, IRP_MJ_READ, lba, cnt, buffer);

// send a write

MyFltrSendIrp (DeviceObject, IRP_MJ_WRITE, lba, cnt, buffer);

}

NTSTATUS

MyFltrShutdownFlush(

IN PDEVICE_OBJECT DeviceObject,

IN PIRP Irp

)

/*++

Routine Description:

This routine is called for a shutdown and flush IRPs. These are sent by the

system before it actually shuts down or when the file system does a flush.

Arguments:

DriverObject - Pointer to device object to being shutdown by system.

Irp - IRP involved.

Return Value:

NT Status

–*/

{

PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;

PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation (Irp);

DebugPrint((2, “MyFltrShutdownFlush: DeviceObject %X Irp %X\n”,

DeviceObject, Irp));

switch (stack->MajorFunction) {

case IRP_MJ_FLUSH_BUFFERS:

break;

case IRP_MJ_SHUTDOWN:

DbgPrintEx (DPFLTR_IHVDRIVER_ID,

DPFLTR_INFO_LEVEL,

MyFltrShutdownFlush: DeviceObject [0x%X], PendingIrpCnt [0x%x]\n",

DeviceObject,

InterlockedCompareExchange (&deviceExtension->PendingIrpCnt, 0, 0));

ASSERT (KeGetCurrentIrql () == PASSIVE_LEVEL);

MyFltrTestSyncReadWrite (DeviceObject);

break;

default:

ASSERT (0);

break;

}

IoSkipCurrentIrpStackLocation(Irp);

return IoCallDriver(deviceExtension->TargetDeviceObject, Irp);

} // end MyFltrShutdownFlush()

Why are you setting the next stack location and then copying it to the next? So that you have a valid stack location in your completion routine? This is a sync operation so I would think the c.r. just sets the event (via context) and that is it. Are you sure there are enough remaining stack locations to burn one like this? It is odd that you are passing your device object to MyFltrBuildIrp and not TargetDeviceObject

d

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@yahoo.com
Sent: Monday, April 27, 2009 2:18 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] write IRPs to boot disk fails upon shutdown

I wrote a simplified version of the same code in diskperf to reproduce the problem. In total I receive 3 IRP_MJ_SHUTDOWN irps. Reads sent after receiving these shutdown irps completed successfully while first 2 writes failed with STATUS_ACCESS_DENIED and 3rd write never came back keeping the thread wait in MyFltrSendIrp (). Following is the code. Can anybody point out what is missing here? Thanks.

PIRP MyFltrBuildIrp (IN PDEVICE_OBJECT DeviceObject,

IN UCHAR ReqCode,

IN ULONG LBA,

IN ULONG Count,

PUCHAR Buffer)

{

PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;

PIRP irp;

PIO_STACK_LOCATION stack;

LARGE_INTEGER startingOffset;

ULONG numOfBytes;

startingOffset.QuadPart = (LONGLONG)LBA * 512;

numOfBytes = Count * 512;

irp = IoAllocateIrp (DeviceObject->StackSize, FALSE);

if (!irp) {

ASSERT (0);

return (NULL);

}

IoSetNextIrpStackLocation (irp);

stack = IoGetCurrentIrpStackLocation (irp);

stack->MajorFunction = ReqCode;

switch (ReqCode) {

case IRP_MJ_WRITE:

stack->Parameters.Write.Length = numOfBytes;

stack->Parameters.Write.ByteOffset = startingOffset;

break;

case IRP_MJ_READ:

stack->Parameters.Read.Length = numOfBytes;

stack->Parameters.Read.ByteOffset = startingOffset;

break;

default:

ASSERT (0);

break;

}

IoCopyCurrentIrpStackLocationToNext (irp);

irp->IoStatus.Information = 0;

ASSERT (deviceExtension->TargetDeviceObject->Flags & DO_DIRECT_IO);

irp->MdlAddress = IoAllocateMdl (Buffer,

numOfBytes,

FALSE,

FALSE,

NULL);

if (!irp->MdlAddress) {

ASSERT (0);

IoFreeIrp (irp);

return (NULL);

}

MmBuildMdlForNonPagedPool (irp->MdlAddress);

return (irp);

}

VOID MyFltrSendIrp (IN PDEVICE_OBJECT DeviceObject,

IN UCHAR ReqCode,

IN ULONG LBA,

IN ULONG Count,

IN PUCHAR Buffer)

{

PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;

PIRP irp;

KEVENT event;

NTSTATUS status;

irp = MyFltrBuildIrp (DeviceObject, ReqCode, LBA, Count, Buffer);

if (!irp) {

ASSERT (0);

return;

}

KeInitializeEvent (&event, NotificationEvent, FALSE);

IoSetCompletionRoutine (irp,

MyFltrIrpCompletion,

&event,

TRUE,

TRUE,

TRUE);

status = IoCallDriver (deviceExtension->TargetDeviceObject, irp);

if (status == STATUS_PENDING) {

KeWaitForSingleObject (&event, Executive, KernelMode, FALSE, NULL);

status = irp->IoStatus.Status;

if (!NT_SUCCESS (status)) {

switch (ReqCode) {

case IRP_MJ_WRITE:

DbgPrintEx (DPFLTR_IHVDRIVER_ID,

DPFLTR_ERROR_LEVEL,

“MyFltrSendIrp: WRITE FAILED with Status [0x%x] !!!.”

“Information = 0x%x\n”,

status,

irp->IoStatus.Information);

break;

case IRP_MJ_READ:

DbgPrintEx (DPFLTR_IHVDRIVER_ID,

DPFLTR_ERROR_LEVEL,

“MyFltrSendIrp: READ FAILED with Status [0x%x] !!!.”

“Information = 0x%x\n”,

status,

irp->IoStatus.Information);

break;

default:

ASSERT (0);

}

}

}

if (irp->MdlAddress) {

PMDL mdl, nextMdl;

for (mdl = irp->MdlAddress; mdl != NULL; mdl = nextMdl) {

nextMdl = mdl->Next;

IoFreeMdl (mdl);

}

irp->MdlAddress = NULL;

}

IoFreeIrp (irp);

}

VOID MyFltrTestSyncReadWrite (IN PDEVICE_OBJECT DeviceObject)

{

ULONG lba, cnt;

UCHAR buffer[512];

lba = 0x1600000;

cnt = 0x1;

RtlZeroMemory (buffer, 512);

// send a read

MyFltrSendIrp (DeviceObject, IRP_MJ_READ, lba, cnt, buffer);

// send a write

MyFltrSendIrp (DeviceObject, IRP_MJ_WRITE, lba, cnt, buffer);

}

NTSTATUS

MyFltrShutdownFlush(

IN PDEVICE_OBJECT DeviceObject,

IN PIRP Irp

)

/*++

Routine Description:

This routine is called for a shutdown and flush IRPs. These are sent by the

system before it actually shuts down or when the file system does a flush.

Arguments:

DriverObject - Pointer to device object to being shutdown by system.

Irp - IRP involved.

Return Value:

NT Status

–*/

{

PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;

PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation (Irp);

DebugPrint((2, “MyFltrShutdownFlush: DeviceObject %X Irp %X\n”,

DeviceObject, Irp));

switch (stack->MajorFunction) {

case IRP_MJ_FLUSH_BUFFERS:

break;

case IRP_MJ_SHUTDOWN:

DbgPrintEx (DPFLTR_IHVDRIVER_ID,

DPFLTR_INFO_LEVEL,

MyFltrShutdownFlush: DeviceObject [0x%X], PendingIrpCnt [0x%x]\n",

DeviceObject,

InterlockedCompareExchange (&deviceExtension->PendingIrpCnt, 0, 0));

ASSERT (KeGetCurrentIrql () == PASSIVE_LEVEL);

MyFltrTestSyncReadWrite (DeviceObject);

break;

default:

ASSERT (0);

break;

}

IoSkipCurrentIrpStackLocation(Irp);

return IoCallDriver(deviceExtension->TargetDeviceObject, Irp);

} // end MyFltrShutdownFlush()


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

>>Why are you setting the next stack location and then copying it to the next? So that you have a valid stack location in your completion routine?

Yes that is the reason. Otherwise the stack locations gets zeroed by the lower drivers.

> This is a sync operation so I would think the c.r. just sets the event (via context) and that is it. Are you sure there are enough remaining stack locations to burn one like this? It is odd that you are passing your device object to MyFltrBuildIrp and not TargetDeviceObject

My assumption is: DeviceObject->StackSize == (TargetDeviceObject->StackSize + 1); where TargetDeviceObject is the next device object in the stack. Is it not correct?