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