1 /*++
2
3 Copyright (c) Microsoft Corporation
4
5 Module Name:
6
7 FxCollectionApi.cpp
8
9 Abstract:
10
11 This module implements the "C" interface to the collection object.
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 "C" {
28 // #include "FxCollectionApi.tmh"
29 }
30
31 //
32 // Extern the entire file
33 //
34 extern "C" {
35 _Must_inspect_result_
__drv_maxIRQL(DISPATCH_LEVEL)36 __drv_maxIRQL(DISPATCH_LEVEL)
37 NTSTATUS
38 STDCALL
39 WDFEXPORT(WdfCollectionCreate)(
40 __in
41 PWDF_DRIVER_GLOBALS DriverGlobals,
42 __in_opt
43 PWDF_OBJECT_ATTRIBUTES CollectionAttributes,
44 __out
45 WDFCOLLECTION *Collection
46 )
47 {
48 DDI_ENTRY();
49
50 PFX_DRIVER_GLOBALS pFxDriverGlobals;
51 NTSTATUS status;
52 FxCollection *pCollection;
53 WDFCOLLECTION hCol;
54
55 pFxDriverGlobals = GetFxDriverGlobals(DriverGlobals);
56
57 //
58 // Get the parent's globals if it is present
59 //
60 if (NT_SUCCESS(FxValidateObjectAttributesForParentHandle(
61 pFxDriverGlobals, CollectionAttributes))) {
62 FxObject* pParent;
63
64 FxObjectHandleGetPtrAndGlobals(pFxDriverGlobals,
65 CollectionAttributes->ParentObject,
66 FX_TYPE_OBJECT,
67 (PVOID*)&pParent,
68 &pFxDriverGlobals);
69 }
70
71 FxPointerNotNull(pFxDriverGlobals, Collection);
72
73 *Collection = NULL;
74
75 status = FxValidateObjectAttributes(pFxDriverGlobals, CollectionAttributes);
76 if (!NT_SUCCESS(status)) {
77 return status;
78 }
79
80 pCollection = new (pFxDriverGlobals, CollectionAttributes)
81 FxCollection(pFxDriverGlobals);
82
83 if (pCollection != NULL) {
84 status = pCollection->Commit(CollectionAttributes, (WDFOBJECT*)&hCol);
85
86 if (NT_SUCCESS(status)) {
87 *Collection = hCol;
88 }
89 else {
90 DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGERROR,
91 "Could not create collection object: %!STATUS!",
92 status);
93
94 pCollection->DeleteFromFailedCreate();
95 }
96 }
97 else {
98 DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGERROR,
99 "Could not create collection object: "
100 "STATUS_INSUFFICIENT_RESOURCES" );
101 status = STATUS_INSUFFICIENT_RESOURCES;
102 }
103
104 return status;
105 }
106
__drv_maxIRQL(DISPATCH_LEVEL)107 __drv_maxIRQL(DISPATCH_LEVEL)
108 ULONG
109 STDCALL
110 WDFEXPORT(WdfCollectionGetCount)(
111 __in
112 PWDF_DRIVER_GLOBALS DriverGlobals,
113 __in
114 WDFCOLLECTION Collection
115 )
116 {
117 DDI_ENTRY();
118
119 FxCollection *pCollection;
120 KIRQL irql;
121 ULONG count;
122
123 FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals),
124 Collection,
125 FX_TYPE_COLLECTION,
126 (PVOID *)&pCollection);
127
128 pCollection->Lock(&irql);
129 count = pCollection->Count();
130 pCollection->Unlock(irql);
131
132 return count;
133 }
134
135 _Must_inspect_result_
__drv_maxIRQL(DISPATCH_LEVEL)136 __drv_maxIRQL(DISPATCH_LEVEL)
137 NTSTATUS
138 STDCALL
139 WDFEXPORT(WdfCollectionAdd)(
140 __in
141 PWDF_DRIVER_GLOBALS DriverGlobals,
142 __in
143 WDFCOLLECTION Collection,
144 __in
145 WDFOBJECT Object
146 )
147 {
148 DDI_ENTRY();
149
150 PFX_DRIVER_GLOBALS pFxDriverGlobals;
151 FxCollection *pCollection;
152 FxObject *pObject;
153 NTSTATUS status;
154 KIRQL irql;
155
156 FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
157 Collection,
158 FX_TYPE_COLLECTION,
159 (PVOID*) &pCollection,
160 &pFxDriverGlobals);
161
162 FxObjectHandleGetPtr(pFxDriverGlobals,
163 Object,
164 FX_TYPE_OBJECT,
165 (PVOID*) &pObject);
166
167 pCollection->Lock(&irql);
168 status = pCollection->Add(pObject) ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL;
169 pCollection->Unlock(irql);
170
171 return status;
172 }
173
__drv_maxIRQL(DISPATCH_LEVEL)174 __drv_maxIRQL(DISPATCH_LEVEL)
175 VOID
176 STDCALL
177 WDFEXPORT(WdfCollectionRemoveItem)(
178 __in
179 PWDF_DRIVER_GLOBALS DriverGlobals,
180 __in
181 WDFCOLLECTION Collection,
182 __in
183 ULONG Index
184 )
185 {
186 DDI_ENTRY();
187
188 PFX_DRIVER_GLOBALS pFxDriverGlobals;
189 FxCollection* pCollection;
190 FxCollectionEntry* pEntry;
191 FxObject* pObject;
192 NTSTATUS status;
193 KIRQL irql;
194
195 FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
196 Collection,
197 FX_TYPE_COLLECTION,
198 (PVOID*) &pCollection,
199 &pFxDriverGlobals);
200
201 pCollection->Lock(&irql);
202
203 pEntry = pCollection->FindEntry(Index);
204
205 if (pEntry != NULL) {
206 pObject = pEntry->m_Object;
207 pCollection->CleanupEntry(pEntry);
208 status = STATUS_SUCCESS;
209 }
210 else {
211 pObject = NULL;
212 status = STATUS_NOT_FOUND;
213 }
214
215 pCollection->Unlock(irql);
216
217 if (pObject != NULL) {
218 pCollection->CleanupEntryObject(pObject);
219 }
220
221 if (!NT_SUCCESS(status)) {
222 DoTraceLevelMessage(
223 pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGERROR,
224 "Index %d is not valid in WDFCOLLECTION %p (count is %d), %!STATUS!",
225 Index, Collection, pCollection->Count(), status);
226 FxVerifierDbgBreakPoint(pFxDriverGlobals);
227 }
228 }
229
__drv_maxIRQL(DISPATCH_LEVEL)230 __drv_maxIRQL(DISPATCH_LEVEL)
231 VOID
232 STDCALL
233 WDFEXPORT(WdfCollectionRemove)(
234 __in
235 PWDF_DRIVER_GLOBALS DriverGlobals,
236 __in
237 WDFCOLLECTION Collection,
238 __in
239 WDFOBJECT Item
240 )
241 {
242 DDI_ENTRY();
243
244 PFX_DRIVER_GLOBALS pFxDriverGlobals;
245 FxCollection *pCollection;
246 FxCollectionEntry *pEntry;
247 FxObject* pObject;
248 NTSTATUS status;
249 KIRQL irql;
250
251 FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
252 Collection,
253 FX_TYPE_COLLECTION,
254 (PVOID*) &pCollection,
255 &pFxDriverGlobals);
256
257 FxObjectHandleGetPtr(pFxDriverGlobals,
258 Item,
259 FX_TYPE_OBJECT,
260 (PVOID*) &pObject);
261
262 pCollection->Lock(&irql);
263
264 pEntry = pCollection->FindEntryByObject(pObject);
265
266 if (pEntry != NULL) {
267 pCollection->CleanupEntry(pEntry);
268 status = STATUS_SUCCESS;
269 }
270 else {
271 pObject = NULL;
272 status = STATUS_NOT_FOUND;
273 }
274
275 pCollection->Unlock(irql);
276
277 if (pObject != NULL) {
278 pCollection->CleanupEntryObject(pObject);
279 }
280
281 if (!NT_SUCCESS(status)) {
282 DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGERROR,
283 "WDFOBJECT %p not in WDFCOLLECTION %p, %!STATUS!",
284 Item, Collection, status);
285 FxVerifierDbgBreakPoint(pFxDriverGlobals);
286 }
287 }
288
__drv_maxIRQL(DISPATCH_LEVEL)289 __drv_maxIRQL(DISPATCH_LEVEL)
290 WDFOBJECT
291 STDCALL
292 WDFEXPORT(WdfCollectionGetItem)(
293 __in
294 PWDF_DRIVER_GLOBALS DriverGlobals,
295 __in
296 WDFCOLLECTION Collection,
297 __in
298 ULONG Index
299 )
300 {
301 DDI_ENTRY();
302
303 FxCollection *pCollection;
304 FxObject *pObject;
305 KIRQL irql;
306
307 FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals),
308 Collection,
309 FX_TYPE_COLLECTION,
310 (PVOID*) &pCollection);
311
312 pCollection->Lock(&irql);
313 pObject = pCollection->GetItem(Index);
314 pCollection->Unlock(irql);
315
316 if (pObject == NULL) {
317 return NULL;
318 }
319
320 return pObject->GetObjectHandle();
321 }
322
__drv_maxIRQL(DISPATCH_LEVEL)323 __drv_maxIRQL(DISPATCH_LEVEL)
324 WDFOBJECT
325 STDCALL
326 WDFEXPORT(WdfCollectionGetFirstItem)(
327 __in
328 PWDF_DRIVER_GLOBALS DriverGlobals,
329 __in
330 WDFCOLLECTION Collection
331 )
332 {
333 DDI_ENTRY();
334
335 FxCollection *pCollection;
336 FxObject* pObject;
337 KIRQL irql;
338
339 FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals),
340 Collection,
341 FX_TYPE_COLLECTION,
342 (PVOID*) &pCollection);
343
344 pCollection->Lock(&irql);
345 pObject = pCollection->GetFirstItem();
346 pCollection->Unlock(irql);
347
348 if (pObject != NULL) {
349 return pObject->GetObjectHandle();
350 }
351 else {
352 return NULL;
353 }
354 }
355
__drv_maxIRQL(DISPATCH_LEVEL)356 __drv_maxIRQL(DISPATCH_LEVEL)
357 WDFOBJECT
358 STDCALL
359 WDFEXPORT(WdfCollectionGetLastItem)(
360 __in
361 PWDF_DRIVER_GLOBALS DriverGlobals,
362 __in
363 WDFCOLLECTION Collection
364 )
365 {
366 DDI_ENTRY();
367
368 FxCollection *pCollection;
369 FxObject* pObject;
370 KIRQL irql;
371
372 FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals),
373 Collection,
374 FX_TYPE_COLLECTION,
375 (PVOID*) &pCollection);
376
377 pCollection->Lock(&irql);
378 pObject = pCollection->GetLastItem();
379 pCollection->Unlock(irql);
380
381 if (pObject != NULL) {
382 return pObject->GetObjectHandle();
383 }
384 else {
385 return NULL;
386 }
387 }
388
389 } // extern "C" of entire file
390