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

Last change on this file since 6712 was 6712, checked in by sandervl, 24 years ago

restored old version

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