annotate lib/legacy_dx/strsafe.h @ 0:9c0607679772

init
author Ritor1
date Sat, 12 Jan 2013 09:45:18 +0600
parents
children
rev   line source
0
Ritor1
parents:
diff changeset
1 /******************************************************************
Ritor1
parents:
diff changeset
2 * *
Ritor1
parents:
diff changeset
3 * strsafe.h -- This module defines safer C library string *
Ritor1
parents:
diff changeset
4 * routine replacements. These are meant to make C *
Ritor1
parents:
diff changeset
5 * a bit more safe in reference to security and *
Ritor1
parents:
diff changeset
6 * robustness *
Ritor1
parents:
diff changeset
7 * *
Ritor1
parents:
diff changeset
8 * Copyright (c) Microsoft Corp. All rights reserved. *
Ritor1
parents:
diff changeset
9 * *
Ritor1
parents:
diff changeset
10 ******************************************************************/
Ritor1
parents:
diff changeset
11 #ifndef _STRSAFE_H_INCLUDED_
Ritor1
parents:
diff changeset
12 #define _STRSAFE_H_INCLUDED_
Ritor1
parents:
diff changeset
13 #pragma once
Ritor1
parents:
diff changeset
14
Ritor1
parents:
diff changeset
15 #include <stdio.h> // for _vsnprintf, _vsnwprintf, getc, getwc
Ritor1
parents:
diff changeset
16 #include <string.h> // for memset
Ritor1
parents:
diff changeset
17 #include <stdarg.h> // for va_start, etc.
Ritor1
parents:
diff changeset
18
Ritor1
parents:
diff changeset
19
Ritor1
parents:
diff changeset
20 #ifndef _SIZE_T_DEFINED
Ritor1
parents:
diff changeset
21 #ifdef _WIN64
Ritor1
parents:
diff changeset
22 typedef unsigned __int64 size_t;
Ritor1
parents:
diff changeset
23 #else
Ritor1
parents:
diff changeset
24 typedef __w64 unsigned int size_t;
Ritor1
parents:
diff changeset
25 #endif // !_WIN64
Ritor1
parents:
diff changeset
26 #define _SIZE_T_DEFINED
Ritor1
parents:
diff changeset
27 #endif // !_SIZE_T_DEFINED
Ritor1
parents:
diff changeset
28
Ritor1
parents:
diff changeset
29 #if !defined(_WCHAR_T_DEFINED) && !defined(_NATIVE_WCHAR_T_DEFINED)
Ritor1
parents:
diff changeset
30 typedef unsigned short wchar_t;
Ritor1
parents:
diff changeset
31 #define _WCHAR_T_DEFINED
Ritor1
parents:
diff changeset
32 #endif
Ritor1
parents:
diff changeset
33
Ritor1
parents:
diff changeset
34 #ifndef _HRESULT_DEFINED
Ritor1
parents:
diff changeset
35 #define _HRESULT_DEFINED
Ritor1
parents:
diff changeset
36 typedef long HRESULT;
Ritor1
parents:
diff changeset
37 #endif // !_HRESULT_DEFINED
Ritor1
parents:
diff changeset
38
Ritor1
parents:
diff changeset
39 #ifndef SUCCEEDED
Ritor1
parents:
diff changeset
40 #define SUCCEEDED(hr) ((HRESULT)(hr) >= 0)
Ritor1
parents:
diff changeset
41 #endif
Ritor1
parents:
diff changeset
42
Ritor1
parents:
diff changeset
43 #ifndef FAILED
Ritor1
parents:
diff changeset
44 #define FAILED(hr) ((HRESULT)(hr) < 0)
Ritor1
parents:
diff changeset
45 #endif
Ritor1
parents:
diff changeset
46
Ritor1
parents:
diff changeset
47 #ifndef S_OK
Ritor1
parents:
diff changeset
48 #define S_OK ((HRESULT)0x00000000L)
Ritor1
parents:
diff changeset
49 #endif
Ritor1
parents:
diff changeset
50
Ritor1
parents:
diff changeset
51 #ifdef __cplusplus
Ritor1
parents:
diff changeset
52 #define _STRSAFE_EXTERN_C extern "C"
Ritor1
parents:
diff changeset
53 #else
Ritor1
parents:
diff changeset
54 #define _STRSAFE_EXTERN_C extern
Ritor1
parents:
diff changeset
55 #endif
Ritor1
parents:
diff changeset
56
Ritor1
parents:
diff changeset
57 // If you do not want to use these functions inline (and instead want to link w/ strsafe.lib), then
Ritor1
parents:
diff changeset
58 // #define STRSAFE_LIB before including this header file.
Ritor1
parents:
diff changeset
59 #if defined(STRSAFE_LIB)
Ritor1
parents:
diff changeset
60 #define STRSAFEAPI _STRSAFE_EXTERN_C HRESULT __stdcall
Ritor1
parents:
diff changeset
61 #pragma comment(lib, "strsafe.lib")
Ritor1
parents:
diff changeset
62 #elif defined(STRSAFE_LIB_IMPL)
Ritor1
parents:
diff changeset
63 #define STRSAFEAPI _STRSAFE_EXTERN_C HRESULT __stdcall
Ritor1
parents:
diff changeset
64 #else
Ritor1
parents:
diff changeset
65 #define STRSAFEAPI __inline HRESULT __stdcall
Ritor1
parents:
diff changeset
66 #define STRSAFE_INLINE
Ritor1
parents:
diff changeset
67 #endif
Ritor1
parents:
diff changeset
68
Ritor1
parents:
diff changeset
69 // Some functions always run inline because they use stdin and we want to avoid building multiple
Ritor1
parents:
diff changeset
70 // versions of strsafe lib depending on if you use msvcrt, libcmt, etc.
Ritor1
parents:
diff changeset
71 #define STRSAFE_INLINE_API __inline HRESULT __stdcall
Ritor1
parents:
diff changeset
72
Ritor1
parents:
diff changeset
73 // The user can request no "Cb" or no "Cch" fuctions, but not both!
Ritor1
parents:
diff changeset
74 #if defined(STRSAFE_NO_CB_FUNCTIONS) && defined(STRSAFE_NO_CCH_FUNCTIONS)
Ritor1
parents:
diff changeset
75 #error cannot specify both STRSAFE_NO_CB_FUNCTIONS and STRSAFE_NO_CCH_FUNCTIONS !!
Ritor1
parents:
diff changeset
76 #endif
Ritor1
parents:
diff changeset
77
Ritor1
parents:
diff changeset
78 // This should only be defined when we are building strsafe.lib
Ritor1
parents:
diff changeset
79 #ifdef STRSAFE_LIB_IMPL
Ritor1
parents:
diff changeset
80 #define STRSAFE_INLINE
Ritor1
parents:
diff changeset
81 #endif
Ritor1
parents:
diff changeset
82
Ritor1
parents:
diff changeset
83
Ritor1
parents:
diff changeset
84 // If both strsafe.h and ntstrsafe.h are included, only use definitions from one.
Ritor1
parents:
diff changeset
85 #ifndef _NTSTRSAFE_H_INCLUDED_
Ritor1
parents:
diff changeset
86
Ritor1
parents:
diff changeset
87 #define STRSAFE_MAX_CCH 2147483647 // max # of characters we support (same as INT_MAX)
Ritor1
parents:
diff changeset
88
Ritor1
parents:
diff changeset
89 // Flags for controling the Ex functions
Ritor1
parents:
diff changeset
90 //
Ritor1
parents:
diff changeset
91 // STRSAFE_FILL_BYTE(0xFF) 0x000000FF // bottom byte specifies fill pattern
Ritor1
parents:
diff changeset
92 #define STRSAFE_IGNORE_NULLS 0x00000100 // treat null as TEXT("") -- don't fault on NULL buffers
Ritor1
parents:
diff changeset
93 #define STRSAFE_FILL_BEHIND_NULL 0x00000200 // fill in extra space behind the null terminator
Ritor1
parents:
diff changeset
94 #define STRSAFE_FILL_ON_FAILURE 0x00000400 // on failure, overwrite pszDest with fill pattern and null terminate it
Ritor1
parents:
diff changeset
95 #define STRSAFE_NULL_ON_FAILURE 0x00000800 // on failure, set *pszDest = TEXT('\0')
Ritor1
parents:
diff changeset
96 #define STRSAFE_NO_TRUNCATION 0x00001000 // instead of returning a truncated result, copy/append nothing to pszDest and null terminate it
Ritor1
parents:
diff changeset
97
Ritor1
parents:
diff changeset
98 #define STRSAFE_VALID_FLAGS (0x000000FF | STRSAFE_IGNORE_NULLS | STRSAFE_FILL_BEHIND_NULL | STRSAFE_FILL_ON_FAILURE | STRSAFE_NULL_ON_FAILURE | STRSAFE_NO_TRUNCATION)
Ritor1
parents:
diff changeset
99
Ritor1
parents:
diff changeset
100 // helper macro to set the fill character and specify buffer filling
Ritor1
parents:
diff changeset
101 #define STRSAFE_FILL_BYTE(x) ((unsigned long)((x & 0x000000FF) | STRSAFE_FILL_BEHIND_NULL))
Ritor1
parents:
diff changeset
102 #define STRSAFE_FAILURE_BYTE(x) ((unsigned long)((x & 0x000000FF) | STRSAFE_FILL_ON_FAILURE))
Ritor1
parents:
diff changeset
103
Ritor1
parents:
diff changeset
104 #define STRSAFE_GET_FILL_PATTERN(dwFlags) ((int)(dwFlags & 0x000000FF))
Ritor1
parents:
diff changeset
105
Ritor1
parents:
diff changeset
106 #endif // _NTSTRSAFE_H_INCLUDED_
Ritor1
parents:
diff changeset
107
Ritor1
parents:
diff changeset
108 // STRSAFE error return codes
Ritor1
parents:
diff changeset
109 //
Ritor1
parents:
diff changeset
110 #define STRSAFE_E_INSUFFICIENT_BUFFER ((HRESULT)0x8007007AL) // 0x7A = 122L = ERROR_INSUFFICIENT_BUFFER
Ritor1
parents:
diff changeset
111 #define STRSAFE_E_INVALID_PARAMETER ((HRESULT)0x80070057L) // 0x57 = 87L = ERROR_INVALID_PARAMETER
Ritor1
parents:
diff changeset
112 #define STRSAFE_E_END_OF_FILE ((HRESULT)0x80070026L) // 0x26 = 38L = ERROR_HANDLE_EOF
Ritor1
parents:
diff changeset
113
Ritor1
parents:
diff changeset
114 // prototypes for the worker functions
Ritor1
parents:
diff changeset
115 #ifdef STRSAFE_INLINE
Ritor1
parents:
diff changeset
116 STRSAFEAPI StringCopyWorkerA(char* pszDest, size_t cchDest, const char* pszSrc);
Ritor1
parents:
diff changeset
117 STRSAFEAPI StringCopyWorkerW(wchar_t* pszDest, size_t cchDest, const wchar_t* pszSrc);
Ritor1
parents:
diff changeset
118 STRSAFEAPI StringCopyExWorkerA(char* pszDest, size_t cchDest, size_t cbDest, const char* pszSrc, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags);
Ritor1
parents:
diff changeset
119 STRSAFEAPI StringCopyExWorkerW(wchar_t* pszDest, size_t cchDest, size_t cbDest, const wchar_t* pszSrc, wchar_t** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags);
Ritor1
parents:
diff changeset
120 STRSAFEAPI StringCopyNWorkerA(char* pszDest, size_t cchDest, const char* pszSrc, size_t cchSrc);
Ritor1
parents:
diff changeset
121 STRSAFEAPI StringCopyNWorkerW(wchar_t* pszDest, size_t cchDest, const wchar_t* pszSrc, size_t cchSrc);
Ritor1
parents:
diff changeset
122 STRSAFEAPI StringCopyNExWorkerA(char* pszDest, size_t cchDest, size_t cbDest, const char* pszSrc, size_t cchSrc, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags);
Ritor1
parents:
diff changeset
123 STRSAFEAPI StringCopyNExWorkerW(wchar_t* pszDest, size_t cchDest, size_t cbDest, const wchar_t* pszSrc, size_t cchSrc, wchar_t** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags);
Ritor1
parents:
diff changeset
124 STRSAFEAPI StringCatWorkerA(char* pszDest, size_t cchDest, const char* pszSrc);
Ritor1
parents:
diff changeset
125 STRSAFEAPI StringCatWorkerW(wchar_t* pszDest, size_t cchDest, const wchar_t* pszSrc);
Ritor1
parents:
diff changeset
126 STRSAFEAPI StringCatExWorkerA(char* pszDest, size_t cchDest, size_t cbDest, const char* pszSrc, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags);
Ritor1
parents:
diff changeset
127 STRSAFEAPI StringCatExWorkerW(wchar_t* pszDest, size_t cchDest, size_t cbDest, const wchar_t* pszSrc, wchar_t** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags);
Ritor1
parents:
diff changeset
128 STRSAFEAPI StringCatNWorkerA(char* pszDest, size_t cchDest, const char* pszSrc, size_t cchMaxAppend);
Ritor1
parents:
diff changeset
129 STRSAFEAPI StringCatNWorkerW(wchar_t* pszDest, size_t cchDest, const wchar_t* pszSrc, size_t cchMaxAppend);
Ritor1
parents:
diff changeset
130 STRSAFEAPI StringCatNExWorkerA(char* pszDest, size_t cchDest, size_t cbDest, const char* pszSrc, size_t cchMaxAppend, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags);
Ritor1
parents:
diff changeset
131 STRSAFEAPI StringCatNExWorkerW(wchar_t* pszDest, size_t cchDest, size_t cbDest, const wchar_t* pszSrc, size_t cchMaxAppend, wchar_t** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags);
Ritor1
parents:
diff changeset
132 STRSAFEAPI StringVPrintfWorkerA(char* pszDest, size_t cchDest, const char* pszFormat, va_list argList);
Ritor1
parents:
diff changeset
133 STRSAFEAPI StringVPrintfWorkerW(wchar_t* pszDest, size_t cchDest, const wchar_t* pszFormat, va_list argList);
Ritor1
parents:
diff changeset
134 STRSAFEAPI StringVPrintfExWorkerA(char* pszDest, size_t cchDest, size_t cbDest, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags, const char* pszFormat, va_list argList);
Ritor1
parents:
diff changeset
135 STRSAFEAPI StringVPrintfExWorkerW(wchar_t* pszDest, size_t cchDest, size_t cbDest, wchar_t** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags, const wchar_t* pszFormat, va_list argList);
Ritor1
parents:
diff changeset
136 STRSAFEAPI StringLengthWorkerA(const char* psz, size_t cchMax, size_t* pcch);
Ritor1
parents:
diff changeset
137 STRSAFEAPI StringLengthWorkerW(const wchar_t* psz, size_t cchMax, size_t* pcch);
Ritor1
parents:
diff changeset
138 #endif // STRSAFE_INLINE
Ritor1
parents:
diff changeset
139
Ritor1
parents:
diff changeset
140 #ifndef STRSAFE_LIB_IMPL
Ritor1
parents:
diff changeset
141 // these functions are always inline
Ritor1
parents:
diff changeset
142 STRSAFE_INLINE_API StringGetsExWorkerA(char* pszDest, size_t cchDest, size_t cbDest, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags);
Ritor1
parents:
diff changeset
143 STRSAFE_INLINE_API StringGetsExWorkerW(wchar_t* pszDest, size_t cchDest, size_t cbDest, wchar_t** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags);
Ritor1
parents:
diff changeset
144 #endif
Ritor1
parents:
diff changeset
145
Ritor1
parents:
diff changeset
146 #ifdef _NTSTRSAFE_H_INCLUDED_
Ritor1
parents:
diff changeset
147 #pragma warning(push)
Ritor1
parents:
diff changeset
148 #pragma warning(disable : 4995)
Ritor1
parents:
diff changeset
149 #endif // _NTSTRSAFE_H_INCLUDED_
Ritor1
parents:
diff changeset
150
Ritor1
parents:
diff changeset
151
Ritor1
parents:
diff changeset
152 #ifndef STRSAFE_NO_CCH_FUNCTIONS
Ritor1
parents:
diff changeset
153 /*++
Ritor1
parents:
diff changeset
154
Ritor1
parents:
diff changeset
155 STDAPI
Ritor1
parents:
diff changeset
156 StringCchCopy(
Ritor1
parents:
diff changeset
157 OUT LPTSTR pszDest,
Ritor1
parents:
diff changeset
158 IN size_t cchDest,
Ritor1
parents:
diff changeset
159 IN LPCTSTR pszSrc
Ritor1
parents:
diff changeset
160 );
Ritor1
parents:
diff changeset
161
Ritor1
parents:
diff changeset
162 Routine Description:
Ritor1
parents:
diff changeset
163
Ritor1
parents:
diff changeset
164 This routine is a safer version of the C built-in function 'strcpy'.
Ritor1
parents:
diff changeset
165 The size of the destination buffer (in characters) is a parameter and
Ritor1
parents:
diff changeset
166 this function will not write past the end of this buffer and it will
Ritor1
parents:
diff changeset
167 ALWAYS null terminate the destination buffer (unless it is zero length).
Ritor1
parents:
diff changeset
168
Ritor1
parents:
diff changeset
169 This routine is not a replacement for strncpy. That function will pad the
Ritor1
parents:
diff changeset
170 destination string with extra null termination characters if the count is
Ritor1
parents:
diff changeset
171 greater than the length of the source string, and it will fail to null
Ritor1
parents:
diff changeset
172 terminate the destination string if the source string length is greater
Ritor1
parents:
diff changeset
173 than or equal to the count. You can not blindly use this instead of strncpy:
Ritor1
parents:
diff changeset
174 it is common for code to use it to "patch" strings and you would introduce
Ritor1
parents:
diff changeset
175 errors if the code started null terminating in the middle of the string.
Ritor1
parents:
diff changeset
176
Ritor1
parents:
diff changeset
177 This function returns a hresult, and not a pointer. It returns
Ritor1
parents:
diff changeset
178 S_OK if the string was copied without truncation and null terminated,
Ritor1
parents:
diff changeset
179 otherwise it will return a failure code. In failure cases as much of
Ritor1
parents:
diff changeset
180 pszSrc will be copied to pszDest as possible, and pszDest will be null
Ritor1
parents:
diff changeset
181 terminated.
Ritor1
parents:
diff changeset
182
Ritor1
parents:
diff changeset
183 Arguments:
Ritor1
parents:
diff changeset
184
Ritor1
parents:
diff changeset
185 pszDest - destination string
Ritor1
parents:
diff changeset
186
Ritor1
parents:
diff changeset
187 cchDest - size of destination buffer in characters.
Ritor1
parents:
diff changeset
188 length must be = (_tcslen(src) + 1) to hold all of the
Ritor1
parents:
diff changeset
189 source including the null terminator
Ritor1
parents:
diff changeset
190
Ritor1
parents:
diff changeset
191 pszSrc - source string which must be null terminated
Ritor1
parents:
diff changeset
192
Ritor1
parents:
diff changeset
193 Notes:
Ritor1
parents:
diff changeset
194 Behavior is undefined if source and destination strings overlap.
Ritor1
parents:
diff changeset
195
Ritor1
parents:
diff changeset
196 pszDest and pszSrc should not be NULL. See StringCchCopyEx if you require
Ritor1
parents:
diff changeset
197 the handling of NULL values.
Ritor1
parents:
diff changeset
198
Ritor1
parents:
diff changeset
199 Return Value:
Ritor1
parents:
diff changeset
200
Ritor1
parents:
diff changeset
201 S_OK - if there was source data and it was all copied and the
Ritor1
parents:
diff changeset
202 resultant dest string was null terminated
Ritor1
parents:
diff changeset
203
Ritor1
parents:
diff changeset
204 failure - you can use the macro HRESULT_CODE() to get a win32
Ritor1
parents:
diff changeset
205 error code for all hresult failure cases
Ritor1
parents:
diff changeset
206
Ritor1
parents:
diff changeset
207 STRSAFE_E_INSUFFICIENT_BUFFER /
Ritor1
parents:
diff changeset
208 HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER
Ritor1
parents:
diff changeset
209 - this return value is an indication that the copy
Ritor1
parents:
diff changeset
210 operation failed due to insufficient space. When this
Ritor1
parents:
diff changeset
211 error occurs, the destination buffer is modified to
Ritor1
parents:
diff changeset
212 contain a truncated version of the ideal result and is
Ritor1
parents:
diff changeset
213 null terminated. This is useful for situations where
Ritor1
parents:
diff changeset
214 truncation is ok
Ritor1
parents:
diff changeset
215
Ritor1
parents:
diff changeset
216 It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the
Ritor1
parents:
diff changeset
217 return value of this function.
Ritor1
parents:
diff changeset
218
Ritor1
parents:
diff changeset
219 --*/
Ritor1
parents:
diff changeset
220
Ritor1
parents:
diff changeset
221 STRSAFEAPI StringCchCopyA(char* pszDest, size_t cchDest, const char* pszSrc);
Ritor1
parents:
diff changeset
222 STRSAFEAPI StringCchCopyW(wchar_t* pszDest, size_t cchDest, const wchar_t* pszSrc);
Ritor1
parents:
diff changeset
223 #ifdef UNICODE
Ritor1
parents:
diff changeset
224 #define StringCchCopy StringCchCopyW
Ritor1
parents:
diff changeset
225 #else
Ritor1
parents:
diff changeset
226 #define StringCchCopy StringCchCopyA
Ritor1
parents:
diff changeset
227 #endif // !UNICODE
Ritor1
parents:
diff changeset
228
Ritor1
parents:
diff changeset
229 #ifdef STRSAFE_INLINE
Ritor1
parents:
diff changeset
230 STRSAFEAPI StringCchCopyA(char* pszDest, size_t cchDest, const char* pszSrc)
Ritor1
parents:
diff changeset
231 {
Ritor1
parents:
diff changeset
232 HRESULT hr;
Ritor1
parents:
diff changeset
233
Ritor1
parents:
diff changeset
234 if (cchDest > STRSAFE_MAX_CCH)
Ritor1
parents:
diff changeset
235 {
Ritor1
parents:
diff changeset
236 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
237 }
Ritor1
parents:
diff changeset
238 else
Ritor1
parents:
diff changeset
239 {
Ritor1
parents:
diff changeset
240 hr = StringCopyWorkerA(pszDest, cchDest, pszSrc);
Ritor1
parents:
diff changeset
241 }
Ritor1
parents:
diff changeset
242
Ritor1
parents:
diff changeset
243 return hr;
Ritor1
parents:
diff changeset
244 }
Ritor1
parents:
diff changeset
245
Ritor1
parents:
diff changeset
246 STRSAFEAPI StringCchCopyW(wchar_t* pszDest, size_t cchDest, const wchar_t* pszSrc)
Ritor1
parents:
diff changeset
247 {
Ritor1
parents:
diff changeset
248 HRESULT hr;
Ritor1
parents:
diff changeset
249
Ritor1
parents:
diff changeset
250 if (cchDest > STRSAFE_MAX_CCH)
Ritor1
parents:
diff changeset
251 {
Ritor1
parents:
diff changeset
252 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
253 }
Ritor1
parents:
diff changeset
254 else
Ritor1
parents:
diff changeset
255 {
Ritor1
parents:
diff changeset
256 hr = StringCopyWorkerW(pszDest, cchDest, pszSrc);
Ritor1
parents:
diff changeset
257 }
Ritor1
parents:
diff changeset
258
Ritor1
parents:
diff changeset
259 return hr;
Ritor1
parents:
diff changeset
260 }
Ritor1
parents:
diff changeset
261 #endif // STRSAFE_INLINE
Ritor1
parents:
diff changeset
262 #endif // !STRSAFE_NO_CCH_FUNCTIONS
Ritor1
parents:
diff changeset
263
Ritor1
parents:
diff changeset
264
Ritor1
parents:
diff changeset
265 #ifndef STRSAFE_NO_CB_FUNCTIONS
Ritor1
parents:
diff changeset
266 /*++
Ritor1
parents:
diff changeset
267
Ritor1
parents:
diff changeset
268 STDAPI
Ritor1
parents:
diff changeset
269 StringCbCopy(
Ritor1
parents:
diff changeset
270 OUT LPTSTR pszDest,
Ritor1
parents:
diff changeset
271 IN size_t cbDest,
Ritor1
parents:
diff changeset
272 IN LPCTSTR pszSrc
Ritor1
parents:
diff changeset
273 );
Ritor1
parents:
diff changeset
274
Ritor1
parents:
diff changeset
275 Routine Description:
Ritor1
parents:
diff changeset
276
Ritor1
parents:
diff changeset
277 This routine is a safer version of the C built-in function 'strcpy'.
Ritor1
parents:
diff changeset
278 The size of the destination buffer (in bytes) is a parameter and this
Ritor1
parents:
diff changeset
279 function will not write past the end of this buffer and it will ALWAYS
Ritor1
parents:
diff changeset
280 null terminate the destination buffer (unless it is zero length).
Ritor1
parents:
diff changeset
281
Ritor1
parents:
diff changeset
282 This routine is not a replacement for strncpy. That function will pad the
Ritor1
parents:
diff changeset
283 destination string with extra null termination characters if the count is
Ritor1
parents:
diff changeset
284 greater than the length of the source string, and it will fail to null
Ritor1
parents:
diff changeset
285 terminate the destination string if the source string length is greater
Ritor1
parents:
diff changeset
286 than or equal to the count. You can not blindly use this instead of strncpy:
Ritor1
parents:
diff changeset
287 it is common for code to use it to "patch" strings and you would introduce
Ritor1
parents:
diff changeset
288 errors if the code started null terminating in the middle of the string.
Ritor1
parents:
diff changeset
289
Ritor1
parents:
diff changeset
290 This function returns a hresult, and not a pointer. It returns
Ritor1
parents:
diff changeset
291 S_OK if the string was copied without truncation and null terminated,
Ritor1
parents:
diff changeset
292 otherwise it will return a failure code. In failure cases as much of pszSrc
Ritor1
parents:
diff changeset
293 will be copied to pszDest as possible, and pszDest will be null terminated.
Ritor1
parents:
diff changeset
294
Ritor1
parents:
diff changeset
295 Arguments:
Ritor1
parents:
diff changeset
296
Ritor1
parents:
diff changeset
297 pszDest - destination string
Ritor1
parents:
diff changeset
298
Ritor1
parents:
diff changeset
299 cbDest - size of destination buffer in bytes.
Ritor1
parents:
diff changeset
300 length must be = ((_tcslen(src) + 1) * sizeof(TCHAR)) to
Ritor1
parents:
diff changeset
301 hold all of the source including the null terminator
Ritor1
parents:
diff changeset
302
Ritor1
parents:
diff changeset
303 pszSrc - source string which must be null terminated
Ritor1
parents:
diff changeset
304
Ritor1
parents:
diff changeset
305 Notes:
Ritor1
parents:
diff changeset
306 Behavior is undefined if source and destination strings overlap.
Ritor1
parents:
diff changeset
307
Ritor1
parents:
diff changeset
308 pszDest and pszSrc should not be NULL. See StringCbCopyEx if you require
Ritor1
parents:
diff changeset
309 the handling of NULL values.
Ritor1
parents:
diff changeset
310
Ritor1
parents:
diff changeset
311 Return Value:
Ritor1
parents:
diff changeset
312
Ritor1
parents:
diff changeset
313 S_OK - if there was source data and it was all copied and the
Ritor1
parents:
diff changeset
314 resultant dest string was null terminated
Ritor1
parents:
diff changeset
315
Ritor1
parents:
diff changeset
316 failure - you can use the macro HRESULT_CODE() to get a win32
Ritor1
parents:
diff changeset
317 error code for all hresult failure cases
Ritor1
parents:
diff changeset
318
Ritor1
parents:
diff changeset
319 STRSAFE_E_INSUFFICIENT_BUFFER /
Ritor1
parents:
diff changeset
320 HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER
Ritor1
parents:
diff changeset
321 - this return value is an indication that the copy
Ritor1
parents:
diff changeset
322 operation failed due to insufficient space. When this
Ritor1
parents:
diff changeset
323 error occurs, the destination buffer is modified to
Ritor1
parents:
diff changeset
324 contain a truncated version of the ideal result and is
Ritor1
parents:
diff changeset
325 null terminated. This is useful for situations where
Ritor1
parents:
diff changeset
326 truncation is ok
Ritor1
parents:
diff changeset
327
Ritor1
parents:
diff changeset
328 It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the
Ritor1
parents:
diff changeset
329 return value of this function.
Ritor1
parents:
diff changeset
330
Ritor1
parents:
diff changeset
331 --*/
Ritor1
parents:
diff changeset
332
Ritor1
parents:
diff changeset
333 STRSAFEAPI StringCbCopyA(char* pszDest, size_t cbDest, const char* pszSrc);
Ritor1
parents:
diff changeset
334 STRSAFEAPI StringCbCopyW(wchar_t* pszDest, size_t cbDest, const wchar_t* pszSrc);
Ritor1
parents:
diff changeset
335 #ifdef UNICODE
Ritor1
parents:
diff changeset
336 #define StringCbCopy StringCbCopyW
Ritor1
parents:
diff changeset
337 #else
Ritor1
parents:
diff changeset
338 #define StringCbCopy StringCbCopyA
Ritor1
parents:
diff changeset
339 #endif // !UNICODE
Ritor1
parents:
diff changeset
340
Ritor1
parents:
diff changeset
341 #ifdef STRSAFE_INLINE
Ritor1
parents:
diff changeset
342 STRSAFEAPI StringCbCopyA(char* pszDest, size_t cbDest, const char* pszSrc)
Ritor1
parents:
diff changeset
343 {
Ritor1
parents:
diff changeset
344 HRESULT hr;
Ritor1
parents:
diff changeset
345 size_t cchDest;
Ritor1
parents:
diff changeset
346
Ritor1
parents:
diff changeset
347 // convert to count of characters
Ritor1
parents:
diff changeset
348 cchDest = cbDest / sizeof(char);
Ritor1
parents:
diff changeset
349
Ritor1
parents:
diff changeset
350 if (cchDest > STRSAFE_MAX_CCH)
Ritor1
parents:
diff changeset
351 {
Ritor1
parents:
diff changeset
352 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
353 }
Ritor1
parents:
diff changeset
354 else
Ritor1
parents:
diff changeset
355 {
Ritor1
parents:
diff changeset
356 hr = StringCopyWorkerA(pszDest, cchDest, pszSrc);
Ritor1
parents:
diff changeset
357 }
Ritor1
parents:
diff changeset
358
Ritor1
parents:
diff changeset
359 return hr;
Ritor1
parents:
diff changeset
360 }
Ritor1
parents:
diff changeset
361
Ritor1
parents:
diff changeset
362 STRSAFEAPI StringCbCopyW(wchar_t* pszDest, size_t cbDest, const wchar_t* pszSrc)
Ritor1
parents:
diff changeset
363 {
Ritor1
parents:
diff changeset
364 HRESULT hr;
Ritor1
parents:
diff changeset
365 size_t cchDest;
Ritor1
parents:
diff changeset
366
Ritor1
parents:
diff changeset
367 // convert to count of characters
Ritor1
parents:
diff changeset
368 cchDest = cbDest / sizeof(wchar_t);
Ritor1
parents:
diff changeset
369
Ritor1
parents:
diff changeset
370 if (cchDest > STRSAFE_MAX_CCH)
Ritor1
parents:
diff changeset
371 {
Ritor1
parents:
diff changeset
372 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
373 }
Ritor1
parents:
diff changeset
374 else
Ritor1
parents:
diff changeset
375 {
Ritor1
parents:
diff changeset
376 hr = StringCopyWorkerW(pszDest, cchDest, pszSrc);
Ritor1
parents:
diff changeset
377 }
Ritor1
parents:
diff changeset
378
Ritor1
parents:
diff changeset
379 return hr;
Ritor1
parents:
diff changeset
380 }
Ritor1
parents:
diff changeset
381 #endif // STRSAFE_INLINE
Ritor1
parents:
diff changeset
382 #endif // !STRSAFE_NO_CB_FUNCTIONS
Ritor1
parents:
diff changeset
383
Ritor1
parents:
diff changeset
384
Ritor1
parents:
diff changeset
385 #ifndef STRSAFE_NO_CCH_FUNCTIONS
Ritor1
parents:
diff changeset
386 /*++
Ritor1
parents:
diff changeset
387
Ritor1
parents:
diff changeset
388 STDAPI
Ritor1
parents:
diff changeset
389 StringCchCopyEx(
Ritor1
parents:
diff changeset
390 OUT LPTSTR pszDest OPTIONAL,
Ritor1
parents:
diff changeset
391 IN size_t cchDest,
Ritor1
parents:
diff changeset
392 IN LPCTSTR pszSrc OPTIONAL,
Ritor1
parents:
diff changeset
393 OUT LPTSTR* ppszDestEnd OPTIONAL,
Ritor1
parents:
diff changeset
394 OUT size_t* pcchRemaining OPTIONAL,
Ritor1
parents:
diff changeset
395 IN DWORD dwFlags
Ritor1
parents:
diff changeset
396 );
Ritor1
parents:
diff changeset
397
Ritor1
parents:
diff changeset
398 Routine Description:
Ritor1
parents:
diff changeset
399
Ritor1
parents:
diff changeset
400 This routine is a safer version of the C built-in function 'strcpy' with
Ritor1
parents:
diff changeset
401 some additional parameters. In addition to functionality provided by
Ritor1
parents:
diff changeset
402 StringCchCopy, this routine also returns a pointer to the end of the
Ritor1
parents:
diff changeset
403 destination string and the number of characters left in the destination string
Ritor1
parents:
diff changeset
404 including the null terminator. The flags parameter allows additional controls.
Ritor1
parents:
diff changeset
405
Ritor1
parents:
diff changeset
406 Arguments:
Ritor1
parents:
diff changeset
407
Ritor1
parents:
diff changeset
408 pszDest - destination string
Ritor1
parents:
diff changeset
409
Ritor1
parents:
diff changeset
410 cchDest - size of destination buffer in characters.
Ritor1
parents:
diff changeset
411 length must be = (_tcslen(pszSrc) + 1) to hold all of
Ritor1
parents:
diff changeset
412 the source including the null terminator
Ritor1
parents:
diff changeset
413
Ritor1
parents:
diff changeset
414 pszSrc - source string which must be null terminated
Ritor1
parents:
diff changeset
415
Ritor1
parents:
diff changeset
416 ppszDestEnd - if ppszDestEnd is non-null, the function will return a
Ritor1
parents:
diff changeset
417 pointer to the end of the destination string. If the
Ritor1
parents:
diff changeset
418 function copied any data, the result will point to the
Ritor1
parents:
diff changeset
419 null termination character
Ritor1
parents:
diff changeset
420
Ritor1
parents:
diff changeset
421 pcchRemaining - if pcchRemaining is non-null, the function will return the
Ritor1
parents:
diff changeset
422 number of characters left in the destination string,
Ritor1
parents:
diff changeset
423 including the null terminator
Ritor1
parents:
diff changeset
424
Ritor1
parents:
diff changeset
425 dwFlags - controls some details of the string copy:
Ritor1
parents:
diff changeset
426
Ritor1
parents:
diff changeset
427 STRSAFE_FILL_BEHIND_NULL
Ritor1
parents:
diff changeset
428 if the function succeeds, the low byte of dwFlags will be
Ritor1
parents:
diff changeset
429 used to fill the uninitialize part of destination buffer
Ritor1
parents:
diff changeset
430 behind the null terminator
Ritor1
parents:
diff changeset
431
Ritor1
parents:
diff changeset
432 STRSAFE_IGNORE_NULLS
Ritor1
parents:
diff changeset
433 treat NULL string pointers like empty strings (TEXT("")).
Ritor1
parents:
diff changeset
434 this flag is useful for emulating functions like lstrcpy
Ritor1
parents:
diff changeset
435
Ritor1
parents:
diff changeset
436 STRSAFE_FILL_ON_FAILURE
Ritor1
parents:
diff changeset
437 if the function fails, the low byte of dwFlags will be
Ritor1
parents:
diff changeset
438 used to fill all of the destination buffer, and it will
Ritor1
parents:
diff changeset
439 be null terminated. This will overwrite any truncated
Ritor1
parents:
diff changeset
440 string returned when the failure is
Ritor1
parents:
diff changeset
441 STRSAFE_E_INSUFFICIENT_BUFFER
Ritor1
parents:
diff changeset
442
Ritor1
parents:
diff changeset
443 STRSAFE_NO_TRUNCATION /
Ritor1
parents:
diff changeset
444 STRSAFE_NULL_ON_FAILURE
Ritor1
parents:
diff changeset
445 if the function fails, the destination buffer will be set
Ritor1
parents:
diff changeset
446 to the empty string. This will overwrite any truncated string
Ritor1
parents:
diff changeset
447 returned when the failure is STRSAFE_E_INSUFFICIENT_BUFFER.
Ritor1
parents:
diff changeset
448
Ritor1
parents:
diff changeset
449 Notes:
Ritor1
parents:
diff changeset
450 Behavior is undefined if source and destination strings overlap.
Ritor1
parents:
diff changeset
451
Ritor1
parents:
diff changeset
452 pszDest and pszSrc should not be NULL unless the STRSAFE_IGNORE_NULLS flag
Ritor1
parents:
diff changeset
453 is specified. If STRSAFE_IGNORE_NULLS is passed, both pszDest and pszSrc
Ritor1
parents:
diff changeset
454 may be NULL. An error may still be returned even though NULLS are ignored
Ritor1
parents:
diff changeset
455 due to insufficient space.
Ritor1
parents:
diff changeset
456
Ritor1
parents:
diff changeset
457 Return Value:
Ritor1
parents:
diff changeset
458
Ritor1
parents:
diff changeset
459 S_OK - if there was source data and it was all copied and the
Ritor1
parents:
diff changeset
460 resultant dest string was null terminated
Ritor1
parents:
diff changeset
461
Ritor1
parents:
diff changeset
462 failure - you can use the macro HRESULT_CODE() to get a win32
Ritor1
parents:
diff changeset
463 error code for all hresult failure cases
Ritor1
parents:
diff changeset
464
Ritor1
parents:
diff changeset
465 STRSAFE_E_INSUFFICIENT_BUFFER /
Ritor1
parents:
diff changeset
466 HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER
Ritor1
parents:
diff changeset
467 - this return value is an indication that the copy
Ritor1
parents:
diff changeset
468 operation failed due to insufficient space. When this
Ritor1
parents:
diff changeset
469 error occurs, the destination buffer is modified to
Ritor1
parents:
diff changeset
470 contain a truncated version of the ideal result and is
Ritor1
parents:
diff changeset
471 null terminated. This is useful for situations where
Ritor1
parents:
diff changeset
472 truncation is ok.
Ritor1
parents:
diff changeset
473
Ritor1
parents:
diff changeset
474 It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the
Ritor1
parents:
diff changeset
475 return value of this function
Ritor1
parents:
diff changeset
476
Ritor1
parents:
diff changeset
477 --*/
Ritor1
parents:
diff changeset
478
Ritor1
parents:
diff changeset
479 STRSAFEAPI StringCchCopyExA(char* pszDest, size_t cchDest, const char* pszSrc, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags);
Ritor1
parents:
diff changeset
480 STRSAFEAPI StringCchCopyExW(wchar_t* pszDest, size_t cchDest, const wchar_t* pszSrc, wchar_t** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags);
Ritor1
parents:
diff changeset
481 #ifdef UNICODE
Ritor1
parents:
diff changeset
482 #define StringCchCopyEx StringCchCopyExW
Ritor1
parents:
diff changeset
483 #else
Ritor1
parents:
diff changeset
484 #define StringCchCopyEx StringCchCopyExA
Ritor1
parents:
diff changeset
485 #endif // !UNICODE
Ritor1
parents:
diff changeset
486
Ritor1
parents:
diff changeset
487 #ifdef STRSAFE_INLINE
Ritor1
parents:
diff changeset
488 STRSAFEAPI StringCchCopyExA(char* pszDest, size_t cchDest, const char* pszSrc, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags)
Ritor1
parents:
diff changeset
489 {
Ritor1
parents:
diff changeset
490 HRESULT hr;
Ritor1
parents:
diff changeset
491
Ritor1
parents:
diff changeset
492 if (cchDest > STRSAFE_MAX_CCH)
Ritor1
parents:
diff changeset
493 {
Ritor1
parents:
diff changeset
494 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
495 }
Ritor1
parents:
diff changeset
496 else
Ritor1
parents:
diff changeset
497 {
Ritor1
parents:
diff changeset
498 size_t cbDest;
Ritor1
parents:
diff changeset
499
Ritor1
parents:
diff changeset
500 // safe to multiply cchDest * sizeof(char) since cchDest < STRSAFE_MAX_CCH and sizeof(char) is 1
Ritor1
parents:
diff changeset
501 cbDest = cchDest * sizeof(char);
Ritor1
parents:
diff changeset
502
Ritor1
parents:
diff changeset
503 hr = StringCopyExWorkerA(pszDest, cchDest, cbDest, pszSrc, ppszDestEnd, pcchRemaining, dwFlags);
Ritor1
parents:
diff changeset
504 }
Ritor1
parents:
diff changeset
505
Ritor1
parents:
diff changeset
506 return hr;
Ritor1
parents:
diff changeset
507 }
Ritor1
parents:
diff changeset
508
Ritor1
parents:
diff changeset
509 STRSAFEAPI StringCchCopyExW(wchar_t* pszDest, size_t cchDest, const wchar_t* pszSrc, wchar_t** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags)
Ritor1
parents:
diff changeset
510 {
Ritor1
parents:
diff changeset
511 HRESULT hr;
Ritor1
parents:
diff changeset
512
Ritor1
parents:
diff changeset
513 if (cchDest > STRSAFE_MAX_CCH)
Ritor1
parents:
diff changeset
514 {
Ritor1
parents:
diff changeset
515 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
516 }
Ritor1
parents:
diff changeset
517 else
Ritor1
parents:
diff changeset
518 {
Ritor1
parents:
diff changeset
519 size_t cbDest;
Ritor1
parents:
diff changeset
520
Ritor1
parents:
diff changeset
521 // safe to multiply cchDest * sizeof(wchar_t) since cchDest < STRSAFE_MAX_CCH and sizeof(wchar_t) is 2
Ritor1
parents:
diff changeset
522 cbDest = cchDest * sizeof(wchar_t);
Ritor1
parents:
diff changeset
523
Ritor1
parents:
diff changeset
524 hr = StringCopyExWorkerW(pszDest, cchDest, cbDest, pszSrc, ppszDestEnd, pcchRemaining, dwFlags);
Ritor1
parents:
diff changeset
525 }
Ritor1
parents:
diff changeset
526
Ritor1
parents:
diff changeset
527 return hr;
Ritor1
parents:
diff changeset
528 }
Ritor1
parents:
diff changeset
529 #endif // STRSAFE_INLINE
Ritor1
parents:
diff changeset
530 #endif // !STRSAFE_NO_CCH_FUNCTIONS
Ritor1
parents:
diff changeset
531
Ritor1
parents:
diff changeset
532
Ritor1
parents:
diff changeset
533 #ifndef STRSAFE_NO_CB_FUNCTIONS
Ritor1
parents:
diff changeset
534 /*++
Ritor1
parents:
diff changeset
535
Ritor1
parents:
diff changeset
536 STDAPI
Ritor1
parents:
diff changeset
537 StringCbCopyEx(
Ritor1
parents:
diff changeset
538 OUT LPTSTR pszDest OPTIONAL,
Ritor1
parents:
diff changeset
539 IN size_t cbDest,
Ritor1
parents:
diff changeset
540 IN LPCTSTR pszSrc OPTIONAL,
Ritor1
parents:
diff changeset
541 OUT LPTSTR* ppszDestEnd OPTIONAL,
Ritor1
parents:
diff changeset
542 OUT size_t* pcbRemaining OPTIONAL,
Ritor1
parents:
diff changeset
543 IN DWORD dwFlags
Ritor1
parents:
diff changeset
544 );
Ritor1
parents:
diff changeset
545
Ritor1
parents:
diff changeset
546 Routine Description:
Ritor1
parents:
diff changeset
547
Ritor1
parents:
diff changeset
548 This routine is a safer version of the C built-in function 'strcpy' with
Ritor1
parents:
diff changeset
549 some additional parameters. In addition to functionality provided by
Ritor1
parents:
diff changeset
550 StringCbCopy, this routine also returns a pointer to the end of the
Ritor1
parents:
diff changeset
551 destination string and the number of bytes left in the destination string
Ritor1
parents:
diff changeset
552 including the null terminator. The flags parameter allows additional controls.
Ritor1
parents:
diff changeset
553
Ritor1
parents:
diff changeset
554 Arguments:
Ritor1
parents:
diff changeset
555
Ritor1
parents:
diff changeset
556 pszDest - destination string
Ritor1
parents:
diff changeset
557
Ritor1
parents:
diff changeset
558 cbDest - size of destination buffer in bytes.
Ritor1
parents:
diff changeset
559 length must be ((_tcslen(pszSrc) + 1) * sizeof(TCHAR)) to
Ritor1
parents:
diff changeset
560 hold all of the source including the null terminator
Ritor1
parents:
diff changeset
561
Ritor1
parents:
diff changeset
562 pszSrc - source string which must be null terminated
Ritor1
parents:
diff changeset
563
Ritor1
parents:
diff changeset
564 ppszDestEnd - if ppszDestEnd is non-null, the function will return a
Ritor1
parents:
diff changeset
565 pointer to the end of the destination string. If the
Ritor1
parents:
diff changeset
566 function copied any data, the result will point to the
Ritor1
parents:
diff changeset
567 null termination character
Ritor1
parents:
diff changeset
568
Ritor1
parents:
diff changeset
569 pcbRemaining - pcbRemaining is non-null,the function will return the
Ritor1
parents:
diff changeset
570 number of bytes left in the destination string,
Ritor1
parents:
diff changeset
571 including the null terminator
Ritor1
parents:
diff changeset
572
Ritor1
parents:
diff changeset
573 dwFlags - controls some details of the string copy:
Ritor1
parents:
diff changeset
574
Ritor1
parents:
diff changeset
575 STRSAFE_FILL_BEHIND_NULL
Ritor1
parents:
diff changeset
576 if the function succeeds, the low byte of dwFlags will be
Ritor1
parents:
diff changeset
577 used to fill the uninitialize part of destination buffer
Ritor1
parents:
diff changeset
578 behind the null terminator
Ritor1
parents:
diff changeset
579
Ritor1
parents:
diff changeset
580 STRSAFE_IGNORE_NULLS
Ritor1
parents:
diff changeset
581 treat NULL string pointers like empty strings (TEXT("")).
Ritor1
parents:
diff changeset
582 this flag is useful for emulating functions like lstrcpy
Ritor1
parents:
diff changeset
583
Ritor1
parents:
diff changeset
584 STRSAFE_FILL_ON_FAILURE
Ritor1
parents:
diff changeset
585 if the function fails, the low byte of dwFlags will be
Ritor1
parents:
diff changeset
586 used to fill all of the destination buffer, and it will
Ritor1
parents:
diff changeset
587 be null terminated. This will overwrite any truncated
Ritor1
parents:
diff changeset
588 string returned when the failure is
Ritor1
parents:
diff changeset
589 STRSAFE_E_INSUFFICIENT_BUFFER
Ritor1
parents:
diff changeset
590
Ritor1
parents:
diff changeset
591 STRSAFE_NO_TRUNCATION /
Ritor1
parents:
diff changeset
592 STRSAFE_NULL_ON_FAILURE
Ritor1
parents:
diff changeset
593 if the function fails, the destination buffer will be set
Ritor1
parents:
diff changeset
594 to the empty string. This will overwrite any truncated string
Ritor1
parents:
diff changeset
595 returned when the failure is STRSAFE_E_INSUFFICIENT_BUFFER.
Ritor1
parents:
diff changeset
596
Ritor1
parents:
diff changeset
597 Notes:
Ritor1
parents:
diff changeset
598 Behavior is undefined if source and destination strings overlap.
Ritor1
parents:
diff changeset
599
Ritor1
parents:
diff changeset
600 pszDest and pszSrc should not be NULL unless the STRSAFE_IGNORE_NULLS flag
Ritor1
parents:
diff changeset
601 is specified. If STRSAFE_IGNORE_NULLS is passed, both pszDest and pszSrc
Ritor1
parents:
diff changeset
602 may be NULL. An error may still be returned even though NULLS are ignored
Ritor1
parents:
diff changeset
603 due to insufficient space.
Ritor1
parents:
diff changeset
604
Ritor1
parents:
diff changeset
605 Return Value:
Ritor1
parents:
diff changeset
606
Ritor1
parents:
diff changeset
607 S_OK - if there was source data and it was all copied and the
Ritor1
parents:
diff changeset
608 resultant dest string was null terminated
Ritor1
parents:
diff changeset
609
Ritor1
parents:
diff changeset
610 failure - you can use the macro HRESULT_CODE() to get a win32
Ritor1
parents:
diff changeset
611 error code for all hresult failure cases
Ritor1
parents:
diff changeset
612
Ritor1
parents:
diff changeset
613 STRSAFE_E_INSUFFICIENT_BUFFER /
Ritor1
parents:
diff changeset
614 HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER
Ritor1
parents:
diff changeset
615 - this return value is an indication that the copy
Ritor1
parents:
diff changeset
616 operation failed due to insufficient space. When this
Ritor1
parents:
diff changeset
617 error occurs, the destination buffer is modified to
Ritor1
parents:
diff changeset
618 contain a truncated version of the ideal result and is
Ritor1
parents:
diff changeset
619 null terminated. This is useful for situations where
Ritor1
parents:
diff changeset
620 truncation is ok.
Ritor1
parents:
diff changeset
621
Ritor1
parents:
diff changeset
622 It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the
Ritor1
parents:
diff changeset
623 return value of this function
Ritor1
parents:
diff changeset
624
Ritor1
parents:
diff changeset
625 --*/
Ritor1
parents:
diff changeset
626
Ritor1
parents:
diff changeset
627 STRSAFEAPI StringCbCopyExA(char* pszDest, size_t cbDest, const char* pszSrc, char** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags);
Ritor1
parents:
diff changeset
628 STRSAFEAPI StringCbCopyExW(wchar_t* pszDest, size_t cbDest, const wchar_t* pszSrc, wchar_t** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags);
Ritor1
parents:
diff changeset
629 #ifdef UNICODE
Ritor1
parents:
diff changeset
630 #define StringCbCopyEx StringCbCopyExW
Ritor1
parents:
diff changeset
631 #else
Ritor1
parents:
diff changeset
632 #define StringCbCopyEx StringCbCopyExA
Ritor1
parents:
diff changeset
633 #endif // !UNICODE
Ritor1
parents:
diff changeset
634
Ritor1
parents:
diff changeset
635 #ifdef STRSAFE_INLINE
Ritor1
parents:
diff changeset
636 STRSAFEAPI StringCbCopyExA(char* pszDest, size_t cbDest, const char* pszSrc, char** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags)
Ritor1
parents:
diff changeset
637 {
Ritor1
parents:
diff changeset
638 HRESULT hr;
Ritor1
parents:
diff changeset
639 size_t cchDest;
Ritor1
parents:
diff changeset
640 size_t cchRemaining = 0;
Ritor1
parents:
diff changeset
641
Ritor1
parents:
diff changeset
642 cchDest = cbDest / sizeof(char);
Ritor1
parents:
diff changeset
643
Ritor1
parents:
diff changeset
644 if (cchDest > STRSAFE_MAX_CCH)
Ritor1
parents:
diff changeset
645 {
Ritor1
parents:
diff changeset
646 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
647 }
Ritor1
parents:
diff changeset
648 else
Ritor1
parents:
diff changeset
649 {
Ritor1
parents:
diff changeset
650 hr = StringCopyExWorkerA(pszDest, cchDest, cbDest, pszSrc, ppszDestEnd, &cchRemaining, dwFlags);
Ritor1
parents:
diff changeset
651 }
Ritor1
parents:
diff changeset
652
Ritor1
parents:
diff changeset
653 if (SUCCEEDED(hr) || (hr == STRSAFE_E_INSUFFICIENT_BUFFER))
Ritor1
parents:
diff changeset
654 {
Ritor1
parents:
diff changeset
655 if (pcbRemaining)
Ritor1
parents:
diff changeset
656 {
Ritor1
parents:
diff changeset
657 // safe to multiply cchRemaining * sizeof(char) since cchRemaining < STRSAFE_MAX_CCH and sizeof(char) is 1
Ritor1
parents:
diff changeset
658 *pcbRemaining = (cchRemaining * sizeof(char)) + (cbDest % sizeof(char));
Ritor1
parents:
diff changeset
659 }
Ritor1
parents:
diff changeset
660 }
Ritor1
parents:
diff changeset
661
Ritor1
parents:
diff changeset
662 return hr;
Ritor1
parents:
diff changeset
663 }
Ritor1
parents:
diff changeset
664
Ritor1
parents:
diff changeset
665 STRSAFEAPI StringCbCopyExW(wchar_t* pszDest, size_t cbDest, const wchar_t* pszSrc, wchar_t** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags)
Ritor1
parents:
diff changeset
666 {
Ritor1
parents:
diff changeset
667 HRESULT hr;
Ritor1
parents:
diff changeset
668 size_t cchDest;
Ritor1
parents:
diff changeset
669 size_t cchRemaining = 0;
Ritor1
parents:
diff changeset
670
Ritor1
parents:
diff changeset
671 cchDest = cbDest / sizeof(wchar_t);
Ritor1
parents:
diff changeset
672
Ritor1
parents:
diff changeset
673 if (cchDest > STRSAFE_MAX_CCH)
Ritor1
parents:
diff changeset
674 {
Ritor1
parents:
diff changeset
675 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
676 }
Ritor1
parents:
diff changeset
677 else
Ritor1
parents:
diff changeset
678 {
Ritor1
parents:
diff changeset
679 hr = StringCopyExWorkerW(pszDest, cchDest, cbDest, pszSrc, ppszDestEnd, &cchRemaining, dwFlags);
Ritor1
parents:
diff changeset
680 }
Ritor1
parents:
diff changeset
681
Ritor1
parents:
diff changeset
682 if (SUCCEEDED(hr) || (hr == STRSAFE_E_INSUFFICIENT_BUFFER))
Ritor1
parents:
diff changeset
683 {
Ritor1
parents:
diff changeset
684 if (pcbRemaining)
Ritor1
parents:
diff changeset
685 {
Ritor1
parents:
diff changeset
686 // safe to multiply cchRemaining * sizeof(wchar_t) since cchRemaining < STRSAFE_MAX_CCH and sizeof(wchar_t) is 2
Ritor1
parents:
diff changeset
687 *pcbRemaining = (cchRemaining * sizeof(wchar_t)) + (cbDest % sizeof(wchar_t));
Ritor1
parents:
diff changeset
688 }
Ritor1
parents:
diff changeset
689 }
Ritor1
parents:
diff changeset
690
Ritor1
parents:
diff changeset
691 return hr;
Ritor1
parents:
diff changeset
692 }
Ritor1
parents:
diff changeset
693 #endif // STRSAFE_INLINE
Ritor1
parents:
diff changeset
694 #endif // !STRSAFE_NO_CB_FUNCTIONS
Ritor1
parents:
diff changeset
695
Ritor1
parents:
diff changeset
696
Ritor1
parents:
diff changeset
697 #ifndef STRSAFE_NO_CCH_FUNCTIONS
Ritor1
parents:
diff changeset
698 /*++
Ritor1
parents:
diff changeset
699
Ritor1
parents:
diff changeset
700 STDAPI
Ritor1
parents:
diff changeset
701 StringCchCopyN(
Ritor1
parents:
diff changeset
702 OUT LPTSTR pszDest,
Ritor1
parents:
diff changeset
703 IN size_t cchDest,
Ritor1
parents:
diff changeset
704 IN LPCTSTR pszSrc,
Ritor1
parents:
diff changeset
705 IN size_t cchSrc
Ritor1
parents:
diff changeset
706 );
Ritor1
parents:
diff changeset
707
Ritor1
parents:
diff changeset
708 Routine Description:
Ritor1
parents:
diff changeset
709
Ritor1
parents:
diff changeset
710 This routine is a safer version of the C built-in function 'strncpy'.
Ritor1
parents:
diff changeset
711 The size of the destination buffer (in characters) is a parameter and
Ritor1
parents:
diff changeset
712 this function will not write past the end of this buffer and it will
Ritor1
parents:
diff changeset
713 ALWAYS null terminate the destination buffer (unless it is zero length).
Ritor1
parents:
diff changeset
714
Ritor1
parents:
diff changeset
715 This routine is meant as a replacement for strncpy, but it does behave
Ritor1
parents:
diff changeset
716 differently. This function will not pad the destination buffer with extra
Ritor1
parents:
diff changeset
717 null termination characters if cchSrc is greater than the length of pszSrc.
Ritor1
parents:
diff changeset
718
Ritor1
parents:
diff changeset
719 This function returns a hresult, and not a pointer. It returns
Ritor1
parents:
diff changeset
720 S_OK if the entire string or the first cchSrc characters were copied
Ritor1
parents:
diff changeset
721 without truncation and the resultant destination string was null terminated,
Ritor1
parents:
diff changeset
722 otherwise it will return a failure code. In failure cases as much of pszSrc
Ritor1
parents:
diff changeset
723 will be copied to pszDest as possible, and pszDest will be null terminated.
Ritor1
parents:
diff changeset
724
Ritor1
parents:
diff changeset
725 Arguments:
Ritor1
parents:
diff changeset
726
Ritor1
parents:
diff changeset
727 pszDest - destination string
Ritor1
parents:
diff changeset
728
Ritor1
parents:
diff changeset
729 cchDest - size of destination buffer in characters.
Ritor1
parents:
diff changeset
730 length must be = (_tcslen(src) + 1) to hold all of the
Ritor1
parents:
diff changeset
731 source including the null terminator
Ritor1
parents:
diff changeset
732
Ritor1
parents:
diff changeset
733 pszSrc - source string
Ritor1
parents:
diff changeset
734
Ritor1
parents:
diff changeset
735 cchSrc - maximum number of characters to copy from source string,
Ritor1
parents:
diff changeset
736 not including the null terminator.
Ritor1
parents:
diff changeset
737
Ritor1
parents:
diff changeset
738 Notes:
Ritor1
parents:
diff changeset
739 Behavior is undefined if source and destination strings overlap.
Ritor1
parents:
diff changeset
740
Ritor1
parents:
diff changeset
741 pszDest and pszSrc should not be NULL. See StringCchCopyNEx if you require
Ritor1
parents:
diff changeset
742 the handling of NULL values.
Ritor1
parents:
diff changeset
743
Ritor1
parents:
diff changeset
744 Return Value:
Ritor1
parents:
diff changeset
745
Ritor1
parents:
diff changeset
746 S_OK - if there was source data and it was all copied and the
Ritor1
parents:
diff changeset
747 resultant dest string was null terminated
Ritor1
parents:
diff changeset
748
Ritor1
parents:
diff changeset
749 failure - you can use the macro HRESULT_CODE() to get a win32
Ritor1
parents:
diff changeset
750 error code for all hresult failure cases
Ritor1
parents:
diff changeset
751
Ritor1
parents:
diff changeset
752 STRSAFE_E_INSUFFICIENT_BUFFER /
Ritor1
parents:
diff changeset
753 HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER
Ritor1
parents:
diff changeset
754 - this return value is an indication that the copy
Ritor1
parents:
diff changeset
755 operation failed due to insufficient space. When this
Ritor1
parents:
diff changeset
756 error occurs, the destination buffer is modified to
Ritor1
parents:
diff changeset
757 contain a truncated version of the ideal result and is
Ritor1
parents:
diff changeset
758 null terminated. This is useful for situations where
Ritor1
parents:
diff changeset
759 truncation is ok
Ritor1
parents:
diff changeset
760
Ritor1
parents:
diff changeset
761 It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the
Ritor1
parents:
diff changeset
762 return value of this function.
Ritor1
parents:
diff changeset
763
Ritor1
parents:
diff changeset
764 --*/
Ritor1
parents:
diff changeset
765
Ritor1
parents:
diff changeset
766 STRSAFEAPI StringCchCopyNA(char* pszDest, size_t cchDest, const char* pszSrc, size_t cchSrc);
Ritor1
parents:
diff changeset
767 STRSAFEAPI StringCchCopyNW(wchar_t* pszDest, size_t cchDest, const wchar_t* pszSrc, size_t cchSrc);
Ritor1
parents:
diff changeset
768 #ifdef UNICODE
Ritor1
parents:
diff changeset
769 #define StringCchCopyN StringCchCopyNW
Ritor1
parents:
diff changeset
770 #else
Ritor1
parents:
diff changeset
771 #define StringCchCopyN StringCchCopyNA
Ritor1
parents:
diff changeset
772 #endif // !UNICODE
Ritor1
parents:
diff changeset
773
Ritor1
parents:
diff changeset
774 #ifdef STRSAFE_INLINE
Ritor1
parents:
diff changeset
775 STRSAFEAPI StringCchCopyNA(char* pszDest, size_t cchDest, const char* pszSrc, size_t cchSrc)
Ritor1
parents:
diff changeset
776 {
Ritor1
parents:
diff changeset
777 HRESULT hr;
Ritor1
parents:
diff changeset
778
Ritor1
parents:
diff changeset
779 if ((cchDest > STRSAFE_MAX_CCH) ||
Ritor1
parents:
diff changeset
780 (cchSrc > STRSAFE_MAX_CCH))
Ritor1
parents:
diff changeset
781 {
Ritor1
parents:
diff changeset
782 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
783 }
Ritor1
parents:
diff changeset
784 else
Ritor1
parents:
diff changeset
785 {
Ritor1
parents:
diff changeset
786 hr = StringCopyNWorkerA(pszDest, cchDest, pszSrc, cchSrc);
Ritor1
parents:
diff changeset
787 }
Ritor1
parents:
diff changeset
788
Ritor1
parents:
diff changeset
789 return hr;
Ritor1
parents:
diff changeset
790 }
Ritor1
parents:
diff changeset
791
Ritor1
parents:
diff changeset
792 STRSAFEAPI StringCchCopyNW(wchar_t* pszDest, size_t cchDest, const wchar_t* pszSrc, size_t cchSrc)
Ritor1
parents:
diff changeset
793 {
Ritor1
parents:
diff changeset
794 HRESULT hr;
Ritor1
parents:
diff changeset
795
Ritor1
parents:
diff changeset
796 if ((cchDest > STRSAFE_MAX_CCH) ||
Ritor1
parents:
diff changeset
797 (cchSrc > STRSAFE_MAX_CCH))
Ritor1
parents:
diff changeset
798 {
Ritor1
parents:
diff changeset
799 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
800 }
Ritor1
parents:
diff changeset
801 else
Ritor1
parents:
diff changeset
802 {
Ritor1
parents:
diff changeset
803 hr = StringCopyNWorkerW(pszDest, cchDest, pszSrc, cchSrc);
Ritor1
parents:
diff changeset
804 }
Ritor1
parents:
diff changeset
805
Ritor1
parents:
diff changeset
806 return hr;
Ritor1
parents:
diff changeset
807 }
Ritor1
parents:
diff changeset
808 #endif // STRSAFE_INLINE
Ritor1
parents:
diff changeset
809 #endif // !STRSAFE_NO_CCH_FUNCTIONS
Ritor1
parents:
diff changeset
810
Ritor1
parents:
diff changeset
811
Ritor1
parents:
diff changeset
812 #ifndef STRSAFE_NO_CB_FUNCTIONS
Ritor1
parents:
diff changeset
813 /*++
Ritor1
parents:
diff changeset
814
Ritor1
parents:
diff changeset
815 STDAPI
Ritor1
parents:
diff changeset
816 StringCbCopyN(
Ritor1
parents:
diff changeset
817 OUT LPTSTR pszDest,
Ritor1
parents:
diff changeset
818 IN size_t cbDest,
Ritor1
parents:
diff changeset
819 IN LPCTSTR pszSrc,
Ritor1
parents:
diff changeset
820 IN size_t cbSrc
Ritor1
parents:
diff changeset
821 );
Ritor1
parents:
diff changeset
822
Ritor1
parents:
diff changeset
823 Routine Description:
Ritor1
parents:
diff changeset
824
Ritor1
parents:
diff changeset
825 This routine is a safer version of the C built-in function 'strncpy'.
Ritor1
parents:
diff changeset
826 The size of the destination buffer (in bytes) is a parameter and this
Ritor1
parents:
diff changeset
827 function will not write past the end of this buffer and it will ALWAYS
Ritor1
parents:
diff changeset
828 null terminate the destination buffer (unless it is zero length).
Ritor1
parents:
diff changeset
829
Ritor1
parents:
diff changeset
830 This routine is meant as a replacement for strncpy, but it does behave
Ritor1
parents:
diff changeset
831 differently. This function will not pad the destination buffer with extra
Ritor1
parents:
diff changeset
832 null termination characters if cbSrc is greater than the size of pszSrc.
Ritor1
parents:
diff changeset
833
Ritor1
parents:
diff changeset
834 This function returns a hresult, and not a pointer. It returns
Ritor1
parents:
diff changeset
835 S_OK if the entire string or the first cbSrc characters were
Ritor1
parents:
diff changeset
836 copied without truncation and the resultant destination string was null
Ritor1
parents:
diff changeset
837 terminated, otherwise it will return a failure code. In failure cases as
Ritor1
parents:
diff changeset
838 much of pszSrc will be copied to pszDest as possible, and pszDest will be
Ritor1
parents:
diff changeset
839 null terminated.
Ritor1
parents:
diff changeset
840
Ritor1
parents:
diff changeset
841 Arguments:
Ritor1
parents:
diff changeset
842
Ritor1
parents:
diff changeset
843 pszDest - destination string
Ritor1
parents:
diff changeset
844
Ritor1
parents:
diff changeset
845 cbDest - size of destination buffer in bytes.
Ritor1
parents:
diff changeset
846 length must be = ((_tcslen(src) + 1) * sizeof(TCHAR)) to
Ritor1
parents:
diff changeset
847 hold all of the source including the null terminator
Ritor1
parents:
diff changeset
848
Ritor1
parents:
diff changeset
849 pszSrc - source string
Ritor1
parents:
diff changeset
850
Ritor1
parents:
diff changeset
851 cbSrc - maximum number of bytes to copy from source string,
Ritor1
parents:
diff changeset
852 not including the null terminator.
Ritor1
parents:
diff changeset
853
Ritor1
parents:
diff changeset
854 Notes:
Ritor1
parents:
diff changeset
855 Behavior is undefined if source and destination strings overlap.
Ritor1
parents:
diff changeset
856
Ritor1
parents:
diff changeset
857 pszDest and pszSrc should not be NULL. See StringCbCopyEx if you require
Ritor1
parents:
diff changeset
858 the handling of NULL values.
Ritor1
parents:
diff changeset
859
Ritor1
parents:
diff changeset
860 Return Value:
Ritor1
parents:
diff changeset
861
Ritor1
parents:
diff changeset
862 S_OK - if there was source data and it was all copied and the
Ritor1
parents:
diff changeset
863 resultant dest string was null terminated
Ritor1
parents:
diff changeset
864
Ritor1
parents:
diff changeset
865 failure - you can use the macro HRESULT_CODE() to get a win32
Ritor1
parents:
diff changeset
866 error code for all hresult failure cases
Ritor1
parents:
diff changeset
867
Ritor1
parents:
diff changeset
868 STRSAFE_E_INSUFFICIENT_BUFFER /
Ritor1
parents:
diff changeset
869 HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER
Ritor1
parents:
diff changeset
870 - this return value is an indication that the copy
Ritor1
parents:
diff changeset
871 operation failed due to insufficient space. When this
Ritor1
parents:
diff changeset
872 error occurs, the destination buffer is modified to
Ritor1
parents:
diff changeset
873 contain a truncated version of the ideal result and is
Ritor1
parents:
diff changeset
874 null terminated. This is useful for situations where
Ritor1
parents:
diff changeset
875 truncation is ok
Ritor1
parents:
diff changeset
876
Ritor1
parents:
diff changeset
877 It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the
Ritor1
parents:
diff changeset
878 return value of this function.
Ritor1
parents:
diff changeset
879
Ritor1
parents:
diff changeset
880 --*/
Ritor1
parents:
diff changeset
881
Ritor1
parents:
diff changeset
882 STRSAFEAPI StringCbCopyNA(char* pszDest, size_t cbDest, const char* pszSrc, size_t cbSrc);
Ritor1
parents:
diff changeset
883 STRSAFEAPI StringCbCopyNW(wchar_t* pszDest, size_t cbDest, const wchar_t* pszSrc, size_t cbSrc);
Ritor1
parents:
diff changeset
884 #ifdef UNICODE
Ritor1
parents:
diff changeset
885 #define StringCbCopyN StringCbCopyNW
Ritor1
parents:
diff changeset
886 #else
Ritor1
parents:
diff changeset
887 #define StringCbCopyN StringCbCopyNA
Ritor1
parents:
diff changeset
888 #endif // !UNICODE
Ritor1
parents:
diff changeset
889
Ritor1
parents:
diff changeset
890 #ifdef STRSAFE_INLINE
Ritor1
parents:
diff changeset
891 STRSAFEAPI StringCbCopyNA(char* pszDest, size_t cbDest, const char* pszSrc, size_t cbSrc)
Ritor1
parents:
diff changeset
892 {
Ritor1
parents:
diff changeset
893 HRESULT hr;
Ritor1
parents:
diff changeset
894 size_t cchDest;
Ritor1
parents:
diff changeset
895 size_t cchSrc;
Ritor1
parents:
diff changeset
896
Ritor1
parents:
diff changeset
897 // convert to count of characters
Ritor1
parents:
diff changeset
898 cchDest = cbDest / sizeof(char);
Ritor1
parents:
diff changeset
899 cchSrc = cbSrc / sizeof(char);
Ritor1
parents:
diff changeset
900
Ritor1
parents:
diff changeset
901 if ((cchDest > STRSAFE_MAX_CCH) ||
Ritor1
parents:
diff changeset
902 (cchSrc > STRSAFE_MAX_CCH))
Ritor1
parents:
diff changeset
903 {
Ritor1
parents:
diff changeset
904 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
905 }
Ritor1
parents:
diff changeset
906 else
Ritor1
parents:
diff changeset
907 {
Ritor1
parents:
diff changeset
908 hr = StringCopyNWorkerA(pszDest, cchDest, pszSrc, cchSrc);
Ritor1
parents:
diff changeset
909 }
Ritor1
parents:
diff changeset
910
Ritor1
parents:
diff changeset
911 return hr;
Ritor1
parents:
diff changeset
912 }
Ritor1
parents:
diff changeset
913
Ritor1
parents:
diff changeset
914 STRSAFEAPI StringCbCopyNW(wchar_t* pszDest, size_t cbDest, const wchar_t* pszSrc, size_t cbSrc)
Ritor1
parents:
diff changeset
915 {
Ritor1
parents:
diff changeset
916 HRESULT hr;
Ritor1
parents:
diff changeset
917 size_t cchDest;
Ritor1
parents:
diff changeset
918 size_t cchSrc;
Ritor1
parents:
diff changeset
919
Ritor1
parents:
diff changeset
920 // convert to count of characters
Ritor1
parents:
diff changeset
921 cchDest = cbDest / sizeof(wchar_t);
Ritor1
parents:
diff changeset
922 cchSrc = cbSrc / sizeof(wchar_t);
Ritor1
parents:
diff changeset
923
Ritor1
parents:
diff changeset
924 if ((cchDest > STRSAFE_MAX_CCH) ||
Ritor1
parents:
diff changeset
925 (cchSrc > STRSAFE_MAX_CCH))
Ritor1
parents:
diff changeset
926 {
Ritor1
parents:
diff changeset
927 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
928 }
Ritor1
parents:
diff changeset
929 else
Ritor1
parents:
diff changeset
930 {
Ritor1
parents:
diff changeset
931 hr = StringCopyNWorkerW(pszDest, cchDest, pszSrc, cchSrc);
Ritor1
parents:
diff changeset
932 }
Ritor1
parents:
diff changeset
933
Ritor1
parents:
diff changeset
934 return hr;
Ritor1
parents:
diff changeset
935 }
Ritor1
parents:
diff changeset
936 #endif // STRSAFE_INLINE
Ritor1
parents:
diff changeset
937 #endif // !STRSAFE_NO_CB_FUNCTIONS
Ritor1
parents:
diff changeset
938
Ritor1
parents:
diff changeset
939
Ritor1
parents:
diff changeset
940 #ifndef STRSAFE_NO_CCH_FUNCTIONS
Ritor1
parents:
diff changeset
941 /*++
Ritor1
parents:
diff changeset
942
Ritor1
parents:
diff changeset
943 STDAPI
Ritor1
parents:
diff changeset
944 StringCchCopyNEx(
Ritor1
parents:
diff changeset
945 OUT LPTSTR pszDest OPTIONAL,
Ritor1
parents:
diff changeset
946 IN size_t cchDest,
Ritor1
parents:
diff changeset
947 IN LPCTSTR pszSrc OPTIONAL,
Ritor1
parents:
diff changeset
948 IN size_t cchSrc,
Ritor1
parents:
diff changeset
949 OUT LPTSTR* ppszDestEnd OPTIONAL,
Ritor1
parents:
diff changeset
950 OUT size_t* pcchRemaining OPTIONAL,
Ritor1
parents:
diff changeset
951 IN DWORD dwFlags
Ritor1
parents:
diff changeset
952 );
Ritor1
parents:
diff changeset
953
Ritor1
parents:
diff changeset
954 Routine Description:
Ritor1
parents:
diff changeset
955
Ritor1
parents:
diff changeset
956 This routine is a safer version of the C built-in function 'strncpy' with
Ritor1
parents:
diff changeset
957 some additional parameters. In addition to functionality provided by
Ritor1
parents:
diff changeset
958 StringCchCopyN, this routine also returns a pointer to the end of the
Ritor1
parents:
diff changeset
959 destination string and the number of characters left in the destination
Ritor1
parents:
diff changeset
960 string including the null terminator. The flags parameter allows
Ritor1
parents:
diff changeset
961 additional controls.
Ritor1
parents:
diff changeset
962
Ritor1
parents:
diff changeset
963 This routine is meant as a replacement for strncpy, but it does behave
Ritor1
parents:
diff changeset
964 differently. This function will not pad the destination buffer with extra
Ritor1
parents:
diff changeset
965 null termination characters if cchSrc is greater than the length of pszSrc.
Ritor1
parents:
diff changeset
966
Ritor1
parents:
diff changeset
967 Arguments:
Ritor1
parents:
diff changeset
968
Ritor1
parents:
diff changeset
969 pszDest - destination string
Ritor1
parents:
diff changeset
970
Ritor1
parents:
diff changeset
971 cchDest - size of destination buffer in characters.
Ritor1
parents:
diff changeset
972 length must be = (_tcslen(pszSrc) + 1) to hold all of
Ritor1
parents:
diff changeset
973 the source including the null terminator
Ritor1
parents:
diff changeset
974
Ritor1
parents:
diff changeset
975 pszSrc - source string
Ritor1
parents:
diff changeset
976
Ritor1
parents:
diff changeset
977 cchSrc - maximum number of characters to copy from the source
Ritor1
parents:
diff changeset
978 string
Ritor1
parents:
diff changeset
979
Ritor1
parents:
diff changeset
980 ppszDestEnd - if ppszDestEnd is non-null, the function will return a
Ritor1
parents:
diff changeset
981 pointer to the end of the destination string. If the
Ritor1
parents:
diff changeset
982 function copied any data, the result will point to the
Ritor1
parents:
diff changeset
983 null termination character
Ritor1
parents:
diff changeset
984
Ritor1
parents:
diff changeset
985 pcchRemaining - if pcchRemaining is non-null, the function will return the
Ritor1
parents:
diff changeset
986 number of characters left in the destination string,
Ritor1
parents:
diff changeset
987 including the null terminator
Ritor1
parents:
diff changeset
988
Ritor1
parents:
diff changeset
989 dwFlags - controls some details of the string copy:
Ritor1
parents:
diff changeset
990
Ritor1
parents:
diff changeset
991 STRSAFE_FILL_BEHIND_NULL
Ritor1
parents:
diff changeset
992 if the function succeeds, the low byte of dwFlags will be
Ritor1
parents:
diff changeset
993 used to fill the uninitialize part of destination buffer
Ritor1
parents:
diff changeset
994 behind the null terminator
Ritor1
parents:
diff changeset
995
Ritor1
parents:
diff changeset
996 STRSAFE_IGNORE_NULLS
Ritor1
parents:
diff changeset
997 treat NULL string pointers like empty strings (TEXT("")).
Ritor1
parents:
diff changeset
998 this flag is useful for emulating functions like lstrcpy
Ritor1
parents:
diff changeset
999
Ritor1
parents:
diff changeset
1000 STRSAFE_FILL_ON_FAILURE
Ritor1
parents:
diff changeset
1001 if the function fails, the low byte of dwFlags will be
Ritor1
parents:
diff changeset
1002 used to fill all of the destination buffer, and it will
Ritor1
parents:
diff changeset
1003 be null terminated. This will overwrite any truncated
Ritor1
parents:
diff changeset
1004 string returned when the failure is
Ritor1
parents:
diff changeset
1005 STRSAFE_E_INSUFFICIENT_BUFFER
Ritor1
parents:
diff changeset
1006
Ritor1
parents:
diff changeset
1007 STRSAFE_NO_TRUNCATION /
Ritor1
parents:
diff changeset
1008 STRSAFE_NULL_ON_FAILURE
Ritor1
parents:
diff changeset
1009 if the function fails, the destination buffer will be set
Ritor1
parents:
diff changeset
1010 to the empty string. This will overwrite any truncated string
Ritor1
parents:
diff changeset
1011 returned when the failure is STRSAFE_E_INSUFFICIENT_BUFFER.
Ritor1
parents:
diff changeset
1012
Ritor1
parents:
diff changeset
1013 Notes:
Ritor1
parents:
diff changeset
1014 Behavior is undefined if source and destination strings overlap.
Ritor1
parents:
diff changeset
1015
Ritor1
parents:
diff changeset
1016 pszDest and pszSrc should not be NULL unless the STRSAFE_IGNORE_NULLS flag
Ritor1
parents:
diff changeset
1017 is specified. If STRSAFE_IGNORE_NULLS is passed, both pszDest and pszSrc
Ritor1
parents:
diff changeset
1018 may be NULL. An error may still be returned even though NULLS are ignored
Ritor1
parents:
diff changeset
1019 due to insufficient space.
Ritor1
parents:
diff changeset
1020
Ritor1
parents:
diff changeset
1021 Return Value:
Ritor1
parents:
diff changeset
1022
Ritor1
parents:
diff changeset
1023 S_OK - if there was source data and it was all copied and the
Ritor1
parents:
diff changeset
1024 resultant dest string was null terminated
Ritor1
parents:
diff changeset
1025
Ritor1
parents:
diff changeset
1026 failure - you can use the macro HRESULT_CODE() to get a win32
Ritor1
parents:
diff changeset
1027 error code for all hresult failure cases
Ritor1
parents:
diff changeset
1028
Ritor1
parents:
diff changeset
1029 STRSAFE_E_INSUFFICIENT_BUFFER /
Ritor1
parents:
diff changeset
1030 HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER
Ritor1
parents:
diff changeset
1031 - this return value is an indication that the copy
Ritor1
parents:
diff changeset
1032 operation failed due to insufficient space. When this
Ritor1
parents:
diff changeset
1033 error occurs, the destination buffer is modified to
Ritor1
parents:
diff changeset
1034 contain a truncated version of the ideal result and is
Ritor1
parents:
diff changeset
1035 null terminated. This is useful for situations where
Ritor1
parents:
diff changeset
1036 truncation is ok.
Ritor1
parents:
diff changeset
1037
Ritor1
parents:
diff changeset
1038 It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the
Ritor1
parents:
diff changeset
1039 return value of this function
Ritor1
parents:
diff changeset
1040
Ritor1
parents:
diff changeset
1041 --*/
Ritor1
parents:
diff changeset
1042
Ritor1
parents:
diff changeset
1043 STRSAFEAPI StringCchCopyNExA(char* pszDest, size_t cchDest, const char* pszSrc, size_t cchSrc, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags);
Ritor1
parents:
diff changeset
1044 STRSAFEAPI StringCchCopyNExW(wchar_t* pszDest, size_t cchDest, const wchar_t* pszSrc, size_t cchSrc, wchar_t** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags);
Ritor1
parents:
diff changeset
1045 #ifdef UNICODE
Ritor1
parents:
diff changeset
1046 #define StringCchCopyNEx StringCchCopyNExW
Ritor1
parents:
diff changeset
1047 #else
Ritor1
parents:
diff changeset
1048 #define StringCchCopyNEx StringCchCopyNExA
Ritor1
parents:
diff changeset
1049 #endif // !UNICODE
Ritor1
parents:
diff changeset
1050
Ritor1
parents:
diff changeset
1051 #ifdef STRSAFE_INLINE
Ritor1
parents:
diff changeset
1052 STRSAFEAPI StringCchCopyNExA(char* pszDest, size_t cchDest, const char* pszSrc, size_t cchSrc, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags)
Ritor1
parents:
diff changeset
1053 {
Ritor1
parents:
diff changeset
1054 HRESULT hr;
Ritor1
parents:
diff changeset
1055
Ritor1
parents:
diff changeset
1056 if ((cchDest > STRSAFE_MAX_CCH) ||
Ritor1
parents:
diff changeset
1057 (cchSrc > STRSAFE_MAX_CCH))
Ritor1
parents:
diff changeset
1058 {
Ritor1
parents:
diff changeset
1059 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
1060 }
Ritor1
parents:
diff changeset
1061 else
Ritor1
parents:
diff changeset
1062 {
Ritor1
parents:
diff changeset
1063 size_t cbDest;
Ritor1
parents:
diff changeset
1064
Ritor1
parents:
diff changeset
1065 // safe to multiply cchDest * sizeof(char) since cchDest < STRSAFE_MAX_CCH and sizeof(char) is 1
Ritor1
parents:
diff changeset
1066 cbDest = cchDest * sizeof(char);
Ritor1
parents:
diff changeset
1067
Ritor1
parents:
diff changeset
1068 hr = StringCopyNExWorkerA(pszDest, cchDest, cbDest, pszSrc, cchSrc, ppszDestEnd, pcchRemaining, dwFlags);
Ritor1
parents:
diff changeset
1069 }
Ritor1
parents:
diff changeset
1070
Ritor1
parents:
diff changeset
1071 return hr;
Ritor1
parents:
diff changeset
1072 }
Ritor1
parents:
diff changeset
1073
Ritor1
parents:
diff changeset
1074 STRSAFEAPI StringCchCopyNExW(wchar_t* pszDest, size_t cchDest, const wchar_t* pszSrc, size_t cchSrc, wchar_t** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags)
Ritor1
parents:
diff changeset
1075 {
Ritor1
parents:
diff changeset
1076 HRESULT hr;
Ritor1
parents:
diff changeset
1077
Ritor1
parents:
diff changeset
1078 if ((cchDest > STRSAFE_MAX_CCH) ||
Ritor1
parents:
diff changeset
1079 (cchSrc > STRSAFE_MAX_CCH))
Ritor1
parents:
diff changeset
1080 {
Ritor1
parents:
diff changeset
1081 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
1082 }
Ritor1
parents:
diff changeset
1083 else
Ritor1
parents:
diff changeset
1084 {
Ritor1
parents:
diff changeset
1085 size_t cbDest;
Ritor1
parents:
diff changeset
1086
Ritor1
parents:
diff changeset
1087 // safe to multiply cchDest * sizeof(wchar_t) since cchDest < STRSAFE_MAX_CCH and sizeof(wchar_t) is 2
Ritor1
parents:
diff changeset
1088 cbDest = cchDest * sizeof(wchar_t);
Ritor1
parents:
diff changeset
1089
Ritor1
parents:
diff changeset
1090 hr = StringCopyNExWorkerW(pszDest, cchDest, cbDest, pszSrc, cchSrc, ppszDestEnd, pcchRemaining, dwFlags);
Ritor1
parents:
diff changeset
1091 }
Ritor1
parents:
diff changeset
1092
Ritor1
parents:
diff changeset
1093 return hr;
Ritor1
parents:
diff changeset
1094 }
Ritor1
parents:
diff changeset
1095 #endif // STRSAFE_INLINE
Ritor1
parents:
diff changeset
1096 #endif // !STRSAFE_NO_CCH_FUNCTIONS
Ritor1
parents:
diff changeset
1097
Ritor1
parents:
diff changeset
1098
Ritor1
parents:
diff changeset
1099 #ifndef STRSAFE_NO_CB_FUNCTIONS
Ritor1
parents:
diff changeset
1100 /*++
Ritor1
parents:
diff changeset
1101
Ritor1
parents:
diff changeset
1102 STDAPI
Ritor1
parents:
diff changeset
1103 StringCbCopyNEx(
Ritor1
parents:
diff changeset
1104 OUT LPTSTR pszDest OPTIONAL,
Ritor1
parents:
diff changeset
1105 IN size_t cbDest,
Ritor1
parents:
diff changeset
1106 IN LPCTSTR pszSrc OPTIONAL,
Ritor1
parents:
diff changeset
1107 IN size_t cbSrc,
Ritor1
parents:
diff changeset
1108 OUT LPTSTR* ppszDestEnd OPTIONAL,
Ritor1
parents:
diff changeset
1109 OUT size_t* pcbRemaining OPTIONAL,
Ritor1
parents:
diff changeset
1110 IN DWORD dwFlags
Ritor1
parents:
diff changeset
1111 );
Ritor1
parents:
diff changeset
1112
Ritor1
parents:
diff changeset
1113 Routine Description:
Ritor1
parents:
diff changeset
1114
Ritor1
parents:
diff changeset
1115 This routine is a safer version of the C built-in function 'strncpy' with
Ritor1
parents:
diff changeset
1116 some additional parameters. In addition to functionality provided by
Ritor1
parents:
diff changeset
1117 StringCbCopyN, this routine also returns a pointer to the end of the
Ritor1
parents:
diff changeset
1118 destination string and the number of bytes left in the destination string
Ritor1
parents:
diff changeset
1119 including the null terminator. The flags parameter allows additional controls.
Ritor1
parents:
diff changeset
1120
Ritor1
parents:
diff changeset
1121 This routine is meant as a replacement for strncpy, but it does behave
Ritor1
parents:
diff changeset
1122 differently. This function will not pad the destination buffer with extra
Ritor1
parents:
diff changeset
1123 null termination characters if cbSrc is greater than the size of pszSrc.
Ritor1
parents:
diff changeset
1124
Ritor1
parents:
diff changeset
1125 Arguments:
Ritor1
parents:
diff changeset
1126
Ritor1
parents:
diff changeset
1127 pszDest - destination string
Ritor1
parents:
diff changeset
1128
Ritor1
parents:
diff changeset
1129 cbDest - size of destination buffer in bytes.
Ritor1
parents:
diff changeset
1130 length must be ((_tcslen(pszSrc) + 1) * sizeof(TCHAR)) to
Ritor1
parents:
diff changeset
1131 hold all of the source including the null terminator
Ritor1
parents:
diff changeset
1132
Ritor1
parents:
diff changeset
1133 pszSrc - source string
Ritor1
parents:
diff changeset
1134
Ritor1
parents:
diff changeset
1135 cbSrc - maximum number of bytes to copy from source string
Ritor1
parents:
diff changeset
1136
Ritor1
parents:
diff changeset
1137 ppszDestEnd - if ppszDestEnd is non-null, the function will return a
Ritor1
parents:
diff changeset
1138 pointer to the end of the destination string. If the
Ritor1
parents:
diff changeset
1139 function copied any data, the result will point to the
Ritor1
parents:
diff changeset
1140 null termination character
Ritor1
parents:
diff changeset
1141
Ritor1
parents:
diff changeset
1142 pcbRemaining - pcbRemaining is non-null,the function will return the
Ritor1
parents:
diff changeset
1143 number of bytes left in the destination string,
Ritor1
parents:
diff changeset
1144 including the null terminator
Ritor1
parents:
diff changeset
1145
Ritor1
parents:
diff changeset
1146 dwFlags - controls some details of the string copy:
Ritor1
parents:
diff changeset
1147
Ritor1
parents:
diff changeset
1148 STRSAFE_FILL_BEHIND_NULL
Ritor1
parents:
diff changeset
1149 if the function succeeds, the low byte of dwFlags will be
Ritor1
parents:
diff changeset
1150 used to fill the uninitialize part of destination buffer
Ritor1
parents:
diff changeset
1151 behind the null terminator
Ritor1
parents:
diff changeset
1152
Ritor1
parents:
diff changeset
1153 STRSAFE_IGNORE_NULLS
Ritor1
parents:
diff changeset
1154 treat NULL string pointers like empty strings (TEXT("")).
Ritor1
parents:
diff changeset
1155 this flag is useful for emulating functions like lstrcpy
Ritor1
parents:
diff changeset
1156
Ritor1
parents:
diff changeset
1157 STRSAFE_FILL_ON_FAILURE
Ritor1
parents:
diff changeset
1158 if the function fails, the low byte of dwFlags will be
Ritor1
parents:
diff changeset
1159 used to fill all of the destination buffer, and it will
Ritor1
parents:
diff changeset
1160 be null terminated. This will overwrite any truncated
Ritor1
parents:
diff changeset
1161 string returned when the failure is
Ritor1
parents:
diff changeset
1162 STRSAFE_E_INSUFFICIENT_BUFFER
Ritor1
parents:
diff changeset
1163
Ritor1
parents:
diff changeset
1164 STRSAFE_NO_TRUNCATION /
Ritor1
parents:
diff changeset
1165 STRSAFE_NULL_ON_FAILURE
Ritor1
parents:
diff changeset
1166 if the function fails, the destination buffer will be set
Ritor1
parents:
diff changeset
1167 to the empty string. This will overwrite any truncated string
Ritor1
parents:
diff changeset
1168 returned when the failure is STRSAFE_E_INSUFFICIENT_BUFFER.
Ritor1
parents:
diff changeset
1169
Ritor1
parents:
diff changeset
1170 Notes:
Ritor1
parents:
diff changeset
1171 Behavior is undefined if source and destination strings overlap.
Ritor1
parents:
diff changeset
1172
Ritor1
parents:
diff changeset
1173 pszDest and pszSrc should not be NULL unless the STRSAFE_IGNORE_NULLS flag
Ritor1
parents:
diff changeset
1174 is specified. If STRSAFE_IGNORE_NULLS is passed, both pszDest and pszSrc
Ritor1
parents:
diff changeset
1175 may be NULL. An error may still be returned even though NULLS are ignored
Ritor1
parents:
diff changeset
1176 due to insufficient space.
Ritor1
parents:
diff changeset
1177
Ritor1
parents:
diff changeset
1178 Return Value:
Ritor1
parents:
diff changeset
1179
Ritor1
parents:
diff changeset
1180 S_OK - if there was source data and it was all copied and the
Ritor1
parents:
diff changeset
1181 resultant dest string was null terminated
Ritor1
parents:
diff changeset
1182
Ritor1
parents:
diff changeset
1183 failure - you can use the macro HRESULT_CODE() to get a win32
Ritor1
parents:
diff changeset
1184 error code for all hresult failure cases
Ritor1
parents:
diff changeset
1185
Ritor1
parents:
diff changeset
1186 STRSAFE_E_INSUFFICIENT_BUFFER /
Ritor1
parents:
diff changeset
1187 HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER
Ritor1
parents:
diff changeset
1188 - this return value is an indication that the copy
Ritor1
parents:
diff changeset
1189 operation failed due to insufficient space. When this
Ritor1
parents:
diff changeset
1190 error occurs, the destination buffer is modified to
Ritor1
parents:
diff changeset
1191 contain a truncated version of the ideal result and is
Ritor1
parents:
diff changeset
1192 null terminated. This is useful for situations where
Ritor1
parents:
diff changeset
1193 truncation is ok.
Ritor1
parents:
diff changeset
1194
Ritor1
parents:
diff changeset
1195 It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the
Ritor1
parents:
diff changeset
1196 return value of this function
Ritor1
parents:
diff changeset
1197
Ritor1
parents:
diff changeset
1198 --*/
Ritor1
parents:
diff changeset
1199
Ritor1
parents:
diff changeset
1200 STRSAFEAPI StringCbCopyNExA(char* pszDest, size_t cbDest, const char* pszSrc, size_t cbSrc, char** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags);
Ritor1
parents:
diff changeset
1201 STRSAFEAPI StringCbCopyNExW(wchar_t* pszDest, size_t cbDest, const wchar_t* pszSrc, size_t cbSrc, wchar_t** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags);
Ritor1
parents:
diff changeset
1202 #ifdef UNICODE
Ritor1
parents:
diff changeset
1203 #define StringCbCopyNEx StringCbCopyNExW
Ritor1
parents:
diff changeset
1204 #else
Ritor1
parents:
diff changeset
1205 #define StringCbCopyNEx StringCbCopyNExA
Ritor1
parents:
diff changeset
1206 #endif // !UNICODE
Ritor1
parents:
diff changeset
1207
Ritor1
parents:
diff changeset
1208 #ifdef STRSAFE_INLINE
Ritor1
parents:
diff changeset
1209 STRSAFEAPI StringCbCopyNExA(char* pszDest, size_t cbDest, const char* pszSrc, size_t cbSrc, char** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags)
Ritor1
parents:
diff changeset
1210 {
Ritor1
parents:
diff changeset
1211 HRESULT hr;
Ritor1
parents:
diff changeset
1212 size_t cchDest;
Ritor1
parents:
diff changeset
1213 size_t cchSrc;
Ritor1
parents:
diff changeset
1214 size_t cchRemaining = 0;
Ritor1
parents:
diff changeset
1215
Ritor1
parents:
diff changeset
1216 cchDest = cbDest / sizeof(char);
Ritor1
parents:
diff changeset
1217 cchSrc = cbSrc / sizeof(char);
Ritor1
parents:
diff changeset
1218
Ritor1
parents:
diff changeset
1219 if ((cchDest > STRSAFE_MAX_CCH) ||
Ritor1
parents:
diff changeset
1220 (cchSrc > STRSAFE_MAX_CCH))
Ritor1
parents:
diff changeset
1221 {
Ritor1
parents:
diff changeset
1222 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
1223 }
Ritor1
parents:
diff changeset
1224 else
Ritor1
parents:
diff changeset
1225 {
Ritor1
parents:
diff changeset
1226 hr = StringCopyNExWorkerA(pszDest, cchDest, cbDest, pszSrc, cchSrc, ppszDestEnd, &cchRemaining, dwFlags);
Ritor1
parents:
diff changeset
1227 }
Ritor1
parents:
diff changeset
1228
Ritor1
parents:
diff changeset
1229 if (SUCCEEDED(hr) || (hr == STRSAFE_E_INSUFFICIENT_BUFFER))
Ritor1
parents:
diff changeset
1230 {
Ritor1
parents:
diff changeset
1231 if (pcbRemaining)
Ritor1
parents:
diff changeset
1232 {
Ritor1
parents:
diff changeset
1233 // safe to multiply cchRemaining * sizeof(char) since cchRemaining < STRSAFE_MAX_CCH and sizeof(char) is 1
Ritor1
parents:
diff changeset
1234 *pcbRemaining = (cchRemaining * sizeof(char)) + (cbDest % sizeof(char));
Ritor1
parents:
diff changeset
1235 }
Ritor1
parents:
diff changeset
1236 }
Ritor1
parents:
diff changeset
1237
Ritor1
parents:
diff changeset
1238 return hr;
Ritor1
parents:
diff changeset
1239 }
Ritor1
parents:
diff changeset
1240
Ritor1
parents:
diff changeset
1241 STRSAFEAPI StringCbCopyNExW(wchar_t* pszDest, size_t cbDest, const wchar_t* pszSrc, size_t cbSrc, wchar_t** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags)
Ritor1
parents:
diff changeset
1242 {
Ritor1
parents:
diff changeset
1243 HRESULT hr;
Ritor1
parents:
diff changeset
1244 size_t cchDest;
Ritor1
parents:
diff changeset
1245 size_t cchSrc;
Ritor1
parents:
diff changeset
1246 size_t cchRemaining = 0;
Ritor1
parents:
diff changeset
1247
Ritor1
parents:
diff changeset
1248 cchDest = cbDest / sizeof(wchar_t);
Ritor1
parents:
diff changeset
1249 cchSrc = cbSrc / sizeof(wchar_t);
Ritor1
parents:
diff changeset
1250
Ritor1
parents:
diff changeset
1251 if ((cchDest > STRSAFE_MAX_CCH) ||
Ritor1
parents:
diff changeset
1252 (cchSrc > STRSAFE_MAX_CCH))
Ritor1
parents:
diff changeset
1253 {
Ritor1
parents:
diff changeset
1254 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
1255 }
Ritor1
parents:
diff changeset
1256 else
Ritor1
parents:
diff changeset
1257 {
Ritor1
parents:
diff changeset
1258 hr = StringCopyNExWorkerW(pszDest, cchDest, cbDest, pszSrc, cchSrc, ppszDestEnd, &cchRemaining, dwFlags);
Ritor1
parents:
diff changeset
1259 }
Ritor1
parents:
diff changeset
1260
Ritor1
parents:
diff changeset
1261 if (SUCCEEDED(hr) || (hr == STRSAFE_E_INSUFFICIENT_BUFFER))
Ritor1
parents:
diff changeset
1262 {
Ritor1
parents:
diff changeset
1263 if (pcbRemaining)
Ritor1
parents:
diff changeset
1264 {
Ritor1
parents:
diff changeset
1265 // safe to multiply cchRemaining * sizeof(wchar_t) since cchRemaining < STRSAFE_MAX_CCH and sizeof(wchar_t) is 2
Ritor1
parents:
diff changeset
1266 *pcbRemaining = (cchRemaining * sizeof(wchar_t)) + (cbDest % sizeof(wchar_t));
Ritor1
parents:
diff changeset
1267 }
Ritor1
parents:
diff changeset
1268 }
Ritor1
parents:
diff changeset
1269
Ritor1
parents:
diff changeset
1270 return hr;
Ritor1
parents:
diff changeset
1271 }
Ritor1
parents:
diff changeset
1272 #endif // STRSAFE_INLINE
Ritor1
parents:
diff changeset
1273 #endif // !STRSAFE_NO_CB_FUNCTIONS
Ritor1
parents:
diff changeset
1274
Ritor1
parents:
diff changeset
1275
Ritor1
parents:
diff changeset
1276 #ifndef STRSAFE_NO_CCH_FUNCTIONS
Ritor1
parents:
diff changeset
1277 /*++
Ritor1
parents:
diff changeset
1278
Ritor1
parents:
diff changeset
1279 STDAPI
Ritor1
parents:
diff changeset
1280 StringCchCat(
Ritor1
parents:
diff changeset
1281 IN OUT LPTSTR pszDest,
Ritor1
parents:
diff changeset
1282 IN size_t cchDest,
Ritor1
parents:
diff changeset
1283 IN LPCTSTR pszSrc
Ritor1
parents:
diff changeset
1284 );
Ritor1
parents:
diff changeset
1285
Ritor1
parents:
diff changeset
1286 Routine Description:
Ritor1
parents:
diff changeset
1287
Ritor1
parents:
diff changeset
1288 This routine is a safer version of the C built-in function 'strcat'.
Ritor1
parents:
diff changeset
1289 The size of the destination buffer (in characters) is a parameter and this
Ritor1
parents:
diff changeset
1290 function will not write past the end of this buffer and it will ALWAYS
Ritor1
parents:
diff changeset
1291 null terminate the destination buffer (unless it is zero length).
Ritor1
parents:
diff changeset
1292
Ritor1
parents:
diff changeset
1293 This function returns a hresult, and not a pointer. It returns
Ritor1
parents:
diff changeset
1294 S_OK if the string was concatenated without truncation and null terminated,
Ritor1
parents:
diff changeset
1295 otherwise it will return a failure code. In failure cases as much of pszSrc
Ritor1
parents:
diff changeset
1296 will be appended to pszDest as possible, and pszDest will be null
Ritor1
parents:
diff changeset
1297 terminated.
Ritor1
parents:
diff changeset
1298
Ritor1
parents:
diff changeset
1299 Arguments:
Ritor1
parents:
diff changeset
1300
Ritor1
parents:
diff changeset
1301 pszDest - destination string which must be null terminated
Ritor1
parents:
diff changeset
1302
Ritor1
parents:
diff changeset
1303 cchDest - size of destination buffer in characters.
Ritor1
parents:
diff changeset
1304 length must be = (_tcslen(pszDest) + _tcslen(pszSrc) + 1)
Ritor1
parents:
diff changeset
1305 to hold all of the combine string plus the null
Ritor1
parents:
diff changeset
1306 terminator
Ritor1
parents:
diff changeset
1307
Ritor1
parents:
diff changeset
1308 pszSrc - source string which must be null terminated
Ritor1
parents:
diff changeset
1309
Ritor1
parents:
diff changeset
1310 Notes:
Ritor1
parents:
diff changeset
1311 Behavior is undefined if source and destination strings overlap.
Ritor1
parents:
diff changeset
1312
Ritor1
parents:
diff changeset
1313 pszDest and pszSrc should not be NULL. See StringCchCatEx if you require
Ritor1
parents:
diff changeset
1314 the handling of NULL values.
Ritor1
parents:
diff changeset
1315
Ritor1
parents:
diff changeset
1316 Return Value:
Ritor1
parents:
diff changeset
1317
Ritor1
parents:
diff changeset
1318 S_OK - if there was source data and it was all concatenated and
Ritor1
parents:
diff changeset
1319 the resultant dest string was null terminated
Ritor1
parents:
diff changeset
1320
Ritor1
parents:
diff changeset
1321 failure - you can use the macro HRESULT_CODE() to get a win32
Ritor1
parents:
diff changeset
1322 error code for all hresult failure cases
Ritor1
parents:
diff changeset
1323
Ritor1
parents:
diff changeset
1324 STRSAFE_E_INSUFFICIENT_BUFFER /
Ritor1
parents:
diff changeset
1325 HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER
Ritor1
parents:
diff changeset
1326 - this return value is an indication that the operation
Ritor1
parents:
diff changeset
1327 failed due to insufficient space. When this error occurs,
Ritor1
parents:
diff changeset
1328 the destination buffer is modified to contain a truncated
Ritor1
parents:
diff changeset
1329 version of the ideal result and is null terminated. This
Ritor1
parents:
diff changeset
1330 is useful for situations where truncation is ok.
Ritor1
parents:
diff changeset
1331
Ritor1
parents:
diff changeset
1332 It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the
Ritor1
parents:
diff changeset
1333 return value of this function
Ritor1
parents:
diff changeset
1334
Ritor1
parents:
diff changeset
1335 --*/
Ritor1
parents:
diff changeset
1336
Ritor1
parents:
diff changeset
1337 STRSAFEAPI StringCchCatA(char* pszDest, size_t cchDest, const char* pszSrc);
Ritor1
parents:
diff changeset
1338 STRSAFEAPI StringCchCatW(wchar_t* pszDest, size_t cchDest, const wchar_t* pszSrc);
Ritor1
parents:
diff changeset
1339 #ifdef UNICODE
Ritor1
parents:
diff changeset
1340 #define StringCchCat StringCchCatW
Ritor1
parents:
diff changeset
1341 #else
Ritor1
parents:
diff changeset
1342 #define StringCchCat StringCchCatA
Ritor1
parents:
diff changeset
1343 #endif // !UNICODE
Ritor1
parents:
diff changeset
1344
Ritor1
parents:
diff changeset
1345 #ifdef STRSAFE_INLINE
Ritor1
parents:
diff changeset
1346 STRSAFEAPI StringCchCatA(char* pszDest, size_t cchDest, const char* pszSrc)
Ritor1
parents:
diff changeset
1347 {
Ritor1
parents:
diff changeset
1348 HRESULT hr;
Ritor1
parents:
diff changeset
1349
Ritor1
parents:
diff changeset
1350 if (cchDest > STRSAFE_MAX_CCH)
Ritor1
parents:
diff changeset
1351 {
Ritor1
parents:
diff changeset
1352 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
1353 }
Ritor1
parents:
diff changeset
1354 else
Ritor1
parents:
diff changeset
1355 {
Ritor1
parents:
diff changeset
1356 hr = StringCatWorkerA(pszDest, cchDest, pszSrc);
Ritor1
parents:
diff changeset
1357 }
Ritor1
parents:
diff changeset
1358
Ritor1
parents:
diff changeset
1359 return hr;
Ritor1
parents:
diff changeset
1360 }
Ritor1
parents:
diff changeset
1361
Ritor1
parents:
diff changeset
1362 STRSAFEAPI StringCchCatW(wchar_t* pszDest, size_t cchDest, const wchar_t* pszSrc)
Ritor1
parents:
diff changeset
1363 {
Ritor1
parents:
diff changeset
1364 HRESULT hr;
Ritor1
parents:
diff changeset
1365
Ritor1
parents:
diff changeset
1366 if (cchDest > STRSAFE_MAX_CCH)
Ritor1
parents:
diff changeset
1367 {
Ritor1
parents:
diff changeset
1368 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
1369 }
Ritor1
parents:
diff changeset
1370 else
Ritor1
parents:
diff changeset
1371 {
Ritor1
parents:
diff changeset
1372 hr = StringCatWorkerW(pszDest, cchDest, pszSrc);
Ritor1
parents:
diff changeset
1373 }
Ritor1
parents:
diff changeset
1374
Ritor1
parents:
diff changeset
1375 return hr;
Ritor1
parents:
diff changeset
1376 }
Ritor1
parents:
diff changeset
1377 #endif // STRSAFE_INLINE
Ritor1
parents:
diff changeset
1378 #endif // !STRSAFE_NO_CCH_FUNCTIONS
Ritor1
parents:
diff changeset
1379
Ritor1
parents:
diff changeset
1380
Ritor1
parents:
diff changeset
1381 #ifndef STRSAFE_NO_CB_FUNCTIONS
Ritor1
parents:
diff changeset
1382 /*++
Ritor1
parents:
diff changeset
1383
Ritor1
parents:
diff changeset
1384 STDAPI
Ritor1
parents:
diff changeset
1385 StringCbCat(
Ritor1
parents:
diff changeset
1386 IN OUT LPTSTR pszDest,
Ritor1
parents:
diff changeset
1387 IN size_t cbDest,
Ritor1
parents:
diff changeset
1388 IN LPCTSTR pszSrc
Ritor1
parents:
diff changeset
1389 );
Ritor1
parents:
diff changeset
1390
Ritor1
parents:
diff changeset
1391 Routine Description:
Ritor1
parents:
diff changeset
1392
Ritor1
parents:
diff changeset
1393 This routine is a safer version of the C built-in function 'strcat'.
Ritor1
parents:
diff changeset
1394 The size of the destination buffer (in bytes) is a parameter and this
Ritor1
parents:
diff changeset
1395 function will not write past the end of this buffer and it will ALWAYS
Ritor1
parents:
diff changeset
1396 null terminate the destination buffer (unless it is zero length).
Ritor1
parents:
diff changeset
1397
Ritor1
parents:
diff changeset
1398 This function returns a hresult, and not a pointer. It returns
Ritor1
parents:
diff changeset
1399 S_OK if the string was concatenated without truncation and null terminated,
Ritor1
parents:
diff changeset
1400 otherwise it will return a failure code. In failure cases as much of pszSrc
Ritor1
parents:
diff changeset
1401 will be appended to pszDest as possible, and pszDest will be null
Ritor1
parents:
diff changeset
1402 terminated.
Ritor1
parents:
diff changeset
1403
Ritor1
parents:
diff changeset
1404 Arguments:
Ritor1
parents:
diff changeset
1405
Ritor1
parents:
diff changeset
1406 pszDest - destination string which must be null terminated
Ritor1
parents:
diff changeset
1407
Ritor1
parents:
diff changeset
1408 cbDest - size of destination buffer in bytes.
Ritor1
parents:
diff changeset
1409 length must be = ((_tcslen(pszDest) + _tcslen(pszSrc) + 1) * sizeof(TCHAR)
Ritor1
parents:
diff changeset
1410 to hold all of the combine string plus the null
Ritor1
parents:
diff changeset
1411 terminator
Ritor1
parents:
diff changeset
1412
Ritor1
parents:
diff changeset
1413 pszSrc - source string which must be null terminated
Ritor1
parents:
diff changeset
1414
Ritor1
parents:
diff changeset
1415 Notes:
Ritor1
parents:
diff changeset
1416 Behavior is undefined if source and destination strings overlap.
Ritor1
parents:
diff changeset
1417
Ritor1
parents:
diff changeset
1418 pszDest and pszSrc should not be NULL. See StringCbCatEx if you require
Ritor1
parents:
diff changeset
1419 the handling of NULL values.
Ritor1
parents:
diff changeset
1420
Ritor1
parents:
diff changeset
1421 Return Value:
Ritor1
parents:
diff changeset
1422
Ritor1
parents:
diff changeset
1423 S_OK - if there was source data and it was all concatenated and
Ritor1
parents:
diff changeset
1424 the resultant dest string was null terminated
Ritor1
parents:
diff changeset
1425
Ritor1
parents:
diff changeset
1426 failure - you can use the macro HRESULT_CODE() to get a win32
Ritor1
parents:
diff changeset
1427 error code for all hresult failure cases
Ritor1
parents:
diff changeset
1428
Ritor1
parents:
diff changeset
1429 STRSAFE_E_INSUFFICIENT_BUFFER /
Ritor1
parents:
diff changeset
1430 HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER
Ritor1
parents:
diff changeset
1431 - this return value is an indication that the operation
Ritor1
parents:
diff changeset
1432 failed due to insufficient space. When this error occurs,
Ritor1
parents:
diff changeset
1433 the destination buffer is modified to contain a truncated
Ritor1
parents:
diff changeset
1434 version of the ideal result and is null terminated. This
Ritor1
parents:
diff changeset
1435 is useful for situations where truncation is ok.
Ritor1
parents:
diff changeset
1436
Ritor1
parents:
diff changeset
1437 It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the
Ritor1
parents:
diff changeset
1438 return value of this function
Ritor1
parents:
diff changeset
1439
Ritor1
parents:
diff changeset
1440 --*/
Ritor1
parents:
diff changeset
1441
Ritor1
parents:
diff changeset
1442 STRSAFEAPI StringCbCatA(char* pszDest, size_t cbDest, const char* pszSrc);
Ritor1
parents:
diff changeset
1443 STRSAFEAPI StringCbCatW(wchar_t* pszDest, size_t cbDest, const wchar_t* pszSrc);
Ritor1
parents:
diff changeset
1444 #ifdef UNICODE
Ritor1
parents:
diff changeset
1445 #define StringCbCat StringCbCatW
Ritor1
parents:
diff changeset
1446 #else
Ritor1
parents:
diff changeset
1447 #define StringCbCat StringCbCatA
Ritor1
parents:
diff changeset
1448 #endif // !UNICODE
Ritor1
parents:
diff changeset
1449
Ritor1
parents:
diff changeset
1450 #ifdef STRSAFE_INLINE
Ritor1
parents:
diff changeset
1451 STRSAFEAPI StringCbCatA(char* pszDest, size_t cbDest, const char* pszSrc)
Ritor1
parents:
diff changeset
1452 {
Ritor1
parents:
diff changeset
1453 HRESULT hr;
Ritor1
parents:
diff changeset
1454 size_t cchDest;
Ritor1
parents:
diff changeset
1455
Ritor1
parents:
diff changeset
1456 cchDest = cbDest / sizeof(char);
Ritor1
parents:
diff changeset
1457
Ritor1
parents:
diff changeset
1458 if (cchDest > STRSAFE_MAX_CCH)
Ritor1
parents:
diff changeset
1459 {
Ritor1
parents:
diff changeset
1460 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
1461 }
Ritor1
parents:
diff changeset
1462 else
Ritor1
parents:
diff changeset
1463 {
Ritor1
parents:
diff changeset
1464 hr = StringCatWorkerA(pszDest, cchDest, pszSrc);
Ritor1
parents:
diff changeset
1465 }
Ritor1
parents:
diff changeset
1466
Ritor1
parents:
diff changeset
1467 return hr;
Ritor1
parents:
diff changeset
1468 }
Ritor1
parents:
diff changeset
1469
Ritor1
parents:
diff changeset
1470 STRSAFEAPI StringCbCatW(wchar_t* pszDest, size_t cbDest, const wchar_t* pszSrc)
Ritor1
parents:
diff changeset
1471 {
Ritor1
parents:
diff changeset
1472 HRESULT hr;
Ritor1
parents:
diff changeset
1473 size_t cchDest;
Ritor1
parents:
diff changeset
1474
Ritor1
parents:
diff changeset
1475 cchDest = cbDest / sizeof(wchar_t);
Ritor1
parents:
diff changeset
1476
Ritor1
parents:
diff changeset
1477 if (cchDest > STRSAFE_MAX_CCH)
Ritor1
parents:
diff changeset
1478 {
Ritor1
parents:
diff changeset
1479 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
1480 }
Ritor1
parents:
diff changeset
1481 else
Ritor1
parents:
diff changeset
1482 {
Ritor1
parents:
diff changeset
1483 hr = StringCatWorkerW(pszDest, cchDest, pszSrc);
Ritor1
parents:
diff changeset
1484 }
Ritor1
parents:
diff changeset
1485
Ritor1
parents:
diff changeset
1486 return hr;
Ritor1
parents:
diff changeset
1487 }
Ritor1
parents:
diff changeset
1488 #endif // STRSAFE_INLINE
Ritor1
parents:
diff changeset
1489 #endif // !STRSAFE_NO_CB_FUNCTIONS
Ritor1
parents:
diff changeset
1490
Ritor1
parents:
diff changeset
1491
Ritor1
parents:
diff changeset
1492 #ifndef STRSAFE_NO_CCH_FUNCTIONS
Ritor1
parents:
diff changeset
1493 /*++
Ritor1
parents:
diff changeset
1494
Ritor1
parents:
diff changeset
1495 STDAPI
Ritor1
parents:
diff changeset
1496 StringCchCatEx(
Ritor1
parents:
diff changeset
1497 IN OUT LPTSTR pszDest OPTIONAL,
Ritor1
parents:
diff changeset
1498 IN size_t cchDest,
Ritor1
parents:
diff changeset
1499 IN LPCTSTR pszSrc OPTIONAL,
Ritor1
parents:
diff changeset
1500 OUT LPTSTR* ppszDestEnd OPTIONAL,
Ritor1
parents:
diff changeset
1501 OUT size_t* pcchRemaining OPTIONAL,
Ritor1
parents:
diff changeset
1502 IN DWORD dwFlags
Ritor1
parents:
diff changeset
1503 );
Ritor1
parents:
diff changeset
1504
Ritor1
parents:
diff changeset
1505 Routine Description:
Ritor1
parents:
diff changeset
1506
Ritor1
parents:
diff changeset
1507 This routine is a safer version of the C built-in function 'strcat' with
Ritor1
parents:
diff changeset
1508 some additional parameters. In addition to functionality provided by
Ritor1
parents:
diff changeset
1509 StringCchCat, this routine also returns a pointer to the end of the
Ritor1
parents:
diff changeset
1510 destination string and the number of characters left in the destination string
Ritor1
parents:
diff changeset
1511 including the null terminator. The flags parameter allows additional controls.
Ritor1
parents:
diff changeset
1512
Ritor1
parents:
diff changeset
1513 Arguments:
Ritor1
parents:
diff changeset
1514
Ritor1
parents:
diff changeset
1515 pszDest - destination string which must be null terminated
Ritor1
parents:
diff changeset
1516
Ritor1
parents:
diff changeset
1517 cchDest - size of destination buffer in characters
Ritor1
parents:
diff changeset
1518 length must be (_tcslen(pszDest) + _tcslen(pszSrc) + 1)
Ritor1
parents:
diff changeset
1519 to hold all of the combine string plus the null
Ritor1
parents:
diff changeset
1520 terminator.
Ritor1
parents:
diff changeset
1521
Ritor1
parents:
diff changeset
1522 pszSrc - source string which must be null terminated
Ritor1
parents:
diff changeset
1523
Ritor1
parents:
diff changeset
1524 ppszDestEnd - if ppszDestEnd is non-null, the function will return a
Ritor1
parents:
diff changeset
1525 pointer to the end of the destination string. If the
Ritor1
parents:
diff changeset
1526 function appended any data, the result will point to the
Ritor1
parents:
diff changeset
1527 null termination character
Ritor1
parents:
diff changeset
1528
Ritor1
parents:
diff changeset
1529 pcchRemaining - if pcchRemaining is non-null, the function will return the
Ritor1
parents:
diff changeset
1530 number of characters left in the destination string,
Ritor1
parents:
diff changeset
1531 including the null terminator
Ritor1
parents:
diff changeset
1532
Ritor1
parents:
diff changeset
1533 dwFlags - controls some details of the string copy:
Ritor1
parents:
diff changeset
1534
Ritor1
parents:
diff changeset
1535 STRSAFE_FILL_BEHIND_NULL
Ritor1
parents:
diff changeset
1536 if the function succeeds, the low byte of dwFlags will be
Ritor1
parents:
diff changeset
1537 used to fill the uninitialize part of destination buffer
Ritor1
parents:
diff changeset
1538 behind the null terminator
Ritor1
parents:
diff changeset
1539
Ritor1
parents:
diff changeset
1540 STRSAFE_IGNORE_NULLS
Ritor1
parents:
diff changeset
1541 treat NULL string pointers like empty strings (TEXT("")).
Ritor1
parents:
diff changeset
1542 this flag is useful for emulating functions like lstrcat
Ritor1
parents:
diff changeset
1543
Ritor1
parents:
diff changeset
1544 STRSAFE_FILL_ON_FAILURE
Ritor1
parents:
diff changeset
1545 if the function fails, the low byte of dwFlags will be
Ritor1
parents:
diff changeset
1546 used to fill all of the destination buffer, and it will
Ritor1
parents:
diff changeset
1547 be null terminated. This will overwrite any pre-existing
Ritor1
parents:
diff changeset
1548 or truncated string
Ritor1
parents:
diff changeset
1549
Ritor1
parents:
diff changeset
1550 STRSAFE_NULL_ON_FAILURE
Ritor1
parents:
diff changeset
1551 if the function fails, the destination buffer will be set
Ritor1
parents:
diff changeset
1552 to the empty string. This will overwrite any pre-existing or
Ritor1
parents:
diff changeset
1553 truncated string
Ritor1
parents:
diff changeset
1554
Ritor1
parents:
diff changeset
1555 STRSAFE_NO_TRUNCATION
Ritor1
parents:
diff changeset
1556 if the function returns STRSAFE_E_INSUFFICIENT_BUFFER, pszDest
Ritor1
parents:
diff changeset
1557 will not contain a truncated string, it will remain unchanged.
Ritor1
parents:
diff changeset
1558
Ritor1
parents:
diff changeset
1559 Notes:
Ritor1
parents:
diff changeset
1560 Behavior is undefined if source and destination strings overlap.
Ritor1
parents:
diff changeset
1561
Ritor1
parents:
diff changeset
1562 pszDest and pszSrc should not be NULL unless the STRSAFE_IGNORE_NULLS flag
Ritor1
parents:
diff changeset
1563 is specified. If STRSAFE_IGNORE_NULLS is passed, both pszDest and pszSrc
Ritor1
parents:
diff changeset
1564 may be NULL. An error may still be returned even though NULLS are ignored
Ritor1
parents:
diff changeset
1565 due to insufficient space.
Ritor1
parents:
diff changeset
1566
Ritor1
parents:
diff changeset
1567 Return Value:
Ritor1
parents:
diff changeset
1568
Ritor1
parents:
diff changeset
1569 S_OK - if there was source data and it was all concatenated and
Ritor1
parents:
diff changeset
1570 the resultant dest string was null terminated
Ritor1
parents:
diff changeset
1571
Ritor1
parents:
diff changeset
1572 failure - you can use the macro HRESULT_CODE() to get a win32
Ritor1
parents:
diff changeset
1573 error code for all hresult failure cases
Ritor1
parents:
diff changeset
1574
Ritor1
parents:
diff changeset
1575 STRSAFE_E_INSUFFICIENT_BUFFER /
Ritor1
parents:
diff changeset
1576 HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER
Ritor1
parents:
diff changeset
1577 - this return value is an indication that the operation
Ritor1
parents:
diff changeset
1578 failed due to insufficient space. When this error
Ritor1
parents:
diff changeset
1579 occurs, the destination buffer is modified to contain
Ritor1
parents:
diff changeset
1580 a truncated version of the ideal result and is null
Ritor1
parents:
diff changeset
1581 terminated. This is useful for situations where
Ritor1
parents:
diff changeset
1582 truncation is ok.
Ritor1
parents:
diff changeset
1583
Ritor1
parents:
diff changeset
1584 It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the
Ritor1
parents:
diff changeset
1585 return value of this function
Ritor1
parents:
diff changeset
1586
Ritor1
parents:
diff changeset
1587 --*/
Ritor1
parents:
diff changeset
1588
Ritor1
parents:
diff changeset
1589 STRSAFEAPI StringCchCatExA(char* pszDest, size_t cchDest, const char* pszSrc, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags);
Ritor1
parents:
diff changeset
1590 STRSAFEAPI StringCchCatExW(wchar_t* pszDest, size_t cchDest, const wchar_t* pszSrc, wchar_t** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags);
Ritor1
parents:
diff changeset
1591 #ifdef UNICODE
Ritor1
parents:
diff changeset
1592 #define StringCchCatEx StringCchCatExW
Ritor1
parents:
diff changeset
1593 #else
Ritor1
parents:
diff changeset
1594 #define StringCchCatEx StringCchCatExA
Ritor1
parents:
diff changeset
1595 #endif // !UNICODE
Ritor1
parents:
diff changeset
1596
Ritor1
parents:
diff changeset
1597 #ifdef STRSAFE_INLINE
Ritor1
parents:
diff changeset
1598 STRSAFEAPI StringCchCatExA(char* pszDest, size_t cchDest, const char* pszSrc, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags)
Ritor1
parents:
diff changeset
1599 {
Ritor1
parents:
diff changeset
1600 HRESULT hr;
Ritor1
parents:
diff changeset
1601
Ritor1
parents:
diff changeset
1602 if (cchDest > STRSAFE_MAX_CCH)
Ritor1
parents:
diff changeset
1603 {
Ritor1
parents:
diff changeset
1604 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
1605 }
Ritor1
parents:
diff changeset
1606 else
Ritor1
parents:
diff changeset
1607 {
Ritor1
parents:
diff changeset
1608 size_t cbDest;
Ritor1
parents:
diff changeset
1609
Ritor1
parents:
diff changeset
1610 // safe to multiply cchDest * sizeof(char) since cchDest < STRSAFE_MAX_CCH and sizeof(char) is 1
Ritor1
parents:
diff changeset
1611 cbDest = cchDest * sizeof(char);
Ritor1
parents:
diff changeset
1612
Ritor1
parents:
diff changeset
1613 hr = StringCatExWorkerA(pszDest, cchDest, cbDest, pszSrc, ppszDestEnd, pcchRemaining, dwFlags);
Ritor1
parents:
diff changeset
1614 }
Ritor1
parents:
diff changeset
1615
Ritor1
parents:
diff changeset
1616 return hr;
Ritor1
parents:
diff changeset
1617 }
Ritor1
parents:
diff changeset
1618
Ritor1
parents:
diff changeset
1619 STRSAFEAPI StringCchCatExW(wchar_t* pszDest, size_t cchDest, const wchar_t* pszSrc, wchar_t** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags)
Ritor1
parents:
diff changeset
1620 {
Ritor1
parents:
diff changeset
1621 HRESULT hr;
Ritor1
parents:
diff changeset
1622
Ritor1
parents:
diff changeset
1623 if (cchDest > STRSAFE_MAX_CCH)
Ritor1
parents:
diff changeset
1624 {
Ritor1
parents:
diff changeset
1625 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
1626 }
Ritor1
parents:
diff changeset
1627 else
Ritor1
parents:
diff changeset
1628 {
Ritor1
parents:
diff changeset
1629 size_t cbDest;
Ritor1
parents:
diff changeset
1630
Ritor1
parents:
diff changeset
1631 // safe to multiply cchDest * sizeof(wchar_t) since cchDest < STRSAFE_MAX_CCH and sizeof(wchar_t) is 2
Ritor1
parents:
diff changeset
1632 cbDest = cchDest * sizeof(wchar_t);
Ritor1
parents:
diff changeset
1633
Ritor1
parents:
diff changeset
1634 hr = StringCatExWorkerW(pszDest, cchDest, cbDest, pszSrc, ppszDestEnd, pcchRemaining, dwFlags);
Ritor1
parents:
diff changeset
1635 }
Ritor1
parents:
diff changeset
1636
Ritor1
parents:
diff changeset
1637 return hr;
Ritor1
parents:
diff changeset
1638 }
Ritor1
parents:
diff changeset
1639 #endif // STRSAFE_INLINE
Ritor1
parents:
diff changeset
1640 #endif // !STRSAFE_NO_CCH_FUNCTIONS
Ritor1
parents:
diff changeset
1641
Ritor1
parents:
diff changeset
1642
Ritor1
parents:
diff changeset
1643 #ifndef STRSAFE_NO_CB_FUNCTIONS
Ritor1
parents:
diff changeset
1644 /*++
Ritor1
parents:
diff changeset
1645
Ritor1
parents:
diff changeset
1646 STDAPI
Ritor1
parents:
diff changeset
1647 StringCbCatEx(
Ritor1
parents:
diff changeset
1648 IN OUT LPTSTR pszDest OPTIONAL,
Ritor1
parents:
diff changeset
1649 IN size_t cbDest,
Ritor1
parents:
diff changeset
1650 IN LPCTSTR pszSrc OPTIONAL,
Ritor1
parents:
diff changeset
1651 OUT LPTSTR* ppszDestEnd OPTIONAL,
Ritor1
parents:
diff changeset
1652 OUT size_t* pcbRemaining OPTIONAL,
Ritor1
parents:
diff changeset
1653 IN DWORD dwFlags
Ritor1
parents:
diff changeset
1654 );
Ritor1
parents:
diff changeset
1655
Ritor1
parents:
diff changeset
1656 Routine Description:
Ritor1
parents:
diff changeset
1657
Ritor1
parents:
diff changeset
1658 This routine is a safer version of the C built-in function 'strcat' with
Ritor1
parents:
diff changeset
1659 some additional parameters. In addition to functionality provided by
Ritor1
parents:
diff changeset
1660 StringCbCat, this routine also returns a pointer to the end of the
Ritor1
parents:
diff changeset
1661 destination string and the number of bytes left in the destination string
Ritor1
parents:
diff changeset
1662 including the null terminator. The flags parameter allows additional controls.
Ritor1
parents:
diff changeset
1663
Ritor1
parents:
diff changeset
1664 Arguments:
Ritor1
parents:
diff changeset
1665
Ritor1
parents:
diff changeset
1666 pszDest - destination string which must be null terminated
Ritor1
parents:
diff changeset
1667
Ritor1
parents:
diff changeset
1668 cbDest - size of destination buffer in bytes.
Ritor1
parents:
diff changeset
1669 length must be ((_tcslen(pszDest) + _tcslen(pszSrc) + 1) * sizeof(TCHAR)
Ritor1
parents:
diff changeset
1670 to hold all of the combine string plus the null
Ritor1
parents:
diff changeset
1671 terminator.
Ritor1
parents:
diff changeset
1672
Ritor1
parents:
diff changeset
1673 pszSrc - source string which must be null terminated
Ritor1
parents:
diff changeset
1674
Ritor1
parents:
diff changeset
1675 ppszDestEnd - if ppszDestEnd is non-null, the function will return a
Ritor1
parents:
diff changeset
1676 pointer to the end of the destination string. If the
Ritor1
parents:
diff changeset
1677 function appended any data, the result will point to the
Ritor1
parents:
diff changeset
1678 null termination character
Ritor1
parents:
diff changeset
1679
Ritor1
parents:
diff changeset
1680 pcbRemaining - if pcbRemaining is non-null, the function will return
Ritor1
parents:
diff changeset
1681 the number of bytes left in the destination string,
Ritor1
parents:
diff changeset
1682 including the null terminator
Ritor1
parents:
diff changeset
1683
Ritor1
parents:
diff changeset
1684 dwFlags - controls some details of the string copy:
Ritor1
parents:
diff changeset
1685
Ritor1
parents:
diff changeset
1686 STRSAFE_FILL_BEHIND_NULL
Ritor1
parents:
diff changeset
1687 if the function succeeds, the low byte of dwFlags will be
Ritor1
parents:
diff changeset
1688 used to fill the uninitialize part of destination buffer
Ritor1
parents:
diff changeset
1689 behind the null terminator
Ritor1
parents:
diff changeset
1690
Ritor1
parents:
diff changeset
1691 STRSAFE_IGNORE_NULLS
Ritor1
parents:
diff changeset
1692 treat NULL string pointers like empty strings (TEXT("")).
Ritor1
parents:
diff changeset
1693 this flag is useful for emulating functions like lstrcat
Ritor1
parents:
diff changeset
1694
Ritor1
parents:
diff changeset
1695 STRSAFE_FILL_ON_FAILURE
Ritor1
parents:
diff changeset
1696 if the function fails, the low byte of dwFlags will be
Ritor1
parents:
diff changeset
1697 used to fill all of the destination buffer, and it will
Ritor1
parents:
diff changeset
1698 be null terminated. This will overwrite any pre-existing
Ritor1
parents:
diff changeset
1699 or truncated string
Ritor1
parents:
diff changeset
1700
Ritor1
parents:
diff changeset
1701 STRSAFE_NULL_ON_FAILURE
Ritor1
parents:
diff changeset
1702 if the function fails, the destination buffer will be set
Ritor1
parents:
diff changeset
1703 to the empty string. This will overwrite any pre-existing or
Ritor1
parents:
diff changeset
1704 truncated string
Ritor1
parents:
diff changeset
1705
Ritor1
parents:
diff changeset
1706 STRSAFE_NO_TRUNCATION
Ritor1
parents:
diff changeset
1707 if the function returns STRSAFE_E_INSUFFICIENT_BUFFER, pszDest
Ritor1
parents:
diff changeset
1708 will not contain a truncated string, it will remain unchanged.
Ritor1
parents:
diff changeset
1709
Ritor1
parents:
diff changeset
1710 Notes:
Ritor1
parents:
diff changeset
1711 Behavior is undefined if source and destination strings overlap.
Ritor1
parents:
diff changeset
1712
Ritor1
parents:
diff changeset
1713 pszDest and pszSrc should not be NULL unless the STRSAFE_IGNORE_NULLS flag
Ritor1
parents:
diff changeset
1714 is specified. If STRSAFE_IGNORE_NULLS is passed, both pszDest and pszSrc
Ritor1
parents:
diff changeset
1715 may be NULL. An error may still be returned even though NULLS are ignored
Ritor1
parents:
diff changeset
1716 due to insufficient space.
Ritor1
parents:
diff changeset
1717
Ritor1
parents:
diff changeset
1718 Return Value:
Ritor1
parents:
diff changeset
1719
Ritor1
parents:
diff changeset
1720 S_OK - if there was source data and it was all concatenated
Ritor1
parents:
diff changeset
1721 and the resultant dest string was null terminated
Ritor1
parents:
diff changeset
1722
Ritor1
parents:
diff changeset
1723 failure - you can use the macro HRESULT_CODE() to get a win32
Ritor1
parents:
diff changeset
1724 error code for all hresult failure cases
Ritor1
parents:
diff changeset
1725
Ritor1
parents:
diff changeset
1726 STRSAFE_E_INSUFFICIENT_BUFFER /
Ritor1
parents:
diff changeset
1727 HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER
Ritor1
parents:
diff changeset
1728 - this return value is an indication that the operation
Ritor1
parents:
diff changeset
1729 failed due to insufficient space. When this error
Ritor1
parents:
diff changeset
1730 occurs, the destination buffer is modified to contain
Ritor1
parents:
diff changeset
1731 a truncated version of the ideal result and is null
Ritor1
parents:
diff changeset
1732 terminated. This is useful for situations where
Ritor1
parents:
diff changeset
1733 truncation is ok.
Ritor1
parents:
diff changeset
1734
Ritor1
parents:
diff changeset
1735 It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the
Ritor1
parents:
diff changeset
1736 return value of this function
Ritor1
parents:
diff changeset
1737
Ritor1
parents:
diff changeset
1738 --*/
Ritor1
parents:
diff changeset
1739
Ritor1
parents:
diff changeset
1740 STRSAFEAPI StringCbCatExA(char* pszDest, size_t cbDest, const char* pszSrc, char** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags);
Ritor1
parents:
diff changeset
1741 STRSAFEAPI StringCbCatExW(wchar_t* pszDest, size_t cbDest, const wchar_t* pszSrc, wchar_t** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags);
Ritor1
parents:
diff changeset
1742 #ifdef UNICODE
Ritor1
parents:
diff changeset
1743 #define StringCbCatEx StringCbCatExW
Ritor1
parents:
diff changeset
1744 #else
Ritor1
parents:
diff changeset
1745 #define StringCbCatEx StringCbCatExA
Ritor1
parents:
diff changeset
1746 #endif // !UNICODE
Ritor1
parents:
diff changeset
1747
Ritor1
parents:
diff changeset
1748 #ifdef STRSAFE_INLINE
Ritor1
parents:
diff changeset
1749 STRSAFEAPI StringCbCatExA(char* pszDest, size_t cbDest, const char* pszSrc, char** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags)
Ritor1
parents:
diff changeset
1750 {
Ritor1
parents:
diff changeset
1751 HRESULT hr;
Ritor1
parents:
diff changeset
1752 size_t cchDest;
Ritor1
parents:
diff changeset
1753 size_t cchRemaining = 0;
Ritor1
parents:
diff changeset
1754
Ritor1
parents:
diff changeset
1755 cchDest = cbDest / sizeof(char);
Ritor1
parents:
diff changeset
1756
Ritor1
parents:
diff changeset
1757 if (cchDest > STRSAFE_MAX_CCH)
Ritor1
parents:
diff changeset
1758 {
Ritor1
parents:
diff changeset
1759 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
1760 }
Ritor1
parents:
diff changeset
1761 else
Ritor1
parents:
diff changeset
1762 {
Ritor1
parents:
diff changeset
1763 hr = StringCatExWorkerA(pszDest, cchDest, cbDest, pszSrc, ppszDestEnd, &cchRemaining, dwFlags);
Ritor1
parents:
diff changeset
1764 }
Ritor1
parents:
diff changeset
1765
Ritor1
parents:
diff changeset
1766 if (SUCCEEDED(hr) || (hr == STRSAFE_E_INSUFFICIENT_BUFFER))
Ritor1
parents:
diff changeset
1767 {
Ritor1
parents:
diff changeset
1768 if (pcbRemaining)
Ritor1
parents:
diff changeset
1769 {
Ritor1
parents:
diff changeset
1770 // safe to multiply cchRemaining * sizeof(char) since cchRemaining < STRSAFE_MAX_CCH and sizeof(char) is 1
Ritor1
parents:
diff changeset
1771 *pcbRemaining = (cchRemaining * sizeof(char)) + (cbDest % sizeof(char));
Ritor1
parents:
diff changeset
1772 }
Ritor1
parents:
diff changeset
1773 }
Ritor1
parents:
diff changeset
1774
Ritor1
parents:
diff changeset
1775 return hr;
Ritor1
parents:
diff changeset
1776 }
Ritor1
parents:
diff changeset
1777
Ritor1
parents:
diff changeset
1778 STRSAFEAPI StringCbCatExW(wchar_t* pszDest, size_t cbDest, const wchar_t* pszSrc, wchar_t** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags)
Ritor1
parents:
diff changeset
1779 {
Ritor1
parents:
diff changeset
1780 HRESULT hr;
Ritor1
parents:
diff changeset
1781 size_t cchDest;
Ritor1
parents:
diff changeset
1782 size_t cchRemaining = 0;
Ritor1
parents:
diff changeset
1783
Ritor1
parents:
diff changeset
1784 cchDest = cbDest / sizeof(wchar_t);
Ritor1
parents:
diff changeset
1785
Ritor1
parents:
diff changeset
1786 if (cchDest > STRSAFE_MAX_CCH)
Ritor1
parents:
diff changeset
1787 {
Ritor1
parents:
diff changeset
1788 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
1789 }
Ritor1
parents:
diff changeset
1790 else
Ritor1
parents:
diff changeset
1791 {
Ritor1
parents:
diff changeset
1792 hr = StringCatExWorkerW(pszDest, cchDest, cbDest, pszSrc, ppszDestEnd, &cchRemaining, dwFlags);
Ritor1
parents:
diff changeset
1793 }
Ritor1
parents:
diff changeset
1794
Ritor1
parents:
diff changeset
1795 if (SUCCEEDED(hr) || (hr == STRSAFE_E_INSUFFICIENT_BUFFER))
Ritor1
parents:
diff changeset
1796 {
Ritor1
parents:
diff changeset
1797 if (pcbRemaining)
Ritor1
parents:
diff changeset
1798 {
Ritor1
parents:
diff changeset
1799 // safe to multiply cchRemaining * sizeof(wchar_t) since cchRemaining < STRSAFE_MAX_CCH and sizeof(wchar_t) is 2
Ritor1
parents:
diff changeset
1800 *pcbRemaining = (cchRemaining * sizeof(wchar_t)) + (cbDest % sizeof(wchar_t));
Ritor1
parents:
diff changeset
1801 }
Ritor1
parents:
diff changeset
1802 }
Ritor1
parents:
diff changeset
1803
Ritor1
parents:
diff changeset
1804 return hr;
Ritor1
parents:
diff changeset
1805 }
Ritor1
parents:
diff changeset
1806 #endif // STRSAFE_INLINE
Ritor1
parents:
diff changeset
1807 #endif // !STRSAFE_NO_CB_FUNCTIONS
Ritor1
parents:
diff changeset
1808
Ritor1
parents:
diff changeset
1809
Ritor1
parents:
diff changeset
1810 #ifndef STRSAFE_NO_CCH_FUNCTIONS
Ritor1
parents:
diff changeset
1811 /*++
Ritor1
parents:
diff changeset
1812
Ritor1
parents:
diff changeset
1813 STDAPI
Ritor1
parents:
diff changeset
1814 StringCchCatN(
Ritor1
parents:
diff changeset
1815 IN OUT LPTSTR pszDest,
Ritor1
parents:
diff changeset
1816 IN size_t cchDest,
Ritor1
parents:
diff changeset
1817 IN LPCTSTR pszSrc,
Ritor1
parents:
diff changeset
1818 IN size_t cchMaxAppend
Ritor1
parents:
diff changeset
1819 );
Ritor1
parents:
diff changeset
1820
Ritor1
parents:
diff changeset
1821 Routine Description:
Ritor1
parents:
diff changeset
1822
Ritor1
parents:
diff changeset
1823 This routine is a safer version of the C built-in function 'strncat'.
Ritor1
parents:
diff changeset
1824 The size of the destination buffer (in characters) is a parameter as well as
Ritor1
parents:
diff changeset
1825 the maximum number of characters to append, excluding the null terminator.
Ritor1
parents:
diff changeset
1826 This function will not write past the end of the destination buffer and it will
Ritor1
parents:
diff changeset
1827 ALWAYS null terminate pszDest (unless it is zero length).
Ritor1
parents:
diff changeset
1828
Ritor1
parents:
diff changeset
1829 This function returns a hresult, and not a pointer. It returns
Ritor1
parents:
diff changeset
1830 S_OK if all of pszSrc or the first cchMaxAppend characters were appended
Ritor1
parents:
diff changeset
1831 to the destination string and it was null terminated, otherwise it will
Ritor1
parents:
diff changeset
1832 return a failure code. In failure cases as much of pszSrc will be appended
Ritor1
parents:
diff changeset
1833 to pszDest as possible, and pszDest will be null terminated.
Ritor1
parents:
diff changeset
1834
Ritor1
parents:
diff changeset
1835 Arguments:
Ritor1
parents:
diff changeset
1836
Ritor1
parents:
diff changeset
1837 pszDest - destination string which must be null terminated
Ritor1
parents:
diff changeset
1838
Ritor1
parents:
diff changeset
1839 cchDest - size of destination buffer in characters.
Ritor1
parents:
diff changeset
1840 length must be (_tcslen(pszDest) + min(cchMaxAppend, _tcslen(pszSrc)) + 1)
Ritor1
parents:
diff changeset
1841 to hold all of the combine string plus the null
Ritor1
parents:
diff changeset
1842 terminator.
Ritor1
parents:
diff changeset
1843
Ritor1
parents:
diff changeset
1844 pszSrc - source string
Ritor1
parents:
diff changeset
1845
Ritor1
parents:
diff changeset
1846 cchMaxAppend - maximum number of characters to append
Ritor1
parents:
diff changeset
1847
Ritor1
parents:
diff changeset
1848 Notes:
Ritor1
parents:
diff changeset
1849 Behavior is undefined if source and destination strings overlap.
Ritor1
parents:
diff changeset
1850
Ritor1
parents:
diff changeset
1851 pszDest and pszSrc should not be NULL. See StringCchCatNEx if you require
Ritor1
parents:
diff changeset
1852 the handling of NULL values.
Ritor1
parents:
diff changeset
1853
Ritor1
parents:
diff changeset
1854 Return Value:
Ritor1
parents:
diff changeset
1855
Ritor1
parents:
diff changeset
1856 S_OK - if all of pszSrc or the first cchMaxAppend characters
Ritor1
parents:
diff changeset
1857 were concatenated to pszDest and the resultant dest
Ritor1
parents:
diff changeset
1858 string was null terminated
Ritor1
parents:
diff changeset
1859
Ritor1
parents:
diff changeset
1860 failure - you can use the macro HRESULT_CODE() to get a win32
Ritor1
parents:
diff changeset
1861 error code for all hresult failure cases
Ritor1
parents:
diff changeset
1862
Ritor1
parents:
diff changeset
1863 STRSAFE_E_INSUFFICIENT_BUFFER /
Ritor1
parents:
diff changeset
1864 HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER
Ritor1
parents:
diff changeset
1865 - this return value is an indication that the operation
Ritor1
parents:
diff changeset
1866 failed due to insufficient space. When this error
Ritor1
parents:
diff changeset
1867 occurs, the destination buffer is modified to contain
Ritor1
parents:
diff changeset
1868 a truncated version of the ideal result and is null
Ritor1
parents:
diff changeset
1869 terminated. This is useful for situations where
Ritor1
parents:
diff changeset
1870 truncation is ok.
Ritor1
parents:
diff changeset
1871
Ritor1
parents:
diff changeset
1872 It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the
Ritor1
parents:
diff changeset
1873 return value of this function
Ritor1
parents:
diff changeset
1874
Ritor1
parents:
diff changeset
1875 --*/
Ritor1
parents:
diff changeset
1876
Ritor1
parents:
diff changeset
1877 STRSAFEAPI StringCchCatNA(char* pszDest, size_t cchDest, const char* pszSrc, size_t cchMaxAppend);
Ritor1
parents:
diff changeset
1878 STRSAFEAPI StringCchCatNW(wchar_t* pszDest, size_t cchDest, const wchar_t* pszSrc, size_t cchMaxAppend);
Ritor1
parents:
diff changeset
1879 #ifdef UNICODE
Ritor1
parents:
diff changeset
1880 #define StringCchCatN StringCchCatNW
Ritor1
parents:
diff changeset
1881 #else
Ritor1
parents:
diff changeset
1882 #define StringCchCatN StringCchCatNA
Ritor1
parents:
diff changeset
1883 #endif // !UNICODE
Ritor1
parents:
diff changeset
1884
Ritor1
parents:
diff changeset
1885 #ifdef STRSAFE_INLINE
Ritor1
parents:
diff changeset
1886 STRSAFEAPI StringCchCatNA(char* pszDest, size_t cchDest, const char* pszSrc, size_t cchMaxAppend)
Ritor1
parents:
diff changeset
1887 {
Ritor1
parents:
diff changeset
1888 HRESULT hr;
Ritor1
parents:
diff changeset
1889
Ritor1
parents:
diff changeset
1890 if (cchDest > STRSAFE_MAX_CCH)
Ritor1
parents:
diff changeset
1891 {
Ritor1
parents:
diff changeset
1892 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
1893 }
Ritor1
parents:
diff changeset
1894 else
Ritor1
parents:
diff changeset
1895 {
Ritor1
parents:
diff changeset
1896 hr = StringCatNWorkerA(pszDest, cchDest, pszSrc, cchMaxAppend);
Ritor1
parents:
diff changeset
1897 }
Ritor1
parents:
diff changeset
1898
Ritor1
parents:
diff changeset
1899 return hr;
Ritor1
parents:
diff changeset
1900 }
Ritor1
parents:
diff changeset
1901
Ritor1
parents:
diff changeset
1902 STRSAFEAPI StringCchCatNW(wchar_t* pszDest, size_t cchDest, const wchar_t* pszSrc, size_t cchMaxAppend)
Ritor1
parents:
diff changeset
1903 {
Ritor1
parents:
diff changeset
1904 HRESULT hr;
Ritor1
parents:
diff changeset
1905
Ritor1
parents:
diff changeset
1906 if (cchDest > STRSAFE_MAX_CCH)
Ritor1
parents:
diff changeset
1907 {
Ritor1
parents:
diff changeset
1908 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
1909 }
Ritor1
parents:
diff changeset
1910 else
Ritor1
parents:
diff changeset
1911 {
Ritor1
parents:
diff changeset
1912 hr = StringCatNWorkerW(pszDest, cchDest, pszSrc, cchMaxAppend);
Ritor1
parents:
diff changeset
1913 }
Ritor1
parents:
diff changeset
1914
Ritor1
parents:
diff changeset
1915 return hr;
Ritor1
parents:
diff changeset
1916 }
Ritor1
parents:
diff changeset
1917 #endif // STRSAFE_INLINE
Ritor1
parents:
diff changeset
1918 #endif // !STRSAFE_NO_CCH_FUNCTIONS
Ritor1
parents:
diff changeset
1919
Ritor1
parents:
diff changeset
1920
Ritor1
parents:
diff changeset
1921 #ifndef STRSAFE_NO_CB_FUNCTIONS
Ritor1
parents:
diff changeset
1922 /*++
Ritor1
parents:
diff changeset
1923
Ritor1
parents:
diff changeset
1924 STDAPI
Ritor1
parents:
diff changeset
1925 StringCbCatN(
Ritor1
parents:
diff changeset
1926 IN OUT LPTSTR pszDest,
Ritor1
parents:
diff changeset
1927 IN size_t cbDest,
Ritor1
parents:
diff changeset
1928 IN LPCTSTR pszSrc,
Ritor1
parents:
diff changeset
1929 IN size_t cbMaxAppend
Ritor1
parents:
diff changeset
1930 );
Ritor1
parents:
diff changeset
1931
Ritor1
parents:
diff changeset
1932 Routine Description:
Ritor1
parents:
diff changeset
1933
Ritor1
parents:
diff changeset
1934 This routine is a safer version of the C built-in function 'strncat'.
Ritor1
parents:
diff changeset
1935 The size of the destination buffer (in bytes) is a parameter as well as
Ritor1
parents:
diff changeset
1936 the maximum number of bytes to append, excluding the null terminator.
Ritor1
parents:
diff changeset
1937 This function will not write past the end of the destination buffer and it will
Ritor1
parents:
diff changeset
1938 ALWAYS null terminate pszDest (unless it is zero length).
Ritor1
parents:
diff changeset
1939
Ritor1
parents:
diff changeset
1940 This function returns a hresult, and not a pointer. It returns
Ritor1
parents:
diff changeset
1941 S_OK if all of pszSrc or the first cbMaxAppend bytes were appended
Ritor1
parents:
diff changeset
1942 to the destination string and it was null terminated, otherwise it will
Ritor1
parents:
diff changeset
1943 return a failure code. In failure cases as much of pszSrc will be appended
Ritor1
parents:
diff changeset
1944 to pszDest as possible, and pszDest will be null terminated.
Ritor1
parents:
diff changeset
1945
Ritor1
parents:
diff changeset
1946 Arguments:
Ritor1
parents:
diff changeset
1947
Ritor1
parents:
diff changeset
1948 pszDest - destination string which must be null terminated
Ritor1
parents:
diff changeset
1949
Ritor1
parents:
diff changeset
1950 cbDest - size of destination buffer in bytes.
Ritor1
parents:
diff changeset
1951 length must be ((_tcslen(pszDest) + min(cbMaxAppend / sizeof(TCHAR), _tcslen(pszSrc)) + 1) * sizeof(TCHAR)
Ritor1
parents:
diff changeset
1952 to hold all of the combine string plus the null
Ritor1
parents:
diff changeset
1953 terminator.
Ritor1
parents:
diff changeset
1954
Ritor1
parents:
diff changeset
1955 pszSrc - source string
Ritor1
parents:
diff changeset
1956
Ritor1
parents:
diff changeset
1957 cbMaxAppend - maximum number of bytes to append
Ritor1
parents:
diff changeset
1958
Ritor1
parents:
diff changeset
1959 Notes:
Ritor1
parents:
diff changeset
1960 Behavior is undefined if source and destination strings overlap.
Ritor1
parents:
diff changeset
1961
Ritor1
parents:
diff changeset
1962 pszDest and pszSrc should not be NULL. See StringCbCatNEx if you require
Ritor1
parents:
diff changeset
1963 the handling of NULL values.
Ritor1
parents:
diff changeset
1964
Ritor1
parents:
diff changeset
1965 Return Value:
Ritor1
parents:
diff changeset
1966
Ritor1
parents:
diff changeset
1967 S_OK - if all of pszSrc or the first cbMaxAppend bytes were
Ritor1
parents:
diff changeset
1968 concatenated to pszDest and the resultant dest string
Ritor1
parents:
diff changeset
1969 was null terminated
Ritor1
parents:
diff changeset
1970
Ritor1
parents:
diff changeset
1971 failure - you can use the macro HRESULT_CODE() to get a win32
Ritor1
parents:
diff changeset
1972 error code for all hresult failure cases
Ritor1
parents:
diff changeset
1973
Ritor1
parents:
diff changeset
1974 STRSAFE_E_INSUFFICIENT_BUFFER /
Ritor1
parents:
diff changeset
1975 HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER
Ritor1
parents:
diff changeset
1976 - this return value is an indication that the operation
Ritor1
parents:
diff changeset
1977 failed due to insufficient space. When this error
Ritor1
parents:
diff changeset
1978 occurs, the destination buffer is modified to contain
Ritor1
parents:
diff changeset
1979 a truncated version of the ideal result and is null
Ritor1
parents:
diff changeset
1980 terminated. This is useful for situations where
Ritor1
parents:
diff changeset
1981 truncation is ok.
Ritor1
parents:
diff changeset
1982
Ritor1
parents:
diff changeset
1983 It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the
Ritor1
parents:
diff changeset
1984 return value of this function
Ritor1
parents:
diff changeset
1985
Ritor1
parents:
diff changeset
1986 --*/
Ritor1
parents:
diff changeset
1987
Ritor1
parents:
diff changeset
1988 STRSAFEAPI StringCbCatNA(char* pszDest, size_t cbDest, const char* pszSrc, size_t cbMaxAppend);
Ritor1
parents:
diff changeset
1989 STRSAFEAPI StringCbCatNW(wchar_t* pszDest, size_t cbDest, const wchar_t* pszSrc, size_t cbMaxAppend);
Ritor1
parents:
diff changeset
1990 #ifdef UNICODE
Ritor1
parents:
diff changeset
1991 #define StringCbCatN StringCbCatNW
Ritor1
parents:
diff changeset
1992 #else
Ritor1
parents:
diff changeset
1993 #define StringCbCatN StringCbCatNA
Ritor1
parents:
diff changeset
1994 #endif // !UNICODE
Ritor1
parents:
diff changeset
1995
Ritor1
parents:
diff changeset
1996 #ifdef STRSAFE_INLINE
Ritor1
parents:
diff changeset
1997 STRSAFEAPI StringCbCatNA(char* pszDest, size_t cbDest, const char* pszSrc, size_t cbMaxAppend)
Ritor1
parents:
diff changeset
1998 {
Ritor1
parents:
diff changeset
1999 HRESULT hr;
Ritor1
parents:
diff changeset
2000 size_t cchDest;
Ritor1
parents:
diff changeset
2001
Ritor1
parents:
diff changeset
2002 cchDest = cbDest / sizeof(char);
Ritor1
parents:
diff changeset
2003
Ritor1
parents:
diff changeset
2004 if (cchDest > STRSAFE_MAX_CCH)
Ritor1
parents:
diff changeset
2005 {
Ritor1
parents:
diff changeset
2006 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
2007 }
Ritor1
parents:
diff changeset
2008 else
Ritor1
parents:
diff changeset
2009 {
Ritor1
parents:
diff changeset
2010 size_t cchMaxAppend;
Ritor1
parents:
diff changeset
2011
Ritor1
parents:
diff changeset
2012 cchMaxAppend = cbMaxAppend / sizeof(char);
Ritor1
parents:
diff changeset
2013
Ritor1
parents:
diff changeset
2014 hr = StringCatNWorkerA(pszDest, cchDest, pszSrc, cchMaxAppend);
Ritor1
parents:
diff changeset
2015 }
Ritor1
parents:
diff changeset
2016
Ritor1
parents:
diff changeset
2017 return hr;
Ritor1
parents:
diff changeset
2018 }
Ritor1
parents:
diff changeset
2019
Ritor1
parents:
diff changeset
2020 STRSAFEAPI StringCbCatNW(wchar_t* pszDest, size_t cbDest, const wchar_t* pszSrc, size_t cbMaxAppend)
Ritor1
parents:
diff changeset
2021 {
Ritor1
parents:
diff changeset
2022 HRESULT hr;
Ritor1
parents:
diff changeset
2023 size_t cchDest;
Ritor1
parents:
diff changeset
2024
Ritor1
parents:
diff changeset
2025 cchDest = cbDest / sizeof(wchar_t);
Ritor1
parents:
diff changeset
2026
Ritor1
parents:
diff changeset
2027 if (cchDest > STRSAFE_MAX_CCH)
Ritor1
parents:
diff changeset
2028 {
Ritor1
parents:
diff changeset
2029 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
2030 }
Ritor1
parents:
diff changeset
2031 else
Ritor1
parents:
diff changeset
2032 {
Ritor1
parents:
diff changeset
2033 size_t cchMaxAppend;
Ritor1
parents:
diff changeset
2034
Ritor1
parents:
diff changeset
2035 cchMaxAppend = cbMaxAppend / sizeof(wchar_t);
Ritor1
parents:
diff changeset
2036
Ritor1
parents:
diff changeset
2037 hr = StringCatNWorkerW(pszDest, cchDest, pszSrc, cchMaxAppend);
Ritor1
parents:
diff changeset
2038 }
Ritor1
parents:
diff changeset
2039
Ritor1
parents:
diff changeset
2040 return hr;
Ritor1
parents:
diff changeset
2041 }
Ritor1
parents:
diff changeset
2042 #endif // STRSAFE_INLINE
Ritor1
parents:
diff changeset
2043 #endif // !STRSAFE_NO_CB_FUNCTIONS
Ritor1
parents:
diff changeset
2044
Ritor1
parents:
diff changeset
2045
Ritor1
parents:
diff changeset
2046 #ifndef STRSAFE_NO_CCH_FUNCTIONS
Ritor1
parents:
diff changeset
2047 /*++
Ritor1
parents:
diff changeset
2048
Ritor1
parents:
diff changeset
2049 STDAPI
Ritor1
parents:
diff changeset
2050 StringCchCatNEx(
Ritor1
parents:
diff changeset
2051 IN OUT LPTSTR pszDest OPTIONAL,
Ritor1
parents:
diff changeset
2052 IN size_t cchDest,
Ritor1
parents:
diff changeset
2053 IN LPCTSTR pszSrc OPTIONAL,
Ritor1
parents:
diff changeset
2054 IN size_t cchMaxAppend,
Ritor1
parents:
diff changeset
2055 OUT LPTSTR* ppszDestEnd OPTIONAL,
Ritor1
parents:
diff changeset
2056 OUT size_t* pcchRemaining OPTIONAL,
Ritor1
parents:
diff changeset
2057 IN DWORD dwFlags
Ritor1
parents:
diff changeset
2058 );
Ritor1
parents:
diff changeset
2059
Ritor1
parents:
diff changeset
2060 Routine Description:
Ritor1
parents:
diff changeset
2061
Ritor1
parents:
diff changeset
2062 This routine is a safer version of the C built-in function 'strncat', with
Ritor1
parents:
diff changeset
2063 some additional parameters. In addition to functionality provided by
Ritor1
parents:
diff changeset
2064 StringCchCatN, this routine also returns a pointer to the end of the
Ritor1
parents:
diff changeset
2065 destination string and the number of characters left in the destination string
Ritor1
parents:
diff changeset
2066 including the null terminator. The flags parameter allows additional controls.
Ritor1
parents:
diff changeset
2067
Ritor1
parents:
diff changeset
2068 Arguments:
Ritor1
parents:
diff changeset
2069
Ritor1
parents:
diff changeset
2070 pszDest - destination string which must be null terminated
Ritor1
parents:
diff changeset
2071
Ritor1
parents:
diff changeset
2072 cchDest - size of destination buffer in characters.
Ritor1
parents:
diff changeset
2073 length must be (_tcslen(pszDest) + min(cchMaxAppend, _tcslen(pszSrc)) + 1)
Ritor1
parents:
diff changeset
2074 to hold all of the combine string plus the null
Ritor1
parents:
diff changeset
2075 terminator.
Ritor1
parents:
diff changeset
2076
Ritor1
parents:
diff changeset
2077 pszSrc - source string
Ritor1
parents:
diff changeset
2078
Ritor1
parents:
diff changeset
2079 cchMaxAppend - maximum number of characters to append
Ritor1
parents:
diff changeset
2080
Ritor1
parents:
diff changeset
2081 ppszDestEnd - if ppszDestEnd is non-null, the function will return a
Ritor1
parents:
diff changeset
2082 pointer to the end of the destination string. If the
Ritor1
parents:
diff changeset
2083 function appended any data, the result will point to the
Ritor1
parents:
diff changeset
2084 null termination character
Ritor1
parents:
diff changeset
2085
Ritor1
parents:
diff changeset
2086 pcchRemaining - if pcchRemaining is non-null, the function will return the
Ritor1
parents:
diff changeset
2087 number of characters left in the destination string,
Ritor1
parents:
diff changeset
2088 including the null terminator
Ritor1
parents:
diff changeset
2089
Ritor1
parents:
diff changeset
2090 dwFlags - controls some details of the string copy:
Ritor1
parents:
diff changeset
2091
Ritor1
parents:
diff changeset
2092 STRSAFE_FILL_BEHIND_NULL
Ritor1
parents:
diff changeset
2093 if the function succeeds, the low byte of dwFlags will be
Ritor1
parents:
diff changeset
2094 used to fill the uninitialize part of destination buffer
Ritor1
parents:
diff changeset
2095 behind the null terminator
Ritor1
parents:
diff changeset
2096
Ritor1
parents:
diff changeset
2097 STRSAFE_IGNORE_NULLS
Ritor1
parents:
diff changeset
2098 treat NULL string pointers like empty strings (TEXT(""))
Ritor1
parents:
diff changeset
2099
Ritor1
parents:
diff changeset
2100 STRSAFE_FILL_ON_FAILURE
Ritor1
parents:
diff changeset
2101 if the function fails, the low byte of dwFlags will be
Ritor1
parents:
diff changeset
2102 used to fill all of the destination buffer, and it will
Ritor1
parents:
diff changeset
2103 be null terminated. This will overwrite any pre-existing
Ritor1
parents:
diff changeset
2104 or truncated string
Ritor1
parents:
diff changeset
2105
Ritor1
parents:
diff changeset
2106 STRSAFE_NULL_ON_FAILURE
Ritor1
parents:
diff changeset
2107 if the function fails, the destination buffer will be set
Ritor1
parents:
diff changeset
2108 to the empty string. This will overwrite any pre-existing or
Ritor1
parents:
diff changeset
2109 truncated string
Ritor1
parents:
diff changeset
2110
Ritor1
parents:
diff changeset
2111 STRSAFE_NO_TRUNCATION
Ritor1
parents:
diff changeset
2112 if the function returns STRSAFE_E_INSUFFICIENT_BUFFER, pszDest
Ritor1
parents:
diff changeset
2113 will not contain a truncated string, it will remain unchanged.
Ritor1
parents:
diff changeset
2114
Ritor1
parents:
diff changeset
2115 Notes:
Ritor1
parents:
diff changeset
2116 Behavior is undefined if source and destination strings overlap.
Ritor1
parents:
diff changeset
2117
Ritor1
parents:
diff changeset
2118 pszDest and pszSrc should not be NULL unless the STRSAFE_IGNORE_NULLS flag
Ritor1
parents:
diff changeset
2119 is specified. If STRSAFE_IGNORE_NULLS is passed, both pszDest and pszSrc
Ritor1
parents:
diff changeset
2120 may be NULL. An error may still be returned even though NULLS are ignored
Ritor1
parents:
diff changeset
2121 due to insufficient space.
Ritor1
parents:
diff changeset
2122
Ritor1
parents:
diff changeset
2123 Return Value:
Ritor1
parents:
diff changeset
2124
Ritor1
parents:
diff changeset
2125 S_OK - if all of pszSrc or the first cchMaxAppend characters
Ritor1
parents:
diff changeset
2126 were concatenated to pszDest and the resultant dest
Ritor1
parents:
diff changeset
2127 string was null terminated
Ritor1
parents:
diff changeset
2128
Ritor1
parents:
diff changeset
2129 failure - you can use the macro HRESULT_CODE() to get a win32
Ritor1
parents:
diff changeset
2130 error code for all hresult failure cases
Ritor1
parents:
diff changeset
2131
Ritor1
parents:
diff changeset
2132 STRSAFE_E_INSUFFICIENT_BUFFER /
Ritor1
parents:
diff changeset
2133 HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER
Ritor1
parents:
diff changeset
2134 - this return value is an indication that the operation
Ritor1
parents:
diff changeset
2135 failed due to insufficient space. When this error
Ritor1
parents:
diff changeset
2136 occurs, the destination buffer is modified to contain
Ritor1
parents:
diff changeset
2137 a truncated version of the ideal result and is null
Ritor1
parents:
diff changeset
2138 terminated. This is useful for situations where
Ritor1
parents:
diff changeset
2139 truncation is ok.
Ritor1
parents:
diff changeset
2140
Ritor1
parents:
diff changeset
2141 It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the
Ritor1
parents:
diff changeset
2142 return value of this function
Ritor1
parents:
diff changeset
2143
Ritor1
parents:
diff changeset
2144 --*/
Ritor1
parents:
diff changeset
2145
Ritor1
parents:
diff changeset
2146 STRSAFEAPI StringCchCatNExA(char* pszDest, size_t cchDest, const char* pszSrc, size_t cchMaxAppend, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags);
Ritor1
parents:
diff changeset
2147 STRSAFEAPI StringCchCatNExW(wchar_t* pszDest, size_t cchDest, const wchar_t* pszSrc, size_t cchMaxAppend, wchar_t** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags);
Ritor1
parents:
diff changeset
2148 #ifdef UNICODE
Ritor1
parents:
diff changeset
2149 #define StringCchCatNEx StringCchCatNExW
Ritor1
parents:
diff changeset
2150 #else
Ritor1
parents:
diff changeset
2151 #define StringCchCatNEx StringCchCatNExA
Ritor1
parents:
diff changeset
2152 #endif // !UNICODE
Ritor1
parents:
diff changeset
2153
Ritor1
parents:
diff changeset
2154 #ifdef STRSAFE_INLINE
Ritor1
parents:
diff changeset
2155 STRSAFEAPI StringCchCatNExA(char* pszDest, size_t cchDest, const char* pszSrc, size_t cchMaxAppend, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags)
Ritor1
parents:
diff changeset
2156 {
Ritor1
parents:
diff changeset
2157 HRESULT hr;
Ritor1
parents:
diff changeset
2158
Ritor1
parents:
diff changeset
2159 if (cchDest > STRSAFE_MAX_CCH)
Ritor1
parents:
diff changeset
2160 {
Ritor1
parents:
diff changeset
2161 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
2162 }
Ritor1
parents:
diff changeset
2163 else
Ritor1
parents:
diff changeset
2164 {
Ritor1
parents:
diff changeset
2165 size_t cbDest;
Ritor1
parents:
diff changeset
2166
Ritor1
parents:
diff changeset
2167 // safe to multiply cchDest * sizeof(char) since cchDest < STRSAFE_MAX_CCH and sizeof(char) is 1
Ritor1
parents:
diff changeset
2168 cbDest = cchDest * sizeof(char);
Ritor1
parents:
diff changeset
2169
Ritor1
parents:
diff changeset
2170 hr = StringCatNExWorkerA(pszDest, cchDest, cbDest, pszSrc, cchMaxAppend, ppszDestEnd, pcchRemaining, dwFlags);
Ritor1
parents:
diff changeset
2171 }
Ritor1
parents:
diff changeset
2172
Ritor1
parents:
diff changeset
2173 return hr;
Ritor1
parents:
diff changeset
2174 }
Ritor1
parents:
diff changeset
2175
Ritor1
parents:
diff changeset
2176 STRSAFEAPI StringCchCatNExW(wchar_t* pszDest, size_t cchDest, const wchar_t* pszSrc, size_t cchMaxAppend, wchar_t** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags)
Ritor1
parents:
diff changeset
2177 {
Ritor1
parents:
diff changeset
2178 HRESULT hr;
Ritor1
parents:
diff changeset
2179
Ritor1
parents:
diff changeset
2180 if (cchDest > STRSAFE_MAX_CCH)
Ritor1
parents:
diff changeset
2181 {
Ritor1
parents:
diff changeset
2182 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
2183 }
Ritor1
parents:
diff changeset
2184 else
Ritor1
parents:
diff changeset
2185 {
Ritor1
parents:
diff changeset
2186 size_t cbDest;
Ritor1
parents:
diff changeset
2187
Ritor1
parents:
diff changeset
2188 // safe to multiply cchDest * sizeof(wchar_t) since cchDest < STRSAFE_MAX_CCH and sizeof(wchar_t) is 2
Ritor1
parents:
diff changeset
2189 cbDest = cchDest * sizeof(wchar_t);
Ritor1
parents:
diff changeset
2190
Ritor1
parents:
diff changeset
2191 hr = StringCatNExWorkerW(pszDest, cchDest, cbDest, pszSrc, cchMaxAppend, ppszDestEnd, pcchRemaining, dwFlags);
Ritor1
parents:
diff changeset
2192 }
Ritor1
parents:
diff changeset
2193
Ritor1
parents:
diff changeset
2194 return hr;
Ritor1
parents:
diff changeset
2195 }
Ritor1
parents:
diff changeset
2196 #endif // STRSAFE_INLINE
Ritor1
parents:
diff changeset
2197 #endif // !STRSAFE_NO_CCH_FUNCTIONS
Ritor1
parents:
diff changeset
2198
Ritor1
parents:
diff changeset
2199
Ritor1
parents:
diff changeset
2200 #ifndef STRSAFE_NO_CB_FUNCTIONS
Ritor1
parents:
diff changeset
2201 /*++
Ritor1
parents:
diff changeset
2202
Ritor1
parents:
diff changeset
2203 STDAPI
Ritor1
parents:
diff changeset
2204 StringCbCatNEx(
Ritor1
parents:
diff changeset
2205 IN OUT LPTSTR pszDest OPTIONAL,
Ritor1
parents:
diff changeset
2206 IN size_t cbDest,
Ritor1
parents:
diff changeset
2207 IN LPCTSTR pszSrc OPTIONAL,
Ritor1
parents:
diff changeset
2208 IN size_t cbMaxAppend,
Ritor1
parents:
diff changeset
2209 OUT LPTSTR* ppszDestEnd OPTIONAL,
Ritor1
parents:
diff changeset
2210 OUT size_t* pcchRemaining OPTIONAL,
Ritor1
parents:
diff changeset
2211 IN DWORD dwFlags
Ritor1
parents:
diff changeset
2212 );
Ritor1
parents:
diff changeset
2213
Ritor1
parents:
diff changeset
2214 Routine Description:
Ritor1
parents:
diff changeset
2215
Ritor1
parents:
diff changeset
2216 This routine is a safer version of the C built-in function 'strncat', with
Ritor1
parents:
diff changeset
2217 some additional parameters. In addition to functionality provided by
Ritor1
parents:
diff changeset
2218 StringCbCatN, this routine also returns a pointer to the end of the
Ritor1
parents:
diff changeset
2219 destination string and the number of bytes left in the destination string
Ritor1
parents:
diff changeset
2220 including the null terminator. The flags parameter allows additional controls.
Ritor1
parents:
diff changeset
2221
Ritor1
parents:
diff changeset
2222 Arguments:
Ritor1
parents:
diff changeset
2223
Ritor1
parents:
diff changeset
2224 pszDest - destination string which must be null terminated
Ritor1
parents:
diff changeset
2225
Ritor1
parents:
diff changeset
2226 cbDest - size of destination buffer in bytes.
Ritor1
parents:
diff changeset
2227 length must be ((_tcslen(pszDest) + min(cbMaxAppend / sizeof(TCHAR), _tcslen(pszSrc)) + 1) * sizeof(TCHAR)
Ritor1
parents:
diff changeset
2228 to hold all of the combine string plus the null
Ritor1
parents:
diff changeset
2229 terminator.
Ritor1
parents:
diff changeset
2230
Ritor1
parents:
diff changeset
2231 pszSrc - source string
Ritor1
parents:
diff changeset
2232
Ritor1
parents:
diff changeset
2233 cbMaxAppend - maximum number of bytes to append
Ritor1
parents:
diff changeset
2234
Ritor1
parents:
diff changeset
2235 ppszDestEnd - if ppszDestEnd is non-null, the function will return a
Ritor1
parents:
diff changeset
2236 pointer to the end of the destination string. If the
Ritor1
parents:
diff changeset
2237 function appended any data, the result will point to the
Ritor1
parents:
diff changeset
2238 null termination character
Ritor1
parents:
diff changeset
2239
Ritor1
parents:
diff changeset
2240 pcbRemaining - if pcbRemaining is non-null, the function will return the
Ritor1
parents:
diff changeset
2241 number of bytes left in the destination string,
Ritor1
parents:
diff changeset
2242 including the null terminator
Ritor1
parents:
diff changeset
2243
Ritor1
parents:
diff changeset
2244 dwFlags - controls some details of the string copy:
Ritor1
parents:
diff changeset
2245
Ritor1
parents:
diff changeset
2246 STRSAFE_FILL_BEHIND_NULL
Ritor1
parents:
diff changeset
2247 if the function succeeds, the low byte of dwFlags will be
Ritor1
parents:
diff changeset
2248 used to fill the uninitialize part of destination buffer
Ritor1
parents:
diff changeset
2249 behind the null terminator
Ritor1
parents:
diff changeset
2250
Ritor1
parents:
diff changeset
2251 STRSAFE_IGNORE_NULLS
Ritor1
parents:
diff changeset
2252 treat NULL string pointers like empty strings (TEXT(""))
Ritor1
parents:
diff changeset
2253
Ritor1
parents:
diff changeset
2254 STRSAFE_FILL_ON_FAILURE
Ritor1
parents:
diff changeset
2255 if the function fails, the low byte of dwFlags will be
Ritor1
parents:
diff changeset
2256 used to fill all of the destination buffer, and it will
Ritor1
parents:
diff changeset
2257 be null terminated. This will overwrite any pre-existing
Ritor1
parents:
diff changeset
2258 or truncated string
Ritor1
parents:
diff changeset
2259
Ritor1
parents:
diff changeset
2260 STRSAFE_NULL_ON_FAILURE
Ritor1
parents:
diff changeset
2261 if the function fails, the destination buffer will be set
Ritor1
parents:
diff changeset
2262 to the empty string. This will overwrite any pre-existing or
Ritor1
parents:
diff changeset
2263 truncated string
Ritor1
parents:
diff changeset
2264
Ritor1
parents:
diff changeset
2265 STRSAFE_NO_TRUNCATION
Ritor1
parents:
diff changeset
2266 if the function returns STRSAFE_E_INSUFFICIENT_BUFFER, pszDest
Ritor1
parents:
diff changeset
2267 will not contain a truncated string, it will remain unchanged.
Ritor1
parents:
diff changeset
2268
Ritor1
parents:
diff changeset
2269 Notes:
Ritor1
parents:
diff changeset
2270 Behavior is undefined if source and destination strings overlap.
Ritor1
parents:
diff changeset
2271
Ritor1
parents:
diff changeset
2272 pszDest and pszSrc should not be NULL unless the STRSAFE_IGNORE_NULLS flag
Ritor1
parents:
diff changeset
2273 is specified. If STRSAFE_IGNORE_NULLS is passed, both pszDest and pszSrc
Ritor1
parents:
diff changeset
2274 may be NULL. An error may still be returned even though NULLS are ignored
Ritor1
parents:
diff changeset
2275 due to insufficient space.
Ritor1
parents:
diff changeset
2276
Ritor1
parents:
diff changeset
2277 Return Value:
Ritor1
parents:
diff changeset
2278
Ritor1
parents:
diff changeset
2279 S_OK - if all of pszSrc or the first cbMaxAppend bytes were
Ritor1
parents:
diff changeset
2280 concatenated to pszDest and the resultant dest string
Ritor1
parents:
diff changeset
2281 was null terminated
Ritor1
parents:
diff changeset
2282
Ritor1
parents:
diff changeset
2283 failure - you can use the macro HRESULT_CODE() to get a win32
Ritor1
parents:
diff changeset
2284 error code for all hresult failure cases
Ritor1
parents:
diff changeset
2285
Ritor1
parents:
diff changeset
2286 STRSAFE_E_INSUFFICIENT_BUFFER /
Ritor1
parents:
diff changeset
2287 HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER
Ritor1
parents:
diff changeset
2288 - this return value is an indication that the operation
Ritor1
parents:
diff changeset
2289 failed due to insufficient space. When this error
Ritor1
parents:
diff changeset
2290 occurs, the destination buffer is modified to contain
Ritor1
parents:
diff changeset
2291 a truncated version of the ideal result and is null
Ritor1
parents:
diff changeset
2292 terminated. This is useful for situations where
Ritor1
parents:
diff changeset
2293 truncation is ok.
Ritor1
parents:
diff changeset
2294
Ritor1
parents:
diff changeset
2295 It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the
Ritor1
parents:
diff changeset
2296 return value of this function
Ritor1
parents:
diff changeset
2297
Ritor1
parents:
diff changeset
2298 --*/
Ritor1
parents:
diff changeset
2299
Ritor1
parents:
diff changeset
2300 STRSAFEAPI StringCbCatNExA(char* pszDest, size_t cbDest, const char* pszSrc, size_t cbMaxAppend, char** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags);
Ritor1
parents:
diff changeset
2301 STRSAFEAPI StringCbCatNExW(wchar_t* pszDest, size_t cbDest, const wchar_t* pszSrc, size_t cbMaxAppend, wchar_t** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags);
Ritor1
parents:
diff changeset
2302 #ifdef UNICODE
Ritor1
parents:
diff changeset
2303 #define StringCbCatNEx StringCbCatNExW
Ritor1
parents:
diff changeset
2304 #else
Ritor1
parents:
diff changeset
2305 #define StringCbCatNEx StringCbCatNExA
Ritor1
parents:
diff changeset
2306 #endif // !UNICODE
Ritor1
parents:
diff changeset
2307
Ritor1
parents:
diff changeset
2308 #ifdef STRSAFE_INLINE
Ritor1
parents:
diff changeset
2309 STRSAFEAPI StringCbCatNExA(char* pszDest, size_t cbDest, const char* pszSrc, size_t cbMaxAppend, char** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags)
Ritor1
parents:
diff changeset
2310 {
Ritor1
parents:
diff changeset
2311 HRESULT hr;
Ritor1
parents:
diff changeset
2312 size_t cchDest;
Ritor1
parents:
diff changeset
2313 size_t cchRemaining = 0;
Ritor1
parents:
diff changeset
2314
Ritor1
parents:
diff changeset
2315 cchDest = cbDest / sizeof(char);
Ritor1
parents:
diff changeset
2316
Ritor1
parents:
diff changeset
2317 if (cchDest > STRSAFE_MAX_CCH)
Ritor1
parents:
diff changeset
2318 {
Ritor1
parents:
diff changeset
2319 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
2320 }
Ritor1
parents:
diff changeset
2321 else
Ritor1
parents:
diff changeset
2322 {
Ritor1
parents:
diff changeset
2323 size_t cchMaxAppend;
Ritor1
parents:
diff changeset
2324
Ritor1
parents:
diff changeset
2325 cchMaxAppend = cbMaxAppend / sizeof(char);
Ritor1
parents:
diff changeset
2326
Ritor1
parents:
diff changeset
2327 hr = StringCatNExWorkerA(pszDest, cchDest, cbDest, pszSrc, cchMaxAppend, ppszDestEnd, &cchRemaining, dwFlags);
Ritor1
parents:
diff changeset
2328 }
Ritor1
parents:
diff changeset
2329
Ritor1
parents:
diff changeset
2330 if (SUCCEEDED(hr) || (hr == STRSAFE_E_INSUFFICIENT_BUFFER))
Ritor1
parents:
diff changeset
2331 {
Ritor1
parents:
diff changeset
2332 if (pcbRemaining)
Ritor1
parents:
diff changeset
2333 {
Ritor1
parents:
diff changeset
2334 // safe to multiply cchRemaining * sizeof(char) since cchRemaining < STRSAFE_MAX_CCH and sizeof(char) is 1
Ritor1
parents:
diff changeset
2335 *pcbRemaining = (cchRemaining * sizeof(char)) + (cbDest % sizeof(char));
Ritor1
parents:
diff changeset
2336 }
Ritor1
parents:
diff changeset
2337 }
Ritor1
parents:
diff changeset
2338
Ritor1
parents:
diff changeset
2339 return hr;
Ritor1
parents:
diff changeset
2340 }
Ritor1
parents:
diff changeset
2341
Ritor1
parents:
diff changeset
2342 STRSAFEAPI StringCbCatNExW(wchar_t* pszDest, size_t cbDest, const wchar_t* pszSrc, size_t cbMaxAppend, wchar_t** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags)
Ritor1
parents:
diff changeset
2343 {
Ritor1
parents:
diff changeset
2344 HRESULT hr;
Ritor1
parents:
diff changeset
2345 size_t cchDest;
Ritor1
parents:
diff changeset
2346 size_t cchRemaining = 0;
Ritor1
parents:
diff changeset
2347
Ritor1
parents:
diff changeset
2348 cchDest = cbDest / sizeof(wchar_t);
Ritor1
parents:
diff changeset
2349
Ritor1
parents:
diff changeset
2350 if (cchDest > STRSAFE_MAX_CCH)
Ritor1
parents:
diff changeset
2351 {
Ritor1
parents:
diff changeset
2352 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
2353 }
Ritor1
parents:
diff changeset
2354 else
Ritor1
parents:
diff changeset
2355 {
Ritor1
parents:
diff changeset
2356 size_t cchMaxAppend;
Ritor1
parents:
diff changeset
2357
Ritor1
parents:
diff changeset
2358 cchMaxAppend = cbMaxAppend / sizeof(wchar_t);
Ritor1
parents:
diff changeset
2359
Ritor1
parents:
diff changeset
2360 hr = StringCatNExWorkerW(pszDest, cchDest, cbDest, pszSrc, cchMaxAppend, ppszDestEnd, &cchRemaining, dwFlags);
Ritor1
parents:
diff changeset
2361 }
Ritor1
parents:
diff changeset
2362
Ritor1
parents:
diff changeset
2363 if (SUCCEEDED(hr) || (hr == STRSAFE_E_INSUFFICIENT_BUFFER))
Ritor1
parents:
diff changeset
2364 {
Ritor1
parents:
diff changeset
2365 if (pcbRemaining)
Ritor1
parents:
diff changeset
2366 {
Ritor1
parents:
diff changeset
2367 // safe to multiply cchRemaining * sizeof(wchar_t) since cchRemaining < STRSAFE_MAX_CCH and sizeof(wchar_t) is 2
Ritor1
parents:
diff changeset
2368 *pcbRemaining = (cchRemaining * sizeof(wchar_t)) + (cbDest % sizeof(wchar_t));
Ritor1
parents:
diff changeset
2369 }
Ritor1
parents:
diff changeset
2370 }
Ritor1
parents:
diff changeset
2371
Ritor1
parents:
diff changeset
2372 return hr;
Ritor1
parents:
diff changeset
2373 }
Ritor1
parents:
diff changeset
2374 #endif // STRSAFE_INLINE
Ritor1
parents:
diff changeset
2375 #endif // !STRSAFE_NO_CB_FUNCTIONS
Ritor1
parents:
diff changeset
2376
Ritor1
parents:
diff changeset
2377
Ritor1
parents:
diff changeset
2378 #ifndef STRSAFE_NO_CCH_FUNCTIONS
Ritor1
parents:
diff changeset
2379 /*++
Ritor1
parents:
diff changeset
2380
Ritor1
parents:
diff changeset
2381 STDAPI
Ritor1
parents:
diff changeset
2382 StringCchVPrintf(
Ritor1
parents:
diff changeset
2383 OUT LPTSTR pszDest,
Ritor1
parents:
diff changeset
2384 IN size_t cchDest,
Ritor1
parents:
diff changeset
2385 IN LPCTSTR pszFormat,
Ritor1
parents:
diff changeset
2386 IN va_list argList
Ritor1
parents:
diff changeset
2387 );
Ritor1
parents:
diff changeset
2388
Ritor1
parents:
diff changeset
2389 Routine Description:
Ritor1
parents:
diff changeset
2390
Ritor1
parents:
diff changeset
2391 This routine is a safer version of the C built-in function 'vsprintf'.
Ritor1
parents:
diff changeset
2392 The size of the destination buffer (in characters) is a parameter and
Ritor1
parents:
diff changeset
2393 this function will not write past the end of this buffer and it will
Ritor1
parents:
diff changeset
2394 ALWAYS null terminate the destination buffer (unless it is zero length).
Ritor1
parents:
diff changeset
2395
Ritor1
parents:
diff changeset
2396 This function returns a hresult, and not a pointer. It returns
Ritor1
parents:
diff changeset
2397 S_OK if the string was printed without truncation and null terminated,
Ritor1
parents:
diff changeset
2398 otherwise it will return a failure code. In failure cases it will return
Ritor1
parents:
diff changeset
2399 a truncated version of the ideal result.
Ritor1
parents:
diff changeset
2400
Ritor1
parents:
diff changeset
2401 Arguments:
Ritor1
parents:
diff changeset
2402
Ritor1
parents:
diff changeset
2403 pszDest - destination string
Ritor1
parents:
diff changeset
2404
Ritor1
parents:
diff changeset
2405 cchDest - size of destination buffer in characters
Ritor1
parents:
diff changeset
2406 length must be sufficient to hold the resulting formatted
Ritor1
parents:
diff changeset
2407 string, including the null terminator.
Ritor1
parents:
diff changeset
2408
Ritor1
parents:
diff changeset
2409 pszFormat - format string which must be null terminated
Ritor1
parents:
diff changeset
2410
Ritor1
parents:
diff changeset
2411 argList - va_list from the variable arguments according to the
Ritor1
parents:
diff changeset
2412 stdarg.h convention
Ritor1
parents:
diff changeset
2413
Ritor1
parents:
diff changeset
2414 Notes:
Ritor1
parents:
diff changeset
2415 Behavior is undefined if destination, format strings or any arguments
Ritor1
parents:
diff changeset
2416 strings overlap.
Ritor1
parents:
diff changeset
2417
Ritor1
parents:
diff changeset
2418 pszDest and pszFormat should not be NULL. See StringCchVPrintfEx if you
Ritor1
parents:
diff changeset
2419 require the handling of NULL values.
Ritor1
parents:
diff changeset
2420
Ritor1
parents:
diff changeset
2421 Return Value:
Ritor1
parents:
diff changeset
2422
Ritor1
parents:
diff changeset
2423 S_OK - if there was sufficient space in the dest buffer for
Ritor1
parents:
diff changeset
2424 the resultant string and it was null terminated.
Ritor1
parents:
diff changeset
2425
Ritor1
parents:
diff changeset
2426 failure - you can use the macro HRESULT_CODE() to get a win32
Ritor1
parents:
diff changeset
2427 error code for all hresult failure cases
Ritor1
parents:
diff changeset
2428
Ritor1
parents:
diff changeset
2429 STRSAFE_E_INSUFFICIENT_BUFFER /
Ritor1
parents:
diff changeset
2430 HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER
Ritor1
parents:
diff changeset
2431 - this return value is an indication that the print
Ritor1
parents:
diff changeset
2432 operation failed due to insufficient space. When this
Ritor1
parents:
diff changeset
2433 error occurs, the destination buffer is modified to
Ritor1
parents:
diff changeset
2434 contain a truncated version of the ideal result and is
Ritor1
parents:
diff changeset
2435 null terminated. This is useful for situations where
Ritor1
parents:
diff changeset
2436 truncation is ok.
Ritor1
parents:
diff changeset
2437
Ritor1
parents:
diff changeset
2438 It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the
Ritor1
parents:
diff changeset
2439 return value of this function
Ritor1
parents:
diff changeset
2440
Ritor1
parents:
diff changeset
2441 --*/
Ritor1
parents:
diff changeset
2442
Ritor1
parents:
diff changeset
2443 STRSAFEAPI StringCchVPrintfA(char* pszDest, size_t cchDest, const char* pszFormat, va_list argList);
Ritor1
parents:
diff changeset
2444 STRSAFEAPI StringCchVPrintfW(wchar_t* pszDest, size_t cchDest, const wchar_t* pszFormat, va_list argList);
Ritor1
parents:
diff changeset
2445 #ifdef UNICODE
Ritor1
parents:
diff changeset
2446 #define StringCchVPrintf StringCchVPrintfW
Ritor1
parents:
diff changeset
2447 #else
Ritor1
parents:
diff changeset
2448 #define StringCchVPrintf StringCchVPrintfA
Ritor1
parents:
diff changeset
2449 #endif // !UNICODE
Ritor1
parents:
diff changeset
2450
Ritor1
parents:
diff changeset
2451 #ifdef STRSAFE_INLINE
Ritor1
parents:
diff changeset
2452 STRSAFEAPI StringCchVPrintfA(char* pszDest, size_t cchDest, const char* pszFormat, va_list argList)
Ritor1
parents:
diff changeset
2453 {
Ritor1
parents:
diff changeset
2454 HRESULT hr;
Ritor1
parents:
diff changeset
2455
Ritor1
parents:
diff changeset
2456 if (cchDest > STRSAFE_MAX_CCH)
Ritor1
parents:
diff changeset
2457 {
Ritor1
parents:
diff changeset
2458 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
2459 }
Ritor1
parents:
diff changeset
2460 else
Ritor1
parents:
diff changeset
2461 {
Ritor1
parents:
diff changeset
2462 hr = StringVPrintfWorkerA(pszDest, cchDest, pszFormat, argList);
Ritor1
parents:
diff changeset
2463 }
Ritor1
parents:
diff changeset
2464
Ritor1
parents:
diff changeset
2465 return hr;
Ritor1
parents:
diff changeset
2466 }
Ritor1
parents:
diff changeset
2467
Ritor1
parents:
diff changeset
2468 STRSAFEAPI StringCchVPrintfW(wchar_t* pszDest, size_t cchDest, const wchar_t* pszFormat, va_list argList)
Ritor1
parents:
diff changeset
2469 {
Ritor1
parents:
diff changeset
2470 HRESULT hr;
Ritor1
parents:
diff changeset
2471
Ritor1
parents:
diff changeset
2472 if (cchDest > STRSAFE_MAX_CCH)
Ritor1
parents:
diff changeset
2473 {
Ritor1
parents:
diff changeset
2474 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
2475 }
Ritor1
parents:
diff changeset
2476 else
Ritor1
parents:
diff changeset
2477 {
Ritor1
parents:
diff changeset
2478 hr = StringVPrintfWorkerW(pszDest, cchDest, pszFormat, argList);
Ritor1
parents:
diff changeset
2479 }
Ritor1
parents:
diff changeset
2480
Ritor1
parents:
diff changeset
2481 return hr;
Ritor1
parents:
diff changeset
2482 }
Ritor1
parents:
diff changeset
2483 #endif // STRSAFE_INLINE
Ritor1
parents:
diff changeset
2484 #endif // !STRSAFE_NO_CCH_FUNCTIONS
Ritor1
parents:
diff changeset
2485
Ritor1
parents:
diff changeset
2486
Ritor1
parents:
diff changeset
2487 #ifndef STRSAFE_NO_CB_FUNCTIONS
Ritor1
parents:
diff changeset
2488 /*++
Ritor1
parents:
diff changeset
2489
Ritor1
parents:
diff changeset
2490 STDAPI
Ritor1
parents:
diff changeset
2491 StringCbVPrintf(
Ritor1
parents:
diff changeset
2492 OUT LPTSTR pszDest,
Ritor1
parents:
diff changeset
2493 IN size_t cbDest,
Ritor1
parents:
diff changeset
2494 IN LPCTSTR pszFormat,
Ritor1
parents:
diff changeset
2495 IN va_list argList
Ritor1
parents:
diff changeset
2496 );
Ritor1
parents:
diff changeset
2497
Ritor1
parents:
diff changeset
2498 Routine Description:
Ritor1
parents:
diff changeset
2499
Ritor1
parents:
diff changeset
2500 This routine is a safer version of the C built-in function 'vsprintf'.
Ritor1
parents:
diff changeset
2501 The size of the destination buffer (in bytes) is a parameter and
Ritor1
parents:
diff changeset
2502 this function will not write past the end of this buffer and it will
Ritor1
parents:
diff changeset
2503 ALWAYS null terminate the destination buffer (unless it is zero length).
Ritor1
parents:
diff changeset
2504
Ritor1
parents:
diff changeset
2505 This function returns a hresult, and not a pointer. It returns
Ritor1
parents:
diff changeset
2506 S_OK if the string was printed without truncation and null terminated,
Ritor1
parents:
diff changeset
2507 otherwise it will return a failure code. In failure cases it will return
Ritor1
parents:
diff changeset
2508 a truncated version of the ideal result.
Ritor1
parents:
diff changeset
2509
Ritor1
parents:
diff changeset
2510 Arguments:
Ritor1
parents:
diff changeset
2511
Ritor1
parents:
diff changeset
2512 pszDest - destination string
Ritor1
parents:
diff changeset
2513
Ritor1
parents:
diff changeset
2514 cbDest - size of destination buffer in bytes
Ritor1
parents:
diff changeset
2515 length must be sufficient to hold the resulting formatted
Ritor1
parents:
diff changeset
2516 string, including the null terminator.
Ritor1
parents:
diff changeset
2517
Ritor1
parents:
diff changeset
2518 pszFormat - format string which must be null terminated
Ritor1
parents:
diff changeset
2519
Ritor1
parents:
diff changeset
2520 argList - va_list from the variable arguments according to the
Ritor1
parents:
diff changeset
2521 stdarg.h convention
Ritor1
parents:
diff changeset
2522
Ritor1
parents:
diff changeset
2523 Notes:
Ritor1
parents:
diff changeset
2524 Behavior is undefined if destination, format strings or any arguments
Ritor1
parents:
diff changeset
2525 strings overlap.
Ritor1
parents:
diff changeset
2526
Ritor1
parents:
diff changeset
2527 pszDest and pszFormat should not be NULL. See StringCbVPrintfEx if you
Ritor1
parents:
diff changeset
2528 require the handling of NULL values.
Ritor1
parents:
diff changeset
2529
Ritor1
parents:
diff changeset
2530
Ritor1
parents:
diff changeset
2531 Return Value:
Ritor1
parents:
diff changeset
2532
Ritor1
parents:
diff changeset
2533 S_OK - if there was sufficient space in the dest buffer for
Ritor1
parents:
diff changeset
2534 the resultant string and it was null terminated.
Ritor1
parents:
diff changeset
2535
Ritor1
parents:
diff changeset
2536 failure - you can use the macro HRESULT_CODE() to get a win32
Ritor1
parents:
diff changeset
2537 error code for all hresult failure cases
Ritor1
parents:
diff changeset
2538
Ritor1
parents:
diff changeset
2539 STRSAFE_E_INSUFFICIENT_BUFFER /
Ritor1
parents:
diff changeset
2540 HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER
Ritor1
parents:
diff changeset
2541 - this return value is an indication that the print
Ritor1
parents:
diff changeset
2542 operation failed due to insufficient space. When this
Ritor1
parents:
diff changeset
2543 error occurs, the destination buffer is modified to
Ritor1
parents:
diff changeset
2544 contain a truncated version of the ideal result and is
Ritor1
parents:
diff changeset
2545 null terminated. This is useful for situations where
Ritor1
parents:
diff changeset
2546 truncation is ok.
Ritor1
parents:
diff changeset
2547
Ritor1
parents:
diff changeset
2548 It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the
Ritor1
parents:
diff changeset
2549 return value of this function
Ritor1
parents:
diff changeset
2550
Ritor1
parents:
diff changeset
2551 --*/
Ritor1
parents:
diff changeset
2552
Ritor1
parents:
diff changeset
2553 STRSAFEAPI StringCbVPrintfA(char* pszDest, size_t cbDest, const char* pszFormat, va_list argList);
Ritor1
parents:
diff changeset
2554 STRSAFEAPI StringCbVPrintfW(wchar_t* pszDest, size_t cbDest, const wchar_t* pszFormat, va_list argList);
Ritor1
parents:
diff changeset
2555 #ifdef UNICODE
Ritor1
parents:
diff changeset
2556 #define StringCbVPrintf StringCbVPrintfW
Ritor1
parents:
diff changeset
2557 #else
Ritor1
parents:
diff changeset
2558 #define StringCbVPrintf StringCbVPrintfA
Ritor1
parents:
diff changeset
2559 #endif // !UNICODE
Ritor1
parents:
diff changeset
2560
Ritor1
parents:
diff changeset
2561 #ifdef STRSAFE_INLINE
Ritor1
parents:
diff changeset
2562 STRSAFEAPI StringCbVPrintfA(char* pszDest, size_t cbDest, const char* pszFormat, va_list argList)
Ritor1
parents:
diff changeset
2563 {
Ritor1
parents:
diff changeset
2564 HRESULT hr;
Ritor1
parents:
diff changeset
2565 size_t cchDest;
Ritor1
parents:
diff changeset
2566
Ritor1
parents:
diff changeset
2567 cchDest = cbDest / sizeof(char);
Ritor1
parents:
diff changeset
2568
Ritor1
parents:
diff changeset
2569 if (cchDest > STRSAFE_MAX_CCH)
Ritor1
parents:
diff changeset
2570 {
Ritor1
parents:
diff changeset
2571 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
2572 }
Ritor1
parents:
diff changeset
2573 else
Ritor1
parents:
diff changeset
2574 {
Ritor1
parents:
diff changeset
2575 hr = StringVPrintfWorkerA(pszDest, cchDest, pszFormat, argList);
Ritor1
parents:
diff changeset
2576 }
Ritor1
parents:
diff changeset
2577
Ritor1
parents:
diff changeset
2578 return hr;
Ritor1
parents:
diff changeset
2579 }
Ritor1
parents:
diff changeset
2580
Ritor1
parents:
diff changeset
2581 STRSAFEAPI StringCbVPrintfW(wchar_t* pszDest, size_t cbDest, const wchar_t* pszFormat, va_list argList)
Ritor1
parents:
diff changeset
2582 {
Ritor1
parents:
diff changeset
2583 HRESULT hr;
Ritor1
parents:
diff changeset
2584 size_t cchDest;
Ritor1
parents:
diff changeset
2585
Ritor1
parents:
diff changeset
2586 cchDest = cbDest / sizeof(wchar_t);
Ritor1
parents:
diff changeset
2587
Ritor1
parents:
diff changeset
2588 if (cchDest > STRSAFE_MAX_CCH)
Ritor1
parents:
diff changeset
2589 {
Ritor1
parents:
diff changeset
2590 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
2591 }
Ritor1
parents:
diff changeset
2592 else
Ritor1
parents:
diff changeset
2593 {
Ritor1
parents:
diff changeset
2594 hr = StringVPrintfWorkerW(pszDest, cchDest, pszFormat, argList);
Ritor1
parents:
diff changeset
2595 }
Ritor1
parents:
diff changeset
2596
Ritor1
parents:
diff changeset
2597 return hr;
Ritor1
parents:
diff changeset
2598 }
Ritor1
parents:
diff changeset
2599 #endif // STRSAFE_INLINE
Ritor1
parents:
diff changeset
2600 #endif // !STRSAFE_NO_CB_FUNCTIONS
Ritor1
parents:
diff changeset
2601
Ritor1
parents:
diff changeset
2602
Ritor1
parents:
diff changeset
2603 #ifndef STRSAFE_NO_CCH_FUNCTIONS
Ritor1
parents:
diff changeset
2604 /*++
Ritor1
parents:
diff changeset
2605
Ritor1
parents:
diff changeset
2606 STDAPI
Ritor1
parents:
diff changeset
2607 StringCchPrintf(
Ritor1
parents:
diff changeset
2608 OUT LPTSTR pszDest,
Ritor1
parents:
diff changeset
2609 IN size_t cchDest,
Ritor1
parents:
diff changeset
2610 IN LPCTSTR pszFormat,
Ritor1
parents:
diff changeset
2611 ...
Ritor1
parents:
diff changeset
2612 );
Ritor1
parents:
diff changeset
2613
Ritor1
parents:
diff changeset
2614 Routine Description:
Ritor1
parents:
diff changeset
2615
Ritor1
parents:
diff changeset
2616 This routine is a safer version of the C built-in function 'sprintf'.
Ritor1
parents:
diff changeset
2617 The size of the destination buffer (in characters) is a parameter and
Ritor1
parents:
diff changeset
2618 this function will not write past the end of this buffer and it will
Ritor1
parents:
diff changeset
2619 ALWAYS null terminate the destination buffer (unless it is zero length).
Ritor1
parents:
diff changeset
2620
Ritor1
parents:
diff changeset
2621 This function returns a hresult, and not a pointer. It returns
Ritor1
parents:
diff changeset
2622 S_OK if the string was printed without truncation and null terminated,
Ritor1
parents:
diff changeset
2623 otherwise it will return a failure code. In failure cases it will return
Ritor1
parents:
diff changeset
2624 a truncated version of the ideal result.
Ritor1
parents:
diff changeset
2625
Ritor1
parents:
diff changeset
2626 Arguments:
Ritor1
parents:
diff changeset
2627
Ritor1
parents:
diff changeset
2628 pszDest - destination string
Ritor1
parents:
diff changeset
2629
Ritor1
parents:
diff changeset
2630 cchDest - size of destination buffer in characters
Ritor1
parents:
diff changeset
2631 length must be sufficient to hold the resulting formatted
Ritor1
parents:
diff changeset
2632 string, including the null terminator.
Ritor1
parents:
diff changeset
2633
Ritor1
parents:
diff changeset
2634 pszFormat - format string which must be null terminated
Ritor1
parents:
diff changeset
2635
Ritor1
parents:
diff changeset
2636 ... - additional parameters to be formatted according to
Ritor1
parents:
diff changeset
2637 the format string
Ritor1
parents:
diff changeset
2638
Ritor1
parents:
diff changeset
2639 Notes:
Ritor1
parents:
diff changeset
2640 Behavior is undefined if destination, format strings or any arguments
Ritor1
parents:
diff changeset
2641 strings overlap.
Ritor1
parents:
diff changeset
2642
Ritor1
parents:
diff changeset
2643 pszDest and pszFormat should not be NULL. See StringCchPrintfEx if you
Ritor1
parents:
diff changeset
2644 require the handling of NULL values.
Ritor1
parents:
diff changeset
2645
Ritor1
parents:
diff changeset
2646 Return Value:
Ritor1
parents:
diff changeset
2647
Ritor1
parents:
diff changeset
2648 S_OK - if there was sufficient space in the dest buffer for
Ritor1
parents:
diff changeset
2649 the resultant string and it was null terminated.
Ritor1
parents:
diff changeset
2650
Ritor1
parents:
diff changeset
2651 failure - you can use the macro HRESULT_CODE() to get a win32
Ritor1
parents:
diff changeset
2652 error code for all hresult failure cases
Ritor1
parents:
diff changeset
2653
Ritor1
parents:
diff changeset
2654 STRSAFE_E_INSUFFICIENT_BUFFER /
Ritor1
parents:
diff changeset
2655 HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER
Ritor1
parents:
diff changeset
2656 - this return value is an indication that the print
Ritor1
parents:
diff changeset
2657 operation failed due to insufficient space. When this
Ritor1
parents:
diff changeset
2658 error occurs, the destination buffer is modified to
Ritor1
parents:
diff changeset
2659 contain a truncated version of the ideal result and is
Ritor1
parents:
diff changeset
2660 null terminated. This is useful for situations where
Ritor1
parents:
diff changeset
2661 truncation is ok.
Ritor1
parents:
diff changeset
2662
Ritor1
parents:
diff changeset
2663 It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the
Ritor1
parents:
diff changeset
2664 return value of this function
Ritor1
parents:
diff changeset
2665
Ritor1
parents:
diff changeset
2666 --*/
Ritor1
parents:
diff changeset
2667
Ritor1
parents:
diff changeset
2668 STRSAFEAPI StringCchPrintfA(char* pszDest, size_t cchDest, const char* pszFormat, ...);
Ritor1
parents:
diff changeset
2669 STRSAFEAPI StringCchPrintfW(wchar_t* pszDest, size_t cchDest, const wchar_t* pszFormat, ...);
Ritor1
parents:
diff changeset
2670 #ifdef UNICODE
Ritor1
parents:
diff changeset
2671 #define StringCchPrintf StringCchPrintfW
Ritor1
parents:
diff changeset
2672 #else
Ritor1
parents:
diff changeset
2673 #define StringCchPrintf StringCchPrintfA
Ritor1
parents:
diff changeset
2674 #endif // !UNICODE
Ritor1
parents:
diff changeset
2675
Ritor1
parents:
diff changeset
2676 #ifdef STRSAFE_INLINE
Ritor1
parents:
diff changeset
2677 STRSAFEAPI StringCchPrintfA(char* pszDest, size_t cchDest, const char* pszFormat, ...)
Ritor1
parents:
diff changeset
2678 {
Ritor1
parents:
diff changeset
2679 HRESULT hr;
Ritor1
parents:
diff changeset
2680
Ritor1
parents:
diff changeset
2681 if (cchDest > STRSAFE_MAX_CCH)
Ritor1
parents:
diff changeset
2682 {
Ritor1
parents:
diff changeset
2683 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
2684 }
Ritor1
parents:
diff changeset
2685 else
Ritor1
parents:
diff changeset
2686 {
Ritor1
parents:
diff changeset
2687 va_list argList;
Ritor1
parents:
diff changeset
2688
Ritor1
parents:
diff changeset
2689 va_start(argList, pszFormat);
Ritor1
parents:
diff changeset
2690
Ritor1
parents:
diff changeset
2691 hr = StringVPrintfWorkerA(pszDest, cchDest, pszFormat, argList);
Ritor1
parents:
diff changeset
2692
Ritor1
parents:
diff changeset
2693 va_end(argList);
Ritor1
parents:
diff changeset
2694 }
Ritor1
parents:
diff changeset
2695
Ritor1
parents:
diff changeset
2696 return hr;
Ritor1
parents:
diff changeset
2697 }
Ritor1
parents:
diff changeset
2698
Ritor1
parents:
diff changeset
2699 STRSAFEAPI StringCchPrintfW(wchar_t* pszDest, size_t cchDest, const wchar_t* pszFormat, ...)
Ritor1
parents:
diff changeset
2700 {
Ritor1
parents:
diff changeset
2701 HRESULT hr;
Ritor1
parents:
diff changeset
2702
Ritor1
parents:
diff changeset
2703 if (cchDest > STRSAFE_MAX_CCH)
Ritor1
parents:
diff changeset
2704 {
Ritor1
parents:
diff changeset
2705 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
2706 }
Ritor1
parents:
diff changeset
2707 else
Ritor1
parents:
diff changeset
2708 {
Ritor1
parents:
diff changeset
2709 va_list argList;
Ritor1
parents:
diff changeset
2710
Ritor1
parents:
diff changeset
2711 va_start(argList, pszFormat);
Ritor1
parents:
diff changeset
2712
Ritor1
parents:
diff changeset
2713 hr = StringVPrintfWorkerW(pszDest, cchDest, pszFormat, argList);
Ritor1
parents:
diff changeset
2714
Ritor1
parents:
diff changeset
2715 va_end(argList);
Ritor1
parents:
diff changeset
2716 }
Ritor1
parents:
diff changeset
2717
Ritor1
parents:
diff changeset
2718 return hr;
Ritor1
parents:
diff changeset
2719 }
Ritor1
parents:
diff changeset
2720 #endif // STRSAFE_INLINE
Ritor1
parents:
diff changeset
2721 #endif // !STRSAFE_NO_CCH_FUNCTIONS
Ritor1
parents:
diff changeset
2722
Ritor1
parents:
diff changeset
2723
Ritor1
parents:
diff changeset
2724 #ifndef STRSAFE_NO_CB_FUNCTIONS
Ritor1
parents:
diff changeset
2725 /*++
Ritor1
parents:
diff changeset
2726
Ritor1
parents:
diff changeset
2727 STDAPI
Ritor1
parents:
diff changeset
2728 StringCbPrintf(
Ritor1
parents:
diff changeset
2729 OUT LPTSTR pszDest,
Ritor1
parents:
diff changeset
2730 IN size_t cbDest,
Ritor1
parents:
diff changeset
2731 IN LPCTSTR pszFormat,
Ritor1
parents:
diff changeset
2732 ...
Ritor1
parents:
diff changeset
2733 );
Ritor1
parents:
diff changeset
2734
Ritor1
parents:
diff changeset
2735 Routine Description:
Ritor1
parents:
diff changeset
2736
Ritor1
parents:
diff changeset
2737 This routine is a safer version of the C built-in function 'sprintf'.
Ritor1
parents:
diff changeset
2738 The size of the destination buffer (in bytes) is a parameter and
Ritor1
parents:
diff changeset
2739 this function will not write past the end of this buffer and it will
Ritor1
parents:
diff changeset
2740 ALWAYS null terminate the destination buffer (unless it is zero length).
Ritor1
parents:
diff changeset
2741
Ritor1
parents:
diff changeset
2742 This function returns a hresult, and not a pointer. It returns
Ritor1
parents:
diff changeset
2743 S_OK if the string was printed without truncation and null terminated,
Ritor1
parents:
diff changeset
2744 otherwise it will return a failure code. In failure cases it will return
Ritor1
parents:
diff changeset
2745 a truncated version of the ideal result.
Ritor1
parents:
diff changeset
2746
Ritor1
parents:
diff changeset
2747 Arguments:
Ritor1
parents:
diff changeset
2748
Ritor1
parents:
diff changeset
2749 pszDest - destination string
Ritor1
parents:
diff changeset
2750
Ritor1
parents:
diff changeset
2751 cbDest - size of destination buffer in bytes
Ritor1
parents:
diff changeset
2752 length must be sufficient to hold the resulting formatted
Ritor1
parents:
diff changeset
2753 string, including the null terminator.
Ritor1
parents:
diff changeset
2754
Ritor1
parents:
diff changeset
2755 pszFormat - format string which must be null terminated
Ritor1
parents:
diff changeset
2756
Ritor1
parents:
diff changeset
2757 ... - additional parameters to be formatted according to
Ritor1
parents:
diff changeset
2758 the format string
Ritor1
parents:
diff changeset
2759
Ritor1
parents:
diff changeset
2760 Notes:
Ritor1
parents:
diff changeset
2761 Behavior is undefined if destination, format strings or any arguments
Ritor1
parents:
diff changeset
2762 strings overlap.
Ritor1
parents:
diff changeset
2763
Ritor1
parents:
diff changeset
2764 pszDest and pszFormat should not be NULL. See StringCbPrintfEx if you
Ritor1
parents:
diff changeset
2765 require the handling of NULL values.
Ritor1
parents:
diff changeset
2766
Ritor1
parents:
diff changeset
2767
Ritor1
parents:
diff changeset
2768 Return Value:
Ritor1
parents:
diff changeset
2769
Ritor1
parents:
diff changeset
2770 S_OK - if there was sufficient space in the dest buffer for
Ritor1
parents:
diff changeset
2771 the resultant string and it was null terminated.
Ritor1
parents:
diff changeset
2772
Ritor1
parents:
diff changeset
2773 failure - you can use the macro HRESULT_CODE() to get a win32
Ritor1
parents:
diff changeset
2774 error code for all hresult failure cases
Ritor1
parents:
diff changeset
2775
Ritor1
parents:
diff changeset
2776 STRSAFE_E_INSUFFICIENT_BUFFER /
Ritor1
parents:
diff changeset
2777 HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER
Ritor1
parents:
diff changeset
2778 - this return value is an indication that the print
Ritor1
parents:
diff changeset
2779 operation failed due to insufficient space. When this
Ritor1
parents:
diff changeset
2780 error occurs, the destination buffer is modified to
Ritor1
parents:
diff changeset
2781 contain a truncated version of the ideal result and is
Ritor1
parents:
diff changeset
2782 null terminated. This is useful for situations where
Ritor1
parents:
diff changeset
2783 truncation is ok.
Ritor1
parents:
diff changeset
2784
Ritor1
parents:
diff changeset
2785 It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the
Ritor1
parents:
diff changeset
2786 return value of this function
Ritor1
parents:
diff changeset
2787
Ritor1
parents:
diff changeset
2788 --*/
Ritor1
parents:
diff changeset
2789
Ritor1
parents:
diff changeset
2790 STRSAFEAPI StringCbPrintfA(char* pszDest, size_t cbDest, const char* pszFormat, ...);
Ritor1
parents:
diff changeset
2791 STRSAFEAPI StringCbPrintfW(wchar_t* pszDest, size_t cbDest, const wchar_t* pszFormat, ...);
Ritor1
parents:
diff changeset
2792 #ifdef UNICODE
Ritor1
parents:
diff changeset
2793 #define StringCbPrintf StringCbPrintfW
Ritor1
parents:
diff changeset
2794 #else
Ritor1
parents:
diff changeset
2795 #define StringCbPrintf StringCbPrintfA
Ritor1
parents:
diff changeset
2796 #endif // !UNICODE
Ritor1
parents:
diff changeset
2797
Ritor1
parents:
diff changeset
2798 #ifdef STRSAFE_INLINE
Ritor1
parents:
diff changeset
2799 STRSAFEAPI StringCbPrintfA(char* pszDest, size_t cbDest, const char* pszFormat, ...)
Ritor1
parents:
diff changeset
2800 {
Ritor1
parents:
diff changeset
2801 HRESULT hr;
Ritor1
parents:
diff changeset
2802 size_t cchDest;
Ritor1
parents:
diff changeset
2803
Ritor1
parents:
diff changeset
2804 cchDest = cbDest / sizeof(char);
Ritor1
parents:
diff changeset
2805
Ritor1
parents:
diff changeset
2806 if (cchDest > STRSAFE_MAX_CCH)
Ritor1
parents:
diff changeset
2807 {
Ritor1
parents:
diff changeset
2808 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
2809 }
Ritor1
parents:
diff changeset
2810 else
Ritor1
parents:
diff changeset
2811 {
Ritor1
parents:
diff changeset
2812 va_list argList;
Ritor1
parents:
diff changeset
2813
Ritor1
parents:
diff changeset
2814 va_start(argList, pszFormat);
Ritor1
parents:
diff changeset
2815
Ritor1
parents:
diff changeset
2816 hr = StringVPrintfWorkerA(pszDest, cchDest, pszFormat, argList);
Ritor1
parents:
diff changeset
2817
Ritor1
parents:
diff changeset
2818 va_end(argList);
Ritor1
parents:
diff changeset
2819 }
Ritor1
parents:
diff changeset
2820
Ritor1
parents:
diff changeset
2821 return hr;
Ritor1
parents:
diff changeset
2822 }
Ritor1
parents:
diff changeset
2823
Ritor1
parents:
diff changeset
2824 STRSAFEAPI StringCbPrintfW(wchar_t* pszDest, size_t cbDest, const wchar_t* pszFormat, ...)
Ritor1
parents:
diff changeset
2825 {
Ritor1
parents:
diff changeset
2826 HRESULT hr;
Ritor1
parents:
diff changeset
2827 size_t cchDest;
Ritor1
parents:
diff changeset
2828
Ritor1
parents:
diff changeset
2829 cchDest = cbDest / sizeof(wchar_t);
Ritor1
parents:
diff changeset
2830
Ritor1
parents:
diff changeset
2831 if (cchDest > STRSAFE_MAX_CCH)
Ritor1
parents:
diff changeset
2832 {
Ritor1
parents:
diff changeset
2833 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
2834 }
Ritor1
parents:
diff changeset
2835 else
Ritor1
parents:
diff changeset
2836 {
Ritor1
parents:
diff changeset
2837 va_list argList;
Ritor1
parents:
diff changeset
2838
Ritor1
parents:
diff changeset
2839 va_start(argList, pszFormat);
Ritor1
parents:
diff changeset
2840
Ritor1
parents:
diff changeset
2841 hr = StringVPrintfWorkerW(pszDest, cchDest, pszFormat, argList);
Ritor1
parents:
diff changeset
2842
Ritor1
parents:
diff changeset
2843 va_end(argList);
Ritor1
parents:
diff changeset
2844 }
Ritor1
parents:
diff changeset
2845
Ritor1
parents:
diff changeset
2846 return hr;
Ritor1
parents:
diff changeset
2847 }
Ritor1
parents:
diff changeset
2848 #endif // STRSAFE_INLINE
Ritor1
parents:
diff changeset
2849 #endif // !STRSAFE_NO_CB_FUNCTIONS
Ritor1
parents:
diff changeset
2850
Ritor1
parents:
diff changeset
2851
Ritor1
parents:
diff changeset
2852 #ifndef STRSAFE_NO_CCH_FUNCTIONS
Ritor1
parents:
diff changeset
2853 /*++
Ritor1
parents:
diff changeset
2854
Ritor1
parents:
diff changeset
2855 STDAPI
Ritor1
parents:
diff changeset
2856 StringCchPrintfEx(
Ritor1
parents:
diff changeset
2857 OUT LPTSTR pszDest OPTIONAL,
Ritor1
parents:
diff changeset
2858 IN size_t cchDest,
Ritor1
parents:
diff changeset
2859 OUT LPTSTR* ppszDestEnd OPTIONAL,
Ritor1
parents:
diff changeset
2860 OUT size_t* pcchRemaining OPTIONAL,
Ritor1
parents:
diff changeset
2861 IN DWORD dwFlags,
Ritor1
parents:
diff changeset
2862 IN LPCTSTR pszFormat OPTIONAL,
Ritor1
parents:
diff changeset
2863 ...
Ritor1
parents:
diff changeset
2864 );
Ritor1
parents:
diff changeset
2865
Ritor1
parents:
diff changeset
2866 Routine Description:
Ritor1
parents:
diff changeset
2867
Ritor1
parents:
diff changeset
2868 This routine is a safer version of the C built-in function 'sprintf' with
Ritor1
parents:
diff changeset
2869 some additional parameters. In addition to functionality provided by
Ritor1
parents:
diff changeset
2870 StringCchPrintf, this routine also returns a pointer to the end of the
Ritor1
parents:
diff changeset
2871 destination string and the number of characters left in the destination string
Ritor1
parents:
diff changeset
2872 including the null terminator. The flags parameter allows additional controls.
Ritor1
parents:
diff changeset
2873
Ritor1
parents:
diff changeset
2874 Arguments:
Ritor1
parents:
diff changeset
2875
Ritor1
parents:
diff changeset
2876 pszDest - destination string
Ritor1
parents:
diff changeset
2877
Ritor1
parents:
diff changeset
2878 cchDest - size of destination buffer in characters.
Ritor1
parents:
diff changeset
2879 length must be sufficient to contain the resulting
Ritor1
parents:
diff changeset
2880 formatted string plus the null terminator.
Ritor1
parents:
diff changeset
2881
Ritor1
parents:
diff changeset
2882 ppszDestEnd - if ppszDestEnd is non-null, the function will return a
Ritor1
parents:
diff changeset
2883 pointer to the end of the destination string. If the
Ritor1
parents:
diff changeset
2884 function printed any data, the result will point to the
Ritor1
parents:
diff changeset
2885 null termination character
Ritor1
parents:
diff changeset
2886
Ritor1
parents:
diff changeset
2887 pcchRemaining - if pcchRemaining is non-null, the function will return
Ritor1
parents:
diff changeset
2888 the number of characters left in the destination string,
Ritor1
parents:
diff changeset
2889 including the null terminator
Ritor1
parents:
diff changeset
2890
Ritor1
parents:
diff changeset
2891 dwFlags - controls some details of the string copy:
Ritor1
parents:
diff changeset
2892
Ritor1
parents:
diff changeset
2893 STRSAFE_FILL_BEHIND_NULL
Ritor1
parents:
diff changeset
2894 if the function succeeds, the low byte of dwFlags will be
Ritor1
parents:
diff changeset
2895 used to fill the uninitialize part of destination buffer
Ritor1
parents:
diff changeset
2896 behind the null terminator
Ritor1
parents:
diff changeset
2897
Ritor1
parents:
diff changeset
2898 STRSAFE_IGNORE_NULLS
Ritor1
parents:
diff changeset
2899 treat NULL string pointers like empty strings (TEXT(""))
Ritor1
parents:
diff changeset
2900
Ritor1
parents:
diff changeset
2901 STRSAFE_FILL_ON_FAILURE
Ritor1
parents:
diff changeset
2902 if the function fails, the low byte of dwFlags will be
Ritor1
parents:
diff changeset
2903 used to fill all of the destination buffer, and it will
Ritor1
parents:
diff changeset
2904 be null terminated. This will overwrite any truncated
Ritor1
parents:
diff changeset
2905 string returned when the failure is
Ritor1
parents:
diff changeset
2906 STRSAFE_E_INSUFFICIENT_BUFFER
Ritor1
parents:
diff changeset
2907
Ritor1
parents:
diff changeset
2908 STRSAFE_NO_TRUNCATION /
Ritor1
parents:
diff changeset
2909 STRSAFE_NULL_ON_FAILURE
Ritor1
parents:
diff changeset
2910 if the function fails, the destination buffer will be set
Ritor1
parents:
diff changeset
2911 to the empty string. This will overwrite any truncated string
Ritor1
parents:
diff changeset
2912 returned when the failure is STRSAFE_E_INSUFFICIENT_BUFFER.
Ritor1
parents:
diff changeset
2913
Ritor1
parents:
diff changeset
2914 pszFormat - format string which must be null terminated
Ritor1
parents:
diff changeset
2915
Ritor1
parents:
diff changeset
2916 ... - additional parameters to be formatted according to
Ritor1
parents:
diff changeset
2917 the format string
Ritor1
parents:
diff changeset
2918
Ritor1
parents:
diff changeset
2919 Notes:
Ritor1
parents:
diff changeset
2920 Behavior is undefined if destination, format strings or any arguments
Ritor1
parents:
diff changeset
2921 strings overlap.
Ritor1
parents:
diff changeset
2922
Ritor1
parents:
diff changeset
2923 pszDest and pszFormat should not be NULL unless the STRSAFE_IGNORE_NULLS
Ritor1
parents:
diff changeset
2924 flag is specified. If STRSAFE_IGNORE_NULLS is passed, both pszDest and
Ritor1
parents:
diff changeset
2925 pszFormat may be NULL. An error may still be returned even though NULLS
Ritor1
parents:
diff changeset
2926 are ignored due to insufficient space.
Ritor1
parents:
diff changeset
2927
Ritor1
parents:
diff changeset
2928 Return Value:
Ritor1
parents:
diff changeset
2929
Ritor1
parents:
diff changeset
2930 S_OK - if there was source data and it was all concatenated and
Ritor1
parents:
diff changeset
2931 the resultant dest string was null terminated
Ritor1
parents:
diff changeset
2932
Ritor1
parents:
diff changeset
2933 failure - you can use the macro HRESULT_CODE() to get a win32
Ritor1
parents:
diff changeset
2934 error code for all hresult failure cases
Ritor1
parents:
diff changeset
2935
Ritor1
parents:
diff changeset
2936 STRSAFE_E_INSUFFICIENT_BUFFER /
Ritor1
parents:
diff changeset
2937 HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER
Ritor1
parents:
diff changeset
2938 - this return value is an indication that the print
Ritor1
parents:
diff changeset
2939 operation failed due to insufficient space. When this
Ritor1
parents:
diff changeset
2940 error occurs, the destination buffer is modified to
Ritor1
parents:
diff changeset
2941 contain a truncated version of the ideal result and is
Ritor1
parents:
diff changeset
2942 null terminated. This is useful for situations where
Ritor1
parents:
diff changeset
2943 truncation is ok.
Ritor1
parents:
diff changeset
2944
Ritor1
parents:
diff changeset
2945 It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the
Ritor1
parents:
diff changeset
2946 return value of this function
Ritor1
parents:
diff changeset
2947
Ritor1
parents:
diff changeset
2948 --*/
Ritor1
parents:
diff changeset
2949
Ritor1
parents:
diff changeset
2950 STRSAFEAPI StringCchPrintfExA(char* pszDest, size_t cchDest, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags, const char* pszFormat, ...);
Ritor1
parents:
diff changeset
2951 STRSAFEAPI StringCchPrintfExW(wchar_t* pszDest, size_t cchDest, wchar_t** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags, const wchar_t* pszFormat, ...);
Ritor1
parents:
diff changeset
2952 #ifdef UNICODE
Ritor1
parents:
diff changeset
2953 #define StringCchPrintfEx StringCchPrintfExW
Ritor1
parents:
diff changeset
2954 #else
Ritor1
parents:
diff changeset
2955 #define StringCchPrintfEx StringCchPrintfExA
Ritor1
parents:
diff changeset
2956 #endif // !UNICODE
Ritor1
parents:
diff changeset
2957
Ritor1
parents:
diff changeset
2958 #ifdef STRSAFE_INLINE
Ritor1
parents:
diff changeset
2959 STRSAFEAPI StringCchPrintfExA(char* pszDest, size_t cchDest, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags, const char* pszFormat, ...)
Ritor1
parents:
diff changeset
2960 {
Ritor1
parents:
diff changeset
2961 HRESULT hr;
Ritor1
parents:
diff changeset
2962
Ritor1
parents:
diff changeset
2963 if (cchDest > STRSAFE_MAX_CCH)
Ritor1
parents:
diff changeset
2964 {
Ritor1
parents:
diff changeset
2965 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
2966 }
Ritor1
parents:
diff changeset
2967 else
Ritor1
parents:
diff changeset
2968 {
Ritor1
parents:
diff changeset
2969 size_t cbDest;
Ritor1
parents:
diff changeset
2970 va_list argList;
Ritor1
parents:
diff changeset
2971
Ritor1
parents:
diff changeset
2972 // safe to multiply cchDest * sizeof(char) since cchDest < STRSAFE_MAX_CCH and sizeof(char) is 1
Ritor1
parents:
diff changeset
2973 cbDest = cchDest * sizeof(char);
Ritor1
parents:
diff changeset
2974 va_start(argList, pszFormat);
Ritor1
parents:
diff changeset
2975
Ritor1
parents:
diff changeset
2976 hr = StringVPrintfExWorkerA(pszDest, cchDest, cbDest, ppszDestEnd, pcchRemaining, dwFlags, pszFormat, argList);
Ritor1
parents:
diff changeset
2977
Ritor1
parents:
diff changeset
2978 va_end(argList);
Ritor1
parents:
diff changeset
2979 }
Ritor1
parents:
diff changeset
2980
Ritor1
parents:
diff changeset
2981 return hr;
Ritor1
parents:
diff changeset
2982 }
Ritor1
parents:
diff changeset
2983
Ritor1
parents:
diff changeset
2984 STRSAFEAPI StringCchPrintfExW(wchar_t* pszDest, size_t cchDest, wchar_t** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags, const wchar_t* pszFormat, ...)
Ritor1
parents:
diff changeset
2985 {
Ritor1
parents:
diff changeset
2986 HRESULT hr;
Ritor1
parents:
diff changeset
2987
Ritor1
parents:
diff changeset
2988 if (cchDest > STRSAFE_MAX_CCH)
Ritor1
parents:
diff changeset
2989 {
Ritor1
parents:
diff changeset
2990 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
2991 }
Ritor1
parents:
diff changeset
2992 else
Ritor1
parents:
diff changeset
2993 {
Ritor1
parents:
diff changeset
2994 size_t cbDest;
Ritor1
parents:
diff changeset
2995 va_list argList;
Ritor1
parents:
diff changeset
2996
Ritor1
parents:
diff changeset
2997 // safe to multiply cchDest * sizeof(wchar_t) since cchDest < STRSAFE_MAX_CCH and sizeof(wchar_t) is 2
Ritor1
parents:
diff changeset
2998 cbDest = cchDest * sizeof(wchar_t);
Ritor1
parents:
diff changeset
2999 va_start(argList, pszFormat);
Ritor1
parents:
diff changeset
3000
Ritor1
parents:
diff changeset
3001 hr = StringVPrintfExWorkerW(pszDest, cchDest, cbDest, ppszDestEnd, pcchRemaining, dwFlags, pszFormat, argList);
Ritor1
parents:
diff changeset
3002
Ritor1
parents:
diff changeset
3003 va_end(argList);
Ritor1
parents:
diff changeset
3004 }
Ritor1
parents:
diff changeset
3005
Ritor1
parents:
diff changeset
3006 return hr;
Ritor1
parents:
diff changeset
3007 }
Ritor1
parents:
diff changeset
3008 #endif // STRSAFE_INLINE
Ritor1
parents:
diff changeset
3009 #endif // !STRSAFE_NO_CCH_FUNCTIONS
Ritor1
parents:
diff changeset
3010
Ritor1
parents:
diff changeset
3011
Ritor1
parents:
diff changeset
3012 #ifndef STRSAFE_NO_CB_FUNCTIONS
Ritor1
parents:
diff changeset
3013 /*++
Ritor1
parents:
diff changeset
3014
Ritor1
parents:
diff changeset
3015 STDAPI
Ritor1
parents:
diff changeset
3016 StringCbPrintfEx(
Ritor1
parents:
diff changeset
3017 OUT LPTSTR pszDest OPTIONAL,
Ritor1
parents:
diff changeset
3018 IN size_t cbDest,
Ritor1
parents:
diff changeset
3019 OUT LPTSTR* ppszDestEnd OPTIONAL,
Ritor1
parents:
diff changeset
3020 OUT size_t* pcbRemaining OPTIONAL,
Ritor1
parents:
diff changeset
3021 IN DWORD dwFlags,
Ritor1
parents:
diff changeset
3022 IN LPCTSTR pszFormat OPTIONAL,
Ritor1
parents:
diff changeset
3023 ...
Ritor1
parents:
diff changeset
3024 );
Ritor1
parents:
diff changeset
3025
Ritor1
parents:
diff changeset
3026 Routine Description:
Ritor1
parents:
diff changeset
3027
Ritor1
parents:
diff changeset
3028 This routine is a safer version of the C built-in function 'sprintf' with
Ritor1
parents:
diff changeset
3029 some additional parameters. In addition to functionality provided by
Ritor1
parents:
diff changeset
3030 StringCbPrintf, this routine also returns a pointer to the end of the
Ritor1
parents:
diff changeset
3031 destination string and the number of bytes left in the destination string
Ritor1
parents:
diff changeset
3032 including the null terminator. The flags parameter allows additional controls.
Ritor1
parents:
diff changeset
3033
Ritor1
parents:
diff changeset
3034 Arguments:
Ritor1
parents:
diff changeset
3035
Ritor1
parents:
diff changeset
3036 pszDest - destination string
Ritor1
parents:
diff changeset
3037
Ritor1
parents:
diff changeset
3038 cbDest - size of destination buffer in bytes.
Ritor1
parents:
diff changeset
3039 length must be sufficient to contain the resulting
Ritor1
parents:
diff changeset
3040 formatted string plus the null terminator.
Ritor1
parents:
diff changeset
3041
Ritor1
parents:
diff changeset
3042 ppszDestEnd - if ppszDestEnd is non-null, the function will return a
Ritor1
parents:
diff changeset
3043 pointer to the end of the destination string. If the
Ritor1
parents:
diff changeset
3044 function printed any data, the result will point to the
Ritor1
parents:
diff changeset
3045 null termination character
Ritor1
parents:
diff changeset
3046
Ritor1
parents:
diff changeset
3047 pcbRemaining - if pcbRemaining is non-null, the function will return
Ritor1
parents:
diff changeset
3048 the number of bytes left in the destination string,
Ritor1
parents:
diff changeset
3049 including the null terminator
Ritor1
parents:
diff changeset
3050
Ritor1
parents:
diff changeset
3051 dwFlags - controls some details of the string copy:
Ritor1
parents:
diff changeset
3052
Ritor1
parents:
diff changeset
3053 STRSAFE_FILL_BEHIND_NULL
Ritor1
parents:
diff changeset
3054 if the function succeeds, the low byte of dwFlags will be
Ritor1
parents:
diff changeset
3055 used to fill the uninitialize part of destination buffer
Ritor1
parents:
diff changeset
3056 behind the null terminator
Ritor1
parents:
diff changeset
3057
Ritor1
parents:
diff changeset
3058 STRSAFE_IGNORE_NULLS
Ritor1
parents:
diff changeset
3059 treat NULL string pointers like empty strings (TEXT(""))
Ritor1
parents:
diff changeset
3060
Ritor1
parents:
diff changeset
3061 STRSAFE_FILL_ON_FAILURE
Ritor1
parents:
diff changeset
3062 if the function fails, the low byte of dwFlags will be
Ritor1
parents:
diff changeset
3063 used to fill all of the destination buffer, and it will
Ritor1
parents:
diff changeset
3064 be null terminated. This will overwrite any truncated
Ritor1
parents:
diff changeset
3065 string returned when the failure is
Ritor1
parents:
diff changeset
3066 STRSAFE_E_INSUFFICIENT_BUFFER
Ritor1
parents:
diff changeset
3067
Ritor1
parents:
diff changeset
3068 STRSAFE_NO_TRUNCATION /
Ritor1
parents:
diff changeset
3069 STRSAFE_NULL_ON_FAILURE
Ritor1
parents:
diff changeset
3070 if the function fails, the destination buffer will be set
Ritor1
parents:
diff changeset
3071 to the empty string. This will overwrite any truncated string
Ritor1
parents:
diff changeset
3072 returned when the failure is STRSAFE_E_INSUFFICIENT_BUFFER.
Ritor1
parents:
diff changeset
3073
Ritor1
parents:
diff changeset
3074 pszFormat - format string which must be null terminated
Ritor1
parents:
diff changeset
3075
Ritor1
parents:
diff changeset
3076 ... - additional parameters to be formatted according to
Ritor1
parents:
diff changeset
3077 the format string
Ritor1
parents:
diff changeset
3078
Ritor1
parents:
diff changeset
3079 Notes:
Ritor1
parents:
diff changeset
3080 Behavior is undefined if destination, format strings or any arguments
Ritor1
parents:
diff changeset
3081 strings overlap.
Ritor1
parents:
diff changeset
3082
Ritor1
parents:
diff changeset
3083 pszDest and pszFormat should not be NULL unless the STRSAFE_IGNORE_NULLS
Ritor1
parents:
diff changeset
3084 flag is specified. If STRSAFE_IGNORE_NULLS is passed, both pszDest and
Ritor1
parents:
diff changeset
3085 pszFormat may be NULL. An error may still be returned even though NULLS
Ritor1
parents:
diff changeset
3086 are ignored due to insufficient space.
Ritor1
parents:
diff changeset
3087
Ritor1
parents:
diff changeset
3088 Return Value:
Ritor1
parents:
diff changeset
3089
Ritor1
parents:
diff changeset
3090 S_OK - if there was source data and it was all concatenated and
Ritor1
parents:
diff changeset
3091 the resultant dest string was null terminated
Ritor1
parents:
diff changeset
3092
Ritor1
parents:
diff changeset
3093 failure - you can use the macro HRESULT_CODE() to get a win32
Ritor1
parents:
diff changeset
3094 error code for all hresult failure cases
Ritor1
parents:
diff changeset
3095
Ritor1
parents:
diff changeset
3096 STRSAFE_E_INSUFFICIENT_BUFFER /
Ritor1
parents:
diff changeset
3097 HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER
Ritor1
parents:
diff changeset
3098 - this return value is an indication that the print
Ritor1
parents:
diff changeset
3099 operation failed due to insufficient space. When this
Ritor1
parents:
diff changeset
3100 error occurs, the destination buffer is modified to
Ritor1
parents:
diff changeset
3101 contain a truncated version of the ideal result and is
Ritor1
parents:
diff changeset
3102 null terminated. This is useful for situations where
Ritor1
parents:
diff changeset
3103 truncation is ok.
Ritor1
parents:
diff changeset
3104
Ritor1
parents:
diff changeset
3105 It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the
Ritor1
parents:
diff changeset
3106 return value of this function
Ritor1
parents:
diff changeset
3107
Ritor1
parents:
diff changeset
3108 --*/
Ritor1
parents:
diff changeset
3109
Ritor1
parents:
diff changeset
3110 STRSAFEAPI StringCbPrintfExA(char* pszDest, size_t cbDest, char** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags, const char* pszFormat, ...);
Ritor1
parents:
diff changeset
3111 STRSAFEAPI StringCbPrintfExW(wchar_t* pszDest, size_t cbDest, wchar_t** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags, const wchar_t* pszFormat, ...);
Ritor1
parents:
diff changeset
3112 #ifdef UNICODE
Ritor1
parents:
diff changeset
3113 #define StringCbPrintfEx StringCbPrintfExW
Ritor1
parents:
diff changeset
3114 #else
Ritor1
parents:
diff changeset
3115 #define StringCbPrintfEx StringCbPrintfExA
Ritor1
parents:
diff changeset
3116 #endif // !UNICODE
Ritor1
parents:
diff changeset
3117
Ritor1
parents:
diff changeset
3118 #ifdef STRSAFE_INLINE
Ritor1
parents:
diff changeset
3119 STRSAFEAPI StringCbPrintfExA(char* pszDest, size_t cbDest, char** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags, const char* pszFormat, ...)
Ritor1
parents:
diff changeset
3120 {
Ritor1
parents:
diff changeset
3121 HRESULT hr;
Ritor1
parents:
diff changeset
3122 size_t cchDest;
Ritor1
parents:
diff changeset
3123 size_t cchRemaining = 0;
Ritor1
parents:
diff changeset
3124
Ritor1
parents:
diff changeset
3125 cchDest = cbDest / sizeof(char);
Ritor1
parents:
diff changeset
3126
Ritor1
parents:
diff changeset
3127 if (cchDest > STRSAFE_MAX_CCH)
Ritor1
parents:
diff changeset
3128 {
Ritor1
parents:
diff changeset
3129 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
3130 }
Ritor1
parents:
diff changeset
3131 else
Ritor1
parents:
diff changeset
3132 {
Ritor1
parents:
diff changeset
3133 va_list argList;
Ritor1
parents:
diff changeset
3134
Ritor1
parents:
diff changeset
3135 va_start(argList, pszFormat);
Ritor1
parents:
diff changeset
3136
Ritor1
parents:
diff changeset
3137 hr = StringVPrintfExWorkerA(pszDest, cchDest, cbDest, ppszDestEnd, &cchRemaining, dwFlags, pszFormat, argList);
Ritor1
parents:
diff changeset
3138
Ritor1
parents:
diff changeset
3139 va_end(argList);
Ritor1
parents:
diff changeset
3140 }
Ritor1
parents:
diff changeset
3141
Ritor1
parents:
diff changeset
3142 if (SUCCEEDED(hr) || (hr == STRSAFE_E_INSUFFICIENT_BUFFER))
Ritor1
parents:
diff changeset
3143 {
Ritor1
parents:
diff changeset
3144 if (pcbRemaining)
Ritor1
parents:
diff changeset
3145 {
Ritor1
parents:
diff changeset
3146 // safe to multiply cchRemaining * sizeof(char) since cchRemaining < STRSAFE_MAX_CCH and sizeof(char) is 1
Ritor1
parents:
diff changeset
3147 *pcbRemaining = (cchRemaining * sizeof(char)) + (cbDest % sizeof(char));
Ritor1
parents:
diff changeset
3148 }
Ritor1
parents:
diff changeset
3149 }
Ritor1
parents:
diff changeset
3150
Ritor1
parents:
diff changeset
3151 return hr;
Ritor1
parents:
diff changeset
3152 }
Ritor1
parents:
diff changeset
3153
Ritor1
parents:
diff changeset
3154 STRSAFEAPI StringCbPrintfExW(wchar_t* pszDest, size_t cbDest, wchar_t** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags, const wchar_t* pszFormat, ...)
Ritor1
parents:
diff changeset
3155 {
Ritor1
parents:
diff changeset
3156 HRESULT hr;
Ritor1
parents:
diff changeset
3157 size_t cchDest;
Ritor1
parents:
diff changeset
3158 size_t cchRemaining = 0;
Ritor1
parents:
diff changeset
3159
Ritor1
parents:
diff changeset
3160 cchDest = cbDest / sizeof(wchar_t);
Ritor1
parents:
diff changeset
3161
Ritor1
parents:
diff changeset
3162 if (cchDest > STRSAFE_MAX_CCH)
Ritor1
parents:
diff changeset
3163 {
Ritor1
parents:
diff changeset
3164 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
3165 }
Ritor1
parents:
diff changeset
3166 else
Ritor1
parents:
diff changeset
3167 {
Ritor1
parents:
diff changeset
3168 va_list argList;
Ritor1
parents:
diff changeset
3169
Ritor1
parents:
diff changeset
3170 va_start(argList, pszFormat);
Ritor1
parents:
diff changeset
3171
Ritor1
parents:
diff changeset
3172 hr = StringVPrintfExWorkerW(pszDest, cchDest, cbDest, ppszDestEnd, &cchRemaining, dwFlags, pszFormat, argList);
Ritor1
parents:
diff changeset
3173
Ritor1
parents:
diff changeset
3174 va_end(argList);
Ritor1
parents:
diff changeset
3175 }
Ritor1
parents:
diff changeset
3176
Ritor1
parents:
diff changeset
3177 if (SUCCEEDED(hr) || (hr == STRSAFE_E_INSUFFICIENT_BUFFER))
Ritor1
parents:
diff changeset
3178 {
Ritor1
parents:
diff changeset
3179 if (pcbRemaining)
Ritor1
parents:
diff changeset
3180 {
Ritor1
parents:
diff changeset
3181 // safe to multiply cchRemaining * sizeof(wchar_t) since cchRemaining < STRSAFE_MAX_CCH and sizeof(wchar_t) is 2
Ritor1
parents:
diff changeset
3182 *pcbRemaining = (cchRemaining * sizeof(wchar_t)) + (cbDest % sizeof(wchar_t));
Ritor1
parents:
diff changeset
3183 }
Ritor1
parents:
diff changeset
3184 }
Ritor1
parents:
diff changeset
3185
Ritor1
parents:
diff changeset
3186 return hr;
Ritor1
parents:
diff changeset
3187 }
Ritor1
parents:
diff changeset
3188 #endif // STRSAFE_INLINE
Ritor1
parents:
diff changeset
3189 #endif // !STRSAFE_NO_CB_FUNCTIONS
Ritor1
parents:
diff changeset
3190
Ritor1
parents:
diff changeset
3191
Ritor1
parents:
diff changeset
3192 #ifndef STRSAFE_NO_CCH_FUNCTIONS
Ritor1
parents:
diff changeset
3193 /*++
Ritor1
parents:
diff changeset
3194
Ritor1
parents:
diff changeset
3195 STDAPI
Ritor1
parents:
diff changeset
3196 StringCchVPrintfEx(
Ritor1
parents:
diff changeset
3197 OUT LPTSTR pszDest OPTIONAL,
Ritor1
parents:
diff changeset
3198 IN size_t cchDest,
Ritor1
parents:
diff changeset
3199 OUT LPTSTR* ppszDestEnd OPTIONAL,
Ritor1
parents:
diff changeset
3200 OUT size_t* pcchRemaining OPTIONAL,
Ritor1
parents:
diff changeset
3201 IN DWORD dwFlags,
Ritor1
parents:
diff changeset
3202 IN LPCTSTR pszFormat OPTIONAL,
Ritor1
parents:
diff changeset
3203 IN va_list argList
Ritor1
parents:
diff changeset
3204 );
Ritor1
parents:
diff changeset
3205
Ritor1
parents:
diff changeset
3206 Routine Description:
Ritor1
parents:
diff changeset
3207
Ritor1
parents:
diff changeset
3208 This routine is a safer version of the C built-in function 'vsprintf' with
Ritor1
parents:
diff changeset
3209 some additional parameters. In addition to functionality provided by
Ritor1
parents:
diff changeset
3210 StringCchVPrintf, this routine also returns a pointer to the end of the
Ritor1
parents:
diff changeset
3211 destination string and the number of characters left in the destination string
Ritor1
parents:
diff changeset
3212 including the null terminator. The flags parameter allows additional controls.
Ritor1
parents:
diff changeset
3213
Ritor1
parents:
diff changeset
3214 Arguments:
Ritor1
parents:
diff changeset
3215
Ritor1
parents:
diff changeset
3216 pszDest - destination string
Ritor1
parents:
diff changeset
3217
Ritor1
parents:
diff changeset
3218 cchDest - size of destination buffer in characters.
Ritor1
parents:
diff changeset
3219 length must be sufficient to contain the resulting
Ritor1
parents:
diff changeset
3220 formatted string plus the null terminator.
Ritor1
parents:
diff changeset
3221
Ritor1
parents:
diff changeset
3222 ppszDestEnd - if ppszDestEnd is non-null, the function will return a
Ritor1
parents:
diff changeset
3223 pointer to the end of the destination string. If the
Ritor1
parents:
diff changeset
3224 function printed any data, the result will point to the
Ritor1
parents:
diff changeset
3225 null termination character
Ritor1
parents:
diff changeset
3226
Ritor1
parents:
diff changeset
3227 pcchRemaining - if pcchRemaining is non-null, the function will return
Ritor1
parents:
diff changeset
3228 the number of characters left in the destination string,
Ritor1
parents:
diff changeset
3229 including the null terminator
Ritor1
parents:
diff changeset
3230
Ritor1
parents:
diff changeset
3231 dwFlags - controls some details of the string copy:
Ritor1
parents:
diff changeset
3232
Ritor1
parents:
diff changeset
3233 STRSAFE_FILL_BEHIND_NULL
Ritor1
parents:
diff changeset
3234 if the function succeeds, the low byte of dwFlags will be
Ritor1
parents:
diff changeset
3235 used to fill the uninitialize part of destination buffer
Ritor1
parents:
diff changeset
3236 behind the null terminator
Ritor1
parents:
diff changeset
3237
Ritor1
parents:
diff changeset
3238 STRSAFE_IGNORE_NULLS
Ritor1
parents:
diff changeset
3239 treat NULL string pointers like empty strings (TEXT(""))
Ritor1
parents:
diff changeset
3240
Ritor1
parents:
diff changeset
3241 STRSAFE_FILL_ON_FAILURE
Ritor1
parents:
diff changeset
3242 if the function fails, the low byte of dwFlags will be
Ritor1
parents:
diff changeset
3243 used to fill all of the destination buffer, and it will
Ritor1
parents:
diff changeset
3244 be null terminated. This will overwrite any truncated
Ritor1
parents:
diff changeset
3245 string returned when the failure is
Ritor1
parents:
diff changeset
3246 STRSAFE_E_INSUFFICIENT_BUFFER
Ritor1
parents:
diff changeset
3247
Ritor1
parents:
diff changeset
3248 STRSAFE_NO_TRUNCATION /
Ritor1
parents:
diff changeset
3249 STRSAFE_NULL_ON_FAILURE
Ritor1
parents:
diff changeset
3250 if the function fails, the destination buffer will be set
Ritor1
parents:
diff changeset
3251 to the empty string. This will overwrite any truncated string
Ritor1
parents:
diff changeset
3252 returned when the failure is STRSAFE_E_INSUFFICIENT_BUFFER.
Ritor1
parents:
diff changeset
3253
Ritor1
parents:
diff changeset
3254 pszFormat - format string which must be null terminated
Ritor1
parents:
diff changeset
3255
Ritor1
parents:
diff changeset
3256 argList - va_list from the variable arguments according to the
Ritor1
parents:
diff changeset
3257 stdarg.h convention
Ritor1
parents:
diff changeset
3258
Ritor1
parents:
diff changeset
3259 Notes:
Ritor1
parents:
diff changeset
3260 Behavior is undefined if destination, format strings or any arguments
Ritor1
parents:
diff changeset
3261 strings overlap.
Ritor1
parents:
diff changeset
3262
Ritor1
parents:
diff changeset
3263 pszDest and pszFormat should not be NULL unless the STRSAFE_IGNORE_NULLS
Ritor1
parents:
diff changeset
3264 flag is specified. If STRSAFE_IGNORE_NULLS is passed, both pszDest and
Ritor1
parents:
diff changeset
3265 pszFormat may be NULL. An error may still be returned even though NULLS
Ritor1
parents:
diff changeset
3266 are ignored due to insufficient space.
Ritor1
parents:
diff changeset
3267
Ritor1
parents:
diff changeset
3268 Return Value:
Ritor1
parents:
diff changeset
3269
Ritor1
parents:
diff changeset
3270 S_OK - if there was source data and it was all concatenated and
Ritor1
parents:
diff changeset
3271 the resultant dest string was null terminated
Ritor1
parents:
diff changeset
3272
Ritor1
parents:
diff changeset
3273 failure - you can use the macro HRESULT_CODE() to get a win32
Ritor1
parents:
diff changeset
3274 error code for all hresult failure cases
Ritor1
parents:
diff changeset
3275
Ritor1
parents:
diff changeset
3276 STRSAFE_E_INSUFFICIENT_BUFFER /
Ritor1
parents:
diff changeset
3277 HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER
Ritor1
parents:
diff changeset
3278 - this return value is an indication that the print
Ritor1
parents:
diff changeset
3279 operation failed due to insufficient space. When this
Ritor1
parents:
diff changeset
3280 error occurs, the destination buffer is modified to
Ritor1
parents:
diff changeset
3281 contain a truncated version of the ideal result and is
Ritor1
parents:
diff changeset
3282 null terminated. This is useful for situations where
Ritor1
parents:
diff changeset
3283 truncation is ok.
Ritor1
parents:
diff changeset
3284
Ritor1
parents:
diff changeset
3285 It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the
Ritor1
parents:
diff changeset
3286 return value of this function
Ritor1
parents:
diff changeset
3287
Ritor1
parents:
diff changeset
3288 --*/
Ritor1
parents:
diff changeset
3289
Ritor1
parents:
diff changeset
3290 STRSAFEAPI StringCchVPrintfExA(char* pszDest, size_t cchDest, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags, const char* pszFormat, va_list argList);
Ritor1
parents:
diff changeset
3291 STRSAFEAPI StringCchVPrintfExW(wchar_t* pszDest, size_t cchDest, wchar_t** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags, const wchar_t* pszFormat, va_list argList);
Ritor1
parents:
diff changeset
3292 #ifdef UNICODE
Ritor1
parents:
diff changeset
3293 #define StringCchVPrintfEx StringCchVPrintfExW
Ritor1
parents:
diff changeset
3294 #else
Ritor1
parents:
diff changeset
3295 #define StringCchVPrintfEx StringCchVPrintfExA
Ritor1
parents:
diff changeset
3296 #endif // !UNICODE
Ritor1
parents:
diff changeset
3297
Ritor1
parents:
diff changeset
3298 #ifdef STRSAFE_INLINE
Ritor1
parents:
diff changeset
3299 STRSAFEAPI StringCchVPrintfExA(char* pszDest, size_t cchDest, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags, const char* pszFormat, va_list argList)
Ritor1
parents:
diff changeset
3300 {
Ritor1
parents:
diff changeset
3301 HRESULT hr;
Ritor1
parents:
diff changeset
3302
Ritor1
parents:
diff changeset
3303 if (cchDest > STRSAFE_MAX_CCH)
Ritor1
parents:
diff changeset
3304 {
Ritor1
parents:
diff changeset
3305 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
3306 }
Ritor1
parents:
diff changeset
3307 else
Ritor1
parents:
diff changeset
3308 {
Ritor1
parents:
diff changeset
3309 size_t cbDest;
Ritor1
parents:
diff changeset
3310
Ritor1
parents:
diff changeset
3311 // safe to multiply cchDest * sizeof(char) since cchDest < STRSAFE_MAX_CCH and sizeof(char) is 1
Ritor1
parents:
diff changeset
3312 cbDest = cchDest * sizeof(char);
Ritor1
parents:
diff changeset
3313
Ritor1
parents:
diff changeset
3314 hr = StringVPrintfExWorkerA(pszDest, cchDest, cbDest, ppszDestEnd, pcchRemaining, dwFlags, pszFormat, argList);
Ritor1
parents:
diff changeset
3315 }
Ritor1
parents:
diff changeset
3316
Ritor1
parents:
diff changeset
3317 return hr;
Ritor1
parents:
diff changeset
3318 }
Ritor1
parents:
diff changeset
3319
Ritor1
parents:
diff changeset
3320 STRSAFEAPI StringCchVPrintfExW(wchar_t* pszDest, size_t cchDest, wchar_t** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags, const wchar_t* pszFormat, va_list argList)
Ritor1
parents:
diff changeset
3321 {
Ritor1
parents:
diff changeset
3322 HRESULT hr;
Ritor1
parents:
diff changeset
3323
Ritor1
parents:
diff changeset
3324 if (cchDest > STRSAFE_MAX_CCH)
Ritor1
parents:
diff changeset
3325 {
Ritor1
parents:
diff changeset
3326 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
3327 }
Ritor1
parents:
diff changeset
3328 else
Ritor1
parents:
diff changeset
3329 {
Ritor1
parents:
diff changeset
3330 size_t cbDest;
Ritor1
parents:
diff changeset
3331
Ritor1
parents:
diff changeset
3332 // safe to multiply cchDest * sizeof(wchar_t) since cchDest < STRSAFE_MAX_CCH and sizeof(wchar_t) is 2
Ritor1
parents:
diff changeset
3333 cbDest = cchDest * sizeof(wchar_t);
Ritor1
parents:
diff changeset
3334
Ritor1
parents:
diff changeset
3335 hr = StringVPrintfExWorkerW(pszDest, cchDest, cbDest, ppszDestEnd, pcchRemaining, dwFlags, pszFormat, argList);
Ritor1
parents:
diff changeset
3336 }
Ritor1
parents:
diff changeset
3337
Ritor1
parents:
diff changeset
3338 return hr;
Ritor1
parents:
diff changeset
3339 }
Ritor1
parents:
diff changeset
3340 #endif // STRSAFE_INLINE
Ritor1
parents:
diff changeset
3341 #endif // !STRSAFE_NO_CCH_FUNCTIONS
Ritor1
parents:
diff changeset
3342
Ritor1
parents:
diff changeset
3343
Ritor1
parents:
diff changeset
3344 #ifndef STRSAFE_NO_CB_FUNCTIONS
Ritor1
parents:
diff changeset
3345 /*++
Ritor1
parents:
diff changeset
3346
Ritor1
parents:
diff changeset
3347 STDAPI
Ritor1
parents:
diff changeset
3348 StringCbVPrintfEx(
Ritor1
parents:
diff changeset
3349 OUT LPTSTR pszDest OPTIONAL,
Ritor1
parents:
diff changeset
3350 IN size_t cbDest,
Ritor1
parents:
diff changeset
3351 OUT LPTSTR* ppszDestEnd OPTIONAL,
Ritor1
parents:
diff changeset
3352 OUT size_t* pcbRemaining OPTIONAL,
Ritor1
parents:
diff changeset
3353 IN DWORD dwFlags,
Ritor1
parents:
diff changeset
3354 IN LPCTSTR pszFormat OPTIONAL,
Ritor1
parents:
diff changeset
3355 IN va_list argList
Ritor1
parents:
diff changeset
3356 );
Ritor1
parents:
diff changeset
3357
Ritor1
parents:
diff changeset
3358 Routine Description:
Ritor1
parents:
diff changeset
3359
Ritor1
parents:
diff changeset
3360 This routine is a safer version of the C built-in function 'vsprintf' with
Ritor1
parents:
diff changeset
3361 some additional parameters. In addition to functionality provided by
Ritor1
parents:
diff changeset
3362 StringCbVPrintf, this routine also returns a pointer to the end of the
Ritor1
parents:
diff changeset
3363 destination string and the number of characters left in the destination string
Ritor1
parents:
diff changeset
3364 including the null terminator. The flags parameter allows additional controls.
Ritor1
parents:
diff changeset
3365
Ritor1
parents:
diff changeset
3366 Arguments:
Ritor1
parents:
diff changeset
3367
Ritor1
parents:
diff changeset
3368 pszDest - destination string
Ritor1
parents:
diff changeset
3369
Ritor1
parents:
diff changeset
3370 cbDest - size of destination buffer in bytes.
Ritor1
parents:
diff changeset
3371 length must be sufficient to contain the resulting
Ritor1
parents:
diff changeset
3372 formatted string plus the null terminator.
Ritor1
parents:
diff changeset
3373
Ritor1
parents:
diff changeset
3374 ppszDestEnd - if ppszDestEnd is non-null, the function will return
Ritor1
parents:
diff changeset
3375 a pointer to the end of the destination string. If the
Ritor1
parents:
diff changeset
3376 function printed any data, the result will point to the
Ritor1
parents:
diff changeset
3377 null termination character
Ritor1
parents:
diff changeset
3378
Ritor1
parents:
diff changeset
3379 pcbRemaining - if pcbRemaining is non-null, the function will return
Ritor1
parents:
diff changeset
3380 the number of bytes left in the destination string,
Ritor1
parents:
diff changeset
3381 including the null terminator
Ritor1
parents:
diff changeset
3382
Ritor1
parents:
diff changeset
3383 dwFlags - controls some details of the string copy:
Ritor1
parents:
diff changeset
3384
Ritor1
parents:
diff changeset
3385 STRSAFE_FILL_BEHIND_NULL
Ritor1
parents:
diff changeset
3386 if the function succeeds, the low byte of dwFlags will be
Ritor1
parents:
diff changeset
3387 used to fill the uninitialize part of destination buffer
Ritor1
parents:
diff changeset
3388 behind the null terminator
Ritor1
parents:
diff changeset
3389
Ritor1
parents:
diff changeset
3390 STRSAFE_IGNORE_NULLS
Ritor1
parents:
diff changeset
3391 treat NULL string pointers like empty strings (TEXT(""))
Ritor1
parents:
diff changeset
3392
Ritor1
parents:
diff changeset
3393 STRSAFE_FILL_ON_FAILURE
Ritor1
parents:
diff changeset
3394 if the function fails, the low byte of dwFlags will be
Ritor1
parents:
diff changeset
3395 used to fill all of the destination buffer, and it will
Ritor1
parents:
diff changeset
3396 be null terminated. This will overwrite any truncated
Ritor1
parents:
diff changeset
3397 string returned when the failure is
Ritor1
parents:
diff changeset
3398 STRSAFE_E_INSUFFICIENT_BUFFER
Ritor1
parents:
diff changeset
3399
Ritor1
parents:
diff changeset
3400 STRSAFE_NO_TRUNCATION /
Ritor1
parents:
diff changeset
3401 STRSAFE_NULL_ON_FAILURE
Ritor1
parents:
diff changeset
3402 if the function fails, the destination buffer will be set
Ritor1
parents:
diff changeset
3403 to the empty string. This will overwrite any truncated string
Ritor1
parents:
diff changeset
3404 returned when the failure is STRSAFE_E_INSUFFICIENT_BUFFER.
Ritor1
parents:
diff changeset
3405
Ritor1
parents:
diff changeset
3406 pszFormat - format string which must be null terminated
Ritor1
parents:
diff changeset
3407
Ritor1
parents:
diff changeset
3408 argList - va_list from the variable arguments according to the
Ritor1
parents:
diff changeset
3409 stdarg.h convention
Ritor1
parents:
diff changeset
3410
Ritor1
parents:
diff changeset
3411 Notes:
Ritor1
parents:
diff changeset
3412 Behavior is undefined if destination, format strings or any arguments
Ritor1
parents:
diff changeset
3413 strings overlap.
Ritor1
parents:
diff changeset
3414
Ritor1
parents:
diff changeset
3415 pszDest and pszFormat should not be NULL unless the STRSAFE_IGNORE_NULLS
Ritor1
parents:
diff changeset
3416 flag is specified. If STRSAFE_IGNORE_NULLS is passed, both pszDest and
Ritor1
parents:
diff changeset
3417 pszFormat may be NULL. An error may still be returned even though NULLS
Ritor1
parents:
diff changeset
3418 are ignored due to insufficient space.
Ritor1
parents:
diff changeset
3419
Ritor1
parents:
diff changeset
3420 Return Value:
Ritor1
parents:
diff changeset
3421
Ritor1
parents:
diff changeset
3422 S_OK - if there was source data and it was all concatenated and
Ritor1
parents:
diff changeset
3423 the resultant dest string was null terminated
Ritor1
parents:
diff changeset
3424
Ritor1
parents:
diff changeset
3425 failure - you can use the macro HRESULT_CODE() to get a win32
Ritor1
parents:
diff changeset
3426 error code for all hresult failure cases
Ritor1
parents:
diff changeset
3427
Ritor1
parents:
diff changeset
3428 STRSAFE_E_INSUFFICIENT_BUFFER /
Ritor1
parents:
diff changeset
3429 HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER
Ritor1
parents:
diff changeset
3430 - this return value is an indication that the print
Ritor1
parents:
diff changeset
3431 operation failed due to insufficient space. When this
Ritor1
parents:
diff changeset
3432 error occurs, the destination buffer is modified to
Ritor1
parents:
diff changeset
3433 contain a truncated version of the ideal result and is
Ritor1
parents:
diff changeset
3434 null terminated. This is useful for situations where
Ritor1
parents:
diff changeset
3435 truncation is ok.
Ritor1
parents:
diff changeset
3436
Ritor1
parents:
diff changeset
3437 It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the
Ritor1
parents:
diff changeset
3438 return value of this function
Ritor1
parents:
diff changeset
3439
Ritor1
parents:
diff changeset
3440 --*/
Ritor1
parents:
diff changeset
3441
Ritor1
parents:
diff changeset
3442 STRSAFEAPI StringCbVPrintfExA(char* pszDest, size_t cbDest, char** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags, const char* pszFormat, va_list argList);
Ritor1
parents:
diff changeset
3443 STRSAFEAPI StringCbVPrintfExW(wchar_t* pszDest, size_t cbDest, wchar_t** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags, const wchar_t* pszFormat, va_list argList);
Ritor1
parents:
diff changeset
3444 #ifdef UNICODE
Ritor1
parents:
diff changeset
3445 #define StringCbVPrintfEx StringCbVPrintfExW
Ritor1
parents:
diff changeset
3446 #else
Ritor1
parents:
diff changeset
3447 #define StringCbVPrintfEx StringCbVPrintfExA
Ritor1
parents:
diff changeset
3448 #endif // !UNICODE
Ritor1
parents:
diff changeset
3449
Ritor1
parents:
diff changeset
3450 #ifdef STRSAFE_INLINE
Ritor1
parents:
diff changeset
3451 STRSAFEAPI StringCbVPrintfExA(char* pszDest, size_t cbDest, char** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags, const char* pszFormat, va_list argList)
Ritor1
parents:
diff changeset
3452 {
Ritor1
parents:
diff changeset
3453 HRESULT hr;
Ritor1
parents:
diff changeset
3454 size_t cchDest;
Ritor1
parents:
diff changeset
3455 size_t cchRemaining = 0;
Ritor1
parents:
diff changeset
3456
Ritor1
parents:
diff changeset
3457 cchDest = cbDest / sizeof(char);
Ritor1
parents:
diff changeset
3458
Ritor1
parents:
diff changeset
3459 if (cchDest > STRSAFE_MAX_CCH)
Ritor1
parents:
diff changeset
3460 {
Ritor1
parents:
diff changeset
3461 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
3462 }
Ritor1
parents:
diff changeset
3463 else
Ritor1
parents:
diff changeset
3464 {
Ritor1
parents:
diff changeset
3465 hr = StringVPrintfExWorkerA(pszDest, cchDest, cbDest, ppszDestEnd, &cchRemaining, dwFlags, pszFormat, argList);
Ritor1
parents:
diff changeset
3466 }
Ritor1
parents:
diff changeset
3467
Ritor1
parents:
diff changeset
3468 if (SUCCEEDED(hr) || (hr == STRSAFE_E_INSUFFICIENT_BUFFER))
Ritor1
parents:
diff changeset
3469 {
Ritor1
parents:
diff changeset
3470 if (pcbRemaining)
Ritor1
parents:
diff changeset
3471 {
Ritor1
parents:
diff changeset
3472 // safe to multiply cchRemaining * sizeof(char) since cchRemaining < STRSAFE_MAX_CCH and sizeof(char) is 1
Ritor1
parents:
diff changeset
3473 *pcbRemaining = (cchRemaining * sizeof(char)) + (cbDest % sizeof(char));
Ritor1
parents:
diff changeset
3474 }
Ritor1
parents:
diff changeset
3475 }
Ritor1
parents:
diff changeset
3476
Ritor1
parents:
diff changeset
3477 return hr;
Ritor1
parents:
diff changeset
3478 }
Ritor1
parents:
diff changeset
3479
Ritor1
parents:
diff changeset
3480 STRSAFEAPI StringCbVPrintfExW(wchar_t* pszDest, size_t cbDest, wchar_t** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags, const wchar_t* pszFormat, va_list argList)
Ritor1
parents:
diff changeset
3481 {
Ritor1
parents:
diff changeset
3482 HRESULT hr;
Ritor1
parents:
diff changeset
3483 size_t cchDest;
Ritor1
parents:
diff changeset
3484 size_t cchRemaining = 0;
Ritor1
parents:
diff changeset
3485
Ritor1
parents:
diff changeset
3486 cchDest = cbDest / sizeof(wchar_t);
Ritor1
parents:
diff changeset
3487
Ritor1
parents:
diff changeset
3488 if (cchDest > STRSAFE_MAX_CCH)
Ritor1
parents:
diff changeset
3489 {
Ritor1
parents:
diff changeset
3490 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
3491 }
Ritor1
parents:
diff changeset
3492 else
Ritor1
parents:
diff changeset
3493 {
Ritor1
parents:
diff changeset
3494 hr = StringVPrintfExWorkerW(pszDest, cchDest, cbDest, ppszDestEnd, &cchRemaining, dwFlags, pszFormat, argList);
Ritor1
parents:
diff changeset
3495 }
Ritor1
parents:
diff changeset
3496
Ritor1
parents:
diff changeset
3497 if (SUCCEEDED(hr) || (hr == STRSAFE_E_INSUFFICIENT_BUFFER))
Ritor1
parents:
diff changeset
3498 {
Ritor1
parents:
diff changeset
3499 if (pcbRemaining)
Ritor1
parents:
diff changeset
3500 {
Ritor1
parents:
diff changeset
3501 // safe to multiply cchRemaining * sizeof(wchar_t) since cchRemaining < STRSAFE_MAX_CCH and sizeof(wchar_t) is 2
Ritor1
parents:
diff changeset
3502 *pcbRemaining = (cchRemaining * sizeof(wchar_t)) + (cbDest % sizeof(wchar_t));
Ritor1
parents:
diff changeset
3503 }
Ritor1
parents:
diff changeset
3504 }
Ritor1
parents:
diff changeset
3505
Ritor1
parents:
diff changeset
3506 return hr;
Ritor1
parents:
diff changeset
3507 }
Ritor1
parents:
diff changeset
3508 #endif // STRSAFE_INLINE
Ritor1
parents:
diff changeset
3509 #endif // !STRSAFE_NO_CB_FUNCTIONS
Ritor1
parents:
diff changeset
3510
Ritor1
parents:
diff changeset
3511
Ritor1
parents:
diff changeset
3512 #ifndef STRSAFE_NO_CCH_FUNCTIONS
Ritor1
parents:
diff changeset
3513 /*++
Ritor1
parents:
diff changeset
3514
Ritor1
parents:
diff changeset
3515 STDAPI
Ritor1
parents:
diff changeset
3516 StringCchGets(
Ritor1
parents:
diff changeset
3517 OUT LPTSTR pszDest,
Ritor1
parents:
diff changeset
3518 IN size_t cchDest
Ritor1
parents:
diff changeset
3519 );
Ritor1
parents:
diff changeset
3520
Ritor1
parents:
diff changeset
3521 Routine Description:
Ritor1
parents:
diff changeset
3522
Ritor1
parents:
diff changeset
3523 This routine is a safer version of the C built-in function 'gets'.
Ritor1
parents:
diff changeset
3524 The size of the destination buffer (in characters) is a parameter and
Ritor1
parents:
diff changeset
3525 this function will not write past the end of this buffer and it will
Ritor1
parents:
diff changeset
3526 ALWAYS null terminate the destination buffer (unless it is zero length).
Ritor1
parents:
diff changeset
3527
Ritor1
parents:
diff changeset
3528 This routine is not a replacement for fgets. That function does not replace
Ritor1
parents:
diff changeset
3529 newline characters with a null terminator.
Ritor1
parents:
diff changeset
3530
Ritor1
parents:
diff changeset
3531 This function returns a hresult, and not a pointer. It returns
Ritor1
parents:
diff changeset
3532 S_OK if any characters were read from stdin and copied to pszDest and
Ritor1
parents:
diff changeset
3533 pszDest was null terminated, otherwise it will return a failure code.
Ritor1
parents:
diff changeset
3534
Ritor1
parents:
diff changeset
3535 Arguments:
Ritor1
parents:
diff changeset
3536
Ritor1
parents:
diff changeset
3537 pszDest - destination string
Ritor1
parents:
diff changeset
3538
Ritor1
parents:
diff changeset
3539 cchDest - size of destination buffer in characters.
Ritor1
parents:
diff changeset
3540
Ritor1
parents:
diff changeset
3541 Notes:
Ritor1
parents:
diff changeset
3542 pszDest should not be NULL. See StringCchGetsEx if you require the handling
Ritor1
parents:
diff changeset
3543 of NULL values.
Ritor1
parents:
diff changeset
3544
Ritor1
parents:
diff changeset
3545 cchDest must be > 1 for this function to succeed.
Ritor1
parents:
diff changeset
3546
Ritor1
parents:
diff changeset
3547 Return Value:
Ritor1
parents:
diff changeset
3548
Ritor1
parents:
diff changeset
3549 S_OK - data was read from stdin and copied, and the resultant
Ritor1
parents:
diff changeset
3550 dest string was null terminated
Ritor1
parents:
diff changeset
3551
Ritor1
parents:
diff changeset
3552 failure - you can use the macro HRESULT_CODE() to get a win32
Ritor1
parents:
diff changeset
3553 error code for all hresult failure cases
Ritor1
parents:
diff changeset
3554
Ritor1
parents:
diff changeset
3555 STRSAFE_E_END_OF_FILE /
Ritor1
parents:
diff changeset
3556 HRESULT_CODE(hr) == ERROR_HANDLE_EOF
Ritor1
parents:
diff changeset
3557 - this return value indicates an error or end-of-file
Ritor1
parents:
diff changeset
3558 condition, use feof or ferror to determine which one has
Ritor1
parents:
diff changeset
3559 occured.
Ritor1
parents:
diff changeset
3560
Ritor1
parents:
diff changeset
3561 STRSAFE_E_INSUFFICIENT_BUFFER /
Ritor1
parents:
diff changeset
3562 HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER
Ritor1
parents:
diff changeset
3563 - this return value is an indication that there was
Ritor1
parents:
diff changeset
3564 insufficient space in the destination buffer to copy any
Ritor1
parents:
diff changeset
3565 data
Ritor1
parents:
diff changeset
3566
Ritor1
parents:
diff changeset
3567 It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the
Ritor1
parents:
diff changeset
3568 return value of this function.
Ritor1
parents:
diff changeset
3569
Ritor1
parents:
diff changeset
3570 --*/
Ritor1
parents:
diff changeset
3571
Ritor1
parents:
diff changeset
3572 #ifndef STRSAFE_LIB_IMPL
Ritor1
parents:
diff changeset
3573 STRSAFE_INLINE_API StringCchGetsA(char* pszDest, size_t cchDest);
Ritor1
parents:
diff changeset
3574 STRSAFE_INLINE_API StringCchGetsW(wchar_t* pszDest, size_t cchDest);
Ritor1
parents:
diff changeset
3575 #ifdef UNICODE
Ritor1
parents:
diff changeset
3576 #define StringCchGets StringCchGetsW
Ritor1
parents:
diff changeset
3577 #else
Ritor1
parents:
diff changeset
3578 #define StringCchGets StringCchGetsA
Ritor1
parents:
diff changeset
3579 #endif // !UNICODE
Ritor1
parents:
diff changeset
3580
Ritor1
parents:
diff changeset
3581 STRSAFE_INLINE_API StringCchGetsA(char* pszDest, size_t cchDest)
Ritor1
parents:
diff changeset
3582 {
Ritor1
parents:
diff changeset
3583 HRESULT hr;
Ritor1
parents:
diff changeset
3584
Ritor1
parents:
diff changeset
3585 if (cchDest > STRSAFE_MAX_CCH)
Ritor1
parents:
diff changeset
3586 {
Ritor1
parents:
diff changeset
3587 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
3588 }
Ritor1
parents:
diff changeset
3589 else
Ritor1
parents:
diff changeset
3590 {
Ritor1
parents:
diff changeset
3591 size_t cbDest;
Ritor1
parents:
diff changeset
3592
Ritor1
parents:
diff changeset
3593 // safe to multiply cchDest * sizeof(char) since cchDest < STRSAFE_MAX_CCH and sizeof(char) is 1
Ritor1
parents:
diff changeset
3594 cbDest = cchDest * sizeof(char);
Ritor1
parents:
diff changeset
3595
Ritor1
parents:
diff changeset
3596 hr = StringGetsExWorkerA(pszDest, cchDest, cbDest, NULL, NULL, 0);
Ritor1
parents:
diff changeset
3597 }
Ritor1
parents:
diff changeset
3598
Ritor1
parents:
diff changeset
3599 return hr;
Ritor1
parents:
diff changeset
3600 }
Ritor1
parents:
diff changeset
3601
Ritor1
parents:
diff changeset
3602 STRSAFE_INLINE_API StringCchGetsW(wchar_t* pszDest, size_t cchDest)
Ritor1
parents:
diff changeset
3603 {
Ritor1
parents:
diff changeset
3604 HRESULT hr;
Ritor1
parents:
diff changeset
3605
Ritor1
parents:
diff changeset
3606 if (cchDest > STRSAFE_MAX_CCH)
Ritor1
parents:
diff changeset
3607 {
Ritor1
parents:
diff changeset
3608 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
3609 }
Ritor1
parents:
diff changeset
3610 else
Ritor1
parents:
diff changeset
3611 {
Ritor1
parents:
diff changeset
3612 size_t cbDest;
Ritor1
parents:
diff changeset
3613
Ritor1
parents:
diff changeset
3614 // safe to multiply cchDest * sizeof(wchar_t) since cchDest < STRSAFE_MAX_CCH and sizeof(wchar_t) is 2
Ritor1
parents:
diff changeset
3615 cbDest = cchDest * sizeof(wchar_t);
Ritor1
parents:
diff changeset
3616
Ritor1
parents:
diff changeset
3617 hr = StringGetsExWorkerW(pszDest, cchDest, cbDest, NULL, NULL, 0);
Ritor1
parents:
diff changeset
3618 }
Ritor1
parents:
diff changeset
3619
Ritor1
parents:
diff changeset
3620 return hr;
Ritor1
parents:
diff changeset
3621 }
Ritor1
parents:
diff changeset
3622 #endif // !STRSAFE_NO_CCH_FUNCTIONS
Ritor1
parents:
diff changeset
3623 #endif // !STRSAFE_LIB_IMPL
Ritor1
parents:
diff changeset
3624
Ritor1
parents:
diff changeset
3625 #ifndef STRSAFE_NO_CB_FUNCTIONS
Ritor1
parents:
diff changeset
3626 /*++
Ritor1
parents:
diff changeset
3627
Ritor1
parents:
diff changeset
3628 STDAPI
Ritor1
parents:
diff changeset
3629 StringCbGets(
Ritor1
parents:
diff changeset
3630 OUT LPTSTR pszDest,
Ritor1
parents:
diff changeset
3631 IN size_t cbDest
Ritor1
parents:
diff changeset
3632 );
Ritor1
parents:
diff changeset
3633
Ritor1
parents:
diff changeset
3634 Routine Description:
Ritor1
parents:
diff changeset
3635
Ritor1
parents:
diff changeset
3636 This routine is a safer version of the C built-in function 'gets'.
Ritor1
parents:
diff changeset
3637 The size of the destination buffer (in bytes) is a parameter and
Ritor1
parents:
diff changeset
3638 this function will not write past the end of this buffer and it will
Ritor1
parents:
diff changeset
3639 ALWAYS null terminate the destination buffer (unless it is zero length).
Ritor1
parents:
diff changeset
3640
Ritor1
parents:
diff changeset
3641 This routine is not a replacement for fgets. That function does not replace
Ritor1
parents:
diff changeset
3642 newline characters with a null terminator.
Ritor1
parents:
diff changeset
3643
Ritor1
parents:
diff changeset
3644 This function returns a hresult, and not a pointer. It returns
Ritor1
parents:
diff changeset
3645 S_OK if any characters were read from stdin and copied to pszDest
Ritor1
parents:
diff changeset
3646 and pszDest was null terminated, otherwise it will return a failure code.
Ritor1
parents:
diff changeset
3647
Ritor1
parents:
diff changeset
3648 Arguments:
Ritor1
parents:
diff changeset
3649
Ritor1
parents:
diff changeset
3650 pszDest - destination string
Ritor1
parents:
diff changeset
3651
Ritor1
parents:
diff changeset
3652 cbDest - size of destination buffer in bytes.
Ritor1
parents:
diff changeset
3653
Ritor1
parents:
diff changeset
3654 Notes:
Ritor1
parents:
diff changeset
3655 pszDest should not be NULL. See StringCbGetsEx if you require the handling
Ritor1
parents:
diff changeset
3656 of NULL values.
Ritor1
parents:
diff changeset
3657
Ritor1
parents:
diff changeset
3658 cbDest must be > sizeof(TCHAR) for this function to succeed.
Ritor1
parents:
diff changeset
3659
Ritor1
parents:
diff changeset
3660 Return Value:
Ritor1
parents:
diff changeset
3661
Ritor1
parents:
diff changeset
3662 S_OK - data was read from stdin and copied, and the resultant
Ritor1
parents:
diff changeset
3663 dest string was null terminated
Ritor1
parents:
diff changeset
3664
Ritor1
parents:
diff changeset
3665 failure - you can use the macro HRESULT_CODE() to get a win32
Ritor1
parents:
diff changeset
3666 error code for all hresult failure cases
Ritor1
parents:
diff changeset
3667
Ritor1
parents:
diff changeset
3668 STRSAFE_E_END_OF_FILE /
Ritor1
parents:
diff changeset
3669 HRESULT_CODE(hr) == ERROR_HANDLE_EOF
Ritor1
parents:
diff changeset
3670 - this return value indicates an error or end-of-file
Ritor1
parents:
diff changeset
3671 condition, use feof or ferror to determine which one has
Ritor1
parents:
diff changeset
3672 occured.
Ritor1
parents:
diff changeset
3673
Ritor1
parents:
diff changeset
3674 STRSAFE_E_INSUFFICIENT_BUFFER /
Ritor1
parents:
diff changeset
3675 HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER
Ritor1
parents:
diff changeset
3676 - this return value is an indication that there was
Ritor1
parents:
diff changeset
3677 insufficient space in the destination buffer to copy any
Ritor1
parents:
diff changeset
3678 data
Ritor1
parents:
diff changeset
3679
Ritor1
parents:
diff changeset
3680 It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the
Ritor1
parents:
diff changeset
3681 return value of this function.
Ritor1
parents:
diff changeset
3682
Ritor1
parents:
diff changeset
3683 --*/
Ritor1
parents:
diff changeset
3684
Ritor1
parents:
diff changeset
3685 #ifndef STRSAFE_LIB_IMPL
Ritor1
parents:
diff changeset
3686 STRSAFE_INLINE_API StringCbGetsA(char* pszDest, size_t cbDest);
Ritor1
parents:
diff changeset
3687 STRSAFE_INLINE_API StringCbGetsW(wchar_t* pszDest, size_t cbDest);
Ritor1
parents:
diff changeset
3688 #ifdef UNICODE
Ritor1
parents:
diff changeset
3689 #define StringCbGets StringCbGetsW
Ritor1
parents:
diff changeset
3690 #else
Ritor1
parents:
diff changeset
3691 #define StringCbGets StringCbGetsA
Ritor1
parents:
diff changeset
3692 #endif // !UNICODE
Ritor1
parents:
diff changeset
3693
Ritor1
parents:
diff changeset
3694 STRSAFE_INLINE_API StringCbGetsA(char* pszDest, size_t cbDest)
Ritor1
parents:
diff changeset
3695 {
Ritor1
parents:
diff changeset
3696 HRESULT hr;
Ritor1
parents:
diff changeset
3697 size_t cchDest;
Ritor1
parents:
diff changeset
3698
Ritor1
parents:
diff changeset
3699 // convert to count of characters
Ritor1
parents:
diff changeset
3700 cchDest = cbDest / sizeof(char);
Ritor1
parents:
diff changeset
3701
Ritor1
parents:
diff changeset
3702 if (cchDest > STRSAFE_MAX_CCH)
Ritor1
parents:
diff changeset
3703 {
Ritor1
parents:
diff changeset
3704 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
3705 }
Ritor1
parents:
diff changeset
3706 else
Ritor1
parents:
diff changeset
3707 {
Ritor1
parents:
diff changeset
3708 hr = StringGetsExWorkerA(pszDest, cchDest, cbDest, NULL, NULL, 0);
Ritor1
parents:
diff changeset
3709 }
Ritor1
parents:
diff changeset
3710
Ritor1
parents:
diff changeset
3711 return hr;
Ritor1
parents:
diff changeset
3712 }
Ritor1
parents:
diff changeset
3713
Ritor1
parents:
diff changeset
3714 STRSAFE_INLINE_API StringCbGetsW(wchar_t* pszDest, size_t cbDest)
Ritor1
parents:
diff changeset
3715 {
Ritor1
parents:
diff changeset
3716 HRESULT hr;
Ritor1
parents:
diff changeset
3717 size_t cchDest;
Ritor1
parents:
diff changeset
3718
Ritor1
parents:
diff changeset
3719 // convert to count of characters
Ritor1
parents:
diff changeset
3720 cchDest = cbDest / sizeof(wchar_t);
Ritor1
parents:
diff changeset
3721
Ritor1
parents:
diff changeset
3722 if (cchDest > STRSAFE_MAX_CCH)
Ritor1
parents:
diff changeset
3723 {
Ritor1
parents:
diff changeset
3724 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
3725 }
Ritor1
parents:
diff changeset
3726 else
Ritor1
parents:
diff changeset
3727 {
Ritor1
parents:
diff changeset
3728 hr = StringGetsExWorkerW(pszDest, cchDest, cbDest, NULL, NULL, 0);
Ritor1
parents:
diff changeset
3729 }
Ritor1
parents:
diff changeset
3730
Ritor1
parents:
diff changeset
3731 return hr;
Ritor1
parents:
diff changeset
3732 }
Ritor1
parents:
diff changeset
3733 #endif // !STRSAFE_NO_CB_FUNCTIONS
Ritor1
parents:
diff changeset
3734 #endif // !STRSAFE_LIB_IMPL
Ritor1
parents:
diff changeset
3735
Ritor1
parents:
diff changeset
3736 #ifndef STRSAFE_NO_CCH_FUNCTIONS
Ritor1
parents:
diff changeset
3737 /*++
Ritor1
parents:
diff changeset
3738
Ritor1
parents:
diff changeset
3739 STDAPI
Ritor1
parents:
diff changeset
3740 StringCchGetsEx(
Ritor1
parents:
diff changeset
3741 OUT LPTSTR pszDest OPTIONAL,
Ritor1
parents:
diff changeset
3742 IN size_t cchDest,
Ritor1
parents:
diff changeset
3743 OUT LPTSTR* ppszDestEnd OPTIONAL,
Ritor1
parents:
diff changeset
3744 OUT size_t* pcchRemaining OPTIONAL,
Ritor1
parents:
diff changeset
3745 IN DWORD dwFlags
Ritor1
parents:
diff changeset
3746 );
Ritor1
parents:
diff changeset
3747
Ritor1
parents:
diff changeset
3748 Routine Description:
Ritor1
parents:
diff changeset
3749
Ritor1
parents:
diff changeset
3750 This routine is a safer version of the C built-in function 'gets' with
Ritor1
parents:
diff changeset
3751 some additional parameters. In addition to functionality provided by
Ritor1
parents:
diff changeset
3752 StringCchGets, this routine also returns a pointer to the end of the
Ritor1
parents:
diff changeset
3753 destination string and the number of characters left in the destination string
Ritor1
parents:
diff changeset
3754 including the null terminator. The flags parameter allows additional controls.
Ritor1
parents:
diff changeset
3755
Ritor1
parents:
diff changeset
3756 Arguments:
Ritor1
parents:
diff changeset
3757
Ritor1
parents:
diff changeset
3758 pszDest - destination string
Ritor1
parents:
diff changeset
3759
Ritor1
parents:
diff changeset
3760 cchDest - size of destination buffer in characters.
Ritor1
parents:
diff changeset
3761
Ritor1
parents:
diff changeset
3762 ppszDestEnd - if ppszDestEnd is non-null, the function will return a
Ritor1
parents:
diff changeset
3763 pointer to the end of the destination string. If the
Ritor1
parents:
diff changeset
3764 function copied any data, the result will point to the
Ritor1
parents:
diff changeset
3765 null termination character
Ritor1
parents:
diff changeset
3766
Ritor1
parents:
diff changeset
3767 pcchRemaining - if pcchRemaining is non-null, the function will return the
Ritor1
parents:
diff changeset
3768 number of characters left in the destination string,
Ritor1
parents:
diff changeset
3769 including the null terminator
Ritor1
parents:
diff changeset
3770
Ritor1
parents:
diff changeset
3771 dwFlags - controls some details of the string copy:
Ritor1
parents:
diff changeset
3772
Ritor1
parents:
diff changeset
3773 STRSAFE_FILL_BEHIND_NULL
Ritor1
parents:
diff changeset
3774 if the function succeeds, the low byte of dwFlags will be
Ritor1
parents:
diff changeset
3775 used to fill the uninitialize part of destination buffer
Ritor1
parents:
diff changeset
3776 behind the null terminator
Ritor1
parents:
diff changeset
3777
Ritor1
parents:
diff changeset
3778 STRSAFE_IGNORE_NULLS
Ritor1
parents:
diff changeset
3779 treat NULL string pointers like empty strings (TEXT("")).
Ritor1
parents:
diff changeset
3780
Ritor1
parents:
diff changeset
3781 STRSAFE_FILL_ON_FAILURE
Ritor1
parents:
diff changeset
3782 if the function fails, the low byte of dwFlags will be
Ritor1
parents:
diff changeset
3783 used to fill all of the destination buffer, and it will
Ritor1
parents:
diff changeset
3784 be null terminated.
Ritor1
parents:
diff changeset
3785
Ritor1
parents:
diff changeset
3786 STRSAFE_NO_TRUNCATION /
Ritor1
parents:
diff changeset
3787 STRSAFE_NULL_ON_FAILURE
Ritor1
parents:
diff changeset
3788 if the function fails, the destination buffer will be set
Ritor1
parents:
diff changeset
3789 to the empty string.
Ritor1
parents:
diff changeset
3790
Ritor1
parents:
diff changeset
3791 Notes:
Ritor1
parents:
diff changeset
3792 pszDest should not be NULL unless the STRSAFE_IGNORE_NULLS flag is specified.
Ritor1
parents:
diff changeset
3793 If STRSAFE_IGNORE_NULLS is passed and pszDest is NULL, an error may still be
Ritor1
parents:
diff changeset
3794 returned even though NULLS are ignored
Ritor1
parents:
diff changeset
3795
Ritor1
parents:
diff changeset
3796 cchDest must be > 1 for this function to succeed.
Ritor1
parents:
diff changeset
3797
Ritor1
parents:
diff changeset
3798 Return Value:
Ritor1
parents:
diff changeset
3799
Ritor1
parents:
diff changeset
3800 S_OK - data was read from stdin and copied, and the resultant
Ritor1
parents:
diff changeset
3801 dest string was null terminated
Ritor1
parents:
diff changeset
3802
Ritor1
parents:
diff changeset
3803 failure - you can use the macro HRESULT_CODE() to get a win32
Ritor1
parents:
diff changeset
3804 error code for all hresult failure cases
Ritor1
parents:
diff changeset
3805
Ritor1
parents:
diff changeset
3806 STRSAFE_E_END_OF_FILE /
Ritor1
parents:
diff changeset
3807 HRESULT_CODE(hr) == ERROR_HANDLE_EOF
Ritor1
parents:
diff changeset
3808 - this return value indicates an error or end-of-file
Ritor1
parents:
diff changeset
3809 condition, use feof or ferror to determine which one has
Ritor1
parents:
diff changeset
3810 occured.
Ritor1
parents:
diff changeset
3811
Ritor1
parents:
diff changeset
3812 STRSAFE_E_INSUFFICIENT_BUFFER /
Ritor1
parents:
diff changeset
3813 HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER
Ritor1
parents:
diff changeset
3814 - this return value is an indication that there was
Ritor1
parents:
diff changeset
3815 insufficient space in the destination buffer to copy any
Ritor1
parents:
diff changeset
3816 data
Ritor1
parents:
diff changeset
3817
Ritor1
parents:
diff changeset
3818 It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the
Ritor1
parents:
diff changeset
3819 return value of this function.
Ritor1
parents:
diff changeset
3820
Ritor1
parents:
diff changeset
3821 --*/
Ritor1
parents:
diff changeset
3822
Ritor1
parents:
diff changeset
3823 #ifndef STRSAFE_LIB_IMPL
Ritor1
parents:
diff changeset
3824 STRSAFE_INLINE_API StringCchGetsExA(char* pszDest, size_t cchDest, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags);
Ritor1
parents:
diff changeset
3825 STRSAFE_INLINE_API StringCchGetsExW(wchar_t* pszDest, size_t cchDest, wchar_t** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags);
Ritor1
parents:
diff changeset
3826 #ifdef UNICODE
Ritor1
parents:
diff changeset
3827 #define StringCchGetsEx StringCchGetsExW
Ritor1
parents:
diff changeset
3828 #else
Ritor1
parents:
diff changeset
3829 #define StringCchGetsEx StringCchGetsExA
Ritor1
parents:
diff changeset
3830 #endif // !UNICODE
Ritor1
parents:
diff changeset
3831
Ritor1
parents:
diff changeset
3832 STRSAFE_INLINE_API StringCchGetsExA(char* pszDest, size_t cchDest, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags)
Ritor1
parents:
diff changeset
3833 {
Ritor1
parents:
diff changeset
3834 HRESULT hr;
Ritor1
parents:
diff changeset
3835
Ritor1
parents:
diff changeset
3836 if (cchDest > STRSAFE_MAX_CCH)
Ritor1
parents:
diff changeset
3837 {
Ritor1
parents:
diff changeset
3838 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
3839 }
Ritor1
parents:
diff changeset
3840 else
Ritor1
parents:
diff changeset
3841 {
Ritor1
parents:
diff changeset
3842 size_t cbDest;
Ritor1
parents:
diff changeset
3843
Ritor1
parents:
diff changeset
3844 // safe to multiply cchDest * sizeof(char) since cchDest < STRSAFE_MAX_CCH and sizeof(char) is 1
Ritor1
parents:
diff changeset
3845 cbDest = cchDest * sizeof(char);
Ritor1
parents:
diff changeset
3846
Ritor1
parents:
diff changeset
3847 hr = StringGetsExWorkerA(pszDest, cchDest, cbDest, ppszDestEnd, pcchRemaining, dwFlags);
Ritor1
parents:
diff changeset
3848 }
Ritor1
parents:
diff changeset
3849
Ritor1
parents:
diff changeset
3850 return hr;
Ritor1
parents:
diff changeset
3851 }
Ritor1
parents:
diff changeset
3852
Ritor1
parents:
diff changeset
3853 STRSAFE_INLINE_API StringCchGetsExW(wchar_t* pszDest, size_t cchDest, wchar_t** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags)
Ritor1
parents:
diff changeset
3854 {
Ritor1
parents:
diff changeset
3855 HRESULT hr;
Ritor1
parents:
diff changeset
3856
Ritor1
parents:
diff changeset
3857 if (cchDest > STRSAFE_MAX_CCH)
Ritor1
parents:
diff changeset
3858 {
Ritor1
parents:
diff changeset
3859 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
3860 }
Ritor1
parents:
diff changeset
3861 else
Ritor1
parents:
diff changeset
3862 {
Ritor1
parents:
diff changeset
3863 size_t cbDest;
Ritor1
parents:
diff changeset
3864
Ritor1
parents:
diff changeset
3865 // safe to multiply cchDest * sizeof(wchar_t) since cchDest < STRSAFE_MAX_CCH and sizeof(wchar_t) is 2
Ritor1
parents:
diff changeset
3866 cbDest = cchDest * sizeof(wchar_t);
Ritor1
parents:
diff changeset
3867
Ritor1
parents:
diff changeset
3868 hr = StringGetsExWorkerW(pszDest, cchDest, cbDest, ppszDestEnd, pcchRemaining, dwFlags);
Ritor1
parents:
diff changeset
3869 }
Ritor1
parents:
diff changeset
3870
Ritor1
parents:
diff changeset
3871 return hr;
Ritor1
parents:
diff changeset
3872 }
Ritor1
parents:
diff changeset
3873 #endif // !STRSAFE_NO_CCH_FUNCTIONS
Ritor1
parents:
diff changeset
3874 #endif // !STRSAFE_LIB_IMPL
Ritor1
parents:
diff changeset
3875
Ritor1
parents:
diff changeset
3876 #ifndef STRSAFE_NO_CB_FUNCTIONS
Ritor1
parents:
diff changeset
3877 /*++
Ritor1
parents:
diff changeset
3878
Ritor1
parents:
diff changeset
3879 STDAPI
Ritor1
parents:
diff changeset
3880 StringCbGetsEx(
Ritor1
parents:
diff changeset
3881 OUT LPTSTR pszDest OPTIONAL,
Ritor1
parents:
diff changeset
3882 IN size_t cbDest,
Ritor1
parents:
diff changeset
3883 OUT LPTSTR* ppszDestEnd OPTIONAL,
Ritor1
parents:
diff changeset
3884 OUT size_t* pcbRemaining OPTIONAL,
Ritor1
parents:
diff changeset
3885 IN DWORD dwFlags
Ritor1
parents:
diff changeset
3886 );
Ritor1
parents:
diff changeset
3887
Ritor1
parents:
diff changeset
3888 Routine Description:
Ritor1
parents:
diff changeset
3889
Ritor1
parents:
diff changeset
3890 This routine is a safer version of the C built-in function 'gets' with
Ritor1
parents:
diff changeset
3891 some additional parameters. In addition to functionality provided by
Ritor1
parents:
diff changeset
3892 StringCbGets, this routine also returns a pointer to the end of the
Ritor1
parents:
diff changeset
3893 destination string and the number of characters left in the destination string
Ritor1
parents:
diff changeset
3894 including the null terminator. The flags parameter allows additional controls.
Ritor1
parents:
diff changeset
3895
Ritor1
parents:
diff changeset
3896 Arguments:
Ritor1
parents:
diff changeset
3897
Ritor1
parents:
diff changeset
3898 pszDest - destination string
Ritor1
parents:
diff changeset
3899
Ritor1
parents:
diff changeset
3900 cbDest - size of destination buffer in bytes.
Ritor1
parents:
diff changeset
3901
Ritor1
parents:
diff changeset
3902 ppszDestEnd - if ppszDestEnd is non-null, the function will return a
Ritor1
parents:
diff changeset
3903 pointer to the end of the destination string. If the
Ritor1
parents:
diff changeset
3904 function copied any data, the result will point to the
Ritor1
parents:
diff changeset
3905 null termination character
Ritor1
parents:
diff changeset
3906
Ritor1
parents:
diff changeset
3907 pcbRemaining - if pbRemaining is non-null, the function will return the
Ritor1
parents:
diff changeset
3908 number of bytes left in the destination string,
Ritor1
parents:
diff changeset
3909 including the null terminator
Ritor1
parents:
diff changeset
3910
Ritor1
parents:
diff changeset
3911 dwFlags - controls some details of the string copy:
Ritor1
parents:
diff changeset
3912
Ritor1
parents:
diff changeset
3913 STRSAFE_FILL_BEHIND_NULL
Ritor1
parents:
diff changeset
3914 if the function succeeds, the low byte of dwFlags will be
Ritor1
parents:
diff changeset
3915 used to fill the uninitialize part of destination buffer
Ritor1
parents:
diff changeset
3916 behind the null terminator
Ritor1
parents:
diff changeset
3917
Ritor1
parents:
diff changeset
3918 STRSAFE_IGNORE_NULLS
Ritor1
parents:
diff changeset
3919 treat NULL string pointers like empty strings (TEXT("")).
Ritor1
parents:
diff changeset
3920
Ritor1
parents:
diff changeset
3921 STRSAFE_FILL_ON_FAILURE
Ritor1
parents:
diff changeset
3922 if the function fails, the low byte of dwFlags will be
Ritor1
parents:
diff changeset
3923 used to fill all of the destination buffer, and it will
Ritor1
parents:
diff changeset
3924 be null terminated.
Ritor1
parents:
diff changeset
3925
Ritor1
parents:
diff changeset
3926 STRSAFE_NO_TRUNCATION /
Ritor1
parents:
diff changeset
3927 STRSAFE_NULL_ON_FAILURE
Ritor1
parents:
diff changeset
3928 if the function fails, the destination buffer will be set
Ritor1
parents:
diff changeset
3929 to the empty string.
Ritor1
parents:
diff changeset
3930
Ritor1
parents:
diff changeset
3931 Notes:
Ritor1
parents:
diff changeset
3932 pszDest should not be NULL unless the STRSAFE_IGNORE_NULLS flag is specified.
Ritor1
parents:
diff changeset
3933 If STRSAFE_IGNORE_NULLS is passed and pszDest is NULL, an error may still be
Ritor1
parents:
diff changeset
3934 returned even though NULLS are ignored
Ritor1
parents:
diff changeset
3935
Ritor1
parents:
diff changeset
3936 cbDest must be > sizeof(TCHAR) for this function to succeed
Ritor1
parents:
diff changeset
3937
Ritor1
parents:
diff changeset
3938 Return Value:
Ritor1
parents:
diff changeset
3939
Ritor1
parents:
diff changeset
3940 S_OK - data was read from stdin and copied, and the resultant
Ritor1
parents:
diff changeset
3941 dest string was null terminated
Ritor1
parents:
diff changeset
3942
Ritor1
parents:
diff changeset
3943 failure - you can use the macro HRESULT_CODE() to get a win32
Ritor1
parents:
diff changeset
3944 error code for all hresult failure cases
Ritor1
parents:
diff changeset
3945
Ritor1
parents:
diff changeset
3946 STRSAFE_E_END_OF_FILE /
Ritor1
parents:
diff changeset
3947 HRESULT_CODE(hr) == ERROR_HANDLE_EOF
Ritor1
parents:
diff changeset
3948 - this return value indicates an error or end-of-file
Ritor1
parents:
diff changeset
3949 condition, use feof or ferror to determine which one has
Ritor1
parents:
diff changeset
3950 occured.
Ritor1
parents:
diff changeset
3951
Ritor1
parents:
diff changeset
3952 STRSAFE_E_INSUFFICIENT_BUFFER /
Ritor1
parents:
diff changeset
3953 HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER
Ritor1
parents:
diff changeset
3954 - this return value is an indication that there was
Ritor1
parents:
diff changeset
3955 insufficient space in the destination buffer to copy any
Ritor1
parents:
diff changeset
3956 data
Ritor1
parents:
diff changeset
3957
Ritor1
parents:
diff changeset
3958 It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the
Ritor1
parents:
diff changeset
3959 return value of this function.
Ritor1
parents:
diff changeset
3960
Ritor1
parents:
diff changeset
3961 --*/
Ritor1
parents:
diff changeset
3962
Ritor1
parents:
diff changeset
3963 #ifndef STRSAFE_LIB_IMPL
Ritor1
parents:
diff changeset
3964 STRSAFE_INLINE_API StringCbGetsExA(char* pszDest, size_t cbDest, char** ppszDestEnd, size_t* pbRemaining, unsigned long dwFlags);
Ritor1
parents:
diff changeset
3965 STRSAFE_INLINE_API StringCbGetsExW(wchar_t* pszDest, size_t cbDest, wchar_t** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags);
Ritor1
parents:
diff changeset
3966 #ifdef UNICODE
Ritor1
parents:
diff changeset
3967 #define StringCbGetsEx StringCbGetsExW
Ritor1
parents:
diff changeset
3968 #else
Ritor1
parents:
diff changeset
3969 #define StringCbGetsEx StringCbGetsExA
Ritor1
parents:
diff changeset
3970 #endif // !UNICODE
Ritor1
parents:
diff changeset
3971
Ritor1
parents:
diff changeset
3972 STRSAFE_INLINE_API StringCbGetsExA(char* pszDest, size_t cbDest, char** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags)
Ritor1
parents:
diff changeset
3973 {
Ritor1
parents:
diff changeset
3974 HRESULT hr;
Ritor1
parents:
diff changeset
3975 size_t cchDest;
Ritor1
parents:
diff changeset
3976 size_t cchRemaining = 0;
Ritor1
parents:
diff changeset
3977
Ritor1
parents:
diff changeset
3978 cchDest = cbDest / sizeof(char);
Ritor1
parents:
diff changeset
3979
Ritor1
parents:
diff changeset
3980 if (cchDest > STRSAFE_MAX_CCH)
Ritor1
parents:
diff changeset
3981 {
Ritor1
parents:
diff changeset
3982 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
3983 }
Ritor1
parents:
diff changeset
3984 else
Ritor1
parents:
diff changeset
3985 {
Ritor1
parents:
diff changeset
3986 hr = StringGetsExWorkerA(pszDest, cchDest, cbDest, ppszDestEnd, &cchRemaining, dwFlags);
Ritor1
parents:
diff changeset
3987 }
Ritor1
parents:
diff changeset
3988
Ritor1
parents:
diff changeset
3989 if (SUCCEEDED(hr) ||
Ritor1
parents:
diff changeset
3990 (hr == STRSAFE_E_INSUFFICIENT_BUFFER) ||
Ritor1
parents:
diff changeset
3991 (hr == STRSAFE_E_END_OF_FILE))
Ritor1
parents:
diff changeset
3992 {
Ritor1
parents:
diff changeset
3993 if (pcbRemaining)
Ritor1
parents:
diff changeset
3994 {
Ritor1
parents:
diff changeset
3995 // safe to multiply cchRemaining * sizeof(char) since cchRemaining < STRSAFE_MAX_CCH and sizeof(char) is 1
Ritor1
parents:
diff changeset
3996 *pcbRemaining = (cchRemaining * sizeof(char)) + (cbDest % sizeof(char));
Ritor1
parents:
diff changeset
3997 }
Ritor1
parents:
diff changeset
3998 }
Ritor1
parents:
diff changeset
3999
Ritor1
parents:
diff changeset
4000 return hr;
Ritor1
parents:
diff changeset
4001 }
Ritor1
parents:
diff changeset
4002
Ritor1
parents:
diff changeset
4003 STRSAFE_INLINE_API StringCbGetsExW(wchar_t* pszDest, size_t cbDest, wchar_t** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags)
Ritor1
parents:
diff changeset
4004 {
Ritor1
parents:
diff changeset
4005 HRESULT hr;
Ritor1
parents:
diff changeset
4006 size_t cchDest;
Ritor1
parents:
diff changeset
4007 size_t cchRemaining = 0;
Ritor1
parents:
diff changeset
4008
Ritor1
parents:
diff changeset
4009 cchDest = cbDest / sizeof(wchar_t);
Ritor1
parents:
diff changeset
4010
Ritor1
parents:
diff changeset
4011 if (cchDest > STRSAFE_MAX_CCH)
Ritor1
parents:
diff changeset
4012 {
Ritor1
parents:
diff changeset
4013 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
4014 }
Ritor1
parents:
diff changeset
4015 else
Ritor1
parents:
diff changeset
4016 {
Ritor1
parents:
diff changeset
4017 hr = StringGetsExWorkerW(pszDest, cchDest, cbDest, ppszDestEnd, &cchRemaining, dwFlags);
Ritor1
parents:
diff changeset
4018 }
Ritor1
parents:
diff changeset
4019
Ritor1
parents:
diff changeset
4020 if (SUCCEEDED(hr) ||
Ritor1
parents:
diff changeset
4021 (hr == STRSAFE_E_INSUFFICIENT_BUFFER) ||
Ritor1
parents:
diff changeset
4022 (hr == STRSAFE_E_END_OF_FILE))
Ritor1
parents:
diff changeset
4023 {
Ritor1
parents:
diff changeset
4024 if (pcbRemaining)
Ritor1
parents:
diff changeset
4025 {
Ritor1
parents:
diff changeset
4026 // safe to multiply cchRemaining * sizeof(wchar_t) since cchRemaining < STRSAFE_MAX_CCH and sizeof(wchar_t) is 2
Ritor1
parents:
diff changeset
4027 *pcbRemaining = (cchRemaining * sizeof(wchar_t)) + (cbDest % sizeof(wchar_t));
Ritor1
parents:
diff changeset
4028 }
Ritor1
parents:
diff changeset
4029 }
Ritor1
parents:
diff changeset
4030
Ritor1
parents:
diff changeset
4031 return hr;
Ritor1
parents:
diff changeset
4032 }
Ritor1
parents:
diff changeset
4033 #endif // !STRSAFE_NO_CB_FUNCTIONS
Ritor1
parents:
diff changeset
4034 #endif // !STRSAFE_LIB_IMPL
Ritor1
parents:
diff changeset
4035
Ritor1
parents:
diff changeset
4036 #ifndef STRSAFE_NO_CCH_FUNCTIONS
Ritor1
parents:
diff changeset
4037 /*++
Ritor1
parents:
diff changeset
4038
Ritor1
parents:
diff changeset
4039 STDAPI
Ritor1
parents:
diff changeset
4040 StringCchLength(
Ritor1
parents:
diff changeset
4041 IN LPCTSTR psz,
Ritor1
parents:
diff changeset
4042 IN size_t cchMax,
Ritor1
parents:
diff changeset
4043 OUT size_t* pcch OPTIONAL
Ritor1
parents:
diff changeset
4044 );
Ritor1
parents:
diff changeset
4045
Ritor1
parents:
diff changeset
4046 Routine Description:
Ritor1
parents:
diff changeset
4047
Ritor1
parents:
diff changeset
4048 This routine is a safer version of the C built-in function 'strlen'.
Ritor1
parents:
diff changeset
4049 It is used to make sure a string is not larger than a given length, and
Ritor1
parents:
diff changeset
4050 it optionally returns the current length in characters not including
Ritor1
parents:
diff changeset
4051 the null terminator.
Ritor1
parents:
diff changeset
4052
Ritor1
parents:
diff changeset
4053 This function returns a hresult, and not a pointer. It returns
Ritor1
parents:
diff changeset
4054 S_OK if the string is non-null and the length including the null
Ritor1
parents:
diff changeset
4055 terminator is less than or equal to cchMax characters.
Ritor1
parents:
diff changeset
4056
Ritor1
parents:
diff changeset
4057 Arguments:
Ritor1
parents:
diff changeset
4058
Ritor1
parents:
diff changeset
4059 psz - string to check the length of
Ritor1
parents:
diff changeset
4060
Ritor1
parents:
diff changeset
4061 cchMax - maximum number of characters including the null terminator
Ritor1
parents:
diff changeset
4062 that psz is allowed to contain
Ritor1
parents:
diff changeset
4063
Ritor1
parents:
diff changeset
4064 pcch - if the function succeeds and pcch is non-null, the current length
Ritor1
parents:
diff changeset
4065 in characters of psz excluding the null terminator will be returned.
Ritor1
parents:
diff changeset
4066 This out parameter is equivalent to the return value of strlen(psz)
Ritor1
parents:
diff changeset
4067
Ritor1
parents:
diff changeset
4068 Notes:
Ritor1
parents:
diff changeset
4069 psz can be null but the function will fail
Ritor1
parents:
diff changeset
4070
Ritor1
parents:
diff changeset
4071 cchMax should be greater than zero or the function will fail
Ritor1
parents:
diff changeset
4072
Ritor1
parents:
diff changeset
4073 Return Value:
Ritor1
parents:
diff changeset
4074
Ritor1
parents:
diff changeset
4075 S_OK - psz is non-null and the length including the null
Ritor1
parents:
diff changeset
4076 terminator is less than or equal to cchMax characters
Ritor1
parents:
diff changeset
4077
Ritor1
parents:
diff changeset
4078 failure - you can use the macro HRESULT_CODE() to get a win32
Ritor1
parents:
diff changeset
4079 error code for all hresult failure cases
Ritor1
parents:
diff changeset
4080
Ritor1
parents:
diff changeset
4081 It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the
Ritor1
parents:
diff changeset
4082 return value of this function.
Ritor1
parents:
diff changeset
4083
Ritor1
parents:
diff changeset
4084 --*/
Ritor1
parents:
diff changeset
4085
Ritor1
parents:
diff changeset
4086 STRSAFEAPI StringCchLengthA(const char* psz, size_t cchMax, size_t* pcch);
Ritor1
parents:
diff changeset
4087 STRSAFEAPI StringCchLengthW(const wchar_t* psz, size_t cchMax, size_t* pcch);
Ritor1
parents:
diff changeset
4088 #ifdef UNICODE
Ritor1
parents:
diff changeset
4089 #define StringCchLength StringCchLengthW
Ritor1
parents:
diff changeset
4090 #else
Ritor1
parents:
diff changeset
4091 #define StringCchLength StringCchLengthA
Ritor1
parents:
diff changeset
4092 #endif // !UNICODE
Ritor1
parents:
diff changeset
4093
Ritor1
parents:
diff changeset
4094 #ifdef STRSAFE_INLINE
Ritor1
parents:
diff changeset
4095 STRSAFEAPI StringCchLengthA(const char* psz, size_t cchMax, size_t* pcch)
Ritor1
parents:
diff changeset
4096 {
Ritor1
parents:
diff changeset
4097 HRESULT hr;
Ritor1
parents:
diff changeset
4098
Ritor1
parents:
diff changeset
4099 if ((psz == NULL) || (cchMax > STRSAFE_MAX_CCH))
Ritor1
parents:
diff changeset
4100 {
Ritor1
parents:
diff changeset
4101 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
4102 }
Ritor1
parents:
diff changeset
4103 else
Ritor1
parents:
diff changeset
4104 {
Ritor1
parents:
diff changeset
4105 hr = StringLengthWorkerA(psz, cchMax, pcch);
Ritor1
parents:
diff changeset
4106 }
Ritor1
parents:
diff changeset
4107
Ritor1
parents:
diff changeset
4108 return hr;
Ritor1
parents:
diff changeset
4109 }
Ritor1
parents:
diff changeset
4110
Ritor1
parents:
diff changeset
4111 STRSAFEAPI StringCchLengthW(const wchar_t* psz, size_t cchMax, size_t* pcch)
Ritor1
parents:
diff changeset
4112 {
Ritor1
parents:
diff changeset
4113 HRESULT hr;
Ritor1
parents:
diff changeset
4114
Ritor1
parents:
diff changeset
4115 if ((psz == NULL) || (cchMax > STRSAFE_MAX_CCH))
Ritor1
parents:
diff changeset
4116 {
Ritor1
parents:
diff changeset
4117 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
4118 }
Ritor1
parents:
diff changeset
4119 else
Ritor1
parents:
diff changeset
4120 {
Ritor1
parents:
diff changeset
4121 hr = StringLengthWorkerW(psz, cchMax, pcch);
Ritor1
parents:
diff changeset
4122 }
Ritor1
parents:
diff changeset
4123
Ritor1
parents:
diff changeset
4124 return hr;
Ritor1
parents:
diff changeset
4125 }
Ritor1
parents:
diff changeset
4126 #endif // STRSAFE_INLINE
Ritor1
parents:
diff changeset
4127 #endif // !STRSAFE_NO_CCH_FUNCTIONS
Ritor1
parents:
diff changeset
4128
Ritor1
parents:
diff changeset
4129
Ritor1
parents:
diff changeset
4130 #ifndef STRSAFE_NO_CB_FUNCTIONS
Ritor1
parents:
diff changeset
4131 /*++
Ritor1
parents:
diff changeset
4132
Ritor1
parents:
diff changeset
4133 STDAPI
Ritor1
parents:
diff changeset
4134 StringCbLength(
Ritor1
parents:
diff changeset
4135 IN LPCTSTR psz,
Ritor1
parents:
diff changeset
4136 IN size_t cbMax,
Ritor1
parents:
diff changeset
4137 OUT size_t* pcb OPTIONAL
Ritor1
parents:
diff changeset
4138 );
Ritor1
parents:
diff changeset
4139
Ritor1
parents:
diff changeset
4140 Routine Description:
Ritor1
parents:
diff changeset
4141
Ritor1
parents:
diff changeset
4142 This routine is a safer version of the C built-in function 'strlen'.
Ritor1
parents:
diff changeset
4143 It is used to make sure a string is not larger than a given length, and
Ritor1
parents:
diff changeset
4144 it optionally returns the current length in bytes not including
Ritor1
parents:
diff changeset
4145 the null terminator.
Ritor1
parents:
diff changeset
4146
Ritor1
parents:
diff changeset
4147 This function returns a hresult, and not a pointer. It returns
Ritor1
parents:
diff changeset
4148 S_OK if the string is non-null and the length including the null
Ritor1
parents:
diff changeset
4149 terminator is less than or equal to cbMax bytes.
Ritor1
parents:
diff changeset
4150
Ritor1
parents:
diff changeset
4151 Arguments:
Ritor1
parents:
diff changeset
4152
Ritor1
parents:
diff changeset
4153 psz - string to check the length of
Ritor1
parents:
diff changeset
4154
Ritor1
parents:
diff changeset
4155 cbMax - maximum number of bytes including the null terminator
Ritor1
parents:
diff changeset
4156 that psz is allowed to contain
Ritor1
parents:
diff changeset
4157
Ritor1
parents:
diff changeset
4158 pcb - if the function succeeds and pcb is non-null, the current length
Ritor1
parents:
diff changeset
4159 in bytes of psz excluding the null terminator will be returned.
Ritor1
parents:
diff changeset
4160 This out parameter is equivalent to the return value of strlen(psz) * sizeof(TCHAR)
Ritor1
parents:
diff changeset
4161
Ritor1
parents:
diff changeset
4162 Notes:
Ritor1
parents:
diff changeset
4163 psz can be null but the function will fail
Ritor1
parents:
diff changeset
4164
Ritor1
parents:
diff changeset
4165 cbMax should be greater than or equal to sizeof(TCHAR) or the function will fail
Ritor1
parents:
diff changeset
4166
Ritor1
parents:
diff changeset
4167 Return Value:
Ritor1
parents:
diff changeset
4168
Ritor1
parents:
diff changeset
4169 S_OK - psz is non-null and the length including the null
Ritor1
parents:
diff changeset
4170 terminator is less than or equal to cbMax bytes
Ritor1
parents:
diff changeset
4171
Ritor1
parents:
diff changeset
4172 failure - you can use the macro HRESULT_CODE() to get a win32
Ritor1
parents:
diff changeset
4173 error code for all hresult failure cases
Ritor1
parents:
diff changeset
4174
Ritor1
parents:
diff changeset
4175 It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the
Ritor1
parents:
diff changeset
4176 return value of this function.
Ritor1
parents:
diff changeset
4177
Ritor1
parents:
diff changeset
4178 --*/
Ritor1
parents:
diff changeset
4179
Ritor1
parents:
diff changeset
4180 STRSAFEAPI StringCbLengthA(const char* psz, size_t cchMax, size_t* pcch);
Ritor1
parents:
diff changeset
4181 STRSAFEAPI StringCbLengthW(const wchar_t* psz, size_t cchMax, size_t* pcch);
Ritor1
parents:
diff changeset
4182 #ifdef UNICODE
Ritor1
parents:
diff changeset
4183 #define StringCbLength StringCbLengthW
Ritor1
parents:
diff changeset
4184 #else
Ritor1
parents:
diff changeset
4185 #define StringCbLength StringCbLengthA
Ritor1
parents:
diff changeset
4186 #endif // !UNICODE
Ritor1
parents:
diff changeset
4187
Ritor1
parents:
diff changeset
4188 #ifdef STRSAFE_INLINE
Ritor1
parents:
diff changeset
4189 STRSAFEAPI StringCbLengthA(const char* psz, size_t cbMax, size_t* pcb)
Ritor1
parents:
diff changeset
4190 {
Ritor1
parents:
diff changeset
4191 HRESULT hr;
Ritor1
parents:
diff changeset
4192 size_t cchMax;
Ritor1
parents:
diff changeset
4193 size_t cch = 0;
Ritor1
parents:
diff changeset
4194
Ritor1
parents:
diff changeset
4195 cchMax = cbMax / sizeof(char);
Ritor1
parents:
diff changeset
4196
Ritor1
parents:
diff changeset
4197 if ((psz == NULL) || (cchMax > STRSAFE_MAX_CCH))
Ritor1
parents:
diff changeset
4198 {
Ritor1
parents:
diff changeset
4199 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
4200 }
Ritor1
parents:
diff changeset
4201 else
Ritor1
parents:
diff changeset
4202 {
Ritor1
parents:
diff changeset
4203 hr = StringLengthWorkerA(psz, cchMax, &cch);
Ritor1
parents:
diff changeset
4204 }
Ritor1
parents:
diff changeset
4205
Ritor1
parents:
diff changeset
4206 if (SUCCEEDED(hr) && pcb)
Ritor1
parents:
diff changeset
4207 {
Ritor1
parents:
diff changeset
4208 // safe to multiply cch * sizeof(char) since cch < STRSAFE_MAX_CCH and sizeof(char) is 1
Ritor1
parents:
diff changeset
4209 *pcb = cch * sizeof(char);
Ritor1
parents:
diff changeset
4210 }
Ritor1
parents:
diff changeset
4211
Ritor1
parents:
diff changeset
4212 return hr;
Ritor1
parents:
diff changeset
4213 }
Ritor1
parents:
diff changeset
4214
Ritor1
parents:
diff changeset
4215 STRSAFEAPI StringCbLengthW(const wchar_t* psz, size_t cbMax, size_t* pcb)
Ritor1
parents:
diff changeset
4216 {
Ritor1
parents:
diff changeset
4217 HRESULT hr;
Ritor1
parents:
diff changeset
4218 size_t cchMax;
Ritor1
parents:
diff changeset
4219 size_t cch = 0;
Ritor1
parents:
diff changeset
4220
Ritor1
parents:
diff changeset
4221 cchMax = cbMax / sizeof(wchar_t);
Ritor1
parents:
diff changeset
4222
Ritor1
parents:
diff changeset
4223 if ((psz == NULL) || (cchMax > STRSAFE_MAX_CCH))
Ritor1
parents:
diff changeset
4224 {
Ritor1
parents:
diff changeset
4225 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
4226 }
Ritor1
parents:
diff changeset
4227 else
Ritor1
parents:
diff changeset
4228 {
Ritor1
parents:
diff changeset
4229 hr = StringLengthWorkerW(psz, cchMax, &cch);
Ritor1
parents:
diff changeset
4230 }
Ritor1
parents:
diff changeset
4231
Ritor1
parents:
diff changeset
4232 if (SUCCEEDED(hr) && pcb)
Ritor1
parents:
diff changeset
4233 {
Ritor1
parents:
diff changeset
4234 // safe to multiply cch * sizeof(wchar_t) since cch < STRSAFE_MAX_CCH and sizeof(wchar_t) is 2
Ritor1
parents:
diff changeset
4235 *pcb = cch * sizeof(wchar_t);
Ritor1
parents:
diff changeset
4236 }
Ritor1
parents:
diff changeset
4237
Ritor1
parents:
diff changeset
4238 return hr;
Ritor1
parents:
diff changeset
4239 }
Ritor1
parents:
diff changeset
4240 #endif // STRSAFE_INLINE
Ritor1
parents:
diff changeset
4241 #endif // !STRSAFE_NO_CB_FUNCTIONS
Ritor1
parents:
diff changeset
4242
Ritor1
parents:
diff changeset
4243
Ritor1
parents:
diff changeset
4244 // these are the worker functions that actually do the work
Ritor1
parents:
diff changeset
4245 #ifdef STRSAFE_INLINE
Ritor1
parents:
diff changeset
4246 STRSAFEAPI StringCopyWorkerA(char* pszDest, size_t cchDest, const char* pszSrc)
Ritor1
parents:
diff changeset
4247 {
Ritor1
parents:
diff changeset
4248 HRESULT hr = S_OK;
Ritor1
parents:
diff changeset
4249
Ritor1
parents:
diff changeset
4250 if (cchDest == 0)
Ritor1
parents:
diff changeset
4251 {
Ritor1
parents:
diff changeset
4252 // can not null terminate a zero-byte dest buffer
Ritor1
parents:
diff changeset
4253 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
4254 }
Ritor1
parents:
diff changeset
4255 else
Ritor1
parents:
diff changeset
4256 {
Ritor1
parents:
diff changeset
4257 while (cchDest && (*pszSrc != '\0'))
Ritor1
parents:
diff changeset
4258 {
Ritor1
parents:
diff changeset
4259 *pszDest++ = *pszSrc++;
Ritor1
parents:
diff changeset
4260 cchDest--;
Ritor1
parents:
diff changeset
4261 }
Ritor1
parents:
diff changeset
4262
Ritor1
parents:
diff changeset
4263 if (cchDest == 0)
Ritor1
parents:
diff changeset
4264 {
Ritor1
parents:
diff changeset
4265 // we are going to truncate pszDest
Ritor1
parents:
diff changeset
4266 pszDest--;
Ritor1
parents:
diff changeset
4267 hr = STRSAFE_E_INSUFFICIENT_BUFFER;
Ritor1
parents:
diff changeset
4268 }
Ritor1
parents:
diff changeset
4269
Ritor1
parents:
diff changeset
4270 *pszDest= '\0';
Ritor1
parents:
diff changeset
4271 }
Ritor1
parents:
diff changeset
4272
Ritor1
parents:
diff changeset
4273 return hr;
Ritor1
parents:
diff changeset
4274 }
Ritor1
parents:
diff changeset
4275
Ritor1
parents:
diff changeset
4276 STRSAFEAPI StringCopyWorkerW(wchar_t* pszDest, size_t cchDest, const wchar_t* pszSrc)
Ritor1
parents:
diff changeset
4277 {
Ritor1
parents:
diff changeset
4278 HRESULT hr = S_OK;
Ritor1
parents:
diff changeset
4279
Ritor1
parents:
diff changeset
4280 if (cchDest == 0)
Ritor1
parents:
diff changeset
4281 {
Ritor1
parents:
diff changeset
4282 // can not null terminate a zero-byte dest buffer
Ritor1
parents:
diff changeset
4283 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
4284 }
Ritor1
parents:
diff changeset
4285 else
Ritor1
parents:
diff changeset
4286 {
Ritor1
parents:
diff changeset
4287 while (cchDest && (*pszSrc != L'\0'))
Ritor1
parents:
diff changeset
4288 {
Ritor1
parents:
diff changeset
4289 *pszDest++ = *pszSrc++;
Ritor1
parents:
diff changeset
4290 cchDest--;
Ritor1
parents:
diff changeset
4291 }
Ritor1
parents:
diff changeset
4292
Ritor1
parents:
diff changeset
4293 if (cchDest == 0)
Ritor1
parents:
diff changeset
4294 {
Ritor1
parents:
diff changeset
4295 // we are going to truncate pszDest
Ritor1
parents:
diff changeset
4296 pszDest--;
Ritor1
parents:
diff changeset
4297 hr = STRSAFE_E_INSUFFICIENT_BUFFER;
Ritor1
parents:
diff changeset
4298 }
Ritor1
parents:
diff changeset
4299
Ritor1
parents:
diff changeset
4300 *pszDest= L'\0';
Ritor1
parents:
diff changeset
4301 }
Ritor1
parents:
diff changeset
4302
Ritor1
parents:
diff changeset
4303 return hr;
Ritor1
parents:
diff changeset
4304 }
Ritor1
parents:
diff changeset
4305
Ritor1
parents:
diff changeset
4306 STRSAFEAPI StringCopyExWorkerA(char* pszDest, size_t cchDest, size_t cbDest, const char* pszSrc, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags)
Ritor1
parents:
diff changeset
4307 {
Ritor1
parents:
diff changeset
4308 HRESULT hr = S_OK;
Ritor1
parents:
diff changeset
4309 char* pszDestEnd = pszDest;
Ritor1
parents:
diff changeset
4310 size_t cchRemaining = 0;
Ritor1
parents:
diff changeset
4311
Ritor1
parents:
diff changeset
4312 // ASSERT(cbDest == (cchDest * sizeof(char)) ||
Ritor1
parents:
diff changeset
4313 // cbDest == (cchDest * sizeof(char)) + (cbDest % sizeof(char)));
Ritor1
parents:
diff changeset
4314
Ritor1
parents:
diff changeset
4315 // only accept valid flags
Ritor1
parents:
diff changeset
4316 if (dwFlags & (~STRSAFE_VALID_FLAGS))
Ritor1
parents:
diff changeset
4317 {
Ritor1
parents:
diff changeset
4318 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
4319 }
Ritor1
parents:
diff changeset
4320 else
Ritor1
parents:
diff changeset
4321 {
Ritor1
parents:
diff changeset
4322 if (dwFlags & STRSAFE_IGNORE_NULLS)
Ritor1
parents:
diff changeset
4323 {
Ritor1
parents:
diff changeset
4324 if (pszDest == NULL)
Ritor1
parents:
diff changeset
4325 {
Ritor1
parents:
diff changeset
4326 if ((cchDest != 0) || (cbDest != 0))
Ritor1
parents:
diff changeset
4327 {
Ritor1
parents:
diff changeset
4328 // NULL pszDest and non-zero cchDest/cbDest is invalid
Ritor1
parents:
diff changeset
4329 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
4330 }
Ritor1
parents:
diff changeset
4331 }
Ritor1
parents:
diff changeset
4332
Ritor1
parents:
diff changeset
4333 if (pszSrc == NULL)
Ritor1
parents:
diff changeset
4334 {
Ritor1
parents:
diff changeset
4335 pszSrc = "";
Ritor1
parents:
diff changeset
4336 }
Ritor1
parents:
diff changeset
4337 }
Ritor1
parents:
diff changeset
4338
Ritor1
parents:
diff changeset
4339 if (SUCCEEDED(hr))
Ritor1
parents:
diff changeset
4340 {
Ritor1
parents:
diff changeset
4341 if (cchDest == 0)
Ritor1
parents:
diff changeset
4342 {
Ritor1
parents:
diff changeset
4343 pszDestEnd = pszDest;
Ritor1
parents:
diff changeset
4344 cchRemaining = 0;
Ritor1
parents:
diff changeset
4345
Ritor1
parents:
diff changeset
4346 // only fail if there was actually src data to copy
Ritor1
parents:
diff changeset
4347 if (*pszSrc != '\0')
Ritor1
parents:
diff changeset
4348 {
Ritor1
parents:
diff changeset
4349 if (pszDest == NULL)
Ritor1
parents:
diff changeset
4350 {
Ritor1
parents:
diff changeset
4351 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
4352 }
Ritor1
parents:
diff changeset
4353 else
Ritor1
parents:
diff changeset
4354 {
Ritor1
parents:
diff changeset
4355 hr = STRSAFE_E_INSUFFICIENT_BUFFER;
Ritor1
parents:
diff changeset
4356 }
Ritor1
parents:
diff changeset
4357 }
Ritor1
parents:
diff changeset
4358 }
Ritor1
parents:
diff changeset
4359 else
Ritor1
parents:
diff changeset
4360 {
Ritor1
parents:
diff changeset
4361 pszDestEnd = pszDest;
Ritor1
parents:
diff changeset
4362 cchRemaining = cchDest;
Ritor1
parents:
diff changeset
4363
Ritor1
parents:
diff changeset
4364 while (cchRemaining && (*pszSrc != '\0'))
Ritor1
parents:
diff changeset
4365 {
Ritor1
parents:
diff changeset
4366 *pszDestEnd++= *pszSrc++;
Ritor1
parents:
diff changeset
4367 cchRemaining--;
Ritor1
parents:
diff changeset
4368 }
Ritor1
parents:
diff changeset
4369
Ritor1
parents:
diff changeset
4370 if (cchRemaining > 0)
Ritor1
parents:
diff changeset
4371 {
Ritor1
parents:
diff changeset
4372 if (dwFlags & STRSAFE_FILL_BEHIND_NULL)
Ritor1
parents:
diff changeset
4373 {
Ritor1
parents:
diff changeset
4374 memset(pszDestEnd + 1, STRSAFE_GET_FILL_PATTERN(dwFlags), ((cchRemaining - 1) * sizeof(char)) + (cbDest % sizeof(char)));
Ritor1
parents:
diff changeset
4375 }
Ritor1
parents:
diff changeset
4376 }
Ritor1
parents:
diff changeset
4377 else
Ritor1
parents:
diff changeset
4378 {
Ritor1
parents:
diff changeset
4379 // we are going to truncate pszDest
Ritor1
parents:
diff changeset
4380 pszDestEnd--;
Ritor1
parents:
diff changeset
4381 cchRemaining++;
Ritor1
parents:
diff changeset
4382
Ritor1
parents:
diff changeset
4383 hr = STRSAFE_E_INSUFFICIENT_BUFFER;
Ritor1
parents:
diff changeset
4384 }
Ritor1
parents:
diff changeset
4385
Ritor1
parents:
diff changeset
4386 *pszDestEnd = '\0';
Ritor1
parents:
diff changeset
4387 }
Ritor1
parents:
diff changeset
4388 }
Ritor1
parents:
diff changeset
4389 }
Ritor1
parents:
diff changeset
4390
Ritor1
parents:
diff changeset
4391 if (FAILED(hr))
Ritor1
parents:
diff changeset
4392 {
Ritor1
parents:
diff changeset
4393 if (pszDest)
Ritor1
parents:
diff changeset
4394 {
Ritor1
parents:
diff changeset
4395 if (dwFlags & STRSAFE_FILL_ON_FAILURE)
Ritor1
parents:
diff changeset
4396 {
Ritor1
parents:
diff changeset
4397 memset(pszDest, STRSAFE_GET_FILL_PATTERN(dwFlags), cbDest);
Ritor1
parents:
diff changeset
4398
Ritor1
parents:
diff changeset
4399 if (STRSAFE_GET_FILL_PATTERN(dwFlags) == 0)
Ritor1
parents:
diff changeset
4400 {
Ritor1
parents:
diff changeset
4401 pszDestEnd = pszDest;
Ritor1
parents:
diff changeset
4402 cchRemaining = cchDest;
Ritor1
parents:
diff changeset
4403 }
Ritor1
parents:
diff changeset
4404 else if (cchDest > 0)
Ritor1
parents:
diff changeset
4405 {
Ritor1
parents:
diff changeset
4406 pszDestEnd = pszDest + cchDest - 1;
Ritor1
parents:
diff changeset
4407 cchRemaining = 1;
Ritor1
parents:
diff changeset
4408
Ritor1
parents:
diff changeset
4409 // null terminate the end of the string
Ritor1
parents:
diff changeset
4410 *pszDestEnd = '\0';
Ritor1
parents:
diff changeset
4411 }
Ritor1
parents:
diff changeset
4412 }
Ritor1
parents:
diff changeset
4413
Ritor1
parents:
diff changeset
4414 if (dwFlags & (STRSAFE_NULL_ON_FAILURE | STRSAFE_NO_TRUNCATION))
Ritor1
parents:
diff changeset
4415 {
Ritor1
parents:
diff changeset
4416 if (cchDest > 0)
Ritor1
parents:
diff changeset
4417 {
Ritor1
parents:
diff changeset
4418 pszDestEnd = pszDest;
Ritor1
parents:
diff changeset
4419 cchRemaining = cchDest;
Ritor1
parents:
diff changeset
4420
Ritor1
parents:
diff changeset
4421 // null terminate the beginning of the string
Ritor1
parents:
diff changeset
4422 *pszDestEnd = '\0';
Ritor1
parents:
diff changeset
4423 }
Ritor1
parents:
diff changeset
4424 }
Ritor1
parents:
diff changeset
4425 }
Ritor1
parents:
diff changeset
4426 }
Ritor1
parents:
diff changeset
4427
Ritor1
parents:
diff changeset
4428 if (SUCCEEDED(hr) || (hr == STRSAFE_E_INSUFFICIENT_BUFFER))
Ritor1
parents:
diff changeset
4429 {
Ritor1
parents:
diff changeset
4430 if (ppszDestEnd)
Ritor1
parents:
diff changeset
4431 {
Ritor1
parents:
diff changeset
4432 *ppszDestEnd = pszDestEnd;
Ritor1
parents:
diff changeset
4433 }
Ritor1
parents:
diff changeset
4434
Ritor1
parents:
diff changeset
4435 if (pcchRemaining)
Ritor1
parents:
diff changeset
4436 {
Ritor1
parents:
diff changeset
4437 *pcchRemaining = cchRemaining;
Ritor1
parents:
diff changeset
4438 }
Ritor1
parents:
diff changeset
4439 }
Ritor1
parents:
diff changeset
4440
Ritor1
parents:
diff changeset
4441 return hr;
Ritor1
parents:
diff changeset
4442 }
Ritor1
parents:
diff changeset
4443
Ritor1
parents:
diff changeset
4444 STRSAFEAPI StringCopyExWorkerW(wchar_t* pszDest, size_t cchDest, size_t cbDest, const wchar_t* pszSrc, wchar_t** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags)
Ritor1
parents:
diff changeset
4445 {
Ritor1
parents:
diff changeset
4446 HRESULT hr = S_OK;
Ritor1
parents:
diff changeset
4447 wchar_t* pszDestEnd = pszDest;
Ritor1
parents:
diff changeset
4448 size_t cchRemaining = 0;
Ritor1
parents:
diff changeset
4449
Ritor1
parents:
diff changeset
4450 // ASSERT(cbDest == (cchDest * sizeof(wchar_t)) ||
Ritor1
parents:
diff changeset
4451 // cbDest == (cchDest * sizeof(wchar_t)) + (cbDest % sizeof(wchar_t)));
Ritor1
parents:
diff changeset
4452
Ritor1
parents:
diff changeset
4453 // only accept valid flags
Ritor1
parents:
diff changeset
4454 if (dwFlags & (~STRSAFE_VALID_FLAGS))
Ritor1
parents:
diff changeset
4455 {
Ritor1
parents:
diff changeset
4456 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
4457 }
Ritor1
parents:
diff changeset
4458 else
Ritor1
parents:
diff changeset
4459 {
Ritor1
parents:
diff changeset
4460 if (dwFlags & STRSAFE_IGNORE_NULLS)
Ritor1
parents:
diff changeset
4461 {
Ritor1
parents:
diff changeset
4462 if (pszDest == NULL)
Ritor1
parents:
diff changeset
4463 {
Ritor1
parents:
diff changeset
4464 if ((cchDest != 0) || (cbDest != 0))
Ritor1
parents:
diff changeset
4465 {
Ritor1
parents:
diff changeset
4466 // NULL pszDest and non-zero cchDest/cbDest is invalid
Ritor1
parents:
diff changeset
4467 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
4468 }
Ritor1
parents:
diff changeset
4469 }
Ritor1
parents:
diff changeset
4470
Ritor1
parents:
diff changeset
4471 if (pszSrc == NULL)
Ritor1
parents:
diff changeset
4472 {
Ritor1
parents:
diff changeset
4473 pszSrc = L"";
Ritor1
parents:
diff changeset
4474 }
Ritor1
parents:
diff changeset
4475 }
Ritor1
parents:
diff changeset
4476
Ritor1
parents:
diff changeset
4477 if (SUCCEEDED(hr))
Ritor1
parents:
diff changeset
4478 {
Ritor1
parents:
diff changeset
4479 if (cchDest == 0)
Ritor1
parents:
diff changeset
4480 {
Ritor1
parents:
diff changeset
4481 pszDestEnd = pszDest;
Ritor1
parents:
diff changeset
4482 cchRemaining = 0;
Ritor1
parents:
diff changeset
4483
Ritor1
parents:
diff changeset
4484 // only fail if there was actually src data to copy
Ritor1
parents:
diff changeset
4485 if (*pszSrc != L'\0')
Ritor1
parents:
diff changeset
4486 {
Ritor1
parents:
diff changeset
4487 if (pszDest == NULL)
Ritor1
parents:
diff changeset
4488 {
Ritor1
parents:
diff changeset
4489 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
4490 }
Ritor1
parents:
diff changeset
4491 else
Ritor1
parents:
diff changeset
4492 {
Ritor1
parents:
diff changeset
4493 hr = STRSAFE_E_INSUFFICIENT_BUFFER;
Ritor1
parents:
diff changeset
4494 }
Ritor1
parents:
diff changeset
4495 }
Ritor1
parents:
diff changeset
4496 }
Ritor1
parents:
diff changeset
4497 else
Ritor1
parents:
diff changeset
4498 {
Ritor1
parents:
diff changeset
4499 pszDestEnd = pszDest;
Ritor1
parents:
diff changeset
4500 cchRemaining = cchDest;
Ritor1
parents:
diff changeset
4501
Ritor1
parents:
diff changeset
4502 while (cchRemaining && (*pszSrc != L'\0'))
Ritor1
parents:
diff changeset
4503 {
Ritor1
parents:
diff changeset
4504 *pszDestEnd++= *pszSrc++;
Ritor1
parents:
diff changeset
4505 cchRemaining--;
Ritor1
parents:
diff changeset
4506 }
Ritor1
parents:
diff changeset
4507
Ritor1
parents:
diff changeset
4508 if (cchRemaining > 0)
Ritor1
parents:
diff changeset
4509 {
Ritor1
parents:
diff changeset
4510 if (dwFlags & STRSAFE_FILL_BEHIND_NULL)
Ritor1
parents:
diff changeset
4511 {
Ritor1
parents:
diff changeset
4512 memset(pszDestEnd + 1, STRSAFE_GET_FILL_PATTERN(dwFlags), ((cchRemaining - 1) * sizeof(wchar_t)) + (cbDest % sizeof(wchar_t)));
Ritor1
parents:
diff changeset
4513 }
Ritor1
parents:
diff changeset
4514 }
Ritor1
parents:
diff changeset
4515 else
Ritor1
parents:
diff changeset
4516 {
Ritor1
parents:
diff changeset
4517 // we are going to truncate pszDest
Ritor1
parents:
diff changeset
4518 pszDestEnd--;
Ritor1
parents:
diff changeset
4519 cchRemaining++;
Ritor1
parents:
diff changeset
4520
Ritor1
parents:
diff changeset
4521 hr = STRSAFE_E_INSUFFICIENT_BUFFER;
Ritor1
parents:
diff changeset
4522 }
Ritor1
parents:
diff changeset
4523
Ritor1
parents:
diff changeset
4524 *pszDestEnd = L'\0';
Ritor1
parents:
diff changeset
4525 }
Ritor1
parents:
diff changeset
4526 }
Ritor1
parents:
diff changeset
4527 }
Ritor1
parents:
diff changeset
4528
Ritor1
parents:
diff changeset
4529 if (FAILED(hr))
Ritor1
parents:
diff changeset
4530 {
Ritor1
parents:
diff changeset
4531 if (pszDest)
Ritor1
parents:
diff changeset
4532 {
Ritor1
parents:
diff changeset
4533 if (dwFlags & STRSAFE_FILL_ON_FAILURE)
Ritor1
parents:
diff changeset
4534 {
Ritor1
parents:
diff changeset
4535 memset(pszDest, STRSAFE_GET_FILL_PATTERN(dwFlags), cbDest);
Ritor1
parents:
diff changeset
4536
Ritor1
parents:
diff changeset
4537 if (STRSAFE_GET_FILL_PATTERN(dwFlags) == 0)
Ritor1
parents:
diff changeset
4538 {
Ritor1
parents:
diff changeset
4539 pszDestEnd = pszDest;
Ritor1
parents:
diff changeset
4540 cchRemaining = cchDest;
Ritor1
parents:
diff changeset
4541 }
Ritor1
parents:
diff changeset
4542 else if (cchDest > 0)
Ritor1
parents:
diff changeset
4543 {
Ritor1
parents:
diff changeset
4544 pszDestEnd = pszDest + cchDest - 1;
Ritor1
parents:
diff changeset
4545 cchRemaining = 1;
Ritor1
parents:
diff changeset
4546
Ritor1
parents:
diff changeset
4547 // null terminate the end of the string
Ritor1
parents:
diff changeset
4548 *pszDestEnd = L'\0';
Ritor1
parents:
diff changeset
4549 }
Ritor1
parents:
diff changeset
4550 }
Ritor1
parents:
diff changeset
4551
Ritor1
parents:
diff changeset
4552 if (dwFlags & (STRSAFE_NULL_ON_FAILURE | STRSAFE_NO_TRUNCATION))
Ritor1
parents:
diff changeset
4553 {
Ritor1
parents:
diff changeset
4554 if (cchDest > 0)
Ritor1
parents:
diff changeset
4555 {
Ritor1
parents:
diff changeset
4556 pszDestEnd = pszDest;
Ritor1
parents:
diff changeset
4557 cchRemaining = cchDest;
Ritor1
parents:
diff changeset
4558
Ritor1
parents:
diff changeset
4559 // null terminate the beginning of the string
Ritor1
parents:
diff changeset
4560 *pszDestEnd = L'\0';
Ritor1
parents:
diff changeset
4561 }
Ritor1
parents:
diff changeset
4562 }
Ritor1
parents:
diff changeset
4563 }
Ritor1
parents:
diff changeset
4564 }
Ritor1
parents:
diff changeset
4565
Ritor1
parents:
diff changeset
4566 if (SUCCEEDED(hr) || (hr == STRSAFE_E_INSUFFICIENT_BUFFER))
Ritor1
parents:
diff changeset
4567 {
Ritor1
parents:
diff changeset
4568 if (ppszDestEnd)
Ritor1
parents:
diff changeset
4569 {
Ritor1
parents:
diff changeset
4570 *ppszDestEnd = pszDestEnd;
Ritor1
parents:
diff changeset
4571 }
Ritor1
parents:
diff changeset
4572
Ritor1
parents:
diff changeset
4573 if (pcchRemaining)
Ritor1
parents:
diff changeset
4574 {
Ritor1
parents:
diff changeset
4575 *pcchRemaining = cchRemaining;
Ritor1
parents:
diff changeset
4576 }
Ritor1
parents:
diff changeset
4577 }
Ritor1
parents:
diff changeset
4578
Ritor1
parents:
diff changeset
4579 return hr;
Ritor1
parents:
diff changeset
4580 }
Ritor1
parents:
diff changeset
4581
Ritor1
parents:
diff changeset
4582 STRSAFEAPI StringCopyNWorkerA(char* pszDest, size_t cchDest, const char* pszSrc, size_t cchSrc)
Ritor1
parents:
diff changeset
4583 {
Ritor1
parents:
diff changeset
4584 HRESULT hr = S_OK;
Ritor1
parents:
diff changeset
4585
Ritor1
parents:
diff changeset
4586 if (cchDest == 0)
Ritor1
parents:
diff changeset
4587 {
Ritor1
parents:
diff changeset
4588 // can not null terminate a zero-byte dest buffer
Ritor1
parents:
diff changeset
4589 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
4590 }
Ritor1
parents:
diff changeset
4591 else
Ritor1
parents:
diff changeset
4592 {
Ritor1
parents:
diff changeset
4593 while (cchDest && cchSrc && (*pszSrc != '\0'))
Ritor1
parents:
diff changeset
4594 {
Ritor1
parents:
diff changeset
4595 *pszDest++= *pszSrc++;
Ritor1
parents:
diff changeset
4596 cchDest--;
Ritor1
parents:
diff changeset
4597 cchSrc--;
Ritor1
parents:
diff changeset
4598 }
Ritor1
parents:
diff changeset
4599
Ritor1
parents:
diff changeset
4600 if (cchDest == 0)
Ritor1
parents:
diff changeset
4601 {
Ritor1
parents:
diff changeset
4602 // we are going to truncate pszDest
Ritor1
parents:
diff changeset
4603 pszDest--;
Ritor1
parents:
diff changeset
4604 hr = STRSAFE_E_INSUFFICIENT_BUFFER;
Ritor1
parents:
diff changeset
4605 }
Ritor1
parents:
diff changeset
4606
Ritor1
parents:
diff changeset
4607 *pszDest= '\0';
Ritor1
parents:
diff changeset
4608 }
Ritor1
parents:
diff changeset
4609
Ritor1
parents:
diff changeset
4610 return hr;
Ritor1
parents:
diff changeset
4611 }
Ritor1
parents:
diff changeset
4612
Ritor1
parents:
diff changeset
4613 STRSAFEAPI StringCopyNWorkerW(wchar_t* pszDest, size_t cchDest, const wchar_t* pszSrc, size_t cchSrc)
Ritor1
parents:
diff changeset
4614 {
Ritor1
parents:
diff changeset
4615 HRESULT hr = S_OK;
Ritor1
parents:
diff changeset
4616
Ritor1
parents:
diff changeset
4617 if (cchDest == 0)
Ritor1
parents:
diff changeset
4618 {
Ritor1
parents:
diff changeset
4619 // can not null terminate a zero-byte dest buffer
Ritor1
parents:
diff changeset
4620 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
4621 }
Ritor1
parents:
diff changeset
4622 else
Ritor1
parents:
diff changeset
4623 {
Ritor1
parents:
diff changeset
4624 while (cchDest && cchSrc && (*pszSrc != L'\0'))
Ritor1
parents:
diff changeset
4625 {
Ritor1
parents:
diff changeset
4626 *pszDest++= *pszSrc++;
Ritor1
parents:
diff changeset
4627 cchDest--;
Ritor1
parents:
diff changeset
4628 cchSrc--;
Ritor1
parents:
diff changeset
4629 }
Ritor1
parents:
diff changeset
4630
Ritor1
parents:
diff changeset
4631 if (cchDest == 0)
Ritor1
parents:
diff changeset
4632 {
Ritor1
parents:
diff changeset
4633 // we are going to truncate pszDest
Ritor1
parents:
diff changeset
4634 pszDest--;
Ritor1
parents:
diff changeset
4635 hr = STRSAFE_E_INSUFFICIENT_BUFFER;
Ritor1
parents:
diff changeset
4636 }
Ritor1
parents:
diff changeset
4637
Ritor1
parents:
diff changeset
4638 *pszDest= L'\0';
Ritor1
parents:
diff changeset
4639 }
Ritor1
parents:
diff changeset
4640
Ritor1
parents:
diff changeset
4641 return hr;
Ritor1
parents:
diff changeset
4642 }
Ritor1
parents:
diff changeset
4643
Ritor1
parents:
diff changeset
4644 STRSAFEAPI StringCopyNExWorkerA(char* pszDest, size_t cchDest, size_t cbDest, const char* pszSrc, size_t cchSrc, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags)
Ritor1
parents:
diff changeset
4645 {
Ritor1
parents:
diff changeset
4646 HRESULT hr = S_OK;
Ritor1
parents:
diff changeset
4647 char* pszDestEnd = pszDest;
Ritor1
parents:
diff changeset
4648 size_t cchRemaining = 0;
Ritor1
parents:
diff changeset
4649
Ritor1
parents:
diff changeset
4650 // ASSERT(cbDest == (cchDest * sizeof(char)) ||
Ritor1
parents:
diff changeset
4651 // cbDest == (cchDest * sizeof(char)) + (cbDest % sizeof(char)));
Ritor1
parents:
diff changeset
4652
Ritor1
parents:
diff changeset
4653 // only accept valid flags
Ritor1
parents:
diff changeset
4654 if (dwFlags & (~STRSAFE_VALID_FLAGS))
Ritor1
parents:
diff changeset
4655 {
Ritor1
parents:
diff changeset
4656 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
4657 }
Ritor1
parents:
diff changeset
4658 else
Ritor1
parents:
diff changeset
4659 {
Ritor1
parents:
diff changeset
4660 if (dwFlags & STRSAFE_IGNORE_NULLS)
Ritor1
parents:
diff changeset
4661 {
Ritor1
parents:
diff changeset
4662 if (pszDest == NULL)
Ritor1
parents:
diff changeset
4663 {
Ritor1
parents:
diff changeset
4664 if ((cchDest != 0) || (cbDest != 0))
Ritor1
parents:
diff changeset
4665 {
Ritor1
parents:
diff changeset
4666 // NULL pszDest and non-zero cchDest/cbDest is invalid
Ritor1
parents:
diff changeset
4667 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
4668 }
Ritor1
parents:
diff changeset
4669 }
Ritor1
parents:
diff changeset
4670
Ritor1
parents:
diff changeset
4671 if (pszSrc == NULL)
Ritor1
parents:
diff changeset
4672 {
Ritor1
parents:
diff changeset
4673 pszSrc = "";
Ritor1
parents:
diff changeset
4674 }
Ritor1
parents:
diff changeset
4675 }
Ritor1
parents:
diff changeset
4676
Ritor1
parents:
diff changeset
4677 if (SUCCEEDED(hr))
Ritor1
parents:
diff changeset
4678 {
Ritor1
parents:
diff changeset
4679 if (cchDest == 0)
Ritor1
parents:
diff changeset
4680 {
Ritor1
parents:
diff changeset
4681 pszDestEnd = pszDest;
Ritor1
parents:
diff changeset
4682 cchRemaining = 0;
Ritor1
parents:
diff changeset
4683
Ritor1
parents:
diff changeset
4684 // only fail if there was actually src data to copy
Ritor1
parents:
diff changeset
4685 if (*pszSrc != '\0')
Ritor1
parents:
diff changeset
4686 {
Ritor1
parents:
diff changeset
4687 if (pszDest == NULL)
Ritor1
parents:
diff changeset
4688 {
Ritor1
parents:
diff changeset
4689 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
4690 }
Ritor1
parents:
diff changeset
4691 else
Ritor1
parents:
diff changeset
4692 {
Ritor1
parents:
diff changeset
4693 hr = STRSAFE_E_INSUFFICIENT_BUFFER;
Ritor1
parents:
diff changeset
4694 }
Ritor1
parents:
diff changeset
4695 }
Ritor1
parents:
diff changeset
4696 }
Ritor1
parents:
diff changeset
4697 else
Ritor1
parents:
diff changeset
4698 {
Ritor1
parents:
diff changeset
4699 pszDestEnd = pszDest;
Ritor1
parents:
diff changeset
4700 cchRemaining = cchDest;
Ritor1
parents:
diff changeset
4701
Ritor1
parents:
diff changeset
4702 while (cchRemaining && cchSrc && (*pszSrc != '\0'))
Ritor1
parents:
diff changeset
4703 {
Ritor1
parents:
diff changeset
4704 *pszDestEnd++= *pszSrc++;
Ritor1
parents:
diff changeset
4705 cchRemaining--;
Ritor1
parents:
diff changeset
4706 cchSrc--;
Ritor1
parents:
diff changeset
4707 }
Ritor1
parents:
diff changeset
4708
Ritor1
parents:
diff changeset
4709 if (cchRemaining > 0)
Ritor1
parents:
diff changeset
4710 {
Ritor1
parents:
diff changeset
4711 if (dwFlags & STRSAFE_FILL_BEHIND_NULL)
Ritor1
parents:
diff changeset
4712 {
Ritor1
parents:
diff changeset
4713 memset(pszDestEnd + 1, STRSAFE_GET_FILL_PATTERN(dwFlags), ((cchRemaining - 1) * sizeof(char)) + (cbDest % sizeof(char)));
Ritor1
parents:
diff changeset
4714 }
Ritor1
parents:
diff changeset
4715 }
Ritor1
parents:
diff changeset
4716 else
Ritor1
parents:
diff changeset
4717 {
Ritor1
parents:
diff changeset
4718 // we are going to truncate pszDest
Ritor1
parents:
diff changeset
4719 pszDestEnd--;
Ritor1
parents:
diff changeset
4720 cchRemaining++;
Ritor1
parents:
diff changeset
4721
Ritor1
parents:
diff changeset
4722 hr = STRSAFE_E_INSUFFICIENT_BUFFER;
Ritor1
parents:
diff changeset
4723 }
Ritor1
parents:
diff changeset
4724
Ritor1
parents:
diff changeset
4725 *pszDestEnd = '\0';
Ritor1
parents:
diff changeset
4726 }
Ritor1
parents:
diff changeset
4727 }
Ritor1
parents:
diff changeset
4728 }
Ritor1
parents:
diff changeset
4729
Ritor1
parents:
diff changeset
4730 if (FAILED(hr))
Ritor1
parents:
diff changeset
4731 {
Ritor1
parents:
diff changeset
4732 if (pszDest)
Ritor1
parents:
diff changeset
4733 {
Ritor1
parents:
diff changeset
4734 if (dwFlags & STRSAFE_FILL_ON_FAILURE)
Ritor1
parents:
diff changeset
4735 {
Ritor1
parents:
diff changeset
4736 memset(pszDest, STRSAFE_GET_FILL_PATTERN(dwFlags), cbDest);
Ritor1
parents:
diff changeset
4737
Ritor1
parents:
diff changeset
4738 if (STRSAFE_GET_FILL_PATTERN(dwFlags) == 0)
Ritor1
parents:
diff changeset
4739 {
Ritor1
parents:
diff changeset
4740 pszDestEnd = pszDest;
Ritor1
parents:
diff changeset
4741 cchRemaining = cchDest;
Ritor1
parents:
diff changeset
4742 }
Ritor1
parents:
diff changeset
4743 else if (cchDest > 0)
Ritor1
parents:
diff changeset
4744 {
Ritor1
parents:
diff changeset
4745 pszDestEnd = pszDest + cchDest - 1;
Ritor1
parents:
diff changeset
4746 cchRemaining = 1;
Ritor1
parents:
diff changeset
4747
Ritor1
parents:
diff changeset
4748 // null terminate the end of the string
Ritor1
parents:
diff changeset
4749 *pszDestEnd = '\0';
Ritor1
parents:
diff changeset
4750 }
Ritor1
parents:
diff changeset
4751 }
Ritor1
parents:
diff changeset
4752
Ritor1
parents:
diff changeset
4753 if (dwFlags & (STRSAFE_NULL_ON_FAILURE | STRSAFE_NO_TRUNCATION))
Ritor1
parents:
diff changeset
4754 {
Ritor1
parents:
diff changeset
4755 if (cchDest > 0)
Ritor1
parents:
diff changeset
4756 {
Ritor1
parents:
diff changeset
4757 pszDestEnd = pszDest;
Ritor1
parents:
diff changeset
4758 cchRemaining = cchDest;
Ritor1
parents:
diff changeset
4759
Ritor1
parents:
diff changeset
4760 // null terminate the beginning of the string
Ritor1
parents:
diff changeset
4761 *pszDestEnd = '\0';
Ritor1
parents:
diff changeset
4762 }
Ritor1
parents:
diff changeset
4763 }
Ritor1
parents:
diff changeset
4764 }
Ritor1
parents:
diff changeset
4765 }
Ritor1
parents:
diff changeset
4766
Ritor1
parents:
diff changeset
4767 if (SUCCEEDED(hr) || (hr == STRSAFE_E_INSUFFICIENT_BUFFER))
Ritor1
parents:
diff changeset
4768 {
Ritor1
parents:
diff changeset
4769 if (ppszDestEnd)
Ritor1
parents:
diff changeset
4770 {
Ritor1
parents:
diff changeset
4771 *ppszDestEnd = pszDestEnd;
Ritor1
parents:
diff changeset
4772 }
Ritor1
parents:
diff changeset
4773
Ritor1
parents:
diff changeset
4774 if (pcchRemaining)
Ritor1
parents:
diff changeset
4775 {
Ritor1
parents:
diff changeset
4776 *pcchRemaining = cchRemaining;
Ritor1
parents:
diff changeset
4777 }
Ritor1
parents:
diff changeset
4778 }
Ritor1
parents:
diff changeset
4779
Ritor1
parents:
diff changeset
4780 return hr;
Ritor1
parents:
diff changeset
4781 }
Ritor1
parents:
diff changeset
4782
Ritor1
parents:
diff changeset
4783 STRSAFEAPI StringCopyNExWorkerW(wchar_t* pszDest, size_t cchDest, size_t cbDest, const wchar_t* pszSrc, size_t cchSrc, wchar_t** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags)
Ritor1
parents:
diff changeset
4784 {
Ritor1
parents:
diff changeset
4785 HRESULT hr = S_OK;
Ritor1
parents:
diff changeset
4786 wchar_t* pszDestEnd = pszDest;
Ritor1
parents:
diff changeset
4787 size_t cchRemaining = 0;
Ritor1
parents:
diff changeset
4788
Ritor1
parents:
diff changeset
4789 // ASSERT(cbDest == (cchDest * sizeof(wchar_t)) ||
Ritor1
parents:
diff changeset
4790 // cbDest == (cchDest * sizeof(wchar_t)) + (cbDest % sizeof(wchar_t)));
Ritor1
parents:
diff changeset
4791
Ritor1
parents:
diff changeset
4792 // only accept valid flags
Ritor1
parents:
diff changeset
4793 if (dwFlags & (~STRSAFE_VALID_FLAGS))
Ritor1
parents:
diff changeset
4794 {
Ritor1
parents:
diff changeset
4795 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
4796 }
Ritor1
parents:
diff changeset
4797 else
Ritor1
parents:
diff changeset
4798 {
Ritor1
parents:
diff changeset
4799 if (dwFlags & STRSAFE_IGNORE_NULLS)
Ritor1
parents:
diff changeset
4800 {
Ritor1
parents:
diff changeset
4801 if (pszDest == NULL)
Ritor1
parents:
diff changeset
4802 {
Ritor1
parents:
diff changeset
4803 if ((cchDest != 0) || (cbDest != 0))
Ritor1
parents:
diff changeset
4804 {
Ritor1
parents:
diff changeset
4805 // NULL pszDest and non-zero cchDest/cbDest is invalid
Ritor1
parents:
diff changeset
4806 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
4807 }
Ritor1
parents:
diff changeset
4808 }
Ritor1
parents:
diff changeset
4809
Ritor1
parents:
diff changeset
4810 if (pszSrc == NULL)
Ritor1
parents:
diff changeset
4811 {
Ritor1
parents:
diff changeset
4812 pszSrc = L"";
Ritor1
parents:
diff changeset
4813 }
Ritor1
parents:
diff changeset
4814 }
Ritor1
parents:
diff changeset
4815
Ritor1
parents:
diff changeset
4816 if (SUCCEEDED(hr))
Ritor1
parents:
diff changeset
4817 {
Ritor1
parents:
diff changeset
4818 if (cchDest == 0)
Ritor1
parents:
diff changeset
4819 {
Ritor1
parents:
diff changeset
4820 pszDestEnd = pszDest;
Ritor1
parents:
diff changeset
4821 cchRemaining = 0;
Ritor1
parents:
diff changeset
4822
Ritor1
parents:
diff changeset
4823 // only fail if there was actually src data to copy
Ritor1
parents:
diff changeset
4824 if (*pszSrc != L'\0')
Ritor1
parents:
diff changeset
4825 {
Ritor1
parents:
diff changeset
4826 if (pszDest == NULL)
Ritor1
parents:
diff changeset
4827 {
Ritor1
parents:
diff changeset
4828 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
4829 }
Ritor1
parents:
diff changeset
4830 else
Ritor1
parents:
diff changeset
4831 {
Ritor1
parents:
diff changeset
4832 hr = STRSAFE_E_INSUFFICIENT_BUFFER;
Ritor1
parents:
diff changeset
4833 }
Ritor1
parents:
diff changeset
4834 }
Ritor1
parents:
diff changeset
4835 }
Ritor1
parents:
diff changeset
4836 else
Ritor1
parents:
diff changeset
4837 {
Ritor1
parents:
diff changeset
4838 pszDestEnd = pszDest;
Ritor1
parents:
diff changeset
4839 cchRemaining = cchDest;
Ritor1
parents:
diff changeset
4840
Ritor1
parents:
diff changeset
4841 while (cchRemaining && cchSrc && (*pszSrc != L'\0'))
Ritor1
parents:
diff changeset
4842 {
Ritor1
parents:
diff changeset
4843 *pszDestEnd++= *pszSrc++;
Ritor1
parents:
diff changeset
4844 cchRemaining--;
Ritor1
parents:
diff changeset
4845 cchSrc--;
Ritor1
parents:
diff changeset
4846 }
Ritor1
parents:
diff changeset
4847
Ritor1
parents:
diff changeset
4848 if (cchRemaining > 0)
Ritor1
parents:
diff changeset
4849 {
Ritor1
parents:
diff changeset
4850 if (dwFlags & STRSAFE_FILL_BEHIND_NULL)
Ritor1
parents:
diff changeset
4851 {
Ritor1
parents:
diff changeset
4852 memset(pszDestEnd + 1, STRSAFE_GET_FILL_PATTERN(dwFlags), ((cchRemaining - 1) * sizeof(wchar_t)) + (cbDest % sizeof(wchar_t)));
Ritor1
parents:
diff changeset
4853 }
Ritor1
parents:
diff changeset
4854 }
Ritor1
parents:
diff changeset
4855 else
Ritor1
parents:
diff changeset
4856 {
Ritor1
parents:
diff changeset
4857 // we are going to truncate pszDest
Ritor1
parents:
diff changeset
4858 pszDestEnd--;
Ritor1
parents:
diff changeset
4859 cchRemaining++;
Ritor1
parents:
diff changeset
4860
Ritor1
parents:
diff changeset
4861 hr = STRSAFE_E_INSUFFICIENT_BUFFER;
Ritor1
parents:
diff changeset
4862 }
Ritor1
parents:
diff changeset
4863
Ritor1
parents:
diff changeset
4864 *pszDestEnd = L'\0';
Ritor1
parents:
diff changeset
4865 }
Ritor1
parents:
diff changeset
4866 }
Ritor1
parents:
diff changeset
4867 }
Ritor1
parents:
diff changeset
4868
Ritor1
parents:
diff changeset
4869 if (FAILED(hr))
Ritor1
parents:
diff changeset
4870 {
Ritor1
parents:
diff changeset
4871 if (pszDest)
Ritor1
parents:
diff changeset
4872 {
Ritor1
parents:
diff changeset
4873 if (dwFlags & STRSAFE_FILL_ON_FAILURE)
Ritor1
parents:
diff changeset
4874 {
Ritor1
parents:
diff changeset
4875 memset(pszDest, STRSAFE_GET_FILL_PATTERN(dwFlags), cbDest);
Ritor1
parents:
diff changeset
4876
Ritor1
parents:
diff changeset
4877 if (STRSAFE_GET_FILL_PATTERN(dwFlags) == 0)
Ritor1
parents:
diff changeset
4878 {
Ritor1
parents:
diff changeset
4879 pszDestEnd = pszDest;
Ritor1
parents:
diff changeset
4880 cchRemaining = cchDest;
Ritor1
parents:
diff changeset
4881 }
Ritor1
parents:
diff changeset
4882 else if (cchDest > 0)
Ritor1
parents:
diff changeset
4883 {
Ritor1
parents:
diff changeset
4884 pszDestEnd = pszDest + cchDest - 1;
Ritor1
parents:
diff changeset
4885 cchRemaining = 1;
Ritor1
parents:
diff changeset
4886
Ritor1
parents:
diff changeset
4887 // null terminate the end of the string
Ritor1
parents:
diff changeset
4888 *pszDestEnd = L'\0';
Ritor1
parents:
diff changeset
4889 }
Ritor1
parents:
diff changeset
4890 }
Ritor1
parents:
diff changeset
4891
Ritor1
parents:
diff changeset
4892 if (dwFlags & (STRSAFE_NULL_ON_FAILURE | STRSAFE_NO_TRUNCATION))
Ritor1
parents:
diff changeset
4893 {
Ritor1
parents:
diff changeset
4894 if (cchDest > 0)
Ritor1
parents:
diff changeset
4895 {
Ritor1
parents:
diff changeset
4896 pszDestEnd = pszDest;
Ritor1
parents:
diff changeset
4897 cchRemaining = cchDest;
Ritor1
parents:
diff changeset
4898
Ritor1
parents:
diff changeset
4899 // null terminate the beginning of the string
Ritor1
parents:
diff changeset
4900 *pszDestEnd = L'\0';
Ritor1
parents:
diff changeset
4901 }
Ritor1
parents:
diff changeset
4902 }
Ritor1
parents:
diff changeset
4903 }
Ritor1
parents:
diff changeset
4904 }
Ritor1
parents:
diff changeset
4905
Ritor1
parents:
diff changeset
4906 if (SUCCEEDED(hr) || (hr == STRSAFE_E_INSUFFICIENT_BUFFER))
Ritor1
parents:
diff changeset
4907 {
Ritor1
parents:
diff changeset
4908 if (ppszDestEnd)
Ritor1
parents:
diff changeset
4909 {
Ritor1
parents:
diff changeset
4910 *ppszDestEnd = pszDestEnd;
Ritor1
parents:
diff changeset
4911 }
Ritor1
parents:
diff changeset
4912
Ritor1
parents:
diff changeset
4913 if (pcchRemaining)
Ritor1
parents:
diff changeset
4914 {
Ritor1
parents:
diff changeset
4915 *pcchRemaining = cchRemaining;
Ritor1
parents:
diff changeset
4916 }
Ritor1
parents:
diff changeset
4917 }
Ritor1
parents:
diff changeset
4918
Ritor1
parents:
diff changeset
4919 return hr;
Ritor1
parents:
diff changeset
4920 }
Ritor1
parents:
diff changeset
4921
Ritor1
parents:
diff changeset
4922 STRSAFEAPI StringCatWorkerA(char* pszDest, size_t cchDest, const char* pszSrc)
Ritor1
parents:
diff changeset
4923 {
Ritor1
parents:
diff changeset
4924 HRESULT hr;
Ritor1
parents:
diff changeset
4925 size_t cchDestCurrent;
Ritor1
parents:
diff changeset
4926
Ritor1
parents:
diff changeset
4927 hr = StringLengthWorkerA(pszDest, cchDest, &cchDestCurrent);
Ritor1
parents:
diff changeset
4928
Ritor1
parents:
diff changeset
4929 if (SUCCEEDED(hr))
Ritor1
parents:
diff changeset
4930 {
Ritor1
parents:
diff changeset
4931 hr = StringCopyWorkerA(pszDest + cchDestCurrent,
Ritor1
parents:
diff changeset
4932 cchDest - cchDestCurrent,
Ritor1
parents:
diff changeset
4933 pszSrc);
Ritor1
parents:
diff changeset
4934 }
Ritor1
parents:
diff changeset
4935
Ritor1
parents:
diff changeset
4936 return hr;
Ritor1
parents:
diff changeset
4937 }
Ritor1
parents:
diff changeset
4938
Ritor1
parents:
diff changeset
4939 STRSAFEAPI StringCatWorkerW(wchar_t* pszDest, size_t cchDest, const wchar_t* pszSrc)
Ritor1
parents:
diff changeset
4940 {
Ritor1
parents:
diff changeset
4941 HRESULT hr;
Ritor1
parents:
diff changeset
4942 size_t cchDestCurrent;
Ritor1
parents:
diff changeset
4943
Ritor1
parents:
diff changeset
4944 hr = StringLengthWorkerW(pszDest, cchDest, &cchDestCurrent);
Ritor1
parents:
diff changeset
4945
Ritor1
parents:
diff changeset
4946 if (SUCCEEDED(hr))
Ritor1
parents:
diff changeset
4947 {
Ritor1
parents:
diff changeset
4948 hr = StringCopyWorkerW(pszDest + cchDestCurrent,
Ritor1
parents:
diff changeset
4949 cchDest - cchDestCurrent,
Ritor1
parents:
diff changeset
4950 pszSrc);
Ritor1
parents:
diff changeset
4951 }
Ritor1
parents:
diff changeset
4952
Ritor1
parents:
diff changeset
4953 return hr;
Ritor1
parents:
diff changeset
4954 }
Ritor1
parents:
diff changeset
4955
Ritor1
parents:
diff changeset
4956 STRSAFEAPI StringCatExWorkerA(char* pszDest, size_t cchDest, size_t cbDest, const char* pszSrc, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags)
Ritor1
parents:
diff changeset
4957 {
Ritor1
parents:
diff changeset
4958 HRESULT hr = S_OK;
Ritor1
parents:
diff changeset
4959 char* pszDestEnd = pszDest;
Ritor1
parents:
diff changeset
4960 size_t cchRemaining = 0;
Ritor1
parents:
diff changeset
4961
Ritor1
parents:
diff changeset
4962 // ASSERT(cbDest == (cchDest * sizeof(char)) ||
Ritor1
parents:
diff changeset
4963 // cbDest == (cchDest * sizeof(char)) + (cbDest % sizeof(char)));
Ritor1
parents:
diff changeset
4964
Ritor1
parents:
diff changeset
4965 // only accept valid flags
Ritor1
parents:
diff changeset
4966 if (dwFlags & (~STRSAFE_VALID_FLAGS))
Ritor1
parents:
diff changeset
4967 {
Ritor1
parents:
diff changeset
4968 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
4969 }
Ritor1
parents:
diff changeset
4970 else
Ritor1
parents:
diff changeset
4971 {
Ritor1
parents:
diff changeset
4972 size_t cchDestCurrent;
Ritor1
parents:
diff changeset
4973
Ritor1
parents:
diff changeset
4974 if (dwFlags & STRSAFE_IGNORE_NULLS)
Ritor1
parents:
diff changeset
4975 {
Ritor1
parents:
diff changeset
4976 if (pszDest == NULL)
Ritor1
parents:
diff changeset
4977 {
Ritor1
parents:
diff changeset
4978 if ((cchDest == 0) && (cbDest == 0))
Ritor1
parents:
diff changeset
4979 {
Ritor1
parents:
diff changeset
4980 cchDestCurrent = 0;
Ritor1
parents:
diff changeset
4981 }
Ritor1
parents:
diff changeset
4982 else
Ritor1
parents:
diff changeset
4983 {
Ritor1
parents:
diff changeset
4984 // NULL pszDest and non-zero cchDest/cbDest is invalid
Ritor1
parents:
diff changeset
4985 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
4986 }
Ritor1
parents:
diff changeset
4987 }
Ritor1
parents:
diff changeset
4988 else
Ritor1
parents:
diff changeset
4989 {
Ritor1
parents:
diff changeset
4990 hr = StringLengthWorkerA(pszDest, cchDest, &cchDestCurrent);
Ritor1
parents:
diff changeset
4991
Ritor1
parents:
diff changeset
4992 if (SUCCEEDED(hr))
Ritor1
parents:
diff changeset
4993 {
Ritor1
parents:
diff changeset
4994 pszDestEnd = pszDest + cchDestCurrent;
Ritor1
parents:
diff changeset
4995 cchRemaining = cchDest - cchDestCurrent;
Ritor1
parents:
diff changeset
4996 }
Ritor1
parents:
diff changeset
4997 }
Ritor1
parents:
diff changeset
4998
Ritor1
parents:
diff changeset
4999 if (pszSrc == NULL)
Ritor1
parents:
diff changeset
5000 {
Ritor1
parents:
diff changeset
5001 pszSrc = "";
Ritor1
parents:
diff changeset
5002 }
Ritor1
parents:
diff changeset
5003 }
Ritor1
parents:
diff changeset
5004 else
Ritor1
parents:
diff changeset
5005 {
Ritor1
parents:
diff changeset
5006 hr = StringLengthWorkerA(pszDest, cchDest, &cchDestCurrent);
Ritor1
parents:
diff changeset
5007
Ritor1
parents:
diff changeset
5008 if (SUCCEEDED(hr))
Ritor1
parents:
diff changeset
5009 {
Ritor1
parents:
diff changeset
5010 pszDestEnd = pszDest + cchDestCurrent;
Ritor1
parents:
diff changeset
5011 cchRemaining = cchDest - cchDestCurrent;
Ritor1
parents:
diff changeset
5012 }
Ritor1
parents:
diff changeset
5013 }
Ritor1
parents:
diff changeset
5014
Ritor1
parents:
diff changeset
5015 if (SUCCEEDED(hr))
Ritor1
parents:
diff changeset
5016 {
Ritor1
parents:
diff changeset
5017 if (cchDest == 0)
Ritor1
parents:
diff changeset
5018 {
Ritor1
parents:
diff changeset
5019 // only fail if there was actually src data to append
Ritor1
parents:
diff changeset
5020 if (*pszSrc != '\0')
Ritor1
parents:
diff changeset
5021 {
Ritor1
parents:
diff changeset
5022 if (pszDest == NULL)
Ritor1
parents:
diff changeset
5023 {
Ritor1
parents:
diff changeset
5024 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
5025 }
Ritor1
parents:
diff changeset
5026 else
Ritor1
parents:
diff changeset
5027 {
Ritor1
parents:
diff changeset
5028 hr = STRSAFE_E_INSUFFICIENT_BUFFER;
Ritor1
parents:
diff changeset
5029 }
Ritor1
parents:
diff changeset
5030 }
Ritor1
parents:
diff changeset
5031 }
Ritor1
parents:
diff changeset
5032 else
Ritor1
parents:
diff changeset
5033 {
Ritor1
parents:
diff changeset
5034 // we handle the STRSAFE_FILL_ON_FAILURE and STRSAFE_NULL_ON_FAILURE cases below, so do not pass
Ritor1
parents:
diff changeset
5035 // those flags through
Ritor1
parents:
diff changeset
5036 hr = StringCopyExWorkerA(pszDestEnd,
Ritor1
parents:
diff changeset
5037 cchRemaining,
Ritor1
parents:
diff changeset
5038 (cchRemaining * sizeof(char)) + (cbDest % sizeof(char)),
Ritor1
parents:
diff changeset
5039 pszSrc,
Ritor1
parents:
diff changeset
5040 &pszDestEnd,
Ritor1
parents:
diff changeset
5041 &cchRemaining,
Ritor1
parents:
diff changeset
5042 dwFlags & (~(STRSAFE_FILL_ON_FAILURE | STRSAFE_NULL_ON_FAILURE)));
Ritor1
parents:
diff changeset
5043 }
Ritor1
parents:
diff changeset
5044 }
Ritor1
parents:
diff changeset
5045 }
Ritor1
parents:
diff changeset
5046
Ritor1
parents:
diff changeset
5047 if (FAILED(hr))
Ritor1
parents:
diff changeset
5048 {
Ritor1
parents:
diff changeset
5049 if (pszDest)
Ritor1
parents:
diff changeset
5050 {
Ritor1
parents:
diff changeset
5051 // STRSAFE_NO_TRUNCATION is taken care of by StringCopyExWorkerA()
Ritor1
parents:
diff changeset
5052
Ritor1
parents:
diff changeset
5053 if (dwFlags & STRSAFE_FILL_ON_FAILURE)
Ritor1
parents:
diff changeset
5054 {
Ritor1
parents:
diff changeset
5055 memset(pszDest, STRSAFE_GET_FILL_PATTERN(dwFlags), cbDest);
Ritor1
parents:
diff changeset
5056
Ritor1
parents:
diff changeset
5057 if (STRSAFE_GET_FILL_PATTERN(dwFlags) == 0)
Ritor1
parents:
diff changeset
5058 {
Ritor1
parents:
diff changeset
5059 pszDestEnd = pszDest;
Ritor1
parents:
diff changeset
5060 cchRemaining = cchDest;
Ritor1
parents:
diff changeset
5061 }
Ritor1
parents:
diff changeset
5062 else
Ritor1
parents:
diff changeset
5063 if (cchDest > 0)
Ritor1
parents:
diff changeset
5064 {
Ritor1
parents:
diff changeset
5065 pszDestEnd = pszDest + cchDest - 1;
Ritor1
parents:
diff changeset
5066 cchRemaining = 1;
Ritor1
parents:
diff changeset
5067
Ritor1
parents:
diff changeset
5068 // null terminate the end of the string
Ritor1
parents:
diff changeset
5069 *pszDestEnd = '\0';
Ritor1
parents:
diff changeset
5070 }
Ritor1
parents:
diff changeset
5071 }
Ritor1
parents:
diff changeset
5072
Ritor1
parents:
diff changeset
5073 if (dwFlags & STRSAFE_NULL_ON_FAILURE)
Ritor1
parents:
diff changeset
5074 {
Ritor1
parents:
diff changeset
5075 if (cchDest > 0)
Ritor1
parents:
diff changeset
5076 {
Ritor1
parents:
diff changeset
5077 pszDestEnd = pszDest;
Ritor1
parents:
diff changeset
5078 cchRemaining = cchDest;
Ritor1
parents:
diff changeset
5079
Ritor1
parents:
diff changeset
5080 // null terminate the beginning of the string
Ritor1
parents:
diff changeset
5081 *pszDestEnd = '\0';
Ritor1
parents:
diff changeset
5082 }
Ritor1
parents:
diff changeset
5083 }
Ritor1
parents:
diff changeset
5084 }
Ritor1
parents:
diff changeset
5085 }
Ritor1
parents:
diff changeset
5086
Ritor1
parents:
diff changeset
5087 if (SUCCEEDED(hr) || (hr == STRSAFE_E_INSUFFICIENT_BUFFER))
Ritor1
parents:
diff changeset
5088 {
Ritor1
parents:
diff changeset
5089 if (ppszDestEnd)
Ritor1
parents:
diff changeset
5090 {
Ritor1
parents:
diff changeset
5091 *ppszDestEnd = pszDestEnd;
Ritor1
parents:
diff changeset
5092 }
Ritor1
parents:
diff changeset
5093
Ritor1
parents:
diff changeset
5094 if (pcchRemaining)
Ritor1
parents:
diff changeset
5095 {
Ritor1
parents:
diff changeset
5096 *pcchRemaining = cchRemaining;
Ritor1
parents:
diff changeset
5097 }
Ritor1
parents:
diff changeset
5098 }
Ritor1
parents:
diff changeset
5099
Ritor1
parents:
diff changeset
5100 return hr;
Ritor1
parents:
diff changeset
5101 }
Ritor1
parents:
diff changeset
5102
Ritor1
parents:
diff changeset
5103 STRSAFEAPI StringCatExWorkerW(wchar_t* pszDest, size_t cchDest, size_t cbDest, const wchar_t* pszSrc, wchar_t** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags)
Ritor1
parents:
diff changeset
5104 {
Ritor1
parents:
diff changeset
5105 HRESULT hr = S_OK;
Ritor1
parents:
diff changeset
5106 wchar_t* pszDestEnd = pszDest;
Ritor1
parents:
diff changeset
5107 size_t cchRemaining = 0;
Ritor1
parents:
diff changeset
5108
Ritor1
parents:
diff changeset
5109 // ASSERT(cbDest == (cchDest * sizeof(wchar_t)) ||
Ritor1
parents:
diff changeset
5110 // cbDest == (cchDest * sizeof(wchar_t)) + (cbDest % sizeof(wchar_t)));
Ritor1
parents:
diff changeset
5111
Ritor1
parents:
diff changeset
5112 // only accept valid flags
Ritor1
parents:
diff changeset
5113 if (dwFlags & (~STRSAFE_VALID_FLAGS))
Ritor1
parents:
diff changeset
5114 {
Ritor1
parents:
diff changeset
5115 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
5116 }
Ritor1
parents:
diff changeset
5117 else
Ritor1
parents:
diff changeset
5118 {
Ritor1
parents:
diff changeset
5119 size_t cchDestCurrent;
Ritor1
parents:
diff changeset
5120
Ritor1
parents:
diff changeset
5121 if (dwFlags & STRSAFE_IGNORE_NULLS)
Ritor1
parents:
diff changeset
5122 {
Ritor1
parents:
diff changeset
5123 if (pszDest == NULL)
Ritor1
parents:
diff changeset
5124 {
Ritor1
parents:
diff changeset
5125 if ((cchDest == 0) && (cbDest == 0))
Ritor1
parents:
diff changeset
5126 {
Ritor1
parents:
diff changeset
5127 cchDestCurrent = 0;
Ritor1
parents:
diff changeset
5128 }
Ritor1
parents:
diff changeset
5129 else
Ritor1
parents:
diff changeset
5130 {
Ritor1
parents:
diff changeset
5131 // NULL pszDest and non-zero cchDest/cbDest is invalid
Ritor1
parents:
diff changeset
5132 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
5133 }
Ritor1
parents:
diff changeset
5134 }
Ritor1
parents:
diff changeset
5135 else
Ritor1
parents:
diff changeset
5136 {
Ritor1
parents:
diff changeset
5137 hr = StringLengthWorkerW(pszDest, cchDest, &cchDestCurrent);
Ritor1
parents:
diff changeset
5138
Ritor1
parents:
diff changeset
5139 if (SUCCEEDED(hr))
Ritor1
parents:
diff changeset
5140 {
Ritor1
parents:
diff changeset
5141 pszDestEnd = pszDest + cchDestCurrent;
Ritor1
parents:
diff changeset
5142 cchRemaining = cchDest - cchDestCurrent;
Ritor1
parents:
diff changeset
5143 }
Ritor1
parents:
diff changeset
5144 }
Ritor1
parents:
diff changeset
5145
Ritor1
parents:
diff changeset
5146 if (pszSrc == NULL)
Ritor1
parents:
diff changeset
5147 {
Ritor1
parents:
diff changeset
5148 pszSrc = L"";
Ritor1
parents:
diff changeset
5149 }
Ritor1
parents:
diff changeset
5150 }
Ritor1
parents:
diff changeset
5151 else
Ritor1
parents:
diff changeset
5152 {
Ritor1
parents:
diff changeset
5153 hr = StringLengthWorkerW(pszDest, cchDest, &cchDestCurrent);
Ritor1
parents:
diff changeset
5154
Ritor1
parents:
diff changeset
5155 if (SUCCEEDED(hr))
Ritor1
parents:
diff changeset
5156 {
Ritor1
parents:
diff changeset
5157 pszDestEnd = pszDest + cchDestCurrent;
Ritor1
parents:
diff changeset
5158 cchRemaining = cchDest - cchDestCurrent;
Ritor1
parents:
diff changeset
5159 }
Ritor1
parents:
diff changeset
5160 }
Ritor1
parents:
diff changeset
5161
Ritor1
parents:
diff changeset
5162 if (SUCCEEDED(hr))
Ritor1
parents:
diff changeset
5163 {
Ritor1
parents:
diff changeset
5164 if (cchDest == 0)
Ritor1
parents:
diff changeset
5165 {
Ritor1
parents:
diff changeset
5166 // only fail if there was actually src data to append
Ritor1
parents:
diff changeset
5167 if (*pszSrc != L'\0')
Ritor1
parents:
diff changeset
5168 {
Ritor1
parents:
diff changeset
5169 if (pszDest == NULL)
Ritor1
parents:
diff changeset
5170 {
Ritor1
parents:
diff changeset
5171 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
5172 }
Ritor1
parents:
diff changeset
5173 else
Ritor1
parents:
diff changeset
5174 {
Ritor1
parents:
diff changeset
5175 hr = STRSAFE_E_INSUFFICIENT_BUFFER;
Ritor1
parents:
diff changeset
5176 }
Ritor1
parents:
diff changeset
5177 }
Ritor1
parents:
diff changeset
5178 }
Ritor1
parents:
diff changeset
5179 else
Ritor1
parents:
diff changeset
5180 {
Ritor1
parents:
diff changeset
5181 // we handle the STRSAFE_FILL_ON_FAILURE and STRSAFE_NULL_ON_FAILURE cases below, so do not pass
Ritor1
parents:
diff changeset
5182 // those flags through
Ritor1
parents:
diff changeset
5183 hr = StringCopyExWorkerW(pszDestEnd,
Ritor1
parents:
diff changeset
5184 cchRemaining,
Ritor1
parents:
diff changeset
5185 (cchRemaining * sizeof(wchar_t)) + (cbDest % sizeof(wchar_t)),
Ritor1
parents:
diff changeset
5186 pszSrc,
Ritor1
parents:
diff changeset
5187 &pszDestEnd,
Ritor1
parents:
diff changeset
5188 &cchRemaining,
Ritor1
parents:
diff changeset
5189 dwFlags & (~(STRSAFE_FILL_ON_FAILURE | STRSAFE_NULL_ON_FAILURE)));
Ritor1
parents:
diff changeset
5190 }
Ritor1
parents:
diff changeset
5191 }
Ritor1
parents:
diff changeset
5192 }
Ritor1
parents:
diff changeset
5193
Ritor1
parents:
diff changeset
5194 if (FAILED(hr))
Ritor1
parents:
diff changeset
5195 {
Ritor1
parents:
diff changeset
5196 if (pszDest)
Ritor1
parents:
diff changeset
5197 {
Ritor1
parents:
diff changeset
5198 // STRSAFE_NO_TRUNCATION is taken care of by StringCopyExWorkerW()
Ritor1
parents:
diff changeset
5199
Ritor1
parents:
diff changeset
5200 if (dwFlags & STRSAFE_FILL_ON_FAILURE)
Ritor1
parents:
diff changeset
5201 {
Ritor1
parents:
diff changeset
5202 memset(pszDest, STRSAFE_GET_FILL_PATTERN(dwFlags), cbDest);
Ritor1
parents:
diff changeset
5203
Ritor1
parents:
diff changeset
5204 if (STRSAFE_GET_FILL_PATTERN(dwFlags) == 0)
Ritor1
parents:
diff changeset
5205 {
Ritor1
parents:
diff changeset
5206 pszDestEnd = pszDest;
Ritor1
parents:
diff changeset
5207 cchRemaining = cchDest;
Ritor1
parents:
diff changeset
5208 }
Ritor1
parents:
diff changeset
5209 else if (cchDest > 0)
Ritor1
parents:
diff changeset
5210 {
Ritor1
parents:
diff changeset
5211 pszDestEnd = pszDest + cchDest - 1;
Ritor1
parents:
diff changeset
5212 cchRemaining = 1;
Ritor1
parents:
diff changeset
5213
Ritor1
parents:
diff changeset
5214 // null terminate the end of the string
Ritor1
parents:
diff changeset
5215 *pszDestEnd = L'\0';
Ritor1
parents:
diff changeset
5216 }
Ritor1
parents:
diff changeset
5217 }
Ritor1
parents:
diff changeset
5218
Ritor1
parents:
diff changeset
5219 if (dwFlags & STRSAFE_NULL_ON_FAILURE)
Ritor1
parents:
diff changeset
5220 {
Ritor1
parents:
diff changeset
5221 if (cchDest > 0)
Ritor1
parents:
diff changeset
5222 {
Ritor1
parents:
diff changeset
5223 pszDestEnd = pszDest;
Ritor1
parents:
diff changeset
5224 cchRemaining = cchDest;
Ritor1
parents:
diff changeset
5225
Ritor1
parents:
diff changeset
5226 // null terminate the beginning of the string
Ritor1
parents:
diff changeset
5227 *pszDestEnd = L'\0';
Ritor1
parents:
diff changeset
5228 }
Ritor1
parents:
diff changeset
5229 }
Ritor1
parents:
diff changeset
5230 }
Ritor1
parents:
diff changeset
5231 }
Ritor1
parents:
diff changeset
5232
Ritor1
parents:
diff changeset
5233 if (SUCCEEDED(hr) || (hr == STRSAFE_E_INSUFFICIENT_BUFFER))
Ritor1
parents:
diff changeset
5234 {
Ritor1
parents:
diff changeset
5235 if (ppszDestEnd)
Ritor1
parents:
diff changeset
5236 {
Ritor1
parents:
diff changeset
5237 *ppszDestEnd = pszDestEnd;
Ritor1
parents:
diff changeset
5238 }
Ritor1
parents:
diff changeset
5239
Ritor1
parents:
diff changeset
5240 if (pcchRemaining)
Ritor1
parents:
diff changeset
5241 {
Ritor1
parents:
diff changeset
5242 *pcchRemaining = cchRemaining;
Ritor1
parents:
diff changeset
5243 }
Ritor1
parents:
diff changeset
5244 }
Ritor1
parents:
diff changeset
5245
Ritor1
parents:
diff changeset
5246 return hr;
Ritor1
parents:
diff changeset
5247 }
Ritor1
parents:
diff changeset
5248
Ritor1
parents:
diff changeset
5249 STRSAFEAPI StringCatNWorkerA(char* pszDest, size_t cchDest, const char* pszSrc, size_t cchMaxAppend)
Ritor1
parents:
diff changeset
5250 {
Ritor1
parents:
diff changeset
5251 HRESULT hr;
Ritor1
parents:
diff changeset
5252 size_t cchDestCurrent;
Ritor1
parents:
diff changeset
5253
Ritor1
parents:
diff changeset
5254 hr = StringLengthWorkerA(pszDest, cchDest, &cchDestCurrent);
Ritor1
parents:
diff changeset
5255
Ritor1
parents:
diff changeset
5256 if (SUCCEEDED(hr))
Ritor1
parents:
diff changeset
5257 {
Ritor1
parents:
diff changeset
5258 hr = StringCopyNWorkerA(pszDest + cchDestCurrent,
Ritor1
parents:
diff changeset
5259 cchDest - cchDestCurrent,
Ritor1
parents:
diff changeset
5260 pszSrc,
Ritor1
parents:
diff changeset
5261 cchMaxAppend);
Ritor1
parents:
diff changeset
5262 }
Ritor1
parents:
diff changeset
5263
Ritor1
parents:
diff changeset
5264 return hr;
Ritor1
parents:
diff changeset
5265 }
Ritor1
parents:
diff changeset
5266
Ritor1
parents:
diff changeset
5267 STRSAFEAPI StringCatNWorkerW(wchar_t* pszDest, size_t cchDest, const wchar_t* pszSrc, size_t cchMaxAppend)
Ritor1
parents:
diff changeset
5268 {
Ritor1
parents:
diff changeset
5269 HRESULT hr;
Ritor1
parents:
diff changeset
5270 size_t cchDestCurrent;
Ritor1
parents:
diff changeset
5271
Ritor1
parents:
diff changeset
5272 hr = StringLengthWorkerW(pszDest, cchDest, &cchDestCurrent);
Ritor1
parents:
diff changeset
5273
Ritor1
parents:
diff changeset
5274 if (SUCCEEDED(hr))
Ritor1
parents:
diff changeset
5275 {
Ritor1
parents:
diff changeset
5276 hr = StringCopyNWorkerW(pszDest + cchDestCurrent,
Ritor1
parents:
diff changeset
5277 cchDest - cchDestCurrent,
Ritor1
parents:
diff changeset
5278 pszSrc,
Ritor1
parents:
diff changeset
5279 cchMaxAppend);
Ritor1
parents:
diff changeset
5280 }
Ritor1
parents:
diff changeset
5281
Ritor1
parents:
diff changeset
5282 return hr;
Ritor1
parents:
diff changeset
5283 }
Ritor1
parents:
diff changeset
5284
Ritor1
parents:
diff changeset
5285 STRSAFEAPI StringCatNExWorkerA(char* pszDest, size_t cchDest, size_t cbDest, const char* pszSrc, size_t cchMaxAppend, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags)
Ritor1
parents:
diff changeset
5286 {
Ritor1
parents:
diff changeset
5287 HRESULT hr = S_OK;
Ritor1
parents:
diff changeset
5288 char* pszDestEnd = pszDest;
Ritor1
parents:
diff changeset
5289 size_t cchRemaining = 0;
Ritor1
parents:
diff changeset
5290 size_t cchDestCurrent = 0;
Ritor1
parents:
diff changeset
5291
Ritor1
parents:
diff changeset
5292 // ASSERT(cbDest == (cchDest * sizeof(char)) ||
Ritor1
parents:
diff changeset
5293 // cbDest == (cchDest * sizeof(char)) + (cbDest % sizeof(char)));
Ritor1
parents:
diff changeset
5294
Ritor1
parents:
diff changeset
5295 // only accept valid flags
Ritor1
parents:
diff changeset
5296 if (dwFlags & (~STRSAFE_VALID_FLAGS))
Ritor1
parents:
diff changeset
5297 {
Ritor1
parents:
diff changeset
5298 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
5299 }
Ritor1
parents:
diff changeset
5300 else
Ritor1
parents:
diff changeset
5301 {
Ritor1
parents:
diff changeset
5302 if (dwFlags & STRSAFE_IGNORE_NULLS)
Ritor1
parents:
diff changeset
5303 {
Ritor1
parents:
diff changeset
5304 if (pszDest == NULL)
Ritor1
parents:
diff changeset
5305 {
Ritor1
parents:
diff changeset
5306 if ((cchDest == 0) && (cbDest == 0))
Ritor1
parents:
diff changeset
5307 {
Ritor1
parents:
diff changeset
5308 cchDestCurrent = 0;
Ritor1
parents:
diff changeset
5309 }
Ritor1
parents:
diff changeset
5310 else
Ritor1
parents:
diff changeset
5311 {
Ritor1
parents:
diff changeset
5312 // NULL pszDest and non-zero cchDest/cbDest is invalid
Ritor1
parents:
diff changeset
5313 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
5314 }
Ritor1
parents:
diff changeset
5315 }
Ritor1
parents:
diff changeset
5316 else
Ritor1
parents:
diff changeset
5317 {
Ritor1
parents:
diff changeset
5318 hr = StringLengthWorkerA(pszDest, cchDest, &cchDestCurrent);
Ritor1
parents:
diff changeset
5319
Ritor1
parents:
diff changeset
5320 if (SUCCEEDED(hr))
Ritor1
parents:
diff changeset
5321 {
Ritor1
parents:
diff changeset
5322 pszDestEnd = pszDest + cchDestCurrent;
Ritor1
parents:
diff changeset
5323 cchRemaining = cchDest - cchDestCurrent;
Ritor1
parents:
diff changeset
5324 }
Ritor1
parents:
diff changeset
5325 }
Ritor1
parents:
diff changeset
5326
Ritor1
parents:
diff changeset
5327 if (pszSrc == NULL)
Ritor1
parents:
diff changeset
5328 {
Ritor1
parents:
diff changeset
5329 pszSrc = "";
Ritor1
parents:
diff changeset
5330 }
Ritor1
parents:
diff changeset
5331 }
Ritor1
parents:
diff changeset
5332 else
Ritor1
parents:
diff changeset
5333 {
Ritor1
parents:
diff changeset
5334 hr = StringLengthWorkerA(pszDest, cchDest, &cchDestCurrent);
Ritor1
parents:
diff changeset
5335
Ritor1
parents:
diff changeset
5336 if (SUCCEEDED(hr))
Ritor1
parents:
diff changeset
5337 {
Ritor1
parents:
diff changeset
5338 pszDestEnd = pszDest + cchDestCurrent;
Ritor1
parents:
diff changeset
5339 cchRemaining = cchDest - cchDestCurrent;
Ritor1
parents:
diff changeset
5340 }
Ritor1
parents:
diff changeset
5341 }
Ritor1
parents:
diff changeset
5342
Ritor1
parents:
diff changeset
5343 if (SUCCEEDED(hr))
Ritor1
parents:
diff changeset
5344 {
Ritor1
parents:
diff changeset
5345 if (cchDest == 0)
Ritor1
parents:
diff changeset
5346 {
Ritor1
parents:
diff changeset
5347 // only fail if there was actually src data to append
Ritor1
parents:
diff changeset
5348 if (*pszSrc != '\0')
Ritor1
parents:
diff changeset
5349 {
Ritor1
parents:
diff changeset
5350 if (pszDest == NULL)
Ritor1
parents:
diff changeset
5351 {
Ritor1
parents:
diff changeset
5352 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
5353 }
Ritor1
parents:
diff changeset
5354 else
Ritor1
parents:
diff changeset
5355 {
Ritor1
parents:
diff changeset
5356 hr = STRSAFE_E_INSUFFICIENT_BUFFER;
Ritor1
parents:
diff changeset
5357 }
Ritor1
parents:
diff changeset
5358 }
Ritor1
parents:
diff changeset
5359 }
Ritor1
parents:
diff changeset
5360 else
Ritor1
parents:
diff changeset
5361 {
Ritor1
parents:
diff changeset
5362 // we handle the STRSAFE_FILL_ON_FAILURE and STRSAFE_NULL_ON_FAILURE cases below, so do not pass
Ritor1
parents:
diff changeset
5363 // those flags through
Ritor1
parents:
diff changeset
5364 hr = StringCopyNExWorkerA(pszDestEnd,
Ritor1
parents:
diff changeset
5365 cchRemaining,
Ritor1
parents:
diff changeset
5366 (cchRemaining * sizeof(char)) + (cbDest % sizeof(char)),
Ritor1
parents:
diff changeset
5367 pszSrc,
Ritor1
parents:
diff changeset
5368 cchMaxAppend,
Ritor1
parents:
diff changeset
5369 &pszDestEnd,
Ritor1
parents:
diff changeset
5370 &cchRemaining,
Ritor1
parents:
diff changeset
5371 dwFlags & (~(STRSAFE_FILL_ON_FAILURE | STRSAFE_NULL_ON_FAILURE)));
Ritor1
parents:
diff changeset
5372 }
Ritor1
parents:
diff changeset
5373 }
Ritor1
parents:
diff changeset
5374 }
Ritor1
parents:
diff changeset
5375
Ritor1
parents:
diff changeset
5376 if (FAILED(hr))
Ritor1
parents:
diff changeset
5377 {
Ritor1
parents:
diff changeset
5378 if (pszDest)
Ritor1
parents:
diff changeset
5379 {
Ritor1
parents:
diff changeset
5380 // STRSAFE_NO_TRUNCATION is taken care of by StringCopyNExWorkerA()
Ritor1
parents:
diff changeset
5381
Ritor1
parents:
diff changeset
5382 if (dwFlags & STRSAFE_FILL_ON_FAILURE)
Ritor1
parents:
diff changeset
5383 {
Ritor1
parents:
diff changeset
5384 memset(pszDest, STRSAFE_GET_FILL_PATTERN(dwFlags), cbDest);
Ritor1
parents:
diff changeset
5385
Ritor1
parents:
diff changeset
5386 if (STRSAFE_GET_FILL_PATTERN(dwFlags) == 0)
Ritor1
parents:
diff changeset
5387 {
Ritor1
parents:
diff changeset
5388 pszDestEnd = pszDest;
Ritor1
parents:
diff changeset
5389 cchRemaining = cchDest;
Ritor1
parents:
diff changeset
5390 }
Ritor1
parents:
diff changeset
5391 else if (cchDest > 0)
Ritor1
parents:
diff changeset
5392 {
Ritor1
parents:
diff changeset
5393 pszDestEnd = pszDest + cchDest - 1;
Ritor1
parents:
diff changeset
5394 cchRemaining = 1;
Ritor1
parents:
diff changeset
5395
Ritor1
parents:
diff changeset
5396 // null terminate the end of the string
Ritor1
parents:
diff changeset
5397 *pszDestEnd = '\0';
Ritor1
parents:
diff changeset
5398 }
Ritor1
parents:
diff changeset
5399 }
Ritor1
parents:
diff changeset
5400
Ritor1
parents:
diff changeset
5401 if (dwFlags & (STRSAFE_NULL_ON_FAILURE))
Ritor1
parents:
diff changeset
5402 {
Ritor1
parents:
diff changeset
5403 if (cchDest > 0)
Ritor1
parents:
diff changeset
5404 {
Ritor1
parents:
diff changeset
5405 pszDestEnd = pszDest;
Ritor1
parents:
diff changeset
5406 cchRemaining = cchDest;
Ritor1
parents:
diff changeset
5407
Ritor1
parents:
diff changeset
5408 // null terminate the beginning of the string
Ritor1
parents:
diff changeset
5409 *pszDestEnd = '\0';
Ritor1
parents:
diff changeset
5410 }
Ritor1
parents:
diff changeset
5411 }
Ritor1
parents:
diff changeset
5412 }
Ritor1
parents:
diff changeset
5413 }
Ritor1
parents:
diff changeset
5414
Ritor1
parents:
diff changeset
5415 if (SUCCEEDED(hr) || (hr == STRSAFE_E_INSUFFICIENT_BUFFER))
Ritor1
parents:
diff changeset
5416 {
Ritor1
parents:
diff changeset
5417 if (ppszDestEnd)
Ritor1
parents:
diff changeset
5418 {
Ritor1
parents:
diff changeset
5419 *ppszDestEnd = pszDestEnd;
Ritor1
parents:
diff changeset
5420 }
Ritor1
parents:
diff changeset
5421
Ritor1
parents:
diff changeset
5422 if (pcchRemaining)
Ritor1
parents:
diff changeset
5423 {
Ritor1
parents:
diff changeset
5424 *pcchRemaining = cchRemaining;
Ritor1
parents:
diff changeset
5425 }
Ritor1
parents:
diff changeset
5426 }
Ritor1
parents:
diff changeset
5427
Ritor1
parents:
diff changeset
5428 return hr;
Ritor1
parents:
diff changeset
5429 }
Ritor1
parents:
diff changeset
5430
Ritor1
parents:
diff changeset
5431 STRSAFEAPI StringCatNExWorkerW(wchar_t* pszDest, size_t cchDest, size_t cbDest, const wchar_t* pszSrc, size_t cchMaxAppend, wchar_t** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags)
Ritor1
parents:
diff changeset
5432 {
Ritor1
parents:
diff changeset
5433 HRESULT hr = S_OK;
Ritor1
parents:
diff changeset
5434 wchar_t* pszDestEnd = pszDest;
Ritor1
parents:
diff changeset
5435 size_t cchRemaining = 0;
Ritor1
parents:
diff changeset
5436 size_t cchDestCurrent = 0;
Ritor1
parents:
diff changeset
5437
Ritor1
parents:
diff changeset
5438
Ritor1
parents:
diff changeset
5439 // ASSERT(cbDest == (cchDest * sizeof(wchar_t)) ||
Ritor1
parents:
diff changeset
5440 // cbDest == (cchDest * sizeof(wchar_t)) + (cbDest % sizeof(wchar_t)));
Ritor1
parents:
diff changeset
5441
Ritor1
parents:
diff changeset
5442 // only accept valid flags
Ritor1
parents:
diff changeset
5443 if (dwFlags & (~STRSAFE_VALID_FLAGS))
Ritor1
parents:
diff changeset
5444 {
Ritor1
parents:
diff changeset
5445 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
5446 }
Ritor1
parents:
diff changeset
5447 else
Ritor1
parents:
diff changeset
5448 {
Ritor1
parents:
diff changeset
5449 if (dwFlags & STRSAFE_IGNORE_NULLS)
Ritor1
parents:
diff changeset
5450 {
Ritor1
parents:
diff changeset
5451 if (pszDest == NULL)
Ritor1
parents:
diff changeset
5452 {
Ritor1
parents:
diff changeset
5453 if ((cchDest == 0) && (cbDest == 0))
Ritor1
parents:
diff changeset
5454 {
Ritor1
parents:
diff changeset
5455 cchDestCurrent = 0;
Ritor1
parents:
diff changeset
5456 }
Ritor1
parents:
diff changeset
5457 else
Ritor1
parents:
diff changeset
5458 {
Ritor1
parents:
diff changeset
5459 // NULL pszDest and non-zero cchDest/cbDest is invalid
Ritor1
parents:
diff changeset
5460 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
5461 }
Ritor1
parents:
diff changeset
5462 }
Ritor1
parents:
diff changeset
5463 else
Ritor1
parents:
diff changeset
5464 {
Ritor1
parents:
diff changeset
5465 hr = StringLengthWorkerW(pszDest, cchDest, &cchDestCurrent);
Ritor1
parents:
diff changeset
5466
Ritor1
parents:
diff changeset
5467 if (SUCCEEDED(hr))
Ritor1
parents:
diff changeset
5468 {
Ritor1
parents:
diff changeset
5469 pszDestEnd = pszDest + cchDestCurrent;
Ritor1
parents:
diff changeset
5470 cchRemaining = cchDest - cchDestCurrent;
Ritor1
parents:
diff changeset
5471 }
Ritor1
parents:
diff changeset
5472 }
Ritor1
parents:
diff changeset
5473
Ritor1
parents:
diff changeset
5474 if (pszSrc == NULL)
Ritor1
parents:
diff changeset
5475 {
Ritor1
parents:
diff changeset
5476 pszSrc = L"";
Ritor1
parents:
diff changeset
5477 }
Ritor1
parents:
diff changeset
5478 }
Ritor1
parents:
diff changeset
5479 else
Ritor1
parents:
diff changeset
5480 {
Ritor1
parents:
diff changeset
5481 hr = StringLengthWorkerW(pszDest, cchDest, &cchDestCurrent);
Ritor1
parents:
diff changeset
5482
Ritor1
parents:
diff changeset
5483 if (SUCCEEDED(hr))
Ritor1
parents:
diff changeset
5484 {
Ritor1
parents:
diff changeset
5485 pszDestEnd = pszDest + cchDestCurrent;
Ritor1
parents:
diff changeset
5486 cchRemaining = cchDest - cchDestCurrent;
Ritor1
parents:
diff changeset
5487 }
Ritor1
parents:
diff changeset
5488 }
Ritor1
parents:
diff changeset
5489
Ritor1
parents:
diff changeset
5490 if (SUCCEEDED(hr))
Ritor1
parents:
diff changeset
5491 {
Ritor1
parents:
diff changeset
5492 if (cchDest == 0)
Ritor1
parents:
diff changeset
5493 {
Ritor1
parents:
diff changeset
5494 // only fail if there was actually src data to append
Ritor1
parents:
diff changeset
5495 if (*pszSrc != L'\0')
Ritor1
parents:
diff changeset
5496 {
Ritor1
parents:
diff changeset
5497 if (pszDest == NULL)
Ritor1
parents:
diff changeset
5498 {
Ritor1
parents:
diff changeset
5499 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
5500 }
Ritor1
parents:
diff changeset
5501 else
Ritor1
parents:
diff changeset
5502 {
Ritor1
parents:
diff changeset
5503 hr = STRSAFE_E_INSUFFICIENT_BUFFER;
Ritor1
parents:
diff changeset
5504 }
Ritor1
parents:
diff changeset
5505 }
Ritor1
parents:
diff changeset
5506 }
Ritor1
parents:
diff changeset
5507 else
Ritor1
parents:
diff changeset
5508 {
Ritor1
parents:
diff changeset
5509 // we handle the STRSAFE_FILL_ON_FAILURE and STRSAFE_NULL_ON_FAILURE cases below, so do not pass
Ritor1
parents:
diff changeset
5510 // those flags through
Ritor1
parents:
diff changeset
5511 hr = StringCopyNExWorkerW(pszDestEnd,
Ritor1
parents:
diff changeset
5512 cchRemaining,
Ritor1
parents:
diff changeset
5513 (cchRemaining * sizeof(wchar_t)) + (cbDest % sizeof(wchar_t)),
Ritor1
parents:
diff changeset
5514 pszSrc,
Ritor1
parents:
diff changeset
5515 cchMaxAppend,
Ritor1
parents:
diff changeset
5516 &pszDestEnd,
Ritor1
parents:
diff changeset
5517 &cchRemaining,
Ritor1
parents:
diff changeset
5518 dwFlags & (~(STRSAFE_FILL_ON_FAILURE | STRSAFE_NULL_ON_FAILURE)));
Ritor1
parents:
diff changeset
5519 }
Ritor1
parents:
diff changeset
5520 }
Ritor1
parents:
diff changeset
5521 }
Ritor1
parents:
diff changeset
5522
Ritor1
parents:
diff changeset
5523 if (FAILED(hr))
Ritor1
parents:
diff changeset
5524 {
Ritor1
parents:
diff changeset
5525 if (pszDest)
Ritor1
parents:
diff changeset
5526 {
Ritor1
parents:
diff changeset
5527 // STRSAFE_NO_TRUNCATION is taken care of by StringCopyNExWorkerW()
Ritor1
parents:
diff changeset
5528
Ritor1
parents:
diff changeset
5529 if (dwFlags & STRSAFE_FILL_ON_FAILURE)
Ritor1
parents:
diff changeset
5530 {
Ritor1
parents:
diff changeset
5531 memset(pszDest, STRSAFE_GET_FILL_PATTERN(dwFlags), cbDest);
Ritor1
parents:
diff changeset
5532
Ritor1
parents:
diff changeset
5533 if (STRSAFE_GET_FILL_PATTERN(dwFlags) == 0)
Ritor1
parents:
diff changeset
5534 {
Ritor1
parents:
diff changeset
5535 pszDestEnd = pszDest;
Ritor1
parents:
diff changeset
5536 cchRemaining = cchDest;
Ritor1
parents:
diff changeset
5537 }
Ritor1
parents:
diff changeset
5538 else if (cchDest > 0)
Ritor1
parents:
diff changeset
5539 {
Ritor1
parents:
diff changeset
5540 pszDestEnd = pszDest + cchDest - 1;
Ritor1
parents:
diff changeset
5541 cchRemaining = 1;
Ritor1
parents:
diff changeset
5542
Ritor1
parents:
diff changeset
5543 // null terminate the end of the string
Ritor1
parents:
diff changeset
5544 *pszDestEnd = L'\0';
Ritor1
parents:
diff changeset
5545 }
Ritor1
parents:
diff changeset
5546 }
Ritor1
parents:
diff changeset
5547
Ritor1
parents:
diff changeset
5548 if (dwFlags & (STRSAFE_NULL_ON_FAILURE))
Ritor1
parents:
diff changeset
5549 {
Ritor1
parents:
diff changeset
5550 if (cchDest > 0)
Ritor1
parents:
diff changeset
5551 {
Ritor1
parents:
diff changeset
5552 pszDestEnd = pszDest;
Ritor1
parents:
diff changeset
5553 cchRemaining = cchDest;
Ritor1
parents:
diff changeset
5554
Ritor1
parents:
diff changeset
5555 // null terminate the beginning of the string
Ritor1
parents:
diff changeset
5556 *pszDestEnd = L'\0';
Ritor1
parents:
diff changeset
5557 }
Ritor1
parents:
diff changeset
5558 }
Ritor1
parents:
diff changeset
5559 }
Ritor1
parents:
diff changeset
5560 }
Ritor1
parents:
diff changeset
5561
Ritor1
parents:
diff changeset
5562 if (SUCCEEDED(hr) || (hr == STRSAFE_E_INSUFFICIENT_BUFFER))
Ritor1
parents:
diff changeset
5563 {
Ritor1
parents:
diff changeset
5564 if (ppszDestEnd)
Ritor1
parents:
diff changeset
5565 {
Ritor1
parents:
diff changeset
5566 *ppszDestEnd = pszDestEnd;
Ritor1
parents:
diff changeset
5567 }
Ritor1
parents:
diff changeset
5568
Ritor1
parents:
diff changeset
5569 if (pcchRemaining)
Ritor1
parents:
diff changeset
5570 {
Ritor1
parents:
diff changeset
5571 *pcchRemaining = cchRemaining;
Ritor1
parents:
diff changeset
5572 }
Ritor1
parents:
diff changeset
5573 }
Ritor1
parents:
diff changeset
5574
Ritor1
parents:
diff changeset
5575 return hr;
Ritor1
parents:
diff changeset
5576 }
Ritor1
parents:
diff changeset
5577
Ritor1
parents:
diff changeset
5578 STRSAFEAPI StringVPrintfWorkerA(char* pszDest, size_t cchDest, const char* pszFormat, va_list argList)
Ritor1
parents:
diff changeset
5579 {
Ritor1
parents:
diff changeset
5580 HRESULT hr = S_OK;
Ritor1
parents:
diff changeset
5581
Ritor1
parents:
diff changeset
5582 if (cchDest == 0)
Ritor1
parents:
diff changeset
5583 {
Ritor1
parents:
diff changeset
5584 // can not null terminate a zero-byte dest buffer
Ritor1
parents:
diff changeset
5585 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
5586 }
Ritor1
parents:
diff changeset
5587 else
Ritor1
parents:
diff changeset
5588 {
Ritor1
parents:
diff changeset
5589 int iRet;
Ritor1
parents:
diff changeset
5590 size_t cchMax;
Ritor1
parents:
diff changeset
5591
Ritor1
parents:
diff changeset
5592 // leave the last space for the null terminator
Ritor1
parents:
diff changeset
5593 cchMax = cchDest - 1;
Ritor1
parents:
diff changeset
5594
Ritor1
parents:
diff changeset
5595 iRet = _vsnprintf(pszDest, cchMax, pszFormat, argList);
Ritor1
parents:
diff changeset
5596 // ASSERT((iRet < 0) || (((size_t)iRet) <= cchMax));
Ritor1
parents:
diff changeset
5597
Ritor1
parents:
diff changeset
5598 if ((iRet < 0) || (((size_t)iRet) > cchMax))
Ritor1
parents:
diff changeset
5599 {
Ritor1
parents:
diff changeset
5600 // need to null terminate the string
Ritor1
parents:
diff changeset
5601 pszDest += cchMax;
Ritor1
parents:
diff changeset
5602 *pszDest = '\0';
Ritor1
parents:
diff changeset
5603
Ritor1
parents:
diff changeset
5604 // we have truncated pszDest
Ritor1
parents:
diff changeset
5605 hr = STRSAFE_E_INSUFFICIENT_BUFFER;
Ritor1
parents:
diff changeset
5606 }
Ritor1
parents:
diff changeset
5607 else if (((size_t)iRet) == cchMax)
Ritor1
parents:
diff changeset
5608 {
Ritor1
parents:
diff changeset
5609 // need to null terminate the string
Ritor1
parents:
diff changeset
5610 pszDest += cchMax;
Ritor1
parents:
diff changeset
5611 *pszDest = '\0';
Ritor1
parents:
diff changeset
5612 }
Ritor1
parents:
diff changeset
5613 }
Ritor1
parents:
diff changeset
5614
Ritor1
parents:
diff changeset
5615 return hr;
Ritor1
parents:
diff changeset
5616 }
Ritor1
parents:
diff changeset
5617
Ritor1
parents:
diff changeset
5618 STRSAFEAPI StringVPrintfWorkerW(wchar_t* pszDest, size_t cchDest, const wchar_t* pszFormat, va_list argList)
Ritor1
parents:
diff changeset
5619 {
Ritor1
parents:
diff changeset
5620 HRESULT hr = S_OK;
Ritor1
parents:
diff changeset
5621
Ritor1
parents:
diff changeset
5622 if (cchDest == 0)
Ritor1
parents:
diff changeset
5623 {
Ritor1
parents:
diff changeset
5624 // can not null terminate a zero-byte dest buffer
Ritor1
parents:
diff changeset
5625 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
5626 }
Ritor1
parents:
diff changeset
5627 else
Ritor1
parents:
diff changeset
5628 {
Ritor1
parents:
diff changeset
5629 int iRet;
Ritor1
parents:
diff changeset
5630 size_t cchMax;
Ritor1
parents:
diff changeset
5631
Ritor1
parents:
diff changeset
5632 // leave the last space for the null terminator
Ritor1
parents:
diff changeset
5633 cchMax = cchDest - 1;
Ritor1
parents:
diff changeset
5634
Ritor1
parents:
diff changeset
5635 iRet = _vsnwprintf(pszDest, cchMax, pszFormat, argList);
Ritor1
parents:
diff changeset
5636 // ASSERT((iRet < 0) || (((size_t)iRet) <= cchMax));
Ritor1
parents:
diff changeset
5637
Ritor1
parents:
diff changeset
5638 if ((iRet < 0) || (((size_t)iRet) > cchMax))
Ritor1
parents:
diff changeset
5639 {
Ritor1
parents:
diff changeset
5640 // need to null terminate the string
Ritor1
parents:
diff changeset
5641 pszDest += cchMax;
Ritor1
parents:
diff changeset
5642 *pszDest = L'\0';
Ritor1
parents:
diff changeset
5643
Ritor1
parents:
diff changeset
5644 // we have truncated pszDest
Ritor1
parents:
diff changeset
5645 hr = STRSAFE_E_INSUFFICIENT_BUFFER;
Ritor1
parents:
diff changeset
5646 }
Ritor1
parents:
diff changeset
5647 else if (((size_t)iRet) == cchMax)
Ritor1
parents:
diff changeset
5648 {
Ritor1
parents:
diff changeset
5649 // need to null terminate the string
Ritor1
parents:
diff changeset
5650 pszDest += cchMax;
Ritor1
parents:
diff changeset
5651 *pszDest = L'\0';
Ritor1
parents:
diff changeset
5652 }
Ritor1
parents:
diff changeset
5653 }
Ritor1
parents:
diff changeset
5654
Ritor1
parents:
diff changeset
5655 return hr;
Ritor1
parents:
diff changeset
5656 }
Ritor1
parents:
diff changeset
5657
Ritor1
parents:
diff changeset
5658 STRSAFEAPI StringVPrintfExWorkerA(char* pszDest, size_t cchDest, size_t cbDest, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags, const char* pszFormat, va_list argList)
Ritor1
parents:
diff changeset
5659 {
Ritor1
parents:
diff changeset
5660 HRESULT hr = S_OK;
Ritor1
parents:
diff changeset
5661 char* pszDestEnd = pszDest;
Ritor1
parents:
diff changeset
5662 size_t cchRemaining = 0;
Ritor1
parents:
diff changeset
5663
Ritor1
parents:
diff changeset
5664 // ASSERT(cbDest == (cchDest * sizeof(char)) ||
Ritor1
parents:
diff changeset
5665 // cbDest == (cchDest * sizeof(char)) + (cbDest % sizeof(char)));
Ritor1
parents:
diff changeset
5666
Ritor1
parents:
diff changeset
5667 // only accept valid flags
Ritor1
parents:
diff changeset
5668 if (dwFlags & (~STRSAFE_VALID_FLAGS))
Ritor1
parents:
diff changeset
5669 {
Ritor1
parents:
diff changeset
5670 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
5671 }
Ritor1
parents:
diff changeset
5672 else
Ritor1
parents:
diff changeset
5673 {
Ritor1
parents:
diff changeset
5674 if (dwFlags & STRSAFE_IGNORE_NULLS)
Ritor1
parents:
diff changeset
5675 {
Ritor1
parents:
diff changeset
5676 if (pszDest == NULL)
Ritor1
parents:
diff changeset
5677 {
Ritor1
parents:
diff changeset
5678 if ((cchDest != 0) || (cbDest != 0))
Ritor1
parents:
diff changeset
5679 {
Ritor1
parents:
diff changeset
5680 // NULL pszDest and non-zero cchDest/cbDest is invalid
Ritor1
parents:
diff changeset
5681 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
5682 }
Ritor1
parents:
diff changeset
5683 }
Ritor1
parents:
diff changeset
5684
Ritor1
parents:
diff changeset
5685 if (pszFormat == NULL)
Ritor1
parents:
diff changeset
5686 {
Ritor1
parents:
diff changeset
5687 pszFormat = "";
Ritor1
parents:
diff changeset
5688 }
Ritor1
parents:
diff changeset
5689 }
Ritor1
parents:
diff changeset
5690
Ritor1
parents:
diff changeset
5691 if (SUCCEEDED(hr))
Ritor1
parents:
diff changeset
5692 {
Ritor1
parents:
diff changeset
5693 if (cchDest == 0)
Ritor1
parents:
diff changeset
5694 {
Ritor1
parents:
diff changeset
5695 pszDestEnd = pszDest;
Ritor1
parents:
diff changeset
5696 cchRemaining = 0;
Ritor1
parents:
diff changeset
5697
Ritor1
parents:
diff changeset
5698 // only fail if there was actually a non-empty format string
Ritor1
parents:
diff changeset
5699 if (*pszFormat != '\0')
Ritor1
parents:
diff changeset
5700 {
Ritor1
parents:
diff changeset
5701 if (pszDest == NULL)
Ritor1
parents:
diff changeset
5702 {
Ritor1
parents:
diff changeset
5703 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
5704 }
Ritor1
parents:
diff changeset
5705 else
Ritor1
parents:
diff changeset
5706 {
Ritor1
parents:
diff changeset
5707 hr = STRSAFE_E_INSUFFICIENT_BUFFER;
Ritor1
parents:
diff changeset
5708 }
Ritor1
parents:
diff changeset
5709 }
Ritor1
parents:
diff changeset
5710 }
Ritor1
parents:
diff changeset
5711 else
Ritor1
parents:
diff changeset
5712 {
Ritor1
parents:
diff changeset
5713 int iRet;
Ritor1
parents:
diff changeset
5714 size_t cchMax;
Ritor1
parents:
diff changeset
5715
Ritor1
parents:
diff changeset
5716 // leave the last space for the null terminator
Ritor1
parents:
diff changeset
5717 cchMax = cchDest - 1;
Ritor1
parents:
diff changeset
5718
Ritor1
parents:
diff changeset
5719 iRet = _vsnprintf(pszDest, cchMax, pszFormat, argList);
Ritor1
parents:
diff changeset
5720 // ASSERT((iRet < 0) || (((size_t)iRet) <= cchMax));
Ritor1
parents:
diff changeset
5721
Ritor1
parents:
diff changeset
5722 if ((iRet < 0) || (((size_t)iRet) > cchMax))
Ritor1
parents:
diff changeset
5723 {
Ritor1
parents:
diff changeset
5724 // we have truncated pszDest
Ritor1
parents:
diff changeset
5725 pszDestEnd = pszDest + cchMax;
Ritor1
parents:
diff changeset
5726 cchRemaining = 1;
Ritor1
parents:
diff changeset
5727
Ritor1
parents:
diff changeset
5728 // need to null terminate the string
Ritor1
parents:
diff changeset
5729 *pszDestEnd = '\0';
Ritor1
parents:
diff changeset
5730
Ritor1
parents:
diff changeset
5731 hr = STRSAFE_E_INSUFFICIENT_BUFFER;
Ritor1
parents:
diff changeset
5732 }
Ritor1
parents:
diff changeset
5733 else if (((size_t)iRet) == cchMax)
Ritor1
parents:
diff changeset
5734 {
Ritor1
parents:
diff changeset
5735 // string fit perfectly
Ritor1
parents:
diff changeset
5736 pszDestEnd = pszDest + cchMax;
Ritor1
parents:
diff changeset
5737 cchRemaining = 1;
Ritor1
parents:
diff changeset
5738
Ritor1
parents:
diff changeset
5739 // need to null terminate the string
Ritor1
parents:
diff changeset
5740 *pszDestEnd = '\0';
Ritor1
parents:
diff changeset
5741 }
Ritor1
parents:
diff changeset
5742 else if (((size_t)iRet) < cchMax)
Ritor1
parents:
diff changeset
5743 {
Ritor1
parents:
diff changeset
5744 // there is extra room
Ritor1
parents:
diff changeset
5745 pszDestEnd = pszDest + iRet;
Ritor1
parents:
diff changeset
5746 cchRemaining = cchDest - iRet;
Ritor1
parents:
diff changeset
5747
Ritor1
parents:
diff changeset
5748 if (dwFlags & STRSAFE_FILL_BEHIND_NULL)
Ritor1
parents:
diff changeset
5749 {
Ritor1
parents:
diff changeset
5750 memset(pszDestEnd + 1, STRSAFE_GET_FILL_PATTERN(dwFlags), ((cchRemaining - 1) * sizeof(char)) + (cbDest % sizeof(char)));
Ritor1
parents:
diff changeset
5751 }
Ritor1
parents:
diff changeset
5752 }
Ritor1
parents:
diff changeset
5753 }
Ritor1
parents:
diff changeset
5754 }
Ritor1
parents:
diff changeset
5755 }
Ritor1
parents:
diff changeset
5756
Ritor1
parents:
diff changeset
5757 if (FAILED(hr))
Ritor1
parents:
diff changeset
5758 {
Ritor1
parents:
diff changeset
5759 if (pszDest)
Ritor1
parents:
diff changeset
5760 {
Ritor1
parents:
diff changeset
5761 if (dwFlags & STRSAFE_FILL_ON_FAILURE)
Ritor1
parents:
diff changeset
5762 {
Ritor1
parents:
diff changeset
5763 memset(pszDest, STRSAFE_GET_FILL_PATTERN(dwFlags), cbDest);
Ritor1
parents:
diff changeset
5764
Ritor1
parents:
diff changeset
5765 if (STRSAFE_GET_FILL_PATTERN(dwFlags) == 0)
Ritor1
parents:
diff changeset
5766 {
Ritor1
parents:
diff changeset
5767 pszDestEnd = pszDest;
Ritor1
parents:
diff changeset
5768 cchRemaining = cchDest;
Ritor1
parents:
diff changeset
5769 }
Ritor1
parents:
diff changeset
5770 else if (cchDest > 0)
Ritor1
parents:
diff changeset
5771 {
Ritor1
parents:
diff changeset
5772 pszDestEnd = pszDest + cchDest - 1;
Ritor1
parents:
diff changeset
5773 cchRemaining = 1;
Ritor1
parents:
diff changeset
5774
Ritor1
parents:
diff changeset
5775 // null terminate the end of the string
Ritor1
parents:
diff changeset
5776 *pszDestEnd = '\0';
Ritor1
parents:
diff changeset
5777 }
Ritor1
parents:
diff changeset
5778 }
Ritor1
parents:
diff changeset
5779
Ritor1
parents:
diff changeset
5780 if (dwFlags & (STRSAFE_NULL_ON_FAILURE | STRSAFE_NO_TRUNCATION))
Ritor1
parents:
diff changeset
5781 {
Ritor1
parents:
diff changeset
5782 if (cchDest > 0)
Ritor1
parents:
diff changeset
5783 {
Ritor1
parents:
diff changeset
5784 pszDestEnd = pszDest;
Ritor1
parents:
diff changeset
5785 cchRemaining = cchDest;
Ritor1
parents:
diff changeset
5786
Ritor1
parents:
diff changeset
5787 // null terminate the beginning of the string
Ritor1
parents:
diff changeset
5788 *pszDestEnd = '\0';
Ritor1
parents:
diff changeset
5789 }
Ritor1
parents:
diff changeset
5790 }
Ritor1
parents:
diff changeset
5791 }
Ritor1
parents:
diff changeset
5792 }
Ritor1
parents:
diff changeset
5793
Ritor1
parents:
diff changeset
5794 if (SUCCEEDED(hr) || (hr == STRSAFE_E_INSUFFICIENT_BUFFER))
Ritor1
parents:
diff changeset
5795 {
Ritor1
parents:
diff changeset
5796 if (ppszDestEnd)
Ritor1
parents:
diff changeset
5797 {
Ritor1
parents:
diff changeset
5798 *ppszDestEnd = pszDestEnd;
Ritor1
parents:
diff changeset
5799 }
Ritor1
parents:
diff changeset
5800
Ritor1
parents:
diff changeset
5801 if (pcchRemaining)
Ritor1
parents:
diff changeset
5802 {
Ritor1
parents:
diff changeset
5803 *pcchRemaining = cchRemaining;
Ritor1
parents:
diff changeset
5804 }
Ritor1
parents:
diff changeset
5805 }
Ritor1
parents:
diff changeset
5806
Ritor1
parents:
diff changeset
5807 return hr;
Ritor1
parents:
diff changeset
5808 }
Ritor1
parents:
diff changeset
5809
Ritor1
parents:
diff changeset
5810 STRSAFEAPI StringVPrintfExWorkerW(wchar_t* pszDest, size_t cchDest, size_t cbDest, wchar_t** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags, const wchar_t* pszFormat, va_list argList)
Ritor1
parents:
diff changeset
5811 {
Ritor1
parents:
diff changeset
5812 HRESULT hr = S_OK;
Ritor1
parents:
diff changeset
5813 wchar_t* pszDestEnd = pszDest;
Ritor1
parents:
diff changeset
5814 size_t cchRemaining = 0;
Ritor1
parents:
diff changeset
5815
Ritor1
parents:
diff changeset
5816 // ASSERT(cbDest == (cchDest * sizeof(wchar_t)) ||
Ritor1
parents:
diff changeset
5817 // cbDest == (cchDest * sizeof(wchar_t)) + (cbDest % sizeof(wchar_t)));
Ritor1
parents:
diff changeset
5818
Ritor1
parents:
diff changeset
5819 // only accept valid flags
Ritor1
parents:
diff changeset
5820 if (dwFlags & (~STRSAFE_VALID_FLAGS))
Ritor1
parents:
diff changeset
5821 {
Ritor1
parents:
diff changeset
5822 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
5823 }
Ritor1
parents:
diff changeset
5824 else
Ritor1
parents:
diff changeset
5825 {
Ritor1
parents:
diff changeset
5826 if (dwFlags & STRSAFE_IGNORE_NULLS)
Ritor1
parents:
diff changeset
5827 {
Ritor1
parents:
diff changeset
5828 if (pszDest == NULL)
Ritor1
parents:
diff changeset
5829 {
Ritor1
parents:
diff changeset
5830 if ((cchDest != 0) || (cbDest != 0))
Ritor1
parents:
diff changeset
5831 {
Ritor1
parents:
diff changeset
5832 // NULL pszDest and non-zero cchDest/cbDest is invalid
Ritor1
parents:
diff changeset
5833 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
5834 }
Ritor1
parents:
diff changeset
5835 }
Ritor1
parents:
diff changeset
5836
Ritor1
parents:
diff changeset
5837 if (pszFormat == NULL)
Ritor1
parents:
diff changeset
5838 {
Ritor1
parents:
diff changeset
5839 pszFormat = L"";
Ritor1
parents:
diff changeset
5840 }
Ritor1
parents:
diff changeset
5841 }
Ritor1
parents:
diff changeset
5842
Ritor1
parents:
diff changeset
5843 if (SUCCEEDED(hr))
Ritor1
parents:
diff changeset
5844 {
Ritor1
parents:
diff changeset
5845 if (cchDest == 0)
Ritor1
parents:
diff changeset
5846 {
Ritor1
parents:
diff changeset
5847 pszDestEnd = pszDest;
Ritor1
parents:
diff changeset
5848 cchRemaining = 0;
Ritor1
parents:
diff changeset
5849
Ritor1
parents:
diff changeset
5850 // only fail if there was actually a non-empty format string
Ritor1
parents:
diff changeset
5851 if (*pszFormat != L'\0')
Ritor1
parents:
diff changeset
5852 {
Ritor1
parents:
diff changeset
5853 if (pszDest == NULL)
Ritor1
parents:
diff changeset
5854 {
Ritor1
parents:
diff changeset
5855 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
5856 }
Ritor1
parents:
diff changeset
5857 else
Ritor1
parents:
diff changeset
5858 {
Ritor1
parents:
diff changeset
5859 hr = STRSAFE_E_INSUFFICIENT_BUFFER;
Ritor1
parents:
diff changeset
5860 }
Ritor1
parents:
diff changeset
5861 }
Ritor1
parents:
diff changeset
5862 }
Ritor1
parents:
diff changeset
5863 else
Ritor1
parents:
diff changeset
5864 {
Ritor1
parents:
diff changeset
5865 int iRet;
Ritor1
parents:
diff changeset
5866 size_t cchMax;
Ritor1
parents:
diff changeset
5867
Ritor1
parents:
diff changeset
5868 // leave the last space for the null terminator
Ritor1
parents:
diff changeset
5869 cchMax = cchDest - 1;
Ritor1
parents:
diff changeset
5870
Ritor1
parents:
diff changeset
5871 iRet = _vsnwprintf(pszDest, cchMax, pszFormat, argList);
Ritor1
parents:
diff changeset
5872 // ASSERT((iRet < 0) || (((size_t)iRet) <= cchMax));
Ritor1
parents:
diff changeset
5873
Ritor1
parents:
diff changeset
5874 if ((iRet < 0) || (((size_t)iRet) > cchMax))
Ritor1
parents:
diff changeset
5875 {
Ritor1
parents:
diff changeset
5876 // we have truncated pszDest
Ritor1
parents:
diff changeset
5877 pszDestEnd = pszDest + cchMax;
Ritor1
parents:
diff changeset
5878 cchRemaining = 1;
Ritor1
parents:
diff changeset
5879
Ritor1
parents:
diff changeset
5880 // need to null terminate the string
Ritor1
parents:
diff changeset
5881 *pszDestEnd = L'\0';
Ritor1
parents:
diff changeset
5882
Ritor1
parents:
diff changeset
5883 hr = STRSAFE_E_INSUFFICIENT_BUFFER;
Ritor1
parents:
diff changeset
5884 }
Ritor1
parents:
diff changeset
5885 else if (((size_t)iRet) == cchMax)
Ritor1
parents:
diff changeset
5886 {
Ritor1
parents:
diff changeset
5887 // string fit perfectly
Ritor1
parents:
diff changeset
5888 pszDestEnd = pszDest + cchMax;
Ritor1
parents:
diff changeset
5889 cchRemaining = 1;
Ritor1
parents:
diff changeset
5890
Ritor1
parents:
diff changeset
5891 // need to null terminate the string
Ritor1
parents:
diff changeset
5892 *pszDestEnd = L'\0';
Ritor1
parents:
diff changeset
5893 }
Ritor1
parents:
diff changeset
5894 else if (((size_t)iRet) < cchMax)
Ritor1
parents:
diff changeset
5895 {
Ritor1
parents:
diff changeset
5896 // there is extra room
Ritor1
parents:
diff changeset
5897 pszDestEnd = pszDest + iRet;
Ritor1
parents:
diff changeset
5898 cchRemaining = cchDest - iRet;
Ritor1
parents:
diff changeset
5899
Ritor1
parents:
diff changeset
5900 if (dwFlags & STRSAFE_FILL_BEHIND_NULL)
Ritor1
parents:
diff changeset
5901 {
Ritor1
parents:
diff changeset
5902 memset(pszDestEnd + 1, STRSAFE_GET_FILL_PATTERN(dwFlags), ((cchRemaining - 1) * sizeof(wchar_t)) + (cbDest % sizeof(wchar_t)));
Ritor1
parents:
diff changeset
5903 }
Ritor1
parents:
diff changeset
5904 }
Ritor1
parents:
diff changeset
5905 }
Ritor1
parents:
diff changeset
5906 }
Ritor1
parents:
diff changeset
5907 }
Ritor1
parents:
diff changeset
5908
Ritor1
parents:
diff changeset
5909 if (FAILED(hr))
Ritor1
parents:
diff changeset
5910 {
Ritor1
parents:
diff changeset
5911 if (pszDest)
Ritor1
parents:
diff changeset
5912 {
Ritor1
parents:
diff changeset
5913 if (dwFlags & STRSAFE_FILL_ON_FAILURE)
Ritor1
parents:
diff changeset
5914 {
Ritor1
parents:
diff changeset
5915 memset(pszDest, STRSAFE_GET_FILL_PATTERN(dwFlags), cbDest);
Ritor1
parents:
diff changeset
5916
Ritor1
parents:
diff changeset
5917 if (STRSAFE_GET_FILL_PATTERN(dwFlags) == 0)
Ritor1
parents:
diff changeset
5918 {
Ritor1
parents:
diff changeset
5919 pszDestEnd = pszDest;
Ritor1
parents:
diff changeset
5920 cchRemaining = cchDest;
Ritor1
parents:
diff changeset
5921 }
Ritor1
parents:
diff changeset
5922 else if (cchDest > 0)
Ritor1
parents:
diff changeset
5923 {
Ritor1
parents:
diff changeset
5924 pszDestEnd = pszDest + cchDest - 1;
Ritor1
parents:
diff changeset
5925 cchRemaining = 1;
Ritor1
parents:
diff changeset
5926
Ritor1
parents:
diff changeset
5927 // null terminate the end of the string
Ritor1
parents:
diff changeset
5928 *pszDestEnd = L'\0';
Ritor1
parents:
diff changeset
5929 }
Ritor1
parents:
diff changeset
5930 }
Ritor1
parents:
diff changeset
5931
Ritor1
parents:
diff changeset
5932 if (dwFlags & (STRSAFE_NULL_ON_FAILURE | STRSAFE_NO_TRUNCATION))
Ritor1
parents:
diff changeset
5933 {
Ritor1
parents:
diff changeset
5934 if (cchDest > 0)
Ritor1
parents:
diff changeset
5935 {
Ritor1
parents:
diff changeset
5936 pszDestEnd = pszDest;
Ritor1
parents:
diff changeset
5937 cchRemaining = cchDest;
Ritor1
parents:
diff changeset
5938
Ritor1
parents:
diff changeset
5939 // null terminate the beginning of the string
Ritor1
parents:
diff changeset
5940 *pszDestEnd = L'\0';
Ritor1
parents:
diff changeset
5941 }
Ritor1
parents:
diff changeset
5942 }
Ritor1
parents:
diff changeset
5943 }
Ritor1
parents:
diff changeset
5944 }
Ritor1
parents:
diff changeset
5945
Ritor1
parents:
diff changeset
5946 if (SUCCEEDED(hr) || (hr == STRSAFE_E_INSUFFICIENT_BUFFER))
Ritor1
parents:
diff changeset
5947 {
Ritor1
parents:
diff changeset
5948 if (ppszDestEnd)
Ritor1
parents:
diff changeset
5949 {
Ritor1
parents:
diff changeset
5950 *ppszDestEnd = pszDestEnd;
Ritor1
parents:
diff changeset
5951 }
Ritor1
parents:
diff changeset
5952
Ritor1
parents:
diff changeset
5953 if (pcchRemaining)
Ritor1
parents:
diff changeset
5954 {
Ritor1
parents:
diff changeset
5955 *pcchRemaining = cchRemaining;
Ritor1
parents:
diff changeset
5956 }
Ritor1
parents:
diff changeset
5957 }
Ritor1
parents:
diff changeset
5958
Ritor1
parents:
diff changeset
5959 return hr;
Ritor1
parents:
diff changeset
5960 }
Ritor1
parents:
diff changeset
5961
Ritor1
parents:
diff changeset
5962 STRSAFEAPI StringLengthWorkerA(const char* psz, size_t cchMax, size_t* pcch)
Ritor1
parents:
diff changeset
5963 {
Ritor1
parents:
diff changeset
5964 HRESULT hr = S_OK;
Ritor1
parents:
diff changeset
5965 size_t cchMaxPrev = cchMax;
Ritor1
parents:
diff changeset
5966
Ritor1
parents:
diff changeset
5967 while (cchMax && (*psz != '\0'))
Ritor1
parents:
diff changeset
5968 {
Ritor1
parents:
diff changeset
5969 psz++;
Ritor1
parents:
diff changeset
5970 cchMax--;
Ritor1
parents:
diff changeset
5971 }
Ritor1
parents:
diff changeset
5972
Ritor1
parents:
diff changeset
5973 if (cchMax == 0)
Ritor1
parents:
diff changeset
5974 {
Ritor1
parents:
diff changeset
5975 // the string is longer than cchMax
Ritor1
parents:
diff changeset
5976 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
5977 }
Ritor1
parents:
diff changeset
5978
Ritor1
parents:
diff changeset
5979 if (SUCCEEDED(hr) && pcch)
Ritor1
parents:
diff changeset
5980 {
Ritor1
parents:
diff changeset
5981 *pcch = cchMaxPrev - cchMax;
Ritor1
parents:
diff changeset
5982 }
Ritor1
parents:
diff changeset
5983
Ritor1
parents:
diff changeset
5984 return hr;
Ritor1
parents:
diff changeset
5985 }
Ritor1
parents:
diff changeset
5986
Ritor1
parents:
diff changeset
5987 STRSAFEAPI StringLengthWorkerW(const wchar_t* psz, size_t cchMax, size_t* pcch)
Ritor1
parents:
diff changeset
5988 {
Ritor1
parents:
diff changeset
5989 HRESULT hr = S_OK;
Ritor1
parents:
diff changeset
5990 size_t cchMaxPrev = cchMax;
Ritor1
parents:
diff changeset
5991
Ritor1
parents:
diff changeset
5992 while (cchMax && (*psz != L'\0'))
Ritor1
parents:
diff changeset
5993 {
Ritor1
parents:
diff changeset
5994 psz++;
Ritor1
parents:
diff changeset
5995 cchMax--;
Ritor1
parents:
diff changeset
5996 }
Ritor1
parents:
diff changeset
5997
Ritor1
parents:
diff changeset
5998 if (cchMax == 0)
Ritor1
parents:
diff changeset
5999 {
Ritor1
parents:
diff changeset
6000 // the string is longer than cchMax
Ritor1
parents:
diff changeset
6001 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
6002 }
Ritor1
parents:
diff changeset
6003
Ritor1
parents:
diff changeset
6004 if (SUCCEEDED(hr) && pcch)
Ritor1
parents:
diff changeset
6005 {
Ritor1
parents:
diff changeset
6006 *pcch = cchMaxPrev - cchMax;
Ritor1
parents:
diff changeset
6007 }
Ritor1
parents:
diff changeset
6008
Ritor1
parents:
diff changeset
6009 return hr;
Ritor1
parents:
diff changeset
6010 }
Ritor1
parents:
diff changeset
6011 #endif // STRSAFE_INLINE
Ritor1
parents:
diff changeset
6012
Ritor1
parents:
diff changeset
6013 #ifndef STRSAFE_LIB_IMPL
Ritor1
parents:
diff changeset
6014 STRSAFE_INLINE_API StringGetsExWorkerA(char* pszDest, size_t cchDest, size_t cbDest, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags)
Ritor1
parents:
diff changeset
6015 {
Ritor1
parents:
diff changeset
6016 HRESULT hr = S_OK;
Ritor1
parents:
diff changeset
6017 char* pszDestEnd = pszDest;
Ritor1
parents:
diff changeset
6018 size_t cchRemaining = 0;
Ritor1
parents:
diff changeset
6019
Ritor1
parents:
diff changeset
6020 // ASSERT(cbDest == (cchDest * sizeof(char)) ||
Ritor1
parents:
diff changeset
6021 // cbDest == (cchDest * sizeof(char)) + (cbDest % sizeof(char)));
Ritor1
parents:
diff changeset
6022
Ritor1
parents:
diff changeset
6023 // only accept valid flags
Ritor1
parents:
diff changeset
6024 if (dwFlags & (~STRSAFE_VALID_FLAGS))
Ritor1
parents:
diff changeset
6025 {
Ritor1
parents:
diff changeset
6026 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
6027 }
Ritor1
parents:
diff changeset
6028 else
Ritor1
parents:
diff changeset
6029 {
Ritor1
parents:
diff changeset
6030 if (dwFlags & STRSAFE_IGNORE_NULLS)
Ritor1
parents:
diff changeset
6031 {
Ritor1
parents:
diff changeset
6032 if (pszDest == NULL)
Ritor1
parents:
diff changeset
6033 {
Ritor1
parents:
diff changeset
6034 if ((cchDest != 0) || (cbDest != 0))
Ritor1
parents:
diff changeset
6035 {
Ritor1
parents:
diff changeset
6036 // NULL pszDest and non-zero cchDest/cbDest is invalid
Ritor1
parents:
diff changeset
6037 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
6038 }
Ritor1
parents:
diff changeset
6039 }
Ritor1
parents:
diff changeset
6040 }
Ritor1
parents:
diff changeset
6041
Ritor1
parents:
diff changeset
6042 if (SUCCEEDED(hr))
Ritor1
parents:
diff changeset
6043 {
Ritor1
parents:
diff changeset
6044 if (cchDest <= 1)
Ritor1
parents:
diff changeset
6045 {
Ritor1
parents:
diff changeset
6046 pszDestEnd = pszDest;
Ritor1
parents:
diff changeset
6047 cchRemaining = cchDest;
Ritor1
parents:
diff changeset
6048
Ritor1
parents:
diff changeset
6049 if (cchDest == 1)
Ritor1
parents:
diff changeset
6050 {
Ritor1
parents:
diff changeset
6051 *pszDestEnd = '\0';
Ritor1
parents:
diff changeset
6052 }
Ritor1
parents:
diff changeset
6053
Ritor1
parents:
diff changeset
6054 hr = STRSAFE_E_INSUFFICIENT_BUFFER;
Ritor1
parents:
diff changeset
6055 }
Ritor1
parents:
diff changeset
6056 else
Ritor1
parents:
diff changeset
6057 {
Ritor1
parents:
diff changeset
6058 char ch;
Ritor1
parents:
diff changeset
6059
Ritor1
parents:
diff changeset
6060 pszDestEnd = pszDest;
Ritor1
parents:
diff changeset
6061 cchRemaining = cchDest;
Ritor1
parents:
diff changeset
6062
Ritor1
parents:
diff changeset
6063 while ((cchRemaining > 1) && (ch = (char)getc(stdin)) != '\n')
Ritor1
parents:
diff changeset
6064 {
Ritor1
parents:
diff changeset
6065 if (ch == EOF)
Ritor1
parents:
diff changeset
6066 {
Ritor1
parents:
diff changeset
6067 if (pszDestEnd == pszDest)
Ritor1
parents:
diff changeset
6068 {
Ritor1
parents:
diff changeset
6069 // we failed to read anything from stdin
Ritor1
parents:
diff changeset
6070 hr = STRSAFE_E_END_OF_FILE;
Ritor1
parents:
diff changeset
6071 }
Ritor1
parents:
diff changeset
6072 break;
Ritor1
parents:
diff changeset
6073 }
Ritor1
parents:
diff changeset
6074
Ritor1
parents:
diff changeset
6075 *pszDestEnd = ch;
Ritor1
parents:
diff changeset
6076
Ritor1
parents:
diff changeset
6077 pszDestEnd++;
Ritor1
parents:
diff changeset
6078 cchRemaining--;
Ritor1
parents:
diff changeset
6079 }
Ritor1
parents:
diff changeset
6080
Ritor1
parents:
diff changeset
6081 if (cchRemaining > 0)
Ritor1
parents:
diff changeset
6082 {
Ritor1
parents:
diff changeset
6083 // there is extra room
Ritor1
parents:
diff changeset
6084 if (dwFlags & STRSAFE_FILL_BEHIND_NULL)
Ritor1
parents:
diff changeset
6085 {
Ritor1
parents:
diff changeset
6086 memset(pszDestEnd + 1, STRSAFE_GET_FILL_PATTERN(dwFlags), ((cchRemaining - 1) * sizeof(char)) + (cbDest % sizeof(char)));
Ritor1
parents:
diff changeset
6087 }
Ritor1
parents:
diff changeset
6088 }
Ritor1
parents:
diff changeset
6089
Ritor1
parents:
diff changeset
6090 *pszDestEnd = '\0';
Ritor1
parents:
diff changeset
6091 }
Ritor1
parents:
diff changeset
6092 }
Ritor1
parents:
diff changeset
6093 }
Ritor1
parents:
diff changeset
6094
Ritor1
parents:
diff changeset
6095 if (FAILED(hr))
Ritor1
parents:
diff changeset
6096 {
Ritor1
parents:
diff changeset
6097 if (pszDest)
Ritor1
parents:
diff changeset
6098 {
Ritor1
parents:
diff changeset
6099 if (dwFlags & STRSAFE_FILL_ON_FAILURE)
Ritor1
parents:
diff changeset
6100 {
Ritor1
parents:
diff changeset
6101 memset(pszDest, STRSAFE_GET_FILL_PATTERN(dwFlags), cbDest);
Ritor1
parents:
diff changeset
6102
Ritor1
parents:
diff changeset
6103 if (STRSAFE_GET_FILL_PATTERN(dwFlags) == 0)
Ritor1
parents:
diff changeset
6104 {
Ritor1
parents:
diff changeset
6105 pszDestEnd = pszDest;
Ritor1
parents:
diff changeset
6106 cchRemaining = cchDest;
Ritor1
parents:
diff changeset
6107 }
Ritor1
parents:
diff changeset
6108 else if (cchDest > 0)
Ritor1
parents:
diff changeset
6109 {
Ritor1
parents:
diff changeset
6110 pszDestEnd = pszDest + cchDest - 1;
Ritor1
parents:
diff changeset
6111 cchRemaining = 1;
Ritor1
parents:
diff changeset
6112
Ritor1
parents:
diff changeset
6113 // null terminate the end of the string
Ritor1
parents:
diff changeset
6114 *pszDestEnd = '\0';
Ritor1
parents:
diff changeset
6115 }
Ritor1
parents:
diff changeset
6116 }
Ritor1
parents:
diff changeset
6117
Ritor1
parents:
diff changeset
6118 if (dwFlags & (STRSAFE_NULL_ON_FAILURE | STRSAFE_NO_TRUNCATION))
Ritor1
parents:
diff changeset
6119 {
Ritor1
parents:
diff changeset
6120 if (cchDest > 0)
Ritor1
parents:
diff changeset
6121 {
Ritor1
parents:
diff changeset
6122 pszDestEnd = pszDest;
Ritor1
parents:
diff changeset
6123 cchRemaining = cchDest;
Ritor1
parents:
diff changeset
6124
Ritor1
parents:
diff changeset
6125 // null terminate the beginning of the string
Ritor1
parents:
diff changeset
6126 *pszDestEnd = '\0';
Ritor1
parents:
diff changeset
6127 }
Ritor1
parents:
diff changeset
6128 }
Ritor1
parents:
diff changeset
6129 }
Ritor1
parents:
diff changeset
6130 }
Ritor1
parents:
diff changeset
6131
Ritor1
parents:
diff changeset
6132 if (SUCCEEDED(hr) ||
Ritor1
parents:
diff changeset
6133 (hr == STRSAFE_E_INSUFFICIENT_BUFFER) ||
Ritor1
parents:
diff changeset
6134 (hr == STRSAFE_E_END_OF_FILE))
Ritor1
parents:
diff changeset
6135 {
Ritor1
parents:
diff changeset
6136 if (ppszDestEnd)
Ritor1
parents:
diff changeset
6137 {
Ritor1
parents:
diff changeset
6138 *ppszDestEnd = pszDestEnd;
Ritor1
parents:
diff changeset
6139 }
Ritor1
parents:
diff changeset
6140
Ritor1
parents:
diff changeset
6141 if (pcchRemaining)
Ritor1
parents:
diff changeset
6142 {
Ritor1
parents:
diff changeset
6143 *pcchRemaining = cchRemaining;
Ritor1
parents:
diff changeset
6144 }
Ritor1
parents:
diff changeset
6145 }
Ritor1
parents:
diff changeset
6146
Ritor1
parents:
diff changeset
6147 return hr;
Ritor1
parents:
diff changeset
6148 }
Ritor1
parents:
diff changeset
6149
Ritor1
parents:
diff changeset
6150 STRSAFE_INLINE_API StringGetsExWorkerW(wchar_t* pszDest, size_t cchDest, size_t cbDest, wchar_t** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags)
Ritor1
parents:
diff changeset
6151 {
Ritor1
parents:
diff changeset
6152 HRESULT hr = S_OK;
Ritor1
parents:
diff changeset
6153 wchar_t* pszDestEnd = pszDest;
Ritor1
parents:
diff changeset
6154 size_t cchRemaining = 0;
Ritor1
parents:
diff changeset
6155
Ritor1
parents:
diff changeset
6156 // ASSERT(cbDest == (cchDest * sizeof(char)) ||
Ritor1
parents:
diff changeset
6157 // cbDest == (cchDest * sizeof(char)) + (cbDest % sizeof(char)));
Ritor1
parents:
diff changeset
6158
Ritor1
parents:
diff changeset
6159 // only accept valid flags
Ritor1
parents:
diff changeset
6160 if (dwFlags & (~STRSAFE_VALID_FLAGS))
Ritor1
parents:
diff changeset
6161 {
Ritor1
parents:
diff changeset
6162 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
6163 }
Ritor1
parents:
diff changeset
6164 else
Ritor1
parents:
diff changeset
6165 {
Ritor1
parents:
diff changeset
6166 if (dwFlags & STRSAFE_IGNORE_NULLS)
Ritor1
parents:
diff changeset
6167 {
Ritor1
parents:
diff changeset
6168 if (pszDest == NULL)
Ritor1
parents:
diff changeset
6169 {
Ritor1
parents:
diff changeset
6170 if ((cchDest != 0) || (cbDest != 0))
Ritor1
parents:
diff changeset
6171 {
Ritor1
parents:
diff changeset
6172 // NULL pszDest and non-zero cchDest/cbDest is invalid
Ritor1
parents:
diff changeset
6173 hr = STRSAFE_E_INVALID_PARAMETER;
Ritor1
parents:
diff changeset
6174 }
Ritor1
parents:
diff changeset
6175 }
Ritor1
parents:
diff changeset
6176 }
Ritor1
parents:
diff changeset
6177
Ritor1
parents:
diff changeset
6178 if (SUCCEEDED(hr))
Ritor1
parents:
diff changeset
6179 {
Ritor1
parents:
diff changeset
6180 if (cchDest <= 1)
Ritor1
parents:
diff changeset
6181 {
Ritor1
parents:
diff changeset
6182 pszDestEnd = pszDest;
Ritor1
parents:
diff changeset
6183 cchRemaining = cchDest;
Ritor1
parents:
diff changeset
6184
Ritor1
parents:
diff changeset
6185 if (cchDest == 1)
Ritor1
parents:
diff changeset
6186 {
Ritor1
parents:
diff changeset
6187 *pszDestEnd = L'\0';
Ritor1
parents:
diff changeset
6188 }
Ritor1
parents:
diff changeset
6189
Ritor1
parents:
diff changeset
6190 hr = STRSAFE_E_INSUFFICIENT_BUFFER;
Ritor1
parents:
diff changeset
6191 }
Ritor1
parents:
diff changeset
6192 else
Ritor1
parents:
diff changeset
6193 {
Ritor1
parents:
diff changeset
6194 wchar_t ch;
Ritor1
parents:
diff changeset
6195
Ritor1
parents:
diff changeset
6196 pszDestEnd = pszDest;
Ritor1
parents:
diff changeset
6197 cchRemaining = cchDest;
Ritor1
parents:
diff changeset
6198
Ritor1
parents:
diff changeset
6199 while ((cchRemaining > 1) && (ch = (wchar_t)getwc(stdin)) != L'\n')
Ritor1
parents:
diff changeset
6200 {
Ritor1
parents:
diff changeset
6201 if (ch == EOF)
Ritor1
parents:
diff changeset
6202 {
Ritor1
parents:
diff changeset
6203 if (pszDestEnd == pszDest)
Ritor1
parents:
diff changeset
6204 {
Ritor1
parents:
diff changeset
6205 // we failed to read anything from stdin
Ritor1
parents:
diff changeset
6206 hr = STRSAFE_E_END_OF_FILE;
Ritor1
parents:
diff changeset
6207 }
Ritor1
parents:
diff changeset
6208 break;
Ritor1
parents:
diff changeset
6209 }
Ritor1
parents:
diff changeset
6210
Ritor1
parents:
diff changeset
6211 *pszDestEnd = ch;
Ritor1
parents:
diff changeset
6212
Ritor1
parents:
diff changeset
6213 pszDestEnd++;
Ritor1
parents:
diff changeset
6214 cchRemaining--;
Ritor1
parents:
diff changeset
6215 }
Ritor1
parents:
diff changeset
6216
Ritor1
parents:
diff changeset
6217 if (cchRemaining > 0)
Ritor1
parents:
diff changeset
6218 {
Ritor1
parents:
diff changeset
6219 // there is extra room
Ritor1
parents:
diff changeset
6220 if (dwFlags & STRSAFE_FILL_BEHIND_NULL)
Ritor1
parents:
diff changeset
6221 {
Ritor1
parents:
diff changeset
6222 memset(pszDestEnd + 1, STRSAFE_GET_FILL_PATTERN(dwFlags), ((cchRemaining - 1) * sizeof(wchar_t)) + (cbDest % sizeof(wchar_t)));
Ritor1
parents:
diff changeset
6223 }
Ritor1
parents:
diff changeset
6224 }
Ritor1
parents:
diff changeset
6225
Ritor1
parents:
diff changeset
6226 *pszDestEnd = L'\0';
Ritor1
parents:
diff changeset
6227 }
Ritor1
parents:
diff changeset
6228 }
Ritor1
parents:
diff changeset
6229 }
Ritor1
parents:
diff changeset
6230
Ritor1
parents:
diff changeset
6231 if (FAILED(hr))
Ritor1
parents:
diff changeset
6232 {
Ritor1
parents:
diff changeset
6233 if (pszDest)
Ritor1
parents:
diff changeset
6234 {
Ritor1
parents:
diff changeset
6235 if (dwFlags & STRSAFE_FILL_ON_FAILURE)
Ritor1
parents:
diff changeset
6236 {
Ritor1
parents:
diff changeset
6237 memset(pszDest, STRSAFE_GET_FILL_PATTERN(dwFlags), cbDest);
Ritor1
parents:
diff changeset
6238
Ritor1
parents:
diff changeset
6239 if (STRSAFE_GET_FILL_PATTERN(dwFlags) == 0)
Ritor1
parents:
diff changeset
6240 {
Ritor1
parents:
diff changeset
6241 pszDestEnd = pszDest;
Ritor1
parents:
diff changeset
6242 cchRemaining = cchDest;
Ritor1
parents:
diff changeset
6243 }
Ritor1
parents:
diff changeset
6244 else if (cchDest > 0)
Ritor1
parents:
diff changeset
6245 {
Ritor1
parents:
diff changeset
6246 pszDestEnd = pszDest + cchDest - 1;
Ritor1
parents:
diff changeset
6247 cchRemaining = 1;
Ritor1
parents:
diff changeset
6248
Ritor1
parents:
diff changeset
6249 // null terminate the end of the string
Ritor1
parents:
diff changeset
6250 *pszDestEnd = L'\0';
Ritor1
parents:
diff changeset
6251 }
Ritor1
parents:
diff changeset
6252 }
Ritor1
parents:
diff changeset
6253
Ritor1
parents:
diff changeset
6254 if (dwFlags & (STRSAFE_NULL_ON_FAILURE | STRSAFE_NO_TRUNCATION))
Ritor1
parents:
diff changeset
6255 {
Ritor1
parents:
diff changeset
6256 if (cchDest > 0)
Ritor1
parents:
diff changeset
6257 {
Ritor1
parents:
diff changeset
6258 pszDestEnd = pszDest;
Ritor1
parents:
diff changeset
6259 cchRemaining = cchDest;
Ritor1
parents:
diff changeset
6260
Ritor1
parents:
diff changeset
6261 // null terminate the beginning of the string
Ritor1
parents:
diff changeset
6262 *pszDestEnd = L'\0';
Ritor1
parents:
diff changeset
6263 }
Ritor1
parents:
diff changeset
6264 }
Ritor1
parents:
diff changeset
6265 }
Ritor1
parents:
diff changeset
6266 }
Ritor1
parents:
diff changeset
6267
Ritor1
parents:
diff changeset
6268 if (SUCCEEDED(hr) ||
Ritor1
parents:
diff changeset
6269 (hr == STRSAFE_E_INSUFFICIENT_BUFFER) ||
Ritor1
parents:
diff changeset
6270 (hr == STRSAFE_E_END_OF_FILE))
Ritor1
parents:
diff changeset
6271 {
Ritor1
parents:
diff changeset
6272 if (ppszDestEnd)
Ritor1
parents:
diff changeset
6273 {
Ritor1
parents:
diff changeset
6274 *ppszDestEnd = pszDestEnd;
Ritor1
parents:
diff changeset
6275 }
Ritor1
parents:
diff changeset
6276
Ritor1
parents:
diff changeset
6277 if (pcchRemaining)
Ritor1
parents:
diff changeset
6278 {
Ritor1
parents:
diff changeset
6279 *pcchRemaining = cchRemaining;
Ritor1
parents:
diff changeset
6280 }
Ritor1
parents:
diff changeset
6281 }
Ritor1
parents:
diff changeset
6282
Ritor1
parents:
diff changeset
6283 return hr;
Ritor1
parents:
diff changeset
6284 }
Ritor1
parents:
diff changeset
6285 #endif // !STRSAFE_LIB_IMPL
Ritor1
parents:
diff changeset
6286
Ritor1
parents:
diff changeset
6287
Ritor1
parents:
diff changeset
6288 // Do not call these functions, they are worker functions for internal use within this file
Ritor1
parents:
diff changeset
6289 #ifdef DEPRECATE_SUPPORTED
Ritor1
parents:
diff changeset
6290 #pragma deprecated(StringCopyWorkerA)
Ritor1
parents:
diff changeset
6291 #pragma deprecated(StringCopyWorkerW)
Ritor1
parents:
diff changeset
6292 #pragma deprecated(StringCopyExWorkerA)
Ritor1
parents:
diff changeset
6293 #pragma deprecated(StringCopyExWorkerW)
Ritor1
parents:
diff changeset
6294 #pragma deprecated(StringCatWorkerA)
Ritor1
parents:
diff changeset
6295 #pragma deprecated(StringCatWorkerW)
Ritor1
parents:
diff changeset
6296 #pragma deprecated(StringCatExWorkerA)
Ritor1
parents:
diff changeset
6297 #pragma deprecated(StringCatExWorkerW)
Ritor1
parents:
diff changeset
6298 #pragma deprecated(StringCatNWorkerA)
Ritor1
parents:
diff changeset
6299 #pragma deprecated(StringCatNWorkerW)
Ritor1
parents:
diff changeset
6300 #pragma deprecated(StringCatNExWorkerA)
Ritor1
parents:
diff changeset
6301 #pragma deprecated(StringCatNExWorkerW)
Ritor1
parents:
diff changeset
6302 #pragma deprecated(StringVPrintfWorkerA)
Ritor1
parents:
diff changeset
6303 #pragma deprecated(StringVPrintfWorkerW)
Ritor1
parents:
diff changeset
6304 #pragma deprecated(StringVPrintfExWorkerA)
Ritor1
parents:
diff changeset
6305 #pragma deprecated(StringVPrintfExWorkerW)
Ritor1
parents:
diff changeset
6306 #pragma deprecated(StringLengthWorkerA)
Ritor1
parents:
diff changeset
6307 #pragma deprecated(StringLengthWorkerW)
Ritor1
parents:
diff changeset
6308 #else
Ritor1
parents:
diff changeset
6309 #define StringCopyWorkerA StringCopyWorkerA_instead_use_StringCchCopyA_or_StringCchCopyExA;
Ritor1
parents:
diff changeset
6310 #define StringCopyWorkerW StringCopyWorkerW_instead_use_StringCchCopyW_or_StringCchCopyExW;
Ritor1
parents:
diff changeset
6311 #define StringCopyExWorkerA StringCopyExWorkerA_instead_use_StringCchCopyA_or_StringCchCopyExA;
Ritor1
parents:
diff changeset
6312 #define StringCopyExWorkerW StringCopyExWorkerW_instead_use_StringCchCopyW_or_StringCchCopyExW;
Ritor1
parents:
diff changeset
6313 #define StringCatWorkerA StringCatWorkerA_instead_use_StringCchCatA_or_StringCchCatExA;
Ritor1
parents:
diff changeset
6314 #define StringCatWorkerW StringCatWorkerW_instead_use_StringCchCatW_or_StringCchCatExW;
Ritor1
parents:
diff changeset
6315 #define StringCatExWorkerA StringCatExWorkerA_instead_use_StringCchCatA_or_StringCchCatExA;
Ritor1
parents:
diff changeset
6316 #define StringCatExWorkerW StringCatExWorkerW_instead_use_StringCchCatW_or_StringCchCatExW;
Ritor1
parents:
diff changeset
6317 #define StringCatNWorkerA StringCatNWorkerA_instead_use_StringCchCatNA_or_StrincCbCatNA;
Ritor1
parents:
diff changeset
6318 #define StringCatNWorkerW StringCatNWorkerW_instead_use_StringCchCatNW_or_StringCbCatNW;
Ritor1
parents:
diff changeset
6319 #define StringCatNExWorkerA StringCatNExWorkerA_instead_use_StringCchCatNExA_or_StringCbCatNExA;
Ritor1
parents:
diff changeset
6320 #define StringCatNExWorkerW StringCatNExWorkerW_instead_use_StringCchCatNExW_or_StringCbCatNExW;
Ritor1
parents:
diff changeset
6321 #define StringVPrintfWorkerA StringVPrintfWorkerA_instead_use_StringCchVPrintfA_or_StringCchVPrintfExA;
Ritor1
parents:
diff changeset
6322 #define StringVPrintfWorkerW StringVPrintfWorkerW_instead_use_StringCchVPrintfW_or_StringCchVPrintfExW;
Ritor1
parents:
diff changeset
6323 #define StringVPrintfExWorkerA StringVPrintfExWorkerA_instead_use_StringCchVPrintfA_or_StringCchVPrintfExA;
Ritor1
parents:
diff changeset
6324 #define StringVPrintfExWorkerW StringVPrintfExWorkerW_instead_use_StringCchVPrintfW_or_StringCchVPrintfExW;
Ritor1
parents:
diff changeset
6325 #define StringLengthWorkerA StringLengthWorkerA_instead_use_StringCchLengthA_or_StringCbLengthA;
Ritor1
parents:
diff changeset
6326 #define StringLengthWorkerW StringLengthWorkerW_instead_use_StringCchLengthW_or_StringCbLengthW;
Ritor1
parents:
diff changeset
6327 #endif // !DEPRECATE_SUPPORTED
Ritor1
parents:
diff changeset
6328
Ritor1
parents:
diff changeset
6329
Ritor1
parents:
diff changeset
6330 #ifndef STRSAFE_NO_DEPRECATE
Ritor1
parents:
diff changeset
6331 // Deprecate all of the unsafe functions to generate compiletime errors. If you do not want
Ritor1
parents:
diff changeset
6332 // this then you can #define STRSAFE_NO_DEPRECATE before including this file.
Ritor1
parents:
diff changeset
6333 #ifdef DEPRECATE_SUPPORTED
Ritor1
parents:
diff changeset
6334
Ritor1
parents:
diff changeset
6335 // First all the names that are a/w variants (or shouldn't be #defined by now anyway).
Ritor1
parents:
diff changeset
6336 #pragma deprecated(lstrcpyA)
Ritor1
parents:
diff changeset
6337 #pragma deprecated(lstrcpyW)
Ritor1
parents:
diff changeset
6338 #pragma deprecated(lstrcatA)
Ritor1
parents:
diff changeset
6339 #pragma deprecated(lstrcatW)
Ritor1
parents:
diff changeset
6340 #pragma deprecated(wsprintfA)
Ritor1
parents:
diff changeset
6341 #pragma deprecated(wsprintfW)
Ritor1
parents:
diff changeset
6342
Ritor1
parents:
diff changeset
6343 #pragma deprecated(StrCpyW)
Ritor1
parents:
diff changeset
6344 #pragma deprecated(StrCatW)
Ritor1
parents:
diff changeset
6345 #pragma deprecated(StrNCatA)
Ritor1
parents:
diff changeset
6346 #pragma deprecated(StrNCatW)
Ritor1
parents:
diff changeset
6347 #pragma deprecated(StrCatNA)
Ritor1
parents:
diff changeset
6348 #pragma deprecated(StrCatNW)
Ritor1
parents:
diff changeset
6349 #pragma deprecated(wvsprintfA)
Ritor1
parents:
diff changeset
6350 #pragma deprecated(wvsprintfW)
Ritor1
parents:
diff changeset
6351
Ritor1
parents:
diff changeset
6352 #pragma deprecated(strcpy)
Ritor1
parents:
diff changeset
6353 #pragma deprecated(wcscpy)
Ritor1
parents:
diff changeset
6354 #pragma deprecated(strcat)
Ritor1
parents:
diff changeset
6355 #pragma deprecated(wcscat)
Ritor1
parents:
diff changeset
6356 #pragma deprecated(sprintf)
Ritor1
parents:
diff changeset
6357 #pragma deprecated(swprintf)
Ritor1
parents:
diff changeset
6358 #pragma deprecated(vsprintf)
Ritor1
parents:
diff changeset
6359 #pragma deprecated(vswprintf)
Ritor1
parents:
diff changeset
6360 #pragma deprecated(_snprintf)
Ritor1
parents:
diff changeset
6361 #pragma deprecated(_snwprintf)
Ritor1
parents:
diff changeset
6362 #pragma deprecated(_vsnprintf)
Ritor1
parents:
diff changeset
6363 #pragma deprecated(_vsnwprintf)
Ritor1
parents:
diff changeset
6364 #pragma deprecated(gets)
Ritor1
parents:
diff changeset
6365 #pragma deprecated(_getws)
Ritor1
parents:
diff changeset
6366
Ritor1
parents:
diff changeset
6367 // Then all the windows.h names - we need to undef and redef based on UNICODE setting
Ritor1
parents:
diff changeset
6368 #undef lstrcpy
Ritor1
parents:
diff changeset
6369 #undef lstrcat
Ritor1
parents:
diff changeset
6370 #undef wsprintf
Ritor1
parents:
diff changeset
6371 #undef wvsprintf
Ritor1
parents:
diff changeset
6372 #pragma deprecated(lstrcpy)
Ritor1
parents:
diff changeset
6373 #pragma deprecated(lstrcat)
Ritor1
parents:
diff changeset
6374 #pragma deprecated(wsprintf)
Ritor1
parents:
diff changeset
6375 #pragma deprecated(wvsprintf)
Ritor1
parents:
diff changeset
6376 #ifdef UNICODE
Ritor1
parents:
diff changeset
6377 #define lstrcpy lstrcpyW
Ritor1
parents:
diff changeset
6378 #define lstrcat lstrcatW
Ritor1
parents:
diff changeset
6379 #define wsprintf wsprintfW
Ritor1
parents:
diff changeset
6380 #define wvsprintf wvsprintfW
Ritor1
parents:
diff changeset
6381 #else
Ritor1
parents:
diff changeset
6382 #define lstrcpy lstrcpyA
Ritor1
parents:
diff changeset
6383 #define lstrcat lstrcatA
Ritor1
parents:
diff changeset
6384 #define wsprintf wsprintfA
Ritor1
parents:
diff changeset
6385 #define wvsprintf wvsprintfA
Ritor1
parents:
diff changeset
6386 #endif
Ritor1
parents:
diff changeset
6387
Ritor1
parents:
diff changeset
6388 // Then the shlwapi names - they key off UNICODE also.
Ritor1
parents:
diff changeset
6389 #undef StrCpyA
Ritor1
parents:
diff changeset
6390 #undef StrCpy
Ritor1
parents:
diff changeset
6391 #undef StrCatA
Ritor1
parents:
diff changeset
6392 #undef StrCat
Ritor1
parents:
diff changeset
6393 #undef StrNCat
Ritor1
parents:
diff changeset
6394 #undef StrCatN
Ritor1
parents:
diff changeset
6395 #pragma deprecated(StrCpyA)
Ritor1
parents:
diff changeset
6396 #pragma deprecated(StrCatA)
Ritor1
parents:
diff changeset
6397 #pragma deprecated(StrCatN)
Ritor1
parents:
diff changeset
6398 #pragma deprecated(StrCpy)
Ritor1
parents:
diff changeset
6399 #pragma deprecated(StrCat)
Ritor1
parents:
diff changeset
6400 #pragma deprecated(StrNCat)
Ritor1
parents:
diff changeset
6401 #define StrCpyA lstrcpyA
Ritor1
parents:
diff changeset
6402 #define StrCatA lstrcatA
Ritor1
parents:
diff changeset
6403 #define StrCatN StrNCat
Ritor1
parents:
diff changeset
6404 #ifdef UNICODE
Ritor1
parents:
diff changeset
6405 #define StrCpy StrCpyW
Ritor1
parents:
diff changeset
6406 #define StrCat StrCatW
Ritor1
parents:
diff changeset
6407 #define StrNCat StrNCatW
Ritor1
parents:
diff changeset
6408 #else
Ritor1
parents:
diff changeset
6409 #define StrCpy lstrcpyA
Ritor1
parents:
diff changeset
6410 #define StrCat lstrcatA
Ritor1
parents:
diff changeset
6411 #define StrNCat StrNCatA
Ritor1
parents:
diff changeset
6412 #endif
Ritor1
parents:
diff changeset
6413
Ritor1
parents:
diff changeset
6414 // Then all the CRT names - we need to undef/redef based on _UNICODE value.
Ritor1
parents:
diff changeset
6415 #undef _tcscpy
Ritor1
parents:
diff changeset
6416 #undef _ftcscpy
Ritor1
parents:
diff changeset
6417 #undef _tcscat
Ritor1
parents:
diff changeset
6418 #undef _ftcscat
Ritor1
parents:
diff changeset
6419 #undef _stprintf
Ritor1
parents:
diff changeset
6420 #undef _sntprintf
Ritor1
parents:
diff changeset
6421 #undef _vstprintf
Ritor1
parents:
diff changeset
6422 #undef _vsntprintf
Ritor1
parents:
diff changeset
6423 #undef _getts
Ritor1
parents:
diff changeset
6424 #pragma deprecated(_tcscpy)
Ritor1
parents:
diff changeset
6425 #pragma deprecated(_ftcscpy)
Ritor1
parents:
diff changeset
6426 #pragma deprecated(_tcscat)
Ritor1
parents:
diff changeset
6427 #pragma deprecated(_ftcscat)
Ritor1
parents:
diff changeset
6428 #pragma deprecated(_stprintf)
Ritor1
parents:
diff changeset
6429 #pragma deprecated(_sntprintf)
Ritor1
parents:
diff changeset
6430 #pragma deprecated(_vstprintf)
Ritor1
parents:
diff changeset
6431 #pragma deprecated(_vsntprintf)
Ritor1
parents:
diff changeset
6432 #pragma deprecated(_getts)
Ritor1
parents:
diff changeset
6433 #ifdef _UNICODE
Ritor1
parents:
diff changeset
6434 #define _tcscpy wcscpy
Ritor1
parents:
diff changeset
6435 #define _ftcscpy wcscpy
Ritor1
parents:
diff changeset
6436 #define _tcscat wcscat
Ritor1
parents:
diff changeset
6437 #define _ftcscat wcscat
Ritor1
parents:
diff changeset
6438 #define _stprintf swprintf
Ritor1
parents:
diff changeset
6439 #define _sntprintf _snwprintf
Ritor1
parents:
diff changeset
6440 #define _vstprintf vswprintf
Ritor1
parents:
diff changeset
6441 #define _vsntprintf _vsnwprintf
Ritor1
parents:
diff changeset
6442 #define _getts _getws
Ritor1
parents:
diff changeset
6443 #else
Ritor1
parents:
diff changeset
6444 #define _tcscpy strcpy
Ritor1
parents:
diff changeset
6445 #define _ftcscpy strcpy
Ritor1
parents:
diff changeset
6446 #define _tcscat strcat
Ritor1
parents:
diff changeset
6447 #define _ftcscat strcat
Ritor1
parents:
diff changeset
6448 #define _stprintf sprintf
Ritor1
parents:
diff changeset
6449 #define _sntprintf _snprintf
Ritor1
parents:
diff changeset
6450 #define _vstprintf vsprintf
Ritor1
parents:
diff changeset
6451 #define _vsntprintf _vsnprintf
Ritor1
parents:
diff changeset
6452 #define _getts gets
Ritor1
parents:
diff changeset
6453 #endif
Ritor1
parents:
diff changeset
6454
Ritor1
parents:
diff changeset
6455 #else // DEPRECATE_SUPPORTED
Ritor1
parents:
diff changeset
6456
Ritor1
parents:
diff changeset
6457 #undef strcpy
Ritor1
parents:
diff changeset
6458 #define strcpy strcpy_instead_use_StringCbCopyA_or_StringCchCopyA;
Ritor1
parents:
diff changeset
6459
Ritor1
parents:
diff changeset
6460 #undef wcscpy
Ritor1
parents:
diff changeset
6461 #define wcscpy wcscpy_instead_use_StringCbCopyW_or_StringCchCopyW;
Ritor1
parents:
diff changeset
6462
Ritor1
parents:
diff changeset
6463 #undef strcat
Ritor1
parents:
diff changeset
6464 #define strcat strcat_instead_use_StringCbCatA_or_StringCchCatA;
Ritor1
parents:
diff changeset
6465
Ritor1
parents:
diff changeset
6466 #undef wcscat
Ritor1
parents:
diff changeset
6467 #define wcscat wcscat_instead_use_StringCbCatW_or_StringCchCatW;
Ritor1
parents:
diff changeset
6468
Ritor1
parents:
diff changeset
6469 #undef sprintf
Ritor1
parents:
diff changeset
6470 #define sprintf sprintf_instead_use_StringCbPrintfA_or_StringCchPrintfA;
Ritor1
parents:
diff changeset
6471
Ritor1
parents:
diff changeset
6472 #undef swprintf
Ritor1
parents:
diff changeset
6473 #define swprintf swprintf_instead_use_StringCbPrintfW_or_StringCchPrintfW;
Ritor1
parents:
diff changeset
6474
Ritor1
parents:
diff changeset
6475 #undef vsprintf
Ritor1
parents:
diff changeset
6476 #define vsprintf vsprintf_instead_use_StringCbVPrintfA_or_StringCchVPrintfA;
Ritor1
parents:
diff changeset
6477
Ritor1
parents:
diff changeset
6478 #undef vswprintf
Ritor1
parents:
diff changeset
6479 #define vswprintf vswprintf_instead_use_StringCbVPrintfW_or_StringCchVPrintfW;
Ritor1
parents:
diff changeset
6480
Ritor1
parents:
diff changeset
6481 #undef _snprintf
Ritor1
parents:
diff changeset
6482 #define _snprintf _snprintf_instead_use_StringCbPrintfA_or_StringCchPrintfA;
Ritor1
parents:
diff changeset
6483
Ritor1
parents:
diff changeset
6484 #undef _snwprintf
Ritor1
parents:
diff changeset
6485 #define _snwprintf _snwprintf_instead_use_StringCbPrintfW_or_StringCchPrintfW;
Ritor1
parents:
diff changeset
6486
Ritor1
parents:
diff changeset
6487 #undef _vsnprintf
Ritor1
parents:
diff changeset
6488 #define _vsnprintf _vsnprintf_instead_use_StringCbVPrintfA_or_StringCchVPrintfA;
Ritor1
parents:
diff changeset
6489
Ritor1
parents:
diff changeset
6490 #undef _vsnwprintf
Ritor1
parents:
diff changeset
6491 #define _vsnwprintf _vsnwprintf_instead_use_StringCbVPrintfW_or_StringCchVPrintfW;
Ritor1
parents:
diff changeset
6492
Ritor1
parents:
diff changeset
6493 #undef strcpyA
Ritor1
parents:
diff changeset
6494 #define strcpyA strcpyA_instead_use_StringCbCopyA_or_StringCchCopyA;
Ritor1
parents:
diff changeset
6495
Ritor1
parents:
diff changeset
6496 #undef strcpyW
Ritor1
parents:
diff changeset
6497 #define strcpyW strcpyW_instead_use_StringCbCopyW_or_StringCchCopyW;
Ritor1
parents:
diff changeset
6498
Ritor1
parents:
diff changeset
6499 #undef lstrcpy
Ritor1
parents:
diff changeset
6500 #define lstrcpy lstrcpy_instead_use_StringCbCopy_or_StringCchCopy;
Ritor1
parents:
diff changeset
6501
Ritor1
parents:
diff changeset
6502 #undef lstrcpyA
Ritor1
parents:
diff changeset
6503 #define lstrcpyA lstrcpyA_instead_use_StringCbCopyA_or_StringCchCopyA;
Ritor1
parents:
diff changeset
6504
Ritor1
parents:
diff changeset
6505 #undef lstrcpyW
Ritor1
parents:
diff changeset
6506 #define lstrcpyW lstrcpyW_instead_use_StringCbCopyW_or_StringCchCopyW;
Ritor1
parents:
diff changeset
6507
Ritor1
parents:
diff changeset
6508 #undef StrCpy
Ritor1
parents:
diff changeset
6509 #define StrCpy StrCpy_instead_use_StringCbCopy_or_StringCchCopy;
Ritor1
parents:
diff changeset
6510
Ritor1
parents:
diff changeset
6511 #undef StrCpyA
Ritor1
parents:
diff changeset
6512 #define StrCpyA StrCpyA_instead_use_StringCbCopyA_or_StringCchCopyA;
Ritor1
parents:
diff changeset
6513
Ritor1
parents:
diff changeset
6514 #undef StrCpyW
Ritor1
parents:
diff changeset
6515 #define StrCpyW StrCpyW_instead_use_StringCbCopyW_or_StringCchCopyW;
Ritor1
parents:
diff changeset
6516
Ritor1
parents:
diff changeset
6517 #undef _tcscpy
Ritor1
parents:
diff changeset
6518 #define _tcscpy _tcscpy_instead_use_StringCbCopy_or_StringCchCopy;
Ritor1
parents:
diff changeset
6519
Ritor1
parents:
diff changeset
6520 #undef _ftcscpy
Ritor1
parents:
diff changeset
6521 #define _ftcscpy _ftcscpy_instead_use_StringCbCopy_or_StringCchCopy;
Ritor1
parents:
diff changeset
6522
Ritor1
parents:
diff changeset
6523 #undef lstrcat
Ritor1
parents:
diff changeset
6524 #define lstrcat lstrcat_instead_use_StringCbCat_or_StringCchCat;
Ritor1
parents:
diff changeset
6525
Ritor1
parents:
diff changeset
6526 #undef lstrcatA
Ritor1
parents:
diff changeset
6527 #define lstrcatA lstrcatA_instead_use_StringCbCatA_or_StringCchCatA;
Ritor1
parents:
diff changeset
6528
Ritor1
parents:
diff changeset
6529 #undef lstrcatW
Ritor1
parents:
diff changeset
6530 #define lstrcatW lstrcatW_instead_use_StringCbCatW_or_StringCchCatW;
Ritor1
parents:
diff changeset
6531
Ritor1
parents:
diff changeset
6532 #undef StrCat
Ritor1
parents:
diff changeset
6533 #define StrCat StrCat_instead_use_StringCbCat_or_StringCchCat;
Ritor1
parents:
diff changeset
6534
Ritor1
parents:
diff changeset
6535 #undef StrCatA
Ritor1
parents:
diff changeset
6536 #define StrCatA StrCatA_instead_use_StringCbCatA_or_StringCchCatA;
Ritor1
parents:
diff changeset
6537
Ritor1
parents:
diff changeset
6538 #undef StrCatW
Ritor1
parents:
diff changeset
6539 #define StrCatW StrCatW_instead_use_StringCbCatW_or_StringCchCatW;
Ritor1
parents:
diff changeset
6540
Ritor1
parents:
diff changeset
6541 #undef StrNCat
Ritor1
parents:
diff changeset
6542 #define StrNCat StrNCat_instead_use_StringCbCatN_or_StringCchCatN;
Ritor1
parents:
diff changeset
6543
Ritor1
parents:
diff changeset
6544 #undef StrNCatA
Ritor1
parents:
diff changeset
6545 #define StrNCatA StrNCatA_instead_use_StringCbCatNA_or_StringCchCatNA;
Ritor1
parents:
diff changeset
6546
Ritor1
parents:
diff changeset
6547 #undef StrNCatW
Ritor1
parents:
diff changeset
6548 #define StrNCatW StrNCatW_instead_use_StringCbCatNW_or_StringCchCatNW;
Ritor1
parents:
diff changeset
6549
Ritor1
parents:
diff changeset
6550 #undef StrCatN
Ritor1
parents:
diff changeset
6551 #define StrCatN StrCatN_instead_use_StringCbCatN_or_StringCchCatN;
Ritor1
parents:
diff changeset
6552
Ritor1
parents:
diff changeset
6553 #undef StrCatNA
Ritor1
parents:
diff changeset
6554 #define StrCatNA StrCatNA_instead_use_StringCbCatNA_or_StringCchCatNA;
Ritor1
parents:
diff changeset
6555
Ritor1
parents:
diff changeset
6556 #undef StrCatNW
Ritor1
parents:
diff changeset
6557 #define StrCatNW StrCatNW_instead_use_StringCbCatNW_or_StringCchCatNW;
Ritor1
parents:
diff changeset
6558
Ritor1
parents:
diff changeset
6559 #undef _tcscat
Ritor1
parents:
diff changeset
6560 #define _tcscat _tcscat_instead_use_StringCbCat_or_StringCchCat;
Ritor1
parents:
diff changeset
6561
Ritor1
parents:
diff changeset
6562 #undef _ftcscat
Ritor1
parents:
diff changeset
6563 #define _ftcscat _ftcscat_instead_use_StringCbCat_or_StringCchCat;
Ritor1
parents:
diff changeset
6564
Ritor1
parents:
diff changeset
6565 #undef wsprintf
Ritor1
parents:
diff changeset
6566 #define wsprintf wsprintf_instead_use_StringCbPrintf_or_StringCchPrintf;
Ritor1
parents:
diff changeset
6567
Ritor1
parents:
diff changeset
6568 #undef wsprintfA
Ritor1
parents:
diff changeset
6569 #define wsprintfA wsprintfA_instead_use_StringCbPrintfA_or_StringCchPrintfA;
Ritor1
parents:
diff changeset
6570
Ritor1
parents:
diff changeset
6571 #undef wsprintfW
Ritor1
parents:
diff changeset
6572 #define wsprintfW wsprintfW_instead_use_StringCbPrintfW_or_StringCchPrintfW;
Ritor1
parents:
diff changeset
6573
Ritor1
parents:
diff changeset
6574 #undef wvsprintf
Ritor1
parents:
diff changeset
6575 #define wvsprintf wvsprintf_instead_use_StringCbVPrintf_or_StringCchVPrintf;
Ritor1
parents:
diff changeset
6576
Ritor1
parents:
diff changeset
6577 #undef wvsprintfA
Ritor1
parents:
diff changeset
6578 #define wvsprintfA wvsprintfA_instead_use_StringCbVPrintfA_or_StringCchVPrintfA;
Ritor1
parents:
diff changeset
6579
Ritor1
parents:
diff changeset
6580 #undef wvsprintfW
Ritor1
parents:
diff changeset
6581 #define wvsprintfW wvsprintfW_instead_use_StringCbVPrintfW_or_StringCchVPrintfW;
Ritor1
parents:
diff changeset
6582
Ritor1
parents:
diff changeset
6583 #undef _vstprintf
Ritor1
parents:
diff changeset
6584 #define _vstprintf _vstprintf_instead_use_StringCbVPrintf_or_StringCchVPrintf;
Ritor1
parents:
diff changeset
6585
Ritor1
parents:
diff changeset
6586 #undef _vsntprintf
Ritor1
parents:
diff changeset
6587 #define _vsntprintf _vsntprintf_instead_use_StringCbVPrintf_or_StringCchVPrintf;
Ritor1
parents:
diff changeset
6588
Ritor1
parents:
diff changeset
6589 #undef _stprintf
Ritor1
parents:
diff changeset
6590 #define _stprintf _stprintf_instead_use_StringCbPrintf_or_StringCchPrintf;
Ritor1
parents:
diff changeset
6591
Ritor1
parents:
diff changeset
6592 #undef _sntprintf
Ritor1
parents:
diff changeset
6593 #define _sntprintf _sntprintf_instead_use_StringCbPrintf_or_StringCchPrintf;
Ritor1
parents:
diff changeset
6594
Ritor1
parents:
diff changeset
6595 #undef _getts
Ritor1
parents:
diff changeset
6596 #define _getts _getts_instead_use_StringCbGets_or_StringCchGets;
Ritor1
parents:
diff changeset
6597
Ritor1
parents:
diff changeset
6598 #undef gets
Ritor1
parents:
diff changeset
6599 #define gets _gets_instead_use_StringCbGetsA_or_StringCchGetsA;
Ritor1
parents:
diff changeset
6600
Ritor1
parents:
diff changeset
6601 #undef _getws
Ritor1
parents:
diff changeset
6602 #define _getws _getws_instead_use_StringCbGetsW_or_StringCchGetsW;
Ritor1
parents:
diff changeset
6603
Ritor1
parents:
diff changeset
6604 #endif // !DEPRECATE_SUPPORTED
Ritor1
parents:
diff changeset
6605 #endif // !STRSAFE_NO_DEPRECATE
Ritor1
parents:
diff changeset
6606
Ritor1
parents:
diff changeset
6607 #ifdef _NTSTRSAFE_H_INCLUDED_
Ritor1
parents:
diff changeset
6608 #pragma warning(pop)
Ritor1
parents:
diff changeset
6609 #endif // _NTSTRSAFE_H_INCLUDED_
Ritor1
parents:
diff changeset
6610
Ritor1
parents:
diff changeset
6611 #endif // _STRSAFE_H_INCLUDED_