Sync with trunk (r47116), hopefully without breaking anything.
[reactos.git] / include / psdk / strsafe.h
1 #ifndef __STRSAFE_H_
2 #define __STRSAFE_H_
3
4 #include <stdlib.h>
5 #include <stdarg.h>
6
7 #if defined(STRSAFE_NO_CCH_FUNCTIONS) && defined(STRSAFE_NO_CB_FUNCTIONS)
8 #error Both STRSAFE_NO_CCH_FUNCTIONS and STRSAFE_NO_CB_FUNCTIONS are defined
9 #endif
10
11 #ifndef SUCCEEDED
12 #define SUCCEEDED(Status) ((HRESULT)(Status) >= 0)
13 #endif
14 #define STRSAFE_MAX_CCH 2147483647
15 #define STRSAFE_E_INVALID_PARAMETER ((HRESULT)0x80070057L)
16 #define STRSAFE_E_INSUFFICIENT_BUFFER ((HRESULT)0x8007007AL)
17 #define STRSAFE_E_END_OF_FILE ((HRESULT)0x80070026L)
18
19 #define STRSAFE_FILL_BEHIND_NULL 0x00000200
20 #define STRSAFE_IGNORE_NULLS 0x00000200
21 #define STRSAFE_FILL_ON_FAILURE 0x00000400
22 #define STRSAFE_NULL_ON_FAILURE 0x00000800
23 #define STRSAFE_NO_TRUNCATION 0x00001000
24
25 #ifndef S_OK
26 #define S_OK ((HRESULT)0x00000000L)
27 #endif
28
29 #define STRSAFE_MIN(a,b) (((a) < (b))?(a):(b))
30
31 #ifndef _HRESULT_DEFINED
32 #define _HRESULT_DEFINED
33 typedef long HRESULT;
34 #endif
35
36 typedef char * STRSAFE_LPSTR;
37 typedef const char * STRSAFE_LPCSTR;
38 typedef wchar_t * STRSAFE_LPWSTR;
39 typedef const wchar_t * STRSAFE_LPCWSTR;
40 typedef unsigned long STRSAFE_DWORD;
41
42 #define STRSAFE_PASS2
43
44 /* Implement Cb functions for ansi and unicode */
45 #ifndef STRSAFE_NO_CB_FUNCTIONS
46 #define STRSAFE_CB
47 #define STRSAFE_UNICODE 0
48 # include <strsafe.h>
49 #undef STRSAFE_UNICODE
50 #define STRSAFE_UNICODE 1
51 # include <strsafe.h>
52 #undef STRSAFE_UNICODE
53 #undef STRSAFE_CB
54 #endif // !STRSAFE_NO_CB_FUNCTIONS
55
56 /* Implement Cch functions for ansi and unicode */
57 #ifndef STRSAFE_NO_CCH_FUNCTIONS
58 #define STRSAFE_UNICODE 0
59 # include <strsafe.h>
60 #undef STRSAFE_UNICODE
61 #define STRSAFE_UNICODE 1
62 # include <strsafe.h>
63 #undef STRSAFE_UNICODE
64 #endif // !STRSAFE_NO_CCH_FUNCTIONS
65
66 #undef STRSAFE_PASS2
67
68 /* Now define the functions depending on UNICODE */
69 #if defined(UNICODE)
70 # define STRSAFE_UNICODE 1
71 #else
72 # define STRSAFE_UNICODE 0
73 #endif
74 #include <strsafe.h>
75 #undef STRSAFE_UNICODE
76
77 #endif // !__STRSAFE_H_
78
79 /*****************************************************************************/
80
81 #if defined(STRSAFE_UNICODE)
82 #if (STRSAFE_UNICODE == 1)
83
84 #define STRSAFE_LPTSTR STRSAFE_LPWSTR
85 #define STRSAFE_LPCTSTR STRSAFE_LPCWSTR
86 #define STRSAFE_TCHAR wchar_t
87
88 #define StringCbCat StringCbCatW
89 #define StringCbCatEx StringCbCatExW
90 #define StringCbCatN StringCbCatNW
91 #define StringCbCatNEx StringCbCatNExW
92 #define StringCbCatWorker StringCxxCatWorkerW
93 #define StringCbCopy StringCbCopyW
94 #define StringCbCopyEx StringCbCopyExW
95 #define StringCbCopyN StringCbCopyNW
96 #define StringCbCopyNEx StringCbCopyNExW
97 #define StringCbGets StringCbGetsW
98 #define StringCbGetsEx StringCbGetsExW
99 #define StringCbLength StringCbLengthW
100 #define StringCbPrintf StringCbPrintfW
101 #define StringCbPrintfEx StringCbPrintfExW
102 #define StringCbVPrintf StringCbVPrintfW
103 #define StringCbVPrintfEx StringCbVPrintfExW
104 #define StringCchCat StringCchCatW
105 #define StringCchCatEx StringCchCatExW
106 #define StringCchCatN StringCchCatNW
107 #define StringCchCatNEx StringCchCatNExW
108 #define StringCchCatWorker StringCchCatWorkerW
109 #define StringCchCopy StringCchCopyW
110 #define StringCchCopyEx StringCchCopyExW
111 #define StringCchCopyN StringCchCopyNW
112 #define StringCchCopyNEx StringCchCopyNExW
113 #define StringCchGets StringCchGetsW
114 #define StringCchGetsEx StringCchGetsExW
115 #define StringCchLength StringCchLengthW
116 #define StringCchPrintf StringCchPrintfW
117 #define StringCchPrintfEx StringCchPrintfExW
118 #define StringCchVPrintf StringCchVPrintfW
119 #define StringCchVPrintfEx StringCchVPrintfExW
120 #define _vsnprintfAW _vsnwprintf
121
122 #else // (STRSAFE_UNICODE != 1)
123
124 #define STRSAFE_LPTSTR STRSAFE_LPSTR
125 #define STRSAFE_LPCTSTR STRSAFE_LPCSTR
126 #define STRSAFE_TCHAR char
127
128 #define StringCbCat StringCbCatA
129 #define StringCbCatEx StringCbCatExA
130 #define StringCbCatN StringCbCatNA
131 #define StringCbCatNEx StringCbCatNExA
132 #define StringCbCatWorker StringCxxCatWorkerA
133 #define StringCbCopy StringCbCopyA
134 #define StringCbCopyEx StringCbCopyExA
135 #define StringCbCopyN StringCbCopyNA
136 #define StringCbCopyNEx StringCbCopyNExA
137 #define StringCbGets StringCbGetsA
138 #define StringCbGetsEx StringCbGetsExA
139 #define StringCbLength StringCbLengthA
140 #define StringCbPrintf StringCbPrintfA
141 #define StringCbPrintfEx StringCbPrintfExA
142 #define StringCbVPrintf StringCbVPrintfA
143 #define StringCbVPrintfEx StringCbVPrintfExA
144 #define StringCchCat StringCchCatA
145 #define StringCchCatEx StringCchCatExA
146 #define StringCchCatN StringCchCatNA
147 #define StringCchCatNEx StringCchCatNExA
148 #define StringCchCatWorker StringCchCatWorkerA
149 #define StringCchCopy StringCchCopyA
150 #define StringCchCopyEx StringCchCopyExA
151 #define StringCchCopyN StringCchCopyNA
152 #define StringCchCopyNEx StringCchCopyNExA
153 #define StringCchGets StringCchGetsA
154 #define StringCchGetsEx StringCchGetsExA
155 #define StringCchLength StringCchLengthA
156 #define StringCchPrintf StringCchPrintfA
157 #define StringCchPrintfEx StringCchPrintfExA
158 #define StringCchVPrintf StringCchVPrintfA
159 #define StringCchVPrintfEx StringCchVPrintfExA
160 #define _vsnprintfAW _vsnprintf
161
162 #endif // (STRSAFE_UNICODE != 1)
163 #endif // defined(STRSAFE_UNICODE)
164
165 /*****************************************************************************/
166
167 #if defined (STRSAFE_PASS2)
168
169 #if defined(STRSAFE_CB)
170
171 #define STRSAFE_CXXtoCB(x) (x)
172 #define STRSAFE_CBtoCXX(x) (x)
173 #define STRSAFE_CXXtoCCH(x) (x)/sizeof(STRSAFE_TCHAR)
174 #define STRSAFE_CCHtoCXX(x) (x)*sizeof(STRSAFE_TCHAR)
175 #define StringCxxCat StringCbCat
176 #define StringCxxCatEx StringCbCatEx
177 #define StringCxxCatN StringCbCatN
178 #define StringCxxCatNEx StringCbCatNEx
179 #define StringCxxCatWorker StringCbCatWorker
180 #define StringCxxCopy StringCbCopy
181 #define StringCxxCopyEx StringCbCopyEx
182 #define StringCxxCopyN StringCbCopyN
183 #define StringCxxCopyNEx StringCbCopyNEx
184 #define StringCxxGets StringCbGets
185 #define StringCxxGetsEx StringCbGetsEx
186 #define StringCxxLength StringCbLength
187 #define StringCxxPrintf StringCbPrintf
188 #define StringCxxPrintfEx StringCbPrintfEx
189 #define StringCxxVPrintf StringCbVPrintf
190 #define StringCxxVPrintfEx StringCbVPrintfEx
191
192 #else // !STRSAFE_CB
193
194 #define STRSAFE_CXXtoCB(x) (x)*sizeof(STRSAFE_TCHAR)
195 #define STRSAFE_CBtoCXX(x) (x)/sizeof(STRSAFE_TCHAR)
196 #define STRSAFE_CXXtoCCH(x) (x)
197 #define STRSAFE_CCHtoCXX(x) (x)
198 #define StringCxxCat StringCchCat
199 #define StringCxxCatEx StringCchCatEx
200 #define StringCxxCatN StringCchCatN
201 #define StringCxxCatNEx StringCchCatNEx
202 #define StringCxxCatWorker StringCchCatWorker
203 #define StringCxxCopy StringCchCopy
204 #define StringCxxCopyEx StringCchCopyEx
205 #define StringCxxCopyN StringCchCopyN
206 #define StringCxxCopyNEx StringCchCopyNEx
207 #define StringCxxGets StringCchGets
208 #define StringCxxGetsEx StringCchGetsEx
209 #define StringCxxLength StringCchLength
210 #define StringCxxPrintf StringCchPrintf
211 #define StringCxxPrintfEx StringCchPrintfEx
212 #define StringCxxVPrintf StringCchVPrintf
213 #define StringCxxVPrintfEx StringCchVPrintfEx
214
215 #endif // !STRSAFE_CB
216
217 #ifdef STRSAFE_LIB
218
219 /* Normal function prototypes only */
220 #define STRSAFEAPI HRESULT __stdcall
221
222 STRSAFEAPI StringCxxCat(STRSAFE_LPTSTR pszDest, size_t cxDest, STRSAFE_LPCTSTR pszSrc);
223 STRSAFEAPI StringCxxCatEx(STRSAFE_LPTSTR pszDest, size_t cxDest, STRSAFE_LPCTSTR pszSrc, STRSAFE_LPTSTR *ppszDestEnd, size_t *pcbRemaining, STRSAFE_DWORD dwFlags);
224 STRSAFEAPI StringCxxCatN(STRSAFE_LPTSTR pszDest, size_t cxDest, STRSAFE_LPCTSTR pszSrc, size_t cbMaxAppend);
225 STRSAFEAPI StringCxxCatNEx(STRSAFE_LPTSTR pszDest, size_t cxDest, STRSAFE_LPCTSTR pszSrc, size_t cbMaxAppend, STRSAFE_LPTSTR *ppszDestEnd, size_t *pcbRemaining, STRSAFE_DWORD dwFlags);
226 STRSAFEAPI StringCxxCopy(STRSAFE_LPTSTR pszDest, size_t cxDest, STRSAFE_LPCTSTR pszSrc);
227 STRSAFEAPI StringCxxCopyEx(STRSAFE_LPTSTR pszDest, size_t cxDest, STRSAFE_LPCTSTR pszSrc, STRSAFE_LPTSTR *ppszDestEnd, size_t *pcbRemaining, STRSAFE_DWORD dwFlags);
228 STRSAFEAPI StringCxxCopyN(STRSAFE_LPTSTR pszDest, size_t cxDest, STRSAFE_LPCTSTR pszSrc, size_t cbSrc);
229 STRSAFEAPI StringCxxCopyNEx(STRSAFE_LPTSTR pszDest, size_t cxDest, STRSAFE_LPCTSTR pszSrc, size_t cbSrc, STRSAFE_LPTSTR *ppszDestEnd, size_t *pcbRemaining, STRSAFE_DWORD dwFlags);
230 STRSAFEAPI StringCxxGets(STRSAFE_LPTSTR pszDest, size_t cxDest);
231 STRSAFEAPI StringCxxGetsEx(STRSAFE_LPTSTR pszDest, size_t cxDest, STRSAFE_LPTSTR *ppszDestEnd, size_t *pcbRemaining, STRSAFE_DWORD dwFlags);
232 STRSAFEAPI StringCxxLength(STRSAFE_LPCTSTR psz, size_t cxMax, size_t *pcb);
233 STRSAFEAPI StringCxxPrintf(STRSAFE_LPTSTR pszDest, size_t cxDest, STRSAFE_LPCTSTR pszFormat, ...);
234 STRSAFEAPI StringCxxPrintfEx(STRSAFE_LPTSTR pszDest, size_t cxDest, STRSAFE_LPTSTR *ppszDestEnd, size_t *pcbRemaining, STRSAFE_DWORD dwFlags, STRSAFE_LPCTSTR pszFormat, ...);
235 STRSAFEAPI StringCxxVPrintf(STRSAFE_LPTSTR pszDest, size_t cxDest, STRSAFE_LPCTSTR pszFormat, va_list args);
236 STRSAFEAPI StringCxxVPrintfEx(STRSAFE_LPTSTR pszDest, size_t cxDest, STRSAFE_LPTSTR *ppszDestEnd, size_t *pcbRemaining, STRSAFE_DWORD dwFlags, LPCTSTR pszFormat, va_list args);
237
238 #else // !STRSAFE_LIB
239
240 /* Create inlined versions */
241 #define STRSAFEAPI HRESULT static __inline__
242
243 #define STRSAFE_MAX_CXX STRSAFE_CCHtoCXX(STRSAFE_MAX_CCH)
244
245 STRSAFEAPI
246 StringCxxCatWorker(
247 STRSAFE_LPTSTR pszDest,
248 size_t cxDest,
249 STRSAFE_LPCTSTR pszSrc,
250 size_t cxMaxAppend,
251 STRSAFE_LPTSTR *ppszDestEnd,
252 size_t *pcbRemaining,
253 STRSAFE_DWORD dwFlags,
254 int UseN)
255 {
256 HRESULT result;
257 STRSAFE_LPTSTR psz = pszDest;
258 size_t cch = STRSAFE_CXXtoCCH(cxDest);
259
260 if (!pszDest || !pszSrc || cxDest > STRSAFE_MAX_CXX || cxDest == 0)
261 {
262 return STRSAFE_E_INVALID_PARAMETER;
263 }
264
265 for (--psz; *(++psz) != 0 && --cch > 0;);
266 if (cch == 0)
267 {
268 return STRSAFE_E_INSUFFICIENT_BUFFER;
269 }
270
271 if (UseN)
272 {
273 cch = STRSAFE_MIN(cxDest, STRSAFE_CXXtoCCH(cxMaxAppend));
274 }
275
276 for (--pszSrc, --psz; (*(++psz) = *(++pszSrc)) != 0 && --cch > 0;);
277 if (cch == 0)
278 {
279 result = STRSAFE_E_INSUFFICIENT_BUFFER;
280 }
281 else
282 result = S_OK;
283
284 if (ppszDestEnd)
285 {
286 *ppszDestEnd = psz;
287 }
288
289 if (pcbRemaining)
290 {
291 *pcbRemaining = STRSAFE_CCHtoCXX(cch);
292 }
293
294 if (dwFlags & STRSAFE_FILL_BEHIND_NULL)
295 {
296 for (--psz, ++cch; --cch; *(++psz) = dwFlags & 0xff);
297 }
298
299 if (!SUCCEEDED(result))
300 {
301 if (dwFlags & STRSAFE_FILL_ON_FAILURE)
302 {
303 cch = STRSAFE_CXXtoCCH(cxDest);
304 for (--pszDest, ++cch; --cch; *(++pszDest) = dwFlags & 0xff);
305 }
306
307 if (dwFlags & STRSAFE_NULL_ON_FAILURE)
308 {
309 *pszDest = 0;
310 }
311 }
312
313 return result;
314 }
315
316 STRSAFEAPI
317 StringCxxCatEx(
318 STRSAFE_LPTSTR pszDest,
319 size_t cxDest,
320 STRSAFE_LPCTSTR pszSrc,
321 STRSAFE_LPTSTR *ppszDestEnd,
322 size_t *pcbRemaining,
323 STRSAFE_DWORD dwFlags)
324 {
325 return StringCxxCatWorker(pszDest, cxDest, pszSrc, 0, ppszDestEnd, pcbRemaining, dwFlags, 0);
326 }
327
328 STRSAFEAPI
329 StringCxxCat(
330 STRSAFE_LPTSTR pszDest,
331 size_t cxDest,
332 STRSAFE_LPCTSTR pszSrc)
333 {
334 return StringCxxCatWorker(pszDest, cxDest, pszSrc, 0, NULL, NULL, 0, 0);
335 }
336
337 STRSAFEAPI
338 StringCxxCatN(
339 STRSAFE_LPTSTR pszDest,
340 size_t cxDest,
341 STRSAFE_LPCTSTR pszSrc,
342 size_t cbMaxAppend)
343 {
344 return StringCxxCatWorker(pszDest, cxDest, pszSrc, cbMaxAppend, NULL, NULL, 0, 1);
345 }
346
347 STRSAFEAPI
348 StringCxxCatNEx(
349 STRSAFE_LPTSTR pszDest,
350 size_t cxDest,
351 STRSAFE_LPCTSTR pszSrc,
352 size_t cbMaxAppend,
353 STRSAFE_LPTSTR *ppszDestEnd,
354 size_t *pcbRemaining,
355 STRSAFE_DWORD dwFlags)
356 {
357 return StringCxxCatWorker(pszDest, cxDest, pszSrc, cbMaxAppend, ppszDestEnd, pcbRemaining, dwFlags, 1);
358 }
359
360 STRSAFEAPI
361 StringCxxCopy(
362 STRSAFE_LPTSTR pszDest,
363 size_t cbDest,
364 STRSAFE_LPCTSTR pszSrc)
365 {
366 return 0; // FIXME
367 }
368
369 STRSAFEAPI
370 StringCxxCopyEx(
371 STRSAFE_LPTSTR pszDest,
372 size_t cbDest,
373 STRSAFE_LPCTSTR pszSrc,
374 STRSAFE_LPTSTR *ppszDestEnd,
375 size_t *pcbRemaining,
376 STRSAFE_DWORD dwFlags)
377 {
378 return 0; // FIXME
379 }
380
381 STRSAFEAPI
382 StringCxxCopyN(
383 STRSAFE_LPTSTR pszDest,
384 size_t cbDest,
385 STRSAFE_LPCTSTR pszSrc,
386 size_t cbSrc)
387 {
388 return 0; // FIXME
389 }
390
391 STRSAFEAPI
392 StringCxxCopyNEx(
393 STRSAFE_LPTSTR pszDest,
394 size_t cbDest,
395 STRSAFE_LPCTSTR pszSrc,
396 size_t cbSrc,
397 STRSAFE_LPTSTR *ppszDestEnd,
398 size_t *pcbRemaining,
399 STRSAFE_DWORD dwFlags)
400 {
401 return 0; // FIXME
402 }
403
404 STRSAFEAPI
405 StringCxxGets(
406 STRSAFE_LPTSTR pszDest,
407 size_t cbDest)
408 {
409 return 0; // FIXME
410 }
411
412 STRSAFEAPI
413 StringCxxGetsEx(
414 STRSAFE_LPTSTR pszDest,
415 size_t cbDest,
416 STRSAFE_LPTSTR *ppszDestEnd,
417 size_t *pcbRemaining,
418 STRSAFE_DWORD dwFlags)
419 {
420 return 0; // FIXME
421 }
422
423 STRSAFEAPI
424 StringCxxLength(
425 STRSAFE_LPCTSTR psz,
426 size_t cxMax,
427 size_t *pcx)
428 {
429 size_t cch = STRSAFE_CXXtoCCH(cxMax);
430
431 /* Default return on error */
432 if (pcx)
433 *pcx = 0;
434
435 if (!psz || cxMax > STRSAFE_MAX_CXX || cxMax == 0)
436 {
437 return STRSAFE_E_INVALID_PARAMETER;
438 }
439
440 for (--psz; *(++psz) != 0 && --cch > 0;);
441
442 if (cch == 0)
443 {
444 return STRSAFE_E_INVALID_PARAMETER;
445 }
446
447 if (pcx)
448 *pcx = cxMax - STRSAFE_CCHtoCXX(cch);
449
450 return S_OK;
451 }
452
453 STRSAFEAPI
454 StringCxxVPrintfEx(
455 STRSAFE_LPTSTR pszDest,
456 size_t cxDest,
457 STRSAFE_LPTSTR *ppszDestEnd,
458 size_t *pcxRemaining,
459 STRSAFE_DWORD dwFlags,
460 STRSAFE_LPCTSTR pszFormat,
461 va_list args)
462 {
463 size_t cchDest = STRSAFE_CXXtoCCH(cxDest);
464 size_t cchMax = cchDest - 1;
465 int iResult;
466 HRESULT hr;
467
468 if (dwFlags & STRSAFE_IGNORE_NULLS)
469 {
470 if (!pszDest) pszDest = (STRSAFE_LPTSTR)L"";
471 if (!pszFormat) pszFormat = (STRSAFE_LPTSTR)L"";
472 }
473
474 if (!pszDest || !pszFormat || cxDest > STRSAFE_MAX_CXX || cxDest == 0)
475 {
476 return STRSAFE_E_INVALID_PARAMETER;
477 }
478
479 #if (STRSAFE_USE_SECURE_CRT == 1)
480 iResult = _vsnprintf_sAW(pszDest, cchDest, cchMax, pszFormat, args);
481 #else
482 iResult = _vsnprintfAW(pszDest, cchMax, pszFormat, args);
483 #endif
484
485 hr = (iResult == -1) ? STRSAFE_E_INSUFFICIENT_BUFFER : S_OK;
486
487 if ((size_t)iResult >= cchMax)
488 {
489 pszDest[cchMax] = 0;
490 iResult = cchMax;
491 }
492
493 if (ppszDestEnd) *ppszDestEnd = pszDest + iResult;
494
495 if (pcxRemaining) *pcxRemaining = STRSAFE_CCHtoCXX(cchMax - iResult);
496
497 if (SUCCEEDED(hr))
498 {
499 if ((dwFlags & STRSAFE_FILL_BEHIND_NULL) && (iResult + 1 < cchMax))
500 {
501 memset(pszDest + iResult + 1,
502 dwFlags & 0xff,
503 (cchMax - iResult - 1) * sizeof(STRSAFE_TCHAR));
504 }
505 }
506 else
507 {
508 if (dwFlags & STRSAFE_FILL_ON_FAILURE)
509 {
510 memset(pszDest, dwFlags & 0xff, cchMax * sizeof(STRSAFE_TCHAR));
511 }
512 else if (dwFlags & STRSAFE_NULL_ON_FAILURE)
513 {
514 *pszDest = 0;
515 }
516 }
517
518 return hr;
519 }
520
521 STRSAFEAPI
522 StringCxxVPrintf(
523 STRSAFE_LPTSTR pszDest,
524 size_t cxDest,
525 STRSAFE_LPCTSTR pszFormat,
526 va_list args)
527 {
528 return StringCxxVPrintfEx(pszDest, cxDest, NULL, NULL, 0, pszFormat, args);
529 }
530
531 STRSAFEAPI
532 StringCxxPrintf(
533 STRSAFE_LPTSTR pszDest,
534 size_t cxDest,
535 STRSAFE_LPCTSTR pszFormat, ...)
536 {
537 HRESULT result;
538 va_list args;
539 va_start(args, pszFormat);
540 result = StringCxxVPrintf(pszDest, cxDest, pszFormat, args);
541 va_end(args);
542 return result;
543 }
544
545 STRSAFEAPI
546 StringCxxPrintfEx(
547 STRSAFE_LPTSTR pszDest,
548 size_t cxDest,
549 STRSAFE_LPTSTR *ppszDestEnd,
550 size_t *pcbRemaining,
551 STRSAFE_DWORD dwFlags,
552 STRSAFE_LPCTSTR pszFormat, ...)
553 {
554 HRESULT result;
555 va_list args;
556 va_start(args, pszFormat);
557 result = StringCxxVPrintfEx(pszDest, cxDest, ppszDestEnd, pcbRemaining, dwFlags, pszFormat, args);
558 va_end(args);
559 return result;
560 }
561
562 #endif // !STRSAFE_LIB
563
564 /* Functions are implemented or defined, clear #defines for next pass */
565 #undef StringCxxCat
566 #undef StringCxxCatEx
567 #undef StringCxxCatN
568 #undef StringCxxCatNEx
569 #undef StringCxxCatWorker
570 #undef StringCxxCopy
571 #undef StringCxxCopyEx
572 #undef StringCxxCopyN
573 #undef StringCxxCopyNEx
574 #undef StringCxxGets
575 #undef StringCxxGetsEx
576 #undef StringCxxLength
577 #undef StringCxxPrintf
578 #undef StringCxxPrintfEx
579 #undef StringCxxVPrintf
580 #undef StringCxxVPrintfEx
581
582 #undef StringCbCat
583 #undef StringCbCatEx
584 #undef StringCbCatN
585 #undef StringCbCatNEx
586 #undef StringCbCatWorker
587 #undef StringCbCopy
588 #undef StringCbCopyEx
589 #undef StringCbCopyN
590 #undef StringCbCopyNEx
591 #undef StringCbGets
592 #undef StringCbGetsEx
593 #undef StringCbLength
594 #undef StringCbPrintf
595 #undef StringCbPrintfEx
596 #undef StringCbVPrintf
597 #undef StringCbVPrintfEx
598 #undef StringCchCat
599 #undef StringCchCatEx
600 #undef StringCchCatN
601 #undef StringCchCatNEx
602 #undef StringCchCatWorker
603 #undef StringCchCopy
604 #undef StringCchCopyEx
605 #undef StringCchCopyN
606 #undef StringCchCopyNEx
607 #undef StringCchGets
608 #undef StringCchGetsEx
609 #undef StringCchLength
610 #undef StringCchPrintf
611 #undef StringCchPrintfEx
612 #undef StringCchVPrintf
613 #undef StringCchVPrintfEx
614 #undef _vsnprintfAW
615
616 #undef STRSAFE_LPTSTR
617 #undef STRSAFE_LPCTSTR
618 #undef STRSAFE_TCHAR
619
620 #undef STRSAFE_CXXtoCB
621 #undef STRSAFE_CBtoCXX
622 #undef STRSAFE_CXXtoCCH
623 #undef STRSAFE_CCHtoCXX
624
625 #endif // defined (STRSAFE_PASS2)
626