Author: gedmurphy
Date: Mon Jan  4 12:50:06 2016
New Revision: 70488

URL: http://svn.reactos.org/svn/reactos?rev=70488&view=rev
Log:
[FLTMGR]
- Plug in the dispatch routines. These are just pass through methods for now to 
get the filter up and running.
- Implement the FastIo handlers. The majority of these call the FastIo routines 
of the attached device object.
- Make sure we detach from devices that are being deleted in FastIoDetachDevice.
- Move the FastIoDetachDevice routine to a deferred call as it's too expensive 
to tie up a FastIo request.

Modified:
    trunk/reactos/drivers/fs_minifilter/fltmgr/Interface.c

Modified: trunk/reactos/drivers/fs_minifilter/fltmgr/Interface.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/fs_minifilter/fltmgr/Interface.c?rev=70488&r1=70487&r2=70488&view=diff
==============================================================================
--- trunk/reactos/drivers/fs_minifilter/fltmgr/Interface.c      [iso-8859-1] 
(original)
+++ trunk/reactos/drivers/fs_minifilter/fltmgr/Interface.c      [iso-8859-1] 
Mon Jan  4 12:50:06 2016
@@ -36,6 +36,12 @@
     _In_ PDEVICE_OBJECT SourceDevice,
     _In_ PDEVICE_OBJECT Targetevice,
     _Out_ PDEVICE_OBJECT *AttachedToDeviceObject
+);
+
+static
+VOID
+FltpCleanupDeviceObject(
+    _In_ PDEVICE_OBJECT DeviceObject
 );
 
 static
@@ -94,8 +100,6 @@
     /* The file system we're attached to */
     PDEVICE_OBJECT AttachedToDeviceObject;
 
-    //  Pointer to the real (disk) device object that is associated with
-    //  the file system device object we are attached to
     /* The storage stack(disk) accociated with the file system device object 
we're attached to */
     PDEVICE_OBJECT StorageStackDeviceObject;
 
@@ -106,7 +110,13 @@
 
 } FLTMGR_DEVICE_EXTENSION, *PFLTMGR_DEVICE_EXTENSION;
 
-
+typedef struct _DETATCH_DEVICE_WORK_ITEM
+{
+    WORK_QUEUE_ITEM WorkItem;
+    PDEVICE_OBJECT SourceDevice;
+    PDEVICE_OBJECT TargetDevice;
+
+} DETATCH_DEVICE_WORK_ITEM, *PDETATCH_DEVICE_WORK_ITEM;
 
 
 /* DISPATCH ROUTINES **********************************************/
@@ -139,10 +149,15 @@
 FltpDispatch(_In_ PDEVICE_OBJECT DeviceObject,
              _Inout_ PIRP Irp)
 {
-    UNREFERENCED_PARAMETER(DeviceObject);
-    UNREFERENCED_PARAMETER(Irp);
+    PFLTMGR_DEVICE_EXTENSION DeviceExtension;
+    DeviceExtension = DeviceObject->DeviceExtension;
     __debugbreak();
-    return STATUS_SUCCESS;
+    FLT_ASSERT(DeviceExtension &&
+               DeviceExtension->AttachedToDeviceObject);
+
+    /* Just pass the IRP down the stack */
+    IoSkipCurrentIrpStackLocation(Irp);
+    return IoCallDriver(DeviceExtension->AttachedToDeviceObject, Irp);
 }
 
 NTSTATUS
@@ -150,10 +165,15 @@
 FltpCreate(_In_ PDEVICE_OBJECT DeviceObject,
            _Inout_ PIRP Irp)
 {
-    UNREFERENCED_PARAMETER(DeviceObject);
-    UNREFERENCED_PARAMETER(Irp);
+    PFLTMGR_DEVICE_EXTENSION DeviceExtension;
+    DeviceExtension = DeviceObject->DeviceExtension;
     __debugbreak();
-    return STATUS_SUCCESS;
+    FLT_ASSERT(DeviceExtension &&
+               DeviceExtension->AttachedToDeviceObject);
+
+    /* Just pass the IRP down the stack */
+    IoSkipCurrentIrpStackLocation(Irp);
+    return IoCallDriver(DeviceExtension->AttachedToDeviceObject, Irp);
 }
 
 NTSTATUS
