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 *****************************************************************/
31 RtlAnsiCharToUnicodeChar(IN CHAR AnsiChar)
38 Size = (NlsLeadByteInfo[AnsiChar] == 0) ? 1 : 2;
41 RtlMultiByteToUnicodeN(&UnicodeChar,
53 RtlAnsiStringToUnicodeSize(IN PANSI_STRING AnsiString)
57 RtlMultiByteToUnicodeSize(&Size,
67 RtlAnsiStringToUnicodeString(IN OUT PUNICODE_STRING DestinationString,
68 IN PANSI_STRING SourceString,
69 IN BOOLEAN AllocateDestinationString)
74 if (NlsMbCodePageTag == TRUE)
75 Length = RtlAnsiStringToUnicodeSize (SourceString);
77 Length = SourceString->Length * sizeof(WCHAR);
80 return STATUS_INVALID_PARAMETER_2;
82 if (AllocateDestinationString == TRUE)
84 DestinationString->MaximumLength = Length + sizeof(WCHAR);
85 DestinationString->Buffer =
86 ExAllocatePoolWithTag (NonPagedPool,
87 DestinationString->MaximumLength,
89 if (DestinationString->Buffer == NULL)
90 return STATUS_NO_MEMORY;
94 if (Length + sizeof(WCHAR) > DestinationString->MaximumLength)
96 DPRINT("STATUS_BUFFER_TOO_SMALL\n");
97 return STATUS_BUFFER_TOO_SMALL;
100 DestinationString->Length = Length;
102 RtlZeroMemory (DestinationString->Buffer,
103 DestinationString->Length);
105 Status = RtlMultiByteToUnicodeN (DestinationString->Buffer,
106 DestinationString->Length,
108 SourceString->Buffer,
109 SourceString->Length);
110 if (!NT_SUCCESS(Status))
112 if (AllocateDestinationString)
113 ExFreePool (DestinationString->Buffer);
117 DestinationString->Buffer[Length / sizeof(WCHAR)] = 0;
119 return STATUS_SUCCESS;
125 RtlAppendAsciizToString(IN OUT PSTRING Destination,
132 return STATUS_SUCCESS;
134 Length = strlen (Source);
135 if (Destination->Length + Length >= Destination->MaximumLength)
136 return STATUS_BUFFER_TOO_SMALL;
138 Ptr = Destination->Buffer + Destination->Length;
145 Destination->Length += Length;
147 return STATUS_SUCCESS;
153 RtlAppendStringToString(IN OUT PSTRING Destination,
158 if (Source->Length == 0)
159 return(STATUS_SUCCESS);
161 if (Destination->Length + Source->Length >= Destination->MaximumLength)
162 return(STATUS_BUFFER_TOO_SMALL);
164 Ptr = Destination->Buffer + Destination->Length;
168 Ptr += Source->Length;
171 Destination->Length += Source->Length;
173 return(STATUS_SUCCESS);
179 RtlAppendUnicodeStringToString(IN OUT PUNICODE_STRING Destination,
180 IN PUNICODE_STRING Source)
185 if ((Source->Length + Destination->Length) >= Destination->MaximumLength)
186 return STATUS_BUFFER_TOO_SMALL;
188 Src = Source->Buffer;
189 Dest = Destination->Buffer + (Destination->Length / sizeof (WCHAR));
190 for (i = 0; i < (Source->Length / sizeof(WCHAR)); i++)
198 Destination->Length += Source->Length;
200 return STATUS_SUCCESS;
205 RtlAppendUnicodeToString(IN OUT PUNICODE_STRING Destination,
213 slen = wcslen(Source) * sizeof(WCHAR);
215 if (Destination->Length + slen >= Destination->MaximumLength)
216 return(STATUS_BUFFER_TOO_SMALL);
219 Dest = Destination->Buffer + (Destination->Length / sizeof(WCHAR));
221 for (i = 0; i < (slen / sizeof(WCHAR)); i++)
229 Destination->Length += slen;
231 return(STATUS_SUCCESS);
237 RtlCharToInteger(IN PCSZ String,
252 if ((*String == 'x') && isxdigit (String[1]))
260 if (!isxdigit (*String))
261 return(STATUS_INVALID_PARAMETER);
263 while (isxdigit (*String) &&
264 (Val = isdigit (*String) ? * String - '0' : (islower (*String)
265 ? toupper (*String) : *String) - 'A' + 10) < Base)
267 *Value = *Value * Base + Val;
271 return(STATUS_SUCCESS);
277 RtlCompareString(IN PSTRING String1,
279 IN BOOLEAN CaseInsensitive)
285 if (String1 && String2)
287 len1 = String1->Length;
288 len2 = String2->Length;
289 s1 = String1->Buffer;
290 s2 = String2->Buffer;
298 c1 = len1-- ? RtlUpperChar (*s1++) : 0;
299 c2 = len2-- ? RtlUpperChar (*s2++) : 0;
300 if (!c1 || !c2 || c1 != c2)
308 c1 = len1-- ? *s1++ : 0;
309 c2 = len2-- ? *s2++ : 0;
310 if (!c1 || !c2 || c1 != c2)
323 RtlCompareUnicodeString(IN PUNICODE_STRING String1,
324 IN PUNICODE_STRING String2,
325 IN BOOLEAN CaseInsensitive)
331 if (String1 && String2)
333 len1 = String1->Length / sizeof(WCHAR);
334 len2 = String2->Length / sizeof(WCHAR);
335 s1 = String1->Buffer;
336 s2 = String2->Buffer;
344 c1 = len1-- ? RtlUpcaseUnicodeChar (*s1++) : 0;
345 c2 = len2-- ? RtlUpcaseUnicodeChar (*s2++) : 0;
346 if (!c1 || !c2 || c1 != c2)
354 c1 = len1-- ? *s1++ : 0;
355 c2 = len2-- ? *s2++ : 0;
356 if (!c1 || !c2 || c1 != c2)
369 RtlCopyString(IN OUT PSTRING DestinationString,
370 IN PSTRING SourceString)
375 if(SourceString == NULL)
377 DestinationString->Length = 0;
381 copylen = min (DestinationString->MaximumLength - sizeof(CHAR),
382 SourceString->Length);
383 Src = SourceString->Buffer;
384 Dest = DestinationString->Buffer;
386 for (i = 0; i < copylen; i++)
394 DestinationString->Length = copylen;
400 RtlCopyUnicodeString(IN OUT PUNICODE_STRING DestinationString,
401 IN PUNICODE_STRING SourceString)
406 if(SourceString==NULL)
408 DestinationString->Length=0;
412 copylen = min(DestinationString->MaximumLength - sizeof(WCHAR),
413 SourceString->Length);
414 Src = SourceString->Buffer;
415 Dest = DestinationString->Buffer;
417 for (i = 0; i < (copylen / sizeof (WCHAR)); i++)
425 DestinationString->Length = copylen;
431 RtlCreateUnicodeString(IN OUT PUNICODE_STRING Destination,
436 Length = (wcslen (Source) + 1) * sizeof(WCHAR);
438 Destination->Buffer = ExAllocatePoolWithTag (NonPagedPool,
441 if (Destination->Buffer == NULL)
444 memmove (Destination->Buffer,
448 Destination->MaximumLength = Length;
449 Destination->Length = Length - sizeof (WCHAR);
457 RtlCreateUnicodeStringFromAsciiz(IN OUT PUNICODE_STRING Destination,
460 ANSI_STRING AnsiString;
463 RtlInitAnsiString(&AnsiString,
466 Status = RtlAnsiStringToUnicodeString(Destination,
470 return(NT_SUCCESS(Status));
476 RtlDowncaseUnicodeString(IN OUT PUNICODE_STRING DestinationString,
477 IN PUNICODE_STRING SourceString,
478 IN BOOLEAN AllocateDestinationString)
483 if (AllocateDestinationString == TRUE)
485 DestinationString->MaximumLength = SourceString->Length + sizeof(WCHAR);
486 DestinationString->Buffer =
487 ExAllocatePoolWithTag (NonPagedPool,
488 SourceString->Length + sizeof(WCHAR),
490 if (DestinationString->Buffer == NULL)
491 return STATUS_NO_MEMORY;
495 if (SourceString->Length >= DestinationString->MaximumLength)
496 return STATUS_BUFFER_TOO_SMALL;
498 DestinationString->Length = SourceString->Length;
500 Src = SourceString->Buffer;
501 Dest = DestinationString->Buffer;
502 for (i=0; i < SourceString->Length / sizeof(WCHAR); i++)
508 else if (*Src <= L'Z')
510 *Dest = (*Src + (L'a' - L'A'));
514 /* FIXME: characters above 'Z' */
523 return STATUS_SUCCESS;
529 RtlEqualString(IN PSTRING String1,
531 IN BOOLEAN CaseInsensitive)
533 unsigned long s1l=String1->Length;
534 unsigned long s2l=String2->Length;
541 for (i = 0; i < s1l; i++)
543 c1 = *String1->Buffer;
544 c2 = *String2->Buffer;
546 if (CaseInsensitive == TRUE)
548 c1 = RtlUpperChar (c1);
549 c2 = RtlUpperChar (c2);
554 String1->Buffer -= i;
555 String2->Buffer -= i;
563 String1->Buffer -= i;
564 String2->Buffer -= i;
572 RtlEqualUnicodeString(IN PUNICODE_STRING String1,
573 IN PUNICODE_STRING String2,
574 IN BOOLEAN CaseInsensitive)
576 unsigned long s1l = String1->Length / sizeof(WCHAR);
577 unsigned long s2l = String2->Length / sizeof(WCHAR);
585 pw1 = String1->Buffer;
586 pw2 = String2->Buffer;
588 for (i = 0; i < s1l; i++)
590 if(CaseInsensitive == TRUE)
592 wc1 = RtlUpcaseUnicodeChar (*pw1);
593 wc2 = RtlUpcaseUnicodeChar (*pw2);
614 RtlFreeAnsiString(IN PANSI_STRING AnsiString)
616 if (AnsiString->Buffer == NULL)
619 ExFreePool (AnsiString->Buffer);
621 AnsiString->Buffer = NULL;
622 AnsiString->Length = 0;
623 AnsiString->MaximumLength = 0;
629 RtlFreeOemString(IN POEM_STRING OemString)
631 if (OemString->Buffer == NULL)
634 ExFreePool (OemString->Buffer);
636 OemString->Buffer = NULL;
637 OemString->Length = 0;
638 OemString->MaximumLength = 0;
644 RtlFreeUnicodeString(IN PUNICODE_STRING UnicodeString)
646 if (UnicodeString->Buffer == NULL)
649 ExFreePool (UnicodeString->Buffer);
651 UnicodeString->Buffer = NULL;
652 UnicodeString->Length = 0;
653 UnicodeString->MaximumLength = 0;
659 RtlInitAnsiString(IN OUT PANSI_STRING DestinationString,
660 IN PCSZ SourceString)
664 if (SourceString == NULL)
666 DestinationString->Length = 0;
667 DestinationString->MaximumLength = 0;
671 DestSize = strlen ((const char *)SourceString);
672 DestinationString->Length = DestSize;
673 DestinationString->MaximumLength = DestSize + sizeof(CHAR);
675 DestinationString->Buffer = (PCHAR)SourceString;
681 RtlInitString(IN OUT PSTRING DestinationString,
682 IN PCSZ SourceString)
686 if (SourceString == NULL)
688 DestinationString->Length = 0;
689 DestinationString->MaximumLength = 0;
693 DestSize = strlen((const char *)SourceString);
694 DestinationString->Length = DestSize;
695 DestinationString->MaximumLength = DestSize + sizeof(CHAR);
697 DestinationString->Buffer = (PCHAR)SourceString;
703 RtlInitUnicodeString(IN OUT PUNICODE_STRING DestinationString,
704 IN PCWSTR SourceString)
708 DPRINT("RtlInitUnicodeString(DestinationString %x, SourceString %x)\n",
712 if (SourceString == NULL)
714 DestinationString->Length = 0;
715 DestinationString->MaximumLength = 0;
719 DestSize = wcslen((PWSTR)SourceString) * sizeof(WCHAR);
720 DestinationString->Length = DestSize;
721 DestinationString->MaximumLength = DestSize + sizeof(WCHAR);
723 DestinationString->Buffer = (PWSTR)SourceString;
729 RtlIntegerToChar(IN ULONG Value,
745 if ((Radix != 2) && (Radix != 8) &&
746 (Radix != 10) && (Radix != 16))
747 return STATUS_INVALID_PARAMETER;
750 while (v || tp == temp)
761 if ((ULONG) (tp - temp) >= Length)
762 return STATUS_BUFFER_TOO_SMALL;
769 return STATUS_SUCCESS;
775 RtlIntegerToUnicodeString(IN ULONG Value,
776 IN ULONG Base, /* optional */
777 IN OUT PUNICODE_STRING String)
779 ANSI_STRING AnsiString;
783 Status = RtlIntegerToChar (Value,
787 if (!NT_SUCCESS(Status))
790 AnsiString.Buffer = Buffer;
791 AnsiString.Length = strlen (Buffer);
792 AnsiString.MaximumLength = 33;
794 Status = RtlAnsiStringToUnicodeString (String,
804 RtlOemStringToCountedUnicodeString(IN OUT PUNICODE_STRING DestinationString,
805 IN POEM_STRING SourceString,
806 IN BOOLEAN AllocateDestinationString)
811 if (NlsMbCodePageTag == TRUE)
812 Length = RtlAnsiStringToUnicodeSize (SourceString);
814 Length = SourceString->Length * sizeof(WCHAR);
817 return STATUS_INVALID_PARAMETER_2;
819 if (AllocateDestinationString == TRUE)
821 DestinationString->MaximumLength = Length + sizeof(WCHAR);
822 DestinationString->Buffer =
823 ExAllocatePoolWithTag (NonPagedPool,
824 DestinationString->MaximumLength,
826 if (DestinationString->Buffer == NULL)
827 return STATUS_NO_MEMORY;
831 if (Length > DestinationString->MaximumLength)
832 return STATUS_BUFFER_TOO_SMALL;
834 DestinationString->Length = Length;
836 RtlZeroMemory (DestinationString->Buffer,
837 DestinationString->Length);
839 Status = RtlOemToUnicodeN (DestinationString->Buffer,
840 DestinationString->Length,
842 SourceString->Buffer,
843 SourceString->Length);
844 if (!NT_SUCCESS(Status))
846 if (AllocateDestinationString)
847 ExFreePool (DestinationString->Buffer);
852 DestinationString->Buffer[Length / sizeof(WCHAR)] = 0;
854 return STATUS_SUCCESS;
860 RtlOemStringToUnicodeSize(IN POEM_STRING OemString)
864 RtlMultiByteToUnicodeSize(&Size,
874 RtlOemStringToUnicodeString(IN OUT PUNICODE_STRING DestinationString,
875 IN POEM_STRING SourceString,
876 IN BOOLEAN AllocateDestinationString)
881 if (NlsMbCodePageTag == TRUE)
882 Length = RtlAnsiStringToUnicodeSize (SourceString);
884 Length = SourceString->Length * sizeof(WCHAR);
887 return STATUS_INVALID_PARAMETER_2;
889 if (AllocateDestinationString == TRUE)
891 DestinationString->MaximumLength = Length + sizeof(WCHAR);
892 DestinationString->Buffer =
893 ExAllocatePoolWithTag (NonPagedPool,
894 DestinationString->MaximumLength,
896 if (DestinationString->Buffer == NULL)
897 return STATUS_NO_MEMORY;
901 if (Length + sizeof(WCHAR) > DestinationString->MaximumLength)
903 DPRINT("STATUS_BUFFER_TOO_SMALL\n");
904 return STATUS_BUFFER_TOO_SMALL;
907 DestinationString->Length = Length;
909 RtlZeroMemory (DestinationString->Buffer,
910 DestinationString->Length);
912 Status = RtlOemToUnicodeN (DestinationString->Buffer,
913 DestinationString->Length,
915 SourceString->Buffer,
916 SourceString->Length);
917 if (!NT_SUCCESS(Status))
919 if (AllocateDestinationString)
920 ExFreePool (DestinationString->Buffer);
924 DestinationString->Buffer[Length / sizeof(WCHAR)] = 0;
926 return STATUS_SUCCESS;
932 RtlPrefixString(IN PANSI_STRING String1,
933 IN PANSI_STRING String2,
934 IN BOOLEAN CaseInsensitive)
940 if (String2->Length < String1->Length)
943 Length = String1->Length;
944 pc1 = String1->Buffer;
945 pc2 = String2->Buffer;
953 if (RtlUpperChar (*pc1++) != RtlUpperChar (*pc2++))
961 if (*pc1++ != *pc2++)
973 RtlPrefixUnicodeString(IN PUNICODE_STRING String1,
974 IN PUNICODE_STRING String2,
975 IN BOOLEAN CaseInsensitive)
981 if (String2->Length < String1->Length)
984 Length = String1->Length / 2;
985 pc1 = String1->Buffer;
986 pc2 = String2->Buffer;
994 if (RtlUpcaseUnicodeChar (*pc1++)
995 != RtlUpcaseUnicodeChar (*pc2++))
1003 if( *pc1++ != *pc2++ )
1015 RtlUnicodeStringToAnsiSize(IN PUNICODE_STRING UnicodeString)
1019 RtlUnicodeToMultiByteSize(&Size,
1020 UnicodeString->Buffer,
1021 UnicodeString->Length);
1029 RtlUnicodeStringToAnsiString(IN OUT PANSI_STRING DestinationString,
1030 IN PUNICODE_STRING SourceString,
1031 IN BOOLEAN AllocateDestinationString)
1036 if (NlsMbCodePageTag == TRUE){
1037 Length = RtlUnicodeStringToAnsiSize (SourceString); Length--;
1040 Length = SourceString->Length / sizeof(WCHAR);
1042 if (AllocateDestinationString == TRUE)
1044 DestinationString->MaximumLength = Length + sizeof(CHAR);
1045 DestinationString->Buffer =
1046 ExAllocatePoolWithTag (NonPagedPool,
1047 DestinationString->MaximumLength,
1049 if (DestinationString->Buffer == NULL)
1050 return STATUS_NO_MEMORY;
1054 if (Length >= DestinationString->MaximumLength)
1055 return STATUS_BUFFER_TOO_SMALL;
1057 DestinationString->Length = Length;
1059 RtlZeroMemory (DestinationString->Buffer,
1060 DestinationString->Length);
1062 Status = RtlUnicodeToMultiByteN (DestinationString->Buffer,
1063 DestinationString->Length,
1065 SourceString->Buffer,
1066 SourceString->Length);
1067 if (!NT_SUCCESS(Status))
1069 if (AllocateDestinationString)
1070 ExFreePool (DestinationString->Buffer);
1074 DestinationString->Buffer[Length] = 0;
1076 return STATUS_SUCCESS;
1082 RtlUnicodeStringToCountedOemString(IN OUT POEM_STRING DestinationString,
1083 IN PUNICODE_STRING SourceString,
1084 IN BOOLEAN AllocateDestinationString)
1090 if (NlsMbOemCodePageTag == TRUE)
1091 Length = RtlUnicodeStringToAnsiSize (SourceString)/* + 1*/;
1093 Length = SourceString->Length / sizeof(WCHAR) + 1;
1095 if (Length > 0x0000FFFF)
1096 return STATUS_INVALID_PARAMETER_2;
1098 DestinationString->Length = (WORD)(Length - 1);
1100 if (AllocateDestinationString)
1102 DestinationString->Buffer = ExAllocatePoolWithTag (NonPagedPool,
1106 if (DestinationString->Buffer == NULL)
1107 return STATUS_NO_MEMORY;
1109 RtlZeroMemory (DestinationString->Buffer,
1111 DestinationString->MaximumLength = (WORD)Length;
1115 if (Length > DestinationString->MaximumLength)
1117 if (DestinationString->MaximumLength == 0)
1118 return STATUS_BUFFER_OVERFLOW;
1119 DestinationString->Length =
1120 DestinationString->MaximumLength - 1;
1124 Status = RtlUnicodeToOemN (DestinationString->Buffer,
1125 DestinationString->Length,
1127 SourceString->Buffer,
1128 SourceString->Length);
1129 if (!NT_SUCCESS(Status))
1131 if (AllocateDestinationString)
1132 ExFreePool (DestinationString->Buffer);
1137 DestinationString->Buffer[Size] = 0;
1139 return STATUS_SUCCESS;
1145 RtlUnicodeStringToInteger(IN PUNICODE_STRING String,
1153 BOOLEAN addneg = FALSE;
1156 Str = String->Buffer;
1158 for (i = 0; i < String->Length / sizeof(WCHAR); i++)
1165 else if (*Str == L'o')
1170 else if (*Str == L'd')
1175 else if (*Str == L'x')
1180 else if (*Str == L'+')
1184 else if (*Str == L'-')
1189 else if ((*Str > L'1') && (Base == 2))
1191 return STATUS_INVALID_PARAMETER;
1193 else if (((*Str > L'7') || (*Str < L'0')) && (Base == 8))
1195 return STATUS_INVALID_PARAMETER;
1197 else if (((*Str > L'9') || (*Str < L'0')) && (Base == 10))
1199 return STATUS_INVALID_PARAMETER;
1201 else if ((((*Str > L'9') || (*Str < L'0')) ||
1202 ((towupper (*Str) > L'F') ||
1203 (towupper (*Str) < L'A'))) && (Base == 16))
1205 return STATUS_INVALID_PARAMETER;
1211 Str = String->Buffer + lenmin;
1216 while (iswxdigit (*Str) &&
1217 (Val = iswdigit (*Str) ? *Str - L'0' : (iswlower (*Str)
1218 ? toupper (*Str) : *Str) - L'A' + 10) < Base)
1220 *Value = *Value * Base + Val;
1227 return STATUS_SUCCESS;
1233 RtlUnicodeStringToOemSize(IN PUNICODE_STRING UnicodeString)
1237 RtlUnicodeToMultiByteSize(&Size,
1238 UnicodeString->Buffer,
1239 UnicodeString->Length);
1246 RtlUnicodeStringToOemString(IN OUT POEM_STRING DestinationString,
1247 IN PUNICODE_STRING SourceString,
1248 IN BOOLEAN AllocateDestinationString)
1253 if (NlsMbOemCodePageTag == TRUE){
1254 Length = RtlUnicodeStringToAnsiSize (SourceString); Length--;
1257 Length = SourceString->Length / sizeof(WCHAR);
1259 if (AllocateDestinationString == TRUE)
1261 DestinationString->MaximumLength = Length + sizeof(CHAR);
1262 DestinationString->Buffer =
1263 ExAllocatePoolWithTag (NonPagedPool,
1264 DestinationString->MaximumLength,
1266 if (DestinationString->Buffer == NULL)
1267 return STATUS_NO_MEMORY;
1271 if (Length >= DestinationString->MaximumLength)
1272 return STATUS_BUFFER_TOO_SMALL;
1274 DestinationString->Length = Length;
1276 RtlZeroMemory(DestinationString->Buffer,
1277 DestinationString->Length);
1279 Status = RtlUnicodeToOemN(DestinationString->Buffer,
1280 DestinationString->Length,
1282 SourceString->Buffer,
1283 SourceString->Length);
1284 if (!NT_SUCCESS(Status))
1286 if (AllocateDestinationString)
1287 ExFreePool(DestinationString->Buffer);
1291 DestinationString->Buffer[Length] = 0;
1293 return STATUS_SUCCESS;
1299 RtlUpcaseUnicodeChar(IN WCHAR Source)
1305 return(Source - (L'a' - L'A'));
1307 /* FIXME: characters above 'z' */
1314 RtlUpcaseUnicodeString(IN OUT PUNICODE_STRING DestinationString,
1315 IN PUNICODE_STRING SourceString,
1316 IN BOOLEAN AllocateDestinationString)
1321 if (AllocateDestinationString == TRUE)
1323 DestinationString->MaximumLength = SourceString->Length + sizeof(WCHAR);
1324 DestinationString->Buffer =
1325 ExAllocatePoolWithTag(NonPagedPool,
1326 SourceString->Length + sizeof(WCHAR),
1328 if (DestinationString->Buffer == NULL)
1329 return(STATUS_NO_MEMORY);
1333 if (SourceString->Length >= DestinationString->MaximumLength)
1334 return(STATUS_BUFFER_TOO_SMALL);
1336 DestinationString->Length = SourceString->Length;
1338 Src = SourceString->Buffer;
1339 Dest = DestinationString->Buffer;
1340 for (i=0; i < SourceString->Length / sizeof(WCHAR); i++)
1342 *Dest = RtlUpcaseUnicodeChar(*Src);
1348 return(STATUS_SUCCESS);
1354 RtlUpcaseUnicodeStringToAnsiString(IN OUT PANSI_STRING DestinationString,
1355 IN PUNICODE_STRING SourceString,
1356 IN BOOLEAN AllocateDestinationString)
1361 if (NlsMbCodePageTag == TRUE){
1362 Length = RtlUnicodeStringToAnsiSize(SourceString); Length--;
1365 Length = SourceString->Length / sizeof(WCHAR);
1367 if (AllocateDestinationString == TRUE)
1369 DestinationString->MaximumLength = Length + sizeof(CHAR);
1370 DestinationString->Buffer =
1371 ExAllocatePoolWithTag(NonPagedPool,
1372 DestinationString->MaximumLength,
1374 if (DestinationString->Buffer == NULL)
1375 return(STATUS_NO_MEMORY);
1379 if (Length >= DestinationString->MaximumLength)
1380 return(STATUS_BUFFER_TOO_SMALL);
1382 DestinationString->Length = Length;
1384 RtlZeroMemory(DestinationString->Buffer,
1385 DestinationString->Length);
1387 Status = RtlUpcaseUnicodeToMultiByteN(DestinationString->Buffer,
1388 DestinationString->Length,
1390 SourceString->Buffer,
1391 SourceString->Length);
1392 if (!NT_SUCCESS(Status))
1394 if (AllocateDestinationString)
1395 ExFreePool(DestinationString->Buffer);
1399 DestinationString->Buffer[Length] = 0;
1401 return(STATUS_SUCCESS);
1407 RtlUpcaseUnicodeStringToCountedOemString(IN OUT POEM_STRING DestinationString,
1408 IN PUNICODE_STRING SourceString,
1409 IN BOOLEAN AllocateDestinationString)
1415 if (NlsMbCodePageTag == TRUE)
1416 Length = RtlUnicodeStringToAnsiSize (SourceString)/* + 1*/;
1418 Length = SourceString->Length / sizeof(WCHAR) + 1;
1420 if (Length > 0x0000FFFF)
1421 return(STATUS_INVALID_PARAMETER_2);
1423 DestinationString->Length = (WORD)(Length - 1);
1425 if (AllocateDestinationString == TRUE)
1427 DestinationString->Buffer =
1428 ExAllocatePoolWithTag(NonPagedPool,
1431 if (DestinationString->Buffer == NULL)
1432 return(STATUS_NO_MEMORY);
1434 RtlZeroMemory(DestinationString->Buffer,
1436 DestinationString->MaximumLength = (WORD)Length;
1440 if (Length > DestinationString->MaximumLength)
1442 if (DestinationString->MaximumLength == 0)
1443 return(STATUS_BUFFER_OVERFLOW);
1444 DestinationString->Length =
1445 DestinationString->MaximumLength - 1;
1449 Status = RtlUpcaseUnicodeToOemN(DestinationString->Buffer,
1450 DestinationString->Length,
1452 SourceString->Buffer,
1453 SourceString->Length);
1454 if (!NT_SUCCESS(Status))
1456 if (AllocateDestinationString)
1457 ExFreePool(DestinationString->Buffer);
1461 DestinationString->Buffer[Size] = 0;
1463 return(STATUS_SUCCESS);
1469 RtlUpcaseUnicodeStringToOemString(IN OUT POEM_STRING DestinationString,
1470 IN PUNICODE_STRING SourceString,
1471 IN BOOLEAN AllocateDestinationString)
1476 if (NlsMbOemCodePageTag == TRUE) {
1477 Length = RtlUnicodeStringToOemSize(SourceString); Length--;
1480 Length = SourceString->Length / sizeof(WCHAR);
1482 if (AllocateDestinationString == TRUE)
1484 DestinationString->MaximumLength = Length + sizeof(CHAR);
1485 DestinationString->Buffer =
1486 ExAllocatePoolWithTag(NonPagedPool,
1487 DestinationString->MaximumLength,
1489 if (DestinationString->Buffer == NULL)
1490 return(STATUS_NO_MEMORY);
1494 if (Length >= DestinationString->MaximumLength)
1495 return(STATUS_BUFFER_TOO_SMALL);
1497 DestinationString->Length = Length;
1499 RtlZeroMemory(DestinationString->Buffer,
1500 DestinationString->Length);
1502 Status = RtlUpcaseUnicodeToOemN(DestinationString->Buffer,
1503 DestinationString->Length,
1505 SourceString->Buffer,
1506 SourceString->Length);
1507 if (!NT_SUCCESS(Status))
1509 if (AllocateDestinationString)
1510 ExFreePool(DestinationString->Buffer);
1514 DestinationString->Buffer[Length] = 0;
1516 return(STATUS_SUCCESS);
1522 RtlUpperChar(IN CHAR Source)
1527 if (NlsMbCodePageTag == FALSE)
1529 /* single-byte code page */
1531 Unicode = (WCHAR)Source;
1533 Unicode = NlsAnsiToUnicodeData[Source];
1536 /* upcase conversion */
1537 Unicode = RtlUpcaseUnicodeChar (Unicode);
1539 /* unicode -> ansi */
1540 Destination = (CHAR)Unicode;
1542 Destination = NlsUnicodeToAnsiData[Unicode];
1547 /* single-byte code page */
1548 /* FIXME: implement the multi-byte stuff!! */
1549 Destination = Source;
1552 return(Destination);
1558 RtlUpperString(PSTRING DestinationString,
1559 PSTRING SourceString)
1566 Length = min(SourceString->Length,
1567 DestinationString->MaximumLength - 1);
1569 Src = SourceString->Buffer;
1570 Dest = DestinationString->Buffer;
1571 for (i = 0; i < Length; i++)
1573 *Dest = RtlUpperChar(*Src);
1579 DestinationString->Length = SourceString->Length;
1585 RtlxAnsiStringToUnicodeSize(IN PANSI_STRING AnsiString)
1587 return RtlAnsiStringToUnicodeSize(AnsiString);
1593 RtlxOemStringToUnicodeSize(IN POEM_STRING OemString)
1595 return RtlOemStringToUnicodeSize((PANSI_STRING)OemString);
1601 RtlxUnicodeStringToAnsiSize(IN PUNICODE_STRING UnicodeString)
1603 return RtlUnicodeStringToAnsiSize(UnicodeString);
1609 RtlxUnicodeStringToOemSize(IN PUNICODE_STRING UnicodeString)
1611 return RtlUnicodeStringToOemSize(UnicodeString);