[PSDK] Add CLSID_ISFBand, IShellFolderBand and IFolderBandPriv
[reactos.git] / sdk / include / ddk / ntstrsafe.h
1 /**
2 * This file has no copyright assigned and is placed in the Public Domain.
3 * This file is part of the w64 mingw-runtime package.
4 * No warranty is given; refer to the file DISCLAIMER.PD within this package.
5 */
6 #ifndef _NTSTRSAFE_H_INCLUDED_
7 #define _NTSTRSAFE_H_INCLUDED_
8
9 #include <stdio.h>
10 #include <string.h>
11 #include <stdarg.h>
12
13 #ifdef _MSC_VER
14 #pragma warning(push)
15 #pragma warning(disable:28719) /* disable banned api usage warning */
16 #endif /* _MSC_VER */
17
18 #ifndef C_ASSERT
19 #ifdef _MSC_VER
20 # define C_ASSERT(e) typedef char __C_ASSERT__[(e)?1:-1]
21 #else
22 # define C_ASSERT(e) extern void __C_ASSERT__(int [(e)?1:-1])
23 #endif
24 #endif /* C_ASSERT */
25
26 #ifdef __cplusplus
27 #define _STRSAFE_EXTERN_C extern "C"
28 #else
29 #define _STRSAFE_EXTERN_C extern
30 #endif
31
32 #define NTSTRSAFEAPI static __inline NTSTATUS NTAPI
33 #define NTSTRSAFE_INLINE_API static __inline NTSTATUS NTAPI
34
35 #ifndef NTSTRSAFE_MAX_CCH
36 #define NTSTRSAFE_MAX_CCH 2147483647
37 #endif
38
39 #ifndef NTSTRSAFE_UNICODE_STRING_MAX_CCH
40 #define NTSTRSAFE_UNICODE_STRING_MAX_CCH 32767
41 #endif
42
43 #ifndef _STRSAFE_H_INCLUDED_
44 #define STRSAFE_IGNORE_NULLS 0x00000100
45 #define STRSAFE_FILL_BEHIND_NULL 0x00000200
46 #define STRSAFE_FILL_ON_FAILURE 0x00000400
47 #define STRSAFE_NULL_ON_FAILURE 0x00000800
48 #define STRSAFE_NO_TRUNCATION 0x00001000
49 #define STRSAFE_IGNORE_NULL_UNICODE_STRINGS 0x00010000
50 #define STRSAFE_UNICODE_STRING_DEST_NULL_TERMINATED 0x00020000
51
52 #define STRSAFE_VALID_FLAGS (0x000000FF | STRSAFE_IGNORE_NULLS | STRSAFE_FILL_BEHIND_NULL | STRSAFE_FILL_ON_FAILURE | STRSAFE_NULL_ON_FAILURE | STRSAFE_NO_TRUNCATION)
53 #define STRSAFE_UNICODE_STRING_VALID_FLAGS (STRSAFE_VALID_FLAGS | STRSAFE_IGNORE_NULL_UNICODE_STRINGS | STRSAFE_UNICODE_STRING_DEST_NULL_TERMINATED)
54
55 #define STRSAFE_FILL_BYTE(x) ((STRSAFE_DWORD)(((x) & 0x000000FF) | STRSAFE_FILL_BEHIND_NULL))
56 #define STRSAFE_FAILURE_BYTE(x) ((STRSAFE_DWORD)(((x) & 0x000000FF) | STRSAFE_FILL_ON_FAILURE))
57
58 #define STRSAFE_GET_FILL_PATTERN(dwFlags) ((int)((dwFlags) & 0x000000FF))
59 #endif
60
61 typedef char *STRSAFE_LPSTR;
62 typedef const char *STRSAFE_LPCSTR;
63 typedef wchar_t *STRSAFE_LPWSTR;
64 typedef const wchar_t *STRSAFE_LPCWSTR;
65
66 typedef _Null_terminated_ char *NTSTRSAFE_PSTR;
67 typedef _Null_terminated_ const char *NTSTRSAFE_PCSTR;
68 typedef _Null_terminated_ wchar_t *NTSTRSAFE_PWSTR;
69 typedef _Null_terminated_ const wchar_t *NTSTRSAFE_PCWSTR;
70
71 typedef ULONG STRSAFE_DWORD;
72
73 NTSTRSAFEAPI RtlStringCopyWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc);
74 NTSTRSAFEAPI RtlStringCopyWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc);
75 NTSTRSAFEAPI RtlStringCopyExWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags);
76 NTSTRSAFEAPI RtlStringCopyExWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags);
77 NTSTRSAFEAPI RtlStringCopyNWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc,size_t cchToCopy);
78 NTSTRSAFEAPI RtlStringCopyNWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc,size_t cchToCopy);
79 NTSTRSAFEAPI RtlStringCopyNExWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,size_t cchToCopy,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags);
80 NTSTRSAFEAPI RtlStringCopyNExWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,size_t cchToCopy,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags);
81 NTSTRSAFEAPI RtlStringCatWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc);
82 NTSTRSAFEAPI RtlStringCatWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc);
83 NTSTRSAFEAPI RtlStringCatExWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags);
84 NTSTRSAFEAPI RtlStringCatExWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags);
85 NTSTRSAFEAPI RtlStringCatNWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc,size_t cchToAppend);
86 NTSTRSAFEAPI RtlStringCatNWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc,size_t cchToAppend);
87 NTSTRSAFEAPI RtlStringCatNExWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,size_t cchToAppend,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags);
88 NTSTRSAFEAPI RtlStringCatNExWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,size_t cchToAppend,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags);
89 NTSTRSAFEAPI RtlStringVPrintfWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszFormat,va_list argList);
90 NTSTRSAFEAPI RtlStringVPrintfWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszFormat,va_list argList);
91 NTSTRSAFEAPI RtlStringVPrintfExWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCSTR pszFormat,va_list argList);
92 NTSTRSAFEAPI RtlStringVPrintfExWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCWSTR pszFormat,va_list argList);
93
94 NTSTRSAFEAPI
95 RtlStringLengthWorkerA(
96 _In_reads_or_z_(cchMax) STRSAFE_LPCSTR psz,
97 _In_ _In_range_(<=, NTSTRSAFE_MAX_CCH) size_t cchMax,
98 _Out_opt_ _Deref_out_range_(<, cchMax) size_t *pcchLength);
99
100 NTSTRSAFEAPI
101 RtlStringLengthWorkerW(
102 _In_reads_or_z_(cchMax) STRSAFE_LPCWSTR psz,
103 _In_ _In_range_(<=, NTSTRSAFE_MAX_CCH) size_t cchMax,
104 _Out_opt_ _Deref_out_range_(<, cchMax) size_t *pcchLength);
105
106 NTSTRSAFEAPI
107 RtlStringCchCopyA(
108 _Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest,
109 _In_ size_t cchDest,
110 _In_ NTSTRSAFE_PCSTR pszSrc);
111
112 NTSTRSAFEAPI
113 RtlStringCchCopyW(
114 _Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest,
115 _In_ size_t cchDest,
116 _In_ NTSTRSAFE_PCWSTR pszSrc);
117
118 NTSTRSAFEAPI
119 RtlStringCchCopyA(
120 _Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest,
121 _In_ size_t cchDest,
122 _In_ NTSTRSAFE_PCSTR pszSrc)
123 {
124 if (cchDest > NTSTRSAFE_MAX_CCH)
125 {
126 if (cchDest > 0)
127 *pszDest = '\0';
128 return STATUS_INVALID_PARAMETER;
129 }
130
131 return RtlStringCopyWorkerA(pszDest, cchDest, pszSrc);
132 }
133
134 NTSTRSAFEAPI
135 RtlStringCchCopyW(
136 _Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest,
137 _In_ size_t cchDest,
138 _In_ NTSTRSAFE_PCWSTR pszSrc)
139 {
140 if (cchDest > NTSTRSAFE_MAX_CCH)
141 {
142 if (cchDest > 0)
143 *pszDest = '\0';
144 return STATUS_INVALID_PARAMETER;
145 }
146
147 return RtlStringCopyWorkerW(pszDest,cchDest,pszSrc);
148 }
149
150 NTSTRSAFEAPI
151 RtlStringCbCopyA(
152 _Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest,
153 _In_ size_t cbDest,
154 _In_ NTSTRSAFE_PCSTR pszSrc);
155
156 NTSTRSAFEAPI
157 RtlStringCbCopyW(
158 _Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest,
159 _In_ size_t cbDest,
160 _In_ NTSTRSAFE_PCWSTR pszSrc);
161
162 NTSTRSAFEAPI
163 RtlStringCbCopyA(
164 _Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest,
165 _In_ size_t cbDest,
166 _In_ NTSTRSAFE_PCSTR pszSrc)
167 {
168 size_t cchDest = cbDest / sizeof(char);
169 if (cchDest > NTSTRSAFE_MAX_CCH)
170 {
171 if (cchDest > 0)
172 *pszDest = '\0';
173 return STATUS_INVALID_PARAMETER;
174 }
175 return RtlStringCopyWorkerA(pszDest,cbDest,pszSrc);
176 }
177
178 NTSTRSAFEAPI
179 RtlStringCbCopyW(
180 _Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest,
181 _In_ size_t cbDest,
182 _In_ NTSTRSAFE_PCWSTR pszSrc)
183 {
184 size_t cchDest = cbDest / sizeof(wchar_t);
185 if (cchDest > NTSTRSAFE_MAX_CCH)
186 {
187 if (cchDest > 0)
188 *pszDest = '\0';
189 return STATUS_INVALID_PARAMETER;
190 }
191 return RtlStringCopyWorkerW(pszDest,cchDest,pszSrc);
192 }
193
194 NTSTRSAFEAPI
195 RtlStringCchCopyExA(
196 _Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest,
197 _In_ size_t cchDest,
198 _In_ NTSTRSAFE_PCSTR pszSrc,
199 _Outptr_opt_result_buffer_(*pcchRemaining) NTSTRSAFE_PSTR *ppszDestEnd,
200 _Out_opt_ size_t *pcchRemaining,
201 _In_ STRSAFE_DWORD dwFlags);
202
203 NTSTRSAFEAPI
204 RtlStringCchCopyExW(
205 _Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest,
206 _In_ size_t cchDest,
207 _In_ NTSTRSAFE_PCWSTR pszSrc,
208 _Outptr_opt_result_buffer_(*pcchRemaining) NTSTRSAFE_PWSTR *ppszDestEnd,
209 _Out_opt_ size_t *pcchRemaining,
210 _In_ STRSAFE_DWORD dwFlags);
211
212 NTSTRSAFEAPI
213 RtlStringCchCopyExA(
214 _Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest,
215 _In_ size_t cchDest,
216 _In_ NTSTRSAFE_PCSTR pszSrc,
217 _Outptr_opt_result_buffer_(*pcchRemaining) NTSTRSAFE_PSTR *ppszDestEnd,
218 _Out_opt_ size_t *pcchRemaining,
219 _In_ STRSAFE_DWORD dwFlags)
220 {
221 if (cchDest > NTSTRSAFE_MAX_CCH)
222 {
223 if (cchDest > 0)
224 *pszDest = '\0';
225 return STATUS_INVALID_PARAMETER;
226 }
227 return RtlStringCopyExWorkerA(pszDest,cchDest,cchDest,pszSrc,ppszDestEnd,pcchRemaining,dwFlags);
228 }
229
230 NTSTRSAFEAPI
231 RtlStringCchCopyExW(
232 _Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest,
233 _In_ size_t cchDest,
234 _In_ NTSTRSAFE_PCWSTR pszSrc,
235 _Outptr_opt_result_buffer_(*pcchRemaining) NTSTRSAFE_PWSTR *ppszDestEnd,
236 _Out_opt_ size_t *pcchRemaining,
237 _In_ STRSAFE_DWORD dwFlags)
238 {
239 size_t cbDest = cchDest * sizeof(wchar_t);
240
241 if (cchDest > NTSTRSAFE_MAX_CCH)
242 {
243 if (cchDest > 0)
244 *pszDest = L'\0';
245 return STATUS_INVALID_PARAMETER;
246 }
247
248 return RtlStringCopyExWorkerW(pszDest,cchDest,cbDest,pszSrc,ppszDestEnd,pcchRemaining,dwFlags);
249 }
250
251 NTSTRSAFEAPI
252 RtlStringCbCopyExA(
253 _Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest,
254 _In_ size_t cbDest,
255 _In_ NTSTRSAFE_PCSTR pszSrc,
256 _Outptr_opt_result_bytebuffer_(*pcbRemaining) STRSAFE_LPSTR *ppszDestEnd,
257 _Out_opt_ size_t *pcbRemaining,
258 _In_ STRSAFE_DWORD dwFlags);
259
260 NTSTRSAFEAPI
261 RtlStringCbCopyExW(
262 _Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest,
263 _In_ size_t cbDest,
264 _In_ NTSTRSAFE_PCWSTR pszSrc,
265 _Outptr_opt_result_bytebuffer_(*pcbRemaining) NTSTRSAFE_PWSTR *ppszDestEnd,
266 _Out_opt_ size_t *pcbRemaining,
267 _In_ STRSAFE_DWORD dwFlags);
268
269 NTSTRSAFEAPI
270 RtlStringCbCopyExA(
271 _Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest,
272 _In_ size_t cbDest,
273 _In_ NTSTRSAFE_PCSTR pszSrc,
274 _Outptr_opt_result_bytebuffer_(*pcbRemaining) STRSAFE_LPSTR *ppszDestEnd,
275 _Out_opt_ size_t *pcbRemaining,
276 _In_ STRSAFE_DWORD dwFlags)
277 {
278 NTSTATUS Status;
279 size_t cchDest = cbDest / sizeof(char);
280 size_t cchRemaining = 0;
281
282 if (cchDest > NTSTRSAFE_MAX_CCH)
283 {
284 if (cchDest > 0)
285 *pszDest = '\0';
286 return STATUS_INVALID_PARAMETER;
287 }
288
289 Status = RtlStringCopyExWorkerA(pszDest,cbDest,cbDest,pszSrc,ppszDestEnd,&cchRemaining,dwFlags);
290 if (NT_SUCCESS(Status) || Status == STATUS_BUFFER_OVERFLOW)
291 {
292 if (pcbRemaining)
293 *pcbRemaining = (cchRemaining*sizeof(char)) + (cbDest % sizeof(char));
294 }
295 return Status;
296 }
297
298 NTSTRSAFEAPI
299 RtlStringCbCopyExW(
300 _Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest,
301 _In_ size_t cbDest,
302 _In_ NTSTRSAFE_PCWSTR pszSrc,
303 _Outptr_opt_result_bytebuffer_(*pcbRemaining) NTSTRSAFE_PWSTR *ppszDestEnd,
304 _Out_opt_ size_t *pcbRemaining,
305 _In_ STRSAFE_DWORD dwFlags)
306 {
307 NTSTATUS Status;
308 size_t cchDest = cbDest / sizeof(wchar_t);
309 size_t cchRemaining = 0;
310
311 if (cchDest > NTSTRSAFE_MAX_CCH)
312 {
313 if (cchDest > 0)
314 *pszDest = L'\0';
315 return STATUS_INVALID_PARAMETER;
316 }
317
318 Status = RtlStringCopyExWorkerW(pszDest,cchDest,cbDest,pszSrc,ppszDestEnd,&cchRemaining,dwFlags);
319 if (NT_SUCCESS(Status) || (Status==STATUS_BUFFER_OVERFLOW))
320 {
321 if (pcbRemaining)
322 *pcbRemaining = (cchRemaining*sizeof(wchar_t)) + (cbDest % sizeof(wchar_t));
323 }
324 return Status;
325 }
326
327 NTSTRSAFEAPI
328 RtlStringCchCopyNA(
329 _Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest,
330 _In_ size_t cchDest,
331 _In_reads_or_z_(cchToCopy) STRSAFE_LPCSTR pszSrc,
332 _In_ size_t cchToCopy);
333
334 NTSTRSAFEAPI
335 RtlStringCchCopyNW(
336 _Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest,
337 _In_ size_t cchDest,
338 _In_reads_or_z_(cchToCopy) STRSAFE_LPCWSTR pszSrc,
339 _In_ size_t cchToCopy);
340
341
342 NTSTRSAFEAPI
343 RtlStringCchCopyNA(
344 _Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest,
345 _In_ size_t cchDest,
346 _In_reads_or_z_(cchToCopy) STRSAFE_LPCSTR pszSrc,
347 _In_ size_t cchToCopy)
348 {
349 if (cchDest > NTSTRSAFE_MAX_CCH || cchToCopy > NTSTRSAFE_MAX_CCH)
350 {
351 if (cchDest > 0)
352 *pszDest = '\0';
353 return STATUS_INVALID_PARAMETER;
354 }
355
356 return RtlStringCopyNWorkerA(pszDest,cchDest,pszSrc,cchToCopy);
357 }
358
359 NTSTRSAFEAPI
360 RtlStringCchCopyNW(
361 _Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest,
362 _In_ size_t cchDest,
363 _In_reads_or_z_(cchToCopy) STRSAFE_LPCWSTR pszSrc,
364 _In_ size_t cchToCopy)
365 {
366 if (cchDest > NTSTRSAFE_MAX_CCH || cchToCopy > NTSTRSAFE_MAX_CCH)
367 {
368 if (cchDest > 0)
369 *pszDest = L'\0';
370 return STATUS_INVALID_PARAMETER;
371 }
372
373 return RtlStringCopyNWorkerW(pszDest,cchDest,pszSrc,cchToCopy);
374 }
375
376 NTSTRSAFEAPI
377 RtlStringCbCopyNA(
378 _Out_writes_bytes_(cbDest) NTSTRSAFE_PSTR pszDest,
379 _In_ size_t cbDest,
380 _In_reads_bytes_(cbToCopy) STRSAFE_LPCSTR pszSrc,
381 _In_ size_t cbToCopy);
382
383 NTSTRSAFEAPI
384 RtlStringCbCopyNW(
385 _Out_writes_bytes_(cbDest) NTSTRSAFE_PWSTR pszDest,
386 _In_ size_t cbDest,
387 _In_reads_bytes_(cbToCopy) STRSAFE_LPCWSTR pszSrc,
388 _In_ size_t cbToCopy);
389
390 NTSTRSAFEAPI
391 RtlStringCbCopyNA(
392 _Out_writes_bytes_(cbDest) NTSTRSAFE_PSTR pszDest,
393 _In_ size_t cbDest,
394 _In_reads_bytes_(cbToCopy) STRSAFE_LPCSTR pszSrc,
395 _In_ size_t cbToCopy)
396 {
397 size_t cchDest = cbDest / sizeof(char);
398 size_t cchToCopy = cbToCopy / sizeof(char);
399
400 if (cchDest > NTSTRSAFE_MAX_CCH || cchToCopy > NTSTRSAFE_MAX_CCH)
401 {
402 if (cchDest > 0)
403 *pszDest = '\0';
404 return STATUS_INVALID_PARAMETER;
405 }
406
407 return RtlStringCopyNWorkerA(pszDest, cchDest, pszSrc, cchToCopy);
408 }
409
410 NTSTRSAFEAPI
411 RtlStringCbCopyNW(
412 _Out_writes_bytes_(cbDest) NTSTRSAFE_PWSTR pszDest,
413 _In_ size_t cbDest,
414 _In_reads_bytes_(cbToCopy) STRSAFE_LPCWSTR pszSrc,
415 _In_ size_t cbToCopy)
416 {
417 size_t cchDest = cbDest / sizeof(wchar_t);
418 size_t cchToCopy = cbToCopy / sizeof(wchar_t);
419
420 if (cchDest > NTSTRSAFE_MAX_CCH || cchToCopy > NTSTRSAFE_MAX_CCH)
421 {
422 if (cchDest > 0)
423 *pszDest = L'\0';
424 return STATUS_INVALID_PARAMETER;
425 }
426
427 return RtlStringCopyNWorkerW(pszDest, cchDest, pszSrc, cchToCopy);
428 }
429
430 NTSTRSAFEAPI
431 RtlStringCchCopyNExA(
432 _Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest,
433 _In_ size_t cchDest,
434 _In_reads_or_z_(cchToCopy) STRSAFE_LPCSTR pszSrc,
435 _In_ size_t cchToCopy,
436 _Outptr_opt_result_buffer_(*pcchRemaining) NTSTRSAFE_PSTR *ppszDestEnd,
437 _Out_opt_ size_t *pcchRemaining,
438 _In_ STRSAFE_DWORD dwFlags);
439
440 NTSTRSAFEAPI
441 RtlStringCchCopyNExW(
442 _Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest,
443 _In_ size_t cchDest,
444 _In_reads_or_z_(cchToCopy) STRSAFE_LPCWSTR pszSrc,
445 _In_ size_t cchToCopy,
446 _Outptr_opt_result_buffer_(*pcchRemaining) NTSTRSAFE_PWSTR *ppszDestEnd,
447 _Out_opt_ size_t *pcchRemaining,
448 _In_ STRSAFE_DWORD dwFlags);
449
450 NTSTRSAFEAPI
451 RtlStringCchCopyNExA(
452 _Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest,
453 _In_ size_t cchDest,
454 _In_reads_or_z_(cchToCopy) STRSAFE_LPCSTR pszSrc,
455 _In_ size_t cchToCopy,
456 _Outptr_opt_result_buffer_(*pcchRemaining) NTSTRSAFE_PSTR *ppszDestEnd,
457 _Out_opt_ size_t *pcchRemaining,
458 _In_ STRSAFE_DWORD dwFlags)
459 {
460 if (cchDest > NTSTRSAFE_MAX_CCH)
461 {
462 if (cchDest > 0)
463 *pszDest = '\0';
464 return STATUS_INVALID_PARAMETER;
465 }
466
467 return RtlStringCopyNExWorkerA(pszDest, cchDest, cchDest, pszSrc, cchToCopy, ppszDestEnd, pcchRemaining, dwFlags);
468 }
469
470 NTSTRSAFEAPI
471 RtlStringCchCopyNExW(
472 _Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest,
473 _In_ size_t cchDest,
474 _In_reads_or_z_(cchToCopy) STRSAFE_LPCWSTR pszSrc,
475 _In_ size_t cchToCopy,
476 _Outptr_opt_result_buffer_(*pcchRemaining) NTSTRSAFE_PWSTR *ppszDestEnd,
477 _Out_opt_ size_t *pcchRemaining,
478 _In_ STRSAFE_DWORD dwFlags)
479 {
480 if (cchDest > NTSTRSAFE_MAX_CCH)
481 {
482 if (cchDest > 0)
483 *pszDest = L'\0';
484 return STATUS_INVALID_PARAMETER;
485 }
486
487 return RtlStringCopyNExWorkerW(pszDest,cchDest,cchDest * sizeof(wchar_t), pszSrc, cchToCopy, ppszDestEnd, pcchRemaining, dwFlags);
488 }
489
490 NTSTRSAFEAPI
491 RtlStringCbCopyNExA(
492 _Out_writes_bytes_(cbDest) NTSTRSAFE_PSTR pszDest,
493 _In_ size_t cbDest,
494 _In_reads_bytes_(cbToCopy) STRSAFE_LPCSTR pszSrc,
495 _In_ size_t cbToCopy,
496 _Outptr_opt_result_bytebuffer_(*pcbRemaining) NTSTRSAFE_PSTR *ppszDestEnd,
497 _Out_opt_ size_t *pcbRemaining,
498 _In_ STRSAFE_DWORD dwFlags);
499
500 NTSTRSAFEAPI
501 RtlStringCbCopyNExW(
502 _Out_writes_bytes_(cbDest) NTSTRSAFE_PWSTR pszDest,
503 _In_ size_t cbDest,
504 _In_reads_bytes_(cbToCopy) STRSAFE_LPCWSTR pszSrc,
505 _In_ size_t cbToCopy,
506 _Outptr_opt_result_bytebuffer_(*pcbRemaining) NTSTRSAFE_PWSTR *ppszDestEnd,
507 _Out_opt_ size_t *pcbRemaining,
508 _In_ STRSAFE_DWORD dwFlags);
509
510 NTSTRSAFEAPI
511 RtlStringCbCopyNExA(
512 _Out_writes_bytes_(cbDest) STRSAFE_LPSTR pszDest,
513 _In_ size_t cbDest,
514 _In_reads_bytes_(cbToCopy) STRSAFE_LPCSTR pszSrc,
515 _In_ size_t cbToCopy,
516 _Outptr_opt_result_bytebuffer_(*pcbRemaining) STRSAFE_LPSTR *ppszDestEnd,
517 _Out_opt_ size_t *pcbRemaining,
518 _In_ STRSAFE_DWORD dwFlags)
519 {
520 NTSTATUS Status;
521 size_t cchRemaining = 0;
522
523 if (cbDest > NTSTRSAFE_MAX_CCH)
524 {
525 if ((pszDest != NULL) && (cbDest > 0))
526 *pszDest = L'\0';
527 return STATUS_INVALID_PARAMETER;
528 }
529
530 Status = RtlStringCopyNExWorkerA(pszDest,cbDest,cbDest,pszSrc,cbToCopy,ppszDestEnd,&cchRemaining,dwFlags);
531 if ((NT_SUCCESS(Status) || Status == STATUS_BUFFER_OVERFLOW) && pcbRemaining)
532 *pcbRemaining = cchRemaining;
533 return Status;
534 }
535
536 NTSTRSAFEAPI
537 RtlStringCbCopyNExW(
538 _Out_writes_bytes_(cbDest) NTSTRSAFE_PWSTR pszDest,
539 _In_ size_t cbDest,
540 _In_reads_bytes_(cbToCopy) STRSAFE_LPCWSTR pszSrc,
541 _In_ size_t cbToCopy,
542 _Outptr_opt_result_bytebuffer_(*pcbRemaining) NTSTRSAFE_PWSTR *ppszDestEnd,
543 _Out_opt_ size_t *pcbRemaining,
544 _In_ STRSAFE_DWORD dwFlags)
545 {
546 NTSTATUS Status;
547 size_t cchDest;
548 size_t cchToCopy;
549 size_t cchRemaining = 0;
550 cchDest = cbDest / sizeof(wchar_t);
551 cchToCopy = cbToCopy / sizeof(wchar_t);
552 if (cchDest > NTSTRSAFE_MAX_CCH)
553 {
554 if ((pszDest != NULL) && (cbDest > 0))
555 *pszDest = L'\0';
556 return STATUS_INVALID_PARAMETER;
557 }
558
559 Status = RtlStringCopyNExWorkerW(pszDest,cchDest,cbDest,pszSrc,cchToCopy,ppszDestEnd,&cchRemaining,dwFlags);
560 if ((NT_SUCCESS(Status) || Status == STATUS_BUFFER_OVERFLOW) && pcbRemaining)
561 *pcbRemaining = (cchRemaining*sizeof(wchar_t)) + (cbDest % sizeof(wchar_t));
562 return Status;
563 }
564
565 NTSTRSAFEAPI
566 RtlStringCchCatA(
567 _Inout_updates_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest,
568 _In_ size_t cchDest,
569 _In_ NTSTRSAFE_PCSTR pszSrc);
570
571 NTSTRSAFEAPI
572 RtlStringCchCatW(
573 _Inout_updates_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest,
574 _In_ size_t cchDest,
575 _In_ NTSTRSAFE_PCWSTR pszSrc);
576
577 NTSTRSAFEAPI
578 RtlStringCchCatA(
579 _Inout_updates_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest,
580 _In_ size_t cchDest,
581 _In_ NTSTRSAFE_PCSTR pszSrc)
582 {
583 if (cchDest > NTSTRSAFE_MAX_CCH)
584 return STATUS_INVALID_PARAMETER;
585 return RtlStringCatWorkerA(pszDest,cchDest,pszSrc);
586 }
587
588 NTSTRSAFEAPI
589 RtlStringCchCatW(
590 _Inout_updates_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest,
591 _In_ size_t cchDest,
592 _In_ NTSTRSAFE_PCWSTR pszSrc)
593 {
594 if (cchDest > NTSTRSAFE_MAX_CCH)
595 return STATUS_INVALID_PARAMETER;
596 return RtlStringCatWorkerW(pszDest,cchDest,pszSrc);
597 }
598
599 NTSTRSAFEAPI
600 RtlStringCbCatA(
601 _Inout_updates_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest,
602 _In_ size_t cbDest,
603 _In_ NTSTRSAFE_PCSTR pszSrc);
604
605 NTSTRSAFEAPI
606 RtlStringCbCatW(
607 _Inout_updates_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest,
608 _In_ size_t cbDest,
609 _In_ NTSTRSAFE_PCWSTR pszSrc);
610
611 NTSTRSAFEAPI
612 RtlStringCbCatA(
613 _Inout_updates_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest,
614 _In_ size_t cbDest,
615 _In_ NTSTRSAFE_PCSTR pszSrc)
616 {
617 if (cbDest > NTSTRSAFE_MAX_CCH)
618 return STATUS_INVALID_PARAMETER;
619 return RtlStringCatWorkerA(pszDest,cbDest,pszSrc);
620 }
621
622 NTSTRSAFEAPI
623 RtlStringCbCatW(
624 _Inout_updates_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest,
625 _In_ size_t cbDest,
626 _In_ NTSTRSAFE_PCWSTR pszSrc)
627 {
628 size_t cchDest = cbDest / sizeof(wchar_t);
629 if (cchDest > NTSTRSAFE_MAX_CCH)
630 return STATUS_INVALID_PARAMETER;
631 return RtlStringCatWorkerW(pszDest,cchDest,pszSrc);
632 }
633
634 NTSTRSAFEAPI
635 RtlStringCchCatExA(
636 _Inout_updates_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest,
637 _In_ size_t cchDest,
638 _In_ NTSTRSAFE_PCSTR pszSrc,
639 _Outptr_opt_result_buffer_(*pcchRemaining) NTSTRSAFE_PSTR *ppszDestEnd,
640 _Out_opt_ size_t *pcchRemaining,
641 _In_ STRSAFE_DWORD dwFlags);
642
643 NTSTRSAFEAPI
644 RtlStringCchCatExW(
645 _Inout_updates_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest,
646 _In_ size_t cchDest,
647 _In_ NTSTRSAFE_PCWSTR pszSrc,
648 _Outptr_opt_result_buffer_(*pcchRemaining) NTSTRSAFE_PWSTR *ppszDestEnd,
649 _Out_opt_ size_t *pcchRemaining,
650 _In_ STRSAFE_DWORD dwFlags);
651
652 NTSTRSAFEAPI
653 RtlStringCchCatExA(
654 _Inout_updates_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest,
655 _In_ size_t cchDest,
656 _In_ NTSTRSAFE_PCSTR pszSrc,
657 _Outptr_opt_result_buffer_(*pcchRemaining) NTSTRSAFE_PSTR *ppszDestEnd,
658 _Out_opt_ size_t *pcchRemaining,
659 _In_ STRSAFE_DWORD dwFlags)
660 {
661 if (cchDest > NTSTRSAFE_MAX_CCH)
662 return STATUS_INVALID_PARAMETER;
663 return RtlStringCatExWorkerA(pszDest,cchDest,cchDest,pszSrc,ppszDestEnd,pcchRemaining,dwFlags);
664 }
665
666 NTSTRSAFEAPI
667 RtlStringCchCatExW(
668 _Inout_updates_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest,
669 _In_ size_t cchDest,
670 _In_ NTSTRSAFE_PCWSTR pszSrc,
671 _Outptr_opt_result_buffer_(*pcchRemaining) NTSTRSAFE_PWSTR *ppszDestEnd,
672 _Out_opt_ size_t *pcchRemaining,
673 _In_ STRSAFE_DWORD dwFlags)
674 {
675 size_t cbDest = cchDest*sizeof(wchar_t);
676 if (cchDest > NTSTRSAFE_MAX_CCH)
677 return STATUS_INVALID_PARAMETER;
678 return RtlStringCatExWorkerW(pszDest,cchDest,cbDest,pszSrc,ppszDestEnd,pcchRemaining,dwFlags);
679 }
680
681 NTSTRSAFEAPI
682 RtlStringCbCatExA(
683 _Inout_updates_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest,
684 _In_ size_t cbDest,
685 _In_ NTSTRSAFE_PCSTR pszSrc,
686 _Outptr_opt_result_bytebuffer_(*pcbRemaining) NTSTRSAFE_PSTR *ppszDestEnd,
687 _Out_opt_ size_t *pcbRemaining,
688 _In_ STRSAFE_DWORD dwFlags);
689
690 NTSTRSAFEAPI
691 RtlStringCbCatExW(
692 _Inout_updates_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest,
693 _In_ size_t cbDest,
694 _In_ NTSTRSAFE_PCWSTR pszSrc,
695 _Outptr_opt_result_bytebuffer_(*pcbRemaining) NTSTRSAFE_PWSTR *ppszDestEnd,
696 _Out_opt_ size_t *pcbRemaining,
697 _In_ STRSAFE_DWORD dwFlags);
698
699 NTSTRSAFEAPI
700 RtlStringCbCatExA(
701 _Inout_updates_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest,
702 _In_ size_t cbDest,
703 _In_ NTSTRSAFE_PCSTR pszSrc,
704 _Outptr_opt_result_bytebuffer_(*pcbRemaining) NTSTRSAFE_PSTR *ppszDestEnd,
705 _Out_opt_ size_t *pcbRemaining,
706 _In_ STRSAFE_DWORD dwFlags)
707 {
708 NTSTATUS Status;
709 size_t cchRemaining = 0;
710 if (cbDest > NTSTRSAFE_MAX_CCH)
711 Status = STATUS_INVALID_PARAMETER;
712 else
713 Status = RtlStringCatExWorkerA(pszDest,cbDest,cbDest,pszSrc,ppszDestEnd,&cchRemaining,dwFlags);
714 if ((NT_SUCCESS(Status) || Status == STATUS_BUFFER_OVERFLOW) && pcbRemaining)
715 *pcbRemaining = (cchRemaining*sizeof(char)) + (cbDest % sizeof(char));
716 return Status;
717 }
718
719 NTSTRSAFEAPI
720 RtlStringCbCatExW(
721 _Inout_updates_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest,
722 _In_ size_t cbDest,
723 _In_ NTSTRSAFE_PCWSTR pszSrc,
724 _Outptr_opt_result_bytebuffer_(*pcbRemaining) NTSTRSAFE_PWSTR *ppszDestEnd,
725 _Out_opt_ size_t *pcbRemaining,
726 _In_ STRSAFE_DWORD dwFlags)
727 {
728 NTSTATUS Status;
729 size_t cchDest = cbDest / sizeof(wchar_t);
730 size_t cchRemaining = 0;
731
732 if (cchDest > NTSTRSAFE_MAX_CCH)
733 Status = STATUS_INVALID_PARAMETER;
734 else
735 Status = RtlStringCatExWorkerW(pszDest,cchDest,cbDest,pszSrc,ppszDestEnd,&cchRemaining,dwFlags);
736 if ((NT_SUCCESS(Status) || Status == STATUS_BUFFER_OVERFLOW) && pcbRemaining)
737 *pcbRemaining = (cchRemaining*sizeof(wchar_t)) + (cbDest % sizeof(wchar_t));
738 return Status;
739 }
740
741 NTSTRSAFEAPI
742 RtlStringCchCatNA(
743 _Inout_updates_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest,
744 _In_ size_t cchDest,
745 _In_reads_or_z_(cchToAppend) STRSAFE_LPCSTR pszSrc,
746 _In_ size_t cchToAppend);
747
748 NTSTRSAFEAPI
749 RtlStringCchCatNW(
750 _Inout_updates_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest,
751 _In_ size_t cchDest,
752 _In_reads_or_z_(cchToAppend) STRSAFE_LPCWSTR pszSrc,
753 _In_ size_t cchToAppend);
754
755 NTSTRSAFEAPI
756 RtlStringCchCatNA(
757 _Inout_updates_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest,
758 _In_ size_t cchDest,
759 _In_reads_or_z_(cchToAppend) STRSAFE_LPCSTR pszSrc,
760 _In_ size_t cchToAppend)
761 {
762 if (cchDest > NTSTRSAFE_MAX_CCH)
763 return STATUS_INVALID_PARAMETER;
764 return RtlStringCatNWorkerA(pszDest,cchDest,pszSrc,cchToAppend);
765 }
766
767 NTSTRSAFEAPI
768 RtlStringCchCatNW(
769 _Inout_updates_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest,
770 _In_ size_t cchDest,
771 _In_reads_or_z_(cchToAppend) STRSAFE_LPCWSTR pszSrc,
772 _In_ size_t cchToAppend)
773 {
774 if (cchDest > NTSTRSAFE_MAX_CCH)
775 return STATUS_INVALID_PARAMETER;
776 return RtlStringCatNWorkerW(pszDest,cchDest,pszSrc,cchToAppend);
777 }
778
779 NTSTRSAFEAPI
780 RtlStringCbCatNA(
781 _Inout_updates_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest,
782 _In_ size_t cbDest,
783 _In_reads_bytes_(cbToAppend) STRSAFE_LPCSTR pszSrc,
784 _In_ size_t cbToAppend);
785
786 NTSTRSAFEAPI
787 RtlStringCbCatNW(
788 _Inout_updates_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest,
789 _In_ size_t cbDest,
790 _In_reads_bytes_(cbToAppend) STRSAFE_LPCWSTR pszSrc,
791 _In_ size_t cbToAppend);
792
793 NTSTRSAFEAPI
794 RtlStringCbCatNA(
795 _Inout_updates_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest,
796 _In_ size_t cbDest,
797 _In_reads_bytes_(cbToAppend) STRSAFE_LPCSTR pszSrc,
798 _In_ size_t cbToAppend)
799 {
800 if (cbDest > NTSTRSAFE_MAX_CCH)
801 return STATUS_INVALID_PARAMETER;
802 return RtlStringCatNWorkerA(pszDest,cbDest,pszSrc,cbToAppend);
803 }
804
805 NTSTRSAFEAPI
806 RtlStringCbCatNW(
807 _Inout_updates_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest,
808 _In_ size_t cbDest,
809 _In_reads_bytes_(cbToAppend) STRSAFE_LPCWSTR pszSrc,
810 _In_ size_t cbToAppend)
811 {
812 size_t cchDest = cbDest / sizeof(wchar_t);
813 size_t cchToAppend = cbToAppend / sizeof(wchar_t);
814
815 if (cchDest > NTSTRSAFE_MAX_CCH)
816 return STATUS_INVALID_PARAMETER;
817 return RtlStringCatNWorkerW(pszDest,cchDest,pszSrc,cchToAppend);
818 }
819
820 NTSTRSAFEAPI
821 RtlStringCchCatNExA(
822 _Inout_updates_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest,
823 _In_ size_t cchDest,
824 _In_reads_or_z_(cchToAppend) STRSAFE_LPCSTR pszSrc,
825 _In_ size_t cchToAppend,
826 _Outptr_opt_result_buffer_(*pcchRemaining) NTSTRSAFE_PSTR *ppszDestEnd,
827 _Out_opt_ size_t *pcchRemaining,
828 _In_ STRSAFE_DWORD dwFlags);
829
830 NTSTRSAFEAPI
831 RtlStringCchCatNExW(
832 _Inout_updates_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest,
833 _In_ size_t cchDest,
834 _In_reads_or_z_(cchToAppend) STRSAFE_LPCWSTR pszSrc,
835 _In_ size_t cchToAppend,
836 _Outptr_opt_result_buffer_(*pcchRemaining) NTSTRSAFE_PWSTR *ppszDestEnd,
837 _Out_opt_ size_t *pcchRemaining,
838 _In_ STRSAFE_DWORD dwFlags);
839
840 NTSTRSAFEAPI
841 RtlStringCchCatNExA(
842 _Inout_updates_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest,
843 _In_ size_t cchDest,
844 _In_reads_or_z_(cchToAppend) STRSAFE_LPCSTR pszSrc,
845 _In_ size_t cchToAppend,
846 _Outptr_opt_result_buffer_(*pcchRemaining) NTSTRSAFE_PSTR *ppszDestEnd,
847 _Out_opt_ size_t *pcchRemaining,
848 _In_ STRSAFE_DWORD dwFlags)
849 {
850 if (cchDest > NTSTRSAFE_MAX_CCH)
851 return STATUS_INVALID_PARAMETER;
852 return RtlStringCatNExWorkerA(pszDest,cchDest,cchDest,pszSrc,cchToAppend,ppszDestEnd,pcchRemaining,dwFlags);
853 }
854
855 NTSTRSAFEAPI
856 RtlStringCchCatNExW(
857 _Inout_updates_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest,
858 _In_ size_t cchDest,
859 _In_reads_or_z_(cchToAppend) STRSAFE_LPCWSTR pszSrc,
860 _In_ size_t cchToAppend,
861 _Outptr_opt_result_buffer_(*pcchRemaining) NTSTRSAFE_PWSTR *ppszDestEnd,
862 _Out_opt_ size_t *pcchRemaining,
863 _In_ STRSAFE_DWORD dwFlags)
864 {
865 if (cchDest > NTSTRSAFE_MAX_CCH)
866 return STATUS_INVALID_PARAMETER;
867 return RtlStringCatNExWorkerW(pszDest,cchDest,(cchDest*sizeof(wchar_t)),pszSrc,cchToAppend,ppszDestEnd,pcchRemaining,dwFlags);
868 }
869
870 NTSTRSAFEAPI
871 RtlStringCbCatNExA(
872 _Inout_updates_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest,
873 _In_ size_t cbDest,
874 _In_reads_bytes_(cbToAppend) STRSAFE_LPCSTR pszSrc,
875 _In_ size_t cbToAppend,
876 _Outptr_opt_result_bytebuffer_(*pcbRemaining) NTSTRSAFE_PSTR *ppszDestEnd,
877 _Out_opt_ size_t *pcbRemaining,
878 _In_ STRSAFE_DWORD dwFlags);
879
880 NTSTRSAFEAPI
881 RtlStringCbCatNExW(
882 _Inout_updates_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest,
883 _In_ size_t cbDest,
884 _In_reads_bytes_(cbToAppend) STRSAFE_LPCWSTR pszSrc,
885 _In_ size_t cbToAppend,
886 _Outptr_opt_result_bytebuffer_(*pcbRemaining) NTSTRSAFE_PWSTR *ppszDestEnd,
887 _Out_opt_ size_t *pcbRemaining,
888 _In_ STRSAFE_DWORD dwFlags);
889
890 NTSTRSAFEAPI
891 RtlStringCbCatNExA(
892 _Inout_updates_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest,
893 _In_ size_t cbDest,
894 _In_reads_bytes_(cbToAppend) STRSAFE_LPCSTR pszSrc,
895 _In_ size_t cbToAppend,
896 _Outptr_opt_result_bytebuffer_(*pcbRemaining) NTSTRSAFE_PSTR *ppszDestEnd,
897 _Out_opt_ size_t *pcbRemaining,
898 _In_ STRSAFE_DWORD dwFlags)
899 {
900 NTSTATUS Status;
901 size_t cchRemaining = 0;
902 if (cbDest > NTSTRSAFE_MAX_CCH)
903 Status = STATUS_INVALID_PARAMETER;
904 else
905 Status = RtlStringCatNExWorkerA(pszDest,cbDest,cbDest,pszSrc,cbToAppend,ppszDestEnd,&cchRemaining,dwFlags);
906 if ((NT_SUCCESS(Status) || Status == STATUS_BUFFER_OVERFLOW) && pcbRemaining)
907 *pcbRemaining = (cchRemaining*sizeof(char)) + (cbDest % sizeof(char));
908 return Status;
909 }
910
911 NTSTRSAFEAPI
912 RtlStringCbCatNExW(
913 _Inout_updates_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest,
914 _In_ size_t cbDest,
915 _In_reads_bytes_(cbToAppend) STRSAFE_LPCWSTR pszSrc,
916 _In_ size_t cbToAppend,
917 _Outptr_opt_result_bytebuffer_(*pcbRemaining) NTSTRSAFE_PWSTR *ppszDestEnd,
918 _Out_opt_ size_t *pcbRemaining,
919 _In_ STRSAFE_DWORD dwFlags)
920 {
921 NTSTATUS Status;
922 size_t cchDest = cbDest / sizeof(wchar_t);
923 size_t cchToAppend = cbToAppend / sizeof(wchar_t);
924 size_t cchRemaining = 0;
925 if (cchDest > NTSTRSAFE_MAX_CCH)
926 Status = STATUS_INVALID_PARAMETER;
927 else
928 Status = RtlStringCatNExWorkerW(pszDest,cchDest,cbDest,pszSrc,cchToAppend,ppszDestEnd,&cchRemaining,dwFlags);
929 if ((NT_SUCCESS(Status) || Status == STATUS_BUFFER_OVERFLOW) && pcbRemaining)
930 *pcbRemaining = (cchRemaining*sizeof(wchar_t)) + (cbDest % sizeof(wchar_t));
931 return Status;
932 }
933
934 NTSTRSAFEAPI
935 RtlStringCchVPrintfA(
936 _Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest,
937 _In_ size_t cchDest,
938 _In_ _Printf_format_string_ NTSTRSAFE_PCSTR pszFormat,
939 _In_ va_list argList);
940
941 NTSTRSAFEAPI
942 RtlStringCchVPrintfW(
943 _Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest,
944 _In_ size_t cchDest,
945 _In_ _Printf_format_string_ NTSTRSAFE_PCWSTR pszFormat,
946 _In_ va_list argList);
947
948 NTSTRSAFEAPI
949 RtlStringCchVPrintfA(
950 _Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest,
951 _In_ size_t cchDest,
952 _In_ _Printf_format_string_ NTSTRSAFE_PCSTR pszFormat,
953 _In_ va_list argList)
954 {
955 if (cchDest > NTSTRSAFE_MAX_CCH)
956 {
957 if (cchDest > 0)
958 *pszDest = '\0';
959 return STATUS_INVALID_PARAMETER;
960 }
961
962 return RtlStringVPrintfWorkerA(pszDest,cchDest,pszFormat,argList);
963 }
964
965 NTSTRSAFEAPI
966 RtlStringCchVPrintfW(
967 _Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest,
968 _In_ size_t cchDest,
969 _In_ _Printf_format_string_ NTSTRSAFE_PCWSTR pszFormat,
970 _In_ va_list argList)
971 {
972 if (cchDest > NTSTRSAFE_MAX_CCH)
973 {
974 if (cchDest > 0)
975 *pszDest = L'\0';
976 return STATUS_INVALID_PARAMETER;
977 }
978 return RtlStringVPrintfWorkerW(pszDest,cchDest,pszFormat,argList);
979 }
980
981 NTSTRSAFEAPI
982 RtlStringCbVPrintfA(
983 _Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest,
984 _In_ size_t cbDest,
985 _In_ _Printf_format_string_ NTSTRSAFE_PCSTR pszFormat,
986 _In_ va_list argList);
987
988 NTSTRSAFEAPI
989 RtlStringCbVPrintfW(
990 _Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest,
991 _In_ size_t cbDest,
992 _In_ _Printf_format_string_ NTSTRSAFE_PCWSTR pszFormat,
993 _In_ va_list argList);
994
995 NTSTRSAFEAPI
996 RtlStringCbVPrintfA(
997 _Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest,
998 _In_ size_t cbDest,
999 _In_ _Printf_format_string_ NTSTRSAFE_PCSTR pszFormat,
1000 _In_ va_list argList)
1001 {
1002 if (cbDest > NTSTRSAFE_MAX_CCH)
1003 {
1004 if (cbDest > 0)
1005 *pszDest = '\0';
1006 return STATUS_INVALID_PARAMETER;
1007 }
1008 return RtlStringVPrintfWorkerA(pszDest,cbDest,pszFormat,argList);
1009 }
1010
1011 NTSTRSAFEAPI
1012 RtlStringCbVPrintfW(
1013 _Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest,
1014 _In_ size_t cbDest,
1015 _In_ _Printf_format_string_ NTSTRSAFE_PCWSTR pszFormat,
1016 _In_ va_list argList)
1017 {
1018 size_t cchDest = cbDest / sizeof(wchar_t);
1019 if (cchDest > NTSTRSAFE_MAX_CCH)
1020 {
1021 if (cchDest > 0)
1022 *pszDest = L'\0';
1023 return STATUS_INVALID_PARAMETER;
1024 }
1025 return RtlStringVPrintfWorkerW(pszDest,cchDest,pszFormat,argList);
1026 }
1027
1028 static __inline NTSTATUS
1029 RtlStringCchPrintfA(
1030 _Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest,
1031 _In_ size_t cchDest,
1032 _In_ _Printf_format_string_ NTSTRSAFE_PCSTR pszFormat,
1033 ...);
1034
1035 static __inline NTSTATUS
1036 RtlStringCchPrintfW(
1037 _Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest,
1038 _In_ size_t cchDest,
1039 _In_ _Printf_format_string_ NTSTRSAFE_PCWSTR pszFormat,
1040 ...);
1041
1042 static __inline NTSTATUS
1043 RtlStringCchPrintfA(
1044 _Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest,
1045 _In_ size_t cchDest,
1046 _In_ _Printf_format_string_ NTSTRSAFE_PCSTR pszFormat,
1047 ...)
1048 {
1049 NTSTATUS Status;
1050 va_list argList;
1051 if (cchDest > NTSTRSAFE_MAX_CCH)
1052 {
1053 if (cchDest > 0)
1054 *pszDest = '\0';
1055 return STATUS_INVALID_PARAMETER;
1056 }
1057 va_start(argList,pszFormat);
1058 Status = RtlStringVPrintfWorkerA(pszDest,cchDest,pszFormat,argList);
1059 va_end(argList);
1060 return Status;
1061 }
1062
1063 static __inline NTSTATUS
1064 RtlStringCchPrintfW(
1065 _Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest,
1066 _In_ size_t cchDest,
1067 _In_ _Printf_format_string_ NTSTRSAFE_PCWSTR pszFormat,
1068 ...)
1069 {
1070 NTSTATUS Status;
1071 va_list argList;
1072 if (cchDest > NTSTRSAFE_MAX_CCH)
1073 {
1074 if (cchDest > 0)
1075 *pszDest = L'\0';
1076 return STATUS_INVALID_PARAMETER;
1077 }
1078 va_start(argList,pszFormat);
1079 Status = RtlStringVPrintfWorkerW(pszDest,cchDest,pszFormat,argList);
1080 va_end(argList);
1081 return Status;
1082 }
1083
1084 static __inline NTSTATUS
1085 RtlStringCbPrintfA(
1086 _Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest,
1087 _In_ size_t cbDest,
1088 _In_ _Printf_format_string_ NTSTRSAFE_PCSTR pszFormat,
1089 ...);
1090
1091 static __inline NTSTATUS
1092 RtlStringCbPrintfW(
1093 _Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest,
1094 _In_ size_t cbDest,
1095 _In_ _Printf_format_string_ NTSTRSAFE_PCWSTR pszFormat,
1096 ...);
1097
1098 static __inline NTSTATUS
1099 RtlStringCbPrintfA(
1100 _Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest,
1101 _In_ size_t cbDest,
1102 _In_ _Printf_format_string_ NTSTRSAFE_PCSTR pszFormat,
1103 ...)
1104 {
1105 NTSTATUS Status;
1106 va_list argList;
1107 if (cbDest > NTSTRSAFE_MAX_CCH)
1108 {
1109 if (cbDest > 0)
1110 *pszDest = '\0';
1111 return STATUS_INVALID_PARAMETER;
1112 }
1113 va_start(argList,pszFormat);
1114 Status = RtlStringVPrintfWorkerA(pszDest,cbDest,pszFormat,argList);
1115 va_end(argList);
1116 return Status;
1117 }
1118
1119 static __inline NTSTATUS
1120 RtlStringCbPrintfW(
1121 _Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest,
1122 _In_ size_t cbDest,
1123 _In_ _Printf_format_string_ NTSTRSAFE_PCWSTR pszFormat,
1124 ...)
1125 {
1126 NTSTATUS Status;
1127 va_list argList;
1128 size_t cchDest = cbDest / sizeof(wchar_t);
1129 if (cchDest > NTSTRSAFE_MAX_CCH)
1130 {
1131 if (cchDest > 0)
1132 *pszDest = L'\0';
1133 return STATUS_INVALID_PARAMETER;
1134 }
1135 va_start(argList,pszFormat);
1136 Status = RtlStringVPrintfWorkerW(pszDest,cchDest,pszFormat,argList);
1137 va_end(argList);
1138 return Status;
1139 }
1140
1141 static __inline NTSTATUS
1142 RtlStringCchPrintfExA(
1143 _Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest,
1144 _In_ size_t cchDest,
1145 _Outptr_opt_result_buffer_(*pcchRemaining) NTSTRSAFE_PSTR *ppszDestEnd,
1146 _Out_opt_ size_t *pcchRemaining,
1147 _In_ STRSAFE_DWORD dwFlags,
1148 _In_ _Printf_format_string_ NTSTRSAFE_PCSTR pszFormat,
1149 ...);
1150
1151 static __inline NTSTATUS
1152 RtlStringCchPrintfExW(
1153 _Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest,
1154 _In_ size_t cchDest,
1155 _Outptr_opt_result_buffer_(*pcchRemaining) NTSTRSAFE_PWSTR *ppszDestEnd,
1156 _Out_opt_ size_t *pcchRemaining,
1157 _In_ STRSAFE_DWORD dwFlags,
1158 _In_ _Printf_format_string_ NTSTRSAFE_PCWSTR pszFormat,
1159 ...);
1160
1161 static __inline NTSTATUS
1162 RtlStringCchPrintfExA(
1163 _Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest,
1164 _In_ size_t cchDest,
1165 _Outptr_opt_result_buffer_(*pcchRemaining) NTSTRSAFE_PSTR *ppszDestEnd,
1166 _Out_opt_ size_t *pcchRemaining,
1167 _In_ STRSAFE_DWORD dwFlags,
1168 _In_ _Printf_format_string_ NTSTRSAFE_PCSTR pszFormat,
1169 ...)
1170 {
1171 NTSTATUS Status;
1172 va_list argList;
1173 if (cchDest > NTSTRSAFE_MAX_CCH)
1174 {
1175 if (cchDest > 0)
1176 *pszDest = '\0';
1177 return STATUS_INVALID_PARAMETER;
1178 }
1179 va_start(argList,pszFormat);
1180 Status = RtlStringVPrintfExWorkerA(pszDest,cchDest,cchDest,ppszDestEnd,pcchRemaining,dwFlags,pszFormat,argList);
1181 va_end(argList);
1182 return Status;
1183 }
1184
1185 static __inline NTSTATUS
1186 RtlStringCchPrintfExW(
1187 _Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest,
1188 _In_ size_t cchDest,
1189 _Outptr_opt_result_buffer_(*pcchRemaining) NTSTRSAFE_PWSTR *ppszDestEnd,
1190 _Out_opt_ size_t *pcchRemaining,
1191 _In_ STRSAFE_DWORD dwFlags,
1192 _In_ _Printf_format_string_ NTSTRSAFE_PCWSTR pszFormat,
1193 ...)
1194 {
1195 NTSTATUS Status;
1196 size_t cbDest = cchDest * sizeof(wchar_t);
1197 va_list argList;
1198 if (cchDest > NTSTRSAFE_MAX_CCH)
1199 {
1200 if (cchDest > 0)
1201 *pszDest = L'\0';
1202 return STATUS_INVALID_PARAMETER;
1203 }
1204 va_start(argList,pszFormat);
1205 Status = RtlStringVPrintfExWorkerW(pszDest,cchDest,cbDest,ppszDestEnd,pcchRemaining,dwFlags,pszFormat,argList);
1206 va_end(argList);
1207 return Status;
1208 }
1209
1210 static __inline NTSTATUS
1211 RtlStringCbPrintfExA(
1212 _Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest,
1213 _In_ size_t cbDest,
1214 _Outptr_opt_result_bytebuffer_(*pcbRemaining) NTSTRSAFE_PSTR *ppszDestEnd,
1215 _Out_opt_ size_t *pcbRemaining,
1216 _In_ STRSAFE_DWORD dwFlags,
1217 _In_ _Printf_format_string_ NTSTRSAFE_PCSTR pszFormat,
1218 ...);
1219
1220 static __inline NTSTATUS
1221 RtlStringCbPrintfExW(
1222 _Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest,
1223 _In_ size_t cbDest,
1224 _Outptr_opt_result_bytebuffer_(*pcbRemaining) NTSTRSAFE_PWSTR *ppszDestEnd,
1225 _Out_opt_ size_t *pcbRemaining,
1226 _In_ STRSAFE_DWORD dwFlags,
1227 _In_ _Printf_format_string_ NTSTRSAFE_PCWSTR pszFormat,
1228 ...);
1229
1230 static __inline NTSTATUS
1231 RtlStringCbPrintfExA(
1232 _Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest,
1233 _In_ size_t cbDest,
1234 _Outptr_opt_result_bytebuffer_(*pcbRemaining) NTSTRSAFE_PSTR *ppszDestEnd,
1235 _Out_opt_ size_t *pcbRemaining,
1236 _In_ STRSAFE_DWORD dwFlags,
1237 _In_ _Printf_format_string_ NTSTRSAFE_PCSTR pszFormat,
1238 ...)
1239 {
1240 NTSTATUS Status;
1241 size_t cchDest;
1242 size_t cchRemaining = 0;
1243
1244 cchDest = cbDest / sizeof(char);
1245 if (cchDest > NTSTRSAFE_MAX_CCH)
1246 {
1247 if (cchDest > 0)
1248 *pszDest = '\0';
1249 return STATUS_INVALID_PARAMETER;
1250 }
1251
1252 {
1253 va_list argList;
1254 va_start(argList,pszFormat);
1255 Status = RtlStringVPrintfExWorkerA(pszDest,cchDest,cbDest,ppszDestEnd,&cchRemaining,dwFlags,pszFormat,argList);
1256 va_end(argList);
1257 }
1258 if (NT_SUCCESS(Status) || (Status==STATUS_BUFFER_OVERFLOW))
1259 {
1260 if (pcbRemaining)
1261 {
1262 *pcbRemaining = (cchRemaining*sizeof(char)) + (cbDest % sizeof(char));
1263 }
1264 }
1265 return Status;
1266 }
1267
1268 static __inline NTSTATUS
1269 RtlStringCbPrintfExW(
1270 _Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest,
1271 _In_ size_t cbDest,
1272 _Outptr_opt_result_bytebuffer_(*pcbRemaining) NTSTRSAFE_PWSTR *ppszDestEnd,
1273 _Out_opt_ size_t *pcbRemaining,
1274 _In_ STRSAFE_DWORD dwFlags,
1275 _In_ _Printf_format_string_ NTSTRSAFE_PCWSTR pszFormat,
1276 ...)
1277 {
1278 NTSTATUS Status;
1279 size_t cchDest;
1280 size_t cchRemaining = 0;
1281 cchDest = cbDest / sizeof(wchar_t);
1282 if (cchDest > NTSTRSAFE_MAX_CCH)
1283 {
1284 if (cchDest > 0)
1285 *pszDest = L'\0';
1286 return STATUS_INVALID_PARAMETER;
1287 }
1288
1289 {
1290 va_list argList;
1291 va_start(argList,pszFormat);
1292 Status = RtlStringVPrintfExWorkerW(pszDest,cchDest,cbDest,ppszDestEnd,&cchRemaining,dwFlags,pszFormat,argList);
1293 va_end(argList);
1294 }
1295 if (NT_SUCCESS(Status) || (Status==STATUS_BUFFER_OVERFLOW))
1296 {
1297 if (pcbRemaining)
1298 {
1299 *pcbRemaining = (cchRemaining*sizeof(wchar_t)) + (cbDest % sizeof(wchar_t));
1300 }
1301 }
1302 return Status;
1303 }
1304
1305 NTSTRSAFEAPI
1306 RtlStringCchVPrintfExA(
1307 _Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest,
1308 _In_ size_t cchDest,
1309 _Outptr_opt_result_buffer_(*pcchRemaining) NTSTRSAFE_PSTR *ppszDestEnd,
1310 _Out_opt_ size_t *pcchRemaining,
1311 _In_ STRSAFE_DWORD dwFlags,
1312 _In_ _Printf_format_string_ NTSTRSAFE_PCSTR pszFormat,
1313 _In_ va_list argList);
1314
1315 NTSTRSAFEAPI
1316 RtlStringCchVPrintfExW(
1317 _Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest,
1318 _In_ size_t cchDest,
1319 _Outptr_opt_result_buffer_(*pcchRemaining) NTSTRSAFE_PWSTR *ppszDestEnd,
1320 _Out_opt_ size_t *pcchRemaining,
1321 _In_ STRSAFE_DWORD dwFlags,
1322 _In_ _Printf_format_string_ NTSTRSAFE_PCWSTR pszFormat,
1323 _In_ va_list argList);
1324
1325 NTSTRSAFEAPI
1326 RtlStringCchVPrintfExA(
1327 _Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest,
1328 _In_ size_t cchDest,
1329 _Outptr_opt_result_buffer_(*pcchRemaining) NTSTRSAFE_PSTR *ppszDestEnd,
1330 _Out_opt_ size_t *pcchRemaining,
1331 _In_ STRSAFE_DWORD dwFlags,
1332 _In_ _Printf_format_string_ NTSTRSAFE_PCSTR pszFormat,
1333 _In_ va_list argList)
1334 {
1335 NTSTATUS Status;
1336 if (cchDest > NTSTRSAFE_MAX_CCH)
1337 {
1338 if (cchDest > 0)
1339 *pszDest = '\0';
1340 return STATUS_INVALID_PARAMETER;
1341 }
1342
1343 {
1344 size_t cbDest;
1345 cbDest = cchDest*sizeof(char);
1346 Status = RtlStringVPrintfExWorkerA(pszDest,cchDest,cbDest,ppszDestEnd,pcchRemaining,dwFlags,pszFormat,argList);
1347 }
1348 return Status;
1349 }
1350
1351 NTSTRSAFEAPI
1352 RtlStringCchVPrintfExW(
1353 _Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest,
1354 _In_ size_t cchDest,
1355 _Outptr_opt_result_buffer_(*pcchRemaining) NTSTRSAFE_PWSTR *ppszDestEnd,
1356 _Out_opt_ size_t *pcchRemaining,
1357 _In_ STRSAFE_DWORD dwFlags,
1358 _In_ _Printf_format_string_ NTSTRSAFE_PCWSTR pszFormat,
1359 _In_ va_list argList)
1360 {
1361 NTSTATUS Status;
1362 if (cchDest > NTSTRSAFE_MAX_CCH)
1363 {
1364 if (cchDest > 0)
1365 *pszDest = L'\0';
1366 return STATUS_INVALID_PARAMETER;
1367 }
1368
1369 {
1370 size_t cbDest;
1371 cbDest = cchDest*sizeof(wchar_t);
1372 Status = RtlStringVPrintfExWorkerW(pszDest,cchDest,cbDest,ppszDestEnd,pcchRemaining,dwFlags,pszFormat,argList);
1373 }
1374 return Status;
1375 }
1376
1377 NTSTRSAFEAPI
1378 RtlStringCbVPrintfExA(
1379 _Out_writes_bytes_(cbDest) NTSTRSAFE_PSTR pszDest,
1380 _In_ size_t cbDest,
1381 _Outptr_opt_result_bytebuffer_(*pcbRemaining) NTSTRSAFE_PSTR *ppszDestEnd,
1382 _Out_opt_ size_t *pcbRemaining,
1383 _In_ STRSAFE_DWORD dwFlags,
1384 _In_ _Printf_format_string_ NTSTRSAFE_PCSTR pszFormat,
1385 _In_ va_list argList);
1386
1387 NTSTRSAFEAPI
1388 RtlStringCbVPrintfExW(
1389 _Out_writes_bytes_(cbDest) NTSTRSAFE_PWSTR pszDest,
1390 _In_ size_t cbDest,
1391 _Outptr_opt_result_bytebuffer_(*pcbRemaining) NTSTRSAFE_PWSTR *ppszDestEnd,
1392 _Out_opt_ size_t *pcbRemaining,
1393 _In_ STRSAFE_DWORD dwFlags,
1394 _In_ _Printf_format_string_ NTSTRSAFE_PCWSTR pszFormat,
1395 _In_ va_list argList);
1396
1397 NTSTRSAFEAPI
1398 RtlStringCbVPrintfExA(
1399 _Out_writes_bytes_(cbDest) NTSTRSAFE_PSTR pszDest,
1400 _In_ size_t cbDest,
1401 _Outptr_opt_result_bytebuffer_(*pcbRemaining) NTSTRSAFE_PSTR *ppszDestEnd,
1402 _Out_opt_ size_t *pcbRemaining,
1403 _In_ STRSAFE_DWORD dwFlags,
1404 _In_ _Printf_format_string_ NTSTRSAFE_PCSTR pszFormat,
1405 _In_ va_list argList)
1406 {
1407 NTSTATUS Status;
1408 size_t cchDest;
1409 size_t cchRemaining = 0;
1410 cchDest = cbDest / sizeof(char);
1411 if (cchDest > NTSTRSAFE_MAX_CCH)
1412 Status = STATUS_INVALID_PARAMETER;
1413 else
1414 Status = RtlStringVPrintfExWorkerA(pszDest,cchDest,cbDest,ppszDestEnd,&cchRemaining,dwFlags,pszFormat,argList);
1415 if (NT_SUCCESS(Status) || (Status==STATUS_BUFFER_OVERFLOW))
1416 {
1417 if (pcbRemaining)
1418 {
1419 *pcbRemaining = (cchRemaining*sizeof(char)) + (cbDest % sizeof(char));
1420 }
1421 }
1422 return Status;
1423 }
1424
1425 NTSTRSAFEAPI
1426 RtlStringCbVPrintfExW(
1427 _Out_writes_bytes_(cbDest) NTSTRSAFE_PWSTR pszDest,
1428 _In_ size_t cbDest,
1429 _Outptr_opt_result_bytebuffer_(*pcbRemaining) NTSTRSAFE_PWSTR *ppszDestEnd,
1430 _Out_opt_ size_t *pcbRemaining,
1431 _In_ STRSAFE_DWORD dwFlags,
1432 _In_ _Printf_format_string_ NTSTRSAFE_PCWSTR pszFormat,
1433 _In_ va_list argList)
1434 {
1435 NTSTATUS Status;
1436 size_t cchDest;
1437 size_t cchRemaining = 0;
1438 cchDest = cbDest / sizeof(wchar_t);
1439 if (cchDest > NTSTRSAFE_MAX_CCH)
1440 Status = STATUS_INVALID_PARAMETER;
1441 else
1442 Status = RtlStringVPrintfExWorkerW(pszDest,cchDest,cbDest,ppszDestEnd,&cchRemaining,dwFlags,pszFormat,argList);
1443 if (NT_SUCCESS(Status) || (Status==STATUS_BUFFER_OVERFLOW))
1444 {
1445 if (pcbRemaining)
1446 {
1447 *pcbRemaining = (cchRemaining*sizeof(wchar_t)) + (cbDest % sizeof(wchar_t));
1448 }
1449 }
1450 return Status;
1451 }
1452
1453
1454 _Must_inspect_result_
1455 NTSTRSAFEAPI
1456 RtlStringCchLengthA(
1457 _In_reads_or_z_(cchMax) STRSAFE_LPCSTR psz,
1458 _In_ _In_range_(1, NTSTRSAFE_MAX_CCH) size_t cchMax,
1459 _Out_opt_ _Deref_out_range_(<, cchMax) _Deref_out_range_(<=, _String_length_(psz)) size_t *pcchLength);
1460
1461 _Must_inspect_result_
1462 NTSTRSAFEAPI
1463 RtlStringCchLengthW(
1464 _In_reads_or_z_(cchMax) STRSAFE_LPCWSTR psz,
1465 _In_ _In_range_(1, NTSTRSAFE_MAX_CCH) size_t cchMax,
1466 _Out_opt_ _Deref_out_range_(<, cchMax) _Deref_out_range_(<=, _String_length_(psz)) size_t *pcchLength);
1467
1468 _Must_inspect_result_
1469 NTSTRSAFEAPI
1470 RtlStringCchLengthA(
1471 _In_reads_or_z_(cchMax) STRSAFE_LPCSTR psz,
1472 _In_ _In_range_(1, NTSTRSAFE_MAX_CCH) size_t cchMax,
1473 _Out_opt_ _Deref_out_range_(<, cchMax) _Deref_out_range_(<=, _String_length_(psz)) size_t *pcchLength)
1474 {
1475 NTSTATUS Status;
1476 if (!psz || (cchMax > NTSTRSAFE_MAX_CCH))
1477 Status = STATUS_INVALID_PARAMETER;
1478 else
1479 Status = RtlStringLengthWorkerA(psz,cchMax,pcchLength);
1480 if (!NT_SUCCESS(Status) && pcchLength)
1481 {
1482 *pcchLength = 0;
1483 }
1484 return Status;
1485 }
1486
1487 _Must_inspect_result_
1488 NTSTRSAFEAPI
1489 RtlStringCchLengthW(
1490 _In_reads_or_z_(cchMax) STRSAFE_LPCWSTR psz,
1491 _In_ _In_range_(1, NTSTRSAFE_MAX_CCH) size_t cchMax,
1492 _Out_opt_ _Deref_out_range_(<, cchMax) _Deref_out_range_(<=, _String_length_(psz)) size_t *pcchLength)
1493 {
1494 NTSTATUS Status;
1495 if (!psz || (cchMax > NTSTRSAFE_MAX_CCH))
1496 Status = STATUS_INVALID_PARAMETER;
1497 else
1498 Status = RtlStringLengthWorkerW(psz,cchMax,pcchLength);
1499 if (!NT_SUCCESS(Status) && pcchLength)
1500 {
1501 *pcchLength = 0;
1502 }
1503 return Status;
1504 }
1505
1506 _Must_inspect_result_
1507 NTSTRSAFEAPI
1508 RtlStringCbLengthA(
1509 _In_reads_or_z_(cbMax) STRSAFE_LPCSTR psz,
1510 _In_ _In_range_(1, NTSTRSAFE_MAX_CCH * sizeof(char)) size_t cbMax,
1511 _Out_opt_ _Deref_out_range_(<, cbMax) size_t *pcbLength);
1512
1513 _Must_inspect_result_
1514 NTSTRSAFEAPI
1515 RtlStringCbLengthW(
1516 _In_reads_or_z_(cbMax / sizeof(wchar_t)) STRSAFE_LPCWSTR psz,
1517 _In_ _In_range_(1, NTSTRSAFE_MAX_CCH * sizeof(wchar_t)) size_t cbMax,
1518 _Out_opt_ _Deref_out_range_(<, cbMax - 1) size_t *pcbLength);
1519
1520 _Must_inspect_result_
1521 NTSTRSAFEAPI
1522 RtlStringCbLengthA(
1523 _In_reads_or_z_(cbMax) STRSAFE_LPCSTR psz,
1524 _In_ _In_range_(1, NTSTRSAFE_MAX_CCH * sizeof(char)) size_t cbMax,
1525 _Out_opt_ _Deref_out_range_(<, cbMax) size_t *pcbLength)
1526 {
1527 NTSTATUS Status;
1528 size_t cchMax;
1529 size_t cchLength = 0;
1530 cchMax = cbMax / sizeof(char);
1531 if (!psz || (cchMax > NTSTRSAFE_MAX_CCH))
1532 Status = STATUS_INVALID_PARAMETER;
1533 else
1534 Status = RtlStringLengthWorkerA(psz,cchMax,&cchLength);
1535 if (pcbLength)
1536 {
1537 if (NT_SUCCESS(Status))
1538 {
1539 *pcbLength = cchLength*sizeof(char);
1540 }
1541 else
1542 {
1543 *pcbLength = 0;
1544 }
1545 }
1546 return Status;
1547 }
1548
1549 _Must_inspect_result_
1550 NTSTRSAFEAPI
1551 RtlStringCbLengthW(
1552 _In_reads_or_z_(cbMax / sizeof(wchar_t)) STRSAFE_LPCWSTR psz,
1553 _In_ _In_range_(1, NTSTRSAFE_MAX_CCH * sizeof(wchar_t)) size_t cbMax,
1554 _Out_opt_ _Deref_out_range_(<, cbMax - 1) size_t *pcbLength)
1555 {
1556 NTSTATUS Status;
1557 size_t cchMax;
1558 size_t cchLength = 0;
1559 cchMax = cbMax / sizeof(wchar_t);
1560 if (!psz || (cchMax > NTSTRSAFE_MAX_CCH))
1561 Status = STATUS_INVALID_PARAMETER;
1562 else
1563 Status = RtlStringLengthWorkerW(psz,cchMax,&cchLength);
1564 if (pcbLength)
1565 {
1566 if (NT_SUCCESS(Status))
1567 {
1568 *pcbLength = cchLength*sizeof(wchar_t);
1569 }
1570 else
1571 {
1572 *pcbLength = 0;
1573 }
1574 }
1575 return Status;
1576 }
1577
1578 NTSTRSAFEAPI RtlStringCopyWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc)
1579 {
1580 NTSTATUS Status = STATUS_SUCCESS;
1581 if (cchDest==0)
1582 Status = STATUS_INVALID_PARAMETER;
1583 else
1584 {
1585 while(cchDest && (*pszSrc!='\0'))
1586 {
1587 *pszDest++ = *pszSrc++;
1588 cchDest--;
1589 }
1590 if (cchDest==0)
1591 {
1592 pszDest--;
1593 Status = STATUS_BUFFER_OVERFLOW;
1594 }
1595 *pszDest= '\0';
1596 }
1597 return Status;
1598 }
1599
1600 NTSTRSAFEAPI RtlStringCopyWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc)
1601 {
1602 NTSTATUS Status = STATUS_SUCCESS;
1603 if (cchDest==0)
1604 Status = STATUS_INVALID_PARAMETER;
1605 else
1606 {
1607 while(cchDest && (*pszSrc!=L'\0'))
1608 {
1609 *pszDest++ = *pszSrc++;
1610 cchDest--;
1611 }
1612 if (cchDest==0)
1613 {
1614 pszDest--;
1615 Status = STATUS_BUFFER_OVERFLOW;
1616 }
1617 *pszDest= L'\0';
1618 }
1619 return Status;
1620 }
1621
1622 NTSTRSAFEAPI RtlStringCopyExWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags)
1623 {
1624 NTSTATUS Status = STATUS_SUCCESS;
1625 STRSAFE_LPSTR pszDestEnd = pszDest;
1626 size_t cchRemaining = 0;
1627 if (dwFlags & (~STRSAFE_VALID_FLAGS))
1628 Status = STATUS_INVALID_PARAMETER;
1629 else
1630 {
1631 if (dwFlags & STRSAFE_IGNORE_NULLS)
1632 {
1633 if (!pszDest)
1634 {
1635 if ((cchDest!=0) || (cbDest!=0))
1636 Status = STATUS_INVALID_PARAMETER;
1637 }
1638 if (!pszSrc)
1639 pszSrc = "";
1640 }
1641 if (NT_SUCCESS(Status))
1642 {
1643 if (cchDest==0)
1644 {
1645 pszDestEnd = pszDest;
1646 cchRemaining = 0;
1647 if (*pszSrc!='\0')
1648 {
1649 if (!pszDest)
1650 Status = STATUS_INVALID_PARAMETER;
1651 else
1652 Status = STATUS_BUFFER_OVERFLOW;
1653 }
1654 }
1655 else
1656 {
1657 pszDestEnd = pszDest;
1658 cchRemaining = cchDest;
1659 while(cchRemaining && (*pszSrc!='\0'))
1660 {
1661 *pszDestEnd++ = *pszSrc++;
1662 cchRemaining--;
1663 }
1664 if (cchRemaining > 0)
1665 {
1666 if (dwFlags & STRSAFE_FILL_BEHIND_NULL)
1667 {
1668 memset(pszDestEnd + 1,STRSAFE_GET_FILL_PATTERN(dwFlags),((cchRemaining - 1)*sizeof(char)) + (cbDest % sizeof(char)));
1669 }
1670 }
1671 else
1672 {
1673 pszDestEnd--;
1674 cchRemaining++;
1675 Status = STATUS_BUFFER_OVERFLOW;
1676 }
1677 *pszDestEnd = '\0';
1678 }
1679 }
1680 }
1681 if (!NT_SUCCESS(Status))
1682 {
1683 if (pszDest)
1684 {
1685 if (dwFlags & STRSAFE_FILL_ON_FAILURE)
1686 {
1687 memset(pszDest,STRSAFE_GET_FILL_PATTERN(dwFlags),cbDest);
1688 if (STRSAFE_GET_FILL_PATTERN(dwFlags)==0)
1689 {
1690 pszDestEnd = pszDest;
1691 cchRemaining = cchDest;
1692 }
1693 else
1694 if (cchDest > 0)
1695 {
1696 pszDestEnd = pszDest + cchDest - 1;
1697 cchRemaining = 1;
1698 *pszDestEnd = '\0';
1699 }
1700 }
1701 if (dwFlags & (STRSAFE_NULL_ON_FAILURE | STRSAFE_NO_TRUNCATION))
1702 {
1703 if (cchDest > 0)
1704 {
1705 pszDestEnd = pszDest;
1706 cchRemaining = cchDest;
1707 *pszDestEnd = '\0';
1708 }
1709 }
1710 }
1711 }
1712 if (NT_SUCCESS(Status) || (Status==STATUS_BUFFER_OVERFLOW))
1713 {
1714 if (ppszDestEnd)
1715 *ppszDestEnd = pszDestEnd;
1716 if (pcchRemaining)
1717 *pcchRemaining = cchRemaining;
1718 }
1719 return Status;
1720 }
1721
1722 NTSTRSAFEAPI RtlStringCopyExWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags)
1723 {
1724 NTSTATUS Status = STATUS_SUCCESS;
1725 STRSAFE_LPWSTR pszDestEnd = pszDest;
1726 size_t cchRemaining = 0;
1727 if (dwFlags & (~STRSAFE_VALID_FLAGS))
1728 Status = STATUS_INVALID_PARAMETER;
1729 else
1730 {
1731 if (dwFlags & STRSAFE_IGNORE_NULLS)
1732 {
1733 if (!pszDest)
1734 {
1735 if ((cchDest!=0) || (cbDest!=0))
1736 Status = STATUS_INVALID_PARAMETER;
1737 }
1738 if (!pszSrc)
1739 pszSrc = L"";
1740 }
1741 if (NT_SUCCESS(Status))
1742 {
1743 if (cchDest==0)
1744 {
1745 pszDestEnd = pszDest;
1746 cchRemaining = 0;
1747 if (*pszSrc!=L'\0')
1748 {
1749 if (!pszDest)
1750 Status = STATUS_INVALID_PARAMETER;
1751 else
1752 Status = STATUS_BUFFER_OVERFLOW;
1753 }
1754 }
1755 else
1756 {
1757 pszDestEnd = pszDest;
1758 cchRemaining = cchDest;
1759 while(cchRemaining && (*pszSrc!=L'\0'))
1760 {
1761 *pszDestEnd++ = *pszSrc++;
1762 cchRemaining--;
1763 }
1764 if (cchRemaining > 0)
1765 {
1766 if (dwFlags & STRSAFE_FILL_BEHIND_NULL)
1767 {
1768 memset(pszDestEnd + 1,STRSAFE_GET_FILL_PATTERN(dwFlags),((cchRemaining - 1)*sizeof(wchar_t)) + (cbDest % sizeof(wchar_t)));
1769 }
1770 }
1771 else
1772 {
1773 pszDestEnd--;
1774 cchRemaining++;
1775 Status = STATUS_BUFFER_OVERFLOW;
1776 }
1777 *pszDestEnd = L'\0';
1778 }
1779 }
1780 }
1781 if (!NT_SUCCESS(Status))
1782 {
1783 if (pszDest)
1784 {
1785 if (dwFlags & STRSAFE_FILL_ON_FAILURE)
1786 {
1787 memset(pszDest,STRSAFE_GET_FILL_PATTERN(dwFlags),cbDest);
1788 if (STRSAFE_GET_FILL_PATTERN(dwFlags)==0)
1789 {
1790 pszDestEnd = pszDest;
1791 cchRemaining = cchDest;
1792 }
1793 else
1794 if (cchDest > 0)
1795 {
1796 pszDestEnd = pszDest + cchDest - 1;
1797 cchRemaining = 1;
1798 *pszDestEnd = L'\0';
1799 }
1800 }
1801 if (dwFlags & (STRSAFE_NULL_ON_FAILURE | STRSAFE_NO_TRUNCATION))
1802 {
1803 if (cchDest > 0)
1804 {
1805 pszDestEnd = pszDest;
1806 cchRemaining = cchDest;
1807 *pszDestEnd = L'\0';
1808 }
1809 }
1810 }
1811 }
1812 if (NT_SUCCESS(Status) || (Status==STATUS_BUFFER_OVERFLOW))
1813 {
1814 if (ppszDestEnd)
1815 *ppszDestEnd = pszDestEnd;
1816 if (pcchRemaining)
1817 *pcchRemaining = cchRemaining;
1818 }
1819 return Status;
1820 }
1821
1822 NTSTRSAFEAPI RtlStringCopyNWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc,size_t cchSrc)
1823 {
1824 NTSTATUS Status = STATUS_SUCCESS;
1825 if (cchDest==0)
1826 Status = STATUS_INVALID_PARAMETER;
1827 else
1828 {
1829 while(cchDest && cchSrc && (*pszSrc!='\0'))
1830 {
1831 *pszDest++ = *pszSrc++;
1832 cchDest--;
1833 cchSrc--;
1834 }
1835 if (cchDest==0)
1836 {
1837 pszDest--;
1838 Status = STATUS_BUFFER_OVERFLOW;
1839 }
1840 *pszDest= '\0';
1841 }
1842 return Status;
1843 }
1844
1845 NTSTRSAFEAPI RtlStringCopyNWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc,size_t cchToCopy)
1846 {
1847 NTSTATUS Status = STATUS_SUCCESS;
1848 if (cchDest==0)
1849 Status = STATUS_INVALID_PARAMETER;
1850 else
1851 {
1852 while(cchDest && cchToCopy && (*pszSrc!=L'\0'))
1853 {
1854 *pszDest++ = *pszSrc++;
1855 cchDest--;
1856 cchToCopy--;
1857 }
1858 if (cchDest==0)
1859 {
1860 pszDest--;
1861 Status = STATUS_BUFFER_OVERFLOW;
1862 }
1863 *pszDest= L'\0';
1864 }
1865 return Status;
1866 }
1867
1868 NTSTRSAFEAPI RtlStringCopyNExWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,size_t cchToCopy,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags)
1869 {
1870 NTSTATUS Status = STATUS_SUCCESS;
1871 STRSAFE_LPSTR pszDestEnd = pszDest;
1872 size_t cchRemaining = 0;
1873 if (dwFlags & (~STRSAFE_VALID_FLAGS))
1874 Status = STATUS_INVALID_PARAMETER;
1875 else
1876 if (cchToCopy > NTSTRSAFE_MAX_CCH)
1877 Status = STATUS_INVALID_PARAMETER;
1878 else
1879 {
1880 if (dwFlags & STRSAFE_IGNORE_NULLS)
1881 {
1882 if (!pszDest)
1883 {
1884 if ((cchDest!=0) || (cbDest!=0))
1885 Status = STATUS_INVALID_PARAMETER;
1886 }
1887 if (!pszSrc)
1888 pszSrc = "";
1889 }
1890 if (NT_SUCCESS(Status))
1891 {
1892 if (cchDest==0)
1893 {
1894 pszDestEnd = pszDest;
1895 cchRemaining = 0;
1896 if ((cchToCopy!=0) && (*pszSrc!='\0'))
1897 {
1898 if (!pszDest)
1899 Status = STATUS_INVALID_PARAMETER;
1900 else
1901 Status = STATUS_BUFFER_OVERFLOW;
1902 }
1903 }
1904 else
1905 {
1906 pszDestEnd = pszDest;
1907 cchRemaining = cchDest;
1908 while(cchRemaining && cchToCopy && (*pszSrc!='\0'))
1909 {
1910 *pszDestEnd++ = *pszSrc++;
1911 cchRemaining--;
1912 cchToCopy--;
1913 }
1914 if (cchRemaining > 0)
1915 {
1916 if (dwFlags & STRSAFE_FILL_BEHIND_NULL)
1917 {
1918 memset(pszDestEnd + 1,STRSAFE_GET_FILL_PATTERN(dwFlags),((cchRemaining - 1)*sizeof(char)) + (cbDest % sizeof(char)));
1919 }
1920 }
1921 else
1922 {
1923 pszDestEnd--;
1924 cchRemaining++;
1925 Status = STATUS_BUFFER_OVERFLOW;
1926 }
1927 *pszDestEnd = '\0';
1928 }
1929 }
1930 }
1931 if (!NT_SUCCESS(Status))
1932 {
1933 if (pszDest)
1934 {
1935 if (dwFlags & STRSAFE_FILL_ON_FAILURE)
1936 {
1937 memset(pszDest,STRSAFE_GET_FILL_PATTERN(dwFlags),cbDest);
1938 if (STRSAFE_GET_FILL_PATTERN(dwFlags)==0)
1939 {
1940 pszDestEnd = pszDest;
1941 cchRemaining = cchDest;
1942 }
1943 else
1944 if (cchDest > 0)
1945 {
1946 pszDestEnd = pszDest + cchDest - 1;
1947 cchRemaining = 1;
1948 *pszDestEnd = '\0';
1949 }
1950 }
1951 if (dwFlags & (STRSAFE_NULL_ON_FAILURE | STRSAFE_NO_TRUNCATION))
1952 {
1953 if (cchDest > 0)
1954 {
1955 pszDestEnd = pszDest;
1956 cchRemaining = cchDest;
1957 *pszDestEnd = '\0';
1958 }
1959 }
1960 }
1961 }
1962 if (NT_SUCCESS(Status) || (Status==STATUS_BUFFER_OVERFLOW))
1963 {
1964 if (ppszDestEnd)
1965 *ppszDestEnd = pszDestEnd;
1966 if (pcchRemaining)
1967 *pcchRemaining = cchRemaining;
1968 }
1969 return Status;
1970 }
1971
1972 NTSTRSAFEAPI RtlStringCopyNExWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,size_t cchToCopy,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags)
1973 {
1974 NTSTATUS Status = STATUS_SUCCESS;
1975 STRSAFE_LPWSTR pszDestEnd = pszDest;
1976 size_t cchRemaining = 0;
1977 if (dwFlags & (~STRSAFE_VALID_FLAGS))
1978 Status = STATUS_INVALID_PARAMETER;
1979 else
1980 if (cchToCopy > NTSTRSAFE_MAX_CCH)
1981 Status = STATUS_INVALID_PARAMETER;
1982 else
1983 {
1984 if (dwFlags & STRSAFE_IGNORE_NULLS)
1985 {
1986 if (!pszDest)
1987 {
1988 if ((cchDest!=0) || (cbDest!=0))
1989 Status = STATUS_INVALID_PARAMETER;
1990 }
1991 if (!pszSrc)
1992 pszSrc = L"";
1993 }
1994 if (NT_SUCCESS(Status))
1995 {
1996 if (cchDest==0)
1997 {
1998 pszDestEnd = pszDest;
1999 cchRemaining = 0;
2000 if ((cchToCopy!=0) && (*pszSrc!=L'\0'))
2001 {
2002 if (!pszDest)
2003 Status = STATUS_INVALID_PARAMETER;
2004 else
2005 Status = STATUS_BUFFER_OVERFLOW;
2006 }
2007 }
2008 else
2009 {
2010 pszDestEnd = pszDest;
2011 cchRemaining = cchDest;
2012 while(cchRemaining && cchToCopy && (*pszSrc!=L'\0'))
2013 {
2014 *pszDestEnd++ = *pszSrc++;
2015 cchRemaining--;
2016 cchToCopy--;
2017 }
2018 if (cchRemaining > 0)
2019 {
2020 if (dwFlags & STRSAFE_FILL_BEHIND_NULL)
2021 {
2022 memset(pszDestEnd + 1,STRSAFE_GET_FILL_PATTERN(dwFlags),((cchRemaining - 1)*sizeof(wchar_t)) + (cbDest % sizeof(wchar_t)));
2023 }
2024 }
2025 else
2026 {
2027 pszDestEnd--;
2028 cchRemaining++;
2029 Status = STATUS_BUFFER_OVERFLOW;
2030 }
2031 *pszDestEnd = L'\0';
2032 }
2033 }
2034 }
2035 if (!NT_SUCCESS(Status))
2036 {
2037 if (pszDest)
2038 {
2039 if (dwFlags & STRSAFE_FILL_ON_FAILURE)
2040 {
2041 memset(pszDest,STRSAFE_GET_FILL_PATTERN(dwFlags),cbDest);
2042 if (STRSAFE_GET_FILL_PATTERN(dwFlags)==0)
2043 {
2044 pszDestEnd = pszDest;
2045 cchRemaining = cchDest;
2046 }
2047 else
2048 if (cchDest > 0)
2049 {
2050 pszDestEnd = pszDest + cchDest - 1;
2051 cchRemaining = 1;
2052 *pszDestEnd = L'\0';
2053 }
2054 }
2055 if (dwFlags & (STRSAFE_NULL_ON_FAILURE | STRSAFE_NO_TRUNCATION))
2056 {
2057 if (cchDest > 0)
2058 {
2059 pszDestEnd = pszDest;
2060 cchRemaining = cchDest;
2061 *pszDestEnd = L'\0';
2062 }
2063 }
2064 }
2065 }
2066 if (NT_SUCCESS(Status) || (Status==STATUS_BUFFER_OVERFLOW))
2067 {
2068 if (ppszDestEnd)
2069 *ppszDestEnd = pszDestEnd;
2070 if (pcchRemaining)
2071 *pcchRemaining = cchRemaining;
2072 }
2073 return Status;
2074 }
2075
2076 NTSTRSAFEAPI RtlStringCatWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc)
2077 {
2078 NTSTATUS Status;
2079 size_t cchDestLength;
2080 Status = RtlStringLengthWorkerA(pszDest,cchDest,&cchDestLength);
2081 if (NT_SUCCESS(Status))
2082 Status = RtlStringCopyWorkerA(pszDest + cchDestLength,cchDest - cchDestLength,pszSrc);
2083 return Status;
2084 }
2085
2086 NTSTRSAFEAPI RtlStringCatWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc)
2087 {
2088 NTSTATUS Status;
2089 size_t cchDestLength;
2090 Status = RtlStringLengthWorkerW(pszDest,cchDest,&cchDestLength);
2091 if (NT_SUCCESS(Status))
2092 Status = RtlStringCopyWorkerW(pszDest + cchDestLength,cchDest - cchDestLength,pszSrc);
2093 return Status;
2094 }
2095
2096 NTSTRSAFEAPI RtlStringCatExWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags)
2097 {
2098 NTSTATUS Status = STATUS_SUCCESS;
2099 STRSAFE_LPSTR pszDestEnd = pszDest;
2100 size_t cchRemaining = 0;
2101 if (dwFlags & (~STRSAFE_VALID_FLAGS))
2102 Status = STATUS_INVALID_PARAMETER;
2103 else
2104 {
2105 size_t cchDestLength;
2106 if (dwFlags & STRSAFE_IGNORE_NULLS)
2107 {
2108 if (!pszDest)
2109 {
2110 if ((cchDest==0) && (cbDest==0))
2111 cchDestLength = 0;
2112 else
2113 Status = STATUS_INVALID_PARAMETER;
2114 }
2115 else
2116 {
2117 Status = RtlStringLengthWorkerA(pszDest,cchDest,&cchDestLength);
2118 if (NT_SUCCESS(Status))
2119 {
2120 pszDestEnd = pszDest + cchDestLength;
2121 cchRemaining = cchDest - cchDestLength;
2122 }
2123 }
2124 if (!pszSrc)
2125 pszSrc = "";
2126 }
2127 else
2128 {
2129 Status = RtlStringLengthWorkerA(pszDest,cchDest,&cchDestLength);
2130 if (NT_SUCCESS(Status))
2131 {
2132 pszDestEnd = pszDest + cchDestLength;
2133 cchRemaining = cchDest - cchDestLength;
2134 }
2135 }
2136 if (NT_SUCCESS(Status))
2137 {
2138 if (cchDest==0)
2139 {
2140 if (*pszSrc!='\0')
2141 {
2142 if (!pszDest)
2143 Status = STATUS_INVALID_PARAMETER;
2144 else
2145 Status = STATUS_BUFFER_OVERFLOW;
2146 }
2147 }
2148 else
2149 Status = RtlStringCopyExWorkerA(pszDestEnd,cchRemaining,(cchRemaining*sizeof(char)) + (cbDest % sizeof(char)),pszSrc,&pszDestEnd,&cchRemaining,dwFlags & (~(STRSAFE_FILL_ON_FAILURE | STRSAFE_NULL_ON_FAILURE)));
2150 }
2151 }
2152 if (!NT_SUCCESS(Status))
2153 {
2154 if (pszDest)
2155 {
2156 if (dwFlags & STRSAFE_FILL_ON_FAILURE)
2157 {
2158 memset(pszDest,STRSAFE_GET_FILL_PATTERN(dwFlags),cbDest);
2159 if (STRSAFE_GET_FILL_PATTERN(dwFlags)==0)
2160 {
2161 pszDestEnd = pszDest;
2162 cchRemaining = cchDest;
2163 }
2164 else
2165 if (cchDest > 0)
2166 {
2167 pszDestEnd = pszDest + cchDest - 1;
2168 cchRemaining = 1;
2169 *pszDestEnd = '\0';
2170 }
2171 }
2172 if (dwFlags & STRSAFE_NULL_ON_FAILURE)
2173 {
2174 if (cchDest > 0)
2175 {
2176 pszDestEnd = pszDest;
2177 cchRemaining = cchDest;
2178 *pszDestEnd = '\0';
2179 }
2180 }
2181 }
2182 }
2183 if (NT_SUCCESS(Status) || (Status==STATUS_BUFFER_OVERFLOW))
2184 {
2185 if (ppszDestEnd)
2186 *ppszDestEnd = pszDestEnd;
2187 if (pcchRemaining)
2188 *pcchRemaining = cchRemaining;
2189 }
2190 return Status;
2191 }
2192
2193 NTSTRSAFEAPI RtlStringCatExWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags)
2194 {
2195 NTSTATUS Status = STATUS_SUCCESS;
2196 STRSAFE_LPWSTR pszDestEnd = pszDest;
2197 size_t cchRemaining = 0;
2198 if (dwFlags & (~STRSAFE_VALID_FLAGS))
2199 Status = STATUS_INVALID_PARAMETER;
2200 else
2201 {
2202 size_t cchDestLength;
2203 if (dwFlags & STRSAFE_IGNORE_NULLS)
2204 {
2205 if (!pszDest)
2206 {
2207 if ((cchDest==0) && (cbDest==0))
2208 cchDestLength = 0;
2209 else
2210 Status = STATUS_INVALID_PARAMETER;
2211 }
2212 else
2213 {
2214 Status = RtlStringLengthWorkerW(pszDest,cchDest,&cchDestLength);
2215 if (NT_SUCCESS(Status))
2216 {
2217 pszDestEnd = pszDest + cchDestLength;
2218 cchRemaining = cchDest - cchDestLength;
2219 }
2220 }
2221 if (!pszSrc)
2222 pszSrc = L"";
2223 }
2224 else
2225 {
2226 Status = RtlStringLengthWorkerW(pszDest,cchDest,&cchDestLength);
2227 if (NT_SUCCESS(Status))
2228 {
2229 pszDestEnd = pszDest + cchDestLength;
2230 cchRemaining = cchDest - cchDestLength;
2231 }
2232 }
2233 if (NT_SUCCESS(Status))
2234 {
2235 if (cchDest==0)
2236 {
2237 if (*pszSrc!=L'\0')
2238 {
2239 if (!pszDest)
2240 Status = STATUS_INVALID_PARAMETER;
2241 else
2242 Status = STATUS_BUFFER_OVERFLOW;
2243 }
2244 }
2245 else
2246 Status = RtlStringCopyExWorkerW(pszDestEnd,cchRemaining,(cchRemaining*sizeof(wchar_t)) + (cbDest % sizeof(wchar_t)),pszSrc,&pszDestEnd,&cchRemaining,dwFlags & (~(STRSAFE_FILL_ON_FAILURE | STRSAFE_NULL_ON_FAILURE)));
2247 }
2248 }
2249 if (!NT_SUCCESS(Status))
2250 {
2251 if (pszDest)
2252 {
2253 if (dwFlags & STRSAFE_FILL_ON_FAILURE)
2254 {
2255 memset(pszDest,STRSAFE_GET_FILL_PATTERN(dwFlags),cbDest);
2256 if (STRSAFE_GET_FILL_PATTERN(dwFlags)==0)
2257 {
2258 pszDestEnd = pszDest;
2259 cchRemaining = cchDest;
2260 }
2261 else
2262 if (cchDest > 0)
2263 {
2264 pszDestEnd = pszDest + cchDest - 1;
2265 cchRemaining = 1;
2266 *pszDestEnd = L'\0';
2267 }
2268 }
2269 if (dwFlags & STRSAFE_NULL_ON_FAILURE)
2270 {
2271 if (cchDest > 0)
2272 {
2273 pszDestEnd = pszDest;
2274 cchRemaining = cchDest;
2275 *pszDestEnd = L'\0';
2276 }
2277 }
2278 }
2279 }
2280 if (NT_SUCCESS(Status) || (Status==STATUS_BUFFER_OVERFLOW))
2281 {
2282 if (ppszDestEnd)
2283 *ppszDestEnd = pszDestEnd;
2284 if (pcchRemaining)
2285 *pcchRemaining = cchRemaining;
2286 }
2287 return Status;
2288 }
2289
2290 NTSTRSAFEAPI RtlStringCatNWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc,size_t cchToAppend)
2291 {
2292 NTSTATUS Status;
2293 size_t cchDestLength;
2294 Status = RtlStringLengthWorkerA(pszDest,cchDest,&cchDestLength);
2295 if (NT_SUCCESS(Status))
2296 Status = RtlStringCopyNWorkerA(pszDest + cchDestLength,cchDest - cchDestLength,pszSrc,cchToAppend);
2297 return Status;
2298 }
2299
2300 NTSTRSAFEAPI RtlStringCatNWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc,size_t cchToAppend)
2301 {
2302 NTSTATUS Status;
2303 size_t cchDestLength;
2304 Status = RtlStringLengthWorkerW(pszDest,cchDest,&cchDestLength);
2305 if (NT_SUCCESS(Status))
2306 Status = RtlStringCopyNWorkerW(pszDest + cchDestLength,cchDest - cchDestLength,pszSrc,cchToAppend);
2307 return Status;
2308 }
2309
2310 NTSTRSAFEAPI RtlStringCatNExWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,size_t cchToAppend,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags)
2311 {
2312 NTSTATUS Status = STATUS_SUCCESS;
2313 STRSAFE_LPSTR pszDestEnd = pszDest;
2314 size_t cchRemaining = 0;
2315 size_t cchDestLength = 0;
2316 if (dwFlags & (~STRSAFE_VALID_FLAGS))
2317 Status = STATUS_INVALID_PARAMETER;
2318 else
2319 if (cchToAppend > NTSTRSAFE_MAX_CCH)
2320 Status = STATUS_INVALID_PARAMETER;
2321 else
2322 {
2323 if (dwFlags & STRSAFE_IGNORE_NULLS)
2324 {
2325 if (!pszDest)
2326 {
2327 if ((cchDest==0) && (cbDest==0))
2328 cchDestLength = 0;
2329 else
2330 Status = STATUS_INVALID_PARAMETER;
2331 }
2332 else
2333 {
2334 Status = RtlStringLengthWorkerA(pszDest,cchDest,&cchDestLength);
2335 if (NT_SUCCESS(Status))
2336 {
2337 pszDestEnd = pszDest + cchDestLength;
2338 cchRemaining = cchDest - cchDestLength;
2339 }
2340 }
2341 if (!pszSrc)
2342 pszSrc = "";
2343 }
2344 else
2345 {
2346 Status = RtlStringLengthWorkerA(pszDest,cchDest,&cchDestLength);
2347 if (NT_SUCCESS(Status))
2348 {
2349 pszDestEnd = pszDest + cchDestLength;
2350 cchRemaining = cchDest - cchDestLength;
2351 }
2352 }
2353 if (NT_SUCCESS(Status))
2354 {
2355 if (cchDest==0)
2356 {
2357 if ((cchToAppend!=0) && (*pszSrc!='\0'))
2358 {
2359 if (!pszDest)
2360 Status = STATUS_INVALID_PARAMETER;
2361 else
2362 Status = STATUS_BUFFER_OVERFLOW;
2363 }
2364 }
2365 else
2366 Status = RtlStringCopyNExWorkerA(pszDestEnd,cchRemaining,(cchRemaining*sizeof(char)) + (cbDest % sizeof(char)),pszSrc,cchToAppend,&pszDestEnd,&cchRemaining,dwFlags & (~(STRSAFE_FILL_ON_FAILURE | STRSAFE_NULL_ON_FAILURE)));
2367 }
2368 }
2369 if (!NT_SUCCESS(Status))
2370 {
2371 if (pszDest)
2372 {
2373 if (dwFlags & STRSAFE_FILL_ON_FAILURE)
2374 {
2375 memset(pszDest,STRSAFE_GET_FILL_PATTERN(dwFlags),cbDest);
2376 if (STRSAFE_GET_FILL_PATTERN(dwFlags)==0)
2377 {
2378 pszDestEnd = pszDest;
2379 cchRemaining = cchDest;
2380 }
2381 else
2382 if (cchDest > 0)
2383 {
2384 pszDestEnd = pszDest + cchDest - 1;
2385 cchRemaining = 1;
2386 *pszDestEnd = '\0';
2387 }
2388 }
2389 if (dwFlags & (STRSAFE_NULL_ON_FAILURE))
2390 {
2391 if (cchDest > 0)
2392 {
2393 pszDestEnd = pszDest;
2394 cchRemaining = cchDest;
2395 *pszDestEnd = '\0';
2396 }
2397 }
2398 }
2399 }
2400 if (NT_SUCCESS(Status) || (Status==STATUS_BUFFER_OVERFLOW))
2401 {
2402 if (ppszDestEnd)
2403 *ppszDestEnd = pszDestEnd;
2404 if (pcchRemaining)
2405 *pcchRemaining = cchRemaining;
2406 }
2407 return Status;
2408 }
2409
2410 NTSTRSAFEAPI RtlStringCatNExWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,size_t cchToAppend,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags)
2411 {
2412 NTSTATUS Status = STATUS_SUCCESS;
2413 STRSAFE_LPWSTR pszDestEnd = pszDest;
2414 size_t cchRemaining = 0;
2415 size_t cchDestLength = 0;
2416 if (dwFlags & (~STRSAFE_VALID_FLAGS))
2417 Status = STATUS_INVALID_PARAMETER;
2418 else
2419 if (cchToAppend > NTSTRSAFE_MAX_CCH)
2420 Status = STATUS_INVALID_PARAMETER;
2421 else
2422 {
2423 if (dwFlags & STRSAFE_IGNORE_NULLS)
2424 {
2425 if (!pszDest)
2426 {
2427 if ((cchDest==0) && (cbDest==0))
2428 cchDestLength = 0;
2429 else
2430 Status = STATUS_INVALID_PARAMETER;
2431 }
2432 else
2433 {
2434 Status = RtlStringLengthWorkerW(pszDest,cchDest,&cchDestLength);
2435 if (NT_SUCCESS(Status))
2436 {
2437 pszDestEnd = pszDest + cchDestLength;
2438 cchRemaining = cchDest - cchDestLength;
2439 }
2440 }
2441 if (!pszSrc)
2442 pszSrc = L"";
2443 }
2444 else
2445 {
2446 Status = RtlStringLengthWorkerW(pszDest,cchDest,&cchDestLength);
2447 if (NT_SUCCESS(Status))
2448 {
2449 pszDestEnd = pszDest + cchDestLength;
2450 cchRemaining = cchDest - cchDestLength;
2451 }
2452 }
2453 if (NT_SUCCESS(Status))
2454 {
2455 if (cchDest==0)
2456 {
2457 if ((cchToAppend!=0) && (*pszSrc!=L'\0'))
2458 {
2459 if (!pszDest)
2460 Status = STATUS_INVALID_PARAMETER;
2461 else
2462 Status = STATUS_BUFFER_OVERFLOW;
2463 }
2464 }
2465 else
2466 Status = RtlStringCopyNExWorkerW(pszDestEnd,cchRemaining,(cchRemaining*sizeof(wchar_t)) + (cbDest % sizeof(wchar_t)),pszSrc,cchToAppend,&pszDestEnd,&cchRemaining,dwFlags & (~(STRSAFE_FILL_ON_FAILURE | STRSAFE_NULL_ON_FAILURE)));
2467 }
2468 }
2469 if (!NT_SUCCESS(Status))
2470 {
2471 if (pszDest)
2472 {
2473 if (dwFlags & STRSAFE_FILL_ON_FAILURE)
2474 {
2475 memset(pszDest,STRSAFE_GET_FILL_PATTERN(dwFlags),cbDest);
2476 if (STRSAFE_GET_FILL_PATTERN(dwFlags)==0)
2477 {
2478 pszDestEnd = pszDest;
2479 cchRemaining = cchDest;
2480 }
2481 else
2482 if (cchDest > 0)
2483 {
2484 pszDestEnd = pszDest + cchDest - 1;
2485 cchRemaining = 1;
2486 *pszDestEnd = L'\0';
2487 }
2488 }
2489 if (dwFlags & (STRSAFE_NULL_ON_FAILURE))
2490 {
2491 if (cchDest > 0)
2492 {
2493 pszDestEnd = pszDest;
2494 cchRemaining = cchDest;
2495 *pszDestEnd = L'\0';
2496 }
2497 }
2498 }
2499 }
2500 if (NT_SUCCESS(Status) || (Status==STATUS_BUFFER_OVERFLOW))
2501 {
2502 if (ppszDestEnd)
2503 *ppszDestEnd = pszDestEnd;
2504 if (pcchRemaining)
2505 *pcchRemaining = cchRemaining;
2506 }
2507 return Status;
2508 }
2509
2510 NTSTRSAFEAPI RtlStringVPrintfWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszFormat,va_list argList)
2511 {
2512 NTSTATUS Status = STATUS_SUCCESS;
2513 if (cchDest==0)
2514 Status = STATUS_INVALID_PARAMETER;
2515 else
2516 {
2517 int iRet;
2518 size_t cchMax;
2519 cchMax = cchDest - 1;
2520 iRet = _vsnprintf(pszDest,cchMax,pszFormat,argList);
2521 if ((iRet < 0) || (((size_t)iRet) > cchMax))
2522 {
2523 pszDest += cchMax;
2524 *pszDest = '\0';
2525 Status = STATUS_BUFFER_OVERFLOW;
2526 }
2527 else
2528 if (((size_t)iRet)==cchMax)
2529 {
2530 pszDest += cchMax;
2531 *pszDest = '\0';
2532 }
2533 }
2534 return Status;
2535 }
2536
2537 NTSTRSAFEAPI RtlStringVPrintfWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszFormat,va_list argList)
2538 {
2539 NTSTATUS Status = STATUS_SUCCESS;
2540 if (cchDest==0)
2541 Status = STATUS_INVALID_PARAMETER;
2542 else
2543 {
2544 int iRet;
2545 size_t cchMax;
2546 cchMax = cchDest - 1;
2547 iRet = _vsnwprintf(pszDest,cchMax,pszFormat,argList);
2548 if ((iRet < 0) || (((size_t)iRet) > cchMax))
2549 {
2550 pszDest += cchMax;
2551 *pszDest = L'\0';
2552 Status = STATUS_BUFFER_OVERFLOW;
2553 }
2554 else
2555 if (((size_t)iRet)==cchMax)
2556 {
2557 pszDest += cchMax;
2558 *pszDest = L'\0';
2559 }
2560 }
2561 return Status;
2562 }
2563
2564 NTSTRSAFEAPI RtlStringVPrintfExWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCSTR pszFormat,va_list argList)
2565 {
2566 NTSTATUS Status = STATUS_SUCCESS;
2567 STRSAFE_LPSTR pszDestEnd = pszDest;
2568 size_t cchRemaining = 0;
2569 if (dwFlags & (~STRSAFE_VALID_FLAGS))
2570 Status = STATUS_INVALID_PARAMETER;
2571 else
2572 {
2573 if (dwFlags & STRSAFE_IGNORE_NULLS)
2574 {
2575 if (!pszDest)
2576 {
2577 if ((cchDest!=0) || (cbDest!=0))
2578 Status = STATUS_INVALID_PARAMETER;
2579 }
2580 if (!pszFormat)
2581 pszFormat = "";
2582 }
2583 if (NT_SUCCESS(Status))
2584 {
2585 if (cchDest==0)
2586 {
2587 pszDestEnd = pszDest;
2588 cchRemaining = 0;
2589 if (*pszFormat!='\0')
2590 {
2591 if (!pszDest)
2592 Status = STATUS_INVALID_PARAMETER;
2593 else
2594 Status = STATUS_BUFFER_OVERFLOW;
2595 }
2596 }
2597 else
2598 {
2599 int iRet;
2600 size_t cchMax;
2601 cchMax = cchDest - 1;
2602 iRet = _vsnprintf(pszDest,cchMax,pszFormat,argList);
2603 if ((iRet < 0) || (((size_t)iRet) > cchMax))
2604 {
2605 pszDestEnd = pszDest + cchMax;
2606 cchRemaining = 1;
2607 *pszDestEnd = '\0';
2608 Status = STATUS_BUFFER_OVERFLOW;
2609 }
2610 else
2611 if (((size_t)iRet)==cchMax)
2612 {
2613 pszDestEnd = pszDest + cchMax;
2614 cchRemaining = 1;
2615 *pszDestEnd = '\0';
2616 }
2617 else
2618 if (((size_t)iRet) < cchMax)
2619 {
2620 pszDestEnd = pszDest + iRet;
2621 cchRemaining = cchDest - iRet;
2622 if (dwFlags & STRSAFE_FILL_BEHIND_NULL)
2623 {
2624 memset(pszDestEnd + 1,STRSAFE_GET_FILL_PATTERN(dwFlags),((cchRemaining - 1)*sizeof(char)) + (cbDest % sizeof(char)));
2625 }
2626 }
2627 }
2628 }
2629 }
2630 if (!NT_SUCCESS(Status))
2631 {
2632 if (pszDest)
2633 {
2634 if (dwFlags & STRSAFE_FILL_ON_FAILURE)
2635 {
2636 memset(pszDest,STRSAFE_GET_FILL_PATTERN(dwFlags),cbDest);
2637 if (STRSAFE_GET_FILL_PATTERN(dwFlags)==0)
2638 {
2639 pszDestEnd = pszDest;
2640 cchRemaining = cchDest;
2641 }
2642 else
2643 if (cchDest > 0)
2644 {
2645 pszDestEnd = pszDest + cchDest - 1;
2646 cchRemaining = 1;
2647 *pszDestEnd = '\0';
2648 }
2649 }
2650 if (dwFlags & (STRSAFE_NULL_ON_FAILURE | STRSAFE_NO_TRUNCATION))
2651 {
2652 if (cchDest > 0)
2653 {
2654 pszDestEnd = pszDest;
2655 cchRemaining = cchDest;
2656 *pszDestEnd = '\0';
2657 }
2658 }
2659 }
2660 }
2661 if (NT_SUCCESS(Status) || (Status==STATUS_BUFFER_OVERFLOW))
2662 {
2663 if (ppszDestEnd)
2664 *ppszDestEnd = pszDestEnd;
2665 if (pcchRemaining)
2666 *pcchRemaining = cchRemaining;
2667 }
2668 return Status;
2669 }
2670
2671 NTSTRSAFEAPI RtlStringVPrintfExWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCWSTR pszFormat,va_list argList)
2672 {
2673 NTSTATUS Status = STATUS_SUCCESS;
2674 STRSAFE_LPWSTR pszDestEnd = pszDest;
2675 size_t cchRemaining = 0;
2676 if (dwFlags & (~STRSAFE_VALID_FLAGS))
2677 Status = STATUS_INVALID_PARAMETER;
2678 else
2679 {
2680 if (dwFlags & STRSAFE_IGNORE_NULLS)
2681 {
2682 if (!pszDest)
2683 {
2684 if ((cchDest!=0) || (cbDest!=0))
2685 Status = STATUS_INVALID_PARAMETER;
2686 }
2687 if (!pszFormat)
2688 pszFormat = L"";
2689 }
2690 if (NT_SUCCESS(Status))
2691 {
2692 if (cchDest==0)
2693 {
2694 pszDestEnd = pszDest;
2695 cchRemaining = 0;
2696 if (*pszFormat!=L'\0')
2697 {
2698 if (!pszDest)
2699 Status = STATUS_INVALID_PARAMETER;
2700 else
2701 Status = STATUS_BUFFER_OVERFLOW;
2702 }
2703 }
2704 else
2705 {
2706 int iRet;
2707 size_t cchMax;
2708 cchMax = cchDest - 1;
2709 iRet = _vsnwprintf(pszDest,cchMax,pszFormat,argList);
2710 if ((iRet < 0) || (((size_t)iRet) > cchMax))
2711 {
2712 pszDestEnd = pszDest + cchMax;
2713 cchRemaining = 1;
2714 *pszDestEnd = L'\0';
2715 Status = STATUS_BUFFER_OVERFLOW;
2716 }
2717 else
2718 if (((size_t)iRet)==cchMax)
2719 {
2720 pszDestEnd = pszDest + cchMax;
2721 cchRemaining = 1;
2722 *pszDestEnd = L'\0';
2723 }
2724 else
2725 if (((size_t)iRet) < cchMax)
2726 {
2727 pszDestEnd = pszDest + iRet;
2728 cchRemaining = cchDest - iRet;
2729 if (dwFlags & STRSAFE_FILL_BEHIND_NULL)
2730 {
2731 memset(pszDestEnd + 1,STRSAFE_GET_FILL_PATTERN(dwFlags),((cchRemaining - 1)*sizeof(wchar_t)) + (cbDest % sizeof(wchar_t)));
2732 }
2733 }
2734 }
2735 }
2736 }
2737 if (!NT_SUCCESS(Status))
2738 {
2739 if (pszDest)
2740 {
2741 if (dwFlags & STRSAFE_FILL_ON_FAILURE)
2742 {
2743 memset(pszDest,STRSAFE_GET_FILL_PATTERN(dwFlags),cbDest);
2744 if (STRSAFE_GET_FILL_PATTERN(dwFlags)==0)
2745 {
2746 pszDestEnd = pszDest;
2747 cchRemaining = cchDest;
2748 }
2749 else
2750 if (cchDest > 0)
2751 {
2752 pszDestEnd = pszDest + cchDest - 1;
2753 cchRemaining = 1;
2754 *pszDestEnd = L'\0';
2755 }
2756 }
2757 if (dwFlags & (STRSAFE_NULL_ON_FAILURE | STRSAFE_NO_TRUNCATION))
2758 {
2759 if (cchDest > 0)
2760 {
2761 pszDestEnd = pszDest;
2762 cchRemaining = cchDest;
2763 *pszDestEnd = L'\0';
2764 }
2765 }
2766 }
2767 }
2768 if (NT_SUCCESS(Status) || (Status==STATUS_BUFFER_OVERFLOW))
2769 {
2770 if (ppszDestEnd)
2771 *ppszDestEnd = pszDestEnd;
2772 if (pcchRemaining)
2773 *pcchRemaining = cchRemaining;
2774 }
2775 return Status;
2776 }
2777
2778 NTSTRSAFEAPI
2779 RtlStringLengthWorkerA(
2780 _In_reads_or_z_(cchMax) STRSAFE_LPCSTR psz,
2781 _In_ _In_range_(<=, NTSTRSAFE_MAX_CCH) size_t cchMax,
2782 _Out_opt_ _Deref_out_range_(<, cchMax) size_t *pcchLength)
2783 {
2784 NTSTATUS Status = STATUS_SUCCESS;
2785 size_t cchMaxPrev = cchMax;
2786 while(cchMax && (*psz!='\0'))
2787 {
2788 psz++;
2789 cchMax--;
2790 }
2791 if (cchMax==0)
2792 Status = STATUS_INVALID_PARAMETER;
2793 if (pcchLength)
2794 {
2795 if (NT_SUCCESS(Status))
2796 *pcchLength = cchMaxPrev - cchMax;
2797 else
2798 *pcchLength = 0;
2799 }
2800 return Status;
2801 }
2802
2803 NTSTRSAFEAPI
2804 RtlStringLengthWorkerW(
2805 _In_reads_or_z_(cchMax) STRSAFE_LPCWSTR psz,
2806 _In_ _In_range_(<=, NTSTRSAFE_MAX_CCH) size_t cchMax,
2807 _Out_opt_ _Deref_out_range_(<, cchMax) size_t *pcchLength)
2808 {
2809 NTSTATUS Status = STATUS_SUCCESS;
2810 size_t cchMaxPrev = cchMax;
2811 while(cchMax && (*psz!=L'\0'))
2812 {
2813 psz++;
2814 cchMax--;
2815 }
2816 if (cchMax==0)
2817 Status = STATUS_INVALID_PARAMETER;
2818 if (pcchLength)
2819 {
2820 if (NT_SUCCESS(Status))
2821 *pcchLength = cchMaxPrev - cchMax;
2822 else
2823 *pcchLength = 0;
2824 }
2825 return Status;
2826 }
2827
2828 #define RtlStringCopyWorkerA RtlStringCopyWorkerA_instead_use_StringCchCopyA_or_StringCchCopyExA;
2829 #define RtlStringCopyWorkerW RtlStringCopyWorkerW_instead_use_StringCchCopyW_or_StringCchCopyExW;
2830 #define RtlStringCopyExWorkerA RtlStringCopyExWorkerA_instead_use_StringCchCopyA_or_StringCchCopyExA;
2831 #define RtlStringCopyExWorkerW RtlStringCopyExWorkerW_instead_use_StringCchCopyW_or_StringCchCopyExW;
2832 #define RtlStringCatWorkerA RtlStringCatWorkerA_instead_use_StringCchCatA_or_StringCchCatExA;
2833 #define RtlStringCatWorkerW RtlStringCatWorkerW_instead_use_StringCchCatW_or_StringCchCatExW;
2834 #define RtlStringCatExWorkerA RtlStringCatExWorkerA_instead_use_StringCchCatA_or_StringCchCatExA;
2835 #define RtlStringCatExWorkerW RtlStringCatExWorkerW_instead_use_StringCchCatW_or_StringCchCatExW;
2836 #define RtlStringCatNWorkerA RtlStringCatNWorkerA_instead_use_StringCchCatNA_or_StrincCbCatNA;
2837 #define RtlStringCatNWorkerW RtlStringCatNWorkerW_instead_use_StringCchCatNW_or_StringCbCatNW;
2838 #define RtlStringCatNExWorkerA RtlStringCatNExWorkerA_instead_use_StringCchCatNExA_or_StringCbCatNExA;
2839 #define RtlStringCatNExWorkerW RtlStringCatNExWorkerW_instead_use_StringCchCatNExW_or_StringCbCatNExW;
2840 #define RtlStringVPrintfWorkerA RtlStringVPrintfWorkerA_instead_use_StringCchVPrintfA_or_StringCchVPrintfExA;
2841 #define RtlStringVPrintfWorkerW RtlStringVPrintfWorkerW_instead_use_StringCchVPrintfW_or_StringCchVPrintfExW;
2842 #define RtlStringVPrintfExWorkerA RtlStringVPrintfExWorkerA_instead_use_StringCchVPrintfA_or_StringCchVPrintfExA;
2843 #define RtlStringVPrintfExWorkerW RtlStringVPrintfExWorkerW_instead_use_StringCchVPrintfW_or_StringCchVPrintfExW;
2844 #define RtlStringLengthWorkerA RtlStringLengthWorkerA_instead_use_StringCchLengthA_or_StringCbLengthA;
2845 #define RtlStringLengthWorkerW RtlStringLengthWorkerW_instead_use_StringCchLengthW_or_StringCbLengthW;
2846
2847 #ifdef _MSC_VER
2848 #pragma warning(pop)
2849 #endif /* _MSC_VER */
2850
2851 #endif /* _NTSTRSAFE_H_INCLUDED_ */