@@ -161,16 +181,1025 @@
 FltpFsControl(_In_ PDEVICE_OBJECT DeviceObject,
               _Inout_ PIRP Irp)
 {
-    UNREFERENCED_PARAMETER(DeviceObject);
-    UNREFERENCED_PARAMETER(Irp);
+    PFLTMGR_DEVICE_EXTENSION DeviceExtension;
+    DeviceExtension = DeviceObject->DeviceExtension;
     __debugbreak();
-    return STATUS_SUCCESS;
+    FLT_ASSERT(DeviceExtension &&
+               DeviceExtension->AttachedToDeviceObject);
+    /* Just pass the IRP down the stack */
+    IoSkipCurrentIrpStackLocation(Irp);
+    return IoCallDriver(DeviceExtension->AttachedToDeviceObject, Irp);
+}
+
+
+
+/* FASTIO ROUTINES ************************************************/
+
+BOOLEAN
+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
+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
+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
+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
+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
+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
+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
+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
+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
+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
+FltpFastIoDetatchDeviceWorker(_In_ PVOID Parameter)
+{
+    PDETATCH_DEVICE_WORK_ITEM DetatchDeviceWorkItem = Parameter;
+
+    /* Run any cleanup routines */
+    FltpCleanupDeviceObject(DetatchDeviceWorkItem->SourceDevice);
+
+    /* Detatch from the target device */
+    IoDetachDevice(DetatchDeviceWorkItem->TargetDevice);
+
+    /* Delete the source */
+    IoDeleteDevice(DetatchDeviceWorkItem->SourceDevice);
+
+    /* Free the pool we allocated in FltpFastIoDetachDevice */
+    ExFreePoolWithTag(DetatchDeviceWorkItem, 0x1234);
+}
+
+VOID
+FltpFastIoDetachDevice(_In_ PDEVICE_OBJECT SourceDevice,
+                     _In_ PDEVICE_OBJECT TargetDevice)
+{
+    PDETATCH_DEVICE_WORK_ITEM DetatchDeviceWorkItem;
+
+    PAGED_CODE();
+
+    /*
+     * Detatching 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 */
+    DetatchDeviceWorkItem = ExAllocatePoolWithTag(NonPagedPool,
+                                                  
sizeof(DETATCH_DEVICE_WORK_ITEM),
+                                                  0x1234);
+    if (DetatchDeviceWorkItem)
+    {
+        /* Initialize the work item */
+        ExInitializeWorkItem(&DetatchDeviceWorkItem->WorkItem,
+                             FltpFastIoDetatchDeviceWorker,
+                             DetatchDeviceWorkItem);
+
+        /* Queue the work item and return the call */
+        ExQueueWorkItem(&DetatchDeviceWorkItem->WorkItem,
+                        DelayedWorkQueue);
+    }
+    else
+    {
+        /* We failed to defer, just cleanup here */
+        FltpCleanupDeviceObject(SourceDevice);
+        IoDetachDevice(TargetDevice);
+        IoDeleteDevice(SourceDevice);
+    }
+
+}
+
+BOOLEAN
+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
+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
+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
+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
+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
+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
+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
+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
+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
+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)
 {
@@ -555,7 +1584,8 @@
     AttachedDevice = IoGetAttachedDeviceReference(DeviceObject);
 
     /* Loop through all attached devices until we reach the bottom (file 
system driver) */
-    while (AttachedDevice->DriverObject != DriverData.DriverObject)
+    while (AttachedDevice == NULL ||
+           AttachedDevice->DriverObject != DriverData.DriverObject)
     {
         /* Get the attached device */
         LowestDevice = IoGetLowerDeviceObject(AttachedDevice);
@@ -682,7 +1712,7 @@
 
     /* 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, but I'm not sure how that can happen??
+    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;
 
     /* IoRegisterFsRegistrationChange isn't notified about the raw  file 
systems, so we attach to them manually */
@@ -762,29 +1792,30 @@
     /* Fill out the FastIo table  */
     RtlZeroMemory(FastIoDispatch, sizeof(FAST_IO_DISPATCH));
     FastIoDispatch->SizeOfFastIoDispatch = sizeof(FAST_IO_DISPATCH);
-    FastIoDispatch->FastIoCheckIfPossible = (PFAST_IO_CHECK_IF_POSSIBLE)NULL;
-    FastIoDispatch->FastIoRead = (PFAST_IO_READ)NULL;
-    FastIoDispatch->FastIoWrite = (PFAST_IO_WRITE)NULL;
-    FastIoDispatch->FastIoQueryBasicInfo = (PFAST_IO_QUERY_BASIC_INFO)NULL;
-    FastIoDispatch->FastIoQueryStandardInfo = 
(PFAST_IO_QUERY_STANDARD_INFO)NULL;
-    FastIoDispatch->FastIoLock = (PFAST_IO_LOCK)NULL;
-    FastIoDispatch->FastIoUnlockSingle = (PFAST_IO_UNLOCK_SINGLE)NULL;
-    FastIoDispatch->FastIoUnlockAll = (PFAST_IO_UNLOCK_ALL)NULL;
-    FastIoDispatch->FastIoUnlockAllByKey = (PFAST_IO_UNLOCK_ALL_BY_KEY)NULL;
-    FastIoDispatch->FastIoDeviceControl = (PFAST_IO_DEVICE_CONTROL)NULL;
-    FastIoDispatch->FastIoDetachDevice = (PFAST_IO_DETACH_DEVICE)NULL;
-    FastIoDispatch->FastIoQueryNetworkOpenInfo = 
(PFAST_IO_QUERY_NETWORK_OPEN_INFO)NULL;
-    FastIoDispatch->MdlRead = (PFAST_IO_MDL_READ)NULL;
-    FastIoDispatch->MdlReadComplete = (PFAST_IO_MDL_READ_COMPLETE)NULL;
-    FastIoDispatch->PrepareMdlWrite = (PFAST_IO_PREPARE_MDL_WRITE)NULL;
-    FastIoDispatch->MdlWriteComplete = (PFAST_IO_MDL_WRITE_COMPLETE)NULL;
-    FastIoDispatch->FastIoReadCompressed = (PFAST_IO_READ_COMPRESSED)NULL;
-    FastIoDispatch->FastIoWriteCompressed = (PFAST_IO_WRITE_COMPRESSED)NULL;
-    FastIoDispatch->MdlReadCompleteCompressed = 
(PFAST_IO_MDL_READ_COMPLETE_COMPRESSED)NULL;
-    FastIoDispatch->MdlWriteCompleteCompressed = 
(PFAST_IO_MDL_WRITE_COMPLETE_COMPRESSED)NULL;
-    FastIoDispatch->FastIoQueryOpen = (PFAST_IO_QUERY_OPEN)NULL;
-
-    /* Store the FastIo table address for easy reference */
+    FastIoDispatch->FastIoCheckIfPossible = 
(PFAST_IO_CHECK_IF_POSSIBLE)FltpFastIoCheckIfPossible;
+    FastIoDispatch->FastIoRead = (PFAST_IO_READ)FltpFastIoRead;
+    FastIoDispatch->FastIoWrite = (PFAST_IO_WRITE)FltpFastIoWrite;
+    FastIoDispatch->FastIoQueryBasicInfo = 
(PFAST_IO_QUERY_BASIC_INFO)FltpFastIoQueryBasicInfo;
+    FastIoDispatch->FastIoQueryStandardInfo = 
(PFAST_IO_QUERY_STANDARD_INFO)FltpFastIoQueryStandardInfo;
+    FastIoDispatch->FastIoLock = (PFAST_IO_LOCK)FltpFastIoLock;
+    FastIoDispatch->FastIoUnlockSingle = 
(PFAST_IO_UNLOCK_SINGLE)FltpFastIoUnlockSingle;
+    FastIoDispatch->FastIoUnlockAll = (PFAST_IO_UNLOCK_ALL)FltpFastIoUnlockAll;
+    FastIoDispatch->FastIoUnlockAllByKey = 
(PFAST_IO_UNLOCK_ALL_BY_KEY)FltpFastIoUnlockAllByKey;
+    FastIoDispatch->FastIoDeviceControl = 
(PFAST_IO_DEVICE_CONTROL)FltpFastIoDeviceControl;
+    FastIoDispatch->FastIoDetachDevice = 
(PFAST_IO_DETACH_DEVICE)FltpFastIoDetachDevice;
+    FastIoDispatch->FastIoQueryNetworkOpenInfo = 
(PFAST_IO_QUERY_NETWORK_OPEN_INFO)FltpFastIoQueryNetworkOpenInfo;
+    FastIoDispatch->MdlRead = (PFAST_IO_MDL_READ)FltpFastIoMdlRead;
+    FastIoDispatch->MdlReadComplete = 
(PFAST_IO_MDL_READ_COMPLETE)FltpFastIoMdlReadComplete;
+    FastIoDispatch->PrepareMdlWrite = 
(PFAST_IO_PREPARE_MDL_WRITE)FltpFastIoPrepareMdlWrite;
+    FastIoDispatch->MdlWriteComplete = 
(PFAST_IO_MDL_WRITE_COMPLETE)FltpFastIoMdlWriteComplete;
+    FastIoDispatch->FastIoReadCompressed = 
(PFAST_IO_READ_COMPRESSED)FltpFastIoReadCompressed;
+    FastIoDispatch->FastIoWriteCompressed = 
(PFAST_IO_WRITE_COMPRESSED)FltpFastIoWriteCompressed;
+    FastIoDispatch->MdlReadCompleteCompressed = 
(PFAST_IO_MDL_READ_COMPLETE_COMPRESSED)FltpFastIoMdlReadCompleteCompressed;
+    FastIoDispatch->MdlWriteCompleteCompressed = 
(PFAST_IO_MDL_WRITE_COMPLETE_COMPRESSED)FltpFastIoMdlWriteCompleteCompressed;
+    FastIoDispatch->FastIoQueryOpen = (PFAST_IO_QUERY_OPEN)FltpFastIoQueryOpen;
+
+    /* Store the FastIo table for internal and our access */
+    DriverObject->FastIoDispatch = FastIoDispatch;
     DriverData.FastIoDispatch = FastIoDispatch;
 
     /* Initialize the callback table */


Reply via email to