Author: tfaber Date: Sat Jul 16 07:08:21 2016 New Revision: 71950 URL: http://svn.reactos.org/svn/reactos?rev=71950&view=rev Log: [KERNEL32] - Fix GetComputerNameEx behavior with regard to NULL/non-NULL buffers and size calculation CORE-11368
Added: trunk/rostests/apitests/kernel32/GetComputerNameEx.c (with props) Modified: trunk/reactos/dll/win32/kernel32/client/compname.c trunk/rostests/apitests/kernel32/CMakeLists.txt trunk/rostests/apitests/kernel32/testlist.c Modified: trunk/reactos/dll/win32/kernel32/client/compname.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/client/compname.c?rev=71950&r1=71949&r2=71950&view=diff ============================================================================== --- trunk/reactos/dll/win32/kernel32/client/compname.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/kernel32/client/compname.c [iso-8859-1] Sat Jul 16 07:08:21 2016 @@ -88,7 +88,7 @@ if (!NT_SUCCESS(Status)) { - *nSize = ReturnSize; + *nSize = (ReturnSize - FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data)) / sizeof(WCHAR); goto failed; } @@ -100,7 +100,7 @@ if (!lpBuffer || *nSize < (KeyInfo->DataLength / sizeof(WCHAR))) { - *nSize = ReturnSize; + *nSize = (ReturnSize - FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data)) / sizeof(WCHAR); Status = STATUS_BUFFER_OVERFLOW; goto failed; } @@ -134,6 +134,13 @@ NTSTATUS Status; BOOL ret = TRUE; DWORD HostSize; + + if ((nSize == NULL) || + (lpBuffer == NULL && *nSize > 0)) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } switch (NameType) { @@ -263,19 +270,23 @@ UNICODE_STRING UnicodeString; ANSI_STRING AnsiString; BOOL Result; - PWCHAR TempBuffer; - - if (!lpBuffer) + PWCHAR TempBuffer = NULL; + + if ((nSize == NULL) || + (lpBuffer == NULL && *nSize > 0)) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } - TempBuffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, *nSize * sizeof(WCHAR)); - if (!TempBuffer) - { - SetLastError(ERROR_NOT_ENOUGH_MEMORY); - return FALSE; + if (*nSize > 0) + { + TempBuffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, *nSize * sizeof(WCHAR)); + if (!TempBuffer) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return FALSE; + } } AnsiString.MaximumLength = (USHORT)*nSize; @@ -287,7 +298,7 @@ if (Result) { UnicodeString.MaximumLength = (USHORT)*nSize * sizeof(WCHAR) + sizeof(WCHAR); - UnicodeString.Length = (USHORT)*nSize * sizeof(WCHAR) + sizeof(WCHAR); + UnicodeString.Length = (USHORT)*nSize * sizeof(WCHAR); UnicodeString.Buffer = TempBuffer; RtlUnicodeStringToAnsiString(&AnsiString, Modified: trunk/rostests/apitests/kernel32/CMakeLists.txt URL: http://svn.reactos.org/svn/reactos/trunk/rostests/apitests/kernel32/CMakeLists.txt?rev=71950&r1=71949&r2=71950&view=diff ============================================================================== --- trunk/rostests/apitests/kernel32/CMakeLists.txt [iso-8859-1] (original) +++ trunk/rostests/apitests/kernel32/CMakeLists.txt [iso-8859-1] Sat Jul 16 07:08:21 2016 @@ -2,6 +2,7 @@ list(APPEND SOURCE dosdev.c FindFiles.c + GetComputerNameEx.c GetCurrentDirectory.c GetDriveType.c GetModuleFileName.c Added: trunk/rostests/apitests/kernel32/GetComputerNameEx.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/apitests/kernel32/GetComputerNameEx.c?rev=71950 ============================================================================== --- trunk/rostests/apitests/kernel32/GetComputerNameEx.c (added) +++ trunk/rostests/apitests/kernel32/GetComputerNameEx.c [iso-8859-1] Sat Jul 16 07:08:21 2016 @@ -0,0 +1,192 @@ +/* + * PROJECT: ReactOS API tests + * LICENSE: LGPLv2.1+ - See COPYING.LIB in the top level directory + * PURPOSE: Test for GetComputerNameEx + * PROGRAMMER: Thomas Faber <thomas.fa...@reactos.org> + */ + +#include <apitest.h> + +#define WIN32_NO_STATUS +#include <stdio.h> +#include <ndk/rtltypes.h> + +static +VOID +TestGetComputerNameEx( + _In_ COMPUTER_NAME_FORMAT NameType) +{ + WCHAR Reference[128]; + DWORD ReferenceLen; + WCHAR BufferW[128]; + CHAR BufferA[128]; + BOOL Ret; + DWORD Size; + DWORD Error; + ULONG i; + + Size = RTL_NUMBER_OF(Reference); + Ret = GetComputerNameExW(NameType, Reference, &Size); + ok(Ret == TRUE, "[%d] GetComputerNameExW returned %d\n", NameType, Ret); + if (!Ret) + { + skip("[%d] Failed to get reference string\n", NameType); + return; + } + trace("[%d] Reference is %ls\n", NameType, Reference); + ReferenceLen = wcslen(Reference); + ok(ReferenceLen < RTL_NUMBER_OF(Reference), + "[%d] Unexpected ReferenceLen %lu\n", NameType, ReferenceLen); + if (NameType != ComputerNameDnsDomain && NameType != ComputerNamePhysicalDnsDomain) + { + ok(ReferenceLen != 0, "[%d] Unexpected ReferenceLen %lu\n", NameType, ReferenceLen); + } + ok(Size == ReferenceLen, "[%d] Size is %lu, expected %lu\n", NameType, Size, ReferenceLen); + + /* NULL buffer, NULL size */ + StartSeh() + Ret = GetComputerNameExW(NameType, NULL, NULL); + Error = GetLastError(); + ok(Ret == FALSE, "[%d] GetComputerNameExW returned %d\n", NameType, Ret); + ok(Error == ERROR_INVALID_PARAMETER, "[%d] GetComputerNameExW returned error %lu\n", NameType, Error); + EndSeh(STATUS_SUCCESS); + StartSeh() + Ret = GetComputerNameExA(NameType, NULL, NULL); + Error = GetLastError(); + ok(Ret == FALSE, "[%d] GetComputerNameExW returned %d\n", NameType, Ret); + ok(Error == ERROR_INVALID_PARAMETER, "[%d] GetComputerNameExW returned error %lu\n", NameType, Error); + EndSeh(STATUS_SUCCESS); + + /* NULL buffer, nonzero size */ + Size = 0x55555555; + Ret = GetComputerNameExW(NameType, NULL, &Size); + Error = GetLastError(); + ok(Ret == FALSE, "[%d] GetComputerNameExW returned %d\n", NameType, Ret); + ok(Error == ERROR_INVALID_PARAMETER, "[%d] GetComputerNameExW returned error %lu\n", NameType, Error); + ok(Size == 0x55555555, "[%d] Got Size %lu\n", NameType, Size); + + Size = 0x55555555; + Ret = GetComputerNameExA(NameType, NULL, &Size); + Error = GetLastError(); + ok(Ret == FALSE, "[%d] GetComputerNameExA returned %d\n", NameType, Ret); + ok(Error == ERROR_INVALID_PARAMETER, "[%d] GetComputerNameExA returned error %lu\n", NameType, Error); + ok(Size == 0x55555555, "[%d] Got Size %lu\n", NameType, Size); + + /* non-NULL buffer, NULL size */ + RtlFillMemory(BufferW, sizeof(BufferW), 0x55); + Ret = GetComputerNameExW(NameType, BufferW, NULL); + Error = GetLastError(); + ok(Ret == FALSE, "[%d] GetComputerNameExW returned %d\n", NameType, Ret); + ok(Error == ERROR_INVALID_PARAMETER, "[%d] GetComputerNameExW returned error %lu\n", NameType, Error); + ok(BufferW[0] == 0x5555, "[%d] BufferW[0] = 0x%x\n", NameType, BufferW[0]); + + RtlFillMemory(BufferA, sizeof(BufferA), 0x55); + Ret = GetComputerNameExA(NameType, BufferA, NULL); + Error = GetLastError(); + ok(Ret == FALSE, "[%d] GetComputerNameExA returned %d\n", NameType, Ret); + ok(Error == ERROR_INVALID_PARAMETER, "[%d] GetComputerNameExA returned error %lu\n", NameType, Error); + ok(BufferA[0] == 0x55, "[%d] BufferA[0] = 0x%x\n", NameType, BufferA[0]); + + /* NULL buffer, zero size */ + Size = 0; + Ret = GetComputerNameExW(NameType, NULL, &Size); + Error = GetLastError(); + ok(Ret == FALSE, "[%d] GetComputerNameExW returned %d\n", NameType, Ret); + ok(Error == ERROR_MORE_DATA, "[%d] GetComputerNameExW returned error %lu\n", NameType, Error); + ok(Size == ReferenceLen + 1, "[%d] Got Size %lu, expected %lu\n", NameType, Size, ReferenceLen + 1); + + Size = 0; + Ret = GetComputerNameExA(NameType, NULL, &Size); + Error = GetLastError(); + ok(Ret == FALSE, "[%d] GetComputerNameExA returned %d\n", NameType, Ret); + ok(Error == ERROR_MORE_DATA, "[%d] GetComputerNameExA returned error %lu\n", NameType, Error); + ok(Size == ReferenceLen + 1, "[%d] Got Size %lu, expected %lu\n", NameType, Size, ReferenceLen + 1); + + /* non-NULL buffer, zero size */ + RtlFillMemory(BufferW, sizeof(BufferW), 0x55); + Size = 0; + Ret = GetComputerNameExW(NameType, BufferW, &Size); + Error = GetLastError(); + ok(Ret == FALSE, "[%d] GetComputerNameExW returned %d\n", NameType, Ret); + ok(Error == ERROR_MORE_DATA, "[%d] GetComputerNameExW returned error %lu\n", NameType, Error); + ok(Size == ReferenceLen + 1, "[%d] Got Size %lu, expected %lu\n", NameType, Size, ReferenceLen + 1); + ok(BufferW[0] == 0x5555, "[%d] BufferW[0] = 0x%x\n", NameType, BufferW[0]); + + RtlFillMemory(BufferA, sizeof(BufferA), 0x55); + Size = 0; + Ret = GetComputerNameExA(NameType, BufferA, &Size); + Error = GetLastError(); + ok(Ret == FALSE, "[%d] GetComputerNameExA returned %d\n", NameType, Ret); + ok(Error == ERROR_MORE_DATA, "[%d] GetComputerNameExA returned error %lu\n", NameType, Error); + ok(Size == ReferenceLen + 1, "[%d] Got Size %lu, expected %lu\n", NameType, Size, ReferenceLen + 1); + ok(BufferA[0] == 0x55, "[%d] BufferA[0] = 0x%x\n", NameType, BufferA[0]); + + /* non-NULL buffer, too small size */ + RtlFillMemory(BufferW, sizeof(BufferW), 0x55); + Size = ReferenceLen; + Ret = GetComputerNameExW(NameType, BufferW, &Size); + Error = GetLastError(); + ok(Ret == FALSE, "[%d] GetComputerNameExW returned %d\n", NameType, Ret); + ok(Error == ERROR_MORE_DATA, "[%d] GetComputerNameExW returned error %lu\n", NameType, Error); + ok(Size == ReferenceLen + 1, "[%d] Got Size %lu, expected %lu\n", NameType, Size, ReferenceLen + 1); + if (NameType != ComputerNameNetBIOS && NameType != ComputerNamePhysicalNetBIOS) + { + if (ReferenceLen == 0) + { + ok(BufferW[0] == 0x5555, "[%d] BufferW[0] = 0x%x\n", + NameType, BufferW[0]); + } + else + { + ok(BufferW[0] == 0, "[%d] BufferW[0] = 0x%x\n", + NameType, BufferW[0]); + } + } + ok(BufferW[1] == 0x5555, "[%d] BufferW[1] = 0x%x\n", NameType, BufferW[1]); + + RtlFillMemory(BufferA, sizeof(BufferA), 0x55); + Size = ReferenceLen; + Ret = GetComputerNameExA(NameType, BufferA, &Size); + Error = GetLastError(); + ok(Ret == FALSE, "[%d] GetComputerNameExA returned %d\n", NameType, Ret); + ok(Error == ERROR_MORE_DATA, "[%d] GetComputerNameExA returned error %lu\n", NameType, Error); + ok(Size == ReferenceLen + 1, "[%d] Got Size %lu, expected %lu\n", NameType, Size, ReferenceLen + 1); + ok(BufferA[0] == 0x55, "[%d] BufferA[0] = 0x%x\n", NameType, BufferA[0]); + + /* non-NULL buffer, exact size */ + RtlFillMemory(BufferW, sizeof(BufferW), 0x55); + Size = ReferenceLen + 1; + Ret = GetComputerNameExW(NameType, BufferW, &Size); + ok(Ret == TRUE, "[%d] GetComputerNameExW returned %d\n", NameType, Ret); + ok(Size == ReferenceLen, "[%d] Got Size %lu, expected %lu\n", NameType, Size, ReferenceLen + 1); + ok(BufferW[ReferenceLen] == 0, "[%d] BufferW[ReferenceLen] = 0x%x\n", NameType, BufferW[ReferenceLen]); + ok(BufferW[ReferenceLen + 1] == 0x5555, "[%d] BufferW[ReferenceLen + 1] = 0x%x\n", NameType, BufferW[ReferenceLen + 1]); + ok(!wcscmp(BufferW, Reference), "[%d] '%ls' != '%ls'\n", NameType, BufferW, Reference); + + RtlFillMemory(BufferA, sizeof(BufferA), 0x55); + Size = ReferenceLen + 1; + Ret = GetComputerNameExA(NameType, BufferA, &Size); + ok(Ret == TRUE, "[%d] GetComputerNameExA returned %d\n", NameType, Ret); + ok(Size == ReferenceLen, "[%d] Got Size %lu, expected %lu\n", NameType, Size, ReferenceLen + 1); + ok(BufferA[ReferenceLen] == 0, "[%d] BufferA[ReferenceLen] = 0x%x\n", NameType, BufferA[ReferenceLen]); + ok(BufferA[ReferenceLen + 1] == 0x55, "[%d] BufferA[ReferenceLen + 1] = 0x%x\n", NameType, BufferA[ReferenceLen + 1]); + for (i = 0; i < ReferenceLen; i++) + { + if (BufferA[i] != Reference[i]) + { + ok(0, "[%d] BufferA[%lu] = 0x%x, expected 0x%x\n", NameType, i, BufferA[i], Reference[i]); + } + } +} + +START_TEST(GetComputerNameEx) +{ + TestGetComputerNameEx(ComputerNameNetBIOS); + TestGetComputerNameEx(ComputerNameDnsHostname); + TestGetComputerNameEx(ComputerNameDnsDomain); + //TestGetComputerNameEx(ComputerNameDnsFullyQualified); + TestGetComputerNameEx(ComputerNamePhysicalNetBIOS); + TestGetComputerNameEx(ComputerNamePhysicalDnsHostname); + TestGetComputerNameEx(ComputerNamePhysicalDnsDomain); + //TestGetComputerNameEx(ComputerNamePhysicalDnsFullyQualified); +} Propchange: trunk/rostests/apitests/kernel32/GetComputerNameEx.c ------------------------------------------------------------------------------ svn:eol-style = native Modified: trunk/rostests/apitests/kernel32/testlist.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/apitests/kernel32/testlist.c?rev=71950&r1=71949&r2=71950&view=diff ============================================================================== --- trunk/rostests/apitests/kernel32/testlist.c [iso-8859-1] (original) +++ trunk/rostests/apitests/kernel32/testlist.c [iso-8859-1] Sat Jul 16 07:08:21 2016 @@ -5,6 +5,7 @@ extern void func_dosdev(void); extern void func_FindFiles(void); +extern void func_GetComputerNameEx(void); extern void func_GetCurrentDirectory(void); extern void func_GetDriveType(void); extern void func_GetModuleFileName(void); @@ -22,6 +23,7 @@ { { "dosdev", func_dosdev }, { "FindFiles", func_FindFiles }, + { "GetComputerNameEx", func_GetComputerNameEx }, { "GetCurrentDirectory", func_GetCurrentDirectory }, { "GetDriveType", func_GetDriveType }, { "GetModuleFileName", func_GetModuleFileName },