1 /* 2 * COPYRIGHT: See COPYRIGHT.TXT 3 * PROJECT: Ext2 File System Driver for WinNT/2K/XP 4 * FILE: fastio.c 5 * PROGRAMMER: Matt Wu <mattwu@163.com> 6 * HOMEPAGE: http://www.ext2fsd.com 7 * UPDATE HISTORY: 8 */ 9 10 /* INCLUDES *****************************************************************/ 11 12 #include "ext2fs.h" 13 14 /* GLOBALS ***************************************************************/ 15 16 extern PEXT2_GLOBAL Ext2Global; 17 18 /* DEFINITIONS *************************************************************/ 19 20 #define FASTIO_DEBUG_LEVEL DL_NVR 21 22 23 #ifdef ALLOC_PRAGMA 24 25 #pragma alloc_text(PAGE, Ext2FastIoRead) 26 #pragma alloc_text(PAGE, Ext2FastIoWrite) 27 #pragma alloc_text(PAGE, Ext2FastIoCheckIfPossible) 28 #pragma alloc_text(PAGE, Ext2FastIoQueryBasicInfo) 29 #pragma alloc_text(PAGE, Ext2FastIoQueryStandardInfo) 30 #pragma alloc_text(PAGE, Ext2FastIoQueryNetworkOpenInfo) 31 #pragma alloc_text(PAGE, Ext2FastIoLock) 32 #pragma alloc_text(PAGE, Ext2FastIoUnlockSingle) 33 #pragma alloc_text(PAGE, Ext2FastIoUnlockAll) 34 #pragma alloc_text(PAGE, Ext2FastIoUnlockAll) 35 #endif 36 37 FAST_IO_POSSIBLE 38 Ext2IsFastIoPossible( 39 IN PEXT2_FCB Fcb 40 ) 41 { 42 FAST_IO_POSSIBLE IsPossible = FastIoIsNotPossible; 43 44 if (!Fcb || !FsRtlOplockIsFastIoPossible(&Fcb->Oplock)) 45 return IsPossible; 46 47 IsPossible = FastIoIsQuestionable; 48 49 if (!FsRtlAreThereCurrentFileLocks(&Fcb->FileLockAnchor)) { 50 if (!IsVcbReadOnly(Fcb->Vcb) && !FlagOn(Fcb->Vcb->Flags, VCB_VOLUME_LOCKED)) { 51 IsPossible = FastIoIsPossible; 52 } 53 } 54 55 return IsPossible; 56 } 57 58 59 BOOLEAN NTAPI 60 Ext2FastIoCheckIfPossible ( 61 IN PFILE_OBJECT FileObject, 62 IN PLARGE_INTEGER FileOffset, 63 IN ULONG Length, 64 IN BOOLEAN Wait, 65 IN ULONG LockKey, 66 IN BOOLEAN CheckForReadOperation, 67 OUT PIO_STATUS_BLOCK IoStatus, 68 IN PDEVICE_OBJECT DeviceObject 69 ) 70 { 71 BOOLEAN bPossible = FastIoIsNotPossible; 72 PEXT2_FCB Fcb; 73 PEXT2_CCB Ccb; 74 LARGE_INTEGER lLength; 75 76 lLength.QuadPart = Length; 77 78 _SEH2_TRY { 79 80 FsRtlEnterFileSystem(); 81 82 _SEH2_TRY { 83 84 if (IsExt2FsDevice(DeviceObject)) { 85 _SEH2_LEAVE; 86 } 87 88 Fcb = (PEXT2_FCB) FileObject->FsContext; 89 if (Fcb == NULL || Fcb->Identifier.Type == EXT2VCB) { 90 _SEH2_LEAVE; 91 } 92 93 ASSERT((Fcb->Identifier.Type == EXT2FCB) && 94 (Fcb->Identifier.Size == sizeof(EXT2_FCB))); 95 96 if (IsDirectory(Fcb)) { 97 _SEH2_LEAVE; 98 } 99 100 Ccb = (PEXT2_CCB) FileObject->FsContext2; 101 if (Ccb == NULL) { 102 _SEH2_LEAVE; 103 } 104 105 if (CheckForReadOperation) { 106 107 bPossible = FsRtlFastCheckLockForRead( 108 &Fcb->FileLockAnchor, 109 FileOffset, 110 &lLength, 111 LockKey, 112 FileObject, 113 PsGetCurrentProcess()); 114 115 } else { 116 117 if (!IsVcbReadOnly(Fcb->Vcb)) { 118 bPossible = FsRtlFastCheckLockForWrite( 119 &Fcb->FileLockAnchor, 120 FileOffset, 121 &lLength, 122 LockKey, 123 FileObject, 124 PsGetCurrentProcess()); 125 } 126 } 127 128 #if EXT2_DEBUG 129 DEBUG(DL_INF, ("Ext2FastIIOCheckPossible: %s %s %wZ\n", 130 Ext2GetCurrentProcessName(), 131 "FASTIO_CHECK_IF_POSSIBLE", 132 &Fcb->Mcb->FullName 133 )); 134 135 DEBUG(DL_INF, ( 136 "Ext2FastIIOCheckPossible: Offset: %I64xg Length: %xh Key: %u %s %s\n", 137 FileOffset->QuadPart, 138 Length, 139 LockKey, 140 (CheckForReadOperation ? "CheckForReadOperation:" : 141 "CheckForWriteOperation:"), 142 (bPossible ? "Succeeded" : "Failed"))); 143 #endif 144 145 } _SEH2_EXCEPT (EXCEPTION_EXECUTE_HANDLER) { 146 bPossible = FastIoIsNotPossible; 147 } _SEH2_END; 148 149 } _SEH2_FINALLY { 150 151 FsRtlExitFileSystem(); 152 } _SEH2_END; 153 154 return bPossible; 155 } 156 157 158 BOOLEAN NTAPI 159 Ext2FastIoRead (IN PFILE_OBJECT FileObject, 160 IN PLARGE_INTEGER FileOffset, 161 IN ULONG Length, 162 IN BOOLEAN Wait, 163 IN ULONG LockKey, 164 OUT PVOID Buffer, 165 OUT PIO_STATUS_BLOCK IoStatus, 166 IN PDEVICE_OBJECT DeviceObject) 167 { 168 PEXT2_FCB Fcb; 169 BOOLEAN Status = FALSE; 170 171 Fcb = (PEXT2_FCB) FileObject->FsContext; 172 if (Fcb == NULL) { 173 return FALSE; 174 } 175 176 ASSERT((Fcb->Identifier.Type == EXT2FCB) && 177 (Fcb->Identifier.Size == sizeof(EXT2_FCB))); 178 179 Status = FsRtlCopyRead ( 180 FileObject, FileOffset, Length, Wait, 181 LockKey, Buffer, IoStatus, DeviceObject); 182 183 DEBUG(DL_IO, ("Ext2FastIoRead: %wZ Offset: %I64xh Length: %xh Key: %u Status: %d\n", 184 &Fcb->Mcb->ShortName, FileOffset->QuadPart, Length, LockKey, Status)); 185 186 return Status; 187 } 188 189 BOOLEAN NTAPI 190 Ext2FastIoWrite ( 191 IN PFILE_OBJECT FileObject, 192 IN PLARGE_INTEGER FileOffset, 193 IN ULONG Length, 194 IN BOOLEAN Wait, 195 IN ULONG LockKey, 196 OUT PVOID Buffer, 197 OUT PIO_STATUS_BLOCK IoStatus, 198 IN PDEVICE_OBJECT DeviceObject) 199 { 200 PEXT2_FCB Fcb = NULL; 201 BOOLEAN Status = FALSE; 202 BOOLEAN Locked = FALSE; 203 204 Fcb = (PEXT2_FCB) FileObject->FsContext; 205 if (Fcb == NULL) 206 return FALSE; 207 208 _SEH2_TRY { 209 210 FsRtlEnterFileSystem(); 211 212 ASSERT((Fcb->Identifier.Type == EXT2FCB) && 213 (Fcb->Identifier.Size == sizeof(EXT2_FCB))); 214 215 if (IsVcbReadOnly(Fcb->Vcb)) { 216 _SEH2_LEAVE; 217 } 218 219 if (!ExAcquireResourceSharedLite(Fcb->Header.Resource, Wait)) { 220 _SEH2_LEAVE; 221 } 222 Locked = TRUE; 223 224 if (IsWritingToEof(*FileOffset) || 225 Fcb->Header.ValidDataLength.QuadPart < FileOffset->QuadPart + Length || 226 Fcb->Header.FileSize.QuadPart < FileOffset->QuadPart + Length ) { 227 Status = FALSE; 228 _SEH2_LEAVE; 229 } 230 231 if (Locked) { 232 ExReleaseResourceLite(Fcb->Header.Resource); 233 Locked = FALSE; 234 } 235 236 Status = FsRtlCopyWrite(FileObject, FileOffset, Length, Wait, 237 LockKey, Buffer, IoStatus, DeviceObject); 238 if (Status) { 239 if (IoStatus) 240 Length = (ULONG)IoStatus->Information; 241 } 242 243 } _SEH2_FINALLY { 244 245 if (Locked) { 246 ExReleaseResourceLite(Fcb->Header.Resource); 247 } 248 249 FsRtlExitFileSystem(); 250 } _SEH2_END; 251 252 DEBUG(DL_IO, ("Ext2FastIoWrite: %wZ Offset: %I64xh Length: %xh Key: %xh Status=%d\n", 253 &Fcb->Mcb->ShortName, FileOffset->QuadPart, Length, LockKey, Status)); 254 255 return Status; 256 } 257 258 BOOLEAN NTAPI 259 Ext2FastIoQueryBasicInfo ( 260 IN PFILE_OBJECT FileObject, 261 IN BOOLEAN Wait, 262 OUT PFILE_BASIC_INFORMATION Buffer, 263 OUT PIO_STATUS_BLOCK IoStatus, 264 IN PDEVICE_OBJECT DeviceObject) 265 { 266 PEXT2_FCB Fcb = NULL; 267 PEXT2_CCB Ccb = NULL; 268 PEXT2_MCB Mcb = NULL; 269 BOOLEAN Status = FALSE; 270 BOOLEAN FcbMainResourceAcquired = FALSE; 271 272 _SEH2_TRY { 273 274 FsRtlEnterFileSystem(); 275 276 _SEH2_TRY { 277 278 if (IsExt2FsDevice(DeviceObject)) { 279 IoStatus->Status = STATUS_INVALID_DEVICE_REQUEST; 280 _SEH2_LEAVE; 281 } 282 283 Fcb = (PEXT2_FCB) FileObject->FsContext; 284 if (Fcb == NULL || Fcb->Identifier.Type == EXT2VCB) { 285 IoStatus->Status = STATUS_INVALID_PARAMETER; 286 _SEH2_LEAVE; 287 } 288 Ccb = (PEXT2_CCB) FileObject->FsContext2; 289 Mcb = Fcb->Mcb; 290 ASSERT((Fcb->Identifier.Type == EXT2FCB) && 291 (Fcb->Identifier.Size == sizeof(EXT2_FCB))); 292 #if EXT2_DEBUG 293 DEBUG(DL_INF, ( 294 "Ext2FastIoQueryBasicInfo: %s %s %wZ\n", 295 Ext2GetCurrentProcessName(), 296 "FASTIO_QUERY_BASIC_INFO", 297 &Fcb->Mcb->FullName 298 )); 299 #endif 300 if (!IsFlagOn(Fcb->Flags, FCB_PAGE_FILE)) { 301 if (!ExAcquireResourceSharedLite( 302 &Fcb->MainResource, 303 Wait)) { 304 _SEH2_LEAVE; 305 } 306 FcbMainResourceAcquired = TRUE; 307 } 308 309 RtlZeroMemory(Buffer, sizeof(FILE_BASIC_INFORMATION)); 310 311 /* 312 typedef struct _FILE_BASIC_INFORMATION { 313 LARGE_INTEGER CreationTime; 314 LARGE_INTEGER LastAccessTime; 315 LARGE_INTEGER LastWriteTime; 316 LARGE_INTEGER ChangeTime; 317 ULONG FileAttributes; 318 } FILE_BASIC_INFORMATION, *PFILE_BASIC_INFORMATION; 319 */ 320 321 Buffer->CreationTime = Mcb->CreationTime; 322 Buffer->LastAccessTime = Mcb->LastAccessTime; 323 Buffer->LastWriteTime = Mcb->LastWriteTime; 324 Buffer->ChangeTime = Mcb->ChangeTime; 325 Buffer->FileAttributes = Mcb->FileAttr; 326 if (Buffer->FileAttributes == 0) { 327 Buffer->FileAttributes = FILE_ATTRIBUTE_NORMAL; 328 } 329 330 IoStatus->Information = sizeof(FILE_BASIC_INFORMATION); 331 IoStatus->Status = STATUS_SUCCESS; 332 333 Status = TRUE; 334 335 } _SEH2_EXCEPT (EXCEPTION_EXECUTE_HANDLER) { 336 IoStatus->Status = _SEH2_GetExceptionCode(); 337 } _SEH2_END; 338 339 } _SEH2_FINALLY { 340 341 if (FcbMainResourceAcquired) { 342 ExReleaseResourceLite(&Fcb->MainResource); 343 } 344 345 FsRtlExitFileSystem(); 346 } _SEH2_END; 347 348 #if EXT2_DEBUG 349 350 if (Status == FALSE) { 351 352 DEBUG(DL_ERR, ("Ext2FastIoQueryBasicInfo: %s %s Status: FALSE ***\n", 353 Ext2GetCurrentProcessName(), 354 "FASTIO_QUERY_BASIC_INFO")); 355 356 } else if (IoStatus->Status != STATUS_SUCCESS) { 357 358 DEBUG(DL_ERR, ( 359 "Ext2FastIoQueryBasicInfo: %s %s Status: %#x ***\n", 360 Ext2FastIoQueryBasicInfo, 361 "FASTIO_QUERY_BASIC_INFO", 362 IoStatus->Status 363 )); 364 } 365 #endif 366 367 return Status; 368 } 369 370 BOOLEAN NTAPI 371 Ext2FastIoQueryStandardInfo ( 372 IN PFILE_OBJECT FileObject, 373 IN BOOLEAN Wait, 374 OUT PFILE_STANDARD_INFORMATION Buffer, 375 OUT PIO_STATUS_BLOCK IoStatus, 376 IN PDEVICE_OBJECT DeviceObject 377 ) 378 { 379 380 BOOLEAN Status = FALSE; 381 PEXT2_VCB Vcb = NULL; 382 PEXT2_FCB Fcb = NULL; 383 BOOLEAN FcbMainResourceAcquired = FALSE; 384 385 _SEH2_TRY { 386 387 FsRtlEnterFileSystem(); 388 389 _SEH2_TRY { 390 391 if (IsExt2FsDevice(DeviceObject)) { 392 IoStatus->Status = STATUS_INVALID_DEVICE_REQUEST; 393 _SEH2_LEAVE; 394 } 395 396 Fcb = (PEXT2_FCB) FileObject->FsContext; 397 if (Fcb == NULL || Fcb->Identifier.Type == EXT2VCB) { 398 IoStatus->Status = STATUS_INVALID_PARAMETER; 399 _SEH2_LEAVE; 400 } 401 402 ASSERT((Fcb->Identifier.Type == EXT2FCB) && 403 (Fcb->Identifier.Size == sizeof(EXT2_FCB))); 404 405 #if EXT2_DEBUG 406 DEBUG(DL_INF, ( 407 "Ext2FastIoQueryStandardInfo: %s %s %wZ\n", 408 Ext2GetCurrentProcessName(), 409 "FASTIO_QUERY_STANDARD_INFO", 410 &Fcb->Mcb->FullName )); 411 #endif 412 Vcb = Fcb->Vcb; 413 414 if (!IsFlagOn(Fcb->Flags, FCB_PAGE_FILE)) { 415 if (!ExAcquireResourceSharedLite( 416 &Fcb->MainResource, 417 Wait )) { 418 _SEH2_LEAVE; 419 } 420 FcbMainResourceAcquired = TRUE; 421 } 422 423 RtlZeroMemory(Buffer, sizeof(FILE_STANDARD_INFORMATION)); 424 425 /* 426 typedef struct _FILE_STANDARD_INFORMATION { 427 LARGE_INTEGER AllocationSize; 428 LARGE_INTEGER EndOfFile; 429 ULONG NumberOfLinks; 430 BOOLEAN DeletePending; 431 BOOLEAN Directory; 432 } FILE_STANDARD_INFORMATION, *PFILE_STANDARD_INFORMATION; 433 */ 434 435 Buffer->NumberOfLinks = Fcb->Inode->i_nlink; 436 Buffer->DeletePending = IsFlagOn(Fcb->Flags, FCB_DELETE_PENDING); 437 438 if (IsDirectory(Fcb)) { 439 Buffer->Directory = IsDirectory(Fcb); 440 Buffer->AllocationSize.QuadPart = 0; 441 Buffer->EndOfFile.QuadPart = 0; 442 } else { 443 Buffer->Directory = FALSE; 444 Buffer->AllocationSize = Fcb->Header.AllocationSize; 445 Buffer->EndOfFile = Fcb->Header.FileSize; 446 } 447 448 IoStatus->Information = sizeof(FILE_STANDARD_INFORMATION); 449 IoStatus->Status = STATUS_SUCCESS; 450 #if EXT2_DEBUG 451 DEBUG(DL_INF, ( "Ext2FastIoQueryStandInfo: AllocatieonSize = %I64xh FileSize = %I64xh\n", 452 Buffer->AllocationSize.QuadPart, Buffer->EndOfFile.QuadPart)); 453 #endif 454 Status = TRUE; 455 456 } _SEH2_EXCEPT (EXCEPTION_EXECUTE_HANDLER) { 457 IoStatus->Status = _SEH2_GetExceptionCode(); 458 } _SEH2_END; 459 460 } _SEH2_FINALLY { 461 462 if (FcbMainResourceAcquired) { 463 ExReleaseResourceLite(&Fcb->MainResource); 464 } 465 466 FsRtlExitFileSystem(); 467 } _SEH2_END; 468 469 #if EXT2_DEBUG 470 if (Status == FALSE) { 471 DEBUG(DL_INF, ( 472 "Ext2FastIoQueryStandardInfo: %s %s Status: FALSE ***\n", 473 Ext2GetCurrentProcessName(), 474 "FASTIO_QUERY_STANDARD_INFO" )); 475 } else if (IoStatus->Status != STATUS_SUCCESS) { 476 DEBUG(DL_INF, ( 477 "Ext2FastIoQueryStandardInfo: %s %s Status: %#x ***\n", 478 Ext2GetCurrentProcessName(), 479 "FASTIO_QUERY_STANDARD_INFO", 480 IoStatus->Status )); 481 } 482 #endif 483 484 return Status; 485 } 486 487 BOOLEAN NTAPI 488 Ext2FastIoLock ( 489 IN PFILE_OBJECT FileObject, 490 IN PLARGE_INTEGER FileOffset, 491 IN PLARGE_INTEGER Length, 492 IN PEPROCESS Process, 493 IN ULONG Key, 494 IN BOOLEAN FailImmediately, 495 IN BOOLEAN ExclusiveLock, 496 OUT PIO_STATUS_BLOCK IoStatus, 497 IN PDEVICE_OBJECT DeviceObject 498 ) 499 { 500 BOOLEAN Status = FALSE; 501 PEXT2_FCB Fcb; 502 503 _SEH2_TRY { 504 505 FsRtlEnterFileSystem(); 506 507 _SEH2_TRY { 508 509 if (IsExt2FsDevice(DeviceObject)) { 510 IoStatus->Status = STATUS_INVALID_DEVICE_REQUEST; 511 _SEH2_LEAVE; 512 } 513 514 Fcb = (PEXT2_FCB) FileObject->FsContext; 515 if (Fcb == NULL || Fcb->Identifier.Type == EXT2VCB) { 516 IoStatus->Status = STATUS_INVALID_PARAMETER; 517 _SEH2_LEAVE; 518 } 519 520 ASSERT((Fcb->Identifier.Type == EXT2FCB) && 521 (Fcb->Identifier.Size == sizeof(EXT2_FCB))); 522 523 if (IsDirectory(Fcb)) { 524 DbgBreak(); 525 IoStatus->Status = STATUS_INVALID_PARAMETER; 526 _SEH2_LEAVE; 527 } 528 #if EXT2_DEBUG 529 DEBUG(DL_INF, ( 530 "Ext2FastIoLock: %s %s %wZ\n", 531 Ext2GetCurrentProcessName(), 532 "FASTIO_LOCK", 533 &Fcb->Mcb->FullName )); 534 535 DEBUG(DL_INF, ( 536 "Ext2FastIoLock: Offset: %I64xh Length: %I64xh Key: %u %s%s\n", 537 FileOffset->QuadPart, 538 Length->QuadPart, 539 Key, 540 (FailImmediately ? "FailImmediately " : ""), 541 (ExclusiveLock ? "ExclusiveLock " : "") )); 542 #endif 543 544 if (!FsRtlOplockIsFastIoPossible(&Fcb->Oplock)) { 545 _SEH2_LEAVE; 546 } 547 548 Status = FsRtlFastLock( 549 &Fcb->FileLockAnchor, 550 FileObject, 551 FileOffset, 552 Length, 553 Process, 554 Key, 555 FailImmediately, 556 ExclusiveLock, 557 IoStatus, 558 NULL, 559 FALSE); 560 561 if (Status) { 562 Fcb->Header.IsFastIoPossible = Ext2IsFastIoPossible(Fcb); 563 } 564 565 } _SEH2_EXCEPT (EXCEPTION_EXECUTE_HANDLER) { 566 IoStatus->Status = _SEH2_GetExceptionCode(); 567 } _SEH2_END; 568 569 } _SEH2_FINALLY { 570 571 FsRtlExitFileSystem(); 572 } _SEH2_END; 573 574 #if EXT2_DEBUG 575 if (Status == FALSE) { 576 DEBUG(DL_ERR, ( 577 "Ext2FastIoLock: %s %s *** Status: FALSE ***\n", 578 (PUCHAR) Process + ProcessNameOffset, 579 "FASTIO_LOCK" 580 )); 581 } else if (IoStatus->Status != STATUS_SUCCESS) { 582 DEBUG(DL_ERR, ( 583 "Ext2FastIoLock: %s %s *** Status: %s (%#x) ***\n", 584 (PUCHAR) Process + ProcessNameOffset, 585 "FASTIO_LOCK", 586 Ext2NtStatusToString(IoStatus->Status), 587 IoStatus->Status 588 )); 589 } 590 #endif 591 592 return Status; 593 } 594 595 BOOLEAN NTAPI 596 Ext2FastIoUnlockSingle ( 597 IN PFILE_OBJECT FileObject, 598 IN PLARGE_INTEGER FileOffset, 599 IN PLARGE_INTEGER Length, 600 IN PEPROCESS Process, 601 IN ULONG Key, 602 OUT PIO_STATUS_BLOCK IoStatus, 603 IN PDEVICE_OBJECT DeviceObject 604 ) 605 { 606 BOOLEAN Status = FALSE; 607 PEXT2_FCB Fcb; 608 609 _SEH2_TRY { 610 611 FsRtlEnterFileSystem(); 612 613 _SEH2_TRY { 614 615 if (IsExt2FsDevice(DeviceObject)) { 616 IoStatus->Status = STATUS_INVALID_DEVICE_REQUEST; 617 _SEH2_LEAVE; 618 } 619 620 Fcb = (PEXT2_FCB) FileObject->FsContext; 621 if (Fcb == NULL || Fcb->Identifier.Type == EXT2VCB) { 622 DbgBreak(); 623 IoStatus->Status = STATUS_INVALID_PARAMETER; 624 _SEH2_LEAVE; 625 } 626 627 ASSERT((Fcb->Identifier.Type == EXT2FCB) && 628 (Fcb->Identifier.Size == sizeof(EXT2_FCB))); 629 630 if (IsDirectory(Fcb)) { 631 DbgBreak(); 632 IoStatus->Status = STATUS_INVALID_PARAMETER; 633 _SEH2_LEAVE; 634 } 635 636 #if EXT2_DEBUG 637 DEBUG(DL_INF, ( 638 "Ext2FastIoUnlockSingle: %s %s %wZ\n", 639 (PUCHAR) Process + ProcessNameOffset, 640 "FASTIO_UNLOCK_SINGLE", 641 &Fcb->Mcb->FullName )); 642 643 DEBUG(DL_INF, ( 644 "Ext2FastIoUnlockSingle: Offset: %I64xh Length: %I64xh Key: %u\n", 645 FileOffset->QuadPart, 646 Length->QuadPart, 647 Key )); 648 #endif 649 650 if (!FsRtlOplockIsFastIoPossible(&Fcb->Oplock)) { 651 _SEH2_LEAVE; 652 } 653 654 IoStatus->Status = FsRtlFastUnlockSingle( 655 &Fcb->FileLockAnchor, 656 FileObject, 657 FileOffset, 658 Length, 659 Process, 660 Key, 661 NULL, 662 FALSE); 663 664 IoStatus->Information = 0; 665 Status = TRUE; 666 667 Fcb->Header.IsFastIoPossible = Ext2IsFastIoPossible(Fcb); 668 669 } _SEH2_EXCEPT (EXCEPTION_EXECUTE_HANDLER) { 670 IoStatus->Status = _SEH2_GetExceptionCode(); 671 } _SEH2_END; 672 673 } _SEH2_FINALLY { 674 675 FsRtlExitFileSystem(); 676 } _SEH2_END; 677 678 #if EXT2_DEBUG 679 if (Status == FALSE) { 680 681 DEBUG(DL_ERR, ( 682 "Ext2FastIoUnlockSingle: %s %s *** Status: FALSE ***\n", 683 (PUCHAR) Process + ProcessNameOffset, 684 "FASTIO_UNLOCK_SINGLE" )); 685 } else if (IoStatus->Status != STATUS_SUCCESS) { 686 DEBUG(DL_ERR, ( 687 "Ext2FastIoUnlockSingle: %s %s *** Status: %s (%#x) ***\n", 688 (PUCHAR) Process + ProcessNameOffset, 689 "FASTIO_UNLOCK_SINGLE", 690 Ext2NtStatusToString(IoStatus->Status), 691 IoStatus->Status )); 692 } 693 #endif 694 695 return Status; 696 } 697 698 BOOLEAN NTAPI 699 Ext2FastIoUnlockAll ( 700 IN PFILE_OBJECT FileObject, 701 IN PEPROCESS Process, 702 OUT PIO_STATUS_BLOCK IoStatus, 703 IN PDEVICE_OBJECT DeviceObject) 704 { 705 BOOLEAN Status = FALSE; 706 PEXT2_FCB Fcb; 707 708 _SEH2_TRY { 709 710 FsRtlEnterFileSystem(); 711 712 _SEH2_TRY { 713 714 if (IsExt2FsDevice(DeviceObject)) { 715 IoStatus->Status = STATUS_INVALID_DEVICE_REQUEST; 716 _SEH2_LEAVE; 717 } 718 719 Fcb = (PEXT2_FCB) FileObject->FsContext; 720 if (Fcb == NULL || Fcb->Identifier.Type == EXT2VCB) { 721 DbgBreak(); 722 IoStatus->Status = STATUS_INVALID_PARAMETER; 723 _SEH2_LEAVE; 724 } 725 726 ASSERT((Fcb->Identifier.Type == EXT2FCB) && 727 (Fcb->Identifier.Size == sizeof(EXT2_FCB))); 728 729 if (IsDirectory(Fcb)) { 730 DbgBreak(); 731 IoStatus->Status = STATUS_INVALID_PARAMETER; 732 _SEH2_LEAVE; 733 } 734 #if EXT2_DEBUG 735 DEBUG(DL_INF, ( 736 "Ext2FastIoUnlockSingle: %s %s %wZ\n", 737 (PUCHAR) Process + ProcessNameOffset, 738 "FASTIO_UNLOCK_ALL", 739 &Fcb->Mcb->FullName 740 )); 741 #endif 742 743 if (!FsRtlOplockIsFastIoPossible(&Fcb->Oplock)) { 744 _SEH2_LEAVE; 745 } 746 747 IoStatus->Status = FsRtlFastUnlockAll( 748 &Fcb->FileLockAnchor, 749 FileObject, 750 Process, 751 NULL ); 752 753 IoStatus->Information = 0; 754 Status = TRUE; 755 756 Fcb->Header.IsFastIoPossible = Ext2IsFastIoPossible(Fcb); 757 758 } _SEH2_EXCEPT (EXCEPTION_EXECUTE_HANDLER) { 759 IoStatus->Status = _SEH2_GetExceptionCode(); 760 } _SEH2_END; 761 762 } _SEH2_FINALLY { 763 764 FsRtlExitFileSystem(); 765 } _SEH2_END; 766 767 #if EXT2_DEBUG 768 if (Status == FALSE) { 769 770 DEBUG(DL_ERR, ( 771 "Ext2FastIoUnlockSingle: %s %s *** Status: FALSE ***\n", 772 (PUCHAR) Process + ProcessNameOffset, 773 "FASTIO_UNLOCK_ALL" 774 )); 775 } else if (IoStatus->Status != STATUS_SUCCESS) { 776 DEBUG(DL_ERR, ( 777 "Ext2FastIoUnlockSingle: %s %s *** Status: %s (%#x) ***\n", 778 (PUCHAR) Process + ProcessNameOffset, 779 "FASTIO_UNLOCK_ALL", 780 Ext2NtStatusToString(IoStatus->Status), 781 IoStatus->Status 782 )); 783 } 784 #endif 785 786 return Status; 787 } 788 789 BOOLEAN NTAPI 790 Ext2FastIoUnlockAllByKey ( 791 IN PFILE_OBJECT FileObject, 792 #ifdef __REACTOS__ 793 IN PVOID Process, 794 #else 795 IN PEPROCESS Process, 796 #endif 797 IN ULONG Key, 798 OUT PIO_STATUS_BLOCK IoStatus, 799 IN PDEVICE_OBJECT DeviceObject 800 ) 801 { 802 BOOLEAN Status = FALSE; 803 PEXT2_FCB Fcb; 804 805 _SEH2_TRY { 806 807 FsRtlEnterFileSystem(); 808 809 _SEH2_TRY { 810 811 if (IsExt2FsDevice(DeviceObject)) { 812 IoStatus->Status = STATUS_INVALID_DEVICE_REQUEST; 813 _SEH2_LEAVE; 814 } 815 816 Fcb = (PEXT2_FCB) FileObject->FsContext; 817 if (Fcb == NULL || Fcb->Identifier.Type == EXT2VCB) { 818 DbgBreak(); 819 IoStatus->Status = STATUS_INVALID_PARAMETER; 820 _SEH2_LEAVE; 821 } 822 823 ASSERT((Fcb->Identifier.Type == EXT2FCB) && 824 (Fcb->Identifier.Size == sizeof(EXT2_FCB))); 825 826 if (IsDirectory(Fcb)) { 827 DbgBreak(); 828 IoStatus->Status = STATUS_INVALID_PARAMETER; 829 _SEH2_LEAVE; 830 } 831 832 #if EXT2_DEBUG 833 DEBUG(DL_INF, ( 834 "Ext2FastIoUnlockAllByKey: %s %s %wZ\n", 835 (PUCHAR) Process + ProcessNameOffset, 836 "FASTIO_UNLOCK_ALL_BY_KEY", 837 &Fcb->Mcb->FullName 838 )); 839 840 DEBUG(DL_INF, ( 841 "Ext2FastIoUnlockAllByKey: Key: %u\n", 842 Key 843 )); 844 #endif 845 846 if (!FsRtlOplockIsFastIoPossible(&Fcb->Oplock)) { 847 _SEH2_LEAVE; 848 } 849 850 IoStatus->Status = FsRtlFastUnlockAllByKey( 851 &Fcb->FileLockAnchor, 852 FileObject, 853 Process, 854 Key, 855 NULL 856 ); 857 858 IoStatus->Information = 0; 859 Status = TRUE; 860 861 Fcb->Header.IsFastIoPossible = Ext2IsFastIoPossible(Fcb); 862 863 } _SEH2_EXCEPT (EXCEPTION_EXECUTE_HANDLER) { 864 IoStatus->Status = _SEH2_GetExceptionCode(); 865 } _SEH2_END; 866 867 } _SEH2_FINALLY { 868 869 FsRtlExitFileSystem(); 870 } _SEH2_END; 871 872 #if EXT2_DEBUG 873 if (Status == FALSE) { 874 875 DEBUG(DL_ERR, ( 876 "Ext2FastIoUnlockAllByKey: %s %s *** Status: FALSE ***\n", 877 (PUCHAR) Process + ProcessNameOffset, 878 "FASTIO_UNLOCK_ALL_BY_KEY" 879 )); 880 } else if (IoStatus->Status != STATUS_SUCCESS) { 881 882 DEBUG(DL_ERR, ( 883 "Ext2FastIoUnlockAllByKey: %s %s *** Status: %s (%#x) ***\n", 884 (PUCHAR) Process + ProcessNameOffset, 885 "FASTIO_UNLOCK_ALL_BY_KEY", 886 Ext2NtStatusToString(IoStatus->Status), 887 IoStatus->Status 888 )); 889 } 890 #endif 891 892 return Status; 893 } 894 895 896 BOOLEAN NTAPI 897 Ext2FastIoQueryNetworkOpenInfo ( 898 IN PFILE_OBJECT FileObject, 899 IN BOOLEAN Wait, 900 IN OUT PFILE_NETWORK_OPEN_INFORMATION PFNOI, 901 OUT PIO_STATUS_BLOCK IoStatus, 902 IN PDEVICE_OBJECT DeviceObject 903 ) 904 { 905 PEXT2_FCB Fcb = NULL; 906 PEXT2_CCB Ccb = NULL; 907 PEXT2_MCB Mcb = NULL; 908 909 BOOLEAN bResult = FALSE; 910 BOOLEAN FcbResourceAcquired = FALSE; 911 912 _SEH2_TRY { 913 914 FsRtlEnterFileSystem(); 915 916 if (IsExt2FsDevice(DeviceObject)) { 917 IoStatus->Status = STATUS_INVALID_DEVICE_REQUEST; 918 _SEH2_LEAVE; 919 } 920 921 Fcb = (PEXT2_FCB) FileObject->FsContext; 922 if (Fcb == NULL || Fcb->Identifier.Type == EXT2VCB) { 923 DbgBreak(); 924 IoStatus->Status = STATUS_INVALID_PARAMETER; 925 _SEH2_LEAVE; 926 } 927 928 ASSERT((Fcb->Identifier.Type == EXT2FCB) && 929 (Fcb->Identifier.Size == sizeof(EXT2_FCB))); 930 Ccb = (PEXT2_CCB) FileObject->FsContext2; 931 Mcb = Fcb->Mcb; 932 933 #if EXT2_DEBUG 934 DEBUG(DL_INF, ( 935 "%-31s %wZ\n", 936 "FASTIO_QUERY_NETWORK_OPEN_INFO", 937 &Fcb->Mcb->FullName 938 )); 939 #endif 940 941 if (!Ccb) { 942 _SEH2_LEAVE; 943 } 944 945 if (!IsFlagOn(Fcb->Flags, FCB_PAGE_FILE)) { 946 947 if (!ExAcquireResourceSharedLite( 948 &Fcb->MainResource, 949 Wait 950 )) { 951 _SEH2_LEAVE; 952 } 953 954 FcbResourceAcquired = TRUE; 955 } 956 957 if (IsDirectory(Fcb)) { 958 PFNOI->AllocationSize.QuadPart = 0; 959 PFNOI->EndOfFile.QuadPart = 0; 960 } else { 961 PFNOI->AllocationSize = Fcb->Header.AllocationSize; 962 PFNOI->EndOfFile = Fcb->Header.FileSize; 963 } 964 965 PFNOI->FileAttributes = Mcb->FileAttr; 966 if (PFNOI->FileAttributes == 0) { 967 PFNOI->FileAttributes = FILE_ATTRIBUTE_NORMAL; 968 } 969 970 PFNOI->CreationTime = Mcb->CreationTime; 971 PFNOI->LastAccessTime = Mcb->LastAccessTime; 972 PFNOI->LastWriteTime = Mcb->LastWriteTime; 973 PFNOI->ChangeTime = Mcb->ChangeTime; 974 975 bResult = TRUE; 976 977 IoStatus->Status = STATUS_SUCCESS; 978 IoStatus->Information = sizeof(FILE_NETWORK_OPEN_INFORMATION); 979 980 } _SEH2_FINALLY { 981 982 if (FcbResourceAcquired) { 983 ExReleaseResourceLite(&Fcb->MainResource); 984 } 985 986 FsRtlExitFileSystem(); 987 } _SEH2_END; 988 989 return bResult; 990 } 991 992 993 VOID NTAPI 994 Ext2AcquireForCreateSection ( 995 IN PFILE_OBJECT FileObject 996 ) 997 998 { 999 PEXT2_FCB Fcb = FileObject->FsContext; 1000 1001 if (Fcb->Header.Resource != NULL) { 1002 ExAcquireResourceExclusiveLite(Fcb->Header.Resource, TRUE); 1003 } 1004 1005 DEBUG(FASTIO_DEBUG_LEVEL, ("Ext2AcquireForCreateSection: Fcb=%p\n", Fcb)); 1006 } 1007 1008 VOID NTAPI 1009 Ext2ReleaseForCreateSection ( 1010 IN PFILE_OBJECT FileObject 1011 ) 1012 { 1013 PEXT2_FCB Fcb = FileObject->FsContext; 1014 1015 DEBUG(FASTIO_DEBUG_LEVEL, ("Ext2ReleaseForCreateSection: Fcb=%p\n", Fcb)); 1016 1017 if (Fcb->Header.Resource != NULL) { 1018 ExReleaseResourceLite(Fcb->Header.Resource); 1019 } 1020 } 1021 1022 1023 NTSTATUS NTAPI 1024 Ext2AcquireFileForModWrite ( 1025 IN PFILE_OBJECT FileObject, 1026 IN PLARGE_INTEGER EndingOffset, 1027 OUT PERESOURCE *ResourceToRelease, 1028 IN PDEVICE_OBJECT DeviceObject 1029 ) 1030 1031 { 1032 BOOLEAN ResourceAcquired = FALSE; 1033 1034 PEXT2_FCB Fcb = FileObject->FsContext; 1035 1036 *ResourceToRelease = Fcb->Header.Resource; 1037 ResourceAcquired = ExAcquireResourceExclusiveLite(*ResourceToRelease, FALSE); 1038 if (!ResourceAcquired) { 1039 *ResourceToRelease = NULL; 1040 } 1041 1042 DEBUG(FASTIO_DEBUG_LEVEL, ("Ext2AcquireFileForModWrite: Fcb=%p Acquired=%d\n", 1043 Fcb, ResourceAcquired)); 1044 1045 return (ResourceAcquired ? STATUS_SUCCESS : STATUS_CANT_WAIT); 1046 } 1047 1048 NTSTATUS NTAPI 1049 Ext2ReleaseFileForModWrite ( 1050 IN PFILE_OBJECT FileObject, 1051 IN PERESOURCE ResourceToRelease, 1052 IN PDEVICE_OBJECT DeviceObject 1053 ) 1054 { 1055 PEXT2_FCB Fcb = FileObject->FsContext; 1056 1057 DEBUG(FASTIO_DEBUG_LEVEL, ("Ext2ReleaseFileForModWrite: Fcb=%p\n", Fcb)); 1058 1059 if (ResourceToRelease != NULL) { 1060 ASSERT(ResourceToRelease == Fcb->Header.Resource); 1061 ExReleaseResourceLite(ResourceToRelease); 1062 } else { 1063 DbgBreak(); 1064 } 1065 1066 return STATUS_SUCCESS; 1067 } 1068 1069 NTSTATUS NTAPI 1070 Ext2AcquireFileForCcFlush ( 1071 IN PFILE_OBJECT FileObject, 1072 IN PDEVICE_OBJECT DeviceObject 1073 ) 1074 { 1075 PEXT2_FCB Fcb = FileObject->FsContext; 1076 1077 if (Fcb->Header.Resource != NULL) { 1078 ExAcquireResourceExclusiveLite(Fcb->Header.Resource, TRUE); 1079 } 1080 1081 DEBUG(FASTIO_DEBUG_LEVEL, ("Ext2AcquireFileForCcFlush: Fcb=%p\n", Fcb)); 1082 1083 return STATUS_SUCCESS; 1084 } 1085 1086 NTSTATUS NTAPI 1087 Ext2ReleaseFileForCcFlush ( 1088 IN PFILE_OBJECT FileObject, 1089 IN PDEVICE_OBJECT DeviceObject 1090 ) 1091 { 1092 PEXT2_FCB Fcb = FileObject->FsContext; 1093 1094 DEBUG(FASTIO_DEBUG_LEVEL, ("Ext2ReleaseFileForCcFlush: Fcb=%p\n", Fcb)); 1095 1096 if (Fcb->Header.Resource != NULL) { 1097 ExReleaseResourceLite(Fcb->Header.Resource); 1098 } 1099 1100 return STATUS_SUCCESS; 1101 } 1102 1103 1104 NTSTATUS NTAPI 1105 Ext2PreAcquireForCreateSection( 1106 IN PFS_FILTER_CALLBACK_DATA cd, 1107 OUT PVOID *cc 1108 ) 1109 { 1110 PEXT2_FCB Fcb = (PEXT2_FCB)cd->FileObject->FsContext; 1111 NTSTATUS status; 1112 1113 ASSERT(cd->Operation == FS_FILTER_ACQUIRE_FOR_SECTION_SYNCHRONIZATION); 1114 ExAcquireResourceExclusiveLite(Fcb->Header.Resource, TRUE); 1115 if (cd->Parameters.AcquireForSectionSynchronization.SyncType != SyncTypeCreateSection) { 1116 status = STATUS_FSFILTER_OP_COMPLETED_SUCCESSFULLY; 1117 } else if (Fcb->ShareAccess.Writers == 0) { 1118 status = STATUS_FILE_LOCKED_WITH_ONLY_READERS; 1119 } else { 1120 status = STATUS_FILE_LOCKED_WITH_WRITERS; 1121 } 1122 1123 return status; 1124 } 1125