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
FxObjectHandleCreate(__in FxObject * Object,__out PWDFOBJECT Handle)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
FxObjectCheckType(__in FxObject * Object,__in WDFTYPE Type)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
FxObjectHandleGetPtr(__in PFX_DRIVER_GLOBALS FxDriverGlobals,__in WDFOBJECT Handle,__in WDFTYPE Type,__out PVOID * PPObject)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
FxObjectHandleGetPtrOffset(__in PFX_DRIVER_GLOBALS FxDriverGlobals,__in WDFOBJECT Handle,__in WDFTYPE Type,__out PVOID * PPObject,__out PWDFOBJECT_OFFSET Offset)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
FxObjectHandleGetPtrAndGlobals(__in PFX_DRIVER_GLOBALS CallersGlobals,__in WDFOBJECT Handle,__in WDFTYPE Type,__out PVOID * PPObject,__out PFX_DRIVER_GLOBALS * ObjectGlobals)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
FxObjectHandleGetGlobals(__in PFX_DRIVER_GLOBALS CallersGlobals,__in WDFOBJECT Handle,__out PFX_DRIVER_GLOBALS * ObjectGlobals)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