[EXPLORER] -Use WM_POPUPSYSTEMMENU to open the system menu of a window. CORE-13400
[reactos.git] / rostests / apitests / ws2_32 / WSAIoctl.c
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 <apitest.h>
10
11 #include <stdio.h>
12 #include "ws2tcpip.h"
13 #include "iphlpapi.h"
14
15 void traceaddr(char* txt, sockaddr_gen a)
16 {
17 trace(" %s.AddressIn.sin_family %x\n", txt, a.AddressIn.sin_family);
18 trace(" %s.AddressIn.sin_port %x\n", txt, a.AddressIn.sin_port);
19 trace(" %s.AddressIn.sin_addr.s_addr %lx\n", txt, a.AddressIn.sin_addr.s_addr);
20 }
21
22 BOOL Test_WSAIoctl_InitTest(
23 OUT PMIB_IPADDRTABLE* ppTable)
24 {
25 PMIB_IPADDRROW pRow;
26 DWORD ret, i1;
27 ULONG TableSize;
28 PMIB_IPADDRTABLE pTable;
29
30 TableSize = 0;
31 *ppTable = NULL;
32 ret = GetIpAddrTable(NULL, &TableSize, FALSE);
33 if (ret != ERROR_INSUFFICIENT_BUFFER)
34 {
35 skip("GetIpAddrTable failed with %ld. Abort Testing.\n", ret);
36 return FALSE;
37 }
38
39 /* get sorted ip-address table. Sort order is the ip-address. */
40 pTable = (PMIB_IPADDRTABLE)malloc(TableSize);
41 *ppTable = pTable;
42 ret = GetIpAddrTable(pTable, &TableSize, TRUE);
43 if (ret != NO_ERROR)
44 {
45 skip("GetIpAddrTable failed with %ld. Abort Testing.\n", ret);
46 return FALSE;
47 }
48
49 if (winetest_debug >= 2)
50 {
51 trace("Result of GetIpAddrTable:\n");
52 trace("Count: %ld\n", pTable->dwNumEntries);
53 pRow = pTable->table;
54 for (i1 = 0; i1 < pTable->dwNumEntries; i1++)
55 {
56 trace("** Entry %ld **\n", i1);
57 trace(" dwAddr %lx\n", pRow->dwAddr);
58 trace(" dwIndex %lx\n", pRow->dwIndex);
59 trace(" dwMask %lx\n", pRow->dwMask);
60 trace(" dwBCastAddr %lx\n", pRow->dwBCastAddr);
61 trace(" dwReasmSize %lx\n", pRow->dwReasmSize);
62 trace(" wType %x\n", pRow->wType);
63 pRow++;
64 }
65 trace("END\n");
66 }
67
68 return TRUE;
69 }
70
71 void Test_WSAIoctl_GetInterfaceList()
72 {
73 WSADATA wdata;
74 INT iResult;
75 SOCKET sck;
76 ULONG buflen, BytesReturned, BCastAddr;
77 ULONG infoCount, i1, j1, iiFlagsExpected;
78 BYTE* buf = NULL;
79 LPINTERFACE_INFO ifInfo;
80 PMIB_IPADDRTABLE pTable = NULL;
81 PMIB_IPADDRROW pRow;
82
83 /* Get PMIB_IPADDRTABE - these results we should get from wshtcpip.dll too. */
84 /* pTable is allocated by Test_WSAIoctl_InitTest! */
85 if (!Test_WSAIoctl_InitTest(&pTable))
86 goto cleanup;
87
88 /* Start up Winsock */
89 iResult = WSAStartup(MAKEWORD(2, 2), &wdata);
90 ok(iResult == 0, "WSAStartup failed. iResult = %d\n", iResult);
91
92 /* Create the socket */
93 sck = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_IP, 0, 0, 0);
94 ok(sck != INVALID_SOCKET, "WSASocket failed. sck = %d\n", (INT)sck);
95 if (sck == INVALID_SOCKET)
96 {
97 skip("Failed to create socket!\n");
98 goto cleanup;
99 }
100
101 /* Do the Ioctl (buffer to small) */
102 buflen = sizeof(INTERFACE_INFO)-1;
103 buf = (BYTE*)HeapAlloc(GetProcessHeap(), 0, buflen);
104 if (buf == NULL)
105 {
106 skip("Failed to allocate memory!\n");
107 goto cleanup;
108 }
109 BytesReturned = 0;
110 iResult = WSAIoctl(sck, SIO_GET_INTERFACE_LIST, 0, 0,
111 buf, buflen, &BytesReturned, 0, 0);
112 ok(iResult == -1, "WSAIoctl/SIO_GET_INTERFACE_LIST did not fail! iResult = %d.\n", iResult);
113 ok_hex(WSAGetLastError(), WSAEFAULT);
114 ok(BytesReturned == 0, "WSAIoctl/SIO_GET_INTERFACE_LIST: BytesReturned should be 0, not %ld.\n", BytesReturned);
115 HeapFree(GetProcessHeap(), 0, buf);
116 buf = NULL;
117
118 /* Do the Ioctl
119 In most cases no loop is done.
120 Only if WSAIoctl fails with WSAEFAULT (buffer to small) we need to retry with a
121 larger buffer */
122 i1 = 0;
123 while (TRUE)
124 {
125 if (buf != NULL)
126 {
127 HeapFree(GetProcessHeap(), 0, buf);
128 buf = NULL;
129 }
130
131 buflen = sizeof(INTERFACE_INFO) * (i1+1) * 32;
132 buf = (BYTE*)HeapAlloc(GetProcessHeap(), 0, buflen);
133 if (buf == NULL)
134 {
135 skip("Failed to allocate memory!\n");
136 goto cleanup;
137 }
138 BytesReturned = 0;
139 iResult = WSAIoctl(sck, SIO_GET_INTERFACE_LIST, 0, 0,
140 buf, buflen, &BytesReturned, 0, 0);
141 /* we have what we want ... leave loop */
142 if (iResult == NO_ERROR)
143 break;
144 /* only retry if buffer was to small */
145 /* to avoid infinite loop we maximum retry count is 4 */
146 if ((i1 >= 4) || (WSAGetLastError() != WSAEFAULT))
147 {
148 ok_hex(iResult, NO_ERROR);
149 skip("WSAIoctl / SIO_GET_INTERFACE_LIST\n");
150 goto cleanup;
151 }
152 /* buffer to small -> retry */
153 i1++;
154 }
155
156 ok_dec(BytesReturned % sizeof(INTERFACE_INFO), 0);
157
158 /* Calculate how many INTERFACE_INFO we got */
159 infoCount = BytesReturned / sizeof(INTERFACE_INFO);
160 ok(infoCount == pTable->dwNumEntries,
161 "Wrong count of entries! Got %ld, expected %ld.\n", pTable->dwNumEntries, infoCount);
162
163 if (winetest_debug >= 2)
164 {
165 trace("WSAIoctl\n");
166 trace(" BytesReturned %ld - InfoCount %ld\n ", BytesReturned, infoCount);
167 ifInfo = (LPINTERFACE_INFO)buf;
168 for (i1 = 0; i1 < infoCount; i1++)
169 {
170 trace("entry-index %ld\n", i1);
171 trace(" iiFlags %ld\n", ifInfo->iiFlags);
172 traceaddr("ifInfo^.iiAddress", ifInfo->iiAddress);
173 traceaddr("ifInfo^.iiBroadcastAddress", ifInfo->iiBroadcastAddress);
174 traceaddr("ifInfo^.iiNetmask", ifInfo->iiNetmask);
175 ifInfo++;
176 }
177 }
178
179 /* compare entries */
180 ifInfo = (LPINTERFACE_INFO)buf;
181 for (i1 = 0; i1 < infoCount; i1++)
182 {
183 if (winetest_debug >= 2)
184 trace("Entry %ld\n", i1);
185 for (j1 = 0; j1 < pTable->dwNumEntries; j1++)
186 {
187 if (ifInfo[i1].iiAddress.AddressIn.sin_addr.s_addr == pTable->table[j1].dwAddr)
188 {
189 pRow = &pTable->table[j1];
190 break;
191 }
192 }
193 if (j1 == pTable->dwNumEntries)
194 {
195 skip("Skipping interface\n");
196 continue;
197 }
198
199 /* iiFlags
200 * Don't know if this value is fix for SIO_GET_INTERFACE_LIST! */
201 iiFlagsExpected = IFF_BROADCAST | IFF_MULTICAST;
202 if ((pRow->wType & MIB_IPADDR_DISCONNECTED) == 0)
203 iiFlagsExpected |= IFF_UP;
204 if (pRow->dwAddr == ntohl(INADDR_LOOPBACK))
205 {
206 iiFlagsExpected |= IFF_LOOPBACK;
207 /* on Windows 7 loopback has broadcast flag cleared */
208 //iiFlagsExpected &= ~IFF_BROADCAST;
209 }
210
211 ok_hex(ifInfo[i1].iiFlags, iiFlagsExpected);
212 ok_hex(ifInfo[i1].iiAddress.AddressIn.sin_addr.s_addr, pRow->dwAddr);
213 // dwBCastAddr is not the "real" Broadcast-Address.
214 BCastAddr = (pRow->dwBCastAddr == 1 && (iiFlagsExpected & IFF_BROADCAST) != 0) ? 0xFFFFFFFF : 0x0;
215 ok_hex(ifInfo[i1].iiBroadcastAddress.AddressIn.sin_addr.s_addr, BCastAddr);
216 ok_hex(ifInfo[i1].iiNetmask.AddressIn.sin_addr.s_addr, pRow->dwMask);
217 }
218
219 cleanup:
220 if (sck != 0)
221 closesocket(sck);
222 if (pTable != NULL)
223 free(pTable);
224 if (buf != NULL)
225 HeapFree(GetProcessHeap(), 0, buf);
226 WSACleanup();
227 }
228
229 START_TEST(WSAIoctl)
230 {
231 Test_WSAIoctl_GetInterfaceList();
232 }