iphlpapi: Stub more IP_ADAPTER_UNICAST_ADDRESS fields in GetAdaptersAddresses.
[wine.git] / dlls / iphlpapi / tests / iphlpapi.c
blob58fb843e4f6becc36bb734c0d340b499c2482fc2
1 /*
2 * iphlpapi dll test
4 * Copyright (C) 2003 Juan Lang
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.
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.
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
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).
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.
34 * The DomainName field of FIXED_INFO isn't NULL-terminated on Win98.
37 #include <stdarg.h>
38 #include "winsock2.h"
39 #include "windef.h"
40 #include "winbase.h"
41 #include "iphlpapi.h"
42 #include "iprtrmib.h"
43 #include "wine/test.h"
44 #include <stdio.h>
45 #include <stdlib.h>
47 #define ICMP_MINLEN 8 /* copied from dlls/iphlpapi/ip_icmp.h file */
49 static HMODULE hLibrary = NULL;
51 static DWORD (WINAPI *pGetNumberOfInterfaces)(PDWORD);
52 static DWORD (WINAPI *pGetIpAddrTable)(PMIB_IPADDRTABLE,PULONG,BOOL);
53 static DWORD (WINAPI *pGetIfEntry)(PMIB_IFROW);
54 static DWORD (WINAPI *pGetFriendlyIfIndex)(DWORD);
55 static DWORD (WINAPI *pGetIfTable)(PMIB_IFTABLE,PULONG,BOOL);
56 static DWORD (WINAPI *pGetIpForwardTable)(PMIB_IPFORWARDTABLE,PULONG,BOOL);
57 static DWORD (WINAPI *pGetIpNetTable)(PMIB_IPNETTABLE,PULONG,BOOL);
58 static DWORD (WINAPI *pGetInterfaceInfo)(PIP_INTERFACE_INFO,PULONG);
59 static DWORD (WINAPI *pGetAdaptersInfo)(PIP_ADAPTER_INFO,PULONG);
60 static DWORD (WINAPI *pGetNetworkParams)(PFIXED_INFO,PULONG);
61 static DWORD (WINAPI *pGetIcmpStatistics)(PMIB_ICMP);
62 static DWORD (WINAPI *pGetIpStatistics)(PMIB_IPSTATS);
63 static DWORD (WINAPI *pGetTcpStatistics)(PMIB_TCPSTATS);
64 static DWORD (WINAPI *pGetUdpStatistics)(PMIB_UDPSTATS);
65 static DWORD (WINAPI *pGetIcmpStatisticsEx)(PMIB_ICMP_EX,DWORD);
66 static DWORD (WINAPI *pGetIpStatisticsEx)(PMIB_IPSTATS,DWORD);
67 static DWORD (WINAPI *pGetTcpStatisticsEx)(PMIB_TCPSTATS,DWORD);
68 static DWORD (WINAPI *pGetUdpStatisticsEx)(PMIB_UDPSTATS,DWORD);
69 static DWORD (WINAPI *pGetTcpTable)(PMIB_TCPTABLE,PDWORD,BOOL);
70 static DWORD (WINAPI *pGetUdpTable)(PMIB_UDPTABLE,PDWORD,BOOL);
71 static DWORD (WINAPI *pGetPerAdapterInfo)(ULONG,PIP_PER_ADAPTER_INFO,PULONG);
72 static DWORD (WINAPI *pGetAdaptersAddresses)(ULONG,ULONG,PVOID,PIP_ADAPTER_ADDRESSES,PULONG);
73 static DWORD (WINAPI *pNotifyAddrChange)(PHANDLE,LPOVERLAPPED);
74 static BOOL (WINAPI *pCancelIPChangeNotify)(LPOVERLAPPED);
75 static DWORD (WINAPI *pGetExtendedTcpTable)(PVOID,PDWORD,BOOL,ULONG,TCP_TABLE_CLASS,ULONG);
76 static DWORD (WINAPI *pGetExtendedUdpTable)(PVOID,PDWORD,BOOL,ULONG,UDP_TABLE_CLASS,ULONG);
77 static DWORD (WINAPI *pSetTcpEntry)(PMIB_TCPROW);
78 static HANDLE(WINAPI *pIcmpCreateFile)(VOID);
79 static DWORD (WINAPI *pIcmpSendEcho)(HANDLE,IPAddr,LPVOID,WORD,PIP_OPTION_INFORMATION,LPVOID,DWORD,DWORD);
81 static void loadIPHlpApi(void)
83 hLibrary = LoadLibraryA("iphlpapi.dll");
84 if (hLibrary) {
85 pGetNumberOfInterfaces = (void *)GetProcAddress(hLibrary, "GetNumberOfInterfaces");
86 pGetIpAddrTable = (void *)GetProcAddress(hLibrary, "GetIpAddrTable");
87 pGetIfEntry = (void *)GetProcAddress(hLibrary, "GetIfEntry");
88 pGetFriendlyIfIndex = (void *)GetProcAddress(hLibrary, "GetFriendlyIfIndex");
89 pGetIfTable = (void *)GetProcAddress(hLibrary, "GetIfTable");
90 pGetIpForwardTable = (void *)GetProcAddress(hLibrary, "GetIpForwardTable");
91 pGetIpNetTable = (void *)GetProcAddress(hLibrary, "GetIpNetTable");
92 pGetInterfaceInfo = (void *)GetProcAddress(hLibrary, "GetInterfaceInfo");
93 pGetAdaptersInfo = (void *)GetProcAddress(hLibrary, "GetAdaptersInfo");
94 pGetNetworkParams = (void *)GetProcAddress(hLibrary, "GetNetworkParams");
95 pGetIcmpStatistics = (void *)GetProcAddress(hLibrary, "GetIcmpStatistics");
96 pGetIpStatistics = (void *)GetProcAddress(hLibrary, "GetIpStatistics");
97 pGetTcpStatistics = (void *)GetProcAddress(hLibrary, "GetTcpStatistics");
98 pGetUdpStatistics = (void *)GetProcAddress(hLibrary, "GetUdpStatistics");
99 pGetIcmpStatisticsEx = (void *)GetProcAddress(hLibrary, "GetIcmpStatisticsEx");
100 pGetIpStatisticsEx = (void *)GetProcAddress(hLibrary, "GetIpStatisticsEx");
101 pGetTcpStatisticsEx = (void *)GetProcAddress(hLibrary, "GetTcpStatisticsEx");
102 pGetUdpStatisticsEx = (void *)GetProcAddress(hLibrary, "GetUdpStatisticsEx");
103 pGetTcpTable = (void *)GetProcAddress(hLibrary, "GetTcpTable");
104 pGetUdpTable = (void *)GetProcAddress(hLibrary, "GetUdpTable");
105 pGetPerAdapterInfo = (void *)GetProcAddress(hLibrary, "GetPerAdapterInfo");
106 pGetAdaptersAddresses = (void *)GetProcAddress(hLibrary, "GetAdaptersAddresses");
107 pNotifyAddrChange = (void *)GetProcAddress(hLibrary, "NotifyAddrChange");
108 pCancelIPChangeNotify = (void *)GetProcAddress(hLibrary, "CancelIPChangeNotify");
109 pGetExtendedTcpTable = (void *)GetProcAddress(hLibrary, "GetExtendedTcpTable");
110 pGetExtendedUdpTable = (void *)GetProcAddress(hLibrary, "GetExtendedUdpTable");
111 pSetTcpEntry = (void *)GetProcAddress(hLibrary, "SetTcpEntry");
112 pIcmpCreateFile = (void *)GetProcAddress(hLibrary, "IcmpCreateFile");
113 pIcmpSendEcho = (void *)GetProcAddress(hLibrary, "IcmpSendEcho");
117 static void freeIPHlpApi(void)
119 FreeLibrary(hLibrary);
122 /* replacement for inet_ntoa */
123 static const char *ntoa( DWORD ip )
125 static char buffer[40];
127 ip = htonl(ip);
128 sprintf( buffer, "%u.%u.%u.%u", (ip >> 24) & 0xff, (ip >> 16) & 0xff, (ip >> 8) & 0xff, ip & 0xff );
129 return buffer;
132 static inline const char* debugstr_longlong(ULONGLONG ll)
134 static char string[17];
135 if (sizeof(ll) > sizeof(unsigned long) && ll >> 32)
136 sprintf(string, "%lx%08lx", (unsigned long)(ll >> 32), (unsigned long)ll);
137 else
138 sprintf(string, "%lx", (unsigned long)ll);
139 return string;
143 still-to-be-tested 98-only functions:
144 GetUniDirectionalAdapterInfo
146 static void testWin98OnlyFunctions(void)
150 static void testGetNumberOfInterfaces(void)
152 if (pGetNumberOfInterfaces) {
153 DWORD apiReturn, numInterfaces;
155 /* Crashes on Vista */
156 if (0) {
157 apiReturn = pGetNumberOfInterfaces(NULL);
158 if (apiReturn == ERROR_NOT_SUPPORTED)
159 return;
160 ok(apiReturn == ERROR_INVALID_PARAMETER,
161 "GetNumberOfInterfaces(NULL) returned %d, expected ERROR_INVALID_PARAMETER\n",
162 apiReturn);
165 apiReturn = pGetNumberOfInterfaces(&numInterfaces);
166 if (apiReturn == ERROR_NOT_SUPPORTED) {
167 skip("GetNumberOfInterfaces is not supported\n");
168 return;
170 ok(apiReturn == NO_ERROR,
171 "GetNumberOfInterfaces returned %d, expected 0\n", apiReturn);
175 static void testGetIfEntry(DWORD index)
177 if (pGetIfEntry) {
178 DWORD apiReturn;
179 MIB_IFROW row;
181 memset(&row, 0, sizeof(row));
182 apiReturn = pGetIfEntry(NULL);
183 if (apiReturn == ERROR_NOT_SUPPORTED) {
184 skip("GetIfEntry is not supported\n");
185 return;
187 ok(apiReturn == ERROR_INVALID_PARAMETER,
188 "GetIfEntry(NULL) returned %d, expected ERROR_INVALID_PARAMETER\n",
189 apiReturn);
190 row.dwIndex = -1; /* hope that's always bogus! */
191 apiReturn = pGetIfEntry(&row);
192 ok(apiReturn == ERROR_INVALID_DATA ||
193 apiReturn == ERROR_FILE_NOT_FOUND /* Vista */,
194 "GetIfEntry(bogus row) returned %d, expected ERROR_INVALID_DATA or ERROR_FILE_NOT_FOUND\n",
195 apiReturn);
196 row.dwIndex = index;
197 apiReturn = pGetIfEntry(&row);
198 ok(apiReturn == NO_ERROR,
199 "GetIfEntry returned %d, expected NO_ERROR\n", apiReturn);
203 static void testGetIpAddrTable(void)
205 if (pGetIpAddrTable) {
206 DWORD apiReturn;
207 ULONG dwSize = 0;
209 apiReturn = pGetIpAddrTable(NULL, NULL, FALSE);
210 if (apiReturn == ERROR_NOT_SUPPORTED) {
211 skip("GetIpAddrTable is not supported\n");
212 return;
214 ok(apiReturn == ERROR_INVALID_PARAMETER,
215 "GetIpAddrTable(NULL, NULL, FALSE) returned %d, expected ERROR_INVALID_PARAMETER\n",
216 apiReturn);
217 apiReturn = pGetIpAddrTable(NULL, &dwSize, FALSE);
218 ok(apiReturn == ERROR_INSUFFICIENT_BUFFER,
219 "GetIpAddrTable(NULL, &dwSize, FALSE) returned %d, expected ERROR_INSUFFICIENT_BUFFER\n",
220 apiReturn);
221 if (apiReturn == ERROR_INSUFFICIENT_BUFFER) {
222 PMIB_IPADDRTABLE buf = HeapAlloc(GetProcessHeap(), 0, dwSize);
224 apiReturn = pGetIpAddrTable(buf, &dwSize, FALSE);
225 ok(apiReturn == NO_ERROR,
226 "GetIpAddrTable(buf, &dwSize, FALSE) returned %d, expected NO_ERROR\n",
227 apiReturn);
228 if (apiReturn == NO_ERROR && buf->dwNumEntries)
229 testGetIfEntry(buf->table[0].dwIndex);
230 HeapFree(GetProcessHeap(), 0, buf);
235 static void testGetIfTable(void)
237 if (pGetIfTable) {
238 DWORD apiReturn;
239 ULONG dwSize = 0;
241 apiReturn = pGetIfTable(NULL, NULL, FALSE);
242 if (apiReturn == ERROR_NOT_SUPPORTED) {
243 skip("GetIfTable is not supported\n");
244 return;
246 ok(apiReturn == ERROR_INVALID_PARAMETER,
247 "GetIfTable(NULL, NULL, FALSE) returned %d, expected ERROR_INVALID_PARAMETER\n",
248 apiReturn);
249 apiReturn = pGetIfTable(NULL, &dwSize, FALSE);
250 ok(apiReturn == ERROR_INSUFFICIENT_BUFFER,
251 "GetIfTable(NULL, &dwSize, FALSE) returned %d, expected ERROR_INSUFFICIENT_BUFFER\n",
252 apiReturn);
253 if (apiReturn == ERROR_INSUFFICIENT_BUFFER) {
254 PMIB_IFTABLE buf = HeapAlloc(GetProcessHeap(), 0, dwSize);
256 apiReturn = pGetIfTable(buf, &dwSize, FALSE);
257 ok(apiReturn == NO_ERROR,
258 "GetIfTable(buf, &dwSize, FALSE) returned %d, expected NO_ERROR\n\n",
259 apiReturn);
261 if (apiReturn == NO_ERROR && winetest_debug > 1)
263 DWORD i, j;
264 char name[MAX_INTERFACE_NAME_LEN];
266 trace( "interface table: %u entries\n", buf->dwNumEntries );
267 for (i = 0; i < buf->dwNumEntries; i++)
269 MIB_IFROW *row = &buf->table[i];
270 WideCharToMultiByte( CP_ACP, 0, row->wszName, -1, name, MAX_INTERFACE_NAME_LEN, NULL, NULL );
271 trace( "%u: '%s' type %u mtu %u speed %u phys",
272 row->dwIndex, name, row->dwType, row->dwMtu, row->dwSpeed );
273 for (j = 0; j < row->dwPhysAddrLen; j++)
274 printf( " %02x", row->bPhysAddr[j] );
275 printf( "\n" );
276 trace( " in: bytes %u upkts %u nupkts %u disc %u err %u unk %u\n",
277 row->dwInOctets, row->dwInUcastPkts, row->dwInNUcastPkts,
278 row->dwInDiscards, row->dwInErrors, row->dwInUnknownProtos );
279 trace( " out: bytes %u upkts %u nupkts %u disc %u err %u\n",
280 row->dwOutOctets, row->dwOutUcastPkts, row->dwOutNUcastPkts,
281 row->dwOutDiscards, row->dwOutErrors );
284 HeapFree(GetProcessHeap(), 0, buf);
289 static void testGetIpForwardTable(void)
291 if (pGetIpForwardTable) {
292 DWORD apiReturn;
293 ULONG dwSize = 0;
295 apiReturn = pGetIpForwardTable(NULL, NULL, FALSE);
296 if (apiReturn == ERROR_NOT_SUPPORTED) {
297 skip("GetIpForwardTable is not supported\n");
298 return;
300 ok(apiReturn == ERROR_INVALID_PARAMETER,
301 "GetIpForwardTable(NULL, NULL, FALSE) returned %d, expected ERROR_INVALID_PARAMETER\n",
302 apiReturn);
303 apiReturn = pGetIpForwardTable(NULL, &dwSize, FALSE);
304 ok(apiReturn == ERROR_INSUFFICIENT_BUFFER,
305 "GetIpForwardTable(NULL, &dwSize, FALSE) returned %d, expected ERROR_INSUFFICIENT_BUFFER\n",
306 apiReturn);
307 if (apiReturn == ERROR_INSUFFICIENT_BUFFER) {
308 PMIB_IPFORWARDTABLE buf = HeapAlloc(GetProcessHeap(), 0, dwSize);
310 apiReturn = pGetIpForwardTable(buf, &dwSize, FALSE);
311 ok(apiReturn == NO_ERROR,
312 "GetIpForwardTable(buf, &dwSize, FALSE) returned %d, expected NO_ERROR\n",
313 apiReturn);
315 if (apiReturn == NO_ERROR && winetest_debug > 1)
317 DWORD i;
319 trace( "IP forward table: %u entries\n", buf->dwNumEntries );
320 for (i = 0; i < buf->dwNumEntries; i++)
322 char buffer[100];
323 sprintf( buffer, "dest %s", ntoa( buf->table[i].dwForwardDest ));
324 sprintf( buffer + strlen(buffer), " mask %s", ntoa( buf->table[i].dwForwardMask ));
325 trace( "%u: %s gw %s if %u type %u\n", i, buffer,
326 ntoa( buf->table[i].dwForwardNextHop ),
327 buf->table[i].dwForwardIfIndex, U1(buf->table[i]).dwForwardType );
330 HeapFree(GetProcessHeap(), 0, buf);
335 static void testGetIpNetTable(void)
337 if (pGetIpNetTable) {
338 DWORD apiReturn;
339 ULONG dwSize = 0;
341 apiReturn = pGetIpNetTable(NULL, NULL, FALSE);
342 if (apiReturn == ERROR_NOT_SUPPORTED) {
343 skip("GetIpNetTable is not supported\n");
344 return;
346 ok(apiReturn == ERROR_INVALID_PARAMETER,
347 "GetIpNetTable(NULL, NULL, FALSE) returned %d, expected ERROR_INVALID_PARAMETER\n",
348 apiReturn);
349 apiReturn = pGetIpNetTable(NULL, &dwSize, FALSE);
350 ok(apiReturn == ERROR_NO_DATA || apiReturn == ERROR_INSUFFICIENT_BUFFER,
351 "GetIpNetTable(NULL, &dwSize, FALSE) returned %d, expected ERROR_NO_DATA or ERROR_INSUFFICIENT_BUFFER\n",
352 apiReturn);
353 if (apiReturn == ERROR_NO_DATA)
354 ; /* empty ARP table's okay */
355 else if (apiReturn == ERROR_INSUFFICIENT_BUFFER) {
356 PMIB_IPNETTABLE buf = HeapAlloc(GetProcessHeap(), 0, dwSize);
358 apiReturn = pGetIpNetTable(buf, &dwSize, FALSE);
359 ok(apiReturn == NO_ERROR ||
360 apiReturn == ERROR_NO_DATA, /* empty ARP table's okay */
361 "GetIpNetTable(buf, &dwSize, FALSE) returned %d, expected NO_ERROR\n",
362 apiReturn);
364 if (apiReturn == NO_ERROR && winetest_debug > 1)
366 DWORD i, j;
368 trace( "IP net table: %u entries\n", buf->dwNumEntries );
369 for (i = 0; i < buf->dwNumEntries; i++)
371 trace( "%u: idx %u type %u addr %s phys",
372 i, buf->table[i].dwIndex, U(buf->table[i]).dwType, ntoa( buf->table[i].dwAddr ));
373 for (j = 0; j < buf->table[i].dwPhysAddrLen; j++)
374 printf( " %02x", buf->table[i].bPhysAddr[j] );
375 printf( "\n" );
378 HeapFree(GetProcessHeap(), 0, buf);
383 static void testGetIcmpStatistics(void)
385 if (pGetIcmpStatistics) {
386 DWORD apiReturn;
387 MIB_ICMP stats;
389 /* Crashes on Vista */
390 if (0) {
391 apiReturn = pGetIcmpStatistics(NULL);
392 if (apiReturn == ERROR_NOT_SUPPORTED)
393 return;
394 ok(apiReturn == ERROR_INVALID_PARAMETER,
395 "GetIcmpStatistics(NULL) returned %d, expected ERROR_INVALID_PARAMETER\n",
396 apiReturn);
399 apiReturn = pGetIcmpStatistics(&stats);
400 if (apiReturn == ERROR_NOT_SUPPORTED)
402 skip("GetIcmpStatistics is not supported\n");
403 return;
405 ok(apiReturn == NO_ERROR,
406 "GetIcmpStatistics returned %d, expected NO_ERROR\n", apiReturn);
407 if (apiReturn == NO_ERROR && winetest_debug > 1)
409 trace( "ICMP stats: %8s %8s\n", "in", "out" );
410 trace( " dwMsgs: %8u %8u\n", stats.stats.icmpInStats.dwMsgs, stats.stats.icmpOutStats.dwMsgs );
411 trace( " dwErrors: %8u %8u\n", stats.stats.icmpInStats.dwErrors, stats.stats.icmpOutStats.dwErrors );
412 trace( " dwDestUnreachs: %8u %8u\n", stats.stats.icmpInStats.dwDestUnreachs, stats.stats.icmpOutStats.dwDestUnreachs );
413 trace( " dwTimeExcds: %8u %8u\n", stats.stats.icmpInStats.dwTimeExcds, stats.stats.icmpOutStats.dwTimeExcds );
414 trace( " dwParmProbs: %8u %8u\n", stats.stats.icmpInStats.dwParmProbs, stats.stats.icmpOutStats.dwParmProbs );
415 trace( " dwSrcQuenchs: %8u %8u\n", stats.stats.icmpInStats.dwSrcQuenchs, stats.stats.icmpOutStats.dwSrcQuenchs );
416 trace( " dwRedirects: %8u %8u\n", stats.stats.icmpInStats.dwRedirects, stats.stats.icmpOutStats.dwRedirects );
417 trace( " dwEchos: %8u %8u\n", stats.stats.icmpInStats.dwEchos, stats.stats.icmpOutStats.dwEchos );
418 trace( " dwEchoReps: %8u %8u\n", stats.stats.icmpInStats.dwEchoReps, stats.stats.icmpOutStats.dwEchoReps );
419 trace( " dwTimestamps: %8u %8u\n", stats.stats.icmpInStats.dwTimestamps, stats.stats.icmpOutStats.dwTimestamps );
420 trace( " dwTimestampReps: %8u %8u\n", stats.stats.icmpInStats.dwTimestampReps, stats.stats.icmpOutStats.dwTimestampReps );
421 trace( " dwAddrMasks: %8u %8u\n", stats.stats.icmpInStats.dwAddrMasks, stats.stats.icmpOutStats.dwAddrMasks );
422 trace( " dwAddrMaskReps: %8u %8u\n", stats.stats.icmpInStats.dwAddrMaskReps, stats.stats.icmpOutStats.dwAddrMaskReps );
427 static void testGetIpStatistics(void)
429 if (pGetIpStatistics) {
430 DWORD apiReturn;
431 MIB_IPSTATS stats;
433 apiReturn = pGetIpStatistics(NULL);
434 if (apiReturn == ERROR_NOT_SUPPORTED) {
435 skip("GetIpStatistics is not supported\n");
436 return;
438 ok(apiReturn == ERROR_INVALID_PARAMETER,
439 "GetIpStatistics(NULL) returned %d, expected ERROR_INVALID_PARAMETER\n",
440 apiReturn);
441 apiReturn = pGetIpStatistics(&stats);
442 ok(apiReturn == NO_ERROR,
443 "GetIpStatistics returned %d, expected NO_ERROR\n", apiReturn);
444 if (apiReturn == NO_ERROR && winetest_debug > 1)
446 trace( "IP stats:\n" );
447 trace( " dwForwarding: %u\n", U(stats).dwForwarding );
448 trace( " dwDefaultTTL: %u\n", stats.dwDefaultTTL );
449 trace( " dwInReceives: %u\n", stats.dwInReceives );
450 trace( " dwInHdrErrors: %u\n", stats.dwInHdrErrors );
451 trace( " dwInAddrErrors: %u\n", stats.dwInAddrErrors );
452 trace( " dwForwDatagrams: %u\n", stats.dwForwDatagrams );
453 trace( " dwInUnknownProtos: %u\n", stats.dwInUnknownProtos );
454 trace( " dwInDiscards: %u\n", stats.dwInDiscards );
455 trace( " dwInDelivers: %u\n", stats.dwInDelivers );
456 trace( " dwOutRequests: %u\n", stats.dwOutRequests );
457 trace( " dwRoutingDiscards: %u\n", stats.dwRoutingDiscards );
458 trace( " dwOutDiscards: %u\n", stats.dwOutDiscards );
459 trace( " dwOutNoRoutes: %u\n", stats.dwOutNoRoutes );
460 trace( " dwReasmTimeout: %u\n", stats.dwReasmTimeout );
461 trace( " dwReasmReqds: %u\n", stats.dwReasmReqds );
462 trace( " dwReasmOks: %u\n", stats.dwReasmOks );
463 trace( " dwReasmFails: %u\n", stats.dwReasmFails );
464 trace( " dwFragOks: %u\n", stats.dwFragOks );
465 trace( " dwFragFails: %u\n", stats.dwFragFails );
466 trace( " dwFragCreates: %u\n", stats.dwFragCreates );
467 trace( " dwNumIf: %u\n", stats.dwNumIf );
468 trace( " dwNumAddr: %u\n", stats.dwNumAddr );
469 trace( " dwNumRoutes: %u\n", stats.dwNumRoutes );
474 static void testGetTcpStatistics(void)
476 if (pGetTcpStatistics) {
477 DWORD apiReturn;
478 MIB_TCPSTATS stats;
480 apiReturn = pGetTcpStatistics(NULL);
481 if (apiReturn == ERROR_NOT_SUPPORTED) {
482 skip("GetTcpStatistics is not supported\n");
483 return;
485 ok(apiReturn == ERROR_INVALID_PARAMETER,
486 "GetTcpStatistics(NULL) returned %d, expected ERROR_INVALID_PARAMETER\n",
487 apiReturn);
488 apiReturn = pGetTcpStatistics(&stats);
489 ok(apiReturn == NO_ERROR,
490 "GetTcpStatistics returned %d, expected NO_ERROR\n", apiReturn);
491 if (apiReturn == NO_ERROR && winetest_debug > 1)
493 trace( "TCP stats:\n" );
494 trace( " dwRtoAlgorithm: %u\n", U(stats).dwRtoAlgorithm );
495 trace( " dwRtoMin: %u\n", stats.dwRtoMin );
496 trace( " dwRtoMax: %u\n", stats.dwRtoMax );
497 trace( " dwMaxConn: %u\n", stats.dwMaxConn );
498 trace( " dwActiveOpens: %u\n", stats.dwActiveOpens );
499 trace( " dwPassiveOpens: %u\n", stats.dwPassiveOpens );
500 trace( " dwAttemptFails: %u\n", stats.dwAttemptFails );
501 trace( " dwEstabResets: %u\n", stats.dwEstabResets );
502 trace( " dwCurrEstab: %u\n", stats.dwCurrEstab );
503 trace( " dwInSegs: %u\n", stats.dwInSegs );
504 trace( " dwOutSegs: %u\n", stats.dwOutSegs );
505 trace( " dwRetransSegs: %u\n", stats.dwRetransSegs );
506 trace( " dwInErrs: %u\n", stats.dwInErrs );
507 trace( " dwOutRsts: %u\n", stats.dwOutRsts );
508 trace( " dwNumConns: %u\n", stats.dwNumConns );
513 static void testGetUdpStatistics(void)
515 if (pGetUdpStatistics) {
516 DWORD apiReturn;
517 MIB_UDPSTATS stats;
519 apiReturn = pGetUdpStatistics(NULL);
520 if (apiReturn == ERROR_NOT_SUPPORTED) {
521 skip("GetUdpStatistics is not supported\n");
522 return;
524 ok(apiReturn == ERROR_INVALID_PARAMETER,
525 "GetUdpStatistics(NULL) returned %d, expected ERROR_INVALID_PARAMETER\n",
526 apiReturn);
527 apiReturn = pGetUdpStatistics(&stats);
528 ok(apiReturn == NO_ERROR,
529 "GetUdpStatistics returned %d, expected NO_ERROR\n", apiReturn);
530 if (apiReturn == NO_ERROR && winetest_debug > 1)
532 trace( "UDP stats:\n" );
533 trace( " dwInDatagrams: %u\n", stats.dwInDatagrams );
534 trace( " dwNoPorts: %u\n", stats.dwNoPorts );
535 trace( " dwInErrors: %u\n", stats.dwInErrors );
536 trace( " dwOutDatagrams: %u\n", stats.dwOutDatagrams );
537 trace( " dwNumAddrs: %u\n", stats.dwNumAddrs );
542 static void testGetIcmpStatisticsEx(void)
544 DWORD apiReturn;
545 MIB_ICMP_EX stats;
547 if (!pGetIcmpStatisticsEx)
549 win_skip( "GetIcmpStatisticsEx not available\n" );
550 return;
553 /* Crashes on Vista */
554 if (1) {
555 apiReturn = pGetIcmpStatisticsEx(NULL, AF_INET);
556 ok(apiReturn == ERROR_INVALID_PARAMETER,
557 "GetIcmpStatisticsEx(NULL, AF_INET) returned %d, expected ERROR_INVALID_PARAMETER\n", apiReturn);
560 apiReturn = pGetIcmpStatisticsEx(&stats, AF_BAN);
561 ok(apiReturn == ERROR_INVALID_PARAMETER,
562 "GetIcmpStatisticsEx(&stats, AF_BAN) returned %d, expected ERROR_INVALID_PARAMETER\n", apiReturn);
564 apiReturn = pGetIcmpStatisticsEx(&stats, AF_INET);
565 ok(apiReturn == NO_ERROR, "GetIcmpStatisticsEx returned %d, expected NO_ERROR\n", apiReturn);
566 if (apiReturn == NO_ERROR && winetest_debug > 1)
568 INT i;
569 trace( "ICMP IPv4 Ex stats: %8s %8s\n", "in", "out" );
570 trace( " dwMsgs: %8u %8u\n", stats.icmpInStats.dwMsgs, stats.icmpOutStats.dwMsgs );
571 trace( " dwErrors: %8u %8u\n", stats.icmpInStats.dwErrors, stats.icmpOutStats.dwErrors );
572 for (i = 0; i < 256; i++)
573 trace( " rgdwTypeCount[%3i]: %8u %8u\n", i, stats.icmpInStats.rgdwTypeCount[i], stats.icmpOutStats.rgdwTypeCount[i] );
576 apiReturn = pGetIcmpStatisticsEx(&stats, AF_INET6);
577 ok(apiReturn == NO_ERROR || broken(apiReturn == ERROR_NOT_SUPPORTED),
578 "GetIcmpStatisticsEx returned %d, expected NO_ERROR\n", apiReturn);
579 if (apiReturn == NO_ERROR && winetest_debug > 1)
581 INT i;
582 trace( "ICMP IPv6 Ex stats: %8s %8s\n", "in", "out" );
583 trace( " dwMsgs: %8u %8u\n", stats.icmpInStats.dwMsgs, stats.icmpOutStats.dwMsgs );
584 trace( " dwErrors: %8u %8u\n", stats.icmpInStats.dwErrors, stats.icmpOutStats.dwErrors );
585 for (i = 0; i < 256; i++)
586 trace( " rgdwTypeCount[%3i]: %8u %8u\n", i, stats.icmpInStats.rgdwTypeCount[i], stats.icmpOutStats.rgdwTypeCount[i] );
590 static void testGetIpStatisticsEx(void)
592 DWORD apiReturn;
593 MIB_IPSTATS stats;
595 if (!pGetIpStatisticsEx)
597 win_skip( "GetIpStatisticsEx not available\n" );
598 return;
601 apiReturn = pGetIpStatisticsEx(NULL, AF_INET);
602 ok(apiReturn == ERROR_INVALID_PARAMETER,
603 "GetIpStatisticsEx(NULL, AF_INET) returned %d, expected ERROR_INVALID_PARAMETER\n", apiReturn);
605 apiReturn = pGetIpStatisticsEx(&stats, AF_BAN);
606 ok(apiReturn == ERROR_INVALID_PARAMETER,
607 "GetIpStatisticsEx(&stats, AF_BAN) returned %d, expected ERROR_INVALID_PARAMETER\n", apiReturn);
609 apiReturn = pGetIpStatisticsEx(&stats, AF_INET);
610 ok(apiReturn == NO_ERROR, "GetIpStatisticsEx returned %d, expected NO_ERROR\n", apiReturn);
611 if (apiReturn == NO_ERROR && winetest_debug > 1)
613 trace( "IP IPv4 Ex stats:\n" );
614 trace( " dwForwarding: %u\n", U(stats).dwForwarding );
615 trace( " dwDefaultTTL: %u\n", stats.dwDefaultTTL );
616 trace( " dwInReceives: %u\n", stats.dwInReceives );
617 trace( " dwInHdrErrors: %u\n", stats.dwInHdrErrors );
618 trace( " dwInAddrErrors: %u\n", stats.dwInAddrErrors );
619 trace( " dwForwDatagrams: %u\n", stats.dwForwDatagrams );
620 trace( " dwInUnknownProtos: %u\n", stats.dwInUnknownProtos );
621 trace( " dwInDiscards: %u\n", stats.dwInDiscards );
622 trace( " dwInDelivers: %u\n", stats.dwInDelivers );
623 trace( " dwOutRequests: %u\n", stats.dwOutRequests );
624 trace( " dwRoutingDiscards: %u\n", stats.dwRoutingDiscards );
625 trace( " dwOutDiscards: %u\n", stats.dwOutDiscards );
626 trace( " dwOutNoRoutes: %u\n", stats.dwOutNoRoutes );
627 trace( " dwReasmTimeout: %u\n", stats.dwReasmTimeout );
628 trace( " dwReasmReqds: %u\n", stats.dwReasmReqds );
629 trace( " dwReasmOks: %u\n", stats.dwReasmOks );
630 trace( " dwReasmFails: %u\n", stats.dwReasmFails );
631 trace( " dwFragOks: %u\n", stats.dwFragOks );
632 trace( " dwFragFails: %u\n", stats.dwFragFails );
633 trace( " dwFragCreates: %u\n", stats.dwFragCreates );
634 trace( " dwNumIf: %u\n", stats.dwNumIf );
635 trace( " dwNumAddr: %u\n", stats.dwNumAddr );
636 trace( " dwNumRoutes: %u\n", stats.dwNumRoutes );
639 apiReturn = pGetIpStatisticsEx(&stats, AF_INET6);
640 ok(apiReturn == NO_ERROR || broken(apiReturn == ERROR_NOT_SUPPORTED),
641 "GetIpStatisticsEx returned %d, expected NO_ERROR\n", apiReturn);
642 if (apiReturn == NO_ERROR && winetest_debug > 1)
644 trace( "IP IPv6 Ex stats:\n" );
645 trace( " dwForwarding: %u\n", U(stats).dwForwarding );
646 trace( " dwDefaultTTL: %u\n", stats.dwDefaultTTL );
647 trace( " dwInReceives: %u\n", stats.dwInReceives );
648 trace( " dwInHdrErrors: %u\n", stats.dwInHdrErrors );
649 trace( " dwInAddrErrors: %u\n", stats.dwInAddrErrors );
650 trace( " dwForwDatagrams: %u\n", stats.dwForwDatagrams );
651 trace( " dwInUnknownProtos: %u\n", stats.dwInUnknownProtos );
652 trace( " dwInDiscards: %u\n", stats.dwInDiscards );
653 trace( " dwInDelivers: %u\n", stats.dwInDelivers );
654 trace( " dwOutRequests: %u\n", stats.dwOutRequests );
655 trace( " dwRoutingDiscards: %u\n", stats.dwRoutingDiscards );
656 trace( " dwOutDiscards: %u\n", stats.dwOutDiscards );
657 trace( " dwOutNoRoutes: %u\n", stats.dwOutNoRoutes );
658 trace( " dwReasmTimeout: %u\n", stats.dwReasmTimeout );
659 trace( " dwReasmReqds: %u\n", stats.dwReasmReqds );
660 trace( " dwReasmOks: %u\n", stats.dwReasmOks );
661 trace( " dwReasmFails: %u\n", stats.dwReasmFails );
662 trace( " dwFragOks: %u\n", stats.dwFragOks );
663 trace( " dwFragFails: %u\n", stats.dwFragFails );
664 trace( " dwFragCreates: %u\n", stats.dwFragCreates );
665 trace( " dwNumIf: %u\n", stats.dwNumIf );
666 trace( " dwNumAddr: %u\n", stats.dwNumAddr );
667 trace( " dwNumRoutes: %u\n", stats.dwNumRoutes );
671 static void testGetTcpStatisticsEx(void)
673 DWORD apiReturn;
674 MIB_TCPSTATS stats;
676 if (!pGetTcpStatisticsEx)
678 win_skip( "GetTcpStatisticsEx not available\n" );
679 return;
682 apiReturn = pGetTcpStatisticsEx(NULL, AF_INET);
683 ok(apiReturn == ERROR_INVALID_PARAMETER,
684 "GetTcpStatisticsEx(NULL, AF_INET); returned %d, expected ERROR_INVALID_PARAMETER\n", apiReturn);
686 apiReturn = pGetTcpStatisticsEx(&stats, AF_BAN);
687 ok(apiReturn == ERROR_INVALID_PARAMETER || apiReturn == ERROR_NOT_SUPPORTED,
688 "GetTcpStatisticsEx(&stats, AF_BAN) returned %d, expected ERROR_INVALID_PARAMETER\n", apiReturn);
690 apiReturn = pGetTcpStatisticsEx(&stats, AF_INET);
691 ok(apiReturn == NO_ERROR, "GetTcpStatisticsEx returned %d, expected NO_ERROR\n", apiReturn);
692 if (apiReturn == NO_ERROR && winetest_debug > 1)
694 trace( "TCP IPv4 Ex stats:\n" );
695 trace( " dwRtoAlgorithm: %u\n", U(stats).dwRtoAlgorithm );
696 trace( " dwRtoMin: %u\n", stats.dwRtoMin );
697 trace( " dwRtoMax: %u\n", stats.dwRtoMax );
698 trace( " dwMaxConn: %u\n", stats.dwMaxConn );
699 trace( " dwActiveOpens: %u\n", stats.dwActiveOpens );
700 trace( " dwPassiveOpens: %u\n", stats.dwPassiveOpens );
701 trace( " dwAttemptFails: %u\n", stats.dwAttemptFails );
702 trace( " dwEstabResets: %u\n", stats.dwEstabResets );
703 trace( " dwCurrEstab: %u\n", stats.dwCurrEstab );
704 trace( " dwInSegs: %u\n", stats.dwInSegs );
705 trace( " dwOutSegs: %u\n", stats.dwOutSegs );
706 trace( " dwRetransSegs: %u\n", stats.dwRetransSegs );
707 trace( " dwInErrs: %u\n", stats.dwInErrs );
708 trace( " dwOutRsts: %u\n", stats.dwOutRsts );
709 trace( " dwNumConns: %u\n", stats.dwNumConns );
712 apiReturn = pGetTcpStatisticsEx(&stats, AF_INET6);
713 todo_wine ok(apiReturn == NO_ERROR || broken(apiReturn == ERROR_NOT_SUPPORTED),
714 "GetTcpStatisticsEx returned %d, expected NO_ERROR\n", apiReturn);
715 if (apiReturn == NO_ERROR && winetest_debug > 1)
717 trace( "TCP IPv6 Ex stats:\n" );
718 trace( " dwRtoAlgorithm: %u\n", U(stats).dwRtoAlgorithm );
719 trace( " dwRtoMin: %u\n", stats.dwRtoMin );
720 trace( " dwRtoMax: %u\n", stats.dwRtoMax );
721 trace( " dwMaxConn: %u\n", stats.dwMaxConn );
722 trace( " dwActiveOpens: %u\n", stats.dwActiveOpens );
723 trace( " dwPassiveOpens: %u\n", stats.dwPassiveOpens );
724 trace( " dwAttemptFails: %u\n", stats.dwAttemptFails );
725 trace( " dwEstabResets: %u\n", stats.dwEstabResets );
726 trace( " dwCurrEstab: %u\n", stats.dwCurrEstab );
727 trace( " dwInSegs: %u\n", stats.dwInSegs );
728 trace( " dwOutSegs: %u\n", stats.dwOutSegs );
729 trace( " dwRetransSegs: %u\n", stats.dwRetransSegs );
730 trace( " dwInErrs: %u\n", stats.dwInErrs );
731 trace( " dwOutRsts: %u\n", stats.dwOutRsts );
732 trace( " dwNumConns: %u\n", stats.dwNumConns );
736 static void testGetUdpStatisticsEx(void)
738 DWORD apiReturn;
739 MIB_UDPSTATS stats;
741 if (!pGetUdpStatisticsEx)
743 win_skip( "GetUdpStatisticsEx not available\n" );
744 return;
747 apiReturn = pGetUdpStatisticsEx(NULL, AF_INET);
748 ok(apiReturn == ERROR_INVALID_PARAMETER,
749 "GetUdpStatisticsEx(NULL, AF_INET); returned %d, expected ERROR_INVALID_PARAMETER\n", apiReturn);
751 apiReturn = pGetUdpStatisticsEx(&stats, AF_BAN);
752 ok(apiReturn == ERROR_INVALID_PARAMETER || apiReturn == ERROR_NOT_SUPPORTED,
753 "GetUdpStatisticsEx(&stats, AF_BAN) returned %d, expected ERROR_INVALID_PARAMETER\n", apiReturn);
755 apiReturn = pGetUdpStatisticsEx(&stats, AF_INET);
756 ok(apiReturn == NO_ERROR, "GetUdpStatisticsEx returned %d, expected NO_ERROR\n", apiReturn);
757 if (apiReturn == NO_ERROR && winetest_debug > 1)
759 trace( "UDP IPv4 Ex stats:\n" );
760 trace( " dwInDatagrams: %u\n", stats.dwInDatagrams );
761 trace( " dwNoPorts: %u\n", stats.dwNoPorts );
762 trace( " dwInErrors: %u\n", stats.dwInErrors );
763 trace( " dwOutDatagrams: %u\n", stats.dwOutDatagrams );
764 trace( " dwNumAddrs: %u\n", stats.dwNumAddrs );
767 apiReturn = pGetUdpStatisticsEx(&stats, AF_INET6);
768 ok(apiReturn == NO_ERROR || broken(apiReturn == ERROR_NOT_SUPPORTED),
769 "GetUdpStatisticsEx returned %d, expected NO_ERROR\n", apiReturn);
770 if (apiReturn == NO_ERROR && winetest_debug > 1)
772 trace( "UDP IPv6 Ex stats:\n" );
773 trace( " dwInDatagrams: %u\n", stats.dwInDatagrams );
774 trace( " dwNoPorts: %u\n", stats.dwNoPorts );
775 trace( " dwInErrors: %u\n", stats.dwInErrors );
776 trace( " dwOutDatagrams: %u\n", stats.dwOutDatagrams );
777 trace( " dwNumAddrs: %u\n", stats.dwNumAddrs );
781 static void testGetTcpTable(void)
783 if (pGetTcpTable) {
784 DWORD apiReturn;
785 ULONG dwSize = 0;
787 apiReturn = pGetTcpTable(NULL, &dwSize, FALSE);
788 if (apiReturn == ERROR_NOT_SUPPORTED) {
789 skip("GetTcpTable is not supported\n");
790 return;
792 ok(apiReturn == ERROR_INSUFFICIENT_BUFFER ||
793 broken(apiReturn == ERROR_NO_DATA), /* win95 */
794 "GetTcpTable(NULL, &dwSize, FALSE) returned %d, expected ERROR_INSUFFICIENT_BUFFER\n",
795 apiReturn);
796 if (apiReturn == ERROR_INSUFFICIENT_BUFFER) {
797 PMIB_TCPTABLE buf = HeapAlloc(GetProcessHeap(), 0, dwSize);
799 apiReturn = pGetTcpTable(buf, &dwSize, FALSE);
800 ok(apiReturn == NO_ERROR,
801 "GetTcpTable(buf, &dwSize, FALSE) returned %d, expected NO_ERROR\n",
802 apiReturn);
804 if (apiReturn == NO_ERROR && winetest_debug > 1)
806 DWORD i;
807 trace( "TCP table: %u entries\n", buf->dwNumEntries );
808 for (i = 0; i < buf->dwNumEntries; i++)
810 char buffer[40];
811 sprintf( buffer, "local %s:%u",
812 ntoa(buf->table[i].dwLocalAddr), ntohs(buf->table[i].dwLocalPort) );
813 trace( "%u: %s remote %s:%u state %u\n",
814 i, buffer, ntoa( buf->table[i].dwRemoteAddr ),
815 ntohs(buf->table[i].dwRemotePort), U(buf->table[i]).dwState );
818 HeapFree(GetProcessHeap(), 0, buf);
823 static void testGetUdpTable(void)
825 if (pGetUdpTable) {
826 DWORD apiReturn;
827 ULONG dwSize = 0;
829 apiReturn = pGetUdpTable(NULL, &dwSize, FALSE);
830 if (apiReturn == ERROR_NOT_SUPPORTED) {
831 skip("GetUdpTable is not supported\n");
832 return;
834 ok(apiReturn == ERROR_INSUFFICIENT_BUFFER,
835 "GetUdpTable(NULL, &dwSize, FALSE) returned %d, expected ERROR_INSUFFICIENT_BUFFER\n",
836 apiReturn);
837 if (apiReturn == ERROR_INSUFFICIENT_BUFFER) {
838 PMIB_UDPTABLE buf = HeapAlloc(GetProcessHeap(), 0, dwSize);
840 apiReturn = pGetUdpTable(buf, &dwSize, FALSE);
841 ok(apiReturn == NO_ERROR,
842 "GetUdpTable(buf, &dwSize, FALSE) returned %d, expected NO_ERROR\n",
843 apiReturn);
845 if (apiReturn == NO_ERROR && winetest_debug > 1)
847 DWORD i;
848 trace( "UDP table: %u entries\n", buf->dwNumEntries );
849 for (i = 0; i < buf->dwNumEntries; i++)
850 trace( "%u: %s:%u\n",
851 i, ntoa( buf->table[i].dwLocalAddr ), ntohs(buf->table[i].dwLocalPort) );
853 HeapFree(GetProcessHeap(), 0, buf);
858 static void testSetTcpEntry(void)
860 DWORD ret;
861 MIB_TCPROW row;
863 memset(&row, 0, sizeof(row));
864 if(0) /* This test crashes in OS >= VISTA */
866 ret = pSetTcpEntry(NULL);
867 ok( ret == ERROR_INVALID_PARAMETER, "got %u, expected %u\n", ret, ERROR_INVALID_PARAMETER);
870 ret = pSetTcpEntry(&row);
871 if (ret == ERROR_NETWORK_ACCESS_DENIED)
873 win_skip("SetTcpEntry failed with access error. Skipping test.\n");
874 return;
876 todo_wine ok( ret == ERROR_INVALID_PARAMETER, "got %u, expected %u\n", ret, ERROR_INVALID_PARAMETER);
878 U(row).dwState = MIB_TCP_STATE_DELETE_TCB;
879 ret = pSetTcpEntry(&row);
880 todo_wine ok( ret == ERROR_MR_MID_NOT_FOUND || broken(ret == ERROR_INVALID_PARAMETER),
881 "got %u, expected %u\n", ret, ERROR_MR_MID_NOT_FOUND);
884 static void testIcmpSendEcho(void)
886 HANDLE icmp;
887 char senddata[32], replydata[sizeof(senddata) + sizeof(ICMP_ECHO_REPLY)];
888 DWORD ret, error, replysz = sizeof(replydata);
889 IPAddr address;
891 if (!pIcmpSendEcho || !pIcmpCreateFile)
893 win_skip( "IcmpSendEcho or IcmpCreateFile not available\n" );
894 return;
896 memset(senddata, 0, sizeof(senddata));
898 address = htonl(INADDR_LOOPBACK);
899 SetLastError(0xdeadbeef);
900 ret = pIcmpSendEcho(INVALID_HANDLE_VALUE, address, senddata, sizeof(senddata), NULL, replydata, replysz, 1000);
901 error = GetLastError();
902 ok (!ret, "IcmpSendEcho succeeded unexpectedly\n");
903 todo_wine
904 ok (error == ERROR_INVALID_PARAMETER
905 || broken(error == ERROR_INVALID_HANDLE) /* <= 2003 */,
906 "expected 87, got %d\n", error);
908 icmp = pIcmpCreateFile();
909 if (icmp == INVALID_HANDLE_VALUE)
911 error = GetLastError();
912 if (error == ERROR_ACCESS_DENIED)
914 skip ("ICMP is not available.\n");
915 return;
918 ok (icmp != INVALID_HANDLE_VALUE, "IcmpCreateFile failed unexpectedly with error %d\n", GetLastError());
920 address = 0;
921 SetLastError(0xdeadbeef);
922 ret = pIcmpSendEcho(icmp, address, senddata, sizeof(senddata), NULL, replydata, replysz, 1000);
923 error = GetLastError();
924 ok (!ret, "IcmpSendEcho succeeded unexpectedly\n");
925 ok (error == ERROR_INVALID_NETNAME
926 || broken(error == IP_BAD_DESTINATION) /* <= 2003 */,
927 "expected 1214, got %d\n", error);
929 address = htonl(INADDR_LOOPBACK);
930 if (0) /* crashes in XP */
932 ret = pIcmpSendEcho(icmp, address, NULL, sizeof(senddata), NULL, replydata, replysz, 1000);
933 ok (!ret, "IcmpSendEcho succeeded unexpectedly\n");
936 SetLastError(0xdeadbeef);
937 ret = pIcmpSendEcho(icmp, address, senddata, 0, NULL, replydata, replysz, 1000);
938 error = GetLastError();
939 ok (ret, "IcmpSendEcho failed unexpectedly with error %d\n", error);
941 SetLastError(0xdeadbeef);
942 ret = pIcmpSendEcho(icmp, address, NULL, 0, NULL, replydata, replysz, 1000);
943 error = GetLastError();
944 ok (ret, "IcmpSendEcho failed unexpectedly with error %d\n", error);
946 if (0) /* crashes in wine, remove IF when fixed */
948 SetLastError(0xdeadbeef);
949 ret = pIcmpSendEcho(icmp, address, senddata, sizeof(senddata), NULL, NULL, replysz, 1000);
950 error = GetLastError();
951 ok (!ret, "IcmpSendEcho succeeded unexpectedly\n");
952 ok (error == ERROR_INVALID_PARAMETER, "expected 87, got %d\n", error);
955 SetLastError(0xdeadbeef);
956 ret = pIcmpSendEcho(icmp, address, senddata, sizeof(senddata), NULL, replydata, 0, 1000);
957 error = GetLastError();
958 ok (!ret, "IcmpSendEcho succeeded unexpectedly\n");
959 todo_wine
960 ok (error == ERROR_INVALID_PARAMETER
961 || broken(error == ERROR_INSUFFICIENT_BUFFER) /* <= 2003 */,
962 "expected 87, got %d\n", error);
964 SetLastError(0xdeadbeef);
965 ret = pIcmpSendEcho(icmp, address, senddata, sizeof(senddata), NULL, NULL, 0, 1000);
966 error = GetLastError();
967 ok (!ret, "IcmpSendEcho succeeded unexpectedly\n");
968 todo_wine
969 ok (error == ERROR_INVALID_PARAMETER
970 || broken(error == ERROR_INSUFFICIENT_BUFFER) /* <= 2003 */,
971 "expected 87, got %d\n", error);
973 SetLastError(0xdeadbeef);
974 replysz = sizeof(replydata) - 1;
975 ret = pIcmpSendEcho(icmp, address, senddata, sizeof(senddata), NULL, replydata, replysz, 1000);
976 error = GetLastError();
977 todo_wine {
978 ok (!ret, "IcmpSendEcho succeeded unexpectedly\n");
979 ok (error == IP_GENERAL_FAILURE
980 || broken(error == IP_BUF_TOO_SMALL) /* <= 2003 */,
981 "expected 11050, got %d\n", error);
984 SetLastError(0xdeadbeef);
985 replysz = sizeof(ICMP_ECHO_REPLY);
986 ret = pIcmpSendEcho(icmp, address, senddata, 0, NULL, replydata, replysz, 1000);
987 error = GetLastError();
988 todo_wine
989 ok (ret, "IcmpSendEcho failed unexpectedly with error %d\n", error);
991 SetLastError(0xdeadbeef);
992 replysz = sizeof(ICMP_ECHO_REPLY) + ICMP_MINLEN;
993 ret = pIcmpSendEcho(icmp, address, senddata, ICMP_MINLEN, NULL, replydata, replysz, 1000);
994 error = GetLastError();
995 todo_wine
996 ok (ret, "IcmpSendEcho failed unexpectedly with error %d\n", error);
998 SetLastError(0xdeadbeef);
999 replysz = sizeof(ICMP_ECHO_REPLY) + ICMP_MINLEN;
1000 ret = pIcmpSendEcho(icmp, address, senddata, ICMP_MINLEN + 1, NULL, replydata, replysz, 1000);
1001 error = GetLastError();
1002 ok (!ret, "IcmpSendEcho succeeded unexpectedly\n");
1003 todo_wine
1004 ok (error == IP_GENERAL_FAILURE
1005 || broken(error == IP_BUF_TOO_SMALL) /* <= 2003 */,
1006 "expected 11050, got %d\n", error);
1008 SetLastError(0xdeadbeef);
1009 ret = pIcmpSendEcho(icmp, address, senddata, ICMP_MINLEN, NULL, replydata, replysz - 1, 1000);
1010 error = GetLastError();
1011 ok (!ret, "IcmpSendEcho succeeded unexpectedly\n");
1012 todo_wine
1013 ok (error == IP_GENERAL_FAILURE
1014 || broken(error == IP_BUF_TOO_SMALL) /* <= 2003 */,
1015 "expected 11050, got %d\n", error);
1017 /* in windows >= vista the timeout can't be invalid */
1018 SetLastError(0xdeadbeef);
1019 replysz = sizeof(replydata);
1020 ret = pIcmpSendEcho(icmp, address, senddata, sizeof(senddata), NULL, replydata, replysz, 0);
1021 error = GetLastError();
1022 if (!ret) ok(error == ERROR_INVALID_PARAMETER, "expected 87, got %d\n", error);
1024 SetLastError(0xdeadbeef);
1025 ret = pIcmpSendEcho(icmp, address, senddata, sizeof(senddata), NULL, replydata, replysz, -1);
1026 error = GetLastError();
1027 if (!ret) ok(error == ERROR_INVALID_PARAMETER, "expected 87, got %d\n", error);
1029 /* real ping test */
1030 SetLastError(0xdeadbeef);
1031 address = htonl(INADDR_LOOPBACK);
1032 ret = pIcmpSendEcho(icmp, address, senddata, sizeof(senddata), NULL, replydata, replysz, 1000);
1033 error = GetLastError();
1034 if (ret)
1036 PICMP_ECHO_REPLY pong = (PICMP_ECHO_REPLY) replydata;
1037 trace ("ping roundtrip: %u ms\n", pong->RoundTripTime);
1039 else
1041 skip ("Failed to ping with error %d, is lo interface down?.\n", error);
1046 still-to-be-tested NT4-onward functions:
1047 CreateIpForwardEntry
1048 DeleteIpForwardEntry
1049 CreateIpNetEntry
1050 DeleteIpNetEntry
1051 GetFriendlyIfIndex
1052 GetRTTAndHopCount
1053 SetIfEntry
1054 SetIpForwardEntry
1055 SetIpNetEntry
1056 SetIpStatistics
1057 SetIpTTL
1059 static void testWinNT4Functions(void)
1061 testGetNumberOfInterfaces();
1062 testGetIpAddrTable();
1063 testGetIfTable();
1064 testGetIpForwardTable();
1065 testGetIpNetTable();
1066 testGetIcmpStatistics();
1067 testGetIpStatistics();
1068 testGetTcpStatistics();
1069 testGetUdpStatistics();
1070 testGetIcmpStatisticsEx();
1071 testGetIpStatisticsEx();
1072 testGetTcpStatisticsEx();
1073 testGetUdpStatisticsEx();
1074 testGetTcpTable();
1075 testGetUdpTable();
1076 testSetTcpEntry();
1077 testIcmpSendEcho();
1080 static void testGetInterfaceInfo(void)
1082 if (pGetInterfaceInfo) {
1083 DWORD apiReturn;
1084 ULONG len = 0;
1086 apiReturn = pGetInterfaceInfo(NULL, NULL);
1087 if (apiReturn == ERROR_NOT_SUPPORTED) {
1088 skip("GetInterfaceInfo is not supported\n");
1089 return;
1091 ok(apiReturn == ERROR_INVALID_PARAMETER,
1092 "GetInterfaceInfo returned %d, expected ERROR_INVALID_PARAMETER\n",
1093 apiReturn);
1094 apiReturn = pGetInterfaceInfo(NULL, &len);
1095 ok(apiReturn == ERROR_INSUFFICIENT_BUFFER,
1096 "GetInterfaceInfo returned %d, expected ERROR_INSUFFICIENT_BUFFER\n",
1097 apiReturn);
1098 if (apiReturn == ERROR_INSUFFICIENT_BUFFER) {
1099 PIP_INTERFACE_INFO buf = HeapAlloc(GetProcessHeap(), 0, len);
1101 apiReturn = pGetInterfaceInfo(buf, &len);
1102 ok(apiReturn == NO_ERROR,
1103 "GetInterfaceInfo(buf, &dwSize) returned %d, expected NO_ERROR\n",
1104 apiReturn);
1105 HeapFree(GetProcessHeap(), 0, buf);
1110 static void testGetAdaptersInfo(void)
1112 if (pGetAdaptersInfo) {
1113 DWORD apiReturn;
1114 ULONG len = 0;
1116 apiReturn = pGetAdaptersInfo(NULL, NULL);
1117 if (apiReturn == ERROR_NOT_SUPPORTED) {
1118 skip("GetAdaptersInfo is not supported\n");
1119 return;
1121 ok(apiReturn == ERROR_INVALID_PARAMETER,
1122 "GetAdaptersInfo returned %d, expected ERROR_INVALID_PARAMETER\n",
1123 apiReturn);
1124 apiReturn = pGetAdaptersInfo(NULL, &len);
1125 ok(apiReturn == ERROR_NO_DATA || apiReturn == ERROR_BUFFER_OVERFLOW,
1126 "GetAdaptersInfo returned %d, expected ERROR_NO_DATA or ERROR_BUFFER_OVERFLOW\n",
1127 apiReturn);
1128 if (apiReturn == ERROR_NO_DATA)
1129 ; /* no adapter's, that's okay */
1130 else if (apiReturn == ERROR_BUFFER_OVERFLOW) {
1131 PIP_ADAPTER_INFO ptr, buf = HeapAlloc(GetProcessHeap(), 0, len);
1133 apiReturn = pGetAdaptersInfo(buf, &len);
1134 ok(apiReturn == NO_ERROR,
1135 "GetAdaptersInfo(buf, &dwSize) returned %d, expected NO_ERROR\n",
1136 apiReturn);
1137 ptr = buf;
1138 while (ptr) {
1139 ok(ptr->IpAddressList.IpAddress.String[0], "A valid IP must be present\n");
1140 ok(ptr->IpAddressList.IpMask.String[0], "A valid mask must be present\n");
1141 trace("Adapter '%s', IP %s, Mask %s\n", ptr->AdapterName,
1142 ptr->IpAddressList.IpAddress.String, ptr->IpAddressList.IpMask.String);
1143 ptr = ptr->Next;
1145 HeapFree(GetProcessHeap(), 0, buf);
1150 static void testGetNetworkParams(void)
1152 if (pGetNetworkParams) {
1153 DWORD apiReturn;
1154 ULONG len = 0;
1156 apiReturn = pGetNetworkParams(NULL, NULL);
1157 if (apiReturn == ERROR_NOT_SUPPORTED) {
1158 skip("GetNetworkParams is not supported\n");
1159 return;
1161 ok(apiReturn == ERROR_INVALID_PARAMETER,
1162 "GetNetworkParams returned %d, expected ERROR_INVALID_PARAMETER\n",
1163 apiReturn);
1164 apiReturn = pGetNetworkParams(NULL, &len);
1165 ok(apiReturn == ERROR_BUFFER_OVERFLOW,
1166 "GetNetworkParams returned %d, expected ERROR_BUFFER_OVERFLOW\n",
1167 apiReturn);
1168 if (apiReturn == ERROR_BUFFER_OVERFLOW) {
1169 PFIXED_INFO buf = HeapAlloc(GetProcessHeap(), 0, len);
1171 apiReturn = pGetNetworkParams(buf, &len);
1172 ok(apiReturn == NO_ERROR,
1173 "GetNetworkParams(buf, &dwSize) returned %d, expected NO_ERROR\n",
1174 apiReturn);
1175 HeapFree(GetProcessHeap(), 0, buf);
1181 still-to-be-tested 98-onward functions:
1182 GetBestInterface
1183 GetBestRoute
1184 IpReleaseAddress
1185 IpRenewAddress
1187 static DWORD CALLBACK testWin98Functions(void *p)
1189 testGetInterfaceInfo();
1190 testGetAdaptersInfo();
1191 testGetNetworkParams();
1192 return 0;
1195 static void testGetPerAdapterInfo(void)
1197 DWORD ret, needed;
1198 void *buffer;
1200 if (!pGetPerAdapterInfo) return;
1201 ret = pGetPerAdapterInfo(1, NULL, NULL);
1202 if (ret == ERROR_NOT_SUPPORTED) {
1203 skip("GetPerAdapterInfo is not supported\n");
1204 return;
1206 ok( ret == ERROR_INVALID_PARAMETER, "got %u instead of ERROR_INVALID_PARAMETER\n", ret );
1207 needed = 0xdeadbeef;
1208 ret = pGetPerAdapterInfo(1, NULL, &needed);
1209 if (ret == ERROR_NO_DATA) return; /* no such adapter */
1210 ok( ret == ERROR_BUFFER_OVERFLOW, "got %u instead of ERROR_BUFFER_OVERFLOW\n", ret );
1211 ok( needed != 0xdeadbeef, "needed not set\n" );
1212 buffer = HeapAlloc( GetProcessHeap(), 0, needed );
1213 ret = pGetPerAdapterInfo(1, buffer, &needed);
1214 ok( ret == NO_ERROR, "got %u instead of NO_ERROR\n", ret );
1215 HeapFree( GetProcessHeap(), 0, buffer );
1218 static void testNotifyAddrChange(void)
1220 DWORD ret, bytes;
1221 OVERLAPPED overlapped;
1222 HANDLE handle;
1223 BOOL success;
1225 if (!pNotifyAddrChange)
1227 win_skip("NotifyAddrChange not present\n");
1228 return;
1230 if (!pCancelIPChangeNotify)
1232 win_skip("CancelIPChangeNotify not present\n");
1233 return;
1236 handle = NULL;
1237 ZeroMemory(&overlapped, sizeof(overlapped));
1238 ret = pNotifyAddrChange(&handle, &overlapped);
1239 if (ret == ERROR_NOT_SUPPORTED)
1241 win_skip("NotifyAddrChange is not supported\n");
1242 return;
1244 ok(ret == ERROR_IO_PENDING, "NotifyAddrChange returned %d, expected ERROR_IO_PENDING\n", ret);
1245 ret = GetLastError();
1246 todo_wine ok(ret == ERROR_IO_PENDING, "GetLastError returned %d, expected ERROR_IO_PENDING\n", ret);
1247 success = pCancelIPChangeNotify(&overlapped);
1248 todo_wine ok(success == TRUE, "CancelIPChangeNotify returned FALSE, expected TRUE\n");
1250 ZeroMemory(&overlapped, sizeof(overlapped));
1251 success = pCancelIPChangeNotify(&overlapped);
1252 ok(success == FALSE, "CancelIPChangeNotify returned TRUE, expected FALSE\n");
1254 handle = NULL;
1255 ZeroMemory(&overlapped, sizeof(overlapped));
1256 overlapped.hEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
1257 ret = pNotifyAddrChange(&handle, &overlapped);
1258 ok(ret == ERROR_IO_PENDING, "NotifyAddrChange returned %d, expected ERROR_IO_PENDING\n", ret);
1259 todo_wine ok(handle != INVALID_HANDLE_VALUE, "NotifyAddrChange returned invalid file handle\n");
1260 success = GetOverlappedResult(handle, &overlapped, &bytes, FALSE);
1261 ok(success == FALSE, "GetOverlappedResult returned TRUE, expected FALSE\n");
1262 ret = GetLastError();
1263 ok(ret == ERROR_IO_INCOMPLETE, "GetLastError returned %d, expected ERROR_IO_INCOMPLETE\n", ret);
1264 success = pCancelIPChangeNotify(&overlapped);
1265 todo_wine ok(success == TRUE, "CancelIPChangeNotify returned FALSE, expected TRUE\n");
1267 if (winetest_interactive)
1269 handle = NULL;
1270 ZeroMemory(&overlapped, sizeof(overlapped));
1271 overlapped.hEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
1272 trace("Testing asynchronous ipv4 address change notification. Please "
1273 "change the ipv4 address of one of your network interfaces\n");
1274 ret = pNotifyAddrChange(&handle, &overlapped);
1275 ok(ret == ERROR_IO_PENDING, "NotifyAddrChange returned %d, expected NO_ERROR\n", ret);
1276 success = GetOverlappedResult(handle, &overlapped, &bytes, TRUE);
1277 ok(success == TRUE, "GetOverlappedResult returned FALSE, expected TRUE\n");
1280 /* test synchronous functionality */
1281 if (winetest_interactive)
1283 trace("Testing synchronous ipv4 address change notification. Please "
1284 "change the ipv4 address of one of your network interfaces\n");
1285 ret = pNotifyAddrChange(NULL, NULL);
1286 todo_wine ok(ret == NO_ERROR, "NotifyAddrChange returned %d, expected NO_ERROR\n", ret);
1291 still-to-be-tested 2K-onward functions:
1292 AddIPAddress
1293 CreateProxyArpEntry
1294 DeleteIPAddress
1295 DeleteProxyArpEntry
1296 EnableRouter
1297 FlushIpNetTable
1298 GetAdapterIndex
1299 NotifyRouteChange + CancelIPChangeNotify
1300 SendARP
1301 UnenableRouter
1303 static void testWin2KFunctions(void)
1305 testGetPerAdapterInfo();
1306 testNotifyAddrChange();
1309 static void test_GetAdaptersAddresses(void)
1311 ULONG ret, size, osize, i;
1312 IP_ADAPTER_ADDRESSES *aa, *ptr;
1313 IP_ADAPTER_UNICAST_ADDRESS *ua;
1315 if (!pGetAdaptersAddresses)
1317 win_skip("GetAdaptersAddresses not present\n");
1318 return;
1321 ret = pGetAdaptersAddresses(AF_UNSPEC, 0, NULL, NULL, NULL);
1322 ok(ret == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER got %u\n", ret);
1324 /* size should be ignored and overwritten if buffer is NULL */
1325 size = 0x7fffffff;
1326 ret = pGetAdaptersAddresses(AF_UNSPEC, 0, NULL, NULL, &size);
1327 ok(ret == ERROR_BUFFER_OVERFLOW, "expected ERROR_BUFFER_OVERFLOW, got %u\n", ret);
1328 if (ret != ERROR_BUFFER_OVERFLOW) return;
1330 ptr = HeapAlloc(GetProcessHeap(), 0, size);
1331 ret = pGetAdaptersAddresses(AF_UNSPEC, 0, NULL, ptr, &size);
1332 ok(!ret, "expected ERROR_SUCCESS got %u\n", ret);
1333 HeapFree(GetProcessHeap(), 0, ptr);
1335 /* higher size must not be changed to lower size */
1336 size *= 2;
1337 osize = size;
1338 ptr = HeapAlloc(GetProcessHeap(), 0, osize);
1339 ret = pGetAdaptersAddresses(AF_UNSPEC, 0, NULL, ptr, &osize);
1340 ok(!ret, "expected ERROR_SUCCESS got %u\n", ret);
1341 ok(osize == size, "expected %d, got %d\n", size, osize);
1343 for (aa = ptr; !ret && aa; aa = aa->Next)
1345 char temp[128];
1347 ok(S(U(*aa)).Length == sizeof(IP_ADAPTER_ADDRESSES_LH) ||
1348 S(U(*aa)).Length == sizeof(IP_ADAPTER_ADDRESSES_XP),
1349 "Unknown structure size of %u bytes\n", S(U(*aa)).Length);
1350 ok(aa->DnsSuffix != NULL, "DnsSuffix is not a valid pointer\n");
1351 ok(aa->Description != NULL, "Description is not a valid pointer\n");
1352 ok(aa->FriendlyName != NULL, "FriendlyName is not a valid pointer\n");
1354 trace("\n");
1355 trace("Length: %u\n", S(U(*aa)).Length);
1356 trace("IfIndex: %u\n", S(U(*aa)).IfIndex);
1357 trace("Next: %p\n", aa->Next);
1358 trace("AdapterName: %s\n", aa->AdapterName);
1359 trace("FirstUnicastAddress: %p\n", aa->FirstUnicastAddress);
1360 ua = aa->FirstUnicastAddress;
1361 while (ua)
1363 ok(ua->PrefixOrigin != IpPrefixOriginOther,
1364 "bad address config value %d\n", ua->PrefixOrigin);
1365 ok(ua->SuffixOrigin != IpSuffixOriginOther,
1366 "bad address config value %d\n", ua->PrefixOrigin);
1367 /* Address configured manually or from DHCP server? */
1368 if (ua->PrefixOrigin == IpPrefixOriginManual ||
1369 ua->PrefixOrigin == IpPrefixOriginDhcp)
1371 ok(ua->ValidLifetime, "expected non-zero value\n");
1372 ok(ua->PreferredLifetime, "expected non-zero value\n");
1373 ok(ua->LeaseLifetime, "expected non-zero\n");
1375 /* Is the address ok in the network (not duplicated)? */
1376 ok(ua->DadState != IpDadStateInvalid && ua->DadState != IpDadStateDuplicate,
1377 "bad address duplication value %d\n", ua->DadState);
1378 trace("\tLength: %u\n", S(U(*ua)).Length);
1379 trace("\tFlags: 0x%08x\n", S(U(*ua)).Flags);
1380 trace("\tNext: %p\n", ua->Next);
1381 trace("\tAddress.lpSockaddr: %p\n", ua->Address.lpSockaddr);
1382 trace("\tAddress.iSockaddrLength: %d\n", ua->Address.iSockaddrLength);
1383 trace("\tPrefixOrigin: %u\n", ua->PrefixOrigin);
1384 trace("\tSuffixOrigin: %u\n", ua->SuffixOrigin);
1385 trace("\tDadState: %u\n", ua->DadState);
1386 trace("\tValidLifetime: %u seconds\n", ua->ValidLifetime);
1387 trace("\tPreferredLifetime: %u seconds\n", ua->PreferredLifetime);
1388 trace("\tLeaseLifetime: %u seconds\n", ua->LeaseLifetime);
1389 trace("\n");
1390 ua = ua->Next;
1392 trace("FirstAnycastAddress: %p\n", aa->FirstAnycastAddress);
1393 trace("FirstMulticastAddress: %p\n", aa->FirstMulticastAddress);
1394 trace("FirstDnsServerAddress: %p\n", aa->FirstDnsServerAddress);
1395 trace("DnsSuffix: %s %p\n", wine_dbgstr_w(aa->DnsSuffix), aa->DnsSuffix);
1396 trace("Description: %s %p\n", wine_dbgstr_w(aa->Description), aa->Description);
1397 trace("FriendlyName: %s %p\n", wine_dbgstr_w(aa->FriendlyName), aa->FriendlyName);
1398 trace("PhysicalAddressLength: %u\n", aa->PhysicalAddressLength);
1399 for (i = 0; i < aa->PhysicalAddressLength; i++)
1400 sprintf(temp + i * 3, "%02X-", aa->PhysicalAddress[i]);
1401 temp[i ? i * 3 - 1 : 0] = '\0';
1402 trace("PhysicalAddress: %s\n", temp);
1403 trace("Flags: 0x%08x\n", aa->Flags);
1404 trace("Mtu: %u\n", aa->Mtu);
1405 trace("IfType: %u\n", aa->IfType);
1406 trace("OperStatus: %u\n", aa->OperStatus);
1407 trace("Ipv6IfIndex: %u\n", aa->Ipv6IfIndex);
1408 for (i = 0, temp[0] = '\0'; i < sizeof(aa->ZoneIndices) / sizeof(aa->ZoneIndices[0]); i++)
1409 sprintf(temp + strlen(temp), "%d ", aa->ZoneIndices[i]);
1410 trace("ZoneIndices: %s\n", temp);
1411 trace("FirstPrefix: %p\n", aa->FirstPrefix);
1413 if (S(U(*aa)).Length < sizeof(IP_ADAPTER_ADDRESSES_LH)) continue;
1414 trace("TransmitLinkSpeed: %s\n", debugstr_longlong(aa->TransmitLinkSpeed));
1415 trace("ReceiveLinkSpeed: %s\n", debugstr_longlong(aa->ReceiveLinkSpeed));
1416 trace("FirstWinsServerAddress:%p\n", aa->FirstWinsServerAddress);
1417 trace("FirstGatewayAddress: %p\n", aa->FirstGatewayAddress);
1418 trace("Ipv4Metric: %u\n", aa->Ipv4Metric);
1419 trace("Ipv6Metric: %u\n", aa->Ipv6Metric);
1420 trace("Luid: %p\n", &aa->Luid);
1421 trace("Dhcpv4Server: %p\n", &aa->Dhcpv4Server);
1422 trace("CompartmentId: %u\n", aa->CompartmentId);
1423 trace("NetworkGuid: %s\n", wine_dbgstr_guid((GUID*) &aa->NetworkGuid));
1424 trace("ConnectionType: %u\n", aa->ConnectionType);
1425 trace("TunnelType: %u\n", aa->TunnelType);
1426 trace("Dhcpv6Server: %p\n", &aa->Dhcpv6Server);
1427 trace("Dhcpv6ClientDuidLength:%u\n", aa->Dhcpv6ClientDuidLength);
1428 trace("Dhcpv6ClientDuid: %p\n", aa->Dhcpv6ClientDuid);
1429 trace("Dhcpv6Iaid: %u\n", aa->Dhcpv6Iaid);
1430 trace("FirstDnsSuffix: %p\n", aa->FirstDnsSuffix);
1431 trace("\n");
1433 HeapFree(GetProcessHeap(), 0, ptr);
1436 static void test_GetExtendedTcpTable(void)
1438 DWORD ret, size;
1439 MIB_TCPTABLE *table;
1440 MIB_TCPTABLE_OWNER_PID *table_pid;
1441 MIB_TCPTABLE_OWNER_MODULE *table_module;
1443 if (!pGetExtendedTcpTable)
1445 win_skip("GetExtendedTcpTable not available\n");
1446 return;
1448 ret = pGetExtendedTcpTable( NULL, NULL, TRUE, AF_INET, TCP_TABLE_BASIC_ALL, 0 );
1449 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
1451 size = 0;
1452 ret = pGetExtendedTcpTable( NULL, &size, TRUE, AF_INET, TCP_TABLE_BASIC_ALL, 0 );
1453 ok( ret == ERROR_INSUFFICIENT_BUFFER, "got %u\n", ret );
1455 table = HeapAlloc( GetProcessHeap(), 0, size );
1456 ret = pGetExtendedTcpTable( table, &size, TRUE, AF_INET, TCP_TABLE_BASIC_ALL, 0 );
1457 ok( ret == ERROR_SUCCESS, "got %u\n", ret );
1458 HeapFree( GetProcessHeap(), 0, table );
1460 size = 0;
1461 ret = pGetExtendedTcpTable( NULL, &size, TRUE, AF_INET, TCP_TABLE_BASIC_LISTENER, 0 );
1462 ok( ret == ERROR_INSUFFICIENT_BUFFER, "got %u\n", ret );
1464 table = HeapAlloc( GetProcessHeap(), 0, size );
1465 ret = pGetExtendedTcpTable( table, &size, TRUE, AF_INET, TCP_TABLE_BASIC_LISTENER, 0 );
1466 ok( ret == ERROR_SUCCESS, "got %u\n", ret );
1467 HeapFree( GetProcessHeap(), 0, table );
1469 size = 0;
1470 ret = pGetExtendedTcpTable( NULL, &size, TRUE, AF_INET, TCP_TABLE_OWNER_PID_ALL, 0 );
1471 ok( ret == ERROR_INSUFFICIENT_BUFFER, "got %u\n", ret );
1473 table_pid = HeapAlloc( GetProcessHeap(), 0, size );
1474 ret = pGetExtendedTcpTable( table_pid, &size, TRUE, AF_INET, TCP_TABLE_OWNER_PID_ALL, 0 );
1475 ok( ret == ERROR_SUCCESS, "got %u\n", ret );
1476 HeapFree( GetProcessHeap(), 0, table_pid );
1478 size = 0;
1479 ret = pGetExtendedTcpTable( NULL, &size, TRUE, AF_INET, TCP_TABLE_OWNER_PID_LISTENER, 0 );
1480 ok( ret == ERROR_INSUFFICIENT_BUFFER, "got %u\n", ret );
1482 table_pid = HeapAlloc( GetProcessHeap(), 0, size );
1483 ret = pGetExtendedTcpTable( table_pid, &size, TRUE, AF_INET, TCP_TABLE_OWNER_PID_LISTENER, 0 );
1484 ok( ret == ERROR_SUCCESS, "got %u\n", ret );
1485 HeapFree( GetProcessHeap(), 0, table_pid );
1487 size = 0;
1488 ret = pGetExtendedTcpTable( NULL, &size, TRUE, AF_INET, TCP_TABLE_OWNER_MODULE_ALL, 0 );
1489 ok( ret == ERROR_INSUFFICIENT_BUFFER, "got %u\n", ret );
1491 table_module = HeapAlloc( GetProcessHeap(), 0, size );
1492 ret = pGetExtendedTcpTable( table_module, &size, TRUE, AF_INET, TCP_TABLE_OWNER_MODULE_ALL, 0 );
1493 ok( ret == ERROR_SUCCESS, "got %u\n", ret );
1494 HeapFree( GetProcessHeap(), 0, table_module );
1496 size = 0;
1497 ret = pGetExtendedTcpTable( NULL, &size, TRUE, AF_INET, TCP_TABLE_OWNER_MODULE_LISTENER, 0 );
1498 ok( ret == ERROR_INSUFFICIENT_BUFFER, "got %u\n", ret );
1500 table_module = HeapAlloc( GetProcessHeap(), 0, size );
1501 ret = pGetExtendedTcpTable( table_module, &size, TRUE, AF_INET, TCP_TABLE_OWNER_MODULE_LISTENER, 0 );
1502 ok( ret == ERROR_SUCCESS, "got %u\n", ret );
1503 HeapFree( GetProcessHeap(), 0, table_module );
1506 static void test_GetExtendedUdpTable(void)
1508 DWORD ret, size;
1509 MIB_UDPTABLE *table;
1510 MIB_UDPTABLE_OWNER_PID *table_pid;
1511 MIB_UDPTABLE_OWNER_MODULE *table_module;
1513 if (!pGetExtendedUdpTable)
1515 win_skip("GetExtendedUdpTable not available\n");
1516 return;
1518 ret = pGetExtendedUdpTable( NULL, NULL, TRUE, AF_INET, UDP_TABLE_BASIC, 0 );
1519 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
1521 size = 0;
1522 ret = pGetExtendedUdpTable( NULL, &size, TRUE, AF_INET, UDP_TABLE_BASIC, 0 );
1523 ok( ret == ERROR_INSUFFICIENT_BUFFER, "got %u\n", ret );
1525 table = HeapAlloc( GetProcessHeap(), 0, size );
1526 ret = pGetExtendedUdpTable( table, &size, TRUE, AF_INET, UDP_TABLE_BASIC, 0 );
1527 ok( ret == ERROR_SUCCESS, "got %u\n", ret );
1528 HeapFree( GetProcessHeap(), 0, table );
1530 size = 0;
1531 ret = pGetExtendedUdpTable( NULL, &size, TRUE, AF_INET, UDP_TABLE_OWNER_PID, 0 );
1532 ok( ret == ERROR_INSUFFICIENT_BUFFER, "got %u\n", ret );
1534 table_pid = HeapAlloc( GetProcessHeap(), 0, size );
1535 ret = pGetExtendedUdpTable( table_pid, &size, TRUE, AF_INET, UDP_TABLE_OWNER_PID, 0 );
1536 ok( ret == ERROR_SUCCESS, "got %u\n", ret );
1537 HeapFree( GetProcessHeap(), 0, table_pid );
1539 size = 0;
1540 ret = pGetExtendedUdpTable( NULL, &size, TRUE, AF_INET, UDP_TABLE_OWNER_MODULE, 0 );
1541 ok( ret == ERROR_INSUFFICIENT_BUFFER, "got %u\n", ret );
1543 table_module = HeapAlloc( GetProcessHeap(), 0, size );
1544 ret = pGetExtendedUdpTable( table_module, &size, TRUE, AF_INET, UDP_TABLE_OWNER_MODULE, 0 );
1545 ok( ret == ERROR_SUCCESS, "got %u\n", ret );
1546 HeapFree( GetProcessHeap(), 0, table_module );
1549 START_TEST(iphlpapi)
1552 loadIPHlpApi();
1553 if (hLibrary) {
1554 HANDLE thread;
1556 testWin98OnlyFunctions();
1557 testWinNT4Functions();
1559 /* run testGetXXXX in two threads at once to make sure we don't crash in that case */
1560 thread = CreateThread(NULL, 0, testWin98Functions, NULL, 0, NULL);
1561 testWin98Functions(NULL);
1562 WaitForSingleObject(thread, INFINITE);
1564 testWin2KFunctions();
1565 test_GetAdaptersAddresses();
1566 test_GetExtendedTcpTable();
1567 test_GetExtendedUdpTable();
1568 freeIPHlpApi();