summaryrefslogtreecommitdiffstats
path: root/private/newsam2/server/close.c
blob: 8443b329fe960fbcc3137dc9b0d05d8a44922b4e (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
169
170
171
172
173
174
175
176
177
178
179
180
181
/*++

Copyright (c) 1990  Microsoft Corporation

Module Name:

    close.c

Abstract:

    This file contains the object close routine for SAM objects.


Author:

    Jim Kelly    (JimK)  4-July-1991

Environment:

    User Mode - Win32

Revision History:


--*/

///////////////////////////////////////////////////////////////////////////////
//                                                                           //
// Includes                                                                  //
//                                                                           //
///////////////////////////////////////////////////////////////////////////////

#include <samsrvp.h>





///////////////////////////////////////////////////////////////////////////////
//                                                                           //
// private service prototypes                                                //
//                                                                           //
///////////////////////////////////////////////////////////////////////////////





///////////////////////////////////////////////////////////////////////////////
//                                                                           //
// Routines                                                                  //
//                                                                           //
///////////////////////////////////////////////////////////////////////////////






NTSTATUS
SamrCloseHandle(
    IN OUT SAMPR_HANDLE * SamHandle
    )

/*++

Routine Description:

    This service closes a handle for any type of SAM object.

    Any race conditions that may occur with respect to attempts to
    close a handle that is just becoming invalid by other means are
    expected to be handled by the RPC runtime.  That is, this service
    will never be called by the RPC runtime when the handle value is
    no longer valid.  It will also never call this routine when there
    is another call outstanding with this same context handle.

Arguments:

    SamHandle - A valid handle to a SAM object.

Return Value:


    STATUS_SUCCESS - The handle has successfully been closed.

    Others that might be returned by:

                SampLookupcontext()


--*/
{
    NTSTATUS            NtStatus;
    PSAMP_OBJECT        Context;
    SAMP_OBJECT_TYPE    FoundType;

    SAMTRACE("SamrCloseHandle");

    Context = (PSAMP_OBJECT)(* SamHandle);

    //
    // Grab a read lock
    //

    SampAcquireReadLock();

    NtStatus = SampLookupContext(
                   Context,                     //Context
                   0,                           //DesiredAccess
                   SampUnknownObjectType,       //ExpectedType
                   &FoundType                   //FoundType
                   );

    if (NT_SUCCESS(NtStatus)) {

        //
        // Mark it for delete and remove the reference caused by
        // context creation (representing the handle reference).
        //

        SampDeleteContext( Context );

        //
        // And drop our reference from the lookup operation
        //

        SampDeReferenceContext( Context, FALSE );

        //
        // Tell RPC that the handle is no longer valid...
        //

        (*SamHandle) = NULL;
    }

    //
    // Free read lock
    //

    SampReleaseReadLock();

    if ( ( NT_SUCCESS( NtStatus ) ) &&
        ( FoundType == SampServerObjectType ) &&
        ( !(LastUnflushedChange.QuadPart == SampHasNeverTime.QuadPart) ) ) {

        //
        // Some app is closing the server object after having made
        // changes.  We should make sure that the changes get
        // flushed to disk before the app exits.  We need to get
        // the write lock for this.
        //

        FlushImmediately = TRUE;

        NtStatus = SampAcquireWriteLock();

        if ( NT_SUCCESS( NtStatus ) ) {

            if ( !(LastUnflushedChange.QuadPart ==SampHasNeverTime.QuadPart) ) {

                //
                // Nobody flushed while we were waiting for the
                // write lock.  So flush the changes now.
                //

                NtStatus = NtFlushKey( SampKey );

                if ( NT_SUCCESS( NtStatus ) ) {

                    FlushImmediately = FALSE;
                    LastUnflushedChange = SampHasNeverTime;
                }
            }

            SampReleaseWriteLock( FALSE );
        }
    }

    return(NtStatus);
}