3 Copyright (c) 1989-2000 Microsoft Corporation
11 This module implements the Lock Control routines for Cdfs called
12 by the Fsd/Fsp dispatch driver.
20 // The Bug check file id for this module
23 #define BugCheckFileId (CDFS_BUG_CHECK_LOCKCTRL)
26 #pragma alloc_text(PAGE, CdCommonLockControl)
27 #pragma alloc_text(PAGE, CdFastLock)
28 #pragma alloc_text(PAGE, CdFastUnlockAll)
29 #pragma alloc_text(PAGE, CdFastUnlockAllByKey)
30 #pragma alloc_text(PAGE, CdFastUnlockSingle)
36 _Inout_ PIRP_CONTEXT IrpContext
,
44 This is the common routine for Lock Control called by both the fsd and fsp
49 Irp - Supplies the Irp to process
53 NTSTATUS - The return status for the operation
59 PIO_STACK_LOCATION IrpSp
= IoGetCurrentIrpStackLocation( Irp
);
61 TYPE_OF_OPEN TypeOfOpen
;
68 // Extract and decode the type of file object we're being asked to process
71 TypeOfOpen
= CdDecodeFileObject( IrpContext
, IrpSp
->FileObject
, &Fcb
, &Ccb
);
74 // If the file is not a user file open then we reject the request
75 // as an invalid parameter
78 if (TypeOfOpen
!= UserFileOpen
) {
80 CdCompleteRequest( IrpContext
, Irp
, STATUS_INVALID_PARAMETER
);
81 return STATUS_INVALID_PARAMETER
;
85 // We check whether we can proceed based on the state of the file oplocks.
86 // This call might post the irp for us.
89 Status
= FsRtlCheckOplock( CdGetFcbOplock(Fcb
),
92 (PVOID
)CdOplockComplete
,/* ReactOS Change: GCC "assignment from incompatible pointer type" */
96 // If we don't get success then the oplock package completed the request.
99 if (Status
!= STATUS_SUCCESS
) {
108 CdVerifyFcbOperation( IrpContext
, Fcb
);
111 // If we don't have a file lock, then get one now.
114 if (Fcb
->FileLock
== NULL
) { CdCreateFileLock( IrpContext
, Fcb
, TRUE
); }
117 // Now call the FsRtl routine to do the actual processing of the
121 Status
= FsRtlProcessFileLock( Fcb
->FileLock
, Irp
, NULL
);
124 // Set the flag indicating if Fast I/O is possible
127 CdLockFcb( IrpContext
, Fcb
);
128 Fcb
->IsFastIoPossible
= CdIsFastIoPossible( Fcb
);
129 CdUnlockFcb( IrpContext
, Fcb
);
132 // Complete the request.
135 CdCompleteRequest( IrpContext
, NULL
, Status
);
141 NTAPI
/* ReactOS Change: GCC Does not support STDCALL by default */
143 _In_ PFILE_OBJECT FileObject
,
144 _In_ PLARGE_INTEGER FileOffset
,
145 _In_ PLARGE_INTEGER Length
,
146 _In_ PEPROCESS ProcessId
,
148 _In_ BOOLEAN FailImmediately
,
149 _In_ BOOLEAN ExclusiveLock
,
150 _Out_ PIO_STATUS_BLOCK IoStatus
,
151 _In_ PDEVICE_OBJECT DeviceObject
158 This is a call back routine for doing the fast lock call.
162 FileObject - Supplies the file object used in this operation
164 FileOffset - Supplies the file offset used in this operation
166 Length - Supplies the length used in this operation
168 ProcessId - Supplies the process ID used in this operation
170 Key - Supplies the key used in this operation
172 FailImmediately - Indicates if the request should fail immediately
173 if the lock cannot be granted.
175 ExclusiveLock - Indicates if this is a request for an exclusive or
178 IoStatus - Receives the Status if this operation is successful
182 BOOLEAN - TRUE if this operation completed and FALSE if caller
183 needs to take the long route.
188 BOOLEAN Results
= FALSE
;
191 TYPE_OF_OPEN TypeOfOpen
;
195 UNREFERENCED_PARAMETER( DeviceObject
);
197 ASSERT_FILE_OBJECT( FileObject
);
199 IoStatus
->Information
= 0;
202 // Decode the type of file object we're being asked to process and
203 // make sure that is is only a user file open.
206 TypeOfOpen
= CdFastDecodeFileObject( FileObject
, &Fcb
);
208 if (TypeOfOpen
!= UserFileOpen
) {
210 IoStatus
->Status
= STATUS_INVALID_PARAMETER
;
215 // Only deal with 'good' Fcb's.
218 if (!CdVerifyFcbOperation( NULL
, Fcb
)) {
223 FsRtlEnterFileSystem();
226 // Use a try-finally to facilitate cleanup.
232 // We check whether we can proceed based on the state of the file oplocks.
235 if (!FsRtlOplockIsFastIoPossible( CdGetFcbOplock(Fcb
) )) {
237 try_return( NOTHING
);
241 // If we don't have a file lock, then get one now.
244 if ((Fcb
->FileLock
== NULL
) && !CdCreateFileLock( NULL
, Fcb
, FALSE
)) {
246 try_return( NOTHING
);
250 // Now call the FsRtl routine to perform the lock request.
254 #pragma prefast(suppress: 28159, "prefast thinks this is an obsolete routine, but it is ok for CDFS to use it")
256 if ((Results
= FsRtlFastLock( Fcb
->FileLock
,
269 // Set the flag indicating if Fast I/O is questionable. We
270 // only change this flag if the current state is possible.
271 // Retest again after synchronizing on the header.
274 if (Fcb
->IsFastIoPossible
== FastIoIsPossible
) {
276 CdLockFcb( NULL
, Fcb
);
277 Fcb
->IsFastIoPossible
= CdIsFastIoPossible( Fcb
);
278 CdUnlockFcb( NULL
, Fcb
);
285 FsRtlExitFileSystem();
293 NTAPI
/* ReactOS Change: GCC Does not support STDCALL by default */
295 _In_ PFILE_OBJECT FileObject
,
296 _In_ PLARGE_INTEGER FileOffset
,
297 _In_ PLARGE_INTEGER Length
,
298 _In_ PEPROCESS ProcessId
,
300 _Out_ PIO_STATUS_BLOCK IoStatus
,
301 _In_ PDEVICE_OBJECT DeviceObject
308 This is a call back routine for doing the fast unlock single call.
312 FileObject - Supplies the file object used in this operation
314 FileOffset - Supplies the file offset used in this operation
316 Length - Supplies the length used in this operation
318 ProcessId - Supplies the process ID used in this operation
320 Key - Supplies the key used in this operation
322 Status - Receives the Status if this operation is successful
326 BOOLEAN - TRUE if this operation completed and FALSE if caller
327 needs to take the long route.
332 BOOLEAN Results
= FALSE
;
333 TYPE_OF_OPEN TypeOfOpen
;
338 UNREFERENCED_PARAMETER( DeviceObject
);
340 IoStatus
->Information
= 0;
343 // Decode the type of file object we're being asked to process and
344 // make sure that is is only a user file open.
347 TypeOfOpen
= CdFastDecodeFileObject( FileObject
, &Fcb
);
349 if (TypeOfOpen
!= UserFileOpen
) {
351 IoStatus
->Status
= STATUS_INVALID_PARAMETER
;
356 // Only deal with 'good' Fcb's.
359 if (!CdVerifyFcbOperation( NULL
, Fcb
)) {
365 // If there is no lock then return immediately.
368 if (Fcb
->FileLock
== NULL
) {
370 IoStatus
->Status
= STATUS_RANGE_NOT_LOCKED
;
374 FsRtlEnterFileSystem();
379 // We check whether we can proceed based on the state of the file oplocks.
382 if (!FsRtlOplockIsFastIoPossible( CdGetFcbOplock(Fcb
) )) {
384 try_return( NOTHING
);
388 // If we don't have a file lock, then get one now.
391 if ((Fcb
->FileLock
== NULL
) && !CdCreateFileLock( NULL
, Fcb
, FALSE
)) {
393 try_return( NOTHING
);
397 // Now call the FsRtl routine to do the actual processing of the
398 // Lock request. The call will always succeed.
402 IoStatus
->Status
= FsRtlFastUnlockSingle( Fcb
->FileLock
,
412 // Set the flag indicating if Fast I/O is possible. We are
413 // only concerned if there are no longer any filelocks on this
417 if (!FsRtlAreThereCurrentFileLocks( Fcb
->FileLock
) &&
418 (Fcb
->IsFastIoPossible
!= FastIoIsPossible
)) {
420 CdLockFcb( IrpContext
, Fcb
);
421 Fcb
->IsFastIoPossible
= CdIsFastIoPossible( Fcb
);
422 CdUnlockFcb( IrpContext
, Fcb
);
428 FsRtlExitFileSystem();
436 NTAPI
/* ReactOS Change: GCC Does not support STDCALL by default */
438 _In_ PFILE_OBJECT FileObject
,
439 _In_ PEPROCESS ProcessId
,
440 _Out_ PIO_STATUS_BLOCK IoStatus
,
441 _In_ PDEVICE_OBJECT DeviceObject
448 This is a call back routine for doing the fast unlock all call.
452 FileObject - Supplies the file object used in this operation
454 ProcessId - Supplies the process ID used in this operation
456 Status - Receives the Status if this operation is successful
460 BOOLEAN - TRUE if this operation completed and FALSE if caller
461 needs to take the long route.
466 BOOLEAN Results
= FALSE
;
467 TYPE_OF_OPEN TypeOfOpen
;
472 UNREFERENCED_PARAMETER( DeviceObject
);
474 IoStatus
->Information
= 0;
477 // Decode the type of file object we're being asked to process and
478 // make sure that is is only a user file open.
481 TypeOfOpen
= CdFastDecodeFileObject( FileObject
, &Fcb
);
483 if (TypeOfOpen
!= UserFileOpen
) {
485 IoStatus
->Status
= STATUS_INVALID_PARAMETER
;
490 // Only deal with 'good' Fcb's.
493 if (!CdVerifyFcbOperation( NULL
, Fcb
)) {
499 // If there is no lock then return immediately.
502 if (Fcb
->FileLock
== NULL
) {
504 IoStatus
->Status
= STATUS_RANGE_NOT_LOCKED
;
508 FsRtlEnterFileSystem();
513 // We check whether we can proceed based on the state of the file oplocks.
516 if (!FsRtlOplockIsFastIoPossible( CdGetFcbOplock(Fcb
) )) {
518 try_return( NOTHING
);
522 // If we don't have a file lock, then get one now.
525 if ((Fcb
->FileLock
== NULL
) && !CdCreateFileLock( NULL
, Fcb
, FALSE
)) {
527 try_return( NOTHING
);
531 // Now call the FsRtl routine to do the actual processing of the
532 // Lock request. The call will always succeed.
536 IoStatus
->Status
= FsRtlFastUnlockAll( Fcb
->FileLock
,
543 // Set the flag indicating if Fast I/O is possible
546 CdLockFcb( IrpContext
, Fcb
);
547 Fcb
->IsFastIoPossible
= CdIsFastIoPossible( Fcb
);
548 CdUnlockFcb( IrpContext
, Fcb
);
553 FsRtlExitFileSystem();
561 NTAPI
/* ReactOS Change: GCC Does not support STDCALL by default */
562 CdFastUnlockAllByKey (
563 _In_ PFILE_OBJECT FileObject
,
564 _In_ PVOID ProcessId
,
566 _Out_ PIO_STATUS_BLOCK IoStatus
,
567 _In_ PDEVICE_OBJECT DeviceObject
574 This is a call back routine for doing the fast unlock all by key call.
578 FileObject - Supplies the file object used in this operation
580 ProcessId - Supplies the process ID used in this operation
582 Key - Supplies the key used in this operation
584 Status - Receives the Status if this operation is successful
588 BOOLEAN - TRUE if this operation completed and FALSE if caller
589 needs to take the long route.
594 BOOLEAN Results
= FALSE
;
595 TYPE_OF_OPEN TypeOfOpen
;
600 UNREFERENCED_PARAMETER( DeviceObject
);
602 IoStatus
->Information
= 0;
605 // Decode the type of file object we're being asked to process and
606 // make sure that is is only a user file open.
609 TypeOfOpen
= CdFastDecodeFileObject( FileObject
, &Fcb
);
611 if (TypeOfOpen
!= UserFileOpen
) {
613 IoStatus
->Status
= STATUS_INVALID_PARAMETER
;
618 // Only deal with 'good' Fcb's.
621 if (!CdVerifyFcbOperation( NULL
, Fcb
)) {
627 // If there is no lock then return immediately.
630 if (Fcb
->FileLock
== NULL
) {
632 IoStatus
->Status
= STATUS_RANGE_NOT_LOCKED
;
636 FsRtlEnterFileSystem();
641 // We check whether we can proceed based on the state of the file oplocks.
644 if (!FsRtlOplockIsFastIoPossible( CdGetFcbOplock(Fcb
) )) {
646 try_return( NOTHING
);
650 // If we don't have a file lock, then get one now.
653 if ((Fcb
->FileLock
== NULL
) && !CdCreateFileLock( NULL
, Fcb
, FALSE
)) {
655 try_return( NOTHING
);
659 // Now call the FsRtl routine to do the actual processing of the
660 // Lock request. The call will always succeed.
664 IoStatus
->Status
= FsRtlFastUnlockAllByKey( Fcb
->FileLock
,
672 // Set the flag indicating if Fast I/O is possible
675 CdLockFcb( IrpContext
, Fcb
);
676 Fcb
->IsFastIoPossible
= CdIsFastIoPossible( Fcb
);
677 CdUnlockFcb( IrpContext
, Fcb
);
682 FsRtlExitFileSystem();