BOOLEAN FatFastUnlockAllByKey ( IN PFILE_OBJECT FileObject, PVOID ProcessId, ULONG Key, OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject ) /*++ Routine Description: This is a call back routine for doing the fast unlock all by key call. Arguments: FileObject - Supplies the file object used in this operation ProcessId - Supplies the process ID used in this operation Key - Supplies the key used in this operation Status - 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, "FatFastUnlockAllByKey\n", 0); IoStatus->Information = 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; DebugTrace(-1, Dbg, "FatFastUnlockAll -> TRUE (STATUS_INVALID_PARAMETER)\n", 0); return TRUE; } // // Acquire exclusive access to the Fcb this operation can always wait // FsRtlEnterFileSystem(); (VOID) ExAcquireResourceSharedLite( Fcb->Header.Resource, TRUE ); 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. The call will always succeed. // Results = TRUE; IoStatus->Status = FsRtlFastUnlockAllByKey( &Fcb->Specific.Fcb.FileLock, FileObject, ProcessId, Key, NULL ); // // Set the flag indicating if Fast I/O is possible // Fcb->Header.IsFastIoPossible = FatIsFastIoPossible( Fcb ); try_exit: NOTHING; } finally { DebugUnwind( FatFastUnlockAllByKey ); // // Release the Fcb, and return to our caller // ExReleaseResourceLite( (Fcb)->Header.Resource ); FsRtlExitFileSystem(); DebugTrace(-1, Dbg, "FatFastUnlockAllByKey -> %08lx\n", Results); } return Results; }
/* * @implemented */ NTSTATUS NTAPI FsRtlProcessFileLock(IN PFILE_LOCK FileLock, IN PIRP Irp, IN PVOID Context OPTIONAL) { PIO_STACK_LOCATION IoStackLocation; NTSTATUS Status; IO_STATUS_BLOCK IoStatusBlock; /* Get the I/O Stack location */ IoStackLocation = IoGetCurrentIrpStackLocation(Irp); ASSERT(IoStackLocation->MajorFunction == IRP_MJ_LOCK_CONTROL); /* Clear the I/O status block and check what function this is */ IoStatusBlock.Information = 0; switch(IoStackLocation->MinorFunction) { /* A lock */ case IRP_MN_LOCK: /* Call the private lock routine */ FsRtlPrivateLock(FileLock, IoStackLocation->FileObject, &IoStackLocation-> Parameters.LockControl.ByteOffset, IoStackLocation->Parameters.LockControl.Length, IoGetRequestorProcess(Irp), IoStackLocation->Parameters.LockControl.Key, IoStackLocation->Flags & SL_FAIL_IMMEDIATELY, IoStackLocation->Flags & SL_EXCLUSIVE_LOCK, &IoStatusBlock, Irp, Context, FALSE); break; /* A single unlock */ case IRP_MN_UNLOCK_SINGLE: /* Call fast unlock */ IoStatusBlock.Status = FsRtlFastUnlockSingle(FileLock, IoStackLocation->FileObject, &IoStackLocation->Parameters.LockControl. ByteOffset, IoStackLocation->Parameters.LockControl. Length, IoGetRequestorProcess(Irp), IoStackLocation->Parameters.LockControl. Key, Context, FALSE); /* Complete the IRP */ FsRtlCompleteLockIrpReal(FileLock->CompleteLockIrpRoutine, Context, Irp, IoStatusBlock.Status, &Status, NULL); break; /* Total unlock */ case IRP_MN_UNLOCK_ALL: /* Do a fast unlock */ IoStatusBlock.Status = FsRtlFastUnlockAll(FileLock, IoStackLocation-> FileObject, IoGetRequestorProcess(Irp), Context); /* Complete the IRP */ FsRtlCompleteLockIrpReal(FileLock->CompleteLockIrpRoutine, Context, Irp, IoStatusBlock.Status, &Status, NULL); break; /* Unlock by key */ case IRP_MN_UNLOCK_ALL_BY_KEY: /* Do it */ IoStatusBlock.Status = FsRtlFastUnlockAllByKey(FileLock, IoStackLocation->FileObject, IoGetRequestorProcess(Irp), IoStackLocation->Parameters. LockControl.Key, Context); /* Complete the IRP */ FsRtlCompleteLockIrpReal(FileLock->CompleteLockIrpRoutine, Context, Irp, IoStatusBlock.Status, &Status, NULL); break; /* Invalid request */ default: /* Complete it */ FsRtlCompleteRequest(Irp, STATUS_INVALID_DEVICE_REQUEST); IoStatusBlock.Status = STATUS_INVALID_DEVICE_REQUEST; break; } /* Return the status */ return IoStatusBlock.Status; }
BOOLEAN NtfsFastUnlockAllByKey ( IN PFILE_OBJECT FileObject, PVOID ProcessId, ULONG Key, OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject ) /*++ Routine Description: This is a call back routine for doing the fast unlock all by key call. Arguments: FileObject - Supplies the file object used in this operation ProcessId - Supplies the process ID used in this operation Key - Supplies the key used in this operation Status - 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; IRP_CONTEXT IrpContext; TYPE_OF_OPEN TypeOfOpen; PVCB Vcb; PFCB Fcb; PSCB Scb; PCCB Ccb; UNREFERENCED_PARAMETER( DeviceObject ); PAGED_CODE(); DebugTrace( +1, Dbg, ("NtfsFastUnlockAllByKey\n") ); 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 = NtfsDecodeFileObject( &IrpContext, FileObject, &Vcb, &Fcb, &Scb, &Ccb, FALSE ); if (TypeOfOpen != UserFileOpen) { IoStatus->Status = STATUS_INVALID_PARAMETER; IoStatus->Information = 0; DebugTrace( -1, Dbg, ("NtfsFastUnlockAllByKey -> TRUE (STATUS_INVALID_PARAMETER)\n") ); return TRUE; } // // Acquire exclusive access to the Fcb this operation can always wait // FsRtlEnterFileSystem(); if (Scb->ScbType.Data.FileLock == NULL) { (VOID) ExAcquireResourceExclusive( Fcb->Resource, TRUE ); } else { (VOID) ExAcquireResourceShared( Fcb->Resource, TRUE ); } try { // // We check whether we can proceed based on the state of the file oplocks. // if (!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. The call will always succeed. // Results = TRUE; IoStatus->Status = FsRtlFastUnlockAllByKey( Scb->ScbType.Data.FileLock, FileObject, ProcessId, Key, NULL ); // // Set the flag indicating if Fast I/O is possible // NtfsAcquireFsrtlHeader( Scb ); Scb->Header.IsFastIoPossible = NtfsIsFastIoPossible( Scb ); NtfsReleaseFsrtlHeader( Scb ); try_exit: NOTHING; } finally { DebugUnwind( NtfsFastUnlockAllByKey ); // // Release the Fcb, and return to our caller // ExReleaseResource( Fcb->Resource ); FsRtlExitFileSystem(); DebugTrace( -1, Dbg, ("NtfsFastUnlockAllByKey -> %08lx\n", Results) ); } return Results; }
BOOLEAN CdFastUnlockAllByKey ( IN PFILE_OBJECT FileObject, PVOID ProcessId, ULONG Key, OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject ) /*++ Routine Description: This is a call back routine for doing the fast unlock all by key call. Arguments: FileObject - Supplies the file object used in this operation ProcessId - Supplies the process ID used in this operation Key - Supplies the key used in this operation Status - 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; TYPE_OF_OPEN TypeOfOpen; PFCB Fcb; PAGED_CODE(); 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; } // // If there is no lock then return immediately. // if (Fcb->FileLock == NULL) { IoStatus->Status = STATUS_RANGE_NOT_LOCKED; return TRUE; } FsRtlEnterFileSystem(); 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 do the actual processing of the // Lock request. The call will always succeed. // Results = TRUE; IoStatus->Status = FsRtlFastUnlockAllByKey( Fcb->FileLock, FileObject, ProcessId, Key, NULL ); // // Set the flag indicating if Fast I/O is possible // CdLockFcb( IrpContext, Fcb ); Fcb->IsFastIoPossible = CdIsFastIoPossible( Fcb ); CdUnlockFcb( IrpContext, Fcb ); try_exit: NOTHING; } finally { FsRtlExitFileSystem(); } return Results; }
BOOLEAN Ext2FastIoUnlockAllByKey ( IN PFILE_OBJECT FileObject, IN PEPROCESS Process, IN ULONG Key, 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) { DbgBreak(); 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, ( "Ext2FastIoUnlockAllByKey: %s %s %wZ\n", (PUCHAR) Process + ProcessNameOffset, "FASTIO_UNLOCK_ALL_BY_KEY", &Fcb->Mcb->FullName )); DEBUG(DL_INF, ( "Ext2FastIoUnlockAllByKey: Key: %u\n", Key )); #endif if (!FsRtlOplockIsFastIoPossible(&Fcb->Oplock)) { __leave; } IoStatus->Status = FsRtlFastUnlockAllByKey( &Fcb->FileLockAnchor, FileObject, Process, Key, NULL ); IoStatus->Information = 0; Status = TRUE; Fcb->Header.IsFastIoPossible = Ext2IsFastIoPossible(Fcb); } __except (EXCEPTION_EXECUTE_HANDLER) { IoStatus->Status = GetExceptionCode(); } } __finally { FsRtlExitFileSystem(); } #if EXT2_DEBUG if (Status == FALSE) { DEBUG(DL_ERR, ( "Ext2FastIoUnlockAllByKey: %s %s *** Status: FALSE ***\n", (PUCHAR) Process + ProcessNameOffset, "FASTIO_UNLOCK_ALL_BY_KEY" )); } else if (IoStatus->Status != STATUS_SUCCESS) { DEBUG(DL_ERR, ( "Ext2FastIoUnlockAllByKey: %s %s *** Status: %s (%#x) ***\n", (PUCHAR) Process + ProcessNameOffset, "FASTIO_UNLOCK_ALL_BY_KEY", Ext2NtStatusToString(IoStatus->Status), IoStatus->Status )); } #endif return Status; }