reactos/drivers/filesystems/ffs/src/lock.c

137 lines
2.6 KiB
C

/*
* FFS File System Driver for Windows
*
* lock.c
*
* 2004.5.6 ~
*
* Lee Jae-Hong, http://www.pyrasis.com
*
* See License.txt
*
*/
#include "ntifs.h"
#include "ffsdrv.h"
/* Globals */
extern PFFS_GLOBAL FFSGlobal;
/* Definitions */
#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE, FFSLockControl)
#endif
__drv_mustHoldCriticalRegion
NTSTATUS
FFSLockControl(
IN PFFS_IRP_CONTEXT IrpContext)
{
PDEVICE_OBJECT DeviceObject;
BOOLEAN CompleteRequest;
NTSTATUS Status = STATUS_UNSUCCESSFUL;
PFILE_OBJECT FileObject;
PFFS_FCB Fcb;
PIRP Irp;
PAGED_CODE();
_SEH2_TRY
{
ASSERT(IrpContext != NULL);
ASSERT((IrpContext->Identifier.Type == FFSICX) &&
(IrpContext->Identifier.Size == sizeof(FFS_IRP_CONTEXT)));
DeviceObject = IrpContext->DeviceObject;
if (DeviceObject == FFSGlobal->DeviceObject)
{
CompleteRequest = TRUE;
Status = STATUS_INVALID_DEVICE_REQUEST;
_SEH2_LEAVE;
}
FileObject = IrpContext->FileObject;
Fcb = (PFFS_FCB)FileObject->FsContext;
ASSERT(Fcb != NULL);
if (Fcb->Identifier.Type == FFSVCB)
{
CompleteRequest = TRUE;
Status = STATUS_INVALID_PARAMETER;
_SEH2_LEAVE;
}
ASSERT((Fcb->Identifier.Type == FFSFCB) &&
(Fcb->Identifier.Size == sizeof(FFS_FCB)));
if (FlagOn(Fcb->FFSMcb->FileAttr, FILE_ATTRIBUTE_DIRECTORY))
{
CompleteRequest = TRUE;
Status = STATUS_INVALID_PARAMETER;
_SEH2_LEAVE;
}
Irp = IrpContext->Irp;
//
// While the file has any byte range locks we set IsFastIoPossible to
// FastIoIsQuestionable so that the FastIoCheckIfPossible function is
// called to check the locks for any fast I/O read/write operation.
//
if (Fcb->Header.IsFastIoPossible != FastIoIsQuestionable)
{
FFSPrint((DBG_INFO,
"FFSLockControl: %-16.16s %-31s %s\n",
FFSGetCurrentProcessName(),
"FastIoIsQuestionable",
Fcb->AnsiFileName.Buffer));
Fcb->Header.IsFastIoPossible = FastIoIsQuestionable;
}
//
// FsRtlProcessFileLock acquires FileObject->FsContext->Resource while
// modifying the file locks and calls IoCompleteRequest when it's done.
//
CompleteRequest = FALSE;
Status = FsRtlProcessFileLock(
&Fcb->FileLockAnchor,
Irp,
NULL);
if (!NT_SUCCESS(Status))
{
FFSPrint((DBG_ERROR,
"FFSLockControl: %-16.16s %-31s *** Status: %s (%#x) ***\n",
FFSGetCurrentProcessName(),
"IRP_MJ_LOCK_CONTROL",
FFSNtStatusToString(Status),
Status));
}
}
_SEH2_FINALLY
{
if (!IrpContext->ExceptionInProgress)
{
if (!CompleteRequest)
{
IrpContext->Irp = NULL;
}
FFSCompleteIrpContext(IrpContext, Status);
}
} _SEH2_END;
return Status;
}