diff --git a/sdk/lib/rtl/unicode.c b/sdk/lib/rtl/unicode.c index 7f04540132..0524c5922c 100644 --- a/sdk/lib/rtl/unicode.c +++ b/sdk/lib/rtl/unicode.c @@ -3,7 +3,7 @@ * PROJECT: ReactOS system libraries * PURPOSE: Unicode Conversion Routines * FILE: lib/rtl/unicode.c - * PROGRAMMER: Alex Ionescu (alex@relsoft.net) + * PROGRAMMER: Alex Ionescu (alex.ionescu@reactos.org) * Emanuele Aliberti * Gunnar Dalsnes */ @@ -32,19 +32,71 @@ extern PUSHORT NlsUnicodeToMbOemTable; /* FUNCTIONS *****************************************************************/ +/* + * @implemented + */ NTSTATUS NTAPI RtlMultiAppendUnicodeStringBuffer(OUT PRTL_UNICODE_STRING_BUFFER StringBuffer, - IN ULONG NumberOfAddends, - IN PCUNICODE_STRING Addends) + IN ULONG NumberOfStrings, + IN PCUNICODE_STRING StringArray) { - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; + NTSTATUS Status; + SIZE_T Length, TotalLength, MaximumLength; + ULONG i; + + Length = TotalLength = StringBuffer->String.Length; + + /* Determine the total length we need for the destination string buffer */ + i = 0; + while (i < NumberOfStrings) + { + TotalLength += StringArray[i++].Length; + + /* Fail if we overflow */ + if (TotalLength > UNICODE_STRING_MAX_BYTES) + return STATUS_NAME_TOO_LONG; + } + + /* Account for the terminating NULL character */ + MaximumLength = TotalLength + sizeof(UNICODE_NULL); + + /* Fail if we overflow */ + if (MaximumLength > UNICODE_STRING_MAX_BYTES) + return STATUS_NAME_TOO_LONG; + + /* + * Ensure the size of the destination string buffer is big + * enough to hold the result, and grow it if necessary. + */ + Status = RtlEnsureBufferSize(0, &StringBuffer->ByteBuffer, MaximumLength); + if (!NT_SUCCESS(Status)) return Status; + + /* Initialize the destination string */ + StringBuffer->String.Buffer = (PWSTR)StringBuffer->ByteBuffer.Buffer; + StringBuffer->String.Length = (USHORT)TotalLength; + StringBuffer->String.MaximumLength = (USHORT)MaximumLength; + + /* Append each string into the destination string */ + i = 0; + while (i < NumberOfStrings) + { + RtlMoveMemory(&StringBuffer->String.Buffer[Length / sizeof(WCHAR)], + StringArray[i].Buffer, + StringArray[i].Length); + Length += StringArray[i++].Length; + } + + /* NULL-terminate the destination string */ + StringBuffer->String.Buffer[Length / sizeof(WCHAR)] = UNICODE_NULL; + + /* Done */ + return STATUS_SUCCESS; } /* -* @implemented -*/ + * @implemented + */ WCHAR NTAPI RtlAnsiCharToUnicodeChar(IN OUT PUCHAR *AnsiChar) @@ -2549,7 +2601,10 @@ RtlValidateUnicodeString( if (Flags != 0) return STATUS_INVALID_PARAMETER; - /* NOTE: a NULL Unicode string pointer is considered to be a valid one! */ + /* NOTE: + * A NULL Unicode string pointer is considered + * to be a valid unicode string! + */ if (String == NULL) { return STATUS_SUCCESS;