2 * PROJECT: Filesystem Filter Manager
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: drivers/filters/fltmgr/interface.c
5 * PURPOSE: Implements the driver interface
6 * PROGRAMMERS: Ged Murphy (gedmurphy@reactos.org)
9 /* INCLUDES ******************************************************************/
12 #include "fltmgrint.h"
18 /* DATA *********************************************************************/
20 #define VALID_FAST_IO_DISPATCH_HANDLER(_FastIoDispatchPtr, _FieldName) \
21 (((_FastIoDispatchPtr) != NULL) && \
22 (((_FastIoDispatchPtr)->SizeOfFastIoDispatch) >= \
23 (FIELD_OFFSET(FAST_IO_DISPATCH, _FieldName) + sizeof(void *))) && \
24 ((_FastIoDispatchPtr)->_FieldName != NULL))
26 #define IS_MY_DEVICE_OBJECT(_devObj) \
27 (((_devObj) != NULL) && \
28 ((_devObj)->DriverObject == Dispatcher::DriverObject) && \
29 ((_devObj)->DeviceExtension != NULL))
31 extern PDEVICE_OBJECT CommsDeviceObject
;
32 extern LIST_ENTRY FilterList
;
33 extern ERESOURCE FilterListLock
;
35 DRIVER_DATA DriverData
;
37 typedef struct _DETACH_DEVICE_WORK_ITEM
39 WORK_QUEUE_ITEM WorkItem
;
40 PDEVICE_OBJECT SourceDevice
;
41 PDEVICE_OBJECT TargetDevice
;
43 } DETACH_DEVICE_WORK_ITEM
, *PDETACH_DEVICE_WORK_ITEM
;
45 /* LOCAL FUNCTIONS ****************************************/
49 FltpCleanupDeviceObject(_In_ PDEVICE_OBJECT DeviceObject
)
51 PFLTMGR_DEVICE_EXTENSION DeviceExtension
;
53 DeviceExtension
= DeviceObject
->DeviceExtension
;
56 // cleanup device extension
63 FltpAttachDeviceObject(_In_ PDEVICE_OBJECT SourceDevice
,
64 _In_ PDEVICE_OBJECT TargetDevice
,
65 _Out_ PDEVICE_OBJECT
*AttachedToDeviceObject
)
71 /* Before attaching, copy the flags from the device we're going to attach to */
72 if (FlagOn(SourceDevice
->Flags
, DO_BUFFERED_IO
))
74 SetFlag(TargetDevice
->Flags
, DO_BUFFERED_IO
);
76 if (FlagOn(SourceDevice
->Flags
, DO_DIRECT_IO
))
78 SetFlag(TargetDevice
->Flags
, DO_DIRECT_IO
);
80 if (FlagOn(SourceDevice
->Flags
, DO_SYSTEM_BOOT_PARTITION
))
82 SetFlag(TargetDevice
->Characteristics
, FILE_DEVICE_SECURE_OPEN
);
85 /* Attach this device to the top of the driver stack */
86 Status
= IoAttachDeviceToDeviceStackSafe(SourceDevice
,
88 AttachedToDeviceObject
);
96 FltpIsAttachedToDevice(_In_ PDEVICE_OBJECT DeviceObject
,
97 _In_opt_ PDEVICE_OBJECT
*AttachedDeviceObject
)
99 PDEVICE_OBJECT CurrentDeviceObject
;
100 PDEVICE_OBJECT NextDeviceObject
;
104 /* Initialize the return pointer */
105 if (AttachedDeviceObject
) *AttachedDeviceObject
= NULL
;
107 /* Start by getting the top level device in the chain */
108 CurrentDeviceObject
= IoGetAttachedDeviceReference(DeviceObject
);
110 /* Loop while there are attached devices */
111 while (CurrentDeviceObject
)
113 /* Check if this device driver matches ours */
114 if (CurrentDeviceObject
->DriverObject
== DriverData
.DriverObject
)
116 FLT_ASSERT(CurrentDeviceObject
->DeviceExtension
!= NULL
);
118 /* We're attached, return the device object if the caller asked for it */
119 if (AttachedDeviceObject
)
121 *AttachedDeviceObject
= CurrentDeviceObject
;
125 /* We aren't returning the reference, so decrement the count */
126 ObDereferenceObject(CurrentDeviceObject
);
132 /* Get the next device in the chain */
133 NextDeviceObject
= IoGetLowerDeviceObject(CurrentDeviceObject
);
135 /* Decrement the count on the last device before we update the pointer */
136 ObDereferenceObject(CurrentDeviceObject
);
137 CurrentDeviceObject
= NextDeviceObject
;
146 FltpEnumerateFileSystemVolumes(_In_ PDEVICE_OBJECT DeviceObject
)
148 PFLTMGR_DEVICE_EXTENSION NewDeviceExtension
;
149 PDEVICE_OBJECT BaseDeviceObject
;
150 PDEVICE_OBJECT NewDeviceObject
;
151 PDEVICE_OBJECT
*DeviceList
;
152 PDEVICE_OBJECT StorageStackDeviceObject
;
153 UNICODE_STRING DeviceName
;
160 /* Get the base device */
161 BaseDeviceObject
= IoGetDeviceAttachmentBaseRef(DeviceObject
);
163 /* get the number of device object linked to the base file system */
164 Status
= IoEnumerateDeviceObjectList(BaseDeviceObject
->DriverObject
,
168 if (Status
!= STATUS_BUFFER_TOO_SMALL
) return Status
;
170 /* Add a few more slots in case the size changed between calls and allocate some memory to hold the pointers */
172 DeviceList
= ExAllocatePoolWithTag(NonPagedPool
,
173 (NumDevices
* sizeof(PDEVICE_OBJECT
)),
174 FM_TAG_DEV_OBJ_PTRS
);
175 if (DeviceList
== NULL
) return STATUS_INSUFFICIENT_RESOURCES
;
177 /* Now get all the device objects that this base driver has created */
178 Status
= IoEnumerateDeviceObjectList(BaseDeviceObject
->DriverObject
,
180 (NumDevices
* sizeof(PDEVICE_OBJECT
)),
182 if (!NT_SUCCESS(Status
))
184 ExFreePoolWithTag(DeviceList
, FM_TAG_DEV_OBJ_PTRS
);
188 /* Loop through all the devices looking for ones to attach to */
189 for (i
= 0; i
< NumDevices
; i
++)
191 RtlInitUnicodeString(&DeviceName
, NULL
);
192 StorageStackDeviceObject
= NULL
;
193 NewDeviceObject
= NULL
;
195 /* Ignore the device we passed in, and devices of the wrong type */
196 if ((DeviceList
[i
] == BaseDeviceObject
) ||
197 (DeviceList
[i
]->DeviceType
!= BaseDeviceObject
->DeviceType
))
202 /* Ignore this device if we're already attached to it */
203 if (FltpIsAttachedToDevice(DeviceList
[i
], NULL
) == FALSE
)
210 * If the device has a name, it must be a control device.
211 * This handles drivers with more then one control device (like FastFat)
213 FltpGetBaseDeviceObjectName(DeviceList
[i
], &DeviceName
);
214 if (NT_SUCCESS(Status
) && DeviceName
.Length
> 0)
220 * Try to get the storage stack (disk) device object associated with
221 * this file system device object. Ignore the device if we don't have one
223 Status
= IoGetDiskDeviceObject(DeviceList
[i
],
224 &StorageStackDeviceObject
);
225 if (!NT_SUCCESS(Status
))
232 * TODO: Don't attach to shadow copy volumes,
233 * ros doesn't have any so it's not an issues yet
237 * We're far enough to be ready to attach, create a device
238 * object which we'll use to do so
240 Status
= IoCreateDevice(DriverData
.DriverObject
,
241 sizeof(FLTMGR_DEVICE_EXTENSION
),
243 DeviceList
[i
]->DeviceType
,
247 if (!NT_SUCCESS(Status
))
252 /* Get the device extension for this new object and store our disk object there */
253 NewDeviceExtension
= NewDeviceObject
->DeviceExtension
;
254 NewDeviceExtension
->StorageStackDeviceObject
= StorageStackDeviceObject
;
256 /* Lookup and store the device name for the storage stack */
257 RtlInitEmptyUnicodeString(&NewDeviceExtension
->DeviceName
,
258 NewDeviceExtension
->DeviceNameBuffer
,
259 sizeof(NewDeviceExtension
->DeviceNameBuffer
));
260 FltpGetObjectName(StorageStackDeviceObject
,
261 &NewDeviceExtension
->DeviceName
);
264 /* Grab the attach lock before we attempt to attach */
265 ExAcquireFastMutex(&DriverData
.FilterAttachLock
);
267 /* Check again that we aren't already attached. It may have changed since our last check */
268 if (FltpIsAttachedToDevice(DeviceList
[i
], NULL
) == FALSE
)
270 FLT_ASSERT(NewDeviceObject
->DriverObject
== DriverData
.DriverObject
);
272 /* Finally, attach to the volume */
273 Status
= FltpAttachDeviceObject(DeviceList
[i
],
275 &NewDeviceExtension
->AttachedToDeviceObject
);
276 if (NT_SUCCESS(Status
))
278 /* Clean the initializing flag so other filters can attach to our device object */
279 ClearFlag(NewDeviceObject
->Flags
, DO_DEVICE_INITIALIZING
);
284 /* We're already attached. Just cleanup */
285 Status
= STATUS_DEVICE_ALREADY_ATTACHED
;
288 ExReleaseFastMutex(&DriverData
.FilterAttachLock
);
292 if (!NT_SUCCESS(Status
))
296 FltpCleanupDeviceObject(NewDeviceObject
);
297 IoDeleteDevice(NewDeviceObject
);
301 if (StorageStackDeviceObject
)
303 /* A ref was added for us when we attached, so we can deref ours now */
304 ObDereferenceObject(StorageStackDeviceObject
);
307 /* Remove the ref which was added by IoEnumerateDeviceObjectList */
308 ObDereferenceObject(DeviceList
[i
]);
310 /* Free the buffer that FltpGetBaseDeviceObjectName added */
311 FltpFreeUnicodeString(&DeviceName
);
315 /* Free the memory we allocated for the list */
316 ExFreePoolWithTag(DeviceList
, FM_TAG_DEV_OBJ_PTRS
);
318 return STATUS_SUCCESS
;
324 FltpAttachToFileSystemDevice(_In_ PDEVICE_OBJECT DeviceObject
,
325 _In_ PUNICODE_STRING DeviceName
)
327 PFLTMGR_DEVICE_EXTENSION DeviceExtension
;
328 PDEVICE_OBJECT NewDeviceObject
;
329 WCHAR Buffer
[MAX_DEVNAME_LENGTH
];
330 UNICODE_STRING FileSystemDeviceName
;
331 UNICODE_STRING FsRecDeviceName
;
336 /* Only handle device types we're interested in */
337 if (DeviceObject
->DeviceType
!= FILE_DEVICE_DISK_FILE_SYSTEM
&&
338 DeviceObject
->DeviceType
!= FILE_DEVICE_CD_ROM_FILE_SYSTEM
&&
339 DeviceObject
->DeviceType
!= FILE_DEVICE_NETWORK_FILE_SYSTEM
)
341 return STATUS_SUCCESS
;
344 /* Setup the buffer to hold the device name */
345 RtlInitEmptyUnicodeString(&FileSystemDeviceName
,
347 MAX_DEVNAME_LENGTH
* sizeof(WCHAR
));
349 /* Get the the name of the file system device */
350 Status
= FltpGetObjectName(DeviceObject
->DriverObject
, &FileSystemDeviceName
);
351 if (!NT_SUCCESS(Status
)) return Status
;
353 DPRINT("Found device %wZ, checking if we need to attach...\n", &FileSystemDeviceName
);
355 /* Build up the name of the file system recognizer device */
356 RtlInitUnicodeString(&FsRecDeviceName
, L
"\\FileSystem\\Fs_Rec");
358 /* We don't attach to recognizer devices, so bail if this is one */
359 if (RtlCompareUnicodeString(&FileSystemDeviceName
, &FsRecDeviceName
, TRUE
) == 0)
361 return STATUS_SUCCESS
;
364 /* Create a device object which we can attach to this file system */
365 Status
= IoCreateDevice(DriverData
.DriverObject
,
366 sizeof(FLTMGR_DEVICE_EXTENSION
),
368 DeviceObject
->DeviceType
,
372 if (!NT_SUCCESS(Status
))
374 DPRINT1("Failed to create a DO for attaching to a FS : 0x%X\n", Status
);
378 /* Cast the device extension to something we understand */
379 DeviceExtension
= NewDeviceObject
->DeviceExtension
;
381 /* Attach this device to the top of the driver stack and store the DO we attached to in the DE */
382 Status
= FltpAttachDeviceObject(NewDeviceObject
,
384 &DeviceExtension
->AttachedToDeviceObject
);
385 if (NT_SUCCESS(Status
))
387 DPRINT("Attached to %wZ\n", &FileSystemDeviceName
);
391 DPRINT1("Failed to attach to the driver stack : 0x%X\n", Status
);
395 /* Setup the unicode string buffer and copy the device name to the device extension */
396 RtlInitEmptyUnicodeString(&DeviceExtension
->DeviceName
,
397 DeviceExtension
->DeviceNameBuffer
,
398 MAX_DEVNAME_LENGTH
* sizeof(WCHAR
));
399 RtlCopyUnicodeString(&DeviceExtension
->DeviceName
, DeviceName
);
401 /* We're done, remove the initializing flag */
402 ClearFlag(NewDeviceObject
->Flags
, DO_DEVICE_INITIALIZING
);
404 /* Look for existing mounted devices for this file system */
405 Status
= FltpEnumerateFileSystemVolumes(DeviceObject
);
406 if (!NT_SUCCESS(Status
))
408 DPRINT1("Failed to enumerate file system volumes for this file system : 0x%X\n", Status
);
409 IoDetachDevice(DeviceExtension
->AttachedToDeviceObject
);
414 if (!NT_SUCCESS(Status
))
416 IoDeleteDevice(NewDeviceObject
);
425 FltpDetachFromFileSystemDevice(_In_ PDEVICE_OBJECT DeviceObject
)
427 PDEVICE_OBJECT AttachedDevice
, NextDevice
;
428 PFLTMGR_DEVICE_EXTENSION DeviceExtension
;
433 /* Get the top device in the chain and increment the ref count on it */
434 AttachedDevice
= IoGetAttachedDeviceReference(DeviceObject
);
436 /* Loop all attached devices looking for our file system driver */
437 while (AttachedDevice
->DriverObject
!= DriverData
.DriverObject
)
439 FLT_ASSERT(AttachedDevice
!= NULL
);
441 /* Get the next lower device object. This adds a ref on NextDevice */
442 NextDevice
= IoGetLowerDeviceObject(AttachedDevice
);
444 /* Remove the reference we added */
445 Count
= ObDereferenceObject(AttachedDevice
);
447 /* Bail if this is the last one */
448 if (NextDevice
== NULL
) return Count
;
450 /* Try the next one */
451 AttachedDevice
= NextDevice
;
455 DeviceExtension
= AttachedDevice
->DeviceExtension
;
459 // FIXME: Put any device extension cleanup code here
463 /* Detach the device from the chain and delete the object */
464 IoDetachDevice(DeviceObject
);
465 IoDeleteDevice(AttachedDevice
);
467 /* Remove the reference we added so the delete can complete */
468 return ObDereferenceObject(AttachedDevice
);
472 /* DISPATCH ROUTINES **********************************************/
476 FltpPreFsFilterOperation(_In_ PFS_FILTER_CALLBACK_DATA Data
,
477 _Out_ PVOID
*CompletionContext
)
479 UNREFERENCED_PARAMETER(Data
);
480 UNREFERENCED_PARAMETER(CompletionContext
);
482 return STATUS_SUCCESS
;
487 FltpPostFsFilterOperation(_In_ PFS_FILTER_CALLBACK_DATA Data
,
488 _In_ NTSTATUS OperationStatus
,
489 _In_ PVOID CompletionContext
)
491 UNREFERENCED_PARAMETER(Data
);
492 UNREFERENCED_PARAMETER(OperationStatus
);
493 UNREFERENCED_PARAMETER(CompletionContext
);
499 FltpDispatch(_In_ PDEVICE_OBJECT DeviceObject
,
502 PFLTMGR_DEVICE_EXTENSION DeviceExtension
;
503 PIO_STACK_LOCATION StackPtr
;
506 DeviceExtension
= DeviceObject
->DeviceExtension
;
508 /* Check if this is a request for us */
509 if (DeviceObject
== DriverData
.DeviceObject
)
511 FLT_ASSERT(DeviceObject
->DriverObject
== DriverData
.DriverObject
);
512 FLT_ASSERT(DeviceExtension
== NULL
);
514 /* Hand it off to our internal handler */
515 Status
= FltpDispatchHandler(DeviceObject
, Irp
);
516 if (Status
!= STATUS_REPARSE
)
518 Irp
->IoStatus
.Status
= Status
;
519 Irp
->IoStatus
.Information
= 0;
520 IoCompleteRequest(Irp
, 0);
525 /* Check if this is a request for a the messaging device */
526 if (DeviceObject
== CommsDeviceObject
)
528 /* Hand off to our internal routine */
529 return FltpMsgDispatch(DeviceObject
, Irp
);
532 FLT_ASSERT(DeviceExtension
&&
533 DeviceExtension
->AttachedToDeviceObject
);
535 StackPtr
= IoGetCurrentIrpStackLocation(Irp
);
536 if (StackPtr
->MajorFunction
== IRP_MJ_SHUTDOWN
)
538 // handle shutdown request
541 DPRINT1("Received %X from %wZ\n", StackPtr
->MajorFunction
, &DeviceExtension
->DeviceName
);
543 /* Just pass the IRP down the stack */
544 IoSkipCurrentIrpStackLocation(Irp
);
545 return IoCallDriver(DeviceExtension
->AttachedToDeviceObject
, Irp
);
551 FltpCreate(_In_ PDEVICE_OBJECT DeviceObject
,
554 PFLTMGR_DEVICE_EXTENSION DeviceExtension
;
558 DeviceExtension
= DeviceObject
->DeviceExtension
;
560 /* Check if this is a request for us */
561 if (DeviceObject
== DriverData
.DeviceObject
)
563 FLT_ASSERT(DeviceObject
->DriverObject
== DriverData
.DriverObject
);
564 FLT_ASSERT(DeviceExtension
== NULL
);
566 /* Someone wants a handle to the fltmgr, allow it */
567 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
568 Irp
->IoStatus
.Information
= 0;
569 IofCompleteRequest(Irp
, 0);
570 return STATUS_SUCCESS
;
573 /* Check if this is a request for a the new comms connection */
574 if (DeviceObject
== CommsDeviceObject
)
576 /* Hand off to our internal routine */
577 return FltpMsgCreate(DeviceObject
, Irp
);
580 FLT_ASSERT(DeviceExtension
&&
581 DeviceExtension
->AttachedToDeviceObject
);
583 DPRINT1("Received create from %wZ (%lu)\n", &DeviceExtension
->DeviceName
, PsGetCurrentProcessId());
585 /* Just pass the IRP down the stack */
586 IoSkipCurrentIrpStackLocation(Irp
);
587 return IoCallDriver(DeviceExtension
->AttachedToDeviceObject
, Irp
);
593 FltpFsControl(_In_ PDEVICE_OBJECT DeviceObject
,
596 PFLTMGR_DEVICE_EXTENSION DeviceExtension
;
600 /* Check if this is a request for us */
601 if (DeviceObject
== DriverData
.DeviceObject
)
603 /* We don't handle this request */
604 Irp
->IoStatus
.Information
= 0;
605 Irp
->IoStatus
.Status
= STATUS_INVALID_DEVICE_REQUEST
;
606 IofCompleteRequest(Irp
, 0);
607 return STATUS_INVALID_DEVICE_REQUEST
;
610 DeviceExtension
= DeviceObject
->DeviceExtension
;
612 FLT_ASSERT(DeviceExtension
&&
613 DeviceExtension
->AttachedToDeviceObject
);
615 /* Just pass the IRP down the stack */
616 IoSkipCurrentIrpStackLocation(Irp
);
617 return IoCallDriver(DeviceExtension
->AttachedToDeviceObject
, Irp
);
622 FltpDeviceControl(_In_ PDEVICE_OBJECT DeviceObject
,
625 PFLTMGR_DEVICE_EXTENSION DeviceExtension
;
628 /* Check if the request was meant for us */
629 if (DeviceObject
== DriverData
.DeviceObject
)
631 Status
= FltpDeviceControlHandler(DeviceObject
, Irp
);
632 if (Status
!= STATUS_REPARSE
)
634 Irp
->IoStatus
.Status
= Status
;
635 Irp
->IoStatus
.Information
= 0;
636 IoCompleteRequest(Irp
, 0);
642 DeviceExtension
= DeviceObject
->DeviceExtension
;
644 FLT_ASSERT(DeviceExtension
&&
645 DeviceExtension
->AttachedToDeviceObject
);
647 /* Just pass the IRP down the stack */
648 IoSkipCurrentIrpStackLocation(Irp
);
649 return IoCallDriver(DeviceExtension
->AttachedToDeviceObject
, Irp
);
654 /* FASTIO ROUTINES ************************************************/
659 FltpFastIoCheckIfPossible(_In_ PFILE_OBJECT FileObject
,
660 _In_ PLARGE_INTEGER FileOffset
,
664 _In_ BOOLEAN CheckForReadOperation
,
665 _Out_ PIO_STATUS_BLOCK IoStatus
,
666 _In_ PDEVICE_OBJECT DeviceObject
)
669 PFLTMGR_DEVICE_EXTENSION DeviceExtension
;
670 PDEVICE_OBJECT AttachedDeviceObject
;
671 PFAST_IO_DISPATCH FastIoDispatch
;
675 /* If it doesn't have a device extension, then it's not our device object */
676 if (DeviceObject
->DeviceExtension
== NULL
)
679 IoStatus
->Status
= STATUS_INVALID_DEVICE_REQUEST
;
680 IoStatus
->Information
= 0;
684 DeviceExtension
= DeviceObject
->DeviceExtension
;
685 FLT_ASSERT(DeviceExtension
->AttachedToDeviceObject
);
687 /* Get the device that we attached to */
688 AttachedDeviceObject
= DeviceExtension
->AttachedToDeviceObject
;
689 FastIoDispatch
= AttachedDeviceObject
->DriverObject
->FastIoDispatch
;
691 /* Make sure our FastIo table is valid */
692 if (FastIoDispatch
&& FastIoDispatch
->FastIoCheckIfPossible
)
694 /* Forward the call onto the device we attached to */
695 return FastIoDispatch
->FastIoCheckIfPossible(FileObject
,
700 CheckForReadOperation
,
702 AttachedDeviceObject
);
705 /* We failed to handle the request, send it down the slow path */
713 FltpFastIoRead(_In_ PFILE_OBJECT FileObject
,
714 _In_ PLARGE_INTEGER FileOffset
,
719 _Out_ PIO_STATUS_BLOCK IoStatus
,
720 _In_ PDEVICE_OBJECT DeviceObject
)
722 PFLTMGR_DEVICE_EXTENSION DeviceExtension
;
723 PDEVICE_OBJECT AttachedDeviceObject
;
724 PFAST_IO_DISPATCH FastIoDispatch
;
728 /* If it doesn't have a device extension, then it's not our device object */
729 if (DeviceObject
->DeviceExtension
== NULL
)
732 IoStatus
->Status
= STATUS_INVALID_DEVICE_REQUEST
;
733 IoStatus
->Information
= 0;
737 DeviceExtension
= DeviceObject
->DeviceExtension
;
738 FLT_ASSERT(DeviceExtension
->AttachedToDeviceObject
);
740 /* Get the device that we attached to */
741 AttachedDeviceObject
= DeviceExtension
->AttachedToDeviceObject
;
742 FastIoDispatch
= AttachedDeviceObject
->DriverObject
->FastIoDispatch
;
744 /* Make sure our FastIo table is valid */
745 if (FastIoDispatch
&& FastIoDispatch
->FastIoRead
)
747 /* Forward the call onto the device we attached to */
748 return FastIoDispatch
->FastIoRead(FileObject
,
755 AttachedDeviceObject
);
758 /* We failed to handle the request, send it down the slow path */
766 FltpFastIoWrite(_In_ PFILE_OBJECT FileObject
,
767 _In_ PLARGE_INTEGER FileOffset
,
772 _Out_ PIO_STATUS_BLOCK IoStatus
,
773 _In_ PDEVICE_OBJECT DeviceObject
)
775 PFLTMGR_DEVICE_EXTENSION DeviceExtension
;
776 PDEVICE_OBJECT AttachedDeviceObject
;
777 PFAST_IO_DISPATCH FastIoDispatch
;
781 /* If it doesn't have a device extension, then it's not our device object */
782 if (DeviceObject
->DeviceExtension
== NULL
)
785 IoStatus
->Status
= STATUS_INVALID_DEVICE_REQUEST
;
786 IoStatus
->Information
= 0;
790 DeviceExtension
= DeviceObject
->DeviceExtension
;
791 FLT_ASSERT(DeviceExtension
->AttachedToDeviceObject
);
793 /* Get the device that we attached to */
794 AttachedDeviceObject
= DeviceExtension
->AttachedToDeviceObject
;
795 FastIoDispatch
= AttachedDeviceObject
->DriverObject
->FastIoDispatch
;
797 /* Make sure our FastIo table is valid */
798 if (FastIoDispatch
&& FastIoDispatch
->FastIoWrite
)
800 /* Forward the call onto the device we attached to */
801 return FastIoDispatch
->FastIoWrite(FileObject
,
808 AttachedDeviceObject
);
811 /* We failed to handle the request, send it down the slow path */
819 FltpFastIoQueryBasicInfo(_In_ PFILE_OBJECT FileObject
,
821 _Out_ PFILE_BASIC_INFORMATION Buffer
,
822 _Out_ PIO_STATUS_BLOCK IoStatus
,
823 _In_ PDEVICE_OBJECT DeviceObject
)
825 PFLTMGR_DEVICE_EXTENSION DeviceExtension
;
826 PDEVICE_OBJECT AttachedDeviceObject
;
827 PFAST_IO_DISPATCH FastIoDispatch
;
831 /* If it doesn't have a device extension, then it's not our device object */
832 if (DeviceObject
->DeviceExtension
== NULL
)
835 IoStatus
->Status
= STATUS_INVALID_DEVICE_REQUEST
;
836 IoStatus
->Information
= 0;
840 DeviceExtension
= DeviceObject
->DeviceExtension
;
841 FLT_ASSERT(DeviceExtension
->AttachedToDeviceObject
);
843 /* Get the device that we attached to */
844 AttachedDeviceObject
= DeviceExtension
->AttachedToDeviceObject
;
845 FastIoDispatch
= AttachedDeviceObject
->DriverObject
->FastIoDispatch
;
847 /* Make sure our FastIo table is valid */
848 if (FastIoDispatch
&& FastIoDispatch
->FastIoQueryBasicInfo
)
850 /* Forward the call onto the device we attached to */
851 return FastIoDispatch
->FastIoQueryBasicInfo(FileObject
,
855 AttachedDeviceObject
);
858 /* We failed to handle the request, send it down the slow path */
866 FltpFastIoQueryStandardInfo(_In_ PFILE_OBJECT FileObject
,
868 _Out_ PFILE_STANDARD_INFORMATION Buffer
,
869 _Out_ PIO_STATUS_BLOCK IoStatus
,
870 _In_ PDEVICE_OBJECT DeviceObject
)
872 PFLTMGR_DEVICE_EXTENSION DeviceExtension
;
873 PDEVICE_OBJECT AttachedDeviceObject
;
874 PFAST_IO_DISPATCH FastIoDispatch
;
878 /* If it doesn't have a device extension, then it's not our device object */
879 if (DeviceObject
->DeviceExtension
== NULL
)
882 IoStatus
->Status
= STATUS_INVALID_DEVICE_REQUEST
;
883 IoStatus
->Information
= 0;
887 DeviceExtension
= DeviceObject
->DeviceExtension
;
888 FLT_ASSERT(DeviceExtension
->AttachedToDeviceObject
);
890 /* Get the device that we attached to */
891 AttachedDeviceObject
= DeviceExtension
->AttachedToDeviceObject
;
892 FastIoDispatch
= AttachedDeviceObject
->DriverObject
->FastIoDispatch
;
894 /* Make sure our FastIo table is valid */
895 if (FastIoDispatch
&& FastIoDispatch
->FastIoQueryStandardInfo
)
897 /* Forward the call onto the device we attached to */
898 return FastIoDispatch
->FastIoQueryStandardInfo(FileObject
,
902 AttachedDeviceObject
);
905 /* We failed to handle the request, send it down the slow path */
913 FltpFastIoLock(_In_ PFILE_OBJECT FileObject
,
914 _In_ PLARGE_INTEGER FileOffset
,
915 _In_ PLARGE_INTEGER Length
,
916 _In_ PEPROCESS ProcessId
,
918 _In_ BOOLEAN FailImmediately
,
919 _In_ BOOLEAN ExclusiveLock
,
920 _Out_ PIO_STATUS_BLOCK IoStatus
,
921 _In_ PDEVICE_OBJECT DeviceObject
)
923 PFLTMGR_DEVICE_EXTENSION DeviceExtension
;
924 PDEVICE_OBJECT AttachedDeviceObject
;
925 PFAST_IO_DISPATCH FastIoDispatch
;
929 /* If it doesn't have a device extension, then it's not our device object */
930 if (DeviceObject
->DeviceExtension
== NULL
)
933 IoStatus
->Status
= STATUS_INVALID_DEVICE_REQUEST
;
934 IoStatus
->Information
= 0;
938 DeviceExtension
= DeviceObject
->DeviceExtension
;
939 FLT_ASSERT(DeviceExtension
->AttachedToDeviceObject
);
941 /* Get the device that we attached to */
942 AttachedDeviceObject
= DeviceExtension
->AttachedToDeviceObject
;
943 FastIoDispatch
= AttachedDeviceObject
->DriverObject
->FastIoDispatch
;
945 /* Make sure our FastIo table is valid */
946 if (FastIoDispatch
&& FastIoDispatch
->FastIoLock
)
948 /* Forward the call onto the device we attached to */
949 return FastIoDispatch
->FastIoLock(FileObject
,
957 AttachedDeviceObject
);
960 /* We failed to handle the request, send it down the slow path */
968 FltpFastIoUnlockSingle(_In_ PFILE_OBJECT FileObject
,
969 _In_ PLARGE_INTEGER FileOffset
,
970 _In_ PLARGE_INTEGER Length
,
971 _In_ PEPROCESS ProcessId
,
973 _Out_ PIO_STATUS_BLOCK IoStatus
,
974 _In_ PDEVICE_OBJECT DeviceObject
)
976 PFLTMGR_DEVICE_EXTENSION DeviceExtension
;
977 PDEVICE_OBJECT AttachedDeviceObject
;
978 PFAST_IO_DISPATCH FastIoDispatch
;
982 /* If it doesn't have a device extension, then it's not our device object */
983 if (DeviceObject
->DeviceExtension
== NULL
)
986 IoStatus
->Status
= STATUS_INVALID_DEVICE_REQUEST
;
987 IoStatus
->Information
= 0;
991 DeviceExtension
= DeviceObject
->DeviceExtension
;
992 FLT_ASSERT(DeviceExtension
->AttachedToDeviceObject
);
994 /* Get the device that we attached to */
995 AttachedDeviceObject
= DeviceExtension
->AttachedToDeviceObject
;
996 FastIoDispatch
= AttachedDeviceObject
->DriverObject
->FastIoDispatch
;
998 /* Make sure our FastIo table is valid */
999 if (FastIoDispatch
&& FastIoDispatch
->FastIoUnlockSingle
)
1001 /* Forward the call onto the device we attached to */
1002 return FastIoDispatch
->FastIoUnlockSingle(FileObject
,
1008 AttachedDeviceObject
);
1011 /* We failed to handle the request, send it down the slow path */
1019 FltpFastIoUnlockAll(_In_ PFILE_OBJECT FileObject
,
1020 _In_ PEPROCESS ProcessId
,
1021 _Out_ PIO_STATUS_BLOCK IoStatus
,
1022 _In_ PDEVICE_OBJECT DeviceObject
)
1025 PFLTMGR_DEVICE_EXTENSION DeviceExtension
;
1026 PDEVICE_OBJECT AttachedDeviceObject
;
1027 PFAST_IO_DISPATCH FastIoDispatch
;
1031 /* If it doesn't have a device extension, then it's not our device object */
1032 if (DeviceObject
->DeviceExtension
== NULL
)
1035 IoStatus
->Status
= STATUS_INVALID_DEVICE_REQUEST
;
1036 IoStatus
->Information
= 0;
1040 DeviceExtension
= DeviceObject
->DeviceExtension
;
1041 FLT_ASSERT(DeviceExtension
->AttachedToDeviceObject
);
1043 /* Get the device that we attached to */
1044 AttachedDeviceObject
= DeviceExtension
->AttachedToDeviceObject
;
1045 FastIoDispatch
= AttachedDeviceObject
->DriverObject
->FastIoDispatch
;
1047 /* Make sure our FastIo table is valid */
1048 if (FastIoDispatch
&& FastIoDispatch
->FastIoUnlockAll
)
1050 /* Forward the call onto the device we attached to */
1051 return FastIoDispatch
->FastIoUnlockAll(FileObject
,
1054 AttachedDeviceObject
);
1057 /* We failed to handle the request, send it down the slow path */
1065 FltpFastIoUnlockAllByKey(_In_ PFILE_OBJECT FileObject
,
1066 _In_ PVOID ProcessId
,
1068 _Out_ PIO_STATUS_BLOCK IoStatus
,
1069 _In_ PDEVICE_OBJECT DeviceObject
)
1071 PFLTMGR_DEVICE_EXTENSION DeviceExtension
;
1072 PDEVICE_OBJECT AttachedDeviceObject
;
1073 PFAST_IO_DISPATCH FastIoDispatch
;
1077 /* If it doesn't have a device extension, then it's not our device object */
1078 if (DeviceObject
->DeviceExtension
== NULL
)
1081 IoStatus
->Status
= STATUS_INVALID_DEVICE_REQUEST
;
1082 IoStatus
->Information
= 0;
1086 DeviceExtension
= DeviceObject
->DeviceExtension
;
1087 FLT_ASSERT(DeviceExtension
->AttachedToDeviceObject
);
1089 /* Get the device that we attached to */
1090 AttachedDeviceObject
= DeviceExtension
->AttachedToDeviceObject
;
1091 FastIoDispatch
= AttachedDeviceObject
->DriverObject
->FastIoDispatch
;
1093 /* Make sure our FastIo table is valid */
1094 if (FastIoDispatch
&& FastIoDispatch
->FastIoUnlockAllByKey
)
1096 /* Forward the call onto the device we attached to */
1097 return FastIoDispatch
->FastIoUnlockAllByKey(FileObject
,
1101 AttachedDeviceObject
);
1104 /* We failed to handle the request, send it down the slow path */
1112 FltpFastIoDeviceControl(_In_ PFILE_OBJECT FileObject
,
1114 _In_opt_ PVOID InputBuffer
,
1115 _In_ ULONG InputBufferLength
,
1116 _Out_opt_ PVOID OutputBuffer
,
1117 _In_ ULONG OutputBufferLength
,
1118 _In_ ULONG IoControlCode
,
1119 _Out_ PIO_STATUS_BLOCK IoStatus
,
1120 _In_ PDEVICE_OBJECT DeviceObject
)
1122 PFLTMGR_DEVICE_EXTENSION DeviceExtension
;
1123 PDEVICE_OBJECT AttachedDeviceObject
;
1124 PFAST_IO_DISPATCH FastIoDispatch
;
1128 /* If it doesn't have a device extension, then it's not our device object */
1129 if (DeviceObject
->DeviceExtension
== NULL
)
1131 /* Fail the request, send it down the slow path */
1135 DeviceExtension
= DeviceObject
->DeviceExtension
;
1136 FLT_ASSERT(DeviceExtension
->AttachedToDeviceObject
);
1138 /* Get the device that we attached to */
1139 AttachedDeviceObject
= DeviceExtension
->AttachedToDeviceObject
;
1140 FastIoDispatch
= AttachedDeviceObject
->DriverObject
->FastIoDispatch
;
1142 /* Make sure our FastIo table is valid */
1143 if (FastIoDispatch
&& FastIoDispatch
->FastIoDeviceControl
)
1145 /* Forward the call onto the device we attached to */
1146 return FastIoDispatch
->FastIoDeviceControl(FileObject
,
1154 AttachedDeviceObject
);
1157 /* We failed to handle the request, send it down the slow path */
1164 FltpFastIoDetachDeviceWorker(_In_ PVOID Parameter
)
1166 PDETACH_DEVICE_WORK_ITEM DetachDeviceWorkItem
= Parameter
;
1168 /* Run any cleanup routines */
1169 FltpCleanupDeviceObject(DetachDeviceWorkItem
->SourceDevice
);
1171 /* Detach from the target device */
1172 IoDetachDevice(DetachDeviceWorkItem
->TargetDevice
);
1174 /* Delete the source */
1175 IoDeleteDevice(DetachDeviceWorkItem
->SourceDevice
);
1177 /* Free the pool we allocated in FltpFastIoDetachDevice */
1178 ExFreePoolWithTag(DetachDeviceWorkItem
, 0x1234);
1184 FltpFastIoDetachDevice(_In_ PDEVICE_OBJECT SourceDevice
,
1185 _In_ PDEVICE_OBJECT TargetDevice
)
1187 PDETACH_DEVICE_WORK_ITEM DetachDeviceWorkItem
;
1192 * Detaching and deleting devices is a lot of work and takes too long
1193 * to be a worthwhile FastIo candidate, so we defer this call to speed
1194 * it up. There's no return value so we're okay to do this.
1197 /* Allocate the work item and it's corresponding data */
1198 DetachDeviceWorkItem
= ExAllocatePoolWithTag(NonPagedPool
,
1199 sizeof(DETACH_DEVICE_WORK_ITEM
),
1201 if (DetachDeviceWorkItem
)
1203 /* Initialize the work item */
1204 ExInitializeWorkItem(&DetachDeviceWorkItem
->WorkItem
,
1205 FltpFastIoDetachDeviceWorker
,
1206 DetachDeviceWorkItem
);
1208 /* Queue the work item and return the call */
1209 ExQueueWorkItem(&DetachDeviceWorkItem
->WorkItem
,
1214 /* We failed to defer, just cleanup here */
1215 FltpCleanupDeviceObject(SourceDevice
);
1216 IoDetachDevice(TargetDevice
);
1217 IoDeleteDevice(SourceDevice
);
1225 FltpFastIoQueryNetworkOpenInfo(_In_ PFILE_OBJECT FileObject
,
1227 _Out_ PFILE_NETWORK_OPEN_INFORMATION Buffer
,
1228 _Out_ PIO_STATUS_BLOCK IoStatus
,
1229 _In_ PDEVICE_OBJECT DeviceObject
)
1231 PFLTMGR_DEVICE_EXTENSION DeviceExtension
;
1232 PDEVICE_OBJECT AttachedDeviceObject
;
1233 PFAST_IO_DISPATCH FastIoDispatch
;
1237 /* If it doesn't have a device extension, then it's not our device object */
1238 if (DeviceObject
->DeviceExtension
== NULL
)
1241 IoStatus
->Status
= STATUS_INVALID_DEVICE_REQUEST
;
1242 IoStatus
->Information
= 0;
1246 DeviceExtension
= DeviceObject
->DeviceExtension
;
1247 FLT_ASSERT(DeviceExtension
->AttachedToDeviceObject
);
1249 /* Get the device that we attached to */
1250 AttachedDeviceObject
= DeviceExtension
->AttachedToDeviceObject
;
1251 FastIoDispatch
= AttachedDeviceObject
->DriverObject
->FastIoDispatch
;
1253 /* Make sure our FastIo table is valid */
1254 if (FastIoDispatch
&& FastIoDispatch
->FastIoQueryNetworkOpenInfo
)
1256 /* Forward the call onto the device we attached to */
1257 return FastIoDispatch
->FastIoQueryNetworkOpenInfo(FileObject
,
1261 AttachedDeviceObject
);
1264 /* We failed to handle the request, send it down the slow path */
1272 FltpFastIoMdlRead(_In_ PFILE_OBJECT FileObject
,
1273 _In_ PLARGE_INTEGER FileOffset
,
1276 _Out_ PMDL
*MdlChain
,
1277 _Out_ PIO_STATUS_BLOCK IoStatus
,
1278 _In_ PDEVICE_OBJECT DeviceObject
)
1280 PFLTMGR_DEVICE_EXTENSION DeviceExtension
;
1281 PDEVICE_OBJECT AttachedDeviceObject
;
1282 PFAST_IO_DISPATCH FastIoDispatch
;
1286 /* If it doesn't have a device extension, then it's not our device object */
1287 if (DeviceObject
->DeviceExtension
== NULL
)
1290 IoStatus
->Status
= STATUS_INVALID_DEVICE_REQUEST
;
1291 IoStatus
->Information
= 0;
1295 DeviceExtension
= DeviceObject
->DeviceExtension
;
1296 FLT_ASSERT(DeviceExtension
->AttachedToDeviceObject
);
1298 /* Get the device that we attached to */
1299 AttachedDeviceObject
= DeviceExtension
->AttachedToDeviceObject
;
1300 FastIoDispatch
= AttachedDeviceObject
->DriverObject
->FastIoDispatch
;
1302 /* Make sure our FastIo table is valid */
1303 if (FastIoDispatch
&& FastIoDispatch
->MdlRead
)
1305 /* Forward the call onto the device we attached to */
1306 return FastIoDispatch
->MdlRead(FileObject
,
1312 AttachedDeviceObject
);
1315 /* We failed to handle the request, send it down the slow path */
1323 FltpFastIoMdlReadComplete(_In_ PFILE_OBJECT FileObject
,
1325 _In_ PDEVICE_OBJECT DeviceObject
)
1328 PFLTMGR_DEVICE_EXTENSION DeviceExtension
;
1329 PDEVICE_OBJECT AttachedDeviceObject
;
1330 PFAST_IO_DISPATCH FastIoDispatch
;
1334 /* If it doesn't have a device extension, then it's not our device object */
1335 if (DeviceObject
->DeviceExtension
== NULL
)
1337 /* Fail the request, send it down the slow path */
1341 DeviceExtension
= DeviceObject
->DeviceExtension
;
1342 FLT_ASSERT(DeviceExtension
->AttachedToDeviceObject
);
1344 /* Get the device that we attached to */
1345 AttachedDeviceObject
= DeviceExtension
->AttachedToDeviceObject
;
1346 FastIoDispatch
= AttachedDeviceObject
->DriverObject
->FastIoDispatch
;
1348 /* Make sure our FastIo table is valid */
1349 if (FastIoDispatch
&& FastIoDispatch
->MdlReadComplete
)
1351 /* Forward the call onto the device we attached to */
1352 return FastIoDispatch
->MdlReadComplete(FileObject
,
1354 AttachedDeviceObject
);
1357 /* We failed to handle the request, send it down the slow path */
1365 FltpFastIoPrepareMdlWrite(_In_ PFILE_OBJECT FileObject
,
1366 _In_ PLARGE_INTEGER FileOffset
,
1369 _Out_ PMDL
*MdlChain
,
1370 _Out_ PIO_STATUS_BLOCK IoStatus
,
1371 _In_ PDEVICE_OBJECT DeviceObject
)
1373 PFLTMGR_DEVICE_EXTENSION DeviceExtension
;
1374 PDEVICE_OBJECT AttachedDeviceObject
;
1375 PFAST_IO_DISPATCH FastIoDispatch
;
1379 /* If it doesn't have a device extension, then it's not our device object */
1380 if (DeviceObject
->DeviceExtension
== NULL
)
1383 IoStatus
->Status
= STATUS_INVALID_DEVICE_REQUEST
;
1384 IoStatus
->Information
= 0;
1388 DeviceExtension
= DeviceObject
->DeviceExtension
;
1389 FLT_ASSERT(DeviceExtension
->AttachedToDeviceObject
);
1391 /* Get the device that we attached to */
1392 AttachedDeviceObject
= DeviceExtension
->AttachedToDeviceObject
;
1393 FastIoDispatch
= AttachedDeviceObject
->DriverObject
->FastIoDispatch
;
1395 /* Make sure our FastIo table is valid */
1396 if (FastIoDispatch
&& FastIoDispatch
->PrepareMdlWrite
)
1398 /* Forward the call onto the device we attached to */
1399 return FastIoDispatch
->PrepareMdlWrite(FileObject
,
1405 AttachedDeviceObject
);
1408 /* We failed to handle the request, send it down the slow path */
1416 FltpFastIoMdlWriteComplete(_In_ PFILE_OBJECT FileObject
,
1417 _In_ PLARGE_INTEGER FileOffset
,
1419 _In_ PDEVICE_OBJECT DeviceObject
)
1421 PFLTMGR_DEVICE_EXTENSION DeviceExtension
;
1422 PDEVICE_OBJECT AttachedDeviceObject
;
1423 PFAST_IO_DISPATCH FastIoDispatch
;
1427 /* If it doesn't have a device extension, then it's not our device object */
1428 if (DeviceObject
->DeviceExtension
== NULL
)
1430 /* Fail the request, send it down the slow path */
1434 DeviceExtension
= DeviceObject
->DeviceExtension
;
1435 FLT_ASSERT(DeviceExtension
->AttachedToDeviceObject
);
1437 /* Get the device that we attached to */
1438 AttachedDeviceObject
= DeviceExtension
->AttachedToDeviceObject
;
1439 FastIoDispatch
= AttachedDeviceObject
->DriverObject
->FastIoDispatch
;
1441 /* Make sure our FastIo table is valid */
1442 if (FastIoDispatch
&& FastIoDispatch
->MdlWriteComplete
)
1444 /* Forward the call onto the device we attached to */
1445 return FastIoDispatch
->MdlWriteComplete(FileObject
,
1448 AttachedDeviceObject
);
1451 /* We failed to handle the request, send it down the slow path */
1459 FltpFastIoReadCompressed(_In_ PFILE_OBJECT FileObject
,
1460 _In_ PLARGE_INTEGER FileOffset
,
1464 _Out_ PMDL
*MdlChain
,
1465 _Out_ PIO_STATUS_BLOCK IoStatus
,
1466 _Out_ PCOMPRESSED_DATA_INFO CompressedDataInfo
,
1467 _In_ ULONG CompressedDataInfoLength
,
1468 _In_ PDEVICE_OBJECT DeviceObject
)
1470 PFLTMGR_DEVICE_EXTENSION DeviceExtension
;
1471 PDEVICE_OBJECT AttachedDeviceObject
;
1472 PFAST_IO_DISPATCH FastIoDispatch
;
1476 /* If it doesn't have a device extension, then it's not our device object */
1477 if (DeviceObject
->DeviceExtension
== NULL
)
1479 /* Fail the request, send it down the slow path */
1483 DeviceExtension
= DeviceObject
->DeviceExtension
;
1484 FLT_ASSERT(DeviceExtension
->AttachedToDeviceObject
);
1486 /* Get the device that we attached to */
1487 AttachedDeviceObject
= DeviceExtension
->AttachedToDeviceObject
;
1488 FastIoDispatch
= AttachedDeviceObject
->DriverObject
->FastIoDispatch
;
1490 /* Make sure our FastIo table is valid */
1491 if (FastIoDispatch
&& FastIoDispatch
->FastIoReadCompressed
)
1493 /* Forward the call onto the device we attached to */
1494 return FastIoDispatch
->FastIoReadCompressed(FileObject
,
1502 CompressedDataInfoLength
,
1503 AttachedDeviceObject
);
1506 /* We failed to handle the request, send it down the slow path */
1514 FltpFastIoWriteCompressed(_In_ PFILE_OBJECT FileObject
,
1515 _In_ PLARGE_INTEGER FileOffset
,
1519 _Out_ PMDL
*MdlChain
,
1520 _Out_ PIO_STATUS_BLOCK IoStatus
,
1521 _In_ PCOMPRESSED_DATA_INFO CompressedDataInfo
,
1522 _In_ ULONG CompressedDataInfoLength
,
1523 _In_ PDEVICE_OBJECT DeviceObject
)
1525 PFLTMGR_DEVICE_EXTENSION DeviceExtension
;
1526 PDEVICE_OBJECT AttachedDeviceObject
;
1527 PFAST_IO_DISPATCH FastIoDispatch
;
1531 /* If it doesn't have a device extension, then it's not our device object */
1532 if (DeviceObject
->DeviceExtension
== NULL
)
1534 /* Fail the request, send it down the slow path */
1538 DeviceExtension
= DeviceObject
->DeviceExtension
;
1539 FLT_ASSERT(DeviceExtension
->AttachedToDeviceObject
);
1541 /* Get the device that we attached to */
1542 AttachedDeviceObject
= DeviceExtension
->AttachedToDeviceObject
;
1543 FastIoDispatch
= AttachedDeviceObject
->DriverObject
->FastIoDispatch
;
1545 /* Make sure our FastIo table is valid */
1546 if (FastIoDispatch
&& FastIoDispatch
->FastIoWriteCompressed
)
1548 /* Forward the call onto the device we attached to */
1549 return FastIoDispatch
->FastIoWriteCompressed(FileObject
,
1557 CompressedDataInfoLength
,
1558 AttachedDeviceObject
);
1561 /* We failed to handle the request, send it down the slow path */
1569 FltpFastIoMdlReadCompleteCompressed(_In_ PFILE_OBJECT FileObject
,
1571 _In_ PDEVICE_OBJECT DeviceObject
)
1573 PFLTMGR_DEVICE_EXTENSION DeviceExtension
;
1574 PDEVICE_OBJECT AttachedDeviceObject
;
1575 PFAST_IO_DISPATCH FastIoDispatch
;
1579 /* If it doesn't have a device extension, then it's not our device object */
1580 if (DeviceObject
->DeviceExtension
== NULL
)
1585 DeviceExtension
= DeviceObject
->DeviceExtension
;
1586 FLT_ASSERT(DeviceExtension
->AttachedToDeviceObject
);
1588 /* Get the device that we attached to */
1589 AttachedDeviceObject
= DeviceExtension
->AttachedToDeviceObject
;
1590 FastIoDispatch
= AttachedDeviceObject
->DriverObject
->FastIoDispatch
;
1592 /* Make sure our FastIo table is valid */
1593 if (FastIoDispatch
&& FastIoDispatch
->MdlReadCompleteCompressed
)
1595 /* Forward the call onto the device we attached to */
1596 return FastIoDispatch
->MdlReadCompleteCompressed(FileObject
,
1598 AttachedDeviceObject
);
1601 /* We failed to handle the request, send it down the slow path */
1609 FltpFastIoMdlWriteCompleteCompressed(_In_ PFILE_OBJECT FileObject
,
1610 _In_ PLARGE_INTEGER FileOffset
,
1612 _In_ PDEVICE_OBJECT DeviceObject
)
1614 PFLTMGR_DEVICE_EXTENSION DeviceExtension
;
1615 PDEVICE_OBJECT AttachedDeviceObject
;
1616 PFAST_IO_DISPATCH FastIoDispatch
;
1620 /* If it doesn't have a device extension, then it's not our device object */
1621 if (DeviceObject
->DeviceExtension
== NULL
)
1626 DeviceExtension
= DeviceObject
->DeviceExtension
;
1627 FLT_ASSERT(DeviceExtension
->AttachedToDeviceObject
);
1629 /* Get the device that we attached to */
1630 AttachedDeviceObject
= DeviceExtension
->AttachedToDeviceObject
;
1631 FastIoDispatch
= AttachedDeviceObject
->DriverObject
->FastIoDispatch
;
1633 /* Make sure our FastIo table is valid */
1634 if (FastIoDispatch
&& FastIoDispatch
->MdlWriteCompleteCompressed
)
1636 /* Forward the call onto the device we attached to */
1637 return FastIoDispatch
->MdlWriteCompleteCompressed(FileObject
,
1640 AttachedDeviceObject
);
1643 /* We failed to handle the request, send it down the slow path */
1651 FltpFastIoQueryOpen(_Inout_ PIRP Irp
,
1652 _Out_ PFILE_NETWORK_OPEN_INFORMATION NetworkInformation
,
1653 _In_ PDEVICE_OBJECT DeviceObject
)
1655 PFLTMGR_DEVICE_EXTENSION DeviceExtension
;
1656 PDEVICE_OBJECT AttachedDeviceObject
;
1657 PFAST_IO_DISPATCH FastIoDispatch
;
1662 /* If it doesn't have a device extension, then it's not our device object */
1663 if (DeviceObject
->DeviceExtension
== NULL
)
1668 DeviceExtension
= DeviceObject
->DeviceExtension
;
1669 FLT_ASSERT(DeviceExtension
->AttachedToDeviceObject
);
1671 /* Get the device that we attached to */
1672 AttachedDeviceObject
= DeviceExtension
->AttachedToDeviceObject
;
1673 FastIoDispatch
= AttachedDeviceObject
->DriverObject
->FastIoDispatch
;
1675 /* Make sure our FastIo table is valid */
1676 if (FastIoDispatch
&& FastIoDispatch
->FastIoQueryOpen
)
1678 PIO_STACK_LOCATION StackPtr
= IoGetCurrentIrpStackLocation(Irp
);
1680 /* Update the stack to contain the correct device for the next filter */
1681 StackPtr
->DeviceObject
= AttachedDeviceObject
;
1683 /* Now forward the call */
1684 Success
= FastIoDispatch
->FastIoQueryOpen(Irp
,
1686 AttachedDeviceObject
);
1688 /* Restore the DeviceObject as we found it */
1689 StackPtr
->DeviceObject
= DeviceObject
;
1693 /* We failed to handle the request, send it down the slow path */
1699 DRIVER_FS_NOTIFICATION FltpFsNotification
;
1704 FltpFsNotification(_In_ PDEVICE_OBJECT DeviceObject
,
1705 _In_ BOOLEAN FsActive
)
1707 UNICODE_STRING DeviceName
;
1712 /* Set an empty string */
1713 RtlInitUnicodeString(&DeviceName
, NULL
);
1715 /* Get the name of the lowest device object on the stack */
1716 Status
= FltpGetBaseDeviceObjectName(DeviceObject
, &DeviceName
);
1717 if (NT_SUCCESS(Status
))
1719 /* Check if it's attaching or detaching */
1722 /* Run the attach routine */
1723 FltpAttachToFileSystemDevice(DeviceObject
, &DeviceName
);
1727 /* Run the detach routine */
1728 FltpDetachFromFileSystemDevice(DeviceObject
);
1731 /* Free the buffer which FltpGetBaseDeviceObjectName allocated */
1732 FltpFreeUnicodeString(&DeviceName
);
1739 SetupDispatchAndCallbacksTables(_In_ PDRIVER_OBJECT DriverObject
)
1741 PFAST_IO_DISPATCH FastIoDispatch
;
1742 FS_FILTER_CALLBACKS Callbacks
;
1745 /* Plug all the IRPs */
1746 for (i
= 0; i
<= IRP_MJ_MAXIMUM_FUNCTION
; i
++)
1748 DriverObject
->MajorFunction
[i
] = FltpDispatch
;
1751 /* Override the ones we're interested in */
1752 DriverObject
->MajorFunction
[IRP_MJ_CREATE
] = FltpCreate
;
1753 DriverObject
->MajorFunction
[IRP_MJ_CREATE_NAMED_PIPE
] = FltpCreate
;
1754 DriverObject
->MajorFunction
[IRP_MJ_CREATE_MAILSLOT
] = FltpCreate
;
1755 DriverObject
->MajorFunction
[IRP_MJ_FILE_SYSTEM_CONTROL
] = FltpFsControl
;
1756 DriverObject
->MajorFunction
[IRP_MJ_DEVICE_CONTROL
] = FltpDeviceControl
;
1758 /* The FastIo dispatch table is stored in the pool along with a tag */
1759 FastIoDispatch
= ExAllocatePoolWithTag(NonPagedPool
, sizeof(FAST_IO_DISPATCH
), FM_TAG_DISPATCH_TABLE
);
1760 if (FastIoDispatch
== NULL
) return STATUS_INSUFFICIENT_RESOURCES
;
1762 /* Fill out the FastIo table */
1763 RtlZeroMemory(FastIoDispatch
, sizeof(FAST_IO_DISPATCH
));
1764 FastIoDispatch
->SizeOfFastIoDispatch
= sizeof(FAST_IO_DISPATCH
);
1765 FastIoDispatch
->FastIoCheckIfPossible
= FltpFastIoCheckIfPossible
;
1766 FastIoDispatch
->FastIoRead
= FltpFastIoRead
;
1767 FastIoDispatch
->FastIoWrite
= FltpFastIoWrite
;
1768 FastIoDispatch
->FastIoQueryBasicInfo
= FltpFastIoQueryBasicInfo
;
1769 FastIoDispatch
->FastIoQueryStandardInfo
= FltpFastIoQueryStandardInfo
;
1770 FastIoDispatch
->FastIoLock
= FltpFastIoLock
;
1771 FastIoDispatch
->FastIoUnlockSingle
= FltpFastIoUnlockSingle
;
1772 FastIoDispatch
->FastIoUnlockAll
= FltpFastIoUnlockAll
;
1773 FastIoDispatch
->FastIoUnlockAllByKey
= FltpFastIoUnlockAllByKey
;
1774 FastIoDispatch
->FastIoDeviceControl
= FltpFastIoDeviceControl
;
1775 FastIoDispatch
->FastIoDetachDevice
= FltpFastIoDetachDevice
;
1776 FastIoDispatch
->FastIoQueryNetworkOpenInfo
= FltpFastIoQueryNetworkOpenInfo
;
1777 FastIoDispatch
->MdlRead
= FltpFastIoMdlRead
;
1778 FastIoDispatch
->MdlReadComplete
= FltpFastIoMdlReadComplete
;
1779 FastIoDispatch
->PrepareMdlWrite
= FltpFastIoPrepareMdlWrite
;
1780 FastIoDispatch
->MdlWriteComplete
= FltpFastIoMdlWriteComplete
;
1781 FastIoDispatch
->FastIoReadCompressed
= FltpFastIoReadCompressed
;
1782 FastIoDispatch
->FastIoWriteCompressed
= FltpFastIoWriteCompressed
;
1783 FastIoDispatch
->MdlReadCompleteCompressed
= FltpFastIoMdlReadCompleteCompressed
;
1784 FastIoDispatch
->MdlWriteCompleteCompressed
= FltpFastIoMdlWriteCompleteCompressed
;
1785 FastIoDispatch
->FastIoQueryOpen
= FltpFastIoQueryOpen
;
1787 /* Store the FastIo table for internal and our access */
1788 DriverObject
->FastIoDispatch
= FastIoDispatch
;
1789 DriverData
.FastIoDispatch
= FastIoDispatch
;
1791 /* Initialize the callback table */
1792 Callbacks
.SizeOfFsFilterCallbacks
= sizeof(FS_FILTER_CALLBACKS
);
1793 Callbacks
.PreAcquireForSectionSynchronization
= FltpPreFsFilterOperation
;
1794 Callbacks
.PostAcquireForSectionSynchronization
= FltpPostFsFilterOperation
;
1795 Callbacks
.PreReleaseForSectionSynchronization
= FltpPreFsFilterOperation
;
1796 Callbacks
.PostReleaseForSectionSynchronization
= FltpPostFsFilterOperation
;
1797 Callbacks
.PreAcquireForCcFlush
= FltpPreFsFilterOperation
;
1798 Callbacks
.PostAcquireForCcFlush
= FltpPostFsFilterOperation
;
1799 Callbacks
.PreReleaseForCcFlush
= FltpPreFsFilterOperation
;
1800 Callbacks
.PostReleaseForCcFlush
= FltpPostFsFilterOperation
;
1801 Callbacks
.PreAcquireForModifiedPageWriter
= FltpPreFsFilterOperation
;
1802 Callbacks
.PostAcquireForModifiedPageWriter
= FltpPostFsFilterOperation
;
1803 Callbacks
.PreReleaseForModifiedPageWriter
= FltpPreFsFilterOperation
;
1804 Callbacks
.PostReleaseForModifiedPageWriter
= FltpPostFsFilterOperation
;
1806 /* Register our callbacks */
1807 return FsRtlRegisterFileSystemFilterCallbacks(DriverObject
, &Callbacks
);
1810 CODE_SEG("INIT") DRIVER_INITIALIZE DriverEntry
;
1815 DriverEntry(_In_ PDRIVER_OBJECT DriverObject
,
1816 _In_ PUNICODE_STRING RegistryPath
)
1818 UNICODE_STRING DeviceName
= RTL_CONSTANT_STRING(L
"\\FileSystem\\Filters\\"DRIVER_NAME
);
1819 PDEVICE_OBJECT RawDeviceObject
;
1820 PDEVICE_OBJECT DeviceObject
;
1821 PFILE_OBJECT RawFileObject
;
1822 UNICODE_STRING ObjectName
;
1823 UNICODE_STRING SymLink
;
1827 RtlZeroMemory(&DriverData
, sizeof(DRIVER_DATA
));
1828 DriverData
.DriverObject
= DriverObject
;
1830 /* Save the registry key for this driver */
1831 DriverData
.ServiceKey
.Length
= RegistryPath
->Length
;
1832 DriverData
.ServiceKey
.MaximumLength
= RegistryPath
->MaximumLength
;
1833 DriverData
.ServiceKey
.Buffer
= (PWCHAR
)ExAllocatePoolWithTag(NonPagedPool
,
1834 RegistryPath
->MaximumLength
,
1835 FM_TAG_REGISTRY_DATA
);
1836 if (!DriverData
.ServiceKey
.Buffer
) return STATUS_INSUFFICIENT_RESOURCES
;
1837 RtlCopyUnicodeString(&DriverData
.ServiceKey
, RegistryPath
);
1839 /* Do some initialization */
1840 ExInitializeFastMutex(&DriverData
.FilterAttachLock
);
1842 /* Create the main filter manager device object */
1843 Status
= IoCreateDevice(DriverObject
,
1846 FILE_DEVICE_DISK_FILE_SYSTEM
,
1847 FILE_DEVICE_SECURE_OPEN
,
1850 if (!NT_SUCCESS(Status
))
1852 DPRINT1("fltmgr IoCreateDevice failed. Status = %X\n", Status
);
1856 /* Store a global reference so we can access from callbacks */
1857 DriverData
.DeviceObject
= DeviceObject
;
1859 /* Generate the symbolic link name */
1860 RtlInitUnicodeString(&SymLink
, L
"\\??\\"DRIVER_NAME
);
1861 Status
= IoCreateSymbolicLink(&SymLink
, &DeviceName
);
1862 if (!NT_SUCCESS(Status
)) goto Cleanup
;
1864 /* Create the callbacks for the dispatch table, FastIo and FS callbacks */
1865 Status
= SetupDispatchAndCallbacksTables(DriverObject
);
1866 if (!NT_SUCCESS(Status
)) goto Cleanup
;
1868 /* Initialize the comms objects */
1869 Status
= FltpSetupCommunicationObjects(DriverObject
);
1870 if (!NT_SUCCESS(Status
)) goto Cleanup
;
1872 /* Register for notifications when a new file system is loaded. This also enumerates any existing file systems */
1873 Status
= IoRegisterFsRegistrationChange(DriverObject
, FltpFsNotification
);
1874 FLT_ASSERT(Status
!= STATUS_DEVICE_ALREADY_ATTACHED
); // Windows checks for this, I'm not sure how it can happen. Needs investigation??
1875 if (!NT_SUCCESS(Status
)) goto Cleanup
;
1877 InitializeListHead(&FilterList
);
1878 ExInitializeResourceLite(&FilterListLock
);
1880 /* IoRegisterFsRegistrationChange isn't notified about the raw file systems, so we attach to them manually */
1881 RtlInitUnicodeString(&ObjectName
, L
"\\Device\\RawDisk");
1882 Status
= IoGetDeviceObjectPointer(&ObjectName
,
1883 FILE_READ_ATTRIBUTES
,
1886 if (NT_SUCCESS(Status
))
1888 FltpFsNotification(RawDeviceObject
, TRUE
);
1889 ObDereferenceObject(RawFileObject
);
1892 RtlInitUnicodeString(&ObjectName
, L
"\\Device\\RawCdRom");
1893 Status
= IoGetDeviceObjectPointer(&ObjectName
,
1894 FILE_READ_ATTRIBUTES
,
1897 if (NT_SUCCESS(Status
))
1899 FltpFsNotification(RawDeviceObject
, TRUE
);
1900 ObDereferenceObject(RawFileObject
);
1903 /* We're done, clear the initializing flag */
1904 ClearFlag(DeviceObject
->Flags
, DO_DEVICE_INITIALIZING
);
1905 Status
= STATUS_SUCCESS
;
1909 if (!NT_SUCCESS(Status
))
1911 if (DriverData
.FastIoDispatch
)
1913 DriverObject
->FastIoDispatch
= NULL
;
1914 ExFreePoolWithTag(DriverData
.FastIoDispatch
, FM_TAG_DISPATCH_TABLE
);
1917 IoDeleteSymbolicLink(&SymLink
);
1920 IoDeleteDevice(DeviceObject
);
1922 if (DriverData
.ServiceKey
.Buffer
)
1923 ExFreePoolWithTag(DriverData
.ServiceKey
.Buffer
, FM_TAG_REGISTRY_DATA
);