summaryrefslogtreecommitdiffstats
path: root/private/nw/rdr/lockcode.c
blob: 1a2941c2dd05e522312cf7e3e73da6e881d87a0d (plain) (blame)
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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168

/*++

Copyright (c) 1994  Microsoft Corporation

Module Name:

    lockcode.c

Abstract:

Author:

    Chuck Lenzmeier (chuckl) 30-Jan-1994
    Manny Weiser (mannyw)    17-May-1994

Revision History:

--*/

#include "Procs.h"


#ifndef QFE_BUILD

#ifdef ALLOC_PRAGMA
#pragma alloc_text( PAGE, NwReferenceUnlockableCodeSection )
#pragma alloc_text( PAGE, NwDereferenceUnlockableCodeSection )
#endif

extern BOOLEAN TimerStop;   //  From Timer.c

//
//  The debug trace level
//

#define Dbg                              (DEBUG_TRACE_CREATE)


VOID
NwReferenceUnlockableCodeSection (
    VOID
    )
{
    ULONG oldCount;

    //
    // Lock the lockable code database.
    //

    ExAcquireResourceExclusive( &NwUnlockableCodeResource, TRUE );

    //
    // Increment the reference count for the section.
    //

    oldCount = NwSectionDescriptor.ReferenceCount++;

    if ( oldCount == 0 && NwSectionDescriptor.Handle == NULL ) {

        //
        // This is the first reference to the section.  Start the timer.
        // Lock our code.
        //

        NwSectionDescriptor.Handle = MmLockPagableCodeSection( NwSectionDescriptor.Base );
        StartTimer( );

    } else {

        //
        // This is not the first reference to the section.  The section
        // had better be locked!
        //

        ASSERT( NwSectionDescriptor.Handle != NULL );

        //
        //  Restart the timer if the rdr was stopped but didn't unload.
        //

        if (TimerStop == TRUE) {
            StartTimer();
        }

    }

    DebugTrace(+0, Dbg, "NwReferenceCodeSection %d\n", NwSectionDescriptor.ReferenceCount );

    ExReleaseResource( &NwUnlockableCodeResource );

    return;

} // NwReferenceUnlockableCodeSection


VOID
NwDereferenceUnlockableCodeSection (
    VOID
    )
{
    ULONG newCount;

    //
    // Lock the lockable code database.
    //

    ExAcquireResourceExclusive( &NwUnlockableCodeResource, TRUE );

    ASSERT( NwSectionDescriptor.Handle != NULL );
    ASSERT( NwSectionDescriptor.ReferenceCount > 0 &&
            NwSectionDescriptor.ReferenceCount < 0x7FFF );

    //
    // Decrement the reference count for the section.
    //

    newCount = --NwSectionDescriptor.ReferenceCount;

    DebugTrace(+0, Dbg, "NwDereferenceCodeSection %d\n", NwSectionDescriptor.ReferenceCount );

    ExReleaseResource( &NwUnlockableCodeResource );

    return;

} // NwDereferenceUnlockableCodeSection

BOOLEAN
NwUnlockCodeSections(
    IN BOOLEAN BlockIndefinitely
    )
{
    //
    // Lock the lockable code database.
    //

    if (!ExAcquireResourceExclusive( &NwUnlockableCodeResource, BlockIndefinitely )) {
        return FALSE;   //  Avoid potential deadlock in timer.c
    }

    DebugTrace(+0, Dbg, "NwUnlockCodeSections %d\n", NwSectionDescriptor.ReferenceCount );

    if ( NwSectionDescriptor.ReferenceCount == 0 ) {

        if ( NwSectionDescriptor.Handle != NULL ) {

            //
            // This is the last reference to the section.  Stop the timer and
            // unlock the code.
            //

            StopTimer();

            MmUnlockPagableImageSection( NwSectionDescriptor.Handle );
            NwSectionDescriptor.Handle = NULL;

        }

        ExReleaseResource( &NwUnlockableCodeResource );
        return TRUE;
    }

    ExReleaseResource( &NwUnlockableCodeResource );
    return FALSE;

}

#endif