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>
14 #include <msvcrt/ctype.h> /* <ctype.h> does not need to define isw*() */
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 * If 'AllocateDestinationString==TRUE' we return zero-terminated 'DestinationString'
1279 * with: DestinationString->MaximumLength=SourceString->Length+sizeof(WCHAR)
1280 * If 'AllocateDestinationString==FALSE' we try to zero-terminate the passed 'DestinationString'
1281 * but we will succeed with no termination if: SourceString->Length==DestinationString->MaximumLength
1282 * Any zero-termination-related behaviour is undocumented by W32,
1283 * is 'DestinationString' required to be zero-terminated at all? Dunno.
1286 RtlUpcaseUnicodeString(IN OUT PUNICODE_STRING DestinationString,
1287 IN PUNICODE_STRING SourceString,
1288 IN BOOLEAN AllocateDestinationString)
1293 if (AllocateDestinationString == TRUE)
1295 DestinationString->MaximumLength = SourceString->Length + sizeof(WCHAR);
1296 DestinationString->Buffer =
1297 ExAllocatePoolWithTag(NonPagedPool,
1298 SourceString->Length + sizeof(WCHAR),
1300 if (DestinationString->Buffer == NULL)
1301 return(STATUS_NO_MEMORY);
1305 if (SourceString->Length > DestinationString->MaximumLength)
1306 return(STATUS_BUFFER_TOO_SMALL);
1308 DestinationString->Length = SourceString->Length;
1310 Src = SourceString->Buffer;
1311 Dest = DestinationString->Buffer;
1312 for (i=0; i < SourceString->Length / sizeof(WCHAR); i++)
1314 *Dest = RtlUpcaseUnicodeChar(*Src);
1318 /* We may get pre-allocated 'DestinationString' with no space for the terminator! */
1319 if (SourceString->Length+sizeof(WCHAR) <= DestinationString->MaximumLength)
1322 return(STATUS_SUCCESS);
1327 RtlUpcaseUnicodeStringToAnsiString(IN OUT PANSI_STRING DestinationString,
1328 IN PUNICODE_STRING SourceString,
1329 IN BOOLEAN AllocateDestinationString)
1334 if (NlsMbCodePageTag == TRUE){
1335 Length = RtlUnicodeStringToAnsiSize(SourceString); Length--;
1338 Length = SourceString->Length / sizeof(WCHAR);
1340 if (AllocateDestinationString == TRUE)
1342 DestinationString->MaximumLength = Length + sizeof(CHAR);
1343 DestinationString->Buffer =
1344 ExAllocatePoolWithTag(NonPagedPool,
1345 DestinationString->MaximumLength,
1347 if (DestinationString->Buffer == NULL)
1348 return(STATUS_NO_MEMORY);
1352 if (Length >= DestinationString->MaximumLength)
1353 return(STATUS_BUFFER_TOO_SMALL);
1355 DestinationString->Length = Length;
1357 RtlZeroMemory(DestinationString->Buffer,
1358 DestinationString->Length);
1360 Status = RtlUpcaseUnicodeToMultiByteN(DestinationString->Buffer,
1361 DestinationString->Length,
1363 SourceString->Buffer,
1364 SourceString->Length);
1365 if (!NT_SUCCESS(Status))
1367 if (AllocateDestinationString)
1368 ExFreePool(DestinationString->Buffer);
1372 DestinationString->Buffer[Length] = 0;
1374 return(STATUS_SUCCESS);
1379 RtlUpcaseUnicodeStringToCountedOemString(IN OUT POEM_STRING DestinationString,
1380 IN PUNICODE_STRING SourceString,
1381 IN BOOLEAN AllocateDestinationString)
1387 if (NlsMbCodePageTag == TRUE)
1388 Length = RtlUnicodeStringToAnsiSize (SourceString)/* + 1*/;
1390 Length = SourceString->Length / sizeof(WCHAR) + 1;
1392 if (Length > 0x0000FFFF)
1393 return(STATUS_INVALID_PARAMETER_2);
1395 DestinationString->Length = (WORD)(Length - 1);
1397 if (AllocateDestinationString == TRUE)
1399 DestinationString->Buffer =
1400 ExAllocatePoolWithTag(NonPagedPool,
1403 if (DestinationString->Buffer == NULL)
1404 return(STATUS_NO_MEMORY);
1406 RtlZeroMemory(DestinationString->Buffer,
1408 DestinationString->MaximumLength = (WORD)Length;
1412 if (Length > DestinationString->MaximumLength)
1414 if (DestinationString->MaximumLength == 0)
1415 return(STATUS_BUFFER_OVERFLOW);
1416 DestinationString->Length =
1417 DestinationString->MaximumLength - 1;
1421 Status = RtlUpcaseUnicodeToOemN(DestinationString->Buffer,
1422 DestinationString->Length,
1424 SourceString->Buffer,
1425 SourceString->Length);
1426 if (!NT_SUCCESS(Status))
1428 if (AllocateDestinationString)
1429 ExFreePool(DestinationString->Buffer);
1433 DestinationString->Buffer[Size] = 0;
1435 return(STATUS_SUCCESS);
1440 RtlUpcaseUnicodeStringToOemString(IN OUT POEM_STRING DestinationString,
1441 IN PUNICODE_STRING SourceString,
1442 IN BOOLEAN AllocateDestinationString)
1447 if (NlsMbOemCodePageTag == TRUE) {
1448 Length = RtlUnicodeStringToOemSize(SourceString); Length--;
1451 Length = SourceString->Length / sizeof(WCHAR);
1453 if (AllocateDestinationString == TRUE)
1455 DestinationString->MaximumLength = Length + sizeof(CHAR);
1456 DestinationString->Buffer =
1457 ExAllocatePoolWithTag(NonPagedPool,
1458 DestinationString->MaximumLength,
1460 if (DestinationString->Buffer == NULL)
1461 return(STATUS_NO_MEMORY);
1465 if (Length >= DestinationString->MaximumLength)
1466 return(STATUS_BUFFER_TOO_SMALL);
1468 DestinationString->Length = Length;
1470 RtlZeroMemory(DestinationString->Buffer,
1471 DestinationString->Length);
1473 Status = RtlUpcaseUnicodeToOemN(DestinationString->Buffer,
1474 DestinationString->Length,
1476 SourceString->Buffer,
1477 SourceString->Length);
1478 if (!NT_SUCCESS(Status))
1480 if (AllocateDestinationString)
1481 ExFreePool(DestinationString->Buffer);
1485 DestinationString->Buffer[Length] = 0;
1487 return(STATUS_SUCCESS);
1492 RtlUpperChar(IN CHAR Source)
1497 if (NlsMbCodePageTag == FALSE)
1499 /* single-byte code page */
1501 Unicode = (WCHAR)Source;
1503 Unicode = NlsAnsiToUnicodeData[Source];
1506 /* upcase conversion */
1507 Unicode = RtlUpcaseUnicodeChar (Unicode);
1509 /* unicode -> ansi */
1510 Destination = (CHAR)Unicode;
1512 Destination = NlsUnicodeToAnsiData[Unicode];
1517 /* single-byte code page */
1518 /* FIXME: implement the multi-byte stuff!! */
1519 Destination = Source;
1522 return(Destination);
1527 RtlUpperString(PSTRING DestinationString,
1528 PSTRING SourceString)
1535 Length = min(SourceString->Length,
1536 DestinationString->MaximumLength - 1);
1538 Src = SourceString->Buffer;
1539 Dest = DestinationString->Buffer;
1540 for (i = 0; i < Length; i++)
1542 *Dest = RtlUpperChar(*Src);
1548 DestinationString->Length = SourceString->Length;
1553 RtlxAnsiStringToUnicodeSize(IN PANSI_STRING AnsiString)
1555 return(RtlAnsiStringToUnicodeSize(AnsiString));
1560 RtlxOemStringToUnicodeSize(IN POEM_STRING OemString)
1562 return(RtlOemStringToUnicodeSize((PANSI_STRING)OemString));
1567 RtlxUnicodeStringToAnsiSize(IN PUNICODE_STRING UnicodeString)
1569 return(RtlUnicodeStringToAnsiSize(UnicodeString));
1574 RtlxUnicodeStringToOemSize(IN PUNICODE_STRING UnicodeString)
1576 return(RtlUnicodeStringToOemSize(UnicodeString));