3 Copyright (c) 1989-2000 Microsoft Corporation
11 This module implements the Lock Control routines for Fat called
12 by the dispatch driver.
20 // The local debug trace level
23 #define Dbg (DEBUG_TRACE_LOCKCTRL)
26 #pragma alloc_text(PAGE, FatCommonLockControl)
27 #pragma alloc_text(PAGE, FatFastLock)
28 #pragma alloc_text(PAGE, FatFastUnlockAll)
29 #pragma alloc_text(PAGE, FatFastUnlockAllByKey)
30 #pragma alloc_text(PAGE, FatFastUnlockSingle)
31 #pragma alloc_text(PAGE, FatFsdLockControl)
38 IN PVOLUME_DEVICE_OBJECT VolumeDeviceObject
,
46 This routine implements the FSD part of Lock control operations
50 VolumeDeviceObject - Supplies the volume device object where the
53 Irp - Supplies the Irp being processed
57 NTSTATUS - The FSD status for the IRP
63 PIRP_CONTEXT IrpContext
= NULL
;
67 DebugTrace(+1, Dbg
, "FatFsdLockControl\n", 0);
70 // Call the common Lock Control routine, with blocking allowed if
74 FsRtlEnterFileSystem();
76 TopLevel
= FatIsIrpTopLevel( Irp
);
80 IrpContext
= FatCreateIrpContext( Irp
, CanFsdWait( Irp
) );
82 Status
= FatCommonLockControl( IrpContext
, Irp
);
84 } _SEH2_EXCEPT(FatExceptionFilter( IrpContext
, _SEH2_GetExceptionInformation() )) {
87 // We had some trouble trying to perform the requested
88 // operation, so we'll abort the I/O request with
89 // the error status that we get back from the
93 Status
= FatProcessException( IrpContext
, Irp
, _SEH2_GetExceptionCode() );
96 if (TopLevel
) { IoSetTopLevelIrp( NULL
); }
98 FsRtlExitFileSystem();
101 // And return to our caller
104 DebugTrace(-1, Dbg
, "FatFsdLockControl -> %08lx\n", Status
);
106 UNREFERENCED_PARAMETER( VolumeDeviceObject
);
115 IN PFILE_OBJECT FileObject
,
116 IN PLARGE_INTEGER FileOffset
,
117 IN PLARGE_INTEGER Length
,
120 BOOLEAN FailImmediately
,
121 BOOLEAN ExclusiveLock
,
122 OUT PIO_STATUS_BLOCK IoStatus
,
123 IN PDEVICE_OBJECT DeviceObject
130 This is a call back routine for doing the fast lock call.
134 FileObject - Supplies the file object used in this operation
136 FileOffset - Supplies the file offset used in this operation
138 Length - Supplies the length used in this operation
140 ProcessId - Supplies the process ID used in this operation
142 Key - Supplies the key used in this operation
144 FailImmediately - Indicates if the request should fail immediately
145 if the lock cannot be granted.
147 ExclusiveLock - Indicates if this is a request for an exclusive or
150 IoStatus - Receives the Status if this operation is successful
154 BOOLEAN - TRUE if this operation completed and FALSE if caller
155 needs to take the long route.
165 DebugTrace(+1, Dbg
, "FatFastLock\n", 0);
168 // Decode the type of file object we're being asked to process and make
169 // sure it is only a user file open.
172 if (FatDecodeFileObject( FileObject
, &Vcb
, &Fcb
, &Ccb
) != UserFileOpen
) {
174 IoStatus
->Status
= STATUS_INVALID_PARAMETER
;
175 IoStatus
->Information
= 0;
177 DebugTrace(-1, Dbg
, "FatFastLock -> TRUE (STATUS_INVALID_PARAMETER)\n", 0);
182 // Acquire exclusive access to the Fcb this operation can always wait
185 FsRtlEnterFileSystem();
190 // We check whether we can proceed
191 // based on the state of the file oplocks.
194 if (!FsRtlOplockIsFastIoPossible( &(Fcb
)->Specific
.Fcb
.Oplock
)) {
196 try_return( Results
= FALSE
);
200 // Now call the FsRtl routine to do the actual processing of the
205 if (Results
= FsRtlFastLock( &Fcb
->Specific
.Fcb
.FileLock
,
207 Results
= FsRtlFastLock( &Fcb
->Specific
.Fcb
.FileLock
,
227 // Set the flag indicating if Fast I/O is possible
230 Fcb
->Header
.IsFastIoPossible
= FatIsFastIoPossible( Fcb
);
236 DebugUnwind( FatFastLock
);
239 // Release the Fcb, and return to our caller
242 FsRtlExitFileSystem();
244 DebugTrace(-1, Dbg
, "FatFastLock -> %08lx\n", Results
);
253 FatFastUnlockSingle (
254 IN PFILE_OBJECT FileObject
,
255 IN PLARGE_INTEGER FileOffset
,
256 IN PLARGE_INTEGER Length
,
259 OUT PIO_STATUS_BLOCK IoStatus
,
260 IN PDEVICE_OBJECT DeviceObject
267 This is a call back routine for doing the fast unlock single call.
271 FileObject - Supplies the file object used in this operation
273 FileOffset - Supplies the file offset used in this operation
275 Length - Supplies the length used in this operation
277 ProcessId - Supplies the process ID used in this operation
279 Key - Supplies the key used in this operation
281 Status - Receives the Status if this operation is successful
285 BOOLEAN - TRUE if this operation completed and FALSE if caller
286 needs to take the long route.
296 DebugTrace(+1, Dbg
, "FatFastUnlockSingle\n", 0);
298 IoStatus
->Information
= 0;
301 // Decode the type of file object we're being asked to process and make sure
302 // it is only a user file open
305 if (FatDecodeFileObject( FileObject
, &Vcb
, &Fcb
, &Ccb
) != UserFileOpen
) {
307 IoStatus
->Status
= STATUS_INVALID_PARAMETER
;
309 DebugTrace(-1, Dbg
, "FatFastUnlockSingle -> TRUE (STATUS_INVALID_PARAMETER)\n", 0);
314 // Acquire exclusive access to the Fcb this operation can always wait
317 FsRtlEnterFileSystem();
322 // We check whether we can proceed based on the state of the file oplocks.
325 if (!FsRtlOplockIsFastIoPossible( &(Fcb
)->Specific
.Fcb
.Oplock
)) {
327 try_return( Results
= FALSE
);
331 // Now call the FsRtl routine to do the actual processing of the
332 // Lock request. The call will always succeed.
336 IoStatus
->Status
= FsRtlFastUnlockSingle( &Fcb
->Specific
.Fcb
.FileLock
,
346 // Set the flag indicating if Fast I/O is possible
349 Fcb
->Header
.IsFastIoPossible
= FatIsFastIoPossible( Fcb
);
354 DebugUnwind( FatFastUnlockSingle
);
357 // Release the Fcb, and return to our caller
360 FsRtlExitFileSystem();
362 DebugTrace(-1, Dbg
, "FatFastUnlockSingle -> %08lx\n", Results
);
372 IN PFILE_OBJECT FileObject
,
374 OUT PIO_STATUS_BLOCK IoStatus
,
375 IN PDEVICE_OBJECT DeviceObject
382 This is a call back routine for doing the fast unlock all call.
386 FileObject - Supplies the file object used in this operation
388 ProcessId - Supplies the process ID used in this operation
390 Status - Receives the Status if this operation is successful
394 BOOLEAN - TRUE if this operation completed and FALSE if caller
395 needs to take the long route.
405 DebugTrace(+1, Dbg
, "FatFastUnlockAll\n", 0);
407 IoStatus
->Information
= 0;
410 // Decode the type of file object we're being asked to process and make sure
411 // it is only a user file open.
414 if (FatDecodeFileObject( FileObject
, &Vcb
, &Fcb
, &Ccb
) != UserFileOpen
) {
416 IoStatus
->Status
= STATUS_INVALID_PARAMETER
;
418 DebugTrace(-1, Dbg
, "FatFastUnlockAll -> TRUE (STATUS_INVALID_PARAMETER)\n", 0);
423 // Acquire exclusive access to the Fcb this operation can always wait
426 FsRtlEnterFileSystem();
428 (VOID
) ExAcquireResourceSharedLite( Fcb
->Header
.Resource
, TRUE
);
433 // We check whether we can proceed based on the state of the file oplocks.
436 if (!FsRtlOplockIsFastIoPossible( &(Fcb
)->Specific
.Fcb
.Oplock
)) {
438 try_return( Results
= FALSE
);
442 // Now call the FsRtl routine to do the actual processing of the
443 // Lock request. The call will always succeed.
447 IoStatus
->Status
= FsRtlFastUnlockAll( &Fcb
->Specific
.Fcb
.FileLock
,
453 // Set the flag indicating if Fast I/O is possible
456 Fcb
->Header
.IsFastIoPossible
= FatIsFastIoPossible( Fcb
);
461 DebugUnwind( FatFastUnlockAll
);
464 // Release the Fcb, and return to our caller
467 ExReleaseResourceLite( (Fcb
)->Header
.Resource
);
469 FsRtlExitFileSystem();
471 DebugTrace(-1, Dbg
, "FatFastUnlockAll -> %08lx\n", Results
);
480 FatFastUnlockAllByKey (
481 IN PFILE_OBJECT FileObject
,
484 OUT PIO_STATUS_BLOCK IoStatus
,
485 IN PDEVICE_OBJECT DeviceObject
492 This is a call back routine for doing the fast unlock all by key call.
496 FileObject - Supplies the file object used in this operation
498 ProcessId - Supplies the process ID used in this operation
500 Key - Supplies the key used in this operation
502 Status - Receives the Status if this operation is successful
506 BOOLEAN - TRUE if this operation completed and FALSE if caller
507 needs to take the long route.
517 DebugTrace(+1, Dbg
, "FatFastUnlockAllByKey\n", 0);
519 IoStatus
->Information
= 0;
522 // Decode the type of file object we're being asked to process and make sure
523 // it is only a user file open.
526 if (FatDecodeFileObject( FileObject
, &Vcb
, &Fcb
, &Ccb
) != UserFileOpen
) {
528 IoStatus
->Status
= STATUS_INVALID_PARAMETER
;
530 DebugTrace(-1, Dbg
, "FatFastUnlockAll -> TRUE (STATUS_INVALID_PARAMETER)\n", 0);
535 // Acquire exclusive access to the Fcb this operation can always wait
538 FsRtlEnterFileSystem();
540 (VOID
) ExAcquireResourceSharedLite( Fcb
->Header
.Resource
, TRUE
);
545 // We check whether we can proceed based on the state of the file oplocks.
548 if (!FsRtlOplockIsFastIoPossible( &(Fcb
)->Specific
.Fcb
.Oplock
)) {
550 try_return( Results
= FALSE
);
554 // Now call the FsRtl routine to do the actual processing of the
555 // Lock request. The call will always succeed.
559 IoStatus
->Status
= FsRtlFastUnlockAllByKey( &Fcb
->Specific
.Fcb
.FileLock
,
566 // Set the flag indicating if Fast I/O is possible
569 Fcb
->Header
.IsFastIoPossible
= FatIsFastIoPossible( Fcb
);
574 DebugUnwind( FatFastUnlockAllByKey
);
577 // Release the Fcb, and return to our caller
580 ExReleaseResourceLite( (Fcb
)->Header
.Resource
);
582 FsRtlExitFileSystem();
584 DebugTrace(-1, Dbg
, "FatFastUnlockAllByKey -> %08lx\n", Results
);
592 FatCommonLockControl (
593 IN PIRP_CONTEXT IrpContext
,
601 This is the common routine for doing Lock control operations called
602 by both the fsd and fsp threads
606 Irp - Supplies the Irp to process
610 NTSTATUS - The return status for the operation
616 PIO_STACK_LOCATION IrpSp
;
618 TYPE_OF_OPEN TypeOfOpen
;
624 BOOLEAN OplockPostIrp
= FALSE
;
627 // Get a pointer to the current Irp stack location
630 IrpSp
= IoGetCurrentIrpStackLocation( Irp
);
632 DebugTrace(+1, Dbg
, "FatCommonLockControl\n", 0);
633 DebugTrace( 0, Dbg
, "Irp = %08lx\n", Irp
);
634 DebugTrace( 0, Dbg
, "MinorFunction = %08lx\n", IrpSp
->MinorFunction
);
637 // Decode the type of file object we're being asked to process
640 TypeOfOpen
= FatDecodeFileObject( IrpSp
->FileObject
, &Vcb
, &Fcb
, &Ccb
);
643 // If the file is not a user file open then we reject the request
644 // as an invalid parameter
647 if (TypeOfOpen
!= UserFileOpen
) {
649 FatCompleteRequest( IrpContext
, Irp
, STATUS_INVALID_PARAMETER
);
651 DebugTrace(-1, Dbg
, "FatCommonLockControl -> STATUS_INVALID_PARAMETER\n", 0);
652 return STATUS_INVALID_PARAMETER
;
656 // Acquire exclusive access to the Fcb and enqueue the Irp if we didn't
660 if (!FatAcquireSharedFcb( IrpContext
, Fcb
)) {
662 Status
= FatFsdPostRequest( IrpContext
, Irp
);
664 DebugTrace(-1, Dbg
, "FatCommonLockControl -> %08lx\n", Status
);
671 // We check whether we can proceed
672 // based on the state of the file oplocks.
675 Status
= FsRtlCheckOplock( &Fcb
->Specific
.Fcb
.Oplock
,
681 if (Status
!= STATUS_SUCCESS
) {
683 OplockPostIrp
= TRUE
;
684 try_return( NOTHING
);
688 // Now call the FsRtl routine to do the actual processing of the
692 Status
= FsRtlProcessFileLock( &Fcb
->Specific
.Fcb
.FileLock
, Irp
, NULL
);
695 // Set the flag indicating if Fast I/O is possible
698 Fcb
->Header
.IsFastIoPossible
= FatIsFastIoPossible( Fcb
);
703 DebugUnwind( FatCommonLockControl
);
706 // Only if this is not an abnormal termination do we delete the
710 if (!_SEH2_AbnormalTermination() && !OplockPostIrp
) {
712 FatCompleteRequest( IrpContext
, FatNull
, 0 );
716 // Release the Fcb, and return to our caller
719 FatReleaseFcb( IrpContext
, Fcb
);
721 DebugTrace(-1, Dbg
, "FatCommonLockControl -> %08lx\n", Status
);