[IPHLPAPI_APITEST] Add tests for interface resolving functions
authorStanislav Motylkov <x86corez@gmail.com>
Sat, 25 Nov 2017 17:06:21 +0000 (20:06 +0300)
committerMark Jansen <mark.jansen@reactos.org>
Sun, 3 Dec 2017 20:08:31 +0000 (21:08 +0100)
CORE-13831, CORE-14033

modules/rostests/apitests/iphlpapi/CMakeLists.txt
modules/rostests/apitests/iphlpapi/GetInterfaceName.c [new file with mode: 0644]
modules/rostests/apitests/iphlpapi/testlist.c

index c5ecc14..2a5a3ad 100644 (file)
@@ -1,5 +1,6 @@
 
 list(APPEND SOURCE
 
 list(APPEND SOURCE
+    GetInterfaceName.c
     GetNetworkParams.c
     icmp.c
     SendARP.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 (file)
index 0000000..f6e3321
--- /dev/null
@@ -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 <apitest.h>
+
+#define WIN32_NO_STATUS
+#include <iphlpapi.h>
+#include <ndk/rtlfuncs.h>
+#include <initguid.h>
+
+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();
+}
index 7eaff2e..942004d 100644 (file)
@@ -3,12 +3,14 @@
 #define STANDALONE
 #include <apitest.h>
 
 #define STANDALONE
 #include <apitest.h>
 
+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[] =
 {
 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 },
     { "GetNetworkParams",     func_GetNetworkParams },
     { "icmp",                 func_icmp },
     { "SendARP",              func_SendARP },