ReactOS  0.4.14-dev-614-gbfd8a84
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 
13 void 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);
113  HeapFree(GetProcessHeap(), 0, buf);
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  {
125  HeapFree(GetProcessHeap(), 0, buf);
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 
217 cleanup:
218  if (sck != 0)
219  closesocket(sck);
220  if (pTable != NULL)
221  free(pTable);
222  if (buf != NULL)
223  HeapFree(GetProcessHeap(), 0, buf);
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
#define TRUE
Definition: types.h:120
struct _INTERFACE_INFO INTERFACE_INFO
#define WSAEFAULT
Definition: winerror.h:1945
#define MAKEWORD(a, b)
Definition: typedefs.h:247
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
#define IFF_UP
Definition: ws2ipdef.h:21
#define free
Definition: debug_ros.c:5
#define closesocket
Definition: precomp.h:57
INT WSAAPI WSACleanup(VOID)
Definition: startup.c:60
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
sockaddr_gen iiAddress
Definition: ws2ipdef.h:166
#define NO_ERROR
Definition: dderror.h:5
DWORD dwReasmSize
Definition: ipmib.h:40
int32_t INT
Definition: typedefs.h:56
int winetest_debug
#define ok_hex(expression, result)
Definition: atltest.h:94
struct _INTERFACE_INFO * LPINTERFACE_INFO
#define IFF_BROADCAST
Definition: ws2ipdef.h:22
unsigned int BOOL
Definition: ntddk_ex.h:94
DWORD WINAPI GetIpAddrTable(PMIB_IPADDRTABLE pIpAddrTable, PULONG pdwSize, BOOL bOrder)
BOOL Test_WSAIoctl_InitTest(OUT PMIB_IPADDRTABLE *ppTable)
Definition: WSAIoctl.c:20
unsigned short wType
Definition: ipmib.h:42
INT WINAPI WSAStartup(IN WORD wVersionRequested, OUT LPWSADATA lpWSAData)
Definition: startup.c:113
smooth NULL
Definition: ftsmooth.c:416
sockaddr_gen iiNetmask
Definition: ws2ipdef.h:168
#define IPPROTO_IP
Definition: winsock.h:255
INT WSAAPI WSAGetLastError(VOID)
Definition: dllmain.c:112
#define GetProcessHeap()
Definition: compat.h:403
#define trace
Definition: atltest.h:70
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
DWORD dwBCastAddr
Definition: ipmib.h:39
#define INVALID_SOCKET
Definition: winsock.h:332
#define WSASocket
Definition: winsock2.h:2407
unsigned long DWORD
Definition: ntddk_ex.h:95
#define MIB_IPADDR_DISCONNECTED
Definition: ipmib.h:28
START_TEST(WSAIoctl)
Definition: WSAIoctl.c:227
int ret
sockaddr_gen iiBroadcastAddress
Definition: ws2ipdef.h:167
unsigned char BYTE
Definition: mem.h:68
DWORD dwMask
Definition: ipmib.h:38
struct _MIB_IPADDRTABLE * PMIB_IPADDRTABLE
#define ok(value,...)
Definition: atltest.h:57
_In_ FILTER_INFORMATION_CLASS _In_ ULONG _Out_ PULONG BytesReturned
Definition: fltkernel.h:1716
IF_INDEX dwIndex
Definition: ipmib.h:37
#define skip(...)
Definition: atltest.h:64
#define OUT
Definition: typedefs.h:39
_Must_inspect_result_ typedef _Out_ PULONG TableSize
Definition: iotypes.h:3971
#define IFF_MULTICAST
Definition: ws2ipdef.h:25
unsigned int ULONG
Definition: retypes.h:1
#define AF_INET
Definition: tcpip.h:117
#define INADDR_LOOPBACK
Definition: winsock.h:312
char * cleanup(char *str)
Definition: wpickclick.c:99
static const EHCI_PERIOD pTable[]
Definition: usbehci.c:29
#define malloc
Definition: debug_ros.c:4
DWORD dwAddr
Definition: ipmib.h:36
UINT_PTR SOCKET
Definition: winsock.h:47
#define SOCK_STREAM
Definition: tcpip.h:118
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
#define SIO_GET_INTERFACE_LIST
Definition: ws2ipdef.h:62
#define ok_dec(expression, result)
Definition: atltest.h:101
#define HeapFree(x, y, z)
Definition: compat.h:402
#define IFF_LOOPBACK
Definition: ws2ipdef.h:23
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10
#define ntohl(x)
Definition: module.h:203