source: trunk/src/NTDLL/rtlstr.c@ 6666

Last change on this file since 6666 was 6648, checked in by bird, 24 years ago

Added $Id:$ keyword.

File size: 23.1 KB
Line 
1/* $Id: rtlstr.c,v 1.4 2001-09-05 13:14:08 bird Exp $ */
2/*
3 * Rtl string functions
4 *
5 * Copyright (C) 1996-1998 Marcus Meissner
6 * Copyright (C) 2000 Alexandre Julliard
7 */
8
9#include "config.h"
10
11#include <stdlib.h>
12#include <string.h>
13#include <ctype.h>
14#include "wine/unicode.h"
15#include "heap.h"
16#include "winnls.h"
17#include "debugtools.h"
18#include "ntdll_misc.h"
19#include "ntddk.h"
20
21DEFAULT_DEBUG_CHANNEL(ntdll);
22
23/* STRING CREATION FUNCTIONS */
24
25/**************************************************************************
26 * RtlInitAnsiString (NTDLL.@)
27 */
28void WINAPI RtlInitAnsiString( PSTRING target, LPCSTR source)
29{
30 if ((target->Buffer = (LPSTR)source))
31 {
32 target->Length = strlen(source);
33 target->MaximumLength = target->Length + 1;
34 }
35 else target->Length = target->MaximumLength = 0;
36}
37
38
39/**************************************************************************
40 * RtlInitString (NTDLL.@)
41 */
42void WINAPI RtlInitString( PSTRING target, LPCSTR source )
43{
44 return RtlInitAnsiString( target, source );
45}
46
47
48/**************************************************************************
49 * RtlFreeAnsiString (NTDLL.@)
50 */
51void WINAPI RtlFreeAnsiString( PSTRING str )
52{
53 if (str->Buffer) HeapFree( GetProcessHeap(), 0, str->Buffer );
54}
55
56
57/**************************************************************************
58 * RtlFreeOemString (NTDLL.@)
59 */
60void WINAPI RtlFreeOemString( PSTRING str )
61{
62 RtlFreeAnsiString( str );
63}
64
65
66/**************************************************************************
67 * RtlCopyString (NTDLL.@)
68 */
69void WINAPI RtlCopyString( STRING *dst, const STRING *src )
70{
71 if (src)
72 {
73 unsigned int len = min( src->Length, dst->MaximumLength );
74 memcpy( dst->Buffer, src->Buffer, len );
75 dst->Length = len;
76 }
77 else dst->Length = 0;
78}
79
80
81/**************************************************************************
82 * RtlInitUnicodeString (NTDLL.@)
83 */
84void WINAPI RtlInitUnicodeString( PUNICODE_STRING target, LPCWSTR source )
85{
86 if ((target->Buffer = (LPWSTR)source))
87 {
88 target->Length = strlenW(source) * sizeof(WCHAR);
89 target->MaximumLength = target->Length + sizeof(WCHAR);
90 }
91 else target->Length = target->MaximumLength = 0;
92}
93
94
95/**************************************************************************
96 * RtlCreateUnicodeString (NTDLL.@)
97 */
98BOOLEAN WINAPI RtlCreateUnicodeString( PUNICODE_STRING target, LPCWSTR src )
99{
100 int len = (strlenW(src) + 1) * sizeof(WCHAR);
101 if (!(target->Buffer = HeapAlloc( GetProcessHeap(), 0, len ))) return FALSE;
102 memcpy( target->Buffer, src, len );
103 target->MaximumLength = len;
104 target->Length = len - 2;
105 return TRUE;
106}
107
108
109/**************************************************************************
110 * RtlCreateUnicodeStringFromAsciiz (NTDLL.@)
111 */
112BOOLEAN WINAPI RtlCreateUnicodeStringFromAsciiz( PUNICODE_STRING target, LPCSTR src )
113{
114 STRING ansi;
115 RtlInitAnsiString( &ansi, src );
116 return !RtlAnsiStringToUnicodeString( target, &ansi, TRUE );
117}
118
119
120/**************************************************************************
121 * RtlFreeUnicodeString (NTDLL.@)
122 */
123void WINAPI RtlFreeUnicodeString( PUNICODE_STRING str )
124{
125 if (str->Buffer) HeapFree( GetProcessHeap(), 0, str->Buffer );
126}
127
128
129/**************************************************************************
130 * RtlCopyUnicodeString (NTDLL.@)
131 */
132void WINAPI RtlCopyUnicodeString( UNICODE_STRING *dst, const UNICODE_STRING *src )
133{
134 if (src)
135 {
136 unsigned int len = min( src->Length, dst->MaximumLength );
137 memcpy( dst->Buffer, src->Buffer, len );
138 dst->Length = len;
139 /* append terminating NULL if enough space */
140 if (len < dst->MaximumLength) dst->Buffer[len / sizeof(WCHAR)] = 0;
141 }
142 else dst->Length = 0;
143}
144
145
146/**************************************************************************
147 * RtlEraseUnicodeString (NTDLL.@)
148 */
149void WINAPI RtlEraseUnicodeString( UNICODE_STRING *str )
150{
151 if (str->Buffer)
152 {
153 memset( str->Buffer, 0, str->MaximumLength );
154 str->Length = 0;
155 }
156}
157
158/*
159 COMPARISON FUNCTIONS
160*/
161
162/******************************************************************************
163 * RtlCompareString (NTDLL.@)
164 */
165LONG WINAPI RtlCompareString( const STRING *s1, const STRING *s2, BOOLEAN CaseInsensitive )
166{
167 unsigned int len;
168 LONG ret = 0;
169 LPCSTR p1, p2;
170
171 len = min(s1->Length, s2->Length);
172 p1 = s1->Buffer;
173 p2 = s2->Buffer;
174
175 if (CaseInsensitive)
176 {
177 while (!ret && len--) ret = toupper(*p1++) - toupper(*p2++);
178 }
179 else
180 {
181 while (!ret && len--) ret = *p1++ - *p2++;
182 }
183 if (!ret) ret = s1->Length - s2->Length;
184 return ret;
185}
186
187
188/******************************************************************************
189 * RtlCompareUnicodeString (NTDLL.@)
190 */
191LONG WINAPI RtlCompareUnicodeString( const UNICODE_STRING *s1, const UNICODE_STRING *s2,
192 BOOLEAN CaseInsensitive )
193{
194 unsigned int len;
195 LONG ret = 0;
196 LPCWSTR p1, p2;
197
198 len = min(s1->Length, s2->Length) / sizeof(WCHAR);
199 p1 = s1->Buffer;
200 p2 = s2->Buffer;
201
202 if (CaseInsensitive)
203 {
204 while (!ret && len--) ret = toupperW(*p1++) - toupperW(*p2++);
205 }
206 else
207 {
208 while (!ret && len--) ret = *p1++ - *p2++;
209 }
210 if (!ret) ret = s1->Length - s2->Length;
211 return ret;
212}
213
214
215/**************************************************************************
216 * RtlEqualString (NTDLL.@)
217 */
218BOOLEAN WINAPI RtlEqualString( const STRING *s1, const STRING *s2, BOOLEAN CaseInsensitive )
219{
220 if (s1->Length != s2->Length) return FALSE;
221 return !RtlCompareString( s1, s2, CaseInsensitive );
222}
223
224
225/**************************************************************************
226 * RtlEqualUnicodeString (NTDLL.@)
227 */
228BOOLEAN WINAPI RtlEqualUnicodeString( const UNICODE_STRING *s1, const UNICODE_STRING *s2,
229 BOOLEAN CaseInsensitive )
230{
231 if (s1->Length != s2->Length) return FALSE;
232 return !RtlCompareUnicodeString( s1, s2, CaseInsensitive );
233}
234
235
236/**************************************************************************
237 * RtlPrefixString (NTDLL.@)
238 *
239 * Test if s1 is a prefix in s2
240 */
241BOOLEAN WINAPI RtlPrefixString( const STRING *s1, const STRING *s2, BOOLEAN ignore_case )
242{
243 unsigned int i;
244
245 if (s1->Length > s2->Length) return FALSE;
246 if (ignore_case)
247 {
248 for (i = 0; i < s1->Length; i++)
249 if (toupper(s1->Buffer[i]) != toupper(s2->Buffer[i])) return FALSE;
250 }
251 else
252 {
253 for (i = 0; i < s1->Length; i++)
254 if (s1->Buffer[i] != s2->Buffer[i]) return FALSE;
255 }
256 return TRUE;
257}
258
259
260/**************************************************************************
261 * RtlPrefixUnicodeString (NTDLL.@)
262 *
263 * Test if s1 is a prefix in s2
264 */
265BOOLEAN WINAPI RtlPrefixUnicodeString( const UNICODE_STRING *s1,
266 const UNICODE_STRING *s2,
267 BOOLEAN ignore_case )
268{
269 unsigned int i;
270
271 if (s1->Length > s2->Length) return FALSE;
272 if (ignore_case)
273 {
274 for (i = 0; i < s1->Length / sizeof(WCHAR); i++)
275 if (toupper(s1->Buffer[i]) != toupper(s2->Buffer[i])) return FALSE;
276 }
277 else
278 {
279 for (i = 0; i < s1->Length / sizeof(WCHAR); i++)
280 if (s1->Buffer[i] != s2->Buffer[i]) return FALSE;
281 }
282 return TRUE;
283}
284
285
286/*
287 COPY BETWEEN ANSI_STRING or UNICODE_STRING
288 there is no parameter checking, it just crashes
289*/
290
291
292/**************************************************************************
293 * RtlAnsiStringToUnicodeString (NTDLL.@)
294 *
295 * NOTES:
296 * writes terminating 0
297 */
298NTSTATUS WINAPI RtlAnsiStringToUnicodeString( UNICODE_STRING *uni,
299 const STRING *ansi,
300 BOOLEAN doalloc )
301{
302 DWORD len = MultiByteToWideChar( CP_ACP, 0, ansi->Buffer, ansi->Length, NULL, 0 );
303 DWORD total = (len + 1) * sizeof(WCHAR);
304
305 if (total > 0xffff) return STATUS_INVALID_PARAMETER_2;
306 uni->Length = len * sizeof(WCHAR);
307 if (doalloc)
308 {
309 uni->MaximumLength = total;
310 if (!(uni->Buffer = HeapAlloc( GetProcessHeap(), 0, total ))) return STATUS_NO_MEMORY;
311 }
312 else if (total > uni->MaximumLength) return STATUS_BUFFER_OVERFLOW;
313
314 MultiByteToWideChar( CP_ACP, 0, ansi->Buffer, ansi->Length, uni->Buffer, len );
315 uni->Buffer[len] = 0;
316 return STATUS_SUCCESS;
317}
318
319
320/**************************************************************************
321 * RtlOemStringToUnicodeString (NTDLL.@)
322 *
323 * NOTES
324 * writes terminating 0
325 * if resulting length > 0xffff it returns STATUS_INVALID_PARAMETER_2
326 */
327NTSTATUS WINAPI RtlOemStringToUnicodeString( UNICODE_STRING *uni,
328 const STRING *oem,
329 BOOLEAN doalloc )
330{
331 DWORD len = MultiByteToWideChar( CP_OEMCP, 0, oem->Buffer, oem->Length, NULL, 0 );
332 DWORD total = (len + 1) * sizeof(WCHAR);
333
334 if (total > 0xffff) return STATUS_INVALID_PARAMETER_2;
335 uni->Length = len * sizeof(WCHAR);
336 if (doalloc)
337 {
338 uni->MaximumLength = total;
339 if (!(uni->Buffer = HeapAlloc( GetProcessHeap(), 0, total ))) return STATUS_NO_MEMORY;
340 }
341 else if (total > uni->MaximumLength) return STATUS_BUFFER_OVERFLOW;
342
343 MultiByteToWideChar( CP_OEMCP, 0, oem->Buffer, oem->Length, uni->Buffer, len );
344 uni->Buffer[len] = 0;
345 return STATUS_SUCCESS;
346}
347
348
349/**************************************************************************
350 * RtlUnicodeStringToAnsiString (NTDLL.@)
351 *
352 * NOTES
353 * writes terminating 0
354 * copies a part if the buffer is too small
355 */
356NTSTATUS WINAPI RtlUnicodeStringToAnsiString( STRING *ansi,
357 const UNICODE_STRING *uni,
358 BOOLEAN doalloc )
359{
360 NTSTATUS ret = STATUS_SUCCESS;
361 DWORD len = RtlUnicodeStringToAnsiSize( uni );
362
363 ansi->Length = len;
364 if (doalloc)
365 {
366 ansi->MaximumLength = len + 1;
367 if (!(ansi->Buffer = HeapAlloc( GetProcessHeap(), 0, len + 1 ))) return STATUS_NO_MEMORY;
368 }
369 else if (ansi->MaximumLength <= len)
370 {
371 if (!ansi->MaximumLength) return STATUS_BUFFER_OVERFLOW;
372 ansi->Length = ansi->MaximumLength - 1;
373 ret = STATUS_BUFFER_OVERFLOW;
374 }
375
376 WideCharToMultiByte( CP_ACP, 0, uni->Buffer, uni->Length / sizeof(WCHAR),
377 ansi->Buffer, ansi->Length, NULL, NULL );
378 ansi->Buffer[ansi->Length] = 0;
379 return ret;
380}
381
382
383/**************************************************************************
384 * RtlUnicodeStringToOemString (NTDLL.@)
385 *
386 * NOTES
387 * allocates uni->Length+1
388 * writes terminating 0
389 */
390NTSTATUS WINAPI RtlUnicodeStringToOemString( STRING *oem,
391 const UNICODE_STRING *uni,
392 BOOLEAN doalloc )
393{
394 NTSTATUS ret = STATUS_SUCCESS;
395 DWORD len = RtlUnicodeStringToOemSize( uni );
396
397 oem->Length = len;
398 if (doalloc)
399 {
400 oem->MaximumLength = len + 1;
401 if (!(oem->Buffer = HeapAlloc( GetProcessHeap(), 0, len + 1 ))) return STATUS_NO_MEMORY;
402 }
403 else if (oem->MaximumLength <= len)
404 {
405 if (!oem->MaximumLength) return STATUS_BUFFER_OVERFLOW;
406 oem->Length = oem->MaximumLength - 1;
407 ret = STATUS_BUFFER_OVERFLOW;
408 }
409
410 WideCharToMultiByte( CP_OEMCP, 0, uni->Buffer, uni->Length / sizeof(WCHAR),
411 oem->Buffer, oem->Length, NULL, NULL );
412 oem->Buffer[oem->Length] = 0;
413 return ret;
414}
415
416
417/**************************************************************************
418 * RtlMultiByteToUnicodeN (NTDLL.@)
419 *
420 * NOTES
421 * if unistr is too small a part is copied
422 */
423NTSTATUS WINAPI RtlMultiByteToUnicodeN( LPWSTR dst, DWORD dstlen, LPDWORD reslen,
424 LPCSTR src, DWORD srclen )
425{
426 DWORD res = MultiByteToWideChar( CP_ACP, 0, src, srclen, dst, dstlen/sizeof(WCHAR) );
427 if (reslen)
428 *reslen = res ? res * sizeof(WCHAR) : dstlen; /* overflow -> we filled up to dstlen */
429 return STATUS_SUCCESS;
430}
431
432
433/**************************************************************************
434 * RtlOemToUnicodeN (NTDLL.@)
435 */
436NTSTATUS WINAPI RtlOemToUnicodeN( LPWSTR dst, DWORD dstlen, LPDWORD reslen,
437 LPCSTR src, DWORD srclen )
438{
439 DWORD res = MultiByteToWideChar( CP_OEMCP, 0, src, srclen, dst, dstlen/sizeof(WCHAR) );
440 if (reslen)
441 *reslen = res ? res * sizeof(WCHAR) : dstlen; /* overflow -> we filled up to dstlen */
442 return STATUS_SUCCESS;
443}
444
445
446/**************************************************************************
447 * RtlUnicodeToMultiByteN (NTDLL.@)
448 */
449NTSTATUS WINAPI RtlUnicodeToMultiByteN( LPSTR dst, DWORD dstlen, LPDWORD reslen,
450 LPCWSTR src, DWORD srclen )
451{
452 DWORD res = WideCharToMultiByte( CP_ACP, 0, src, srclen/sizeof(WCHAR),
453 dst, dstlen, NULL, NULL );
454 if (reslen)
455 *reslen = res ? res * sizeof(WCHAR) : dstlen; /* overflow -> we filled up to dstlen */
456 return STATUS_SUCCESS;
457}
458
459
460/**************************************************************************
461 * RtlUnicodeToOemN (NTDLL.@)
462 */
463NTSTATUS WINAPI RtlUnicodeToOemN( LPSTR dst, DWORD dstlen, LPDWORD reslen,
464 LPCWSTR src, DWORD srclen )
465{
466 DWORD res = WideCharToMultiByte( CP_OEMCP, 0, src, srclen/sizeof(WCHAR),
467 dst, dstlen, NULL, NULL );
468 if (reslen)
469 *reslen = res ? res * sizeof(WCHAR) : dstlen; /* overflow -> we filled up to dstlen */
470 return STATUS_SUCCESS;
471}
472
473
474/*
475 CASE CONVERSIONS
476*/
477
478/**************************************************************************
479 * RtlUpperString (NTDLL.@)
480 */
481void WINAPI RtlUpperString( STRING *dst, const STRING *src )
482{
483 unsigned int i, len = min(src->Length, dst->MaximumLength);
484
485 for (i = 0; i < len; i++) dst->Buffer[i] = toupper(src->Buffer[i]);
486 dst->Length = len;
487}
488
489
490/**************************************************************************
491 * RtlUpcaseUnicodeString (NTDLL.@)
492 *
493 * NOTES:
494 * destination string is never 0-terminated because dest can be equal to src
495 * and src might be not 0-terminated
496 * dest.Length only set when success
497 */
498NTSTATUS WINAPI RtlUpcaseUnicodeString( UNICODE_STRING *dest,
499 const UNICODE_STRING *src,
500 BOOLEAN doalloc )
501{
502 DWORD i, len = src->Length;
503
504 if (doalloc)
505 {
506 dest->MaximumLength = len;
507 if (!(dest->Buffer = HeapAlloc( GetProcessHeap(), 0, len ))) return STATUS_NO_MEMORY;
508 }
509 else if (len > dest->MaximumLength) return STATUS_BUFFER_OVERFLOW;
510
511 for (i = 0; i < len/sizeof(WCHAR); i++) dest->Buffer[i] = toupperW(src->Buffer[i]);
512 dest->Length = len;
513 return STATUS_SUCCESS;
514}
515
516
517/**************************************************************************
518 * RtlUpcaseUnicodeStringToAnsiString (NTDLL.@)
519 *
520 * NOTES
521 * writes terminating 0
522 */
523NTSTATUS WINAPI RtlUpcaseUnicodeStringToAnsiString( STRING *dst,
524 const UNICODE_STRING *src,
525 BOOLEAN doalloc )
526{
527 NTSTATUS ret;
528 UNICODE_STRING upcase;
529
530 if (!(ret = RtlUpcaseUnicodeString( &upcase, src, TRUE )))
531 {
532 ret = RtlUnicodeStringToAnsiString( dst, &upcase, doalloc );
533 RtlFreeUnicodeString( &upcase );
534 }
535 return ret;
536}
537
538
539/**************************************************************************
540 * RtlUpcaseUnicodeStringToOemString (NTDLL.@)
541 *
542 * NOTES
543 * writes terminating 0
544 */
545NTSTATUS WINAPI RtlUpcaseUnicodeStringToOemString( STRING *dst,
546 const UNICODE_STRING *src,
547 BOOLEAN doalloc )
548{
549 NTSTATUS ret;
550 UNICODE_STRING upcase;
551
552 if (!(ret = RtlUpcaseUnicodeString( &upcase, src, TRUE )))
553 {
554 ret = RtlUnicodeStringToOemString( dst, &upcase, doalloc );
555 RtlFreeUnicodeString( &upcase );
556 }
557 return ret;
558}
559
560
561/**************************************************************************
562 * RtlUpcaseUnicodeToMultiByteN (NTDLL.@)
563 */
564NTSTATUS WINAPI RtlUpcaseUnicodeToMultiByteN( LPSTR dst, DWORD dstlen, LPDWORD reslen,
565 LPCWSTR src, DWORD srclen )
566{
567 NTSTATUS ret;
568 LPWSTR upcase;
569 DWORD i;
570
571 if (!(upcase = HeapAlloc( GetProcessHeap(), 0, srclen ))) return STATUS_NO_MEMORY;
572 for (i = 0; i < srclen/sizeof(WCHAR); i++) upcase[i] = toupperW(src[i]);
573 ret = RtlUnicodeToMultiByteN( dst, dstlen, reslen, upcase, srclen );
574 HeapFree( GetProcessHeap(), 0, upcase );
575 return ret;
576}
577
578
579/**************************************************************************
580 * RtlUpcaseUnicodeToOemN (NTDLL.@)
581 */
582NTSTATUS WINAPI RtlUpcaseUnicodeToOemN( LPSTR dst, DWORD dstlen, LPDWORD reslen,
583 LPCWSTR src, DWORD srclen )
584{
585 NTSTATUS ret;
586 LPWSTR upcase;
587 DWORD i;
588
589 if (!(upcase = HeapAlloc( GetProcessHeap(), 0, srclen ))) return STATUS_NO_MEMORY;
590 for (i = 0; i < srclen/sizeof(WCHAR); i++) upcase[i] = toupperW(src[i]);
591 ret = RtlUnicodeToOemN( dst, dstlen, reslen, upcase, srclen );
592 HeapFree( GetProcessHeap(), 0, upcase );
593 return ret;
594}
595
596
597/*
598 STRING SIZE
599*/
600
601/**************************************************************************
602 * RtlOemStringToUnicodeSize (NTDLL.@)
603 *
604 * Return the size in bytes necessary for the Unicode conversion of 'str',
605 * including the terminating NULL.
606 */
607UINT WINAPI RtlOemStringToUnicodeSize(PSTRING str)
608{
609 DWORD ret = MultiByteToWideChar( CP_OEMCP, 0, str->Buffer, str->Length, NULL, 0 );
610 return (ret + 1) * sizeof(WCHAR);
611}
612
613
614/**************************************************************************
615 * RtlAnsiStringToUnicodeSize (NTDLL.@)
616 *
617 * Return the size in bytes necessary for the Unicode conversion of 'str',
618 * including the terminating NULL.
619 */
620DWORD WINAPI RtlAnsiStringToUnicodeSize(PSTRING str)
621{
622 DWORD ret = MultiByteToWideChar( CP_ACP, 0, str->Buffer, str->Length, NULL, 0 );
623 return (ret + 1) * sizeof(WCHAR);
624}
625
626
627/**************************************************************************
628 * RtlMultiByteToUnicodeSize (NTDLL.@)
629 *
630 * Compute the size in bytes necessary for the Unicode conversion of 'str',
631 * without the terminating NULL.
632 */
633NTSTATUS WINAPI RtlMultiByteToUnicodeSize( DWORD *size, LPCSTR str, UINT len )
634{
635 *size = MultiByteToWideChar( CP_ACP, 0, str, len, NULL, 0 ) * sizeof(WCHAR);
636 return 0;
637}
638
639
640/**************************************************************************
641 * RtlUnicodeToMultiByteSize (NTDLL.@)
642 *
643 * Compute the size necessary for the multibyte conversion of 'str',
644 * without the terminating NULL.
645 */
646NTSTATUS WINAPI RtlUnicodeToMultiByteSize( DWORD *size, LPCWSTR str, UINT len )
647{
648 *size = WideCharToMultiByte( CP_ACP, 0, str, len / sizeof(WCHAR), NULL, 0, NULL, NULL );
649 return 0;
650}
651
652
653/**************************************************************************
654 * RtlUnicodeStringToAnsiSize (NTDLL.@)
655 *
656 * Return the size in bytes necessary for the Ansi conversion of 'str',
657 * including the terminating NULL.
658 */
659DWORD WINAPI RtlUnicodeStringToAnsiSize( const UNICODE_STRING *str )
660{
661 return WideCharToMultiByte( CP_ACP, 0, str->Buffer, str->Length / sizeof(WCHAR),
662 NULL, 0, NULL, NULL ) + 1;
663}
664
665
666/**************************************************************************
667 * RtlUnicodeStringToOemSize (NTDLL.@)
668 *
669 * Return the size in bytes necessary for the OEM conversion of 'str',
670 * including the terminating NULL.
671 */
672DWORD WINAPI RtlUnicodeStringToOemSize( const UNICODE_STRING *str )
673{
674 return WideCharToMultiByte( CP_OEMCP, 0, str->Buffer, str->Length / sizeof(WCHAR),
675 NULL, 0, NULL, NULL ) + 1;
676}
677
678
679/**************************************************************************
680 * RtlAppendStringToString (NTDLL.@)
681 */
682NTSTATUS WINAPI RtlAppendStringToString( STRING *dst, const STRING *src )
683{
684 unsigned int len = src->Length + dst->Length;
685 if (len > dst->MaximumLength) return STATUS_BUFFER_TOO_SMALL;
686 memcpy( dst->Buffer + dst->Length, src->Buffer, src->Length );
687 dst->Length = len;
688 return STATUS_SUCCESS;
689}
690
691
692/**************************************************************************
693 * RtlAppendAsciizToString (NTDLL.@)
694 */
695NTSTATUS WINAPI RtlAppendAsciizToString( STRING *dst, LPCSTR src )
696{
697 if (src)
698 {
699 unsigned int srclen = strlen(src);
700 unsigned int total = srclen + dst->Length;
701 if (total > dst->MaximumLength) return STATUS_BUFFER_TOO_SMALL;
702 memcpy( dst->Buffer + dst->Length, src, srclen );
703 dst->Length = total;
704 }
705 return STATUS_SUCCESS;
706}
707
708
709/**************************************************************************
710 * RtlAppendUnicodeToString (NTDLL.@)
711 */
712NTSTATUS WINAPI RtlAppendUnicodeToString( UNICODE_STRING *dst, LPCWSTR src )
713{
714 if (src)
715 {
716 unsigned int srclen = strlenW(src) * sizeof(WCHAR);
717 unsigned int total = srclen + dst->Length;
718 if (total > dst->MaximumLength) return STATUS_BUFFER_TOO_SMALL;
719 memcpy( dst->Buffer + dst->Length/sizeof(WCHAR), src, srclen );
720 dst->Length = total;
721 /* append terminating NULL if enough space */
722 if (total < dst->MaximumLength) dst->Buffer[total / sizeof(WCHAR)] = 0;
723 }
724 return STATUS_SUCCESS;
725}
726
727
728/**************************************************************************
729 * RtlAppendUnicodeStringToString (NTDLL.@)
730 */
731NTSTATUS WINAPI RtlAppendUnicodeStringToString( UNICODE_STRING *dst, const UNICODE_STRING *src )
732{
733 unsigned int len = src->Length + dst->Length;
734 if (len > dst->MaximumLength) return STATUS_BUFFER_TOO_SMALL;
735 memcpy( dst->Buffer + dst->Length/sizeof(WCHAR), src->Buffer, src->Length );
736 dst->Length = len;
737 /* append terminating NULL if enough space */
738 if (len < dst->MaximumLength) dst->Buffer[len / sizeof(WCHAR)] = 0;
739 return STATUS_SUCCESS;
740}
741
742
743/*
744 MISC
745*/
746
747/**************************************************************************
748 * RtlIsTextUnicode
749 *
750 * Apply various feeble heuristics to guess whether
751 * the text buffer contains Unicode.
752 * FIXME: should implement more tests.
753 */
754DWORD WINAPI RtlIsTextUnicode(
755 LPVOID buf,
756 DWORD len,
757 DWORD *pf)
758{
759 LPWSTR s = buf;
760 DWORD flags = -1, out_flags = 0;
761
762 if (!len)
763 goto out;
764 if (pf)
765 flags = *pf;
766 /*
767 * Apply various tests to the text string. According to the
768 * docs, each test "passed" sets the corresponding flag in
769 * the output flags. But some of the tests are mutually
770 * exclusive, so I don't see how you could pass all tests ...
771 */
772
773 /* Check for an odd length ... pass if even. */
774 if (!(len & 1))
775 out_flags |= IS_TEXT_UNICODE_ODD_LENGTH;
776
777 /* Check for the special unicode marker byte. */
778 if (*s == 0xFEFF)
779 out_flags |= IS_TEXT_UNICODE_SIGNATURE;
780
781 /*
782 * Check whether the string passed all of the tests.
783 */
784 flags &= ITU_IMPLEMENTED_TESTS;
785 if ((out_flags & flags) != flags)
786 len = 0;
787out:
788 if (pf)
789 *pf = out_flags;
790 return len;
791}
Note: See TracBrowser for help on using the repository browser.