ReactOS 0.4.16-dev-311-g9382aa2
WSAIoctl.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS api tests
3 * LICENSE: GPL - See COPYING in the top level directory
4 * PURPOSE: Test for WSHIoctl:
5 * - SIO_GET_INTERFACE_LIST
6 * PROGRAMMERS: Andreas Maier
7 */
8
9#include "ws2_32.h"
10
11#include <iphlpapi.h>
12
13void traceaddr(char* txt, sockaddr_gen a)
14{
15 trace(" %s.AddressIn.sin_family %x\n", txt, a.AddressIn.sin_family);
16 trace(" %s.AddressIn.sin_port %x\n", txt, a.AddressIn.sin_port);
17 trace(" %s.AddressIn.sin_addr.s_addr %lx\n", txt, a.AddressIn.sin_addr.s_addr);
18}
19
21 OUT PMIB_IPADDRTABLE* ppTable)
22{
23 PMIB_IPADDRROW pRow;
24 DWORD ret, i1;
27
28 TableSize = 0;
29 *ppTable = NULL;
32 {
33 skip("GetIpAddrTable failed with %ld. Abort Testing.\n", ret);
34 return FALSE;
35 }
36
37 /* get sorted ip-address table. Sort order is the ip-address. */
39 *ppTable = pTable;
41 if (ret != NO_ERROR)
42 {
43 skip("GetIpAddrTable failed with %ld. Abort Testing.\n", ret);
44 return FALSE;
45 }
46
47 if (winetest_debug >= 2)
48 {
49 trace("Result of GetIpAddrTable:\n");
50 trace("Count: %ld\n", pTable->dwNumEntries);
51 pRow = pTable->table;
52 for (i1 = 0; i1 < pTable->dwNumEntries; i1++)
53 {
54 trace("** Entry %ld **\n", i1);
55 trace(" dwAddr %lx\n", pRow->dwAddr);
56 trace(" dwIndex %lx\n", pRow->dwIndex);
57 trace(" dwMask %lx\n", pRow->dwMask);
58 trace(" dwBCastAddr %lx\n", pRow->dwBCastAddr);
59 trace(" dwReasmSize %lx\n", pRow->dwReasmSize);
60 trace(" wType %x\n", pRow->wType);
61 pRow++;
62 }
63 trace("END\n");
64 }
65
66 return TRUE;
67}
68
70{
71 WSADATA wdata;
72 INT iResult;
73 SOCKET sck;
74 ULONG buflen, BytesReturned, BCastAddr;
75 ULONG infoCount, i1, j1, iiFlagsExpected;
76 BYTE* buf = NULL;
77 LPINTERFACE_INFO ifInfo;
79 PMIB_IPADDRROW pRow;
80
81 /* Get PMIB_IPADDRTABE - these results we should get from wshtcpip.dll too. */
82 /* pTable is allocated by Test_WSAIoctl_InitTest! */
84 goto cleanup;
85
86 /* Start up Winsock */
87 iResult = WSAStartup(MAKEWORD(2, 2), &wdata);
88 ok(iResult == 0, "WSAStartup failed. iResult = %d\n", iResult);
89
90 /* Create the socket */
91 sck = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_IP, 0, 0, 0);
92 ok(sck != INVALID_SOCKET, "WSASocket failed. sck = %d\n", (INT)sck);
93 if (sck == INVALID_SOCKET)
94 {
95 skip("Failed to create socket!\n");
96 goto cleanup;
97 }
98
99 /* Do the Ioctl (buffer to small) */
100 buflen = sizeof(INTERFACE_INFO)-1;
101 buf = (BYTE*)HeapAlloc(GetProcessHeap(), 0, buflen);
102 if (buf == NULL)
103 {
104 skip("Failed to allocate memory!\n");
105 goto cleanup;
106 }
107 BytesReturned = 0;
108 iResult = WSAIoctl(sck, SIO_GET_INTERFACE_LIST, 0, 0,
109 buf, buflen, &BytesReturned, 0, 0);
110 ok(iResult == -1, "WSAIoctl/SIO_GET_INTERFACE_LIST did not fail! iResult = %d.\n", iResult);
112 ok(BytesReturned == 0, "WSAIoctl/SIO_GET_INTERFACE_LIST: BytesReturned should be 0, not %ld.\n", BytesReturned);
114 buf = NULL;
115
116 /* Do the Ioctl
117 In most cases no loop is done.
118 Only if WSAIoctl fails with WSAEFAULT (buffer to small) we need to retry with a
119 larger buffer */
120 i1 = 0;
121 while (TRUE)
122 {
123 if (buf != NULL)
124 {
126 buf = NULL;
127 }
128
129 buflen = sizeof(INTERFACE_INFO) * (i1+1) * 32;
130 buf = (BYTE*)HeapAlloc(GetProcessHeap(), 0, buflen);
131 if (buf == NULL)
132 {
133 skip("Failed to allocate memory!\n");
134 goto cleanup;
135 }
136 BytesReturned = 0;
137 iResult = WSAIoctl(sck, SIO_GET_INTERFACE_LIST, 0, 0,
138 buf, buflen, &BytesReturned, 0, 0);
139 /* we have what we want ... leave loop */
140 if (iResult == NO_ERROR)
141 break;
142 /* only retry if buffer was to small */
143 /* to avoid infinite loop we maximum retry count is 4 */
144 if ((i1 >= 4) || (WSAGetLastError() != WSAEFAULT))
145 {
146 ok_hex(iResult, NO_ERROR);
147 skip("WSAIoctl / SIO_GET_INTERFACE_LIST\n");
148 goto cleanup;
149 }
150 /* buffer to small -> retry */
151 i1++;
152 }
153
154 ok_dec(BytesReturned % sizeof(INTERFACE_INFO), 0);
155
156 /* Calculate how many INTERFACE_INFO we got */
157 infoCount = BytesReturned / sizeof(INTERFACE_INFO);
158 ok(infoCount == pTable->dwNumEntries,
159 "Wrong count of entries! Got %ld, expected %ld.\n", pTable->dwNumEntries, infoCount);
160
161 if (winetest_debug >= 2)
162 {
163 trace("WSAIoctl\n");
164 trace(" BytesReturned %ld - InfoCount %ld\n ", BytesReturned, infoCount);
165 ifInfo = (LPINTERFACE_INFO)buf;
166 for (i1 = 0; i1 < infoCount; i1++)
167 {
168 trace("entry-index %ld\n", i1);
169 trace(" iiFlags %ld\n", ifInfo->iiFlags);
170 traceaddr("ifInfo^.iiAddress", ifInfo->iiAddress);
171 traceaddr("ifInfo^.iiBroadcastAddress", ifInfo->iiBroadcastAddress);
172 traceaddr("ifInfo^.iiNetmask", ifInfo->iiNetmask);
173 ifInfo++;
174 }
175 }
176
177 /* compare entries */
178 ifInfo = (LPINTERFACE_INFO)buf;
179 for (i1 = 0; i1 < infoCount; i1++)
180 {
181 if (winetest_debug >= 2)
182 trace("Entry %ld\n", i1);
183 for (j1 = 0; j1 < pTable->dwNumEntries; j1++)
184 {
185 if (ifInfo[i1].iiAddress.AddressIn.sin_addr.s_addr == pTable->table[j1].dwAddr)
186 {
187 pRow = &pTable->table[j1];
188 break;
189 }
190 }
191 if (j1 == pTable->dwNumEntries)
192 {
193 skip("Skipping interface\n");
194 continue;
195 }
196
197 /* iiFlags
198 * Don't know if this value is fix for SIO_GET_INTERFACE_LIST! */
199 iiFlagsExpected = IFF_BROADCAST | IFF_MULTICAST;
200 if ((pRow->wType & MIB_IPADDR_DISCONNECTED) == 0)
201 iiFlagsExpected |= IFF_UP;
202 if (pRow->dwAddr == ntohl(INADDR_LOOPBACK))
203 {
204 iiFlagsExpected |= IFF_LOOPBACK;
205 /* on Windows 7 loopback has broadcast flag cleared */
206 //iiFlagsExpected &= ~IFF_BROADCAST;
207 }
208
209 ok_hex(ifInfo[i1].iiFlags, iiFlagsExpected);
210 ok_hex(ifInfo[i1].iiAddress.AddressIn.sin_addr.s_addr, pRow->dwAddr);
211 // dwBCastAddr is not the "real" Broadcast-Address.
212 BCastAddr = (pRow->dwBCastAddr == 1 && (iiFlagsExpected & IFF_BROADCAST) != 0) ? 0xFFFFFFFF : 0x0;
213 ok_hex(ifInfo[i1].iiBroadcastAddress.AddressIn.sin_addr.s_addr, BCastAddr);
214 ok_hex(ifInfo[i1].iiNetmask.AddressIn.sin_addr.s_addr, pRow->dwMask);
215 }
216
217cleanup:
218 if (sck != 0)
219 closesocket(sck);
220 if (pTable != NULL)
221 free(pTable);
222 if (buf != NULL)
224 WSACleanup();
225}
226
228{
230}
void Test_WSAIoctl_GetInterfaceList()
Definition: WSAIoctl.c:69
void traceaddr(char *txt, sockaddr_gen a)
Definition: WSAIoctl.c:13
BOOL Test_WSAIoctl_InitTest(OUT PMIB_IPADDRTABLE *ppTable)
Definition: WSAIoctl.c:20
#define ok_hex(expression, result)
Definition: atltest.h:94
#define trace
Definition: atltest.h:70
#define ok(value,...)
Definition: atltest.h:57
#define skip(...)
Definition: atltest.h:64
#define ok_dec(expression, result)
Definition: atltest.h:101
#define START_TEST(x)
Definition: atltest.h:75
#define NO_ERROR
Definition: dderror.h:5
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define GetProcessHeap()
Definition: compat.h:736
#define HeapAlloc
Definition: compat.h:733
#define HeapFree(x, y, z)
Definition: compat.h:735
static void cleanup(void)
Definition: main.c:1335
INT WSAAPI WSAIoctl(IN SOCKET s, IN DWORD dwIoControlCode, IN LPVOID lpvInBuffer, IN DWORD cbInBuffer, OUT LPVOID lpvOutBuffer, IN DWORD cbOutBuffer, OUT LPDWORD lpcbBytesReturned, IN LPWSAOVERLAPPED lpOverlapped, IN LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
Definition: ioctl.c:46
INT WINAPI WSAStartup(IN WORD wVersionRequested, OUT LPWSADATA lpWSAData)
Definition: startup.c:113
#define SOCK_STREAM
Definition: tcpip.h:118
#define AF_INET
Definition: tcpip.h:117
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
DWORD WINAPI GetIpAddrTable(PMIB_IPADDRTABLE pIpAddrTable, PULONG pdwSize, BOOL bOrder)
#define MIB_IPADDR_DISCONNECTED
Definition: ipmib.h:28
struct _MIB_IPADDRTABLE * PMIB_IPADDRTABLE
#define INADDR_LOOPBACK
Definition: inet.h:78
#define ntohl(x)
Definition: module.h:205
#define closesocket
Definition: ncftp.h:477
int winetest_debug
sockaddr_gen iiBroadcastAddress
Definition: ws2ipdef.h:167
sockaddr_gen iiNetmask
Definition: ws2ipdef.h:168
sockaddr_gen iiAddress
Definition: ws2ipdef.h:166
DWORD dwReasmSize
Definition: ipmib.h:40
DWORD dwBCastAddr
Definition: ipmib.h:39
DWORD dwMask
Definition: ipmib.h:38
DWORD dwAddr
Definition: ipmib.h:36
IF_INDEX dwIndex
Definition: ipmib.h:37
unsigned short wType
Definition: ipmib.h:42
#define MAKEWORD(a, b)
Definition: typedefs.h:248
int32_t INT
Definition: typedefs.h:58
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
static const EHCI_PERIOD pTable[]
Definition: usbehci.c:29
int ret
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_ ULONG _In_opt_ PWDF_MEMORY_DESCRIPTOR _In_opt_ PWDF_MEMORY_DESCRIPTOR _In_opt_ PWDF_REQUEST_SEND_OPTIONS _Out_opt_ PULONG_PTR BytesReturned
Definition: wdfiotarget.h:1052
#define WSAEFAULT
Definition: winerror.h:1945
#define WSASocket
Definition: winsock2.h:2407
int PASCAL FAR WSAGetLastError(void)
Definition: dllmain.c:112
int PASCAL FAR WSACleanup(void)
Definition: startup.c:60
#define INVALID_SOCKET
Definition: winsock.h:332
UINT_PTR SOCKET
Definition: winsock.h:47
#define IPPROTO_IP
Definition: winsock.h:255
#define IFF_MULTICAST
Definition: ws2ipdef.h:25
#define IFF_BROADCAST
Definition: ws2ipdef.h:22
#define SIO_GET_INTERFACE_LIST
Definition: ws2ipdef.h:62
struct _INTERFACE_INFO INTERFACE_INFO
#define IFF_LOOPBACK
Definition: ws2ipdef.h:23
struct _INTERFACE_INFO * LPINTERFACE_INFO
#define IFF_UP
Definition: ws2ipdef.h:21
_Must_inspect_result_ typedef _Out_ PULONG TableSize
Definition: iotypes.h:4327
unsigned char BYTE
Definition: xxhash.c:193