Author: phater Date: Fri Oct 21 16:47:38 2016 New Revision: 73011
URL: http://svn.reactos.org/svn/reactos?rev=73011&view=rev Log: [WS2_32_APITESTS] Add tests for SIO_GET_INTERFACE_LIST. Brought to you by Andreas Maier. Thanks. Minor modifications by me on comparison and expected flags. ROSTESTS-246
Added: trunk/rostests/apitests/ws2_32/WSAIoctl.c (with props) Modified: trunk/rostests/apitests/ws2_32/CMakeLists.txt trunk/rostests/apitests/ws2_32/testlist.c
Modified: trunk/rostests/apitests/ws2_32/CMakeLists.txt URL: http://svn.reactos.org/svn/reactos/trunk/rostests/apitests/ws2_32/CMakeLists... ============================================================================== --- trunk/rostests/apitests/ws2_32/CMakeLists.txt [iso-8859-1] (original) +++ trunk/rostests/apitests/ws2_32/CMakeLists.txt [iso-8859-1] Fri Oct 21 16:47:38 2016 @@ -9,6 +9,7 @@ nostartup.c recv.c send.c + WSAIoctl.c WSARecv.c WSAStartup.c testlist.c) @@ -16,5 +17,5 @@ add_executable(ws2_32_apitest ${SOURCE}) target_link_libraries(ws2_32_apitest wine ${PSEH_LIB}) set_module_type(ws2_32_apitest win32cui) -add_importlibs(ws2_32_apitest ws2_32 msvcrt kernel32 ntdll) +add_importlibs(ws2_32_apitest ws2_32 msvcrt iphlpapi kernel32 ntdll) add_cd_file(TARGET ws2_32_apitest DESTINATION reactos/bin FOR all)
Added: trunk/rostests/apitests/ws2_32/WSAIoctl.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/apitests/ws2_32/WSAIoctl.c... ============================================================================== --- trunk/rostests/apitests/ws2_32/WSAIoctl.c (added) +++ trunk/rostests/apitests/ws2_32/WSAIoctl.c [iso-8859-1] Fri Oct 21 16:47:38 2016 @@ -0,0 +1,232 @@ +/* + * PROJECT: ReactOS api tests + * LICENSE: GPL - See COPYING in the top level directory + * PURPOSE: Test for WSHIoctl: + * - SIO_GET_INTERFACE_LIST + * PROGRAMMERS: Andreas Maier + */ + +#include <apitest.h> + +#include <stdio.h> +#include "ws2tcpip.h" +#include "iphlpapi.h" + +void traceaddr(char* txt, sockaddr_gen a) +{ + trace(" %s.AddressIn.sin_family %x\n", txt, a.AddressIn.sin_family); + trace(" %s.AddressIn.sin_port %x\n", txt, a.AddressIn.sin_port); + trace(" %s.AddressIn.sin_addr.s_addr %lx\n", txt, a.AddressIn.sin_addr.s_addr); +} + +BOOL Test_WSAIoctl_InitTest( + OUT PMIB_IPADDRTABLE* ppTable) +{ + PMIB_IPADDRROW pRow; + DWORD ret, i1; + ULONG TableSize; + PMIB_IPADDRTABLE pTable; + + TableSize = 0; + *ppTable = NULL; + ret = GetIpAddrTable(NULL, &TableSize, FALSE); + if (ret != ERROR_INSUFFICIENT_BUFFER) + { + skip("GetIpAddrTable failed with %ld. Abort Testing.\n", ret); + return FALSE; + } + + /* get sorted ip-address table. Sort order is the ip-address. */ + pTable = (PMIB_IPADDRTABLE)malloc(TableSize); + *ppTable = pTable; + ret = GetIpAddrTable(pTable, &TableSize, TRUE); + if (ret != NO_ERROR) + { + skip("GetIpAddrTable failed with %ld. Abort Testing.\n", ret); + return FALSE; + } + + if (winetest_debug >= 2) + { + trace("Result of GetIpAddrTable:\n"); + trace("Count: %ld\n", pTable->dwNumEntries); + pRow = pTable->table; + for (i1 = 0; i1 < pTable->dwNumEntries; i1++) + { + trace("** Entry %ld **\n", i1); + trace(" dwAddr %lx\n", pRow->dwAddr); + trace(" dwIndex %lx\n", pRow->dwIndex); + trace(" dwMask %lx\n", pRow->dwMask); + trace(" dwBCastAddr %lx\n", pRow->dwBCastAddr); + trace(" dwReasmSize %lx\n", pRow->dwReasmSize); + trace(" wType %x\n", pRow->wType); + pRow++; + } + trace("END\n"); + } + + return TRUE; +} + +void Test_WSAIoctl_GetInterfaceList() +{ + WSADATA wdata; + INT iResult; + SOCKET sck; + ULONG buflen, BytesReturned, BCastAddr; + ULONG infoCount, i1, j1, iiFlagsExpected; + BYTE* buf = NULL; + LPINTERFACE_INFO ifInfo; + PMIB_IPADDRTABLE pTable = NULL; + PMIB_IPADDRROW pRow; + + /* Get PMIB_IPADDRTABE - these results we should get from wshtcpip.dll too. */ + /* pTable is allocated by Test_WSAIoctl_InitTest! */ + if (!Test_WSAIoctl_InitTest(&pTable)) + goto cleanup; + + /* Start up Winsock */ + iResult = WSAStartup(MAKEWORD(2, 2), &wdata); + ok(iResult == 0, "WSAStartup failed. iResult = %d\n", iResult); + + /* Create the socket */ + sck = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_IP, 0, 0, 0); + ok(sck != INVALID_SOCKET, "WSASocket failed. sck = %d\n", (INT)sck); + if (sck == INVALID_SOCKET) + { + skip("Failed to create socket!\n"); + goto cleanup; + } + + /* Do the Ioctl (buffer to small) */ + buflen = sizeof(INTERFACE_INFO)-1; + buf = (BYTE*)HeapAlloc(GetProcessHeap(), 0, buflen); + if (buf == NULL) + { + skip("Failed to allocate memory!\n"); + goto cleanup; + } + BytesReturned = 0; + iResult = WSAIoctl(sck, SIO_GET_INTERFACE_LIST, 0, 0, + buf, buflen, &BytesReturned, 0, 0); + ok(iResult == -1, "WSAIoctl/SIO_GET_INTERFACE_LIST did not fail! iResult = %d.\n", iResult); + ok_hex(WSAGetLastError(), WSAEFAULT); + ok(BytesReturned == 0, "WSAIoctl/SIO_GET_INTERFACE_LIST: BytesReturned should be 0, not %ld.\n", BytesReturned); + HeapFree(GetProcessHeap(), 0, buf); + buf = NULL; + + /* Do the Ioctl + In most cases no loop is done. + Only if WSAIoctl fails with WSAEFAULT (buffer to small) we need to retry with a + larger buffer */ + i1 = 0; + while (TRUE) + { + if (buf != NULL) + { + HeapFree(GetProcessHeap(), 0, buf); + buf = NULL; + } + + buflen = sizeof(INTERFACE_INFO) * (i1+1) * 32; + buf = (BYTE*)HeapAlloc(GetProcessHeap(), 0, buflen); + if (buf == NULL) + { + skip("Failed to allocate memory!\n"); + goto cleanup; + } + BytesReturned = 0; + iResult = WSAIoctl(sck, SIO_GET_INTERFACE_LIST, 0, 0, + buf, buflen, &BytesReturned, 0, 0); + /* we have what we want ... leave loop */ + if (iResult == NO_ERROR) + break; + /* only retry if buffer was to small */ + /* to avoid infinite loop we maximum retry count is 4 */ + if ((i1 >= 4) || (WSAGetLastError() != WSAEFAULT)) + { + ok_hex(iResult, NO_ERROR); + skip("WSAIoctl / SIO_GET_INTERFACE_LIST\n"); + goto cleanup; + } + /* buffer to small -> retry */ + i1++; + } + + ok_dec(BytesReturned % sizeof(INTERFACE_INFO), 0); + + /* Calculate how many INTERFACE_INFO we got */ + infoCount = BytesReturned / sizeof(INTERFACE_INFO); + ok(infoCount == pTable->dwNumEntries, + "Wrong count of entries! Got %ld, expected %ld.\n", pTable->dwNumEntries, infoCount); + + if (winetest_debug >= 2) + { + trace("WSAIoctl\n"); + trace(" BytesReturned %ld - InfoCount %ld\n ", BytesReturned, infoCount); + ifInfo = (LPINTERFACE_INFO)buf; + for (i1 = 0; i1 < infoCount; i1++) + { + trace("entry-index %ld\n", i1); + trace(" iiFlags %ld\n", ifInfo->iiFlags); + traceaddr("ifInfo^.iiAddress", ifInfo->iiAddress); + traceaddr("ifInfo^.iiBroadcastAddress", ifInfo->iiBroadcastAddress); + traceaddr("ifInfo^.iiNetmask", ifInfo->iiNetmask); + ifInfo++; + } + } + + /* compare entries */ + ifInfo = (LPINTERFACE_INFO)buf; + for (i1 = 0; i1 < infoCount; i1++) + { + if (winetest_debug >= 2) + trace("Entry %ld\n", i1); + for (j1 = 0; j1 < pTable->dwNumEntries; j1++) + { + if (ifInfo[i1].iiAddress.AddressIn.sin_addr.s_addr == pTable->table[j1].dwAddr) + { + pRow = &pTable->table[j1]; + break; + } + } + if (j1 == pTable->dwNumEntries) + { + skip("Skipping interface\n"); + continue; + } + + /* iiFlags + * Don't know if this value is fix for SIO_GET_INTERFACE_LIST! */ + iiFlagsExpected = IFF_BROADCAST | IFF_MULTICAST; + if ((pRow->wType & MIB_IPADDR_DISCONNECTED) == 0) + iiFlagsExpected |= IFF_UP; + if (pRow->dwAddr == ntohl(INADDR_LOOPBACK)) + { + iiFlagsExpected |= IFF_LOOPBACK; + /* on Windows 7 loopback has broadcast flag cleared */ + //iiFlagsExpected &= ~IFF_BROADCAST; + } + + ok_hex(ifInfo[i1].iiFlags, iiFlagsExpected); + ok_hex(ifInfo[i1].iiAddress.AddressIn.sin_addr.s_addr, pRow->dwAddr); + // dwBCastAddr is not the "real" Broadcast-Address. + BCastAddr = (pRow->dwBCastAddr == 1 && (iiFlagsExpected & IFF_BROADCAST) != 0) ? 0xFFFFFFFF : 0x0; + ok_hex(ifInfo[i1].iiBroadcastAddress.AddressIn.sin_addr.s_addr, BCastAddr); + ok_hex(ifInfo[i1].iiNetmask.AddressIn.sin_addr.s_addr, pRow->dwMask); + } + +cleanup: + if (sck != 0) + closesocket(sck); + if (pTable != NULL) + free(pTable); + if (buf != NULL) + HeapFree(GetProcessHeap(), 0, buf); + WSACleanup(); +} + +START_TEST(WSAIoctl) +{ + Test_WSAIoctl_GetInterfaceList(); +}
Propchange: trunk/rostests/apitests/ws2_32/WSAIoctl.c ------------------------------------------------------------------------------ svn:eol-style = native
Modified: trunk/rostests/apitests/ws2_32/testlist.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/apitests/ws2_32/testlist.c... ============================================================================== --- trunk/rostests/apitests/ws2_32/testlist.c [iso-8859-1] (original) +++ trunk/rostests/apitests/ws2_32/testlist.c [iso-8859-1] Fri Oct 21 16:47:38 2016 @@ -11,6 +11,7 @@ extern void func_nostartup(void); extern void func_recv(void); extern void func_send(void); +extern void func_WSAIoctl(void); extern void func_WSARecv(void); extern void func_WSAStartup(void);
@@ -24,6 +25,7 @@ { "nostartup", func_nostartup }, { "recv", func_recv }, { "send", func_send }, + { "WSAIoctl", func_WSAIoctl }, { "WSARecv", func_WSARecv }, { "WSAStartup", func_WSAStartup }, { 0, 0 }