hi pros. I am new to Driver development. I somehow managed to copy paste, understand and modify the code. But its giving me error. it was working fine before.
Notification.c
#include “FsFilter.h”
//////////////////////////////////////////////////////////////////////////
// Prototypes
NTSTATUS FsFilterAttachToFileSystemDevice(
__in PDEVICE_OBJECT DeviceObject
);
VOID FsFilterDetachFromFileSystemDevice(
__in PDEVICE_OBJECT DeviceObject
);
NTSTATUS FsFilterEnumerateFileSystemVolumes(
__in PDEVICE_OBJECT DeviceObject
);
///////////////////////////////////////////////////////////////////////////////////////////////////
// This routine is invoked whenever a file system has either registered or
// unregistered itself as an active file system.
VOID FsFilterNotificationCallback(
__in PDEVICE_OBJECT DeviceObject,
__in BOOLEAN FsActive
)
{
//
// Handle attaching/detaching from the given file system.
//
if (FsActive)
{
FsFilterAttachToFileSystemDevice(DeviceObject);
}
else
{
FsFilterDetachFromFileSystemDevice(DeviceObject);
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// This will attach to the given file system device object
NTSTATUS FsFilterAttachToFileSystemDevice(
__in PDEVICE_OBJECT DeviceObject
)
{
NTSTATUS status = STATUS_SUCCESS;
PDEVICE_OBJECT filterDeviceObject = NULL;
if (!FsFilterIsAttachedToDevice(DeviceObject))
{
status = FsFilterAttachToDevice(DeviceObject, &filterDeviceObject);
if (!NT_SUCCESS(status))
{
return status;
}
//
// Enumerate all the mounted devices that currently exist for this file system and attach to them.
//
status = FsFilterEnumerateFileSystemVolumes(DeviceObject);
if (!NT_SUCCESS(status))
{
FsFilterDetachFromDevice(filterDeviceObject);
return status;
}
}
return STATUS_SUCCESS;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// This will detach us from the chain
VOID FsFilterDetachFromFileSystemDevice(
__in PDEVICE_OBJECT DeviceObject
)
{
PDEVICE_OBJECT device = NULL;
for (device = DeviceObject->AttachedDevice; NULL != device; device = device->AttachedDevice)
{
if (FsFilterIsMyDeviceObject(device))
{
//
// Detach us from the object just below us. Cleanup and delete the object.
//
FsFilterDetachFromDevice(device);
break;
}
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// Enumerate all the mounted devices that currently exist for the given file
// system and attach to them
NTSTATUS FsFilterEnumerateFileSystemVolumes(
__in PDEVICE_OBJECT DeviceObject
)
{
NTSTATUS status = STATUS_SUCCESS;
ULONG numDevices = 0;
ULONG i = 0;
PDEVICE_OBJECT devList[DEVOBJ_LIST_SIZE];
//
// Now get the list of devices.
//
__try
{
status = IoEnumerateDeviceObjectList(
DeviceObject->DriverObject,
devList,
sizeof(devList),
&numDevices);
if (!NT_SUCCESS(status))
{
return status;
}
numDevices = min(numDevices, RTL_NUMBER_OF(devList));
//
// Walk the given list of devices and attach to them if we should.
//
for (i = 0; i < numDevices; ++i)
{
//
// Do not attach if:
// - This is the control device object (the one passed in)
// - The device type does not match
// - We are already attached to it.
//
if (devList[i] != DeviceObject &&
devList[i]->DeviceType == DeviceObject->DeviceType &&
!FsFilterIsAttachedToDevice(devList[i]))
{
status = FsFilterAttachToDevice(devList[i], NULL);
}
ObDereferenceObject(devList[i]);
return STATUS_SUCCESS;
}
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
DbgPrint(“error %x”,GetExceptionCode());
return status;
}
}
************************ AttachDetach.c
#include “FsFilter.h”
///////////////////////////////////////////////////////////////////////////////////////////////////
// This will attach to a DeviceObject that represents a mounted volume
NTSTATUS FsFilterAttachToDevice(
__in PDEVICE_OBJECT DeviceObject,
__out_opt PDEVICE_OBJECT* pFilterDeviceObject
)
{
NTSTATUS status = STATUS_SUCCESS;
PDEVICE_OBJECT filterDeviceObject = NULL;
PFSFILTER_DEVICE_EXTENSION pDevExt = NULL;
ULONG i = 0;
__try
{
ASSERT(!FsFilterIsAttachedToDevice(DeviceObject));
//
// Create a new device object we can attach with.
//
status = IoCreateDevice(
g_fsFilterDriverObject,
sizeof(FSFILTER_DEVICE_EXTENSION),
NULL,
DeviceObject->DeviceType,
0,
FALSE,
&filterDeviceObject);
if (!NT_SUCCESS(status))
{
return status;
}
pDevExt = (PFSFILTER_DEVICE_EXTENSION)filterDeviceObject->DeviceExtension;
//
// Propagate flags from Device Object we are trying to attach to.
//
if (FlagOn(DeviceObject->Flags, DO_BUFFERED_IO))
{
SetFlag(filterDeviceObject->Flags, DO_BUFFERED_IO);
}
if (FlagOn(DeviceObject->Flags, DO_DIRECT_IO))
{
SetFlag(filterDeviceObject->Flags, DO_DIRECT_IO);
}
if (FlagOn(DeviceObject->Characteristics, FILE_DEVICE_SECURE_OPEN))
{
SetFlag(filterDeviceObject->Characteristics, FILE_DEVICE_SECURE_OPEN);
}
//
// Do the attachment.
//
// It is possible for this attachment request to fail because this device
// object has not finished initializing. This can occur if this filter
// loaded just as this volume was being mounted.
//
for (i = 0; i < 8; ++i)
{
LARGE_INTEGER interval;
status = IoAttachDeviceToDeviceStackSafe(
filterDeviceObject,
DeviceObject,
&pDevExt->AttachedToDeviceObject);
if (NT_SUCCESS(status))
{
break;
}
//
// Delay, giving the device object a chance to finish its
// initialization so we can try again.
//
interval.QuadPart = (500 * DELAY_ONE_MILLISECOND);
KeDelayExecutionThread(KernelMode, FALSE, &interval);
}
if (!NT_SUCCESS(status))
{
//
// Clean up.
//
IoDeleteDevice(filterDeviceObject);
filterDeviceObject = NULL;
}
else
{
//
// Mark we are done initializing.
//
ClearFlag(filterDeviceObject->Flags, DO_DEVICE_INITIALIZING);
if (NULL != pFilterDeviceObject)
{
*pFilterDeviceObject = filterDeviceObject;
}
}
}
__except (EXCEPTION_EXECUTE_HANDLER){
DbgPrint(“%x”,GetExceptionCode());
}
return status;
}
void FsFilterDetachFromDevice(
__in PDEVICE_OBJECT DeviceObject
)
{
PFSFILTER_DEVICE_EXTENSION pDevExt = (PFSFILTER_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
IoDetachDevice(pDevExt->AttachedToDeviceObject);
IoDeleteDevice(DeviceObject);
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// This determines whether we are attached to the given device
BOOLEAN FsFilterIsAttachedToDevice(
__in PDEVICE_OBJECT DeviceObject
)
{
PDEVICE_OBJECT nextDevObj = NULL;
PDEVICE_OBJECT currentDevObj = IoGetAttachedDeviceReference(DeviceObject);
//
// Scan down the list to find our device object.
//
do
{
if (FsFilterIsMyDeviceObject(currentDevObj))
{
ObDereferenceObject(currentDevObj);
return TRUE;
}
//
// Get the next attached object.
//
nextDevObj = IoGetLowerDeviceObject(currentDevObj);
//
// Dereference our current device object, before moving to the next one.
//
ObDereferenceObject(currentDevObj);
currentDevObj = nextDevObj;
} while (NULL != currentDevObj);
return FALSE;
}
*********************** FastIo.c
#include “FsFilter.h”
/////////////////////////////////////////////////////////////////////////////
// Fast-IO Handlers
BOOLEAN FsFilterFastIoCheckIfPossible(
__in PFILE_OBJECT FileObject,
__in PLARGE_INTEGER FileOffset,
__in ULONG Length,
__in BOOLEAN Wait,
__in ULONG LockKey,
__in BOOLEAN CheckForReadOperation,
__out PIO_STATUS_BLOCK IoStatus,
__in PDEVICE_OBJECT DeviceObject
)
{
//
// Pass through logic for this type of Fast I/O
//
__try
{
PDEVICE_OBJECT nextDeviceObject = ((PFSFILTER_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->AttachedToDeviceObject;
PFAST_IO_DISPATCH fastIoDispatch = nextDeviceObject->DriverObject->FastIoDispatch;
if (VALID_FAST_IO_DISPATCH_HANDLER(fastIoDispatch, FastIoCheckIfPossible))
{
return (fastIoDispatch->FastIoCheckIfPossible)(
FileObject,
FileOffset,
Length,
Wait,
LockKey,
CheckForReadOperation,
IoStatus,
nextDeviceObject);
}
}
__except(EXCEPTION_EXECUTE_HANDLER){
DbgPrint(“error %x”, GetExceptionCode());
}
return FALSE;
}
BOOLEAN FsFilterFastIoRead(
__in PFILE_OBJECT FileObject,
__in PLARGE_INTEGER FileOffset,
__in ULONG Length,
__in BOOLEAN Wait,
__in ULONG LockKey,
__out PVOID Buffer,
__out PIO_STATUS_BLOCK IoStatus,
__in PDEVICE_OBJECT DeviceObject
)
{
//
// Pass through logic for this type of Fast I/O
//
__try
{
PDEVICE_OBJECT nextDeviceObject = ((PFSFILTER_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->AttachedToDeviceObject;
PFAST_IO_DISPATCH fastIoDispatch = nextDeviceObject->DriverObject->FastIoDispatch;
if (VALID_FAST_IO_DISPATCH_HANDLER(fastIoDispatch, FastIoRead))
{
return (fastIoDispatch->FastIoRead)(
FileObject,
FileOffset,
Length,
Wait,
LockKey,
Buffer,
IoStatus,
nextDeviceObject);
}
}
__except (EXCEPTION_EXECUTE_HANDLER){ DbgPrint(“error %x”, GetExceptionCode()); }
return FALSE;
}
BOOLEAN FsFilterFastIoWrite(
__in PFILE_OBJECT FileObject,
__in PLARGE_INTEGER FileOffset,
__in ULONG Length,
__in BOOLEAN Wait,
__in ULONG LockKey,
__in PVOID Buffer,
__out PIO_STATUS_BLOCK IoStatus,
__in PDEVICE_OBJECT DeviceObject
)
{
//
// Pass through logic for this type of Fast I/O
//
__try
{
PDEVICE_OBJECT nextDeviceObject = ((PFSFILTER_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->AttachedToDeviceObject;
PFAST_IO_DISPATCH fastIoDispatch = nextDeviceObject->DriverObject->FastIoDispatch;
if (VALID_FAST_IO_DISPATCH_HANDLER(fastIoDispatch, FastIoWrite))
{
return (fastIoDispatch->FastIoWrite)(
FileObject,
FileOffset,
Length,
Wait,
LockKey,
Buffer,
IoStatus,
nextDeviceObject);
}
}
__except (EXCEPTION_EXECUTE_HANDLER){ DbgPrint(“error %x”, GetExceptionCode()); }
return FALSE;
}
BOOLEAN FsFilterFastIoQueryBasicInfo(
__in PFILE_OBJECT FileObject,
__in BOOLEAN Wait,
__out PFILE_BASIC_INFORMATION Buffer,
__out PIO_STATUS_BLOCK IoStatus,
__in PDEVICE_OBJECT DeviceObject
)
{
//
// Pass through logic for this type of Fast I/O
//
__try
{
PDEVICE_OBJECT nextDeviceObject = ((PFSFILTER_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->AttachedToDeviceObject;
PFAST_IO_DISPATCH fastIoDispatch = nextDeviceObject->DriverObject->FastIoDispatch;
if (VALID_FAST_IO_DISPATCH_HANDLER(fastIoDispatch, FastIoQueryBasicInfo))
{
return (fastIoDispatch->FastIoQueryBasicInfo)(
FileObject,
Wait,
Buffer,
IoStatus,
nextDeviceObject);
}
}
__except (EXCEPTION_EXECUTE_HANDLER){ DbgPrint(“error %x”, GetExceptionCode()); }
return FALSE;
}
BOOLEAN FsFilterFastIoQueryStandardInfo(
__in PFILE_OBJECT FileObject,
__in BOOLEAN Wait,
__out PFILE_STANDARD_INFORMATION Buffer,
__out PIO_STATUS_BLOCK IoStatus,
__in PDEVICE_OBJECT DeviceObject
)
{
//
// Pass through logic for this type of Fast I/O
//
__try
{
PDEVICE_OBJECT nextDeviceObject = ((PFSFILTER_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->AttachedToDeviceObject;
PFAST_IO_DISPATCH fastIoDispatch = nextDeviceObject->DriverObject->FastIoDispatch;
if (VALID_FAST_IO_DISPATCH_HANDLER(fastIoDispatch, FastIoQueryStandardInfo))
{
return (fastIoDispatch->FastIoQueryStandardInfo)(
FileObject,
Wait,
Buffer,
IoStatus,
nextDeviceObject);
}
}
__except (EXCEPTION_EXECUTE_HANDLER){ DbgPrint(“error %x”, GetExceptionCode()); }
return FALSE;
}
BOOLEAN FsFilterFastIoLock(
__in PFILE_OBJECT FileObject,
__in PLARGE_INTEGER FileOffset,
__in PLARGE_INTEGER Length,
__in PEPROCESS ProcessId,
__in ULONG Key,
__in BOOLEAN FailImmediately,
__in BOOLEAN ExclusiveLock,
__out PIO_STATUS_BLOCK IoStatus,
__in PDEVICE_OBJECT DeviceObject
)
{
//
// Pass through logic for this type of Fast I/O
//
__try
{
PDEVICE_OBJECT nextDeviceObject = ((PFSFILTER_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->AttachedToDeviceObject;
PFAST_IO_DISPATCH fastIoDispatch = nextDeviceObject->DriverObject->FastIoDispatch;
if (VALID_FAST_IO_DISPATCH_HANDLER(fastIoDispatch, FastIoLock))
{
return (fastIoDispatch->FastIoLock)(
FileObject,
FileOffset,
Length,
ProcessId,
Key,
FailImmediately,
ExclusiveLock,
IoStatus,
nextDeviceObject);
}
}
__except (EXCEPTION_EXECUTE_HANDLER){ DbgPrint(“error %x”, GetExceptionCode()); }
return FALSE;
}
BOOLEAN FsFilterFastIoUnlockSingle(
__in PFILE_OBJECT FileObject,
__in PLARGE_INTEGER FileOffset,
__in PLARGE_INTEGER Length,
__in PEPROCESS ProcessId,
__in ULONG Key,
__out PIO_STATUS_BLOCK IoStatus,
__in PDEVICE_OBJECT DeviceObject
)
{
//
// Pass through logic for this type of Fast I/O
//
__try
{
PDEVICE_OBJECT nextDeviceObject = ((PFSFILTER_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->AttachedToDeviceObject;
PFAST_IO_DISPATCH fastIoDispatch = nextDeviceObject->DriverObject->FastIoDispatch;
if (VALID_FAST_IO_DISPATCH_HANDLER(fastIoDispatch, FastIoUnlockSingle))
{
return (fastIoDispatch->FastIoUnlockSingle)(
FileObject,
FileOffset,
Length,
ProcessId,
Key,
IoStatus,
nextDeviceObject);
}
}
__except (EXCEPTION_EXECUTE_HANDLER){ DbgPrint(“error %x”, GetExceptionCode()); }
return FALSE;
}
BOOLEAN FsFilterFastIoUnlockAll(
__in PFILE_OBJECT FileObject,
__in PEPROCESS ProcessId,
__out PIO_STATUS_BLOCK IoStatus,
__in PDEVICE_OBJECT DeviceObject
)
{
//
// Pass through logic for this type of Fast I/O
//
__try
{
PDEVICE_OBJECT nextDeviceObject = ((PFSFILTER_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->AttachedToDeviceObject;
PFAST_IO_DISPATCH fastIoDispatch = nextDeviceObject->DriverObject->FastIoDispatch;
if (VALID_FAST_IO_DISPATCH_HANDLER(fastIoDispatch, FastIoUnlockAll))
{
return (fastIoDispatch->FastIoUnlockAll)(
FileObject,
ProcessId,
IoStatus,
nextDeviceObject);
}
}
__except (EXCEPTION_EXECUTE_HANDLER){ DbgPrint(“error %x”, GetExceptionCode()); }
return FALSE;
}
BOOLEAN FsFilterFastIoUnlockAllByKey(
__in PFILE_OBJECT FileObject,
__in PVOID ProcessId,
__in ULONG Key,
__out PIO_STATUS_BLOCK IoStatus,
__in PDEVICE_OBJECT DeviceObject
)
{
//
// Pass through logic for this type of Fast I/O
//
__try
{
PDEVICE_OBJECT nextDeviceObject = ((PFSFILTER_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->AttachedToDeviceObject;
PFAST_IO_DISPATCH fastIoDispatch = nextDeviceObject->DriverObject->FastIoDispatch;
if (VALID_FAST_IO_DISPATCH_HANDLER(fastIoDispatch, FastIoUnlockAllByKey))
{
return (fastIoDispatch->FastIoUnlockAllByKey)(
FileObject,
ProcessId,
Key,
IoStatus,
nextDeviceObject);
}
}
__except (EXCEPTION_EXECUTE_HANDLER){ DbgPrint(“error %x”, GetExceptionCode()); }
return FALSE;
}
BOOLEAN FsFilterFastIoDeviceControl(
__in PFILE_OBJECT FileObject,
__in BOOLEAN Wait,
__in_opt PVOID InputBuffer,
__in ULONG InputBufferLength,
__out_opt PVOID OutputBuffer,
__in ULONG OutputBufferLength,
__in ULONG IoControlCode,
__out PIO_STATUS_BLOCK IoStatus,
__in PDEVICE_OBJECT DeviceObject
)
{
//
// Pass through logic for this type of Fast I/O
//
__try
{
PDEVICE_OBJECT nextDeviceObject = ((PFSFILTER_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->AttachedToDeviceObject;
PFAST_IO_DISPATCH fastIoDispatch = nextDeviceObject->DriverObject->FastIoDispatch;
if (VALID_FAST_IO_DISPATCH_HANDLER(fastIoDispatch, FastIoDeviceControl))
{
return (fastIoDispatch->FastIoDeviceControl)(
FileObject,
Wait,
InputBuffer,
InputBufferLength,
OutputBuffer,
OutputBufferLength,
IoControlCode,
IoStatus,
nextDeviceObject);
}
}
__except (EXCEPTION_EXECUTE_HANDLER){ DbgPrint(“error %x”, GetExceptionCode()); }
return FALSE;
}
VOID FsFilterFastIoDetachDevice(
__in PDEVICE_OBJECT SourceDevice,
__in PDEVICE_OBJECT TargetDevice
)
{
//
// Detach from the file system’s volume device object.
//
IoDetachDevice(TargetDevice);
IoDeleteDevice(SourceDevice);
}
BOOLEAN FsFilterFastIoQueryNetworkOpenInfo(
__in PFILE_OBJECT FileObject,
__in BOOLEAN Wait,
__out PFILE_NETWORK_OPEN_INFORMATION Buffer,
__out PIO_STATUS_BLOCK IoStatus,
__in PDEVICE_OBJECT DeviceObject
)
{
//
// Pass through logic for this type of Fast I/O
//
__try
{
PDEVICE_OBJECT nextDeviceObject = ((PFSFILTER_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->AttachedToDeviceObject;
PFAST_IO_DISPATCH fastIoDispatch = nextDeviceObject->DriverObject->FastIoDispatch;
if (VALID_FAST_IO_DISPATCH_HANDLER(fastIoDispatch, FastIoQueryNetworkOpenInfo))
{
return (fastIoDispatch->FastIoQueryNetworkOpenInfo)(
FileObject,
Wait,
Buffer,
IoStatus,
nextDeviceObject);
}
}
__except (EXCEPTION_EXECUTE_HANDLER){ DbgPrint(“error %x”, GetExceptionCode()); }
return FALSE;
}
BOOLEAN FsFilterFastIoMdlRead(
__in PFILE_OBJECT FileObject,
__in PLARGE_INTEGER FileOffset,
__in ULONG Length,
__in ULONG LockKey,
__out PMDL* MdlChain,
__out PIO_STATUS_BLOCK IoStatus,
__in PDEVICE_OBJECT DeviceObject
)
{
//
// Pass through logic for this type of Fast I/O
//
__try
{
PDEVICE_OBJECT nextDeviceObject = ((PFSFILTER_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->AttachedToDeviceObject;
PFAST_IO_DISPATCH fastIoDispatch = nextDeviceObject->DriverObject->FastIoDispatch;
if (VALID_FAST_IO_DISPATCH_HANDLER(fastIoDispatch, MdlRead))
{
return (fastIoDispatch->MdlRead)(
FileObject,
FileOffset,
Length,
LockKey,
MdlChain,
IoStatus,
nextDeviceObject);
}
}
__except (EXCEPTION_EXECUTE_HANDLER){ DbgPrint(“error %x”, GetExceptionCode()); }
return FALSE;
}
BOOLEAN FsFilterFastIoMdlReadComplete(
__in PFILE_OBJECT FileObject,
__in PMDL MdlChain,
__in PDEVICE_OBJECT DeviceObject
)
{
//
// Pass through logic for this type of Fast I/O
//
__try
{
PDEVICE_OBJECT nextDeviceObject = ((PFSFILTER_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->AttachedToDeviceObject;
PFAST_IO_DISPATCH fastIoDispatch = nextDeviceObject->DriverObject->FastIoDispatch;
if (VALID_FAST_IO_DISPATCH_HANDLER(fastIoDispatch, MdlReadComplete))
{
return (fastIoDispatch->MdlReadComplete)(
FileObject,
MdlChain,
nextDeviceObject);
}
}
__except (EXCEPTION_EXECUTE_HANDLER){ DbgPrint(“error %x”, GetExceptionCode()); }
return FALSE;
}
BOOLEAN FsFilterFastIoPrepareMdlWrite(
__in PFILE_OBJECT FileObject,
__in PLARGE_INTEGER FileOffset,
__in ULONG Length,
__in ULONG LockKey,
__out PMDL* MdlChain,
__out PIO_STATUS_BLOCK IoStatus,
__in PDEVICE_OBJECT DeviceObject
)
{
//
// Pass through logic for this type of Fast I/O
//
__try
{
PDEVICE_OBJECT nextDeviceObject = ((PFSFILTER_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->AttachedToDeviceObject;
PFAST_IO_DISPATCH fastIoDispatch = nextDeviceObject->DriverObject->FastIoDispatch;
if (VALID_FAST_IO_DISPATCH_HANDLER(fastIoDispatch, PrepareMdlWrite))
{
return (fastIoDispatch->PrepareMdlWrite)(
FileObject,
FileOffset,
Length,
LockKey,
MdlChain,
IoStatus,
nextDeviceObject);
}
}
__except (EXCEPTION_EXECUTE_HANDLER){ DbgPrint(“error %x”, GetExceptionCode()); }
return FALSE;
}
BOOLEAN FsFilterFastIoMdlWriteComplete(
__in PFILE_OBJECT FileObject,
__in PLARGE_INTEGER FileOffset,
__in PMDL MdlChain,
__in PDEVICE_OBJECT DeviceObject
)
{
//
// Pass through logic for this type of Fast I/O
//
__try
{
PDEVICE_OBJECT nextDeviceObject = ((PFSFILTER_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->AttachedToDeviceObject;
PFAST_IO_DISPATCH fastIoDispatch = nextDeviceObject->DriverObject->FastIoDispatch;
if (VALID_FAST_IO_DISPATCH_HANDLER(fastIoDispatch, MdlWriteComplete))
{
return (fastIoDispatch->MdlWriteComplete)(
FileObject,
FileOffset,
MdlChain,
nextDeviceObject);
}
}
__except (EXCEPTION_EXECUTE_HANDLER){ DbgPrint(“error %x”, GetExceptionCode()); }
return FALSE;
}
BOOLEAN FsFilterFastIoReadCompressed(
__in PFILE_OBJECT FileObject,
__in PLARGE_INTEGER FileOffset,
__in ULONG Length,
__in ULONG LockKey,
__out PVOID Buffer,
__out PMDL* MdlChain,
__out PIO_STATUS_BLOCK IoStatus,
__out struct _COMPRESSED_DATA_INFO* CompressedDataInfo,
__in ULONG CompressedDataInfoLength,
__in PDEVICE_OBJECT DeviceObject
)
{
//
// Pass through logic for this type of Fast I/O
//
__try
{
PDEVICE_OBJECT nextDeviceObject = ((PFSFILTER_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->AttachedToDeviceObject;
PFAST_IO_DISPATCH fastIoDispatch = nextDeviceObject->DriverObject->FastIoDispatch;
if (VALID_FAST_IO_DISPATCH_HANDLER(fastIoDispatch, FastIoReadCompressed))
{
return (fastIoDispatch->FastIoReadCompressed)(
FileObject,
FileOffset,
Length,
LockKey,
Buffer,
MdlChain,
IoStatus,
CompressedDataInfo,
CompressedDataInfoLength,
nextDeviceObject);
}
}
__except (EXCEPTION_EXECUTE_HANDLER){ DbgPrint(“error %x”, GetExceptionCode()); }
return FALSE;
}
BOOLEAN FsFilterFastIoWriteCompressed(
__in PFILE_OBJECT FileObject,
__in PLARGE_INTEGER FileOffset,
__in ULONG Length,
__in ULONG LockKey,
__in PVOID Buffer,
__out PMDL* MdlChain,
__out PIO_STATUS_BLOCK IoStatus,
__in struct _COMPRESSED_DATA_INFO* CompressedDataInfo,
__in ULONG CompressedDataInfoLength,
__in PDEVICE_OBJECT DeviceObject
)
{
//
// Pass through logic for this type of Fast I/O
//
__try
{
PDEVICE_OBJECT nextDeviceObject = ((PFSFILTER_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->AttachedToDeviceObject;
PFAST_IO_DISPATCH fastIoDispatch = nextDeviceObject->DriverObject->FastIoDispatch;
if (VALID_FAST_IO_DISPATCH_HANDLER(fastIoDispatch, FastIoWriteCompressed))
{
return (fastIoDispatch->FastIoWriteCompressed)(
FileObject,
FileOffset,
Length,
LockKey,
Buffer,
MdlChain,
IoStatus,
CompressedDataInfo,
CompressedDataInfoLength,
nextDeviceObject);
}
}
__except (EXCEPTION_EXECUTE_HANDLER){ DbgPrint(“error %x”, GetExceptionCode()); }
return FALSE;
}
BOOLEAN FsFilterFastIoMdlReadCompleteCompressed(
__in PFILE_OBJECT FileObject,
__in PMDL MdlChain,
__in PDEVICE_OBJECT DeviceObject
)
{
//
// Pass through logic for this type of Fast I/O
//
__try
{
PDEVICE_OBJECT nextDeviceObject = ((PFSFILTER_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->AttachedToDeviceObject;
PFAST_IO_DISPATCH fastIoDispatch = nextDeviceObject->DriverObject->FastIoDispatch;
if (VALID_FAST_IO_DISPATCH_HANDLER(fastIoDispatch, MdlReadCompleteCompressed))
{
return (fastIoDispatch->MdlReadCompleteCompressed)(
FileObject,
MdlChain,
nextDeviceObject);
}
}
__except (EXCEPTION_EXECUTE_HANDLER){ DbgPrint(“error %x”, GetExceptionCode()); }
return FALSE;
}
BOOLEAN FsFilterFastIoMdlWriteCompleteCompressed(
__in PFILE_OBJECT FileObject,
__in PLARGE_INTEGER FileOffset,
__in PMDL MdlChain,
__in PDEVICE_OBJECT DeviceObject
)
{
//
// Pass through logic for this type of Fast I/O
//
__try
{
PDEVICE_OBJECT nextDeviceObject = ((PFSFILTER_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->AttachedToDeviceObject;
PFAST_IO_DISPATCH fastIoDispatch = nextDeviceObject->DriverObject->FastIoDispatch;
if (VALID_FAST_IO_DISPATCH_HANDLER(fastIoDispatch, MdlWriteCompleteCompressed))
{
return (fastIoDispatch->MdlWriteCompleteCompressed)(
FileObject,
FileOffset,
MdlChain,
nextDeviceObject);
}
}
__except (EXCEPTION_EXECUTE_HANDLER){ DbgPrint(“error %x”, GetExceptionCode()); }
return FALSE;
}
BOOLEAN FsFilterFastIoQueryOpen(
__in PIRP Irp,
__out PFILE_NETWORK_OPEN_INFORMATION NetworkInformation,
__in PDEVICE_OBJECT DeviceObject
)
{
//
// Pass through logic for this type of Fast I/O
//
__try
{
PDEVICE_OBJECT nextDeviceObject = ((PFSFILTER_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->AttachedToDeviceObject;
PFAST_IO_DISPATCH fastIoDispatch = nextDeviceObject->DriverObject->FastIoDispatch;
if (VALID_FAST_IO_DISPATCH_HANDLER(fastIoDispatch, FastIoQueryOpen))
{
BOOLEAN result;
PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation(Irp);
//
// Before calling the next filter, we must make sure their device
// object is in the current stack entry for the given IRP
//
irpSp->DeviceObject = nextDeviceObject;
result = (fastIoDispatch->FastIoQueryOpen)(
Irp,
NetworkInformation,
nextDeviceObject);
//
// Always restore the IRP back to our device object
//
irpSp->DeviceObject = DeviceObject;
return result;
}
}
__except (EXCEPTION_EXECUTE_HANDLER){ DbgPrint(“error %x”, GetExceptionCode()); }
return FALSE;
}
****************** FsFilter.h
#pragma once
#include <ntifs.h>
//////////////////////////////////////////////////////////////////////////
// Defines
#define DELAY_ONE_MICROSECOND (-10)
#define DELAY_ONE_MILLISECOND (DELAY_ONE_MICROSECOND * 1000)
#define DELAY_ONE_SECOND (DELAY_ONE_MILLISECOND * 1000)
#define DEVOBJ_LIST_SIZE 64
// Macro to test if FAST_IO_DISPATCH handling routine is valid
#define VALID_FAST_IO_DISPATCH_HANDLER(_FastIoDispatchPtr, _FieldName) <br> (((_FastIoDispatchPtr) != NULL) && <br> (((FastIoDispatchPtr)->SizeOfFastIoDispatch) >= <br> (FIELD_OFFSET(FAST_IO_DISPATCH, FieldName) + sizeof(void ))) && <br> ((_FastIoDispatchPtr)->_FieldName != NULL))
//////////////////////////////////////////////////////////////////////////
// Structures
typedef struct _FSFILTER_DEVICE_EXTENSION
{
PDEVICE_OBJECT AttachedToDeviceObject;
} FSFILTER_DEVICE_EXTENSION, PFSFILTER_DEVICE_EXTENSION;
//////////////////////////////////////////////////////////////////////////
// General Functions
NTSTATUS FsFilterDispatchPassThrough(
in PDEVICE_OBJECT DeviceObject,
in PIRP Irp
);
NTSTATUS FsFilterDispatchCreate(
in PDEVICE_OBJECT DeviceObject,
in PIRP Irp
);
NTSTATUS FsFilterAttachToDevice(
in PDEVICE_OBJECT DeviceObject,
out_opt PDEVICE_OBJECT pFilterDeviceObject
);
VOID FsFilterDetachFromDevice(
__in PDEVICE_OBJECT DeviceObject
);
BOOLEAN FsFilterIsAttachedToDevice(
__in PDEVICE_OBJECT DeviceObject
);
BOOLEAN FsFilterIsMyDeviceObject(
__in PDEVICE_OBJECT DeviceObject
);
VOID FsFilterNotificationCallback(
__in PDEVICE_OBJECT DeviceObject,
__in BOOLEAN FsActive
);
//////////////////////////////////////////////////////////////////////////
// Fast-IO Handlers
BOOLEAN FsFilterFastIoCheckIfPossible(
__in PFILE_OBJECT FileObject,
in PLARGE_INTEGER FileOffset,
in ULONG Length,
in BOOLEAN Wait,
in ULONG LockKey,
in BOOLEAN CheckForReadOperation,
out PIO_STATUS_BLOCK IoStatus,
__in PDEVICE_OBJECT DeviceObject
);
BOOLEAN FsFilterFastIoRead(
__in PFILE_OBJECT FileObject,
in PLARGE_INTEGER FileOffset,
in ULONG Length,
in BOOLEAN Wait,
in ULONG LockKey,
out PVOID Buffer,
out PIO_STATUS_BLOCK IoStatus,
__in PDEVICE_OBJECT DeviceObject
);
BOOLEAN FsFilterFastIoWrite(
__in PFILE_OBJECT FileObject,
in PLARGE_INTEGER FileOffset,
in ULONG Length,
in BOOLEAN Wait,
in ULONG LockKey,
in PVOID Buffer,
out PIO_STATUS_BLOCK IoStatus,
__in PDEVICE_OBJECT DeviceObject
);
BOOLEAN FsFilterFastIoQueryBasicInfo(
__in PFILE_OBJECT FileObject,
in BOOLEAN Wait,
out PFILE_BASIC_INFORMATION Buffer,
out PIO_STATUS_BLOCK IoStatus,
in PDEVICE_OBJECT DeviceObject
);
BOOLEAN FsFilterFastIoQueryStandardInfo(
in PFILE_OBJECT FileObject,
in BOOLEAN Wait,
out PFILE_STANDARD_INFORMATION Buffer,
out PIO_STATUS_BLOCK IoStatus,
__in PDEVICE_OBJECT DeviceObject
);
BOOLEAN FsFilterFastIoLock(
__in PFILE_OBJECT FileObject,
in PLARGE_INTEGER FileOffset,
in PLARGE_INTEGER Length,
in PEPROCESS ProcessId,
in ULONG Key,
in BOOLEAN FailImmediately,
in BOOLEAN ExclusiveLock,
out PIO_STATUS_BLOCK IoStatus,
in PDEVICE_OBJECT DeviceObject
);
BOOLEAN FsFilterFastIoUnlockSingle(
in PFILE_OBJECT FileObject,
in PLARGE_INTEGER FileOffset,
in PLARGE_INTEGER Length,
in PEPROCESS ProcessId,
in ULONG Key,
out PIO_STATUS_BLOCK IoStatus,
__in PDEVICE_OBJECT DeviceObject
);
BOOLEAN FsFilterFastIoUnlockAll(
__in PFILE_OBJECT FileObject,
in PEPROCESS ProcessId,
out PIO_STATUS_BLOCK IoStatus,
__in PDEVICE_OBJECT DeviceObject
);
BOOLEAN FsFilterFastIoUnlockAllByKey(
__in PFILE_OBJECT FileObject,
in PVOID ProcessId,
in ULONG Key,
out PIO_STATUS_BLOCK IoStatus,
in PDEVICE_OBJECT DeviceObject
);
BOOLEAN FsFilterFastIoDeviceControl(
in PFILE_OBJECT FileObject,
in BOOLEAN Wait,
in_opt PVOID InputBuffer,
in ULONG InputBufferLength,
out_opt PVOID OutputBuffer,
in ULONG OutputBufferLength,
in ULONG IoControlCode,
out PIO_STATUS_BLOCK IoStatus,
__in PDEVICE_OBJECT DeviceObject
);
VOID FsFilterFastIoDetachDevice(
__in PDEVICE_OBJECT SourceDevice,
__in PDEVICE_OBJECT TargetDevice
);
BOOLEAN FsFilterFastIoQueryNetworkOpenInfo(
__in PFILE_OBJECT FileObject,
in BOOLEAN Wait,
out PFILE_NETWORK_OPEN_INFORMATION Buffer,
out PIO_STATUS_BLOCK IoStatus,
in PDEVICE_OBJECT DeviceObject
);
BOOLEAN FsFilterFastIoMdlRead(
in PFILE_OBJECT FileObject,
in PLARGE_INTEGER FileOffset,
in ULONG Length,
in ULONG LockKey,
__out PMDL MdlChain,
out PIO_STATUS_BLOCK IoStatus,
__in PDEVICE_OBJECT DeviceObject
);
BOOLEAN FsFilterFastIoMdlReadComplete(
__in PFILE_OBJECT FileObject,
in PMDL MdlChain,
in PDEVICE_OBJECT DeviceObject
);
BOOLEAN FsFilterFastIoPrepareMdlWrite(
in PFILE_OBJECT FileObject,
in PLARGE_INTEGER FileOffset,
in ULONG Length,
in ULONG LockKey,
out PMDL* MdlChain,
out PIO_STATUS_BLOCK IoStatus,
__in PDEVICE_OBJECT DeviceObject
);
BOOLEAN FsFilterFastIoMdlWriteComplete(
__in PFILE_OBJECT FileObject,
in PLARGE_INTEGER FileOffset,
in PMDL MdlChain,
__in PDEVICE_OBJECT DeviceObject
);
BOOLEAN FsFilterFastIoReadCompressed(
__in PFILE_OBJECT FileObject,
in PLARGE_INTEGER FileOffset,
in ULONG Length,
in ULONG LockKey,
out PVOID Buffer,
out PMDL* MdlChain,
out PIO_STATUS_BLOCK IoStatus,
_out struct COMPRESSED_DATA_INFO* CompressedDataInfo,
in ULONG CompressedDataInfoLength,
__in PDEVICE_OBJECT DeviceObject
);
BOOLEAN FsFilterFastIoWriteCompressed(
__in PFILE_OBJECT FileObject,
in PLARGE_INTEGER FileOffset,
in ULONG Length,
in ULONG LockKey,
in PVOID Buffer,
out PMDL* MdlChain,
out PIO_STATUS_BLOCK IoStatus,
_in struct COMPRESSED_DATA_INFO* CompressedDataInfo,
in ULONG CompressedDataInfoLength,
__in PDEVICE_OBJECT DeviceObject
);
BOOLEAN FsFilterFastIoMdlReadCompleteCompressed(
__in PFILE_OBJECT FileObject,
in PMDL MdlChain,
in PDEVICE_OBJECT DeviceObject
);
BOOLEAN FsFilterFastIoMdlWriteCompleteCompressed(
in PFILE_OBJECT FileObject,
in PLARGE_INTEGER FileOffset,
in PMDL MdlChain,
in PDEVICE_OBJECT DeviceObject
);
BOOLEAN FsFilterFastIoQueryOpen(
in PIRP Irp,
out PFILE_NETWORK_OPEN_INFORMATION NetworkInformation,
__in PDEVICE_OBJECT DeviceObject
);
//////////////////////////////////////////////////////////////////////////
// Global data
extern PDRIVER_OBJECT g_fsFilterDriverObject;
IrpDispatch.c
#include “FsFilter.h”
///////////////////////////////////////////////////////////////////////////////////////////////////
// PassThrough IRP Handler
NTSTATUS FsFilterDispatchPassThrough(
__in PDEVICE_OBJECT DeviceObject,
__in PIRP Irp
)
{
PFSFILTER_DEVICE_EXTENSION pDevExt = (PFSFILTER_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
IoSkipCurrentIrpStackLocation(Irp);
return IoCallDriver(pDevExt->AttachedToDeviceObject, Irp);
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// IRP_MJ_CREATE IRP Handler
NTSTATUS FsFilterDispatchCreate(
__in PDEVICE_OBJECT DeviceObject,
__in PIRP Irp
)
{
PFILE_OBJECT pFileObject = IoGetCurrentIrpStackLocation(Irp)->FileObject;
DbgPrint(“%wZ\n”, &pFileObject->FileName);
return FsFilterDispatchPassThrough(DeviceObject, Irp);
}
Main.c
#include “FsFilter.h”
//////////////////////////////////////////////////////////////////////////
// Function prototypes
VOID FsFilterUnload(
__in PDRIVER_OBJECT DriverObject
);
//////////////////////////////////////////////////////////////////////////
// Global data
PDRIVER_OBJECT g_fsFilterDriverObject = NULL;
FAST_IO_DISPATCH g_fastIoDispatch =
{
sizeof(FAST_IO_DISPATCH),
FsFilterFastIoCheckIfPossible,
FsFilterFastIoRead,
FsFilterFastIoWrite,
FsFilterFastIoQueryBasicInfo,
FsFilterFastIoQueryStandardInfo,
FsFilterFastIoLock,
FsFilterFastIoUnlockSingle,
FsFilterFastIoUnlockAll,
FsFilterFastIoUnlockAllByKey,
FsFilterFastIoDeviceControl,
FsFilterFastIoDetachDevice,
FsFilterFastIoQueryNetworkOpenInfo,
FsFilterFastIoMdlRead,
FsFilterFastIoMdlReadComplete,
FsFilterFastIoPrepareMdlWrite,
FsFilterFastIoMdlWriteComplete,
FsFilterFastIoReadCompressed,
FsFilterFastIoWriteCompressed,
FsFilterFastIoMdlReadCompleteCompressed,
FsFilterFastIoMdlWriteCompleteCompressed,
FsFilterFastIoQueryOpen
};
//////////////////////////////////////////////////////////////////////////
// DriverEntry - Entry point of the driver
NTSTATUS DriverEntry(
inout PDRIVER_OBJECT DriverObject,
in PUNICODE_STRING RegistryPath
)
{
NTSTATUS status = STATUS_SUCCESS;
ULONG i = 0;
__try
{
//ASSERT(FALSE); // This will break to debugger
//
// Store our driver object.
//
g_fsFilterDriverObject = DriverObject;
//
// Initialize the driver object dispatch table.
//
for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; ++i)
{
DriverObject->MajorFunction[i] = FsFilterDispatchPassThrough;
}
DriverObject->MajorFunction[IRP_MJ_CREATE] = FsFilterDispatchCreate;
//
// Set fast-io dispatch table.
//
DriverObject->FastIoDispatch = &g_fastIoDispatch;
//
// Registered callback routine for file system changes.
//
status = IoRegisterFsRegistrationChange(DriverObject, FsFilterNotificationCallback);
if (!NT_SUCCESS(status))
{
return status;
}
//
// Set driver unload routine (debug purpose only).
//
DriverObject->DriverUnload = FsFilterUnload;
return STATUS_SUCCESS;
}
__except (EXCEPTION_EXECUTE_HANDLER){
DbgPrint(“error at %x”,GetExceptionCode());
return status;
}
}
//////////////////////////////////////////////////////////////////////////
// Unload routine
VOID FsFilterUnload(
__in PDRIVER_OBJECT DriverObject
)
{
ULONG numDevices = 0;
ULONG i = 0;
LARGE_INTEGER interval;
PDEVICE_OBJECT devList[DEVOBJ_LIST_SIZE];
interval.QuadPart = (5 * DELAY_ONE_SECOND); //delay 5 seconds
//
// Unregistered callback routine for file system changes.
//
IoUnregisterFsRegistrationChange(DriverObject, FsFilterNotificationCallback);
//
// This is the loop that will go through all of the devices we are attached
// to and detach from them.
//
for (;
{
IoEnumerateDeviceObjectList(
DriverObject,
devList,
sizeof(devList),
&numDevices);
if (0 == numDevices)
{
break;
}
numDevices = min(numDevices, RTL_NUMBER_OF(devList));
for (i = 0; i < numDevices; ++i)
{
FsFilterDetachFromDevice(devList[i]);
ObDereferenceObject(devList[i]);
}
KeDelayExecutionThread(KernelMode, FALSE, &interval);
}
}
//////////////////////////////////////////////////////////////////////////
// Misc
BOOLEAN FsFilterIsMyDeviceObject(
__in PDEVICE_OBJECT DeviceObject
)
{
return DeviceObject->DriverObject == g_fsFilterDriverObject;
}</ntifs.h>