summaryrefslogtreecommitdiffstats
path: root/private/ntos/cntfs/lockctrl.c
diff options
context:
space:
mode:
authorAdam <you@example.com>2020-05-17 05:51:50 +0200
committerAdam <you@example.com>2020-05-17 05:51:50 +0200
commite611b132f9b8abe35b362e5870b74bce94a1e58e (patch)
treea5781d2ec0e085eeca33cf350cf878f2efea6fe5 /private/ntos/cntfs/lockctrl.c
downloadNT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.gz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.bz2
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.lz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.xz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.zst
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.zip
Diffstat (limited to 'private/ntos/cntfs/lockctrl.c')
-rw-r--r--private/ntos/cntfs/lockctrl.c899
1 files changed, 899 insertions, 0 deletions
diff --git a/private/ntos/cntfs/lockctrl.c b/private/ntos/cntfs/lockctrl.c
new file mode 100644
index 000000000..b814895c1
--- /dev/null
+++ b/private/ntos/cntfs/lockctrl.c
@@ -0,0 +1,899 @@
+/*++
+
+Copyright (c) 1991 Microsoft Corporation
+
+Module Name:
+
+ LockCtrl.c
+
+Abstract:
+
+ This module implements the File Lock Control routine for Ntfs called by the
+ dispatch driver.
+
+Author:
+
+ Gary Kimura [GaryKi] 28-May-1991
+
+Revision History:
+
+--*/
+
+#include "NtfsProc.h"
+
+//
+// The local debug trace level
+//
+
+#define Dbg (DEBUG_TRACE_LOCKCTRL)
+
+#ifdef ALLOC_PRAGMA
+#pragma alloc_text(PAGE, NtfsCommonLockControl)
+#pragma alloc_text(PAGE, NtfsFastLock)
+#pragma alloc_text(PAGE, NtfsFastUnlockAll)
+#pragma alloc_text(PAGE, NtfsFastUnlockAllByKey)
+#pragma alloc_text(PAGE, NtfsFastUnlockSingle)
+#pragma alloc_text(PAGE, NtfsFsdLockControl)
+#endif
+
+
+NTSTATUS
+NtfsFsdLockControl (
+ IN PVOLUME_DEVICE_OBJECT VolumeDeviceObject,
+ IN PIRP Irp
+ )
+
+/*++
+
+Routine Description:
+
+ This routine implements the FSD part of Lock Control.
+
+Arguments:
+
+ VolumeDeviceObject - Supplies the volume device object where the
+ file exists
+
+ Irp - Supplies the Irp being processed
+
+Return Value:
+
+ NTSTATUS - The FSD status for the IRP
+
+--*/
+
+{
+ TOP_LEVEL_CONTEXT TopLevelContext;
+ PTOP_LEVEL_CONTEXT ThreadTopLevelContext;
+
+ NTSTATUS Status = STATUS_SUCCESS;
+ PIRP_CONTEXT IrpContext = NULL;
+
+ ASSERT_IRP( Irp );
+
+ UNREFERENCED_PARAMETER( VolumeDeviceObject );
+
+ PAGED_CODE();
+
+ DebugTrace( +1, Dbg, ("NtfsFsdLockControl\n") );
+
+ //
+ // Call the common Lock Control routine
+ //
+
+ FsRtlEnterFileSystem();
+
+ ThreadTopLevelContext = NtfsSetTopLevelIrp( &TopLevelContext, FALSE, FALSE );
+
+ do {
+
+ try {
+
+ //
+ // We are either initiating this request or retrying it.
+ //
+
+ if (IrpContext == NULL) {
+
+ IrpContext = NtfsCreateIrpContext( Irp, CanFsdWait( Irp ) );
+ NtfsUpdateIrpContextWithTopLevel( IrpContext, ThreadTopLevelContext );
+
+ } else if (Status == STATUS_LOG_FILE_FULL) {
+
+ NtfsCheckpointForLogFileFull( IrpContext );
+ }
+
+ Status = NtfsCommonLockControl( IrpContext, Irp );
+ break;
+
+ } except(NtfsExceptionFilter( IrpContext, GetExceptionInformation() )) {
+
+ //
+ // We had some trouble trying to perform the requested
+ // operation, so we'll abort the I/O request with
+ // the error status that we get back from the
+ // execption code
+ //
+
+ Status = NtfsProcessException( IrpContext, Irp, GetExceptionCode() );
+ }
+
+ } while (Status == STATUS_CANT_WAIT ||
+ Status == STATUS_LOG_FILE_FULL);
+
+ if (ThreadTopLevelContext == &TopLevelContext) {
+ NtfsRestoreTopLevelIrp( ThreadTopLevelContext );
+ }
+
+ FsRtlExitFileSystem();
+
+ //
+ // And return to our caller
+ //
+
+ DebugTrace( -1, Dbg, ("NtfsFsdLockControl -> %08lx\n", Status) );
+
+ return Status;
+}
+
+
+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
+NtfsFastUnlockSingle (
+ IN PFILE_OBJECT FileObject,
+ IN PLARGE_INTEGER FileOffset,
+ IN PLARGE_INTEGER Length,
+ PEPROCESS 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 single 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
+
+ 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;
+ PFCB Fcb;
+ PSCB Scb;
+ BOOLEAN ResourceAcquired = FALSE;
+
+ UNREFERENCED_PARAMETER( DeviceObject );
+
+ PAGED_CODE();
+
+ DebugTrace( +1, Dbg, ("NtfsFastUnlockSingle\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.
+ //
+
+ if ((Scb = NtfsFastDecodeUserFileOpen( FileObject )) == NULL) {
+
+ IoStatus->Status = STATUS_INVALID_PARAMETER;
+
+ DebugTrace( -1, Dbg, ("NtfsFastUnlockSingle -> TRUE (STATUS_INVALID_PARAMETER)\n") );
+ return TRUE;
+ }
+
+ Fcb = Scb->Fcb;
+
+ //
+ // Acquire exclusive 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. The call will always succeed.
+ //
+
+ Results = TRUE;
+ IoStatus->Status = FsRtlFastUnlockSingle( Scb->ScbType.Data.FileLock,
+ FileObject,
+ FileOffset,
+ Length,
+ ProcessId,
+ Key,
+ NULL,
+ FALSE );
+
+ //
+ // Set the flag indicating if Fast I/O is possible. We are
+ // only concerned if there are no longer any filelocks on this
+ // file.
+ //
+
+ if (!FsRtlAreThereCurrentFileLocks( Scb->ScbType.Data.FileLock ) &&
+ (Scb->Header.IsFastIoPossible != FastIoIsPossible)) {
+
+ NtfsAcquireFsrtlHeader( Scb );
+ Scb->Header.IsFastIoPossible = NtfsIsFastIoPossible( Scb );
+ NtfsReleaseFsrtlHeader( Scb );
+ }
+
+ try_exit: NOTHING;
+ } finally {
+
+ DebugUnwind( NtfsFastUnlockSingle );
+
+ //
+ // Release the Fcb, and return to our caller
+ //
+
+ if (ResourceAcquired) {
+ ExReleaseResource( Fcb->Resource );
+ }
+
+ FsRtlExitFileSystem();
+
+ DebugTrace( -1, Dbg, ("NtfsFastUnlockSingle -> %08lx\n", Results) );
+ }
+
+ return Results;
+}
+
+
+BOOLEAN
+NtfsFastUnlockAll (
+ IN PFILE_OBJECT FileObject,
+ PEPROCESS ProcessId,
+ OUT PIO_STATUS_BLOCK IoStatus,
+ IN PDEVICE_OBJECT DeviceObject
+ )
+
+/*++
+
+Routine Description:
+
+ This is a call back routine for doing the fast unlock all call.
+
+Arguments:
+
+ FileObject - Supplies the file object used in this operation
+
+ ProcessId - Supplies the process ID 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, ("NtfsFastUnlockAll\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, ("NtfsFastUnlockAll -> 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 = FsRtlFastUnlockAll( Scb->ScbType.Data.FileLock,
+ FileObject,
+ ProcessId,
+ 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( NtfsFastUnlockAll );
+
+ //
+ // Release the Fcb, and return to our caller
+ //
+
+ ExReleaseResource( Fcb->Resource );
+
+ FsRtlExitFileSystem();
+
+ DebugTrace( -1, Dbg, ("NtfsFastUnlockAll -> %08lx\n", Results) );
+ }
+
+ return Results;
+}
+
+
+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;
+}
+
+
+NTSTATUS
+NtfsCommonLockControl (
+ IN PIRP_CONTEXT IrpContext,
+ IN PIRP Irp
+ )
+
+/*++
+
+Routine Description:
+
+ This is the common routine for Lock Control called by both the fsd and fsp
+ threads.
+
+Arguments:
+
+ Irp - Supplies the Irp to process
+
+Return Value:
+
+ NTSTATUS - The return status for the operation
+
+--*/
+
+{
+ NTSTATUS Status;
+ PIO_STACK_LOCATION IrpSp;
+ PFILE_OBJECT FileObject;
+
+ TYPE_OF_OPEN TypeOfOpen;
+ PVCB Vcb;
+ PFCB Fcb;
+ PSCB Scb;
+ PCCB Ccb;
+ BOOLEAN FcbAcquired = FALSE;
+
+ BOOLEAN OplockPostIrp;
+
+ ASSERT_IRP_CONTEXT( IrpContext );
+ ASSERT_IRP( Irp );
+
+ PAGED_CODE();
+
+ //
+ // Get a pointer to the current Irp stack location
+ //
+
+ IrpSp = IoGetCurrentIrpStackLocation( Irp );
+
+ DebugTrace( +1, Dbg, ("NtfsCommonLockControl\n") );
+ DebugTrace( 0, Dbg, ("IrpContext = %08lx\n", IrpContext) );
+ DebugTrace( 0, Dbg, ("Irp = %08lx\n", Irp) );
+ DebugTrace( 0, Dbg, ("MinorFunction = %08lx\n", IrpSp->MinorFunction) );
+
+ //
+ // Extract and decode the type of file object we're being asked to process
+ //
+
+ FileObject = IrpSp->FileObject;
+ TypeOfOpen = NtfsDecodeFileObject( IrpContext, FileObject, &Vcb, &Fcb, &Scb, &Ccb, TRUE );
+
+ //
+ // If the file is not a user file open then we reject the request
+ // as an invalid parameter
+ //
+
+ if (TypeOfOpen != UserFileOpen) {
+
+ NtfsCompleteRequest( &IrpContext, &Irp, STATUS_INVALID_PARAMETER );
+
+ DebugTrace( -1, Dbg, ("NtfsCommonLockControl -> STATUS_INVALID_PARAMETER\n") );
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ //
+ // Acquire exclusive access to the Fcb
+ //
+
+ if (Scb->ScbType.Data.FileLock == NULL) {
+
+ NtfsAcquireExclusiveFcb( IrpContext, Fcb, Scb, FALSE, FALSE );
+ FcbAcquired = TRUE;
+
+ } else {
+
+ //NtfsAcquireSharedFcb( IrpContext, Fcb, Scb );
+ }
+
+ OplockPostIrp = FALSE;
+
+ try {
+
+ //
+ // We check whether we can proceed based on the state of the file oplocks.
+ // This call might post the irp for us.
+ //
+
+ Status = FsRtlCheckOplock( &Scb->ScbType.Data.Oplock,
+ Irp,
+ IrpContext,
+ NtfsOplockComplete,
+ NULL );
+
+ if (Status != STATUS_SUCCESS) {
+
+ OplockPostIrp = TRUE;
+ try_return( NOTHING );
+ }
+
+ //
+ // If we don't have a file lock, then get one now.
+ //
+
+ if (Scb->ScbType.Data.FileLock == NULL) {
+
+ NtfsCreateFileLock( Scb, TRUE );
+ }
+
+ //
+ // Now call the FsRtl routine to do the actual processing of the
+ // Lock request
+ //
+
+ Status = FsRtlProcessFileLock( Scb->ScbType.Data.FileLock, Irp, 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( NtfsCommonLockControl );
+
+ //
+ // Release the Fcb, and return to our caller
+ //
+
+ if (FcbAcquired) {
+ NtfsReleaseFcb( IrpContext, Fcb );
+ }
+
+ //
+ // Only if this is not an abnormal termination and we did not post the irp
+ // do we delete the irp context
+ //
+
+ if (!AbnormalTermination() && !OplockPostIrp) {
+
+ NtfsCompleteRequest( &IrpContext, NULL, 0 );
+ }
+
+ DebugTrace( -1, Dbg, ("NtfsCommonLockControl -> %08lx\n", Status) );
+ }
+
+ return Status;
+}