1 /*++ 2 3 Copyright (c) Microsoft Corporation 4 5 Module Name: 6 7 fxhandle.h 8 9 Abstract: 10 11 Private interfaces for Driver Frameworks handle functions. 12 13 Author: 14 15 16 17 18 Environment: 19 20 Both kernel and user mode 21 22 Revision History: 23 24 25 --*/ 26 27 #ifndef _WDFPHANDLE_H_ 28 #define _WDFPHANDLE_H_ 29 30 /** 31 32 Framework Object Memory Layout (x86 32 bit) 33 34 Note: The handle is XOR'ed with (-1) to scramble it 35 36 ---------------------- handle + sizeof(ContextSize) 37 | | 38 | Drivers Context | 39 | Memory | 40 | | 41 WDFOBJECT handle -> ---------------------- this + sizeof(C++_OBJECT) + _extrasize + sizeof(FxContextHeader) 42 | | 43 | FxContextHeader | 44 | | 45 ---------------------- this + sizeof(C++_OBJECT) + _extrasize (m_ObjectSize) 46 | | 47 | C++ Object | 48 | "extra" memory | 49 | | 50 |--------------------| this + sizeof(C++_OBJECT) 51 | | 52 | C++ Object | 53 | | 54 | | 55 Base Pool Allocation -> ---------------------- this 56 C++ this pointer 57 58 **/ 59 60 struct FxContextHeader; 61 62 struct FxContextHeader { 63 // 64 // Backpointer to the object that this is a context for 65 // 66 FxObject* Object; 67 68 // 69 // Next context in the chain 70 // 71 FxContextHeader* NextHeader; 72 73 // 74 // Function to call when object is deleted 75 // 76 PFN_WDF_OBJECT_CONTEXT_CLEANUP EvtCleanupCallback; 77 78 // 79 // Function to call when the object's memory is destroyed 80 // when the last reference count goes to zero 81 // 82 PFN_WDF_OBJECT_CONTEXT_DESTROY EvtDestroyCallback; 83 84 // 85 // Type associated with this context 86 // 87 PCWDF_OBJECT_CONTEXT_TYPE_INFO ContextTypeInfo; 88 89 // 90 // Start of client's context 91 // 92 DECLSPEC_ALIGN(MEMORY_ALLOCATION_ALIGNMENT) ULONG_PTR Context[1]; 93 }; 94 95 // 96 // We want all the way up to the aligned field, but not the field itself 97 // 98 #define FX_CONTEXT_HEADER_SIZE FIELD_OFFSET(FxContextHeader, Context) 99 100 #define COMPUTE_RAW_OBJECT_SIZE(_rawObjectSize) \ 101 ((USHORT) WDF_ALIGN_SIZE_UP(_rawObjectSize, MEMORY_ALLOCATION_ALIGNMENT)) 102 103 // 104 // Computes the size required for a fixed size object plus any extra buffer space 105 // it requires. The extra buffer space is aligned on a process natural boundary. 106 // 107 #define COMPUTE_OBJECT_SIZE(_rawObjectSize, _extraSize) \ 108 (COMPUTE_RAW_OBJECT_SIZE(_rawObjectSize) + (USHORT) WDF_ALIGN_SIZE_UP(_extraSize, MEMORY_ALLOCATION_ALIGNMENT)) 109 110 // 111 // Gets size of the context associated with the specified attributes structure. 112 // 113 size_t 114 FxGetContextSize( 115 __in_opt PWDF_OBJECT_ATTRIBUTES Attributes 116 ); 117 118 // 119 // Computes the total size of an object taking into account its fixed size, 120 // any additional size after the fixed, and an object header, so the memory looks 121 // like: 122 // 123 // Object 124 // additional optional memory 125 // WDF_HANDLE_HEADER 126 // 127 _Must_inspect_result_ 128 NTSTATUS 129 FxCalculateObjectTotalSize2( 130 __in PFX_DRIVER_GLOBALS FxDriverGlobals, 131 __in USHORT RawObjectSize, 132 __in USHORT ExtraSize, 133 __in size_t ContextSize, 134 __out size_t* Total 135 ); 136 137 _Must_inspect_result_ 138 NTSTATUS 139 FxCalculateObjectTotalSize( 140 __in PFX_DRIVER_GLOBALS FxDriverGlobals, 141 __in USHORT RawObjectSize, 142 __in USHORT ExtraSize, 143 __in_opt PWDF_OBJECT_ATTRIBUTES Attributes, 144 __out size_t* Total 145 ); 146 147 PVOID 148 FxObjectHandleAlloc( 149 __in PFX_DRIVER_GLOBALS FxDriverGlobals, 150 __in POOL_TYPE PoolType, 151 __in size_t Size, 152 __in ULONG Tag, 153 __in_opt PWDF_OBJECT_ATTRIBUTES Attributes, 154 __in USHORT ExtraSize, 155 __in FxObjectType ObjectType 156 ); 157 158 VOID 159 FxContextHeaderInit( 160 __in FxContextHeader* Header, 161 __in FxObject* Object, 162 __in_opt PWDF_OBJECT_ATTRIBUTES Attributes 163 ); 164 165 PVOID 166 FxObjectAndHandleHeaderInit( 167 __in PFX_DRIVER_GLOBALS FxDriverGlobals, 168 __in PVOID AllocationStart, 169 __in USHORT ObjectSize, 170 __in_opt PWDF_OBJECT_ATTRIBUTES Attributes, 171 __in FxObjectType ObjectType 172 ); 173 174 VOID 175 __inline 176 FxObjectHandleCreate( 177 __in FxObject* Object, 178 __out PWDFOBJECT Handle 179 ) 180 { 181 #if FX_SUPER_DBG 182 if (Object->GetDriverGlobals()->FxVerifierHandle) { 183 184 185 186 187 188 189 ASSERT(Object->GetObjectSize() > 0); 190 ASSERT(Object == Object->GetContextHeader()->Object); 191 } 192 #endif 193 194 ASSERT((((ULONG_PTR) Object) & FxHandleFlagMask) == 0x0); 195 *Handle = Object->GetObjectHandle(); 196 } 197 198 /*++ 199 200 Routine Description: 201 202 Retrieves the object pointer from the handle if valid. 203 204 This does not change an objects reference count. 205 206 Arguments: 207 208 handle - The object handle created by WdfObjectCreateHandle 209 210 type - Type of the object from FxTypes.h 211 212 ppObj - Pointer to location to store the returned object. 213 214 Returns: 215 216 NTSTATUS 217 218 --*/ 219 220 VOID 221 FxObjectHandleGetPtrQI( 222 __in FxObject* Object, 223 __out PVOID* PPObject, 224 __in WDFOBJECT Handle, 225 __in WDFTYPE Type, 226 __in WDFOBJECT_OFFSET Offset 227 ); 228 229 _Must_inspect_result_ 230 NTSTATUS 231 FxObjectAllocateContext( 232 __in FxObject* Object, 233 __in PWDF_OBJECT_ATTRIBUTES Attributes, 234 __in BOOLEAN AllowCallbacksOnly, 235 __deref_opt_out PVOID* Context 236 ); 237 238 __inline 239 BOOLEAN 240 FxObjectCheckType( 241 __in FxObject* Object, 242 __in WDFTYPE Type 243 ) 244 /*++ 245 246 Routine Description: 247 Checks if the FxObject is of a the Type. 248 249 Arguments: 250 FxObject - the object being checked 251 Type - The type value to be checked 252 253 Returns: 254 TRUE if the Object is of the type 'Type' 255 FALSE otherwise 256 --*/ 257 { 258 NTSTATUS status; 259 PVOID tmpObject; 260 FxQueryInterfaceParams params = {&tmpObject, Type, 0}; 261 262 // 263 // Do a quick non virtual call for the type and only do the slow QI if 264 // the first types do not match 265 // 266 267 if (Object->GetType() == Type) { 268 return TRUE; 269 } 270 271 status = Object->QueryInterface(¶ms); 272 273 if (!NT_SUCCESS(status)) { 274 return FALSE; 275 } 276 277 return TRUE; 278 279 } 280 281 __inline 282 VOID 283 FxObjectHandleGetPtr( 284 __in PFX_DRIVER_GLOBALS FxDriverGlobals, 285 __in WDFOBJECT Handle, 286 __in WDFTYPE Type, 287 __out PVOID* PPObject 288 ) 289 /*++ 290 291 Routine Description: 292 Converts an externally facing WDF handle into its internal object. 293 294 Arguments: 295 FxDriverGlobals - caller's globals 296 Handle - handle to convert into an object 297 Type - required type of the underlying object 298 PPObject - pointer to receive the underlying object 299 300 --*/ 301 { 302 WDFOBJECT_OFFSET offset; 303 FxObject* pObject; 304 305 if (Handle == NULL) { 306 307 308 309 310 311 FxVerifierBugCheck(FxDriverGlobals, 312 WDF_INVALID_HANDLE, 313 (ULONG_PTR) Handle, 314 Type); 315 316 /* NOTREACHED */ 317 return; 318 } 319 320 offset = 0; 321 pObject = FxObject::_GetObjectFromHandle(Handle, &offset); 322 323 // 324 // The only DDI you can call on an object which has a ref count of zero is 325 // WdfObjectGetTypedContextWorker(). 326 // 327 ASSERT(pObject->GetRefCnt() > 0); 328 329 // 330 // Do a quick non virtual call for the type and only do the slow QI if 331 // the first types do not match 332 // 333 if (pObject->GetType() == Type) { 334 *PPObject = pObject; 335 ASSERT(offset == 0x0); 336 return; 337 } 338 else { 339 FxObjectHandleGetPtrQI(pObject, PPObject, Handle, Type, offset); 340 } 341 } 342 343 __inline 344 VOID 345 FxObjectHandleGetPtrOffset( 346 __in PFX_DRIVER_GLOBALS FxDriverGlobals, 347 __in WDFOBJECT Handle, 348 __in WDFTYPE Type, 349 __out PVOID* PPObject, 350 __out PWDFOBJECT_OFFSET Offset 351 ) 352 /*++ 353 354 Routine Description: 355 This function probably should be removed and the optional Offset paramter 356 moved into the signature for FxObjectHandleGetPtr(). The distinction 357 between these 2 functions was important when both of them were *not* 358 FORCEINLINE functions (since there was an additional parameter to push onto 359 the stack). Now that they are both __inlined, there is no longer a 360 parameter to push, eliminating this optimization. 361 362 Arguments: 363 FxDriverGlobals - caller's globals 364 Handle - handle to convert into an object 365 Type - required type of the underlying object 366 PPObject - pointer to receive the underlying object 367 Offset - offset into the object which the handle resided. Nearly all objects 368 will have a zero offset 369 370 --*/ 371 { 372 FxObject* pObject; 373 374 if (Handle == NULL) { 375 376 377 378 379 380 FxVerifierBugCheck(FxDriverGlobals, 381 WDF_INVALID_HANDLE, 382 (ULONG_PTR) Handle, 383 Type); 384 385 /* NOTREACHED */ 386 return; 387 } 388 389 *Offset = 0; 390 pObject = FxObject::_GetObjectFromHandle(Handle, Offset); 391 392 // 393 // The only DDI you can call on an object which has a ref count of zero is 394 // WdfObjectGetTypedContextWorker(). 395 // 396 ASSERT(pObject->GetRefCnt() > 0); 397 398 // 399 // Do a quick non virtual call for the type and only do the slow QI if 400 // the first types do not match 401 // 402 if (pObject->GetType() == Type) { 403 *PPObject = pObject; 404 ASSERT(*Offset == 0x0); 405 return; 406 } 407 else { 408 FxObjectHandleGetPtrQI(pObject, PPObject, Handle, Type, *Offset); 409 } 410 } 411 412 VOID 413 __inline 414 FxObjectHandleGetPtrAndGlobals( 415 __in PFX_DRIVER_GLOBALS CallersGlobals, 416 __in WDFOBJECT Handle, 417 __in WDFTYPE Type, 418 __out PVOID* PPObject, 419 __out PFX_DRIVER_GLOBALS* ObjectGlobals 420 ) 421 /*++ 422 423 Routine Description: 424 Converts an externally facing WDF handle into its internal object. 425 426 Arguments: 427 FxDriverGlobals - caller's globals 428 Handle - handle to convert into an object 429 Type - required type of the underlying object 430 PPObject - pointer to receive the underlying object 431 ObjectGlobals - pointer to receive the underlying object's globals. 432 433 --*/ 434 { 435 // 436 // All FX_TYPEs except for IFX_TYPE_MEMORY derive from FxObject, so our cast 437 // below will work with all types but IFX_TYPE_MEMORY (in which case the caller 438 // should call FxObjectHandleGetPtr and then get the globals on their own 439 // from the IFxMemory interface). 440 // 441 ASSERT(Type != IFX_TYPE_MEMORY); 442 443 FxObjectHandleGetPtr(CallersGlobals, 444 Handle, 445 Type, 446 PPObject); 447 448 *ObjectGlobals = ((FxObject*) (*PPObject))->GetDriverGlobals(); 449 } 450 451 VOID 452 __inline 453 FxObjectHandleGetGlobals( 454 __in PFX_DRIVER_GLOBALS CallersGlobals, 455 __in WDFOBJECT Handle, 456 __out PFX_DRIVER_GLOBALS* ObjectGlobals 457 ) 458 /*++ 459 460 Routine Description: 461 Converts an externally facing WDF handle into its internal object and 462 returns its globals. 463 464 Arguments: 465 FxDriverGlobals - caller's globals 466 Handle - handle to convert into an object 467 ObjectGlobals - pointer to receive the underlying object's globals. 468 469 --*/ 470 { 471 PVOID pObject; 472 473 FxObjectHandleGetPtrAndGlobals(CallersGlobals, 474 Handle, 475 FX_TYPE_OBJECT, 476 &pObject, 477 ObjectGlobals); 478 479 UNREFERENCED_PARAMETER(pObject); 480 } 481 482 #endif // _WDFPHANDLE_H_ 483