Driver Annotation Syntax
The driver annotations complement the General-Purpose Annotations such as _In_ and _Out_ that are defined in Specstrings.h. The driver annotations use a slightly different syntax from that of general-purpose annotations. With the driver annotations, you have more flexibility about where you place the annotations, and the annotations can have more complex composition.
The Driver Annotations start with the prefix __drv_ and are defined in Driverspecs.h. There are two general categories of driver annotations:
Annotations that identify the exact object that is being annotated. For example, _At_ applies a list of annotations to a named formal parameter to a function. This annotation is also spelled __drv_arg when, by convention, it is applied to parameters.
Annotations that indicate semantics. For example, __drv_maxIRQL indicates the maximum interrupt level at which a function can be called.
All driver annotations either implicitly or explicitly apply to a specific element of the function call that is being annotated. These elements include:
The function itself (that is, the global state of the function)
The return value
A function parameter
The this pointer in C++ code
A driver annotation can apply at any level of dereference (equivalent to the general-purpose partial annotation __deref), and it can apply to the prestate or poststate condition of the function or parameter.
Lower-level general-purpose annotations such as __notnull can be combined with driver annotations. However, composite general-purpose annotations such as those built up from _In_, _Out_, and _Inout_ should not be included directly in driver annotation syntax; they can appear adjacent to driver annotations. For example, a composite general-purpose annotation such as _Inout_updates_to_ should appear separately from driver annotations, either adjacent to them or on a separate line, and should not be concatenated with a driver annotation or included in an annotation list.
Placement of Annotations
Driver annotations can be applied to functions as a whole, to individual function parameters, and to type declarations (typedefs).
If a function has both a declaration (or prototype) and a definition, both must be annotated and the annotations must be identical. If the annotations differ, PFD issues a warning. If a function has only a definition and does not have a separate declaration, it is sufficient to annotate the definition; it is not necessary to create and annotate a declaration.
Annotations that are applied to type declarations (typedef) are implicitly applied to functions and parameters of that type; that is, it is not necessary to apply annotations to both a type declaration and uses of its type, including function type declarations. For more information, see Function Type Declarations.
Annotations that apply to an entire function should be placed immediately before the beginning of the function. Annotations that apply to a function parameter can be placed in one of two locations:
Inline, immediately before the function parameter.
Immediately before the beginning of the function, enclosed in a _At_ (or equivalently __drv_arg) annotation that identifies the parameter to which the annotation applies.
Example of an Annotated Function
The following code example shows the placement of various general-purpose and driver annotations. (The annotations are formatted in bold type to distinguish them from the surrounding code.)
_Check_return_
__drv_allocatesMem(Pool)
_When_(PoolType&0x1f==2 || PoolType&0x1f==6,
_drv_reportError("Must succeed pool allocations are"
"forbidden. Allocation failures cause a system crash"))
__bcount(NumberOfBytes)
PVOID
ExAllocatePoolWithTag(
_In_ __drv_strictTypeMatch(__drv_typeExpr)
POOL_TYPE PoolType,
_In_ SIZE_T NumberOfBytes,
_In_ ULONG Tag
);
In this example:
The annotations _Check_return_, __drv_allocatesMem, _When_, and __drv_reportError apply to the function.
The annotation __bcount applies to the function return value; it indicates that the return value is NumberOfBytes long.
The annotation _In_ __drv_strictTypeMatch applies to the PoolType parameter.
The other _In_ annotations apply to NumberOfBytes and Tag parameters, respectively.
For more information about the annotations __drv_allocatesMem, _When_, __drv_reportError, and __drv_strictTypeMatch see Driver Annotations.
For a description of how PFD interprets _Check_return_, __bcount, and _In_, see General-Purpose Annotations..
Send comments about this topic to Microsoft
Build date: 5/3/2011