Welcome to mirror list, hosted at ThFree Co, Russian Federation.

lock.c « Ext3Fsd - github.com/matt-wu/Ext3Fsd.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 3219f603cf8aab1cbfd8fd97fee7dde14b354a13 (plain)
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;

    __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;
            __leave;
        }

        FileObject = IrpContext->FileObject;

        Fcb = (PEXT2_FCB) FileObject->FsContext;
        ASSERT(Fcb != NULL);
        if (Fcb->Identifier.Type == EXT2VCB) {
            Status = STATUS_INVALID_PARAMETER;
            __leave;
        }

        ASSERT((Fcb->Identifier.Type == EXT2FCB) &&
               (Fcb->Identifier.Size == sizeof(EXT2_FCB)));

        if (FlagOn(Fcb->Mcb->FileAttr, FILE_ATTRIBUTE_DIRECTORY)) {
            Status = STATUS_INVALID_PARAMETER;
            __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;
            __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);

    } __finally {

        if (bFcbAcquired) {
            ExReleaseResourceLite(&Fcb->MainResource);
        }

        if (!IrpContext->ExceptionInProgress) {

            if (!CompleteIrp) {
                IrpContext->Irp = NULL;
            }

            if (CompleteContext) {
                Ext2CompleteIrpContext(IrpContext, Status);
            }
        }
    }

    return Status;
}