1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
/*
 * 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;<--- Status is assigned
            _SEH2_LEAVE;
        }

        FileObject = IrpContext->FileObject;

        Fcb = (PEXT2_FCB) FileObject->FsContext;
        ASSERT(Fcb != NULL);
        if (Fcb->Identifier.Type == EXT2VCB) {
            Status = STATUS_INVALID_PARAMETER;<--- Status is assigned
            _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;<--- Status is assigned
            _SEH2_LEAVE;
        }

        ExAcquireResourceSharedLite(&Fcb->MainResource, TRUE);
        bFcbAcquired = TRUE;

        Irp = IrpContext->Irp;

        CompleteIrp = FALSE;

        Status = FsRtlCheckOplock( &Fcb->Oplock,<--- Status is overwritten<--- Status is overwritten<--- Status is overwritten
                                   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;
}