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_ 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 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_ 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 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 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 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 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 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