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