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