[FASTFAT] Fix size checking in VfatGetFileNameInformation()
[reactos.git] / drivers / filters / fltmgr / Interface.c
1 /*
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)
7 */
8
9 /* INCLUDES ******************************************************************/
10
11 #include "fltmgr.h"
12 #include "fltmgrint.h"
13
14 //#define NDEBUG
15 #include <debug.h>
16
17
18 /* DATA *********************************************************************/
19
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))
25
26 #define IS_MY_DEVICE_OBJECT(_devObj) \
27 (((_devObj) != NULL) && \
28 ((_devObj)->DriverObject == Dispatcher::DriverObject) && \
29 ((_devObj)->DeviceExtension != NULL))
30
31 extern PDEVICE_OBJECT CommsDeviceObject;
32
33
34 DRIVER_INITIALIZE DriverEntry;
35 NTSTATUS
36 NTAPI
37 DriverEntry(
38 _In_ PDRIVER_OBJECT DriverObject,
39 _In_ PUNICODE_STRING RegistryPath
40 );
41
42 static
43 NTSTATUS
44 SetupDispatchAndCallbacksTables(
45 _In_ PDRIVER_OBJECT DriverObject
46 );
47
48 static
49 NTSTATUS
50 FltpAttachDeviceObject(
51 _In_ PDEVICE_OBJECT SourceDevice,
52 _In_ PDEVICE_OBJECT TargetDevice,
53 _Out_ PDEVICE_OBJECT *AttachedToDeviceObject
54 );
55
56 static
57 VOID
58 FltpCleanupDeviceObject(
59 _In_ PDEVICE_OBJECT DeviceObject
60 );
61
62 static
63 BOOLEAN
64 FltpIsAttachedToDevice(
65 _In_ PDEVICE_OBJECT DeviceObject,
66 _In_opt_ PDEVICE_OBJECT *AttachedDeviceObject
67 );
68
69 static
70 NTSTATUS
71 FltpEnumerateFileSystemVolumes(
72 _In_ PDEVICE_OBJECT DeviceObject
73 );
74
75 static
76 NTSTATUS
77 FltpAttachToFileSystemDevice(
78 _In_ PDEVICE_OBJECT DeviceObject,
79 _In_ PUNICODE_STRING DeviceName
80 );
81
82 static
83 LONG_PTR
84 FltpDetachFromFileSystemDevice(
85 _In_ PDEVICE_OBJECT DeviceObject
86 );
87
88 DRIVER_FS_NOTIFICATION FltpFsNotification;
89 VOID
90 NTAPI
91 FltpFsNotification(
92 _In_ PDEVICE_OBJECT DeviceObject,
93 _In_ BOOLEAN FsActive
94 );
95
96 NTSTATUS
97 NTAPI
98 FltpDispatch(
99 _In_ PDEVICE_OBJECT DeviceObject,
100 _Inout_ PIRP Irp
101 );
102
103 NTSTATUS
104 NTAPI
105 FltpCreate(
106 _In_ PDEVICE_OBJECT DeviceObject,
107 _Inout_ PIRP Irp
108 );
109
110 NTSTATUS
111 NTAPI
112 FltpFsControl(
113 _In_ PDEVICE_OBJECT DeviceObject,
114 _Inout_ PIRP Irp
115 );
116
117 NTSTATUS
118 NTAPI
119 FltpDeviceControl(
120 _In_ PDEVICE_OBJECT DeviceObject,
121 _Inout_ PIRP Irp
122 );
123
124 BOOLEAN
125 NTAPI
126 FltpFastIoCheckIfPossible(
127 _In_ PFILE_OBJECT FileObject,
128 _In_ PLARGE_INTEGER FileOffset,
129 _In_ ULONG Length,
130 _In_ BOOLEAN Wait,
131 _In_ ULONG LockKey,
132 _In_ BOOLEAN CheckForReadOperation,
133 _Out_ PIO_STATUS_BLOCK IoStatus,
134 _In_ PDEVICE_OBJECT DeviceObject
135 );
136
137
138 BOOLEAN
139 NTAPI
140 FltpFastIoRead(
141 _In_ PFILE_OBJECT FileObject,
142 _In_ PLARGE_INTEGER FileOffset,
143 _In_ ULONG Length,
144 _In_ BOOLEAN Wait,
145 _In_ ULONG LockKey,
146 _Out_ PVOID Buffer,
147 _Out_ PIO_STATUS_BLOCK IoStatus,
148 _In_ PDEVICE_OBJECT DeviceObject
149 );
150
151 BOOLEAN
152 NTAPI
153 FltpFastIoWrite(
154 _In_ PFILE_OBJECT FileObject,
155 _In_ PLARGE_INTEGER FileOffset,
156 _In_ ULONG Length,
157 _In_ BOOLEAN Wait,
158 _In_ ULONG LockKey,
159 _In_ PVOID Buffer,
160 _Out_ PIO_STATUS_BLOCK IoStatus,
161 _In_ PDEVICE_OBJECT DeviceObject
162 );
163
164 BOOLEAN
165 NTAPI
166 FltpFastIoQueryBasicInfo(
167 _In_ PFILE_OBJECT FileObject,
168 _In_ BOOLEAN Wait,
169 _Out_ PFILE_BASIC_INFORMATION Buffer,
170 _Out_ PIO_STATUS_BLOCK IoStatus,
171 _In_ PDEVICE_OBJECT DeviceObject
172 );
173
174 BOOLEAN
175 NTAPI
176 FltpFastIoQueryStandardInfo(
177 _In_ PFILE_OBJECT FileObject,
178 _In_ BOOLEAN Wait,
179 _Out_ PFILE_STANDARD_INFORMATION Buffer,
180 _Out_ PIO_STATUS_BLOCK IoStatus,
181 _In_ PDEVICE_OBJECT DeviceObject
182 );
183
184 BOOLEAN
185 NTAPI
186 FltpFastIoLock(
187 _In_ PFILE_OBJECT FileObject,
188 _In_ PLARGE_INTEGER FileOffset,
189 _In_ PLARGE_INTEGER Length,
190 _In_ PEPROCESS ProcessId,
191 _In_ ULONG Key,
192 _In_ BOOLEAN FailImmediately,
193 _In_ BOOLEAN ExclusiveLock,
194 _Out_ PIO_STATUS_BLOCK IoStatus,
195 _In_ PDEVICE_OBJECT DeviceObject
196 );
197
198 BOOLEAN
199 NTAPI
200 FltpFastIoUnlockSingle(
201 _In_ PFILE_OBJECT FileObject,
202 _In_ PLARGE_INTEGER FileOffset,
203 _In_ PLARGE_INTEGER Length,
204 _In_ PEPROCESS ProcessId,
205 _In_ ULONG Key,
206 _Out_ PIO_STATUS_BLOCK IoStatus,
207 _In_ PDEVICE_OBJECT DeviceObject
208 );
209
210 BOOLEAN
211 NTAPI
212 FltpFastIoUnlockAll(
213 _In_ PFILE_OBJECT FileObject,
214 _In_ PEPROCESS ProcessId,
215 _Out_ PIO_STATUS_BLOCK IoStatus,
216 _In_ PDEVICE_OBJECT DeviceObject
217 );
218
219 BOOLEAN
220 NTAPI
221 FltpFastIoUnlockAllByKey(
222 _In_ PFILE_OBJECT FileObject,
223 _In_ PVOID ProcessId,
224 _In_ ULONG Key,
225 _Out_ PIO_STATUS_BLOCK IoStatus,
226 _In_ PDEVICE_OBJECT DeviceObject
227 );
228
229 BOOLEAN
230 NTAPI
231 FltpFastIoDeviceControl(
232 _In_ PFILE_OBJECT FileObject,
233 _In_ BOOLEAN Wait,
234 _In_opt_ PVOID InputBuffer,
235 _In_ ULONG InputBufferLength,
236 _Out_opt_ PVOID OutputBuffer,
237 _In_ ULONG OutputBufferLength,
238 _In_ ULONG IoControlCode,
239 _Out_ PIO_STATUS_BLOCK IoStatus,
240 _In_ PDEVICE_OBJECT DeviceObject
241 );
242
243 VOID
244 NTAPI
245 FltpFastIoDetachDevice(
246 _In_ PDEVICE_OBJECT SourceDevice,
247 _In_ PDEVICE_OBJECT TargetDevice
248 );
249
250 BOOLEAN
251 NTAPI
252 FltpFastIoQueryNetworkOpenInfo(
253 _In_ PFILE_OBJECT FileObject,
254 _In_ BOOLEAN Wait,
255 _Out_ PFILE_NETWORK_OPEN_INFORMATION Buffer,
256 _Out_ PIO_STATUS_BLOCK IoStatus,
257 _In_ PDEVICE_OBJECT DeviceObject
258 );
259
260 BOOLEAN
261 NTAPI
262 FltpFastIoMdlRead(
263 _In_ PFILE_OBJECT FileObject,
264 _In_ PLARGE_INTEGER FileOffset,
265 _In_ ULONG Length,
266 _In_ ULONG LockKey,
267 _Out_ PMDL *MdlChain,
268 _Out_ PIO_STATUS_BLOCK IoStatus,
269 _In_ PDEVICE_OBJECT DeviceObject
270 );
271
272 BOOLEAN
273 NTAPI
274 FltpFastIoMdlReadComplete(
275 _In_ PFILE_OBJECT FileObject,
276 _In_ PMDL MdlChain,
277 _In_ PDEVICE_OBJECT DeviceObject
278 );
279
280 BOOLEAN
281 NTAPI
282 FltpFastIoPrepareMdlWrite(
283 _In_ PFILE_OBJECT FileObject,
284 _In_ PLARGE_INTEGER FileOffset,
285 _In_ ULONG Length,
286 _In_ ULONG LockKey,
287 _Out_ PMDL *MdlChain,
288 _Out_ PIO_STATUS_BLOCK IoStatus,
289 _In_ PDEVICE_OBJECT DeviceObject
290 );
291
292 BOOLEAN
293 NTAPI
294 FltpFastIoMdlWriteComplete(
295 _In_ PFILE_OBJECT FileObject,
296 _In_ PLARGE_INTEGER FileOffset,
297 _In_ PMDL MdlChain,
298 _In_ PDEVICE_OBJECT DeviceObject
299 );
300
301 BOOLEAN
302 NTAPI
303 FltpFastIoReadCompressed(
304 _In_ PFILE_OBJECT FileObject,
305 _In_ PLARGE_INTEGER FileOffset,
306 _In_ ULONG Length,
307 _In_ ULONG LockKey,
308 _Out_ PVOID Buffer,
309 _Out_ PMDL *MdlChain,
310 _Out_ PIO_STATUS_BLOCK IoStatus,
311 _Out_ PCOMPRESSED_DATA_INFO CompressedDataInfo,
312 _In_ ULONG CompressedDataInfoLength,
313 _In_ PDEVICE_OBJECT DeviceObject
314 );
315
316 BOOLEAN
317 NTAPI
318 FltpFastIoWriteCompressed(
319 _In_ PFILE_OBJECT FileObject,
320 _In_ PLARGE_INTEGER FileOffset,
321 _In_ ULONG Length,
322 _In_ ULONG LockKey,
323 _In_ PVOID Buffer,
324 _Out_ PMDL *MdlChain,
325 _Out_ PIO_STATUS_BLOCK IoStatus,
326 _In_ PCOMPRESSED_DATA_INFO CompressedDataInfo,
327 _In_ ULONG CompressedDataInfoLength,
328 _In_ PDEVICE_OBJECT DeviceObject
329 );
330
331 BOOLEAN
332 NTAPI
333 FltpFastIoMdlReadCompleteCompressed(
334 _In_ PFILE_OBJECT FileObject,
335 _In_ PMDL MdlChain,
336 _In_ PDEVICE_OBJECT DeviceObject
337 );
338
339 BOOLEAN
340 NTAPI
341 FltpFastIoMdlWriteCompleteCompressed(
342 _In_ PFILE_OBJECT FileObject,
343 _In_ PLARGE_INTEGER FileOffset,
344 _In_ PMDL MdlChain,
345 _In_ PDEVICE_OBJECT DeviceObject
346 );
347
348 BOOLEAN
349 NTAPI
350 FltpFastIoQueryOpen(
351 _Inout_ PIRP Irp,
352 _Out_ PFILE_NETWORK_OPEN_INFORMATION NetworkInformation,
353 _In_ PDEVICE_OBJECT DeviceObject
354 );
355
356
357
358 #ifdef ALLOC_PRAGMA
359 #pragma alloc_text(INIT, DriverEntry)
360 #pragma alloc_text(INIT, SetupDispatchAndCallbacksTables)
361 #pragma alloc_text(PAGE, FltpAttachDeviceObject)
362 #pragma alloc_text(PAGE, FltpIsAttachedToDevice)
363 #pragma alloc_text(PAGE, FltpEnumerateFileSystemVolumes)
364 #pragma alloc_text(PAGE, FltpAttachToFileSystemDevice)
365 #pragma alloc_text(PAGE, FltpDetachFromFileSystemDevice)
366 #pragma alloc_text(PAGE, FltpFsNotification)
367 #pragma alloc_text(PAGE, FltpCreate)
368 #pragma alloc_text(PAGE, FltpFsControl)
369 #pragma alloc_text(PAGE, FltpDeviceControl)
370 #pragma alloc_text(PAGE, FltpFastIoRead)
371 #pragma alloc_text(PAGE, FltpFastIoWrite)
372 #pragma alloc_text(PAGE, FltpFastIoQueryBasicInfo)
373 #pragma alloc_text(PAGE, FltpFastIoQueryStandardInfo)
374 #pragma alloc_text(PAGE, FltpFastIoLock)
375 #pragma alloc_text(PAGE, FltpFastIoUnlockSingle)
376 #pragma alloc_text(PAGE, FltpFastIoUnlockAll)
377 #pragma alloc_text(PAGE, FltpFastIoUnlockAllByKey)
378 #pragma alloc_text(PAGE, FltpFastIoDeviceControl)
379 #pragma alloc_text(PAGE, FltpFastIoDetachDevice)
380 #pragma alloc_text(PAGE, FltpFastIoQueryNetworkOpenInfo)
381 #pragma alloc_text(PAGE, FltpFastIoMdlRead)
382 #pragma alloc_text(PAGE, FltpFastIoMdlReadComplete)
383 #pragma alloc_text(PAGE, FltpFastIoPrepareMdlWrite)
384 #pragma alloc_text(PAGE, FltpFastIoMdlWriteComplete)
385 #pragma alloc_text(PAGE, FltpFastIoReadCompressed)
386 #pragma alloc_text(PAGE, FltpFastIoWriteCompressed)
387 #pragma alloc_text(PAGE, FltpFastIoMdlReadCompleteCompressed)
388 #pragma alloc_text(PAGE, FltpFastIoMdlWriteCompleteCompressed)
389 #pragma alloc_text(PAGE, FltpFastIoQueryOpen)
390 #endif
391
392
393
394 DRIVER_DATA DriverData;
395
396
397 typedef struct _DETACH_DEVICE_WORK_ITEM
398 {
399 WORK_QUEUE_ITEM WorkItem;
400 PDEVICE_OBJECT SourceDevice;
401 PDEVICE_OBJECT TargetDevice;
402
403 } DETACH_DEVICE_WORK_ITEM, *PDETACH_DEVICE_WORK_ITEM;
404
405
406 /* DISPATCH ROUTINES **********************************************/
407
408 NTSTATUS
409 NTAPI
410 FltpPreFsFilterOperation(_In_ PFS_FILTER_CALLBACK_DATA Data,
411 _Out_ PVOID *CompletionContext)
412 {
413 UNREFERENCED_PARAMETER(Data);
414 UNREFERENCED_PARAMETER(CompletionContext);
415 __debugbreak();
416 return STATUS_SUCCESS;
417 }
418
419 VOID
420 NTAPI
421 FltpPostFsFilterOperation(_In_ PFS_FILTER_CALLBACK_DATA Data,
422 _In_ NTSTATUS OperationStatus,
423 _In_ PVOID CompletionContext)
424 {
425 UNREFERENCED_PARAMETER(Data);
426 UNREFERENCED_PARAMETER(OperationStatus);
427 UNREFERENCED_PARAMETER(CompletionContext);
428 __debugbreak();
429 }
430
431 NTSTATUS
432 NTAPI
433 FltpDispatch(_In_ PDEVICE_OBJECT DeviceObject,
434 _Inout_ PIRP Irp)
435 {
436 PFLTMGR_DEVICE_EXTENSION DeviceExtension;
437 PIO_STACK_LOCATION StackPtr;
438 NTSTATUS Status;
439
440 DeviceExtension = DeviceObject->DeviceExtension;
441
442 /* Check if this is a request for us */
443 if (DeviceObject == DriverData.DeviceObject)
444 {
445 FLT_ASSERT(DeviceObject->DriverObject == DriverData.DriverObject);
446 FLT_ASSERT(DeviceExtension == NULL);
447
448 /* Hand it off to our internal handler */
449 Status = FltpDispatchHandler(DeviceObject, Irp);
450 if (Status != STATUS_REPARSE)
451 {
452 Irp->IoStatus.Status = Status;
453 Irp->IoStatus.Information = 0;
454 IoCompleteRequest(Irp, 0);
455 }
456 return Status;
457 }
458
459 /* Check if this is a request for a the messaging device */
460 if (DeviceObject == CommsDeviceObject)
461 {
462 /* Hand off to our internal routine */
463 return FltpMsgDispatch(DeviceObject, Irp);
464 }
465
466 FLT_ASSERT(DeviceExtension &&
467 DeviceExtension->AttachedToDeviceObject);
468
469 StackPtr = IoGetCurrentIrpStackLocation(Irp);
470 if (StackPtr->MajorFunction == IRP_MJ_SHUTDOWN)
471 {
472 // handle shutdown request
473 }
474
475 DPRINT1("Received %X from %wZ\n", StackPtr->MajorFunction, &DeviceExtension->DeviceName);
476
477 /* Just pass the IRP down the stack */
478 IoSkipCurrentIrpStackLocation(Irp);
479 return IoCallDriver(DeviceExtension->AttachedToDeviceObject, Irp);
480 }
481
482 NTSTATUS
483 NTAPI
484 FltpCreate(_In_ PDEVICE_OBJECT DeviceObject,
485 _Inout_ PIRP Irp)
486 {
487 PFLTMGR_DEVICE_EXTENSION DeviceExtension;
488
489 PAGED_CODE();
490
491 DeviceExtension = DeviceObject->DeviceExtension;
492
493 /* Check if this is a request for us */
494 if (DeviceObject == DriverData.DeviceObject)
495 {
496 FLT_ASSERT(DeviceObject->DriverObject == DriverData.DriverObject);
497 FLT_ASSERT(DeviceExtension == NULL);
498
499 /* Someone wants a handle to the fltmgr, allow it */
500 Irp->IoStatus.Status = STATUS_SUCCESS;
501 Irp->IoStatus.Information = 0;
502 IofCompleteRequest(Irp, 0);
503 return STATUS_SUCCESS;
504 }
505
506 /* Check if this is a request for a the new comms connection */
507 if (DeviceObject == CommsDeviceObject)
508 {
509 /* Hand off to our internal routine */
510 return FltpMsgCreate(DeviceObject, Irp);
511 }
512
513 FLT_ASSERT(DeviceExtension &&
514 DeviceExtension->AttachedToDeviceObject);
515
516 DPRINT1("Received create from %wZ (%lu)\n", &DeviceExtension->DeviceName, PsGetCurrentProcessId());
517
518 /* Just pass the IRP down the stack */
519 IoSkipCurrentIrpStackLocation(Irp);
520 return IoCallDriver(DeviceExtension->AttachedToDeviceObject, Irp);
521 }
522
523 NTSTATUS
524 NTAPI
525 FltpFsControl(_In_ PDEVICE_OBJECT DeviceObject,
526 _Inout_ PIRP Irp)
527 {
528 PFLTMGR_DEVICE_EXTENSION DeviceExtension;
529
530 PAGED_CODE();
531
532 /* Check if this is a request for us */
533 if (DeviceObject == DriverData.DeviceObject)
534 {
535 /* We don't handle this request */
536 Irp->IoStatus.Information = 0;
537 Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
538 IofCompleteRequest(Irp, 0);
539 return STATUS_INVALID_DEVICE_REQUEST;
540 }
541
542 DeviceExtension = DeviceObject->DeviceExtension;
543
544 FLT_ASSERT(DeviceExtension &&
545 DeviceExtension->AttachedToDeviceObject);
546
547 /* Just pass the IRP down the stack */
548 IoSkipCurrentIrpStackLocation(Irp);
549 return IoCallDriver(DeviceExtension->AttachedToDeviceObject, Irp);
550 }
551
552 NTSTATUS
553 NTAPI
554 FltpDeviceControl(_In_ PDEVICE_OBJECT DeviceObject,
555 _Inout_ PIRP Irp)
556 {
557 PFLTMGR_DEVICE_EXTENSION DeviceExtension;
558 NTSTATUS Status;
559
560 /* Check if the request was meant for us */
561 if (DeviceObject == DriverData.DeviceObject)
562 {
563 Status = FltpDeviceControlHandler(DeviceObject, Irp);
564 if (Status != STATUS_REPARSE)
565 {
566 Irp->IoStatus.Status = Status;
567 Irp->IoStatus.Information = 0;
568 IoCompleteRequest(Irp, 0);
569 }
570
571 return Status;
572 }
573
574 DeviceExtension = DeviceObject->DeviceExtension;
575
576 FLT_ASSERT(DeviceExtension &&
577 DeviceExtension->AttachedToDeviceObject);
578
579 /* Just pass the IRP down the stack */
580 IoSkipCurrentIrpStackLocation(Irp);
581 return IoCallDriver(DeviceExtension->AttachedToDeviceObject, Irp);
582 }
583
584
585
586 /* FASTIO ROUTINES ************************************************/
587
588 BOOLEAN
589 NTAPI
590 FltpFastIoCheckIfPossible(_In_ PFILE_OBJECT FileObject,
591 _In_ PLARGE_INTEGER FileOffset,
592 _In_ ULONG Length,
593 _In_ BOOLEAN Wait,
594 _In_ ULONG LockKey,
595 _In_ BOOLEAN CheckForReadOperation,
596 _Out_ PIO_STATUS_BLOCK IoStatus,
597 _In_ PDEVICE_OBJECT DeviceObject)
598
599 {
600 PFLTMGR_DEVICE_EXTENSION DeviceExtension;
601 PDEVICE_OBJECT AttachedDeviceObject;
602 PFAST_IO_DISPATCH FastIoDispatch;
603
604 PAGED_CODE();
605
606 /* If it doesn't have a device extension, then it's not our device object */
607 if (DeviceObject->DeviceExtension == NULL)
608 {
609 /* Fail the call */
610 IoStatus->Status = STATUS_INVALID_DEVICE_REQUEST;
611 IoStatus->Information = 0;
612 return TRUE;
613 }
614
615 DeviceExtension = DeviceObject->DeviceExtension;
616 FLT_ASSERT(DeviceExtension->AttachedToDeviceObject);
617
618 /* Get the device that we attached to */
619 AttachedDeviceObject = DeviceExtension->AttachedToDeviceObject;
620 FastIoDispatch = AttachedDeviceObject->DriverObject->FastIoDispatch;
621
622 /* Make sure our FastIo table is valid */
623 if (FastIoDispatch && FastIoDispatch->FastIoCheckIfPossible)
624 {
625 /* Forward the call onto the device we attached to */
626 return FastIoDispatch->FastIoCheckIfPossible(FileObject,
627 FileOffset,
628 Length,
629 Wait,
630 LockKey,
631 CheckForReadOperation,
632 IoStatus,
633 AttachedDeviceObject);
634 }
635
636 /* We failed to handle the request, send it down the slow path */
637 FLT_ASSERT(FALSE);
638 return FALSE;
639 }
640
641 BOOLEAN
642 NTAPI
643 FltpFastIoRead(_In_ PFILE_OBJECT FileObject,
644 _In_ PLARGE_INTEGER FileOffset,
645 _In_ ULONG Length,
646 _In_ BOOLEAN Wait,
647 _In_ ULONG LockKey,
648 _Out_ PVOID Buffer,
649 _Out_ PIO_STATUS_BLOCK IoStatus,
650 _In_ PDEVICE_OBJECT DeviceObject)
651 {
652 PFLTMGR_DEVICE_EXTENSION DeviceExtension;
653 PDEVICE_OBJECT AttachedDeviceObject;
654 PFAST_IO_DISPATCH FastIoDispatch;
655
656 PAGED_CODE();
657
658 /* If it doesn't have a device extension, then it's not our device object */
659 if (DeviceObject->DeviceExtension == NULL)
660 {
661 /* Fail the call */
662 IoStatus->Status = STATUS_INVALID_DEVICE_REQUEST;
663 IoStatus->Information = 0;
664 return TRUE;
665 }
666
667 DeviceExtension = DeviceObject->DeviceExtension;
668 FLT_ASSERT(DeviceExtension->AttachedToDeviceObject);
669
670 /* Get the device that we attached to */
671 AttachedDeviceObject = DeviceExtension->AttachedToDeviceObject;
672 FastIoDispatch = AttachedDeviceObject->DriverObject->FastIoDispatch;
673
674 /* Make sure our FastIo table is valid */
675 if (FastIoDispatch && FastIoDispatch->FastIoRead)
676 {
677 /* Forward the call onto the device we attached to */
678 return FastIoDispatch->FastIoRead(FileObject,
679 FileOffset,
680 Length,
681 Wait,
682 LockKey,
683 Buffer,
684 IoStatus,
685 AttachedDeviceObject);
686 }
687
688 /* We failed to handle the request, send it down the slow path */
689 FLT_ASSERT(FALSE);
690 return FALSE;
691 }
692
693 BOOLEAN
694 NTAPI
695 FltpFastIoWrite(_In_ PFILE_OBJECT FileObject,
696 _In_ PLARGE_INTEGER FileOffset,
697 _In_ ULONG Length,
698 _In_ BOOLEAN Wait,
699 _In_ ULONG LockKey,
700 _In_ PVOID Buffer,
701 _Out_ PIO_STATUS_BLOCK IoStatus,
702 _In_ PDEVICE_OBJECT DeviceObject)
703 {
704 PFLTMGR_DEVICE_EXTENSION DeviceExtension;
705 PDEVICE_OBJECT AttachedDeviceObject;
706 PFAST_IO_DISPATCH FastIoDispatch;
707
708 PAGED_CODE();
709
710 /* If it doesn't have a device extension, then it's not our device object */
711 if (DeviceObject->DeviceExtension == NULL)
712 {
713 /* Fail the call */
714 IoStatus->Status = STATUS_INVALID_DEVICE_REQUEST;
715 IoStatus->Information = 0;
716 return TRUE;
717 }
718
719 DeviceExtension = DeviceObject->DeviceExtension;
720 FLT_ASSERT(DeviceExtension->AttachedToDeviceObject);
721
722 /* Get the device that we attached to */
723 AttachedDeviceObject = DeviceExtension->AttachedToDeviceObject;
724 FastIoDispatch = AttachedDeviceObject->DriverObject->FastIoDispatch;
725
726 /* Make sure our FastIo table is valid */
727 if (FastIoDispatch && FastIoDispatch->FastIoWrite)
728 {
729 /* Forward the call onto the device we attached to */
730 return FastIoDispatch->FastIoWrite(FileObject,
731 FileOffset,
732 Length,
733 Wait,
734 LockKey,
735 Buffer,
736 IoStatus,
737 AttachedDeviceObject);
738 }
739
740 /* We failed to handle the request, send it down the slow path */
741 FLT_ASSERT(FALSE);
742 return FALSE;
743 }
744
745 BOOLEAN
746 NTAPI
747 FltpFastIoQueryBasicInfo(_In_ PFILE_OBJECT FileObject,
748 _In_ BOOLEAN Wait,
749 _Out_ PFILE_BASIC_INFORMATION Buffer,
750 _Out_ PIO_STATUS_BLOCK IoStatus,
751 _In_ PDEVICE_OBJECT DeviceObject)
752 {
753 PFLTMGR_DEVICE_EXTENSION DeviceExtension;
754 PDEVICE_OBJECT AttachedDeviceObject;
755 PFAST_IO_DISPATCH FastIoDispatch;
756
757 PAGED_CODE();
758
759 /* If it doesn't have a device extension, then it's not our device object */
760 if (DeviceObject->DeviceExtension == NULL)
761 {
762 /* Fail the call */
763 IoStatus->Status = STATUS_INVALID_DEVICE_REQUEST;
764 IoStatus->Information = 0;
765 return TRUE;
766 }
767
768 DeviceExtension = DeviceObject->DeviceExtension;
769 FLT_ASSERT(DeviceExtension->AttachedToDeviceObject);
770
771 /* Get the device that we attached to */
772 AttachedDeviceObject = DeviceExtension->AttachedToDeviceObject;
773 FastIoDispatch = AttachedDeviceObject->DriverObject->FastIoDispatch;
774
775 /* Make sure our FastIo table is valid */
776 if (FastIoDispatch && FastIoDispatch->FastIoQueryBasicInfo)
777 {
778 /* Forward the call onto the device we attached to */
779 return FastIoDispatch->FastIoQueryBasicInfo(FileObject,
780 Wait,
781 Buffer,
782 IoStatus,
783 AttachedDeviceObject);
784 }
785
786 /* We failed to handle the request, send it down the slow path */
787 FLT_ASSERT(FALSE);
788 return FALSE;
789 }
790
791 BOOLEAN
792 NTAPI
793 FltpFastIoQueryStandardInfo(_In_ PFILE_OBJECT FileObject,
794 _In_ BOOLEAN Wait,
795 _Out_ PFILE_STANDARD_INFORMATION Buffer,
796 _Out_ PIO_STATUS_BLOCK IoStatus,
797 _In_ PDEVICE_OBJECT DeviceObject)
798 {
799 PFLTMGR_DEVICE_EXTENSION DeviceExtension;
800 PDEVICE_OBJECT AttachedDeviceObject;
801 PFAST_IO_DISPATCH FastIoDispatch;
802
803 PAGED_CODE();
804
805 /* If it doesn't have a device extension, then it's not our device object */
806 if (DeviceObject->DeviceExtension == NULL)
807 {
808 /* Fail the call */
809 IoStatus->Status = STATUS_INVALID_DEVICE_REQUEST;
810 IoStatus->Information = 0;
811 return TRUE;
812 }
813
814 DeviceExtension = DeviceObject->DeviceExtension;
815 FLT_ASSERT(DeviceExtension->AttachedToDeviceObject);
816
817 /* Get the device that we attached to */
818 AttachedDeviceObject = DeviceExtension->AttachedToDeviceObject;
819 FastIoDispatch = AttachedDeviceObject->DriverObject->FastIoDispatch;
820
821 /* Make sure our FastIo table is valid */
822 if (FastIoDispatch && FastIoDispatch->FastIoQueryStandardInfo)
823 {
824 /* Forward the call onto the device we attached to */
825 return FastIoDispatch->FastIoQueryStandardInfo(FileObject,
826 Wait,
827 Buffer,
828 IoStatus,
829 AttachedDeviceObject);
830 }
831
832 /* We failed to handle the request, send it down the slow path */
833 FLT_ASSERT(FALSE);
834 return FALSE;
835 }
836
837 BOOLEAN
838 NTAPI
839 FltpFastIoLock(_In_ PFILE_OBJECT FileObject,
840 _In_ PLARGE_INTEGER FileOffset,
841 _In_ PLARGE_INTEGER Length,
842 _In_ PEPROCESS ProcessId,
843 _In_ ULONG Key,
844 _In_ BOOLEAN FailImmediately,
845 _In_ BOOLEAN ExclusiveLock,
846 _Out_ PIO_STATUS_BLOCK IoStatus,
847 _In_ PDEVICE_OBJECT DeviceObject)
848 {
849 PFLTMGR_DEVICE_EXTENSION DeviceExtension;
850 PDEVICE_OBJECT AttachedDeviceObject;
851 PFAST_IO_DISPATCH FastIoDispatch;
852
853 PAGED_CODE();
854
855 /* If it doesn't have a device extension, then it's not our device object */
856 if (DeviceObject->DeviceExtension == NULL)
857 {
858 /* Fail the call */
859 IoStatus->Status = STATUS_INVALID_DEVICE_REQUEST;
860 IoStatus->Information = 0;
861 return TRUE;
862 }
863
864 DeviceExtension = DeviceObject->DeviceExtension;
865 FLT_ASSERT(DeviceExtension->AttachedToDeviceObject);
866
867 /* Get the device that we attached to */
868 AttachedDeviceObject = DeviceExtension->AttachedToDeviceObject;
869 FastIoDispatch = AttachedDeviceObject->DriverObject->FastIoDispatch;
870
871 /* Make sure our FastIo table is valid */
872 if (FastIoDispatch && FastIoDispatch->FastIoLock)
873 {
874 /* Forward the call onto the device we attached to */
875 return FastIoDispatch->FastIoLock(FileObject,
876 FileOffset,
877 Length,
878 ProcessId,
879 Key,
880 FailImmediately,
881 ExclusiveLock,
882 IoStatus,
883 AttachedDeviceObject);
884 }
885
886 /* We failed to handle the request, send it down the slow path */
887 FLT_ASSERT(FALSE);
888 return FALSE;
889 }
890
891 BOOLEAN
892 NTAPI
893 FltpFastIoUnlockSingle(_In_ PFILE_OBJECT FileObject,
894 _In_ PLARGE_INTEGER FileOffset,
895 _In_ PLARGE_INTEGER Length,
896 _In_ PEPROCESS ProcessId,
897 _In_ ULONG Key,
898 _Out_ PIO_STATUS_BLOCK IoStatus,
899 _In_ PDEVICE_OBJECT DeviceObject)
900 {
901 PFLTMGR_DEVICE_EXTENSION DeviceExtension;
902 PDEVICE_OBJECT AttachedDeviceObject;
903 PFAST_IO_DISPATCH FastIoDispatch;
904
905 PAGED_CODE();
906
907 /* If it doesn't have a device extension, then it's not our device object */
908 if (DeviceObject->DeviceExtension == NULL)
909 {
910 /* Fail the call */
911 IoStatus->Status = STATUS_INVALID_DEVICE_REQUEST;
912 IoStatus->Information = 0;
913 return TRUE;
914 }
915
916 DeviceExtension = DeviceObject->DeviceExtension;
917 FLT_ASSERT(DeviceExtension->AttachedToDeviceObject);
918
919 /* Get the device that we attached to */
920 AttachedDeviceObject = DeviceExtension->AttachedToDeviceObject;
921 FastIoDispatch = AttachedDeviceObject->DriverObject->FastIoDispatch;
922
923 /* Make sure our FastIo table is valid */
924 if (FastIoDispatch && FastIoDispatch->FastIoUnlockSingle)
925 {
926 /* Forward the call onto the device we attached to */
927 return FastIoDispatch->FastIoUnlockSingle(FileObject,
928 FileOffset,
929 Length,
930 ProcessId,
931 Key,
932 IoStatus,
933 AttachedDeviceObject);
934 }
935
936 /* We failed to handle the request, send it down the slow path */
937 FLT_ASSERT(FALSE);
938 return FALSE;
939 }
940
941 BOOLEAN
942 NTAPI
943 FltpFastIoUnlockAll(_In_ PFILE_OBJECT FileObject,
944 _In_ PEPROCESS ProcessId,
945 _Out_ PIO_STATUS_BLOCK IoStatus,
946 _In_ PDEVICE_OBJECT DeviceObject)
947
948 {
949 PFLTMGR_DEVICE_EXTENSION DeviceExtension;
950 PDEVICE_OBJECT AttachedDeviceObject;
951 PFAST_IO_DISPATCH FastIoDispatch;
952
953 PAGED_CODE();
954
955 /* If it doesn't have a device extension, then it's not our device object */
956 if (DeviceObject->DeviceExtension == NULL)
957 {
958 /* Fail the call */
959 IoStatus->Status = STATUS_INVALID_DEVICE_REQUEST;
960 IoStatus->Information = 0;
961 return TRUE;
962 }
963
964 DeviceExtension = DeviceObject->DeviceExtension;
965 FLT_ASSERT(DeviceExtension->AttachedToDeviceObject);
966
967 /* Get the device that we attached to */
968 AttachedDeviceObject = DeviceExtension->AttachedToDeviceObject;
969 FastIoDispatch = AttachedDeviceObject->DriverObject->FastIoDispatch;
970
971 /* Make sure our FastIo table is valid */
972 if (FastIoDispatch && FastIoDispatch->FastIoUnlockAll)
973 {
974 /* Forward the call onto the device we attached to */
975 return FastIoDispatch->FastIoUnlockAll(FileObject,
976 ProcessId,
977 IoStatus,
978 AttachedDeviceObject);
979 }
980
981 /* We failed to handle the request, send it down the slow path */
982 FLT_ASSERT(FALSE);
983 return FALSE;
984 }
985
986 BOOLEAN
987 NTAPI
988 FltpFastIoUnlockAllByKey(_In_ PFILE_OBJECT FileObject,
989 _In_ PVOID ProcessId,
990 _In_ ULONG Key,
991 _Out_ PIO_STATUS_BLOCK IoStatus,
992 _In_ PDEVICE_OBJECT DeviceObject)
993 {
994 PFLTMGR_DEVICE_EXTENSION DeviceExtension;
995 PDEVICE_OBJECT AttachedDeviceObject;
996 PFAST_IO_DISPATCH FastIoDispatch;
997
998 PAGED_CODE();
999
1000 /* If it doesn't have a device extension, then it's not our device object */
1001 if (DeviceObject->DeviceExtension == NULL)
1002 {
1003 /* Fail the call */
1004 IoStatus->Status = STATUS_INVALID_DEVICE_REQUEST;
1005 IoStatus->Information = 0;
1006 return TRUE;
1007 }
1008
1009 DeviceExtension = DeviceObject->DeviceExtension;
1010 FLT_ASSERT(DeviceExtension->AttachedToDeviceObject);
1011
1012 /* Get the device that we attached to */
1013 AttachedDeviceObject = DeviceExtension->AttachedToDeviceObject;
1014 FastIoDispatch = AttachedDeviceObject->DriverObject->FastIoDispatch;
1015
1016 /* Make sure our FastIo table is valid */
1017 if (FastIoDispatch && FastIoDispatch->FastIoUnlockAllByKey)
1018 {
1019 /* Forward the call onto the device we attached to */
1020 return FastIoDispatch->FastIoUnlockAllByKey(FileObject,
1021 ProcessId,
1022 Key,
1023 IoStatus,
1024 AttachedDeviceObject);
1025 }
1026
1027 /* We failed to handle the request, send it down the slow path */
1028 FLT_ASSERT(FALSE);
1029 return FALSE;
1030 }
1031
1032 BOOLEAN
1033 NTAPI
1034 FltpFastIoDeviceControl(_In_ PFILE_OBJECT FileObject,
1035 _In_ BOOLEAN Wait,
1036 _In_opt_ PVOID InputBuffer,
1037 _In_ ULONG InputBufferLength,
1038 _Out_opt_ PVOID OutputBuffer,
1039 _In_ ULONG OutputBufferLength,
1040 _In_ ULONG IoControlCode,
1041 _Out_ PIO_STATUS_BLOCK IoStatus,
1042 _In_ PDEVICE_OBJECT DeviceObject)
1043 {
1044 PFLTMGR_DEVICE_EXTENSION DeviceExtension;
1045 PDEVICE_OBJECT AttachedDeviceObject;
1046 PFAST_IO_DISPATCH FastIoDispatch;
1047
1048 PAGED_CODE();
1049
1050 /* If it doesn't have a device extension, then it's not our device object */
1051 if (DeviceObject->DeviceExtension == NULL)
1052 {
1053 /* Fail the request, send it down the slow path */
1054 return FALSE;
1055 }
1056
1057 DeviceExtension = DeviceObject->DeviceExtension;
1058 FLT_ASSERT(DeviceExtension->AttachedToDeviceObject);
1059
1060 /* Get the device that we attached to */
1061 AttachedDeviceObject = DeviceExtension->AttachedToDeviceObject;
1062 FastIoDispatch = AttachedDeviceObject->DriverObject->FastIoDispatch;
1063
1064 /* Make sure our FastIo table is valid */
1065 if (FastIoDispatch && FastIoDispatch->FastIoDeviceControl)
1066 {
1067 /* Forward the call onto the device we attached to */
1068 return FastIoDispatch->FastIoDeviceControl(FileObject,
1069 Wait,
1070 InputBuffer,
1071 InputBufferLength,
1072 OutputBuffer,
1073 OutputBufferLength,
1074 IoControlCode,
1075 IoStatus,
1076 AttachedDeviceObject);
1077 }
1078
1079 /* We failed to handle the request, send it down the slow path */
1080 FLT_ASSERT(FALSE);
1081 return FALSE;
1082 }
1083
1084 VOID
1085 NTAPI
1086 FltpFastIoDetachDeviceWorker(_In_ PVOID Parameter)
1087 {
1088 PDETACH_DEVICE_WORK_ITEM DetachDeviceWorkItem = Parameter;
1089
1090 /* Run any cleanup routines */
1091 FltpCleanupDeviceObject(DetachDeviceWorkItem->SourceDevice);
1092
1093 /* Detach from the target device */
1094 IoDetachDevice(DetachDeviceWorkItem->TargetDevice);
1095
1096 /* Delete the source */
1097 IoDeleteDevice(DetachDeviceWorkItem->SourceDevice);
1098
1099 /* Free the pool we allocated in FltpFastIoDetachDevice */
1100 ExFreePoolWithTag(DetachDeviceWorkItem, 0x1234);
1101 }
1102
1103 VOID
1104 NTAPI
1105 FltpFastIoDetachDevice(_In_ PDEVICE_OBJECT SourceDevice,
1106 _In_ PDEVICE_OBJECT TargetDevice)
1107 {
1108 PDETACH_DEVICE_WORK_ITEM DetachDeviceWorkItem;
1109
1110 PAGED_CODE();
1111
1112 /*
1113 * Detaching and deleting devices is a lot of work and takes too long
1114 * to be a worthwhile FastIo candidate, so we defer this call to speed
1115 * it up. There's no return value so we're okay to do this.
1116 */
1117
1118 /* Allocate the work item and it's corresponding data */
1119 DetachDeviceWorkItem = ExAllocatePoolWithTag(NonPagedPool,
1120 sizeof(DETACH_DEVICE_WORK_ITEM),
1121 0x1234);
1122 if (DetachDeviceWorkItem)
1123 {
1124 /* Initialize the work item */
1125 ExInitializeWorkItem(&DetachDeviceWorkItem->WorkItem,
1126 FltpFastIoDetachDeviceWorker,
1127 DetachDeviceWorkItem);
1128
1129 /* Queue the work item and return the call */
1130 ExQueueWorkItem(&DetachDeviceWorkItem->WorkItem,
1131 DelayedWorkQueue);
1132 }
1133 else
1134 {
1135 /* We failed to defer, just cleanup here */
1136 FltpCleanupDeviceObject(SourceDevice);
1137 IoDetachDevice(TargetDevice);
1138 IoDeleteDevice(SourceDevice);
1139 }
1140
1141 }
1142
1143 BOOLEAN
1144 NTAPI
1145 FltpFastIoQueryNetworkOpenInfo(_In_ PFILE_OBJECT FileObject,
1146 _In_ BOOLEAN Wait,
1147 _Out_ PFILE_NETWORK_OPEN_INFORMATION Buffer,
1148 _Out_ PIO_STATUS_BLOCK IoStatus,
1149 _In_ PDEVICE_OBJECT DeviceObject)
1150 {
1151 PFLTMGR_DEVICE_EXTENSION DeviceExtension;
1152 PDEVICE_OBJECT AttachedDeviceObject;
1153 PFAST_IO_DISPATCH FastIoDispatch;
1154
1155 PAGED_CODE();
1156
1157 /* If it doesn't have a device extension, then it's not our device object */
1158 if (DeviceObject->DeviceExtension == NULL)
1159 {
1160 /* Fail the call */
1161 IoStatus->Status = STATUS_INVALID_DEVICE_REQUEST;
1162 IoStatus->Information = 0;
1163 return TRUE;
1164 }
1165
1166 DeviceExtension = DeviceObject->DeviceExtension;
1167 FLT_ASSERT(DeviceExtension->AttachedToDeviceObject);
1168
1169 /* Get the device that we attached to */
1170 AttachedDeviceObject = DeviceExtension->AttachedToDeviceObject;
1171 FastIoDispatch = AttachedDeviceObject->DriverObject->FastIoDispatch;
1172
1173 /* Make sure our FastIo table is valid */
1174 if (FastIoDispatch && FastIoDispatch->FastIoQueryNetworkOpenInfo)
1175 {
1176 /* Forward the call onto the device we attached to */
1177 return FastIoDispatch->FastIoQueryNetworkOpenInfo(FileObject,
1178 Wait,
1179 Buffer,
1180 IoStatus,
1181 AttachedDeviceObject);
1182 }
1183
1184 /* We failed to handle the request, send it down the slow path */
1185 FLT_ASSERT(FALSE);
1186 return FALSE;
1187 }
1188
1189 BOOLEAN
1190 NTAPI
1191 FltpFastIoMdlRead(_In_ PFILE_OBJECT FileObject,
1192 _In_ PLARGE_INTEGER FileOffset,
1193 _In_ ULONG Length,
1194 _In_ ULONG LockKey,
1195 _Out_ PMDL *MdlChain,
1196 _Out_ PIO_STATUS_BLOCK IoStatus,
1197 _In_ PDEVICE_OBJECT DeviceObject)
1198 {
1199 PFLTMGR_DEVICE_EXTENSION DeviceExtension;
1200 PDEVICE_OBJECT AttachedDeviceObject;
1201 PFAST_IO_DISPATCH FastIoDispatch;
1202
1203 PAGED_CODE();
1204
1205 /* If it doesn't have a device extension, then it's not our device object */
1206 if (DeviceObject->DeviceExtension == NULL)
1207 {
1208 /* Fail the call */
1209 IoStatus->Status = STATUS_INVALID_DEVICE_REQUEST;
1210 IoStatus->Information = 0;
1211 return TRUE;
1212 }
1213
1214 DeviceExtension = DeviceObject->DeviceExtension;
1215 FLT_ASSERT(DeviceExtension->AttachedToDeviceObject);
1216
1217 /* Get the device that we attached to */
1218 AttachedDeviceObject = DeviceExtension->AttachedToDeviceObject;
1219 FastIoDispatch = AttachedDeviceObject->DriverObject->FastIoDispatch;
1220
1221 /* Make sure our FastIo table is valid */
1222 if (FastIoDispatch && FastIoDispatch->MdlRead)
1223 {
1224 /* Forward the call onto the device we attached to */
1225 return FastIoDispatch->MdlRead(FileObject,
1226 FileOffset,
1227 Length,
1228 LockKey,
1229 MdlChain,
1230 IoStatus,
1231 AttachedDeviceObject);
1232 }
1233
1234 /* We failed to handle the request, send it down the slow path */
1235 FLT_ASSERT(FALSE);
1236 return FALSE;
1237 }
1238
1239 BOOLEAN
1240 NTAPI
1241 FltpFastIoMdlReadComplete(_In_ PFILE_OBJECT FileObject,
1242 _In_ PMDL MdlChain,
1243 _In_ PDEVICE_OBJECT DeviceObject)
1244
1245 {
1246 PFLTMGR_DEVICE_EXTENSION DeviceExtension;
1247 PDEVICE_OBJECT AttachedDeviceObject;
1248 PFAST_IO_DISPATCH FastIoDispatch;
1249
1250 PAGED_CODE();
1251
1252 /* If it doesn't have a device extension, then it's not our device object */
1253 if (DeviceObject->DeviceExtension == NULL)
1254 {
1255 /* Fail the request, send it down the slow path */
1256 return FALSE;
1257 }
1258
1259 DeviceExtension = DeviceObject->DeviceExtension;
1260 FLT_ASSERT(DeviceExtension->AttachedToDeviceObject);
1261
1262 /* Get the device that we attached to */
1263 AttachedDeviceObject = DeviceExtension->AttachedToDeviceObject;
1264 FastIoDispatch = AttachedDeviceObject->DriverObject->FastIoDispatch;
1265
1266 /* Make sure our FastIo table is valid */
1267 if (FastIoDispatch && FastIoDispatch->MdlReadComplete)
1268 {
1269 /* Forward the call onto the device we attached to */
1270 return FastIoDispatch->MdlReadComplete(FileObject,
1271 MdlChain,
1272 AttachedDeviceObject);
1273 }
1274
1275 /* We failed to handle the request, send it down the slow path */
1276 FLT_ASSERT(FALSE);
1277 return FALSE;
1278 }
1279
1280 BOOLEAN
1281 NTAPI
1282 FltpFastIoPrepareMdlWrite(_In_ PFILE_OBJECT FileObject,
1283 _In_ PLARGE_INTEGER FileOffset,
1284 _In_ ULONG Length,
1285 _In_ ULONG LockKey,
1286 _Out_ PMDL *MdlChain,
1287 _Out_ PIO_STATUS_BLOCK IoStatus,
1288 _In_ PDEVICE_OBJECT DeviceObject)
1289 {
1290 PFLTMGR_DEVICE_EXTENSION DeviceExtension;
1291 PDEVICE_OBJECT AttachedDeviceObject;
1292 PFAST_IO_DISPATCH FastIoDispatch;
1293
1294 PAGED_CODE();
1295
1296 /* If it doesn't have a device extension, then it's not our device object */
1297 if (DeviceObject->DeviceExtension == NULL)
1298 {
1299 /* Fail the call */
1300 IoStatus->Status = STATUS_INVALID_DEVICE_REQUEST;
1301 IoStatus->Information = 0;
1302 return TRUE;
1303 }
1304
1305 DeviceExtension = DeviceObject->DeviceExtension;
1306 FLT_ASSERT(DeviceExtension->AttachedToDeviceObject);
1307
1308 /* Get the device that we attached to */
1309 AttachedDeviceObject = DeviceExtension->AttachedToDeviceObject;
1310 FastIoDispatch = AttachedDeviceObject->DriverObject->FastIoDispatch;
1311
1312 /* Make sure our FastIo table is valid */
1313 if (FastIoDispatch && FastIoDispatch->PrepareMdlWrite)
1314 {
1315 /* Forward the call onto the device we attached to */
1316 return FastIoDispatch->PrepareMdlWrite(FileObject,
1317 FileOffset,
1318 Length,
1319 LockKey,
1320 MdlChain,
1321 IoStatus,
1322 AttachedDeviceObject);
1323 }
1324
1325 /* We failed to handle the request, send it down the slow path */
1326 FLT_ASSERT(FALSE);
1327 return FALSE;
1328 }
1329
1330 BOOLEAN
1331 NTAPI
1332 FltpFastIoMdlWriteComplete(_In_ PFILE_OBJECT FileObject,
1333 _In_ PLARGE_INTEGER FileOffset,
1334 _In_ PMDL MdlChain,
1335 _In_ PDEVICE_OBJECT DeviceObject)
1336 {
1337 PFLTMGR_DEVICE_EXTENSION DeviceExtension;
1338 PDEVICE_OBJECT AttachedDeviceObject;
1339 PFAST_IO_DISPATCH FastIoDispatch;
1340
1341 PAGED_CODE();
1342
1343 /* If it doesn't have a device extension, then it's not our device object */
1344 if (DeviceObject->DeviceExtension == NULL)
1345 {
1346 /* Fail the request, send it down the slow path */
1347 return FALSE;
1348 }
1349
1350 DeviceExtension = DeviceObject->DeviceExtension;
1351 FLT_ASSERT(DeviceExtension->AttachedToDeviceObject);
1352
1353 /* Get the device that we attached to */
1354 AttachedDeviceObject = DeviceExtension->AttachedToDeviceObject;
1355 FastIoDispatch = AttachedDeviceObject->DriverObject->FastIoDispatch;
1356
1357 /* Make sure our FastIo table is valid */
1358 if (FastIoDispatch && FastIoDispatch->MdlWriteComplete)
1359 {
1360 /* Forward the call onto the device we attached to */
1361 return FastIoDispatch->MdlWriteComplete(FileObject,
1362 FileOffset,
1363 MdlChain,
1364 AttachedDeviceObject);
1365 }
1366
1367 /* We failed to handle the request, send it down the slow path */
1368 FLT_ASSERT(FALSE);
1369 return FALSE;
1370 }
1371
1372 BOOLEAN
1373 NTAPI
1374 FltpFastIoReadCompressed(_In_ PFILE_OBJECT FileObject,
1375 _In_ PLARGE_INTEGER FileOffset,
1376 _In_ ULONG Length,
1377 _In_ ULONG LockKey,
1378 _Out_ PVOID Buffer,
1379 _Out_ PMDL *MdlChain,
1380 _Out_ PIO_STATUS_BLOCK IoStatus,
1381 _Out_ PCOMPRESSED_DATA_INFO CompressedDataInfo,
1382 _In_ ULONG CompressedDataInfoLength,
1383 _In_ PDEVICE_OBJECT DeviceObject)
1384 {
1385 PFLTMGR_DEVICE_EXTENSION DeviceExtension;
1386 PDEVICE_OBJECT AttachedDeviceObject;
1387 PFAST_IO_DISPATCH FastIoDispatch;
1388
1389 PAGED_CODE();
1390
1391 /* If it doesn't have a device extension, then it's not our device object */
1392 if (DeviceObject->DeviceExtension == NULL)
1393 {
1394 /* Fail the request, send it down the slow path */
1395 return FALSE;
1396 }
1397
1398 DeviceExtension = DeviceObject->DeviceExtension;
1399 FLT_ASSERT(DeviceExtension->AttachedToDeviceObject);
1400
1401 /* Get the device that we attached to */
1402 AttachedDeviceObject = DeviceExtension->AttachedToDeviceObject;
1403 FastIoDispatch = AttachedDeviceObject->DriverObject->FastIoDispatch;
1404
1405 /* Make sure our FastIo table is valid */
1406 if (FastIoDispatch && FastIoDispatch->FastIoReadCompressed)
1407 {
1408 /* Forward the call onto the device we attached to */
1409 return FastIoDispatch->FastIoReadCompressed(FileObject,
1410 FileOffset,
1411 Length,
1412 LockKey,
1413 Buffer,
1414 MdlChain,
1415 IoStatus,
1416 CompressedDataInfo,
1417 CompressedDataInfoLength,
1418 AttachedDeviceObject);
1419 }
1420
1421 /* We failed to handle the request, send it down the slow path */
1422 FLT_ASSERT(FALSE);
1423 return FALSE;
1424 }
1425
1426 BOOLEAN
1427 NTAPI
1428 FltpFastIoWriteCompressed(_In_ PFILE_OBJECT FileObject,
1429 _In_ PLARGE_INTEGER FileOffset,
1430 _In_ ULONG Length,
1431 _In_ ULONG LockKey,
1432 _In_ PVOID Buffer,
1433 _Out_ PMDL *MdlChain,
1434 _Out_ PIO_STATUS_BLOCK IoStatus,
1435 _In_ PCOMPRESSED_DATA_INFO CompressedDataInfo,
1436 _In_ ULONG CompressedDataInfoLength,
1437 _In_ PDEVICE_OBJECT DeviceObject)
1438 {
1439 PFLTMGR_DEVICE_EXTENSION DeviceExtension;
1440 PDEVICE_OBJECT AttachedDeviceObject;
1441 PFAST_IO_DISPATCH FastIoDispatch;
1442
1443 PAGED_CODE();
1444
1445 /* If it doesn't have a device extension, then it's not our device object */
1446 if (DeviceObject->DeviceExtension == NULL)
1447 {
1448 /* Fail the request, send it down the slow path */
1449 return FALSE;
1450 }
1451
1452 DeviceExtension = DeviceObject->DeviceExtension;
1453 FLT_ASSERT(DeviceExtension->AttachedToDeviceObject);
1454
1455 /* Get the device that we attached to */
1456 AttachedDeviceObject = DeviceExtension->AttachedToDeviceObject;
1457 FastIoDispatch = AttachedDeviceObject->DriverObject->FastIoDispatch;
1458
1459 /* Make sure our FastIo table is valid */
1460 if (FastIoDispatch && FastIoDispatch->FastIoWriteCompressed)
1461 {
1462 /* Forward the call onto the device we attached to */
1463 return FastIoDispatch->FastIoWriteCompressed(FileObject,
1464 FileOffset,
1465 Length,
1466 LockKey,
1467 Buffer,
1468 MdlChain,
1469 IoStatus,
1470 CompressedDataInfo,
1471 CompressedDataInfoLength,
1472 AttachedDeviceObject);
1473 }
1474
1475 /* We failed to handle the request, send it down the slow path */
1476 FLT_ASSERT(FALSE);
1477 return FALSE;
1478 }
1479
1480 BOOLEAN
1481 NTAPI
1482 FltpFastIoMdlReadCompleteCompressed(_In_ PFILE_OBJECT FileObject,
1483 _In_ PMDL MdlChain,
1484 _In_ PDEVICE_OBJECT DeviceObject)
1485 {
1486 PFLTMGR_DEVICE_EXTENSION DeviceExtension;
1487 PDEVICE_OBJECT AttachedDeviceObject;
1488 PFAST_IO_DISPATCH FastIoDispatch;
1489
1490 PAGED_CODE();
1491
1492 /* If it doesn't have a device extension, then it's not our device object */
1493 if (DeviceObject->DeviceExtension == NULL)
1494 {
1495 return FALSE;
1496 }
1497
1498 DeviceExtension = DeviceObject->DeviceExtension;
1499 FLT_ASSERT(DeviceExtension->AttachedToDeviceObject);
1500
1501 /* Get the device that we attached to */
1502 AttachedDeviceObject = DeviceExtension->AttachedToDeviceObject;
1503 FastIoDispatch = AttachedDeviceObject->DriverObject->FastIoDispatch;
1504
1505 /* Make sure our FastIo table is valid */
1506 if (FastIoDispatch && FastIoDispatch->MdlReadCompleteCompressed)
1507 {
1508 /* Forward the call onto the device we attached to */
1509 return FastIoDispatch->MdlReadCompleteCompressed(FileObject,
1510 MdlChain,
1511 AttachedDeviceObject);
1512 }
1513
1514 /* We failed to handle the request, send it down the slow path */
1515 FLT_ASSERT(FALSE);
1516 return FALSE;
1517 }
1518
1519 BOOLEAN
1520 NTAPI
1521 FltpFastIoMdlWriteCompleteCompressed(_In_ PFILE_OBJECT FileObject,
1522 _In_ PLARGE_INTEGER FileOffset,
1523 _In_ PMDL MdlChain,
1524 _In_ PDEVICE_OBJECT DeviceObject)
1525 {
1526 PFLTMGR_DEVICE_EXTENSION DeviceExtension;
1527 PDEVICE_OBJECT AttachedDeviceObject;
1528 PFAST_IO_DISPATCH FastIoDispatch;
1529
1530 PAGED_CODE();
1531
1532 /* If it doesn't have a device extension, then it's not our device object */
1533 if (DeviceObject->DeviceExtension == NULL)
1534 {
1535 return FALSE;
1536 }
1537
1538 DeviceExtension = DeviceObject->DeviceExtension;
1539 FLT_ASSERT(DeviceExtension->AttachedToDeviceObject);
1540
1541 /* Get the device that we attached to */
1542 AttachedDeviceObject = DeviceExtension->AttachedToDeviceObject;
1543 FastIoDispatch = AttachedDeviceObject->DriverObject->FastIoDispatch;
1544
1545 /* Make sure our FastIo table is valid */
1546 if (FastIoDispatch && FastIoDispatch->MdlWriteCompleteCompressed)
1547 {
1548 /* Forward the call onto the device we attached to */
1549 return FastIoDispatch->MdlWriteCompleteCompressed(FileObject,
1550 FileOffset,
1551 MdlChain,
1552 AttachedDeviceObject);
1553 }
1554
1555 /* We failed to handle the request, send it down the slow path */
1556 FLT_ASSERT(FALSE);
1557 return FALSE;
1558 }
1559
1560 BOOLEAN
1561 NTAPI
1562 FltpFastIoQueryOpen(_Inout_ PIRP Irp,
1563 _Out_ PFILE_NETWORK_OPEN_INFORMATION NetworkInformation,
1564 _In_ PDEVICE_OBJECT DeviceObject)
1565 {
1566 PFLTMGR_DEVICE_EXTENSION DeviceExtension;
1567 PDEVICE_OBJECT AttachedDeviceObject;
1568 PFAST_IO_DISPATCH FastIoDispatch;
1569 BOOLEAN Success;
1570
1571 PAGED_CODE();
1572
1573 /* If it doesn't have a device extension, then it's not our device object */
1574 if (DeviceObject->DeviceExtension == NULL)
1575 {
1576 return FALSE;
1577 }
1578
1579 DeviceExtension = DeviceObject->DeviceExtension;
1580 FLT_ASSERT(DeviceExtension->AttachedToDeviceObject);
1581
1582 /* Get the device that we attached to */
1583 AttachedDeviceObject = DeviceExtension->AttachedToDeviceObject;
1584 FastIoDispatch = AttachedDeviceObject->DriverObject->FastIoDispatch;
1585
1586 /* Make sure our FastIo table is valid */
1587 if (FastIoDispatch && FastIoDispatch->FastIoQueryOpen)
1588 {
1589 PIO_STACK_LOCATION StackPtr = IoGetCurrentIrpStackLocation(Irp);
1590
1591 /* Update the stack to contain the correct device for the next filter */
1592 StackPtr->DeviceObject = AttachedDeviceObject;
1593
1594 /* Now forward the call */
1595 Success = FastIoDispatch->FastIoQueryOpen(Irp,
1596 NetworkInformation,
1597 AttachedDeviceObject);
1598
1599 /* Restore the DeviceObject as we found it */
1600 StackPtr->DeviceObject = DeviceObject;
1601 return Success;
1602 }
1603
1604 /* We failed to handle the request, send it down the slow path */
1605 FLT_ASSERT(FALSE);
1606 return FALSE;
1607 }
1608
1609
1610
1611 /* FUNCTIONS **********************************************/
1612
1613 static
1614 VOID
1615 FltpCleanupDeviceObject(_In_ PDEVICE_OBJECT DeviceObject)
1616 {
1617 PFLTMGR_DEVICE_EXTENSION DeviceExtension;
1618
1619 DeviceExtension = DeviceObject->DeviceExtension;
1620 if (DeviceExtension)
1621 {
1622 // cleanup device extension
1623 }
1624 }
1625
1626 static
1627 NTSTATUS
1628 FltpAttachDeviceObject(_In_ PDEVICE_OBJECT SourceDevice,
1629 _In_ PDEVICE_OBJECT TargetDevice,
1630 _Out_ PDEVICE_OBJECT *AttachedToDeviceObject)
1631 {
1632 NTSTATUS Status;
1633
1634 PAGED_CODE();
1635
1636 /* Before attaching, copy the flags from the device we're going to attach to */
1637 if (FlagOn(SourceDevice->Flags, DO_BUFFERED_IO))
1638 {
1639 SetFlag(TargetDevice->Flags, DO_BUFFERED_IO);
1640 }
1641 if (FlagOn(SourceDevice->Flags, DO_DIRECT_IO))
1642 {
1643 SetFlag(TargetDevice->Flags, DO_DIRECT_IO);
1644 }
1645 if (FlagOn(SourceDevice->Flags, DO_SYSTEM_BOOT_PARTITION))
1646 {
1647 SetFlag(TargetDevice->Characteristics, FILE_DEVICE_SECURE_OPEN);
1648 }
1649
1650 /* Attach this device to the top of the driver stack */
1651 Status = IoAttachDeviceToDeviceStackSafe(SourceDevice,
1652 TargetDevice,
1653 AttachedToDeviceObject);
1654
1655 return Status;
1656 }
1657
1658 static
1659 BOOLEAN
1660 FltpIsAttachedToDevice(_In_ PDEVICE_OBJECT DeviceObject,
1661 _In_opt_ PDEVICE_OBJECT *AttachedDeviceObject)
1662 {
1663 PDEVICE_OBJECT CurrentDeviceObject;
1664 PDEVICE_OBJECT NextDeviceObject;
1665
1666 PAGED_CODE();
1667
1668 /* Initialize the return pointer */
1669 if (AttachedDeviceObject) *AttachedDeviceObject = NULL;
1670
1671 /* Start by getting the top level device in the chain */
1672 CurrentDeviceObject = IoGetAttachedDeviceReference(DeviceObject);
1673
1674 /* Loop while there are attached devices */
1675 while (CurrentDeviceObject)
1676 {
1677 /* Check if this device driver matches ours */
1678 if (CurrentDeviceObject->DriverObject == DriverData.DriverObject)
1679 {
1680 FLT_ASSERT(CurrentDeviceObject->DeviceExtension != NULL);
1681
1682 /* We're attached, return the device object if the caller asked for it */
1683 if (AttachedDeviceObject)
1684 {
1685 *AttachedDeviceObject = CurrentDeviceObject;
1686 }
1687 else
1688 {
1689 /* We aren't returning the reference, so decrement the count */
1690 ObDereferenceObject(CurrentDeviceObject);
1691 }
1692
1693 return TRUE;
1694 }
1695
1696 /* Get the next device in the chain */
1697 NextDeviceObject = IoGetLowerDeviceObject(CurrentDeviceObject);
1698
1699 /* Decrement the count on the last device before we update the pointer */
1700 ObDereferenceObject(CurrentDeviceObject);
1701 CurrentDeviceObject = NextDeviceObject;
1702 }
1703
1704 return FALSE;
1705 }
1706
1707 static
1708 NTSTATUS
1709 FltpEnumerateFileSystemVolumes(_In_ PDEVICE_OBJECT DeviceObject)
1710 {
1711 PFLTMGR_DEVICE_EXTENSION NewDeviceExtension;
1712 PDEVICE_OBJECT BaseDeviceObject;
1713 PDEVICE_OBJECT NewDeviceObject;
1714 PDEVICE_OBJECT *DeviceList;
1715 PDEVICE_OBJECT StorageStackDeviceObject;
1716 UNICODE_STRING DeviceName;
1717 ULONG NumDevices;
1718 ULONG i;
1719 NTSTATUS Status;
1720
1721 PAGED_CODE();
1722
1723 /* Get the base device */
1724 BaseDeviceObject = IoGetDeviceAttachmentBaseRef(DeviceObject);
1725
1726 /* get the number of device object linked to the base file system */
1727 Status = IoEnumerateDeviceObjectList(BaseDeviceObject->DriverObject,
1728 NULL,
1729 0,
1730 &NumDevices);
1731 if (Status != STATUS_BUFFER_TOO_SMALL) return Status;
1732
1733 /* Add a few more slots in case the size changed between calls and allocate some memory to hold the pointers */
1734 NumDevices += 4;
1735 DeviceList = ExAllocatePoolWithTag(NonPagedPool,
1736 (NumDevices * sizeof(PDEVICE_OBJECT)),
1737 FM_TAG_DEV_OBJ_PTRS);
1738 if (DeviceList == NULL) return STATUS_INSUFFICIENT_RESOURCES;
1739
1740 /* Now get all the device objects that this base driver has created */
1741 Status = IoEnumerateDeviceObjectList(BaseDeviceObject->DriverObject,
1742 DeviceList,
1743 (NumDevices * sizeof(PDEVICE_OBJECT)),
1744 &NumDevices);
1745 if (!NT_SUCCESS(Status))
1746 {
1747 ExFreePoolWithTag(DeviceList, FM_TAG_DEV_OBJ_PTRS);
1748 return Status;
1749 }
1750
1751 /* Loop through all the devices looking for ones to attach to */
1752 for (i = 0; i < NumDevices; i++)
1753 {
1754 RtlInitUnicodeString(&DeviceName, NULL);
1755 StorageStackDeviceObject = NULL;
1756 NewDeviceObject = NULL;
1757
1758 /* Ignore the device we passed in, and devices of the wrong type */
1759 if ((DeviceList[i] == BaseDeviceObject) ||
1760 (DeviceList[i]->DeviceType != BaseDeviceObject->DeviceType))
1761 {
1762 goto CleanupAndNext;
1763 }
1764
1765 /* Ignore this device if we're already attached to it */
1766 if (FltpIsAttachedToDevice(DeviceList[i], NULL) == FALSE)
1767 {
1768 goto CleanupAndNext;
1769 }
1770
1771
1772 /*
1773 * If the device has a name, it must be a control device.
1774 * This handles drivers with more then one control device (like FastFat)
1775 */
1776 FltpGetBaseDeviceObjectName(DeviceList[i], &DeviceName);
1777 if (NT_SUCCESS(Status) && DeviceName.Length > 0)
1778 {
1779 goto CleanupAndNext;
1780 }
1781
1782 /*
1783 * Try to get the storage stack (disk) device object associated with
1784 * this file system device object. Ignore the device if we don't have one
1785 */
1786 Status = IoGetDiskDeviceObject(DeviceList[i],
1787 &StorageStackDeviceObject);
1788 if (!NT_SUCCESS(Status))
1789 {
1790 goto CleanupAndNext;
1791 }
1792
1793
1794 /*
1795 * TODO: Don't attach to shadow copy volumes,
1796 * ros doesn't have any so it's not an issues yet
1797 */
1798
1799 /*
1800 * We're far enough to be ready to attach, create a device
1801 * object which we'll use to do so
1802 */
1803 Status = IoCreateDevice(DriverData.DriverObject,
1804 sizeof(FLTMGR_DEVICE_EXTENSION),
1805 NULL,
1806 DeviceList[i]->DeviceType,
1807 0,
1808 FALSE,
1809 &NewDeviceObject);
1810 if (!NT_SUCCESS(Status))
1811 {
1812 goto CleanupAndNext;
1813 }
1814
1815 /* Get the device extension for this new object and store our disk object there */
1816 NewDeviceExtension = NewDeviceObject->DeviceExtension;
1817 NewDeviceExtension->StorageStackDeviceObject = StorageStackDeviceObject;
1818
1819 /* Lookup and store the device name for the storage stack */
1820 RtlInitEmptyUnicodeString(&NewDeviceExtension->DeviceName,
1821 NewDeviceExtension->DeviceNameBuffer,
1822 sizeof(NewDeviceExtension->DeviceNameBuffer));
1823 FltpGetObjectName(StorageStackDeviceObject,
1824 &NewDeviceExtension->DeviceName);
1825
1826
1827 /* Grab the attach lock before we attempt to attach */
1828 ExAcquireFastMutex(&DriverData.FilterAttachLock);
1829
1830 /* Check again that we aren't already attached. It may have changed since our last check */
1831 if (FltpIsAttachedToDevice(DeviceList[i], NULL) == FALSE)
1832 {
1833 FLT_ASSERT(NewDeviceObject->DriverObject == DriverData.DriverObject);
1834
1835 /* Finally, attach to the volume */
1836 Status = FltpAttachDeviceObject(DeviceList[i],
1837 NewDeviceObject,
1838 &NewDeviceExtension->AttachedToDeviceObject);
1839 if (NT_SUCCESS(Status))
1840 {
1841 /* Clean the initializing flag so other filters can attach to our device object */
1842 ClearFlag(NewDeviceObject->Flags, DO_DEVICE_INITIALIZING);
1843 }
1844 }
1845 else
1846 {
1847 /* We're already attached. Just cleanup */
1848 Status = STATUS_DEVICE_ALREADY_ATTACHED;
1849 }
1850
1851 ExReleaseFastMutex(&DriverData.FilterAttachLock);
1852
1853 CleanupAndNext:
1854
1855 if (!NT_SUCCESS(Status))
1856 {
1857 if (NewDeviceObject)
1858 {
1859 FltpCleanupDeviceObject(NewDeviceObject);
1860 IoDeleteDevice(NewDeviceObject);
1861 }
1862 }
1863
1864 if (StorageStackDeviceObject)
1865 {
1866 /* A ref was added for us when we attached, so we can deref ours now */
1867 ObDereferenceObject(StorageStackDeviceObject);
1868 }
1869
1870 /* Remove the ref which was added by IoEnumerateDeviceObjectList */
1871 ObDereferenceObject(DeviceList[i]);
1872
1873 /* Free the buffer that FltpGetBaseDeviceObjectName added */
1874 FltpFreeUnicodeString(&DeviceName);
1875
1876 }
1877
1878 /* Free the memory we allocated for the list */
1879 ExFreePoolWithTag(DeviceList, FM_TAG_DEV_OBJ_PTRS);
1880
1881 return STATUS_SUCCESS;
1882 }
1883
1884 static
1885 NTSTATUS
1886 FltpAttachToFileSystemDevice(_In_ PDEVICE_OBJECT DeviceObject,
1887 _In_ PUNICODE_STRING DeviceName)
1888 {
1889 PFLTMGR_DEVICE_EXTENSION DeviceExtension;
1890 PDEVICE_OBJECT NewDeviceObject;
1891 WCHAR Buffer[MAX_DEVNAME_LENGTH];
1892 UNICODE_STRING FileSystemDeviceName;
1893 UNICODE_STRING FsRecDeviceName;
1894 NTSTATUS Status;
1895
1896 PAGED_CODE();
1897
1898 /* Only handle device types we're interested in */
1899 if (DeviceObject->DeviceType != FILE_DEVICE_DISK_FILE_SYSTEM &&
1900 DeviceObject->DeviceType != FILE_DEVICE_CD_ROM_FILE_SYSTEM &&
1901 DeviceObject->DeviceType != FILE_DEVICE_NETWORK_FILE_SYSTEM)
1902 {
1903 return STATUS_SUCCESS;
1904 }
1905
1906 /* Setup the buffer to hold the device name */
1907 RtlInitEmptyUnicodeString(&FileSystemDeviceName,
1908 Buffer,
1909 MAX_DEVNAME_LENGTH * sizeof(WCHAR));
1910
1911 /* Get the the name of the file system device */
1912 Status = FltpGetObjectName(DeviceObject->DriverObject, &FileSystemDeviceName);
1913 if (!NT_SUCCESS(Status)) return Status;
1914
1915 DPRINT("Found device %wZ, checking if we need to attach...\n", &FileSystemDeviceName);
1916
1917 /* Build up the name of the file system recognizer device */
1918 RtlInitUnicodeString(&FsRecDeviceName, L"\\FileSystem\\Fs_Rec");
1919
1920 /* We don't attach to recognizer devices, so bail if this is one */
1921 if (RtlCompareUnicodeString(&FileSystemDeviceName, &FsRecDeviceName, TRUE) == 0)
1922 {
1923 return STATUS_SUCCESS;
1924 }
1925
1926 /* Create a device object which we can attach to this file system */
1927 Status = IoCreateDevice(DriverData.DriverObject,
1928 sizeof(FLTMGR_DEVICE_EXTENSION),
1929 NULL,
1930 DeviceObject->DeviceType,
1931 0,
1932 FALSE,
1933 &NewDeviceObject);
1934 if (!NT_SUCCESS(Status))
1935 {
1936 DPRINT1("Failed to create a DO for attaching to a FS : 0x%X\n", Status);
1937 return Status;
1938 }
1939
1940 /* Cast the device extension to something we understand */
1941 DeviceExtension = NewDeviceObject->DeviceExtension;
1942
1943 /* Attach this device to the top of the driver stack and store the DO we attached to in the DE */
1944 Status = FltpAttachDeviceObject(NewDeviceObject,
1945 DeviceObject,
1946 &DeviceExtension->AttachedToDeviceObject);
1947 if (NT_SUCCESS(Status))
1948 {
1949 DPRINT("Attached to %wZ\n", &FileSystemDeviceName);
1950 }
1951 else
1952 {
1953 DPRINT1("Failed to attach to the driver stack : 0x%X\n", Status);
1954 goto Cleanup;
1955 }
1956
1957 /* Setup the unicode string buffer and copy the device name to the device extension */
1958 RtlInitEmptyUnicodeString(&DeviceExtension->DeviceName,
1959 DeviceExtension->DeviceNameBuffer,
1960 MAX_DEVNAME_LENGTH * sizeof(WCHAR));
1961 RtlCopyUnicodeString(&DeviceExtension->DeviceName, DeviceName);
1962
1963 /* We're done, remove the initializing flag */
1964 ClearFlag(NewDeviceObject->Flags, DO_DEVICE_INITIALIZING);
1965
1966 /* Look for existing mounted devices for this file system */
1967 Status = FltpEnumerateFileSystemVolumes(DeviceObject);
1968 if (!NT_SUCCESS(Status))
1969 {
1970 DPRINT1("Failed to enumerate file system volumes for this file system : 0x%X\n", Status);
1971 IoDetachDevice(DeviceExtension->AttachedToDeviceObject);
1972 }
1973
1974 Cleanup:
1975
1976 if (!NT_SUCCESS(Status))
1977 {
1978 IoDeleteDevice(NewDeviceObject);
1979 }
1980
1981 return Status;
1982 }
1983
1984 static
1985 LONG_PTR
1986 FltpDetachFromFileSystemDevice(_In_ PDEVICE_OBJECT DeviceObject)
1987 {
1988 PDEVICE_OBJECT AttachedDevice, NextDevice;
1989 PFLTMGR_DEVICE_EXTENSION DeviceExtension;
1990 LONG_PTR Count;
1991
1992 PAGED_CODE();
1993
1994 /* Get the top device in the chain and increment the ref count on it */
1995 AttachedDevice = IoGetAttachedDeviceReference(DeviceObject);
1996
1997 /* Loop all attached devices looking for our file system driver */
1998 while (AttachedDevice->DriverObject != DriverData.DriverObject)
1999 {
2000 FLT_ASSERT(AttachedDevice != NULL);
2001
2002 /* Get the next lower device object. This adds a ref on NextDevice */
2003 NextDevice = IoGetLowerDeviceObject(AttachedDevice);
2004
2005 /* Remove the reference we added */
2006 Count = ObfDereferenceObject(AttachedDevice);
2007
2008 /* Bail if this is the last one */
2009 if (NextDevice == NULL) return Count;
2010
2011 /* Try the next one */
2012 AttachedDevice = NextDevice;
2013 }
2014
2015
2016 DeviceExtension = AttachedDevice->DeviceExtension;
2017 if (DeviceExtension)
2018 {
2019 //
2020 // FIXME: Put any device extension cleanup code here
2021 //
2022 }
2023
2024 /* Detach the device from the chain and delete the object */
2025 IoDetachDevice(DeviceObject);
2026 IoDeleteDevice(AttachedDevice);
2027
2028 /* Remove the reference we added so the delete can complete */
2029 return ObfDereferenceObject(AttachedDevice);
2030 }
2031
2032 DRIVER_FS_NOTIFICATION FltpFsNotification;
2033 VOID
2034 NTAPI
2035 FltpFsNotification(_In_ PDEVICE_OBJECT DeviceObject,
2036 _In_ BOOLEAN FsActive)
2037 {
2038 UNICODE_STRING DeviceName;
2039 NTSTATUS Status;
2040
2041 PAGED_CODE();
2042
2043 /* Set an empty string */
2044 RtlInitUnicodeString(&DeviceName, NULL);
2045
2046 /* Get the name of the lowest device object on the stack */
2047 Status = FltpGetBaseDeviceObjectName(DeviceObject, &DeviceName);
2048 if (NT_SUCCESS(Status))
2049 {
2050 /* Check if it's attaching or detaching */
2051 if (FsActive)
2052 {
2053 /* Run the attach routine */
2054 FltpAttachToFileSystemDevice(DeviceObject, &DeviceName);
2055 }
2056 else
2057 {
2058 /* Run the detach routine */
2059 FltpDetachFromFileSystemDevice(DeviceObject);
2060 }
2061
2062 /* Free the buffer which FltpGetBaseDeviceObjectName allocated */
2063 FltpFreeUnicodeString(&DeviceName);
2064 }
2065 }
2066
2067 DRIVER_INITIALIZE DriverEntry;
2068 NTSTATUS
2069 NTAPI
2070 DriverEntry(_In_ PDRIVER_OBJECT DriverObject,
2071 _In_ PUNICODE_STRING RegistryPath)
2072 {
2073 UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\FileSystem\\Filters\\"DRIVER_NAME);
2074 PDEVICE_OBJECT RawDeviceObject;
2075 PDEVICE_OBJECT DeviceObject;
2076 PFILE_OBJECT RawFileObject;
2077 UNICODE_STRING ObjectName;
2078 UNICODE_STRING SymLink;
2079
2080 NTSTATUS Status;
2081
2082 RtlZeroMemory(&DriverData, sizeof(DRIVER_DATA));
2083 DriverData.DriverObject = DriverObject;
2084
2085 /* Save the registry key for this driver */
2086 DriverData.ServiceKey.Length = RegistryPath->Length;
2087 DriverData.ServiceKey.MaximumLength = RegistryPath->MaximumLength;
2088 DriverData.ServiceKey.Buffer = (PWCHAR)ExAllocatePoolWithTag(NonPagedPool,
2089 RegistryPath->MaximumLength,
2090 FM_TAG_REGISTRY_DATA);
2091 if (!DriverData.ServiceKey.Buffer) return STATUS_INSUFFICIENT_RESOURCES;
2092 RtlCopyUnicodeString(&DriverData.ServiceKey, RegistryPath);
2093
2094 /* Do some initialization */
2095 ExInitializeFastMutex(&DriverData.FilterAttachLock);
2096
2097 /* Create the main filter manager device object */
2098 Status = IoCreateDevice(DriverObject,
2099 0,
2100 &DeviceName,
2101 FILE_DEVICE_DISK_FILE_SYSTEM,
2102 FILE_DEVICE_SECURE_OPEN,
2103 FALSE,
2104 &DeviceObject);
2105 if (!NT_SUCCESS(Status))
2106 {
2107 DPRINT1("fltmgr IoCreateDevice failed. Status = %X\n", Status);
2108 goto Cleanup;
2109 }
2110
2111 /* Store a global reference so we can access from callbacks */
2112 DriverData.DeviceObject = DeviceObject;
2113
2114 /* Generate the symbolic link name */
2115 RtlInitUnicodeString(&SymLink, L"\\??\\"DRIVER_NAME);
2116 Status = IoCreateSymbolicLink(&SymLink, &DeviceName);
2117 if (!NT_SUCCESS(Status)) goto Cleanup;
2118
2119 /* Create the callbacks for the dispatch table, FastIo and FS callbacks */
2120 Status = SetupDispatchAndCallbacksTables(DriverObject);
2121 if (!NT_SUCCESS(Status)) goto Cleanup;
2122
2123 /* Initialize the comms objects */
2124 Status = FltpSetupCommunicationObjects(DriverObject);
2125 if (!NT_SUCCESS(Status)) goto Cleanup;
2126
2127 /* Register for notifications when a new file system is loaded. This also enumerates any existing file systems */
2128 Status = IoRegisterFsRegistrationChange(DriverObject, FltpFsNotification);
2129 FLT_ASSERT(Status != STATUS_DEVICE_ALREADY_ATTACHED); // Windows checks for this, I'm not sure how it can happen. Needs investigation??
2130 if (!NT_SUCCESS(Status)) goto Cleanup;
2131
2132 /* IoRegisterFsRegistrationChange isn't notified about the raw file systems, so we attach to them manually */
2133 RtlInitUnicodeString(&ObjectName, L"\\Device\\RawDisk");
2134 Status = IoGetDeviceObjectPointer(&ObjectName,
2135 FILE_READ_ATTRIBUTES,
2136 &RawFileObject,
2137 &RawDeviceObject);
2138 if (NT_SUCCESS(Status))
2139 {
2140 FltpFsNotification(RawDeviceObject, TRUE);
2141 ObfDereferenceObject(RawFileObject);
2142 }
2143
2144 RtlInitUnicodeString(&ObjectName, L"\\Device\\RawCdRom");
2145 Status = IoGetDeviceObjectPointer(&ObjectName,
2146 FILE_READ_ATTRIBUTES,
2147 &RawFileObject,
2148 &RawDeviceObject);
2149 if (NT_SUCCESS(Status))
2150 {
2151 FltpFsNotification(RawDeviceObject, TRUE);
2152 ObfDereferenceObject(RawFileObject);
2153 }
2154
2155 /* We're done, clear the initializing flag */
2156 ClearFlag(DeviceObject->Flags, DO_DEVICE_INITIALIZING);
2157 Status = STATUS_SUCCESS;
2158
2159 Cleanup:
2160
2161 if (!NT_SUCCESS(Status))
2162 {
2163 if (DriverData.FastIoDispatch)
2164 {
2165 DriverObject->FastIoDispatch = NULL;
2166 ExFreePoolWithTag(DriverData.FastIoDispatch, FM_TAG_DISPATCH_TABLE);
2167 }
2168
2169 IoDeleteSymbolicLink(&SymLink);
2170
2171 if (DeviceObject)
2172 IoDeleteDevice(DeviceObject);
2173
2174 if (DriverData.ServiceKey.Buffer)
2175 ExFreePoolWithTag(DriverData.ServiceKey.Buffer, FM_TAG_REGISTRY_DATA);
2176 }
2177
2178 return Status;
2179 }
2180
2181
2182 static
2183 NTSTATUS
2184 SetupDispatchAndCallbacksTables(_In_ PDRIVER_OBJECT DriverObject)
2185 {
2186 PFAST_IO_DISPATCH FastIoDispatch;
2187 FS_FILTER_CALLBACKS Callbacks;
2188 ULONG i;
2189
2190 /* Plug all the IRPs */
2191 for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
2192 {
2193 DriverObject->MajorFunction[i] = FltpDispatch;
2194 }
2195
2196 /* Override the ones we're interested in */
2197 DriverObject->MajorFunction[IRP_MJ_CREATE] = FltpCreate;
2198 DriverObject->MajorFunction[IRP_MJ_CREATE_NAMED_PIPE] = FltpCreate;
2199 DriverObject->MajorFunction[IRP_MJ_CREATE_MAILSLOT] = FltpCreate;
2200 DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = FltpFsControl;
2201 DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = FltpDeviceControl;
2202
2203 /* The FastIo dispatch table is stored in the pool along with a tag */
2204 FastIoDispatch = ExAllocatePoolWithTag(NonPagedPool, sizeof(FAST_IO_DISPATCH), FM_TAG_DISPATCH_TABLE);
2205 if (FastIoDispatch == NULL) return STATUS_INSUFFICIENT_RESOURCES;
2206
2207 /* Fill out the FastIo table */
2208 RtlZeroMemory(FastIoDispatch, sizeof(FAST_IO_DISPATCH));
2209 FastIoDispatch->SizeOfFastIoDispatch = sizeof(FAST_IO_DISPATCH);
2210 FastIoDispatch->FastIoCheckIfPossible = FltpFastIoCheckIfPossible;
2211 FastIoDispatch->FastIoRead = FltpFastIoRead;
2212 FastIoDispatch->FastIoWrite = FltpFastIoWrite;
2213 FastIoDispatch->FastIoQueryBasicInfo = FltpFastIoQueryBasicInfo;
2214 FastIoDispatch->FastIoQueryStandardInfo = FltpFastIoQueryStandardInfo;
2215 FastIoDispatch->FastIoLock = FltpFastIoLock;
2216 FastIoDispatch->FastIoUnlockSingle = FltpFastIoUnlockSingle;
2217 FastIoDispatch->FastIoUnlockAll = FltpFastIoUnlockAll;
2218 FastIoDispatch->FastIoUnlockAllByKey = FltpFastIoUnlockAllByKey;
2219 FastIoDispatch->FastIoDeviceControl = FltpFastIoDeviceControl;
2220 FastIoDispatch->FastIoDetachDevice = FltpFastIoDetachDevice;
2221 FastIoDispatch->FastIoQueryNetworkOpenInfo = FltpFastIoQueryNetworkOpenInfo;
2222 FastIoDispatch->MdlRead = FltpFastIoMdlRead;
2223 FastIoDispatch->MdlReadComplete = FltpFastIoMdlReadComplete;
2224 FastIoDispatch->PrepareMdlWrite = FltpFastIoPrepareMdlWrite;
2225 FastIoDispatch->MdlWriteComplete = FltpFastIoMdlWriteComplete;
2226 FastIoDispatch->FastIoReadCompressed = FltpFastIoReadCompressed;
2227 FastIoDispatch->FastIoWriteCompressed = FltpFastIoWriteCompressed;
2228 FastIoDispatch->MdlReadCompleteCompressed = FltpFastIoMdlReadCompleteCompressed;
2229 FastIoDispatch->MdlWriteCompleteCompressed = FltpFastIoMdlWriteCompleteCompressed;
2230 FastIoDispatch->FastIoQueryOpen = FltpFastIoQueryOpen;
2231
2232 /* Store the FastIo table for internal and our access */
2233 DriverObject->FastIoDispatch = FastIoDispatch;
2234 DriverData.FastIoDispatch = FastIoDispatch;
2235
2236 /* Initialize the callback table */
2237 Callbacks.SizeOfFsFilterCallbacks = sizeof(FS_FILTER_CALLBACKS);
2238 Callbacks.PreAcquireForSectionSynchronization = FltpPreFsFilterOperation;
2239 Callbacks.PostAcquireForSectionSynchronization = FltpPostFsFilterOperation;
2240 Callbacks.PreReleaseForSectionSynchronization = FltpPreFsFilterOperation;
2241 Callbacks.PostReleaseForSectionSynchronization = FltpPostFsFilterOperation;
2242 Callbacks.PreAcquireForCcFlush = FltpPreFsFilterOperation;
2243 Callbacks.PostAcquireForCcFlush = FltpPostFsFilterOperation;
2244 Callbacks.PreReleaseForCcFlush = FltpPreFsFilterOperation;
2245 Callbacks.PostReleaseForCcFlush = FltpPostFsFilterOperation;
2246 Callbacks.PreAcquireForModifiedPageWriter = FltpPreFsFilterOperation;
2247 Callbacks.PostAcquireForModifiedPageWriter = FltpPostFsFilterOperation;
2248 Callbacks.PreReleaseForModifiedPageWriter = FltpPreFsFilterOperation;
2249 Callbacks.PostReleaseForModifiedPageWriter = FltpPostFsFilterOperation;
2250
2251 /* Register our callbacks */
2252 return FsRtlRegisterFileSystemFilterCallbacks(DriverObject, &Callbacks);
2253 }