Type Annotations
The C and C++ languages permit some mixing of integer types. In particular, it is acceptable to pass an enumerated type where a generic integer type is expected. However, for a number of functions, it is easy to pass the wrong enumerated type.
Use the __drv_strictTypeMatch and __drv_strictType annotations to ensure that a function is called with exactly the right type. These annotations have the following syntax:
__drv_strictTypeMatch(mode)
__drv_strictType(typename, mode)
mode
The mode argument can be one of the following:mode Description __drv_typeConst
The parameter takes a single simple operand that must match exactly. This annotation is typically used where the value is a single constant.
__drv_typeCond
The ?: operator can be used to select between single operands. Parentheses are also permitted. This annotation is typically to switch dynamically among a few constant arguments.
__drv_typeBitset
The parameter can take expressions that involve only operands of that type. This annotation is typically used for bitsets, but is not limited to bit operations.
__drv_typeExpr
The parameter can take the same operands as a __drv_typeBitset annotation, plus literal constants. For example, the POOL_TYPE parameter to ExAllocatePool uses this annotation.
typename
The typename argument specifies the name of the enumerated type or name of the typedef variable. If either a variable or a constant might be passed to the function, it is helpful to specify both the typedef name (for variables) and an enumerated type (for constants). This can be done by giving the typedef name and the enumerated type name, separated by a slash. For example, in the following annotation, KPROCESSOR_MODE is the typedef and _MODE is the enumerated type. You must specify the type enum along with the name of the enumerated type.__drv_strictType(KPROCESSOR_MODE/enum _MODE, __drv_typeCond)
Comments
For the __drv_stringTypeMatch annotation, the actual parameter must be the same type as the formal parameter, within the limits set by mode.
For the __drv_strictType annotation, the parameters must be the type that is specified by typename, within the limits set by mode.
Example
The function KeWaitForMultipleObjects provides several examples of type annotations. This function has three parameters that are different enumerated types. However, the parameters are easily confused, and the C compiler does not check for correctness. With appropriate annotations, PFD can check that the parameters are of the correct type. See the notes following the example for an explanation.
NTSTATUS KeWaitForMultipleObjects(
__in ULONG Count,
__in PVOID Object[],
__in
__drv_strictTypeMatch(__drv_typeConst) // See Note 1
WAIT_TYPE WaitType,
__in
__drv_strictTypeMatch(__drv_typeConst) // See Note 2
KWAIT_REASON WaitReason,
__in
__drv_strictType(KPROCESSOR_MODE/enum _MODE,
__drv_typeCond) // See Note 3
KPROCESSOR_MODE WaitMode,
__in BOOLEAN Alertable,
__in_opt PLARGE_INTEGER Timeout,
__in_opt PKWAIT_BLOCK WaitBlockArray);
Notes
This annotation indicates that WaitType must be a member of the enumerated type WAIT_TYPE.
This annotation indicates that WaitReason must be a member of the enumerated type KWAIT_REASON.
This annotation indicates that WaitMode must be either a variable of type KPROCESSOR_MODE or a member of the enumerated type _MODE, and can be passed as an expression that uses the ?: conditional operator.
Some additional considerations apply to WaitMode:
- Constants of type enum _MODE are semantically reasonable, and it is semantically reasonable to want to select between them with the ?: conditional operator. However, it is not reasonable to allow arithmetic on those constants. __drv_typeCond allows use of the ?: operator but no other operators.
- KPROCESSOR_MODE is defined to be a char, and enums are defined by C to be the same as int. Thus, there cannot be a symbolic name for a constant of type KPROCESSOR_MODE; enum _MODE is the closest match.
Send comments about this topic to Microsoft
Build date: 5/3/2011