1 | // Licensed to the .NET Foundation under one or more agreements. |
2 | // The .NET Foundation licenses this file to you under the MIT license. |
3 | // See the LICENSE file in the project root for more information. |
4 | |
5 | /************************************************************************* |
6 | * This file documents all the macros approved for use in windows source |
7 | * code. It includes some experimental macros which should only be used by |
8 | * experts. |
9 | * |
10 | * DO NOT include this file directly. This file is include after |
11 | * specstrings.h. So we can undefine every possible old definition including |
12 | * private internal macros people should not be using, as well as macros from |
13 | * sal.h. Macros are redefined here in a way to cause syntax errors when used |
14 | * incorrectly during a normal build when specstrings.h is included and |
15 | * __SPECSTRINGS_STRICT_LEVEL is defined. |
16 | * |
17 | * There are several levels of strictness, each level includes the behavior of |
18 | * all previous levels. |
19 | * |
20 | * 0 - Disable strict checking |
21 | * 1 - Break on unapproved macros and misuse of statement |
22 | * macros such as __fallthrough (default) |
23 | * 2 - Deprecated some old macros that should not be used |
24 | * 3 - Use VS 2005 Source Annotation to make sure every macro |
25 | * is used in the right context. For example placing __in on a return |
26 | * parameter will result in an error. |
27 | * |
28 | |
29 | * |
30 | ************************************************************************/ |
31 | #ifndef __SPECSTRINGS_STRICT_LEVEL |
32 | #define __SPECSTRINGS_STRICT_LEVEL 1 |
33 | #endif |
34 | /************************************************************************ |
35 | * Introduction |
36 | * |
37 | * specstrings.h provides a set of annotations to describe how a function uses |
38 | * its parameters - the assumptions it makes about them, and the guarantees it |
39 | * makes upon finishing. |
40 | * |
41 | * Annotations must be placed before a function parameter's type or its return |
42 | * type. There are two basic classes of common annotations buffer annotations |
43 | * and advanced annotations. Buffer annotations describe how functions use |
44 | * their pointer parameters, and advanced annotations either describe |
45 | * complex/unusual buffer behavior, or provide additional information about a |
46 | * parameter that is not otherwise expressible. |
47 | * |
48 | * Buffer Annotations |
49 | * |
50 | * The most important annotations in SpecStrings.h provide a consistent way to |
51 | * annotate buffer parameters or return values for a function. Each of these |
52 | * annotations describes a single buffer (which could be a string, a |
53 | * fixed-length or variable-length array, or just a pointer) that the function |
54 | * interacts with: where it is, how large it is, how much is initialized, and |
55 | * what the function does with it. |
56 | * |
57 | * The appropriate macro for a given buffer can be constructed using the table |
58 | * below. Just pick the appropriate values from each category, and combine |
59 | * them together with a leading underscore. Some combinations of values do not |
60 | * make sense as buffer annotations. Only meaningful annotations can be added |
61 | * to your code; for a list of these, see the buffer annotation definitions |
62 | * section. |
63 | * |
64 | * Only a single buffer annotation should be used for each parameter. |
65 | * |
66 | * |------------|------------|---------|--------|----------|---------------| |
67 | * | Level | Usage | Size | Output | Optional | Parameters | |
68 | * |------------|------------|---------|--------|----------|---------------| |
69 | * | <> | <> | <> | <> | <> | <> | |
70 | * | _deref | _in | _ecount | _full | _opt | (size) | |
71 | * | _deref_opt | _out | _bcount | _part | | (size,length) | |
72 | * | | _inout | | | | | |
73 | * | | | | | | | |
74 | * |------------|------------|---------|--------|----------|---------------| |
75 | * |
76 | * Note: "<>" represents the empty string. |
77 | * |
78 | * Level: Describes the buffer pointer's level of indirection from the |
79 | * parameter or return value 'p'. |
80 | * |
81 | * <> : p is the buffer pointer. |
82 | * _deref : *p is the buffer pointer. p must not be NULL. |
83 | * _deref_opt : *p may be the buffer pointer. p may be NULL, in which case the |
84 | * rest of the annotation is ignored. |
85 | * |
86 | * Usage: Describes how the function uses the buffer. |
87 | * |
88 | * <> : The buffer is not accessed. If used on the return value or with |
89 | * _deref, the function will provide the buffer, and it will be uninitialized |
90 | * at exit. Otherwise, the caller must provide the buffer. This should only |
91 | * be used for alloc and free functions. |
92 | * |
93 | * _in : The function will only read from the buffer. The caller must provide |
94 | * the buffer and initialize it. |
95 | * |
96 | * _out : The function will only write to the buffer. If used on the return |
97 | * value or with _deref, the function will provide the buffer and initialize |
98 | * it. Otherwise, the caller must provide the buffer, and the function will |
99 | * initialize it. |
100 | * |
101 | * _inout : The function may freely read from and write to the buffer. The |
102 | * caller must provide the buffer and initialize it. If used with _deref, the |
103 | * buffer may be reallocated by the function. |
104 | * |
105 | * Size: Describes the total size of the buffer. This may be less than the |
106 | * space actually allocated for the buffer, in which case it describes the |
107 | * accessible amount. |
108 | * |
109 | * <> : No buffer size is given. If the type specifies the buffer size (such |
110 | * as with LPSTR and LPWSTR), that amount is used. Otherwise, the buffer is |
111 | * one element long. Must be used with _in, _out, or _inout. |
112 | * |
113 | * _ecount : The buffer size is an explicit element count. |
114 | * |
115 | * _bcount : The buffer size is an explicit byte count. |
116 | * |
117 | * Output: Describes how much of the buffer will be initialized by the |
118 | * function. For _inout buffers, this also describes how much is initialized |
119 | * at entry. Omit this category for _in buffers; they must be fully |
120 | * initialized by the caller. |
121 | * |
122 | * <> : The type specifies how much is initialized. For instance, a function |
123 | * initializing an LPWSTR must NULL-terminate the string. |
124 | * |
125 | * _full : The function initializes the entire buffer. |
126 | * |
127 | * _part : The function initializes part of the buffer, and explicitly |
128 | * indicates how much. |
129 | * |
130 | * Optional: Describes if the buffer itself is optional. |
131 | * |
132 | * <> : The pointer to the buffer must not be NULL. |
133 | * |
134 | * _opt : The pointer to the buffer might be NULL. It will be checked before |
135 | * being dereferenced. |
136 | * |
137 | * Parameters: Gives explicit counts for the size and length of the buffer. |
138 | * |
139 | * <> : There is no explicit count. Use when neither _ecount nor _bcount is |
140 | * used. |
141 | * |
142 | * (size) : Only the buffer's total size is given. Use with _ecount or _bcount |
143 | * but not _part. |
144 | * |
145 | * (size,length) : The buffer's total size and initialized length are |
146 | * given. Use with _ecount_part and _bcount_part. |
147 | * |
148 | * ---------------------------------------------------------------------------- |
149 | * Buffer Annotation Examples |
150 | * |
151 | * LWSTDAPI_(BOOL) StrToIntExA( |
152 | * LPCSTR pszString, // No annotation required, const implies __in. |
153 | * DWORD dwFlags, |
154 | * __out int *piRet // A pointer whose dereference will be filled in. |
155 | * ); |
156 | * |
157 | * void MyPaintingFunction( |
158 | * __in HWND hwndControl, // An initialized read-only parameter. |
159 | * __in_opt HDC hdcOptional, // An initialized read-only parameter that |
160 | * // might be NULL. |
161 | * __inout IPropertyStore *ppsStore // An initialized parameter that |
162 | * // may be freely used and modified. |
163 | * ); |
164 | * |
165 | * LWSTDAPI_(BOOL) PathCompactPathExA( |
166 | * __out_ecount(cchMax) LPSTR pszOut, // A string buffer with cch elements |
167 | * // that will be '\0' terminated |
168 | * // on exit. |
169 | * LPCSTR pszSrc, // No annotation required, |
170 | * // const implies __in. |
171 | * UINT cchMax, |
172 | * DWORD dwFlags |
173 | * ); |
174 | * |
175 | * HRESULT SHLocalAllocBytes( |
176 | * size_t cb, |
177 | * __deref_bcount(cb) T **ppv // A pointer whose dereference will be set |
178 | * // to an uninitialized buffer with cb bytes. |
179 | * ); |
180 | * |
181 | * __inout_bcount_full(cb) : A buffer with cb elements that is fully |
182 | * initialized at entry and exit, and may be written to by this function. |
183 | * |
184 | * __out_ecount_part(count, *countOut) : A buffer with count elements that |
185 | * will be partially initialized by this function. The function indicates how |
186 | * much it initialized by setting *countOut. |
187 | * |
188 | ************************************************************************/ |
189 | |
190 | #if (_MSC_VER >= 1400) && !defined(__midl) && !defined(_PREFAST_) && (__SPECSTRINGS_STRICT_LEVEL > 0) |
191 | #pragma once |
192 | #include <specstrings_undef.h> |
193 | #define __ecount(size) _SAL_VERSION_CHECK(__ecount) |
194 | #define __bcount(size) _SAL_VERSION_CHECK(__bcount) |
195 | #define __xcount(size) _SAL_VERSION_CHECK(__xcount) |
196 | #define __in _SAL_VERSION_CHECK(__in) |
197 | #define __in_ecount(size) _SAL_VERSION_CHECK(__in_ecount) |
198 | #define __in_bcount(size) _SAL_VERSION_CHECK(__in_bcount) |
199 | #define __in_xcount(size) _SAL_VERSION_CHECK(__in_xcount) |
200 | #define __in_z _SAL_VERSION_CHECK(__in_z) |
201 | #define __in_ecount_z(size) _SAL_VERSION_CHECK(__in_ecount_z) |
202 | #define __in_bcount_z(size) _SAL_VERSION_CHECK(__in_bcount_z) |
203 | #define __out _SAL_VERSION_CHECK(__out) |
204 | #define __out_ecount(size) _SAL_VERSION_CHECK(__out_ecount) |
205 | #define __out_bcount(size) _SAL_VERSION_CHECK(__out_bcount) |
206 | #define __out_xcount(size) _SAL_VERSION_CHECK(__out_xcount) |
207 | #define __out_ecount_part(size,len) _SAL_VERSION_CHECK(__out_ecount_part) |
208 | #define __out_bcount_part(size,len) _SAL_VERSION_CHECK(__out_bcount_part) |
209 | #define __out_xcount_part(size,len) _SAL_VERSION_CHECK(__out_xcount_part) |
210 | #define __out_ecount_full(size) _SAL_VERSION_CHECK(__out_ecount_full) |
211 | #define __out_bcount_full(size) _SAL_VERSION_CHECK(__out_bcount_full) |
212 | #define __out_xcount_full(size) _SAL_VERSION_CHECK(__out_xcount_full) |
213 | #define __out_z _SAL_VERSION_CHECK(__out_z) |
214 | #define __out_ecount_z(size) _SAL_VERSION_CHECK(__out_ecount_z) |
215 | #define __out_bcount_z(size) _SAL_VERSION_CHECK(__out_bcount_z) |
216 | #define __inout _SAL_VERSION_CHECK(__inout) |
217 | #define __inout_ecount(size) _SAL_VERSION_CHECK(__inout_ecount) |
218 | #define __inout_bcount(size) _SAL_VERSION_CHECK(__inout_bcount) |
219 | #define __inout_xcount(size) _SAL_VERSION_CHECK(__inout_xcount) |
220 | #define __inout_ecount_part(size,len) _SAL_VERSION_CHECK(__inout_ecount_part) |
221 | #define __inout_bcount_part(size,len) _SAL_VERSION_CHECK(__inout_bcount_part) |
222 | #define __inout_xcount_part(size,len) _SAL_VERSION_CHECK(__inout_xcount_part) |
223 | #define __inout_ecount_full(size) _SAL_VERSION_CHECK(__inout_ecount_full) |
224 | #define __inout_bcount_full(size) _SAL_VERSION_CHECK(__inout_bcount_full) |
225 | #define __inout_xcount_full(size) _SAL_VERSION_CHECK(__inout_xcount_full) |
226 | #define __inout_z __allowed(on_parameter) |
227 | #define __inout_ecount_z(size) __allowed(on_parameter) |
228 | #define __inout_bcount_z(size) __allowed(on_parameter) |
229 | #define __ecount_opt(size) __allowed(on_parameter) |
230 | #define __bcount_opt(size) __allowed(on_parameter) |
231 | #define __xcount_opt(size) __allowed(on_parameter) |
232 | #define __in_opt _SAL_VERSION_CHECK(__in_opt) |
233 | #define __in_ecount_opt(size) _SAL_VERSION_CHECK(__in_ecount_opt) |
234 | #define __in_bcount_opt(size) _SAL_VERSION_CHECK(__in_bcount_opt) |
235 | #define __in_z_opt __allowed(on_parameter) |
236 | #define __in_ecount_z_opt(size) __allowed(on_parameter) |
237 | #define __in_bcount_z_opt(size) __allowed(on_parameter) |
238 | #define __in_xcount_opt(size) __allowed(on_parameter) |
239 | #define __out_opt _SAL_VERSION_CHECK(__out_opt) |
240 | #define __out_ecount_opt(size) _SAL_VERSION_CHECK(__out_ecount_opt) |
241 | #define __out_bcount_opt(size) _SAL_VERSION_CHECK(__out_bcount_opt) |
242 | #define __out_xcount_opt(size) __allowed(on_parameter) |
243 | #define __out_ecount_part_opt(size,len) __allowed(on_parameter) |
244 | #define __out_bcount_part_opt(size,len) __allowed(on_parameter) |
245 | #define __out_xcount_part_opt(size,len) __allowed(on_parameter) |
246 | #define __out_ecount_full_opt(size) __allowed(on_parameter) |
247 | #define __out_bcount_full_opt(size) __allowed(on_parameter) |
248 | #define __out_xcount_full_opt(size) __allowed(on_parameter) |
249 | #define __out_ecount_z_opt(size) __allowed(on_parameter) |
250 | #define __out_bcount_z_opt(size) __allowed(on_parameter) |
251 | #define __inout_opt _SAL_VERSION_CHECK(__inout_opt) |
252 | #define __inout_ecount_opt(size) _SAL_VERSION_CHECK(__inout_ecount_opt) |
253 | #define __inout_bcount_opt(size) _SAL_VERSION_CHECK(__inout_bcount_opt) |
254 | #define __inout_xcount_opt(size) _SAL_VERSION_CHECK(__inout_xcount_opt) |
255 | #define __inout_ecount_part_opt(size,len) _SAL_VERSION_CHECK(__inout_ecount_part_opt) |
256 | #define __inout_bcount_part_opt(size,len) _SAL_VERSION_CHECK(__inout_bcount_part_opt) |
257 | #define __inout_xcount_part_opt(size,len) _SAL_VERSION_CHECK(__inout_xcount_part_opt) |
258 | #define __inout_ecount_full_opt(size) _SAL_VERSION_CHECK(__inout_ecount_full_opt) |
259 | #define __inout_bcount_full_opt(size) _SAL_VERSION_CHECK(__inout_bcount_full_opt) |
260 | #define __inout_xcount_full_opt(size) _SAL_VERSION_CHECK(__inout_xcount_full_opt) |
261 | #define __inout_z_opt __allowed(on_parameter) |
262 | #define __inout_ecount_z_opt(size) __allowed(on_parameter) |
263 | #define __inout_ecount_z_opt(size) __allowed(on_parameter) |
264 | #define __inout_bcount_z_opt(size) __allowed(on_parameter) |
265 | #define __deref_ecount(size) __allowed(on_parameter) |
266 | #define __deref_bcount(size) __allowed(on_parameter) |
267 | #define __deref_xcount(size) __allowed(on_parameter) |
268 | #define __deref_in _SAL_VERSION_CHECK(__deref_in) |
269 | #define __deref_in_ecount(size) _SAL_VERSION_CHECK(__deref_in_ecount) |
270 | #define __deref_in_bcount(size) _SAL_VERSION_CHECK(__deref_in_bcount) |
271 | #define __deref_in_xcount(size) _SAL_VERSION_CHECK(__deref_in_xcount) |
272 | #define __deref_out _SAL_VERSION_CHECK(__deref_out) |
273 | #define __deref_out_ecount(size) _SAL_VERSION_CHECK(__deref_out_ecount) |
274 | #define __deref_out_bcount(size) _SAL_VERSION_CHECK(__deref_out_bcount) |
275 | #define __deref_out_xcount(size) _SAL_VERSION_CHECK(__deref_out_xcount) |
276 | #define __deref_out_ecount_part(size,len) _SAL_VERSION_CHECK(__deref_out_ecount_part) |
277 | #define __deref_out_bcount_part(size,len) _SAL_VERSION_CHECK(__deref_out_bcount_part) |
278 | #define __deref_out_xcount_part(size,len) _SAL_VERSION_CHECK(__deref_out_xcount_part) |
279 | #define __deref_out_ecount_full(size) _SAL_VERSION_CHECK(__deref_out_ecount_full) |
280 | #define __deref_out_bcount_full(size) _SAL_VERSION_CHECK(__deref_out_bcount_full) |
281 | #define __deref_out_xcount_full(size) _SAL_VERSION_CHECK(__deref_out_xcount_full) |
282 | #define __deref_out_z __allowed(on_parameter) |
283 | #define __deref_out_ecount_z(size) __allowed(on_parameter) |
284 | #define __deref_out_bcount_z(size) __allowed(on_parameter) |
285 | #define __deref_inout _SAL_VERSION_CHECK(__deref_inout) |
286 | #define __deref_inout_ecount(size) _SAL_VERSION_CHECK(__deref_inout_ecount) |
287 | #define __deref_inout_bcount(size) _SAL_VERSION_CHECK(__deref_inout_bcount) |
288 | #define __deref_inout_xcount(size) _SAL_VERSION_CHECK(__deref_inout_xcount) |
289 | #define __deref_inout_ecount_part(size,len) __allowed(on_parameter) |
290 | #define __deref_inout_bcount_part(size,len) __allowed(on_parameter) |
291 | #define __deref_inout_xcount_part(size,len) __allowed(on_parameter) |
292 | #define __deref_inout_ecount_full(size) __allowed(on_parameter) |
293 | #define __deref_inout_bcount_full(size) __allowed(on_parameter) |
294 | #define __deref_inout_xcount_full(size) __allowed(on_parameter) |
295 | #define __deref_inout_z __allowed(on_parameter) |
296 | #define __deref_inout_ecount_z(size) __allowed(on_parameter) |
297 | #define __deref_inout_bcount_z(size) __allowed(on_parameter) |
298 | #define __deref_ecount_opt(size) __allowed(on_parameter) |
299 | #define __deref_bcount_opt(size) __allowed(on_parameter) |
300 | #define __deref_xcount_opt(size) __allowed(on_parameter) |
301 | #define __deref_in_opt __allowed(on_parameter) |
302 | #define __deref_in_opt_out __allowed(on_parameter) |
303 | #define __deref_in_ecount_opt(size) __allowed(on_parameter) |
304 | #define __deref_in_bcount_opt(size) __allowed(on_parameter) |
305 | #define __deref_in_xcount_opt(size) __allowed(on_parameter) |
306 | #define __deref_out_opt _SAL_VERSION_CHECK(__deref_out_opt) |
307 | #define __deref_out_ecount_opt(size) _SAL_VERSION_CHECK(__deref_out_ecount_opt) |
308 | #define __deref_out_bcount_opt(size) _SAL_VERSION_CHECK(__deref_out_bcount_opt) |
309 | #define __deref_out_xcount_opt(size) _SAL_VERSION_CHECK(__deref_out_xcount_opt) |
310 | #define __deref_out_ecount_part_opt(size,len) _SAL_VERSION_CHECK(__deref_out_ecount_part_opt) |
311 | #define __deref_out_bcount_part_opt(size,len) _SAL_VERSION_CHECK(__deref_out_bcount_part_opt) |
312 | #define __deref_out_xcount_part_opt(size,len) _SAL_VERSION_CHECK(__deref_out_xcount_part_opt) |
313 | #define __deref_out_ecount_full_opt(size) _SAL_VERSION_CHECK(__deref_out_ecount_full_opt) |
314 | #define __deref_out_bcount_full_opt(size) _SAL_VERSION_CHECK(__deref_out_bcount_full_opt) |
315 | #define __deref_out_xcount_full_opt(size) _SAL_VERSION_CHECK(__deref_out_xcount_full_opt) |
316 | #define __deref_out_z_opt __allowed(on_parameter) |
317 | #define __deref_out_ecount_z_opt(size) __allowed(on_parameter) |
318 | #define __deref_out_bcount_z_opt(size) __allowed(on_parameter) |
319 | #define __deref_inout_opt __allowed(on_parameter) |
320 | #define __deref_inout_ecount_opt(size) __allowed(on_parameter) |
321 | #define __deref_inout_bcount_opt(size) __allowed(on_parameter) |
322 | #define __deref_inout_xcount_opt(size) __allowed(on_parameter) |
323 | #define __deref_inout_ecount_part_opt(size,len) __allowed(on_parameter) |
324 | #define __deref_inout_bcount_part_opt(size,len) __allowed(on_parameter) |
325 | #define __deref_inout_xcount_part_opt(size,len) __allowed(on_parameter) |
326 | #define __deref_inout_ecount_full_opt(size) __allowed(on_parameter) |
327 | #define __deref_inout_bcount_full_opt(size) __allowed(on_parameter) |
328 | #define __deref_inout_xcount_full_opt(size) __allowed(on_parameter) |
329 | #define __deref_inout_z_opt __allowed(on_parameter) |
330 | #define __deref_inout_ecount_z_opt(size) __allowed(on_parameter) |
331 | #define __deref_inout_bcount_z_opt(size) __allowed(on_parameter) |
332 | #define __deref_opt_ecount(size) __allowed(on_parameter) |
333 | #define __deref_opt_bcount(size) __allowed(on_parameter) |
334 | #define __deref_opt_xcount(size) __allowed(on_parameter) |
335 | #define __deref_opt_in __allowed(on_parameter) |
336 | #define __deref_opt_in_ecount(size) __allowed(on_parameter) |
337 | #define __deref_opt_in_bcount(size) __allowed(on_parameter) |
338 | #define __deref_opt_in_xcount(size) __allowed(on_parameter) |
339 | #define __deref_opt_out _SAL_VERSION_CHECK(__deref_opt_out) |
340 | #define __deref_opt_out_ecount(size) _SAL_VERSION_CHECK(__deref_opt_out_ecount) |
341 | #define __deref_opt_out_bcount(size) _SAL_VERSION_CHECK(__deref_opt_out_bcount) |
342 | #define __deref_opt_out_xcount(size) _SAL_VERSION_CHECK(__deref_opt_out_xcount) |
343 | #define __deref_opt_out_ecount_part(size,len) __allowed(on_parameter) |
344 | #define __deref_opt_out_bcount_part(size,len) __allowed(on_parameter) |
345 | #define __deref_opt_out_xcount_part(size,len) __allowed(on_parameter) |
346 | #define __deref_opt_out_ecount_full(size) __allowed(on_parameter) |
347 | #define __deref_opt_out_bcount_full(size) __allowed(on_parameter) |
348 | #define __deref_opt_out_xcount_full(size) __allowed(on_parameter) |
349 | #define __deref_opt_inout __allowed(on_parameter) |
350 | #define __deref_opt_inout_ecount(size) __allowed(on_parameter) |
351 | #define __deref_opt_inout_bcount(size) __allowed(on_parameter) |
352 | #define __deref_opt_inout_xcount(size) __allowed(on_parameter) |
353 | #define __deref_opt_inout_ecount_part(size,len) __allowed(on_parameter) |
354 | #define __deref_opt_inout_bcount_part(size,len) __allowed(on_parameter) |
355 | #define __deref_opt_inout_xcount_part(size,len) __allowed(on_parameter) |
356 | #define __deref_opt_inout_ecount_full(size) __allowed(on_parameter) |
357 | #define __deref_opt_inout_bcount_full(size) __allowed(on_parameter) |
358 | #define __deref_opt_inout_xcount_full(size) __allowed(on_parameter) |
359 | #define __deref_opt_inout_z __allowed(on_parameter) |
360 | #define __deref_opt_inout_ecount_z(size) __allowed(on_parameter) |
361 | #define __deref_opt_inout_bcount_z(size) __allowed(on_parameter) |
362 | #define __deref_opt_ecount_opt(size) __allowed(on_parameter) |
363 | #define __deref_opt_bcount_opt(size) __allowed(on_parameter) |
364 | #define __deref_opt_xcount_opt(size) __allowed(on_parameter) |
365 | #define __deref_opt_in_opt __allowed(on_parameter) |
366 | #define __deref_opt_in_ecount_opt(size) __allowed(on_parameter) |
367 | #define __deref_opt_in_bcount_opt(size) __allowed(on_parameter) |
368 | #define __deref_opt_in_xcount_opt(size) __allowed(on_parameter) |
369 | #define __deref_opt_out_opt __allowed(on_parameter) |
370 | #define __deref_opt_out_ecount_opt(size) __allowed(on_parameter) |
371 | #define __deref_opt_out_bcount_opt(size) __allowed(on_parameter) |
372 | #define __deref_opt_out_xcount_opt(size) __allowed(on_parameter) |
373 | #define __deref_opt_out_ecount_part_opt(size,len) __allowed(on_parameter) |
374 | #define __deref_opt_out_bcount_part_opt(size,len) __allowed(on_parameter) |
375 | #define __deref_opt_out_xcount_part_opt(size,len) __allowed(on_parameter) |
376 | #define __deref_opt_out_ecount_full_opt(size) __allowed(on_parameter) |
377 | #define __deref_opt_out_bcount_full_opt(size) __allowed(on_parameter) |
378 | #define __deref_opt_out_xcount_full_opt(size) __allowed(on_parameter) |
379 | #define __deref_opt_out_z_opt __allowed(on_parameter) |
380 | #define __deref_opt_out_ecount_z_opt(size) __allowed(on_parameter) |
381 | #define __deref_opt_out_bcount_z_opt(size) __allowed(on_parameter) |
382 | #define __deref_opt_inout_opt __allowed(on_parameter) |
383 | #define __deref_opt_inout_ecount_opt(size) __allowed(on_parameter) |
384 | #define __deref_opt_inout_bcount_opt(size) __allowed(on_parameter) |
385 | #define __deref_opt_inout_xcount_opt(size) __allowed(on_parameter) |
386 | #define __deref_opt_inout_ecount_part_opt(size,len) __allowed(on_parameter) |
387 | #define __deref_opt_inout_bcount_part_opt(size,len) __allowed(on_parameter) |
388 | #define __deref_opt_inout_xcount_part_opt(size,len) __allowed(on_parameter) |
389 | #define __deref_opt_inout_ecount_full_opt(size) __allowed(on_parameter) |
390 | #define __deref_opt_inout_bcount_full_opt(size) __allowed(on_parameter) |
391 | #define __deref_opt_inout_xcount_full_opt(size) __allowed(on_parameter) |
392 | #define __deref_opt_inout_z_opt __allowed(on_parameter) |
393 | #define __deref_opt_inout_ecount_z_opt(size) __allowed(on_parameter) |
394 | #define __deref_opt_inout_bcount_z_opt(size) __allowed(on_parameter) |
395 | #define __deref_in_ecount_iterator(size,incr) __allowed(on_parameter) |
396 | #define __deref_out_ecount_iterator(size,incr) __allowed(on_parameter) |
397 | #define __deref_inout_ecount_iterator(size,incr) __allowed(on_parameter) |
398 | #define __deref_realloc_bcount(insize,outsize) __allowed(on_parameter) |
399 | |
400 | /************************************************************************ |
401 | * SAL 2 _Ouptr_ family of annotations |
402 | ************************************************************************/ |
403 | |
404 | #define _Outptr_ __allowed(on_parameter) |
405 | #define _Outptr_result_maybenull_ __allowed(on_parameter) |
406 | #define _Outptr_opt_ __allowed(on_parameter) |
407 | #define _Outptr_opt_result_maybenull_ __allowed(on_parameter) |
408 | #define _Outptr_result_z_ __allowed(on_parameter) |
409 | #define _Outptr_opt_result_z_ __allowed(on_parameter) |
410 | #define _Outptr_result_maybenull_z_ __allowed(on_parameter) |
411 | #define _Outptr_opt_result_maybenull_z_ __allowed(on_parameter) |
412 | #define _Outptr_result_nullonfailure_ __allowed(on_parameter) |
413 | #define _Outptr_opt_result_nullonfailure_ __allowed(on_parameter) |
414 | #define _COM_Outptr_ __allowed(on_parameter) |
415 | #define _COM_Outptr_result_maybenull_ __allowed(on_parameter) |
416 | #define _COM_Outptr_opt_ __allowed(on_parameter) |
417 | #define _COM_Outptr_opt_result_maybenull_ __allowed(on_parameter) |
418 | #define _Outptr_result_buffer_(size) __allowed(on_parameter) |
419 | #define _Outptr_opt_result_buffer_(size) __allowed(on_parameter) |
420 | #define _Outptr_result_buffer_to_(size, count) __allowed(on_parameter) |
421 | #define _Outptr_opt_result_buffer_to_(size, count) __allowed(on_parameter) |
422 | #define _Outptr_result_buffer_all_(size) __allowed(on_parameter) |
423 | #define _Outptr_opt_result_buffer_all_(size) __allowed(on_parameter) |
424 | #define _Outptr_result_buffer_maybenull_(size) __allowed(on_parameter) |
425 | #define _Outptr_opt_result_buffer_maybenull_(size) __allowed(on_parameter) |
426 | #define _Outptr_result_buffer_to_maybenull_(size, count) __allowed(on_parameter) |
427 | #define _Outptr_opt_result_buffer_to_maybenull_(size, count) __allowed(on_parameter) |
428 | #define _Outptr_result_buffer_all_maybenull_(size) __allowed(on_parameter) |
429 | #define _Outptr_opt_result_buffer_all_maybenull_(size) __allowed(on_parameter) |
430 | #define _Outptr_result_bytebuffer_(size) __allowed(on_parameter) |
431 | #define _Outptr_opt_result_bytebuffer_(size) __allowed(on_parameter) |
432 | #define _Outptr_result_bytebuffer_to_(size, count) __allowed(on_parameter) |
433 | #define _Outptr_opt_result_bytebuffer_to_(size, count) __allowed(on_parameter) |
434 | #define _Outptr_result_bytebuffer_all_(size) __allowed(on_parameter) |
435 | #define _Outptr_opt_result_bytebuffer_all_(size) __allowed(on_parameter) |
436 | #define _Outptr_result_bytebuffer_maybenull_(size) __allowed(on_parameter) |
437 | #define _Outptr_opt_result_bytebuffer_maybenull_(size) __allowed(on_parameter) |
438 | #define _Outptr_result_bytebuffer_to_maybenull_(size, count) __allowed(on_parameter) |
439 | #define _Outptr_opt_result_bytebuffer_to_maybenull_(size, count) __allowed(on_parameter) |
440 | #define _Outptr_result_bytebuffer_all_maybenull_(size) __allowed(on_parameter) |
441 | #define _Outptr_opt_result_bytebuffer_all_maybenull_(size) __allowed(on_parameter) |
442 | |
443 | /************************************************************************ |
444 | * Orcas SAL |
445 | ************************************************************************/ |
446 | #define _Deref_out_ _SAL_VERSION_CHECK(_Deref_out_) |
447 | #define _Deref_out_opt_ _SAL_VERSION_CHECK(_Deref_out_opt_) |
448 | #define _Deref_opt_out_ _SAL_VERSION_CHECK(_Deref_opt_out_) |
449 | #define _Deref_opt_out_opt_ _SAL_VERSION_CHECK(_Deref_opt_out_opt_) |
450 | #define _In_count_(size) _SAL_VERSION_CHECK(_In_count_) |
451 | #define _In_opt_count_(size) _SAL_VERSION_CHECK(_In_opt_count_) |
452 | #define _In_bytecount_(size) _SAL_VERSION_CHECK(_In_bytecount_) |
453 | #define _In_opt_bytecount_(size) _SAL_VERSION_CHECK(_In_opt_bytecount_) |
454 | #define _Out_cap_(size) _SAL_VERSION_CHECK(_Out_cap_) |
455 | #define _Out_opt_cap_(size) _SAL_VERSION_CHECK(_Out_opt_cap_) |
456 | #define _Out_bytecap_(size) _SAL_VERSION_CHECK(_Out_bytecap_) |
457 | #define _Out_opt_bytecap_(size) _SAL_VERSION_CHECK(_Out_opt_bytecap_) |
458 | #define _Deref_post_count_(size) _SAL_VERSION_CHECK(_Deref_post_count_) |
459 | #define _Deref_post_opt_count_(size) _SAL_VERSION_CHECK(_Deref_post_opt_count_) |
460 | #define _Deref_post_bytecount_(size) _SAL_VERSION_CHECK(_Deref_post_bytecount_) |
461 | #define _Deref_post_opt_bytecount_(size) _SAL_VERSION_CHECK(_Deref_post_opt_bytecount_) |
462 | #define _Deref_post_cap_(size) _SAL_VERSION_CHECK(_Deref_post_cap_) |
463 | #define _Deref_post_opt_cap_(size) _SAL_VERSION_CHECK(_Deref_post_opt_cap_) |
464 | #define _Deref_post_bytecap_(size) _SAL_VERSION_CHECK(_Deref_post_bytecap_) |
465 | #define _Deref_post_opt_bytecap_(size) _SAL_VERSION_CHECK(_Deref_post_opt_bytecap_) |
466 | |
467 | /************************************************************************ |
468 | * Advanced Annotations |
469 | * |
470 | * Advanced annotations describe behavior that is not expressible with the |
471 | * regular buffer macros. These may be used either to annotate buffer |
472 | * parameters that involve complex or conditional behavior, or to enrich |
473 | * existing annotations with additional information. |
474 | * |
475 | * _At_(expr, annotes) : annotation list annotes applies to target 'expr' |
476 | * |
477 | * _When_(expr, annotes) : annotation list annotes applies when 'expr' is true |
478 | * |
479 | * __success(expr) T f() : <expr> indicates whether function f succeeded or |
480 | * not. If <expr> is true at exit, all the function's guarantees (as given |
481 | * by other annotations) must hold. If <expr> is false at exit, the caller |
482 | * should not expect any of the function's guarantees to hold. If not used, |
483 | * the function must always satisfy its guarantees. Added automatically to |
484 | * functions that indicate success in standard ways, such as by returning an |
485 | * HRESULT. |
486 | * |
487 | * __out_awcount(expr, size) T *p : Pointer p is a buffer whose size may be |
488 | * given in either bytes or elements. If <expr> is true, this acts like |
489 | * __out_bcount. If <expr> is false, this acts like __out_ecount. This |
490 | * should only be used to annotate old APIs. |
491 | * |
492 | * __in_awcount(expr, size) T* p : Pointer p is a buffer whose size may be given |
493 | * in either bytes or elements. If <expr> is true, this acts like |
494 | * __in_bcount. If <expr> is false, this acts like __in_ecount. This should |
495 | * only be used to annotate old APIs. |
496 | * |
497 | * __nullterminated T* p : Pointer p is a buffer that may be read or written |
498 | * up to and including the first '\0' character or pointer. May be used on |
499 | * typedefs, which marks valid (properly initialized) instances of that type |
500 | * as being null-terminated. |
501 | * |
502 | * __nullnullterminated T* p : Pointer p is a buffer that may be read or |
503 | * written up to and including the first sequence of two '\0' characters or |
504 | * pointers. May be used on typedefs, which marks valid instances of that |
505 | * type as being double-null terminated. |
506 | * |
507 | * __reserved T v : Value v must be 0/NULL, reserved for future use. |
508 | * |
509 | * __checkReturn T f(); : Return value of f must not be ignored by callers |
510 | * of this function. |
511 | * |
512 | * __typefix(ctype) T v : Value v should be treated as an instance of ctype, |
513 | * rather than its declared type when considering validity. |
514 | * |
515 | * __override T f(); : Specify C#-style 'override' behaviour for overriding |
516 | * virtual methods. |
517 | * |
518 | * __callback T f(); : Function f can be used as a function pointer. |
519 | * |
520 | * __format_string T p : Pointer p is a string that contains % markers in |
521 | * the style of printf. |
522 | * |
523 | * __blocksOn(resource) f(); : Function f blocks on the resource 'resource'. |
524 | * |
525 | * __fallthrough : Annotates switch statement labels where fall-through is |
526 | * desired, to distinguish from forgotten break statements. |
527 | * |
528 | * __range(low_bnd, up_bnd) int f(): The return from the function "f" must |
529 | * be in the inclusive numeric range [low_bnd, up_bnd]. |
530 | * |
531 | * __in_range(low_bnd, up_bnd) int i : Precondition that integer i must be |
532 | * in the inclusive numeric range [low_bnd, up_bnd]. |
533 | * |
534 | * __out_range(low_bnd, up_bnd) int i : Postcondition that integer i must be |
535 | * in the inclusive numeric range [low_bnd, up_bnd]. |
536 | * |
537 | * __deref_in_range(low_bnd, up_bnd) int* pi : Precondition that integer *pi |
538 | * must be in the inclusive numeric range [low_bnd, up_bnd]. |
539 | * |
540 | * __deref_out_range(low_bnd, up_bnd) int* pi : Postcondition that integer |
541 | * *pi must be in the inclusive numeric range [low_bnd, up_bnd]. |
542 | * |
543 | * __deref_inout_range(low_bnd, up_bnd) int* pi : Invariant that the integer |
544 | * *pi must be in the inclusive numeric range [low_bnd, up_bnd]. |
545 | * |
546 | * The first argument of a range macro may also be a C relational operator |
547 | * (<,>,!=, ==, <=, >=). |
548 | * |
549 | * __range(rel_op, j) int f(): Postcondition that "f() rel_op j" must be |
550 | * true. Note that j may be a expression known only at runtime. |
551 | * |
552 | * __in_range(rel_op, j) int i : Precondition that "i rel_op j" must be |
553 | * true. Note that j may be a expression known only at runtime. |
554 | * |
555 | * __out_range(rel_op, j) int i : Postcondition that integer "i rel_op j" |
556 | * must be true. Note that j may be a expression known only at runtime. |
557 | * |
558 | * __deref_in_range(rel_op, j) int *pi : Precondition that "*pi rel_op j" |
559 | * must be true. Note that j may be a expression known only at runtime. |
560 | * |
561 | * __deref_out_range(rel_op, j) int *pi : Postcondition that "*pi rel_op j" |
562 | * must be true. Note that j may be a expression known only at runtime. |
563 | * |
564 | * __deref_inout_range(rel_op, j) int *pi : Invariant that "*pi rel_op j" |
565 | * must be true. Note that j may be a expression known only at runtime. |
566 | * |
567 | * __range_max(a, b) int f(): Postcondition f acts as 'max', returns larger |
568 | * of a and b. Note that a and b may be expressions known only at runtime. |
569 | * |
570 | * __range_min(a, b) int f(): Postcondition f acts as 'min', returns smaller |
571 | * of a and b. Note that a and b may be expressions known only at runtime. |
572 | * |
573 | * __in_bound int i : Precondition that integer i must be bound, but the |
574 | * exact range can't be specified at compile time. __in_range should be |
575 | * used if the range can be explicitly stated. |
576 | * |
577 | * __out_bound int i : Postcondition that integer i must be bound, but the |
578 | * exact range can't be specified at compile time. __out_range should be |
579 | * used if the range can be explicitly stated. |
580 | * |
581 | * __deref_out_bound int pi : Postcondition that integer *pi must be bound, |
582 | * but the exact range can't be specified at compile time. |
583 | * __deref_out_range should be used if the range can be explicitly stated. |
584 | * |
585 | * __assume_bound(expr); : Assume that the expression is bound to some known |
586 | * range. This can be used to suppress integer overflow warnings on integral |
587 | * expressions that are known to be bound due to reasons not explicit in the |
588 | * code. Use as a statement in the body of a function. |
589 | * |
590 | * __analysis_assume_nulltermianted(expr); : Assume that the expression is |
591 | * a null terminated buffer. Use this to suppress tool noise specific to |
592 | * nulltermination warnings, and capture deeper invariants tools can not |
593 | * discover. |
594 | * |
595 | * __allocator void f(): Function allocates memory using an integral size |
596 | * argument |
597 | * |
598 | * void myfree(__deallocate(Mem) void *p) : Memory is freed, no longer usable |
599 | * upon return, and p may not be null. |
600 | * |
601 | * void myfree(__deallocate_opt(Mem) void *p) : Memory is freed, no longer |
602 | * usable upon return, and p may be null. |
603 | * |
604 | * void free(__post_invalid void* x): Mark memory as untouchable when |
605 | * function returns. |
606 | * |
607 | * ---------------------------------------------------------------------------- |
608 | * Advanced Annotation Examples |
609 | * |
610 | * __success(return == TRUE) LWSTDAPI_(BOOL) |
611 | * PathCanonicalizeA(__out_ecount(MAX_PATH) LPSTR pszBuf, LPCSTR pszPath); |
612 | * // pszBuf is only guaranteed to be null-terminated when TRUE is returned. |
613 | * |
614 | * // Initialized LPWSTRs are null-terminated strings. |
615 | * typedef __nullterminated WCHAR* LPWSTR; |
616 | * |
617 | * __out_ecount(cch) __typefix(LPWSTR) void *psz; |
618 | * // psz is a buffer parameter which will be a null-terminated WCHAR string |
619 | * // at exit, and which initially contains cch WCHARs. |
620 | * |
621 | ************************************************************************/ |
622 | #define _At_(expr, annotes) __allowed(on_parameter_or_return) |
623 | #define _When_(expr, annotes) __allowed(on_parameter_or_return) |
624 | #define __success(expr) _SAL_VERSION_CHECK(__success) |
625 | #define __out_awcount(expr,size) __allowed(on_parameter) |
626 | #define __in_awcount(expr,size) __allowed(on_parameter) |
627 | #define __nullterminated _SAL_VERSION_CHECK(__nullterminated) |
628 | #define __nullnullterminated _SAL_VERSION_CHECK(__nullnullterminated) |
629 | #define __clr_reserved _SAL_VERSION_CHECK(__reserved) |
630 | #define __checkReturn _SAL_VERSION_CHECK(__checkReturn) |
631 | #define __typefix(ctype) __allowed(on_parameter_or_return) |
632 | #define __override __allowed(on_function) |
633 | #define __callback __allowed(on_function) |
634 | #define __format_string __allowed(on_parameter_or_return) |
635 | #define __blocksOn(resource) __allowed(on_function) |
636 | #define __fallthrough __allowed(as_statement) |
637 | #define __range(lb,ub) __allowed(on_return) |
638 | #define __in_range(lb,ub) _SAL_VERSION_CHECK(__in_range) |
639 | #define __out_range(lb,ub) _SAL_VERSION_CHECK(__out_range) |
640 | #define __deref_in_range(lb,ub) __allowed(on_parameter) |
641 | #define __deref_out_range(lb,ub) _SAL_VERSION_CHECK(__deref_out_range) |
642 | #define __deref_inout_range(lb,ub) __allowed(on_parameter) |
643 | #define __field_range(lb,ub) _SAL_VERSION_CHECK(__field_range) |
644 | #define __range_max(a,b) __allowed(on_return) |
645 | #define __range_min(a,b) __allowed(on_return) |
646 | #define __bound __allowed(on_return) |
647 | #define __in_bound __allowed(on_parameter) |
648 | #define __out_bound __allowed(on_parameter) |
649 | #define __deref_out_bound __allowed(on_parameter) |
650 | #define __assume_bound(i) __allowed(as_statement_with_arg(i)) |
651 | #define __analysis_assume_nullterminated(x) \ |
652 | __allowed(as_statement_with_arg(x)) |
653 | #define __allocator __allowed(on_function) |
654 | #define __deallocate(kind) __allowed(on_parameter) |
655 | #define __deallocate_opt(kind) __allowed(on_parameter) |
656 | #define __post_invalid __allowed(on_parameter_or_return) |
657 | #define __post_nullnullterminated \ |
658 | __allowed(on_parameter_or_return) |
659 | /*************************************************************************** |
660 | * Expert Macros |
661 | ***************************************************************************/ |
662 | #define __null __allowed(on_typedecl) |
663 | #define __notnull __allowed(on_typedecl) |
664 | #define __maybenull __allowed(on_typedecl) |
665 | #define __exceptthat __allowed(on_typedecl) |
666 | /*************************************************************************** |
667 | * Macros to classify fields of structures. |
668 | * Structure Annotations |
669 | * |
670 | * The buffer annotations are a convenient way of describing |
671 | * relationships between buffers and their size on a function by |
672 | * function basis. Very often struct or class data members have similar |
673 | * invariants, which can be expressed directly on the type. |
674 | * |
675 | * Similar to our buffer annotations we can summarize all the various |
676 | * structure annotations by one choosing an element from each column of |
677 | * this table to build a composite annotation. |
678 | * |
679 | * +--------------------------------------------------+ |
680 | * | Selector | Units | Size/Init | Optional | |
681 | * |----------+---------+------------------+----------| |
682 | * | __field | _ecount | (size) | empty | |
683 | * |----------+---------+------------------+----------| |
684 | * | __struct | _bcount | _full(size) | _opt | |
685 | * |----------+---------+------------------+----------| |
686 | * | | _xcount | _part(size,init) | | |
687 | * +--------------------------------------------------+ |
688 | * |
689 | * Note that empty represents the empty string. Sometime arguments need |
690 | * to be "floated" to the left to give us a valid annotation name. For |
691 | * example the naive combination __field_ecount(size)_opt is actually |
692 | * written as __field_ecount_opt(size). Not all possible combinations |
693 | * are currently supported or sensible. See specstrings_strict.h for |
694 | * the currently supported set. Those that are supported are documented |
695 | * below. |
696 | * |
697 | *Summary of Elements |
698 | * |
699 | * Selector |
700 | * |
701 | * __field |
702 | * The annotation should only be placed in front |
703 | * of data members of structures and classes. The |
704 | * data members are pointers to a block of data. |
705 | * The annotations describe properties about the |
706 | * size of the block of data. This can be used for |
707 | * |
708 | * __struct |
709 | * The annotation should only be placed at the |
710 | * beginning of the definition of a structure or |
711 | * class. These annotations are used when a struct |
712 | * or class is used as a "header" that is |
713 | * allocated inline with a block of data and there |
714 | * is no apparent field that represents the tail |
715 | * end of the structure. |
716 | * |
717 | * Units |
718 | * |
719 | * _ecount |
720 | * All size and initialization values are in terms |
721 | * of elements of the appropriate type |
722 | * |
723 | * _bcount |
724 | * All size and initialization values are in terms |
725 | * of raw byte sizes. |
726 | * |
727 | * _xcount |
728 | * The size or initialization values cannot be |
729 | * properly expressed as a simple byte or element |
730 | * count, and instead a place holder is used to |
731 | * document the relationship. |
732 | * |
733 | * Size/Init |
734 | * All the size/init expressions can contain references to |
735 | * other fields in the struct or class. |
736 | * |
737 | * (size) |
738 | * The size of the buffer is determined by the |
739 | * expression size. Unless, the type of the buffer |
740 | * provides more information nothing is know about |
741 | * how much of this data is initialized. For |
742 | * example, if the data member happens to be a |
743 | * string type such as LPSTR. It is assumed that |
744 | * the data is initialized to the first '\0'. |
745 | * |
746 | * _full(size) |
747 | * The size of the buffer is determined by the |
748 | * expression size and all the data in the buffer |
749 | * is guaranteed to be initialized. |
750 | * |
751 | * _part(size,init) |
752 | * The size of the buffer is determined by the |
753 | * expression size and all the data in the buffer |
754 | * is guaranteed to be initialized up to init |
755 | * elements or bytes. |
756 | * |
757 | * Optional |
758 | * |
759 | * empty |
760 | * The pointer to the block of memory is never |
761 | * NULL |
762 | * |
763 | * _opt |
764 | * The pointer to the block of memory is may be |
765 | * NULL |
766 | * |
767 | * |
768 | * // Basic Usage of Struct Annotations |
769 | * #include <stdio.h> |
770 | * #include <stdlib.h> |
771 | * struct buf_s { |
772 | * int sz; |
773 | * __field_bcount_full(sz) |
774 | * char *buf; |
775 | * }; |
776 | * void InitBuf(__out struct *buf_s b,int sz) { |
777 | * b->buf = calloc(sz,sizeof(char)); |
778 | * b->sz = sz; |
779 | * } |
780 | * void WriteBuf(__in FILE *fp,__in struct *buf_s b) { |
781 | * fwrite(b->buf,b->sz,sizeof(char),fp); |
782 | * } |
783 | * void ReadBuf(__in FILE *fp,__inout struct *buf_s b) { |
784 | * fread(b->buf,b->sz,sizeof(char),fp); |
785 | * } |
786 | * |
787 | * |
788 | * |
789 | * // Inline Allocated Buffer |
790 | * struct buf_s { |
791 | * int sz; |
792 | * __field_bcount(sz) |
793 | * char buf[1]; |
794 | * }; |
795 | * void WriteBuf(__in FILE *fp,__in struct *buf_s b) { |
796 | * fwrite(&(b->buf),b->sz,sizeof(char),fp); |
797 | * } |
798 | * void ReadBuf(__in FILE *fp,__inout struct *buf_s b) { |
799 | * fread(&(b->buf),b->sz,sizeof(char),fp); |
800 | * } |
801 | * |
802 | * |
803 | * |
804 | * // Embedded Header Structure |
805 | * __struct_bcount(sz) |
806 | * struct buf_s { |
807 | * int sz; |
808 | * }; |
809 | * void WriteBuf(__in FILE *fp,__in struct *buf_s b) { |
810 | * fwrite(&b,b->sz,sizeof(char),fp); |
811 | * } |
812 | * void ReadBuf(__in FILE *fp,__inout struct *buf_s b) { |
813 | * fread(&b,b->sz,sizeof(char),fp); |
814 | * } |
815 | * |
816 | * |
817 | ****************************************************************************/ |
818 | #define __field_ecount(size) _SAL_VERSION_CHECK(__field_ecount) |
819 | #define __field_bcount(size) _SAL_VERSION_CHECK(__field_bcount) |
820 | #define __field_xcount(size) __allowed(on_field) |
821 | #define __field_ecount_opt(size) __allowed(on_field) |
822 | #define __field_bcount_opt(size) __allowed(on_field) |
823 | #define __field_xcount_opt(size) __allowed(on_field) |
824 | #define __field_ecount_part(size,init) __allowed(on_field) |
825 | #define __field_bcount_part(size,init) __allowed(on_field) |
826 | #define __field_xcount_part(size,init) __allowed(on_field) |
827 | #define __field_ecount_part_opt(size,init) __allowed(on_field) |
828 | #define __field_bcount_part_opt(size,init) __allowed(on_field) |
829 | #define __field_xcount_part_opt(size,init) __allowed(on_field) |
830 | #define __field_ecount_full(size) __allowed(on_field) |
831 | #define __field_bcount_full(size) __allowed(on_field) |
832 | #define __field_xcount_full(size) __allowed(on_field) |
833 | #define __field_ecount_full_opt(size) __allowed(on_field) |
834 | #define __field_bcount_full_opt(size) __allowed(on_field) |
835 | #define __field_xcount_full_opt(size) __allowed(on_field) |
836 | #define __field_nullterminated __allowed(on_field) |
837 | #define __struct_bcount(size) __allowed(on_struct) |
838 | #define __struct_xcount(size) __allowed(on_struct) |
839 | |
840 | /*************************************************************************** |
841 | * Macros to classify the entrypoints and indicate their category. |
842 | * |
843 | * Pre-defined control point categories include: RPC, KERNEL, GDI. |
844 | * |
845 | * Pre-defined control point macros include: |
846 | * __rpc_entry, __kernel_entry, __gdi_entry. |
847 | ***************************************************************************/ |
848 | #define __control_entrypoint(category) __allowed(on_function) |
849 | #define __rpc_entry __allowed(on_function) |
850 | #define __kernel_entry __allowed(on_function) |
851 | #define __gdi_entry __allowed(on_function) |
852 | |
853 | /*************************************************************************** |
854 | * Macros to track untrusted data and their validation. The list of untrusted |
855 | * sources include: |
856 | * |
857 | * FILE - File reading stream or API |
858 | * NETWORK - Socket readers |
859 | * INTERNET - WinInet and WinHttp readers |
860 | * USER_REGISTRY - HKCU portions of the registry |
861 | * USER_MODE - Parameters to kernel entry points |
862 | * RPC - Parameters to RPC entry points |
863 | * DRIVER - Device driver |
864 | ***************************************************************************/ |
865 | #define __in_data_source(src_sym) __allowed(on_parameter) |
866 | #define __out_data_source(src_sym) __allowed(on_parameter) |
867 | #define __field_data_source(src_sym) __allowed(on_field) |
868 | #define __this_out_data_source(src_syn) __allowed(on_function) |
869 | |
870 | /************************************************************************** |
871 | * Macros to tag file parsing code. Predefined formats include: |
872 | * PNG - Portable Network Graphics |
873 | * JPEG - Joint Photographic Experts Group |
874 | * BMP - Bitmap |
875 | * RC_BMP - Resource bitmap |
876 | * WMF - Windows Metafile |
877 | * EMF - Windows Enhanced Metafile |
878 | * GIF - Graphics Interchange Format |
879 | * MIME_TYPE - MIME type from header tokens |
880 | * MAIL_MONIKER - MAIL information refered by URL moniker |
881 | * HTML - HyperText Markup Language |
882 | * WMPHOTO - Windows media photo |
883 | * OE_VCARD - Outlook Express virtual card |
884 | * OE_CONTACT - Outlook Express contact |
885 | * MIDI - Musical Instrument Digital Interface |
886 | * LDIF - LDAP Data Interchange Format |
887 | * AVI - Audio Visual Interchange |
888 | * ACM - Audio Compression Manager |
889 | **************************************************************************/ |
890 | #define __out_validated(filetype_sym) __allowed(on_parameter) |
891 | #define __this_out_validated(filetype_sym) __allowed(on_function) |
892 | #define __file_parser(filetype_sym) __allowed(on_function) |
893 | #define __file_parser_class(filetype_sym) __allowed(on_struct) |
894 | #define __file_parser_library(filetype_sym) __allowed(as_global_decl) |
895 | |
896 | /*************************************************************************** |
897 | * Macros to track the code content in the file. The type of code |
898 | * contents currently tracked: |
899 | * |
900 | * NDIS_DRIVER - NDIS Device driver |
901 | ***************************************************************************/ |
902 | #define __source_code_content(codetype_sym) __allowed(as_global_decl) |
903 | |
904 | /*************************************************************************** |
905 | * Macros to track the code content in the class. The type of code |
906 | * contents currently tracked: |
907 | * |
908 | * DCOM - Class implementing DCOM |
909 | ***************************************************************************/ |
910 | #define __class_code_content(codetype_sym) __allowed(on_struct) |
911 | |
912 | /************************************************************************* |
913 | * Macros to tag encoded function pointers |
914 | **************************************************************************/ |
915 | #define __encoded_pointer |
916 | #define __encoded_array |
917 | #define __field_encoded_pointer __allowed(on_field) |
918 | #define __field_encoded_array __allowed(on_field) |
919 | |
920 | #define __transfer(formal) __allowed(on_parameter_or_return) |
921 | #define __assume_validated(exp) __allowed(as_statement_with_arg(exp)) |
922 | |
923 | /************************************************************************* |
924 | * __analysis_assume(expr) : Expert macro use only when directed. Use this to |
925 | * tell static analysis tools like PREfix and PREfast about a non-coded |
926 | * assumption that you wish the tools to assume. The assumption will be |
927 | * understood by those tools. By default there is no dynamic checking or |
928 | * static checking of the assumption in any build. |
929 | * |
930 | * To obtain dynamic checking wrap this macro in your local version of a debug |
931 | * assert. |
932 | * Please do not put function calls in the expression because this is not |
933 | * supported by all tools: |
934 | * __analysis_assume(GetObject () != NULL); // DO NOT DO THIS |
935 | * |
936 | *************************************************************************/ |
937 | #define __analysis_assume(expr) __allowed(as_statement_with_arg(expr)) |
938 | #define __analysis_assert(expr) __allowed(as_statement_with_arg(expr)) |
939 | |
940 | /************************************************************************* |
941 | * __analysis_hint(hint_sym) : Expert macro use only when |
942 | * directed. Use this to influence certain analysis heuristics |
943 | * used by the tools. These hints do not describe the semantics |
944 | * of functions but simply direct the tools to act in a certain |
945 | * way. |
946 | * |
947 | * Current hints that are supported are: |
948 | * |
949 | * INLINE - inline this function during analysis overrides any |
950 | * default heuristics |
951 | * NOINLINE - do not inline this function during analysis overrides |
952 | * and default heuristics |
953 | *************************************************************************/ |
954 | #define __analysis_hint(hint) __allowed(on_function) |
955 | |
956 | /************************************************************************* |
957 | * Macros to encode abstract properties of values. Used by SALadt.h |
958 | *************************************************************************/ |
959 | #define __type_has_adt_prop(adt,prop) __allowed(on_typdecl) |
960 | #define __out_has_adt_prop(adt,prop) __allowed(on_parameter) |
961 | #define __out_not_has_adt_prop(adt,prop) __allowed(on_parameter) |
962 | #define __out_transfer_adt_prop(arg) __allowed(on_parameter) |
963 | #define __out_has_type_adt_props(typ) __allowed(on_parameter) |
964 | |
965 | /************************************************************************* |
966 | * Macros used by Prefast for Drivers |
967 | * |
968 | * __possibly_notnullterminated : |
969 | * |
970 | * Used for return values of parameters or functions that do not |
971 | * guarantee nulltermination in all cases. |
972 | * |
973 | *************************************************************************/ |
974 | #define __possibly_notnullterminated __allowed(on_parameter_or_return) |
975 | |
976 | /************************************************************************* |
977 | * Advanced macros |
978 | * |
979 | * __volatile |
980 | * The __volatile annotation identifies a global variable or |
981 | * structure field that: |
982 | * 1) is not declared volatile; |
983 | * 2) is accessed concurrently by multiple threads. |
984 | * |
985 | * The __deref_volatile annotation identifies a global variable |
986 | * or structure field that stores a pointer to some data that: |
987 | * 1) is not declared volatile; |
988 | * 2) is accessed concurrently by multiple threads. |
989 | * |
990 | * Prefast uses these annotations to find patterns of code that |
991 | * may result in unexpected re-fetching of the global variable |
992 | * into a local variable. |
993 | * |
994 | * We also provide two complimentary annotations __nonvolatile |
995 | * and __deref_nonvolatile that could be used to suppress Prefast |
996 | * |
997 | * re-fetching warnings on variables that are known either: |
998 | * 1) not to be in danger of being re-fetched or, |
999 | * 2) not to lead to incorrect results if they are re-fetched |
1000 | * |
1001 | *************************************************************************/ |
1002 | #define __volatile __allowed(on_global_or_field) |
1003 | #define __deref_volatile __allowed(on_global_or_field) |
1004 | #define __nonvolatile __allowed(on_global_or_field) |
1005 | #define __deref_nonvolatile __allowed(on_global_or_field) |
1006 | |
1007 | /************************************************************************* |
1008 | * Macros deprecated with strict level greater then 1. |
1009 | **************************************************************************/ |
1010 | #if (__SPECSTRINGS_STRICT_LEVEL > 1) |
1011 | /* Must come before macro defintions */ |
1012 | #pragma deprecated(__in_nz) |
1013 | #pragma deprecated(__in_ecount_nz) |
1014 | #pragma deprecated(__in_bcount_nz) |
1015 | #pragma deprecated(__out_nz) |
1016 | #pragma deprecated(__out_nz_opt) |
1017 | #pragma deprecated(__out_ecount_nz) |
1018 | #pragma deprecated(__out_bcount_nz) |
1019 | #pragma deprecated(__inout_nz) |
1020 | #pragma deprecated(__inout_ecount_nz) |
1021 | #pragma deprecated(__inout_bcount_nz) |
1022 | #pragma deprecated(__in_nz_opt) |
1023 | #pragma deprecated(__in_ecount_nz_opt) |
1024 | #pragma deprecated(__in_bcount_nz_opt) |
1025 | #pragma deprecated(__out_ecount_nz_opt) |
1026 | #pragma deprecated(__out_bcount_nz_opt) |
1027 | #pragma deprecated(__inout_nz_opt) |
1028 | #pragma deprecated(__inout_ecount_nz_opt) |
1029 | #pragma deprecated(__inout_bcount_nz_opt) |
1030 | #pragma deprecated(__deref_out_nz) |
1031 | #pragma deprecated(__deref_out_ecount_nz) |
1032 | #pragma deprecated(__deref_out_bcount_nz) |
1033 | #pragma deprecated(__deref_inout_nz) |
1034 | #pragma deprecated(__deref_inout_ecount_nz) |
1035 | #pragma deprecated(__deref_inout_bcount_nz) |
1036 | #pragma deprecated(__deref_out_nz_opt) |
1037 | #pragma deprecated(__deref_out_ecount_nz_opt) |
1038 | #pragma deprecated(__deref_out_bcount_nz_opt) |
1039 | #pragma deprecated(__deref_inout_nz_opt) |
1040 | #pragma deprecated(__deref_inout_ecount_nz_opt) |
1041 | #pragma deprecated(__deref_inout_bcount_nz_opt) |
1042 | #pragma deprecated(__deref_opt_inout_nz) |
1043 | #pragma deprecated(__deref_opt_inout_ecount_nz) |
1044 | #pragma deprecated(__deref_opt_inout_bcount_nz) |
1045 | #pragma deprecated(__deref_opt_out_nz_opt) |
1046 | #pragma deprecated(__deref_opt_out_ecount_nz_opt) |
1047 | #pragma deprecated(__deref_opt_out_bcount_nz_opt) |
1048 | #pragma deprecated(__deref_opt_inout_nz_opt) |
1049 | #pragma deprecated(__deref_opt_inout_ecount_nz_opt) |
1050 | #pragma deprecated(__deref_opt_inout_bcount_nz_opt) |
1051 | #pragma deprecated(__deref) |
1052 | #pragma deprecated(__pre) |
1053 | #pragma deprecated(__post) |
1054 | #pragma deprecated(__readableTo) |
1055 | #pragma deprecated(__writableTo) |
1056 | #pragma deprecated(__maybevalid) |
1057 | #pragma deprecated(__data_entrypoint) |
1058 | #pragma deprecated(__inexpressible_readableTo) |
1059 | #pragma deprecated(__readonly) |
1060 | #pragma deprecated(__byte_writableTo) |
1061 | #pragma deprecated(__byte_readableTo) |
1062 | #pragma deprecated(__elem_readableTo) |
1063 | #pragma deprecated(__elem_writableTo) |
1064 | #pragma deprecated(__valid) |
1065 | #pragma deprecated(__notvalid) |
1066 | #pragma deprecated(__refparam) |
1067 | #pragma deprecated(__precond) |
1068 | #endif |
1069 | /* Define soon to be deprecated macros to nops. */ |
1070 | #define __in_nz |
1071 | #define __in_ecount_nz(size) |
1072 | #define __in_bcount_nz(size) |
1073 | #define __out_nz |
1074 | #define __out_nz_opt |
1075 | #define __out_ecount_nz(size) |
1076 | #define __out_bcount_nz(size) |
1077 | #define __inout_nz |
1078 | #define __inout_ecount_nz(size) |
1079 | #define __inout_bcount_nz(size) |
1080 | #define __in_nz_opt |
1081 | #define __in_ecount_nz_opt(size) |
1082 | #define __in_bcount_nz_opt(size) |
1083 | #define __out_ecount_nz_opt(size) |
1084 | #define __out_bcount_nz_opt(size) |
1085 | #define __inout_nz_opt |
1086 | #define __inout_ecount_nz_opt(size) |
1087 | #define __inout_bcount_nz_opt(size) |
1088 | #define __deref_out_nz |
1089 | #define __deref_out_ecount_nz(size) |
1090 | #define __deref_out_bcount_nz(size) |
1091 | #define __deref_inout_nz |
1092 | #define __deref_inout_ecount_nz(size) |
1093 | #define __deref_inout_bcount_nz(size) |
1094 | #define __deref_out_nz_opt |
1095 | #define __deref_out_ecount_nz_opt(size) |
1096 | #define __deref_out_bcount_nz_opt(size) |
1097 | #define __deref_inout_nz_opt |
1098 | #define __deref_inout_ecount_nz_opt(size) |
1099 | #define __deref_inout_bcount_nz_opt(size) |
1100 | #define __deref_opt_inout_nz |
1101 | #define __deref_opt_inout_ecount_nz(size) |
1102 | #define __deref_opt_inout_bcount_nz(size) |
1103 | #define __deref_opt_out_nz_opt |
1104 | #define __deref_opt_out_ecount_nz_opt(size) |
1105 | #define __deref_opt_out_bcount_nz_opt(size) |
1106 | #define __deref_opt_inout_nz_opt |
1107 | #define __deref_opt_inout_ecount_nz_opt(size) |
1108 | #define __deref_opt_inout_bcount_nz_opt(size) |
1109 | #define __deref |
1110 | #define __pre |
1111 | #define __post |
1112 | #define __readableTo(count) |
1113 | #define __writableTo(count) |
1114 | #define __maybevalid |
1115 | #define __inexpressible_readableTo(string) |
1116 | #define __data_entrypoint(category) |
1117 | #define __readonly |
1118 | #define __byte_writableTo(count) |
1119 | #define __byte_readableTo(count) |
1120 | #define __elem_readableTo(count) |
1121 | #define __elem_writableTo(count) |
1122 | #define __valid |
1123 | #define __notvalid |
1124 | #define __refparam |
1125 | #define __precond(condition) |
1126 | |
1127 | /************************************************************************* |
1128 | * Definitions to force a compile error when macros are used improperly. |
1129 | * Relies on VS 2005 source annotations. |
1130 | *************************************************************************/ |
1131 | #if !defined(_MSC_EXTENSIONS) && !defined(_PREFAST_) && !defined(OACR) |
1132 | #define __allowed(p) /* nothing */ |
1133 | #else |
1134 | #define __allowed(p) __$allowed_##p |
1135 | #define __$allowed_as_global_decl /* empty */ |
1136 | #define __$allowed_as_statement_with_arg(x) \ |
1137 | __pragma(warning(push)) __pragma(warning(disable : 4548)) \ |
1138 | do {__noop(x);} while((0,0) __pragma(warning(pop)) ) |
1139 | #define __$allowed_as_statement __$allowed_as_statement_with_arg(1) |
1140 | |
1141 | /************************************************************************** |
1142 | * This should go away. It's only for __success which we should split into. |
1143 | * __success and __typdecl_sucess |
1144 | ***************************************************************************/ |
1145 | #define __$allowed_on_function_or_typedecl /* empty */ |
1146 | #if (__SPECSTRINGS_STRICT_LEVEL == 1) || (__SPECSTRINGS_STRICT_LEVEL == 2) |
1147 | #define __$allowed_on_typedecl /* empty */ |
1148 | #define __$allowed_on_return /* empty */ |
1149 | #define __$allowed_on_parameter /* empty */ |
1150 | #define __$allowed_on_function /* empty */ |
1151 | #define __$allowed_on_struct /* empty */ |
1152 | #define __$allowed_on_field /* empty */ |
1153 | #define __$allowed_on_parameter_or_return /* empty */ |
1154 | #define __$allowed_on_global_or_field /* empty */ |
1155 | #elif __SPECSTRINGS_STRICT_LEVEL == 3 |
1156 | #define __$allowed_on_typedecl /* empty */ |
1157 | /* Define dummy source attributes. Still needs more testing */ |
1158 | #define __$allowed_on_return [returnvalue: OnReturnOnly] |
1159 | #define __$allowed_on_parameter [OnParameterOnly] |
1160 | #define __$allowed_on_function [method: OnFunctionOnly] |
1161 | #define __$allowed_on_struct [OnStructOnly] |
1162 | #define __$allowed_on_field [OnFieldOnly] |
1163 | #define __$allowed_on_parameter_or_return [OnParameterOrReturnOnly] |
1164 | #define __$allowed_on_global_or_field /* empty */ |
1165 | #pragma push_macro( "DECL_SA" ) |
1166 | #pragma push_macro( "SA" ) |
1167 | #ifdef __cplusplus |
1168 | #define SA(x) x |
1169 | #define DECL_SA(name,loc) \ |
1170 | [repeatable] \ |
1171 | [source_annotation_attribute( loc )] \ |
1172 | struct name##Attribute { name##Attribute(); const char* ignored; }; |
1173 | #else |
1174 | #define SA(x) SA_##x |
1175 | #define DECL_SA(name,loc) \ |
1176 | [source_annotation_attribute( loc )] \ |
1177 | struct name { const char* ignored; };\ |
1178 | typedef struct name name; |
1179 | #endif /* #endif __cplusplus */ |
1180 | DECL_SA(OnParameterOnly,SA(Parameter)); |
1181 | DECL_SA(OnReturnOnly,SA(ReturnValue)); |
1182 | DECL_SA(OnFunctionOnly,SA(Method)); |
1183 | DECL_SA(OnStructOnly,SA(Struct)); |
1184 | DECL_SA(OnFieldOnly,SA(Field)); |
1185 | DECL_SA(OnParameterOrReturnOnly,SA(Parameter) | SA(ReturnValue)); |
1186 | #pragma pop_macro( "SA" ) |
1187 | #pragma pop_macro( "DECL_SA" ) |
1188 | #endif |
1189 | #endif |
1190 | #endif |
1191 | |