1 /* $Id: unicode.c,v 1.25 2002/11/10 18:17:42 chorns 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 ((ULONG
) (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
); Length
--;
1009 Length
= SourceString
->Length
/ sizeof(WCHAR
);
1011 if (AllocateDestinationString
== TRUE
)
1013 DestinationString
->MaximumLength
= Length
+ sizeof(CHAR
);
1014 DestinationString
->Buffer
=
1015 ExAllocatePoolWithTag (NonPagedPool
,
1016 DestinationString
->MaximumLength
,
1018 if (DestinationString
->Buffer
== NULL
)
1019 return STATUS_NO_MEMORY
;
1023 if (Length
>= DestinationString
->MaximumLength
)
1024 return STATUS_BUFFER_TOO_SMALL
;
1026 DestinationString
->Length
= Length
;
1028 RtlZeroMemory (DestinationString
->Buffer
,
1029 DestinationString
->Length
);
1031 Status
= RtlUnicodeToMultiByteN (DestinationString
->Buffer
,
1032 DestinationString
->Length
,
1034 SourceString
->Buffer
,
1035 SourceString
->Length
);
1036 if (!NT_SUCCESS(Status
))
1038 if (AllocateDestinationString
)
1039 ExFreePool (DestinationString
->Buffer
);
1043 DestinationString
->Buffer
[Length
] = 0;
1045 return STATUS_SUCCESS
;
1050 RtlUnicodeStringToCountedOemString(IN OUT POEM_STRING DestinationString
,
1051 IN PUNICODE_STRING SourceString
,
1052 IN BOOLEAN AllocateDestinationString
)
1058 if (NlsMbOemCodePageTag
== TRUE
)
1059 Length
= RtlUnicodeStringToAnsiSize (SourceString
)/* + 1*/;
1061 Length
= SourceString
->Length
/ sizeof(WCHAR
) + 1;
1063 if (Length
> 0x0000FFFF)
1064 return STATUS_INVALID_PARAMETER_2
;
1066 DestinationString
->Length
= (WORD
)(Length
- 1);
1068 if (AllocateDestinationString
)
1070 DestinationString
->Buffer
= ExAllocatePoolWithTag (NonPagedPool
,
1074 if (DestinationString
->Buffer
== NULL
)
1075 return STATUS_NO_MEMORY
;
1077 RtlZeroMemory (DestinationString
->Buffer
,
1079 DestinationString
->MaximumLength
= (WORD
)Length
;
1083 if (Length
> DestinationString
->MaximumLength
)
1085 if (DestinationString
->MaximumLength
== 0)
1086 return STATUS_BUFFER_OVERFLOW
;
1087 DestinationString
->Length
=
1088 DestinationString
->MaximumLength
- 1;
1092 Status
= RtlUnicodeToOemN (DestinationString
->Buffer
,
1093 DestinationString
->Length
,
1095 SourceString
->Buffer
,
1096 SourceString
->Length
);
1097 if (!NT_SUCCESS(Status
))
1099 if (AllocateDestinationString
)
1100 ExFreePool (DestinationString
->Buffer
);
1105 DestinationString
->Buffer
[Size
] = 0;
1107 return STATUS_SUCCESS
;
1112 RtlUnicodeStringToInteger(IN PUNICODE_STRING String
,
1120 BOOLEAN addneg
= FALSE
;
1123 Str
= String
->Buffer
;
1125 for (i
= 0; i
< String
->Length
/ sizeof(WCHAR
); i
++)
1132 else if (*Str
== L
'o')
1137 else if (*Str
== L
'd')
1142 else if (*Str
== L
'x')
1147 else if (*Str
== L
'+')
1151 else if (*Str
== L
'-')
1156 else if ((*Str
> L
'1') && (Base
== 2))
1158 return STATUS_INVALID_PARAMETER
;
1160 else if (((*Str
> L
'7') || (*Str
< L
'0')) && (Base
== 8))
1162 return STATUS_INVALID_PARAMETER
;
1164 else if (((*Str
> L
'9') || (*Str
< L
'0')) && (Base
== 10))
1166 return STATUS_INVALID_PARAMETER
;
1168 else if ((((*Str
> L
'9') || (*Str
< L
'0')) ||
1169 ((towupper (*Str
) > L
'F') ||
1170 (towupper (*Str
) < L
'A'))) && (Base
== 16))
1172 return STATUS_INVALID_PARAMETER
;
1178 Str
= String
->Buffer
+ lenmin
;
1183 while (iswxdigit (*Str
) &&
1184 (Val
= iswdigit (*Str
) ? *Str
- L
'0' : (iswlower (*Str
)
1185 ? toupper (*Str
) : *Str
) - L
'A' + 10) < Base
)
1187 *Value
= *Value
* Base
+ Val
;
1194 return STATUS_SUCCESS
;
1199 RtlUnicodeStringToOemSize(IN PUNICODE_STRING UnicodeString
)
1203 RtlUnicodeToMultiByteSize(&Size
,
1204 UnicodeString
->Buffer
,
1205 UnicodeString
->Length
);
1211 RtlUnicodeStringToOemString(IN OUT POEM_STRING DestinationString
,
1212 IN PUNICODE_STRING SourceString
,
1213 IN BOOLEAN AllocateDestinationString
)
1218 if (NlsMbOemCodePageTag
== TRUE
){
1219 Length
= RtlUnicodeStringToAnsiSize (SourceString
); Length
--;
1222 Length
= SourceString
->Length
/ sizeof(WCHAR
);
1224 if (AllocateDestinationString
== TRUE
)
1226 DestinationString
->MaximumLength
= Length
+ sizeof(CHAR
);
1227 DestinationString
->Buffer
=
1228 ExAllocatePoolWithTag (NonPagedPool
,
1229 DestinationString
->MaximumLength
,
1231 if (DestinationString
->Buffer
== NULL
)
1232 return STATUS_NO_MEMORY
;
1236 if (Length
>= DestinationString
->MaximumLength
)
1237 return STATUS_BUFFER_TOO_SMALL
;
1239 DestinationString
->Length
= Length
;
1241 RtlZeroMemory(DestinationString
->Buffer
,
1242 DestinationString
->Length
);
1244 Status
= RtlUnicodeToOemN(DestinationString
->Buffer
,
1245 DestinationString
->Length
,
1247 SourceString
->Buffer
,
1248 SourceString
->Length
);
1249 if (!NT_SUCCESS(Status
))
1251 if (AllocateDestinationString
)
1252 ExFreePool(DestinationString
->Buffer
);
1256 DestinationString
->Buffer
[Length
] = 0;
1258 return STATUS_SUCCESS
;
1263 RtlUpcaseUnicodeChar(IN WCHAR Source
)
1269 return(Source
- (L
'a' - L
'A'));
1271 /* FIXME: characters above 'z' */
1278 RtlUpcaseUnicodeString(IN OUT PUNICODE_STRING DestinationString
,
1279 IN PUNICODE_STRING SourceString
,
1280 IN BOOLEAN AllocateDestinationString
)
1285 if (AllocateDestinationString
== TRUE
)
1287 DestinationString
->MaximumLength
= SourceString
->Length
+ sizeof(WCHAR
);
1288 DestinationString
->Buffer
=
1289 ExAllocatePoolWithTag(NonPagedPool
,
1290 SourceString
->Length
+ sizeof(WCHAR
),
1292 if (DestinationString
->Buffer
== NULL
)
1293 return(STATUS_NO_MEMORY
);
1297 if (SourceString
->Length
>= DestinationString
->MaximumLength
)
1298 return(STATUS_BUFFER_TOO_SMALL
);
1300 DestinationString
->Length
= SourceString
->Length
;
1302 Src
= SourceString
->Buffer
;
1303 Dest
= DestinationString
->Buffer
;
1304 for (i
=0; i
< SourceString
->Length
/ sizeof(WCHAR
); i
++)
1306 *Dest
= RtlUpcaseUnicodeChar(*Src
);
1312 return(STATUS_SUCCESS
);
1317 RtlUpcaseUnicodeStringToAnsiString(IN OUT PANSI_STRING DestinationString
,
1318 IN PUNICODE_STRING SourceString
,
1319 IN BOOLEAN AllocateDestinationString
)
1324 if (NlsMbCodePageTag
== TRUE
){
1325 Length
= RtlUnicodeStringToAnsiSize(SourceString
); Length
--;
1328 Length
= SourceString
->Length
/ sizeof(WCHAR
);
1330 if (AllocateDestinationString
== TRUE
)
1332 DestinationString
->MaximumLength
= Length
+ sizeof(CHAR
);
1333 DestinationString
->Buffer
=
1334 ExAllocatePoolWithTag(NonPagedPool
,
1335 DestinationString
->MaximumLength
,
1337 if (DestinationString
->Buffer
== NULL
)
1338 return(STATUS_NO_MEMORY
);
1342 if (Length
>= DestinationString
->MaximumLength
)
1343 return(STATUS_BUFFER_TOO_SMALL
);
1345 DestinationString
->Length
= Length
;
1347 RtlZeroMemory(DestinationString
->Buffer
,
1348 DestinationString
->Length
);
1350 Status
= RtlUpcaseUnicodeToMultiByteN(DestinationString
->Buffer
,
1351 DestinationString
->Length
,
1353 SourceString
->Buffer
,
1354 SourceString
->Length
);
1355 if (!NT_SUCCESS(Status
))
1357 if (AllocateDestinationString
)
1358 ExFreePool(DestinationString
->Buffer
);
1362 DestinationString
->Buffer
[Length
] = 0;
1364 return(STATUS_SUCCESS
);
1369 RtlUpcaseUnicodeStringToCountedOemString(IN OUT POEM_STRING DestinationString
,
1370 IN PUNICODE_STRING SourceString
,
1371 IN BOOLEAN AllocateDestinationString
)
1377 if (NlsMbCodePageTag
== TRUE
)
1378 Length
= RtlUnicodeStringToAnsiSize (SourceString
)/* + 1*/;
1380 Length
= SourceString
->Length
/ sizeof(WCHAR
) + 1;
1382 if (Length
> 0x0000FFFF)
1383 return(STATUS_INVALID_PARAMETER_2
);
1385 DestinationString
->Length
= (WORD
)(Length
- 1);
1387 if (AllocateDestinationString
== TRUE
)
1389 DestinationString
->Buffer
=
1390 ExAllocatePoolWithTag(NonPagedPool
,
1393 if (DestinationString
->Buffer
== NULL
)
1394 return(STATUS_NO_MEMORY
);
1396 RtlZeroMemory(DestinationString
->Buffer
,
1398 DestinationString
->MaximumLength
= (WORD
)Length
;
1402 if (Length
> DestinationString
->MaximumLength
)
1404 if (DestinationString
->MaximumLength
== 0)
1405 return(STATUS_BUFFER_OVERFLOW
);
1406 DestinationString
->Length
=
1407 DestinationString
->MaximumLength
- 1;
1411 Status
= RtlUpcaseUnicodeToOemN(DestinationString
->Buffer
,
1412 DestinationString
->Length
,
1414 SourceString
->Buffer
,
1415 SourceString
->Length
);
1416 if (!NT_SUCCESS(Status
))
1418 if (AllocateDestinationString
)
1419 ExFreePool(DestinationString
->Buffer
);
1423 DestinationString
->Buffer
[Size
] = 0;
1425 return(STATUS_SUCCESS
);
1430 RtlUpcaseUnicodeStringToOemString(IN OUT POEM_STRING DestinationString
,
1431 IN PUNICODE_STRING SourceString
,
1432 IN BOOLEAN AllocateDestinationString
)
1437 if (NlsMbOemCodePageTag
== TRUE
) {
1438 Length
= RtlUnicodeStringToOemSize(SourceString
); Length
--;
1441 Length
= SourceString
->Length
/ sizeof(WCHAR
);
1443 if (AllocateDestinationString
== TRUE
)
1445 DestinationString
->MaximumLength
= Length
+ sizeof(CHAR
);
1446 DestinationString
->Buffer
=
1447 ExAllocatePoolWithTag(NonPagedPool
,
1448 DestinationString
->MaximumLength
,
1450 if (DestinationString
->Buffer
== NULL
)
1451 return(STATUS_NO_MEMORY
);
1455 if (Length
>= DestinationString
->MaximumLength
)
1456 return(STATUS_BUFFER_TOO_SMALL
);
1458 DestinationString
->Length
= Length
;
1460 RtlZeroMemory(DestinationString
->Buffer
,
1461 DestinationString
->Length
);
1463 Status
= RtlUpcaseUnicodeToOemN(DestinationString
->Buffer
,
1464 DestinationString
->Length
,
1466 SourceString
->Buffer
,
1467 SourceString
->Length
);
1468 if (!NT_SUCCESS(Status
))
1470 if (AllocateDestinationString
)
1471 ExFreePool(DestinationString
->Buffer
);
1475 DestinationString
->Buffer
[Length
] = 0;
1477 return(STATUS_SUCCESS
);
1482 RtlUpperChar(IN CHAR Source
)
1487 if (NlsMbCodePageTag
== FALSE
)
1489 /* single-byte code page */
1491 Unicode
= (WCHAR
)Source
;
1493 Unicode
= NlsAnsiToUnicodeData
[Source
];
1496 /* upcase conversion */
1497 Unicode
= RtlUpcaseUnicodeChar (Unicode
);
1499 /* unicode -> ansi */
1500 Destination
= (CHAR
)Unicode
;
1502 Destination
= NlsUnicodeToAnsiData
[Unicode
];
1507 /* single-byte code page */
1508 /* FIXME: implement the multi-byte stuff!! */
1509 Destination
= Source
;
1512 return(Destination
);
1517 RtlUpperString(PSTRING DestinationString
,
1518 PSTRING SourceString
)
1525 Length
= min(SourceString
->Length
,
1526 DestinationString
->MaximumLength
- 1);
1528 Src
= SourceString
->Buffer
;
1529 Dest
= DestinationString
->Buffer
;
1530 for (i
= 0; i
< Length
; i
++)
1532 *Dest
= RtlUpperChar(*Src
);
1538 DestinationString
->Length
= SourceString
->Length
;
1543 RtlxAnsiStringToUnicodeSize(IN PANSI_STRING AnsiString
)
1545 return(RtlAnsiStringToUnicodeSize(AnsiString
));
1550 RtlxOemStringToUnicodeSize(IN POEM_STRING OemString
)
1552 return(RtlOemStringToUnicodeSize((PANSI_STRING
)OemString
));
1557 RtlxUnicodeStringToAnsiSize(IN PUNICODE_STRING UnicodeString
)
1559 return(RtlUnicodeStringToAnsiSize(UnicodeString
));
1564 RtlxUnicodeStringToOemSize(IN PUNICODE_STRING UnicodeString
)
1566 return(RtlUnicodeStringToOemSize(UnicodeString
));