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