Something went wrong. Try again.
Reactos
Something went wrong. Try again.
16 kB · 689 lines
C
at master
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690/*++
Copyright (c) 1989-2000 Microsoft Corporation
Module Name:
LockCtrl.c
Abstract:
This module implements the Lock Control routines for Cdfs called by the Fsd/Fsp dispatch driver.
--*/
#include "cdprocs.h"
//// The Bug check file id for this module//
#define BugCheckFileId (CDFS_BUG_CHECK_LOCKCTRL)
#ifdef ALLOC_PRAGMA#pragma alloc_text(PAGE, CdCommonLockControl)#pragma alloc_text(PAGE, CdFastLock)#pragma alloc_text(PAGE, CdFastUnlockAll)#pragma alloc_text(PAGE, CdFastUnlockAllByKey)#pragma alloc_text(PAGE, CdFastUnlockSingle)#endif
NTSTATUSCdCommonLockControl ( _Inout_ PIRP_CONTEXT IrpContext, _Inout_ 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 = IoGetCurrentIrpStackLocation( Irp );
TYPE_OF_OPEN TypeOfOpen; PFCB Fcb; PCCB Ccb;
PAGED_CODE();
// // Extract and decode the type of file object we're being asked to process //
TypeOfOpen = CdDecodeFileObject( IrpContext, IrpSp->FileObject, &Fcb, &Ccb );
// // If the file is not a user file open then we reject the request // as an invalid parameter //
if (TypeOfOpen != UserFileOpen) {
CdCompleteRequest( IrpContext, Irp, STATUS_INVALID_PARAMETER ); return STATUS_INVALID_PARAMETER; }
// // We check whether we can proceed based on the state of the file oplocks. // This call might post the irp for us. //
Status = FsRtlCheckOplock( CdGetFcbOplock(Fcb), Irp, IrpContext, (PVOID)CdOplockComplete,/* ReactOS Change: GCC "assignment from incompatible pointer type" */ NULL );
// // If we don't get success then the oplock package completed the request. //
if (Status != STATUS_SUCCESS) {
return Status; }
// // Verify the Fcb. //
CdVerifyFcbOperation( IrpContext, Fcb );
// // If we don't have a file lock, then get one now. //
if (Fcb->FileLock == NULL) { CdCreateFileLock( IrpContext, Fcb, TRUE ); }
// // Now call the FsRtl routine to do the actual processing of the // Lock request //
Status = FsRtlProcessFileLock( Fcb->FileLock, Irp, NULL );
// // Set the flag indicating if Fast I/O is possible //
CdLockFcb( IrpContext, Fcb ); Fcb->IsFastIoPossible = CdIsFastIoPossible( Fcb ); CdUnlockFcb( IrpContext, Fcb );
// // Complete the request. //
CdCompleteRequest( IrpContext, NULL, Status ); return Status;}
BOOLEANNTAPI /* ReactOS Change: GCC Does not support STDCALL by default */CdFastLock ( _In_ PFILE_OBJECT FileObject, _In_ PLARGE_INTEGER FileOffset, _In_ PLARGE_INTEGER Length, _In_ PEPROCESS ProcessId, _In_ ULONG Key, _In_ BOOLEAN FailImmediately, _In_ 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 = FALSE;
PFCB Fcb; TYPE_OF_OPEN TypeOfOpen;
PAGED_CODE();
UNREFERENCED_PARAMETER( DeviceObject );
ASSERT_FILE_OBJECT( FileObject );
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; }
FsRtlEnterFileSystem();
// // Use a try-finally to facilitate cleanup. //
_SEH2_TRY {
// // We check whether we can proceed based on the state of the file oplocks. //
if (!FsRtlOplockIsFastIoPossible( CdGetFcbOplock(Fcb) )) {
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 perform the lock request. //
#ifdef _MSC_VER#pragma prefast(suppress: 28159, "prefast thinks this is an obsolete routine, but it is ok for CDFS to use it")#endif if ((Results = FsRtlFastLock( Fcb->FileLock, FileObject, FileOffset, Length, ProcessId, Key, FailImmediately, ExclusiveLock, IoStatus, NULL, FALSE )) != FALSE) {
// // Set the flag indicating if Fast I/O is questionable. We // only change this flag if the current state is possible. // Retest again after synchronizing on the header. //
if (Fcb->IsFastIoPossible == FastIoIsPossible) {
CdLockFcb( NULL, Fcb ); Fcb->IsFastIoPossible = CdIsFastIoPossible( Fcb ); CdUnlockFcb( NULL, Fcb ); } }
try_exit: NOTHING; } _SEH2_FINALLY {
FsRtlExitFileSystem(); } _SEH2_END;
return Results;}
BOOLEANNTAPI /* ReactOS Change: GCC Does not support STDCALL by default */CdFastUnlockSingle ( _In_ PFILE_OBJECT FileObject, _In_ PLARGE_INTEGER FileOffset, _In_ PLARGE_INTEGER Length, _In_ PEPROCESS ProcessId, _In_ 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 = FALSE; TYPE_OF_OPEN TypeOfOpen; PFCB Fcb;
PAGED_CODE();
UNREFERENCED_PARAMETER( DeviceObject );
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();
_SEH2_TRY {
// // We check whether we can proceed based on the state of the file oplocks. //
if (!FsRtlOplockIsFastIoPossible( CdGetFcbOplock(Fcb) )) {
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 = FsRtlFastUnlockSingle( Fcb->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( Fcb->FileLock ) && (Fcb->IsFastIoPossible != FastIoIsPossible)) {
CdLockFcb( IrpContext, Fcb ); Fcb->IsFastIoPossible = CdIsFastIoPossible( Fcb ); CdUnlockFcb( IrpContext, Fcb ); }
try_exit: NOTHING; } _SEH2_FINALLY {
FsRtlExitFileSystem(); } _SEH2_END;
return Results;}
BOOLEANNTAPI /* ReactOS Change: GCC Does not support STDCALL by default */CdFastUnlockAll ( _In_ PFILE_OBJECT FileObject, _In_ 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 = FALSE; TYPE_OF_OPEN TypeOfOpen; PFCB Fcb;
PAGED_CODE();
UNREFERENCED_PARAMETER( DeviceObject );
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();
_SEH2_TRY {
// // We check whether we can proceed based on the state of the file oplocks. //
if (!FsRtlOplockIsFastIoPossible( CdGetFcbOplock(Fcb) )) {
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 = FsRtlFastUnlockAll( Fcb->FileLock, FileObject, ProcessId, NULL );
// // Set the flag indicating if Fast I/O is possible //
CdLockFcb( IrpContext, Fcb ); Fcb->IsFastIoPossible = CdIsFastIoPossible( Fcb ); CdUnlockFcb( IrpContext, Fcb );
try_exit: NOTHING; } _SEH2_FINALLY {
FsRtlExitFileSystem(); } _SEH2_END;
return Results;}
BOOLEANNTAPI /* ReactOS Change: GCC Does not support STDCALL by default */CdFastUnlockAllByKey ( _In_ PFILE_OBJECT FileObject, _In_ PVOID ProcessId, _In_ 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();
UNREFERENCED_PARAMETER( DeviceObject );
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();
_SEH2_TRY {
// // We check whether we can proceed based on the state of the file oplocks. //
if (!FsRtlOplockIsFastIoPossible( CdGetFcbOplock(Fcb) )) {
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; } _SEH2_FINALLY {
FsRtlExitFileSystem(); } _SEH2_END;
return Results;}