Writting file output during system shutdown

I have a mini-filter driver that’s been working great for several years now - no reported BSODs. The driver monitors the system for file and registry events, and writes certain events to a log file. We have a new requirement that the driver should work through a reboot process.

The problem I’m running into, I can’t seem to get the driver to write to the file on disk during system shutdown. I have a flush routine that calls the ZwXXX APIs and it works if the driver is stopped via ControlService(). But when the system is powered down or rebooted I get no file output. I’ve tried flushing the file from my DriverUnload and FilterUnload routines with no luck. I registered for the IRP_MJ_SHUTDOWN event and tried flushing there, but still no output. My guess is the IRP_MJ_SHUTDOWN event is happening after the file system has been shutdown. Is there another event I can trigger on? I’ve read some people talking about IRP_MJ_POWER. Honestly, I don’t even know if my shutdown handler is getting called. Is there a way I can know for sure my handler is getting called? I added KeBugCheck() to the shutdown handler but go no BSOD on shutdown.

I primarily program in user-mode, so anytime I’m down at the driver level it’s a humbling experience. So any help would be greatly appreciated. Thanks.

There are two APIs:
IoRegisterShutdownNotification
IoRegisterLastChanceShutdownNotification
and MSDN says, the first callback receives IRP_MJ_SHUTDOWN request before
system flushes the file systems.

Old Dmitry G’s NTFSD post
(http://www.osronline.com/showThread.cfm?link=154532) mentions
FltCreateFile/FltWriteFile works correctly.

Also, if your IRP_MJ_SHUTDOWN callback isn’t invoked at all, something went
definitely wrong.

Petr

Thanks for the reply. I decided to take a step back, instead of assuming the problem is how or when I’m trying to flush the file on shutdown, I first wanted to verify my shutdown code is getting called. As far as I can tell, neither DriverUnload nor FilterUnload are called during shutdown. I did have a handler for IoRegisterShutdownNotification but because of an assumption on my part my handler wasn’t getting registered.

I thought I read somewhere that filter driver will create a DEVICE_OBJECT for the driver and will populate appropriate field inside the DRIVER_OBJECT. But I don’t think that’s the case. Here’s a greatly simplified snippet of my code:

NTSTATUS DriverEntry(__in PDRIVER_OBJECT pDriverObject, __in PUNICODE_STRING puszRegistryPath)
{
try
{
pDriverObject->DriverUnload = DriverUnload;
pDriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = DispatchShutdown;

// … initialize filter driver here with calls to FltRegisterFilter, FltStartFiltering, etc.
if(pDriverObject->DeviceObject)
IoRegisterShutdownNotification(pDriverObject->DeviceObject);
}
finally
{
}

return STATUS_SUCCESS;
}

Apparently DeviceObject is NULL, so it never calls IoRegisterShutdownNotification. If I manually call IoCreateDevice and then pass that into IoRegisterShutdownNotification then my driver DOES receive the IRP_MJ_SHUTDOWN message and I CAN flush the file contents from there using the FltXXX APIs.

You have some really broken assumptions. The DriverObject argument to
DriverEntry will never have a DeviceObject, the sequence is that either
DriverEntry creates a device object or AddDevice does. More importantly you
should never reference the DeviceObject field of DriverObject since you
don’t have access to control the list of DeviceObjects! Step back and
check all the basics before you continue messing in the file system space.

Don Burn
Windows Filesystem and Driver Consulting
Website: http://www.windrvr.com
Blog: http://msmvps.com/blogs/WinDrvr

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of
xxxxx@gmail.com
Sent: Friday, July 19, 2013 5:18 PM
To: Windows File Systems Devs Interest List
Subject: RE:[ntfsd] Writting file output during system shutdown

Thanks for the reply. I decided to take a step back, instead of assuming
the problem is how or when I’m trying to flush the file on shutdown, I first
wanted to verify my shutdown code is getting called. As far as I can tell,
neither DriverUnload nor FilterUnload are called during shutdown. I did
have a handler for IoRegisterShutdownNotification but because of an
assumption on my part my handler wasn’t getting registered.

I thought I read somewhere that filter driver will create a DEVICE_OBJECT
for the driver and will populate appropriate field inside the DRIVER_OBJECT.
But I don’t think that’s the case. Here’s a greatly simplified snippet of
my code:

NTSTATUS DriverEntry(__in PDRIVER_OBJECT pDriverObject, __in PUNICODE_STRING
puszRegistryPath) {
try
{
pDriverObject->DriverUnload = DriverUnload;
pDriverObject->MajorFunction[IRP_MJ_SHUTDOWN] =
DispatchShutdown;

// … initialize filter driver here with calls to
FltRegisterFilter, FltStartFiltering, etc.
if(pDriverObject->DeviceObject)

IoRegisterShutdownNotification(pDriverObject->DeviceObject);
}
finally
{
}

return STATUS_SUCCESS;
}

Apparently DeviceObject is NULL, so it never calls
IoRegisterShutdownNotification. If I manually call IoCreateDevice and then
pass that into IoRegisterShutdownNotification then my driver DOES receive
the IRP_MJ_SHUTDOWN message and I CAN flush the file contents from there
using the FltXXX APIs.


NTFSD is sponsored by OSR

OSR is hiring!! Info at http://www.osr.com/careers

For our schedule of debugging and file system 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