From d6e0c422e1661223d60910386164458cc02a9574 Mon Sep 17 00:00:00 2001 From: Stanislav Motylkov Date: Sat, 25 Nov 2017 20:06:21 +0300 Subject: [PATCH] [IPHLPAPI_APITEST] Add tests for interface resolving functions CORE-13831, CORE-14033 --- .../rostests/apitests/iphlpapi/CMakeLists.txt | 1 + .../apitests/iphlpapi/GetInterfaceName.c | 396 ++++++++++++++++++ modules/rostests/apitests/iphlpapi/testlist.c | 2 + 3 files changed, 399 insertions(+) create mode 100644 modules/rostests/apitests/iphlpapi/GetInterfaceName.c diff --git a/modules/rostests/apitests/iphlpapi/CMakeLists.txt b/modules/rostests/apitests/iphlpapi/CMakeLists.txt index c5ecc1457b4..2a5a3ad754c 100644 --- a/modules/rostests/apitests/iphlpapi/CMakeLists.txt +++ b/modules/rostests/apitests/iphlpapi/CMakeLists.txt @@ -1,5 +1,6 @@ list(APPEND SOURCE + GetInterfaceName.c GetNetworkParams.c icmp.c SendARP.c diff --git a/modules/rostests/apitests/iphlpapi/GetInterfaceName.c b/modules/rostests/apitests/iphlpapi/GetInterfaceName.c new file mode 100644 index 00000000000..f6e3321cee8 --- /dev/null +++ b/modules/rostests/apitests/iphlpapi/GetInterfaceName.c @@ -0,0 +1,396 @@ +/* + * PROJECT: ReactOS API Tests + * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+) + * PURPOSE: Tests for network interface name resolving functions + * COPYRIGHT: Copyright 2017 Stanislav Motylkov + */ + +#include + +#define WIN32_NO_STATUS +#include +#include +#include + +DEFINE_GUID(MY_TEST_GUID, 0x8D1AB70F, 0xADF0, 0x49FC, 0x9D, 0x07, 0x4E, 0x89, 0x29, 0x2D, 0xC5, 0x2B); +static DWORD (WINAPI * pNhGetInterfaceNameFromGuid)(PVOID, PVOID, PULONG, DWORD, DWORD); +static DWORD (WINAPI * pNhGetInterfaceNameFromDeviceGuid)(PVOID, PVOID, PULONG, DWORD, DWORD); + +/* + * Tests for NhGetInterfaceNameFromGuid + */ +static +VOID +test_NhGetInterfaceNameFromGuid(GUID AdapterGUID, DWORD par1, DWORD par2) +{ + DWORD ApiReturn, Error; + ULONG ulOutBufLen; + WCHAR Name[MAX_INTERFACE_NAME_LEN + 4]; + GUID UniqueGUID = MY_TEST_GUID; + + // Test NULL GUID + SetLastError(0xbeeffeed); + Error = 0xbeeffeed; + ZeroMemory(&Name, sizeof(Name)); + ApiReturn = ERROR_SUCCESS; + ulOutBufLen = sizeof(Name); + StartSeh() + ApiReturn = pNhGetInterfaceNameFromGuid(NULL, &Name, &ulOutBufLen, par1, par2); + Error = GetLastError(); + EndSeh(STATUS_SUCCESS); + + ok(ApiReturn == ERROR_INVALID_PARAMETER, + "ApiReturn returned %ld, expected ERROR_INVALID_PARAMETER\n", + ApiReturn); + ok(Error == 0xbeeffeed, + "GetLastError() returned %ld, expected 0xbeeffeed\n", + Error); + ok(ulOutBufLen == sizeof(Name), + "ulOutBufLen is %ld, expected = sizeof(Name)\n", + ulOutBufLen); + ok_wstr(L"", Name); + + // Test correct GUID, but NULL name + SetLastError(0xbeeffeed); + ZeroMemory(&Name, sizeof(Name)); + ApiReturn = pNhGetInterfaceNameFromGuid(&AdapterGUID, NULL, &ulOutBufLen, par1, par2); + Error = GetLastError(); + + ok(ApiReturn == ERROR_SUCCESS, + "ApiReturn returned %ld, expected ERROR_SUCCESS\n", + ApiReturn); + ok(Error == 0xbeeffeed, + "GetLastError() returned %ld, expected 0xbeeffeed\n", + Error); + ok(ulOutBufLen > 0, + "ulOutBufLen is %ld, expected > 0\n", + ulOutBufLen); + ok_wstr(L"", Name); + + // NhGetInterfaceNameFromGuid will throw exception if pOutBufLen is NULL + SetLastError(0xbeeffeed); + Error = 0xbeeffeed; + ZeroMemory(&Name, sizeof(Name)); + ApiReturn = ERROR_SUCCESS; + StartSeh() + ApiReturn = pNhGetInterfaceNameFromGuid(&AdapterGUID, &Name, NULL, par1, par2); + Error = GetLastError(); + EndSeh(STATUS_SUCCESS); + + ok(ApiReturn == ERROR_INVALID_PARAMETER, + "ApiReturn returned %ld, expected ERROR_INVALID_PARAMETER\n", + ApiReturn); + ok(Error == 0xbeeffeed, + "GetLastError() returned %ld, expected 0xbeeffeed\n", + Error); + ok(ulOutBufLen > 0, + "ulOutBufLen is %ld, expected > 0\n", + ulOutBufLen); + ok_wstr(L"", Name); + + // Test correct values + SetLastError(0xbeeffeed); + ZeroMemory(&Name, sizeof(Name)); + ulOutBufLen = sizeof(Name); + ApiReturn = pNhGetInterfaceNameFromGuid(&AdapterGUID, &Name, &ulOutBufLen, par1, par2); + Error = GetLastError(); + + ok(ApiReturn == ERROR_SUCCESS, + "ApiReturn returned %ld, expected ERROR_SUCCESS\n", + ApiReturn); + ok(Error == 0xbeeffeed, + "GetLastError() returned %ld, expected 0xbeeffeed\n", + Error); + ok(ulOutBufLen > 0, + "ulOutBufLen is %ld, expected > 0\n", + ulOutBufLen); + Error = wcslen(Name); + ok(Error > 0, + "wcslen(Name) is %ld, expected > 0\n", + Error); + if (Error > 0) + trace("Adapter name: \"%S\"\n", Name); + + // Test correct values, but with new unique GUID + SetLastError(0xbeeffeed); + ZeroMemory(&Name, sizeof(Name)); + ulOutBufLen = sizeof(Name); + ApiReturn = pNhGetInterfaceNameFromGuid((PVOID)&UniqueGUID, &Name, &ulOutBufLen, par1, par2); + Error = GetLastError(); + + ok(ApiReturn == ERROR_NOT_FOUND, + "ApiReturn returned %ld, expected ERROR_NOT_FOUND\n", + ApiReturn); + ok(Error == ERROR_PATH_NOT_FOUND, + "GetLastError() returned %ld, expected ERROR_PATH_NOT_FOUND\n", + Error); + ok(ulOutBufLen == sizeof(Name), + "ulOutBufLen is %ld, expected = sizeof(Name)\n", + ulOutBufLen); + ok_wstr(L"", Name); + + // Test correct values, but with small length + SetLastError(0xbeeffeed); + ZeroMemory(&Name, sizeof(Name)); + ulOutBufLen = 0; + ApiReturn = pNhGetInterfaceNameFromGuid(&AdapterGUID, &Name, &ulOutBufLen, par1, par2); + Error = GetLastError(); + + ok(ApiReturn == ERROR_INSUFFICIENT_BUFFER, + "ApiReturn returned %ld, expected ERROR_INSUFFICIENT_BUFFER\n", + ApiReturn); + ok(Error == 0xbeeffeed, + "GetLastError() returned %ld, expected 0xbeeffeed\n", + Error); + ok(ulOutBufLen == MAX_INTERFACE_NAME_LEN * 2, + "ulOutBufLen is %ld, expected = MAX_INTERFACE_NAME_LEN * 2\n", + ulOutBufLen); + ok_wstr(L"", Name); +} + +/* + * Tests for NhGetInterfaceNameFromDeviceGuid + */ +static +VOID +test_NhGetInterfaceNameFromDeviceGuid(GUID AdapterGUID, DWORD par1, DWORD par2) +{ + DWORD ApiReturn, Error; + ULONG ulOutBufLen; + WCHAR Name[MAX_INTERFACE_NAME_LEN]; + GUID UniqueGUID = MY_TEST_GUID; + + // Test NULL GUID + // Windows XP: NhGetInterfaceNameFromDeviceGuid throws exception here + SetLastError(0xbeeffeed); + Error = 0xbeeffeed; + ZeroMemory(&Name, sizeof(Name)); + ApiReturn = ERROR_SUCCESS; + ulOutBufLen = sizeof(Name); + StartSeh() + ApiReturn = pNhGetInterfaceNameFromDeviceGuid(NULL, &Name, &ulOutBufLen, par1, par2); + Error = GetLastError(); + EndSeh(STATUS_SUCCESS); + + ok(ApiReturn == ERROR_INVALID_PARAMETER, + "ApiReturn returned %ld, expected ERROR_INVALID_PARAMETER\n", + ApiReturn); + ok(Error == ERROR_SUCCESS, + "GetLastError() returned %ld, expected ERROR_SUCCESS\n", + Error); + ok(ulOutBufLen == sizeof(Name), + "ulOutBufLen is %ld, expected = sizeof(Name)\n", + ulOutBufLen); + ok_wstr(L"", Name); + + // Test correct GUID, but NULL name + SetLastError(0xbeeffeed); + Error = 0xbeeffeed; + ZeroMemory(&Name, sizeof(Name)); + ApiReturn = ERROR_SUCCESS; + StartSeh() + ApiReturn = pNhGetInterfaceNameFromDeviceGuid(&AdapterGUID, NULL, &ulOutBufLen, par1, par2); + Error = GetLastError(); + EndSeh(STATUS_SUCCESS); + + ok(ApiReturn == ERROR_INVALID_PARAMETER, + "ApiReturn returned %ld, expected ERROR_INVALID_PARAMETER\n", + ApiReturn); + ok(Error == ERROR_SUCCESS, + "GetLastError() returned %ld, expected ERROR_SUCCESS\n", + Error); + ok(ulOutBufLen > 0, + "ulOutBufLen is %ld, expected > 0\n", + ulOutBufLen); + ok_wstr(L"", Name); + + // NhGetInterfaceNameFromDeviceGuid will throw exception if pOutBufLen is NULL + SetLastError(0xbeeffeed); + Error = 0xbeeffeed; + ZeroMemory(&Name, sizeof(Name)); + ApiReturn = ERROR_SUCCESS; + StartSeh() + ApiReturn = pNhGetInterfaceNameFromDeviceGuid(&AdapterGUID, &Name, NULL, par1, par2); + Error = GetLastError(); + EndSeh(STATUS_SUCCESS); + + ok(ApiReturn == ERROR_INVALID_PARAMETER, + "ApiReturn returned %ld, expected ERROR_INVALID_PARAMETER\n", + ApiReturn); + ok(Error == ERROR_SUCCESS, + "GetLastError() returned %ld, expected ERROR_SUCCESS\n", + Error); + ok(ulOutBufLen > 0, + "ulOutBufLen is %ld, expected > 0\n", + ulOutBufLen); + ok_wstr(L"", Name); + + // Test correct values + SetLastError(0xbeeffeed); + ZeroMemory(&Name, sizeof(Name)); + ulOutBufLen = sizeof(Name); + ApiReturn = pNhGetInterfaceNameFromDeviceGuid(&AdapterGUID, &Name, &ulOutBufLen, par1, par2); + Error = GetLastError(); + + ok(ApiReturn == ERROR_SUCCESS, + "ApiReturn returned %ld, expected ERROR_SUCCESS\n", + ApiReturn); + ok(Error == ERROR_SUCCESS, + "GetLastError() returned %ld, expected ERROR_SUCCESS\n", + Error); + ok(ulOutBufLen > 0, + "ulOutBufLen is %ld, expected > 0\n", + ulOutBufLen); + Error = wcslen(Name); + ok(Error > 0, + "wcslen(Name) is %ld, expected > 0\n", + Error); + if (Error > 0) + trace("Adapter name: \"%S\"\n", Name); + + // Test correct values, but with new unique GUID + SetLastError(0xbeeffeed); + ZeroMemory(&Name, sizeof(Name)); + ulOutBufLen = sizeof(Name); + ApiReturn = pNhGetInterfaceNameFromDeviceGuid((PVOID)&UniqueGUID, &Name, &ulOutBufLen, par1, par2); + Error = GetLastError(); + + ok(ApiReturn == ERROR_NOT_FOUND, + "ApiReturn returned %ld, expected ERROR_NOT_FOUND\n", + ApiReturn); + ok(Error == ERROR_SUCCESS, + "GetLastError() returned %ld, expected ERROR_SUCCESS\n", + Error); + ok(ulOutBufLen == sizeof(Name), + "ulOutBufLen is %ld, expected = sizeof(Name)\n", + ulOutBufLen); + ok_wstr(L"", Name); + + // Test correct values, but with small length + SetLastError(0xbeeffeed); + ZeroMemory(&Name, sizeof(Name)); + ulOutBufLen = 0; + ApiReturn = pNhGetInterfaceNameFromDeviceGuid(&AdapterGUID, &Name, &ulOutBufLen, par1, par2); + Error = GetLastError(); + + ok(ApiReturn == ERROR_INSUFFICIENT_BUFFER, + "ApiReturn returned %ld, expected ERROR_INSUFFICIENT_BUFFER\n", + ApiReturn); + ok(Error == ERROR_SUCCESS, + "GetLastError() returned %ld, expected ERROR_SUCCESS\n", + Error); + ok(ulOutBufLen == MAX_INTERFACE_NAME_LEN * 2, + "ulOutBufLen is %ld, expected = MAX_INTERFACE_NAME_LEN * 2\n", + ulOutBufLen); + ok_wstr(L"", Name); +} + +static +VOID +test_GetInterfaceName(VOID) +{ + PIP_INTERFACE_INFO pInfo = NULL; + ULONG ulOutBufLen = 0; + DWORD ApiReturn; + WCHAR Name[MAX_ADAPTER_NAME]; + UNICODE_STRING GuidString; + GUID AdapterGUID; + HINSTANCE hIpHlpApi; + + ApiReturn = GetInterfaceInfo(pInfo, &ulOutBufLen); + ok(ApiReturn == ERROR_INSUFFICIENT_BUFFER, + "GetInterfaceInfo(pInfo, &ulOutBufLen) returned %ld, expected ERROR_INSUFFICIENT_BUFFER\n", + ApiReturn); + if (ApiReturn != ERROR_INSUFFICIENT_BUFFER) + { + skip("Can't determine size of IP_INTERFACE_INFO. Can't proceed\n"); + return; + } + + pInfo = (IP_INTERFACE_INFO *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ulOutBufLen); + if (pInfo == NULL) + { + skip("pInfo is NULL. Can't proceed\n"); + return; + } + + ApiReturn = GetInterfaceInfo(pInfo, &ulOutBufLen); + ok(ApiReturn == NO_ERROR, + "GetInterfaceInfo(pInfo, &ulOutBufLen) returned %ld, expected NO_ERROR\n", + ApiReturn); + if (ApiReturn != NO_ERROR || ulOutBufLen == 0) + { + skip("GetInterfaceInfo failed with error %ld. Can't proceed\n", ApiReturn); + return; + } + + if (pInfo->NumAdapters > 0) + CopyMemory(&Name, &pInfo->Adapter[0].Name, sizeof(Name)); + + if (pInfo->NumAdapters == 0) + { + HeapFree(GetProcessHeap(), 0, pInfo); + skip("pInfo->NumAdapters = 0. Can't proceed\n"); + return; + } + trace("pInfo->NumAdapters: %lu\n", pInfo->NumAdapters); + + HeapFree(GetProcessHeap(), 0, pInfo); + + ApiReturn = wcsncmp(Name, L"\\DEVICE\\TCPIP_", 14); + ok(ApiReturn == 0, + "wcsncmp(Name, L\"\\DEVICE\\TCPIP_\", 14) returned %ld, expected 0\n", + ApiReturn); + if (ApiReturn != 0) + { + if (wcslen(Name) == 0) + { + skip("pInfo->Adapter[0].Name is empty. Can't proceed\n"); + return; + } + else + { + // workaround for ReactOS + trace("pInfo->Adapter[0].Name = \"%ls\" is incorrect.\n", Name); + RtlInitUnicodeString(&GuidString, &Name[0]); + } + } + else + { + RtlInitUnicodeString(&GuidString, &Name[14]); + } + + ApiReturn = RtlGUIDFromString(&GuidString, &AdapterGUID); + RtlFreeUnicodeString(&GuidString); + if (ApiReturn != 0) + { + skip("RtlGUIDFromString failed. Can't proceed\n"); + return; + } + + hIpHlpApi = GetModuleHandleW(L"iphlpapi.dll"); + if (!hIpHlpApi) + { + skip("Failed to load iphlpapi.dll. Can't proceed\n"); + return; + } + + pNhGetInterfaceNameFromGuid = (void *)GetProcAddress(hIpHlpApi, "NhGetInterfaceNameFromGuid"); + + if (!pNhGetInterfaceNameFromGuid) + skip("NhGetInterfaceNameFromGuid not found. Can't proceed\n"); + else + test_NhGetInterfaceNameFromGuid(AdapterGUID, 0, 0); + + pNhGetInterfaceNameFromDeviceGuid = (void *)GetProcAddress(hIpHlpApi, "NhGetInterfaceNameFromDeviceGuid"); + + if (!pNhGetInterfaceNameFromDeviceGuid) + skip("NhGetInterfaceNameFromDeviceGuid not found. Can't proceed\n"); + else + test_NhGetInterfaceNameFromDeviceGuid(AdapterGUID, 1, 0); +} + +START_TEST(GetInterfaceName) +{ + test_GetInterfaceName(); +} diff --git a/modules/rostests/apitests/iphlpapi/testlist.c b/modules/rostests/apitests/iphlpapi/testlist.c index 7eaff2e2537..942004df68f 100644 --- a/modules/rostests/apitests/iphlpapi/testlist.c +++ b/modules/rostests/apitests/iphlpapi/testlist.c @@ -3,12 +3,14 @@ #define STANDALONE #include +extern void func_GetInterfaceName(void); extern void func_GetNetworkParams(void); extern void func_icmp(void); extern void func_SendARP(void); const struct test winetest_testlist[] = { + { "GetInterfaceName", func_GetInterfaceName }, { "GetNetworkParams", func_GetNetworkParams }, { "icmp", func_icmp }, { "SendARP", func_SendARP }, -- 2.17.1