1 /*++
2 
3 Copyright (c) Microsoft Corporation
4 
5 Module Name:
6 
7     FxWaitLockAPI.cpp
8 
9 Abstract:
10 
11     This module implements the external APIs for FxWaitLock
12 
13 Author:
14 
15 
16 
17 Environment:
18 
19    Both kernel and user mode
20 
21 Revision History:
22 
23 --*/
24 
25 #include "fxsupportpch.hpp"
26 
27 // extern the entire file
28 extern "C" {
29 
30 
31 _Must_inspect_result_
32 __drv_maxIRQL(DISPATCH_LEVEL)
33 NTSTATUS
34 WDFAPI
35 STDCALL
36 WDFEXPORT(WdfWaitLockCreate)(
37     __in
38     PWDF_DRIVER_GLOBALS DriverGlobals,
39      __in_opt
40     PWDF_OBJECT_ATTRIBUTES LockAttributes,
41     __out
42     WDFWAITLOCK* Lock
43     )
44 /*++
45 
46 Routine Description:
47     Creates a lock object which can be acquired at PASSIVE_LEVEL and will return
48     to the caller at PASSIVE_LEVEL once acquired.
49 
50 Arguments:
51     LockAttributes - generic attributes to be associated with the created lock
52 
53     Lock - pointer to receive the newly created lock
54 
55 Return Value:
56     NTSTATUS
57 
58   --*/
59 {
60     DDI_ENTRY();
61 
62     PFX_DRIVER_GLOBALS  fxDriverGlobals;
63     NTSTATUS            status;
64     FxObject*           parent;
65 
66     fxDriverGlobals = GetFxDriverGlobals(DriverGlobals);
67     parent = NULL;
68 
69     //
70     // Get the parent's globals if it is present
71     //
72     if (NT_SUCCESS(FxValidateObjectAttributesForParentHandle(fxDriverGlobals,
73                                                              LockAttributes))) {
74         FxObjectHandleGetPtrAndGlobals(fxDriverGlobals,
75                                        LockAttributes->ParentObject,
76                                        FX_TYPE_OBJECT,
77                                        (PVOID*)&parent,
78                                        &fxDriverGlobals);
79     }
80 
81     FxPointerNotNull(fxDriverGlobals, Lock);
82 
83     status = FxValidateObjectAttributes(fxDriverGlobals, LockAttributes);
84     if (!NT_SUCCESS(status)) {
85         return status;
86     }
87 
88     return FxWaitLock::_Create(fxDriverGlobals,
89                                LockAttributes,
90                                parent,
91                                TRUE,
92                                Lock);
93 }
94 
95 __drv_when(Timeout != 0, _Must_inspect_result_)
96 __drv_when(Timeout == 0, __drv_maxIRQL(PASSIVE_LEVEL))
97 __drv_when(Timeout != 0 && *Timeout == 0, __drv_maxIRQL(DISPATCH_LEVEL))
98 __drv_when(Timeout != 0 && *Timeout != 0, __drv_maxIRQL(PASSIVE_LEVEL))
99 NTSTATUS
100 WDFAPI
101 STDCALL
102 WDFEXPORT(WdfWaitLockAcquire)(
103     __in
104     PWDF_DRIVER_GLOBALS DriverGlobals,
105     __in
106     WDFWAITLOCK Lock,
107     __in_opt
108     PLONGLONG Timeout
109     )
110 /*++
111 
112 Routine Description:
113     Attempts to acquire the lock object.  If a non NULL timeout is provided, the
114     attempt to acquire the lock may fail if it cannot be acquired in the
115     specified time.
116 
117 Arguments:
118     Lock - the lock to acquire
119 
120     Timeout - optional timeout in acquiring the lock.  If calling at an IRQL >=
121               DISPATCH_LEVEL, then this parameter is not NULL (and should more
122               then likely be zero)
123 
124 Return Value:
125     STATUS_TIMEOUT if a timeout was provided and the lock could not be acquired
126     in the specified time, otherwise STATUS_SUCCESS
127 
128   --*/
129 {
130     DDI_ENTRY();
131 
132     PFX_DRIVER_GLOBALS pFxDriverGlobals;
133     FxWaitLock* pLock;
134     NTSTATUS status;
135 
136     FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
137                                    Lock,
138                                    FX_TYPE_WAIT_LOCK,
139                                    (PVOID*) &pLock,
140                                    &pFxDriverGlobals);
141 
142     if (Timeout == NULL || *Timeout != 0) {
143         status = FxVerifierCheckIrqlLevel(pFxDriverGlobals, PASSIVE_LEVEL);
144         if (!NT_SUCCESS(status)) {
145             return status;
146         }
147 
148     }
149 
150     return pLock->AcquireLock(pFxDriverGlobals, Timeout);
151 }
152 
153 __drv_maxIRQL(DISPATCH_LEVEL)
154 VOID
155 WDFAPI
156 STDCALL
157 WDFEXPORT(WdfWaitLockRelease)(
158     __in
159     PWDF_DRIVER_GLOBALS DriverGlobals,
160     __in
161     WDFWAITLOCK Lock
162     )
163 /*++
164 
165 Routine Description:
166     Releases a previously acquired wait lock
167 
168 Arguments:
169     Lock - the lock to release
170 
171   --*/
172 {
173     DDI_ENTRY();
174 
175     PFX_DRIVER_GLOBALS pFxDriverGlobals;
176     FxWaitLock* pLock;
177 
178     FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
179                                    Lock,
180                                    FX_TYPE_WAIT_LOCK,
181                                    (PVOID*) &pLock,
182                                    &pFxDriverGlobals);
183 
184     pLock->ReleaseLock(pFxDriverGlobals);
185 }
186 
187 } // extern "C"
188