2 * PROJECT: Filesystem Filter Manager
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: drivers/fs_minifilter/fltmgr/interface.c
5 * PURPOSE: Implements the driver interface
6 * PROGRAMMERS: Ged Murphy (gedmurphy@reactos.org)
9 /* INCLUDES ******************************************************************/
17 /* DATA *********************************************************************/
19 DRIVER_INITIALIZE DriverEntry
;
23 _In_ PDRIVER_OBJECT DriverObject
,
24 _In_ PUNICODE_STRING RegistryPath
29 SetupDispatchAndCallbacksTables(
30 _In_ PDRIVER_OBJECT DriverObject
35 FltpAttachDeviceObject(
36 _In_ PDEVICE_OBJECT SourceDevice
,
37 _In_ PDEVICE_OBJECT Targetevice
,
38 _Out_ PDEVICE_OBJECT
*AttachedToDeviceObject
43 FltpCleanupDeviceObject(
44 _In_ PDEVICE_OBJECT DeviceObject
49 FltpIsAttachedToDevice(
50 _In_ PDEVICE_OBJECT DeviceObject
,
51 _In_opt_ PDEVICE_OBJECT
*AttachedDeviceObject
56 FltpEnumerateFileSystemVolumes(
57 _In_ PDEVICE_OBJECT DeviceObject
62 FltpAttachToFileSystemDevice(
63 _In_ PDEVICE_OBJECT DeviceObject
,
64 _In_ PUNICODE_STRING DeviceName
69 FltpDetachFromFileSystemDevice(
70 _In_ PDEVICE_OBJECT DeviceObject
73 DRIVER_FS_NOTIFICATION FltpFsNotification
;
77 _In_ PDEVICE_OBJECT DeviceObject
,
84 _In_ PDEVICE_OBJECT DeviceObject
,
91 _In_ PDEVICE_OBJECT DeviceObject
,
98 _In_ PDEVICE_OBJECT DeviceObject
,
104 FltpFastIoCheckIfPossible(
105 _In_ PFILE_OBJECT FileObject
,
106 _In_ PLARGE_INTEGER FileOffset
,
110 _In_ BOOLEAN CheckForReadOperation
,
111 _Out_ PIO_STATUS_BLOCK IoStatus
,
112 _In_ PDEVICE_OBJECT DeviceObject
119 _In_ PFILE_OBJECT FileObject
,
120 _In_ PLARGE_INTEGER FileOffset
,
125 _Out_ PIO_STATUS_BLOCK IoStatus
,
126 _In_ PDEVICE_OBJECT DeviceObject
132 _In_ PFILE_OBJECT FileObject
,
133 _In_ PLARGE_INTEGER FileOffset
,
138 _Out_ PIO_STATUS_BLOCK IoStatus
,
139 _In_ PDEVICE_OBJECT DeviceObject
144 FltpFastIoQueryBasicInfo(
145 _In_ PFILE_OBJECT FileObject
,
147 _Out_ PFILE_BASIC_INFORMATION Buffer
,
148 _Out_ PIO_STATUS_BLOCK IoStatus
,
149 _In_ PDEVICE_OBJECT DeviceObject
154 FltpFastIoQueryStandardInfo(
155 _In_ PFILE_OBJECT FileObject
,
157 _Out_ PFILE_STANDARD_INFORMATION Buffer
,
158 _Out_ PIO_STATUS_BLOCK IoStatus
,
159 _In_ PDEVICE_OBJECT DeviceObject
165 _In_ PFILE_OBJECT FileObject
,
166 _In_ PLARGE_INTEGER FileOffset
,
167 _In_ PLARGE_INTEGER Length
,
168 _In_ PEPROCESS ProcessId
,
170 _In_ BOOLEAN FailImmediately
,
171 _In_ BOOLEAN ExclusiveLock
,
172 _Out_ PIO_STATUS_BLOCK IoStatus
,
173 _In_ PDEVICE_OBJECT DeviceObject
178 FltpFastIoUnlockSingle(
179 _In_ PFILE_OBJECT FileObject
,
180 _In_ PLARGE_INTEGER FileOffset
,
181 _In_ PLARGE_INTEGER Length
,
182 _In_ PEPROCESS ProcessId
,
184 _Out_ PIO_STATUS_BLOCK IoStatus
,
185 _In_ PDEVICE_OBJECT DeviceObject
191 _In_ PFILE_OBJECT FileObject
,
192 _In_ PEPROCESS ProcessId
,
193 _Out_ PIO_STATUS_BLOCK IoStatus
,
194 _In_ PDEVICE_OBJECT DeviceObject
199 FltpFastIoUnlockAllByKey(
200 _In_ PFILE_OBJECT FileObject
,
201 _In_ PVOID ProcessId
,
203 _Out_ PIO_STATUS_BLOCK IoStatus
,
204 _In_ PDEVICE_OBJECT DeviceObject
209 FltpFastIoDeviceControl(
210 _In_ PFILE_OBJECT FileObject
,
212 _In_opt_ PVOID InputBuffer
,
213 _In_ ULONG InputBufferLength
,
214 _Out_opt_ PVOID OutputBuffer
,
215 _In_ ULONG OutputBufferLength
,
216 _In_ ULONG IoControlCode
,
217 _Out_ PIO_STATUS_BLOCK IoStatus
,
218 _In_ PDEVICE_OBJECT DeviceObject
223 FltpFastIoDetachDevice(
224 _In_ PDEVICE_OBJECT SourceDevice
,
225 _In_ PDEVICE_OBJECT TargetDevice
230 FltpFastIoQueryNetworkOpenInfo(
231 _In_ PFILE_OBJECT FileObject
,
233 _Out_ PFILE_NETWORK_OPEN_INFORMATION Buffer
,
234 _Out_ PIO_STATUS_BLOCK IoStatus
,
235 _In_ PDEVICE_OBJECT DeviceObject
241 _In_ PFILE_OBJECT FileObject
,
242 _In_ PLARGE_INTEGER FileOffset
,
245 _Out_ PMDL
*MdlChain
,
246 _Out_ PIO_STATUS_BLOCK IoStatus
,
247 _In_ PDEVICE_OBJECT DeviceObject
252 FltpFastIoMdlReadComplete(
253 _In_ PFILE_OBJECT FileObject
,
255 _In_ PDEVICE_OBJECT DeviceObject
260 FltpFastIoPrepareMdlWrite(
261 _In_ PFILE_OBJECT FileObject
,
262 _In_ PLARGE_INTEGER FileOffset
,
265 _Out_ PMDL
*MdlChain
,
266 _Out_ PIO_STATUS_BLOCK IoStatus
,
267 _In_ PDEVICE_OBJECT DeviceObject
272 FltpFastIoMdlWriteComplete(
273 _In_ PFILE_OBJECT FileObject
,
274 _In_ PLARGE_INTEGER FileOffset
,
276 _In_ PDEVICE_OBJECT DeviceObject
281 FltpFastIoReadCompressed(
282 _In_ PFILE_OBJECT FileObject
,
283 _In_ PLARGE_INTEGER FileOffset
,
287 _Out_ PMDL
*MdlChain
,
288 _Out_ PIO_STATUS_BLOCK IoStatus
,
289 _Out_ PCOMPRESSED_DATA_INFO CompressedDataInfo
,
290 _In_ ULONG CompressedDataInfoLength
,
291 _In_ PDEVICE_OBJECT DeviceObject
296 FltpFastIoWriteCompressed(
297 _In_ PFILE_OBJECT FileObject
,
298 _In_ PLARGE_INTEGER FileOffset
,
302 _Out_ PMDL
*MdlChain
,
303 _Out_ PIO_STATUS_BLOCK IoStatus
,
304 _In_ PCOMPRESSED_DATA_INFO CompressedDataInfo
,
305 _In_ ULONG CompressedDataInfoLength
,
306 _In_ PDEVICE_OBJECT DeviceObject
311 FltpFastIoMdlReadCompleteCompressed(
312 _In_ PFILE_OBJECT FileObject
,
314 _In_ PDEVICE_OBJECT DeviceObject
319 FltpFastIoMdlWriteCompleteCompressed(
320 _In_ PFILE_OBJECT FileObject
,
321 _In_ PLARGE_INTEGER FileOffset
,
323 _In_ PDEVICE_OBJECT DeviceObject
330 _Out_ PFILE_NETWORK_OPEN_INFORMATION NetworkInformation
,
331 _In_ PDEVICE_OBJECT DeviceObject
337 #pragma alloc_text(INIT, DriverEntry)
338 #pragma alloc_text(INIT, SetupDispatchAndCallbacksTables)
339 #pragma alloc_text(PAGE, FltpAttachDeviceObject)
340 #pragma alloc_text(PAGE, FltpIsAttachedToDevice)
341 #pragma alloc_text(PAGE, FltpEnumerateFileSystemVolumes)
342 #pragma alloc_text(PAGE, FltpAttachToFileSystemDevice)
343 #pragma alloc_text(PAGE, FltpDetachFromFileSystemDevice)
344 #pragma alloc_text(PAGE, FltpFsNotification)
345 #pragma alloc_text(PAGE, FltpCreate)
346 #pragma alloc_text(PAGE, FltpFsControl)
347 #pragma alloc_text(PAGE, FltpFastIoRead)
348 #pragma alloc_text(PAGE, FltpFastIoWrite)
349 #pragma alloc_text(PAGE, FltpFastIoQueryBasicInfo)
350 #pragma alloc_text(PAGE, FltpFastIoQueryStandardInfo)
351 #pragma alloc_text(PAGE, FltpFastIoLock)
352 #pragma alloc_text(PAGE, FltpFastIoUnlockSingle)
353 #pragma alloc_text(PAGE, FltpFastIoUnlockAll)
354 #pragma alloc_text(PAGE, FltpFastIoUnlockAllByKey)
355 #pragma alloc_text(PAGE, FltpFastIoDeviceControl)
356 #pragma alloc_text(PAGE, FltpFastIoDetachDevice)
357 #pragma alloc_text(PAGE, FltpFastIoQueryNetworkOpenInfo)
358 #pragma alloc_text(PAGE, FltpFastIoMdlRead)
359 #pragma alloc_text(PAGE, FltpFastIoMdlReadComplete)
360 #pragma alloc_text(PAGE, FltpFastIoPrepareMdlWrite)
361 #pragma alloc_text(PAGE, FltpFastIoMdlWriteComplete)
362 #pragma alloc_text(PAGE, FltpFastIoReadCompressed)
363 #pragma alloc_text(PAGE, FltpFastIoWriteCompressed)
364 #pragma alloc_text(PAGE, FltpFastIoMdlReadCompleteCompressed)
365 #pragma alloc_text(PAGE, FltpFastIoMdlWriteCompleteCompressed)
366 #pragma alloc_text(PAGE, FltpFastIoQueryOpen)
369 #define MAX_DEVNAME_LENGTH 64
371 DRIVER_DATA DriverData
;
374 typedef struct _FLTMGR_DEVICE_EXTENSION
376 /* The file system we're attached to */
377 PDEVICE_OBJECT AttachedToDeviceObject
;
379 /* The storage stack(disk) accociated with the file system device object we're attached to */
380 PDEVICE_OBJECT StorageStackDeviceObject
;
382 /* Either physical drive for volume device objects otherwise
383 * it's the name of the control device we're attached to */
384 UNICODE_STRING DeviceName
;
385 WCHAR DeviceNameBuffer
[MAX_DEVNAME_LENGTH
];
387 } FLTMGR_DEVICE_EXTENSION
, *PFLTMGR_DEVICE_EXTENSION
;
389 typedef struct _DETACH_DEVICE_WORK_ITEM
391 WORK_QUEUE_ITEM WorkItem
;
392 PDEVICE_OBJECT SourceDevice
;
393 PDEVICE_OBJECT TargetDevice
;
395 } DETACH_DEVICE_WORK_ITEM
, *PDETACH_DEVICE_WORK_ITEM
;
398 /* DISPATCH ROUTINES **********************************************/
402 FltpPreFsFilterOperation(_In_ PFS_FILTER_CALLBACK_DATA Data
,
403 _Out_ PVOID
*CompletionContext
)
405 UNREFERENCED_PARAMETER(Data
);
406 UNREFERENCED_PARAMETER(CompletionContext
);
408 return STATUS_SUCCESS
;
413 FltpPostFsFilterOperation(_In_ PFS_FILTER_CALLBACK_DATA Data
,
414 _In_ NTSTATUS OperationStatus
,
415 _In_ PVOID CompletionContext
)
417 UNREFERENCED_PARAMETER(Data
);
418 UNREFERENCED_PARAMETER(OperationStatus
);
419 UNREFERENCED_PARAMETER(CompletionContext
);
425 FltpDispatch(_In_ PDEVICE_OBJECT DeviceObject
,
428 PFLTMGR_DEVICE_EXTENSION DeviceExtension
;
429 PIO_STACK_LOCATION StackPtr
;
431 DeviceExtension
= DeviceObject
->DeviceExtension
;
433 FLT_ASSERT(DeviceExtension
&&
434 DeviceExtension
->AttachedToDeviceObject
);
436 StackPtr
= IoGetCurrentIrpStackLocation(Irp
);
437 if (StackPtr
->MajorFunction
== IRP_MJ_SHUTDOWN
)
439 //FltpProcessShutdownRequest(DeviceObject);
442 /* Just pass the IRP down the stack */
443 IoSkipCurrentIrpStackLocation(Irp
);
444 return IoCallDriver(DeviceExtension
->AttachedToDeviceObject
, Irp
);
449 FltpCreate(_In_ PDEVICE_OBJECT DeviceObject
,
452 PFLTMGR_DEVICE_EXTENSION DeviceExtension
;
456 DeviceExtension
= DeviceObject
->DeviceExtension
;
458 FLT_ASSERT(DeviceExtension
&&
459 DeviceExtension
->AttachedToDeviceObject
);
461 /* Just pass the IRP down the stack */
462 IoSkipCurrentIrpStackLocation(Irp
);
463 return IoCallDriver(DeviceExtension
->AttachedToDeviceObject
, Irp
);
468 FltpFsControl(_In_ PDEVICE_OBJECT DeviceObject
,
471 PFLTMGR_DEVICE_EXTENSION DeviceExtension
;
475 DeviceExtension
= DeviceObject
->DeviceExtension
;
477 FLT_ASSERT(DeviceExtension
&&
478 DeviceExtension
->AttachedToDeviceObject
);
479 /* Just pass the IRP down the stack */
480 IoSkipCurrentIrpStackLocation(Irp
);
481 return IoCallDriver(DeviceExtension
->AttachedToDeviceObject
, Irp
);
486 /* FASTIO ROUTINES ************************************************/
490 FltpFastIoCheckIfPossible(_In_ PFILE_OBJECT FileObject
,
491 _In_ PLARGE_INTEGER FileOffset
,
495 _In_ BOOLEAN CheckForReadOperation
,
496 _Out_ PIO_STATUS_BLOCK IoStatus
,
497 _In_ PDEVICE_OBJECT DeviceObject
)
500 PFLTMGR_DEVICE_EXTENSION DeviceExtension
;
501 PDEVICE_OBJECT AttachedDeviceObject
;
502 PFAST_IO_DISPATCH FastIoDispatch
;
506 /* If it doesn't have a device extension, then it's not our device object */
507 if (DeviceObject
->DeviceExtension
== NULL
)
510 IoStatus
->Status
= STATUS_INVALID_DEVICE_REQUEST
;
511 IoStatus
->Information
= 0;
515 DeviceExtension
= DeviceObject
->DeviceExtension
;
516 FLT_ASSERT(DeviceExtension
->AttachedToDeviceObject
);
518 /* Get the device that we attached to */
519 AttachedDeviceObject
= DeviceExtension
->AttachedToDeviceObject
;
520 FastIoDispatch
= AttachedDeviceObject
->DriverObject
->FastIoDispatch
;
522 /* Make sure our FastIo table is valid */
523 if (FastIoDispatch
&& FastIoDispatch
->FastIoCheckIfPossible
)
525 /* Forward the call onto the device we attached to */
526 return FastIoDispatch
->FastIoCheckIfPossible(FileObject
,
531 CheckForReadOperation
,
533 AttachedDeviceObject
);
536 /* We failed to handle the request, send it down the slow path */
543 FltpFastIoRead(_In_ PFILE_OBJECT FileObject
,
544 _In_ PLARGE_INTEGER FileOffset
,
549 _Out_ PIO_STATUS_BLOCK IoStatus
,
550 _In_ PDEVICE_OBJECT DeviceObject
)
552 PFLTMGR_DEVICE_EXTENSION DeviceExtension
;
553 PDEVICE_OBJECT AttachedDeviceObject
;
554 PFAST_IO_DISPATCH FastIoDispatch
;
558 /* If it doesn't have a device extension, then it's not our device object */
559 if (DeviceObject
->DeviceExtension
== NULL
)
562 IoStatus
->Status
= STATUS_INVALID_DEVICE_REQUEST
;
563 IoStatus
->Information
= 0;
567 DeviceExtension
= DeviceObject
->DeviceExtension
;
568 FLT_ASSERT(DeviceExtension
->AttachedToDeviceObject
);
570 /* Get the device that we attached to */
571 AttachedDeviceObject
= DeviceExtension
->AttachedToDeviceObject
;
572 FastIoDispatch
= AttachedDeviceObject
->DriverObject
->FastIoDispatch
;
574 /* Make sure our FastIo table is valid */
575 if (FastIoDispatch
&& FastIoDispatch
->FastIoRead
)
577 /* Forward the call onto the device we attached to */
578 return FastIoDispatch
->FastIoRead(FileObject
,
585 AttachedDeviceObject
);
588 /* We failed to handle the request, send it down the slow path */
595 FltpFastIoWrite(_In_ PFILE_OBJECT FileObject
,
596 _In_ PLARGE_INTEGER FileOffset
,
601 _Out_ PIO_STATUS_BLOCK IoStatus
,
602 _In_ PDEVICE_OBJECT DeviceObject
)
604 PFLTMGR_DEVICE_EXTENSION DeviceExtension
;
605 PDEVICE_OBJECT AttachedDeviceObject
;
606 PFAST_IO_DISPATCH FastIoDispatch
;
610 /* If it doesn't have a device extension, then it's not our device object */
611 if (DeviceObject
->DeviceExtension
== NULL
)
614 IoStatus
->Status
= STATUS_INVALID_DEVICE_REQUEST
;
615 IoStatus
->Information
= 0;
619 DeviceExtension
= DeviceObject
->DeviceExtension
;
620 FLT_ASSERT(DeviceExtension
->AttachedToDeviceObject
);
622 /* Get the device that we attached to */
623 AttachedDeviceObject
= DeviceExtension
->AttachedToDeviceObject
;
624 FastIoDispatch
= AttachedDeviceObject
->DriverObject
->FastIoDispatch
;
626 /* Make sure our FastIo table is valid */
627 if (FastIoDispatch
&& FastIoDispatch
->FastIoWrite
)
629 /* Forward the call onto the device we attached to */
630 return FastIoDispatch
->FastIoWrite(FileObject
,
637 AttachedDeviceObject
);
640 /* We failed to handle the request, send it down the slow path */
647 FltpFastIoQueryBasicInfo(_In_ PFILE_OBJECT FileObject
,
649 _Out_ PFILE_BASIC_INFORMATION Buffer
,
650 _Out_ PIO_STATUS_BLOCK IoStatus
,
651 _In_ PDEVICE_OBJECT DeviceObject
)
653 PFLTMGR_DEVICE_EXTENSION DeviceExtension
;
654 PDEVICE_OBJECT AttachedDeviceObject
;
655 PFAST_IO_DISPATCH FastIoDispatch
;
659 /* If it doesn't have a device extension, then it's not our device object */
660 if (DeviceObject
->DeviceExtension
== NULL
)
663 IoStatus
->Status
= STATUS_INVALID_DEVICE_REQUEST
;
664 IoStatus
->Information
= 0;
668 DeviceExtension
= DeviceObject
->DeviceExtension
;
669 FLT_ASSERT(DeviceExtension
->AttachedToDeviceObject
);
671 /* Get the device that we attached to */
672 AttachedDeviceObject
= DeviceExtension
->AttachedToDeviceObject
;
673 FastIoDispatch
= AttachedDeviceObject
->DriverObject
->FastIoDispatch
;
675 /* Make sure our FastIo table is valid */
676 if (FastIoDispatch
&& FastIoDispatch
->FastIoQueryBasicInfo
)
678 /* Forward the call onto the device we attached to */
679 return FastIoDispatch
->FastIoQueryBasicInfo(FileObject
,
683 AttachedDeviceObject
);
686 /* We failed to handle the request, send it down the slow path */
693 FltpFastIoQueryStandardInfo(_In_ PFILE_OBJECT FileObject
,
695 _Out_ PFILE_STANDARD_INFORMATION Buffer
,
696 _Out_ PIO_STATUS_BLOCK IoStatus
,
697 _In_ PDEVICE_OBJECT DeviceObject
)
699 PFLTMGR_DEVICE_EXTENSION DeviceExtension
;
700 PDEVICE_OBJECT AttachedDeviceObject
;
701 PFAST_IO_DISPATCH FastIoDispatch
;
705 /* If it doesn't have a device extension, then it's not our device object */
706 if (DeviceObject
->DeviceExtension
== NULL
)
709 IoStatus
->Status
= STATUS_INVALID_DEVICE_REQUEST
;
710 IoStatus
->Information
= 0;
714 DeviceExtension
= DeviceObject
->DeviceExtension
;
715 FLT_ASSERT(DeviceExtension
->AttachedToDeviceObject
);
717 /* Get the device that we attached to */
718 AttachedDeviceObject
= DeviceExtension
->AttachedToDeviceObject
;
719 FastIoDispatch
= AttachedDeviceObject
->DriverObject
->FastIoDispatch
;
721 /* Make sure our FastIo table is valid */
722 if (FastIoDispatch
&& FastIoDispatch
->FastIoQueryStandardInfo
)
724 /* Forward the call onto the device we attached to */
725 return FastIoDispatch
->FastIoQueryStandardInfo(FileObject
,
729 AttachedDeviceObject
);
732 /* We failed to handle the request, send it down the slow path */
739 FltpFastIoLock(_In_ PFILE_OBJECT FileObject
,
740 _In_ PLARGE_INTEGER FileOffset
,
741 _In_ PLARGE_INTEGER Length
,
742 _In_ PEPROCESS ProcessId
,
744 _In_ BOOLEAN FailImmediately
,
745 _In_ BOOLEAN ExclusiveLock
,
746 _Out_ PIO_STATUS_BLOCK IoStatus
,
747 _In_ PDEVICE_OBJECT DeviceObject
)
749 PFLTMGR_DEVICE_EXTENSION DeviceExtension
;
750 PDEVICE_OBJECT AttachedDeviceObject
;
751 PFAST_IO_DISPATCH FastIoDispatch
;
755 /* If it doesn't have a device extension, then it's not our device object */
756 if (DeviceObject
->DeviceExtension
== NULL
)
759 IoStatus
->Status
= STATUS_INVALID_DEVICE_REQUEST
;
760 IoStatus
->Information
= 0;
764 DeviceExtension
= DeviceObject
->DeviceExtension
;
765 FLT_ASSERT(DeviceExtension
->AttachedToDeviceObject
);
767 /* Get the device that we attached to */
768 AttachedDeviceObject
= DeviceExtension
->AttachedToDeviceObject
;
769 FastIoDispatch
= AttachedDeviceObject
->DriverObject
->FastIoDispatch
;
771 /* Make sure our FastIo table is valid */
772 if (FastIoDispatch
&& FastIoDispatch
->FastIoLock
)
774 /* Forward the call onto the device we attached to */
775 return FastIoDispatch
->FastIoLock(FileObject
,
783 AttachedDeviceObject
);
786 /* We failed to handle the request, send it down the slow path */
793 FltpFastIoUnlockSingle(_In_ PFILE_OBJECT FileObject
,
794 _In_ PLARGE_INTEGER FileOffset
,
795 _In_ PLARGE_INTEGER Length
,
796 _In_ PEPROCESS ProcessId
,
798 _Out_ PIO_STATUS_BLOCK IoStatus
,
799 _In_ PDEVICE_OBJECT DeviceObject
)
801 PFLTMGR_DEVICE_EXTENSION DeviceExtension
;
802 PDEVICE_OBJECT AttachedDeviceObject
;
803 PFAST_IO_DISPATCH FastIoDispatch
;
807 /* If it doesn't have a device extension, then it's not our device object */
808 if (DeviceObject
->DeviceExtension
== NULL
)
811 IoStatus
->Status
= STATUS_INVALID_DEVICE_REQUEST
;
812 IoStatus
->Information
= 0;
816 DeviceExtension
= DeviceObject
->DeviceExtension
;
817 FLT_ASSERT(DeviceExtension
->AttachedToDeviceObject
);
819 /* Get the device that we attached to */
820 AttachedDeviceObject
= DeviceExtension
->AttachedToDeviceObject
;
821 FastIoDispatch
= AttachedDeviceObject
->DriverObject
->FastIoDispatch
;
823 /* Make sure our FastIo table is valid */
824 if (FastIoDispatch
&& FastIoDispatch
->FastIoUnlockSingle
)
826 /* Forward the call onto the device we attached to */
827 return FastIoDispatch
->FastIoUnlockSingle(FileObject
,
833 AttachedDeviceObject
);
836 /* We failed to handle the request, send it down the slow path */
843 FltpFastIoUnlockAll(_In_ PFILE_OBJECT FileObject
,
844 _In_ PEPROCESS ProcessId
,
845 _Out_ PIO_STATUS_BLOCK IoStatus
,
846 _In_ PDEVICE_OBJECT DeviceObject
)
849 PFLTMGR_DEVICE_EXTENSION DeviceExtension
;
850 PDEVICE_OBJECT AttachedDeviceObject
;
851 PFAST_IO_DISPATCH FastIoDispatch
;
855 /* If it doesn't have a device extension, then it's not our device object */
856 if (DeviceObject
->DeviceExtension
== NULL
)
859 IoStatus
->Status
= STATUS_INVALID_DEVICE_REQUEST
;
860 IoStatus
->Information
= 0;
864 DeviceExtension
= DeviceObject
->DeviceExtension
;
865 FLT_ASSERT(DeviceExtension
->AttachedToDeviceObject
);
867 /* Get the device that we attached to */
868 AttachedDeviceObject
= DeviceExtension
->AttachedToDeviceObject
;
869 FastIoDispatch
= AttachedDeviceObject
->DriverObject
->FastIoDispatch
;
871 /* Make sure our FastIo table is valid */
872 if (FastIoDispatch
&& FastIoDispatch
->FastIoUnlockAll
)
874 /* Forward the call onto the device we attached to */
875 return FastIoDispatch
->FastIoUnlockAll(FileObject
,
878 AttachedDeviceObject
);
881 /* We failed to handle the request, send it down the slow path */
888 FltpFastIoUnlockAllByKey(_In_ PFILE_OBJECT FileObject
,
889 _In_ PVOID ProcessId
,
891 _Out_ PIO_STATUS_BLOCK IoStatus
,
892 _In_ PDEVICE_OBJECT DeviceObject
)
894 PFLTMGR_DEVICE_EXTENSION DeviceExtension
;
895 PDEVICE_OBJECT AttachedDeviceObject
;
896 PFAST_IO_DISPATCH FastIoDispatch
;
900 /* If it doesn't have a device extension, then it's not our device object */
901 if (DeviceObject
->DeviceExtension
== NULL
)
904 IoStatus
->Status
= STATUS_INVALID_DEVICE_REQUEST
;
905 IoStatus
->Information
= 0;
909 DeviceExtension
= DeviceObject
->DeviceExtension
;
910 FLT_ASSERT(DeviceExtension
->AttachedToDeviceObject
);
912 /* Get the device that we attached to */
913 AttachedDeviceObject
= DeviceExtension
->AttachedToDeviceObject
;
914 FastIoDispatch
= AttachedDeviceObject
->DriverObject
->FastIoDispatch
;
916 /* Make sure our FastIo table is valid */
917 if (FastIoDispatch
&& FastIoDispatch
->FastIoUnlockAllByKey
)
919 /* Forward the call onto the device we attached to */
920 return FastIoDispatch
->FastIoUnlockAllByKey(FileObject
,
924 AttachedDeviceObject
);
927 /* We failed to handle the request, send it down the slow path */
934 FltpFastIoDeviceControl(_In_ PFILE_OBJECT FileObject
,
936 _In_opt_ PVOID InputBuffer
,
937 _In_ ULONG InputBufferLength
,
938 _Out_opt_ PVOID OutputBuffer
,
939 _In_ ULONG OutputBufferLength
,
940 _In_ ULONG IoControlCode
,
941 _Out_ PIO_STATUS_BLOCK IoStatus
,
942 _In_ PDEVICE_OBJECT DeviceObject
)
944 PFLTMGR_DEVICE_EXTENSION DeviceExtension
;
945 PDEVICE_OBJECT AttachedDeviceObject
;
946 PFAST_IO_DISPATCH FastIoDispatch
;
950 /* If it doesn't have a device extension, then it's not our device object */
951 if (DeviceObject
->DeviceExtension
== NULL
)
953 /* Fail the request, send it down the slow path */
957 DeviceExtension
= DeviceObject
->DeviceExtension
;
958 FLT_ASSERT(DeviceExtension
->AttachedToDeviceObject
);
960 /* Get the device that we attached to */
961 AttachedDeviceObject
= DeviceExtension
->AttachedToDeviceObject
;
962 FastIoDispatch
= AttachedDeviceObject
->DriverObject
->FastIoDispatch
;
964 /* Make sure our FastIo table is valid */
965 if (FastIoDispatch
&& FastIoDispatch
->FastIoDeviceControl
)
967 /* Forward the call onto the device we attached to */
968 return FastIoDispatch
->FastIoDeviceControl(FileObject
,
976 AttachedDeviceObject
);
979 /* We failed to handle the request, send it down the slow path */
986 FltpFastIoDetachDeviceWorker(_In_ PVOID Parameter
)
988 PDETACH_DEVICE_WORK_ITEM DetachDeviceWorkItem
= Parameter
;
990 /* Run any cleanup routines */
991 FltpCleanupDeviceObject(DetachDeviceWorkItem
->SourceDevice
);
993 /* Detach from the target device */
994 IoDetachDevice(DetachDeviceWorkItem
->TargetDevice
);
996 /* Delete the source */
997 IoDeleteDevice(DetachDeviceWorkItem
->SourceDevice
);
999 /* Free the pool we allocated in FltpFastIoDetachDevice */
1000 ExFreePoolWithTag(DetachDeviceWorkItem
, 0x1234);
1005 FltpFastIoDetachDevice(_In_ PDEVICE_OBJECT SourceDevice
,
1006 _In_ PDEVICE_OBJECT TargetDevice
)
1008 PDETACH_DEVICE_WORK_ITEM DetachDeviceWorkItem
;
1013 * Detaching and deleting devices is a lot of work and takes too long
1014 * to be a worthwhile FastIo candidate, so we defer this call to speed
1015 * it up. There's no return value so we're okay to do this.
1018 /* Allocate the work item and it's corresponding data */
1019 DetachDeviceWorkItem
= ExAllocatePoolWithTag(NonPagedPool
,
1020 sizeof(DETACH_DEVICE_WORK_ITEM
),
1022 if (DetachDeviceWorkItem
)
1024 /* Initialize the work item */
1025 ExInitializeWorkItem(&DetachDeviceWorkItem
->WorkItem
,
1026 FltpFastIoDetachDeviceWorker
,
1027 DetachDeviceWorkItem
);
1029 /* Queue the work item and return the call */
1030 ExQueueWorkItem(&DetachDeviceWorkItem
->WorkItem
,
1035 /* We failed to defer, just cleanup here */
1036 FltpCleanupDeviceObject(SourceDevice
);
1037 IoDetachDevice(TargetDevice
);
1038 IoDeleteDevice(SourceDevice
);
1045 FltpFastIoQueryNetworkOpenInfo(_In_ PFILE_OBJECT FileObject
,
1047 _Out_ PFILE_NETWORK_OPEN_INFORMATION Buffer
,
1048 _Out_ PIO_STATUS_BLOCK IoStatus
,
1049 _In_ PDEVICE_OBJECT DeviceObject
)
1051 PFLTMGR_DEVICE_EXTENSION DeviceExtension
;
1052 PDEVICE_OBJECT AttachedDeviceObject
;
1053 PFAST_IO_DISPATCH FastIoDispatch
;
1057 /* If it doesn't have a device extension, then it's not our device object */
1058 if (DeviceObject
->DeviceExtension
== NULL
)
1061 IoStatus
->Status
= STATUS_INVALID_DEVICE_REQUEST
;
1062 IoStatus
->Information
= 0;
1066 DeviceExtension
= DeviceObject
->DeviceExtension
;
1067 FLT_ASSERT(DeviceExtension
->AttachedToDeviceObject
);
1069 /* Get the device that we attached to */
1070 AttachedDeviceObject
= DeviceExtension
->AttachedToDeviceObject
;
1071 FastIoDispatch
= AttachedDeviceObject
->DriverObject
->FastIoDispatch
;
1073 /* Make sure our FastIo table is valid */
1074 if (FastIoDispatch
&& FastIoDispatch
->FastIoQueryNetworkOpenInfo
)
1076 /* Forward the call onto the device we attached to */
1077 return FastIoDispatch
->FastIoQueryNetworkOpenInfo(FileObject
,
1081 AttachedDeviceObject
);
1084 /* We failed to handle the request, send it down the slow path */
1091 FltpFastIoMdlRead(_In_ PFILE_OBJECT FileObject
,
1092 _In_ PLARGE_INTEGER FileOffset
,
1095 _Out_ PMDL
*MdlChain
,
1096 _Out_ PIO_STATUS_BLOCK IoStatus
,
1097 _In_ PDEVICE_OBJECT DeviceObject
)
1099 PFLTMGR_DEVICE_EXTENSION DeviceExtension
;
1100 PDEVICE_OBJECT AttachedDeviceObject
;
1101 PFAST_IO_DISPATCH FastIoDispatch
;
1105 /* If it doesn't have a device extension, then it's not our device object */
1106 if (DeviceObject
->DeviceExtension
== NULL
)
1109 IoStatus
->Status
= STATUS_INVALID_DEVICE_REQUEST
;
1110 IoStatus
->Information
= 0;
1114 DeviceExtension
= DeviceObject
->DeviceExtension
;
1115 FLT_ASSERT(DeviceExtension
->AttachedToDeviceObject
);
1117 /* Get the device that we attached to */
1118 AttachedDeviceObject
= DeviceExtension
->AttachedToDeviceObject
;
1119 FastIoDispatch
= AttachedDeviceObject
->DriverObject
->FastIoDispatch
;
1121 /* Make sure our FastIo table is valid */
1122 if (FastIoDispatch
&& FastIoDispatch
->MdlRead
)
1124 /* Forward the call onto the device we attached to */
1125 return FastIoDispatch
->MdlRead(FileObject
,
1131 AttachedDeviceObject
);
1134 /* We failed to handle the request, send it down the slow path */
1141 FltpFastIoMdlReadComplete(_In_ PFILE_OBJECT FileObject
,
1143 _In_ PDEVICE_OBJECT DeviceObject
)
1146 PFLTMGR_DEVICE_EXTENSION DeviceExtension
;
1147 PDEVICE_OBJECT AttachedDeviceObject
;
1148 PFAST_IO_DISPATCH FastIoDispatch
;
1152 /* If it doesn't have a device extension, then it's not our device object */
1153 if (DeviceObject
->DeviceExtension
== NULL
)
1155 /* Fail the request, send it down the slow path */
1159 DeviceExtension
= DeviceObject
->DeviceExtension
;
1160 FLT_ASSERT(DeviceExtension
->AttachedToDeviceObject
);
1162 /* Get the device that we attached to */
1163 AttachedDeviceObject
= DeviceExtension
->AttachedToDeviceObject
;
1164 FastIoDispatch
= AttachedDeviceObject
->DriverObject
->FastIoDispatch
;
1166 /* Make sure our FastIo table is valid */
1167 if (FastIoDispatch
&& FastIoDispatch
->MdlReadComplete
)
1169 /* Forward the call onto the device we attached to */
1170 return FastIoDispatch
->MdlReadComplete(FileObject
,
1172 AttachedDeviceObject
);
1175 /* We failed to handle the request, send it down the slow path */
1182 FltpFastIoPrepareMdlWrite(_In_ PFILE_OBJECT FileObject
,
1183 _In_ PLARGE_INTEGER FileOffset
,
1186 _Out_ PMDL
*MdlChain
,
1187 _Out_ PIO_STATUS_BLOCK IoStatus
,
1188 _In_ PDEVICE_OBJECT DeviceObject
)
1190 PFLTMGR_DEVICE_EXTENSION DeviceExtension
;
1191 PDEVICE_OBJECT AttachedDeviceObject
;
1192 PFAST_IO_DISPATCH FastIoDispatch
;
1196 /* If it doesn't have a device extension, then it's not our device object */
1197 if (DeviceObject
->DeviceExtension
== NULL
)
1200 IoStatus
->Status
= STATUS_INVALID_DEVICE_REQUEST
;
1201 IoStatus
->Information
= 0;
1205 DeviceExtension
= DeviceObject
->DeviceExtension
;
1206 FLT_ASSERT(DeviceExtension
->AttachedToDeviceObject
);
1208 /* Get the device that we attached to */
1209 AttachedDeviceObject
= DeviceExtension
->AttachedToDeviceObject
;
1210 FastIoDispatch
= AttachedDeviceObject
->DriverObject
->FastIoDispatch
;
1212 /* Make sure our FastIo table is valid */
1213 if (FastIoDispatch
&& FastIoDispatch
->PrepareMdlWrite
)
1215 /* Forward the call onto the device we attached to */
1216 return FastIoDispatch
->PrepareMdlWrite(FileObject
,
1222 AttachedDeviceObject
);
1225 /* We failed to handle the request, send it down the slow path */
1232 FltpFastIoMdlWriteComplete(_In_ PFILE_OBJECT FileObject
,
1233 _In_ PLARGE_INTEGER FileOffset
,
1235 _In_ PDEVICE_OBJECT DeviceObject
)
1237 PFLTMGR_DEVICE_EXTENSION DeviceExtension
;
1238 PDEVICE_OBJECT AttachedDeviceObject
;
1239 PFAST_IO_DISPATCH FastIoDispatch
;
1243 /* If it doesn't have a device extension, then it's not our device object */
1244 if (DeviceObject
->DeviceExtension
== NULL
)
1246 /* Fail the request, send it down the slow path */
1250 DeviceExtension
= DeviceObject
->DeviceExtension
;
1251 FLT_ASSERT(DeviceExtension
->AttachedToDeviceObject
);
1253 /* Get the device that we attached to */
1254 AttachedDeviceObject
= DeviceExtension
->AttachedToDeviceObject
;
1255 FastIoDispatch
= AttachedDeviceObject
->DriverObject
->FastIoDispatch
;
1257 /* Make sure our FastIo table is valid */
1258 if (FastIoDispatch
&& FastIoDispatch
->MdlWriteComplete
)
1260 /* Forward the call onto the device we attached to */
1261 return FastIoDispatch
->MdlWriteComplete(FileObject
,
1264 AttachedDeviceObject
);
1267 /* We failed to handle the request, send it down the slow path */
1274 FltpFastIoReadCompressed(_In_ PFILE_OBJECT FileObject
,
1275 _In_ PLARGE_INTEGER FileOffset
,
1279 _Out_ PMDL
*MdlChain
,
1280 _Out_ PIO_STATUS_BLOCK IoStatus
,
1281 _Out_ PCOMPRESSED_DATA_INFO CompressedDataInfo
,
1282 _In_ ULONG CompressedDataInfoLength
,
1283 _In_ PDEVICE_OBJECT DeviceObject
)
1285 PFLTMGR_DEVICE_EXTENSION DeviceExtension
;
1286 PDEVICE_OBJECT AttachedDeviceObject
;
1287 PFAST_IO_DISPATCH FastIoDispatch
;
1291 /* If it doesn't have a device extension, then it's not our device object */
1292 if (DeviceObject
->DeviceExtension
== NULL
)
1294 /* Fail the request, send it down the slow path */
1298 DeviceExtension
= DeviceObject
->DeviceExtension
;
1299 FLT_ASSERT(DeviceExtension
->AttachedToDeviceObject
);
1301 /* Get the device that we attached to */
1302 AttachedDeviceObject
= DeviceExtension
->AttachedToDeviceObject
;
1303 FastIoDispatch
= AttachedDeviceObject
->DriverObject
->FastIoDispatch
;
1305 /* Make sure our FastIo table is valid */
1306 if (FastIoDispatch
&& FastIoDispatch
->FastIoReadCompressed
)
1308 /* Forward the call onto the device we attached to */
1309 return FastIoDispatch
->FastIoReadCompressed(FileObject
,
1317 CompressedDataInfoLength
,
1318 AttachedDeviceObject
);
1321 /* We failed to handle the request, send it down the slow path */
1328 FltpFastIoWriteCompressed(_In_ PFILE_OBJECT FileObject
,
1329 _In_ PLARGE_INTEGER FileOffset
,
1333 _Out_ PMDL
*MdlChain
,
1334 _Out_ PIO_STATUS_BLOCK IoStatus
,
1335 _In_ PCOMPRESSED_DATA_INFO CompressedDataInfo
,
1336 _In_ ULONG CompressedDataInfoLength
,
1337 _In_ PDEVICE_OBJECT DeviceObject
)
1339 PFLTMGR_DEVICE_EXTENSION DeviceExtension
;
1340 PDEVICE_OBJECT AttachedDeviceObject
;
1341 PFAST_IO_DISPATCH FastIoDispatch
;
1345 /* If it doesn't have a device extension, then it's not our device object */
1346 if (DeviceObject
->DeviceExtension
== NULL
)
1348 /* Fail the request, send it down the slow path */
1352 DeviceExtension
= DeviceObject
->DeviceExtension
;
1353 FLT_ASSERT(DeviceExtension
->AttachedToDeviceObject
);
1355 /* Get the device that we attached to */
1356 AttachedDeviceObject
= DeviceExtension
->AttachedToDeviceObject
;
1357 FastIoDispatch
= AttachedDeviceObject
->DriverObject
->FastIoDispatch
;
1359 /* Make sure our FastIo table is valid */
1360 if (FastIoDispatch
&& FastIoDispatch
->FastIoWriteCompressed
)
1362 /* Forward the call onto the device we attached to */
1363 return FastIoDispatch
->FastIoWriteCompressed(FileObject
,
1371 CompressedDataInfoLength
,
1372 AttachedDeviceObject
);
1375 /* We failed to handle the request, send it down the slow path */
1382 FltpFastIoMdlReadCompleteCompressed(_In_ PFILE_OBJECT FileObject
,
1384 _In_ PDEVICE_OBJECT DeviceObject
)
1386 PFLTMGR_DEVICE_EXTENSION DeviceExtension
;
1387 PDEVICE_OBJECT AttachedDeviceObject
;
1388 PFAST_IO_DISPATCH FastIoDispatch
;
1392 /* If it doesn't have a device extension, then it's not our device object */
1393 if (DeviceObject
->DeviceExtension
== NULL
)
1398 DeviceExtension
= DeviceObject
->DeviceExtension
;
1399 FLT_ASSERT(DeviceExtension
->AttachedToDeviceObject
);
1401 /* Get the device that we attached to */
1402 AttachedDeviceObject
= DeviceExtension
->AttachedToDeviceObject
;
1403 FastIoDispatch
= AttachedDeviceObject
->DriverObject
->FastIoDispatch
;
1405 /* Make sure our FastIo table is valid */
1406 if (FastIoDispatch
&& FastIoDispatch
->MdlReadCompleteCompressed
)
1408 /* Forward the call onto the device we attached to */
1409 return FastIoDispatch
->MdlReadCompleteCompressed(FileObject
,
1411 AttachedDeviceObject
);
1414 /* We failed to handle the request, send it down the slow path */
1421 FltpFastIoMdlWriteCompleteCompressed(_In_ PFILE_OBJECT FileObject
,
1422 _In_ PLARGE_INTEGER FileOffset
,
1424 _In_ PDEVICE_OBJECT DeviceObject
)
1426 PFLTMGR_DEVICE_EXTENSION DeviceExtension
;
1427 PDEVICE_OBJECT AttachedDeviceObject
;
1428 PFAST_IO_DISPATCH FastIoDispatch
;
1432 /* If it doesn't have a device extension, then it's not our device object */
1433 if (DeviceObject
->DeviceExtension
== NULL
)
1438 DeviceExtension
= DeviceObject
->DeviceExtension
;
1439 FLT_ASSERT(DeviceExtension
->AttachedToDeviceObject
);
1441 /* Get the device that we attached to */
1442 AttachedDeviceObject
= DeviceExtension
->AttachedToDeviceObject
;
1443 FastIoDispatch
= AttachedDeviceObject
->DriverObject
->FastIoDispatch
;
1445 /* Make sure our FastIo table is valid */
1446 if (FastIoDispatch
&& FastIoDispatch
->MdlWriteCompleteCompressed
)
1448 /* Forward the call onto the device we attached to */
1449 return FastIoDispatch
->MdlWriteCompleteCompressed(FileObject
,
1452 AttachedDeviceObject
);
1455 /* We failed to handle the request, send it down the slow path */
1462 FltpFastIoQueryOpen(_Inout_ PIRP Irp
,
1463 _Out_ PFILE_NETWORK_OPEN_INFORMATION NetworkInformation
,
1464 _In_ PDEVICE_OBJECT DeviceObject
)
1466 PFLTMGR_DEVICE_EXTENSION DeviceExtension
;
1467 PDEVICE_OBJECT AttachedDeviceObject
;
1468 PFAST_IO_DISPATCH FastIoDispatch
;
1473 /* If it doesn't have a device extension, then it's not our device object */
1474 if (DeviceObject
->DeviceExtension
== NULL
)
1479 DeviceExtension
= DeviceObject
->DeviceExtension
;
1480 FLT_ASSERT(DeviceExtension
->AttachedToDeviceObject
);
1482 /* Get the device that we attached to */
1483 AttachedDeviceObject
= DeviceExtension
->AttachedToDeviceObject
;
1484 FastIoDispatch
= AttachedDeviceObject
->DriverObject
->FastIoDispatch
;
1486 /* Make sure our FastIo table is valid */
1487 if (FastIoDispatch
&& FastIoDispatch
->FastIoQueryOpen
)
1489 PIO_STACK_LOCATION StackPtr
= IoGetCurrentIrpStackLocation(Irp
);
1491 /* Update the stack to contain the correct device for the next filter */
1492 StackPtr
->DeviceObject
= AttachedDeviceObject
;
1494 /* Now forward the call */
1495 Success
= FastIoDispatch
->FastIoQueryOpen(Irp
,
1497 AttachedDeviceObject
);
1499 /* Restore the DeviceObject as we found it */
1500 StackPtr
->DeviceObject
= DeviceObject
;
1504 /* We failed to handle the request, send it down the slow path */
1511 /* FUNCTIONS **********************************************/
1515 FltpCleanupDeviceObject(_In_ PDEVICE_OBJECT DeviceObject
)
1517 PFLTMGR_DEVICE_EXTENSION DeviceExtension
;
1519 DeviceExtension
= DeviceObject
->DeviceExtension
;
1520 if (DeviceExtension
)
1522 // cleanup device extension
1528 FltpAttachDeviceObject(_In_ PDEVICE_OBJECT SourceDevice
,
1529 _In_ PDEVICE_OBJECT TargetDevice
,
1530 _Out_ PDEVICE_OBJECT
*AttachedToDeviceObject
)
1536 /* Before attaching, copy the flags from the device we're going to attach to */
1537 if (FlagOn(SourceDevice
->Flags
, DO_BUFFERED_IO
))
1539 SetFlag(TargetDevice
->Flags
, DO_BUFFERED_IO
);
1541 if (FlagOn(SourceDevice
->Flags
, DO_DIRECT_IO
))
1543 SetFlag(TargetDevice
->Flags
, DO_DIRECT_IO
);
1545 if (FlagOn(SourceDevice
->Flags
, DO_SYSTEM_BOOT_PARTITION
))
1547 SetFlag(TargetDevice
->Characteristics
, FILE_DEVICE_SECURE_OPEN
);
1550 /* Attach this device to the top of the driver stack */
1551 Status
= IoAttachDeviceToDeviceStackSafe(SourceDevice
,
1553 AttachedToDeviceObject
);
1560 FltpIsAttachedToDevice(_In_ PDEVICE_OBJECT DeviceObject
,
1561 _In_opt_ PDEVICE_OBJECT
*AttachedDeviceObject
)
1563 PDEVICE_OBJECT CurrentDeviceObject
;
1564 PDEVICE_OBJECT NextDeviceObject
;
1568 /* Initialize the return pointer */
1569 if (AttachedDeviceObject
) *AttachedDeviceObject
= NULL
;
1571 /* Start by getting the top level device in the chain */
1572 CurrentDeviceObject
= IoGetAttachedDeviceReference(DeviceObject
);
1574 /* Loop while there are attached devices */
1575 while (CurrentDeviceObject
)
1577 /* Check if this device driver matches ours */
1578 if (CurrentDeviceObject
->DriverObject
== DriverData
.DriverObject
)
1580 FLT_ASSERT(CurrentDeviceObject
->DeviceExtension
!= NULL
);
1582 /* We're attached, return the device object if the caller asked for it */
1583 if (AttachedDeviceObject
)
1585 *AttachedDeviceObject
= CurrentDeviceObject
;
1589 /* We aren't returning the reference, so decrement the count */
1590 ObDereferenceObject(CurrentDeviceObject
);
1596 /* Get the next device in the chain */
1597 NextDeviceObject
= IoGetLowerDeviceObject(CurrentDeviceObject
);
1599 /* Decrement the count on the last device before we update the pointer */
1600 ObDereferenceObject(CurrentDeviceObject
);
1601 CurrentDeviceObject
= NextDeviceObject
;
1609 FltpEnumerateFileSystemVolumes(_In_ PDEVICE_OBJECT DeviceObject
)
1611 PFLTMGR_DEVICE_EXTENSION NewDeviceExtension
;
1612 PDEVICE_OBJECT BaseDeviceObject
;
1613 PDEVICE_OBJECT NewDeviceObject
;
1614 PDEVICE_OBJECT
*DeviceList
;
1615 PDEVICE_OBJECT StorageStackDeviceObject
;
1616 UNICODE_STRING DeviceName
;
1623 /* Get the base device */
1624 BaseDeviceObject
= IoGetDeviceAttachmentBaseRef(DeviceObject
);
1626 /* get the number of device object linked to the base file system */
1627 Status
= IoEnumerateDeviceObjectList(BaseDeviceObject
->DriverObject
,
1631 if (Status
!= STATUS_BUFFER_TOO_SMALL
) return Status
;
1633 /* Add a few more slots in case the size changed between calls and allocate some memory to hold the pointers */
1635 DeviceList
= ExAllocatePoolWithTag(NonPagedPool
,
1636 (NumDevices
* sizeof(PDEVICE_OBJECT
)),
1637 FM_TAG_DEV_OBJ_PTRS
);
1638 if (DeviceList
== NULL
) return STATUS_INSUFFICIENT_RESOURCES
;
1640 /* Now get all the device objects that this base driver has created */
1641 Status
= IoEnumerateDeviceObjectList(BaseDeviceObject
->DriverObject
,
1643 (NumDevices
* sizeof(PDEVICE_OBJECT
)),
1645 if (!NT_SUCCESS(Status
))
1647 ExFreePoolWithTag(DeviceList
, FM_TAG_DEV_OBJ_PTRS
);
1651 /* Loop through all the devices looking for ones to attach to */
1652 for (i
= 0; i
< NumDevices
; i
++)
1654 RtlInitUnicodeString(&DeviceName
, NULL
);
1655 StorageStackDeviceObject
= NULL
;
1656 NewDeviceObject
= NULL
;
1658 /* Ignore the device we passed in, and devices of the wrong type */
1659 if ((DeviceList
[i
] == BaseDeviceObject
) ||
1660 (DeviceList
[i
]->DeviceType
!= BaseDeviceObject
->DeviceType
))
1662 goto CleanupAndNext
;
1665 /* Ignore this device if we're already attached to it */
1666 if (FltpIsAttachedToDevice(DeviceList
[i
], NULL
) == FALSE
)
1668 goto CleanupAndNext
;
1673 * If the device has a name, it must be a control device.
1674 * This handles drivers with more then one control device (like FastFat)
1676 FltpGetBaseDeviceObjectName(DeviceList
[i
], &DeviceName
);
1677 if (NT_SUCCESS(Status
) && DeviceName
.Length
> 0)
1679 goto CleanupAndNext
;
1683 * Try to get the storage stack (disk) device object accociated with
1684 * this file system device object. Ignore the device if we don't have one
1686 Status
= IoGetDiskDeviceObject(DeviceList
[i
],
1687 &StorageStackDeviceObject
);
1688 if (!NT_SUCCESS(Status
))
1690 goto CleanupAndNext
;
1695 * TODO: Don't attach to shadow copy volumes,
1696 * ros doesn't have any so it's not an issues yet
1700 * We're far enough to be ready to attach, create a device
1701 * object which we'll use to do so
1703 Status
= IoCreateDevice(DriverData
.DriverObject
,
1704 sizeof(FLTMGR_DEVICE_EXTENSION
),
1706 DeviceList
[i
]->DeviceType
,
1710 if (!NT_SUCCESS(Status
))
1712 goto CleanupAndNext
;
1715 /* Get the device extension for this new object and store our disk object there */
1716 NewDeviceExtension
= NewDeviceObject
->DeviceExtension
;
1717 NewDeviceExtension
->StorageStackDeviceObject
= StorageStackDeviceObject
;
1719 /* Lookup and store the device name for the storage stack */
1720 RtlInitEmptyUnicodeString(&NewDeviceExtension
->DeviceName
,
1721 NewDeviceExtension
->DeviceNameBuffer
,
1722 sizeof(NewDeviceExtension
->DeviceNameBuffer
));
1723 FltpGetObjectName(StorageStackDeviceObject
,
1724 &NewDeviceExtension
->DeviceName
);
1727 /* Grab the attach lock before we attempt to attach */
1728 ExAcquireFastMutex(&DriverData
.FilterAttachLock
);
1730 /* Check again that we aren't already attached. It may have changed since our last check */
1731 if (FltpIsAttachedToDevice(DeviceList
[i
], NULL
) == FALSE
)
1733 FLT_ASSERT(NewDeviceObject
->DriverObject
== DriverData
.DriverObject
);
1735 /* Finally, attach to the volume */
1736 Status
= FltpAttachDeviceObject(DeviceList
[i
],
1738 &NewDeviceExtension
->AttachedToDeviceObject
);
1739 if (NT_SUCCESS(Status
))
1741 /* Clean the initializing flag so other filters can attach to our device object */
1742 ClearFlag(NewDeviceObject
->Flags
, DO_DEVICE_INITIALIZING
);
1747 /* We're already attached. Just cleanup */
1748 Status
= STATUS_DEVICE_ALREADY_ATTACHED
;
1751 ExReleaseFastMutex(&DriverData
.FilterAttachLock
);
1755 if (!NT_SUCCESS(Status
))
1757 if (NewDeviceObject
)
1759 FltpCleanupDeviceObject(NewDeviceObject
);
1760 IoDeleteDevice(NewDeviceObject
);
1764 if (StorageStackDeviceObject
)
1766 /* A ref was added for us when we attached, so we can deref ours now */
1767 ObDereferenceObject(StorageStackDeviceObject
);
1770 /* Remove the ref which was added by IoEnumerateDeviceObjectList */
1771 ObDereferenceObject(DeviceList
[i
]);
1773 /* Free the buffer that FltpGetBaseDeviceObjectName added */
1774 FltpFreeUnicodeString(&DeviceName
);
1778 /* Free the memory we allocated for the list */
1779 ExFreePoolWithTag(DeviceList
, FM_TAG_DEV_OBJ_PTRS
);
1781 return STATUS_SUCCESS
;
1786 FltpAttachToFileSystemDevice(_In_ PDEVICE_OBJECT DeviceObject
,
1787 _In_ PUNICODE_STRING DeviceName
)
1789 PFLTMGR_DEVICE_EXTENSION DeviceExtension
;
1790 PDEVICE_OBJECT NewDeviceObject
;
1791 WCHAR Buffer
[MAX_DEVNAME_LENGTH
];
1792 UNICODE_STRING FileSystemDeviceName
;
1793 UNICODE_STRING FsRecDeviceName
;
1798 /* Only handle device types we're interested in */
1799 if (DeviceObject
->DeviceType
!= FILE_DEVICE_DISK_FILE_SYSTEM
&&
1800 DeviceObject
->DeviceType
!= FILE_DEVICE_CD_ROM_FILE_SYSTEM
&&
1801 DeviceObject
->DeviceType
!= FILE_DEVICE_NETWORK_FILE_SYSTEM
)
1803 return STATUS_SUCCESS
;
1806 /* Setup the buffer to hold the device name */
1807 RtlInitEmptyUnicodeString(&FileSystemDeviceName
,
1809 MAX_DEVNAME_LENGTH
* sizeof(WCHAR
));
1811 /* Get the the name of the file system device */
1812 Status
= FltpGetObjectName(DeviceObject
->DriverObject
, &FileSystemDeviceName
);
1813 if (!NT_SUCCESS(Status
)) return Status
;
1815 DPRINT("Found device %wZ, checking if we need to attach...\n", &FileSystemDeviceName
);
1817 /* Build up the name of the file system recognizer device */
1818 RtlInitUnicodeString(&FsRecDeviceName
, L
"\\FileSystem\\Fs_Rec");
1820 /* We don't attach to recognizer devices, so bail if this is one */
1821 if (RtlCompareUnicodeString(&FileSystemDeviceName
, &FsRecDeviceName
, TRUE
) == 0)
1823 return STATUS_SUCCESS
;
1826 /* Create a device object which we can attach to this file system */
1827 Status
= IoCreateDevice(DriverData
.DriverObject
,
1828 sizeof(FLTMGR_DEVICE_EXTENSION
),
1830 DeviceObject
->DeviceType
,
1834 if (!NT_SUCCESS(Status
))
1836 DPRINT1("Failed to create a DO for attatching to a FS : 0x%X\n", Status
);
1840 /* Cast the device extension to something we understand */
1841 DeviceExtension
= NewDeviceObject
->DeviceExtension
;
1843 /* Attach this device to the top of the driver stack and store the DO we attached to in the DE */
1844 Status
= FltpAttachDeviceObject(NewDeviceObject
,
1846 &DeviceExtension
->AttachedToDeviceObject
);
1847 if (NT_SUCCESS(Status
))
1849 DPRINT("Attached to %wZ\n", &FileSystemDeviceName
);
1853 DPRINT1("Failed to attach to the driver stack : 0x%X\n", Status
);
1857 /* Setup the unicode string buffer and copy the device name to the device extension */
1858 RtlInitEmptyUnicodeString(&DeviceExtension
->DeviceName
,
1859 DeviceExtension
->DeviceNameBuffer
,
1860 MAX_DEVNAME_LENGTH
* sizeof(WCHAR
));
1861 RtlCopyUnicodeString(&DeviceExtension
->DeviceName
, DeviceName
);
1863 /* We're done, remove the initializing flag */
1864 ClearFlag(NewDeviceObject
->Flags
, DO_DEVICE_INITIALIZING
);
1866 /* Look for existing mounted devices for this file system */
1867 Status
= FltpEnumerateFileSystemVolumes(DeviceObject
);
1868 if (!NT_SUCCESS(Status
))
1870 DPRINT1("Failed to enumerate file system volumes for this file system : 0x%X\n", Status
);
1871 IoDetachDevice(DeviceExtension
->AttachedToDeviceObject
);
1876 if (!NT_SUCCESS(Status
))
1878 IoDeleteDevice(NewDeviceObject
);
1886 FltpDetachFromFileSystemDevice(_In_ PDEVICE_OBJECT DeviceObject
)
1888 PDEVICE_OBJECT AttachedDevice
, NextDevice
;
1889 PFLTMGR_DEVICE_EXTENSION DeviceExtension
;
1895 /* Get the top device in the chain and increment the ref count on it */
1896 AttachedDevice
= IoGetAttachedDeviceReference(DeviceObject
);
1898 /* Loop all attached devices looking for our file system driver */
1899 while (AttachedDevice
->DriverObject
!= DriverData
.DriverObject
)
1901 FLT_ASSERT(AttachedDevice
!= NULL
);
1903 /* Get the next lower device object. This adds a ref on NextDevice */
1904 NextDevice
= IoGetLowerDeviceObject(AttachedDevice
);
1906 /* Remove the reference we added */
1907 Count
= ObfDereferenceObject(AttachedDevice
);
1909 /* Bail if this is the last one */
1910 if (NextDevice
== NULL
) return Count
;
1912 /* Try the next one */
1913 AttachedDevice
= NextDevice
;
1917 DeviceExtension
= AttachedDevice
->DeviceExtension
;
1918 if (DeviceExtension
)
1921 // FIXME: Put any device extension cleanup code here
1925 /* Detach the device from the chain and delete the object */
1926 IoDetachDevice(DeviceObject
);
1927 IoDeleteDevice(AttachedDevice
);
1929 /* Remove the reference we added so the delete can complete */
1930 return ObfDereferenceObject(AttachedDevice
);
1933 DRIVER_FS_NOTIFICATION FltpFsNotification
;
1936 FltpFsNotification(_In_ PDEVICE_OBJECT DeviceObject
,
1937 _In_ BOOLEAN FsActive
)
1939 UNICODE_STRING DeviceName
;
1944 /* Set an empty string */
1945 RtlInitUnicodeString(&DeviceName
, NULL
);
1947 /* Get the name of the lowest device object on the stack */
1948 Status
= FltpGetBaseDeviceObjectName(DeviceObject
, &DeviceName
);
1949 if (NT_SUCCESS(Status
))
1951 /* Check if it's attaching or detaching */
1954 /* Run the attach routine */
1955 FltpAttachToFileSystemDevice(DeviceObject
, &DeviceName
);
1959 /* Run the detach routine */
1960 FltpDetachFromFileSystemDevice(DeviceObject
);
1963 /* Free the buffer which FltpGetBaseDeviceObjectName allocated */
1964 FltpFreeUnicodeString(&DeviceName
);
1968 DRIVER_INITIALIZE DriverEntry
;
1971 DriverEntry(_In_ PDRIVER_OBJECT DriverObject
,
1972 _In_ PUNICODE_STRING RegistryPath
)
1974 UNICODE_STRING DeviceName
= RTL_CONSTANT_STRING(L
"\\FileSystem\\Filters\\"DRIVER_NAME
);
1975 PDEVICE_OBJECT RawDeviceObject
;
1976 PDEVICE_OBJECT DeviceObject
;
1977 PFILE_OBJECT RawFileObject
;
1978 UNICODE_STRING ObjectName
;
1979 UNICODE_STRING SymLink
;
1983 RtlZeroMemory(&DriverData
, sizeof(DRIVER_DATA
));
1984 DriverData
.DriverObject
= DriverObject
;
1986 /* Save the registry key for this driver */
1987 DriverData
.ServiceKey
.Length
= RegistryPath
->Length
;
1988 DriverData
.ServiceKey
.MaximumLength
= RegistryPath
->MaximumLength
;
1989 DriverData
.ServiceKey
.Buffer
= (PWCHAR
)ExAllocatePoolWithTag(NonPagedPool
,
1990 RegistryPath
->MaximumLength
,
1991 FM_TAG_REGISTRY_DATA
);
1992 if (!DriverData
.ServiceKey
.Buffer
) return STATUS_INSUFFICIENT_RESOURCES
;
1993 RtlCopyUnicodeString(&DriverData
.ServiceKey
, RegistryPath
);
1995 /* Do some initialization */
1996 ExInitializeFastMutex(&DriverData
.FilterAttachLock
);
1998 /* Create the main filter manager device object */
1999 Status
= IoCreateDevice(DriverObject
,
2002 FILE_DEVICE_DISK_FILE_SYSTEM
,
2003 FILE_DEVICE_SECURE_OPEN
,
2006 if (!NT_SUCCESS(Status
))
2008 DPRINT1("fltmgr IoCreateDevice failed. Status = %X\n", Status
);
2012 /* Store a global reference so we can access from callbacks */
2013 DriverData
.DeviceObject
= DeviceObject
;
2015 /* Generate the symbolic link name */
2016 RtlInitUnicodeString(&SymLink
, L
"\\??\\"DRIVER_NAME
);
2017 Status
= IoCreateSymbolicLink(&SymLink
, &DeviceName
);
2018 if (!NT_SUCCESS(Status
)) goto Cleanup
;
2020 /* Create the callbacks for the dispatch table, FastIo and FS callbacks */
2021 Status
= SetupDispatchAndCallbacksTables(DriverObject
);
2022 if (!NT_SUCCESS(Status
)) goto Cleanup
;
2025 // TODO: Create fltmgr message device
2028 /* Register for notifications when a new file system is loaded. This also enumerates any existing file systems */
2029 Status
= IoRegisterFsRegistrationChange(DriverObject
, FltpFsNotification
);
2030 FLT_ASSERT(Status
!= STATUS_DEVICE_ALREADY_ATTACHED
); // Windows checks for this, I'm not sure how it can happen. Needs investigation??
2031 if (!NT_SUCCESS(Status
)) goto Cleanup
;
2033 /* IoRegisterFsRegistrationChange isn't notified about the raw file systems, so we attach to them manually */
2034 RtlInitUnicodeString(&ObjectName
, L
"\\Device\\RawDisk");
2035 Status
= IoGetDeviceObjectPointer(&ObjectName
,
2036 FILE_READ_ATTRIBUTES
,
2039 if (NT_SUCCESS(Status
))
2041 FltpFsNotification(RawDeviceObject
, TRUE
);
2042 ObfDereferenceObject(RawFileObject
);
2045 RtlInitUnicodeString(&ObjectName
, L
"\\Device\\RawCdRom");
2046 Status
= IoGetDeviceObjectPointer(&ObjectName
,
2047 FILE_READ_ATTRIBUTES
,
2050 if (NT_SUCCESS(Status
))
2052 FltpFsNotification(RawDeviceObject
, TRUE
);
2053 ObfDereferenceObject(RawFileObject
);
2056 /* We're done, clear the initializing flag */
2057 ClearFlag(DeviceObject
->Flags
, DO_DEVICE_INITIALIZING
);
2058 Status
= STATUS_SUCCESS
;
2062 if (!NT_SUCCESS(Status
))
2064 if (DriverData
.FastIoDispatch
)
2066 DriverObject
->FastIoDispatch
= NULL
;
2067 ExFreePoolWithTag(DriverData
.FastIoDispatch
, FM_TAG_DISPATCH_TABLE
);
2070 IoDeleteSymbolicLink(&SymLink
);
2073 IoDeleteDevice(DeviceObject
);
2075 if (DriverData
.ServiceKey
.Buffer
)
2076 ExFreePoolWithTag(DriverData
.ServiceKey
.Buffer
, FM_TAG_REGISTRY_DATA
);
2085 SetupDispatchAndCallbacksTables(_In_ PDRIVER_OBJECT DriverObject
)
2087 PFAST_IO_DISPATCH FastIoDispatch
;
2088 FS_FILTER_CALLBACKS Callbacks
;
2091 /* Plug all the IRPs */
2092 for (i
= 0; i
<= IRP_MJ_MAXIMUM_FUNCTION
; i
++)
2094 DriverObject
->MajorFunction
[i
] = FltpDispatch
;
2097 /* Override the ones we're interested in */
2098 DriverObject
->MajorFunction
[IRP_MJ_CREATE
] = FltpCreate
;
2099 DriverObject
->MajorFunction
[IRP_MJ_CREATE_NAMED_PIPE
] = FltpCreate
;
2100 DriverObject
->MajorFunction
[IRP_MJ_CREATE_MAILSLOT
] = FltpCreate
;
2101 DriverObject
->MajorFunction
[IRP_MJ_FILE_SYSTEM_CONTROL
] = FltpFsControl
;
2103 /* The FastIo diapatch table is stored in the pool along with a tag */
2104 FastIoDispatch
= ExAllocatePoolWithTag(NonPagedPool
, sizeof(FAST_IO_DISPATCH
), FM_TAG_DISPATCH_TABLE
);
2105 if (FastIoDispatch
== NULL
) return STATUS_INSUFFICIENT_RESOURCES
;
2107 /* Fill out the FastIo table */
2108 RtlZeroMemory(FastIoDispatch
, sizeof(FAST_IO_DISPATCH
));
2109 FastIoDispatch
->SizeOfFastIoDispatch
= sizeof(FAST_IO_DISPATCH
);
2110 FastIoDispatch
->FastIoCheckIfPossible
= FltpFastIoCheckIfPossible
;
2111 FastIoDispatch
->FastIoRead
= FltpFastIoRead
;
2112 FastIoDispatch
->FastIoWrite
= FltpFastIoWrite
;
2113 FastIoDispatch
->FastIoQueryBasicInfo
= FltpFastIoQueryBasicInfo
;
2114 FastIoDispatch
->FastIoQueryStandardInfo
= FltpFastIoQueryStandardInfo
;
2115 FastIoDispatch
->FastIoLock
= FltpFastIoLock
;
2116 FastIoDispatch
->FastIoUnlockSingle
= FltpFastIoUnlockSingle
;
2117 FastIoDispatch
->FastIoUnlockAll
= FltpFastIoUnlockAll
;
2118 FastIoDispatch
->FastIoUnlockAllByKey
= FltpFastIoUnlockAllByKey
;
2119 FastIoDispatch
->FastIoDeviceControl
= FltpFastIoDeviceControl
;
2120 FastIoDispatch
->FastIoDetachDevice
= FltpFastIoDetachDevice
;
2121 FastIoDispatch
->FastIoQueryNetworkOpenInfo
= FltpFastIoQueryNetworkOpenInfo
;
2122 FastIoDispatch
->MdlRead
= FltpFastIoMdlRead
;
2123 FastIoDispatch
->MdlReadComplete
= FltpFastIoMdlReadComplete
;
2124 FastIoDispatch
->PrepareMdlWrite
= FltpFastIoPrepareMdlWrite
;
2125 FastIoDispatch
->MdlWriteComplete
= FltpFastIoMdlWriteComplete
;
2126 FastIoDispatch
->FastIoReadCompressed
= FltpFastIoReadCompressed
;
2127 FastIoDispatch
->FastIoWriteCompressed
= FltpFastIoWriteCompressed
;
2128 FastIoDispatch
->MdlReadCompleteCompressed
= FltpFastIoMdlReadCompleteCompressed
;
2129 FastIoDispatch
->MdlWriteCompleteCompressed
= FltpFastIoMdlWriteCompleteCompressed
;
2130 FastIoDispatch
->FastIoQueryOpen
= FltpFastIoQueryOpen
;
2132 /* Store the FastIo table for internal and our access */
2133 DriverObject
->FastIoDispatch
= FastIoDispatch
;
2134 DriverData
.FastIoDispatch
= FastIoDispatch
;
2136 /* Initialize the callback table */
2137 Callbacks
.SizeOfFsFilterCallbacks
= sizeof(FS_FILTER_CALLBACKS
);
2138 Callbacks
.PreAcquireForSectionSynchronization
= FltpPreFsFilterOperation
;
2139 Callbacks
.PostAcquireForSectionSynchronization
= FltpPostFsFilterOperation
;
2140 Callbacks
.PreReleaseForSectionSynchronization
= FltpPreFsFilterOperation
;
2141 Callbacks
.PostReleaseForSectionSynchronization
= FltpPostFsFilterOperation
;
2142 Callbacks
.PreAcquireForCcFlush
= FltpPreFsFilterOperation
;
2143 Callbacks
.PostAcquireForCcFlush
= FltpPostFsFilterOperation
;
2144 Callbacks
.PreReleaseForCcFlush
= FltpPreFsFilterOperation
;
2145 Callbacks
.PostReleaseForCcFlush
= FltpPostFsFilterOperation
;
2146 Callbacks
.PreAcquireForModifiedPageWriter
= FltpPreFsFilterOperation
;
2147 Callbacks
.PostAcquireForModifiedPageWriter
= FltpPostFsFilterOperation
;
2148 Callbacks
.PreReleaseForModifiedPageWriter
= FltpPreFsFilterOperation
;
2149 Callbacks
.PostReleaseForModifiedPageWriter
= FltpPostFsFilterOperation
;
2151 /* Register our callbacks */
2152 return FsRtlRegisterFileSystemFilterCallbacks(DriverObject
, &Callbacks
);