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 } 1928