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 IN 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( &Fcb
->Oplock
,
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
,
148 BOOLEAN FailImmediately
,
149 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 ASSERT_FILE_OBJECT( FileObject
);
197 IoStatus
->Information
= 0;
200 // Decode the type of file object we're being asked to process and
201 // make sure that is is only a user file open.
204 TypeOfOpen
= CdFastDecodeFileObject( FileObject
, &Fcb
);
206 if (TypeOfOpen
!= UserFileOpen
) {
208 IoStatus
->Status
= STATUS_INVALID_PARAMETER
;
213 // Only deal with 'good' Fcb's.
216 if (!CdVerifyFcbOperation( NULL
, Fcb
)) {
221 FsRtlEnterFileSystem();
224 // Use a try-finally to facilitate cleanup.
230 // We check whether we can proceed based on the state of the file oplocks.
233 if ((Fcb
->Oplock
!= NULL
) && !FsRtlOplockIsFastIoPossible( &Fcb
->Oplock
)) {
235 try_return( NOTHING
);
239 // If we don't have a file lock, then get one now.
242 if ((Fcb
->FileLock
== NULL
) && !CdCreateFileLock( NULL
, Fcb
, FALSE
)) {
244 try_return( NOTHING
);
248 // Now call the FsRtl routine to perform the lock request.
250 /* ReactOS Change: GCC "suggest parentheses around assignment used as truth value" */
251 if ((Results
= FsRtlFastLock( Fcb
->FileLock
,
264 // Set the flag indicating if Fast I/O is questionable. We
265 // only change this flag if the current state is possible.
266 // Retest again after synchronizing on the header.
269 if (Fcb
->IsFastIoPossible
== FastIoIsPossible
) {
271 CdLockFcb( NULL
, Fcb
);
272 Fcb
->IsFastIoPossible
= CdIsFastIoPossible( Fcb
);
273 CdUnlockFcb( NULL
, Fcb
);
280 FsRtlExitFileSystem();
288 NTAPI
/* ReactOS Change: GCC Does not support STDCALL by default */
290 IN PFILE_OBJECT FileObject
,
291 IN PLARGE_INTEGER FileOffset
,
292 IN PLARGE_INTEGER Length
,
295 OUT PIO_STATUS_BLOCK IoStatus
,
296 IN PDEVICE_OBJECT DeviceObject
303 This is a call back routine for doing the fast unlock single call.
307 FileObject - Supplies the file object used in this operation
309 FileOffset - Supplies the file offset used in this operation
311 Length - Supplies the length used in this operation
313 ProcessId - Supplies the process ID used in this operation
315 Key - Supplies the key used in this operation
317 Status - Receives the Status if this operation is successful
321 BOOLEAN - TRUE if this operation completed and FALSE if caller
322 needs to take the long route.
327 BOOLEAN Results
= FALSE
;
328 TYPE_OF_OPEN TypeOfOpen
;
333 IoStatus
->Information
= 0;
336 // Decode the type of file object we're being asked to process and
337 // make sure that is is only a user file open.
340 TypeOfOpen
= CdFastDecodeFileObject( FileObject
, &Fcb
);
342 if (TypeOfOpen
!= UserFileOpen
) {
344 IoStatus
->Status
= STATUS_INVALID_PARAMETER
;
349 // Only deal with 'good' Fcb's.
352 if (!CdVerifyFcbOperation( NULL
, Fcb
)) {
358 // If there is no lock then return immediately.
361 if (Fcb
->FileLock
== NULL
) {
363 IoStatus
->Status
= STATUS_RANGE_NOT_LOCKED
;
367 FsRtlEnterFileSystem();
372 // We check whether we can proceed based on the state of the file oplocks.
375 if ((Fcb
->Oplock
!= NULL
) && !FsRtlOplockIsFastIoPossible( &Fcb
->Oplock
)) {
377 try_return( NOTHING
);
381 // If we don't have a file lock, then get one now.
384 if ((Fcb
->FileLock
== NULL
) && !CdCreateFileLock( NULL
, Fcb
, FALSE
)) {
386 try_return( NOTHING
);
390 // Now call the FsRtl routine to do the actual processing of the
391 // Lock request. The call will always succeed.
395 IoStatus
->Status
= FsRtlFastUnlockSingle( Fcb
->FileLock
,
405 // Set the flag indicating if Fast I/O is possible. We are
406 // only concerned if there are no longer any filelocks on this
410 if (!FsRtlAreThereCurrentFileLocks( Fcb
->FileLock
) &&
411 (Fcb
->IsFastIoPossible
!= FastIoIsPossible
)) {
413 CdLockFcb( IrpContext
, Fcb
);
414 Fcb
->IsFastIoPossible
= CdIsFastIoPossible( Fcb
);
415 CdUnlockFcb( IrpContext
, Fcb
);
421 FsRtlExitFileSystem();
429 NTAPI
/* ReactOS Change: GCC Does not support STDCALL by default */
431 IN PFILE_OBJECT FileObject
,
433 OUT PIO_STATUS_BLOCK IoStatus
,
434 IN PDEVICE_OBJECT DeviceObject
441 This is a call back routine for doing the fast unlock all call.
445 FileObject - Supplies the file object used in this operation
447 ProcessId - Supplies the process ID used in this operation
449 Status - Receives the Status if this operation is successful
453 BOOLEAN - TRUE if this operation completed and FALSE if caller
454 needs to take the long route.
459 BOOLEAN Results
= FALSE
;
460 TYPE_OF_OPEN TypeOfOpen
;
465 IoStatus
->Information
= 0;
468 // Decode the type of file object we're being asked to process and
469 // make sure that is is only a user file open.
472 TypeOfOpen
= CdFastDecodeFileObject( FileObject
, &Fcb
);
474 if (TypeOfOpen
!= UserFileOpen
) {
476 IoStatus
->Status
= STATUS_INVALID_PARAMETER
;
481 // Only deal with 'good' Fcb's.
484 if (!CdVerifyFcbOperation( NULL
, Fcb
)) {
490 // If there is no lock then return immediately.
493 if (Fcb
->FileLock
== NULL
) {
495 IoStatus
->Status
= STATUS_RANGE_NOT_LOCKED
;
499 FsRtlEnterFileSystem();
504 // We check whether we can proceed based on the state of the file oplocks.
507 if ((Fcb
->Oplock
!= NULL
) && !FsRtlOplockIsFastIoPossible( &Fcb
->Oplock
)) {
509 try_return( NOTHING
);
513 // If we don't have a file lock, then get one now.
516 if ((Fcb
->FileLock
== NULL
) && !CdCreateFileLock( NULL
, Fcb
, FALSE
)) {
518 try_return( NOTHING
);
522 // Now call the FsRtl routine to do the actual processing of the
523 // Lock request. The call will always succeed.
527 IoStatus
->Status
= FsRtlFastUnlockAll( Fcb
->FileLock
,
534 // Set the flag indicating if Fast I/O is possible
537 CdLockFcb( IrpContext
, Fcb
);
538 Fcb
->IsFastIoPossible
= CdIsFastIoPossible( Fcb
);
539 CdUnlockFcb( IrpContext
, Fcb
);
544 FsRtlExitFileSystem();
552 NTAPI
/* ReactOS Change: GCC Does not support STDCALL by default */
553 CdFastUnlockAllByKey (
554 IN PFILE_OBJECT FileObject
,
557 OUT PIO_STATUS_BLOCK IoStatus
,
558 IN PDEVICE_OBJECT DeviceObject
565 This is a call back routine for doing the fast unlock all by key call.
569 FileObject - Supplies the file object used in this operation
571 ProcessId - Supplies the process ID used in this operation
573 Key - Supplies the key used in this operation
575 Status - Receives the Status if this operation is successful
579 BOOLEAN - TRUE if this operation completed and FALSE if caller
580 needs to take the long route.
585 BOOLEAN Results
= FALSE
;
586 TYPE_OF_OPEN TypeOfOpen
;
591 IoStatus
->Information
= 0;
594 // Decode the type of file object we're being asked to process and
595 // make sure that is is only a user file open.
598 TypeOfOpen
= CdFastDecodeFileObject( FileObject
, &Fcb
);
600 if (TypeOfOpen
!= UserFileOpen
) {
602 IoStatus
->Status
= STATUS_INVALID_PARAMETER
;
607 // Only deal with 'good' Fcb's.
610 if (!CdVerifyFcbOperation( NULL
, Fcb
)) {
616 // If there is no lock then return immediately.
619 if (Fcb
->FileLock
== NULL
) {
621 IoStatus
->Status
= STATUS_RANGE_NOT_LOCKED
;
625 FsRtlEnterFileSystem();
630 // We check whether we can proceed based on the state of the file oplocks.
633 if ((Fcb
->Oplock
!= NULL
) && !FsRtlOplockIsFastIoPossible( &Fcb
->Oplock
)) {
635 try_return( NOTHING
);
639 // If we don't have a file lock, then get one now.
642 if ((Fcb
->FileLock
== NULL
) && !CdCreateFileLock( NULL
, Fcb
, FALSE
)) {
644 try_return( NOTHING
);
648 // Now call the FsRtl routine to do the actual processing of the
649 // Lock request. The call will always succeed.
653 IoStatus
->Status
= FsRtlFastUnlockAllByKey( Fcb
->FileLock
,
661 // Set the flag indicating if Fast I/O is possible
664 CdLockFcb( IrpContext
, Fcb
);
665 Fcb
->IsFastIoPossible
= CdIsFastIoPossible( Fcb
);
666 CdUnlockFcb( IrpContext
, Fcb
);
671 FsRtlExitFileSystem();