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