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 *****************************************************************/
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;
1083 RtlUnicodeStringToCountedOemString(IN OUT POEM_STRING DestinationString,
1084 IN PUNICODE_STRING SourceString,
1085 IN BOOLEAN AllocateDestinationString)
1091 if (NlsMbOemCodePageTag == TRUE)
1092 Length = RtlUnicodeStringToAnsiSize (SourceString)/* + 1*/;
1094 Length = SourceString->Length / sizeof(WCHAR) + 1;
1096 if (Length > 0x0000FFFF)
1097 return STATUS_INVALID_PARAMETER_2;
1099 DestinationString->Length = (WORD)(Length - 1);
1101 if (AllocateDestinationString)
1103 DestinationString->Buffer = ExAllocatePoolWithTag (NonPagedPool,
1107 if (DestinationString->Buffer == NULL)
1108 return STATUS_NO_MEMORY;
1110 RtlZeroMemory (DestinationString->Buffer,
1112 DestinationString->MaximumLength = (WORD)Length;
1116 if (Length > DestinationString->MaximumLength)
1118 if (DestinationString->MaximumLength == 0)
1119 return STATUS_BUFFER_OVERFLOW;
1120 DestinationString->Length =
1121 DestinationString->MaximumLength - 1;
1125 Status = RtlUnicodeToOemN (DestinationString->Buffer,
1126 DestinationString->Length,
1128 SourceString->Buffer,
1129 SourceString->Length);
1130 if (!NT_SUCCESS(Status))
1132 if (AllocateDestinationString)
1133 ExFreePool (DestinationString->Buffer);
1138 DestinationString->Buffer[Size] = 0;
1140 return STATUS_SUCCESS;
1143 #endif /* LIBCAPTIVE */
1147 RtlUnicodeStringToInteger(IN PUNICODE_STRING String,
1155 BOOLEAN addneg = FALSE;
1158 Str = String->Buffer;
1160 for (i = 0; i < String->Length / sizeof(WCHAR); i++)
1167 else if (*Str == L'o')
1172 else if (*Str == L'd')
1177 else if (*Str == L'x')
1182 else if (*Str == L'+')
1186 else if (*Str == L'-')
1191 else if ((*Str > L'1') && (Base == 2))
1193 return STATUS_INVALID_PARAMETER;
1195 else if (((*Str > L'7') || (*Str < L'0')) && (Base == 8))
1197 return STATUS_INVALID_PARAMETER;
1199 else if (((*Str > L'9') || (*Str < L'0')) && (Base == 10))
1201 return STATUS_INVALID_PARAMETER;
1203 else if ((((*Str > L'9') || (*Str < L'0')) ||
1204 ((towupper (*Str) > L'F') ||
1205 (towupper (*Str) < L'A'))) && (Base == 16))
1207 return STATUS_INVALID_PARAMETER;
1213 Str = String->Buffer + lenmin;
1218 while (iswxdigit (*Str) &&
1219 (Val = iswdigit (*Str) ? *Str - L'0' : (iswlower (*Str)
1220 ? toupper (*Str) : *Str) - L'A' + 10) < Base)
1222 *Value = *Value * Base + Val;
1229 return STATUS_SUCCESS;
1235 RtlUnicodeStringToOemSize(IN PUNICODE_STRING UnicodeString)
1239 RtlUnicodeToMultiByteSize(&Size,
1240 UnicodeString->Buffer,
1241 UnicodeString->Length);
1248 RtlUnicodeStringToOemString(IN OUT POEM_STRING DestinationString,
1249 IN PUNICODE_STRING SourceString,
1250 IN BOOLEAN AllocateDestinationString)
1255 if (NlsMbOemCodePageTag == TRUE){
1256 Length = RtlUnicodeStringToAnsiSize (SourceString); Length--;
1259 Length = SourceString->Length / sizeof(WCHAR);
1261 if (AllocateDestinationString == TRUE)
1263 DestinationString->MaximumLength = Length + sizeof(CHAR);
1264 DestinationString->Buffer =
1265 ExAllocatePoolWithTag (NonPagedPool,
1266 DestinationString->MaximumLength,
1268 if (DestinationString->Buffer == NULL)
1269 return STATUS_NO_MEMORY;
1273 if (Length >= DestinationString->MaximumLength)
1274 return STATUS_BUFFER_TOO_SMALL;
1276 DestinationString->Length = Length;
1278 RtlZeroMemory(DestinationString->Buffer,
1279 DestinationString->Length);
1281 Status = RtlUnicodeToOemN(DestinationString->Buffer,
1282 DestinationString->Length,
1284 SourceString->Buffer,
1285 SourceString->Length);
1286 if (!NT_SUCCESS(Status))
1288 if (AllocateDestinationString)
1289 ExFreePool(DestinationString->Buffer);
1293 DestinationString->Buffer[Length] = 0;
1295 return STATUS_SUCCESS;
1301 RtlUpcaseUnicodeChar(IN WCHAR Source)
1307 return(Source - (L'a' - L'A'));
1309 /* FIXME: characters above 'z' */
1316 * If 'AllocateDestinationString==TRUE' we return zero-terminated 'DestinationString'
1317 * with: DestinationString->MaximumLength=SourceString->Length+sizeof(WCHAR)
1318 * If 'AllocateDestinationString==FALSE' we try to zero-terminate the passed 'DestinationString'
1319 * but we will succeed with no termination if: SourceString->Length==DestinationString->MaximumLength
1320 * Any zero-termination-related behaviour is undocumented by W32,
1321 * is 'DestinationString' required to be zero-terminated at all? Dunno.
1324 RtlUpcaseUnicodeString(IN OUT PUNICODE_STRING DestinationString,
1325 IN PUNICODE_STRING SourceString,
1326 IN BOOLEAN AllocateDestinationString)
1331 if (AllocateDestinationString == TRUE)
1333 DestinationString->MaximumLength = SourceString->Length + sizeof(WCHAR);
1334 DestinationString->Buffer =
1335 ExAllocatePoolWithTag(NonPagedPool,
1336 SourceString->Length + sizeof(WCHAR),
1338 if (DestinationString->Buffer == NULL)
1339 return(STATUS_NO_MEMORY);
1343 if (SourceString->Length > DestinationString->MaximumLength)
1344 return(STATUS_BUFFER_TOO_SMALL);
1346 DestinationString->Length = SourceString->Length;
1348 Src = SourceString->Buffer;
1349 Dest = DestinationString->Buffer;
1350 for (i=0; i < SourceString->Length / sizeof(WCHAR); i++)
1352 *Dest = RtlUpcaseUnicodeChar(*Src);
1356 /* We may get pre-allocated 'DestinationString' with no space for the terminator! */
1357 if (SourceString->Length+sizeof(WCHAR) <= DestinationString->MaximumLength)
1360 return(STATUS_SUCCESS);
1366 RtlUpcaseUnicodeStringToAnsiString(IN OUT PANSI_STRING DestinationString,
1367 IN PUNICODE_STRING SourceString,
1368 IN BOOLEAN AllocateDestinationString)
1373 if (NlsMbCodePageTag == TRUE){
1374 Length = RtlUnicodeStringToAnsiSize(SourceString); Length--;
1377 Length = SourceString->Length / sizeof(WCHAR);
1379 if (AllocateDestinationString == TRUE)
1381 DestinationString->MaximumLength = Length + sizeof(CHAR);
1382 DestinationString->Buffer =
1383 ExAllocatePoolWithTag(NonPagedPool,
1384 DestinationString->MaximumLength,
1386 if (DestinationString->Buffer == NULL)
1387 return(STATUS_NO_MEMORY);
1391 if (Length >= DestinationString->MaximumLength)
1392 return(STATUS_BUFFER_TOO_SMALL);
1394 DestinationString->Length = Length;
1396 RtlZeroMemory(DestinationString->Buffer,
1397 DestinationString->Length);
1399 Status = RtlUpcaseUnicodeToMultiByteN(DestinationString->Buffer,
1400 DestinationString->Length,
1402 SourceString->Buffer,
1403 SourceString->Length);
1404 if (!NT_SUCCESS(Status))
1406 if (AllocateDestinationString)
1407 ExFreePool(DestinationString->Buffer);
1411 DestinationString->Buffer[Length] = 0;
1413 return(STATUS_SUCCESS);
1419 RtlUpcaseUnicodeStringToCountedOemString(IN OUT POEM_STRING DestinationString,
1420 IN PUNICODE_STRING SourceString,
1421 IN BOOLEAN AllocateDestinationString)
1427 if (NlsMbCodePageTag == TRUE)
1428 Length = RtlUnicodeStringToAnsiSize (SourceString)/* + 1*/;
1430 Length = SourceString->Length / sizeof(WCHAR) + 1;
1432 if (Length > 0x0000FFFF)
1433 return(STATUS_INVALID_PARAMETER_2);
1435 DestinationString->Length = (WORD)(Length - 1);
1437 if (AllocateDestinationString == TRUE)
1439 DestinationString->Buffer =
1440 ExAllocatePoolWithTag(NonPagedPool,
1443 if (DestinationString->Buffer == NULL)
1444 return(STATUS_NO_MEMORY);
1446 RtlZeroMemory(DestinationString->Buffer,
1448 DestinationString->MaximumLength = (WORD)Length;
1452 if (Length > DestinationString->MaximumLength)
1454 if (DestinationString->MaximumLength == 0)
1455 return(STATUS_BUFFER_OVERFLOW);
1456 DestinationString->Length =
1457 DestinationString->MaximumLength - 1;
1461 Status = RtlUpcaseUnicodeToOemN(DestinationString->Buffer,
1462 DestinationString->Length,
1464 SourceString->Buffer,
1465 SourceString->Length);
1466 if (!NT_SUCCESS(Status))
1468 if (AllocateDestinationString)
1469 ExFreePool(DestinationString->Buffer);
1473 DestinationString->Buffer[Size] = 0;
1475 return(STATUS_SUCCESS);
1481 RtlUpcaseUnicodeStringToOemString(IN OUT POEM_STRING DestinationString,
1482 IN PUNICODE_STRING SourceString,
1483 IN BOOLEAN AllocateDestinationString)
1488 if (NlsMbOemCodePageTag == TRUE) {
1489 Length = RtlUnicodeStringToOemSize(SourceString); Length--;
1492 Length = SourceString->Length / sizeof(WCHAR);
1494 if (AllocateDestinationString == TRUE)
1496 DestinationString->MaximumLength = Length + sizeof(CHAR);
1497 DestinationString->Buffer =
1498 ExAllocatePoolWithTag(NonPagedPool,
1499 DestinationString->MaximumLength,
1501 if (DestinationString->Buffer == NULL)
1502 return(STATUS_NO_MEMORY);
1506 if (Length >= DestinationString->MaximumLength)
1507 return(STATUS_BUFFER_TOO_SMALL);
1509 DestinationString->Length = Length;
1511 RtlZeroMemory(DestinationString->Buffer,
1512 DestinationString->Length);
1514 Status = RtlUpcaseUnicodeToOemN(DestinationString->Buffer,
1515 DestinationString->Length,
1517 SourceString->Buffer,
1518 SourceString->Length);
1519 if (!NT_SUCCESS(Status))
1521 if (AllocateDestinationString)
1522 ExFreePool(DestinationString->Buffer);
1526 DestinationString->Buffer[Length] = 0;
1528 return(STATUS_SUCCESS);
1534 RtlUpperChar(IN CHAR Source)
1539 if (NlsMbCodePageTag == FALSE)
1541 /* single-byte code page */
1543 Unicode = (WCHAR)Source;
1545 Unicode = NlsAnsiToUnicodeData[Source];
1548 /* upcase conversion */
1549 Unicode = RtlUpcaseUnicodeChar (Unicode);
1551 /* unicode -> ansi */
1552 Destination = (CHAR)Unicode;
1554 Destination = NlsUnicodeToAnsiData[Unicode];
1559 /* single-byte code page */
1560 /* FIXME: implement the multi-byte stuff!! */
1561 Destination = Source;
1564 return(Destination);
1570 RtlUpperString(PSTRING DestinationString,
1571 PSTRING SourceString)
1578 Length = min(SourceString->Length,
1579 DestinationString->MaximumLength - 1);
1581 Src = SourceString->Buffer;
1582 Dest = DestinationString->Buffer;
1583 for (i = 0; i < Length; i++)
1585 *Dest = RtlUpperChar(*Src);
1591 DestinationString->Length = SourceString->Length;
1597 RtlxAnsiStringToUnicodeSize(IN PANSI_STRING AnsiString)
1599 return RtlAnsiStringToUnicodeSize(AnsiString);
1605 RtlxOemStringToUnicodeSize(IN POEM_STRING OemString)
1607 return RtlOemStringToUnicodeSize((PANSI_STRING)OemString);
1613 RtlxUnicodeStringToAnsiSize(IN PUNICODE_STRING UnicodeString)
1615 return RtlUnicodeStringToAnsiSize(UnicodeString);
1621 RtlxUnicodeStringToOemSize(IN PUNICODE_STRING UnicodeString)
1623 return RtlUnicodeStringToOemSize(UnicodeString);