xref: /reactos/sdk/include/wdf/kmdf/1.17/wdfobject.h (revision c8d07514)
1 /*++
2 
3 Copyright (c) Microsoft Corporation.  All rights reserved.
4 
5 _WdfVersionBuild_
6 
7 Module Name:
8 
9     wdfobject.h
10 
11 Abstract:
12 
13     This is the C header for driver frameworks objects
14 
15 Revision History:
16 
17 
18 --*/
19 
20 //
21 // NOTE: This header is generated by stubwork.  Please make any
22 //       modifications to the corresponding template files
23 //       (.x or .y) and use stubwork to regenerate the header
24 //
25 
26 #ifndef _WDFOBJECT_H_
27 #define _WDFOBJECT_H_
28 
29 #ifndef WDF_EXTERN_C
30   #ifdef __cplusplus
31     #define WDF_EXTERN_C       extern "C"
32     #define WDF_EXTERN_C_START extern "C" {
33     #define WDF_EXTERN_C_END   }
34   #else
35     #define WDF_EXTERN_C
36     #define WDF_EXTERN_C_START
37     #define WDF_EXTERN_C_END
38   #endif
39 #endif
40 
41 WDF_EXTERN_C_START
42 
43 
44 
45 #if (NTDDI_VERSION >= NTDDI_WIN2K)
46 
47 //
48 // Specifies the highest IRQL level allowed on callbacks
49 // to the device driver.
50 //
51 typedef enum _WDF_EXECUTION_LEVEL {
52     WdfExecutionLevelInvalid = 0x00,
53     WdfExecutionLevelInheritFromParent,
54     WdfExecutionLevelPassive,
55     WdfExecutionLevelDispatch,
56 } WDF_EXECUTION_LEVEL;
57 
58 //
59 // Specifies the concurrency of callbacks to the device driver
60 //
61 typedef enum _WDF_SYNCHRONIZATION_SCOPE {
62     WdfSynchronizationScopeInvalid = 0x00,
63     WdfSynchronizationScopeInheritFromParent,
64     WdfSynchronizationScopeDevice,
65     WdfSynchronizationScopeQueue,
66     WdfSynchronizationScopeNone,
67 } WDF_SYNCHRONIZATION_SCOPE;
68 
69 
70 
71 typedef
72 _Function_class_(EVT_WDF_OBJECT_CONTEXT_CLEANUP)
73 _IRQL_requires_same_
74 _IRQL_requires_max_(DISPATCH_LEVEL)
75 VOID
76 STDCALL
77 EVT_WDF_OBJECT_CONTEXT_CLEANUP(
78     _In_
79     WDFOBJECT Object
80     );
81 
82 typedef EVT_WDF_OBJECT_CONTEXT_CLEANUP *PFN_WDF_OBJECT_CONTEXT_CLEANUP;
83 
84 typedef
85 _Function_class_(EVT_WDF_OBJECT_CONTEXT_DESTROY)
86 _IRQL_requires_same_
87 _IRQL_requires_max_(DISPATCH_LEVEL)
88 VOID
89 STDCALL
90 EVT_WDF_OBJECT_CONTEXT_DESTROY(
91     _In_
92     WDFOBJECT Object
93     );
94 
95 typedef EVT_WDF_OBJECT_CONTEXT_DESTROY *PFN_WDF_OBJECT_CONTEXT_DESTROY;
96 
97 
98 typedef const struct _WDF_OBJECT_CONTEXT_TYPE_INFO *PCWDF_OBJECT_CONTEXT_TYPE_INFO;
99 
100 typedef struct _WDF_OBJECT_ATTRIBUTES {
101     //
102     // Size in bytes of this structure
103     //
104     ULONG Size;
105 
106     //
107     // Function to call when the object is deleted
108     //
109     PFN_WDF_OBJECT_CONTEXT_CLEANUP EvtCleanupCallback;
110 
111     //
112     // Function to call when the objects memory is destroyed when the
113     // the last reference count goes to zero
114     //
115     PFN_WDF_OBJECT_CONTEXT_DESTROY EvtDestroyCallback;
116 
117     //
118     // Execution level constraints for Object
119     //
120     WDF_EXECUTION_LEVEL ExecutionLevel;
121 
122     //
123     // Synchronization level constraint for Object
124     //
125     WDF_SYNCHRONIZATION_SCOPE SynchronizationScope;
126 
127     //
128     // Optional Parent Object
129     //
130     WDFOBJECT ParentObject;
131 
132     //
133     // Overrides the size of the context allocated as specified by
134     // ContextTypeInfo->ContextSize
135     //
136     size_t ContextSizeOverride;
137 
138     //
139     // Pointer to the type information to be associated with the object
140     //
141     PCWDF_OBJECT_CONTEXT_TYPE_INFO ContextTypeInfo;
142 
143 } WDF_OBJECT_ATTRIBUTES, *PWDF_OBJECT_ATTRIBUTES;
144 
145 FORCEINLINE
146 VOID
147 WDF_OBJECT_ATTRIBUTES_INIT(
148     _Out_ PWDF_OBJECT_ATTRIBUTES Attributes
149     )
150 {
151     RtlZeroMemory(Attributes, sizeof(WDF_OBJECT_ATTRIBUTES));
152     Attributes->Size = sizeof(WDF_OBJECT_ATTRIBUTES);
153     Attributes->ExecutionLevel = WdfExecutionLevelInheritFromParent;
154     Attributes->SynchronizationScope = WdfSynchronizationScopeInheritFromParent;
155 }
156 
157 #define WDF_OBJECT_ATTRIBUTES_SET_CONTEXT_TYPE(_attributes, _contexttype) \
158     (_attributes)->ContextTypeInfo = WDF_GET_CONTEXT_TYPE_INFO(_contexttype)->UniqueType
159 //
160 // VOID
161 // FORCEINLINE
162 // WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(
163 //     PWDF_OBJECT_ATTRIBUTES Attributes,
164 //     <typename>
165 //     )
166 //
167 // NOTE:  Do not put a ; at the end of the last line.  This will require the
168 // caller to specify a ; after the call.
169 //
170 #define WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(_attributes,  _contexttype) \
171     WDF_OBJECT_ATTRIBUTES_INIT(_attributes);                                \
172     WDF_OBJECT_ATTRIBUTES_SET_CONTEXT_TYPE(_attributes, _contexttype)
173 
174 typedef
175 PCWDF_OBJECT_CONTEXT_TYPE_INFO
176 (__cdecl *PFN_GET_UNIQUE_CONTEXT_TYPE)(
177     VOID
178     );
179 
180 //
181 // Since C does not have strong type checking we must invent our own
182 //
183 typedef struct _WDF_OBJECT_CONTEXT_TYPE_INFO {
184     //
185     // The size of this structure in bytes
186     //
187     ULONG Size;
188 
189     //
190     // String representation of the context's type name, i.e. "DEVICE_CONTEXT"
191     //
192     PCHAR ContextName;
193 
194     //
195     // The size of the context in bytes.  This will be the size of the context
196     // associated with the handle unless
197     // WDF_OBJECT_ATTRIBUTES::ContextSizeOverride is specified.
198     //
199     size_t ContextSize;
200 
201     //
202     // If NULL, this structure is the unique type identifier for the context
203     // type.  If != NULL, the UniqueType pointer value is the unique type id
204     // for the context type.
205     //
206     PCWDF_OBJECT_CONTEXT_TYPE_INFO UniqueType;
207 
208     //
209     // Function pointer to retrieve the context type information structure
210     // pointer from the provider of the context type.  This function is invoked
211     // by the client driver's entry point by the KMDF stub after all class
212     // drivers are loaded and before DriverEntry is invoked.
213     //
214     PFN_GET_UNIQUE_CONTEXT_TYPE EvtDriverGetUniqueContextType;
215 
216 } WDF_OBJECT_CONTEXT_TYPE_INFO, *PWDF_OBJECT_CONTEXT_TYPE_INFO;
217 
218 //
219 // Converts a type name a unique name in which we can retrieve type specific
220 // information.
221 //
222 #define WDF_TYPE_NAME_TO_TYPE_INFO(_contexttype) \
223       _WDF_ ## _contexttype ## _TYPE_INFO
224 
225 //
226 // Converts a type name a unique name to the structure which will initialize
227 // it through an external component.
228 //
229 #define WDF_TYPE_NAME_TO_EXTERNAL_INIT(_contexttype) \
230       _WDF_ ## _contexttype ## _EXTERNAL_INIT
231 
232 #define WDF_TYPE_NAME_TO_EXTERNAL_INIT_FUNCTION(_contexttype) \
233       _contexttype ## _EXTERNAL_INIT_FUNCTION
234 
235 //
236 // Returns an address to the type information representing this typename
237 //
238 #define WDF_GET_CONTEXT_TYPE_INFO(_contexttype) \
239     (&WDF_TYPE_NAME_TO_TYPE_INFO(_contexttype))
240 
241 //
242 // Used to help generate our own usable pointer to the type typedef.  For instance,
243 // a call as WDF_TYPE_NAME_POINTER_TYPE(DEVICE_CONTEXT) would generate:
244 //
245 // WDF_POINTER_TYPE_DEVICE_CONTEXT
246 //
247 // which would be the equivalent of DEVICE_CONTEXT*
248 //
249 #define WDF_TYPE_NAME_POINTER_TYPE(_contexttype) \
250     WDF_POINTER_TYPE_ ## _contexttype
251 
252 //
253 // Declares a typename so that in can be associated with a handle.  This will
254 // use the type's name with a _ prepended as the "friendly name" (which results
255 // in the autogenerated casting function being named WdfObjectGet_<typename>, ie
256 // WdfObjectGet_DEVICE_CONTEXT.  See WDF_DECLARE_CONTEXT_TYPE_WITH_NAME for
257 // more details on what is generated.
258 //
259 #define WDF_DECLARE_CONTEXT_TYPE(_contexttype)  \
260         WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(_contexttype, WdfObjectGet_ ## _contexttype)
261 
262 //
263 // WDF_DECLARE_CONTEXT_TYPE_WITH_NAME performs the following 3 tasks
264 //
265 // 1)  declare a typedef for the context type so that its pointer type can be
266 //     referred to later
267 // 2)  declare and initialize global structure that represents the type
268 //     information for this
269 //     context type
270 // 3)  declare and implement a function named _castingfunction
271 //     which does the proper type conversion.
272 //
273 // WDF_DECLARE_TYPE_AND_GLOBALS implements 1 & 2
274 // WDF_DECLARE_CASTING_FUNCTION implements 3
275 //
276 // For instance, the invocation of
277 // WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(DEVICE_CONTEXT, WdfDeviceGetContext)
278 // would result in the following being generated:
279 //
280 // typedef DEVICE_CONTEXT* WDF_POINTER_TYPE_DEVICE_CONTEXT;
281 //
282 // extern const __declspec(selectany) WDF_OBJECT_CONTEXT_TYPE_INFO  _WDF_DEVICE_CONTEXT_TYPE_INFO =
283 // {
284 //     sizeof(WDF_OBJECT_CONTEXT_TYPE_INFO),
285 //     "DEVICE_CONTEXT",
286 //     sizeof(DEVICE_CONTEXT),
287 // };
288 //
289 // WDF_POINTER_TYPE_DEVICE_CONTEXT
290 // WdfDeviceGetContext(
291 //    WDFOBJECT Handle
292 //    )
293 // {
294 //     return (WDF_POINTER_TYPE_DEVICE_CONTEXT)
295 //         WdfObjectGetTypedContextWorker(
296 //              Handle,
297 //              (&_WDF_DEVICE_CONTEXT_TYPE_INFO)->UniqueType
298 //              );
299 // }
300 //
301 #define WDF_TYPE_INIT_BASE_SECTION_NAME ".kmdftypeinit"
302 #define WDF_TYPE_INIT_SECTION_NAME      ".kmdftypeinit$b"
303 
304 //
305 // .data is the default section that global data would be placed into.  We
306 // cannot just use ".data" in __declspec(allocate()) without first declaring
307 // it in a #pragma section() even though it is a default section name.
308 //
309 #ifndef WDF_TYPE_DEFAULT_SECTION_NAME
310 #define WDF_TYPE_DEFAULT_SECTION_NAME ".data"
311 #endif // WDF_TYPE_DEFAULT_SECTION_NAME
312 
313 #pragma section(WDF_TYPE_INIT_SECTION_NAME, read, write)
314 #pragma section(WDF_TYPE_DEFAULT_SECTION_NAME)
315 
316 #define WDF_DECLARE_TYPE_AND_GLOBALS(_contexttype, _UniqueType, _GetUniqueType, _section)\
317                                                                         \
318 typedef _contexttype* WDF_TYPE_NAME_POINTER_TYPE(_contexttype);         \
319                                                                         \
320 WDF_EXTERN_C                                                            \
321 DECLSPEC_SELECTANY                                                      \
322 const WDF_OBJECT_CONTEXT_TYPE_INFO                                      \
323 WDF_TYPE_NAME_TO_TYPE_INFO(_contexttype) =                              \
324 {                                                                       \
325     sizeof(WDF_OBJECT_CONTEXT_TYPE_INFO),                               \
326     #_contexttype,                                                      \
327     sizeof(_contexttype),                                               \
328     _UniqueType,                                                        \
329     _GetUniqueType,                                                     \
330 };                                                                      \
331 //__declspec(allocate(_section))
332 
333 #define WDF_DECLARE_CASTING_FUNCTION(_contexttype, _castingfunction)    \
334                                                                         \
335 WDF_EXTERN_C                                                            \
336 __drv_aliasesMem                                                        \
337 FORCEINLINE                                                             \
338 WDF_TYPE_NAME_POINTER_TYPE(_contexttype)                                \
339 _castingfunction(                                                       \
340    _In_ WDFOBJECT Handle                                                \
341    )                                                                    \
342 {                                                                       \
343     return (WDF_TYPE_NAME_POINTER_TYPE(_contexttype))                   \
344         WdfObjectGetTypedContextWorker(                                 \
345             Handle,                                                     \
346             WDF_GET_CONTEXT_TYPE_INFO(_contexttype)->UniqueType         \
347             );                                                          \
348 }
349 
350 #define WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(_contexttype, _castingfunction) \
351                                                                         \
352 WDF_DECLARE_TYPE_AND_GLOBALS(                                           \
353     _contexttype,                                                       \
354     WDF_GET_CONTEXT_TYPE_INFO(_contexttype),                            \
355     NULL,                                                               \
356     WDF_TYPE_DEFAULT_SECTION_NAME)                                      \
357                                                                         \
358 WDF_DECLARE_CASTING_FUNCTION(_contexttype, _castingfunction)
359 
360 //
361 // WDF_DECLARE_SHARED_CONTEXT_TYPE_WITH_NAME is the same as
362 // WDF_DECLARE_CONTEXT_TYPE_WITH_NAME with respect to the types and structures
363 // that are created and initialized.  The casting function is different in that
364 // it passes the UniqueType to WdfObjectGetTypedContextWorker() instead of the
365 // global type structure created.  It also creates a structure which will contain
366 // an initialization function which will be invoked before DriverEntry() is
367 // called.
368 //
369 // It is the responsibilty of the component exporting the unique type to define
370 // and implement the function which will return the unique type.   The format of
371 // the define is:
372 //
373 // #define _contexttype ## _EXTERNAL_INIT_FUNCTION
374 //
375 // (e.g. #define DEVICE_CONTEXT_EXTERNALINIT_FUNCTION DeviceContextInit()
376 //  for a type of DEVICE_CONTEXT)
377 //
378 #define WDF_DECLARE_SHARED_CONTEXT_TYPE_WITH_NAME(_contexttype, _castingfunction) \
379                                                                         \
380 WDF_DECLARE_TYPE_AND_GLOBALS(                                           \
381     _contexttype,                                                       \
382     NULL,                                                               \
383     WDF_TYPE_NAME_TO_EXTERNAL_INIT_FUNCTION(_contexttype),              \
384     WDF_TYPE_INIT_SECTION_NAME)                                         \
385                                                                         \
386 WDF_DECLARE_CASTING_FUNCTION(_contexttype, _castingfunction)
387 
388 
389 //
390 // Generic conversion macro from handle to type.  This should be used if the
391 // autogenerated conversion function does not suite the programmers calling style.
392 //
393 // The type parameter should be name of the type (e.g. DEVICE_CONTEXT), not the
394 // name of the pointer to the type (PDEVICE_CONTEXT).
395 //
396 // Example call:
397 //
398 // WDFDEVICE device;
399 // PDEVICE_CONTEXT pContext;
400 //
401 // pContext = WdfObjectGetTypedContext(device, DEVICE_CONTEXT);
402 //
403 //
404 #define WdfObjectGetTypedContext(handle, type)  \
405 (type*)                                         \
406 WdfObjectGetTypedContextWorker(                 \
407     (WDFOBJECT) handle,                         \
408     WDF_GET_CONTEXT_TYPE_INFO(type)->UniqueType \
409     )
410 
411 //
412 // Converts a type name to a unique context name.
413 //
414 #define WDF_CUSTOM_TYPE_CONTEXT_NAME(_type) \
415     WdfCustomType_ ## _type
416 
417 //
418 // Converts a type name to a unique function name to retrieve the type info context.
419 //
420 #define WDF_GET_CUSTOM_TYPE_FUNCTION_NAME(_type) \
421     WdfObjectGetCustomType_ ## _type
422 
423 //
424 // Converts a type name to a unique function name to add the type info context.
425 //
426 #define WDF_ADD_CUSTOM_TYPE_FUNCTION_NAME(_type) \
427     WdfObjectAddCustomType_ ## _type
428 
429 //
430 // Core structure for supporting custom types, see macros below.
431 //
432 typedef struct _WDF_CUSTOM_TYPE_CONTEXT {
433     ULONG       Size;
434     ULONG_PTR   Data;
435 } WDF_CUSTOM_TYPE_CONTEXT, *PWDF_CUSTOM_TYPE_CONTEXT;
436 
437 //
438 // Declares a context and a function to handle the specified type.
439 //
440 // NOTE:  Do not put a ; at the end of the last line.  This will require the
441 // caller to specify a ; after the call.
442 //
443 #define WDF_DECLARE_CUSTOM_TYPE(_type)                                  \
444                                                                         \
445 typedef WDF_CUSTOM_TYPE_CONTEXT WDF_CUSTOM_TYPE_CONTEXT_NAME(_type);    \
446                                                                         \
447 WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(                                     \
448         WDF_CUSTOM_TYPE_CONTEXT_NAME(_type),                            \
449         WDF_GET_CUSTOM_TYPE_FUNCTION_NAME(_type)                        \
450         );                                                              \
451                                                                         \
452 WDF_EXTERN_C                                                            \
453 FORCEINLINE                                                             \
454 NTSTATUS                                                                \
455 WDF_ADD_CUSTOM_TYPE_FUNCTION_NAME(_type)(                               \
456    _In_ WDFOBJECT Handle,                                               \
457    _In_opt_ ULONG_PTR Data,                                             \
458    _In_opt_ PFN_WDF_OBJECT_CONTEXT_CLEANUP EvtCleanupCallback,          \
459    _In_opt_ PFN_WDF_OBJECT_CONTEXT_DESTROY EvtDestroyCallback           \
460    )                                                                    \
461 {                                                                       \
462     NTSTATUS                             status;                        \
463     WDF_OBJECT_ATTRIBUTES                attributes;                    \
464     WDF_CUSTOM_TYPE_CONTEXT_NAME(_type)* typeInfo;                      \
465                                                                         \
466     WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(                            \
467             &attributes,                                                \
468             WDF_CUSTOM_TYPE_CONTEXT_NAME(_type));                       \
469                                                                         \
470     attributes.EvtCleanupCallback = EvtCleanupCallback;                 \
471     attributes.EvtDestroyCallback = EvtDestroyCallback;                 \
472                                                                         \
473     status = WdfObjectAllocateContext(Handle,                           \
474                                       &attributes,                      \
475                                       (PVOID*)&typeInfo);               \
476     if (NT_SUCCESS(status)) {                                           \
477         typeInfo->Size = sizeof(WDF_CUSTOM_TYPE_CONTEXT_NAME(_type));   \
478         typeInfo->Data = Data;                                          \
479     }                                                                   \
480                                                                         \
481     return status;                                                      \
482 }
483 
484 //
485 // BOOLEAN
486 // WdfObjectIsCustomType(
487 //     _In_ _handle,    // WDFOBJECT handle.
488 //     _In_ _type       // Type.
489 //     )
490 //
491 // NOTE:  Do not put a ; at the end of the last line.  This will require the
492 // caller to specify a ; after the call.
493 //
494 #define WdfObjectIsCustomType(_handle, _type)                          \
495     (WdfObjectGetTypedContext(_handle, WDF_CUSTOM_TYPE_CONTEXT_NAME(_type)) \
496         == NULL ? FALSE : TRUE)
497 
498 //
499 // NTSTATUS
500 // WdfObjectAddCustomTypeWithData(
501 //     _In_ _handle,        // WDFOBJECT handle.
502 //     _In_ _type,          // Type.
503 //     _In_opt_ _data,      // Type's data.
504 //     _In_opt_ _cleanup,   // EvtCleanupCallback
505 //     _In_opt_ _destroy    // EvtDestroyCallback
506 //     )
507 //
508 // NOTE:  Do not put a ; at the end of the last line.  This will require the
509 // caller to specify a ; after the call.
510 //
511 #define WdfObjectAddCustomTypeWithData(_handle, _type, _data, _cleanup, _destroy) \
512     WDF_ADD_CUSTOM_TYPE_FUNCTION_NAME(_type)(_handle, _data, _cleanup, _destroy)
513 
514 //
515 // NTSTATUS
516 // WdfObjectAddCustomType(
517 //     _In_ _handle,    // WDFOBJECT handle.
518 //     _In_ _type       // Type.
519 //     )
520 //
521 // NOTE:  Do not put a ; at the end of the last line.  This will require the
522 // caller to specify a ; after the call.
523 //
524 #define WdfObjectAddCustomType(_handle, _type) \
525     WdfObjectAddCustomTypeWithData(_handle, _type, 0, NULL, NULL)
526 
527 //
528 // ULONG_PTR
529 // WdfObjectGetCustomTypeData(
530 //     _In_ _handle,    // WDFOBJECT handle.
531 //     _In_ _type       // Type.
532 //     )
533 //
534 // NOTE:  Do not put a ; at the end of the last line.  This will require the
535 // caller to specify a ; after the call.
536 //
537 #define WdfObjectGetCustomTypeData(_handle, _type) \
538     (WDF_GET_CUSTOM_TYPE_FUNCTION_NAME(_type)(_handle)->Data)
539 
540 
541 //
542 // WDF Function: WdfObjectGetTypedContextWorker
543 //
544 typedef
545 WDFAPI
546 PVOID
547 (FASTCALL *PFN_WDFOBJECTGETTYPEDCONTEXTWORKER)(
548     _In_
549     PWDF_DRIVER_GLOBALS DriverGlobals,
550     _In_
551     WDFOBJECT Handle,
552     _In_
553     PCWDF_OBJECT_CONTEXT_TYPE_INFO TypeInfo
554     );
555 
556 FORCEINLINE
557 PVOID
558 WdfObjectGetTypedContextWorker(
559     _In_
560     WDFOBJECT Handle,
561     _In_
562     PCWDF_OBJECT_CONTEXT_TYPE_INFO TypeInfo
563     )
564 {
565     return ((PFN_WDFOBJECTGETTYPEDCONTEXTWORKER) WdfFunctions[WdfObjectGetTypedContextWorkerTableIndex])(WdfDriverGlobals, Handle, TypeInfo);
566 }
567 
568 //
569 // WDF Function: WdfObjectAllocateContext
570 //
571 typedef
572 WDFAPI
573 NTSTATUS
574 (STDCALL *PFN_WDFOBJECTALLOCATECONTEXT)(
575     _In_
576     PWDF_DRIVER_GLOBALS DriverGlobals,
577     _In_
578     WDFOBJECT Handle,
579     _In_
580     PWDF_OBJECT_ATTRIBUTES ContextAttributes,
581     _Outptr_opt_
582     PVOID* Context
583     );
584 
585 FORCEINLINE
586 NTSTATUS
587 WdfObjectAllocateContext(
588     _In_
589     WDFOBJECT Handle,
590     _In_
591     PWDF_OBJECT_ATTRIBUTES ContextAttributes,
592     _Outptr_opt_
593     PVOID* Context
594     )
595 {
596     return ((PFN_WDFOBJECTALLOCATECONTEXT) WdfFunctions[WdfObjectAllocateContextTableIndex])(WdfDriverGlobals, Handle, ContextAttributes, Context);
597 }
598 
599 //
600 // WDF Function: WdfObjectContextGetObject
601 //
602 typedef
603 WDFAPI
604 WDFOBJECT
605 (FASTCALL *PFN_WDFOBJECTCONTEXTGETOBJECT)(
606     _In_
607     PWDF_DRIVER_GLOBALS DriverGlobals,
608     _In_
609     PVOID ContextPointer
610     );
611 
612 FORCEINLINE
613 WDFOBJECT
614 WdfObjectContextGetObject(
615     _In_
616     PVOID ContextPointer
617     )
618 {
619     return ((PFN_WDFOBJECTCONTEXTGETOBJECT) WdfFunctions[WdfObjectContextGetObjectTableIndex])(WdfDriverGlobals, ContextPointer);
620 }
621 
622 //
623 // WDF Function: WdfObjectReferenceActual
624 //
625 typedef
626 WDFAPI
627 VOID
628 (STDCALL *PFN_WDFOBJECTREFERENCEACTUAL)(
629     _In_
630     PWDF_DRIVER_GLOBALS DriverGlobals,
631     _In_
632     WDFOBJECT Handle,
633     _In_opt_
634     PVOID Tag,
635     _In_
636     LONG Line,
637     _In_z_
638     PCHAR File
639     );
640 
641 FORCEINLINE
642 VOID
643 WdfObjectReferenceActual(
644     _In_
645     WDFOBJECT Handle,
646     _In_opt_
647     PVOID Tag,
648     _In_
649     LONG Line,
650     _In_z_
651     PCHAR File
652     )
653 {
654     ((PFN_WDFOBJECTREFERENCEACTUAL) WdfFunctions[WdfObjectReferenceActualTableIndex])(WdfDriverGlobals, Handle, Tag, Line, File);
655 }
656 
657 //
658 // WDF Function: WdfObjectDereferenceActual
659 //
660 typedef
661 WDFAPI
662 VOID
663 (STDCALL *PFN_WDFOBJECTDEREFERENCEACTUAL)(
664     _In_
665     PWDF_DRIVER_GLOBALS DriverGlobals,
666     _In_
667     WDFOBJECT Handle,
668     _In_opt_
669     PVOID Tag,
670     _In_
671     LONG Line,
672     _In_z_
673     PCHAR File
674     );
675 
676 FORCEINLINE
677 VOID
678 WdfObjectDereferenceActual(
679     _In_
680     WDFOBJECT Handle,
681     _In_opt_
682     PVOID Tag,
683     _In_
684     LONG Line,
685     _In_z_
686     PCHAR File
687     )
688 {
689     ((PFN_WDFOBJECTDEREFERENCEACTUAL) WdfFunctions[WdfObjectDereferenceActualTableIndex])(WdfDriverGlobals, Handle, Tag, Line, File);
690 }
691 
692 //
693 // WDF Function: WdfObjectCreate
694 //
695 typedef
696 _Must_inspect_result_
697 _IRQL_requires_max_(DISPATCH_LEVEL)
698 WDFAPI
699 NTSTATUS
700 (STDCALL *PFN_WDFOBJECTCREATE)(
701     _In_
702     PWDF_DRIVER_GLOBALS DriverGlobals,
703     _In_opt_
704     PWDF_OBJECT_ATTRIBUTES Attributes,
705     _Out_
706     WDFOBJECT* Object
707     );
708 
709 _Must_inspect_result_
710 _IRQL_requires_max_(DISPATCH_LEVEL)
711 FORCEINLINE
712 NTSTATUS
713 WdfObjectCreate(
714     _In_opt_
715     PWDF_OBJECT_ATTRIBUTES Attributes,
716     _Out_
717     WDFOBJECT* Object
718     )
719 {
720     return ((PFN_WDFOBJECTCREATE) WdfFunctions[WdfObjectCreateTableIndex])(WdfDriverGlobals, Attributes, Object);
721 }
722 
723 //
724 // WDF Function: WdfObjectDelete
725 //
726 typedef
727 _IRQL_requires_max_(DISPATCH_LEVEL)
728 WDFAPI
729 VOID
730 (STDCALL *PFN_WDFOBJECTDELETE)(
731     _In_
732     PWDF_DRIVER_GLOBALS DriverGlobals,
733     _In_
734     WDFOBJECT Object
735     );
736 
737 _IRQL_requires_max_(DISPATCH_LEVEL)
738 FORCEINLINE
739 VOID
740 WdfObjectDelete(
741     _In_
742     WDFOBJECT Object
743     )
744 {
745     ((PFN_WDFOBJECTDELETE) WdfFunctions[WdfObjectDeleteTableIndex])(WdfDriverGlobals, Object);
746 }
747 
748 //
749 // WDF Function: WdfObjectQuery
750 //
751 typedef
752 _Must_inspect_result_
753 _IRQL_requires_max_(DISPATCH_LEVEL)
754 WDFAPI
755 NTSTATUS
756 (STDCALL *PFN_WDFOBJECTQUERY)(
757     _In_
758     PWDF_DRIVER_GLOBALS DriverGlobals,
759     _In_
760     WDFOBJECT Object,
761     _In_
762     CONST GUID* Guid,
763     _In_
764     ULONG QueryBufferLength,
765     _Out_writes_bytes_(QueryBufferLength)
766     PVOID QueryBuffer
767     );
768 
769 _Must_inspect_result_
770 _IRQL_requires_max_(DISPATCH_LEVEL)
771 FORCEINLINE
772 NTSTATUS
773 WdfObjectQuery(
774     _In_
775     WDFOBJECT Object,
776     _In_
777     CONST GUID* Guid,
778     _In_
779     ULONG QueryBufferLength,
780     _Out_writes_bytes_(QueryBufferLength)
781     PVOID QueryBuffer
782     )
783 {
784     return ((PFN_WDFOBJECTQUERY) WdfFunctions[WdfObjectQueryTableIndex])(WdfDriverGlobals, Object, Guid, QueryBufferLength, QueryBuffer);
785 }
786 
787 
788 
789 //
790 // Reference an object
791 //
792 // VOID
793 // WdfObjectReference(
794 //    _In_ WDFOBJECT Handle
795 //    );
796 //
797 // VOID
798 // WdfObjectReferenceWithTag(
799 //     _In_ WDFOBJECT Handle,
800 //     _In_ PVOID Tag
801 //     );
802 //
803 #define WdfObjectReference(Handle) \
804         WdfObjectReferenceWithTag(Handle, NULL)
805 
806 #define WdfObjectReferenceWithTag(Handle, Tag) \
807         WdfObjectReferenceActual(Handle, Tag, __LINE__, __FILE__)
808 
809 
810 //
811 // Dereference an object.  If an object allows for a client explicitly deleting
812 // it, call WdfObjectDelete.  Do not use WdfObjectDereferenceXxx to delete an
813 // object.
814 //
815 // VOID
816 // WdfObjectDereference(
817 //   _In_ WDFOBJECT Handle
818 //   );
819 //
820 // VOID
821 // WdfObjectDereferenceWithTag(
822 //     _In_ WDFOBJECT Handle
823 //     _In_ PVOID Tag
824 //     );
825 //
826 #define WdfObjectDereference(Handle)   \
827         WdfObjectDereferenceWithTag(Handle, NULL)
828 
829 #define WdfObjectDereferenceWithTag(Handle, Tag) \
830         WdfObjectDereferenceActual(Handle, Tag, __LINE__, __FILE__)
831 
832 
833 #endif // (NTDDI_VERSION >= NTDDI_WIN2K)
834 
835 
836 WDF_EXTERN_C_END
837 
838 #endif // _WDFOBJECT_H_
839 
840