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

Last change on this file since 8429 was 8429, checked in by sandervl, 23 years ago

resync with latest wine

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