- 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@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]