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

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

update

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