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
12 #define SUCCEEDED(Status) ((HRESULT)(Status) >= 0)
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)
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
26 #define S_OK ((HRESULT)0x00000000L)
29 #define STRSAFE_MIN(a,b) (((a) < (b))?(a):(b))
31 #ifndef _HRESULT_DEFINED
32 #define _HRESULT_DEFINED
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
;
44 /* Implement Cb functions for ansi and unicode */
45 #ifndef STRSAFE_NO_CB_FUNCTIONS
47 #define STRSAFE_UNICODE 0
49 #undef STRSAFE_UNICODE
50 #define STRSAFE_UNICODE 1
52 #undef STRSAFE_UNICODE
54 #endif // !STRSAFE_NO_CB_FUNCTIONS
56 /* Implement Cch functions for ansi and unicode */
57 #ifndef STRSAFE_NO_CCH_FUNCTIONS
58 #define STRSAFE_UNICODE 0
60 #undef STRSAFE_UNICODE
61 #define STRSAFE_UNICODE 1
63 #undef STRSAFE_UNICODE
64 #endif // !STRSAFE_NO_CCH_FUNCTIONS
68 /* Now define the functions depending on UNICODE */
70 # define STRSAFE_UNICODE 1
72 # define STRSAFE_UNICODE 0
75 #undef STRSAFE_UNICODE
77 #endif // !__STRSAFE_H_
79 /*****************************************************************************/
81 #if defined(STRSAFE_UNICODE)
82 #if (STRSAFE_UNICODE == 1)
84 #define STRSAFE_LPTSTR STRSAFE_LPWSTR
85 #define STRSAFE_LPCTSTR STRSAFE_LPCWSTR
86 #define STRSAFE_TCHAR wchar_t
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
122 #else // (STRSAFE_UNICODE != 1)
124 #define STRSAFE_LPTSTR STRSAFE_LPSTR
125 #define STRSAFE_LPCTSTR STRSAFE_LPCSTR
126 #define STRSAFE_TCHAR char
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
162 #endif // (STRSAFE_UNICODE != 1)
163 #endif // defined(STRSAFE_UNICODE)
165 /*****************************************************************************/
167 #if defined (STRSAFE_PASS2)
169 #if defined(STRSAFE_CB)
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
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
215 #endif // !STRSAFE_CB
219 /* Normal function prototypes only */
220 #define STRSAFEAPI HRESULT __stdcall
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
);
238 #else // !STRSAFE_LIB
240 /* Create inlined versions */
241 #define STRSAFEAPI HRESULT static __inline__
243 #define STRSAFE_MAX_CXX STRSAFE_CCHtoCXX(STRSAFE_MAX_CCH)
247 STRSAFE_LPTSTR pszDest
,
249 STRSAFE_LPCTSTR pszSrc
,
251 STRSAFE_LPTSTR
*ppszDestEnd
,
252 size_t *pcbRemaining
,
253 STRSAFE_DWORD dwFlags
,
257 STRSAFE_LPTSTR psz
= pszDest
;
258 size_t cch
= STRSAFE_CXXtoCCH(cxDest
);
260 if (!pszDest
|| !pszSrc
|| cxDest
> STRSAFE_MAX_CXX
|| cxDest
== 0)
262 return STRSAFE_E_INVALID_PARAMETER
;
265 for (--psz
; *(++psz
) != 0 && --cch
> 0;);
268 return STRSAFE_E_INSUFFICIENT_BUFFER
;
273 cch
= STRSAFE_MIN(cxDest
, STRSAFE_CXXtoCCH(cxMaxAppend
));
276 for (--pszSrc
, --psz
; (*(++psz
) = *(++pszSrc
)) != 0 && --cch
> 0;);
279 result
= STRSAFE_E_INSUFFICIENT_BUFFER
;
291 *pcbRemaining
= STRSAFE_CCHtoCXX(cch
);
294 if (dwFlags
& STRSAFE_FILL_BEHIND_NULL
)
296 for (--psz
, ++cch
; --cch
; *(++psz
) = dwFlags
& 0xff);
299 if (!SUCCEEDED(result
))
301 if (dwFlags
& STRSAFE_FILL_ON_FAILURE
)
303 cch
= STRSAFE_CXXtoCCH(cxDest
);
304 for (--pszDest
, ++cch
; --cch
; *(++pszDest
) = dwFlags
& 0xff);
307 if (dwFlags
& STRSAFE_NULL_ON_FAILURE
)
318 STRSAFE_LPTSTR pszDest
,
320 STRSAFE_LPCTSTR pszSrc
,
321 STRSAFE_LPTSTR
*ppszDestEnd
,
322 size_t *pcbRemaining
,
323 STRSAFE_DWORD dwFlags
)
325 return StringCxxCatWorker(pszDest
, cxDest
, pszSrc
, 0, ppszDestEnd
, pcbRemaining
, dwFlags
, 0);
330 STRSAFE_LPTSTR pszDest
,
332 STRSAFE_LPCTSTR pszSrc
)
334 return StringCxxCatWorker(pszDest
, cxDest
, pszSrc
, 0, NULL
, NULL
, 0, 0);
339 STRSAFE_LPTSTR pszDest
,
341 STRSAFE_LPCTSTR pszSrc
,
344 return StringCxxCatWorker(pszDest
, cxDest
, pszSrc
, cbMaxAppend
, NULL
, NULL
, 0, 1);
349 STRSAFE_LPTSTR pszDest
,
351 STRSAFE_LPCTSTR pszSrc
,
353 STRSAFE_LPTSTR
*ppszDestEnd
,
354 size_t *pcbRemaining
,
355 STRSAFE_DWORD dwFlags
)
357 return StringCxxCatWorker(pszDest
, cxDest
, pszSrc
, cbMaxAppend
, ppszDestEnd
, pcbRemaining
, dwFlags
, 1);
362 STRSAFE_LPTSTR pszDest
,
364 STRSAFE_LPCTSTR pszSrc
)
371 STRSAFE_LPTSTR pszDest
,
373 STRSAFE_LPCTSTR pszSrc
,
374 STRSAFE_LPTSTR
*ppszDestEnd
,
375 size_t *pcbRemaining
,
376 STRSAFE_DWORD dwFlags
)
383 STRSAFE_LPTSTR pszDest
,
385 STRSAFE_LPCTSTR pszSrc
,
393 STRSAFE_LPTSTR pszDest
,
395 STRSAFE_LPCTSTR pszSrc
,
397 STRSAFE_LPTSTR
*ppszDestEnd
,
398 size_t *pcbRemaining
,
399 STRSAFE_DWORD dwFlags
)
406 STRSAFE_LPTSTR pszDest
,
414 STRSAFE_LPTSTR pszDest
,
416 STRSAFE_LPTSTR
*ppszDestEnd
,
417 size_t *pcbRemaining
,
418 STRSAFE_DWORD dwFlags
)
429 size_t cch
= STRSAFE_CXXtoCCH(cxMax
);
431 /* Default return on error */
435 if (!psz
|| cxMax
> STRSAFE_MAX_CXX
|| cxMax
== 0)
437 return STRSAFE_E_INVALID_PARAMETER
;
440 for (--psz
; *(++psz
) != 0 && --cch
> 0;);
444 return STRSAFE_E_INVALID_PARAMETER
;
448 *pcx
= cxMax
- STRSAFE_CCHtoCXX(cch
);
455 STRSAFE_LPTSTR pszDest
,
457 STRSAFE_LPTSTR
*ppszDestEnd
,
458 size_t *pcxRemaining
,
459 STRSAFE_DWORD dwFlags
,
460 STRSAFE_LPCTSTR pszFormat
,
463 size_t cchDest
= STRSAFE_CXXtoCCH(cxDest
);
464 size_t cchMax
= cchDest
- 1;
468 if (dwFlags
& STRSAFE_IGNORE_NULLS
)
470 if (!pszDest
) pszDest
= (STRSAFE_LPTSTR
)L
"";
471 if (!pszFormat
) pszFormat
= (STRSAFE_LPTSTR
)L
"";
474 if (!pszDest
|| !pszFormat
|| cxDest
> STRSAFE_MAX_CXX
|| cxDest
== 0)
476 return STRSAFE_E_INVALID_PARAMETER
;
479 #if (STRSAFE_USE_SECURE_CRT == 1)
480 iResult
= _vsnprintf_sAW(pszDest
, cchDest
, cchMax
, pszFormat
, args
);
482 iResult
= _vsnprintfAW(pszDest
, cchMax
, pszFormat
, args
);
485 hr
= (iResult
== -1) ? STRSAFE_E_INSUFFICIENT_BUFFER
: S_OK
;
487 if ((size_t)iResult
>= cchMax
)
493 if (ppszDestEnd
) *ppszDestEnd
= pszDest
+ iResult
;
495 if (pcxRemaining
) *pcxRemaining
= STRSAFE_CCHtoCXX(cchMax
- iResult
);
499 if ((dwFlags
& STRSAFE_FILL_BEHIND_NULL
) && (iResult
+ 1 < cchMax
))
501 memset(pszDest
+ iResult
+ 1,
503 (cchMax
- iResult
- 1) * sizeof(STRSAFE_TCHAR
));
508 if (dwFlags
& STRSAFE_FILL_ON_FAILURE
)
510 memset(pszDest
, dwFlags
& 0xff, cchMax
* sizeof(STRSAFE_TCHAR
));
512 else if (dwFlags
& STRSAFE_NULL_ON_FAILURE
)
523 STRSAFE_LPTSTR pszDest
,
525 STRSAFE_LPCTSTR pszFormat
,
528 return StringCxxVPrintfEx(pszDest
, cxDest
, NULL
, NULL
, 0, pszFormat
, args
);
533 STRSAFE_LPTSTR pszDest
,
535 STRSAFE_LPCTSTR pszFormat
, ...)
539 va_start(args
, pszFormat
);
540 result
= StringCxxVPrintf(pszDest
, cxDest
, pszFormat
, args
);
547 STRSAFE_LPTSTR pszDest
,
549 STRSAFE_LPTSTR
*ppszDestEnd
,
550 size_t *pcbRemaining
,
551 STRSAFE_DWORD dwFlags
,
552 STRSAFE_LPCTSTR pszFormat
, ...)
556 va_start(args
, pszFormat
);
557 result
= StringCxxVPrintfEx(pszDest
, cxDest
, ppszDestEnd
, pcbRemaining
, dwFlags
, pszFormat
, args
);
562 #endif // !STRSAFE_LIB
564 /* Functions are implemented or defined, clear #defines for next pass */
566 #undef StringCxxCatEx
568 #undef StringCxxCatNEx
569 #undef StringCxxCatWorker
571 #undef StringCxxCopyEx
572 #undef StringCxxCopyN
573 #undef StringCxxCopyNEx
575 #undef StringCxxGetsEx
576 #undef StringCxxLength
577 #undef StringCxxPrintf
578 #undef StringCxxPrintfEx
579 #undef StringCxxVPrintf
580 #undef StringCxxVPrintfEx
585 #undef StringCbCatNEx
586 #undef StringCbCatWorker
588 #undef StringCbCopyEx
590 #undef StringCbCopyNEx
592 #undef StringCbGetsEx
593 #undef StringCbLength
594 #undef StringCbPrintf
595 #undef StringCbPrintfEx
596 #undef StringCbVPrintf
597 #undef StringCbVPrintfEx
599 #undef StringCchCatEx
601 #undef StringCchCatNEx
602 #undef StringCchCatWorker
604 #undef StringCchCopyEx
605 #undef StringCchCopyN
606 #undef StringCchCopyNEx
608 #undef StringCchGetsEx
609 #undef StringCchLength
610 #undef StringCchPrintf
611 #undef StringCchPrintfEx
612 #undef StringCchVPrintf
613 #undef StringCchVPrintfEx
616 #undef STRSAFE_LPTSTR
617 #undef STRSAFE_LPCTSTR
620 #undef STRSAFE_CXXtoCB
621 #undef STRSAFE_CBtoCXX
622 #undef STRSAFE_CXXtoCCH
623 #undef STRSAFE_CCHtoCXX
625 #endif // defined (STRSAFE_PASS2)