- Fix a bunch of various bugs in the Rtl String routines, mostly subtle
(ie: fail AFTER writing maximum length, not before (some apps might
depend on it), fix completely broken RtlAnsiCharToUnicodeChar prototype
and functionality, don't clear buffers when we shouldn't/clear buffers
when we should...)
- Also cleanup formatting of the file
- Use Index member from Rtl...To...N API when null-terminating the
strings.
- Various optimizations and simplifications in some of the loops.
- Remove some duplicated code.
- Notes about special handling where required, also implement it in some
parts.
- Add more failure cases.
- Return correct status codes on failures.
Modified: trunk/reactos/lib/rtl/unicode.c
_____
Modified: trunk/reactos/lib/rtl/unicode.c
--- trunk/reactos/lib/rtl/unicode.c 2005-09-23 06:32:47 UTC (rev
18001)
+++ trunk/reactos/lib/rtl/unicode.c 2005-09-23 06:37:14 UTC (rev
18002)
@@ -3,7 +3,9 @@
* PROJECT: ReactOS system libraries
* PURPOSE: Unicode Conversion Routines
* FILE: lib/rtl/unicode.c
- * PROGRAMMER:
+ * PROGRAMMER: Alex Ionescu (alex(a)relsoft.net)
+ * Emanuele Aliberti
+ * Gunnar Dalsnes
*/
/* INCLUDES
*****************************************************************/
@@ -17,35 +19,87 @@
extern BOOLEAN NlsMbCodePageTag;
extern BOOLEAN NlsMbOemCodePageTag;
+extern PUSHORT NlsLeadByteInfo;
/* FUNCTIONS
*****************************************************************/
-
/*
* @implemented
*/
-WCHAR STDCALL
-RtlAnsiCharToUnicodeChar (IN CHAR AnsiChar)
+WCHAR
+STDCALL
+RtlAnsiCharToUnicodeChar(IN PUCHAR *AnsiChar)
{
- ULONG Size;
- WCHAR UnicodeChar;
+ ULONG Size;
+ NTSTATUS Status;
+ WCHAR UnicodeChar = 0x20;
- Size = 1;
-#if 0
+ Size = (NlsLeadByteInfo[**AnsiChar] == 0) ? 1 : 2;
- Size = (NlsLeadByteInfo[AnsiChar] == 0) ? 1 : 2;
-#endif
+ Status = RtlMultiByteToUnicodeN(&UnicodeChar,
+ sizeof(WCHAR),
+ NULL,
+ *AnsiChar,
+ Size);
- RtlMultiByteToUnicodeN (&UnicodeChar,
- sizeof(WCHAR),
- NULL,
- &AnsiChar,
- Size);
+ if (!NT_SUCCESS(Status))
+ {
+ UnicodeChar = 0x20;
+ }
- return UnicodeChar;
+ *AnsiChar += Size;
+ return UnicodeChar;
}
+/*
+ * @implemented
+ *
+ * NOTES
+ * This function always writes a terminating '\0'.
+ * If the dest buffer is too small a partial copy is NOT performed!
+ */
+NTSTATUS
+STDCALL
+RtlAnsiStringToUnicodeString(
+ IN OUT PUNICODE_STRING UniDest,
+ IN PANSI_STRING AnsiSource,
+ IN BOOLEAN AllocateDestinationString)
+{
+ NTSTATUS Status;
+ ULONG Length;
+ ULONG Index;
+ Length = RtlAnsiStringToUnicodeSize(AnsiSource);
+ if (Length > MAXUSHORT) return STATUS_INVALID_PARAMETER_2;
+ UniDest->Length = (USHORT)Length - sizeof(WCHAR);
+
+ if (AllocateDestinationString == TRUE)
+ {
+ UniDest->Buffer = RtlpAllocateStringMemory(Length, TAG_USTR);
+ UniDest->MaximumLength = Length;
+ if (!UniDest->Buffer) return STATUS_NO_MEMORY;
+ }
+ else if (Length >= UniDest->MaximumLength)
+ {
+ return STATUS_BUFFER_TOO_SMALL;
+ }
+
+ Status = RtlMultiByteToUnicodeN(UniDest->Buffer,
+ UniDest->Length,
+ &Index,
+ AnsiSource->Buffer,
+ AnsiSource->Length);
+
+ if (!NT_SUCCESS(Status) && AllocateDestinationString)
+ {
+ RtlpFreeStringMemory(UniDest->Buffer, TAG_USTR);
+ return Status;
+ }
+
+ UniDest->Buffer[Index / sizeof(WCHAR)] = UNICODE_NULL;
+ return Status;
+}
+
/*
* @implemented
*
@@ -67,8 +121,6 @@
return(Size + sizeof(WCHAR));
}
-
-
/*
* @implemented
*
@@ -78,31 +130,28 @@
*/
NTSTATUS
STDCALL
-RtlAppendStringToString(IN OUT PSTRING Destination,
+RtlAppendStringToString(IN PSTRING Destination,
IN PSTRING Source)
{
- PCHAR Ptr;
+ USHORT SourceLength = Source->Length;
- if (Source->Length == 0)
- return(STATUS_SUCCESS);
+ if (SourceLength)
+ {
+ if (Destination->Length + SourceLength >
Destination->MaximumLength)
+ {
+ return STATUS_BUFFER_TOO_SMALL;
+ }
- if (Destination->Length + Source->Length >=
Destination->MaximumLength)
- return(STATUS_BUFFER_TOO_SMALL);
+ RtlMoveMemory(&Destination->Buffer[Destination->Length],
+ Source->Buffer,
+ SourceLength);
- Ptr = Destination->Buffer + Destination->Length;
- memmove(Ptr,
- Source->Buffer,
- Source->Length);
- Ptr += Source->Length;
- *Ptr = 0;
+ Destination->Length += SourceLength;
+ }
- Destination->Length += Source->Length;
-
- return(STATUS_SUCCESS);
+ return STATUS_SUCCESS;
}
-
-
/*
* @implemented
*
@@ -117,20 +166,29 @@
IN OUT PUNICODE_STRING Destination,
IN PCUNICODE_STRING Source)
{
+ USHORT SourceLength = Source->Length;
+ PWCHAR Buffer = &Destination->Buffer[Destination->Length /
sizeof(WCHAR)];
- if ((Source->Length + Destination->Length) >
Destination->MaximumLength)
- return STATUS_BUFFER_TOO_SMALL;
+ if (SourceLength)
+ {
+ if ((SourceLength+ Destination->Length) >
Destination->MaximumLength)
+ {
+ return STATUS_BUFFER_TOO_SMALL;
+ }
- memcpy((char*)Destination->Buffer + Destination->Length,
Source->Buffer, Source->Length);
- Destination->Length += Source->Length;
- /* append terminating '\0' if enough space */
- if( Destination->MaximumLength > Destination->Length )
- Destination->Buffer[Destination->Length / sizeof(WCHAR)] = 0;
+ RtlMoveMemory(Buffer, Source->Buffer, SourceLength);
+ Destination->Length += SourceLength;
- return STATUS_SUCCESS;
+ /* append terminating '\0' if enough space */
+ if (Destination->MaximumLength > Destination->Length)
+ {
+ Buffer[SourceLength / sizeof(WCHAR)] = UNICODE_NULL;
+ }
+ }
+
+ return STATUS_SUCCESS;
}
-
/***********************************************************************
***
* RtlCharToInteger (NTDLL.@)
* @implemented
@@ -251,7 +309,6 @@
return ret;
}
-
/*
* @implemented
*
@@ -265,11 +322,10 @@
IN PSTRING s2,
IN BOOLEAN CaseInsensitive)
{
- if (s1->Length != s2->Length) return FALSE;
- return !RtlCompareString(s1, s2, CaseInsensitive );
+ if (s1->Length != s2->Length) return FALSE;
+ return !RtlCompareString(s1, s2, CaseInsensitive);
}
-
/*
* @implemented
*
@@ -283,11 +339,10 @@
IN CONST UNICODE_STRING *s2,
IN BOOLEAN CaseInsensitive)
{
- if (s1->Length != s2->Length) return FALSE;
- return !RtlCompareUnicodeString((PUNICODE_STRING)s1,
(PUNICODE_STRING)s2, CaseInsensitive );
+ if (s1->Length != s2->Length) return FALSE;
+ return !RtlCompareUnicodeString(s1, s2, CaseInsensitive );
}
-
/*
* @implemented
*/
@@ -295,17 +350,13 @@
STDCALL
RtlFreeAnsiString(IN PANSI_STRING AnsiString)
{
- if (AnsiString->Buffer != NULL)
- {
- RtlpFreeStringMemory(AnsiString->Buffer, TAG_ASTR);
-
- AnsiString->Buffer = NULL;
- AnsiString->Length = 0;
- AnsiString->MaximumLength = 0;
- }
+ if (AnsiString->Buffer)
+ {
+ RtlpFreeStringMemory(AnsiString->Buffer, TAG_ASTR);
+ RtlZeroMemory(AnsiString, sizeof(ANSI_STRING));
+ }
}
-
/*
* @implemented
*/
@@ -313,17 +364,9 @@
STDCALL
RtlFreeOemString(IN POEM_STRING OemString)
{
- if (OemString->Buffer != NULL)
- {
- RtlpFreeStringMemory(OemString->Buffer, TAG_OSTR);
-
- OemString->Buffer = NULL;
- OemString->Length = 0;
- OemString->MaximumLength = 0;
- }
+ if (OemString->Buffer) RtlpFreeStringMemory(OemString->Buffer,
TAG_OSTR);
}
-
/*
* @implemented
*/
@@ -331,14 +374,11 @@
STDCALL
RtlFreeUnicodeString(IN PUNICODE_STRING UnicodeString)
{
- if (UnicodeString->Buffer != NULL)
- {
- RtlpFreeStringMemory(UnicodeString->Buffer, TAG_USTR);
-
- UnicodeString->Buffer = NULL;
- UnicodeString->Length = 0;
- UnicodeString->MaximumLength = 0;
- }
+ if (UnicodeString->Buffer)
+ {
+ RtlpFreeStringMemory(UnicodeString->Buffer, TAG_ASTR);
+ RtlZeroMemory(UnicodeString, sizeof(UNICODE_STRING));
+ }
}
/*
@@ -346,12 +386,10 @@
*/
BOOLEAN
STDCALL
-RtlIsValidOemCharacter (
- IN PWCHAR Char
- )
+RtlIsValidOemCharacter(IN PWCHAR Char)
{
- UNIMPLEMENTED;
- return FALSE;
+ UNIMPLEMENTED;
+ return FALSE;
}
/*
@@ -365,24 +403,23 @@
RtlInitAnsiString(IN OUT PANSI_STRING DestinationString,
IN PCSZ SourceString)
{
- ULONG DestSize;
+ ULONG DestSize;
- if (SourceString == NULL)
- {
- DestinationString->Length = 0;
- DestinationString->MaximumLength = 0;
- }
- else
- {
- DestSize = strlen ((const char *)SourceString);
- DestinationString->Length = DestSize;
- DestinationString->MaximumLength = DestSize + sizeof(CHAR);
- }
- DestinationString->Buffer = (PCHAR)SourceString;
+ if(SourceString)
+ {
+ DestSize = strlen(SourceString);
+ DestinationString->Length = (USHORT)DestSize;
+ DestinationString->MaximumLength = (USHORT)DestSize +
sizeof(CHAR);
+ }
+ else
+ {
+ DestinationString->Length = 0;
+ DestinationString->MaximumLength = 0;
+ }
+
+ DestinationString->Buffer = (PCHAR)SourceString;
}
-
-
/*
* @implemented
*
@@ -395,23 +432,9 @@
IN OUT PSTRING DestinationString,
IN PCSZ SourceString)
{
- ULONG DestSize;
-
- if (SourceString == NULL)
- {
- DestinationString->Length = 0;
- DestinationString->MaximumLength = 0;
- }
- else
- {
- DestSize = strlen((const char *)SourceString);
- DestinationString->Length = DestSize;
- DestinationString->MaximumLength = DestSize + sizeof(CHAR);
- }
- DestinationString->Buffer = (PCHAR)SourceString;
+ RtlInitAnsiString(DestinationString, SourceString);
}
-
/*
* @implemented
*
@@ -423,53 +446,48 @@
RtlInitUnicodeString(IN OUT PUNICODE_STRING DestinationString,
IN PCWSTR SourceString)
{
- ULONG DestSize;
+ ULONG DestSize;
- DPRINT("RtlInitUnicodeString(DestinationString 0x%p, SourceString
0x%p)\n",
- DestinationString,
- SourceString);
+ if(SourceString)
+ {
+ DestSize = wcslen(SourceString) * sizeof(WCHAR);
+ DestinationString->Length = (USHORT)DestSize;
+ DestinationString->MaximumLength = (USHORT)DestSize +
sizeof(WCHAR);
+ }
+ else
+ {
+ DestinationString->Length = 0;
+ DestinationString->MaximumLength = 0;
+ }
- if (SourceString == NULL)
- {
- DestinationString->Length = 0;
- DestinationString->MaximumLength = 0;
- }
- else
- {
- DestSize = wcslen((PWSTR)SourceString) * sizeof(WCHAR);
- DestinationString->Length = DestSize;
- DestinationString->MaximumLength = DestSize + sizeof(WCHAR);
- }
- DestinationString->Buffer = (PWSTR)SourceString;
+ DestinationString->Buffer = (PWCHAR)SourceString;
}
/*
* @implemented
*/
-NTSTATUS STDCALL
+NTSTATUS
+STDCALL
RtlInitUnicodeStringEx(OUT PUNICODE_STRING DestinationString,
IN PCWSTR SourceString)
{
- ULONG Length;
+ ULONG DestSize;
- if (SourceString != NULL)
- {
- Length = wcslen(SourceString) * sizeof(WCHAR);
- if (Length > 0xFFFC)
- return STATUS_NAME_TOO_LONG;
+ if(SourceString)
+ {
+ DestSize = wcslen(SourceString) * sizeof(WCHAR);
+ if (DestSize > 0xFFFC) return STATUS_NAME_TOO_LONG;
+ DestinationString->Length = (USHORT)DestSize;
+ DestinationString->MaximumLength = (USHORT)DestSize +
sizeof(WCHAR);
+ }
+ else
+ {
+ DestinationString->Length = 0;
+ DestinationString->MaximumLength = 0;
+ }
- DestinationString->Length = Length;
- DestinationString->MaximumLength = Length + sizeof(WCHAR);
- DestinationString->Buffer = (PWSTR)SourceString;
- }
- else
- {
- DestinationString->Length = 0;
- DestinationString->MaximumLength = 0;
- DestinationString->Buffer = NULL;
- }
-
- return STATUS_SUCCESS;
+ DestinationString->Buffer = (PWCHAR)SourceString;
+ return STATUS_SUCCESS;
}
/*
@@ -530,7 +548,6 @@
return STATUS_SUCCESS;
}
-
/*
* @implemented
*/
@@ -585,78 +602,63 @@
return STATUS_SUCCESS;
}
-
-
/*
* @implemented
*/
NTSTATUS
STDCALL
RtlIntegerToUnicodeString(
- IN ULONG Value,
- IN ULONG Base, /* optional */
+ IN ULONG Value,
+ IN ULONG Base OPTIONAL,
IN OUT PUNICODE_STRING String)
{
- ANSI_STRING AnsiString;
- CHAR Buffer[33];
- NTSTATUS Status;
+ ANSI_STRING AnsiString;
+ CHAR Buffer[16];
+ NTSTATUS Status;
- Status = RtlIntegerToChar (Value,
- Base,
- sizeof(Buffer),
- Buffer);
- if (NT_SUCCESS(Status))
- {
- AnsiString.Buffer = Buffer;
- AnsiString.Length = strlen (Buffer);
- AnsiString.MaximumLength = sizeof(Buffer);
+ Status = RtlIntegerToChar(Value, Base, sizeof(Buffer), Buffer);
+ if (NT_SUCCESS(Status))
+ {
+ AnsiString.Buffer = Buffer;
+ AnsiString.Length = (USHORT)strlen(Buffer);
+ AnsiString.MaximumLength = sizeof(Buffer);
- Status = RtlAnsiStringToUnicodeString (String,
- &AnsiString,
- FALSE);
- }
+ Status = RtlAnsiStringToUnicodeString(String, &AnsiString,
FALSE);
+ }
- return Status;
+ return Status;
}
-
/*
-* @implemented
-*/
+ * @implemented
+ */
NTSTATUS
STDCALL
RtlInt64ToUnicodeString (
- IN ULONGLONG Value,
- IN ULONG Base OPTIONAL,
- IN OUT PUNICODE_STRING String
- )
+ IN ULONGLONG Value,
+ IN ULONG Base OPTIONAL,
+ IN OUT PUNICODE_STRING String)
{
- LARGE_INTEGER LargeInt;
- ANSI_STRING AnsiString;
- CHAR Buffer[33];
- NTSTATUS Status;
+ LARGE_INTEGER LargeInt;
+ ANSI_STRING AnsiString;
+ CHAR Buffer[32];
+ NTSTATUS Status;
- LargeInt.QuadPart = Value;
+ LargeInt.QuadPart = Value;
- Status = RtlLargeIntegerToChar (&LargeInt,
- Base,
- sizeof(Buffer),
- Buffer);
- if (NT_SUCCESS(Status))
- {
- AnsiString.Buffer = Buffer;
- AnsiString.Length = strlen (Buffer);
- AnsiString.MaximumLength = sizeof(Buffer);
+ Status = RtlLargeIntegerToChar(&LargeInt, Base, sizeof(Buffer),
Buffer);
+ if (NT_SUCCESS(Status))
+ {
+ AnsiString.Buffer = Buffer;
+ AnsiString.Length = (USHORT)strlen(Buffer);
+ AnsiString.MaximumLength = sizeof(Buffer);
- Status = RtlAnsiStringToUnicodeString (String,
- &AnsiString,
- FALSE);
- }
+ Status = RtlAnsiStringToUnicodeString(String, &AnsiString,
FALSE);
+ }
- return Status;
+ return Status;
}
-
/*
* @implemented
*
@@ -704,7 +706,6 @@
return FALSE;
}
-
/*
* @implemented
*
@@ -864,7 +865,6 @@
return STATUS_SUCCESS;
}
-
/*
* @implemented
*
@@ -889,7 +889,6 @@
/*
* @implemented
*
-
* NOTES
* This function always writes a terminating '\0'.
* It performs a partial copy if ansi is too small.
@@ -901,47 +900,46 @@
IN PCUNICODE_STRING UniSource,
IN BOOLEAN AllocateDestinationString)
{
- NTSTATUS Status = STATUS_SUCCESS;
- ULONG Length; /* including nullterm */
+ NTSTATUS Status = STATUS_SUCCESS;
+ NTSTATUS RealStatus;
+ ULONG Length;
+ ULONG Index;
- Length = RtlUnicodeStringToAnsiSize(UniSource);
- AnsiDest->Length = Length - sizeof(CHAR);
+ Length = RtlUnicodeStringToAnsiSize(UniSource);
+ if (Length > MAXUSHORT) return STATUS_INVALID_PARAMETER_2;
- if (AllocateDestinationString)
- {
- AnsiDest->Buffer = RtlpAllocateStringMemory(Length, TAG_ASTR);
- if (AnsiDest->Buffer == NULL)
- return STATUS_NO_MEMORY;
+ AnsiDest->Length = (USHORT)Length - sizeof(CHAR);
- AnsiDest->MaximumLength = Length;
- }
- else if (AnsiDest->MaximumLength == 0)
- {
- return STATUS_BUFFER_TOO_SMALL;
- }
- else if (Length > AnsiDest->MaximumLength)
- {
- /* make room for nullterm */
- AnsiDest->Length = AnsiDest->MaximumLength - sizeof(CHAR);
- }
+ if (AllocateDestinationString)
+ {
+ AnsiDest->Buffer = RtlpAllocateStringMemory(Length, TAG_ASTR);
+ AnsiDest->MaximumLength = Length;
+ if (!AnsiDest->Buffer) return STATUS_NO_MEMORY;
+ }
+ else if (AnsiDest->Length >= AnsiDest->MaximumLength)
+ {
+ if (!AnsiDest->MaximumLength) return STATUS_BUFFER_OVERFLOW;
- Status = RtlUnicodeToMultiByteN (AnsiDest->Buffer,
- AnsiDest->Length,
- NULL,
- UniSource->Buffer,
- UniSource->Length);
+ Status = STATUS_BUFFER_OVERFLOW;
+ AnsiDest->Length = AnsiDest->MaximumLength - 1;
+ }
- if (!NT_SUCCESS(Status) && AllocateDestinationString)
- {
- RtlpFreeStringMemory(AnsiDest->Buffer, TAG_ASTR);
- return Status;
- }
+ RealStatus = RtlUnicodeToMultiByteN(AnsiDest->Buffer,
+ AnsiDest->Length,
+ &Index,
+ UniSource->Buffer,
+ UniSource->Length);
- AnsiDest->Buffer[AnsiDest->Length] = 0;
- return Status;
+ if (!NT_SUCCESS(RealStatus) && AllocateDestinationString)
+ {
+ RtlpFreeStringMemory(AnsiDest->Buffer, TAG_ASTR);
+ return RealStatus;
+ }
+
+ AnsiDest->Buffer[Index] = ANSI_NULL;
+ return Status;
}
-
/*
* @implemented
*
@@ -956,50 +954,43 @@
IN PCOEM_STRING OemSource,
IN BOOLEAN AllocateDestinationString)
{
- NTSTATUS Status;
- ULONG Length; /* including nullterm */
+ NTSTATUS Status;
+ ULONG Length;
+ ULONG Index;
- Length = RtlOemStringToUnicodeSize(OemSource);
- if (Length > 0xffff)
- return STATUS_INVALID_PARAMETER_2;
+ Length = RtlOemStringToUnicodeSize(OemSource);
+ if (Length > MAXUSHORT) return STATUS_INVALID_PARAMETER_2;
- UniDest->Length = (WORD)(Length - sizeof(WCHAR));
+ UniDest->Length = (USHORT)Length - sizeof(WCHAR);
- if (AllocateDestinationString)
- {
- UniDest->Buffer = RtlpAllocateStringMemory(Length, TAG_USTR);
- if (UniDest->Buffer == NULL)
- return STATUS_NO_MEMORY;
+ if (AllocateDestinationString)
+ {
+ UniDest->Buffer = RtlpAllocateStringMemory(Length, TAG_USTR);
+ UniDest->MaximumLength = Length;
+ if (!UniDest->Buffer) return STATUS_NO_MEMORY;
+ }
+ else if (UniDest->Length >= UniDest->MaximumLength)
+ {
+ return STATUS_BUFFER_OVERFLOW;
+ }
- UniDest->MaximumLength = Length;
- }
- else if (Length > UniDest->MaximumLength)
- {
- DPRINT("STATUS_BUFFER_TOO_SMALL\n");
- return STATUS_BUFFER_TOO_SMALL;
- }
-
- /* FIXME: Do we need this????? -Gunnar */
- RtlZeroMemory (UniDest->Buffer,
- UniDest->Length);
-
- Status = RtlOemToUnicodeN (UniDest->Buffer,
+ Status = RtlOemToUnicodeN(UniDest->Buffer,
UniDest->Length,
- NULL,
+ &Index,
OemSource->Buffer,
OemSource->Length);
- if (!NT_SUCCESS(Status) && AllocateDestinationString)
- {
- RtlpFreeStringMemory(UniDest->Buffer, TAG_USTR);
- return Status;
- }
+ if (!NT_SUCCESS(Status) && AllocateDestinationString)
+ {
+ RtlpFreeStringMemory(UniDest->Buffer, TAG_USTR);
+ UniDest->Buffer = NULL;
+ return Status;
+ }
- UniDest->Buffer[UniDest->Length / sizeof(WCHAR)] = 0;
- return STATUS_SUCCESS;
+ UniDest->Buffer[Index / sizeof(WCHAR)] = UNICODE_NULL;
+ return Status;
}
-
/*
* @implemented
*
@@ -1013,52 +1004,45 @@
IN PCUNICODE_STRING UniSource,
IN BOOLEAN AllocateDestinationString)
{
- NTSTATUS Status = STATUS_SUCCESS;
- ULONG Length; //including nullterm
+ NTSTATUS Status;
+ ULONG Length;
+ ULONG Index;
- Length = RtlUnicodeStringToAnsiSize(UniSource);
- if (Length > 0x0000FFFF)
- return STATUS_INVALID_PARAMETER_2;
+ Length = RtlUnicodeStringToOemSize(UniSource);
+ if (Length > MAXUSHORT) return STATUS_INVALID_PARAMETER_2;
- OemDest->Length = (WORD)(Length - sizeof(CHAR));
+ OemDest->Length = (USHORT)Length - sizeof(CHAR);
- if (AllocateDestinationString)
- {
- OemDest->Buffer = RtlpAllocateStringMemory(Length, TAG_OSTR);
- if (OemDest->Buffer == NULL)
- return STATUS_NO_MEMORY;
+ if (AllocateDestinationString)
+ {
+ OemDest->Buffer = RtlpAllocateStringMemory(Length, TAG_OSTR);
+ OemDest->MaximumLength = Length;
+ if (!OemDest->Buffer) return STATUS_NO_MEMORY;
+ }
+ else if (OemDest->Length >= OemDest->MaximumLength)
+ {
+ return STATUS_BUFFER_OVERFLOW;
+ }
- OemDest->MaximumLength = Length;
- }
- else if (OemDest->MaximumLength == 0)
- {
- return STATUS_BUFFER_TOO_SMALL;
- }
- else if (Length > OemDest->MaximumLength)
- {
- //make room for nullterm
- OemDest->Length = OemDest->MaximumLength - sizeof(CHAR);
- }
-
- Status = RtlUnicodeToOemN (OemDest->Buffer,
+ Status = RtlUnicodeToOemN(OemDest->Buffer,
OemDest->Length,
- NULL,
+ &Index,
UniSource->Buffer,
UniSource->Length);
- if (!NT_SUCCESS(Status) && AllocateDestinationString)
- {
- RtlpFreeStringMemory(OemDest->Buffer, TAG_OSTR);
- return Status;
- }
+ if (!NT_SUCCESS(Status) && AllocateDestinationString)
+ {
+ RtlpFreeStringMemory(OemDest->Buffer, TAG_OSTR);
+ OemDest->Buffer = NULL;
+ return Status;
+ }
- OemDest->Buffer[OemDest->Length] = 0;
- return Status;
+ OemDest->Buffer[Index] = ANSI_NULL;
+ return Status;
}
#define ITU_IMPLEMENTED_TESTS
(IS_TEXT_UNICODE_ODD_LENGTH|IS_TEXT_UNICODE_SIGNATURE)
-
/*
* @implemented
*
@@ -1117,7 +1101,6 @@
return Length;
}
-
/*
* @implemented
*
@@ -1132,41 +1115,47 @@
IN PCOEM_STRING OemSource,
IN BOOLEAN AllocateDestinationString)
{
- NTSTATUS Status;
- ULONG Length; /* excluding nullterm */
+ NTSTATUS Status;
+ ULONG Length;
+ ULONG Index;
- Length = RtlOemStringToCountedUnicodeSize(OemSource);
- if (Length > 65535)
- return STATUS_INVALID_PARAMETER_2;
+ Length = RtlOemStringToCountedUnicodeSize(OemSource);
- if (AllocateDestinationString == TRUE)
- {
- UniDest->Buffer = RtlpAllocateStringMemory (Length, TAG_USTR);
- if (UniDest->Buffer == NULL)
- return STATUS_NO_MEMORY;
+ if (!Length)
+ {
+ RtlZeroMemory(UniDest, sizeof(UNICODE_STRING));
+ return STATUS_SUCCESS;
+ }
- UniDest->MaximumLength = Length;
- }
- else if (Length > UniDest->MaximumLength)
- {
- return STATUS_BUFFER_TOO_SMALL;
- }
+ if (Length > MAXUSHORT) return STATUS_INVALID_PARAMETER_2;
- UniDest->Length = Length;
+ UniDest->Length = (USHORT)Length;
- Status = RtlOemToUnicodeN (UniDest->Buffer,
+ if (AllocateDestinationString)
+ {
+ UniDest->Buffer = RtlpAllocateStringMemory(Length, TAG_USTR);
+ UniDest->MaximumLength = Length;
+ if (!UniDest->Buffer) return STATUS_NO_MEMORY;
+ }
+ else if (UniDest->Length >= UniDest->MaximumLength)
+ {
+ return STATUS_BUFFER_OVERFLOW;
+ }
+
+ Status = RtlOemToUnicodeN(UniDest->Buffer,
UniDest->Length,
- NULL,
+ &Index,
OemSource->Buffer,
OemSource->Length);
- if (!NT_SUCCESS(Status) && AllocateDestinationString)
- {
- RtlpFreeStringMemory(UniDest->Buffer, TAG_USTR);
- return Status;
- }
+ if (!NT_SUCCESS(Status) && AllocateDestinationString)
+ {
+ RtlpFreeStringMemory(UniDest->Buffer, TAG_USTR);
+ UniDest->Buffer = NULL;
+ return Status;
+ }
- return Status;
+ return STATUS_SUCCESS;
}
/*
@@ -1184,21 +1173,25 @@
IN PUNICODE_STRING ComputerName1,
IN PUNICODE_STRING ComputerName2)
{
- OEM_STRING OemString1;
- OEM_STRING OemString2;
- BOOLEAN Result = FALSE;
+ OEM_STRING OemString1;
+ OEM_STRING OemString2;
+ BOOLEAN Result = FALSE;
- if (NT_SUCCESS(RtlUpcaseUnicodeStringToOemString( &OemString1,
ComputerName1, TRUE )))
- {
- if (NT_SUCCESS(RtlUpcaseUnicodeStringToOemString( &OemString2,
ComputerName2, TRUE )))
- {
- Result = RtlEqualString( &OemString1, &OemString2, TRUE );
- RtlFreeOemString( &OemString2 );
- }
- RtlFreeOemString( &OemString1 );
- }
+ if (NT_SUCCESS(RtlUpcaseUnicodeStringToOemString(&OemString1,
+ ComputerName1,
+ TRUE)))
+ {
+ if (NT_SUCCESS(RtlUpcaseUnicodeStringToOemString(&OemString2,
+ ComputerName2,
+ TRUE)))
+ {
+ Result = RtlEqualString(&OemString1, &OemString2, FALSE);
+ RtlFreeOemString(&OemString2);
+ }
+ RtlFreeOemString(&OemString1);
+ }
- return Result;
+ return Result;
}
/*
@@ -1217,46 +1210,11 @@
IN PUNICODE_STRING DomainName2
)
{
- return RtlEqualComputerName(DomainName1, DomainName2);
+ return RtlEqualComputerName(DomainName1, DomainName2);
}
-
/*
* @implemented
- */
-/*
-BOOLEAN
-STDCALL
-RtlEqualDomainName (
- IN PUNICODE_STRING DomainName1,
- IN PUNICODE_STRING DomainName2
-)
-{
- OEM_STRING OemString1;
- OEM_STRING OemString2;
- BOOLEAN Result;
-
- RtlUpcaseUnicodeStringToOemString (&OemString1,
- DomainName1,
[truncated at 1000 lines; 877 more skipped]