1 /* $Id: unicode.c,v 1.21 2002/04/01 22:13:15 hbirr Exp $
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/rtl/unicode.c
6 * PURPOSE: String functions
7 * PROGRAMMER: Jason Filby (jasonfilby@yahoo.com)
12 #include <ddk/ntddk.h>
13 //#include <internal/nls.h>
15 #include <ntos/minmax.h>
16 #include <internal/pool.h>
19 #include <internal/debug.h>
21 /* GLOBALS *******************************************************************/
23 #define TAG_USTR TAG('U', 'S', 'T', 'R')
24 #define TAG_ASTR TAG('A', 'S', 'T', 'R')
25 #define TAG_OSTR TAG('O', 'S', 'T', 'R')
27 /* FUNCTIONS *****************************************************************/
30 RtlAnsiCharToUnicodeChar(IN CHAR AnsiChar
)
37 Size
= (NlsLeadByteInfo
[AnsiChar
] == 0) ? 1 : 2;
40 RtlMultiByteToUnicodeN(&UnicodeChar
,
51 RtlAnsiStringToUnicodeSize(IN PANSI_STRING AnsiString
)
55 RtlMultiByteToUnicodeSize(&Size
,
64 RtlAnsiStringToUnicodeString(IN OUT PUNICODE_STRING DestinationString
,
65 IN PANSI_STRING SourceString
,
66 IN BOOLEAN AllocateDestinationString
)
71 if (NlsMbCodePageTag
== TRUE
)
72 Length
= RtlAnsiStringToUnicodeSize (SourceString
);
74 Length
= SourceString
->Length
* sizeof(WCHAR
);
77 return STATUS_INVALID_PARAMETER_2
;
79 if (AllocateDestinationString
== TRUE
)
81 DestinationString
->MaximumLength
= Length
+ sizeof(WCHAR
);
82 DestinationString
->Buffer
=
83 ExAllocatePoolWithTag (NonPagedPool
,
84 DestinationString
->MaximumLength
,
86 if (DestinationString
->Buffer
== NULL
)
87 return STATUS_NO_MEMORY
;
91 if (Length
+ sizeof(WCHAR
) > DestinationString
->MaximumLength
)
93 DPRINT("STATUS_BUFFER_TOO_SMALL\n");
94 return STATUS_BUFFER_TOO_SMALL
;
97 DestinationString
->Length
= Length
;
99 RtlZeroMemory (DestinationString
->Buffer
,
100 DestinationString
->Length
);
102 Status
= RtlMultiByteToUnicodeN (DestinationString
->Buffer
,
103 DestinationString
->Length
,
105 SourceString
->Buffer
,
106 SourceString
->Length
);
107 if (!NT_SUCCESS(Status
))
109 if (AllocateDestinationString
)
110 ExFreePool (DestinationString
->Buffer
);
114 DestinationString
->Buffer
[Length
/ sizeof(WCHAR
)] = 0;
116 return STATUS_SUCCESS
;
121 RtlAppendAsciizToString(IN OUT PSTRING Destination
,
128 return STATUS_SUCCESS
;
130 Length
= strlen (Source
);
131 if (Destination
->Length
+ Length
>= Destination
->MaximumLength
)
132 return STATUS_BUFFER_TOO_SMALL
;
134 Ptr
= Destination
->Buffer
+ Destination
->Length
;
141 Destination
->Length
+= Length
;
143 return STATUS_SUCCESS
;
148 RtlAppendStringToString(IN OUT PSTRING Destination
,
153 if (Source
->Length
== 0)
154 return(STATUS_SUCCESS
);
156 if (Destination
->Length
+ Source
->Length
>= Destination
->MaximumLength
)
157 return(STATUS_BUFFER_TOO_SMALL
);
159 Ptr
= Destination
->Buffer
+ Destination
->Length
;
163 Ptr
+= Source
->Length
;
166 Destination
->Length
+= Source
->Length
;
168 return(STATUS_SUCCESS
);
173 RtlAppendUnicodeStringToString(IN OUT PUNICODE_STRING Destination
,
174 IN PUNICODE_STRING Source
)
179 if ((Source
->Length
+ Destination
->Length
) >= Destination
->MaximumLength
)
180 return STATUS_BUFFER_TOO_SMALL
;
182 Src
= Source
->Buffer
;
183 Dest
= Destination
->Buffer
+ (Destination
->Length
/ sizeof (WCHAR
));
184 for (i
= 0; i
< (Source
->Length
/ sizeof(WCHAR
)); i
++)
192 Destination
->Length
+= Source
->Length
;
194 return STATUS_SUCCESS
;
199 RtlAppendUnicodeToString(IN OUT PUNICODE_STRING Destination
,
207 slen
= wcslen(Source
) * sizeof(WCHAR
);
209 if (Destination
->Length
+ slen
>= Destination
->MaximumLength
)
210 return(STATUS_BUFFER_TOO_SMALL
);
213 Dest
= Destination
->Buffer
+ (Destination
->Length
/ sizeof(WCHAR
));
215 for (i
= 0; i
< (slen
/ sizeof(WCHAR
)); i
++)
223 Destination
->Length
+= slen
;
225 return(STATUS_SUCCESS
);
230 RtlCharToInteger(IN PCSZ String
,
245 if ((*String
== 'x') && isxdigit (String
[1]))
253 if (!isxdigit (*String
))
254 return(STATUS_INVALID_PARAMETER
);
256 while (isxdigit (*String
) &&
257 (Val
= isdigit (*String
) ? * String
- '0' : (islower (*String
)
258 ? toupper (*String
) : *String
) - 'A' + 10) < Base
)
260 *Value
= *Value
* Base
+ Val
;
264 return(STATUS_SUCCESS
);
269 RtlCompareString(IN PSTRING String1
,
271 IN BOOLEAN CaseInsensitive
)
277 if (String1
&& String2
)
279 len1
= String1
->Length
;
280 len2
= String2
->Length
;
281 s1
= String1
->Buffer
;
282 s2
= String2
->Buffer
;
290 c1
= len1
-- ? RtlUpperChar (*s1
++) : 0;
291 c2
= len2
-- ? RtlUpperChar (*s2
++) : 0;
292 if (!c1
|| !c2
|| c1
!= c2
)
300 c1
= len1
-- ? *s1
++ : 0;
301 c2
= len2
-- ? *s2
++ : 0;
302 if (!c1
|| !c2
|| c1
!= c2
)
314 RtlCompareUnicodeString(IN PUNICODE_STRING String1
,
315 IN PUNICODE_STRING String2
,
316 IN BOOLEAN CaseInsensitive
)
322 if (String1
&& String2
)
324 len1
= String1
->Length
/ sizeof(WCHAR
);
325 len2
= String2
->Length
/ sizeof(WCHAR
);
326 s1
= String1
->Buffer
;
327 s2
= String2
->Buffer
;
335 c1
= len1
-- ? RtlUpcaseUnicodeChar (*s1
++) : 0;
336 c2
= len2
-- ? RtlUpcaseUnicodeChar (*s2
++) : 0;
337 if (!c1
|| !c2
|| c1
!= c2
)
345 c1
= len1
-- ? *s1
++ : 0;
346 c2
= len2
-- ? *s2
++ : 0;
347 if (!c1
|| !c2
|| c1
!= c2
)
359 RtlCopyString(IN OUT PSTRING DestinationString
,
360 IN PSTRING SourceString
)
365 if(SourceString
== NULL
)
367 DestinationString
->Length
= 0;
371 copylen
= min (DestinationString
->MaximumLength
- sizeof(CHAR
),
372 SourceString
->Length
);
373 Src
= SourceString
->Buffer
;
374 Dest
= DestinationString
->Buffer
;
376 for (i
= 0; i
< copylen
; i
++)
384 DestinationString
->Length
= copylen
;
389 RtlCopyUnicodeString(IN OUT PUNICODE_STRING DestinationString
,
390 IN PUNICODE_STRING SourceString
)
395 if(SourceString
==NULL
)
397 DestinationString
->Length
=0;
401 copylen
= min(DestinationString
->MaximumLength
- sizeof(WCHAR
),
402 SourceString
->Length
);
403 Src
= SourceString
->Buffer
;
404 Dest
= DestinationString
->Buffer
;
406 for (i
= 0; i
< (copylen
/ sizeof (WCHAR
)); i
++)
414 DestinationString
->Length
= copylen
;
419 RtlCreateUnicodeString(IN OUT PUNICODE_STRING Destination
,
424 Length
= (wcslen (Source
) + 1) * sizeof(WCHAR
);
426 Destination
->Buffer
= ExAllocatePoolWithTag (NonPagedPool
,
429 if (Destination
->Buffer
== NULL
)
432 memmove (Destination
->Buffer
,
436 Destination
->MaximumLength
= Length
;
437 Destination
->Length
= Length
- sizeof (WCHAR
);
444 RtlCreateUnicodeStringFromAsciiz(IN OUT PUNICODE_STRING Destination
,
447 ANSI_STRING AnsiString
;
450 RtlInitAnsiString(&AnsiString
,
453 Status
= RtlAnsiStringToUnicodeString(Destination
,
457 return(NT_SUCCESS(Status
));
462 RtlDowncaseUnicodeString(IN OUT PUNICODE_STRING DestinationString
,
463 IN PUNICODE_STRING SourceString
,
464 IN BOOLEAN AllocateDestinationString
)
469 if (AllocateDestinationString
== TRUE
)
471 DestinationString
->MaximumLength
= SourceString
->Length
+ sizeof(WCHAR
);
472 DestinationString
->Buffer
=
473 ExAllocatePoolWithTag (NonPagedPool
,
474 SourceString
->Length
+ sizeof(WCHAR
),
476 if (DestinationString
->Buffer
== NULL
)
477 return STATUS_NO_MEMORY
;
481 if (SourceString
->Length
>= DestinationString
->MaximumLength
)
482 return STATUS_BUFFER_TOO_SMALL
;
484 DestinationString
->Length
= SourceString
->Length
;
486 Src
= SourceString
->Buffer
;
487 Dest
= DestinationString
->Buffer
;
488 for (i
=0; i
< SourceString
->Length
/ sizeof(WCHAR
); i
++)
494 else if (*Src
<= L
'Z')
496 *Dest
= (*Src
+ (L
'a' - L
'A'));
500 /* FIXME: characters above 'Z' */
509 return STATUS_SUCCESS
;
514 RtlEqualString(IN PSTRING String1
,
516 IN BOOLEAN CaseInsensitive
)
518 unsigned long s1l
=String1
->Length
;
519 unsigned long s2l
=String2
->Length
;
526 for (i
= 0; i
< s1l
; i
++)
528 c1
= *String1
->Buffer
;
529 c2
= *String2
->Buffer
;
531 if (CaseInsensitive
== TRUE
)
533 c1
= RtlUpperChar (c1
);
534 c2
= RtlUpperChar (c2
);
539 String1
->Buffer
-= i
;
540 String2
->Buffer
-= i
;
548 String1
->Buffer
-= i
;
549 String2
->Buffer
-= i
;
556 RtlEqualUnicodeString(IN PUNICODE_STRING String1
,
557 IN PUNICODE_STRING String2
,
558 IN BOOLEAN CaseInsensitive
)
560 unsigned long s1l
= String1
->Length
/ sizeof(WCHAR
);
561 unsigned long s2l
= String2
->Length
/ sizeof(WCHAR
);
569 pw1
= String1
->Buffer
;
570 pw2
= String2
->Buffer
;
572 for (i
= 0; i
< s1l
; i
++)
574 if(CaseInsensitive
== TRUE
)
576 wc1
= RtlUpcaseUnicodeChar (*pw1
);
577 wc2
= RtlUpcaseUnicodeChar (*pw2
);
597 RtlFreeAnsiString(IN PANSI_STRING AnsiString
)
599 if (AnsiString
->Buffer
== NULL
)
602 ExFreePool (AnsiString
->Buffer
);
604 AnsiString
->Buffer
= NULL
;
605 AnsiString
->Length
= 0;
606 AnsiString
->MaximumLength
= 0;
611 RtlFreeOemString(IN POEM_STRING OemString
)
613 if (OemString
->Buffer
== NULL
)
616 ExFreePool (OemString
->Buffer
);
618 OemString
->Buffer
= NULL
;
619 OemString
->Length
= 0;
620 OemString
->MaximumLength
= 0;
625 RtlFreeUnicodeString(IN PUNICODE_STRING UnicodeString
)
627 if (UnicodeString
->Buffer
== NULL
)
630 ExFreePool (UnicodeString
->Buffer
);
632 UnicodeString
->Buffer
= NULL
;
633 UnicodeString
->Length
= 0;
634 UnicodeString
->MaximumLength
= 0;
639 RtlInitAnsiString(IN OUT PANSI_STRING DestinationString
,
640 IN PCSZ SourceString
)
644 if (SourceString
== NULL
)
646 DestinationString
->Length
= 0;
647 DestinationString
->MaximumLength
= 0;
651 DestSize
= strlen ((const char *)SourceString
);
652 DestinationString
->Length
= DestSize
;
653 DestinationString
->MaximumLength
= DestSize
+ sizeof(CHAR
);
655 DestinationString
->Buffer
= (PCHAR
)SourceString
;
660 RtlInitString(IN OUT PSTRING DestinationString
,
661 IN PCSZ SourceString
)
665 if (SourceString
== NULL
)
667 DestinationString
->Length
= 0;
668 DestinationString
->MaximumLength
= 0;
672 DestSize
= strlen((const char *)SourceString
);
673 DestinationString
->Length
= DestSize
;
674 DestinationString
->MaximumLength
= DestSize
+ sizeof(CHAR
);
676 DestinationString
->Buffer
= (PCHAR
)SourceString
;
681 RtlInitUnicodeString(IN OUT PUNICODE_STRING DestinationString
,
682 IN PCWSTR SourceString
)
686 DPRINT("RtlInitUnicodeString(DestinationString %x, SourceString %x)\n",
690 if (SourceString
== NULL
)
692 DestinationString
->Length
= 0;
693 DestinationString
->MaximumLength
= 0;
697 DestSize
= wcslen((PWSTR
)SourceString
) * sizeof(WCHAR
);
698 DestinationString
->Length
= DestSize
;
699 DestinationString
->MaximumLength
= DestSize
+ sizeof(WCHAR
);
701 DestinationString
->Buffer
= (PWSTR
)SourceString
;
706 RtlIntegerToChar(IN ULONG Value
,
722 if ((Radix
!= 2) && (Radix
!= 8) &&
723 (Radix
!= 10) && (Radix
!= 16))
724 return STATUS_INVALID_PARAMETER
;
727 while (v
|| tp
== temp
)
738 if (tp
- temp
>= Length
)
739 return STATUS_BUFFER_TOO_SMALL
;
746 return STATUS_SUCCESS
;
751 RtlIntegerToUnicodeString(IN ULONG Value
,
752 IN ULONG Base
, /* optional */
753 IN OUT PUNICODE_STRING String
)
755 ANSI_STRING AnsiString
;
759 Status
= RtlIntegerToChar (Value
,
763 if (!NT_SUCCESS(Status
))
766 AnsiString
.Buffer
= Buffer
;
767 AnsiString
.Length
= strlen (Buffer
);
768 AnsiString
.MaximumLength
= 33;
770 Status
= RtlAnsiStringToUnicodeString (String
,
779 RtlOemStringToCountedUnicodeString(IN OUT PUNICODE_STRING DestinationString
,
780 IN POEM_STRING SourceString
,
781 IN BOOLEAN AllocateDestinationString
)
786 if (NlsMbCodePageTag
== TRUE
)
787 Length
= RtlAnsiStringToUnicodeSize (SourceString
);
789 Length
= SourceString
->Length
* sizeof(WCHAR
);
792 return STATUS_INVALID_PARAMETER_2
;
794 if (AllocateDestinationString
== TRUE
)
796 DestinationString
->MaximumLength
= Length
+ sizeof(WCHAR
);
797 DestinationString
->Buffer
=
798 ExAllocatePoolWithTag (NonPagedPool
,
799 DestinationString
->MaximumLength
,
801 if (DestinationString
->Buffer
== NULL
)
802 return STATUS_NO_MEMORY
;
806 if (Length
> DestinationString
->MaximumLength
)
807 return STATUS_BUFFER_TOO_SMALL
;
809 DestinationString
->Length
= Length
;
811 RtlZeroMemory (DestinationString
->Buffer
,
812 DestinationString
->Length
);
814 Status
= RtlOemToUnicodeN (DestinationString
->Buffer
,
815 DestinationString
->Length
,
817 SourceString
->Buffer
,
818 SourceString
->Length
);
819 if (!NT_SUCCESS(Status
))
821 if (AllocateDestinationString
)
822 ExFreePool (DestinationString
->Buffer
);
827 DestinationString
->Buffer
[Length
/ sizeof(WCHAR
)] = 0;
829 return STATUS_SUCCESS
;
834 RtlOemStringToUnicodeSize(IN POEM_STRING OemString
)
838 RtlMultiByteToUnicodeSize(&Size
,
847 RtlOemStringToUnicodeString(IN OUT PUNICODE_STRING DestinationString
,
848 IN POEM_STRING SourceString
,
849 IN BOOLEAN AllocateDestinationString
)
854 if (NlsMbCodePageTag
== TRUE
)
855 Length
= RtlAnsiStringToUnicodeSize (SourceString
);
857 Length
= SourceString
->Length
* sizeof(WCHAR
);
860 return STATUS_INVALID_PARAMETER_2
;
862 if (AllocateDestinationString
== TRUE
)
864 DestinationString
->MaximumLength
= Length
+ sizeof(WCHAR
);
865 DestinationString
->Buffer
=
866 ExAllocatePoolWithTag (NonPagedPool
,
867 DestinationString
->MaximumLength
,
869 if (DestinationString
->Buffer
== NULL
)
870 return STATUS_NO_MEMORY
;
874 if (Length
+ sizeof(WCHAR
) > DestinationString
->MaximumLength
)
876 DPRINT("STATUS_BUFFER_TOO_SMALL\n");
877 return STATUS_BUFFER_TOO_SMALL
;
880 DestinationString
->Length
= Length
;
882 RtlZeroMemory (DestinationString
->Buffer
,
883 DestinationString
->Length
);
885 Status
= RtlOemToUnicodeN (DestinationString
->Buffer
,
886 DestinationString
->Length
,
888 SourceString
->Buffer
,
889 SourceString
->Length
);
890 if (!NT_SUCCESS(Status
))
892 if (AllocateDestinationString
)
893 ExFreePool (DestinationString
->Buffer
);
897 DestinationString
->Buffer
[Length
/ sizeof(WCHAR
)] = 0;
899 return STATUS_SUCCESS
;
904 RtlPrefixString(IN PANSI_STRING String1
,
905 IN PANSI_STRING String2
,
906 IN BOOLEAN CaseInsensitive
)
912 if (String2
->Length
< String1
->Length
)
915 Length
= String1
->Length
;
916 pc1
= String1
->Buffer
;
917 pc2
= String2
->Buffer
;
925 if (RtlUpperChar (*pc1
++) != RtlUpperChar (*pc2
++))
933 if (*pc1
++ != *pc2
++)
944 RtlPrefixUnicodeString(IN PUNICODE_STRING String1
,
945 IN PUNICODE_STRING String2
,
946 IN BOOLEAN CaseInsensitive
)
952 if (String2
->Length
< String1
->Length
)
955 Length
= String1
->Length
/ 2;
956 pc1
= String1
->Buffer
;
957 pc2
= String2
->Buffer
;
965 if (RtlUpcaseUnicodeChar (*pc1
++)
966 != RtlUpcaseUnicodeChar (*pc2
++))
974 if( *pc1
++ != *pc2
++ )
985 RtlUnicodeStringToAnsiSize(IN PUNICODE_STRING UnicodeString
)
989 RtlUnicodeToMultiByteSize(&Size
,
990 UnicodeString
->Buffer
,
991 UnicodeString
->Length
);
998 RtlUnicodeStringToAnsiString(IN OUT PANSI_STRING DestinationString
,
999 IN PUNICODE_STRING SourceString
,
1000 IN BOOLEAN AllocateDestinationString
)
1005 if (NlsMbCodePageTag
== TRUE
)
1006 Length
= RtlUnicodeStringToAnsiSize (SourceString
);
1008 Length
= SourceString
->Length
/ sizeof(WCHAR
);
1010 if (AllocateDestinationString
== TRUE
)
1012 DestinationString
->MaximumLength
= Length
+ sizeof(CHAR
);
1013 DestinationString
->Buffer
=
1014 ExAllocatePoolWithTag (NonPagedPool
,
1015 DestinationString
->MaximumLength
,
1017 if (DestinationString
->Buffer
== NULL
)
1018 return STATUS_NO_MEMORY
;
1022 if (Length
>= DestinationString
->MaximumLength
)
1023 return STATUS_BUFFER_TOO_SMALL
;
1025 DestinationString
->Length
= Length
;
1027 RtlZeroMemory (DestinationString
->Buffer
,
1028 DestinationString
->Length
);
1030 Status
= RtlUnicodeToMultiByteN (DestinationString
->Buffer
,
1031 DestinationString
->Length
,
1033 SourceString
->Buffer
,
1034 SourceString
->Length
);
1035 if (!NT_SUCCESS(Status
))
1037 if (AllocateDestinationString
)
1038 ExFreePool (DestinationString
->Buffer
);
1042 DestinationString
->Buffer
[Length
] = 0;
1044 return STATUS_SUCCESS
;
1049 RtlUnicodeStringToCountedOemString(IN OUT POEM_STRING DestinationString
,
1050 IN PUNICODE_STRING SourceString
,
1051 IN BOOLEAN AllocateDestinationString
)
1057 if (NlsMbOemCodePageTag
== TRUE
)
1058 Length
= RtlUnicodeStringToAnsiSize (SourceString
) + 1;
1060 Length
= SourceString
->Length
/ sizeof(WCHAR
) + 1;
1062 if (Length
> 0x0000FFFF)
1063 return STATUS_INVALID_PARAMETER_2
;
1065 DestinationString
->Length
= (WORD
)(Length
- 1);
1067 if (AllocateDestinationString
)
1069 DestinationString
->Buffer
= ExAllocatePoolWithTag (NonPagedPool
,
1073 if (DestinationString
->Buffer
== NULL
)
1074 return STATUS_NO_MEMORY
;
1076 RtlZeroMemory (DestinationString
->Buffer
,
1078 DestinationString
->MaximumLength
= (WORD
)Length
;
1082 if (Length
> DestinationString
->MaximumLength
)
1084 if (DestinationString
->MaximumLength
== 0)
1085 return STATUS_BUFFER_OVERFLOW
;
1086 DestinationString
->Length
=
1087 DestinationString
->MaximumLength
- 1;
1091 Status
= RtlUnicodeToOemN (DestinationString
->Buffer
,
1092 DestinationString
->Length
,
1094 SourceString
->Buffer
,
1095 SourceString
->Length
);
1096 if (!NT_SUCCESS(Status
))
1098 if (AllocateDestinationString
)
1099 ExFreePool (DestinationString
->Buffer
);
1104 DestinationString
->Buffer
[Size
] = 0;
1106 return STATUS_SUCCESS
;
1111 RtlUnicodeStringToInteger(IN PUNICODE_STRING String
,
1119 BOOLEAN addneg
= FALSE
;
1122 Str
= String
->Buffer
;
1124 for (i
= 0; i
< String
->Length
/ sizeof(WCHAR
); i
++)
1131 else if (*Str
== L
'o')
1136 else if (*Str
== L
'd')
1141 else if (*Str
== L
'x')
1146 else if (*Str
== L
'+')
1150 else if (*Str
== L
'-')
1155 else if ((*Str
> L
'1') && (Base
== 2))
1157 return STATUS_INVALID_PARAMETER
;
1159 else if (((*Str
> L
'7') || (*Str
< L
'0')) && (Base
== 8))
1161 return STATUS_INVALID_PARAMETER
;
1163 else if (((*Str
> L
'9') || (*Str
< L
'0')) && (Base
== 10))
1165 return STATUS_INVALID_PARAMETER
;
1167 else if ((((*Str
> L
'9') || (*Str
< L
'0')) ||
1168 ((towupper (*Str
) > L
'F') ||
1169 (towupper (*Str
) < L
'A'))) && (Base
== 16))
1171 return STATUS_INVALID_PARAMETER
;
1177 Str
= String
->Buffer
+ lenmin
;
1182 while (iswxdigit (*Str
) &&
1183 (Val
= iswdigit (*Str
) ? *Str
- L
'0' : (iswlower (*Str
)
1184 ? toupper (*Str
) : *Str
) - L
'A' + 10) < Base
)
1186 *Value
= *Value
* Base
+ Val
;
1193 return STATUS_SUCCESS
;
1198 RtlUnicodeStringToOemSize(IN PUNICODE_STRING UnicodeString
)
1202 RtlUnicodeToMultiByteSize(&Size
,
1203 UnicodeString
->Buffer
,
1204 UnicodeString
->Length
);
1210 RtlUnicodeStringToOemString(IN OUT POEM_STRING DestinationString
,
1211 IN PUNICODE_STRING SourceString
,
1212 IN BOOLEAN AllocateDestinationString
)
1217 if (NlsMbOemCodePageTag
== TRUE
)
1218 Length
= RtlUnicodeStringToAnsiSize (SourceString
);
1220 Length
= SourceString
->Length
/ sizeof(WCHAR
);
1222 if (AllocateDestinationString
== TRUE
)
1224 DestinationString
->MaximumLength
= Length
+ sizeof(CHAR
);
1225 DestinationString
->Buffer
=
1226 ExAllocatePoolWithTag (NonPagedPool
,
1227 DestinationString
->MaximumLength
,
1229 if (DestinationString
->Buffer
== NULL
)
1230 return STATUS_NO_MEMORY
;
1234 if (Length
>= DestinationString
->MaximumLength
)
1235 return STATUS_BUFFER_TOO_SMALL
;
1237 DestinationString
->Length
= Length
;
1239 RtlZeroMemory(DestinationString
->Buffer
,
1240 DestinationString
->Length
);
1242 Status
= RtlUnicodeToOemN(DestinationString
->Buffer
,
1243 DestinationString
->Length
,
1245 SourceString
->Buffer
,
1246 SourceString
->Length
);
1247 if (!NT_SUCCESS(Status
))
1249 if (AllocateDestinationString
)
1250 ExFreePool(DestinationString
->Buffer
);
1254 DestinationString
->Buffer
[Length
] = 0;
1256 return STATUS_SUCCESS
;
1261 RtlUpcaseUnicodeChar(IN WCHAR Source
)
1267 return(Source
- (L
'a' - L
'A'));
1269 /* FIXME: characters above 'z' */
1276 RtlUpcaseUnicodeString(IN OUT PUNICODE_STRING DestinationString
,
1277 IN PUNICODE_STRING SourceString
,
1278 IN BOOLEAN AllocateDestinationString
)
1283 if (AllocateDestinationString
== TRUE
)
1285 DestinationString
->MaximumLength
= SourceString
->Length
+ sizeof(WCHAR
);
1286 DestinationString
->Buffer
=
1287 ExAllocatePoolWithTag(NonPagedPool
,
1288 SourceString
->Length
+ sizeof(WCHAR
),
1290 if (DestinationString
->Buffer
== NULL
)
1291 return(STATUS_NO_MEMORY
);
1295 if (SourceString
->Length
>= DestinationString
->MaximumLength
)
1296 return(STATUS_BUFFER_TOO_SMALL
);
1298 DestinationString
->Length
= SourceString
->Length
;
1300 Src
= SourceString
->Buffer
;
1301 Dest
= DestinationString
->Buffer
;
1302 for (i
=0; i
< SourceString
->Length
/ sizeof(WCHAR
); i
++)
1304 *Dest
= RtlUpcaseUnicodeChar(*Src
);
1310 return(STATUS_SUCCESS
);
1315 RtlUpcaseUnicodeStringToAnsiString(IN OUT PANSI_STRING DestinationString
,
1316 IN PUNICODE_STRING SourceString
,
1317 IN BOOLEAN AllocateDestinationString
)
1322 if (NlsMbCodePageTag
== TRUE
)
1323 Length
= RtlUnicodeStringToAnsiSize(SourceString
);
1325 Length
= SourceString
->Length
/ sizeof(WCHAR
);
1327 if (AllocateDestinationString
== TRUE
)
1329 DestinationString
->MaximumLength
= Length
+ sizeof(CHAR
);
1330 DestinationString
->Buffer
=
1331 ExAllocatePoolWithTag(NonPagedPool
,
1332 DestinationString
->MaximumLength
,
1334 if (DestinationString
->Buffer
== NULL
)
1335 return(STATUS_NO_MEMORY
);
1339 if (Length
>= DestinationString
->MaximumLength
)
1340 return(STATUS_BUFFER_TOO_SMALL
);
1342 DestinationString
->Length
= Length
;
1344 RtlZeroMemory(DestinationString
->Buffer
,
1345 DestinationString
->Length
);
1347 Status
= RtlUpcaseUnicodeToMultiByteN(DestinationString
->Buffer
,
1348 DestinationString
->Length
,
1350 SourceString
->Buffer
,
1351 SourceString
->Length
);
1352 if (!NT_SUCCESS(Status
))
1354 if (AllocateDestinationString
)
1355 ExFreePool(DestinationString
->Buffer
);
1359 DestinationString
->Buffer
[Length
] = 0;
1361 return(STATUS_SUCCESS
);
1366 RtlUpcaseUnicodeStringToCountedOemString(IN OUT POEM_STRING DestinationString
,
1367 IN PUNICODE_STRING SourceString
,
1368 IN BOOLEAN AllocateDestinationString
)
1374 if (NlsMbCodePageTag
== TRUE
)
1375 Length
= RtlUnicodeStringToAnsiSize (SourceString
) + 1;
1377 Length
= SourceString
->Length
/ sizeof(WCHAR
) + 1;
1379 if (Length
> 0x0000FFFF)
1380 return(STATUS_INVALID_PARAMETER_2
);
1382 DestinationString
->Length
= (WORD
)(Length
- 1);
1384 if (AllocateDestinationString
== TRUE
)
1386 DestinationString
->Buffer
=
1387 ExAllocatePoolWithTag(NonPagedPool
,
1390 if (DestinationString
->Buffer
== NULL
)
1391 return(STATUS_NO_MEMORY
);
1393 RtlZeroMemory(DestinationString
->Buffer
,
1395 DestinationString
->MaximumLength
= (WORD
)Length
;
1399 if (Length
> DestinationString
->MaximumLength
)
1401 if (DestinationString
->MaximumLength
== 0)
1402 return(STATUS_BUFFER_OVERFLOW
);
1403 DestinationString
->Length
=
1404 DestinationString
->MaximumLength
- 1;
1408 Status
= RtlUpcaseUnicodeToOemN(DestinationString
->Buffer
,
1409 DestinationString
->Length
,
1411 SourceString
->Buffer
,
1412 SourceString
->Length
);
1413 if (!NT_SUCCESS(Status
))
1415 if (AllocateDestinationString
)
1416 ExFreePool(DestinationString
->Buffer
);
1420 DestinationString
->Buffer
[Size
] = 0;
1422 return(STATUS_SUCCESS
);
1427 RtlUpcaseUnicodeStringToOemString(IN OUT POEM_STRING DestinationString
,
1428 IN PUNICODE_STRING SourceString
,
1429 IN BOOLEAN AllocateDestinationString
)
1434 if (NlsMbOemCodePageTag
== TRUE
)
1435 Length
= RtlUnicodeStringToOemSize(SourceString
);
1437 Length
= SourceString
->Length
/ sizeof(WCHAR
);
1439 if (AllocateDestinationString
== TRUE
)
1441 DestinationString
->MaximumLength
= Length
+ sizeof(CHAR
);
1442 DestinationString
->Buffer
=
1443 ExAllocatePoolWithTag(NonPagedPool
,
1444 DestinationString
->MaximumLength
,
1446 if (DestinationString
->Buffer
== NULL
)
1447 return(STATUS_NO_MEMORY
);
1451 if (Length
>= DestinationString
->MaximumLength
)
1452 return(STATUS_BUFFER_TOO_SMALL
);
1454 DestinationString
->Length
= Length
;
1456 RtlZeroMemory(DestinationString
->Buffer
,
1457 DestinationString
->Length
);
1459 Status
= RtlUpcaseUnicodeToOemN(DestinationString
->Buffer
,
1460 DestinationString
->Length
,
1462 SourceString
->Buffer
,
1463 SourceString
->Length
);
1464 if (!NT_SUCCESS(Status
))
1466 if (AllocateDestinationString
)
1467 ExFreePool(DestinationString
->Buffer
);
1471 DestinationString
->Buffer
[Length
] = 0;
1473 return(STATUS_SUCCESS
);
1478 RtlUpperChar(IN CHAR Source
)
1483 if (NlsMbCodePageTag
== FALSE
)
1485 /* single-byte code page */
1487 Unicode
= (WCHAR
)Source
;
1489 Unicode
= NlsAnsiToUnicodeData
[Source
];
1492 /* upcase conversion */
1493 Unicode
= RtlUpcaseUnicodeChar (Unicode
);
1495 /* unicode -> ansi */
1496 Destination
= (CHAR
)Unicode
;
1498 Destination
= NlsUnicodeToAnsiData
[Unicode
];
1503 /* single-byte code page */
1504 /* FIXME: implement the multi-byte stuff!! */
1505 Destination
= Source
;
1508 return(Destination
);
1513 RtlUpperString(PSTRING DestinationString
,
1514 PSTRING SourceString
)
1521 Length
= min(SourceString
->Length
,
1522 DestinationString
->MaximumLength
- 1);
1524 Src
= SourceString
->Buffer
;
1525 Dest
= DestinationString
->Buffer
;
1526 for (i
= 0; i
< Length
; i
++)
1528 *Dest
= RtlUpperChar(*Src
);
1534 DestinationString
->Length
= SourceString
->Length
;
1539 RtlxAnsiStringToUnicodeSize(IN PANSI_STRING AnsiString
)
1541 return(RtlAnsiStringToUnicodeSize(AnsiString
));
1546 RtlxOemStringToUnicodeSize(IN POEM_STRING OemString
)
1548 return(RtlOemStringToUnicodeSize((PANSI_STRING
)OemString
));
1553 RtlxUnicodeStringToAnsiSize(IN PUNICODE_STRING UnicodeString
)
1555 return(RtlUnicodeStringToAnsiSize(UnicodeString
));
1560 RtlxUnicodeStringToOemSize(IN PUNICODE_STRING UnicodeString
)
1562 return(RtlUnicodeStringToOemSize(UnicodeString
));