Why port to SAL2? Because 2 > 1 obviously. SAL2 does add some new functionality. You should not be lazy and just use SAL2 in new code, and clean up old code to use SAL2 while you are in there working on it. Should you go back and fix old code to use SAL2? It is up to you. It has some new functionality, however, SAL1 will continue to work just fine.
Const Protection, Use It
This isn't SAL, just regular C. Use const protection. Parameters that should not be modified should be const protected. For instance: _In_ const char *p is more correct than _In_ char *p if the p buffer should not be modified. Please use const correctly for parameters and struct members.Here is a table for the basics of SAL2.
Here is my version with SAL to SAL2 notes.
Pointer Parameters
For the annotations in the following table, when a pointer parameter is being annotated, the analyzer reports an error if the pointer is null. This applies to pointers and to any data item that's pointed to.
SAL 1
|
SAL 2
|
Description
|
__in
|
_In_
|
Annotates
input parameters that are scalars, structures, pointers to structures and the
like. Explicitly may be used on simple scalars. The parameter must be valid
in pre-state and will not be modified.
|
__out
|
_Out_
|
Annotates
output parameters that are scalars, structures, pointers to structures and
the like. Do not apply this to an object that cannot return a value—for
example, a scalar that's passed by value. The parameter does not have to be
valid in pre-state but must be valid in post-state.
|
__inout
|
_Inout_
|
Annotates
a parameter that will be changed by the function. It must be valid in both
pre-state and post-state, but is assumed to have different values before and
after the call. Must apply to a modifiable value.
|
__in_z
|
_In_z_
|
A
pointer to a null-terminated string that's used as input. The string must be
valid in pre-state. Variants of PSTR, which already have the correct
annotations, are preferred. <= This is a pet annoyance of mine, don't be the guy that does _In_z_ PCWSTR.
|
__inout_z
|
_Inout_z_
|
A
pointer to a null-terminated character array that will be modified. It must
be valid before and after the call, but the value is assumed to have changed.
The null terminator may be moved, but only the elements up to the original
null terminator may be accessed.
|
__in_ecount(s)
__in_bcount(s) |
_In_reads_(s)
_In_reads_bytes_(s)
|
A
pointer to an array, which is read by the function. The array is of size s elements,
all of which must be valid.
The _bytes_ variant
gives the size in bytes instead of elements. Use this only when the size
cannot be expressed as elements. For example, char strings would
use the _bytes_ variant only if a similar function that uses wchar_t would.
|
__in_ecount_z(s)
|
_In_reads_z_(s)
|
A
pointer to an array that is null-terminated and has a known size. The
elements up to the null terminator—or s if there is no null
terminator—must be valid in pre-state. If the size is known in bytes, scale s by
the element size.
|
_In_reads_or_z_(s)
|
A
pointer to an array that is null-terminated or has a known size, or both. The
elements up to the null terminator—or s if there is no null
terminator—must be valid in pre-state. If the size is known in bytes, scale s by
the element size. (Used for the strn family.)
|
|
_Out_writes_(s)
_Out_writes_bytes_(s)
|
A
pointer to an array of s elements (resp. bytes) that will be
written by the function. The array elements do not have to be valid in
pre-state, and the number of elements that are valid in post-state is
unspecified. If there are annotations on the parameter type, they are applied
in post-state. For example, consider the following code.
C++
typedef
_Null_terminated_ wchar_t *PWSTR;
void
MyStringCopy(_Out_writes_ (size) PWSTR p1,
_In_ size_t size,
_In_ PWSTR p2);
In
this example, the caller provides a buffer of size elements
for p1. MyStringCopy makes some of those elements
valid. More importantly, the _Null_terminated_ annotation onPWSTR means
that p1 is null-terminated in post-state. In this way, the
number of valid elements is still well-defined, but a specific element count
is not required.
The _bytes_ variant
gives the size in bytes instead of elements. Use this only when the size
cannot be expressed as elements. For example, char strings would
use the _bytes_ variant only if a similar function that uses wchar_t would.
|
|
_Out_writes_z_(s)
|
A
pointer to an array of s elements. The elements do not have
to be valid in pre-state. In post-state, the elements up through the null
terminator—which must be present—must be valid. If the size is known in
bytes, scale s by the element size.
|
|
_Inout_updates_(s)
_Inout_updates_bytes_(s)
|
A
pointer to an array, which is both read and written to in the function. It is
of size s elements, and valid in pre-state and post-state.
The _bytes_ variant
gives the size in bytes instead of elements. Use this only when the size
cannot be expressed as elements. For example, char strings would
use the _bytes_ variant only if a similar function that uses wchar_t would.
|
|
_Inout_updates_z_(s)
|
A
pointer to an array that is null-terminated and has a known size. The
elements up through the null terminator—which must be present—must be valid
in both pre-state and post-state. The value in the post-state is presumed to
be different from the value in the pre-state; this includes the location of
the null terminator. If the size is known in bytes, scale s by
the element size.
|
|
_Out_writes_to_(s,c)
_Out_writes_bytes_to_(s,c)
_Out_writes_all_(s)
_Out_writes_bytes_all_(s)
|
A
pointer to an array of s elements. The elements do not have
to be valid in pre-state. In post-state, the elements up to the c-th
element must be valid. If the size is known in bytes, scale s and c by
the element size or use the _bytes_ variant, which is defined as:
C++
_Out_writes_to_(_Old_(s), _Old_(s))
_Out_writes_bytes_to_(_Old_(s), _Old_(s))
In
other words, every element that exists in the buffer up to s in
the pre-state is valid in the post-state. For example:
C++
void
*memcpy(_Out_writes_bytes_all_(s) char *p1,
_In_reads_bytes_(s) char *p2,
_In_ int s);
void
* wordcpy(_Out_writes_all_(s) DWORD *p1,
_In_reads_(s) DWORD *p2,
_In_ int s);
|
|
_Inout_updates_to_(s,c)
_Inout_updates_bytes_to_(s,c)
|
A
pointer to an array, which is both read and written by the function. It is of
size s elements, all of which must be valid in pre-state,
and c elements must be valid in post-state.
The _bytes_ variant
gives the size in bytes instead of elements. Use this only when the size
cannot be expressed as elements. For example, char strings would
use the _bytes_ variant only if a similar function that uses wchar_t would.
|
|
_Inout_updates_all_(s)
_Inout_updates_bytes_all_(s)
|
A
pointer to an array, which is both read and written by the function of size s elements.
Defined as equivalent to:
C++
_Inout_updates_to_(_Old_(s), _Old_(s))
_Inout_updates_bytes_to_(_Old_(s),
_Old_(s))
In
other words, every element that exists in the buffer up to s in
the pre-state is valid in the pre-state and post-state.
The _bytes_ variant
gives the size in bytes instead of elements. Use this only when the size
cannot be expressed as elements. For example, char strings would
use the _bytes_ variant only if a similar function that uses wchar_t would.
|
|
_In_reads_to_ptr_(p)
|
A
pointer to an array for which the expression p – _Curr_ (that
is, p minus _Curr_) is defined by the appropriate
language standard. The elements prior to p must be valid in
pre-state.
|
|
_In_reads_to_ptr_z_(p)
|
A
pointer to a null-terminated array for which the expression p – _Curr_ (that
is, p minus_Curr_) is defined by the appropriate language
standard. The elements prior to p must be valid in
pre-state.
|
|
_Out_writes_to_ptr_(p)
|
A
pointer to an array for which the expression p – _Curr_ (that
is, p minus _Curr_) is defined by the appropriate
language standard. The elements prior to p do not have to be
valid in pre-state and must be valid in post-state.
|
|
_Out_writes_to_ptr_z_(p)
|
A
pointer to a null-terminated array for which the expression p – _Curr_ (that
is, p minus_Curr_) is defined by the appropriate language
standard. The elements prior to p do not have to be valid in
pre-state and must be valid in post-state.
|
No comments:
Post a Comment