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