3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: lib/ntdll/rtl/unicode.c
6 * PURPOSE: String functions
7 * PROGRAMMER: Jason Filby (jasonfilby@yahoo.com)
12 #include <ddk/ntddk.h>
13 #include <ntdll/rtl.h>
14 //#include <internal/nls.h>
16 #include <ntos/minmax.h>
18 #include <ntdll/ntdll.h>
20 /* FUNCTIONS *****************************************************************/
24 RtlAnsiCharToUnicodeChar(
32 Size = (NlsLeadByteInfo[AnsiChar] == 0) ? 1 : 2;
35 RtlMultiByteToUnicodeN (&UnicodeChar,
47 RtlAnsiStringToUnicodeSize(
48 IN PANSI_STRING AnsiString)
52 RtlMultiByteToUnicodeSize (&Size,
62 RtlAnsiStringToUnicodeString(
63 IN OUT PUNICODE_STRING DestinationString,
64 IN PANSI_STRING SourceString,
65 IN BOOLEAN AllocateDestinationString)
70 if (NlsMbCodePageTag == TRUE)
71 Length = RtlAnsiStringToUnicodeSize (SourceString);
73 Length = SourceString->Length * sizeof(WCHAR);
76 return STATUS_INVALID_PARAMETER_2;
78 if (AllocateDestinationString == TRUE)
80 DestinationString->MaximumLength = Length + sizeof(WCHAR);
81 DestinationString->Buffer =
82 RtlAllocateHeap (RtlGetProcessHeap (),
84 DestinationString->MaximumLength);
85 if (DestinationString->Buffer == NULL)
86 return STATUS_NO_MEMORY;
90 if (Length + sizeof(WCHAR) > DestinationString->MaximumLength)
92 DPRINT("STATUS_BUFFER_TOO_SMALL\n");
93 return STATUS_BUFFER_TOO_SMALL;
96 DestinationString->Length = Length;
98 RtlZeroMemory (DestinationString->Buffer,
99 DestinationString->Length);
101 Status = RtlMultiByteToUnicodeN (DestinationString->Buffer,
102 DestinationString->Length,
104 SourceString->Buffer,
105 SourceString->Length);
106 if (!NT_SUCCESS(Status))
108 if (AllocateDestinationString)
110 RtlFreeHeap (RtlGetProcessHeap (),
112 DestinationString->Buffer);
117 DestinationString->Buffer[Length / sizeof(WCHAR)] = 0;
119 return STATUS_SUCCESS;
125 RtlAppendAsciizToString(
126 IN OUT PSTRING Destination,
133 return STATUS_SUCCESS;
135 Length = strlen (Source);
136 if (Destination->Length + Length >= Destination->MaximumLength)
137 return STATUS_BUFFER_TOO_SMALL;
139 Ptr = Destination->Buffer + Destination->Length;
146 Destination->Length += Length;
148 return STATUS_SUCCESS;
154 RtlAppendStringToString(
155 IN OUT PSTRING Destination,
160 if (Source->Length == 0)
161 return STATUS_SUCCESS;
163 if (Destination->Length + Source->Length >= Destination->MaximumLength)
164 return STATUS_BUFFER_TOO_SMALL;
166 Ptr = Destination->Buffer + Destination->Length;
170 Ptr += Source->Length;
173 Destination->Length += Source->Length;
175 return STATUS_SUCCESS;
181 RtlAppendUnicodeStringToString(
182 IN OUT PUNICODE_STRING Destination,
183 IN PUNICODE_STRING Source)
189 if ((Source->Length + Destination->Length) >= Destination->MaximumLength)
190 return STATUS_BUFFER_TOO_SMALL;
192 Src = Source->Buffer;
193 Dest = Destination->Buffer + (Destination->Length / sizeof (WCHAR));
194 for (i = 0; i < (Source->Length / sizeof(WCHAR)); i++)
202 Destination->Length += Source->Length;
204 return STATUS_SUCCESS;
209 RtlAppendUnicodeToString(IN OUT PUNICODE_STRING Destination,
217 slen = wcslen(Source) * sizeof(WCHAR);
219 if (Destination->Length + slen >= Destination->MaximumLength)
220 return(STATUS_BUFFER_TOO_SMALL);
223 Dest = Destination->Buffer + (Destination->Length / sizeof(WCHAR));
225 for (i = 0; i < (slen / sizeof(WCHAR)); i++)
233 Destination->Length += slen;
235 return(STATUS_SUCCESS);
257 if ((*String == 'x') && isxdigit (String[1]))
265 if (!isxdigit (*String))
266 return STATUS_INVALID_PARAMETER;
268 while (isxdigit (*String) &&
269 (Val = isdigit (*String) ? * String - '0' : (islower (*String)
270 ? toupper (*String) : *String) - 'A' + 10) < Base)
272 *Value = *Value * Base + Val;
276 return STATUS_SUCCESS;
285 IN BOOLEAN CaseInsensitive)
291 if (String1 && String2)
293 len1 = String1->Length;
294 len2 = String2->Length;
295 s1 = String1->Buffer;
296 s2 = String2->Buffer;
304 c1 = len1-- ? RtlUpperChar (*s1++) : 0;
305 c2 = len2-- ? RtlUpperChar (*s2++) : 0;
306 if (!c1 || !c2 || c1 != c2)
314 c1 = len1-- ? *s1++ : 0;
315 c2 = len2-- ? *s2++ : 0;
316 if (!c1 || !c2 || c1 != c2)
329 RtlCompareUnicodeString(
330 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)
377 IN OUT PSTRING DestinationString,
378 IN PSTRING SourceString)
383 if (SourceString == NULL)
385 DestinationString->Length = 0;
389 copylen = min (DestinationString->MaximumLength - sizeof(CHAR),
390 SourceString->Length);
391 Src = SourceString->Buffer;
392 Dest = DestinationString->Buffer;
394 for (i = 0; i < copylen; i++)
402 DestinationString->Length = copylen;
408 RtlCopyUnicodeString(
409 IN OUT PUNICODE_STRING DestinationString,
410 IN PUNICODE_STRING SourceString)
415 if (SourceString == NULL)
417 DestinationString->Length = 0;
421 copylen = min (DestinationString->MaximumLength - sizeof(WCHAR),
422 SourceString->Length);
423 Src = SourceString->Buffer;
424 Dest = DestinationString->Buffer;
426 for (i = 0; i < (copylen / sizeof (WCHAR)); i++)
434 DestinationString->Length = copylen;
440 RtlCreateUnicodeString(
441 IN OUT PUNICODE_STRING Destination,
446 Length = (wcslen (Source) + 1) * sizeof(WCHAR);
448 Destination->Buffer = RtlAllocateHeap (RtlGetProcessHeap (),
451 if (Destination->Buffer == NULL)
454 memmove (Destination->Buffer,
458 Destination->MaximumLength = Length;
459 Destination->Length = Length - sizeof (WCHAR);
467 RtlCreateUnicodeStringFromAsciiz(
468 OUT PUNICODE_STRING Destination,
471 ANSI_STRING AnsiString;
474 RtlInitAnsiString (&AnsiString,
477 Status = RtlAnsiStringToUnicodeString (Destination,
481 return NT_SUCCESS(Status);
487 RtlDowncaseUnicodeString(
488 IN OUT PUNICODE_STRING DestinationString,
489 IN PUNICODE_STRING SourceString,
490 IN BOOLEAN AllocateDestinationString)
495 if (AllocateDestinationString == TRUE)
497 DestinationString->MaximumLength = SourceString->Length + sizeof(WCHAR);
498 DestinationString->Buffer = RtlAllocateHeap (RtlGetProcessHeap (),
500 SourceString->Length + sizeof(WCHAR));
504 if (SourceString->Length >= DestinationString->MaximumLength)
505 return STATUS_BUFFER_TOO_SMALL;
507 DestinationString->Length = SourceString->Length;
509 Src = SourceString->Buffer;
510 Dest = DestinationString->Buffer;
511 for (i=0; i < SourceString->Length / sizeof(WCHAR); i++)
517 else if (*Src <= L'Z')
519 *Dest = (*Src + (L'a' - L'A'));
523 /* FIXME: characters above 'Z' */
532 return STATUS_SUCCESS;
538 RtlEqualComputerName(
539 IN PUNICODE_STRING ComputerName1,
540 IN PUNICODE_STRING ComputerName2)
542 return RtlEqualDomainName (ComputerName1,
550 IN PUNICODE_STRING DomainName1,
551 IN PUNICODE_STRING DomainName2
554 OEM_STRING OemString1;
555 OEM_STRING OemString2;
558 RtlUpcaseUnicodeStringToOemString (&OemString1,
561 RtlUpcaseUnicodeStringToOemString (&OemString2,
565 Result = RtlEqualString (&OemString1,
569 RtlFreeOemString (&OemString1);
570 RtlFreeOemString (&OemString2);
581 IN BOOLEAN CaseInsensitive)
587 if (String1->Length != String2->Length)
590 p1 = String1->Buffer;
591 p2 = String2->Buffer;
592 for (i = 0; i < String1->Length; i++)
594 if (CaseInsensitive == TRUE)
596 c1 = RtlUpperChar (*p1);
597 c2 = RtlUpperChar (*p2);
618 RtlEqualUnicodeString(
619 IN PUNICODE_STRING String1,
620 IN PUNICODE_STRING String2,
621 IN BOOLEAN CaseInsensitive)
627 if (String1->Length != String2->Length)
630 pw1 = String1->Buffer;
631 pw2 = String2->Buffer;
633 for (i = 0; i < String1->Length / sizeof(WCHAR); i++)
635 if (CaseInsensitive == TRUE)
637 wc1 = RtlUpcaseUnicodeChar (*pw1);
638 wc2 = RtlUpcaseUnicodeChar (*pw2);
659 RtlEraseUnicodeString(
660 IN PUNICODE_STRING String)
662 if (String->Buffer == NULL)
665 if (String->MaximumLength == 0)
668 memset (String->Buffer,
670 String->MaximumLength);
679 IN PANSI_STRING AnsiString)
681 if (AnsiString->Buffer == NULL)
684 RtlFreeHeap (RtlGetProcessHeap (),
688 AnsiString->Buffer = NULL;
689 AnsiString->Length = 0;
690 AnsiString->MaximumLength = 0;
697 IN POEM_STRING OemString)
699 if (OemString->Buffer == NULL)
702 RtlFreeHeap (RtlGetProcessHeap (),
706 OemString->Buffer = NULL;
707 OemString->Length = 0;
708 OemString->MaximumLength = 0;
714 RtlFreeUnicodeString(
715 IN PUNICODE_STRING UnicodeString)
717 if (UnicodeString->Buffer == NULL)
720 RtlFreeHeap (RtlGetProcessHeap (),
722 UnicodeString->Buffer);
724 UnicodeString->Buffer = NULL;
725 UnicodeString->Length = 0;
726 UnicodeString->MaximumLength = 0;
733 IN OUT PANSI_STRING DestinationString,
734 IN PCSZ SourceString)
738 if(SourceString==NULL)
740 DestinationString->Length = 0;
741 DestinationString->MaximumLength = 0;
745 DestSize = strlen ((const char *)SourceString);
746 DestinationString->Length = DestSize;
747 DestinationString->MaximumLength = DestSize + 1;
749 DestinationString->Buffer = (PCHAR)SourceString;
756 IN OUT PSTRING DestinationString,
757 IN PCSZ SourceString)
761 if (SourceString == NULL)
763 DestinationString->Length = 0;
764 DestinationString->MaximumLength = 0;
768 DestSize = strlen((const char *)SourceString);
769 DestinationString->Length = DestSize;
770 DestinationString->MaximumLength = DestSize + sizeof(CHAR);
772 DestinationString->Buffer = (PCHAR)SourceString;
778 RtlInitUnicodeString(
779 IN OUT PUNICODE_STRING DestinationString,
780 IN PCWSTR SourceString)
784 if (SourceString==NULL)
786 DestinationString->Length=0;
787 DestinationString->MaximumLength=0;
791 DestSize = wcslen((PWSTR)SourceString) * sizeof(WCHAR);
792 DestinationString->Length = DestSize;
793 DestinationString->MaximumLength = DestSize + sizeof(WCHAR);
795 DestinationString->Buffer = (PWSTR)SourceString;
818 if ((Radix != 2) && (Radix != 8) &&
819 (Radix != 10) && (Radix != 16))
820 return STATUS_INVALID_PARAMETER;
823 while (v || tp == temp)
834 if (tp - temp >= Length)
835 return STATUS_BUFFER_TOO_SMALL;
842 return STATUS_SUCCESS;
848 RtlIntegerToUnicodeString(
850 IN ULONG Base, /* optional */
851 IN OUT PUNICODE_STRING String)
853 ANSI_STRING AnsiString;
857 Status = RtlIntegerToChar (Value,
861 if (!NT_SUCCESS(Status))
864 AnsiString.Buffer = Buffer;
865 AnsiString.Length = strlen (Buffer);
866 AnsiString.MaximumLength = 33;
868 Status = RtlAnsiStringToUnicodeString (String,
876 #define ITU_IMPLEMENTED_TESTS (IS_TEXT_UNICODE_ODD_LENGTH|IS_TEXT_UNICODE_SIGNATURE)
879 RtlIsTextUnicode (PVOID Buffer,
884 ULONG in_flags = (ULONG)-1;
894 * Apply various tests to the text string. According to the
895 * docs, each test "passed" sets the corresponding flag in
896 * the output flags. But some of the tests are mutually
897 * exclusive, so I don't see how you could pass all tests ...
900 /* Check for an odd length ... pass if even. */
902 out_flags |= IS_TEXT_UNICODE_ODD_LENGTH;
904 /* Check for the BOM (byte order mark). */
906 out_flags |= IS_TEXT_UNICODE_SIGNATURE;
909 /* Check for the reverse BOM (byte order mark). */
911 out_flags |= IS_TEXT_UNICODE_REVERSE_SIGNATURE;
914 /* FIXME: Add more tests */
917 * Check whether the string passed all of the tests.
919 in_flags &= ITU_IMPLEMENTED_TESTS;
920 if ((out_flags & in_flags) != in_flags)
933 RtlLargeIntegerToChar(
934 IN PLARGE_INTEGER Value,
941 ULONGLONG v = Value->QuadPart;
950 if ((Radix != 2) && (Radix != 8) &&
951 (Radix != 10) && (Radix != 16))
952 return STATUS_INVALID_PARAMETER;
955 while (v || tp == temp)
966 if (tp - temp >= Length)
967 return STATUS_BUFFER_TOO_SMALL;
974 return STATUS_SUCCESS;
980 RtlOemStringToUnicodeSize(
981 IN POEM_STRING OemString)
985 RtlMultiByteToUnicodeSize (&Size,
995 RtlOemStringToUnicodeString(
996 IN OUT PUNICODE_STRING DestinationString,
997 IN POEM_STRING SourceString,
998 IN BOOLEAN AllocateDestinationString)
1003 if (NlsMbCodePageTag == TRUE)
1004 Length = RtlAnsiStringToUnicodeSize (SourceString);
1006 Length = SourceString->Length * sizeof(WCHAR);
1009 return STATUS_INVALID_PARAMETER_2;
1011 if (AllocateDestinationString == TRUE)
1013 DestinationString->MaximumLength = Length + sizeof(WCHAR);
1014 DestinationString->Buffer =
1015 RtlAllocateHeap (RtlGetProcessHeap (),
1017 DestinationString->MaximumLength);
1018 if (DestinationString->Buffer == NULL)
1019 return STATUS_NO_MEMORY;
1023 if (Length + sizeof(WCHAR) > DestinationString->MaximumLength)
1025 DPRINT("STATUS_BUFFER_TOO_SMALL\n");
1026 return STATUS_BUFFER_TOO_SMALL;
1029 DestinationString->Length = Length;
1031 RtlZeroMemory (DestinationString->Buffer,
1032 DestinationString->Length);
1034 Status = RtlOemToUnicodeN (DestinationString->Buffer,
1035 DestinationString->Length,
1037 SourceString->Buffer,
1038 SourceString->Length);
1039 if (!NT_SUCCESS(Status))
1041 if (AllocateDestinationString)
1043 RtlFreeHeap (RtlGetProcessHeap (),
1045 DestinationString->Buffer);
1050 DestinationString->Buffer[Length / sizeof(WCHAR)] = 0;
1052 return STATUS_SUCCESS;
1059 PANSI_STRING String1,
1060 PANSI_STRING String2,
1061 BOOLEAN CaseInsensitive)
1067 if (String2->Length < String1->Length)
1070 Length = String1->Length;
1071 pc1 = String1->Buffer;
1072 pc2 = String2->Buffer;
1076 if (CaseInsensitive)
1080 if (RtlUpperChar (*pc1++) != RtlUpperChar (*pc2++))
1088 if (*pc1++ != *pc2++)
1100 RtlPrefixUnicodeString(
1101 PUNICODE_STRING String1,
1102 PUNICODE_STRING String2,
1103 BOOLEAN CaseInsensitive)
1109 if (String2->Length < String1->Length)
1112 Length = String1->Length / 2;
1113 pc1 = String1->Buffer;
1114 pc2 = String2->Buffer;
1118 if (CaseInsensitive)
1122 if (RtlUpcaseUnicodeChar (*pc1++)
1123 != RtlUpcaseUnicodeChar (*pc2++))
1131 if( *pc1++ != *pc2++ )
1143 RtlUnicodeStringToAnsiSize(
1144 IN PUNICODE_STRING UnicodeString)
1148 RtlUnicodeToMultiByteSize (&Size,
1149 UnicodeString->Buffer,
1150 UnicodeString->Length);
1152 return Size+1; //NB: incl. nullterm
1158 RtlUnicodeStringToAnsiString(
1159 IN OUT PANSI_STRING DestinationString,
1160 IN PUNICODE_STRING SourceString,
1161 IN BOOLEAN AllocateDestinationString)
1166 if (NlsMbCodePageTag == TRUE)
1167 Length = RtlUnicodeStringToAnsiSize (SourceString);
1169 Length = SourceString->Length / sizeof(WCHAR);
1171 if (AllocateDestinationString == TRUE)
1173 DestinationString->MaximumLength = Length + sizeof(CHAR);
1174 DestinationString->Buffer =
1175 RtlAllocateHeap (RtlGetProcessHeap (),
1177 DestinationString->MaximumLength);
1178 if (DestinationString->Buffer == NULL)
1179 return STATUS_NO_MEMORY;
1183 if (Length >= DestinationString->MaximumLength)
1184 return STATUS_BUFFER_TOO_SMALL;
1186 DestinationString->Length = Length;
1188 RtlZeroMemory (DestinationString->Buffer,
1189 DestinationString->Length);
1191 Status = RtlUnicodeToMultiByteN (DestinationString->Buffer,
1192 DestinationString->Length,
1194 SourceString->Buffer,
1195 SourceString->Length);
1196 if (!NT_SUCCESS(Status))
1198 if (AllocateDestinationString == TRUE)
1200 RtlFreeHeap (RtlGetProcessHeap (),
1202 DestinationString->Buffer);
1207 DestinationString->Buffer[Length] = 0;
1209 return STATUS_SUCCESS;
1215 RtlUnicodeStringToInteger(
1216 IN PUNICODE_STRING String,
1224 BOOLEAN addneg = FALSE;
1227 Str = String->Buffer;
1229 for (i = 0; i < String->Length / sizeof(WCHAR); i++)
1236 else if (*Str == L'o')
1241 else if (*Str == L'd')
1246 else if (*Str == L'x')
1251 else if (*Str == L'+')
1255 else if (*Str == L'-')
1260 else if ((*Str > L'1') && (Base == 2))
1262 return STATUS_INVALID_PARAMETER;
1264 else if (((*Str > L'7') || (*Str < L'0')) && (Base == 8))
1266 return STATUS_INVALID_PARAMETER;
1268 else if (((*Str > L'9') || (*Str < L'0')) && (Base == 10))
1270 return STATUS_INVALID_PARAMETER;
1272 else if ((((*Str > L'9') || (*Str < L'0')) ||
1273 ((towupper (*Str) > L'F') ||
1274 (towupper (*Str) < L'A'))) && (Base == 16))
1276 return STATUS_INVALID_PARAMETER;
1282 Str = String->Buffer + lenmin;
1287 while (iswxdigit (*Str) &&
1288 (Val = iswdigit (*Str) ? *Str - L'0' : (iswlower (*Str)
1289 ? toupper (*Str) : *Str) - L'A' + 10) < Base)
1291 *Value = *Value * Base + Val;
1298 return STATUS_SUCCESS;
1304 RtlUnicodeStringToOemSize(
1305 IN PUNICODE_STRING UnicodeString)
1309 RtlUnicodeToMultiByteSize (&Size,
1310 UnicodeString->Buffer,
1311 UnicodeString->Length);
1313 return Size+1; //NB: incl. nullterm
1319 RtlUnicodeStringToCountedOemString(
1320 IN OUT POEM_STRING DestinationString,
1321 IN PUNICODE_STRING SourceString,
1322 IN BOOLEAN AllocateDestinationString)
1328 if (NlsMbOemCodePageTag == TRUE)
1329 Length = RtlUnicodeStringToAnsiSize (SourceString)/* + 1*/;
1331 Length = SourceString->Length / sizeof(WCHAR) + 1;
1333 if (Length > 0x0000FFFF)
1334 return STATUS_INVALID_PARAMETER_2;
1336 DestinationString->Length = (WORD)(Length - 1);
1338 if (AllocateDestinationString)
1340 DestinationString->Buffer = RtlAllocateHeap (RtlGetProcessHeap (),
1343 if (DestinationString->Buffer == NULL)
1344 return STATUS_NO_MEMORY;
1346 RtlZeroMemory (DestinationString->Buffer,
1348 DestinationString->MaximumLength = (WORD)Length;
1352 if (Length > DestinationString->MaximumLength)
1354 if (DestinationString->MaximumLength == 0)
1355 return STATUS_BUFFER_OVERFLOW;
1356 DestinationString->Length =
1357 DestinationString->MaximumLength - 1;
1361 Status = RtlUnicodeToOemN (DestinationString->Buffer,
1362 DestinationString->Length,
1364 SourceString->Buffer,
1365 SourceString->Length);
1366 if (!NT_SUCCESS(Status))
1368 if (AllocateDestinationString)
1370 RtlFreeHeap (RtlGetProcessHeap (),
1372 DestinationString->Buffer);
1377 DestinationString->Buffer[Size] = 0;
1379 return STATUS_SUCCESS;
1385 RtlUnicodeStringToOemString(
1386 IN OUT POEM_STRING DestinationString,
1387 IN PUNICODE_STRING SourceString,
1388 IN BOOLEAN AllocateDestinationString)
1394 if (NlsMbOemCodePageTag == TRUE)
1395 Length = RtlUnicodeStringToAnsiSize (SourceString)/* + 1*/;
1397 Length = SourceString->Length / sizeof(WCHAR) + 1;
1399 if (Length > 0x0000FFFF)
1400 return STATUS_INVALID_PARAMETER_2;
1402 DestinationString->Length = (WORD)(Length - 1);
1404 if (AllocateDestinationString)
1406 DestinationString->Buffer = RtlAllocateHeap (RtlGetProcessHeap (),
1409 if (DestinationString->Buffer == NULL)
1410 return STATUS_NO_MEMORY;
1412 RtlZeroMemory (DestinationString->Buffer,
1414 DestinationString->MaximumLength = (WORD)Length;
1418 if (Length > DestinationString->MaximumLength)
1420 if (DestinationString->MaximumLength == 0)
1421 return STATUS_BUFFER_OVERFLOW;
1422 DestinationString->Length =
1423 DestinationString->MaximumLength - 1;
1427 Status = RtlUnicodeToOemN (DestinationString->Buffer,
1428 DestinationString->Length,
1430 SourceString->Buffer,
1431 SourceString->Length);
1432 if (!NT_SUCCESS(Status))
1434 if (AllocateDestinationString)
1436 RtlFreeHeap (RtlGetProcessHeap (),
1438 DestinationString->Buffer);
1443 DestinationString->Buffer[Size] = 0;
1445 return STATUS_SUCCESS;
1451 RtlUpcaseUnicodeChar(IN WCHAR Source)
1457 return (Source - (L'a' - L'A'));
1459 /* FIXME: characters above 'z' */
1467 RtlUpcaseUnicodeString(
1468 IN OUT PUNICODE_STRING DestinationString,
1469 IN PUNICODE_STRING SourceString,
1470 IN BOOLEAN AllocateDestinationString)
1475 if (AllocateDestinationString == TRUE)
1477 DestinationString->MaximumLength=SourceString->Length+sizeof(WCHAR);
1478 DestinationString->Buffer = RtlAllocateHeap (RtlGetProcessHeap (),
1480 SourceString->Length + sizeof(WCHAR));
1481 if (DestinationString->Buffer == NULL)
1482 return STATUS_NO_MEMORY;
1486 if (SourceString->Length >= DestinationString->MaximumLength)
1487 return STATUS_BUFFER_TOO_SMALL;
1489 DestinationString->Length = SourceString->Length;
1491 Src = SourceString->Buffer;
1492 Dest = DestinationString->Buffer;
1493 for (i = 0; i < SourceString->Length / sizeof(WCHAR); i++)
1495 *Dest = RtlUpcaseUnicodeChar (*Src);
1501 return STATUS_SUCCESS;
1507 RtlUpcaseUnicodeStringToAnsiString(
1508 IN OUT PANSI_STRING DestinationString,
1509 IN PUNICODE_STRING SourceString,
1510 IN BOOLEAN AllocateDestinationString)
1516 if (NlsMbCodePageTag == TRUE)
1517 Length = RtlUnicodeStringToAnsiSize (SourceString)/* + 1*/;
1519 Length = SourceString->Length / sizeof(WCHAR) + 1;
1521 if (Length > 0x0000FFFF)
1522 return STATUS_INVALID_PARAMETER_2;
1524 DestinationString->Length = (WORD)(Length - 1);
1526 if (AllocateDestinationString == TRUE)
1528 DestinationString->Buffer = RtlAllocateHeap (RtlGetProcessHeap (),
1530 DestinationString->MaximumLength);
1531 if (DestinationString->Buffer == NULL)
1532 return STATUS_NO_MEMORY;
1534 RtlZeroMemory (DestinationString->Buffer,
1536 DestinationString->MaximumLength = (WORD)Length;
1540 if (Length > DestinationString->MaximumLength)
1542 if (!DestinationString->MaximumLength)
1543 return STATUS_BUFFER_OVERFLOW;
1544 DestinationString->Length =
1545 DestinationString->MaximumLength - 1;
1549 Status = RtlUpcaseUnicodeToMultiByteN (DestinationString->Buffer,
1550 DestinationString->Length,
1552 SourceString->Buffer,
1553 SourceString->Length);
1554 if (!NT_SUCCESS(Status))
1556 if (AllocateDestinationString)
1558 RtlFreeHeap (RtlGetProcessHeap (),
1560 DestinationString->Buffer);
1565 DestinationString->Buffer[Size] = 0;
1567 return STATUS_SUCCESS;
1573 RtlUpcaseUnicodeStringToCountedOemString(
1574 IN OUT POEM_STRING DestinationString,
1575 IN PUNICODE_STRING SourceString,
1576 IN BOOLEAN AllocateDestinationString)
1582 if (NlsMbCodePageTag == TRUE)
1583 Length = RtlUnicodeStringToAnsiSize (SourceString)/* + 1*/;
1585 Length = SourceString->Length / sizeof(WCHAR) + 1;
1587 if (Length > 0x0000FFFF)
1588 return STATUS_INVALID_PARAMETER_2;
1590 DestinationString->Length = (WORD)(Length - 1);
1592 if (AllocateDestinationString == TRUE)
1594 DestinationString->Buffer = RtlAllocateHeap (RtlGetProcessHeap (),
1597 if (DestinationString->Buffer == NULL)
1598 return STATUS_NO_MEMORY;
1600 RtlZeroMemory (DestinationString->Buffer,
1602 DestinationString->MaximumLength = (WORD)Length;
1606 if (Length > DestinationString->MaximumLength)
1608 if (DestinationString->MaximumLength == 0)
1609 return STATUS_BUFFER_OVERFLOW;
1610 DestinationString->Length =
1611 DestinationString->MaximumLength - 1;
1615 Status = RtlUpcaseUnicodeToOemN (DestinationString->Buffer,
1616 DestinationString->Length,
1618 SourceString->Buffer,
1619 SourceString->Length);
1620 if (!NT_SUCCESS(Status))
1622 if (AllocateDestinationString)
1624 RtlFreeHeap (RtlGetProcessHeap (),
1626 DestinationString->Buffer);
1631 DestinationString->Buffer[Size] = 0;
1633 return STATUS_SUCCESS;
1639 RtlUpcaseUnicodeStringToOemString (
1640 IN OUT POEM_STRING DestinationString,
1641 IN PUNICODE_STRING SourceString,
1642 IN BOOLEAN AllocateDestinationString
1649 if (NlsMbOemCodePageTag == TRUE)
1650 Length = RtlUnicodeStringToAnsiSize (SourceString)/* + 1*/;
1652 Length = SourceString->Length / sizeof(WCHAR) + 1;
1654 if (Length > 0x0000FFFF)
1655 return STATUS_INVALID_PARAMETER_2;
1657 DestinationString->Length = (WORD)(Length - 1);
1659 if (AllocateDestinationString == TRUE)
1661 DestinationString->Buffer = RtlAllocateHeap (RtlGetProcessHeap (),
1664 if (DestinationString->Buffer == NULL)
1665 return STATUS_NO_MEMORY;
1667 RtlZeroMemory (DestinationString->Buffer,
1669 DestinationString->MaximumLength = (WORD)Length;
1673 if (Length > DestinationString->MaximumLength)
1675 if (DestinationString->MaximumLength == 0)
1676 return STATUS_BUFFER_OVERFLOW;
1677 DestinationString->Length =
1678 DestinationString->MaximumLength - 1;
1682 Status = RtlUpcaseUnicodeToOemN (DestinationString->Buffer,
1683 DestinationString->Length,
1685 SourceString->Buffer,
1686 SourceString->Length);
1687 if (!NT_SUCCESS(Status))
1689 if (AllocateDestinationString)
1691 RtlFreeHeap (RtlGetProcessHeap (),
1693 DestinationString->Buffer);
1698 DestinationString->Buffer[Size] = 0;
1700 return STATUS_SUCCESS;
1713 if (NlsMbCodePageTag == FALSE)
1715 /* single-byte code page */
1717 Unicode = (WCHAR)Source;
1719 Unicode = NlsAnsiToUnicodeData[Source];
1722 /* upcase conversion */
1723 Unicode = RtlUpcaseUnicodeChar (Unicode);
1725 /* unicode -> ansi */
1726 Destination = (CHAR)Unicode;
1728 Destination = NlsUnicodeToAnsiData[Unicode];
1733 /* single-byte code page */
1734 /* FIXME: implement the multi-byte stuff!! */
1735 Destination = Source;
1745 IN OUT PSTRING DestinationString,
1746 IN PSTRING SourceString)
1753 Length = min(SourceString->Length, DestinationString->MaximumLength - 1);
1755 Src = SourceString->Buffer;
1756 Dest = DestinationString->Buffer;
1757 for (i = 0; i < Length; i++)
1759 *Dest = RtlUpperChar (*Src);
1765 DestinationString->Length = SourceString->Length;
1771 RtlxAnsiStringToUnicodeSize(IN PANSI_STRING AnsiString)
1773 return RtlAnsiStringToUnicodeSize(AnsiString);
1779 RtlxOemStringToUnicodeSize(IN POEM_STRING OemString)
1781 return RtlAnsiStringToUnicodeSize((PANSI_STRING)OemString);
1787 RtlxUnicodeStringToAnsiSize(IN PUNICODE_STRING UnicodeString)
1789 return RtlUnicodeStringToAnsiSize(UnicodeString);
1795 RtlxUnicodeStringToOemSize(IN PUNICODE_STRING UnicodeString)
1797 return RtlUnicodeStringToAnsiSize(UnicodeString);