1 /* $Id: unicode.c,v 1.32 2003/09/04 06:41:35 vizzini 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 * PROGRAMMERS: Jason Filby (jasonfilby@yahoo.com)
8 * Vizzini (vizzini@plasmic.com)
13 #include <ddk/ntddk.h>
15 #include <ntos/minmax.h>
16 #include <internal/pool.h>
17 #include <internal/nls.h>
20 #include <internal/debug.h>
23 /* GLOBALS *******************************************************************/
25 #define TAG_USTR TAG('U', 'S', 'T', 'R')
26 #define TAG_ASTR TAG('A', 'S', 'T', 'R')
27 #define TAG_OSTR TAG('O', 'S', 'T', 'R')
30 /* FUNCTIONS *****************************************************************/
34 RtlAnsiCharToUnicodeChar(IN CHAR AnsiChar
)
41 Size
= (NlsLeadByteInfo
[AnsiChar
] == 0) ? 1 : 2;
44 RtlMultiByteToUnicodeN(&UnicodeChar
,
59 RtlAnsiStringToUnicodeSize(IN PANSI_STRING AnsiString
)
63 RtlMultiByteToUnicodeSize(&Size
,
76 RtlAnsiStringToUnicodeString(IN OUT PUNICODE_STRING DestinationString
,
77 IN PANSI_STRING SourceString
,
78 IN BOOLEAN AllocateDestinationString
)
83 if (NlsMbCodePageTag
== TRUE
)
84 Length
= RtlAnsiStringToUnicodeSize (SourceString
);
86 Length
= SourceString
->Length
* sizeof(WCHAR
);
89 return STATUS_INVALID_PARAMETER_2
;
91 if (AllocateDestinationString
== TRUE
)
93 DestinationString
->MaximumLength
= Length
+ sizeof(WCHAR
);
94 DestinationString
->Buffer
=
95 ExAllocatePoolWithTag (NonPagedPool
,
96 DestinationString
->MaximumLength
,
98 if (DestinationString
->Buffer
== NULL
)
99 return STATUS_NO_MEMORY
;
103 if (Length
+ sizeof(WCHAR
) > DestinationString
->MaximumLength
)
105 DPRINT("STATUS_BUFFER_TOO_SMALL\n");
106 return STATUS_BUFFER_TOO_SMALL
;
109 DestinationString
->Length
= Length
;
111 RtlZeroMemory (DestinationString
->Buffer
,
112 DestinationString
->Length
);
114 Status
= RtlMultiByteToUnicodeN (DestinationString
->Buffer
,
115 DestinationString
->Length
,
117 SourceString
->Buffer
,
118 SourceString
->Length
);
119 if (!NT_SUCCESS(Status
))
121 if (AllocateDestinationString
)
122 ExFreePool (DestinationString
->Buffer
);
126 DestinationString
->Buffer
[Length
/ sizeof(WCHAR
)] = 0;
128 return STATUS_SUCCESS
;
137 RtlAppendAsciizToString(IN OUT PSTRING Destination
,
144 return STATUS_SUCCESS
;
146 Length
= strlen (Source
);
147 if (Destination
->Length
+ Length
>= Destination
->MaximumLength
)
148 return STATUS_BUFFER_TOO_SMALL
;
150 Ptr
= Destination
->Buffer
+ Destination
->Length
;
157 Destination
->Length
+= Length
;
159 return STATUS_SUCCESS
;
168 RtlAppendStringToString(IN OUT PSTRING Destination
,
173 if (Source
->Length
== 0)
174 return(STATUS_SUCCESS
);
176 if (Destination
->Length
+ Source
->Length
>= Destination
->MaximumLength
)
177 return(STATUS_BUFFER_TOO_SMALL
);
179 Ptr
= Destination
->Buffer
+ Destination
->Length
;
183 Ptr
+= Source
->Length
;
186 Destination
->Length
+= Source
->Length
;
188 return(STATUS_SUCCESS
);
197 RtlAppendUnicodeStringToString(IN OUT PUNICODE_STRING Destination
,
198 IN PUNICODE_STRING Source
)
201 if ((Source
->Length
+ Destination
->Length
) >= Destination
->MaximumLength
)
202 return STATUS_BUFFER_TOO_SMALL
;
204 memcpy((PVOID
)Destination
->Buffer
+ Destination
->Length
, Source
->Buffer
, Source
->Length
);
205 Destination
->Length
+= Source
->Length
;
206 Destination
->Buffer
[Destination
->Length
/ sizeof(WCHAR
)] = 0;
208 return STATUS_SUCCESS
;
216 RtlAppendUnicodeToString(IN OUT PUNICODE_STRING Destination
,
221 slen
= wcslen(Source
) * sizeof(WCHAR
);
223 if (Destination
->Length
+ slen
>= Destination
->MaximumLength
)
224 return(STATUS_BUFFER_TOO_SMALL
);
226 memcpy((PVOID
)Destination
->Buffer
+ Destination
->Length
, Source
, slen
+ sizeof(WCHAR
));
227 Destination
->Length
+= slen
;
229 return(STATUS_SUCCESS
);
238 RtlCharToInteger(IN PCSZ String
,
253 if ((*String
== 'x') && isxdigit (String
[1]))
261 if (!isxdigit (*String
))
262 return(STATUS_INVALID_PARAMETER
);
264 while (isxdigit (*String
) &&
265 (Val
= isdigit (*String
) ? * String
- '0' : (islower (*String
)
266 ? toupper (*String
) : *String
) - 'A' + 10) < Base
)
268 *Value
= *Value
* Base
+ Val
;
272 return(STATUS_SUCCESS
);
281 RtlCompareString(IN PSTRING String1
,
283 IN BOOLEAN CaseInsensitive
)
289 if (String1
&& String2
)
291 len1
= String1
->Length
;
292 len2
= String2
->Length
;
293 s1
= String1
->Buffer
;
294 s2
= String2
->Buffer
;
302 c1
= len1
-- ? RtlUpperChar (*s1
++) : 0;
303 c2
= len2
-- ? RtlUpperChar (*s2
++) : 0;
304 if (!c1
|| !c2
|| c1
!= c2
)
312 c1
= len1
-- ? *s1
++ : 0;
313 c2
= len2
-- ? *s2
++ : 0;
314 if (!c1
|| !c2
|| c1
!= c2
)
330 RtlCompareUnicodeString(IN PUNICODE_STRING String1
,
331 IN PUNICODE_STRING String2
,
332 IN BOOLEAN CaseInsensitive
)
338 if (String1
&& String2
)
340 len1
= String1
->Length
/ sizeof(WCHAR
);
341 len2
= String2
->Length
/ sizeof(WCHAR
);
342 s1
= String1
->Buffer
;
343 s2
= String2
->Buffer
;
351 c1
= len1
-- ? RtlUpcaseUnicodeChar (*s1
++) : 0;
352 c2
= len2
-- ? RtlUpcaseUnicodeChar (*s2
++) : 0;
353 if (!c1
|| !c2
|| c1
!= c2
)
361 c1
= len1
-- ? *s1
++ : 0;
362 c2
= len2
-- ? *s2
++ : 0;
363 if (!c1
|| !c2
|| c1
!= c2
)
379 RtlCopyString(IN OUT PSTRING DestinationString
,
380 IN PSTRING SourceString
)
384 if(SourceString
== NULL
)
386 DestinationString
->Length
= 0;
390 copylen
= min (DestinationString
->MaximumLength
- sizeof(CHAR
),
391 SourceString
->Length
);
393 memcpy(DestinationString
->Buffer
, SourceString
->Buffer
, copylen
);
394 DestinationString
->Buffer
[copylen
] = 0;
395 DestinationString
->Length
= copylen
;
404 RtlCopyUnicodeString(IN OUT PUNICODE_STRING DestinationString
,
405 IN PUNICODE_STRING SourceString
)
409 if(SourceString
==NULL
)
411 DestinationString
->Length
=0;
415 copylen
= min(DestinationString
->MaximumLength
- sizeof(WCHAR
),
416 SourceString
->Length
);
417 memcpy(DestinationString
->Buffer
, SourceString
->Buffer
, copylen
);
418 DestinationString
->Buffer
[copylen
/ sizeof(WCHAR
)] = 0;
419 DestinationString
->Length
= copylen
;
428 RtlCreateUnicodeString(IN OUT PUNICODE_STRING Destination
,
433 Length
= (wcslen (Source
) + 1) * sizeof(WCHAR
);
435 Destination
->Buffer
= ExAllocatePoolWithTag (NonPagedPool
,
438 if (Destination
->Buffer
== NULL
)
441 memmove (Destination
->Buffer
,
445 Destination
->MaximumLength
= Length
;
446 Destination
->Length
= Length
- sizeof (WCHAR
);
454 RtlCreateUnicodeStringFromAsciiz(IN OUT PUNICODE_STRING Destination
,
457 ANSI_STRING AnsiString
;
460 RtlInitAnsiString(&AnsiString
,
463 Status
= RtlAnsiStringToUnicodeString(Destination
,
467 return(NT_SUCCESS(Status
));
475 RtlDowncaseUnicodeString(IN OUT PUNICODE_STRING DestinationString
,
476 IN PUNICODE_STRING SourceString
,
477 IN BOOLEAN AllocateDestinationString
)
482 if (AllocateDestinationString
== TRUE
)
484 DestinationString
->MaximumLength
= SourceString
->Length
+ sizeof(WCHAR
);
485 DestinationString
->Buffer
=
486 ExAllocatePoolWithTag (NonPagedPool
,
487 SourceString
->Length
+ sizeof(WCHAR
),
489 if (DestinationString
->Buffer
== NULL
)
490 return STATUS_NO_MEMORY
;
494 if (SourceString
->Length
>= DestinationString
->MaximumLength
)
495 return STATUS_BUFFER_TOO_SMALL
;
497 DestinationString
->Length
= SourceString
->Length
;
499 Src
= SourceString
->Buffer
;
500 Dest
= DestinationString
->Buffer
;
501 for (i
=0; i
< SourceString
->Length
/ sizeof(WCHAR
); i
++)
507 else if (*Src
<= L
'Z')
509 *Dest
= (*Src
+ (L
'a' - L
'A'));
513 *Dest
= RtlDowncaseUnicodeChar(*Src
);
521 return STATUS_SUCCESS
;
530 RtlEqualString(IN PSTRING String1
,
532 IN BOOLEAN CaseInsensitive
)
534 unsigned long s1l
=String1
->Length
;
535 unsigned long s2l
=String2
->Length
;
542 for (i
= 0; i
< s1l
; i
++)
544 c1
= *String1
->Buffer
;
545 c2
= *String2
->Buffer
;
547 if (CaseInsensitive
== TRUE
)
549 c1
= RtlUpperChar (c1
);
550 c2
= RtlUpperChar (c2
);
555 String1
->Buffer
-= i
;
556 String2
->Buffer
-= i
;
564 String1
->Buffer
-= i
;
565 String2
->Buffer
-= i
;
576 RtlEqualUnicodeString(IN PUNICODE_STRING String1
,
577 IN PUNICODE_STRING String2
,
578 IN BOOLEAN CaseInsensitive
)
580 unsigned long s1l
= String1
->Length
/ sizeof(WCHAR
);
581 unsigned long s2l
= String2
->Length
/ sizeof(WCHAR
);
589 pw1
= String1
->Buffer
;
590 pw2
= String2
->Buffer
;
592 for (i
= 0; i
< s1l
; i
++)
594 if(CaseInsensitive
== TRUE
)
596 wc1
= RtlUpcaseUnicodeChar (*pw1
);
597 wc2
= RtlUpcaseUnicodeChar (*pw2
);
621 RtlFreeAnsiString(IN PANSI_STRING AnsiString
)
623 if (AnsiString
->Buffer
== NULL
)
626 ExFreePool (AnsiString
->Buffer
);
628 AnsiString
->Buffer
= NULL
;
629 AnsiString
->Length
= 0;
630 AnsiString
->MaximumLength
= 0;
639 RtlFreeOemString(IN POEM_STRING OemString
)
641 if (OemString
->Buffer
== NULL
)
644 ExFreePool (OemString
->Buffer
);
646 OemString
->Buffer
= NULL
;
647 OemString
->Length
= 0;
648 OemString
->MaximumLength
= 0;
657 RtlFreeUnicodeString(IN PUNICODE_STRING UnicodeString
)
659 if (UnicodeString
->Buffer
== NULL
)
662 ExFreePool (UnicodeString
->Buffer
);
664 UnicodeString
->Buffer
= NULL
;
665 UnicodeString
->Length
= 0;
666 UnicodeString
->MaximumLength
= 0;
675 RtlInitAnsiString(IN OUT PANSI_STRING DestinationString
,
676 IN PCSZ SourceString
)
680 if (SourceString
== NULL
)
682 DestinationString
->Length
= 0;
683 DestinationString
->MaximumLength
= 0;
687 DestSize
= strlen ((const char *)SourceString
);
688 DestinationString
->Length
= DestSize
;
689 DestinationString
->MaximumLength
= DestSize
+ sizeof(CHAR
);
691 DestinationString
->Buffer
= (PCHAR
)SourceString
;
700 RtlInitString(IN OUT PSTRING DestinationString
,
701 IN PCSZ SourceString
)
705 if (SourceString
== NULL
)
707 DestinationString
->Length
= 0;
708 DestinationString
->MaximumLength
= 0;
712 DestSize
= strlen((const char *)SourceString
);
713 DestinationString
->Length
= DestSize
;
714 DestinationString
->MaximumLength
= DestSize
+ sizeof(CHAR
);
716 DestinationString
->Buffer
= (PCHAR
)SourceString
;
725 RtlInitUnicodeString(IN OUT PUNICODE_STRING DestinationString
,
726 IN PCWSTR SourceString
)
730 DPRINT("RtlInitUnicodeString(DestinationString %x, SourceString %x)\n",
734 if (SourceString
== NULL
)
736 DestinationString
->Length
= 0;
737 DestinationString
->MaximumLength
= 0;
741 DestSize
= wcslen((PWSTR
)SourceString
) * sizeof(WCHAR
);
742 DestinationString
->Length
= DestSize
;
743 DestinationString
->MaximumLength
= DestSize
+ sizeof(WCHAR
);
745 DestinationString
->Buffer
= (PWSTR
)SourceString
;
754 RtlIntegerToChar(IN ULONG Value
,
770 if ((Radix
!= 2) && (Radix
!= 8) &&
771 (Radix
!= 10) && (Radix
!= 16))
772 return STATUS_INVALID_PARAMETER
;
775 while (v
|| tp
== temp
)
786 if ((ULONG
) (tp
- temp
) >= Length
)
787 return STATUS_BUFFER_TOO_SMALL
;
794 return STATUS_SUCCESS
;
803 RtlIntegerToUnicodeString(IN ULONG Value
,
804 IN ULONG Base
, /* optional */
805 IN OUT PUNICODE_STRING String
)
807 ANSI_STRING AnsiString
;
811 Status
= RtlIntegerToChar (Value
,
815 if (!NT_SUCCESS(Status
))
818 AnsiString
.Buffer
= Buffer
;
819 AnsiString
.Length
= strlen (Buffer
);
820 AnsiString
.MaximumLength
= 33;
822 Status
= RtlAnsiStringToUnicodeString (String
,
835 RtlOemStringToCountedUnicodeString(IN OUT PUNICODE_STRING DestinationString
,
836 IN POEM_STRING SourceString
,
837 IN BOOLEAN AllocateDestinationString
)
842 if (NlsMbCodePageTag
== TRUE
)
843 Length
= RtlAnsiStringToUnicodeSize (SourceString
);
845 Length
= SourceString
->Length
* sizeof(WCHAR
);
848 return STATUS_INVALID_PARAMETER_2
;
850 if (AllocateDestinationString
== TRUE
)
852 DestinationString
->MaximumLength
= Length
+ sizeof(WCHAR
);
853 DestinationString
->Buffer
=
854 ExAllocatePoolWithTag (NonPagedPool
,
855 DestinationString
->MaximumLength
,
857 if (DestinationString
->Buffer
== NULL
)
858 return STATUS_NO_MEMORY
;
862 if (Length
> DestinationString
->MaximumLength
)
863 return STATUS_BUFFER_TOO_SMALL
;
865 DestinationString
->Length
= Length
;
867 RtlZeroMemory (DestinationString
->Buffer
,
868 DestinationString
->Length
);
870 Status
= RtlOemToUnicodeN (DestinationString
->Buffer
,
871 DestinationString
->Length
,
873 SourceString
->Buffer
,
874 SourceString
->Length
);
875 if (!NT_SUCCESS(Status
))
877 if (AllocateDestinationString
)
878 ExFreePool (DestinationString
->Buffer
);
883 DestinationString
->Buffer
[Length
/ sizeof(WCHAR
)] = 0;
885 return STATUS_SUCCESS
;
894 RtlOemStringToUnicodeSize(IN POEM_STRING OemString
)
898 RtlMultiByteToUnicodeSize(&Size
,
911 RtlOemStringToUnicodeString(IN OUT PUNICODE_STRING DestinationString
,
912 IN POEM_STRING SourceString
,
913 IN BOOLEAN AllocateDestinationString
)
918 if (NlsMbCodePageTag
== TRUE
)
919 Length
= RtlAnsiStringToUnicodeSize (SourceString
);
921 Length
= SourceString
->Length
* sizeof(WCHAR
);
924 return STATUS_INVALID_PARAMETER_2
;
926 if (AllocateDestinationString
== TRUE
)
928 DestinationString
->MaximumLength
= Length
+ sizeof(WCHAR
);
929 DestinationString
->Buffer
=
930 ExAllocatePoolWithTag (NonPagedPool
,
931 DestinationString
->MaximumLength
,
933 if (DestinationString
->Buffer
== NULL
)
934 return STATUS_NO_MEMORY
;
938 if (Length
+ sizeof(WCHAR
) > DestinationString
->MaximumLength
)
940 DPRINT("STATUS_BUFFER_TOO_SMALL\n");
941 return STATUS_BUFFER_TOO_SMALL
;
944 DestinationString
->Length
= Length
;
946 RtlZeroMemory (DestinationString
->Buffer
,
947 DestinationString
->Length
);
949 Status
= RtlOemToUnicodeN (DestinationString
->Buffer
,
950 DestinationString
->Length
,
952 SourceString
->Buffer
,
953 SourceString
->Length
);
954 if (!NT_SUCCESS(Status
))
956 if (AllocateDestinationString
)
957 ExFreePool (DestinationString
->Buffer
);
961 DestinationString
->Buffer
[Length
/ sizeof(WCHAR
)] = 0;
963 return STATUS_SUCCESS
;
972 RtlPrefixString(IN PANSI_STRING String1
,
973 IN PANSI_STRING String2
,
974 IN BOOLEAN CaseInsensitive
)
980 if (String2
->Length
< String1
->Length
)
983 Length
= String1
->Length
;
984 pc1
= String1
->Buffer
;
985 pc2
= String2
->Buffer
;
993 if (RtlUpperChar (*pc1
++) != RtlUpperChar (*pc2
++))
1001 if (*pc1
++ != *pc2
++)
1016 RtlPrefixUnicodeString(IN PUNICODE_STRING String1
,
1017 IN PUNICODE_STRING String2
,
1018 IN BOOLEAN CaseInsensitive
)
1024 if (String2
->Length
< String1
->Length
)
1027 Length
= String1
->Length
/ 2;
1028 pc1
= String1
->Buffer
;
1029 pc2
= String2
->Buffer
;
1033 if (CaseInsensitive
)
1037 if (RtlUpcaseUnicodeChar (*pc1
++)
1038 != RtlUpcaseUnicodeChar (*pc2
++))
1046 if( *pc1
++ != *pc2
++ )
1061 RtlUnicodeStringToAnsiSize(IN PUNICODE_STRING UnicodeString
)
1065 RtlUnicodeToMultiByteSize(&Size
,
1066 UnicodeString
->Buffer
,
1067 UnicodeString
->Length
);
1078 RtlUnicodeStringToAnsiString(IN OUT PANSI_STRING DestinationString
,
1079 IN PUNICODE_STRING SourceString
,
1080 IN BOOLEAN AllocateDestinationString
)
1085 if (NlsMbCodePageTag
== TRUE
){
1086 Length
= RtlUnicodeStringToAnsiSize (SourceString
); Length
--;
1089 Length
= SourceString
->Length
/ sizeof(WCHAR
);
1091 if (AllocateDestinationString
== TRUE
)
1093 DestinationString
->MaximumLength
= Length
+ sizeof(CHAR
);
1094 DestinationString
->Buffer
=
1095 ExAllocatePoolWithTag (NonPagedPool
,
1096 DestinationString
->MaximumLength
,
1098 if (DestinationString
->Buffer
== NULL
)
1099 return STATUS_NO_MEMORY
;
1103 if (Length
>= DestinationString
->MaximumLength
)
1104 return STATUS_BUFFER_TOO_SMALL
;
1106 DestinationString
->Length
= Length
;
1108 RtlZeroMemory (DestinationString
->Buffer
,
1109 DestinationString
->Length
);
1111 Status
= RtlUnicodeToMultiByteN (DestinationString
->Buffer
,
1112 DestinationString
->Length
,
1114 SourceString
->Buffer
,
1115 SourceString
->Length
);
1116 if (!NT_SUCCESS(Status
))
1118 if (AllocateDestinationString
)
1119 ExFreePool (DestinationString
->Buffer
);
1123 DestinationString
->Buffer
[Length
] = 0;
1125 return STATUS_SUCCESS
;
1134 RtlUnicodeStringToCountedOemString(IN OUT POEM_STRING DestinationString
,
1135 IN PUNICODE_STRING SourceString
,
1136 IN BOOLEAN AllocateDestinationString
)
1142 if (NlsMbOemCodePageTag
== TRUE
)
1143 Length
= RtlUnicodeStringToAnsiSize (SourceString
)/* + 1*/;
1145 Length
= SourceString
->Length
/ sizeof(WCHAR
) + 1;
1147 if (Length
> 0x0000FFFF)
1148 return STATUS_INVALID_PARAMETER_2
;
1150 DestinationString
->Length
= (WORD
)(Length
- 1);
1152 if (AllocateDestinationString
)
1154 DestinationString
->Buffer
= ExAllocatePoolWithTag (NonPagedPool
,
1158 if (DestinationString
->Buffer
== NULL
)
1159 return STATUS_NO_MEMORY
;
1161 RtlZeroMemory (DestinationString
->Buffer
,
1163 DestinationString
->MaximumLength
= (WORD
)Length
;
1167 if (Length
> DestinationString
->MaximumLength
)
1169 if (DestinationString
->MaximumLength
== 0)
1170 return STATUS_BUFFER_OVERFLOW
;
1171 DestinationString
->Length
=
1172 DestinationString
->MaximumLength
- 1;
1176 Status
= RtlUnicodeToOemN (DestinationString
->Buffer
,
1177 DestinationString
->Length
,
1179 SourceString
->Buffer
,
1180 SourceString
->Length
);
1181 if (!NT_SUCCESS(Status
))
1183 if (AllocateDestinationString
)
1184 ExFreePool (DestinationString
->Buffer
);
1189 DestinationString
->Buffer
[Size
] = 0;
1191 return STATUS_SUCCESS
;
1200 RtlUnicodeStringToInteger(IN PUNICODE_STRING InString
,
1204 BOOLEAN Negative
= 0;
1205 PWCHAR String
= InString
->Buffer
;
1206 ULONG MaxLen
= InString
->Length
/ sizeof(WCHAR
);
1215 else if(*String
== L
'+')
1228 else if(*String
== L
'o')
1233 else if(*String
== L
'x')
1242 while(*String
&& MaxLen
)
1248 if(c
>= 'a' && c
<= 'f')
1251 /* validate chars for bases <= 10 */
1252 if( Base
<= 10 && (c
< '0' || c
> '9') )
1253 return STATUS_INVALID_PARAMETER
;
1255 /* validate chars for base 16 */
1256 else if( (c
< '0' || c
> '9') && (c
< 'A' || c
> 'F') )
1257 return STATUS_INVALID_PARAMETER
;
1259 /* perhaps someday we'll validate additional bases */
1261 if(c
>= 'A' && c
<= 'F')
1262 *Value
= *Value
* Base
+ c
- 'A' + 10;
1264 *Value
= *Value
* Base
+ c
- '0';
1270 return STATUS_SUCCESS
;
1278 RtlUnicodeStringToOemSize(IN PUNICODE_STRING UnicodeString
)
1282 RtlUnicodeToMultiByteSize(&Size
,
1283 UnicodeString
->Buffer
,
1284 UnicodeString
->Length
);
1294 RtlUnicodeStringToOemString(IN OUT POEM_STRING DestinationString
,
1295 IN PUNICODE_STRING SourceString
,
1296 IN BOOLEAN AllocateDestinationString
)
1301 if (NlsMbOemCodePageTag
== TRUE
){
1302 Length
= RtlUnicodeStringToAnsiSize (SourceString
); Length
--;
1305 Length
= SourceString
->Length
/ sizeof(WCHAR
);
1307 if (AllocateDestinationString
== TRUE
)
1309 DestinationString
->MaximumLength
= Length
+ sizeof(CHAR
);
1310 DestinationString
->Buffer
=
1311 ExAllocatePoolWithTag (NonPagedPool
,
1312 DestinationString
->MaximumLength
,
1314 if (DestinationString
->Buffer
== NULL
)
1315 return STATUS_NO_MEMORY
;
1319 if (Length
>= DestinationString
->MaximumLength
)
1320 return STATUS_BUFFER_TOO_SMALL
;
1322 DestinationString
->Length
= Length
;
1324 RtlZeroMemory(DestinationString
->Buffer
,
1325 DestinationString
->Length
);
1327 Status
= RtlUnicodeToOemN(DestinationString
->Buffer
,
1328 DestinationString
->Length
,
1330 SourceString
->Buffer
,
1331 SourceString
->Length
);
1332 if (!NT_SUCCESS(Status
))
1334 if (AllocateDestinationString
)
1335 ExFreePool(DestinationString
->Buffer
);
1339 DestinationString
->Buffer
[Length
] = 0;
1341 return STATUS_SUCCESS
;
1349 RtlUpcaseUnicodeString(IN OUT PUNICODE_STRING DestinationString
,
1350 IN PCUNICODE_STRING SourceString
,
1351 IN BOOLEAN AllocateDestinationString
)
1356 if (AllocateDestinationString
== TRUE
)
1358 DestinationString
->MaximumLength
= SourceString
->Length
+ sizeof(WCHAR
);
1359 DestinationString
->Buffer
=
1360 ExAllocatePoolWithTag(NonPagedPool
,
1361 SourceString
->Length
+ sizeof(WCHAR
),
1363 if (DestinationString
->Buffer
== NULL
)
1364 return(STATUS_NO_MEMORY
);
1368 if (SourceString
->Length
>= DestinationString
->MaximumLength
)
1369 return(STATUS_BUFFER_TOO_SMALL
);
1371 DestinationString
->Length
= SourceString
->Length
;
1373 Src
= SourceString
->Buffer
;
1374 Dest
= DestinationString
->Buffer
;
1375 for (i
=0; i
< SourceString
->Length
/ sizeof(WCHAR
); i
++)
1377 *Dest
= RtlUpcaseUnicodeChar(*Src
);
1383 return(STATUS_SUCCESS
);
1391 RtlUpcaseUnicodeStringToAnsiString(IN OUT PANSI_STRING DestinationString
,
1392 IN PUNICODE_STRING SourceString
,
1393 IN BOOLEAN AllocateDestinationString
)
1398 if (NlsMbCodePageTag
== TRUE
)
1400 Length
= RtlUnicodeStringToAnsiSize(SourceString
);
1404 Length
= SourceString
->Length
/ sizeof(WCHAR
);
1406 if (AllocateDestinationString
== TRUE
)
1408 DestinationString
->MaximumLength
= Length
+ sizeof(CHAR
);
1409 DestinationString
->Buffer
=
1410 ExAllocatePoolWithTag(NonPagedPool
,
1411 DestinationString
->MaximumLength
,
1413 if (DestinationString
->Buffer
== NULL
)
1414 return(STATUS_NO_MEMORY
);
1418 if (Length
>= DestinationString
->MaximumLength
)
1419 return(STATUS_BUFFER_TOO_SMALL
);
1421 DestinationString
->Length
= Length
;
1423 RtlZeroMemory(DestinationString
->Buffer
,
1424 DestinationString
->Length
);
1426 Status
= RtlUpcaseUnicodeToMultiByteN(DestinationString
->Buffer
,
1427 DestinationString
->Length
,
1429 SourceString
->Buffer
,
1430 SourceString
->Length
);
1431 if (!NT_SUCCESS(Status
))
1433 if (AllocateDestinationString
)
1434 ExFreePool(DestinationString
->Buffer
);
1438 DestinationString
->Buffer
[Length
] = 0;
1440 return(STATUS_SUCCESS
);
1448 RtlUpcaseUnicodeStringToCountedOemString(IN OUT POEM_STRING DestinationString
,
1449 IN PUNICODE_STRING SourceString
,
1450 IN BOOLEAN AllocateDestinationString
)
1456 if (NlsMbCodePageTag
== TRUE
)
1457 Length
= RtlUnicodeStringToAnsiSize (SourceString
)/* + 1*/;
1459 Length
= SourceString
->Length
/ sizeof(WCHAR
) + 1;
1461 if (Length
> 0x0000FFFF)
1462 return(STATUS_INVALID_PARAMETER_2
);
1464 DestinationString
->Length
= (WORD
)(Length
- 1);
1466 if (AllocateDestinationString
== TRUE
)
1468 DestinationString
->Buffer
=
1469 ExAllocatePoolWithTag(NonPagedPool
,
1472 if (DestinationString
->Buffer
== NULL
)
1473 return(STATUS_NO_MEMORY
);
1475 RtlZeroMemory(DestinationString
->Buffer
,
1477 DestinationString
->MaximumLength
= (WORD
)Length
;
1481 if (Length
> DestinationString
->MaximumLength
)
1483 if (DestinationString
->MaximumLength
== 0)
1484 return(STATUS_BUFFER_OVERFLOW
);
1485 DestinationString
->Length
=
1486 DestinationString
->MaximumLength
- 1;
1490 Status
= RtlUpcaseUnicodeToOemN(DestinationString
->Buffer
,
1491 DestinationString
->Length
,
1493 SourceString
->Buffer
,
1494 SourceString
->Length
);
1495 if (!NT_SUCCESS(Status
))
1497 if (AllocateDestinationString
)
1498 ExFreePool(DestinationString
->Buffer
);
1502 DestinationString
->Buffer
[Size
] = 0;
1504 return(STATUS_SUCCESS
);
1512 RtlUpcaseUnicodeStringToOemString(IN OUT POEM_STRING DestinationString
,
1513 IN PUNICODE_STRING SourceString
,
1514 IN BOOLEAN AllocateDestinationString
)
1519 if (NlsMbOemCodePageTag
== TRUE
) {
1520 Length
= RtlUnicodeStringToOemSize(SourceString
); Length
--;
1523 Length
= SourceString
->Length
/ sizeof(WCHAR
);
1525 if (AllocateDestinationString
== TRUE
)
1527 DestinationString
->MaximumLength
= Length
+ sizeof(CHAR
);
1528 DestinationString
->Buffer
=
1529 ExAllocatePoolWithTag(NonPagedPool
,
1530 DestinationString
->MaximumLength
,
1532 if (DestinationString
->Buffer
== NULL
)
1533 return(STATUS_NO_MEMORY
);
1537 if (Length
>= DestinationString
->MaximumLength
)
1538 return(STATUS_BUFFER_TOO_SMALL
);
1540 DestinationString
->Length
= Length
;
1542 RtlZeroMemory(DestinationString
->Buffer
,
1543 DestinationString
->Length
);
1545 Status
= RtlUpcaseUnicodeToOemN(DestinationString
->Buffer
,
1546 DestinationString
->Length
,
1548 SourceString
->Buffer
,
1549 SourceString
->Length
);
1550 if (!NT_SUCCESS(Status
))
1552 if (AllocateDestinationString
)
1553 ExFreePool(DestinationString
->Buffer
);
1557 DestinationString
->Buffer
[Length
] = 0;
1559 return(STATUS_SUCCESS
);
1567 RtlUpperString(PSTRING DestinationString
,
1568 PSTRING SourceString
)
1575 Length
= min(SourceString
->Length
,
1576 DestinationString
->MaximumLength
- 1);
1578 Src
= SourceString
->Buffer
;
1579 Dest
= DestinationString
->Buffer
;
1580 for (i
= 0; i
< Length
; i
++)
1582 *Dest
= RtlUpperChar(*Src
);
1588 DestinationString
->Length
= SourceString
->Length
;
1596 RtlxAnsiStringToUnicodeSize(IN PANSI_STRING AnsiString
)
1598 return RtlAnsiStringToUnicodeSize(AnsiString
);
1606 RtlxOemStringToUnicodeSize(IN POEM_STRING OemString
)
1608 return RtlOemStringToUnicodeSize((PANSI_STRING
)OemString
);
1616 RtlxUnicodeStringToAnsiSize(IN PUNICODE_STRING UnicodeString
)
1618 return RtlUnicodeStringToAnsiSize(UnicodeString
);
1626 RtlxUnicodeStringToOemSize(IN PUNICODE_STRING UnicodeString
)
1628 return RtlUnicodeStringToOemSize(UnicodeString
);