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

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

forward rtl heap functions to kernel32

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