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