[IPHLPAPI_WINETEST] Sync with Wine Staging 1.7.55. CORE-10536
[reactos.git] / rostests / winetests / iphlpapi / iphlpapi.c
1 /*
2 * iphlpapi dll test
3 *
4 * Copyright (C) 2003 Juan Lang
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21 /*
22 * Some observations that an automated test can't produce:
23 * An adapter index is a key for an adapter. That is, if an index is returned
24 * from one API, that same index may be used successfully in another API, as
25 * long as the adapter remains present.
26 * If the adapter is removed and reinserted, however, the index may change (and
27 * indeed it does change on Win2K).
28 *
29 * The Name field of the IP_ADAPTER_INDEX_MAP entries returned by
30 * GetInterfaceInfo is declared as a wide string, but the bytes are actually
31 * an ASCII string on some versions of the IP helper API under Win9x. This was
32 * apparently an MS bug, it's corrected in later versions.
33 *
34 * The DomainName field of FIXED_INFO isn't NULL-terminated on Win98.
35 */
36
37 #include <stdarg.h>
38 #include "winsock2.h"
39 #include "windef.h"
40 #include "winbase.h"
41 #include "ws2tcpip.h"
42 #include "iphlpapi.h"
43 #include "iprtrmib.h"
44 #include "netioapi.h"
45 #include "wine/test.h"
46 #include <stdio.h>
47 #include <stdlib.h>
48
49 #define ICMP_MINLEN 8 /* copied from dlls/iphlpapi/ip_icmp.h file */
50
51 #undef htonl
52 #undef htons
53 #undef ntohl
54 #undef ntohs
55
56 #define htonl(l) ((u_long)(l))
57 #define htons(s) ((u_short)(s))
58 #define ntohl(l) ((u_long)(l))
59 #define ntohs(s) ((u_short)(s))
60
61 static HMODULE hLibrary = NULL;
62
63 static DWORD (WINAPI *pGetNumberOfInterfaces)(PDWORD);
64 static DWORD (WINAPI *pGetIpAddrTable)(PMIB_IPADDRTABLE,PULONG,BOOL);
65 static DWORD (WINAPI *pGetIfEntry)(PMIB_IFROW);
66 static DWORD (WINAPI *pGetIfEntry2)(PMIB_IF_ROW2);
67 static DWORD (WINAPI *pGetFriendlyIfIndex)(DWORD);
68 static DWORD (WINAPI *pGetIfTable)(PMIB_IFTABLE,PULONG,BOOL);
69 static DWORD (WINAPI *pGetIfTable2)(PMIB_IF_TABLE2*);
70 static DWORD (WINAPI *pGetIpForwardTable)(PMIB_IPFORWARDTABLE,PULONG,BOOL);
71 static DWORD (WINAPI *pGetIpNetTable)(PMIB_IPNETTABLE,PULONG,BOOL);
72 static DWORD (WINAPI *pGetInterfaceInfo)(PIP_INTERFACE_INFO,PULONG);
73 static DWORD (WINAPI *pGetAdaptersInfo)(PIP_ADAPTER_INFO,PULONG);
74 static DWORD (WINAPI *pGetNetworkParams)(PFIXED_INFO,PULONG);
75 static DWORD (WINAPI *pGetIcmpStatistics)(PMIB_ICMP);
76 static DWORD (WINAPI *pGetIpStatistics)(PMIB_IPSTATS);
77 static DWORD (WINAPI *pGetTcpStatistics)(PMIB_TCPSTATS);
78 static DWORD (WINAPI *pGetUdpStatistics)(PMIB_UDPSTATS);
79 static DWORD (WINAPI *pGetIcmpStatisticsEx)(PMIB_ICMP_EX,DWORD);
80 static DWORD (WINAPI *pGetIpStatisticsEx)(PMIB_IPSTATS,DWORD);
81 static DWORD (WINAPI *pGetTcpStatisticsEx)(PMIB_TCPSTATS,DWORD);
82 static DWORD (WINAPI *pGetUdpStatisticsEx)(PMIB_UDPSTATS,DWORD);
83 static DWORD (WINAPI *pGetTcpTable)(PMIB_TCPTABLE,PDWORD,BOOL);
84 static DWORD (WINAPI *pGetUdpTable)(PMIB_UDPTABLE,PDWORD,BOOL);
85 static DWORD (WINAPI *pGetPerAdapterInfo)(ULONG,PIP_PER_ADAPTER_INFO,PULONG);
86 static DWORD (WINAPI *pGetAdaptersAddresses)(ULONG,ULONG,PVOID,PIP_ADAPTER_ADDRESSES,PULONG);
87 static DWORD (WINAPI *pNotifyAddrChange)(PHANDLE,LPOVERLAPPED);
88 static BOOL (WINAPI *pCancelIPChangeNotify)(LPOVERLAPPED);
89 static DWORD (WINAPI *pGetExtendedTcpTable)(PVOID,PDWORD,BOOL,ULONG,TCP_TABLE_CLASS,ULONG);
90 static DWORD (WINAPI *pGetExtendedUdpTable)(PVOID,PDWORD,BOOL,ULONG,UDP_TABLE_CLASS,ULONG);
91 static DWORD (WINAPI *pSetTcpEntry)(PMIB_TCPROW);
92 static HANDLE(WINAPI *pIcmpCreateFile)(VOID);
93 static DWORD (WINAPI *pIcmpSendEcho)(HANDLE,IPAddr,LPVOID,WORD,PIP_OPTION_INFORMATION,LPVOID,DWORD,DWORD);
94 static DWORD (WINAPI *pCreateSortedAddressPairs)(const PSOCKADDR_IN6,ULONG,const PSOCKADDR_IN6,ULONG,ULONG,
95 PSOCKADDR_IN6_PAIR*,ULONG*);
96 static void (WINAPI *pFreeMibTable)(void*);
97 static DWORD (WINAPI *pConvertInterfaceGuidToLuid)(const GUID*,NET_LUID*);
98 static DWORD (WINAPI *pConvertInterfaceIndexToLuid)(NET_IFINDEX,NET_LUID*);
99 static DWORD (WINAPI *pConvertInterfaceLuidToGuid)(const NET_LUID*,GUID*);
100 static DWORD (WINAPI *pConvertInterfaceLuidToIndex)(const NET_LUID*,NET_IFINDEX*);
101 static DWORD (WINAPI *pConvertInterfaceLuidToNameW)(const NET_LUID*,WCHAR*,SIZE_T);
102 static DWORD (WINAPI *pConvertInterfaceLuidToNameA)(const NET_LUID*,char*,SIZE_T);
103 static DWORD (WINAPI *pConvertInterfaceNameToLuidA)(const char*,NET_LUID*);
104 static DWORD (WINAPI *pConvertInterfaceNameToLuidW)(const WCHAR*,NET_LUID*);
105
106 static void loadIPHlpApi(void)
107 {
108 hLibrary = LoadLibraryA("iphlpapi.dll");
109 if (hLibrary) {
110 pGetNumberOfInterfaces = (void *)GetProcAddress(hLibrary, "GetNumberOfInterfaces");
111 pGetIpAddrTable = (void *)GetProcAddress(hLibrary, "GetIpAddrTable");
112 pGetIfEntry = (void *)GetProcAddress(hLibrary, "GetIfEntry");
113 pGetIfEntry2 = (void *)GetProcAddress(hLibrary, "GetIfEntry2");
114 pGetFriendlyIfIndex = (void *)GetProcAddress(hLibrary, "GetFriendlyIfIndex");
115 pGetIfTable = (void *)GetProcAddress(hLibrary, "GetIfTable");
116 pGetIfTable2 = (void *)GetProcAddress(hLibrary, "GetIfTable2");
117 pGetIpForwardTable = (void *)GetProcAddress(hLibrary, "GetIpForwardTable");
118 pGetIpNetTable = (void *)GetProcAddress(hLibrary, "GetIpNetTable");
119 pGetInterfaceInfo = (void *)GetProcAddress(hLibrary, "GetInterfaceInfo");
120 pGetAdaptersInfo = (void *)GetProcAddress(hLibrary, "GetAdaptersInfo");
121 pGetNetworkParams = (void *)GetProcAddress(hLibrary, "GetNetworkParams");
122 pGetIcmpStatistics = (void *)GetProcAddress(hLibrary, "GetIcmpStatistics");
123 pGetIpStatistics = (void *)GetProcAddress(hLibrary, "GetIpStatistics");
124 pGetTcpStatistics = (void *)GetProcAddress(hLibrary, "GetTcpStatistics");
125 pGetUdpStatistics = (void *)GetProcAddress(hLibrary, "GetUdpStatistics");
126 pGetIcmpStatisticsEx = (void *)GetProcAddress(hLibrary, "GetIcmpStatisticsEx");
127 pGetIpStatisticsEx = (void *)GetProcAddress(hLibrary, "GetIpStatisticsEx");
128 pGetTcpStatisticsEx = (void *)GetProcAddress(hLibrary, "GetTcpStatisticsEx");
129 pGetUdpStatisticsEx = (void *)GetProcAddress(hLibrary, "GetUdpStatisticsEx");
130 pGetTcpTable = (void *)GetProcAddress(hLibrary, "GetTcpTable");
131 pGetUdpTable = (void *)GetProcAddress(hLibrary, "GetUdpTable");
132 pGetPerAdapterInfo = (void *)GetProcAddress(hLibrary, "GetPerAdapterInfo");
133 pGetAdaptersAddresses = (void *)GetProcAddress(hLibrary, "GetAdaptersAddresses");
134 pNotifyAddrChange = (void *)GetProcAddress(hLibrary, "NotifyAddrChange");
135 pCancelIPChangeNotify = (void *)GetProcAddress(hLibrary, "CancelIPChangeNotify");
136 pGetExtendedTcpTable = (void *)GetProcAddress(hLibrary, "GetExtendedTcpTable");
137 pGetExtendedUdpTable = (void *)GetProcAddress(hLibrary, "GetExtendedUdpTable");
138 pSetTcpEntry = (void *)GetProcAddress(hLibrary, "SetTcpEntry");
139 pIcmpCreateFile = (void *)GetProcAddress(hLibrary, "IcmpCreateFile");
140 pIcmpSendEcho = (void *)GetProcAddress(hLibrary, "IcmpSendEcho");
141 pCreateSortedAddressPairs = (void *)GetProcAddress(hLibrary, "CreateSortedAddressPairs");
142 pFreeMibTable = (void *)GetProcAddress(hLibrary, "FreeMibTable");
143 pConvertInterfaceGuidToLuid = (void *)GetProcAddress(hLibrary, "ConvertInterfaceGuidToLuid");
144 pConvertInterfaceIndexToLuid = (void *)GetProcAddress(hLibrary, "ConvertInterfaceIndexToLuid");
145 pConvertInterfaceLuidToGuid = (void *)GetProcAddress(hLibrary, "ConvertInterfaceLuidToGuid");
146 pConvertInterfaceLuidToIndex = (void *)GetProcAddress(hLibrary, "ConvertInterfaceLuidToIndex");
147 pConvertInterfaceLuidToNameA = (void *)GetProcAddress(hLibrary, "ConvertInterfaceLuidToNameA");
148 pConvertInterfaceLuidToNameW = (void *)GetProcAddress(hLibrary, "ConvertInterfaceLuidToNameW");
149 pConvertInterfaceNameToLuidA = (void *)GetProcAddress(hLibrary, "ConvertInterfaceNameToLuidA");
150 pConvertInterfaceNameToLuidW = (void *)GetProcAddress(hLibrary, "ConvertInterfaceNameToLuidW");
151 }
152 }
153
154 static void freeIPHlpApi(void)
155 {
156 FreeLibrary(hLibrary);
157 }
158
159 /* replacement for inet_ntoa */
160 static const char *ntoa( DWORD ip )
161 {
162 static char buffer[40];
163
164 ip = htonl(ip);
165 sprintf( buffer, "%u.%u.%u.%u", (ip >> 24) & 0xff, (ip >> 16) & 0xff, (ip >> 8) & 0xff, ip & 0xff );
166 return buffer;
167 }
168
169 static inline const char* debugstr_longlong(ULONGLONG ll)
170 {
171 static char string[17];
172 if (sizeof(ll) > sizeof(unsigned long) && ll >> 32)
173 sprintf(string, "%lx%08lx", (unsigned long)(ll >> 32), (unsigned long)ll);
174 else
175 sprintf(string, "%lx", (unsigned long)ll);
176 return string;
177 }
178
179 /*
180 still-to-be-tested 98-only functions:
181 GetUniDirectionalAdapterInfo
182 */
183 static void testWin98OnlyFunctions(void)
184 {
185 }
186
187 static void testGetNumberOfInterfaces(void)
188 {
189 if (pGetNumberOfInterfaces) {
190 DWORD apiReturn, numInterfaces;
191
192 /* Crashes on Vista */
193 if (0) {
194 apiReturn = pGetNumberOfInterfaces(NULL);
195 if (apiReturn == ERROR_NOT_SUPPORTED)
196 return;
197 ok(apiReturn == ERROR_INVALID_PARAMETER,
198 "GetNumberOfInterfaces(NULL) returned %d, expected ERROR_INVALID_PARAMETER\n",
199 apiReturn);
200 }
201
202 apiReturn = pGetNumberOfInterfaces(&numInterfaces);
203 if (apiReturn == ERROR_NOT_SUPPORTED) {
204 skip("GetNumberOfInterfaces is not supported\n");
205 return;
206 }
207 ok(apiReturn == NO_ERROR,
208 "GetNumberOfInterfaces returned %d, expected 0\n", apiReturn);
209 }
210 }
211
212 static void testGetIfEntry(DWORD index)
213 {
214 if (pGetIfEntry) {
215 DWORD apiReturn;
216 MIB_IFROW row;
217
218 memset(&row, 0, sizeof(row));
219 apiReturn = pGetIfEntry(NULL);
220 if (apiReturn == ERROR_NOT_SUPPORTED) {
221 skip("GetIfEntry is not supported\n");
222 return;
223 }
224 ok(apiReturn == ERROR_INVALID_PARAMETER,
225 "GetIfEntry(NULL) returned %d, expected ERROR_INVALID_PARAMETER\n",
226 apiReturn);
227 row.dwIndex = -1; /* hope that's always bogus! */
228 apiReturn = pGetIfEntry(&row);
229 ok(apiReturn == ERROR_INVALID_DATA ||
230 apiReturn == ERROR_FILE_NOT_FOUND /* Vista */,
231 "GetIfEntry(bogus row) returned %d, expected ERROR_INVALID_DATA or ERROR_FILE_NOT_FOUND\n",
232 apiReturn);
233 row.dwIndex = index;
234 apiReturn = pGetIfEntry(&row);
235 ok(apiReturn == NO_ERROR,
236 "GetIfEntry returned %d, expected NO_ERROR\n", apiReturn);
237 }
238 }
239
240 static void testGetIpAddrTable(void)
241 {
242 if (pGetIpAddrTable) {
243 DWORD apiReturn;
244 ULONG dwSize = 0;
245
246 apiReturn = pGetIpAddrTable(NULL, NULL, FALSE);
247 if (apiReturn == ERROR_NOT_SUPPORTED) {
248 skip("GetIpAddrTable is not supported\n");
249 return;
250 }
251 ok(apiReturn == ERROR_INVALID_PARAMETER,
252 "GetIpAddrTable(NULL, NULL, FALSE) returned %d, expected ERROR_INVALID_PARAMETER\n",
253 apiReturn);
254 apiReturn = pGetIpAddrTable(NULL, &dwSize, FALSE);
255 ok(apiReturn == ERROR_INSUFFICIENT_BUFFER,
256 "GetIpAddrTable(NULL, &dwSize, FALSE) returned %d, expected ERROR_INSUFFICIENT_BUFFER\n",
257 apiReturn);
258 if (apiReturn == ERROR_INSUFFICIENT_BUFFER) {
259 PMIB_IPADDRTABLE buf = HeapAlloc(GetProcessHeap(), 0, dwSize);
260
261 apiReturn = pGetIpAddrTable(buf, &dwSize, FALSE);
262 ok(apiReturn == NO_ERROR,
263 "GetIpAddrTable(buf, &dwSize, FALSE) returned %d, expected NO_ERROR\n",
264 apiReturn);
265 if (apiReturn == NO_ERROR && buf->dwNumEntries)
266 {
267 int i;
268 testGetIfEntry(buf->table[0].dwIndex);
269 for (i = 0; i < buf->dwNumEntries; i++)
270 {
271 ok (buf->table[i].wType != 0, "Test[%d]: expected wType > 0\n", i);
272 trace("Entry[%d]: addr %s, dwIndex %u, wType 0x%x\n", i,
273 ntoa(buf->table[i].dwAddr), buf->table[i].dwIndex, buf->table[i].wType);
274 }
275 }
276 HeapFree(GetProcessHeap(), 0, buf);
277 }
278 }
279 }
280
281 static void testGetIfTable(void)
282 {
283 if (pGetIfTable) {
284 DWORD apiReturn;
285 ULONG dwSize = 0;
286
287 apiReturn = pGetIfTable(NULL, NULL, FALSE);
288 if (apiReturn == ERROR_NOT_SUPPORTED) {
289 skip("GetIfTable is not supported\n");
290 return;
291 }
292 ok(apiReturn == ERROR_INVALID_PARAMETER,
293 "GetIfTable(NULL, NULL, FALSE) returned %d, expected ERROR_INVALID_PARAMETER\n",
294 apiReturn);
295 apiReturn = pGetIfTable(NULL, &dwSize, FALSE);
296 ok(apiReturn == ERROR_INSUFFICIENT_BUFFER,
297 "GetIfTable(NULL, &dwSize, FALSE) returned %d, expected ERROR_INSUFFICIENT_BUFFER\n",
298 apiReturn);
299 if (apiReturn == ERROR_INSUFFICIENT_BUFFER) {
300 PMIB_IFTABLE buf = HeapAlloc(GetProcessHeap(), 0, dwSize);
301
302 apiReturn = pGetIfTable(buf, &dwSize, FALSE);
303 ok(apiReturn == NO_ERROR,
304 "GetIfTable(buf, &dwSize, FALSE) returned %d, expected NO_ERROR\n\n",
305 apiReturn);
306
307 if (apiReturn == NO_ERROR && winetest_debug > 1)
308 {
309 DWORD i, j;
310 char name[MAX_INTERFACE_NAME_LEN];
311
312 trace( "interface table: %u entries\n", buf->dwNumEntries );
313 for (i = 0; i < buf->dwNumEntries; i++)
314 {
315 MIB_IFROW *row = &buf->table[i];
316 WideCharToMultiByte( CP_ACP, 0, row->wszName, -1, name, MAX_INTERFACE_NAME_LEN, NULL, NULL );
317 trace( "%u: '%s' type %u mtu %u speed %u phys",
318 row->dwIndex, name, row->dwType, row->dwMtu, row->dwSpeed );
319 for (j = 0; j < row->dwPhysAddrLen; j++)
320 printf( " %02x", row->bPhysAddr[j] );
321 printf( "\n" );
322 trace( " in: bytes %u upkts %u nupkts %u disc %u err %u unk %u\n",
323 row->dwInOctets, row->dwInUcastPkts, row->dwInNUcastPkts,
324 row->dwInDiscards, row->dwInErrors, row->dwInUnknownProtos );
325 trace( " out: bytes %u upkts %u nupkts %u disc %u err %u\n",
326 row->dwOutOctets, row->dwOutUcastPkts, row->dwOutNUcastPkts,
327 row->dwOutDiscards, row->dwOutErrors );
328 }
329 }
330 HeapFree(GetProcessHeap(), 0, buf);
331 }
332 }
333 }
334
335 static void testGetIpForwardTable(void)
336 {
337 if (pGetIpForwardTable) {
338 DWORD apiReturn;
339 ULONG dwSize = 0;
340
341 apiReturn = pGetIpForwardTable(NULL, NULL, FALSE);
342 if (apiReturn == ERROR_NOT_SUPPORTED) {
343 skip("GetIpForwardTable is not supported\n");
344 return;
345 }
346 ok(apiReturn == ERROR_INVALID_PARAMETER,
347 "GetIpForwardTable(NULL, NULL, FALSE) returned %d, expected ERROR_INVALID_PARAMETER\n",
348 apiReturn);
349 apiReturn = pGetIpForwardTable(NULL, &dwSize, FALSE);
350 ok(apiReturn == ERROR_INSUFFICIENT_BUFFER,
351 "GetIpForwardTable(NULL, &dwSize, FALSE) returned %d, expected ERROR_INSUFFICIENT_BUFFER\n",
352 apiReturn);
353 if (apiReturn == ERROR_INSUFFICIENT_BUFFER) {
354 PMIB_IPFORWARDTABLE buf = HeapAlloc(GetProcessHeap(), 0, dwSize);
355
356 apiReturn = pGetIpForwardTable(buf, &dwSize, FALSE);
357 ok(apiReturn == NO_ERROR,
358 "GetIpForwardTable(buf, &dwSize, FALSE) returned %d, expected NO_ERROR\n",
359 apiReturn);
360
361 if (apiReturn == NO_ERROR && winetest_debug > 1)
362 {
363 DWORD i;
364
365 trace( "IP forward table: %u entries\n", buf->dwNumEntries );
366 for (i = 0; i < buf->dwNumEntries; i++)
367 {
368 char buffer[100];
369 sprintf( buffer, "dest %s", ntoa( buf->table[i].dwForwardDest ));
370 sprintf( buffer + strlen(buffer), " mask %s", ntoa( buf->table[i].dwForwardMask ));
371 trace( "%u: %s gw %s if %u type %u\n", i, buffer,
372 ntoa( buf->table[i].dwForwardNextHop ),
373 buf->table[i].dwForwardIfIndex, U1(buf->table[i]).dwForwardType );
374 }
375 }
376 HeapFree(GetProcessHeap(), 0, buf);
377 }
378 }
379 }
380
381 static void testGetIpNetTable(void)
382 {
383 if (pGetIpNetTable) {
384 DWORD apiReturn;
385 ULONG dwSize = 0;
386
387 apiReturn = pGetIpNetTable(NULL, NULL, FALSE);
388 if (apiReturn == ERROR_NOT_SUPPORTED) {
389 skip("GetIpNetTable is not supported\n");
390 return;
391 }
392 ok(apiReturn == ERROR_INVALID_PARAMETER,
393 "GetIpNetTable(NULL, NULL, FALSE) returned %d, expected ERROR_INVALID_PARAMETER\n",
394 apiReturn);
395 apiReturn = pGetIpNetTable(NULL, &dwSize, FALSE);
396 ok(apiReturn == ERROR_NO_DATA || apiReturn == ERROR_INSUFFICIENT_BUFFER,
397 "GetIpNetTable(NULL, &dwSize, FALSE) returned %d, expected ERROR_NO_DATA or ERROR_INSUFFICIENT_BUFFER\n",
398 apiReturn);
399 if (apiReturn == ERROR_NO_DATA)
400 ; /* empty ARP table's okay */
401 else if (apiReturn == ERROR_INSUFFICIENT_BUFFER) {
402 PMIB_IPNETTABLE buf = HeapAlloc(GetProcessHeap(), 0, dwSize);
403
404 apiReturn = pGetIpNetTable(buf, &dwSize, FALSE);
405 ok(apiReturn == NO_ERROR ||
406 apiReturn == ERROR_NO_DATA, /* empty ARP table's okay */
407 "GetIpNetTable(buf, &dwSize, FALSE) returned %d, expected NO_ERROR\n",
408 apiReturn);
409
410 if (apiReturn == NO_ERROR && winetest_debug > 1)
411 {
412 DWORD i, j;
413
414 trace( "IP net table: %u entries\n", buf->dwNumEntries );
415 for (i = 0; i < buf->dwNumEntries; i++)
416 {
417 trace( "%u: idx %u type %u addr %s phys",
418 i, buf->table[i].dwIndex, U(buf->table[i]).dwType, ntoa( buf->table[i].dwAddr ));
419 for (j = 0; j < buf->table[i].dwPhysAddrLen; j++)
420 printf( " %02x", buf->table[i].bPhysAddr[j] );
421 printf( "\n" );
422 }
423 }
424 HeapFree(GetProcessHeap(), 0, buf);
425 }
426 }
427 }
428
429 static void testGetIcmpStatistics(void)
430 {
431 if (pGetIcmpStatistics) {
432 DWORD apiReturn;
433 MIB_ICMP stats;
434
435 /* Crashes on Vista */
436 if (0) {
437 apiReturn = pGetIcmpStatistics(NULL);
438 if (apiReturn == ERROR_NOT_SUPPORTED)
439 return;
440 ok(apiReturn == ERROR_INVALID_PARAMETER,
441 "GetIcmpStatistics(NULL) returned %d, expected ERROR_INVALID_PARAMETER\n",
442 apiReturn);
443 }
444
445 apiReturn = pGetIcmpStatistics(&stats);
446 if (apiReturn == ERROR_NOT_SUPPORTED)
447 {
448 skip("GetIcmpStatistics is not supported\n");
449 return;
450 }
451 ok(apiReturn == NO_ERROR,
452 "GetIcmpStatistics returned %d, expected NO_ERROR\n", apiReturn);
453 if (apiReturn == NO_ERROR && winetest_debug > 1)
454 {
455 trace( "ICMP stats: %8s %8s\n", "in", "out" );
456 trace( " dwMsgs: %8u %8u\n", stats.stats.icmpInStats.dwMsgs, stats.stats.icmpOutStats.dwMsgs );
457 trace( " dwErrors: %8u %8u\n", stats.stats.icmpInStats.dwErrors, stats.stats.icmpOutStats.dwErrors );
458 trace( " dwDestUnreachs: %8u %8u\n", stats.stats.icmpInStats.dwDestUnreachs, stats.stats.icmpOutStats.dwDestUnreachs );
459 trace( " dwTimeExcds: %8u %8u\n", stats.stats.icmpInStats.dwTimeExcds, stats.stats.icmpOutStats.dwTimeExcds );
460 trace( " dwParmProbs: %8u %8u\n", stats.stats.icmpInStats.dwParmProbs, stats.stats.icmpOutStats.dwParmProbs );
461 trace( " dwSrcQuenchs: %8u %8u\n", stats.stats.icmpInStats.dwSrcQuenchs, stats.stats.icmpOutStats.dwSrcQuenchs );
462 trace( " dwRedirects: %8u %8u\n", stats.stats.icmpInStats.dwRedirects, stats.stats.icmpOutStats.dwRedirects );
463 trace( " dwEchos: %8u %8u\n", stats.stats.icmpInStats.dwEchos, stats.stats.icmpOutStats.dwEchos );
464 trace( " dwEchoReps: %8u %8u\n", stats.stats.icmpInStats.dwEchoReps, stats.stats.icmpOutStats.dwEchoReps );
465 trace( " dwTimestamps: %8u %8u\n", stats.stats.icmpInStats.dwTimestamps, stats.stats.icmpOutStats.dwTimestamps );
466 trace( " dwTimestampReps: %8u %8u\n", stats.stats.icmpInStats.dwTimestampReps, stats.stats.icmpOutStats.dwTimestampReps );
467 trace( " dwAddrMasks: %8u %8u\n", stats.stats.icmpInStats.dwAddrMasks, stats.stats.icmpOutStats.dwAddrMasks );
468 trace( " dwAddrMaskReps: %8u %8u\n", stats.stats.icmpInStats.dwAddrMaskReps, stats.stats.icmpOutStats.dwAddrMaskReps );
469 }
470 }
471 }
472
473 static void testGetIpStatistics(void)
474 {
475 if (pGetIpStatistics) {
476 DWORD apiReturn;
477 MIB_IPSTATS stats;
478
479 apiReturn = pGetIpStatistics(NULL);
480 if (apiReturn == ERROR_NOT_SUPPORTED) {
481 skip("GetIpStatistics is not supported\n");
482 return;
483 }
484 ok(apiReturn == ERROR_INVALID_PARAMETER,
485 "GetIpStatistics(NULL) returned %d, expected ERROR_INVALID_PARAMETER\n",
486 apiReturn);
487 apiReturn = pGetIpStatistics(&stats);
488 ok(apiReturn == NO_ERROR,
489 "GetIpStatistics returned %d, expected NO_ERROR\n", apiReturn);
490 if (apiReturn == NO_ERROR && winetest_debug > 1)
491 {
492 trace( "IP stats:\n" );
493 trace( " dwForwarding: %u\n", U(stats).dwForwarding );
494 trace( " dwDefaultTTL: %u\n", stats.dwDefaultTTL );
495 trace( " dwInReceives: %u\n", stats.dwInReceives );
496 trace( " dwInHdrErrors: %u\n", stats.dwInHdrErrors );
497 trace( " dwInAddrErrors: %u\n", stats.dwInAddrErrors );
498 trace( " dwForwDatagrams: %u\n", stats.dwForwDatagrams );
499 trace( " dwInUnknownProtos: %u\n", stats.dwInUnknownProtos );
500 trace( " dwInDiscards: %u\n", stats.dwInDiscards );
501 trace( " dwInDelivers: %u\n", stats.dwInDelivers );
502 trace( " dwOutRequests: %u\n", stats.dwOutRequests );
503 trace( " dwRoutingDiscards: %u\n", stats.dwRoutingDiscards );
504 trace( " dwOutDiscards: %u\n", stats.dwOutDiscards );
505 trace( " dwOutNoRoutes: %u\n", stats.dwOutNoRoutes );
506 trace( " dwReasmTimeout: %u\n", stats.dwReasmTimeout );
507 trace( " dwReasmReqds: %u\n", stats.dwReasmReqds );
508 trace( " dwReasmOks: %u\n", stats.dwReasmOks );
509 trace( " dwReasmFails: %u\n", stats.dwReasmFails );
510 trace( " dwFragOks: %u\n", stats.dwFragOks );
511 trace( " dwFragFails: %u\n", stats.dwFragFails );
512 trace( " dwFragCreates: %u\n", stats.dwFragCreates );
513 trace( " dwNumIf: %u\n", stats.dwNumIf );
514 trace( " dwNumAddr: %u\n", stats.dwNumAddr );
515 trace( " dwNumRoutes: %u\n", stats.dwNumRoutes );
516 }
517 }
518 }
519
520 static void testGetTcpStatistics(void)
521 {
522 if (pGetTcpStatistics) {
523 DWORD apiReturn;
524 MIB_TCPSTATS stats;
525
526 apiReturn = pGetTcpStatistics(NULL);
527 if (apiReturn == ERROR_NOT_SUPPORTED) {
528 skip("GetTcpStatistics is not supported\n");
529 return;
530 }
531 ok(apiReturn == ERROR_INVALID_PARAMETER,
532 "GetTcpStatistics(NULL) returned %d, expected ERROR_INVALID_PARAMETER\n",
533 apiReturn);
534 apiReturn = pGetTcpStatistics(&stats);
535 ok(apiReturn == NO_ERROR,
536 "GetTcpStatistics returned %d, expected NO_ERROR\n", apiReturn);
537 if (apiReturn == NO_ERROR && winetest_debug > 1)
538 {
539 trace( "TCP stats:\n" );
540 trace( " dwRtoAlgorithm: %u\n", U(stats).dwRtoAlgorithm );
541 trace( " dwRtoMin: %u\n", stats.dwRtoMin );
542 trace( " dwRtoMax: %u\n", stats.dwRtoMax );
543 trace( " dwMaxConn: %u\n", stats.dwMaxConn );
544 trace( " dwActiveOpens: %u\n", stats.dwActiveOpens );
545 trace( " dwPassiveOpens: %u\n", stats.dwPassiveOpens );
546 trace( " dwAttemptFails: %u\n", stats.dwAttemptFails );
547 trace( " dwEstabResets: %u\n", stats.dwEstabResets );
548 trace( " dwCurrEstab: %u\n", stats.dwCurrEstab );
549 trace( " dwInSegs: %u\n", stats.dwInSegs );
550 trace( " dwOutSegs: %u\n", stats.dwOutSegs );
551 trace( " dwRetransSegs: %u\n", stats.dwRetransSegs );
552 trace( " dwInErrs: %u\n", stats.dwInErrs );
553 trace( " dwOutRsts: %u\n", stats.dwOutRsts );
554 trace( " dwNumConns: %u\n", stats.dwNumConns );
555 }
556 }
557 }
558
559 static void testGetUdpStatistics(void)
560 {
561 if (pGetUdpStatistics) {
562 DWORD apiReturn;
563 MIB_UDPSTATS stats;
564
565 apiReturn = pGetUdpStatistics(NULL);
566 if (apiReturn == ERROR_NOT_SUPPORTED) {
567 skip("GetUdpStatistics is not supported\n");
568 return;
569 }
570 ok(apiReturn == ERROR_INVALID_PARAMETER,
571 "GetUdpStatistics(NULL) returned %d, expected ERROR_INVALID_PARAMETER\n",
572 apiReturn);
573 apiReturn = pGetUdpStatistics(&stats);
574 ok(apiReturn == NO_ERROR,
575 "GetUdpStatistics returned %d, expected NO_ERROR\n", apiReturn);
576 if (apiReturn == NO_ERROR && winetest_debug > 1)
577 {
578 trace( "UDP stats:\n" );
579 trace( " dwInDatagrams: %u\n", stats.dwInDatagrams );
580 trace( " dwNoPorts: %u\n", stats.dwNoPorts );
581 trace( " dwInErrors: %u\n", stats.dwInErrors );
582 trace( " dwOutDatagrams: %u\n", stats.dwOutDatagrams );
583 trace( " dwNumAddrs: %u\n", stats.dwNumAddrs );
584 }
585 }
586 }
587
588 static void testGetIcmpStatisticsEx(void)
589 {
590 DWORD apiReturn;
591 MIB_ICMP_EX stats;
592
593 if (!pGetIcmpStatisticsEx)
594 {
595 win_skip( "GetIcmpStatisticsEx not available\n" );
596 return;
597 }
598
599 /* Crashes on Vista */
600 if (1) {
601 apiReturn = pGetIcmpStatisticsEx(NULL, AF_INET);
602 ok(apiReturn == ERROR_INVALID_PARAMETER,
603 "GetIcmpStatisticsEx(NULL, AF_INET) returned %d, expected ERROR_INVALID_PARAMETER\n", apiReturn);
604 }
605
606 apiReturn = pGetIcmpStatisticsEx(&stats, AF_BAN);
607 ok(apiReturn == ERROR_INVALID_PARAMETER,
608 "GetIcmpStatisticsEx(&stats, AF_BAN) returned %d, expected ERROR_INVALID_PARAMETER\n", apiReturn);
609
610 apiReturn = pGetIcmpStatisticsEx(&stats, AF_INET);
611 ok(apiReturn == NO_ERROR, "GetIcmpStatisticsEx returned %d, expected NO_ERROR\n", apiReturn);
612 if (apiReturn == NO_ERROR && winetest_debug > 1)
613 {
614 INT i;
615 trace( "ICMP IPv4 Ex stats: %8s %8s\n", "in", "out" );
616 trace( " dwMsgs: %8u %8u\n", stats.icmpInStats.dwMsgs, stats.icmpOutStats.dwMsgs );
617 trace( " dwErrors: %8u %8u\n", stats.icmpInStats.dwErrors, stats.icmpOutStats.dwErrors );
618 for (i = 0; i < 256; i++)
619 trace( " rgdwTypeCount[%3i]: %8u %8u\n", i, stats.icmpInStats.rgdwTypeCount[i], stats.icmpOutStats.rgdwTypeCount[i] );
620 }
621
622 apiReturn = pGetIcmpStatisticsEx(&stats, AF_INET6);
623 ok(apiReturn == NO_ERROR || broken(apiReturn == ERROR_NOT_SUPPORTED),
624 "GetIcmpStatisticsEx returned %d, expected NO_ERROR\n", apiReturn);
625 if (apiReturn == NO_ERROR && winetest_debug > 1)
626 {
627 INT i;
628 trace( "ICMP IPv6 Ex stats: %8s %8s\n", "in", "out" );
629 trace( " dwMsgs: %8u %8u\n", stats.icmpInStats.dwMsgs, stats.icmpOutStats.dwMsgs );
630 trace( " dwErrors: %8u %8u\n", stats.icmpInStats.dwErrors, stats.icmpOutStats.dwErrors );
631 for (i = 0; i < 256; i++)
632 trace( " rgdwTypeCount[%3i]: %8u %8u\n", i, stats.icmpInStats.rgdwTypeCount[i], stats.icmpOutStats.rgdwTypeCount[i] );
633 }
634 }
635
636 static void testGetIpStatisticsEx(void)
637 {
638 DWORD apiReturn;
639 MIB_IPSTATS stats;
640
641 if (!pGetIpStatisticsEx)
642 {
643 win_skip( "GetIpStatisticsEx not available\n" );
644 return;
645 }
646
647 apiReturn = pGetIpStatisticsEx(NULL, AF_INET);
648 ok(apiReturn == ERROR_INVALID_PARAMETER,
649 "GetIpStatisticsEx(NULL, AF_INET) returned %d, expected ERROR_INVALID_PARAMETER\n", apiReturn);
650
651 apiReturn = pGetIpStatisticsEx(&stats, AF_BAN);
652 ok(apiReturn == ERROR_INVALID_PARAMETER,
653 "GetIpStatisticsEx(&stats, AF_BAN) returned %d, expected ERROR_INVALID_PARAMETER\n", apiReturn);
654
655 apiReturn = pGetIpStatisticsEx(&stats, AF_INET);
656 ok(apiReturn == NO_ERROR, "GetIpStatisticsEx returned %d, expected NO_ERROR\n", apiReturn);
657 if (apiReturn == NO_ERROR && winetest_debug > 1)
658 {
659 trace( "IP IPv4 Ex stats:\n" );
660 trace( " dwForwarding: %u\n", U(stats).dwForwarding );
661 trace( " dwDefaultTTL: %u\n", stats.dwDefaultTTL );
662 trace( " dwInReceives: %u\n", stats.dwInReceives );
663 trace( " dwInHdrErrors: %u\n", stats.dwInHdrErrors );
664 trace( " dwInAddrErrors: %u\n", stats.dwInAddrErrors );
665 trace( " dwForwDatagrams: %u\n", stats.dwForwDatagrams );
666 trace( " dwInUnknownProtos: %u\n", stats.dwInUnknownProtos );
667 trace( " dwInDiscards: %u\n", stats.dwInDiscards );
668 trace( " dwInDelivers: %u\n", stats.dwInDelivers );
669 trace( " dwOutRequests: %u\n", stats.dwOutRequests );
670 trace( " dwRoutingDiscards: %u\n", stats.dwRoutingDiscards );
671 trace( " dwOutDiscards: %u\n", stats.dwOutDiscards );
672 trace( " dwOutNoRoutes: %u\n", stats.dwOutNoRoutes );
673 trace( " dwReasmTimeout: %u\n", stats.dwReasmTimeout );
674 trace( " dwReasmReqds: %u\n", stats.dwReasmReqds );
675 trace( " dwReasmOks: %u\n", stats.dwReasmOks );
676 trace( " dwReasmFails: %u\n", stats.dwReasmFails );
677 trace( " dwFragOks: %u\n", stats.dwFragOks );
678 trace( " dwFragFails: %u\n", stats.dwFragFails );
679 trace( " dwFragCreates: %u\n", stats.dwFragCreates );
680 trace( " dwNumIf: %u\n", stats.dwNumIf );
681 trace( " dwNumAddr: %u\n", stats.dwNumAddr );
682 trace( " dwNumRoutes: %u\n", stats.dwNumRoutes );
683 }
684
685 apiReturn = pGetIpStatisticsEx(&stats, AF_INET6);
686 ok(apiReturn == NO_ERROR || broken(apiReturn == ERROR_NOT_SUPPORTED),
687 "GetIpStatisticsEx returned %d, expected NO_ERROR\n", apiReturn);
688 if (apiReturn == NO_ERROR && winetest_debug > 1)
689 {
690 trace( "IP IPv6 Ex stats:\n" );
691 trace( " dwForwarding: %u\n", U(stats).dwForwarding );
692 trace( " dwDefaultTTL: %u\n", stats.dwDefaultTTL );
693 trace( " dwInReceives: %u\n", stats.dwInReceives );
694 trace( " dwInHdrErrors: %u\n", stats.dwInHdrErrors );
695 trace( " dwInAddrErrors: %u\n", stats.dwInAddrErrors );
696 trace( " dwForwDatagrams: %u\n", stats.dwForwDatagrams );
697 trace( " dwInUnknownProtos: %u\n", stats.dwInUnknownProtos );
698 trace( " dwInDiscards: %u\n", stats.dwInDiscards );
699 trace( " dwInDelivers: %u\n", stats.dwInDelivers );
700 trace( " dwOutRequests: %u\n", stats.dwOutRequests );
701 trace( " dwRoutingDiscards: %u\n", stats.dwRoutingDiscards );
702 trace( " dwOutDiscards: %u\n", stats.dwOutDiscards );
703 trace( " dwOutNoRoutes: %u\n", stats.dwOutNoRoutes );
704 trace( " dwReasmTimeout: %u\n", stats.dwReasmTimeout );
705 trace( " dwReasmReqds: %u\n", stats.dwReasmReqds );
706 trace( " dwReasmOks: %u\n", stats.dwReasmOks );
707 trace( " dwReasmFails: %u\n", stats.dwReasmFails );
708 trace( " dwFragOks: %u\n", stats.dwFragOks );
709 trace( " dwFragFails: %u\n", stats.dwFragFails );
710 trace( " dwFragCreates: %u\n", stats.dwFragCreates );
711 trace( " dwNumIf: %u\n", stats.dwNumIf );
712 trace( " dwNumAddr: %u\n", stats.dwNumAddr );
713 trace( " dwNumRoutes: %u\n", stats.dwNumRoutes );
714 }
715 }
716
717 static void testGetTcpStatisticsEx(void)
718 {
719 DWORD apiReturn;
720 MIB_TCPSTATS stats;
721
722 if (!pGetTcpStatisticsEx)
723 {
724 win_skip( "GetTcpStatisticsEx not available\n" );
725 return;
726 }
727
728 apiReturn = pGetTcpStatisticsEx(NULL, AF_INET);
729 ok(apiReturn == ERROR_INVALID_PARAMETER,
730 "GetTcpStatisticsEx(NULL, AF_INET); returned %d, expected ERROR_INVALID_PARAMETER\n", apiReturn);
731
732 apiReturn = pGetTcpStatisticsEx(&stats, AF_BAN);
733 ok(apiReturn == ERROR_INVALID_PARAMETER || apiReturn == ERROR_NOT_SUPPORTED,
734 "GetTcpStatisticsEx(&stats, AF_BAN) returned %d, expected ERROR_INVALID_PARAMETER\n", apiReturn);
735
736 apiReturn = pGetTcpStatisticsEx(&stats, AF_INET);
737 ok(apiReturn == NO_ERROR, "GetTcpStatisticsEx returned %d, expected NO_ERROR\n", apiReturn);
738 if (apiReturn == NO_ERROR && winetest_debug > 1)
739 {
740 trace( "TCP IPv4 Ex stats:\n" );
741 trace( " dwRtoAlgorithm: %u\n", U(stats).dwRtoAlgorithm );
742 trace( " dwRtoMin: %u\n", stats.dwRtoMin );
743 trace( " dwRtoMax: %u\n", stats.dwRtoMax );
744 trace( " dwMaxConn: %u\n", stats.dwMaxConn );
745 trace( " dwActiveOpens: %u\n", stats.dwActiveOpens );
746 trace( " dwPassiveOpens: %u\n", stats.dwPassiveOpens );
747 trace( " dwAttemptFails: %u\n", stats.dwAttemptFails );
748 trace( " dwEstabResets: %u\n", stats.dwEstabResets );
749 trace( " dwCurrEstab: %u\n", stats.dwCurrEstab );
750 trace( " dwInSegs: %u\n", stats.dwInSegs );
751 trace( " dwOutSegs: %u\n", stats.dwOutSegs );
752 trace( " dwRetransSegs: %u\n", stats.dwRetransSegs );
753 trace( " dwInErrs: %u\n", stats.dwInErrs );
754 trace( " dwOutRsts: %u\n", stats.dwOutRsts );
755 trace( " dwNumConns: %u\n", stats.dwNumConns );
756 }
757
758 apiReturn = pGetTcpStatisticsEx(&stats, AF_INET6);
759 todo_wine ok(apiReturn == NO_ERROR || broken(apiReturn == ERROR_NOT_SUPPORTED),
760 "GetTcpStatisticsEx returned %d, expected NO_ERROR\n", apiReturn);
761 if (apiReturn == NO_ERROR && winetest_debug > 1)
762 {
763 trace( "TCP IPv6 Ex stats:\n" );
764 trace( " dwRtoAlgorithm: %u\n", U(stats).dwRtoAlgorithm );
765 trace( " dwRtoMin: %u\n", stats.dwRtoMin );
766 trace( " dwRtoMax: %u\n", stats.dwRtoMax );
767 trace( " dwMaxConn: %u\n", stats.dwMaxConn );
768 trace( " dwActiveOpens: %u\n", stats.dwActiveOpens );
769 trace( " dwPassiveOpens: %u\n", stats.dwPassiveOpens );
770 trace( " dwAttemptFails: %u\n", stats.dwAttemptFails );
771 trace( " dwEstabResets: %u\n", stats.dwEstabResets );
772 trace( " dwCurrEstab: %u\n", stats.dwCurrEstab );
773 trace( " dwInSegs: %u\n", stats.dwInSegs );
774 trace( " dwOutSegs: %u\n", stats.dwOutSegs );
775 trace( " dwRetransSegs: %u\n", stats.dwRetransSegs );
776 trace( " dwInErrs: %u\n", stats.dwInErrs );
777 trace( " dwOutRsts: %u\n", stats.dwOutRsts );
778 trace( " dwNumConns: %u\n", stats.dwNumConns );
779 }
780 }
781
782 static void testGetUdpStatisticsEx(void)
783 {
784 DWORD apiReturn;
785 MIB_UDPSTATS stats;
786
787 if (!pGetUdpStatisticsEx)
788 {
789 win_skip( "GetUdpStatisticsEx not available\n" );
790 return;
791 }
792
793 apiReturn = pGetUdpStatisticsEx(NULL, AF_INET);
794 ok(apiReturn == ERROR_INVALID_PARAMETER,
795 "GetUdpStatisticsEx(NULL, AF_INET); returned %d, expected ERROR_INVALID_PARAMETER\n", apiReturn);
796
797 apiReturn = pGetUdpStatisticsEx(&stats, AF_BAN);
798 ok(apiReturn == ERROR_INVALID_PARAMETER || apiReturn == ERROR_NOT_SUPPORTED,
799 "GetUdpStatisticsEx(&stats, AF_BAN) returned %d, expected ERROR_INVALID_PARAMETER\n", apiReturn);
800
801 apiReturn = pGetUdpStatisticsEx(&stats, AF_INET);
802 ok(apiReturn == NO_ERROR, "GetUdpStatisticsEx returned %d, expected NO_ERROR\n", apiReturn);
803 if (apiReturn == NO_ERROR && winetest_debug > 1)
804 {
805 trace( "UDP IPv4 Ex stats:\n" );
806 trace( " dwInDatagrams: %u\n", stats.dwInDatagrams );
807 trace( " dwNoPorts: %u\n", stats.dwNoPorts );
808 trace( " dwInErrors: %u\n", stats.dwInErrors );
809 trace( " dwOutDatagrams: %u\n", stats.dwOutDatagrams );
810 trace( " dwNumAddrs: %u\n", stats.dwNumAddrs );
811 }
812
813 apiReturn = pGetUdpStatisticsEx(&stats, AF_INET6);
814 ok(apiReturn == NO_ERROR || broken(apiReturn == ERROR_NOT_SUPPORTED),
815 "GetUdpStatisticsEx returned %d, expected NO_ERROR\n", apiReturn);
816 if (apiReturn == NO_ERROR && winetest_debug > 1)
817 {
818 trace( "UDP IPv6 Ex stats:\n" );
819 trace( " dwInDatagrams: %u\n", stats.dwInDatagrams );
820 trace( " dwNoPorts: %u\n", stats.dwNoPorts );
821 trace( " dwInErrors: %u\n", stats.dwInErrors );
822 trace( " dwOutDatagrams: %u\n", stats.dwOutDatagrams );
823 trace( " dwNumAddrs: %u\n", stats.dwNumAddrs );
824 }
825 }
826
827 static void testGetTcpTable(void)
828 {
829 if (pGetTcpTable) {
830 DWORD apiReturn;
831 ULONG dwSize = 0;
832
833 apiReturn = pGetTcpTable(NULL, &dwSize, FALSE);
834 if (apiReturn == ERROR_NOT_SUPPORTED) {
835 skip("GetTcpTable is not supported\n");
836 return;
837 }
838 ok(apiReturn == ERROR_INSUFFICIENT_BUFFER ||
839 broken(apiReturn == ERROR_NO_DATA), /* win95 */
840 "GetTcpTable(NULL, &dwSize, FALSE) returned %d, expected ERROR_INSUFFICIENT_BUFFER\n",
841 apiReturn);
842 if (apiReturn == ERROR_INSUFFICIENT_BUFFER) {
843 PMIB_TCPTABLE buf = HeapAlloc(GetProcessHeap(), 0, dwSize);
844
845 apiReturn = pGetTcpTable(buf, &dwSize, FALSE);
846 ok(apiReturn == NO_ERROR,
847 "GetTcpTable(buf, &dwSize, FALSE) returned %d, expected NO_ERROR\n",
848 apiReturn);
849
850 if (apiReturn == NO_ERROR && winetest_debug > 1)
851 {
852 DWORD i;
853 trace( "TCP table: %u entries\n", buf->dwNumEntries );
854 for (i = 0; i < buf->dwNumEntries; i++)
855 {
856 char buffer[40];
857 sprintf( buffer, "local %s:%u",
858 ntoa(buf->table[i].dwLocalAddr), ntohs(buf->table[i].dwLocalPort) );
859 trace( "%u: %s remote %s:%u state %u\n",
860 i, buffer, ntoa( buf->table[i].dwRemoteAddr ),
861 ntohs(buf->table[i].dwRemotePort), U(buf->table[i]).dwState );
862 }
863 }
864 HeapFree(GetProcessHeap(), 0, buf);
865 }
866 }
867 }
868
869 static void testGetUdpTable(void)
870 {
871 if (pGetUdpTable) {
872 DWORD apiReturn;
873 ULONG dwSize = 0;
874
875 apiReturn = pGetUdpTable(NULL, &dwSize, FALSE);
876 if (apiReturn == ERROR_NOT_SUPPORTED) {
877 skip("GetUdpTable is not supported\n");
878 return;
879 }
880 ok(apiReturn == ERROR_INSUFFICIENT_BUFFER,
881 "GetUdpTable(NULL, &dwSize, FALSE) returned %d, expected ERROR_INSUFFICIENT_BUFFER\n",
882 apiReturn);
883 if (apiReturn == ERROR_INSUFFICIENT_BUFFER) {
884 PMIB_UDPTABLE buf = HeapAlloc(GetProcessHeap(), 0, dwSize);
885
886 apiReturn = pGetUdpTable(buf, &dwSize, FALSE);
887 ok(apiReturn == NO_ERROR,
888 "GetUdpTable(buf, &dwSize, FALSE) returned %d, expected NO_ERROR\n",
889 apiReturn);
890
891 if (apiReturn == NO_ERROR && winetest_debug > 1)
892 {
893 DWORD i;
894 trace( "UDP table: %u entries\n", buf->dwNumEntries );
895 for (i = 0; i < buf->dwNumEntries; i++)
896 trace( "%u: %s:%u\n",
897 i, ntoa( buf->table[i].dwLocalAddr ), ntohs(buf->table[i].dwLocalPort) );
898 }
899 HeapFree(GetProcessHeap(), 0, buf);
900 }
901 }
902 }
903
904 static void testSetTcpEntry(void)
905 {
906 DWORD ret;
907 MIB_TCPROW row;
908
909 memset(&row, 0, sizeof(row));
910 if(0) /* This test crashes in OS >= VISTA */
911 {
912 ret = pSetTcpEntry(NULL);
913 ok( ret == ERROR_INVALID_PARAMETER, "got %u, expected %u\n", ret, ERROR_INVALID_PARAMETER);
914 }
915
916 ret = pSetTcpEntry(&row);
917 if (ret == ERROR_NETWORK_ACCESS_DENIED)
918 {
919 win_skip("SetTcpEntry failed with access error. Skipping test.\n");
920 return;
921 }
922 todo_wine ok( ret == ERROR_INVALID_PARAMETER, "got %u, expected %u\n", ret, ERROR_INVALID_PARAMETER);
923
924 U(row).dwState = MIB_TCP_STATE_DELETE_TCB;
925 ret = pSetTcpEntry(&row);
926 todo_wine ok( ret == ERROR_MR_MID_NOT_FOUND || broken(ret == ERROR_INVALID_PARAMETER),
927 "got %u, expected %u\n", ret, ERROR_MR_MID_NOT_FOUND);
928 }
929
930 static void testIcmpSendEcho(void)
931 {
932 HANDLE icmp;
933 char senddata[32], replydata[sizeof(senddata) + sizeof(ICMP_ECHO_REPLY)];
934 DWORD ret, error, replysz = sizeof(replydata);
935 IPAddr address;
936
937 if (!pIcmpSendEcho || !pIcmpCreateFile)
938 {
939 win_skip( "IcmpSendEcho or IcmpCreateFile not available\n" );
940 return;
941 }
942 memset(senddata, 0, sizeof(senddata));
943
944 address = htonl(INADDR_LOOPBACK);
945 SetLastError(0xdeadbeef);
946 ret = pIcmpSendEcho(INVALID_HANDLE_VALUE, address, senddata, sizeof(senddata), NULL, replydata, replysz, 1000);
947 error = GetLastError();
948 ok (!ret, "IcmpSendEcho succeeded unexpectedly\n");
949 todo_wine
950 ok (error == ERROR_INVALID_PARAMETER
951 || broken(error == ERROR_INVALID_HANDLE) /* <= 2003 */,
952 "expected 87, got %d\n", error);
953
954 icmp = pIcmpCreateFile();
955 if (icmp == INVALID_HANDLE_VALUE)
956 {
957 error = GetLastError();
958 if (error == ERROR_ACCESS_DENIED)
959 {
960 skip ("ICMP is not available.\n");
961 return;
962 }
963 }
964 ok (icmp != INVALID_HANDLE_VALUE, "IcmpCreateFile failed unexpectedly with error %d\n", GetLastError());
965
966 address = 0;
967 SetLastError(0xdeadbeef);
968 ret = pIcmpSendEcho(icmp, address, senddata, sizeof(senddata), NULL, replydata, replysz, 1000);
969 error = GetLastError();
970 ok (!ret, "IcmpSendEcho succeeded unexpectedly\n");
971 ok (error == ERROR_INVALID_NETNAME
972 || broken(error == IP_BAD_DESTINATION) /* <= 2003 */,
973 "expected 1214, got %d\n", error);
974
975 address = htonl(INADDR_LOOPBACK);
976 if (0) /* crashes in XP */
977 {
978 ret = pIcmpSendEcho(icmp, address, NULL, sizeof(senddata), NULL, replydata, replysz, 1000);
979 ok (!ret, "IcmpSendEcho succeeded unexpectedly\n");
980 }
981
982 SetLastError(0xdeadbeef);
983 ret = pIcmpSendEcho(icmp, address, senddata, 0, NULL, replydata, replysz, 1000);
984 error = GetLastError();
985 ok (ret, "IcmpSendEcho failed unexpectedly with error %d\n", error);
986
987 SetLastError(0xdeadbeef);
988 ret = pIcmpSendEcho(icmp, address, NULL, 0, NULL, replydata, replysz, 1000);
989 error = GetLastError();
990 ok (ret, "IcmpSendEcho failed unexpectedly with error %d\n", error);
991
992 if (0) /* crashes in wine, remove IF when fixed */
993 {
994 SetLastError(0xdeadbeef);
995 ret = pIcmpSendEcho(icmp, address, senddata, sizeof(senddata), NULL, NULL, replysz, 1000);
996 error = GetLastError();
997 ok (!ret, "IcmpSendEcho succeeded unexpectedly\n");
998 ok (error == ERROR_INVALID_PARAMETER, "expected 87, got %d\n", error);
999 }
1000
1001 SetLastError(0xdeadbeef);
1002 ret = pIcmpSendEcho(icmp, address, senddata, sizeof(senddata), NULL, replydata, 0, 1000);
1003 error = GetLastError();
1004 ok (!ret, "IcmpSendEcho succeeded unexpectedly\n");
1005 todo_wine
1006 ok (error == ERROR_INVALID_PARAMETER
1007 || broken(error == ERROR_INSUFFICIENT_BUFFER) /* <= 2003 */,
1008 "expected 87, got %d\n", error);
1009
1010 SetLastError(0xdeadbeef);
1011 ret = pIcmpSendEcho(icmp, address, senddata, sizeof(senddata), NULL, NULL, 0, 1000);
1012 error = GetLastError();
1013 ok (!ret, "IcmpSendEcho succeeded unexpectedly\n");
1014 todo_wine
1015 ok (error == ERROR_INVALID_PARAMETER
1016 || broken(error == ERROR_INSUFFICIENT_BUFFER) /* <= 2003 */,
1017 "expected 87, got %d\n", error);
1018
1019 SetLastError(0xdeadbeef);
1020 replysz = sizeof(replydata) - 1;
1021 ret = pIcmpSendEcho(icmp, address, senddata, sizeof(senddata), NULL, replydata, replysz, 1000);
1022 error = GetLastError();
1023 todo_wine {
1024 ok (!ret, "IcmpSendEcho succeeded unexpectedly\n");
1025 ok (error == IP_GENERAL_FAILURE
1026 || broken(error == IP_BUF_TOO_SMALL) /* <= 2003 */,
1027 "expected 11050, got %d\n", error);
1028 }
1029
1030 SetLastError(0xdeadbeef);
1031 replysz = sizeof(ICMP_ECHO_REPLY);
1032 ret = pIcmpSendEcho(icmp, address, senddata, 0, NULL, replydata, replysz, 1000);
1033 error = GetLastError();
1034 todo_wine
1035 ok (ret, "IcmpSendEcho failed unexpectedly with error %d\n", error);
1036
1037 SetLastError(0xdeadbeef);
1038 replysz = sizeof(ICMP_ECHO_REPLY) + ICMP_MINLEN;
1039 ret = pIcmpSendEcho(icmp, address, senddata, ICMP_MINLEN, NULL, replydata, replysz, 1000);
1040 error = GetLastError();
1041 todo_wine
1042 ok (ret, "IcmpSendEcho failed unexpectedly with error %d\n", error);
1043
1044 SetLastError(0xdeadbeef);
1045 replysz = sizeof(ICMP_ECHO_REPLY) + ICMP_MINLEN;
1046 ret = pIcmpSendEcho(icmp, address, senddata, ICMP_MINLEN + 1, NULL, replydata, replysz, 1000);
1047 error = GetLastError();
1048 ok (!ret, "IcmpSendEcho succeeded unexpectedly\n");
1049 todo_wine
1050 ok (error == IP_GENERAL_FAILURE
1051 || broken(error == IP_BUF_TOO_SMALL) /* <= 2003 */,
1052 "expected 11050, got %d\n", error);
1053
1054 SetLastError(0xdeadbeef);
1055 ret = pIcmpSendEcho(icmp, address, senddata, ICMP_MINLEN, NULL, replydata, replysz - 1, 1000);
1056 error = GetLastError();
1057 ok (!ret, "IcmpSendEcho succeeded unexpectedly\n");
1058 todo_wine
1059 ok (error == IP_GENERAL_FAILURE
1060 || broken(error == IP_BUF_TOO_SMALL) /* <= 2003 */,
1061 "expected 11050, got %d\n", error);
1062
1063 /* in windows >= vista the timeout can't be invalid */
1064 SetLastError(0xdeadbeef);
1065 replysz = sizeof(replydata);
1066 ret = pIcmpSendEcho(icmp, address, senddata, sizeof(senddata), NULL, replydata, replysz, 0);
1067 error = GetLastError();
1068 if (!ret) ok(error == ERROR_INVALID_PARAMETER, "expected 87, got %d\n", error);
1069
1070 SetLastError(0xdeadbeef);
1071 ret = pIcmpSendEcho(icmp, address, senddata, sizeof(senddata), NULL, replydata, replysz, -1);
1072 error = GetLastError();
1073 if (!ret) ok(error == ERROR_INVALID_PARAMETER, "expected 87, got %d\n", error);
1074
1075 /* real ping test */
1076 SetLastError(0xdeadbeef);
1077 address = htonl(INADDR_LOOPBACK);
1078 ret = pIcmpSendEcho(icmp, address, senddata, sizeof(senddata), NULL, replydata, replysz, 1000);
1079 error = GetLastError();
1080 if (ret)
1081 {
1082 PICMP_ECHO_REPLY pong = (PICMP_ECHO_REPLY) replydata;
1083 trace ("send addr : %s\n", ntoa(address));
1084 trace ("reply addr : %s\n", ntoa(pong->Address));
1085 trace ("reply size : %u\n", replysz);
1086 trace ("roundtrip : %u ms\n", pong->RoundTripTime);
1087 trace ("status : %u\n", pong->Status);
1088 trace ("recv size : %u\n", pong->DataSize);
1089 trace ("ttl : %u\n", pong->Options.Ttl);
1090 trace ("flags : 0x%x\n", pong->Options.Flags);
1091 }
1092 else
1093 {
1094 skip ("Failed to ping with error %d, is lo interface down?.\n", error);
1095 }
1096 }
1097
1098 /*
1099 still-to-be-tested NT4-onward functions:
1100 CreateIpForwardEntry
1101 DeleteIpForwardEntry
1102 CreateIpNetEntry
1103 DeleteIpNetEntry
1104 GetFriendlyIfIndex
1105 GetRTTAndHopCount
1106 SetIfEntry
1107 SetIpForwardEntry
1108 SetIpNetEntry
1109 SetIpStatistics
1110 SetIpTTL
1111 */
1112 static void testWinNT4Functions(void)
1113 {
1114 testGetNumberOfInterfaces();
1115 testGetIpAddrTable();
1116 testGetIfTable();
1117 testGetIpForwardTable();
1118 testGetIpNetTable();
1119 testGetIcmpStatistics();
1120 testGetIpStatistics();
1121 testGetTcpStatistics();
1122 testGetUdpStatistics();
1123 testGetIcmpStatisticsEx();
1124 testGetIpStatisticsEx();
1125 testGetTcpStatisticsEx();
1126 testGetUdpStatisticsEx();
1127 testGetTcpTable();
1128 testGetUdpTable();
1129 testSetTcpEntry();
1130 testIcmpSendEcho();
1131 }
1132
1133 static void testGetInterfaceInfo(void)
1134 {
1135 if (pGetInterfaceInfo) {
1136 DWORD apiReturn;
1137 ULONG len = 0;
1138
1139 apiReturn = pGetInterfaceInfo(NULL, NULL);
1140 if (apiReturn == ERROR_NOT_SUPPORTED) {
1141 skip("GetInterfaceInfo is not supported\n");
1142 return;
1143 }
1144 ok(apiReturn == ERROR_INVALID_PARAMETER,
1145 "GetInterfaceInfo returned %d, expected ERROR_INVALID_PARAMETER\n",
1146 apiReturn);
1147 apiReturn = pGetInterfaceInfo(NULL, &len);
1148 ok(apiReturn == ERROR_INSUFFICIENT_BUFFER,
1149 "GetInterfaceInfo returned %d, expected ERROR_INSUFFICIENT_BUFFER\n",
1150 apiReturn);
1151 if (apiReturn == ERROR_INSUFFICIENT_BUFFER) {
1152 PIP_INTERFACE_INFO buf = HeapAlloc(GetProcessHeap(), 0, len);
1153
1154 apiReturn = pGetInterfaceInfo(buf, &len);
1155 ok(apiReturn == NO_ERROR,
1156 "GetInterfaceInfo(buf, &dwSize) returned %d, expected NO_ERROR\n",
1157 apiReturn);
1158 HeapFree(GetProcessHeap(), 0, buf);
1159 }
1160 }
1161 }
1162
1163 static void testGetAdaptersInfo(void)
1164 {
1165 if (pGetAdaptersInfo) {
1166 DWORD apiReturn;
1167 ULONG len = 0;
1168
1169 apiReturn = pGetAdaptersInfo(NULL, NULL);
1170 if (apiReturn == ERROR_NOT_SUPPORTED) {
1171 skip("GetAdaptersInfo is not supported\n");
1172 return;
1173 }
1174 ok(apiReturn == ERROR_INVALID_PARAMETER,
1175 "GetAdaptersInfo returned %d, expected ERROR_INVALID_PARAMETER\n",
1176 apiReturn);
1177 apiReturn = pGetAdaptersInfo(NULL, &len);
1178 ok(apiReturn == ERROR_NO_DATA || apiReturn == ERROR_BUFFER_OVERFLOW,
1179 "GetAdaptersInfo returned %d, expected ERROR_NO_DATA or ERROR_BUFFER_OVERFLOW\n",
1180 apiReturn);
1181 if (apiReturn == ERROR_NO_DATA)
1182 ; /* no adapter's, that's okay */
1183 else if (apiReturn == ERROR_BUFFER_OVERFLOW) {
1184 PIP_ADAPTER_INFO ptr, buf = HeapAlloc(GetProcessHeap(), 0, len);
1185
1186 apiReturn = pGetAdaptersInfo(buf, &len);
1187 ok(apiReturn == NO_ERROR,
1188 "GetAdaptersInfo(buf, &dwSize) returned %d, expected NO_ERROR\n",
1189 apiReturn);
1190 ptr = buf;
1191 while (ptr) {
1192 ok(ptr->IpAddressList.IpAddress.String[0], "A valid IP must be present\n");
1193 ok(ptr->IpAddressList.IpMask.String[0], "A valid mask must be present\n");
1194 trace("Adapter '%s', IP %s, Mask %s\n", ptr->AdapterName,
1195 ptr->IpAddressList.IpAddress.String, ptr->IpAddressList.IpMask.String);
1196 ptr = ptr->Next;
1197 }
1198 HeapFree(GetProcessHeap(), 0, buf);
1199 }
1200 }
1201 }
1202
1203 static void testGetNetworkParams(void)
1204 {
1205 if (pGetNetworkParams) {
1206 DWORD apiReturn;
1207 ULONG len = 0;
1208
1209 apiReturn = pGetNetworkParams(NULL, NULL);
1210 if (apiReturn == ERROR_NOT_SUPPORTED) {
1211 skip("GetNetworkParams is not supported\n");
1212 return;
1213 }
1214 ok(apiReturn == ERROR_INVALID_PARAMETER,
1215 "GetNetworkParams returned %d, expected ERROR_INVALID_PARAMETER\n",
1216 apiReturn);
1217 apiReturn = pGetNetworkParams(NULL, &len);
1218 ok(apiReturn == ERROR_BUFFER_OVERFLOW,
1219 "GetNetworkParams returned %d, expected ERROR_BUFFER_OVERFLOW\n",
1220 apiReturn);
1221 if (apiReturn == ERROR_BUFFER_OVERFLOW) {
1222 PFIXED_INFO buf = HeapAlloc(GetProcessHeap(), 0, len);
1223
1224 apiReturn = pGetNetworkParams(buf, &len);
1225 ok(apiReturn == NO_ERROR,
1226 "GetNetworkParams(buf, &dwSize) returned %d, expected NO_ERROR\n",
1227 apiReturn);
1228 HeapFree(GetProcessHeap(), 0, buf);
1229 }
1230 }
1231 }
1232
1233 /*
1234 still-to-be-tested 98-onward functions:
1235 GetBestInterface
1236 GetBestRoute
1237 IpReleaseAddress
1238 IpRenewAddress
1239 */
1240 static DWORD CALLBACK testWin98Functions(void *p)
1241 {
1242 testGetInterfaceInfo();
1243 testGetAdaptersInfo();
1244 testGetNetworkParams();
1245 return 0;
1246 }
1247
1248 static void testGetPerAdapterInfo(void)
1249 {
1250 DWORD ret, needed;
1251 void *buffer;
1252
1253 if (!pGetPerAdapterInfo) return;
1254 ret = pGetPerAdapterInfo(1, NULL, NULL);
1255 if (ret == ERROR_NOT_SUPPORTED) {
1256 skip("GetPerAdapterInfo is not supported\n");
1257 return;
1258 }
1259 ok( ret == ERROR_INVALID_PARAMETER, "got %u instead of ERROR_INVALID_PARAMETER\n", ret );
1260 needed = 0xdeadbeef;
1261 ret = pGetPerAdapterInfo(1, NULL, &needed);
1262 if (ret == ERROR_NO_DATA) return; /* no such adapter */
1263 ok( ret == ERROR_BUFFER_OVERFLOW, "got %u instead of ERROR_BUFFER_OVERFLOW\n", ret );
1264 ok( needed != 0xdeadbeef, "needed not set\n" );
1265 buffer = HeapAlloc( GetProcessHeap(), 0, needed );
1266 ret = pGetPerAdapterInfo(1, buffer, &needed);
1267 ok( ret == NO_ERROR, "got %u instead of NO_ERROR\n", ret );
1268 HeapFree( GetProcessHeap(), 0, buffer );
1269 }
1270
1271 static void testNotifyAddrChange(void)
1272 {
1273 DWORD ret, bytes;
1274 OVERLAPPED overlapped;
1275 HANDLE handle;
1276 BOOL success;
1277
1278 if (!pNotifyAddrChange)
1279 {
1280 win_skip("NotifyAddrChange not present\n");
1281 return;
1282 }
1283 if (!pCancelIPChangeNotify)
1284 {
1285 win_skip("CancelIPChangeNotify not present\n");
1286 return;
1287 }
1288
1289 handle = NULL;
1290 ZeroMemory(&overlapped, sizeof(overlapped));
1291 ret = pNotifyAddrChange(&handle, &overlapped);
1292 if (ret == ERROR_NOT_SUPPORTED)
1293 {
1294 win_skip("NotifyAddrChange is not supported\n");
1295 return;
1296 }
1297 ok(ret == ERROR_IO_PENDING, "NotifyAddrChange returned %d, expected ERROR_IO_PENDING\n", ret);
1298 ret = GetLastError();
1299 todo_wine ok(ret == ERROR_IO_PENDING, "GetLastError returned %d, expected ERROR_IO_PENDING\n", ret);
1300 success = pCancelIPChangeNotify(&overlapped);
1301 todo_wine ok(success == TRUE, "CancelIPChangeNotify returned FALSE, expected TRUE\n");
1302
1303 ZeroMemory(&overlapped, sizeof(overlapped));
1304 success = pCancelIPChangeNotify(&overlapped);
1305 ok(success == FALSE, "CancelIPChangeNotify returned TRUE, expected FALSE\n");
1306
1307 handle = NULL;
1308 ZeroMemory(&overlapped, sizeof(overlapped));
1309 overlapped.hEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
1310 ret = pNotifyAddrChange(&handle, &overlapped);
1311 ok(ret == ERROR_IO_PENDING, "NotifyAddrChange returned %d, expected ERROR_IO_PENDING\n", ret);
1312 todo_wine ok(handle != INVALID_HANDLE_VALUE, "NotifyAddrChange returned invalid file handle\n");
1313 success = GetOverlappedResult(handle, &overlapped, &bytes, FALSE);
1314 ok(success == FALSE, "GetOverlappedResult returned TRUE, expected FALSE\n");
1315 ret = GetLastError();
1316 ok(ret == ERROR_IO_INCOMPLETE, "GetLastError returned %d, expected ERROR_IO_INCOMPLETE\n", ret);
1317 success = pCancelIPChangeNotify(&overlapped);
1318 todo_wine ok(success == TRUE, "CancelIPChangeNotify returned FALSE, expected TRUE\n");
1319
1320 if (winetest_interactive)
1321 {
1322 handle = NULL;
1323 ZeroMemory(&overlapped, sizeof(overlapped));
1324 overlapped.hEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
1325 trace("Testing asynchronous ipv4 address change notification. Please "
1326 "change the ipv4 address of one of your network interfaces\n");
1327 ret = pNotifyAddrChange(&handle, &overlapped);
1328 ok(ret == ERROR_IO_PENDING, "NotifyAddrChange returned %d, expected NO_ERROR\n", ret);
1329 success = GetOverlappedResult(handle, &overlapped, &bytes, TRUE);
1330 ok(success == TRUE, "GetOverlappedResult returned FALSE, expected TRUE\n");
1331 }
1332
1333 /* test synchronous functionality */
1334 if (winetest_interactive)
1335 {
1336 trace("Testing synchronous ipv4 address change notification. Please "
1337 "change the ipv4 address of one of your network interfaces\n");
1338 ret = pNotifyAddrChange(NULL, NULL);
1339 todo_wine ok(ret == NO_ERROR, "NotifyAddrChange returned %d, expected NO_ERROR\n", ret);
1340 }
1341 }
1342
1343 /*
1344 still-to-be-tested 2K-onward functions:
1345 AddIPAddress
1346 CreateProxyArpEntry
1347 DeleteIPAddress
1348 DeleteProxyArpEntry
1349 EnableRouter
1350 FlushIpNetTable
1351 GetAdapterIndex
1352 NotifyRouteChange + CancelIPChangeNotify
1353 SendARP
1354 UnenableRouter
1355 */
1356 static void testWin2KFunctions(void)
1357 {
1358 testGetPerAdapterInfo();
1359 testNotifyAddrChange();
1360 }
1361
1362 static void test_GetAdaptersAddresses(void)
1363 {
1364 ULONG ret, size, osize, i;
1365 IP_ADAPTER_ADDRESSES *aa, *ptr;
1366 IP_ADAPTER_UNICAST_ADDRESS *ua;
1367
1368 if (!pGetAdaptersAddresses)
1369 {
1370 win_skip("GetAdaptersAddresses not present\n");
1371 return;
1372 }
1373
1374 ret = pGetAdaptersAddresses(AF_UNSPEC, 0, NULL, NULL, NULL);
1375 ok(ret == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER got %u\n", ret);
1376
1377 /* size should be ignored and overwritten if buffer is NULL */
1378 size = 0x7fffffff;
1379 ret = pGetAdaptersAddresses(AF_UNSPEC, 0, NULL, NULL, &size);
1380 ok(ret == ERROR_BUFFER_OVERFLOW, "expected ERROR_BUFFER_OVERFLOW, got %u\n", ret);
1381 if (ret != ERROR_BUFFER_OVERFLOW) return;
1382
1383 ptr = HeapAlloc(GetProcessHeap(), 0, size);
1384 ret = pGetAdaptersAddresses(AF_UNSPEC, 0, NULL, ptr, &size);
1385 ok(!ret, "expected ERROR_SUCCESS got %u\n", ret);
1386 HeapFree(GetProcessHeap(), 0, ptr);
1387
1388 /* higher size must not be changed to lower size */
1389 size *= 2;
1390 osize = size;
1391 ptr = HeapAlloc(GetProcessHeap(), 0, osize);
1392 ret = pGetAdaptersAddresses(AF_UNSPEC, 0, NULL, ptr, &osize);
1393 ok(!ret, "expected ERROR_SUCCESS got %u\n", ret);
1394 ok(osize == size, "expected %d, got %d\n", size, osize);
1395
1396 for (aa = ptr; !ret && aa; aa = aa->Next)
1397 {
1398 char temp[128];
1399
1400 ok(S(U(*aa)).Length == sizeof(IP_ADAPTER_ADDRESSES_LH) ||
1401 S(U(*aa)).Length == sizeof(IP_ADAPTER_ADDRESSES_XP),
1402 "Unknown structure size of %u bytes\n", S(U(*aa)).Length);
1403 ok(aa->DnsSuffix != NULL, "DnsSuffix is not a valid pointer\n");
1404 ok(aa->Description != NULL, "Description is not a valid pointer\n");
1405 ok(aa->FriendlyName != NULL, "FriendlyName is not a valid pointer\n");
1406
1407 trace("\n");
1408 trace("Length: %u\n", S(U(*aa)).Length);
1409 trace("IfIndex: %u\n", S(U(*aa)).IfIndex);
1410 trace("Next: %p\n", aa->Next);
1411 trace("AdapterName: %s\n", aa->AdapterName);
1412 trace("FirstUnicastAddress: %p\n", aa->FirstUnicastAddress);
1413 ua = aa->FirstUnicastAddress;
1414 while (ua)
1415 {
1416 ok(ua->PrefixOrigin != IpPrefixOriginOther,
1417 "bad address config value %d\n", ua->PrefixOrigin);
1418 ok(ua->SuffixOrigin != IpSuffixOriginOther,
1419 "bad address config value %d\n", ua->PrefixOrigin);
1420 /* Address configured manually or from DHCP server? */
1421 if (ua->PrefixOrigin == IpPrefixOriginManual ||
1422 ua->PrefixOrigin == IpPrefixOriginDhcp)
1423 {
1424 ok(ua->ValidLifetime, "expected non-zero value\n");
1425 ok(ua->PreferredLifetime, "expected non-zero value\n");
1426 ok(ua->LeaseLifetime, "expected non-zero\n");
1427 }
1428 /* Is the address ok in the network (not duplicated)? */
1429 ok(ua->DadState != IpDadStateInvalid && ua->DadState != IpDadStateDuplicate,
1430 "bad address duplication value %d\n", ua->DadState);
1431 trace("\tLength: %u\n", S(U(*ua)).Length);
1432 trace("\tFlags: 0x%08x\n", S(U(*ua)).Flags);
1433 trace("\tNext: %p\n", ua->Next);
1434 trace("\tAddress.lpSockaddr: %p\n", ua->Address.lpSockaddr);
1435 trace("\tAddress.iSockaddrLength: %d\n", ua->Address.iSockaddrLength);
1436 trace("\tPrefixOrigin: %u\n", ua->PrefixOrigin);
1437 trace("\tSuffixOrigin: %u\n", ua->SuffixOrigin);
1438 trace("\tDadState: %u\n", ua->DadState);
1439 trace("\tValidLifetime: %u seconds\n", ua->ValidLifetime);
1440 trace("\tPreferredLifetime: %u seconds\n", ua->PreferredLifetime);
1441 trace("\tLeaseLifetime: %u seconds\n", ua->LeaseLifetime);
1442 trace("\n");
1443 ua = ua->Next;
1444 }
1445 trace("FirstAnycastAddress: %p\n", aa->FirstAnycastAddress);
1446 trace("FirstMulticastAddress: %p\n", aa->FirstMulticastAddress);
1447 trace("FirstDnsServerAddress: %p\n", aa->FirstDnsServerAddress);
1448 trace("DnsSuffix: %s %p\n", wine_dbgstr_w(aa->DnsSuffix), aa->DnsSuffix);
1449 trace("Description: %s %p\n", wine_dbgstr_w(aa->Description), aa->Description);
1450 trace("FriendlyName: %s %p\n", wine_dbgstr_w(aa->FriendlyName), aa->FriendlyName);
1451 trace("PhysicalAddressLength: %u\n", aa->PhysicalAddressLength);
1452 for (i = 0; i < aa->PhysicalAddressLength; i++)
1453 sprintf(temp + i * 3, "%02X-", aa->PhysicalAddress[i]);
1454 temp[i ? i * 3 - 1 : 0] = '\0';
1455 trace("PhysicalAddress: %s\n", temp);
1456 trace("Flags: 0x%08x\n", aa->Flags);
1457 trace("Mtu: %u\n", aa->Mtu);
1458 trace("IfType: %u\n", aa->IfType);
1459 trace("OperStatus: %u\n", aa->OperStatus);
1460 trace("Ipv6IfIndex: %u\n", aa->Ipv6IfIndex);
1461 for (i = 0, temp[0] = '\0'; i < sizeof(aa->ZoneIndices) / sizeof(aa->ZoneIndices[0]); i++)
1462 sprintf(temp + strlen(temp), "%d ", aa->ZoneIndices[i]);
1463 trace("ZoneIndices: %s\n", temp);
1464 trace("FirstPrefix: %p\n", aa->FirstPrefix);
1465
1466 if (S(U(*aa)).Length < sizeof(IP_ADAPTER_ADDRESSES_LH)) continue;
1467 #ifndef __REACTOS__
1468 trace("TransmitLinkSpeed: %s\n", debugstr_longlong(aa->TransmitLinkSpeed));
1469 trace("ReceiveLinkSpeed: %s\n", debugstr_longlong(aa->ReceiveLinkSpeed));
1470 trace("FirstWinsServerAddress:%p\n", aa->FirstWinsServerAddress);
1471 trace("FirstGatewayAddress: %p\n", aa->FirstGatewayAddress);
1472 trace("Ipv4Metric: %u\n", aa->Ipv4Metric);
1473 trace("Ipv6Metric: %u\n", aa->Ipv6Metric);
1474 trace("Luid: %p\n", &aa->Luid);
1475 trace("Dhcpv4Server: %p\n", &aa->Dhcpv4Server);
1476 trace("CompartmentId: %u\n", aa->CompartmentId);
1477 trace("NetworkGuid: %s\n", wine_dbgstr_guid((GUID*) &aa->NetworkGuid));
1478 trace("ConnectionType: %u\n", aa->ConnectionType);
1479 trace("TunnelType: %u\n", aa->TunnelType);
1480 trace("Dhcpv6Server: %p\n", &aa->Dhcpv6Server);
1481 trace("Dhcpv6ClientDuidLength:%u\n", aa->Dhcpv6ClientDuidLength);
1482 trace("Dhcpv6ClientDuid: %p\n", aa->Dhcpv6ClientDuid);
1483 trace("Dhcpv6Iaid: %u\n", aa->Dhcpv6Iaid);
1484 trace("FirstDnsSuffix: %p\n", aa->FirstDnsSuffix);
1485 trace("\n");
1486 #endif
1487 }
1488 HeapFree(GetProcessHeap(), 0, ptr);
1489 }
1490
1491 static void test_GetExtendedTcpTable(void)
1492 {
1493 DWORD ret, size;
1494 MIB_TCPTABLE *table;
1495 MIB_TCPTABLE_OWNER_PID *table_pid;
1496 MIB_TCPTABLE_OWNER_MODULE *table_module;
1497
1498 if (!pGetExtendedTcpTable)
1499 {
1500 win_skip("GetExtendedTcpTable not available\n");
1501 return;
1502 }
1503 ret = pGetExtendedTcpTable( NULL, NULL, TRUE, AF_INET, TCP_TABLE_BASIC_ALL, 0 );
1504 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
1505
1506 size = 0;
1507 ret = pGetExtendedTcpTable( NULL, &size, TRUE, AF_INET, TCP_TABLE_BASIC_ALL, 0 );
1508 ok( ret == ERROR_INSUFFICIENT_BUFFER, "got %u\n", ret );
1509
1510 table = HeapAlloc( GetProcessHeap(), 0, size );
1511 ret = pGetExtendedTcpTable( table, &size, TRUE, AF_INET, TCP_TABLE_BASIC_ALL, 0 );
1512 ok( ret == ERROR_SUCCESS, "got %u\n", ret );
1513 HeapFree( GetProcessHeap(), 0, table );
1514
1515 size = 0;
1516 ret = pGetExtendedTcpTable( NULL, &size, TRUE, AF_INET, TCP_TABLE_BASIC_LISTENER, 0 );
1517 ok( ret == ERROR_INSUFFICIENT_BUFFER, "got %u\n", ret );
1518
1519 table = HeapAlloc( GetProcessHeap(), 0, size );
1520 ret = pGetExtendedTcpTable( table, &size, TRUE, AF_INET, TCP_TABLE_BASIC_LISTENER, 0 );
1521 ok( ret == ERROR_SUCCESS, "got %u\n", ret );
1522 HeapFree( GetProcessHeap(), 0, table );
1523
1524 size = 0;
1525 ret = pGetExtendedTcpTable( NULL, &size, TRUE, AF_INET, TCP_TABLE_OWNER_PID_ALL, 0 );
1526 ok( ret == ERROR_INSUFFICIENT_BUFFER, "got %u\n", ret );
1527
1528 table_pid = HeapAlloc( GetProcessHeap(), 0, size );
1529 ret = pGetExtendedTcpTable( table_pid, &size, TRUE, AF_INET, TCP_TABLE_OWNER_PID_ALL, 0 );
1530 ok( ret == ERROR_SUCCESS, "got %u\n", ret );
1531 HeapFree( GetProcessHeap(), 0, table_pid );
1532
1533 size = 0;
1534 ret = pGetExtendedTcpTable( NULL, &size, TRUE, AF_INET, TCP_TABLE_OWNER_PID_LISTENER, 0 );
1535 ok( ret == ERROR_INSUFFICIENT_BUFFER, "got %u\n", ret );
1536
1537 table_pid = HeapAlloc( GetProcessHeap(), 0, size );
1538 ret = pGetExtendedTcpTable( table_pid, &size, TRUE, AF_INET, TCP_TABLE_OWNER_PID_LISTENER, 0 );
1539 ok( ret == ERROR_SUCCESS, "got %u\n", ret );
1540 HeapFree( GetProcessHeap(), 0, table_pid );
1541
1542 size = 0;
1543 ret = pGetExtendedTcpTable( NULL, &size, TRUE, AF_INET, TCP_TABLE_OWNER_MODULE_ALL, 0 );
1544 ok( ret == ERROR_INSUFFICIENT_BUFFER, "got %u\n", ret );
1545
1546 table_module = HeapAlloc( GetProcessHeap(), 0, size );
1547 ret = pGetExtendedTcpTable( table_module, &size, TRUE, AF_INET, TCP_TABLE_OWNER_MODULE_ALL, 0 );
1548 ok( ret == ERROR_SUCCESS, "got %u\n", ret );
1549 HeapFree( GetProcessHeap(), 0, table_module );
1550
1551 size = 0;
1552 ret = pGetExtendedTcpTable( NULL, &size, TRUE, AF_INET, TCP_TABLE_OWNER_MODULE_LISTENER, 0 );
1553 ok( ret == ERROR_INSUFFICIENT_BUFFER, "got %u\n", ret );
1554
1555 table_module = HeapAlloc( GetProcessHeap(), 0, size );
1556 ret = pGetExtendedTcpTable( table_module, &size, TRUE, AF_INET, TCP_TABLE_OWNER_MODULE_LISTENER, 0 );
1557 ok( ret == ERROR_SUCCESS, "got %u\n", ret );
1558 HeapFree( GetProcessHeap(), 0, table_module );
1559 }
1560
1561 static void test_GetExtendedUdpTable(void)
1562 {
1563 DWORD ret, size;
1564 MIB_UDPTABLE *table;
1565 MIB_UDPTABLE_OWNER_PID *table_pid;
1566 MIB_UDPTABLE_OWNER_MODULE *table_module;
1567
1568 if (!pGetExtendedUdpTable)
1569 {
1570 win_skip("GetExtendedUdpTable not available\n");
1571 return;
1572 }
1573 ret = pGetExtendedUdpTable( NULL, NULL, TRUE, AF_INET, UDP_TABLE_BASIC, 0 );
1574 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
1575
1576 size = 0;
1577 ret = pGetExtendedUdpTable( NULL, &size, TRUE, AF_INET, UDP_TABLE_BASIC, 0 );
1578 ok( ret == ERROR_INSUFFICIENT_BUFFER, "got %u\n", ret );
1579
1580 table = HeapAlloc( GetProcessHeap(), 0, size );
1581 ret = pGetExtendedUdpTable( table, &size, TRUE, AF_INET, UDP_TABLE_BASIC, 0 );
1582 ok( ret == ERROR_SUCCESS, "got %u\n", ret );
1583 HeapFree( GetProcessHeap(), 0, table );
1584
1585 size = 0;
1586 ret = pGetExtendedUdpTable( NULL, &size, TRUE, AF_INET, UDP_TABLE_OWNER_PID, 0 );
1587 ok( ret == ERROR_INSUFFICIENT_BUFFER, "got %u\n", ret );
1588
1589 table_pid = HeapAlloc( GetProcessHeap(), 0, size );
1590 ret = pGetExtendedUdpTable( table_pid, &size, TRUE, AF_INET, UDP_TABLE_OWNER_PID, 0 );
1591 ok( ret == ERROR_SUCCESS, "got %u\n", ret );
1592 HeapFree( GetProcessHeap(), 0, table_pid );
1593
1594 size = 0;
1595 ret = pGetExtendedUdpTable( NULL, &size, TRUE, AF_INET, UDP_TABLE_OWNER_MODULE, 0 );
1596 ok( ret == ERROR_INSUFFICIENT_BUFFER, "got %u\n", ret );
1597
1598 table_module = HeapAlloc( GetProcessHeap(), 0, size );
1599 ret = pGetExtendedUdpTable( table_module, &size, TRUE, AF_INET, UDP_TABLE_OWNER_MODULE, 0 );
1600 ok( ret == ERROR_SUCCESS, "got %u\n", ret );
1601 HeapFree( GetProcessHeap(), 0, table_module );
1602 }
1603
1604 static void test_CreateSortedAddressPairs(void)
1605 {
1606 SOCKADDR_IN6 dst[2];
1607 SOCKADDR_IN6_PAIR *pair;
1608 ULONG pair_count;
1609 DWORD ret;
1610
1611 if (!pCreateSortedAddressPairs)
1612 {
1613 win_skip( "CreateSortedAddressPairs not available\n" );
1614 return;
1615 }
1616
1617 memset( dst, 0, sizeof(dst) );
1618 dst[0].sin6_family = AF_INET6;
1619 dst[0].sin6_addr.u.Word[5] = 0xffff;
1620 dst[0].sin6_addr.u.Word[6] = 0x0808;
1621 dst[0].sin6_addr.u.Word[7] = 0x0808;
1622
1623 pair_count = 0xdeadbeef;
1624 ret = pCreateSortedAddressPairs( NULL, 0, dst, 1, 0, NULL, &pair_count );
1625 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
1626 ok( pair_count == 0xdeadbeef, "got %u\n", pair_count );
1627
1628 pair = (SOCKADDR_IN6_PAIR *)0xdeadbeef;
1629 pair_count = 0xdeadbeef;
1630 ret = pCreateSortedAddressPairs( NULL, 0, NULL, 1, 0, &pair, &pair_count );
1631 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
1632 ok( pair == (SOCKADDR_IN6_PAIR *)0xdeadbeef, "got %p\n", pair );
1633 ok( pair_count == 0xdeadbeef, "got %u\n", pair_count );
1634
1635 pair = NULL;
1636 pair_count = 0xdeadbeef;
1637 ret = pCreateSortedAddressPairs( NULL, 0, dst, 1, 0, &pair, &pair_count );
1638 ok( ret == NO_ERROR, "got %u\n", ret );
1639 ok( pair != NULL, "pair not set\n" );
1640 ok( pair_count >= 1, "got %u\n", pair_count );
1641 ok( pair[0].SourceAddress != NULL, "src address not set\n" );
1642 ok( pair[0].DestinationAddress != NULL, "dst address not set\n" );
1643 pFreeMibTable( pair );
1644
1645 dst[1].sin6_family = AF_INET6;
1646 dst[1].sin6_addr.u.Word[5] = 0xffff;
1647 dst[1].sin6_addr.u.Word[6] = 0x0404;
1648 dst[1].sin6_addr.u.Word[7] = 0x0808;
1649
1650 pair = NULL;
1651 pair_count = 0xdeadbeef;
1652 ret = pCreateSortedAddressPairs( NULL, 0, dst, 2, 0, &pair, &pair_count );
1653 ok( ret == NO_ERROR, "got %u\n", ret );
1654 ok( pair != NULL, "pair not set\n" );
1655 ok( pair_count >= 2, "got %u\n", pair_count );
1656 ok( pair[0].SourceAddress != NULL, "src address not set\n" );
1657 ok( pair[0].DestinationAddress != NULL, "dst address not set\n" );
1658 ok( pair[1].SourceAddress != NULL, "src address not set\n" );
1659 ok( pair[1].DestinationAddress != NULL, "dst address not set\n" );
1660 pFreeMibTable( pair );
1661 }
1662
1663 static DWORD get_interface_index(void)
1664 {
1665 DWORD size = 0, ret = 0;
1666 IP_ADAPTER_ADDRESSES *buf, *aa;
1667
1668 if (pGetAdaptersAddresses( AF_UNSPEC, 0, NULL, NULL, &size ) != ERROR_BUFFER_OVERFLOW)
1669 return 0;
1670
1671 buf = HeapAlloc( GetProcessHeap(), 0, size );
1672 pGetAdaptersAddresses( AF_UNSPEC, 0, NULL, buf, &size );
1673 for (aa = buf; aa; aa = aa->Next)
1674 {
1675 if (aa->IfType == IF_TYPE_ETHERNET_CSMACD)
1676 {
1677 ret = aa->IfIndex;
1678 break;
1679 }
1680 }
1681 HeapFree( GetProcessHeap(), 0, buf );
1682 return ret;
1683 }
1684
1685 static void test_interface_identifier_conversion(void)
1686 {
1687 DWORD ret;
1688 NET_LUID luid;
1689 GUID guid;
1690 SIZE_T len;
1691 WCHAR nameW[IF_MAX_STRING_SIZE + 1];
1692 char nameA[IF_MAX_STRING_SIZE + 1];
1693 NET_IFINDEX index;
1694
1695 if (!pConvertInterfaceIndexToLuid)
1696 {
1697 win_skip( "ConvertInterfaceIndexToLuid not available\n" );
1698 return;
1699 }
1700 if (!(index = get_interface_index()))
1701 {
1702 skip( "no suitable interface found\n" );
1703 return;
1704 }
1705
1706 /* ConvertInterfaceIndexToLuid */
1707 ret = pConvertInterfaceIndexToLuid( 0, NULL );
1708 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
1709
1710 memset( &luid, 0xff, sizeof(luid) );
1711 ret = pConvertInterfaceIndexToLuid( 0, &luid );
1712 ok( ret == ERROR_FILE_NOT_FOUND, "got %u\n", ret );
1713 ok( !luid.Info.Reserved, "got %x\n", luid.Info.Reserved );
1714 ok( !luid.Info.NetLuidIndex, "got %u\n", luid.Info.NetLuidIndex );
1715 ok( !luid.Info.IfType, "got %u\n", luid.Info.IfType );
1716
1717 luid.Info.Reserved = luid.Info.NetLuidIndex = luid.Info.IfType = 0xdead;
1718 ret = pConvertInterfaceIndexToLuid( index, &luid );
1719 ok( !ret, "got %u\n", ret );
1720 ok( !luid.Info.Reserved, "got %x\n", luid.Info.Reserved );
1721 ok( luid.Info.NetLuidIndex != 0xdead, "index not set\n" );
1722 ok( luid.Info.IfType == IF_TYPE_ETHERNET_CSMACD, "got %u\n", luid.Info.IfType );
1723
1724 /* ConvertInterfaceLuidToIndex */
1725 ret = pConvertInterfaceLuidToIndex( NULL, NULL );
1726 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
1727
1728 ret = pConvertInterfaceLuidToIndex( NULL, &index );
1729 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
1730
1731 ret = pConvertInterfaceLuidToIndex( &luid, NULL );
1732 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
1733
1734 ret = pConvertInterfaceLuidToIndex( &luid, &index );
1735 ok( !ret, "got %u\n", ret );
1736
1737 /* ConvertInterfaceLuidToGuid */
1738 ret = pConvertInterfaceLuidToGuid( NULL, NULL );
1739 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
1740
1741 memset( &guid, 0xff, sizeof(guid) );
1742 ret = pConvertInterfaceLuidToGuid( NULL, &guid );
1743 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
1744 ok( guid.Data1 == 0xffffffff, "got %x\n", guid.Data1 );
1745
1746 ret = pConvertInterfaceLuidToGuid( &luid, NULL );
1747 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
1748
1749 memset( &guid, 0, sizeof(guid) );
1750 ret = pConvertInterfaceLuidToGuid( &luid, &guid );
1751 ok( !ret, "got %u\n", ret );
1752 ok( guid.Data1, "got %x\n", guid.Data1 );
1753
1754 /* ConvertInterfaceGuidToLuid */
1755 ret = pConvertInterfaceGuidToLuid( NULL, NULL );
1756 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
1757
1758 luid.Info.NetLuidIndex = 1;
1759 ret = pConvertInterfaceGuidToLuid( NULL, &luid );
1760 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
1761 ok( luid.Info.NetLuidIndex == 1, "got %u\n", luid.Info.NetLuidIndex );
1762
1763 ret = pConvertInterfaceGuidToLuid( &guid, NULL );
1764 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
1765
1766 luid.Info.Reserved = luid.Info.NetLuidIndex = luid.Info.IfType = 0xdead;
1767 ret = pConvertInterfaceGuidToLuid( &guid, &luid );
1768 ok( !ret, "got %u\n", ret );
1769 ok( !luid.Info.Reserved, "got %x\n", luid.Info.Reserved );
1770 ok( luid.Info.NetLuidIndex != 0xdead, "index not set\n" );
1771 ok( luid.Info.IfType == IF_TYPE_ETHERNET_CSMACD, "got %u\n", luid.Info.IfType );
1772
1773 /* ConvertInterfaceLuidToNameW */
1774 ret = pConvertInterfaceLuidToNameW( NULL, NULL, 0 );
1775 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
1776
1777 ret = pConvertInterfaceLuidToNameW( &luid, NULL, 0 );
1778 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
1779
1780 ret = pConvertInterfaceLuidToNameW( NULL, nameW, 0 );
1781 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
1782
1783 ret = pConvertInterfaceLuidToNameW( &luid, nameW, 0 );
1784 ok( ret == ERROR_NOT_ENOUGH_MEMORY, "got %u\n", ret );
1785
1786 nameW[0] = 0;
1787 len = sizeof(nameW)/sizeof(nameW[0]);
1788 ret = pConvertInterfaceLuidToNameW( &luid, nameW, len );
1789 ok( !ret, "got %u\n", ret );
1790 ok( nameW[0], "name not set\n" );
1791
1792 /* ConvertInterfaceLuidToNameA */
1793 ret = pConvertInterfaceLuidToNameA( NULL, NULL, 0 );
1794 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
1795
1796 ret = pConvertInterfaceLuidToNameA( &luid, NULL, 0 );
1797 ok( ret == ERROR_NOT_ENOUGH_MEMORY, "got %u\n", ret );
1798
1799 ret = pConvertInterfaceLuidToNameA( NULL, nameA, 0 );
1800 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
1801
1802 ret = pConvertInterfaceLuidToNameA( &luid, nameA, 0 );
1803 ok( ret == ERROR_NOT_ENOUGH_MEMORY, "got %u\n", ret );
1804
1805 nameA[0] = 0;
1806 len = sizeof(nameA)/sizeof(nameA[0]);
1807 ret = pConvertInterfaceLuidToNameA( &luid, nameA, len );
1808 ok( !ret, "got %u\n", ret );
1809 ok( nameA[0], "name not set\n" );
1810
1811 /* ConvertInterfaceNameToLuidW */
1812 ret = pConvertInterfaceNameToLuidW( NULL, NULL );
1813 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
1814
1815 luid.Info.Reserved = luid.Info.NetLuidIndex = luid.Info.IfType = 0xdead;
1816 ret = pConvertInterfaceNameToLuidW( NULL, &luid );
1817 ok( ret == ERROR_INVALID_NAME, "got %u\n", ret );
1818 ok( !luid.Info.Reserved, "got %x\n", luid.Info.Reserved );
1819 ok( luid.Info.NetLuidIndex != 0xdead, "index not set\n" );
1820 ok( !luid.Info.IfType, "got %u\n", luid.Info.IfType );
1821
1822 ret = pConvertInterfaceNameToLuidW( nameW, NULL );
1823 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
1824
1825 luid.Info.Reserved = luid.Info.NetLuidIndex = luid.Info.IfType = 0xdead;
1826 ret = pConvertInterfaceNameToLuidW( nameW, &luid );
1827 ok( !ret, "got %u\n", ret );
1828 ok( !luid.Info.Reserved, "got %x\n", luid.Info.Reserved );
1829 ok( luid.Info.NetLuidIndex != 0xdead, "index not set\n" );
1830 ok( luid.Info.IfType == IF_TYPE_ETHERNET_CSMACD, "got %u\n", luid.Info.IfType );
1831
1832 /* ConvertInterfaceNameToLuidA */
1833 ret = pConvertInterfaceNameToLuidA( NULL, NULL );
1834 ok( ret == ERROR_INVALID_NAME, "got %u\n", ret );
1835
1836 luid.Info.Reserved = luid.Info.NetLuidIndex = luid.Info.IfType = 0xdead;
1837 ret = pConvertInterfaceNameToLuidA( NULL, &luid );
1838 ok( ret == ERROR_INVALID_NAME, "got %u\n", ret );
1839 ok( luid.Info.Reserved == 0xdead, "reserved set\n" );
1840 ok( luid.Info.NetLuidIndex == 0xdead, "index set\n" );
1841 ok( luid.Info.IfType == 0xdead, "type set\n" );
1842
1843 ret = pConvertInterfaceNameToLuidA( nameA, NULL );
1844 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
1845
1846 luid.Info.Reserved = luid.Info.NetLuidIndex = luid.Info.IfType = 0xdead;
1847 ret = pConvertInterfaceNameToLuidA( nameA, &luid );
1848 ok( !ret, "got %u\n", ret );
1849 ok( !luid.Info.Reserved, "got %x\n", luid.Info.Reserved );
1850 ok( luid.Info.NetLuidIndex != 0xdead, "index not set\n" );
1851 ok( luid.Info.IfType == IF_TYPE_ETHERNET_CSMACD, "got %u\n", luid.Info.IfType );
1852 }
1853
1854 static void test_GetIfEntry2(void)
1855 {
1856 DWORD ret;
1857 MIB_IF_ROW2 row;
1858 NET_IFINDEX index;
1859
1860 if (!pGetIfEntry2)
1861 {
1862 win_skip( "GetIfEntry2 not available\n" );
1863 return;
1864 }
1865 if (!(index = get_interface_index()))
1866 {
1867 skip( "no suitable interface found\n" );
1868 return;
1869 }
1870
1871 ret = pGetIfEntry2( NULL );
1872 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
1873
1874 memset( &row, 0, sizeof(row) );
1875 ret = pGetIfEntry2( &row );
1876 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
1877
1878 memset( &row, 0, sizeof(row) );
1879 row.InterfaceIndex = index;
1880 ret = pGetIfEntry2( &row );
1881 ok( ret == NO_ERROR, "got %u\n", ret );
1882 ok( row.InterfaceIndex == index, "got %u\n", index );
1883 }
1884
1885 static void test_GetIfTable2(void)
1886 {
1887 DWORD ret;
1888 MIB_IF_TABLE2 *table;
1889
1890 if (!pGetIfTable2)
1891 {
1892 win_skip( "GetIfTable2 not available\n" );
1893 return;
1894 }
1895
1896 table = NULL;
1897 ret = pGetIfTable2( &table );
1898 ok( ret == NO_ERROR, "got %u\n", ret );
1899 ok( table != NULL, "table not set\n" );
1900 pFreeMibTable( table );
1901 }
1902
1903 START_TEST(iphlpapi)
1904 {
1905
1906 loadIPHlpApi();
1907 if (hLibrary) {
1908 HANDLE thread;
1909
1910 testWin98OnlyFunctions();
1911 testWinNT4Functions();
1912
1913 /* run testGetXXXX in two threads at once to make sure we don't crash in that case */
1914 thread = CreateThread(NULL, 0, testWin98Functions, NULL, 0, NULL);
1915 testWin98Functions(NULL);
1916 WaitForSingleObject(thread, INFINITE);
1917
1918 testWin2KFunctions();
1919 test_GetAdaptersAddresses();
1920 test_GetExtendedTcpTable();
1921 test_GetExtendedUdpTable();
1922 test_CreateSortedAddressPairs();
1923 test_interface_identifier_conversion();
1924 test_GetIfEntry2();
1925 test_GetIfTable2();
1926 freeIPHlpApi();
1927 }
1928 }