BOOLEAN FatFastLock ( IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN PLARGE_INTEGER Length, PEPROCESS ProcessId, ULONG Key, BOOLEAN FailImmediately, BOOLEAN ExclusiveLock, OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject ) /*++ Routine Description: This is a call back routine for doing the fast lock call. Arguments: FileObject - Supplies the file object used in this operation FileOffset - Supplies the file offset used in this operation Length - Supplies the length used in this operation ProcessId - Supplies the process ID used in this operation Key - Supplies the key used in this operation FailImmediately - Indicates if the request should fail immediately if the lock cannot be granted. ExclusiveLock - Indicates if this is a request for an exclusive or shared lock IoStatus - Receives the Status if this operation is successful Return Value: BOOLEAN - TRUE if this operation completed and FALSE if caller needs to take the long route. --*/ { BOOLEAN Results; PVCB Vcb; PFCB Fcb; PCCB Ccb; DebugTrace(+1, Dbg, "FatFastLock\n", 0); // // Decode the type of file object we're being asked to process and make // sure it is only a user file open. // if (FatDecodeFileObject( FileObject, &Vcb, &Fcb, &Ccb ) != UserFileOpen) { IoStatus->Status = STATUS_INVALID_PARAMETER; IoStatus->Information = 0; DebugTrace(-1, Dbg, "FatFastLock -> TRUE (STATUS_INVALID_PARAMETER)\n", 0); return TRUE; } // // Acquire exclusive access to the Fcb this operation can always wait // FsRtlEnterFileSystem(); try { // // We check whether we can proceed // based on the state of the file oplocks. // if (!FsRtlOplockIsFastIoPossible( &(Fcb)->Specific.Fcb.Oplock )) { try_return( Results = FALSE ); } // // Now call the FsRtl routine to do the actual processing of the // Lock request // if (Results = FsRtlFastLock( &Fcb->Specific.Fcb.FileLock, FileObject, FileOffset, Length, ProcessId, Key, FailImmediately, ExclusiveLock, IoStatus, NULL, FALSE )) { // // Set the flag indicating if Fast I/O is possible // Fcb->Header.IsFastIoPossible = FatIsFastIoPossible( Fcb ); } try_exit: NOTHING; } finally { DebugUnwind( FatFastLock ); // // Release the Fcb, and return to our caller // FsRtlExitFileSystem(); DebugTrace(-1, Dbg, "FatFastLock -> %08lx\n", Results); } return Results; }
BOOLEAN NtfsFastLock ( IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN PLARGE_INTEGER Length, PEPROCESS ProcessId, ULONG Key, BOOLEAN FailImmediately, BOOLEAN ExclusiveLock, OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject ) /*++ Routine Description: This is a call back routine for doing the fast lock call. Arguments: FileObject - Supplies the file object used in this operation FileOffset - Supplies the file offset used in this operation Length - Supplies the length used in this operation ProcessId - Supplies the process ID used in this operation Key - Supplies the key used in this operation FailImmediately - Indicates if the request should fail immediately if the lock cannot be granted. ExclusiveLock - Indicates if this is a request for an exclusive or shared lock IoStatus - Receives the Status if this operation is successful Return Value: BOOLEAN - TRUE if this operation completed and FALSE if caller needs to take the long route. --*/ { BOOLEAN Results; PSCB Scb; PFCB Fcb; BOOLEAN ResourceAcquired = FALSE; UNREFERENCED_PARAMETER( DeviceObject ); PAGED_CODE(); DebugTrace( +1, Dbg, ("NtfsFastLock\n") ); // // Decode the type of file object we're being asked to process and // make sure that is is only a user file open. // if ((Scb = NtfsFastDecodeUserFileOpen( FileObject )) == NULL) { IoStatus->Status = STATUS_INVALID_PARAMETER; IoStatus->Information = 0; DebugTrace( -1, Dbg, ("NtfsFastLock -> TRUE (STATUS_INVALID_PARAMETER)\n") ); return TRUE; } Fcb = Scb->Fcb; // // Acquire shared access to the Fcb this operation can always wait // FsRtlEnterFileSystem(); if (Scb->ScbType.Data.FileLock == NULL) { (VOID) ExAcquireResourceExclusive( Fcb->Resource, TRUE ); ResourceAcquired = TRUE; } else { //(VOID) ExAcquireResourceShared( Fcb->Resource, TRUE ); } try { // // We check whether we can proceed // based on the state of the file oplocks. // if ((Scb->ScbType.Data.Oplock != NULL) && !FsRtlOplockIsFastIoPossible( &Scb->ScbType.Data.Oplock )) { try_return( Results = FALSE ); } // // If we don't have a file lock, then get one now. // if (Scb->ScbType.Data.FileLock == NULL && !NtfsCreateFileLock( Scb, FALSE )) { try_return( Results = FALSE ); } // // Now call the FsRtl routine to do the actual processing of the // Lock request // if (Results = FsRtlFastLock( Scb->ScbType.Data.FileLock, FileObject, FileOffset, Length, ProcessId, Key, FailImmediately, ExclusiveLock, IoStatus, NULL, FALSE )) { // // Set the flag indicating if Fast I/O is questionable. We // only change this flag is the current state is possible. // Retest again after synchronizing on the header. // if (Scb->Header.IsFastIoPossible == FastIoIsPossible) { NtfsAcquireFsrtlHeader( Scb ); Scb->Header.IsFastIoPossible = NtfsIsFastIoPossible( Scb ); NtfsReleaseFsrtlHeader( Scb ); } } try_exit: NOTHING; } finally { DebugUnwind( NtfsFastLock ); // // Release the Fcb, and return to our caller // if (ResourceAcquired) { ExReleaseResource( Fcb->Resource ); } FsRtlExitFileSystem(); DebugTrace( -1, Dbg, ("NtfsFastLock -> %08lx\n", Results) ); } return Results; }
BOOLEAN CdFastLock ( IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN PLARGE_INTEGER Length, PEPROCESS ProcessId, ULONG Key, BOOLEAN FailImmediately, BOOLEAN ExclusiveLock, OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject ) /*++ Routine Description: This is a call back routine for doing the fast lock call. Arguments: FileObject - Supplies the file object used in this operation FileOffset - Supplies the file offset used in this operation Length - Supplies the length used in this operation ProcessId - Supplies the process ID used in this operation Key - Supplies the key used in this operation FailImmediately - Indicates if the request should fail immediately if the lock cannot be granted. ExclusiveLock - Indicates if this is a request for an exclusive or shared lock IoStatus - Receives the Status if this operation is successful Return Value: BOOLEAN - TRUE if this operation completed and FALSE if caller needs to take the long route. --*/ { BOOLEAN Results = FALSE; PFCB Fcb; TYPE_OF_OPEN TypeOfOpen; PAGED_CODE(); ASSERT_FILE_OBJECT( FileObject ); IoStatus->Information = 0; // // Decode the type of file object we're being asked to process and // make sure that is is only a user file open. // TypeOfOpen = CdFastDecodeFileObject( FileObject, &Fcb ); if (TypeOfOpen != UserFileOpen) { IoStatus->Status = STATUS_INVALID_PARAMETER; return TRUE; } // // Only deal with 'good' Fcb's. // if (!CdVerifyFcbOperation( NULL, Fcb )) { return FALSE; } FsRtlEnterFileSystem(); // // Use a try-finally to facilitate cleanup. // try { // // We check whether we can proceed based on the state of the file oplocks. // if ((Fcb->Oplock != NULL) && !FsRtlOplockIsFastIoPossible( &Fcb->Oplock )) { try_return( NOTHING ); } // // If we don't have a file lock, then get one now. // if ((Fcb->FileLock == NULL) && !CdCreateFileLock( NULL, Fcb, FALSE )) { try_return( NOTHING ); } // // Now call the FsRtl routine to perform the lock request. // if (Results = FsRtlFastLock( Fcb->FileLock, FileObject, FileOffset, Length, ProcessId, Key, FailImmediately, ExclusiveLock, IoStatus, NULL, FALSE )) { // // Set the flag indicating if Fast I/O is questionable. We // only change this flag if the current state is possible. // Retest again after synchronizing on the header. // if (Fcb->IsFastIoPossible == FastIoIsPossible) { CdLockFcb( NULL, Fcb ); Fcb->IsFastIoPossible = CdIsFastIoPossible( Fcb ); CdUnlockFcb( NULL, Fcb ); } } try_exit: NOTHING; } finally { FsRtlExitFileSystem(); } return Results; }
BOOLEAN Ext2FastIoLock ( IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN PLARGE_INTEGER Length, IN PEPROCESS Process, IN ULONG Key, IN BOOLEAN FailImmediately, IN BOOLEAN ExclusiveLock, OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject ) { BOOLEAN Status = FALSE; PEXT2_FCB Fcb; __try { FsRtlEnterFileSystem(); __try { if (IsExt2FsDevice(DeviceObject)) { IoStatus->Status = STATUS_INVALID_DEVICE_REQUEST; __leave; } Fcb = (PEXT2_FCB) FileObject->FsContext; if (Fcb == NULL || Fcb->Identifier.Type == EXT2VCB) { IoStatus->Status = STATUS_INVALID_PARAMETER; __leave; } ASSERT((Fcb->Identifier.Type == EXT2FCB) && (Fcb->Identifier.Size == sizeof(EXT2_FCB))); if (IsDirectory(Fcb)) { DbgBreak(); IoStatus->Status = STATUS_INVALID_PARAMETER; __leave; } #if EXT2_DEBUG DEBUG(DL_INF, ( "Ext2FastIoLock: %s %s %wZ\n", Ext2GetCurrentProcessName(), "FASTIO_LOCK", &Fcb->Mcb->FullName )); DEBUG(DL_INF, ( "Ext2FastIoLock: Offset: %I64xh Length: %I64xh Key: %u %s%s\n", FileOffset->QuadPart, Length->QuadPart, Key, (FailImmediately ? "FailImmediately " : ""), (ExclusiveLock ? "ExclusiveLock " : "") )); #endif if (!FsRtlOplockIsFastIoPossible(&Fcb->Oplock)) { __leave; } Status = FsRtlFastLock( &Fcb->FileLockAnchor, FileObject, FileOffset, Length, Process, Key, FailImmediately, ExclusiveLock, IoStatus, NULL, FALSE); if (Status) { Fcb->Header.IsFastIoPossible = Ext2IsFastIoPossible(Fcb); } } __except (EXCEPTION_EXECUTE_HANDLER) { IoStatus->Status = GetExceptionCode(); } } __finally { FsRtlExitFileSystem(); } #if EXT2_DEBUG if (Status == FALSE) { DEBUG(DL_ERR, ( "Ext2FastIoLock: %s %s *** Status: FALSE ***\n", (PUCHAR) Process + ProcessNameOffset, "FASTIO_LOCK" )); } else if (IoStatus->Status != STATUS_SUCCESS) { DEBUG(DL_ERR, ( "Ext2FastIoLock: %s %s *** Status: %s (%#x) ***\n", (PUCHAR) Process + ProcessNameOffset, "FASTIO_LOCK", Ext2NtStatusToString(IoStatus->Status), IoStatus->Status )); } #endif return Status; }