[CMAKE]
[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 #ifndef C_ASSERT
14 #ifdef _MSC_VER
15 # define C_ASSERT(e) typedef char __C_ASSERT__[(e)?1:-1]
16 #else
17 # define C_ASSERT(e) extern void __C_ASSERT__(int [(e)?1:-1])
18 #endif
19 #endif /* C_ASSERT */
20
21 #ifdef __cplusplus
22 #define _STRSAFE_EXTERN_C extern "C"
23 #else
24 #define _STRSAFE_EXTERN_C extern
25 #endif
26
27 #define NTSTRSAFEAPI static __inline NTSTATUS NTAPI
28 #define NTSTRSAFE_INLINE_API static __inline NTSTATUS NTAPI
29
30 #ifndef NTSTRSAFE_MAX_CCH
31 #define NTSTRSAFE_MAX_CCH 2147483647
32 #endif
33
34 #ifndef _STRSAFE_H_INCLUDED_
35 #define STRSAFE_IGNORE_NULLS 0x00000100
36 #define STRSAFE_FILL_BEHIND_NULL 0x00000200
37 #define STRSAFE_FILL_ON_FAILURE 0x00000400
38 #define STRSAFE_NULL_ON_FAILURE 0x00000800
39 #define STRSAFE_NO_TRUNCATION 0x00001000
40 #define STRSAFE_IGNORE_NULL_UNICODE_STRINGS 0x00010000
41 #define STRSAFE_UNICODE_STRING_DEST_NULL_TERMINATED 0x00020000
42
43 #define STRSAFE_VALID_FLAGS (0x000000FF | STRSAFE_IGNORE_NULLS | STRSAFE_FILL_BEHIND_NULL | STRSAFE_FILL_ON_FAILURE | STRSAFE_NULL_ON_FAILURE | STRSAFE_NO_TRUNCATION)
44 #define STRSAFE_UNICODE_STRING_VALID_FLAGS (STRSAFE_VALID_FLAGS | STRSAFE_IGNORE_NULL_UNICODE_STRINGS | STRSAFE_UNICODE_STRING_DEST_NULL_TERMINATED)
45
46 #define STRSAFE_FILL_BYTE(x) ((STRSAFE_DWORD)(((x) & 0x000000FF) | STRSAFE_FILL_BEHIND_NULL))
47 #define STRSAFE_FAILURE_BYTE(x) ((STRSAFE_DWORD)(((x) & 0x000000FF) | STRSAFE_FILL_ON_FAILURE))
48
49 #define STRSAFE_GET_FILL_PATTERN(dwFlags) ((int)((dwFlags) & 0x000000FF))
50 #endif
51
52 typedef char *STRSAFE_LPSTR;
53 typedef const char *STRSAFE_LPCSTR;
54 typedef wchar_t *STRSAFE_LPWSTR;
55 typedef const wchar_t *STRSAFE_LPCWSTR;
56
57 typedef ULONG STRSAFE_DWORD;
58
59 NTSTRSAFEAPI RtlStringCopyWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc);
60 NTSTRSAFEAPI RtlStringCopyWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc);
61 NTSTRSAFEAPI RtlStringCopyExWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags);
62 NTSTRSAFEAPI RtlStringCopyExWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags);
63 NTSTRSAFEAPI RtlStringCopyNWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc,size_t cchToCopy);
64 NTSTRSAFEAPI RtlStringCopyNWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc,size_t cchToCopy);
65 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);
66 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);
67 NTSTRSAFEAPI RtlStringCatWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc);
68 NTSTRSAFEAPI RtlStringCatWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc);
69 NTSTRSAFEAPI RtlStringCatExWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags);
70 NTSTRSAFEAPI RtlStringCatExWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags);
71 NTSTRSAFEAPI RtlStringCatNWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc,size_t cchToAppend);
72 NTSTRSAFEAPI RtlStringCatNWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc,size_t cchToAppend);
73 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);
74 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);
75 NTSTRSAFEAPI RtlStringVPrintfWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszFormat,va_list argList);
76 NTSTRSAFEAPI RtlStringVPrintfWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszFormat,va_list argList);
77 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);
78 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);
79 NTSTRSAFEAPI RtlStringLengthWorkerA(STRSAFE_LPCSTR psz,size_t cchMax,size_t *pcchLength);
80 NTSTRSAFEAPI RtlStringLengthWorkerW(STRSAFE_LPCWSTR psz,size_t cchMax,size_t *pcchLength);
81
82 NTSTRSAFEAPI RtlStringCchCopyA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc);
83 NTSTRSAFEAPI RtlStringCchCopyW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc);
84
85
86 NTSTRSAFEAPI RtlStringCchCopyA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc)
87 {
88 return (cchDest > NTSTRSAFE_MAX_CCH ? STATUS_INVALID_PARAMETER : RtlStringCopyWorkerA(pszDest,cchDest,pszSrc));
89 }
90
91 NTSTRSAFEAPI RtlStringCchCopyW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc)
92 {
93 if (cchDest > NTSTRSAFE_MAX_CCH)
94 return STATUS_INVALID_PARAMETER;
95 return RtlStringCopyWorkerW(pszDest,cchDest,pszSrc);
96 }
97
98
99 NTSTRSAFEAPI RtlStringCbCopyA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszSrc);
100 NTSTRSAFEAPI RtlStringCbCopyW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc);
101
102
103 NTSTRSAFEAPI RtlStringCbCopyA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszSrc)
104 {
105 if (cbDest > NTSTRSAFE_MAX_CCH)
106 return STATUS_INVALID_PARAMETER;
107 return RtlStringCopyWorkerA(pszDest,cbDest,pszSrc);
108 }
109
110 NTSTRSAFEAPI RtlStringCbCopyW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc)
111 {
112 size_t cchDest = cbDest / sizeof(wchar_t);
113 if (cchDest > NTSTRSAFE_MAX_CCH)
114 return STATUS_INVALID_PARAMETER;
115 return RtlStringCopyWorkerW(pszDest,cchDest,pszSrc);
116 }
117
118
119 NTSTRSAFEAPI RtlStringCchCopyExA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags);
120 NTSTRSAFEAPI RtlStringCchCopyExW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags);
121
122
123 NTSTRSAFEAPI RtlStringCchCopyExA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags)
124 {
125 if (cchDest > NTSTRSAFE_MAX_CCH)
126 return STATUS_INVALID_PARAMETER;
127 return RtlStringCopyExWorkerA(pszDest,cchDest,cchDest,pszSrc,ppszDestEnd,pcchRemaining,dwFlags);
128 }
129
130 NTSTRSAFEAPI RtlStringCchCopyExW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags)
131 {
132 size_t cbDest;
133 if (cchDest > NTSTRSAFE_MAX_CCH)
134 return STATUS_INVALID_PARAMETER;
135 cbDest = cchDest * sizeof(wchar_t);
136 return RtlStringCopyExWorkerW(pszDest,cchDest,cbDest,pszSrc,ppszDestEnd,pcchRemaining,dwFlags);
137 }
138
139
140 NTSTRSAFEAPI RtlStringCbCopyExA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,STRSAFE_LPSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags);
141 NTSTRSAFEAPI RtlStringCbCopyExW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags);
142
143
144 NTSTRSAFEAPI RtlStringCbCopyExA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,STRSAFE_LPSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags)
145 {
146 NTSTATUS Status;
147 size_t cchRemaining = 0;
148 if (cbDest > NTSTRSAFE_MAX_CCH)
149 return STATUS_INVALID_PARAMETER;
150 Status = RtlStringCopyExWorkerA(pszDest,cbDest,cbDest,pszSrc,ppszDestEnd,&cchRemaining,dwFlags);
151 if (NT_SUCCESS(Status) || Status == STATUS_BUFFER_OVERFLOW)
152 {
153 if (pcbRemaining)
154 *pcbRemaining = (cchRemaining*sizeof(char)) + (cbDest % sizeof(char));
155 }
156 return Status;
157 }
158
159 NTSTRSAFEAPI RtlStringCbCopyExW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags)
160 {
161 NTSTATUS Status;
162 size_t cchDest = cbDest / sizeof(wchar_t);
163 size_t cchRemaining = 0;
164
165 if (cchDest > NTSTRSAFE_MAX_CCH)
166 return STATUS_INVALID_PARAMETER;
167 Status = RtlStringCopyExWorkerW(pszDest,cchDest,cbDest,pszSrc,ppszDestEnd,&cchRemaining,dwFlags);
168 if (NT_SUCCESS(Status) || (Status==STATUS_BUFFER_OVERFLOW))
169 {
170 if (pcbRemaining)
171 *pcbRemaining = (cchRemaining*sizeof(wchar_t)) + (cbDest % sizeof(wchar_t));
172 }
173 return Status;
174 }
175
176
177 NTSTRSAFEAPI RtlStringCchCopyNA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc,size_t cchToCopy);
178 NTSTRSAFEAPI RtlStringCchCopyNW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc,size_t cchToCopy);
179
180
181 NTSTRSAFEAPI RtlStringCchCopyNA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc,size_t cchToCopy)
182 {
183 if (cchDest > NTSTRSAFE_MAX_CCH || cchToCopy > NTSTRSAFE_MAX_CCH)
184 return STATUS_INVALID_PARAMETER;
185 return RtlStringCopyNWorkerA(pszDest,cchDest,pszSrc,cchToCopy);
186 }
187
188 NTSTRSAFEAPI RtlStringCchCopyNW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc,size_t cchToCopy)
189 {
190 if (cchDest > NTSTRSAFE_MAX_CCH || cchToCopy > NTSTRSAFE_MAX_CCH)
191 return STATUS_INVALID_PARAMETER;
192 return RtlStringCopyNWorkerW(pszDest,cchDest,pszSrc,cchToCopy);
193 }
194
195
196 NTSTRSAFEAPI RtlStringCbCopyNA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,size_t cbToCopy);
197 NTSTRSAFEAPI RtlStringCbCopyNW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,size_t cbToCopy);
198
199
200 NTSTRSAFEAPI RtlStringCbCopyNA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,size_t cbToCopy)
201 {
202 if (cbDest > NTSTRSAFE_MAX_CCH || cbToCopy > NTSTRSAFE_MAX_CCH)
203 return STATUS_INVALID_PARAMETER;
204 return RtlStringCopyNWorkerA(pszDest,cbDest,pszSrc,cbToCopy);
205 }
206
207 NTSTRSAFEAPI RtlStringCbCopyNW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,size_t cbToCopy)
208 {
209 size_t cchDest = cbDest / sizeof(wchar_t);
210 size_t cchToCopy = cbToCopy / sizeof(wchar_t);
211 if (cchDest > NTSTRSAFE_MAX_CCH || cchToCopy > NTSTRSAFE_MAX_CCH)
212 return STATUS_INVALID_PARAMETER;
213 return RtlStringCopyNWorkerW(pszDest,cchDest,pszSrc,cchToCopy);
214 }
215
216
217 NTSTRSAFEAPI RtlStringCchCopyNExA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc,size_t cchToCopy,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags);
218 NTSTRSAFEAPI RtlStringCchCopyNExW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc,size_t cchToCopy,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags);
219
220
221 NTSTRSAFEAPI RtlStringCchCopyNExA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc,size_t cchToCopy,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags)
222 {
223 if (cchDest > NTSTRSAFE_MAX_CCH)
224 return STATUS_INVALID_PARAMETER;
225 return RtlStringCopyNExWorkerA(pszDest,cchDest,cchDest,pszSrc,cchToCopy,ppszDestEnd,pcchRemaining,dwFlags);
226 }
227
228 NTSTRSAFEAPI RtlStringCchCopyNExW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc,size_t cchToCopy,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags)
229 {
230 if (cchDest > NTSTRSAFE_MAX_CCH)
231 return STATUS_INVALID_PARAMETER;
232 return RtlStringCopyNExWorkerW(pszDest,cchDest,cchDest * sizeof(wchar_t),pszSrc,cchToCopy,ppszDestEnd,pcchRemaining,dwFlags);
233 }
234
235
236 NTSTRSAFEAPI RtlStringCbCopyNExA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,size_t cbToCopy,STRSAFE_LPSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags);
237 NTSTRSAFEAPI RtlStringCbCopyNExW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,size_t cbToCopy,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags);
238
239
240 NTSTRSAFEAPI RtlStringCbCopyNExA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,size_t cbToCopy,STRSAFE_LPSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags)
241 {
242 NTSTATUS Status;
243 size_t cchRemaining = 0;
244 if (cbDest > NTSTRSAFE_MAX_CCH)
245 Status = STATUS_INVALID_PARAMETER;
246 else
247 Status = RtlStringCopyNExWorkerA(pszDest,cbDest,cbDest,pszSrc,cbToCopy,ppszDestEnd,&cchRemaining,dwFlags);
248 if ((NT_SUCCESS(Status) || Status == STATUS_BUFFER_OVERFLOW) && pcbRemaining)
249 *pcbRemaining = cchRemaining;
250 return Status;
251 }
252
253 NTSTRSAFEAPI RtlStringCbCopyNExW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,size_t cbToCopy,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags)
254 {
255 NTSTATUS Status;
256 size_t cchDest;
257 size_t cchToCopy;
258 size_t cchRemaining = 0;
259 cchDest = cbDest / sizeof(wchar_t);
260 cchToCopy = cbToCopy / sizeof(wchar_t);
261 if (cchDest > NTSTRSAFE_MAX_CCH)
262 Status = STATUS_INVALID_PARAMETER;
263 else
264 Status = RtlStringCopyNExWorkerW(pszDest,cchDest,cbDest,pszSrc,cchToCopy,ppszDestEnd,&cchRemaining,dwFlags);
265 if ((NT_SUCCESS(Status) || Status == STATUS_BUFFER_OVERFLOW) && pcbRemaining)
266 *pcbRemaining = (cchRemaining*sizeof(wchar_t)) + (cbDest % sizeof(wchar_t));
267 return Status;
268 }
269
270
271 NTSTRSAFEAPI RtlStringCchCatA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc);
272 NTSTRSAFEAPI RtlStringCchCatW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc);
273
274
275 NTSTRSAFEAPI RtlStringCchCatA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc)
276 {
277 if (cchDest > NTSTRSAFE_MAX_CCH)
278 return STATUS_INVALID_PARAMETER;
279 return RtlStringCatWorkerA(pszDest,cchDest,pszSrc);
280 }
281
282 NTSTRSAFEAPI RtlStringCchCatW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc)
283 {
284 if (cchDest > NTSTRSAFE_MAX_CCH)
285 return STATUS_INVALID_PARAMETER;
286 return RtlStringCatWorkerW(pszDest,cchDest,pszSrc);
287 }
288
289
290 NTSTRSAFEAPI RtlStringCbCatA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszSrc);
291 NTSTRSAFEAPI RtlStringCbCatW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc);
292
293
294 NTSTRSAFEAPI RtlStringCbCatA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszSrc)
295 {
296 if (cbDest > NTSTRSAFE_MAX_CCH)
297 return STATUS_INVALID_PARAMETER;
298 return RtlStringCatWorkerA(pszDest,cbDest,pszSrc);
299 }
300
301 NTSTRSAFEAPI RtlStringCbCatW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc)
302 {
303 size_t cchDest = cbDest / sizeof(wchar_t);
304 if (cchDest > NTSTRSAFE_MAX_CCH)
305 return STATUS_INVALID_PARAMETER;
306 return RtlStringCatWorkerW(pszDest,cchDest,pszSrc);
307 }
308
309
310 NTSTRSAFEAPI RtlStringCchCatExA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags);
311 NTSTRSAFEAPI RtlStringCchCatExW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags);
312
313
314 NTSTRSAFEAPI RtlStringCchCatExA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags)
315 {
316 if (cchDest > NTSTRSAFE_MAX_CCH)
317 return STATUS_INVALID_PARAMETER;
318 return RtlStringCatExWorkerA(pszDest,cchDest,cchDest,pszSrc,ppszDestEnd,pcchRemaining,dwFlags);
319 }
320
321 NTSTRSAFEAPI RtlStringCchCatExW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags)
322 {
323 size_t cbDest = cchDest*sizeof(wchar_t);
324 if (cchDest > NTSTRSAFE_MAX_CCH)
325 return STATUS_INVALID_PARAMETER;
326 return RtlStringCatExWorkerW(pszDest,cchDest,cbDest,pszSrc,ppszDestEnd,pcchRemaining,dwFlags);
327 }
328
329
330 NTSTRSAFEAPI RtlStringCbCatExA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,STRSAFE_LPSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags);
331 NTSTRSAFEAPI RtlStringCbCatExW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags);
332
333
334 NTSTRSAFEAPI RtlStringCbCatExA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,STRSAFE_LPSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags)
335 {
336 NTSTATUS Status;
337 size_t cchRemaining = 0;
338 if (cbDest > NTSTRSAFE_MAX_CCH)
339 Status = STATUS_INVALID_PARAMETER;
340 else
341 Status = RtlStringCatExWorkerA(pszDest,cbDest,cbDest,pszSrc,ppszDestEnd,&cchRemaining,dwFlags);
342 if ((NT_SUCCESS(Status) || Status == STATUS_BUFFER_OVERFLOW) && pcbRemaining)
343 *pcbRemaining = (cchRemaining*sizeof(char)) + (cbDest % sizeof(char));
344 return Status;
345 }
346
347 NTSTRSAFEAPI RtlStringCbCatExW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags)
348 {
349 NTSTATUS Status;
350 size_t cchDest = cbDest / sizeof(wchar_t);
351 size_t cchRemaining = 0;
352
353 if (cchDest > NTSTRSAFE_MAX_CCH)
354 Status = STATUS_INVALID_PARAMETER;
355 else
356 Status = RtlStringCatExWorkerW(pszDest,cchDest,cbDest,pszSrc,ppszDestEnd,&cchRemaining,dwFlags);
357 if ((NT_SUCCESS(Status) || Status == STATUS_BUFFER_OVERFLOW) && pcbRemaining)
358 *pcbRemaining = (cchRemaining*sizeof(wchar_t)) + (cbDest % sizeof(wchar_t));
359 return Status;
360 }
361
362
363 NTSTRSAFEAPI RtlStringCchCatNA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc,size_t cchToAppend);
364 NTSTRSAFEAPI RtlStringCchCatNW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc,size_t cchToAppend);
365
366
367 NTSTRSAFEAPI RtlStringCchCatNA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc,size_t cchToAppend)
368 {
369 if (cchDest > NTSTRSAFE_MAX_CCH)
370 return STATUS_INVALID_PARAMETER;
371 return RtlStringCatNWorkerA(pszDest,cchDest,pszSrc,cchToAppend);
372 }
373
374 NTSTRSAFEAPI RtlStringCchCatNW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc,size_t cchToAppend)
375 {
376 if (cchDest > NTSTRSAFE_MAX_CCH)
377 return STATUS_INVALID_PARAMETER;
378 return RtlStringCatNWorkerW(pszDest,cchDest,pszSrc,cchToAppend);
379 }
380
381
382 NTSTRSAFEAPI RtlStringCbCatNA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,size_t cbToAppend);
383 NTSTRSAFEAPI RtlStringCbCatNW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,size_t cbToAppend);
384
385
386 NTSTRSAFEAPI RtlStringCbCatNA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,size_t cbToAppend)
387 {
388 if (cbDest > NTSTRSAFE_MAX_CCH)
389 return STATUS_INVALID_PARAMETER;
390 return RtlStringCatNWorkerA(pszDest,cbDest,pszSrc,cbToAppend);
391 }
392
393 NTSTRSAFEAPI RtlStringCbCatNW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,size_t cbToAppend)
394 {
395 size_t cchDest = cbDest / sizeof(wchar_t);
396 size_t cchToAppend = cbToAppend / sizeof(wchar_t);
397
398 if (cchDest > NTSTRSAFE_MAX_CCH)
399 return STATUS_INVALID_PARAMETER;
400 return RtlStringCatNWorkerW(pszDest,cchDest,pszSrc,cchToAppend);
401 }
402
403
404 NTSTRSAFEAPI RtlStringCchCatNExA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc,size_t cchToAppend,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags);
405 NTSTRSAFEAPI RtlStringCchCatNExW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc,size_t cchToAppend,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags);
406
407
408 NTSTRSAFEAPI RtlStringCchCatNExA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc,size_t cchToAppend,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags)
409 {
410 if (cchDest > NTSTRSAFE_MAX_CCH)
411 return STATUS_INVALID_PARAMETER;
412 return RtlStringCatNExWorkerA(pszDest,cchDest,cchDest,pszSrc,cchToAppend,ppszDestEnd,pcchRemaining,dwFlags);
413 }
414
415 NTSTRSAFEAPI RtlStringCchCatNExW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc,size_t cchToAppend,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags)
416 {
417 if (cchDest > NTSTRSAFE_MAX_CCH)
418 return STATUS_INVALID_PARAMETER;
419 return RtlStringCatNExWorkerW(pszDest,cchDest,(cchDest*sizeof(wchar_t)),pszSrc,cchToAppend,ppszDestEnd,pcchRemaining,dwFlags);
420 }
421
422
423 NTSTRSAFEAPI RtlStringCbCatNExA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,size_t cbToAppend,STRSAFE_LPSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags);
424 NTSTRSAFEAPI RtlStringCbCatNExW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,size_t cbToAppend,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags);
425
426
427 NTSTRSAFEAPI RtlStringCbCatNExA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,size_t cbToAppend,STRSAFE_LPSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags)
428 {
429 NTSTATUS Status;
430 size_t cchRemaining = 0;
431 if (cbDest > NTSTRSAFE_MAX_CCH)
432 Status = STATUS_INVALID_PARAMETER;
433 else
434 Status = RtlStringCatNExWorkerA(pszDest,cbDest,cbDest,pszSrc,cbToAppend,ppszDestEnd,&cchRemaining,dwFlags);
435 if ((NT_SUCCESS(Status) || Status == STATUS_BUFFER_OVERFLOW) && pcbRemaining)
436 *pcbRemaining = (cchRemaining*sizeof(char)) + (cbDest % sizeof(char));
437 return Status;
438 }
439
440 NTSTRSAFEAPI RtlStringCbCatNExW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,size_t cbToAppend,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags)
441 {
442 NTSTATUS Status;
443 size_t cchDest = cbDest / sizeof(wchar_t);
444 size_t cchToAppend = cbToAppend / sizeof(wchar_t);
445 size_t cchRemaining = 0;
446 if (cchDest > NTSTRSAFE_MAX_CCH)
447 Status = STATUS_INVALID_PARAMETER;
448 else
449 Status = RtlStringCatNExWorkerW(pszDest,cchDest,cbDest,pszSrc,cchToAppend,ppszDestEnd,&cchRemaining,dwFlags);
450 if ((NT_SUCCESS(Status) || Status == STATUS_BUFFER_OVERFLOW) && pcbRemaining)
451 *pcbRemaining = (cchRemaining*sizeof(wchar_t)) + (cbDest % sizeof(wchar_t));
452 return Status;
453 }
454
455
456 NTSTRSAFEAPI RtlStringCchVPrintfA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszFormat,va_list argList);
457 NTSTRSAFEAPI RtlStringCchVPrintfW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszFormat,va_list argList);
458
459
460 NTSTRSAFEAPI RtlStringCchVPrintfA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszFormat,va_list argList)
461 {
462 if (cchDest > NTSTRSAFE_MAX_CCH)
463 return STATUS_INVALID_PARAMETER;
464 return RtlStringVPrintfWorkerA(pszDest,cchDest,pszFormat,argList);
465 }
466
467 NTSTRSAFEAPI RtlStringCchVPrintfW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszFormat,va_list argList)
468 {
469 if (cchDest > NTSTRSAFE_MAX_CCH)
470 return STATUS_INVALID_PARAMETER;
471 return RtlStringVPrintfWorkerW(pszDest,cchDest,pszFormat,argList);
472 }
473
474
475 NTSTRSAFEAPI RtlStringCbVPrintfA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszFormat,va_list argList);
476 NTSTRSAFEAPI RtlStringCbVPrintfW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszFormat,va_list argList);
477
478
479 NTSTRSAFEAPI RtlStringCbVPrintfA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszFormat,va_list argList)
480 {
481 if (cbDest > NTSTRSAFE_MAX_CCH)
482 return STATUS_INVALID_PARAMETER;
483 return RtlStringVPrintfWorkerA(pszDest,cbDest,pszFormat,argList);
484 }
485
486 NTSTRSAFEAPI RtlStringCbVPrintfW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszFormat,va_list argList)
487 {
488 size_t cchDest = cbDest / sizeof(wchar_t);
489 if (cchDest > NTSTRSAFE_MAX_CCH)
490 return STATUS_INVALID_PARAMETER;
491 return RtlStringVPrintfWorkerW(pszDest,cchDest,pszFormat,argList);
492 }
493
494
495 NTSTRSAFEAPI RtlStringCchPrintfA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszFormat,...);
496 NTSTRSAFEAPI RtlStringCchPrintfW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszFormat,...);
497
498
499 NTSTRSAFEAPI RtlStringCchPrintfA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszFormat,...)
500 {
501 NTSTATUS Status;
502 va_list argList;
503 if (cchDest > NTSTRSAFE_MAX_CCH)
504 return STATUS_INVALID_PARAMETER;
505 va_start(argList,pszFormat);
506 Status = RtlStringVPrintfWorkerA(pszDest,cchDest,pszFormat,argList);
507 va_end(argList);
508 return Status;
509 }
510
511 NTSTRSAFEAPI RtlStringCchPrintfW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszFormat,...)
512 {
513 NTSTATUS Status;
514 va_list argList;
515 if (cchDest > NTSTRSAFE_MAX_CCH)
516 return STATUS_INVALID_PARAMETER;
517 va_start(argList,pszFormat);
518 Status = RtlStringVPrintfWorkerW(pszDest,cchDest,pszFormat,argList);
519 va_end(argList);
520 return Status;
521 }
522
523
524 NTSTRSAFEAPI RtlStringCbPrintfA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszFormat,...);
525 NTSTRSAFEAPI RtlStringCbPrintfW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszFormat,...);
526
527
528 NTSTRSAFEAPI RtlStringCbPrintfA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszFormat,...)
529 {
530 NTSTATUS Status;
531 va_list argList;
532 if (cbDest > NTSTRSAFE_MAX_CCH)
533 return STATUS_INVALID_PARAMETER;
534 va_start(argList,pszFormat);
535 Status = RtlStringVPrintfWorkerA(pszDest,cbDest,pszFormat,argList);
536 va_end(argList);
537 return Status;
538 }
539
540 NTSTRSAFEAPI RtlStringCbPrintfW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszFormat,...)
541 {
542 NTSTATUS Status;
543 va_list argList;
544 size_t cchDest = cbDest / sizeof(wchar_t);
545 if (cchDest > NTSTRSAFE_MAX_CCH)
546 return STATUS_INVALID_PARAMETER;
547 va_start(argList,pszFormat);
548 Status = RtlStringVPrintfWorkerW(pszDest,cchDest,pszFormat,argList);
549 va_end(argList);
550 return Status;
551 }
552
553
554 NTSTRSAFEAPI RtlStringCchPrintfExA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCSTR pszFormat,...);
555 NTSTRSAFEAPI RtlStringCchPrintfExW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCWSTR pszFormat,...);
556
557
558 NTSTRSAFEAPI RtlStringCchPrintfExA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCSTR pszFormat,...)
559 {
560 NTSTATUS Status;
561 va_list argList;
562 if (cchDest > NTSTRSAFE_MAX_CCH)
563 return STATUS_INVALID_PARAMETER;
564 va_start(argList,pszFormat);
565 Status = RtlStringVPrintfExWorkerA(pszDest,cchDest,cchDest,ppszDestEnd,pcchRemaining,dwFlags,pszFormat,argList);
566 va_end(argList);
567 return Status;
568 }
569
570 NTSTRSAFEAPI RtlStringCchPrintfExW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCWSTR pszFormat,...)
571 {
572 NTSTATUS Status;
573 size_t cbDest = cchDest * sizeof(wchar_t);
574 va_list argList;
575 if (cchDest > NTSTRSAFE_MAX_CCH)
576 return STATUS_INVALID_PARAMETER;
577 va_start(argList,pszFormat);
578 Status = RtlStringVPrintfExWorkerW(pszDest,cchDest,cbDest,ppszDestEnd,pcchRemaining,dwFlags,pszFormat,argList);
579 va_end(argList);
580 return Status;
581 }
582
583
584 NTSTRSAFEAPI RtlStringCbPrintfExA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCSTR pszFormat,...);
585 NTSTRSAFEAPI RtlStringCbPrintfExW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCWSTR pszFormat,...);
586
587
588 NTSTRSAFEAPI RtlStringCbPrintfExA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCSTR pszFormat,...)
589 {
590 NTSTATUS Status;
591 size_t cchDest;
592 size_t cchRemaining = 0;
593 cchDest = cbDest / sizeof(char);
594 if (cchDest > NTSTRSAFE_MAX_CCH)
595 Status = STATUS_INVALID_PARAMETER;
596 else
597 {
598 va_list argList;
599 va_start(argList,pszFormat);
600 Status = RtlStringVPrintfExWorkerA(pszDest,cchDest,cbDest,ppszDestEnd,&cchRemaining,dwFlags,pszFormat,argList);
601 va_end(argList);
602 }
603 if (NT_SUCCESS(Status) || (Status==STATUS_BUFFER_OVERFLOW))
604 {
605 if (pcbRemaining)
606 {
607 *pcbRemaining = (cchRemaining*sizeof(char)) + (cbDest % sizeof(char));
608 }
609 }
610 return Status;
611 }
612
613 NTSTRSAFEAPI RtlStringCbPrintfExW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCWSTR pszFormat,...)
614 {
615 NTSTATUS Status;
616 size_t cchDest;
617 size_t cchRemaining = 0;
618 cchDest = cbDest / sizeof(wchar_t);
619 if (cchDest > NTSTRSAFE_MAX_CCH)
620 Status = STATUS_INVALID_PARAMETER;
621 else
622 {
623 va_list argList;
624 va_start(argList,pszFormat);
625 Status = RtlStringVPrintfExWorkerW(pszDest,cchDest,cbDest,ppszDestEnd,&cchRemaining,dwFlags,pszFormat,argList);
626 va_end(argList);
627 }
628 if (NT_SUCCESS(Status) || (Status==STATUS_BUFFER_OVERFLOW))
629 {
630 if (pcbRemaining)
631 {
632 *pcbRemaining = (cchRemaining*sizeof(wchar_t)) + (cbDest % sizeof(wchar_t));
633 }
634 }
635 return Status;
636 }
637
638
639 NTSTRSAFEAPI RtlStringCchVPrintfExA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCSTR pszFormat,va_list argList);
640 NTSTRSAFEAPI RtlStringCchVPrintfExW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCWSTR pszFormat,va_list argList);
641
642
643 NTSTRSAFEAPI RtlStringCchVPrintfExA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCSTR pszFormat,va_list argList)
644 {
645 NTSTATUS Status;
646 if (cchDest > NTSTRSAFE_MAX_CCH)
647 Status = STATUS_INVALID_PARAMETER;
648 else
649 {
650 size_t cbDest;
651 cbDest = cchDest*sizeof(char);
652 Status = RtlStringVPrintfExWorkerA(pszDest,cchDest,cbDest,ppszDestEnd,pcchRemaining,dwFlags,pszFormat,argList);
653 }
654 return Status;
655 }
656
657 NTSTRSAFEAPI RtlStringCchVPrintfExW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCWSTR pszFormat,va_list argList)
658 {
659 NTSTATUS Status;
660 if (cchDest > NTSTRSAFE_MAX_CCH)
661 Status = STATUS_INVALID_PARAMETER;
662 else
663 {
664 size_t cbDest;
665 cbDest = cchDest*sizeof(wchar_t);
666 Status = RtlStringVPrintfExWorkerW(pszDest,cchDest,cbDest,ppszDestEnd,pcchRemaining,dwFlags,pszFormat,argList);
667 }
668 return Status;
669 }
670
671
672 NTSTRSAFEAPI RtlStringCbVPrintfExA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCSTR pszFormat,va_list argList);
673 NTSTRSAFEAPI RtlStringCbVPrintfExW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCWSTR pszFormat,va_list argList);
674
675
676 NTSTRSAFEAPI RtlStringCbVPrintfExA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCSTR pszFormat,va_list argList)
677 {
678 NTSTATUS Status;
679 size_t cchDest;
680 size_t cchRemaining = 0;
681 cchDest = cbDest / sizeof(char);
682 if (cchDest > NTSTRSAFE_MAX_CCH)
683 Status = STATUS_INVALID_PARAMETER;
684 else
685 Status = RtlStringVPrintfExWorkerA(pszDest,cchDest,cbDest,ppszDestEnd,&cchRemaining,dwFlags,pszFormat,argList);
686 if (NT_SUCCESS(Status) || (Status==STATUS_BUFFER_OVERFLOW))
687 {
688 if (pcbRemaining)
689 {
690 *pcbRemaining = (cchRemaining*sizeof(char)) + (cbDest % sizeof(char));
691 }
692 }
693 return Status;
694 }
695
696 NTSTRSAFEAPI RtlStringCbVPrintfExW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCWSTR pszFormat,va_list argList)
697 {
698 NTSTATUS Status;
699 size_t cchDest;
700 size_t cchRemaining = 0;
701 cchDest = cbDest / sizeof(wchar_t);
702 if (cchDest > NTSTRSAFE_MAX_CCH)
703 Status = STATUS_INVALID_PARAMETER;
704 else
705 Status = RtlStringVPrintfExWorkerW(pszDest,cchDest,cbDest,ppszDestEnd,&cchRemaining,dwFlags,pszFormat,argList);
706 if (NT_SUCCESS(Status) || (Status==STATUS_BUFFER_OVERFLOW))
707 {
708 if (pcbRemaining)
709 {
710 *pcbRemaining = (cchRemaining*sizeof(wchar_t)) + (cbDest % sizeof(wchar_t));
711 }
712 }
713 return Status;
714 }
715
716
717 NTSTRSAFEAPI RtlStringCchLengthA(STRSAFE_LPCSTR psz,size_t cchMax,size_t *pcchLength);
718 NTSTRSAFEAPI RtlStringCchLengthW(STRSAFE_LPCWSTR psz,size_t cchMax,size_t *pcchLength);
719
720
721 NTSTRSAFEAPI RtlStringCchLengthA(STRSAFE_LPCSTR psz,size_t cchMax,size_t *pcchLength)
722 {
723 NTSTATUS Status;
724 if (!psz || (cchMax > NTSTRSAFE_MAX_CCH))
725 Status = STATUS_INVALID_PARAMETER;
726 else
727 Status = RtlStringLengthWorkerA(psz,cchMax,pcchLength);
728 if (!NT_SUCCESS(Status) && pcchLength)
729 {
730 *pcchLength = 0;
731 }
732 return Status;
733 }
734
735 NTSTRSAFEAPI RtlStringCchLengthW(STRSAFE_LPCWSTR psz,size_t cchMax,size_t *pcchLength)
736 {
737 NTSTATUS Status;
738 if (!psz || (cchMax > NTSTRSAFE_MAX_CCH))
739 Status = STATUS_INVALID_PARAMETER;
740 else
741 Status = RtlStringLengthWorkerW(psz,cchMax,pcchLength);
742 if (!NT_SUCCESS(Status) && pcchLength)
743 {
744 *pcchLength = 0;
745 }
746 return Status;
747 }
748
749
750 NTSTRSAFEAPI RtlStringCbLengthA(STRSAFE_LPCSTR psz,size_t cbMax,size_t *pcbLength);
751 NTSTRSAFEAPI RtlStringCbLengthW(STRSAFE_LPCWSTR psz,size_t cbMax,size_t *pcbLength);
752
753
754 NTSTRSAFEAPI RtlStringCbLengthA(STRSAFE_LPCSTR psz,size_t cbMax,size_t *pcbLength)
755 {
756 NTSTATUS Status;
757 size_t cchMax;
758 size_t cchLength = 0;
759 cchMax = cbMax / sizeof(char);
760 if (!psz || (cchMax > NTSTRSAFE_MAX_CCH))
761 Status = STATUS_INVALID_PARAMETER;
762 else
763 Status = RtlStringLengthWorkerA(psz,cchMax,&cchLength);
764 if (pcbLength)
765 {
766 if (NT_SUCCESS(Status))
767 {
768 *pcbLength = cchLength*sizeof(char);
769 }
770 else
771 {
772 *pcbLength = 0;
773 }
774 }
775 return Status;
776 }
777
778 NTSTRSAFEAPI RtlStringCbLengthW(STRSAFE_LPCWSTR psz,size_t cbMax,size_t *pcbLength)
779 {
780 NTSTATUS Status;
781 size_t cchMax;
782 size_t cchLength = 0;
783 cchMax = cbMax / sizeof(wchar_t);
784 if (!psz || (cchMax > NTSTRSAFE_MAX_CCH))
785 Status = STATUS_INVALID_PARAMETER;
786 else
787 Status = RtlStringLengthWorkerW(psz,cchMax,&cchLength);
788 if (pcbLength)
789 {
790 if (NT_SUCCESS(Status))
791 {
792 *pcbLength = cchLength*sizeof(wchar_t);
793 }
794 else
795 {
796 *pcbLength = 0;
797 }
798 }
799 return Status;
800 }
801
802 NTSTRSAFEAPI RtlStringCopyWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc)
803 {
804 NTSTATUS Status = STATUS_SUCCESS;
805 if (cchDest==0)
806 Status = STATUS_INVALID_PARAMETER;
807 else
808 {
809 while(cchDest && (*pszSrc!='\0'))
810 {
811 *pszDest++ = *pszSrc++;
812 cchDest--;
813 }
814 if (cchDest==0)
815 {
816 pszDest--;
817 Status = STATUS_BUFFER_OVERFLOW;
818 }
819 *pszDest= '\0';
820 }
821 return Status;
822 }
823
824 NTSTRSAFEAPI RtlStringCopyWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc)
825 {
826 NTSTATUS Status = STATUS_SUCCESS;
827 if (cchDest==0)
828 Status = STATUS_INVALID_PARAMETER;
829 else
830 {
831 while(cchDest && (*pszSrc!=L'\0'))
832 {
833 *pszDest++ = *pszSrc++;
834 cchDest--;
835 }
836 if (cchDest==0)
837 {
838 pszDest--;
839 Status = STATUS_BUFFER_OVERFLOW;
840 }
841 *pszDest= L'\0';
842 }
843 return Status;
844 }
845
846 NTSTRSAFEAPI RtlStringCopyExWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags)
847 {
848 NTSTATUS Status = STATUS_SUCCESS;
849 STRSAFE_LPSTR pszDestEnd = pszDest;
850 size_t cchRemaining = 0;
851 if (dwFlags & (~STRSAFE_VALID_FLAGS))
852 Status = STATUS_INVALID_PARAMETER;
853 else
854 {
855 if (dwFlags & STRSAFE_IGNORE_NULLS)
856 {
857 if (!pszDest)
858 {
859 if ((cchDest!=0) || (cbDest!=0))
860 Status = STATUS_INVALID_PARAMETER;
861 }
862 if (!pszSrc)
863 pszSrc = "";
864 }
865 if (NT_SUCCESS(Status))
866 {
867 if (cchDest==0)
868 {
869 pszDestEnd = pszDest;
870 cchRemaining = 0;
871 if (*pszSrc!='\0')
872 {
873 if (!pszDest)
874 Status = STATUS_INVALID_PARAMETER;
875 else
876 Status = STATUS_BUFFER_OVERFLOW;
877 }
878 }
879 else
880 {
881 pszDestEnd = pszDest;
882 cchRemaining = cchDest;
883 while(cchRemaining && (*pszSrc!='\0'))
884 {
885 *pszDestEnd++ = *pszSrc++;
886 cchRemaining--;
887 }
888 if (cchRemaining > 0)
889 {
890 if (dwFlags & STRSAFE_FILL_BEHIND_NULL)
891 {
892 memset(pszDestEnd + 1,STRSAFE_GET_FILL_PATTERN(dwFlags),((cchRemaining - 1)*sizeof(char)) + (cbDest % sizeof(char)));
893 }
894 }
895 else
896 {
897 pszDestEnd--;
898 cchRemaining++;
899 Status = STATUS_BUFFER_OVERFLOW;
900 }
901 *pszDestEnd = '\0';
902 }
903 }
904 }
905 if (!NT_SUCCESS(Status))
906 {
907 if (pszDest)
908 {
909 if (dwFlags & STRSAFE_FILL_ON_FAILURE)
910 {
911 memset(pszDest,STRSAFE_GET_FILL_PATTERN(dwFlags),cbDest);
912 if (STRSAFE_GET_FILL_PATTERN(dwFlags)==0)
913 {
914 pszDestEnd = pszDest;
915 cchRemaining = cchDest;
916 }
917 else
918 if (cchDest > 0)
919 {
920 pszDestEnd = pszDest + cchDest - 1;
921 cchRemaining = 1;
922 *pszDestEnd = '\0';
923 }
924 }
925 if (dwFlags & (STRSAFE_NULL_ON_FAILURE | STRSAFE_NO_TRUNCATION))
926 {
927 if (cchDest > 0)
928 {
929 pszDestEnd = pszDest;
930 cchRemaining = cchDest;
931 *pszDestEnd = '\0';
932 }
933 }
934 }
935 }
936 if (NT_SUCCESS(Status) || (Status==STATUS_BUFFER_OVERFLOW))
937 {
938 if (ppszDestEnd)
939 *ppszDestEnd = pszDestEnd;
940 if (pcchRemaining)
941 *pcchRemaining = cchRemaining;
942 }
943 return Status;
944 }
945
946 NTSTRSAFEAPI RtlStringCopyExWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags)
947 {
948 NTSTATUS Status = STATUS_SUCCESS;
949 STRSAFE_LPWSTR pszDestEnd = pszDest;
950 size_t cchRemaining = 0;
951 if (dwFlags & (~STRSAFE_VALID_FLAGS))
952 Status = STATUS_INVALID_PARAMETER;
953 else
954 {
955 if (dwFlags & STRSAFE_IGNORE_NULLS)
956 {
957 if (!pszDest)
958 {
959 if ((cchDest!=0) || (cbDest!=0))
960 Status = STATUS_INVALID_PARAMETER;
961 }
962 if (!pszSrc)
963 pszSrc = L"";
964 }
965 if (NT_SUCCESS(Status))
966 {
967 if (cchDest==0)
968 {
969 pszDestEnd = pszDest;
970 cchRemaining = 0;
971 if (*pszSrc!=L'\0')
972 {
973 if (!pszDest)
974 Status = STATUS_INVALID_PARAMETER;
975 else
976 Status = STATUS_BUFFER_OVERFLOW;
977 }
978 }
979 else
980 {
981 pszDestEnd = pszDest;
982 cchRemaining = cchDest;
983 while(cchRemaining && (*pszSrc!=L'\0'))
984 {
985 *pszDestEnd++ = *pszSrc++;
986 cchRemaining--;
987 }
988 if (cchRemaining > 0)
989 {
990 if (dwFlags & STRSAFE_FILL_BEHIND_NULL)
991 {
992 memset(pszDestEnd + 1,STRSAFE_GET_FILL_PATTERN(dwFlags),((cchRemaining - 1)*sizeof(wchar_t)) + (cbDest % sizeof(wchar_t)));
993 }
994 }
995 else
996 {
997 pszDestEnd--;
998 cchRemaining++;
999 Status = STATUS_BUFFER_OVERFLOW;
1000 }
1001 *pszDestEnd = L'\0';
1002 }
1003 }
1004 }
1005 if (!NT_SUCCESS(Status))
1006 {
1007 if (pszDest)
1008 {
1009 if (dwFlags & STRSAFE_FILL_ON_FAILURE)
1010 {
1011 memset(pszDest,STRSAFE_GET_FILL_PATTERN(dwFlags),cbDest);
1012 if (STRSAFE_GET_FILL_PATTERN(dwFlags)==0)
1013 {
1014 pszDestEnd = pszDest;
1015 cchRemaining = cchDest;
1016 }
1017 else
1018 if (cchDest > 0)
1019 {
1020 pszDestEnd = pszDest + cchDest - 1;
1021 cchRemaining = 1;
1022 *pszDestEnd = L'\0';
1023 }
1024 }
1025 if (dwFlags & (STRSAFE_NULL_ON_FAILURE | STRSAFE_NO_TRUNCATION))
1026 {
1027 if (cchDest > 0)
1028 {
1029 pszDestEnd = pszDest;
1030 cchRemaining = cchDest;
1031 *pszDestEnd = L'\0';
1032 }
1033 }
1034 }
1035 }
1036 if (NT_SUCCESS(Status) || (Status==STATUS_BUFFER_OVERFLOW))
1037 {
1038 if (ppszDestEnd)
1039 *ppszDestEnd = pszDestEnd;
1040 if (pcchRemaining)
1041 *pcchRemaining = cchRemaining;
1042 }
1043 return Status;
1044 }
1045
1046 NTSTRSAFEAPI RtlStringCopyNWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc,size_t cchSrc)
1047 {
1048 NTSTATUS Status = STATUS_SUCCESS;
1049 if (cchDest==0)
1050 Status = STATUS_INVALID_PARAMETER;
1051 else
1052 {
1053 while(cchDest && cchSrc && (*pszSrc!='\0'))
1054 {
1055 *pszDest++ = *pszSrc++;
1056 cchDest--;
1057 cchSrc--;
1058 }
1059 if (cchDest==0)
1060 {
1061 pszDest--;
1062 Status = STATUS_BUFFER_OVERFLOW;
1063 }
1064 *pszDest= '\0';
1065 }
1066 return Status;
1067 }
1068
1069 NTSTRSAFEAPI RtlStringCopyNWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc,size_t cchToCopy)
1070 {
1071 NTSTATUS Status = STATUS_SUCCESS;
1072 if (cchDest==0)
1073 Status = STATUS_INVALID_PARAMETER;
1074 else
1075 {
1076 while(cchDest && cchToCopy && (*pszSrc!=L'\0'))
1077 {
1078 *pszDest++ = *pszSrc++;
1079 cchDest--;
1080 cchToCopy--;
1081 }
1082 if (cchDest==0)
1083 {
1084 pszDest--;
1085 Status = STATUS_BUFFER_OVERFLOW;
1086 }
1087 *pszDest= L'\0';
1088 }
1089 return Status;
1090 }
1091
1092 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)
1093 {
1094 NTSTATUS Status = STATUS_SUCCESS;
1095 STRSAFE_LPSTR pszDestEnd = pszDest;
1096 size_t cchRemaining = 0;
1097 if (dwFlags & (~STRSAFE_VALID_FLAGS))
1098 Status = STATUS_INVALID_PARAMETER;
1099 else
1100 if (cchToCopy > NTSTRSAFE_MAX_CCH)
1101 Status = STATUS_INVALID_PARAMETER;
1102 else
1103 {
1104 if (dwFlags & STRSAFE_IGNORE_NULLS)
1105 {
1106 if (!pszDest)
1107 {
1108 if ((cchDest!=0) || (cbDest!=0))
1109 Status = STATUS_INVALID_PARAMETER;
1110 }
1111 if (!pszSrc)
1112 pszSrc = "";
1113 }
1114 if (NT_SUCCESS(Status))
1115 {
1116 if (cchDest==0)
1117 {
1118 pszDestEnd = pszDest;
1119 cchRemaining = 0;
1120 if ((cchToCopy!=0) && (*pszSrc!='\0'))
1121 {
1122 if (!pszDest)
1123 Status = STATUS_INVALID_PARAMETER;
1124 else
1125 Status = STATUS_BUFFER_OVERFLOW;
1126 }
1127 }
1128 else
1129 {
1130 pszDestEnd = pszDest;
1131 cchRemaining = cchDest;
1132 while(cchRemaining && cchToCopy && (*pszSrc!='\0'))
1133 {
1134 *pszDestEnd++ = *pszSrc++;
1135 cchRemaining--;
1136 cchToCopy--;
1137 }
1138 if (cchRemaining > 0)
1139 {
1140 if (dwFlags & STRSAFE_FILL_BEHIND_NULL)
1141 {
1142 memset(pszDestEnd + 1,STRSAFE_GET_FILL_PATTERN(dwFlags),((cchRemaining - 1)*sizeof(char)) + (cbDest % sizeof(char)));
1143 }
1144 }
1145 else
1146 {
1147 pszDestEnd--;
1148 cchRemaining++;
1149 Status = STATUS_BUFFER_OVERFLOW;
1150 }
1151 *pszDestEnd = '\0';
1152 }
1153 }
1154 }
1155 if (!NT_SUCCESS(Status))
1156 {
1157 if (pszDest)
1158 {
1159 if (dwFlags & STRSAFE_FILL_ON_FAILURE)
1160 {
1161 memset(pszDest,STRSAFE_GET_FILL_PATTERN(dwFlags),cbDest);
1162 if (STRSAFE_GET_FILL_PATTERN(dwFlags)==0)
1163 {
1164 pszDestEnd = pszDest;
1165 cchRemaining = cchDest;
1166 }
1167 else
1168 if (cchDest > 0)
1169 {
1170 pszDestEnd = pszDest + cchDest - 1;
1171 cchRemaining = 1;
1172 *pszDestEnd = '\0';
1173 }
1174 }
1175 if (dwFlags & (STRSAFE_NULL_ON_FAILURE | STRSAFE_NO_TRUNCATION))
1176 {
1177 if (cchDest > 0)
1178 {
1179 pszDestEnd = pszDest;
1180 cchRemaining = cchDest;
1181 *pszDestEnd = '\0';
1182 }
1183 }
1184 }
1185 }
1186 if (NT_SUCCESS(Status) || (Status==STATUS_BUFFER_OVERFLOW))
1187 {
1188 if (ppszDestEnd)
1189 *ppszDestEnd = pszDestEnd;
1190 if (pcchRemaining)
1191 *pcchRemaining = cchRemaining;
1192 }
1193 return Status;
1194 }
1195
1196 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)
1197 {
1198 NTSTATUS Status = STATUS_SUCCESS;
1199 STRSAFE_LPWSTR pszDestEnd = pszDest;
1200 size_t cchRemaining = 0;
1201 if (dwFlags & (~STRSAFE_VALID_FLAGS))
1202 Status = STATUS_INVALID_PARAMETER;
1203 else
1204 if (cchToCopy > NTSTRSAFE_MAX_CCH)
1205 Status = STATUS_INVALID_PARAMETER;
1206 else
1207 {
1208 if (dwFlags & STRSAFE_IGNORE_NULLS)
1209 {
1210 if (!pszDest)
1211 {
1212 if ((cchDest!=0) || (cbDest!=0))
1213 Status = STATUS_INVALID_PARAMETER;
1214 }
1215 if (!pszSrc)
1216 pszSrc = L"";
1217 }
1218 if (NT_SUCCESS(Status))
1219 {
1220 if (cchDest==0)
1221 {
1222 pszDestEnd = pszDest;
1223 cchRemaining = 0;
1224 if ((cchToCopy!=0) && (*pszSrc!=L'\0'))
1225 {
1226 if (!pszDest)
1227 Status = STATUS_INVALID_PARAMETER;
1228 else
1229 Status = STATUS_BUFFER_OVERFLOW;
1230 }
1231 }
1232 else
1233 {
1234 pszDestEnd = pszDest;
1235 cchRemaining = cchDest;
1236 while(cchRemaining && cchToCopy && (*pszSrc!=L'\0'))
1237 {
1238 *pszDestEnd++ = *pszSrc++;
1239 cchRemaining--;
1240 cchToCopy--;
1241 }
1242 if (cchRemaining > 0)
1243 {
1244 if (dwFlags & STRSAFE_FILL_BEHIND_NULL)
1245 {
1246 memset(pszDestEnd + 1,STRSAFE_GET_FILL_PATTERN(dwFlags),((cchRemaining - 1)*sizeof(wchar_t)) + (cbDest % sizeof(wchar_t)));
1247 }
1248 }
1249 else
1250 {
1251 pszDestEnd--;
1252 cchRemaining++;
1253 Status = STATUS_BUFFER_OVERFLOW;
1254 }
1255 *pszDestEnd = L'\0';
1256 }
1257 }
1258 }
1259 if (!NT_SUCCESS(Status))
1260 {
1261 if (pszDest)
1262 {
1263 if (dwFlags & STRSAFE_FILL_ON_FAILURE)
1264 {
1265 memset(pszDest,STRSAFE_GET_FILL_PATTERN(dwFlags),cbDest);
1266 if (STRSAFE_GET_FILL_PATTERN(dwFlags)==0)
1267 {
1268 pszDestEnd = pszDest;
1269 cchRemaining = cchDest;
1270 }
1271 else
1272 if (cchDest > 0)
1273 {
1274 pszDestEnd = pszDest + cchDest - 1;
1275 cchRemaining = 1;
1276 *pszDestEnd = L'\0';
1277 }
1278 }
1279 if (dwFlags & (STRSAFE_NULL_ON_FAILURE | STRSAFE_NO_TRUNCATION))
1280 {
1281 if (cchDest > 0)
1282 {
1283 pszDestEnd = pszDest;
1284 cchRemaining = cchDest;
1285 *pszDestEnd = L'\0';
1286 }
1287 }
1288 }
1289 }
1290 if (NT_SUCCESS(Status) || (Status==STATUS_BUFFER_OVERFLOW))
1291 {
1292 if (ppszDestEnd)
1293 *ppszDestEnd = pszDestEnd;
1294 if (pcchRemaining)
1295 *pcchRemaining = cchRemaining;
1296 }
1297 return Status;
1298 }
1299
1300 NTSTRSAFEAPI RtlStringCatWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc)
1301 {
1302 NTSTATUS Status;
1303 size_t cchDestLength;
1304 Status = RtlStringLengthWorkerA(pszDest,cchDest,&cchDestLength);
1305 if (NT_SUCCESS(Status))
1306 Status = RtlStringCopyWorkerA(pszDest + cchDestLength,cchDest - cchDestLength,pszSrc);
1307 return Status;
1308 }
1309
1310 NTSTRSAFEAPI RtlStringCatWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc)
1311 {
1312 NTSTATUS Status;
1313 size_t cchDestLength;
1314 Status = RtlStringLengthWorkerW(pszDest,cchDest,&cchDestLength);
1315 if (NT_SUCCESS(Status))
1316 Status = RtlStringCopyWorkerW(pszDest + cchDestLength,cchDest - cchDestLength,pszSrc);
1317 return Status;
1318 }
1319
1320 NTSTRSAFEAPI RtlStringCatExWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags)
1321 {
1322 NTSTATUS Status = STATUS_SUCCESS;
1323 STRSAFE_LPSTR pszDestEnd = pszDest;
1324 size_t cchRemaining = 0;
1325 if (dwFlags & (~STRSAFE_VALID_FLAGS))
1326 Status = STATUS_INVALID_PARAMETER;
1327 else
1328 {
1329 size_t cchDestLength;
1330 if (dwFlags & STRSAFE_IGNORE_NULLS)
1331 {
1332 if (!pszDest)
1333 {
1334 if ((cchDest==0) && (cbDest==0))
1335 cchDestLength = 0;
1336 else
1337 Status = STATUS_INVALID_PARAMETER;
1338 }
1339 else
1340 {
1341 Status = RtlStringLengthWorkerA(pszDest,cchDest,&cchDestLength);
1342 if (NT_SUCCESS(Status))
1343 {
1344 pszDestEnd = pszDest + cchDestLength;
1345 cchRemaining = cchDest - cchDestLength;
1346 }
1347 }
1348 if (!pszSrc)
1349 pszSrc = "";
1350 }
1351 else
1352 {
1353 Status = RtlStringLengthWorkerA(pszDest,cchDest,&cchDestLength);
1354 if (NT_SUCCESS(Status))
1355 {
1356 pszDestEnd = pszDest + cchDestLength;
1357 cchRemaining = cchDest - cchDestLength;
1358 }
1359 }
1360 if (NT_SUCCESS(Status))
1361 {
1362 if (cchDest==0)
1363 {
1364 if (*pszSrc!='\0')
1365 {
1366 if (!pszDest)
1367 Status = STATUS_INVALID_PARAMETER;
1368 else
1369 Status = STATUS_BUFFER_OVERFLOW;
1370 }
1371 }
1372 else
1373 Status = RtlStringCopyExWorkerA(pszDestEnd,cchRemaining,(cchRemaining*sizeof(char)) + (cbDest % sizeof(char)),pszSrc,&pszDestEnd,&cchRemaining,dwFlags & (~(STRSAFE_FILL_ON_FAILURE | STRSAFE_NULL_ON_FAILURE)));
1374 }
1375 }
1376 if (!NT_SUCCESS(Status))
1377 {
1378 if (pszDest)
1379 {
1380 if (dwFlags & STRSAFE_FILL_ON_FAILURE)
1381 {
1382 memset(pszDest,STRSAFE_GET_FILL_PATTERN(dwFlags),cbDest);
1383 if (STRSAFE_GET_FILL_PATTERN(dwFlags)==0)
1384 {
1385 pszDestEnd = pszDest;
1386 cchRemaining = cchDest;
1387 }
1388 else
1389 if (cchDest > 0)
1390 {
1391 pszDestEnd = pszDest + cchDest - 1;
1392 cchRemaining = 1;
1393 *pszDestEnd = '\0';
1394 }
1395 }
1396 if (dwFlags & STRSAFE_NULL_ON_FAILURE)
1397 {
1398 if (cchDest > 0)
1399 {
1400 pszDestEnd = pszDest;
1401 cchRemaining = cchDest;
1402 *pszDestEnd = '\0';
1403 }
1404 }
1405 }
1406 }
1407 if (NT_SUCCESS(Status) || (Status==STATUS_BUFFER_OVERFLOW))
1408 {
1409 if (ppszDestEnd)
1410 *ppszDestEnd = pszDestEnd;
1411 if (pcchRemaining)
1412 *pcchRemaining = cchRemaining;
1413 }
1414 return Status;
1415 }
1416
1417 NTSTRSAFEAPI RtlStringCatExWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags)
1418 {
1419 NTSTATUS Status = STATUS_SUCCESS;
1420 STRSAFE_LPWSTR pszDestEnd = pszDest;
1421 size_t cchRemaining = 0;
1422 if (dwFlags & (~STRSAFE_VALID_FLAGS))
1423 Status = STATUS_INVALID_PARAMETER;
1424 else
1425 {
1426 size_t cchDestLength;
1427 if (dwFlags & STRSAFE_IGNORE_NULLS)
1428 {
1429 if (!pszDest)
1430 {
1431 if ((cchDest==0) && (cbDest==0))
1432 cchDestLength = 0;
1433 else
1434 Status = STATUS_INVALID_PARAMETER;
1435 }
1436 else
1437 {
1438 Status = RtlStringLengthWorkerW(pszDest,cchDest,&cchDestLength);
1439 if (NT_SUCCESS(Status))
1440 {
1441 pszDestEnd = pszDest + cchDestLength;
1442 cchRemaining = cchDest - cchDestLength;
1443 }
1444 }
1445 if (!pszSrc)
1446 pszSrc = L"";
1447 }
1448 else
1449 {
1450 Status = RtlStringLengthWorkerW(pszDest,cchDest,&cchDestLength);
1451 if (NT_SUCCESS(Status))
1452 {
1453 pszDestEnd = pszDest + cchDestLength;
1454 cchRemaining = cchDest - cchDestLength;
1455 }
1456 }
1457 if (NT_SUCCESS(Status))
1458 {
1459 if (cchDest==0)
1460 {
1461 if (*pszSrc!=L'\0')
1462 {
1463 if (!pszDest)
1464 Status = STATUS_INVALID_PARAMETER;
1465 else
1466 Status = STATUS_BUFFER_OVERFLOW;
1467 }
1468 }
1469 else
1470 Status = RtlStringCopyExWorkerW(pszDestEnd,cchRemaining,(cchRemaining*sizeof(wchar_t)) + (cbDest % sizeof(wchar_t)),pszSrc,&pszDestEnd,&cchRemaining,dwFlags & (~(STRSAFE_FILL_ON_FAILURE | STRSAFE_NULL_ON_FAILURE)));
1471 }
1472 }
1473 if (!NT_SUCCESS(Status))
1474 {
1475 if (pszDest)
1476 {
1477 if (dwFlags & STRSAFE_FILL_ON_FAILURE)
1478 {
1479 memset(pszDest,STRSAFE_GET_FILL_PATTERN(dwFlags),cbDest);
1480 if (STRSAFE_GET_FILL_PATTERN(dwFlags)==0)
1481 {
1482 pszDestEnd = pszDest;
1483 cchRemaining = cchDest;
1484 }
1485 else
1486 if (cchDest > 0)
1487 {
1488 pszDestEnd = pszDest + cchDest - 1;
1489 cchRemaining = 1;
1490 *pszDestEnd = L'\0';
1491 }
1492 }
1493 if (dwFlags & STRSAFE_NULL_ON_FAILURE)
1494 {
1495 if (cchDest > 0)
1496 {
1497 pszDestEnd = pszDest;
1498 cchRemaining = cchDest;
1499 *pszDestEnd = L'\0';
1500 }
1501 }
1502 }
1503 }
1504 if (NT_SUCCESS(Status) || (Status==STATUS_BUFFER_OVERFLOW))
1505 {
1506 if (ppszDestEnd)
1507 *ppszDestEnd = pszDestEnd;
1508 if (pcchRemaining)
1509 *pcchRemaining = cchRemaining;
1510 }
1511 return Status;
1512 }
1513
1514 NTSTRSAFEAPI RtlStringCatNWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc,size_t cchToAppend)
1515 {
1516 NTSTATUS Status;
1517 size_t cchDestLength;
1518 Status = RtlStringLengthWorkerA(pszDest,cchDest,&cchDestLength);
1519 if (NT_SUCCESS(Status))
1520 Status = RtlStringCopyNWorkerA(pszDest + cchDestLength,cchDest - cchDestLength,pszSrc,cchToAppend);
1521 return Status;
1522 }
1523
1524 NTSTRSAFEAPI RtlStringCatNWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc,size_t cchToAppend)
1525 {
1526 NTSTATUS Status;
1527 size_t cchDestLength;
1528 Status = RtlStringLengthWorkerW(pszDest,cchDest,&cchDestLength);
1529 if (NT_SUCCESS(Status))
1530 Status = RtlStringCopyNWorkerW(pszDest + cchDestLength,cchDest - cchDestLength,pszSrc,cchToAppend);
1531 return Status;
1532 }
1533
1534 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)
1535 {
1536 NTSTATUS Status = STATUS_SUCCESS;
1537 STRSAFE_LPSTR pszDestEnd = pszDest;
1538 size_t cchRemaining = 0;
1539 size_t cchDestLength = 0;
1540 if (dwFlags & (~STRSAFE_VALID_FLAGS))
1541 Status = STATUS_INVALID_PARAMETER;
1542 else
1543 if (cchToAppend > NTSTRSAFE_MAX_CCH)
1544 Status = STATUS_INVALID_PARAMETER;
1545 else
1546 {
1547 if (dwFlags & STRSAFE_IGNORE_NULLS)
1548 {
1549 if (!pszDest)
1550 {
1551 if ((cchDest==0) && (cbDest==0))
1552 cchDestLength = 0;
1553 else
1554 Status = STATUS_INVALID_PARAMETER;
1555 }
1556 else
1557 {
1558 Status = RtlStringLengthWorkerA(pszDest,cchDest,&cchDestLength);
1559 if (NT_SUCCESS(Status))
1560 {
1561 pszDestEnd = pszDest + cchDestLength;
1562 cchRemaining = cchDest - cchDestLength;
1563 }
1564 }
1565 if (!pszSrc)
1566 pszSrc = "";
1567 }
1568 else
1569 {
1570 Status = RtlStringLengthWorkerA(pszDest,cchDest,&cchDestLength);
1571 if (NT_SUCCESS(Status))
1572 {
1573 pszDestEnd = pszDest + cchDestLength;
1574 cchRemaining = cchDest - cchDestLength;
1575 }
1576 }
1577 if (NT_SUCCESS(Status))
1578 {
1579 if (cchDest==0)
1580 {
1581 if ((cchToAppend!=0) && (*pszSrc!='\0'))
1582 {
1583 if (!pszDest)
1584 Status = STATUS_INVALID_PARAMETER;
1585 else
1586 Status = STATUS_BUFFER_OVERFLOW;
1587 }
1588 }
1589 else
1590 Status = RtlStringCopyNExWorkerA(pszDestEnd,cchRemaining,(cchRemaining*sizeof(char)) + (cbDest % sizeof(char)),pszSrc,cchToAppend,&pszDestEnd,&cchRemaining,dwFlags & (~(STRSAFE_FILL_ON_FAILURE | STRSAFE_NULL_ON_FAILURE)));
1591 }
1592 }
1593 if (!NT_SUCCESS(Status))
1594 {
1595 if (pszDest)
1596 {
1597 if (dwFlags & STRSAFE_FILL_ON_FAILURE)
1598 {
1599 memset(pszDest,STRSAFE_GET_FILL_PATTERN(dwFlags),cbDest);
1600 if (STRSAFE_GET_FILL_PATTERN(dwFlags)==0)
1601 {
1602 pszDestEnd = pszDest;
1603 cchRemaining = cchDest;
1604 }
1605 else
1606 if (cchDest > 0)
1607 {
1608 pszDestEnd = pszDest + cchDest - 1;
1609 cchRemaining = 1;
1610 *pszDestEnd = '\0';
1611 }
1612 }
1613 if (dwFlags & (STRSAFE_NULL_ON_FAILURE))
1614 {
1615 if (cchDest > 0)
1616 {
1617 pszDestEnd = pszDest;
1618 cchRemaining = cchDest;
1619 *pszDestEnd = '\0';
1620 }
1621 }
1622 }
1623 }
1624 if (NT_SUCCESS(Status) || (Status==STATUS_BUFFER_OVERFLOW))
1625 {
1626 if (ppszDestEnd)
1627 *ppszDestEnd = pszDestEnd;
1628 if (pcchRemaining)
1629 *pcchRemaining = cchRemaining;
1630 }
1631 return Status;
1632 }
1633
1634 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)
1635 {
1636 NTSTATUS Status = STATUS_SUCCESS;
1637 STRSAFE_LPWSTR pszDestEnd = pszDest;
1638 size_t cchRemaining = 0;
1639 size_t cchDestLength = 0;
1640 if (dwFlags & (~STRSAFE_VALID_FLAGS))
1641 Status = STATUS_INVALID_PARAMETER;
1642 else
1643 if (cchToAppend > NTSTRSAFE_MAX_CCH)
1644 Status = STATUS_INVALID_PARAMETER;
1645 else
1646 {
1647 if (dwFlags & STRSAFE_IGNORE_NULLS)
1648 {
1649 if (!pszDest)
1650 {
1651 if ((cchDest==0) && (cbDest==0))
1652 cchDestLength = 0;
1653 else
1654 Status = STATUS_INVALID_PARAMETER;
1655 }
1656 else
1657 {
1658 Status = RtlStringLengthWorkerW(pszDest,cchDest,&cchDestLength);
1659 if (NT_SUCCESS(Status))
1660 {
1661 pszDestEnd = pszDest + cchDestLength;
1662 cchRemaining = cchDest - cchDestLength;
1663 }
1664 }
1665 if (!pszSrc)
1666 pszSrc = L"";
1667 }
1668 else
1669 {
1670 Status = RtlStringLengthWorkerW(pszDest,cchDest,&cchDestLength);
1671 if (NT_SUCCESS(Status))
1672 {
1673 pszDestEnd = pszDest + cchDestLength;
1674 cchRemaining = cchDest - cchDestLength;
1675 }
1676 }
1677 if (NT_SUCCESS(Status))
1678 {
1679 if (cchDest==0)
1680 {
1681 if ((cchToAppend!=0) && (*pszSrc!=L'\0'))
1682 {
1683 if (!pszDest)
1684 Status = STATUS_INVALID_PARAMETER;
1685 else
1686 Status = STATUS_BUFFER_OVERFLOW;
1687 }
1688 }
1689 else
1690 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)));
1691 }
1692 }
1693 if (!NT_SUCCESS(Status))
1694 {
1695 if (pszDest)
1696 {
1697 if (dwFlags & STRSAFE_FILL_ON_FAILURE)
1698 {
1699 memset(pszDest,STRSAFE_GET_FILL_PATTERN(dwFlags),cbDest);
1700 if (STRSAFE_GET_FILL_PATTERN(dwFlags)==0)
1701 {
1702 pszDestEnd = pszDest;
1703 cchRemaining = cchDest;
1704 }
1705 else
1706 if (cchDest > 0)
1707 {
1708 pszDestEnd = pszDest + cchDest - 1;
1709 cchRemaining = 1;
1710 *pszDestEnd = L'\0';
1711 }
1712 }
1713 if (dwFlags & (STRSAFE_NULL_ON_FAILURE))
1714 {
1715 if (cchDest > 0)
1716 {
1717 pszDestEnd = pszDest;
1718 cchRemaining = cchDest;
1719 *pszDestEnd = L'\0';
1720 }
1721 }
1722 }
1723 }
1724 if (NT_SUCCESS(Status) || (Status==STATUS_BUFFER_OVERFLOW))
1725 {
1726 if (ppszDestEnd)
1727 *ppszDestEnd = pszDestEnd;
1728 if (pcchRemaining)
1729 *pcchRemaining = cchRemaining;
1730 }
1731 return Status;
1732 }
1733
1734 NTSTRSAFEAPI RtlStringVPrintfWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszFormat,va_list argList)
1735 {
1736 NTSTATUS Status = STATUS_SUCCESS;
1737 if (cchDest==0)
1738 Status = STATUS_INVALID_PARAMETER;
1739 else
1740 {
1741 int iRet;
1742 size_t cchMax;
1743 cchMax = cchDest - 1;
1744 iRet = _vsnprintf(pszDest,cchMax,pszFormat,argList);
1745 if ((iRet < 0) || (((size_t)iRet) > cchMax))
1746 {
1747 pszDest += cchMax;
1748 *pszDest = '\0';
1749 Status = STATUS_BUFFER_OVERFLOW;
1750 }
1751 else
1752 if (((size_t)iRet)==cchMax)
1753 {
1754 pszDest += cchMax;
1755 *pszDest = '\0';
1756 }
1757 }
1758 return Status;
1759 }
1760
1761 NTSTRSAFEAPI RtlStringVPrintfWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszFormat,va_list argList)
1762 {
1763 NTSTATUS Status = STATUS_SUCCESS;
1764 if (cchDest==0)
1765 Status = STATUS_INVALID_PARAMETER;
1766 else
1767 {
1768 int iRet;
1769 size_t cchMax;
1770 cchMax = cchDest - 1;
1771 iRet = _vsnwprintf(pszDest,cchMax,pszFormat,argList);
1772 if ((iRet < 0) || (((size_t)iRet) > cchMax))
1773 {
1774 pszDest += cchMax;
1775 *pszDest = L'\0';
1776 Status = STATUS_BUFFER_OVERFLOW;
1777 }
1778 else
1779 if (((size_t)iRet)==cchMax)
1780 {
1781 pszDest += cchMax;
1782 *pszDest = L'\0';
1783 }
1784 }
1785 return Status;
1786 }
1787
1788 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)
1789 {
1790 NTSTATUS Status = STATUS_SUCCESS;
1791 STRSAFE_LPSTR pszDestEnd = pszDest;
1792 size_t cchRemaining = 0;
1793 if (dwFlags & (~STRSAFE_VALID_FLAGS))
1794 Status = STATUS_INVALID_PARAMETER;
1795 else
1796 {
1797 if (dwFlags & STRSAFE_IGNORE_NULLS)
1798 {
1799 if (!pszDest)
1800 {
1801 if ((cchDest!=0) || (cbDest!=0))
1802 Status = STATUS_INVALID_PARAMETER;
1803 }
1804 if (!pszFormat)
1805 pszFormat = "";
1806 }
1807 if (NT_SUCCESS(Status))
1808 {
1809 if (cchDest==0)
1810 {
1811 pszDestEnd = pszDest;
1812 cchRemaining = 0;
1813 if (*pszFormat!='\0')
1814 {
1815 if (!pszDest)
1816 Status = STATUS_INVALID_PARAMETER;
1817 else
1818 Status = STATUS_BUFFER_OVERFLOW;
1819 }
1820 }
1821 else
1822 {
1823 int iRet;
1824 size_t cchMax;
1825 cchMax = cchDest - 1;
1826 iRet = _vsnprintf(pszDest,cchMax,pszFormat,argList);
1827 if ((iRet < 0) || (((size_t)iRet) > cchMax))
1828 {
1829 pszDestEnd = pszDest + cchMax;
1830 cchRemaining = 1;
1831 *pszDestEnd = '\0';
1832 Status = STATUS_BUFFER_OVERFLOW;
1833 }
1834 else
1835 if (((size_t)iRet)==cchMax)
1836 {
1837 pszDestEnd = pszDest + cchMax;
1838 cchRemaining = 1;
1839 *pszDestEnd = '\0';
1840 }
1841 else
1842 if (((size_t)iRet) < cchMax)
1843 {
1844 pszDestEnd = pszDest + iRet;
1845 cchRemaining = cchDest - iRet;
1846 if (dwFlags & STRSAFE_FILL_BEHIND_NULL)
1847 {
1848 memset(pszDestEnd + 1,STRSAFE_GET_FILL_PATTERN(dwFlags),((cchRemaining - 1)*sizeof(char)) + (cbDest % sizeof(char)));
1849 }
1850 }
1851 }
1852 }
1853 }
1854 if (!NT_SUCCESS(Status))
1855 {
1856 if (pszDest)
1857 {
1858 if (dwFlags & STRSAFE_FILL_ON_FAILURE)
1859 {
1860 memset(pszDest,STRSAFE_GET_FILL_PATTERN(dwFlags),cbDest);
1861 if (STRSAFE_GET_FILL_PATTERN(dwFlags)==0)
1862 {
1863 pszDestEnd = pszDest;
1864 cchRemaining = cchDest;
1865 }
1866 else
1867 if (cchDest > 0)
1868 {
1869 pszDestEnd = pszDest + cchDest - 1;
1870 cchRemaining = 1;
1871 *pszDestEnd = '\0';
1872 }
1873 }
1874 if (dwFlags & (STRSAFE_NULL_ON_FAILURE | STRSAFE_NO_TRUNCATION))
1875 {
1876 if (cchDest > 0)
1877 {
1878 pszDestEnd = pszDest;
1879 cchRemaining = cchDest;
1880 *pszDestEnd = '\0';
1881 }
1882 }
1883 }
1884 }
1885 if (NT_SUCCESS(Status) || (Status==STATUS_BUFFER_OVERFLOW))
1886 {
1887 if (ppszDestEnd)
1888 *ppszDestEnd = pszDestEnd;
1889 if (pcchRemaining)
1890 *pcchRemaining = cchRemaining;
1891 }
1892 return Status;
1893 }
1894
1895 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)
1896 {
1897 NTSTATUS Status = STATUS_SUCCESS;
1898 STRSAFE_LPWSTR pszDestEnd = pszDest;
1899 size_t cchRemaining = 0;
1900 if (dwFlags & (~STRSAFE_VALID_FLAGS))
1901 Status = STATUS_INVALID_PARAMETER;
1902 else
1903 {
1904 if (dwFlags & STRSAFE_IGNORE_NULLS)
1905 {
1906 if (!pszDest)
1907 {
1908 if ((cchDest!=0) || (cbDest!=0))
1909 Status = STATUS_INVALID_PARAMETER;
1910 }
1911 if (!pszFormat)
1912 pszFormat = L"";
1913 }
1914 if (NT_SUCCESS(Status))
1915 {
1916 if (cchDest==0)
1917 {
1918 pszDestEnd = pszDest;
1919 cchRemaining = 0;
1920 if (*pszFormat!=L'\0')
1921 {
1922 if (!pszDest)
1923 Status = STATUS_INVALID_PARAMETER;
1924 else
1925 Status = STATUS_BUFFER_OVERFLOW;
1926 }
1927 }
1928 else
1929 {
1930 int iRet;
1931 size_t cchMax;
1932 cchMax = cchDest - 1;
1933 iRet = _vsnwprintf(pszDest,cchMax,pszFormat,argList);
1934 if ((iRet < 0) || (((size_t)iRet) > cchMax))
1935 {
1936 pszDestEnd = pszDest + cchMax;
1937 cchRemaining = 1;
1938 *pszDestEnd = L'\0';
1939 Status = STATUS_BUFFER_OVERFLOW;
1940 }
1941 else
1942 if (((size_t)iRet)==cchMax)
1943 {
1944 pszDestEnd = pszDest + cchMax;
1945 cchRemaining = 1;
1946 *pszDestEnd = L'\0';
1947 }
1948 else
1949 if (((size_t)iRet) < cchMax)
1950 {
1951 pszDestEnd = pszDest + iRet;
1952 cchRemaining = cchDest - iRet;
1953 if (dwFlags & STRSAFE_FILL_BEHIND_NULL)
1954 {
1955 memset(pszDestEnd + 1,STRSAFE_GET_FILL_PATTERN(dwFlags),((cchRemaining - 1)*sizeof(wchar_t)) + (cbDest % sizeof(wchar_t)));
1956 }
1957 }
1958 }
1959 }
1960 }
1961 if (!NT_SUCCESS(Status))
1962 {
1963 if (pszDest)
1964 {
1965 if (dwFlags & STRSAFE_FILL_ON_FAILURE)
1966 {
1967 memset(pszDest,STRSAFE_GET_FILL_PATTERN(dwFlags),cbDest);
1968 if (STRSAFE_GET_FILL_PATTERN(dwFlags)==0)
1969 {
1970 pszDestEnd = pszDest;
1971 cchRemaining = cchDest;
1972 }
1973 else
1974 if (cchDest > 0)
1975 {
1976 pszDestEnd = pszDest + cchDest - 1;
1977 cchRemaining = 1;
1978 *pszDestEnd = L'\0';
1979 }
1980 }
1981 if (dwFlags & (STRSAFE_NULL_ON_FAILURE | STRSAFE_NO_TRUNCATION))
1982 {
1983 if (cchDest > 0)
1984 {
1985 pszDestEnd = pszDest;
1986 cchRemaining = cchDest;
1987 *pszDestEnd = L'\0';
1988 }
1989 }
1990 }
1991 }
1992 if (NT_SUCCESS(Status) || (Status==STATUS_BUFFER_OVERFLOW))
1993 {
1994 if (ppszDestEnd)
1995 *ppszDestEnd = pszDestEnd;
1996 if (pcchRemaining)
1997 *pcchRemaining = cchRemaining;
1998 }
1999 return Status;
2000 }
2001
2002 NTSTRSAFEAPI RtlStringLengthWorkerA(STRSAFE_LPCSTR psz,size_t cchMax,size_t *pcchLength)
2003 {
2004 NTSTATUS Status = STATUS_SUCCESS;
2005 size_t cchMaxPrev = cchMax;
2006 while(cchMax && (*psz!='\0'))
2007 {
2008 psz++;
2009 cchMax--;
2010 }
2011 if (cchMax==0)
2012 Status = STATUS_INVALID_PARAMETER;
2013 if (pcchLength)
2014 {
2015 if (NT_SUCCESS(Status))
2016 *pcchLength = cchMaxPrev - cchMax;
2017 else
2018 *pcchLength = 0;
2019 }
2020 return Status;
2021 }
2022
2023 NTSTRSAFEAPI RtlStringLengthWorkerW(STRSAFE_LPCWSTR psz,size_t cchMax,size_t *pcchLength)
2024 {
2025 NTSTATUS Status = STATUS_SUCCESS;
2026 size_t cchMaxPrev = cchMax;
2027 while(cchMax && (*psz!=L'\0'))
2028 {
2029 psz++;
2030 cchMax--;
2031 }
2032 if (cchMax==0)
2033 Status = STATUS_INVALID_PARAMETER;
2034 if (pcchLength)
2035 {
2036 if (NT_SUCCESS(Status))
2037 *pcchLength = cchMaxPrev - cchMax;
2038 else
2039 *pcchLength = 0;
2040 }
2041 return Status;
2042 }
2043
2044
2045
2046 #define RtlStringCopyWorkerA RtlStringCopyWorkerA_instead_use_StringCchCopyA_or_StringCchCopyExA;
2047 #define RtlStringCopyWorkerW RtlStringCopyWorkerW_instead_use_StringCchCopyW_or_StringCchCopyExW;
2048 #define RtlStringCopyExWorkerA RtlStringCopyExWorkerA_instead_use_StringCchCopyA_or_StringCchCopyExA;
2049 #define RtlStringCopyExWorkerW RtlStringCopyExWorkerW_instead_use_StringCchCopyW_or_StringCchCopyExW;
2050 #define RtlStringCatWorkerA RtlStringCatWorkerA_instead_use_StringCchCatA_or_StringCchCatExA;
2051 #define RtlStringCatWorkerW RtlStringCatWorkerW_instead_use_StringCchCatW_or_StringCchCatExW;
2052 #define RtlStringCatExWorkerA RtlStringCatExWorkerA_instead_use_StringCchCatA_or_StringCchCatExA;
2053 #define RtlStringCatExWorkerW RtlStringCatExWorkerW_instead_use_StringCchCatW_or_StringCchCatExW;
2054 #define RtlStringCatNWorkerA RtlStringCatNWorkerA_instead_use_StringCchCatNA_or_StrincCbCatNA;
2055 #define RtlStringCatNWorkerW RtlStringCatNWorkerW_instead_use_StringCchCatNW_or_StringCbCatNW;
2056 #define RtlStringCatNExWorkerA RtlStringCatNExWorkerA_instead_use_StringCchCatNExA_or_StringCbCatNExA;
2057 #define RtlStringCatNExWorkerW RtlStringCatNExWorkerW_instead_use_StringCchCatNExW_or_StringCbCatNExW;
2058 #define RtlStringVPrintfWorkerA RtlStringVPrintfWorkerA_instead_use_StringCchVPrintfA_or_StringCchVPrintfExA;
2059 #define RtlStringVPrintfWorkerW RtlStringVPrintfWorkerW_instead_use_StringCchVPrintfW_or_StringCchVPrintfExW;
2060 #define RtlStringVPrintfExWorkerA RtlStringVPrintfExWorkerA_instead_use_StringCchVPrintfA_or_StringCchVPrintfExA;
2061 #define RtlStringVPrintfExWorkerW RtlStringVPrintfExWorkerW_instead_use_StringCchVPrintfW_or_StringCchVPrintfExW;
2062 #define RtlStringLengthWorkerA RtlStringLengthWorkerA_instead_use_StringCchLengthA_or_StringCbLengthA;
2063 #define RtlStringLengthWorkerW RtlStringLengthWorkerW_instead_use_StringCchLengthW_or_StringCbLengthW;
2064
2065 #endif