--- /dev/null
+/*
+ * COPYRIGHT: See COPYRIGHT.TXT
+ * PROJECT: Ext2 File System Driver for WinNT/2K/XP
+ * FILE: lock.c
+ * PROGRAMMER: Matt Wu <mattwu@163.com>
+ * HOMEPAGE: http://www.ext2fsd.com
+ * UPDATE HISTORY:
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include "ext2fs.h"
+
+/* GLOBALS ***************************************************************/
+
+extern PEXT2_GLOBAL Ext2Global;
+
+/* DEFINITIONS *************************************************************/
+
+#ifdef ALLOC_PRAGMA
+#pragma alloc_text(PAGE, Ext2LockControl)
+#endif
+
+NTSTATUS
+Ext2LockControl (IN PEXT2_IRP_CONTEXT IrpContext)
+{
+ PDEVICE_OBJECT DeviceObject = NULL;
+ PFILE_OBJECT FileObject = NULL;
+ PEXT2_FCB Fcb = NULL;
+ PIRP Irp = NULL;
+
+ NTSTATUS Status = STATUS_UNSUCCESSFUL;
+ BOOLEAN CompleteContext = TRUE;
+ BOOLEAN CompleteIrp = TRUE;
+ BOOLEAN bFcbAcquired = FALSE;
+
+ _SEH2_TRY {
+
+ ASSERT(IrpContext != NULL);
+
+ ASSERT((IrpContext->Identifier.Type == EXT2ICX) &&
+ (IrpContext->Identifier.Size == sizeof(EXT2_IRP_CONTEXT)));
+
+ DeviceObject = IrpContext->DeviceObject;
+
+ if (IsExt2FsDevice(DeviceObject)) {
+ Status = STATUS_INVALID_DEVICE_REQUEST;
+ _SEH2_LEAVE;
+ }
+
+ FileObject = IrpContext->FileObject;
+
+ Fcb = (PEXT2_FCB) FileObject->FsContext;
+ ASSERT(Fcb != NULL);
+ if (Fcb->Identifier.Type == EXT2VCB) {
+ Status = STATUS_INVALID_PARAMETER;
+ _SEH2_LEAVE;
+ }
+
+ ASSERT((Fcb->Identifier.Type == EXT2FCB) &&
+ (Fcb->Identifier.Size == sizeof(EXT2_FCB)));
+
+ if (FlagOn(Fcb->Mcb->FileAttr, FILE_ATTRIBUTE_DIRECTORY)) {
+ Status = STATUS_INVALID_PARAMETER;
+ _SEH2_LEAVE;
+ }
+
+ ExAcquireResourceSharedLite(&Fcb->MainResource, TRUE);
+ bFcbAcquired = TRUE;
+
+ Irp = IrpContext->Irp;
+
+ CompleteIrp = FALSE;
+
+ Status = FsRtlCheckOplock( &Fcb->Oplock,
+ Irp,
+ IrpContext,
+ Ext2OplockComplete,
+ NULL );
+
+ if (Status != STATUS_SUCCESS) {
+ CompleteContext = FALSE;
+ _SEH2_LEAVE;
+ }
+
+ //
+ // FsRtlProcessFileLock acquires FileObject->FsContext->Resource while
+ // modifying the file locks and calls IoCompleteRequest when it's done.
+ //
+
+ Status = FsRtlProcessFileLock(
+ &Fcb->FileLockAnchor,
+ Irp,
+ NULL );
+#if EXT2_DEBUG
+ if (!NT_SUCCESS(Status)) {
+ DEBUG(DL_ERR, (
+ "Ext2LockControl: %-16.16s %-31s Status: %#x ***\n",
+ Ext2GetCurrentProcessName(),
+ "IRP_MJ_LOCK_CONTROL",
+ Status ));
+ }
+#endif
+ Fcb->Header.IsFastIoPossible = Ext2IsFastIoPossible(Fcb);
+
+ } _SEH2_FINALLY {
+
+ if (bFcbAcquired) {
+ ExReleaseResourceLite(&Fcb->MainResource);
+ }
+
+ if (!IrpContext->ExceptionInProgress) {
+
+ if (!CompleteIrp) {
+ IrpContext->Irp = NULL;
+ }
+
+ if (CompleteContext) {
+ Ext2CompleteIrpContext(IrpContext, Status);
+ }
+ }
+ } _SEH2_END;
+
+ return Status;
+}