reactos/drivers/filters/fltmgr/Interface.c
Bișoc George 42ce8519b6 [FASTFAT][FLTMGR][NTOS] Do not explicitly call ObfDereferenceObject() (#1636)
"Most code should not directly call the platform-specific ObfDereferenceObject() function but use the ObDereferenceObject() macro instead."

CORE-16081
2019-06-22 16:20:58 +02:00

2259 lines
72 KiB
C

/*
* PROJECT: Filesystem Filter Manager
* LICENSE: GPL - See COPYING in the top level directory
* FILE: drivers/filters/fltmgr/interface.c
* PURPOSE: Implements the driver interface
* PROGRAMMERS: Ged Murphy (gedmurphy@reactos.org)
*/
/* INCLUDES ******************************************************************/
#include "fltmgr.h"
#include "fltmgrint.h"
//#define NDEBUG
#include <debug.h>
/* DATA *********************************************************************/
#define VALID_FAST_IO_DISPATCH_HANDLER(_FastIoDispatchPtr, _FieldName) \
(((_FastIoDispatchPtr) != NULL) && \
(((_FastIoDispatchPtr)->SizeOfFastIoDispatch) >= \
(FIELD_OFFSET(FAST_IO_DISPATCH, _FieldName) + sizeof(void *))) && \
((_FastIoDispatchPtr)->_FieldName != NULL))
#define IS_MY_DEVICE_OBJECT(_devObj) \
(((_devObj) != NULL) && \
((_devObj)->DriverObject == Dispatcher::DriverObject) && \
((_devObj)->DeviceExtension != NULL))
extern PDEVICE_OBJECT CommsDeviceObject;
extern LIST_ENTRY FilterList;
extern ERESOURCE FilterListLock;
DRIVER_INITIALIZE DriverEntry;
NTSTATUS
NTAPI
DriverEntry(
_In_ PDRIVER_OBJECT DriverObject,
_In_ PUNICODE_STRING RegistryPath
);
static
NTSTATUS
SetupDispatchAndCallbacksTables(
_In_ PDRIVER_OBJECT DriverObject
);
static
NTSTATUS
FltpAttachDeviceObject(
_In_ PDEVICE_OBJECT SourceDevice,
_In_ PDEVICE_OBJECT TargetDevice,
_Out_ PDEVICE_OBJECT *AttachedToDeviceObject
);
static
VOID
FltpCleanupDeviceObject(
_In_ PDEVICE_OBJECT DeviceObject
);
static
BOOLEAN
FltpIsAttachedToDevice(
_In_ PDEVICE_OBJECT DeviceObject,
_In_opt_ PDEVICE_OBJECT *AttachedDeviceObject
);
static
NTSTATUS
FltpEnumerateFileSystemVolumes(
_In_ PDEVICE_OBJECT DeviceObject
);
static
NTSTATUS
FltpAttachToFileSystemDevice(
_In_ PDEVICE_OBJECT DeviceObject,
_In_ PUNICODE_STRING DeviceName
);
static
LONG_PTR
FltpDetachFromFileSystemDevice(
_In_ PDEVICE_OBJECT DeviceObject
);
DRIVER_FS_NOTIFICATION FltpFsNotification;
VOID
NTAPI
FltpFsNotification(
_In_ PDEVICE_OBJECT DeviceObject,
_In_ BOOLEAN FsActive
);
NTSTATUS
NTAPI
FltpDispatch(
_In_ PDEVICE_OBJECT DeviceObject,
_Inout_ PIRP Irp
);
NTSTATUS
NTAPI
FltpCreate(
_In_ PDEVICE_OBJECT DeviceObject,
_Inout_ PIRP Irp
);
NTSTATUS
NTAPI
FltpFsControl(
_In_ PDEVICE_OBJECT DeviceObject,
_Inout_ PIRP Irp
);
NTSTATUS
NTAPI
FltpDeviceControl(
_In_ PDEVICE_OBJECT DeviceObject,
_Inout_ PIRP Irp
);
BOOLEAN
NTAPI
FltpFastIoCheckIfPossible(
_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
NTAPI
FltpFastIoRead(
_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
NTAPI
FltpFastIoWrite(
_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
NTAPI
FltpFastIoQueryBasicInfo(
_In_ PFILE_OBJECT FileObject,
_In_ BOOLEAN Wait,
_Out_ PFILE_BASIC_INFORMATION Buffer,
_Out_ PIO_STATUS_BLOCK IoStatus,
_In_ PDEVICE_OBJECT DeviceObject
);
BOOLEAN
NTAPI
FltpFastIoQueryStandardInfo(
_In_ PFILE_OBJECT FileObject,
_In_ BOOLEAN Wait,
_Out_ PFILE_STANDARD_INFORMATION Buffer,
_Out_ PIO_STATUS_BLOCK IoStatus,
_In_ PDEVICE_OBJECT DeviceObject
);
BOOLEAN
NTAPI
FltpFastIoLock(
_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
NTAPI
FltpFastIoUnlockSingle(
_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
NTAPI
FltpFastIoUnlockAll(
_In_ PFILE_OBJECT FileObject,
_In_ PEPROCESS ProcessId,
_Out_ PIO_STATUS_BLOCK IoStatus,
_In_ PDEVICE_OBJECT DeviceObject
);
BOOLEAN
NTAPI
FltpFastIoUnlockAllByKey(
_In_ PFILE_OBJECT FileObject,
_In_ PVOID ProcessId,
_In_ ULONG Key,
_Out_ PIO_STATUS_BLOCK IoStatus,
_In_ PDEVICE_OBJECT DeviceObject
);
BOOLEAN
NTAPI
FltpFastIoDeviceControl(
_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
NTAPI
FltpFastIoDetachDevice(
_In_ PDEVICE_OBJECT SourceDevice,
_In_ PDEVICE_OBJECT TargetDevice
);
BOOLEAN
NTAPI
FltpFastIoQueryNetworkOpenInfo(
_In_ PFILE_OBJECT FileObject,
_In_ BOOLEAN Wait,
_Out_ PFILE_NETWORK_OPEN_INFORMATION Buffer,
_Out_ PIO_STATUS_BLOCK IoStatus,
_In_ PDEVICE_OBJECT DeviceObject
);
BOOLEAN
NTAPI
FltpFastIoMdlRead(
_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
NTAPI
FltpFastIoMdlReadComplete(
_In_ PFILE_OBJECT FileObject,
_In_ PMDL MdlChain,
_In_ PDEVICE_OBJECT DeviceObject
);
BOOLEAN
NTAPI
FltpFastIoPrepareMdlWrite(
_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
NTAPI
FltpFastIoMdlWriteComplete(
_In_ PFILE_OBJECT FileObject,
_In_ PLARGE_INTEGER FileOffset,
_In_ PMDL MdlChain,
_In_ PDEVICE_OBJECT DeviceObject
);
BOOLEAN
NTAPI
FltpFastIoReadCompressed(
_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_ PCOMPRESSED_DATA_INFO CompressedDataInfo,
_In_ ULONG CompressedDataInfoLength,
_In_ PDEVICE_OBJECT DeviceObject
);
BOOLEAN
NTAPI
FltpFastIoWriteCompressed(
_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_ PCOMPRESSED_DATA_INFO CompressedDataInfo,
_In_ ULONG CompressedDataInfoLength,
_In_ PDEVICE_OBJECT DeviceObject
);
BOOLEAN
NTAPI
FltpFastIoMdlReadCompleteCompressed(
_In_ PFILE_OBJECT FileObject,
_In_ PMDL MdlChain,
_In_ PDEVICE_OBJECT DeviceObject
);
BOOLEAN
NTAPI
FltpFastIoMdlWriteCompleteCompressed(
_In_ PFILE_OBJECT FileObject,
_In_ PLARGE_INTEGER FileOffset,
_In_ PMDL MdlChain,
_In_ PDEVICE_OBJECT DeviceObject
);
BOOLEAN
NTAPI
FltpFastIoQueryOpen(
_Inout_ PIRP Irp,
_Out_ PFILE_NETWORK_OPEN_INFORMATION NetworkInformation,
_In_ PDEVICE_OBJECT DeviceObject
);
#ifdef ALLOC_PRAGMA
#pragma alloc_text(INIT, DriverEntry)
#pragma alloc_text(INIT, SetupDispatchAndCallbacksTables)
#pragma alloc_text(PAGE, FltpAttachDeviceObject)
#pragma alloc_text(PAGE, FltpIsAttachedToDevice)
#pragma alloc_text(PAGE, FltpEnumerateFileSystemVolumes)
#pragma alloc_text(PAGE, FltpAttachToFileSystemDevice)
#pragma alloc_text(PAGE, FltpDetachFromFileSystemDevice)
#pragma alloc_text(PAGE, FltpFsNotification)
#pragma alloc_text(PAGE, FltpCreate)
#pragma alloc_text(PAGE, FltpFsControl)
#pragma alloc_text(PAGE, FltpDeviceControl)
#pragma alloc_text(PAGE, FltpFastIoRead)
#pragma alloc_text(PAGE, FltpFastIoWrite)
#pragma alloc_text(PAGE, FltpFastIoQueryBasicInfo)
#pragma alloc_text(PAGE, FltpFastIoQueryStandardInfo)
#pragma alloc_text(PAGE, FltpFastIoLock)
#pragma alloc_text(PAGE, FltpFastIoUnlockSingle)
#pragma alloc_text(PAGE, FltpFastIoUnlockAll)
#pragma alloc_text(PAGE, FltpFastIoUnlockAllByKey)
#pragma alloc_text(PAGE, FltpFastIoDeviceControl)
#pragma alloc_text(PAGE, FltpFastIoDetachDevice)
#pragma alloc_text(PAGE, FltpFastIoQueryNetworkOpenInfo)
#pragma alloc_text(PAGE, FltpFastIoMdlRead)
#pragma alloc_text(PAGE, FltpFastIoMdlReadComplete)
#pragma alloc_text(PAGE, FltpFastIoPrepareMdlWrite)
#pragma alloc_text(PAGE, FltpFastIoMdlWriteComplete)
#pragma alloc_text(PAGE, FltpFastIoReadCompressed)
#pragma alloc_text(PAGE, FltpFastIoWriteCompressed)
#pragma alloc_text(PAGE, FltpFastIoMdlReadCompleteCompressed)
#pragma alloc_text(PAGE, FltpFastIoMdlWriteCompleteCompressed)
#pragma alloc_text(PAGE, FltpFastIoQueryOpen)
#endif
DRIVER_DATA DriverData;
typedef struct _DETACH_DEVICE_WORK_ITEM
{
WORK_QUEUE_ITEM WorkItem;
PDEVICE_OBJECT SourceDevice;
PDEVICE_OBJECT TargetDevice;
} DETACH_DEVICE_WORK_ITEM, *PDETACH_DEVICE_WORK_ITEM;
/* DISPATCH ROUTINES **********************************************/
NTSTATUS
NTAPI
FltpPreFsFilterOperation(_In_ PFS_FILTER_CALLBACK_DATA Data,
_Out_ PVOID *CompletionContext)
{
UNREFERENCED_PARAMETER(Data);
UNREFERENCED_PARAMETER(CompletionContext);
__debugbreak();
return STATUS_SUCCESS;
}
VOID
NTAPI
FltpPostFsFilterOperation(_In_ PFS_FILTER_CALLBACK_DATA Data,
_In_ NTSTATUS OperationStatus,
_In_ PVOID CompletionContext)
{
UNREFERENCED_PARAMETER(Data);
UNREFERENCED_PARAMETER(OperationStatus);
UNREFERENCED_PARAMETER(CompletionContext);
__debugbreak();
}
NTSTATUS
NTAPI
FltpDispatch(_In_ PDEVICE_OBJECT DeviceObject,
_Inout_ PIRP Irp)
{
PFLTMGR_DEVICE_EXTENSION DeviceExtension;
PIO_STACK_LOCATION StackPtr;
NTSTATUS Status;
DeviceExtension = DeviceObject->DeviceExtension;
/* Check if this is a request for us */
if (DeviceObject == DriverData.DeviceObject)
{
FLT_ASSERT(DeviceObject->DriverObject == DriverData.DriverObject);
FLT_ASSERT(DeviceExtension == NULL);
/* Hand it off to our internal handler */
Status = FltpDispatchHandler(DeviceObject, Irp);
if (Status != STATUS_REPARSE)
{
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, 0);
}
return Status;
}
/* Check if this is a request for a the messaging device */
if (DeviceObject == CommsDeviceObject)
{
/* Hand off to our internal routine */
return FltpMsgDispatch(DeviceObject, Irp);
}
FLT_ASSERT(DeviceExtension &&
DeviceExtension->AttachedToDeviceObject);
StackPtr = IoGetCurrentIrpStackLocation(Irp);
if (StackPtr->MajorFunction == IRP_MJ_SHUTDOWN)
{
// handle shutdown request
}
DPRINT1("Received %X from %wZ\n", StackPtr->MajorFunction, &DeviceExtension->DeviceName);
/* Just pass the IRP down the stack */
IoSkipCurrentIrpStackLocation(Irp);
return IoCallDriver(DeviceExtension->AttachedToDeviceObject, Irp);
}
NTSTATUS
NTAPI
FltpCreate(_In_ PDEVICE_OBJECT DeviceObject,
_Inout_ PIRP Irp)
{
PFLTMGR_DEVICE_EXTENSION DeviceExtension;
PAGED_CODE();
DeviceExtension = DeviceObject->DeviceExtension;
/* Check if this is a request for us */
if (DeviceObject == DriverData.DeviceObject)
{
FLT_ASSERT(DeviceObject->DriverObject == DriverData.DriverObject);
FLT_ASSERT(DeviceExtension == NULL);
/* Someone wants a handle to the fltmgr, allow it */
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IofCompleteRequest(Irp, 0);
return STATUS_SUCCESS;
}
/* Check if this is a request for a the new comms connection */
if (DeviceObject == CommsDeviceObject)
{
/* Hand off to our internal routine */
return FltpMsgCreate(DeviceObject, Irp);
}
FLT_ASSERT(DeviceExtension &&
DeviceExtension->AttachedToDeviceObject);
DPRINT1("Received create from %wZ (%lu)\n", &DeviceExtension->DeviceName, PsGetCurrentProcessId());
/* Just pass the IRP down the stack */
IoSkipCurrentIrpStackLocation(Irp);
return IoCallDriver(DeviceExtension->AttachedToDeviceObject, Irp);
}
NTSTATUS
NTAPI
FltpFsControl(_In_ PDEVICE_OBJECT DeviceObject,
_Inout_ PIRP Irp)
{
PFLTMGR_DEVICE_EXTENSION DeviceExtension;
PAGED_CODE();
/* Check if this is a request for us */
if (DeviceObject == DriverData.DeviceObject)
{
/* We don't handle this request */
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
IofCompleteRequest(Irp, 0);
return STATUS_INVALID_DEVICE_REQUEST;
}
DeviceExtension = DeviceObject->DeviceExtension;
FLT_ASSERT(DeviceExtension &&
DeviceExtension->AttachedToDeviceObject);
/* Just pass the IRP down the stack */
IoSkipCurrentIrpStackLocation(Irp);
return IoCallDriver(DeviceExtension->AttachedToDeviceObject, Irp);
}
NTSTATUS
NTAPI
FltpDeviceControl(_In_ PDEVICE_OBJECT DeviceObject,
_Inout_ PIRP Irp)
{
PFLTMGR_DEVICE_EXTENSION DeviceExtension;
NTSTATUS Status;
/* Check if the request was meant for us */
if (DeviceObject == DriverData.DeviceObject)
{
Status = FltpDeviceControlHandler(DeviceObject, Irp);
if (Status != STATUS_REPARSE)
{
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, 0);
}
return Status;
}
DeviceExtension = DeviceObject->DeviceExtension;
FLT_ASSERT(DeviceExtension &&
DeviceExtension->AttachedToDeviceObject);
/* Just pass the IRP down the stack */
IoSkipCurrentIrpStackLocation(Irp);
return IoCallDriver(DeviceExtension->AttachedToDeviceObject, Irp);
}
/* FASTIO ROUTINES ************************************************/
BOOLEAN
NTAPI
FltpFastIoCheckIfPossible(_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)
{
PFLTMGR_DEVICE_EXTENSION DeviceExtension;
PDEVICE_OBJECT AttachedDeviceObject;
PFAST_IO_DISPATCH FastIoDispatch;
PAGED_CODE();
/* If it doesn't have a device extension, then it's not our device object */
if (DeviceObject->DeviceExtension == NULL)
{
/* Fail the call */
IoStatus->Status = STATUS_INVALID_DEVICE_REQUEST;
IoStatus->Information = 0;
return TRUE;
}
DeviceExtension = DeviceObject->DeviceExtension;
FLT_ASSERT(DeviceExtension->AttachedToDeviceObject);
/* Get the device that we attached to */
AttachedDeviceObject = DeviceExtension->AttachedToDeviceObject;
FastIoDispatch = AttachedDeviceObject->DriverObject->FastIoDispatch;
/* Make sure our FastIo table is valid */
if (FastIoDispatch && FastIoDispatch->FastIoCheckIfPossible)
{
/* Forward the call onto the device we attached to */
return FastIoDispatch->FastIoCheckIfPossible(FileObject,
FileOffset,
Length,
Wait,
LockKey,
CheckForReadOperation,
IoStatus,
AttachedDeviceObject);
}
/* We failed to handle the request, send it down the slow path */
FLT_ASSERT(FALSE);
return FALSE;
}
BOOLEAN
NTAPI
FltpFastIoRead(_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)
{
PFLTMGR_DEVICE_EXTENSION DeviceExtension;
PDEVICE_OBJECT AttachedDeviceObject;
PFAST_IO_DISPATCH FastIoDispatch;
PAGED_CODE();
/* If it doesn't have a device extension, then it's not our device object */
if (DeviceObject->DeviceExtension == NULL)
{
/* Fail the call */
IoStatus->Status = STATUS_INVALID_DEVICE_REQUEST;
IoStatus->Information = 0;
return TRUE;
}
DeviceExtension = DeviceObject->DeviceExtension;
FLT_ASSERT(DeviceExtension->AttachedToDeviceObject);
/* Get the device that we attached to */
AttachedDeviceObject = DeviceExtension->AttachedToDeviceObject;
FastIoDispatch = AttachedDeviceObject->DriverObject->FastIoDispatch;
/* Make sure our FastIo table is valid */
if (FastIoDispatch && FastIoDispatch->FastIoRead)
{
/* Forward the call onto the device we attached to */
return FastIoDispatch->FastIoRead(FileObject,
FileOffset,
Length,
Wait,
LockKey,
Buffer,
IoStatus,
AttachedDeviceObject);
}
/* We failed to handle the request, send it down the slow path */
FLT_ASSERT(FALSE);
return FALSE;
}
BOOLEAN
NTAPI
FltpFastIoWrite(_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)
{
PFLTMGR_DEVICE_EXTENSION DeviceExtension;
PDEVICE_OBJECT AttachedDeviceObject;
PFAST_IO_DISPATCH FastIoDispatch;
PAGED_CODE();
/* If it doesn't have a device extension, then it's not our device object */
if (DeviceObject->DeviceExtension == NULL)
{
/* Fail the call */
IoStatus->Status = STATUS_INVALID_DEVICE_REQUEST;
IoStatus->Information = 0;
return TRUE;
}
DeviceExtension = DeviceObject->DeviceExtension;
FLT_ASSERT(DeviceExtension->AttachedToDeviceObject);
/* Get the device that we attached to */
AttachedDeviceObject = DeviceExtension->AttachedToDeviceObject;
FastIoDispatch = AttachedDeviceObject->DriverObject->FastIoDispatch;
/* Make sure our FastIo table is valid */
if (FastIoDispatch && FastIoDispatch->FastIoWrite)
{
/* Forward the call onto the device we attached to */
return FastIoDispatch->FastIoWrite(FileObject,
FileOffset,
Length,
Wait,
LockKey,
Buffer,
IoStatus,
AttachedDeviceObject);
}
/* We failed to handle the request, send it down the slow path */
FLT_ASSERT(FALSE);
return FALSE;
}
BOOLEAN
NTAPI
FltpFastIoQueryBasicInfo(_In_ PFILE_OBJECT FileObject,
_In_ BOOLEAN Wait,
_Out_ PFILE_BASIC_INFORMATION Buffer,
_Out_ PIO_STATUS_BLOCK IoStatus,
_In_ PDEVICE_OBJECT DeviceObject)
{
PFLTMGR_DEVICE_EXTENSION DeviceExtension;
PDEVICE_OBJECT AttachedDeviceObject;
PFAST_IO_DISPATCH FastIoDispatch;
PAGED_CODE();
/* If it doesn't have a device extension, then it's not our device object */
if (DeviceObject->DeviceExtension == NULL)
{
/* Fail the call */
IoStatus->Status = STATUS_INVALID_DEVICE_REQUEST;
IoStatus->Information = 0;
return TRUE;
}
DeviceExtension = DeviceObject->DeviceExtension;
FLT_ASSERT(DeviceExtension->AttachedToDeviceObject);
/* Get the device that we attached to */
AttachedDeviceObject = DeviceExtension->AttachedToDeviceObject;
FastIoDispatch = AttachedDeviceObject->DriverObject->FastIoDispatch;
/* Make sure our FastIo table is valid */
if (FastIoDispatch && FastIoDispatch->FastIoQueryBasicInfo)
{
/* Forward the call onto the device we attached to */
return FastIoDispatch->FastIoQueryBasicInfo(FileObject,
Wait,
Buffer,
IoStatus,
AttachedDeviceObject);
}
/* We failed to handle the request, send it down the slow path */
FLT_ASSERT(FALSE);
return FALSE;
}
BOOLEAN
NTAPI
FltpFastIoQueryStandardInfo(_In_ PFILE_OBJECT FileObject,
_In_ BOOLEAN Wait,
_Out_ PFILE_STANDARD_INFORMATION Buffer,
_Out_ PIO_STATUS_BLOCK IoStatus,
_In_ PDEVICE_OBJECT DeviceObject)
{
PFLTMGR_DEVICE_EXTENSION DeviceExtension;
PDEVICE_OBJECT AttachedDeviceObject;
PFAST_IO_DISPATCH FastIoDispatch;
PAGED_CODE();
/* If it doesn't have a device extension, then it's not our device object */
if (DeviceObject->DeviceExtension == NULL)
{
/* Fail the call */
IoStatus->Status = STATUS_INVALID_DEVICE_REQUEST;
IoStatus->Information = 0;
return TRUE;
}
DeviceExtension = DeviceObject->DeviceExtension;
FLT_ASSERT(DeviceExtension->AttachedToDeviceObject);
/* Get the device that we attached to */
AttachedDeviceObject = DeviceExtension->AttachedToDeviceObject;
FastIoDispatch = AttachedDeviceObject->DriverObject->FastIoDispatch;
/* Make sure our FastIo table is valid */
if (FastIoDispatch && FastIoDispatch->FastIoQueryStandardInfo)
{
/* Forward the call onto the device we attached to */
return FastIoDispatch->FastIoQueryStandardInfo(FileObject,
Wait,
Buffer,
IoStatus,
AttachedDeviceObject);
}
/* We failed to handle the request, send it down the slow path */
FLT_ASSERT(FALSE);
return FALSE;
}
BOOLEAN
NTAPI
FltpFastIoLock(_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)
{
PFLTMGR_DEVICE_EXTENSION DeviceExtension;
PDEVICE_OBJECT AttachedDeviceObject;
PFAST_IO_DISPATCH FastIoDispatch;
PAGED_CODE();
/* If it doesn't have a device extension, then it's not our device object */
if (DeviceObject->DeviceExtension == NULL)
{
/* Fail the call */
IoStatus->Status = STATUS_INVALID_DEVICE_REQUEST;
IoStatus->Information = 0;
return TRUE;
}
DeviceExtension = DeviceObject->DeviceExtension;
FLT_ASSERT(DeviceExtension->AttachedToDeviceObject);
/* Get the device that we attached to */
AttachedDeviceObject = DeviceExtension->AttachedToDeviceObject;
FastIoDispatch = AttachedDeviceObject->DriverObject->FastIoDispatch;
/* Make sure our FastIo table is valid */
if (FastIoDispatch && FastIoDispatch->FastIoLock)
{
/* Forward the call onto the device we attached to */
return FastIoDispatch->FastIoLock(FileObject,
FileOffset,
Length,
ProcessId,
Key,
FailImmediately,
ExclusiveLock,
IoStatus,
AttachedDeviceObject);
}
/* We failed to handle the request, send it down the slow path */
FLT_ASSERT(FALSE);
return FALSE;
}
BOOLEAN
NTAPI
FltpFastIoUnlockSingle(_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)
{
PFLTMGR_DEVICE_EXTENSION DeviceExtension;
PDEVICE_OBJECT AttachedDeviceObject;
PFAST_IO_DISPATCH FastIoDispatch;
PAGED_CODE();
/* If it doesn't have a device extension, then it's not our device object */
if (DeviceObject->DeviceExtension == NULL)
{
/* Fail the call */
IoStatus->Status = STATUS_INVALID_DEVICE_REQUEST;
IoStatus->Information = 0;
return TRUE;
}
DeviceExtension = DeviceObject->DeviceExtension;
FLT_ASSERT(DeviceExtension->AttachedToDeviceObject);
/* Get the device that we attached to */
AttachedDeviceObject = DeviceExtension->AttachedToDeviceObject;
FastIoDispatch = AttachedDeviceObject->DriverObject->FastIoDispatch;
/* Make sure our FastIo table is valid */
if (FastIoDispatch && FastIoDispatch->FastIoUnlockSingle)
{
/* Forward the call onto the device we attached to */
return FastIoDispatch->FastIoUnlockSingle(FileObject,
FileOffset,
Length,
ProcessId,
Key,
IoStatus,
AttachedDeviceObject);
}
/* We failed to handle the request, send it down the slow path */
FLT_ASSERT(FALSE);
return FALSE;
}
BOOLEAN
NTAPI
FltpFastIoUnlockAll(_In_ PFILE_OBJECT FileObject,
_In_ PEPROCESS ProcessId,
_Out_ PIO_STATUS_BLOCK IoStatus,
_In_ PDEVICE_OBJECT DeviceObject)
{
PFLTMGR_DEVICE_EXTENSION DeviceExtension;
PDEVICE_OBJECT AttachedDeviceObject;
PFAST_IO_DISPATCH FastIoDispatch;
PAGED_CODE();
/* If it doesn't have a device extension, then it's not our device object */
if (DeviceObject->DeviceExtension == NULL)
{
/* Fail the call */
IoStatus->Status = STATUS_INVALID_DEVICE_REQUEST;
IoStatus->Information = 0;
return TRUE;
}
DeviceExtension = DeviceObject->DeviceExtension;
FLT_ASSERT(DeviceExtension->AttachedToDeviceObject);
/* Get the device that we attached to */
AttachedDeviceObject = DeviceExtension->AttachedToDeviceObject;
FastIoDispatch = AttachedDeviceObject->DriverObject->FastIoDispatch;
/* Make sure our FastIo table is valid */
if (FastIoDispatch && FastIoDispatch->FastIoUnlockAll)
{
/* Forward the call onto the device we attached to */
return FastIoDispatch->FastIoUnlockAll(FileObject,
ProcessId,
IoStatus,
AttachedDeviceObject);
}
/* We failed to handle the request, send it down the slow path */
FLT_ASSERT(FALSE);
return FALSE;
}
BOOLEAN
NTAPI
FltpFastIoUnlockAllByKey(_In_ PFILE_OBJECT FileObject,
_In_ PVOID ProcessId,
_In_ ULONG Key,
_Out_ PIO_STATUS_BLOCK IoStatus,
_In_ PDEVICE_OBJECT DeviceObject)
{
PFLTMGR_DEVICE_EXTENSION DeviceExtension;
PDEVICE_OBJECT AttachedDeviceObject;
PFAST_IO_DISPATCH FastIoDispatch;
PAGED_CODE();
/* If it doesn't have a device extension, then it's not our device object */
if (DeviceObject->DeviceExtension == NULL)
{
/* Fail the call */
IoStatus->Status = STATUS_INVALID_DEVICE_REQUEST;
IoStatus->Information = 0;
return TRUE;
}
DeviceExtension = DeviceObject->DeviceExtension;
FLT_ASSERT(DeviceExtension->AttachedToDeviceObject);
/* Get the device that we attached to */
AttachedDeviceObject = DeviceExtension->AttachedToDeviceObject;
FastIoDispatch = AttachedDeviceObject->DriverObject->FastIoDispatch;
/* Make sure our FastIo table is valid */
if (FastIoDispatch && FastIoDispatch->FastIoUnlockAllByKey)
{
/* Forward the call onto the device we attached to */
return FastIoDispatch->FastIoUnlockAllByKey(FileObject,
ProcessId,
Key,
IoStatus,
AttachedDeviceObject);
}
/* We failed to handle the request, send it down the slow path */
FLT_ASSERT(FALSE);
return FALSE;
}
BOOLEAN
NTAPI
FltpFastIoDeviceControl(_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)
{
PFLTMGR_DEVICE_EXTENSION DeviceExtension;
PDEVICE_OBJECT AttachedDeviceObject;
PFAST_IO_DISPATCH FastIoDispatch;
PAGED_CODE();
/* If it doesn't have a device extension, then it's not our device object */
if (DeviceObject->DeviceExtension == NULL)
{
/* Fail the request, send it down the slow path */
return FALSE;
}
DeviceExtension = DeviceObject->DeviceExtension;
FLT_ASSERT(DeviceExtension->AttachedToDeviceObject);
/* Get the device that we attached to */
AttachedDeviceObject = DeviceExtension->AttachedToDeviceObject;
FastIoDispatch = AttachedDeviceObject->DriverObject->FastIoDispatch;
/* Make sure our FastIo table is valid */
if (FastIoDispatch && FastIoDispatch->FastIoDeviceControl)
{
/* Forward the call onto the device we attached to */
return FastIoDispatch->FastIoDeviceControl(FileObject,
Wait,
InputBuffer,
InputBufferLength,
OutputBuffer,
OutputBufferLength,
IoControlCode,
IoStatus,
AttachedDeviceObject);
}
/* We failed to handle the request, send it down the slow path */
FLT_ASSERT(FALSE);
return FALSE;
}
VOID
NTAPI
FltpFastIoDetachDeviceWorker(_In_ PVOID Parameter)
{
PDETACH_DEVICE_WORK_ITEM DetachDeviceWorkItem = Parameter;
/* Run any cleanup routines */
FltpCleanupDeviceObject(DetachDeviceWorkItem->SourceDevice);
/* Detach from the target device */
IoDetachDevice(DetachDeviceWorkItem->TargetDevice);
/* Delete the source */
IoDeleteDevice(DetachDeviceWorkItem->SourceDevice);
/* Free the pool we allocated in FltpFastIoDetachDevice */
ExFreePoolWithTag(DetachDeviceWorkItem, 0x1234);
}
VOID
NTAPI
FltpFastIoDetachDevice(_In_ PDEVICE_OBJECT SourceDevice,
_In_ PDEVICE_OBJECT TargetDevice)
{
PDETACH_DEVICE_WORK_ITEM DetachDeviceWorkItem;
PAGED_CODE();
/*
* Detaching and deleting devices is a lot of work and takes too long
* to be a worthwhile FastIo candidate, so we defer this call to speed
* it up. There's no return value so we're okay to do this.
*/
/* Allocate the work item and it's corresponding data */
DetachDeviceWorkItem = ExAllocatePoolWithTag(NonPagedPool,
sizeof(DETACH_DEVICE_WORK_ITEM),
0x1234);
if (DetachDeviceWorkItem)
{
/* Initialize the work item */
ExInitializeWorkItem(&DetachDeviceWorkItem->WorkItem,
FltpFastIoDetachDeviceWorker,
DetachDeviceWorkItem);
/* Queue the work item and return the call */
ExQueueWorkItem(&DetachDeviceWorkItem->WorkItem,
DelayedWorkQueue);
}
else
{
/* We failed to defer, just cleanup here */
FltpCleanupDeviceObject(SourceDevice);
IoDetachDevice(TargetDevice);
IoDeleteDevice(SourceDevice);
}
}
BOOLEAN
NTAPI
FltpFastIoQueryNetworkOpenInfo(_In_ PFILE_OBJECT FileObject,
_In_ BOOLEAN Wait,
_Out_ PFILE_NETWORK_OPEN_INFORMATION Buffer,
_Out_ PIO_STATUS_BLOCK IoStatus,
_In_ PDEVICE_OBJECT DeviceObject)
{
PFLTMGR_DEVICE_EXTENSION DeviceExtension;
PDEVICE_OBJECT AttachedDeviceObject;
PFAST_IO_DISPATCH FastIoDispatch;
PAGED_CODE();
/* If it doesn't have a device extension, then it's not our device object */
if (DeviceObject->DeviceExtension == NULL)
{
/* Fail the call */
IoStatus->Status = STATUS_INVALID_DEVICE_REQUEST;
IoStatus->Information = 0;
return TRUE;
}
DeviceExtension = DeviceObject->DeviceExtension;
FLT_ASSERT(DeviceExtension->AttachedToDeviceObject);
/* Get the device that we attached to */
AttachedDeviceObject = DeviceExtension->AttachedToDeviceObject;
FastIoDispatch = AttachedDeviceObject->DriverObject->FastIoDispatch;
/* Make sure our FastIo table is valid */
if (FastIoDispatch && FastIoDispatch->FastIoQueryNetworkOpenInfo)
{
/* Forward the call onto the device we attached to */
return FastIoDispatch->FastIoQueryNetworkOpenInfo(FileObject,
Wait,
Buffer,
IoStatus,
AttachedDeviceObject);
}
/* We failed to handle the request, send it down the slow path */
FLT_ASSERT(FALSE);
return FALSE;
}
BOOLEAN
NTAPI
FltpFastIoMdlRead(_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)
{
PFLTMGR_DEVICE_EXTENSION DeviceExtension;
PDEVICE_OBJECT AttachedDeviceObject;
PFAST_IO_DISPATCH FastIoDispatch;
PAGED_CODE();
/* If it doesn't have a device extension, then it's not our device object */
if (DeviceObject->DeviceExtension == NULL)
{
/* Fail the call */
IoStatus->Status = STATUS_INVALID_DEVICE_REQUEST;
IoStatus->Information = 0;
return TRUE;
}
DeviceExtension = DeviceObject->DeviceExtension;
FLT_ASSERT(DeviceExtension->AttachedToDeviceObject);
/* Get the device that we attached to */
AttachedDeviceObject = DeviceExtension->AttachedToDeviceObject;
FastIoDispatch = AttachedDeviceObject->DriverObject->FastIoDispatch;
/* Make sure our FastIo table is valid */
if (FastIoDispatch && FastIoDispatch->MdlRead)
{
/* Forward the call onto the device we attached to */
return FastIoDispatch->MdlRead(FileObject,
FileOffset,
Length,
LockKey,
MdlChain,
IoStatus,
AttachedDeviceObject);
}
/* We failed to handle the request, send it down the slow path */
FLT_ASSERT(FALSE);
return FALSE;
}
BOOLEAN
NTAPI
FltpFastIoMdlReadComplete(_In_ PFILE_OBJECT FileObject,
_In_ PMDL MdlChain,
_In_ PDEVICE_OBJECT DeviceObject)
{
PFLTMGR_DEVICE_EXTENSION DeviceExtension;
PDEVICE_OBJECT AttachedDeviceObject;
PFAST_IO_DISPATCH FastIoDispatch;
PAGED_CODE();
/* If it doesn't have a device extension, then it's not our device object */
if (DeviceObject->DeviceExtension == NULL)
{
/* Fail the request, send it down the slow path */
return FALSE;
}
DeviceExtension = DeviceObject->DeviceExtension;
FLT_ASSERT(DeviceExtension->AttachedToDeviceObject);
/* Get the device that we attached to */
AttachedDeviceObject = DeviceExtension->AttachedToDeviceObject;
FastIoDispatch = AttachedDeviceObject->DriverObject->FastIoDispatch;
/* Make sure our FastIo table is valid */
if (FastIoDispatch && FastIoDispatch->MdlReadComplete)
{
/* Forward the call onto the device we attached to */
return FastIoDispatch->MdlReadComplete(FileObject,
MdlChain,
AttachedDeviceObject);
}
/* We failed to handle the request, send it down the slow path */
FLT_ASSERT(FALSE);
return FALSE;
}
BOOLEAN
NTAPI
FltpFastIoPrepareMdlWrite(_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)
{
PFLTMGR_DEVICE_EXTENSION DeviceExtension;
PDEVICE_OBJECT AttachedDeviceObject;
PFAST_IO_DISPATCH FastIoDispatch;
PAGED_CODE();
/* If it doesn't have a device extension, then it's not our device object */
if (DeviceObject->DeviceExtension == NULL)
{
/* Fail the call */
IoStatus->Status = STATUS_INVALID_DEVICE_REQUEST;
IoStatus->Information = 0;
return TRUE;
}
DeviceExtension = DeviceObject->DeviceExtension;
FLT_ASSERT(DeviceExtension->AttachedToDeviceObject);
/* Get the device that we attached to */
AttachedDeviceObject = DeviceExtension->AttachedToDeviceObject;
FastIoDispatch = AttachedDeviceObject->DriverObject->FastIoDispatch;
/* Make sure our FastIo table is valid */
if (FastIoDispatch && FastIoDispatch->PrepareMdlWrite)
{
/* Forward the call onto the device we attached to */
return FastIoDispatch->PrepareMdlWrite(FileObject,
FileOffset,
Length,
LockKey,
MdlChain,
IoStatus,
AttachedDeviceObject);
}
/* We failed to handle the request, send it down the slow path */
FLT_ASSERT(FALSE);
return FALSE;
}
BOOLEAN
NTAPI
FltpFastIoMdlWriteComplete(_In_ PFILE_OBJECT FileObject,
_In_ PLARGE_INTEGER FileOffset,
_In_ PMDL MdlChain,
_In_ PDEVICE_OBJECT DeviceObject)
{
PFLTMGR_DEVICE_EXTENSION DeviceExtension;
PDEVICE_OBJECT AttachedDeviceObject;
PFAST_IO_DISPATCH FastIoDispatch;
PAGED_CODE();
/* If it doesn't have a device extension, then it's not our device object */
if (DeviceObject->DeviceExtension == NULL)
{
/* Fail the request, send it down the slow path */
return FALSE;
}
DeviceExtension = DeviceObject->DeviceExtension;
FLT_ASSERT(DeviceExtension->AttachedToDeviceObject);
/* Get the device that we attached to */
AttachedDeviceObject = DeviceExtension->AttachedToDeviceObject;
FastIoDispatch = AttachedDeviceObject->DriverObject->FastIoDispatch;
/* Make sure our FastIo table is valid */
if (FastIoDispatch && FastIoDispatch->MdlWriteComplete)
{
/* Forward the call onto the device we attached to */
return FastIoDispatch->MdlWriteComplete(FileObject,
FileOffset,
MdlChain,
AttachedDeviceObject);
}
/* We failed to handle the request, send it down the slow path */
FLT_ASSERT(FALSE);
return FALSE;
}
BOOLEAN
NTAPI
FltpFastIoReadCompressed(_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_ PCOMPRESSED_DATA_INFO CompressedDataInfo,
_In_ ULONG CompressedDataInfoLength,
_In_ PDEVICE_OBJECT DeviceObject)
{
PFLTMGR_DEVICE_EXTENSION DeviceExtension;
PDEVICE_OBJECT AttachedDeviceObject;
PFAST_IO_DISPATCH FastIoDispatch;
PAGED_CODE();
/* If it doesn't have a device extension, then it's not our device object */
if (DeviceObject->DeviceExtension == NULL)
{
/* Fail the request, send it down the slow path */
return FALSE;
}
DeviceExtension = DeviceObject->DeviceExtension;
FLT_ASSERT(DeviceExtension->AttachedToDeviceObject);
/* Get the device that we attached to */
AttachedDeviceObject = DeviceExtension->AttachedToDeviceObject;
FastIoDispatch = AttachedDeviceObject->DriverObject->FastIoDispatch;
/* Make sure our FastIo table is valid */
if (FastIoDispatch && FastIoDispatch->FastIoReadCompressed)
{
/* Forward the call onto the device we attached to */
return FastIoDispatch->FastIoReadCompressed(FileObject,
FileOffset,
Length,
LockKey,
Buffer,
MdlChain,
IoStatus,
CompressedDataInfo,
CompressedDataInfoLength,
AttachedDeviceObject);
}
/* We failed to handle the request, send it down the slow path */
FLT_ASSERT(FALSE);
return FALSE;
}
BOOLEAN
NTAPI
FltpFastIoWriteCompressed(_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_ PCOMPRESSED_DATA_INFO CompressedDataInfo,
_In_ ULONG CompressedDataInfoLength,
_In_ PDEVICE_OBJECT DeviceObject)
{
PFLTMGR_DEVICE_EXTENSION DeviceExtension;
PDEVICE_OBJECT AttachedDeviceObject;
PFAST_IO_DISPATCH FastIoDispatch;
PAGED_CODE();
/* If it doesn't have a device extension, then it's not our device object */
if (DeviceObject->DeviceExtension == NULL)
{
/* Fail the request, send it down the slow path */
return FALSE;
}
DeviceExtension = DeviceObject->DeviceExtension;
FLT_ASSERT(DeviceExtension->AttachedToDeviceObject);
/* Get the device that we attached to */
AttachedDeviceObject = DeviceExtension->AttachedToDeviceObject;
FastIoDispatch = AttachedDeviceObject->DriverObject->FastIoDispatch;
/* Make sure our FastIo table is valid */
if (FastIoDispatch && FastIoDispatch->FastIoWriteCompressed)
{
/* Forward the call onto the device we attached to */
return FastIoDispatch->FastIoWriteCompressed(FileObject,
FileOffset,
Length,
LockKey,
Buffer,
MdlChain,
IoStatus,
CompressedDataInfo,
CompressedDataInfoLength,
AttachedDeviceObject);
}
/* We failed to handle the request, send it down the slow path */
FLT_ASSERT(FALSE);
return FALSE;
}
BOOLEAN
NTAPI
FltpFastIoMdlReadCompleteCompressed(_In_ PFILE_OBJECT FileObject,
_In_ PMDL MdlChain,
_In_ PDEVICE_OBJECT DeviceObject)
{
PFLTMGR_DEVICE_EXTENSION DeviceExtension;
PDEVICE_OBJECT AttachedDeviceObject;
PFAST_IO_DISPATCH FastIoDispatch;
PAGED_CODE();
/* If it doesn't have a device extension, then it's not our device object */
if (DeviceObject->DeviceExtension == NULL)
{
return FALSE;
}
DeviceExtension = DeviceObject->DeviceExtension;
FLT_ASSERT(DeviceExtension->AttachedToDeviceObject);
/* Get the device that we attached to */
AttachedDeviceObject = DeviceExtension->AttachedToDeviceObject;
FastIoDispatch = AttachedDeviceObject->DriverObject->FastIoDispatch;
/* Make sure our FastIo table is valid */
if (FastIoDispatch && FastIoDispatch->MdlReadCompleteCompressed)
{
/* Forward the call onto the device we attached to */
return FastIoDispatch->MdlReadCompleteCompressed(FileObject,
MdlChain,
AttachedDeviceObject);
}
/* We failed to handle the request, send it down the slow path */
FLT_ASSERT(FALSE);
return FALSE;
}
BOOLEAN
NTAPI
FltpFastIoMdlWriteCompleteCompressed(_In_ PFILE_OBJECT FileObject,
_In_ PLARGE_INTEGER FileOffset,
_In_ PMDL MdlChain,
_In_ PDEVICE_OBJECT DeviceObject)
{
PFLTMGR_DEVICE_EXTENSION DeviceExtension;
PDEVICE_OBJECT AttachedDeviceObject;
PFAST_IO_DISPATCH FastIoDispatch;
PAGED_CODE();
/* If it doesn't have a device extension, then it's not our device object */
if (DeviceObject->DeviceExtension == NULL)
{
return FALSE;
}
DeviceExtension = DeviceObject->DeviceExtension;
FLT_ASSERT(DeviceExtension->AttachedToDeviceObject);
/* Get the device that we attached to */
AttachedDeviceObject = DeviceExtension->AttachedToDeviceObject;
FastIoDispatch = AttachedDeviceObject->DriverObject->FastIoDispatch;
/* Make sure our FastIo table is valid */
if (FastIoDispatch && FastIoDispatch->MdlWriteCompleteCompressed)
{
/* Forward the call onto the device we attached to */
return FastIoDispatch->MdlWriteCompleteCompressed(FileObject,
FileOffset,
MdlChain,
AttachedDeviceObject);
}
/* We failed to handle the request, send it down the slow path */
FLT_ASSERT(FALSE);
return FALSE;
}
BOOLEAN
NTAPI
FltpFastIoQueryOpen(_Inout_ PIRP Irp,
_Out_ PFILE_NETWORK_OPEN_INFORMATION NetworkInformation,
_In_ PDEVICE_OBJECT DeviceObject)
{
PFLTMGR_DEVICE_EXTENSION DeviceExtension;
PDEVICE_OBJECT AttachedDeviceObject;
PFAST_IO_DISPATCH FastIoDispatch;
BOOLEAN Success;
PAGED_CODE();
/* If it doesn't have a device extension, then it's not our device object */
if (DeviceObject->DeviceExtension == NULL)
{
return FALSE;
}
DeviceExtension = DeviceObject->DeviceExtension;
FLT_ASSERT(DeviceExtension->AttachedToDeviceObject);
/* Get the device that we attached to */
AttachedDeviceObject = DeviceExtension->AttachedToDeviceObject;
FastIoDispatch = AttachedDeviceObject->DriverObject->FastIoDispatch;
/* Make sure our FastIo table is valid */
if (FastIoDispatch && FastIoDispatch->FastIoQueryOpen)
{
PIO_STACK_LOCATION StackPtr = IoGetCurrentIrpStackLocation(Irp);
/* Update the stack to contain the correct device for the next filter */
StackPtr->DeviceObject = AttachedDeviceObject;
/* Now forward the call */
Success = FastIoDispatch->FastIoQueryOpen(Irp,
NetworkInformation,
AttachedDeviceObject);
/* Restore the DeviceObject as we found it */
StackPtr->DeviceObject = DeviceObject;
return Success;
}
/* We failed to handle the request, send it down the slow path */
FLT_ASSERT(FALSE);
return FALSE;
}
/* FUNCTIONS **********************************************/
static
VOID
FltpCleanupDeviceObject(_In_ PDEVICE_OBJECT DeviceObject)
{
PFLTMGR_DEVICE_EXTENSION DeviceExtension;
DeviceExtension = DeviceObject->DeviceExtension;
if (DeviceExtension)
{
// cleanup device extension
}
}
static
NTSTATUS
FltpAttachDeviceObject(_In_ PDEVICE_OBJECT SourceDevice,
_In_ PDEVICE_OBJECT TargetDevice,
_Out_ PDEVICE_OBJECT *AttachedToDeviceObject)
{
NTSTATUS Status;
PAGED_CODE();
/* Before attaching, copy the flags from the device we're going to attach to */
if (FlagOn(SourceDevice->Flags, DO_BUFFERED_IO))
{
SetFlag(TargetDevice->Flags, DO_BUFFERED_IO);
}
if (FlagOn(SourceDevice->Flags, DO_DIRECT_IO))
{
SetFlag(TargetDevice->Flags, DO_DIRECT_IO);
}
if (FlagOn(SourceDevice->Flags, DO_SYSTEM_BOOT_PARTITION))
{
SetFlag(TargetDevice->Characteristics, FILE_DEVICE_SECURE_OPEN);
}
/* Attach this device to the top of the driver stack */
Status = IoAttachDeviceToDeviceStackSafe(SourceDevice,
TargetDevice,
AttachedToDeviceObject);
return Status;
}
static
BOOLEAN
FltpIsAttachedToDevice(_In_ PDEVICE_OBJECT DeviceObject,
_In_opt_ PDEVICE_OBJECT *AttachedDeviceObject)
{
PDEVICE_OBJECT CurrentDeviceObject;
PDEVICE_OBJECT NextDeviceObject;
PAGED_CODE();
/* Initialize the return pointer */
if (AttachedDeviceObject) *AttachedDeviceObject = NULL;
/* Start by getting the top level device in the chain */
CurrentDeviceObject = IoGetAttachedDeviceReference(DeviceObject);
/* Loop while there are attached devices */
while (CurrentDeviceObject)
{
/* Check if this device driver matches ours */
if (CurrentDeviceObject->DriverObject == DriverData.DriverObject)
{
FLT_ASSERT(CurrentDeviceObject->DeviceExtension != NULL);
/* We're attached, return the device object if the caller asked for it */
if (AttachedDeviceObject)
{
*AttachedDeviceObject = CurrentDeviceObject;
}
else
{
/* We aren't returning the reference, so decrement the count */
ObDereferenceObject(CurrentDeviceObject);
}
return TRUE;
}
/* Get the next device in the chain */
NextDeviceObject = IoGetLowerDeviceObject(CurrentDeviceObject);
/* Decrement the count on the last device before we update the pointer */
ObDereferenceObject(CurrentDeviceObject);
CurrentDeviceObject = NextDeviceObject;
}
return FALSE;
}
static
NTSTATUS
FltpEnumerateFileSystemVolumes(_In_ PDEVICE_OBJECT DeviceObject)
{
PFLTMGR_DEVICE_EXTENSION NewDeviceExtension;
PDEVICE_OBJECT BaseDeviceObject;
PDEVICE_OBJECT NewDeviceObject;
PDEVICE_OBJECT *DeviceList;
PDEVICE_OBJECT StorageStackDeviceObject;
UNICODE_STRING DeviceName;
ULONG NumDevices;
ULONG i;
NTSTATUS Status;
PAGED_CODE();
/* Get the base device */
BaseDeviceObject = IoGetDeviceAttachmentBaseRef(DeviceObject);
/* get the number of device object linked to the base file system */
Status = IoEnumerateDeviceObjectList(BaseDeviceObject->DriverObject,
NULL,
0,
&NumDevices);
if (Status != STATUS_BUFFER_TOO_SMALL) return Status;
/* Add a few more slots in case the size changed between calls and allocate some memory to hold the pointers */
NumDevices += 4;
DeviceList = ExAllocatePoolWithTag(NonPagedPool,
(NumDevices * sizeof(PDEVICE_OBJECT)),
FM_TAG_DEV_OBJ_PTRS);
if (DeviceList == NULL) return STATUS_INSUFFICIENT_RESOURCES;
/* Now get all the device objects that this base driver has created */
Status = IoEnumerateDeviceObjectList(BaseDeviceObject->DriverObject,
DeviceList,
(NumDevices * sizeof(PDEVICE_OBJECT)),
&NumDevices);
if (!NT_SUCCESS(Status))
{
ExFreePoolWithTag(DeviceList, FM_TAG_DEV_OBJ_PTRS);
return Status;
}
/* Loop through all the devices looking for ones to attach to */
for (i = 0; i < NumDevices; i++)
{
RtlInitUnicodeString(&DeviceName, NULL);
StorageStackDeviceObject = NULL;
NewDeviceObject = NULL;
/* Ignore the device we passed in, and devices of the wrong type */
if ((DeviceList[i] == BaseDeviceObject) ||
(DeviceList[i]->DeviceType != BaseDeviceObject->DeviceType))
{
goto CleanupAndNext;
}
/* Ignore this device if we're already attached to it */
if (FltpIsAttachedToDevice(DeviceList[i], NULL) == FALSE)
{
goto CleanupAndNext;
}
/*
* If the device has a name, it must be a control device.
* This handles drivers with more then one control device (like FastFat)
*/
FltpGetBaseDeviceObjectName(DeviceList[i], &DeviceName);
if (NT_SUCCESS(Status) && DeviceName.Length > 0)
{
goto CleanupAndNext;
}
/*
* Try to get the storage stack (disk) device object associated with
* this file system device object. Ignore the device if we don't have one
*/
Status = IoGetDiskDeviceObject(DeviceList[i],
&StorageStackDeviceObject);
if (!NT_SUCCESS(Status))
{
goto CleanupAndNext;
}
/*
* TODO: Don't attach to shadow copy volumes,
* ros doesn't have any so it's not an issues yet
*/
/*
* We're far enough to be ready to attach, create a device
* object which we'll use to do so
*/
Status = IoCreateDevice(DriverData.DriverObject,
sizeof(FLTMGR_DEVICE_EXTENSION),
NULL,
DeviceList[i]->DeviceType,
0,
FALSE,
&NewDeviceObject);
if (!NT_SUCCESS(Status))
{
goto CleanupAndNext;
}
/* Get the device extension for this new object and store our disk object there */
NewDeviceExtension = NewDeviceObject->DeviceExtension;
NewDeviceExtension->StorageStackDeviceObject = StorageStackDeviceObject;
/* Lookup and store the device name for the storage stack */
RtlInitEmptyUnicodeString(&NewDeviceExtension->DeviceName,
NewDeviceExtension->DeviceNameBuffer,
sizeof(NewDeviceExtension->DeviceNameBuffer));
FltpGetObjectName(StorageStackDeviceObject,
&NewDeviceExtension->DeviceName);
/* Grab the attach lock before we attempt to attach */
ExAcquireFastMutex(&DriverData.FilterAttachLock);
/* Check again that we aren't already attached. It may have changed since our last check */
if (FltpIsAttachedToDevice(DeviceList[i], NULL) == FALSE)
{
FLT_ASSERT(NewDeviceObject->DriverObject == DriverData.DriverObject);
/* Finally, attach to the volume */
Status = FltpAttachDeviceObject(DeviceList[i],
NewDeviceObject,
&NewDeviceExtension->AttachedToDeviceObject);
if (NT_SUCCESS(Status))
{
/* Clean the initializing flag so other filters can attach to our device object */
ClearFlag(NewDeviceObject->Flags, DO_DEVICE_INITIALIZING);
}
}
else
{
/* We're already attached. Just cleanup */
Status = STATUS_DEVICE_ALREADY_ATTACHED;
}
ExReleaseFastMutex(&DriverData.FilterAttachLock);
CleanupAndNext:
if (!NT_SUCCESS(Status))
{
if (NewDeviceObject)
{
FltpCleanupDeviceObject(NewDeviceObject);
IoDeleteDevice(NewDeviceObject);
}
}
if (StorageStackDeviceObject)
{
/* A ref was added for us when we attached, so we can deref ours now */
ObDereferenceObject(StorageStackDeviceObject);
}
/* Remove the ref which was added by IoEnumerateDeviceObjectList */
ObDereferenceObject(DeviceList[i]);
/* Free the buffer that FltpGetBaseDeviceObjectName added */
FltpFreeUnicodeString(&DeviceName);
}
/* Free the memory we allocated for the list */
ExFreePoolWithTag(DeviceList, FM_TAG_DEV_OBJ_PTRS);
return STATUS_SUCCESS;
}
static
NTSTATUS
FltpAttachToFileSystemDevice(_In_ PDEVICE_OBJECT DeviceObject,
_In_ PUNICODE_STRING DeviceName)
{
PFLTMGR_DEVICE_EXTENSION DeviceExtension;
PDEVICE_OBJECT NewDeviceObject;
WCHAR Buffer[MAX_DEVNAME_LENGTH];
UNICODE_STRING FileSystemDeviceName;
UNICODE_STRING FsRecDeviceName;
NTSTATUS Status;
PAGED_CODE();
/* Only handle device types we're interested in */
if (DeviceObject->DeviceType != FILE_DEVICE_DISK_FILE_SYSTEM &&
DeviceObject->DeviceType != FILE_DEVICE_CD_ROM_FILE_SYSTEM &&
DeviceObject->DeviceType != FILE_DEVICE_NETWORK_FILE_SYSTEM)
{
return STATUS_SUCCESS;
}
/* Setup the buffer to hold the device name */
RtlInitEmptyUnicodeString(&FileSystemDeviceName,
Buffer,
MAX_DEVNAME_LENGTH * sizeof(WCHAR));
/* Get the the name of the file system device */
Status = FltpGetObjectName(DeviceObject->DriverObject, &FileSystemDeviceName);
if (!NT_SUCCESS(Status)) return Status;
DPRINT("Found device %wZ, checking if we need to attach...\n", &FileSystemDeviceName);
/* Build up the name of the file system recognizer device */
RtlInitUnicodeString(&FsRecDeviceName, L"\\FileSystem\\Fs_Rec");
/* We don't attach to recognizer devices, so bail if this is one */
if (RtlCompareUnicodeString(&FileSystemDeviceName, &FsRecDeviceName, TRUE) == 0)
{
return STATUS_SUCCESS;
}
/* Create a device object which we can attach to this file system */
Status = IoCreateDevice(DriverData.DriverObject,
sizeof(FLTMGR_DEVICE_EXTENSION),
NULL,
DeviceObject->DeviceType,
0,
FALSE,
&NewDeviceObject);
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to create a DO for attaching to a FS : 0x%X\n", Status);
return Status;
}
/* Cast the device extension to something we understand */
DeviceExtension = NewDeviceObject->DeviceExtension;
/* Attach this device to the top of the driver stack and store the DO we attached to in the DE */
Status = FltpAttachDeviceObject(NewDeviceObject,
DeviceObject,
&DeviceExtension->AttachedToDeviceObject);
if (NT_SUCCESS(Status))
{
DPRINT("Attached to %wZ\n", &FileSystemDeviceName);
}
else
{
DPRINT1("Failed to attach to the driver stack : 0x%X\n", Status);
goto Cleanup;
}
/* Setup the unicode string buffer and copy the device name to the device extension */
RtlInitEmptyUnicodeString(&DeviceExtension->DeviceName,
DeviceExtension->DeviceNameBuffer,
MAX_DEVNAME_LENGTH * sizeof(WCHAR));
RtlCopyUnicodeString(&DeviceExtension->DeviceName, DeviceName);
/* We're done, remove the initializing flag */
ClearFlag(NewDeviceObject->Flags, DO_DEVICE_INITIALIZING);
/* Look for existing mounted devices for this file system */
Status = FltpEnumerateFileSystemVolumes(DeviceObject);
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to enumerate file system volumes for this file system : 0x%X\n", Status);
IoDetachDevice(DeviceExtension->AttachedToDeviceObject);
}
Cleanup:
if (!NT_SUCCESS(Status))
{
IoDeleteDevice(NewDeviceObject);
}
return Status;
}
static
LONG_PTR
FltpDetachFromFileSystemDevice(_In_ PDEVICE_OBJECT DeviceObject)
{
PDEVICE_OBJECT AttachedDevice, NextDevice;
PFLTMGR_DEVICE_EXTENSION DeviceExtension;
LONG_PTR Count;
PAGED_CODE();
/* Get the top device in the chain and increment the ref count on it */
AttachedDevice = IoGetAttachedDeviceReference(DeviceObject);
/* Loop all attached devices looking for our file system driver */
while (AttachedDevice->DriverObject != DriverData.DriverObject)
{
FLT_ASSERT(AttachedDevice != NULL);
/* Get the next lower device object. This adds a ref on NextDevice */
NextDevice = IoGetLowerDeviceObject(AttachedDevice);
/* Remove the reference we added */
Count = ObDereferenceObject(AttachedDevice);
/* Bail if this is the last one */
if (NextDevice == NULL) return Count;
/* Try the next one */
AttachedDevice = NextDevice;
}
DeviceExtension = AttachedDevice->DeviceExtension;
if (DeviceExtension)
{
//
// FIXME: Put any device extension cleanup code here
//
}
/* Detach the device from the chain and delete the object */
IoDetachDevice(DeviceObject);
IoDeleteDevice(AttachedDevice);
/* Remove the reference we added so the delete can complete */
return ObDereferenceObject(AttachedDevice);
}
DRIVER_FS_NOTIFICATION FltpFsNotification;
VOID
NTAPI
FltpFsNotification(_In_ PDEVICE_OBJECT DeviceObject,
_In_ BOOLEAN FsActive)
{
UNICODE_STRING DeviceName;
NTSTATUS Status;
PAGED_CODE();
/* Set an empty string */
RtlInitUnicodeString(&DeviceName, NULL);
/* Get the name of the lowest device object on the stack */
Status = FltpGetBaseDeviceObjectName(DeviceObject, &DeviceName);
if (NT_SUCCESS(Status))
{
/* Check if it's attaching or detaching */
if (FsActive)
{
/* Run the attach routine */
FltpAttachToFileSystemDevice(DeviceObject, &DeviceName);
}
else
{
/* Run the detach routine */
FltpDetachFromFileSystemDevice(DeviceObject);
}
/* Free the buffer which FltpGetBaseDeviceObjectName allocated */
FltpFreeUnicodeString(&DeviceName);
}
}
DRIVER_INITIALIZE DriverEntry;
NTSTATUS
NTAPI
DriverEntry(_In_ PDRIVER_OBJECT DriverObject,
_In_ PUNICODE_STRING RegistryPath)
{
UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\FileSystem\\Filters\\"DRIVER_NAME);
PDEVICE_OBJECT RawDeviceObject;
PDEVICE_OBJECT DeviceObject;
PFILE_OBJECT RawFileObject;
UNICODE_STRING ObjectName;
UNICODE_STRING SymLink;
NTSTATUS Status;
RtlZeroMemory(&DriverData, sizeof(DRIVER_DATA));
DriverData.DriverObject = DriverObject;
/* Save the registry key for this driver */
DriverData.ServiceKey.Length = RegistryPath->Length;
DriverData.ServiceKey.MaximumLength = RegistryPath->MaximumLength;
DriverData.ServiceKey.Buffer = (PWCHAR)ExAllocatePoolWithTag(NonPagedPool,
RegistryPath->MaximumLength,
FM_TAG_REGISTRY_DATA);
if (!DriverData.ServiceKey.Buffer) return STATUS_INSUFFICIENT_RESOURCES;
RtlCopyUnicodeString(&DriverData.ServiceKey, RegistryPath);
/* Do some initialization */
ExInitializeFastMutex(&DriverData.FilterAttachLock);
/* Create the main filter manager device object */
Status = IoCreateDevice(DriverObject,
0,
&DeviceName,
FILE_DEVICE_DISK_FILE_SYSTEM,
FILE_DEVICE_SECURE_OPEN,
FALSE,
&DeviceObject);
if (!NT_SUCCESS(Status))
{
DPRINT1("fltmgr IoCreateDevice failed. Status = %X\n", Status);
goto Cleanup;
}
/* Store a global reference so we can access from callbacks */
DriverData.DeviceObject = DeviceObject;
/* Generate the symbolic link name */
RtlInitUnicodeString(&SymLink, L"\\??\\"DRIVER_NAME);
Status = IoCreateSymbolicLink(&SymLink, &DeviceName);
if (!NT_SUCCESS(Status)) goto Cleanup;
/* Create the callbacks for the dispatch table, FastIo and FS callbacks */
Status = SetupDispatchAndCallbacksTables(DriverObject);
if (!NT_SUCCESS(Status)) goto Cleanup;
/* Initialize the comms objects */
Status = FltpSetupCommunicationObjects(DriverObject);
if (!NT_SUCCESS(Status)) goto Cleanup;
/* Register for notifications when a new file system is loaded. This also enumerates any existing file systems */
Status = IoRegisterFsRegistrationChange(DriverObject, FltpFsNotification);
FLT_ASSERT(Status != STATUS_DEVICE_ALREADY_ATTACHED); // Windows checks for this, I'm not sure how it can happen. Needs investigation??
if (!NT_SUCCESS(Status)) goto Cleanup;
InitializeListHead(&FilterList);
ExInitializeResourceLite(&FilterListLock);
/* IoRegisterFsRegistrationChange isn't notified about the raw file systems, so we attach to them manually */
RtlInitUnicodeString(&ObjectName, L"\\Device\\RawDisk");
Status = IoGetDeviceObjectPointer(&ObjectName,
FILE_READ_ATTRIBUTES,
&RawFileObject,
&RawDeviceObject);
if (NT_SUCCESS(Status))
{
FltpFsNotification(RawDeviceObject, TRUE);
ObDereferenceObject(RawFileObject);
}
RtlInitUnicodeString(&ObjectName, L"\\Device\\RawCdRom");
Status = IoGetDeviceObjectPointer(&ObjectName,
FILE_READ_ATTRIBUTES,
&RawFileObject,
&RawDeviceObject);
if (NT_SUCCESS(Status))
{
FltpFsNotification(RawDeviceObject, TRUE);
ObDereferenceObject(RawFileObject);
}
/* We're done, clear the initializing flag */
ClearFlag(DeviceObject->Flags, DO_DEVICE_INITIALIZING);
Status = STATUS_SUCCESS;
Cleanup:
if (!NT_SUCCESS(Status))
{
if (DriverData.FastIoDispatch)
{
DriverObject->FastIoDispatch = NULL;
ExFreePoolWithTag(DriverData.FastIoDispatch, FM_TAG_DISPATCH_TABLE);
}
IoDeleteSymbolicLink(&SymLink);
if (DeviceObject)
IoDeleteDevice(DeviceObject);
if (DriverData.ServiceKey.Buffer)
ExFreePoolWithTag(DriverData.ServiceKey.Buffer, FM_TAG_REGISTRY_DATA);
}
return Status;
}
static
NTSTATUS
SetupDispatchAndCallbacksTables(_In_ PDRIVER_OBJECT DriverObject)
{
PFAST_IO_DISPATCH FastIoDispatch;
FS_FILTER_CALLBACKS Callbacks;
ULONG i;
/* Plug all the IRPs */
for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
{
DriverObject->MajorFunction[i] = FltpDispatch;
}
/* Override the ones we're interested in */
DriverObject->MajorFunction[IRP_MJ_CREATE] = FltpCreate;
DriverObject->MajorFunction[IRP_MJ_CREATE_NAMED_PIPE] = FltpCreate;
DriverObject->MajorFunction[IRP_MJ_CREATE_MAILSLOT] = FltpCreate;
DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = FltpFsControl;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = FltpDeviceControl;
/* The FastIo dispatch table is stored in the pool along with a tag */
FastIoDispatch = ExAllocatePoolWithTag(NonPagedPool, sizeof(FAST_IO_DISPATCH), FM_TAG_DISPATCH_TABLE);
if (FastIoDispatch == NULL) return STATUS_INSUFFICIENT_RESOURCES;
/* Fill out the FastIo table */
RtlZeroMemory(FastIoDispatch, sizeof(FAST_IO_DISPATCH));
FastIoDispatch->SizeOfFastIoDispatch = sizeof(FAST_IO_DISPATCH);
FastIoDispatch->FastIoCheckIfPossible = FltpFastIoCheckIfPossible;
FastIoDispatch->FastIoRead = FltpFastIoRead;
FastIoDispatch->FastIoWrite = FltpFastIoWrite;
FastIoDispatch->FastIoQueryBasicInfo = FltpFastIoQueryBasicInfo;
FastIoDispatch->FastIoQueryStandardInfo = FltpFastIoQueryStandardInfo;
FastIoDispatch->FastIoLock = FltpFastIoLock;
FastIoDispatch->FastIoUnlockSingle = FltpFastIoUnlockSingle;
FastIoDispatch->FastIoUnlockAll = FltpFastIoUnlockAll;
FastIoDispatch->FastIoUnlockAllByKey = FltpFastIoUnlockAllByKey;
FastIoDispatch->FastIoDeviceControl = FltpFastIoDeviceControl;
FastIoDispatch->FastIoDetachDevice = FltpFastIoDetachDevice;
FastIoDispatch->FastIoQueryNetworkOpenInfo = FltpFastIoQueryNetworkOpenInfo;
FastIoDispatch->MdlRead = FltpFastIoMdlRead;
FastIoDispatch->MdlReadComplete = FltpFastIoMdlReadComplete;
FastIoDispatch->PrepareMdlWrite = FltpFastIoPrepareMdlWrite;
FastIoDispatch->MdlWriteComplete = FltpFastIoMdlWriteComplete;
FastIoDispatch->FastIoReadCompressed = FltpFastIoReadCompressed;
FastIoDispatch->FastIoWriteCompressed = FltpFastIoWriteCompressed;
FastIoDispatch->MdlReadCompleteCompressed = FltpFastIoMdlReadCompleteCompressed;
FastIoDispatch->MdlWriteCompleteCompressed = FltpFastIoMdlWriteCompleteCompressed;
FastIoDispatch->FastIoQueryOpen = FltpFastIoQueryOpen;
/* Store the FastIo table for internal and our access */
DriverObject->FastIoDispatch = FastIoDispatch;
DriverData.FastIoDispatch = FastIoDispatch;
/* Initialize the callback table */
Callbacks.SizeOfFsFilterCallbacks = sizeof(FS_FILTER_CALLBACKS);
Callbacks.PreAcquireForSectionSynchronization = FltpPreFsFilterOperation;
Callbacks.PostAcquireForSectionSynchronization = FltpPostFsFilterOperation;
Callbacks.PreReleaseForSectionSynchronization = FltpPreFsFilterOperation;
Callbacks.PostReleaseForSectionSynchronization = FltpPostFsFilterOperation;
Callbacks.PreAcquireForCcFlush = FltpPreFsFilterOperation;
Callbacks.PostAcquireForCcFlush = FltpPostFsFilterOperation;
Callbacks.PreReleaseForCcFlush = FltpPreFsFilterOperation;
Callbacks.PostReleaseForCcFlush = FltpPostFsFilterOperation;
Callbacks.PreAcquireForModifiedPageWriter = FltpPreFsFilterOperation;
Callbacks.PostAcquireForModifiedPageWriter = FltpPostFsFilterOperation;
Callbacks.PreReleaseForModifiedPageWriter = FltpPreFsFilterOperation;
Callbacks.PostReleaseForModifiedPageWriter = FltpPostFsFilterOperation;
/* Register our callbacks */
return FsRtlRegisterFileSystemFilterCallbacks(DriverObject, &Callbacks);
}