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