iphlpapi/tests: Improve IcmpSendEcho trace.
[wine/multimedia.git] / dlls / iphlpapi / tests / iphlpapi.c
blobbc70b51bc7f64f8fb0d52efd149879162e1ac8c2
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)
230 int i;
231 testGetIfEntry(buf->table[0].dwIndex);
232 for (i = 0; i < buf->dwNumEntries; i++)
234 ok (buf->table[i].wType != 0, "Test[%d]: expected wType > 0\n", i);
235 trace("Entry[%d]: addr %s, dwIndex %u, wType 0x%x\n", i,
236 ntoa(buf->table[i].dwAddr), buf->table[i].dwIndex, buf->table[i].wType);
239 HeapFree(GetProcessHeap(), 0, buf);
244 static void testGetIfTable(void)
246 if (pGetIfTable) {
247 DWORD apiReturn;
248 ULONG dwSize = 0;
250 apiReturn = pGetIfTable(NULL, NULL, FALSE);
251 if (apiReturn == ERROR_NOT_SUPPORTED) {
252 skip("GetIfTable is not supported\n");
253 return;
255 ok(apiReturn == ERROR_INVALID_PARAMETER,
256 "GetIfTable(NULL, NULL, FALSE) returned %d, expected ERROR_INVALID_PARAMETER\n",
257 apiReturn);
258 apiReturn = pGetIfTable(NULL, &dwSize, FALSE);
259 ok(apiReturn == ERROR_INSUFFICIENT_BUFFER,
260 "GetIfTable(NULL, &dwSize, FALSE) returned %d, expected ERROR_INSUFFICIENT_BUFFER\n",
261 apiReturn);
262 if (apiReturn == ERROR_INSUFFICIENT_BUFFER) {
263 PMIB_IFTABLE buf = HeapAlloc(GetProcessHeap(), 0, dwSize);
265 apiReturn = pGetIfTable(buf, &dwSize, FALSE);
266 ok(apiReturn == NO_ERROR,
267 "GetIfTable(buf, &dwSize, FALSE) returned %d, expected NO_ERROR\n\n",
268 apiReturn);
270 if (apiReturn == NO_ERROR && winetest_debug > 1)
272 DWORD i, j;
273 char name[MAX_INTERFACE_NAME_LEN];
275 trace( "interface table: %u entries\n", buf->dwNumEntries );
276 for (i = 0; i < buf->dwNumEntries; i++)
278 MIB_IFROW *row = &buf->table[i];
279 WideCharToMultiByte( CP_ACP, 0, row->wszName, -1, name, MAX_INTERFACE_NAME_LEN, NULL, NULL );
280 trace( "%u: '%s' type %u mtu %u speed %u phys",
281 row->dwIndex, name, row->dwType, row->dwMtu, row->dwSpeed );
282 for (j = 0; j < row->dwPhysAddrLen; j++)
283 printf( " %02x", row->bPhysAddr[j] );
284 printf( "\n" );
285 trace( " in: bytes %u upkts %u nupkts %u disc %u err %u unk %u\n",
286 row->dwInOctets, row->dwInUcastPkts, row->dwInNUcastPkts,
287 row->dwInDiscards, row->dwInErrors, row->dwInUnknownProtos );
288 trace( " out: bytes %u upkts %u nupkts %u disc %u err %u\n",
289 row->dwOutOctets, row->dwOutUcastPkts, row->dwOutNUcastPkts,
290 row->dwOutDiscards, row->dwOutErrors );
293 HeapFree(GetProcessHeap(), 0, buf);
298 static void testGetIpForwardTable(void)
300 if (pGetIpForwardTable) {
301 DWORD apiReturn;
302 ULONG dwSize = 0;
304 apiReturn = pGetIpForwardTable(NULL, NULL, FALSE);
305 if (apiReturn == ERROR_NOT_SUPPORTED) {
306 skip("GetIpForwardTable is not supported\n");
307 return;
309 ok(apiReturn == ERROR_INVALID_PARAMETER,
310 "GetIpForwardTable(NULL, NULL, FALSE) returned %d, expected ERROR_INVALID_PARAMETER\n",
311 apiReturn);
312 apiReturn = pGetIpForwardTable(NULL, &dwSize, FALSE);
313 ok(apiReturn == ERROR_INSUFFICIENT_BUFFER,
314 "GetIpForwardTable(NULL, &dwSize, FALSE) returned %d, expected ERROR_INSUFFICIENT_BUFFER\n",
315 apiReturn);
316 if (apiReturn == ERROR_INSUFFICIENT_BUFFER) {
317 PMIB_IPFORWARDTABLE buf = HeapAlloc(GetProcessHeap(), 0, dwSize);
319 apiReturn = pGetIpForwardTable(buf, &dwSize, FALSE);
320 ok(apiReturn == NO_ERROR,
321 "GetIpForwardTable(buf, &dwSize, FALSE) returned %d, expected NO_ERROR\n",
322 apiReturn);
324 if (apiReturn == NO_ERROR && winetest_debug > 1)
326 DWORD i;
328 trace( "IP forward table: %u entries\n", buf->dwNumEntries );
329 for (i = 0; i < buf->dwNumEntries; i++)
331 char buffer[100];
332 sprintf( buffer, "dest %s", ntoa( buf->table[i].dwForwardDest ));
333 sprintf( buffer + strlen(buffer), " mask %s", ntoa( buf->table[i].dwForwardMask ));
334 trace( "%u: %s gw %s if %u type %u\n", i, buffer,
335 ntoa( buf->table[i].dwForwardNextHop ),
336 buf->table[i].dwForwardIfIndex, U1(buf->table[i]).dwForwardType );
339 HeapFree(GetProcessHeap(), 0, buf);
344 static void testGetIpNetTable(void)
346 if (pGetIpNetTable) {
347 DWORD apiReturn;
348 ULONG dwSize = 0;
350 apiReturn = pGetIpNetTable(NULL, NULL, FALSE);
351 if (apiReturn == ERROR_NOT_SUPPORTED) {
352 skip("GetIpNetTable is not supported\n");
353 return;
355 ok(apiReturn == ERROR_INVALID_PARAMETER,
356 "GetIpNetTable(NULL, NULL, FALSE) returned %d, expected ERROR_INVALID_PARAMETER\n",
357 apiReturn);
358 apiReturn = pGetIpNetTable(NULL, &dwSize, FALSE);
359 ok(apiReturn == ERROR_NO_DATA || apiReturn == ERROR_INSUFFICIENT_BUFFER,
360 "GetIpNetTable(NULL, &dwSize, FALSE) returned %d, expected ERROR_NO_DATA or ERROR_INSUFFICIENT_BUFFER\n",
361 apiReturn);
362 if (apiReturn == ERROR_NO_DATA)
363 ; /* empty ARP table's okay */
364 else if (apiReturn == ERROR_INSUFFICIENT_BUFFER) {
365 PMIB_IPNETTABLE buf = HeapAlloc(GetProcessHeap(), 0, dwSize);
367 apiReturn = pGetIpNetTable(buf, &dwSize, FALSE);
368 ok(apiReturn == NO_ERROR ||
369 apiReturn == ERROR_NO_DATA, /* empty ARP table's okay */
370 "GetIpNetTable(buf, &dwSize, FALSE) returned %d, expected NO_ERROR\n",
371 apiReturn);
373 if (apiReturn == NO_ERROR && winetest_debug > 1)
375 DWORD i, j;
377 trace( "IP net table: %u entries\n", buf->dwNumEntries );
378 for (i = 0; i < buf->dwNumEntries; i++)
380 trace( "%u: idx %u type %u addr %s phys",
381 i, buf->table[i].dwIndex, U(buf->table[i]).dwType, ntoa( buf->table[i].dwAddr ));
382 for (j = 0; j < buf->table[i].dwPhysAddrLen; j++)
383 printf( " %02x", buf->table[i].bPhysAddr[j] );
384 printf( "\n" );
387 HeapFree(GetProcessHeap(), 0, buf);
392 static void testGetIcmpStatistics(void)
394 if (pGetIcmpStatistics) {
395 DWORD apiReturn;
396 MIB_ICMP stats;
398 /* Crashes on Vista */
399 if (0) {
400 apiReturn = pGetIcmpStatistics(NULL);
401 if (apiReturn == ERROR_NOT_SUPPORTED)
402 return;
403 ok(apiReturn == ERROR_INVALID_PARAMETER,
404 "GetIcmpStatistics(NULL) returned %d, expected ERROR_INVALID_PARAMETER\n",
405 apiReturn);
408 apiReturn = pGetIcmpStatistics(&stats);
409 if (apiReturn == ERROR_NOT_SUPPORTED)
411 skip("GetIcmpStatistics is not supported\n");
412 return;
414 ok(apiReturn == NO_ERROR,
415 "GetIcmpStatistics returned %d, expected NO_ERROR\n", apiReturn);
416 if (apiReturn == NO_ERROR && winetest_debug > 1)
418 trace( "ICMP stats: %8s %8s\n", "in", "out" );
419 trace( " dwMsgs: %8u %8u\n", stats.stats.icmpInStats.dwMsgs, stats.stats.icmpOutStats.dwMsgs );
420 trace( " dwErrors: %8u %8u\n", stats.stats.icmpInStats.dwErrors, stats.stats.icmpOutStats.dwErrors );
421 trace( " dwDestUnreachs: %8u %8u\n", stats.stats.icmpInStats.dwDestUnreachs, stats.stats.icmpOutStats.dwDestUnreachs );
422 trace( " dwTimeExcds: %8u %8u\n", stats.stats.icmpInStats.dwTimeExcds, stats.stats.icmpOutStats.dwTimeExcds );
423 trace( " dwParmProbs: %8u %8u\n", stats.stats.icmpInStats.dwParmProbs, stats.stats.icmpOutStats.dwParmProbs );
424 trace( " dwSrcQuenchs: %8u %8u\n", stats.stats.icmpInStats.dwSrcQuenchs, stats.stats.icmpOutStats.dwSrcQuenchs );
425 trace( " dwRedirects: %8u %8u\n", stats.stats.icmpInStats.dwRedirects, stats.stats.icmpOutStats.dwRedirects );
426 trace( " dwEchos: %8u %8u\n", stats.stats.icmpInStats.dwEchos, stats.stats.icmpOutStats.dwEchos );
427 trace( " dwEchoReps: %8u %8u\n", stats.stats.icmpInStats.dwEchoReps, stats.stats.icmpOutStats.dwEchoReps );
428 trace( " dwTimestamps: %8u %8u\n", stats.stats.icmpInStats.dwTimestamps, stats.stats.icmpOutStats.dwTimestamps );
429 trace( " dwTimestampReps: %8u %8u\n", stats.stats.icmpInStats.dwTimestampReps, stats.stats.icmpOutStats.dwTimestampReps );
430 trace( " dwAddrMasks: %8u %8u\n", stats.stats.icmpInStats.dwAddrMasks, stats.stats.icmpOutStats.dwAddrMasks );
431 trace( " dwAddrMaskReps: %8u %8u\n", stats.stats.icmpInStats.dwAddrMaskReps, stats.stats.icmpOutStats.dwAddrMaskReps );
436 static void testGetIpStatistics(void)
438 if (pGetIpStatistics) {
439 DWORD apiReturn;
440 MIB_IPSTATS stats;
442 apiReturn = pGetIpStatistics(NULL);
443 if (apiReturn == ERROR_NOT_SUPPORTED) {
444 skip("GetIpStatistics is not supported\n");
445 return;
447 ok(apiReturn == ERROR_INVALID_PARAMETER,
448 "GetIpStatistics(NULL) returned %d, expected ERROR_INVALID_PARAMETER\n",
449 apiReturn);
450 apiReturn = pGetIpStatistics(&stats);
451 ok(apiReturn == NO_ERROR,
452 "GetIpStatistics returned %d, expected NO_ERROR\n", apiReturn);
453 if (apiReturn == NO_ERROR && winetest_debug > 1)
455 trace( "IP stats:\n" );
456 trace( " dwForwarding: %u\n", U(stats).dwForwarding );
457 trace( " dwDefaultTTL: %u\n", stats.dwDefaultTTL );
458 trace( " dwInReceives: %u\n", stats.dwInReceives );
459 trace( " dwInHdrErrors: %u\n", stats.dwInHdrErrors );
460 trace( " dwInAddrErrors: %u\n", stats.dwInAddrErrors );
461 trace( " dwForwDatagrams: %u\n", stats.dwForwDatagrams );
462 trace( " dwInUnknownProtos: %u\n", stats.dwInUnknownProtos );
463 trace( " dwInDiscards: %u\n", stats.dwInDiscards );
464 trace( " dwInDelivers: %u\n", stats.dwInDelivers );
465 trace( " dwOutRequests: %u\n", stats.dwOutRequests );
466 trace( " dwRoutingDiscards: %u\n", stats.dwRoutingDiscards );
467 trace( " dwOutDiscards: %u\n", stats.dwOutDiscards );
468 trace( " dwOutNoRoutes: %u\n", stats.dwOutNoRoutes );
469 trace( " dwReasmTimeout: %u\n", stats.dwReasmTimeout );
470 trace( " dwReasmReqds: %u\n", stats.dwReasmReqds );
471 trace( " dwReasmOks: %u\n", stats.dwReasmOks );
472 trace( " dwReasmFails: %u\n", stats.dwReasmFails );
473 trace( " dwFragOks: %u\n", stats.dwFragOks );
474 trace( " dwFragFails: %u\n", stats.dwFragFails );
475 trace( " dwFragCreates: %u\n", stats.dwFragCreates );
476 trace( " dwNumIf: %u\n", stats.dwNumIf );
477 trace( " dwNumAddr: %u\n", stats.dwNumAddr );
478 trace( " dwNumRoutes: %u\n", stats.dwNumRoutes );
483 static void testGetTcpStatistics(void)
485 if (pGetTcpStatistics) {
486 DWORD apiReturn;
487 MIB_TCPSTATS stats;
489 apiReturn = pGetTcpStatistics(NULL);
490 if (apiReturn == ERROR_NOT_SUPPORTED) {
491 skip("GetTcpStatistics is not supported\n");
492 return;
494 ok(apiReturn == ERROR_INVALID_PARAMETER,
495 "GetTcpStatistics(NULL) returned %d, expected ERROR_INVALID_PARAMETER\n",
496 apiReturn);
497 apiReturn = pGetTcpStatistics(&stats);
498 ok(apiReturn == NO_ERROR,
499 "GetTcpStatistics returned %d, expected NO_ERROR\n", apiReturn);
500 if (apiReturn == NO_ERROR && winetest_debug > 1)
502 trace( "TCP stats:\n" );
503 trace( " dwRtoAlgorithm: %u\n", U(stats).dwRtoAlgorithm );
504 trace( " dwRtoMin: %u\n", stats.dwRtoMin );
505 trace( " dwRtoMax: %u\n", stats.dwRtoMax );
506 trace( " dwMaxConn: %u\n", stats.dwMaxConn );
507 trace( " dwActiveOpens: %u\n", stats.dwActiveOpens );
508 trace( " dwPassiveOpens: %u\n", stats.dwPassiveOpens );
509 trace( " dwAttemptFails: %u\n", stats.dwAttemptFails );
510 trace( " dwEstabResets: %u\n", stats.dwEstabResets );
511 trace( " dwCurrEstab: %u\n", stats.dwCurrEstab );
512 trace( " dwInSegs: %u\n", stats.dwInSegs );
513 trace( " dwOutSegs: %u\n", stats.dwOutSegs );
514 trace( " dwRetransSegs: %u\n", stats.dwRetransSegs );
515 trace( " dwInErrs: %u\n", stats.dwInErrs );
516 trace( " dwOutRsts: %u\n", stats.dwOutRsts );
517 trace( " dwNumConns: %u\n", stats.dwNumConns );
522 static void testGetUdpStatistics(void)
524 if (pGetUdpStatistics) {
525 DWORD apiReturn;
526 MIB_UDPSTATS stats;
528 apiReturn = pGetUdpStatistics(NULL);
529 if (apiReturn == ERROR_NOT_SUPPORTED) {
530 skip("GetUdpStatistics is not supported\n");
531 return;
533 ok(apiReturn == ERROR_INVALID_PARAMETER,
534 "GetUdpStatistics(NULL) returned %d, expected ERROR_INVALID_PARAMETER\n",
535 apiReturn);
536 apiReturn = pGetUdpStatistics(&stats);
537 ok(apiReturn == NO_ERROR,
538 "GetUdpStatistics returned %d, expected NO_ERROR\n", apiReturn);
539 if (apiReturn == NO_ERROR && winetest_debug > 1)
541 trace( "UDP stats:\n" );
542 trace( " dwInDatagrams: %u\n", stats.dwInDatagrams );
543 trace( " dwNoPorts: %u\n", stats.dwNoPorts );
544 trace( " dwInErrors: %u\n", stats.dwInErrors );
545 trace( " dwOutDatagrams: %u\n", stats.dwOutDatagrams );
546 trace( " dwNumAddrs: %u\n", stats.dwNumAddrs );
551 static void testGetIcmpStatisticsEx(void)
553 DWORD apiReturn;
554 MIB_ICMP_EX stats;
556 if (!pGetIcmpStatisticsEx)
558 win_skip( "GetIcmpStatisticsEx not available\n" );
559 return;
562 /* Crashes on Vista */
563 if (1) {
564 apiReturn = pGetIcmpStatisticsEx(NULL, AF_INET);
565 ok(apiReturn == ERROR_INVALID_PARAMETER,
566 "GetIcmpStatisticsEx(NULL, AF_INET) returned %d, expected ERROR_INVALID_PARAMETER\n", apiReturn);
569 apiReturn = pGetIcmpStatisticsEx(&stats, AF_BAN);
570 ok(apiReturn == ERROR_INVALID_PARAMETER,
571 "GetIcmpStatisticsEx(&stats, AF_BAN) returned %d, expected ERROR_INVALID_PARAMETER\n", apiReturn);
573 apiReturn = pGetIcmpStatisticsEx(&stats, AF_INET);
574 ok(apiReturn == NO_ERROR, "GetIcmpStatisticsEx returned %d, expected NO_ERROR\n", apiReturn);
575 if (apiReturn == NO_ERROR && winetest_debug > 1)
577 INT i;
578 trace( "ICMP IPv4 Ex stats: %8s %8s\n", "in", "out" );
579 trace( " dwMsgs: %8u %8u\n", stats.icmpInStats.dwMsgs, stats.icmpOutStats.dwMsgs );
580 trace( " dwErrors: %8u %8u\n", stats.icmpInStats.dwErrors, stats.icmpOutStats.dwErrors );
581 for (i = 0; i < 256; i++)
582 trace( " rgdwTypeCount[%3i]: %8u %8u\n", i, stats.icmpInStats.rgdwTypeCount[i], stats.icmpOutStats.rgdwTypeCount[i] );
585 apiReturn = pGetIcmpStatisticsEx(&stats, AF_INET6);
586 ok(apiReturn == NO_ERROR || broken(apiReturn == ERROR_NOT_SUPPORTED),
587 "GetIcmpStatisticsEx returned %d, expected NO_ERROR\n", apiReturn);
588 if (apiReturn == NO_ERROR && winetest_debug > 1)
590 INT i;
591 trace( "ICMP IPv6 Ex stats: %8s %8s\n", "in", "out" );
592 trace( " dwMsgs: %8u %8u\n", stats.icmpInStats.dwMsgs, stats.icmpOutStats.dwMsgs );
593 trace( " dwErrors: %8u %8u\n", stats.icmpInStats.dwErrors, stats.icmpOutStats.dwErrors );
594 for (i = 0; i < 256; i++)
595 trace( " rgdwTypeCount[%3i]: %8u %8u\n", i, stats.icmpInStats.rgdwTypeCount[i], stats.icmpOutStats.rgdwTypeCount[i] );
599 static void testGetIpStatisticsEx(void)
601 DWORD apiReturn;
602 MIB_IPSTATS stats;
604 if (!pGetIpStatisticsEx)
606 win_skip( "GetIpStatisticsEx not available\n" );
607 return;
610 apiReturn = pGetIpStatisticsEx(NULL, AF_INET);
611 ok(apiReturn == ERROR_INVALID_PARAMETER,
612 "GetIpStatisticsEx(NULL, AF_INET) returned %d, expected ERROR_INVALID_PARAMETER\n", apiReturn);
614 apiReturn = pGetIpStatisticsEx(&stats, AF_BAN);
615 ok(apiReturn == ERROR_INVALID_PARAMETER,
616 "GetIpStatisticsEx(&stats, AF_BAN) returned %d, expected ERROR_INVALID_PARAMETER\n", apiReturn);
618 apiReturn = pGetIpStatisticsEx(&stats, AF_INET);
619 ok(apiReturn == NO_ERROR, "GetIpStatisticsEx returned %d, expected NO_ERROR\n", apiReturn);
620 if (apiReturn == NO_ERROR && winetest_debug > 1)
622 trace( "IP IPv4 Ex stats:\n" );
623 trace( " dwForwarding: %u\n", U(stats).dwForwarding );
624 trace( " dwDefaultTTL: %u\n", stats.dwDefaultTTL );
625 trace( " dwInReceives: %u\n", stats.dwInReceives );
626 trace( " dwInHdrErrors: %u\n", stats.dwInHdrErrors );
627 trace( " dwInAddrErrors: %u\n", stats.dwInAddrErrors );
628 trace( " dwForwDatagrams: %u\n", stats.dwForwDatagrams );
629 trace( " dwInUnknownProtos: %u\n", stats.dwInUnknownProtos );
630 trace( " dwInDiscards: %u\n", stats.dwInDiscards );
631 trace( " dwInDelivers: %u\n", stats.dwInDelivers );
632 trace( " dwOutRequests: %u\n", stats.dwOutRequests );
633 trace( " dwRoutingDiscards: %u\n", stats.dwRoutingDiscards );
634 trace( " dwOutDiscards: %u\n", stats.dwOutDiscards );
635 trace( " dwOutNoRoutes: %u\n", stats.dwOutNoRoutes );
636 trace( " dwReasmTimeout: %u\n", stats.dwReasmTimeout );
637 trace( " dwReasmReqds: %u\n", stats.dwReasmReqds );
638 trace( " dwReasmOks: %u\n", stats.dwReasmOks );
639 trace( " dwReasmFails: %u\n", stats.dwReasmFails );
640 trace( " dwFragOks: %u\n", stats.dwFragOks );
641 trace( " dwFragFails: %u\n", stats.dwFragFails );
642 trace( " dwFragCreates: %u\n", stats.dwFragCreates );
643 trace( " dwNumIf: %u\n", stats.dwNumIf );
644 trace( " dwNumAddr: %u\n", stats.dwNumAddr );
645 trace( " dwNumRoutes: %u\n", stats.dwNumRoutes );
648 apiReturn = pGetIpStatisticsEx(&stats, AF_INET6);
649 ok(apiReturn == NO_ERROR || broken(apiReturn == ERROR_NOT_SUPPORTED),
650 "GetIpStatisticsEx returned %d, expected NO_ERROR\n", apiReturn);
651 if (apiReturn == NO_ERROR && winetest_debug > 1)
653 trace( "IP IPv6 Ex stats:\n" );
654 trace( " dwForwarding: %u\n", U(stats).dwForwarding );
655 trace( " dwDefaultTTL: %u\n", stats.dwDefaultTTL );
656 trace( " dwInReceives: %u\n", stats.dwInReceives );
657 trace( " dwInHdrErrors: %u\n", stats.dwInHdrErrors );
658 trace( " dwInAddrErrors: %u\n", stats.dwInAddrErrors );
659 trace( " dwForwDatagrams: %u\n", stats.dwForwDatagrams );
660 trace( " dwInUnknownProtos: %u\n", stats.dwInUnknownProtos );
661 trace( " dwInDiscards: %u\n", stats.dwInDiscards );
662 trace( " dwInDelivers: %u\n", stats.dwInDelivers );
663 trace( " dwOutRequests: %u\n", stats.dwOutRequests );
664 trace( " dwRoutingDiscards: %u\n", stats.dwRoutingDiscards );
665 trace( " dwOutDiscards: %u\n", stats.dwOutDiscards );
666 trace( " dwOutNoRoutes: %u\n", stats.dwOutNoRoutes );
667 trace( " dwReasmTimeout: %u\n", stats.dwReasmTimeout );
668 trace( " dwReasmReqds: %u\n", stats.dwReasmReqds );
669 trace( " dwReasmOks: %u\n", stats.dwReasmOks );
670 trace( " dwReasmFails: %u\n", stats.dwReasmFails );
671 trace( " dwFragOks: %u\n", stats.dwFragOks );
672 trace( " dwFragFails: %u\n", stats.dwFragFails );
673 trace( " dwFragCreates: %u\n", stats.dwFragCreates );
674 trace( " dwNumIf: %u\n", stats.dwNumIf );
675 trace( " dwNumAddr: %u\n", stats.dwNumAddr );
676 trace( " dwNumRoutes: %u\n", stats.dwNumRoutes );
680 static void testGetTcpStatisticsEx(void)
682 DWORD apiReturn;
683 MIB_TCPSTATS stats;
685 if (!pGetTcpStatisticsEx)
687 win_skip( "GetTcpStatisticsEx not available\n" );
688 return;
691 apiReturn = pGetTcpStatisticsEx(NULL, AF_INET);
692 ok(apiReturn == ERROR_INVALID_PARAMETER,
693 "GetTcpStatisticsEx(NULL, AF_INET); returned %d, expected ERROR_INVALID_PARAMETER\n", apiReturn);
695 apiReturn = pGetTcpStatisticsEx(&stats, AF_BAN);
696 ok(apiReturn == ERROR_INVALID_PARAMETER || apiReturn == ERROR_NOT_SUPPORTED,
697 "GetTcpStatisticsEx(&stats, AF_BAN) returned %d, expected ERROR_INVALID_PARAMETER\n", apiReturn);
699 apiReturn = pGetTcpStatisticsEx(&stats, AF_INET);
700 ok(apiReturn == NO_ERROR, "GetTcpStatisticsEx returned %d, expected NO_ERROR\n", apiReturn);
701 if (apiReturn == NO_ERROR && winetest_debug > 1)
703 trace( "TCP IPv4 Ex stats:\n" );
704 trace( " dwRtoAlgorithm: %u\n", U(stats).dwRtoAlgorithm );
705 trace( " dwRtoMin: %u\n", stats.dwRtoMin );
706 trace( " dwRtoMax: %u\n", stats.dwRtoMax );
707 trace( " dwMaxConn: %u\n", stats.dwMaxConn );
708 trace( " dwActiveOpens: %u\n", stats.dwActiveOpens );
709 trace( " dwPassiveOpens: %u\n", stats.dwPassiveOpens );
710 trace( " dwAttemptFails: %u\n", stats.dwAttemptFails );
711 trace( " dwEstabResets: %u\n", stats.dwEstabResets );
712 trace( " dwCurrEstab: %u\n", stats.dwCurrEstab );
713 trace( " dwInSegs: %u\n", stats.dwInSegs );
714 trace( " dwOutSegs: %u\n", stats.dwOutSegs );
715 trace( " dwRetransSegs: %u\n", stats.dwRetransSegs );
716 trace( " dwInErrs: %u\n", stats.dwInErrs );
717 trace( " dwOutRsts: %u\n", stats.dwOutRsts );
718 trace( " dwNumConns: %u\n", stats.dwNumConns );
721 apiReturn = pGetTcpStatisticsEx(&stats, AF_INET6);
722 todo_wine ok(apiReturn == NO_ERROR || broken(apiReturn == ERROR_NOT_SUPPORTED),
723 "GetTcpStatisticsEx returned %d, expected NO_ERROR\n", apiReturn);
724 if (apiReturn == NO_ERROR && winetest_debug > 1)
726 trace( "TCP IPv6 Ex stats:\n" );
727 trace( " dwRtoAlgorithm: %u\n", U(stats).dwRtoAlgorithm );
728 trace( " dwRtoMin: %u\n", stats.dwRtoMin );
729 trace( " dwRtoMax: %u\n", stats.dwRtoMax );
730 trace( " dwMaxConn: %u\n", stats.dwMaxConn );
731 trace( " dwActiveOpens: %u\n", stats.dwActiveOpens );
732 trace( " dwPassiveOpens: %u\n", stats.dwPassiveOpens );
733 trace( " dwAttemptFails: %u\n", stats.dwAttemptFails );
734 trace( " dwEstabResets: %u\n", stats.dwEstabResets );
735 trace( " dwCurrEstab: %u\n", stats.dwCurrEstab );
736 trace( " dwInSegs: %u\n", stats.dwInSegs );
737 trace( " dwOutSegs: %u\n", stats.dwOutSegs );
738 trace( " dwRetransSegs: %u\n", stats.dwRetransSegs );
739 trace( " dwInErrs: %u\n", stats.dwInErrs );
740 trace( " dwOutRsts: %u\n", stats.dwOutRsts );
741 trace( " dwNumConns: %u\n", stats.dwNumConns );
745 static void testGetUdpStatisticsEx(void)
747 DWORD apiReturn;
748 MIB_UDPSTATS stats;
750 if (!pGetUdpStatisticsEx)
752 win_skip( "GetUdpStatisticsEx not available\n" );
753 return;
756 apiReturn = pGetUdpStatisticsEx(NULL, AF_INET);
757 ok(apiReturn == ERROR_INVALID_PARAMETER,
758 "GetUdpStatisticsEx(NULL, AF_INET); returned %d, expected ERROR_INVALID_PARAMETER\n", apiReturn);
760 apiReturn = pGetUdpStatisticsEx(&stats, AF_BAN);
761 ok(apiReturn == ERROR_INVALID_PARAMETER || apiReturn == ERROR_NOT_SUPPORTED,
762 "GetUdpStatisticsEx(&stats, AF_BAN) returned %d, expected ERROR_INVALID_PARAMETER\n", apiReturn);
764 apiReturn = pGetUdpStatisticsEx(&stats, AF_INET);
765 ok(apiReturn == NO_ERROR, "GetUdpStatisticsEx returned %d, expected NO_ERROR\n", apiReturn);
766 if (apiReturn == NO_ERROR && winetest_debug > 1)
768 trace( "UDP IPv4 Ex stats:\n" );
769 trace( " dwInDatagrams: %u\n", stats.dwInDatagrams );
770 trace( " dwNoPorts: %u\n", stats.dwNoPorts );
771 trace( " dwInErrors: %u\n", stats.dwInErrors );
772 trace( " dwOutDatagrams: %u\n", stats.dwOutDatagrams );
773 trace( " dwNumAddrs: %u\n", stats.dwNumAddrs );
776 apiReturn = pGetUdpStatisticsEx(&stats, AF_INET6);
777 ok(apiReturn == NO_ERROR || broken(apiReturn == ERROR_NOT_SUPPORTED),
778 "GetUdpStatisticsEx returned %d, expected NO_ERROR\n", apiReturn);
779 if (apiReturn == NO_ERROR && winetest_debug > 1)
781 trace( "UDP IPv6 Ex stats:\n" );
782 trace( " dwInDatagrams: %u\n", stats.dwInDatagrams );
783 trace( " dwNoPorts: %u\n", stats.dwNoPorts );
784 trace( " dwInErrors: %u\n", stats.dwInErrors );
785 trace( " dwOutDatagrams: %u\n", stats.dwOutDatagrams );
786 trace( " dwNumAddrs: %u\n", stats.dwNumAddrs );
790 static void testGetTcpTable(void)
792 if (pGetTcpTable) {
793 DWORD apiReturn;
794 ULONG dwSize = 0;
796 apiReturn = pGetTcpTable(NULL, &dwSize, FALSE);
797 if (apiReturn == ERROR_NOT_SUPPORTED) {
798 skip("GetTcpTable is not supported\n");
799 return;
801 ok(apiReturn == ERROR_INSUFFICIENT_BUFFER ||
802 broken(apiReturn == ERROR_NO_DATA), /* win95 */
803 "GetTcpTable(NULL, &dwSize, FALSE) returned %d, expected ERROR_INSUFFICIENT_BUFFER\n",
804 apiReturn);
805 if (apiReturn == ERROR_INSUFFICIENT_BUFFER) {
806 PMIB_TCPTABLE buf = HeapAlloc(GetProcessHeap(), 0, dwSize);
808 apiReturn = pGetTcpTable(buf, &dwSize, FALSE);
809 ok(apiReturn == NO_ERROR,
810 "GetTcpTable(buf, &dwSize, FALSE) returned %d, expected NO_ERROR\n",
811 apiReturn);
813 if (apiReturn == NO_ERROR && winetest_debug > 1)
815 DWORD i;
816 trace( "TCP table: %u entries\n", buf->dwNumEntries );
817 for (i = 0; i < buf->dwNumEntries; i++)
819 char buffer[40];
820 sprintf( buffer, "local %s:%u",
821 ntoa(buf->table[i].dwLocalAddr), ntohs(buf->table[i].dwLocalPort) );
822 trace( "%u: %s remote %s:%u state %u\n",
823 i, buffer, ntoa( buf->table[i].dwRemoteAddr ),
824 ntohs(buf->table[i].dwRemotePort), U(buf->table[i]).dwState );
827 HeapFree(GetProcessHeap(), 0, buf);
832 static void testGetUdpTable(void)
834 if (pGetUdpTable) {
835 DWORD apiReturn;
836 ULONG dwSize = 0;
838 apiReturn = pGetUdpTable(NULL, &dwSize, FALSE);
839 if (apiReturn == ERROR_NOT_SUPPORTED) {
840 skip("GetUdpTable is not supported\n");
841 return;
843 ok(apiReturn == ERROR_INSUFFICIENT_BUFFER,
844 "GetUdpTable(NULL, &dwSize, FALSE) returned %d, expected ERROR_INSUFFICIENT_BUFFER\n",
845 apiReturn);
846 if (apiReturn == ERROR_INSUFFICIENT_BUFFER) {
847 PMIB_UDPTABLE buf = HeapAlloc(GetProcessHeap(), 0, dwSize);
849 apiReturn = pGetUdpTable(buf, &dwSize, FALSE);
850 ok(apiReturn == NO_ERROR,
851 "GetUdpTable(buf, &dwSize, FALSE) returned %d, expected NO_ERROR\n",
852 apiReturn);
854 if (apiReturn == NO_ERROR && winetest_debug > 1)
856 DWORD i;
857 trace( "UDP table: %u entries\n", buf->dwNumEntries );
858 for (i = 0; i < buf->dwNumEntries; i++)
859 trace( "%u: %s:%u\n",
860 i, ntoa( buf->table[i].dwLocalAddr ), ntohs(buf->table[i].dwLocalPort) );
862 HeapFree(GetProcessHeap(), 0, buf);
867 static void testSetTcpEntry(void)
869 DWORD ret;
870 MIB_TCPROW row;
872 memset(&row, 0, sizeof(row));
873 if(0) /* This test crashes in OS >= VISTA */
875 ret = pSetTcpEntry(NULL);
876 ok( ret == ERROR_INVALID_PARAMETER, "got %u, expected %u\n", ret, ERROR_INVALID_PARAMETER);
879 ret = pSetTcpEntry(&row);
880 if (ret == ERROR_NETWORK_ACCESS_DENIED)
882 win_skip("SetTcpEntry failed with access error. Skipping test.\n");
883 return;
885 todo_wine ok( ret == ERROR_INVALID_PARAMETER, "got %u, expected %u\n", ret, ERROR_INVALID_PARAMETER);
887 U(row).dwState = MIB_TCP_STATE_DELETE_TCB;
888 ret = pSetTcpEntry(&row);
889 todo_wine ok( ret == ERROR_MR_MID_NOT_FOUND || broken(ret == ERROR_INVALID_PARAMETER),
890 "got %u, expected %u\n", ret, ERROR_MR_MID_NOT_FOUND);
893 static void testIcmpSendEcho(void)
895 HANDLE icmp;
896 char senddata[32], replydata[sizeof(senddata) + sizeof(ICMP_ECHO_REPLY)];
897 DWORD ret, error, replysz = sizeof(replydata);
898 IPAddr address;
900 if (!pIcmpSendEcho || !pIcmpCreateFile)
902 win_skip( "IcmpSendEcho or IcmpCreateFile not available\n" );
903 return;
905 memset(senddata, 0, sizeof(senddata));
907 address = htonl(INADDR_LOOPBACK);
908 SetLastError(0xdeadbeef);
909 ret = pIcmpSendEcho(INVALID_HANDLE_VALUE, address, senddata, sizeof(senddata), NULL, replydata, replysz, 1000);
910 error = GetLastError();
911 ok (!ret, "IcmpSendEcho succeeded unexpectedly\n");
912 todo_wine
913 ok (error == ERROR_INVALID_PARAMETER
914 || broken(error == ERROR_INVALID_HANDLE) /* <= 2003 */,
915 "expected 87, got %d\n", error);
917 icmp = pIcmpCreateFile();
918 if (icmp == INVALID_HANDLE_VALUE)
920 error = GetLastError();
921 if (error == ERROR_ACCESS_DENIED)
923 skip ("ICMP is not available.\n");
924 return;
927 ok (icmp != INVALID_HANDLE_VALUE, "IcmpCreateFile failed unexpectedly with error %d\n", GetLastError());
929 address = 0;
930 SetLastError(0xdeadbeef);
931 ret = pIcmpSendEcho(icmp, address, senddata, sizeof(senddata), NULL, replydata, replysz, 1000);
932 error = GetLastError();
933 ok (!ret, "IcmpSendEcho succeeded unexpectedly\n");
934 ok (error == ERROR_INVALID_NETNAME
935 || broken(error == IP_BAD_DESTINATION) /* <= 2003 */,
936 "expected 1214, got %d\n", error);
938 address = htonl(INADDR_LOOPBACK);
939 if (0) /* crashes in XP */
941 ret = pIcmpSendEcho(icmp, address, NULL, sizeof(senddata), NULL, replydata, replysz, 1000);
942 ok (!ret, "IcmpSendEcho succeeded unexpectedly\n");
945 SetLastError(0xdeadbeef);
946 ret = pIcmpSendEcho(icmp, address, senddata, 0, NULL, replydata, replysz, 1000);
947 error = GetLastError();
948 ok (ret, "IcmpSendEcho failed unexpectedly with error %d\n", error);
950 SetLastError(0xdeadbeef);
951 ret = pIcmpSendEcho(icmp, address, NULL, 0, NULL, replydata, replysz, 1000);
952 error = GetLastError();
953 ok (ret, "IcmpSendEcho failed unexpectedly with error %d\n", error);
955 if (0) /* crashes in wine, remove IF when fixed */
957 SetLastError(0xdeadbeef);
958 ret = pIcmpSendEcho(icmp, address, senddata, sizeof(senddata), NULL, NULL, replysz, 1000);
959 error = GetLastError();
960 ok (!ret, "IcmpSendEcho succeeded unexpectedly\n");
961 ok (error == ERROR_INVALID_PARAMETER, "expected 87, got %d\n", error);
964 SetLastError(0xdeadbeef);
965 ret = pIcmpSendEcho(icmp, address, senddata, sizeof(senddata), NULL, replydata, 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 ret = pIcmpSendEcho(icmp, address, senddata, sizeof(senddata), NULL, NULL, 0, 1000);
975 error = GetLastError();
976 ok (!ret, "IcmpSendEcho succeeded unexpectedly\n");
977 todo_wine
978 ok (error == ERROR_INVALID_PARAMETER
979 || broken(error == ERROR_INSUFFICIENT_BUFFER) /* <= 2003 */,
980 "expected 87, got %d\n", error);
982 SetLastError(0xdeadbeef);
983 replysz = sizeof(replydata) - 1;
984 ret = pIcmpSendEcho(icmp, address, senddata, sizeof(senddata), NULL, replydata, replysz, 1000);
985 error = GetLastError();
986 todo_wine {
987 ok (!ret, "IcmpSendEcho succeeded unexpectedly\n");
988 ok (error == IP_GENERAL_FAILURE
989 || broken(error == IP_BUF_TOO_SMALL) /* <= 2003 */,
990 "expected 11050, got %d\n", error);
993 SetLastError(0xdeadbeef);
994 replysz = sizeof(ICMP_ECHO_REPLY);
995 ret = pIcmpSendEcho(icmp, address, senddata, 0, NULL, replydata, replysz, 1000);
996 error = GetLastError();
997 todo_wine
998 ok (ret, "IcmpSendEcho failed unexpectedly with error %d\n", error);
1000 SetLastError(0xdeadbeef);
1001 replysz = sizeof(ICMP_ECHO_REPLY) + ICMP_MINLEN;
1002 ret = pIcmpSendEcho(icmp, address, senddata, ICMP_MINLEN, NULL, replydata, replysz, 1000);
1003 error = GetLastError();
1004 todo_wine
1005 ok (ret, "IcmpSendEcho failed unexpectedly with error %d\n", error);
1007 SetLastError(0xdeadbeef);
1008 replysz = sizeof(ICMP_ECHO_REPLY) + ICMP_MINLEN;
1009 ret = pIcmpSendEcho(icmp, address, senddata, ICMP_MINLEN + 1, NULL, replydata, replysz, 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 SetLastError(0xdeadbeef);
1018 ret = pIcmpSendEcho(icmp, address, senddata, ICMP_MINLEN, NULL, replydata, replysz - 1, 1000);
1019 error = GetLastError();
1020 ok (!ret, "IcmpSendEcho succeeded unexpectedly\n");
1021 todo_wine
1022 ok (error == IP_GENERAL_FAILURE
1023 || broken(error == IP_BUF_TOO_SMALL) /* <= 2003 */,
1024 "expected 11050, got %d\n", error);
1026 /* in windows >= vista the timeout can't be invalid */
1027 SetLastError(0xdeadbeef);
1028 replysz = sizeof(replydata);
1029 ret = pIcmpSendEcho(icmp, address, senddata, sizeof(senddata), NULL, replydata, replysz, 0);
1030 error = GetLastError();
1031 if (!ret) ok(error == ERROR_INVALID_PARAMETER, "expected 87, got %d\n", error);
1033 SetLastError(0xdeadbeef);
1034 ret = pIcmpSendEcho(icmp, address, senddata, sizeof(senddata), NULL, replydata, replysz, -1);
1035 error = GetLastError();
1036 if (!ret) ok(error == ERROR_INVALID_PARAMETER, "expected 87, got %d\n", error);
1038 /* real ping test */
1039 SetLastError(0xdeadbeef);
1040 address = htonl(INADDR_LOOPBACK);
1041 ret = pIcmpSendEcho(icmp, address, senddata, sizeof(senddata), NULL, replydata, replysz, 1000);
1042 error = GetLastError();
1043 if (ret)
1045 PICMP_ECHO_REPLY pong = (PICMP_ECHO_REPLY) replydata;
1046 trace ("send addr : %s\n", ntoa(address));
1047 trace ("send size : %u\n", sizeof(senddata));
1048 trace ("reply addr : %s\n", ntoa(pong->Address));
1049 trace ("reply size : %u\n", replysz);
1050 trace ("roundtrip : %u ms\n", pong->RoundTripTime);
1051 trace ("status : %u\n", pong->Status);
1052 trace ("recv size : %u\n", pong->DataSize);
1053 trace ("ttl : %u\n", pong->Options.Ttl);
1054 trace ("flags : 0x%x\n", pong->Options.Flags);
1056 else
1058 skip ("Failed to ping with error %d, is lo interface down?.\n", error);
1063 still-to-be-tested NT4-onward functions:
1064 CreateIpForwardEntry
1065 DeleteIpForwardEntry
1066 CreateIpNetEntry
1067 DeleteIpNetEntry
1068 GetFriendlyIfIndex
1069 GetRTTAndHopCount
1070 SetIfEntry
1071 SetIpForwardEntry
1072 SetIpNetEntry
1073 SetIpStatistics
1074 SetIpTTL
1076 static void testWinNT4Functions(void)
1078 testGetNumberOfInterfaces();
1079 testGetIpAddrTable();
1080 testGetIfTable();
1081 testGetIpForwardTable();
1082 testGetIpNetTable();
1083 testGetIcmpStatistics();
1084 testGetIpStatistics();
1085 testGetTcpStatistics();
1086 testGetUdpStatistics();
1087 testGetIcmpStatisticsEx();
1088 testGetIpStatisticsEx();
1089 testGetTcpStatisticsEx();
1090 testGetUdpStatisticsEx();
1091 testGetTcpTable();
1092 testGetUdpTable();
1093 testSetTcpEntry();
1094 testIcmpSendEcho();
1097 static void testGetInterfaceInfo(void)
1099 if (pGetInterfaceInfo) {
1100 DWORD apiReturn;
1101 ULONG len = 0;
1103 apiReturn = pGetInterfaceInfo(NULL, NULL);
1104 if (apiReturn == ERROR_NOT_SUPPORTED) {
1105 skip("GetInterfaceInfo is not supported\n");
1106 return;
1108 ok(apiReturn == ERROR_INVALID_PARAMETER,
1109 "GetInterfaceInfo returned %d, expected ERROR_INVALID_PARAMETER\n",
1110 apiReturn);
1111 apiReturn = pGetInterfaceInfo(NULL, &len);
1112 ok(apiReturn == ERROR_INSUFFICIENT_BUFFER,
1113 "GetInterfaceInfo returned %d, expected ERROR_INSUFFICIENT_BUFFER\n",
1114 apiReturn);
1115 if (apiReturn == ERROR_INSUFFICIENT_BUFFER) {
1116 PIP_INTERFACE_INFO buf = HeapAlloc(GetProcessHeap(), 0, len);
1118 apiReturn = pGetInterfaceInfo(buf, &len);
1119 ok(apiReturn == NO_ERROR,
1120 "GetInterfaceInfo(buf, &dwSize) returned %d, expected NO_ERROR\n",
1121 apiReturn);
1122 HeapFree(GetProcessHeap(), 0, buf);
1127 static void testGetAdaptersInfo(void)
1129 if (pGetAdaptersInfo) {
1130 DWORD apiReturn;
1131 ULONG len = 0;
1133 apiReturn = pGetAdaptersInfo(NULL, NULL);
1134 if (apiReturn == ERROR_NOT_SUPPORTED) {
1135 skip("GetAdaptersInfo is not supported\n");
1136 return;
1138 ok(apiReturn == ERROR_INVALID_PARAMETER,
1139 "GetAdaptersInfo returned %d, expected ERROR_INVALID_PARAMETER\n",
1140 apiReturn);
1141 apiReturn = pGetAdaptersInfo(NULL, &len);
1142 ok(apiReturn == ERROR_NO_DATA || apiReturn == ERROR_BUFFER_OVERFLOW,
1143 "GetAdaptersInfo returned %d, expected ERROR_NO_DATA or ERROR_BUFFER_OVERFLOW\n",
1144 apiReturn);
1145 if (apiReturn == ERROR_NO_DATA)
1146 ; /* no adapter's, that's okay */
1147 else if (apiReturn == ERROR_BUFFER_OVERFLOW) {
1148 PIP_ADAPTER_INFO ptr, buf = HeapAlloc(GetProcessHeap(), 0, len);
1150 apiReturn = pGetAdaptersInfo(buf, &len);
1151 ok(apiReturn == NO_ERROR,
1152 "GetAdaptersInfo(buf, &dwSize) returned %d, expected NO_ERROR\n",
1153 apiReturn);
1154 ptr = buf;
1155 while (ptr) {
1156 ok(ptr->IpAddressList.IpAddress.String[0], "A valid IP must be present\n");
1157 ok(ptr->IpAddressList.IpMask.String[0], "A valid mask must be present\n");
1158 trace("Adapter '%s', IP %s, Mask %s\n", ptr->AdapterName,
1159 ptr->IpAddressList.IpAddress.String, ptr->IpAddressList.IpMask.String);
1160 ptr = ptr->Next;
1162 HeapFree(GetProcessHeap(), 0, buf);
1167 static void testGetNetworkParams(void)
1169 if (pGetNetworkParams) {
1170 DWORD apiReturn;
1171 ULONG len = 0;
1173 apiReturn = pGetNetworkParams(NULL, NULL);
1174 if (apiReturn == ERROR_NOT_SUPPORTED) {
1175 skip("GetNetworkParams is not supported\n");
1176 return;
1178 ok(apiReturn == ERROR_INVALID_PARAMETER,
1179 "GetNetworkParams returned %d, expected ERROR_INVALID_PARAMETER\n",
1180 apiReturn);
1181 apiReturn = pGetNetworkParams(NULL, &len);
1182 ok(apiReturn == ERROR_BUFFER_OVERFLOW,
1183 "GetNetworkParams returned %d, expected ERROR_BUFFER_OVERFLOW\n",
1184 apiReturn);
1185 if (apiReturn == ERROR_BUFFER_OVERFLOW) {
1186 PFIXED_INFO buf = HeapAlloc(GetProcessHeap(), 0, len);
1188 apiReturn = pGetNetworkParams(buf, &len);
1189 ok(apiReturn == NO_ERROR,
1190 "GetNetworkParams(buf, &dwSize) returned %d, expected NO_ERROR\n",
1191 apiReturn);
1192 HeapFree(GetProcessHeap(), 0, buf);
1198 still-to-be-tested 98-onward functions:
1199 GetBestInterface
1200 GetBestRoute
1201 IpReleaseAddress
1202 IpRenewAddress
1204 static DWORD CALLBACK testWin98Functions(void *p)
1206 testGetInterfaceInfo();
1207 testGetAdaptersInfo();
1208 testGetNetworkParams();
1209 return 0;
1212 static void testGetPerAdapterInfo(void)
1214 DWORD ret, needed;
1215 void *buffer;
1217 if (!pGetPerAdapterInfo) return;
1218 ret = pGetPerAdapterInfo(1, NULL, NULL);
1219 if (ret == ERROR_NOT_SUPPORTED) {
1220 skip("GetPerAdapterInfo is not supported\n");
1221 return;
1223 ok( ret == ERROR_INVALID_PARAMETER, "got %u instead of ERROR_INVALID_PARAMETER\n", ret );
1224 needed = 0xdeadbeef;
1225 ret = pGetPerAdapterInfo(1, NULL, &needed);
1226 if (ret == ERROR_NO_DATA) return; /* no such adapter */
1227 ok( ret == ERROR_BUFFER_OVERFLOW, "got %u instead of ERROR_BUFFER_OVERFLOW\n", ret );
1228 ok( needed != 0xdeadbeef, "needed not set\n" );
1229 buffer = HeapAlloc( GetProcessHeap(), 0, needed );
1230 ret = pGetPerAdapterInfo(1, buffer, &needed);
1231 ok( ret == NO_ERROR, "got %u instead of NO_ERROR\n", ret );
1232 HeapFree( GetProcessHeap(), 0, buffer );
1235 static void testNotifyAddrChange(void)
1237 DWORD ret, bytes;
1238 OVERLAPPED overlapped;
1239 HANDLE handle;
1240 BOOL success;
1242 if (!pNotifyAddrChange)
1244 win_skip("NotifyAddrChange not present\n");
1245 return;
1247 if (!pCancelIPChangeNotify)
1249 win_skip("CancelIPChangeNotify not present\n");
1250 return;
1253 handle = NULL;
1254 ZeroMemory(&overlapped, sizeof(overlapped));
1255 ret = pNotifyAddrChange(&handle, &overlapped);
1256 if (ret == ERROR_NOT_SUPPORTED)
1258 win_skip("NotifyAddrChange is not supported\n");
1259 return;
1261 ok(ret == ERROR_IO_PENDING, "NotifyAddrChange returned %d, expected ERROR_IO_PENDING\n", ret);
1262 ret = GetLastError();
1263 todo_wine ok(ret == ERROR_IO_PENDING, "GetLastError returned %d, expected ERROR_IO_PENDING\n", ret);
1264 success = pCancelIPChangeNotify(&overlapped);
1265 todo_wine ok(success == TRUE, "CancelIPChangeNotify returned FALSE, expected TRUE\n");
1267 ZeroMemory(&overlapped, sizeof(overlapped));
1268 success = pCancelIPChangeNotify(&overlapped);
1269 ok(success == FALSE, "CancelIPChangeNotify returned TRUE, expected FALSE\n");
1271 handle = NULL;
1272 ZeroMemory(&overlapped, sizeof(overlapped));
1273 overlapped.hEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
1274 ret = pNotifyAddrChange(&handle, &overlapped);
1275 ok(ret == ERROR_IO_PENDING, "NotifyAddrChange returned %d, expected ERROR_IO_PENDING\n", ret);
1276 todo_wine ok(handle != INVALID_HANDLE_VALUE, "NotifyAddrChange returned invalid file handle\n");
1277 success = GetOverlappedResult(handle, &overlapped, &bytes, FALSE);
1278 ok(success == FALSE, "GetOverlappedResult returned TRUE, expected FALSE\n");
1279 ret = GetLastError();
1280 ok(ret == ERROR_IO_INCOMPLETE, "GetLastError returned %d, expected ERROR_IO_INCOMPLETE\n", ret);
1281 success = pCancelIPChangeNotify(&overlapped);
1282 todo_wine ok(success == TRUE, "CancelIPChangeNotify returned FALSE, expected TRUE\n");
1284 if (winetest_interactive)
1286 handle = NULL;
1287 ZeroMemory(&overlapped, sizeof(overlapped));
1288 overlapped.hEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
1289 trace("Testing asynchronous ipv4 address change notification. Please "
1290 "change the ipv4 address of one of your network interfaces\n");
1291 ret = pNotifyAddrChange(&handle, &overlapped);
1292 ok(ret == ERROR_IO_PENDING, "NotifyAddrChange returned %d, expected NO_ERROR\n", ret);
1293 success = GetOverlappedResult(handle, &overlapped, &bytes, TRUE);
1294 ok(success == TRUE, "GetOverlappedResult returned FALSE, expected TRUE\n");
1297 /* test synchronous functionality */
1298 if (winetest_interactive)
1300 trace("Testing synchronous ipv4 address change notification. Please "
1301 "change the ipv4 address of one of your network interfaces\n");
1302 ret = pNotifyAddrChange(NULL, NULL);
1303 todo_wine ok(ret == NO_ERROR, "NotifyAddrChange returned %d, expected NO_ERROR\n", ret);
1308 still-to-be-tested 2K-onward functions:
1309 AddIPAddress
1310 CreateProxyArpEntry
1311 DeleteIPAddress
1312 DeleteProxyArpEntry
1313 EnableRouter
1314 FlushIpNetTable
1315 GetAdapterIndex
1316 NotifyRouteChange + CancelIPChangeNotify
1317 SendARP
1318 UnenableRouter
1320 static void testWin2KFunctions(void)
1322 testGetPerAdapterInfo();
1323 testNotifyAddrChange();
1326 static void test_GetAdaptersAddresses(void)
1328 ULONG ret, size, osize, i;
1329 IP_ADAPTER_ADDRESSES *aa, *ptr;
1330 IP_ADAPTER_UNICAST_ADDRESS *ua;
1332 if (!pGetAdaptersAddresses)
1334 win_skip("GetAdaptersAddresses not present\n");
1335 return;
1338 ret = pGetAdaptersAddresses(AF_UNSPEC, 0, NULL, NULL, NULL);
1339 ok(ret == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER got %u\n", ret);
1341 /* size should be ignored and overwritten if buffer is NULL */
1342 size = 0x7fffffff;
1343 ret = pGetAdaptersAddresses(AF_UNSPEC, 0, NULL, NULL, &size);
1344 ok(ret == ERROR_BUFFER_OVERFLOW, "expected ERROR_BUFFER_OVERFLOW, got %u\n", ret);
1345 if (ret != ERROR_BUFFER_OVERFLOW) return;
1347 ptr = HeapAlloc(GetProcessHeap(), 0, size);
1348 ret = pGetAdaptersAddresses(AF_UNSPEC, 0, NULL, ptr, &size);
1349 ok(!ret, "expected ERROR_SUCCESS got %u\n", ret);
1350 HeapFree(GetProcessHeap(), 0, ptr);
1352 /* higher size must not be changed to lower size */
1353 size *= 2;
1354 osize = size;
1355 ptr = HeapAlloc(GetProcessHeap(), 0, osize);
1356 ret = pGetAdaptersAddresses(AF_UNSPEC, 0, NULL, ptr, &osize);
1357 ok(!ret, "expected ERROR_SUCCESS got %u\n", ret);
1358 ok(osize == size, "expected %d, got %d\n", size, osize);
1360 for (aa = ptr; !ret && aa; aa = aa->Next)
1362 char temp[128];
1364 ok(S(U(*aa)).Length == sizeof(IP_ADAPTER_ADDRESSES_LH) ||
1365 S(U(*aa)).Length == sizeof(IP_ADAPTER_ADDRESSES_XP),
1366 "Unknown structure size of %u bytes\n", S(U(*aa)).Length);
1367 ok(aa->DnsSuffix != NULL, "DnsSuffix is not a valid pointer\n");
1368 ok(aa->Description != NULL, "Description is not a valid pointer\n");
1369 ok(aa->FriendlyName != NULL, "FriendlyName is not a valid pointer\n");
1371 trace("\n");
1372 trace("Length: %u\n", S(U(*aa)).Length);
1373 trace("IfIndex: %u\n", S(U(*aa)).IfIndex);
1374 trace("Next: %p\n", aa->Next);
1375 trace("AdapterName: %s\n", aa->AdapterName);
1376 trace("FirstUnicastAddress: %p\n", aa->FirstUnicastAddress);
1377 ua = aa->FirstUnicastAddress;
1378 while (ua)
1380 ok(ua->PrefixOrigin != IpPrefixOriginOther,
1381 "bad address config value %d\n", ua->PrefixOrigin);
1382 ok(ua->SuffixOrigin != IpSuffixOriginOther,
1383 "bad address config value %d\n", ua->PrefixOrigin);
1384 /* Address configured manually or from DHCP server? */
1385 if (ua->PrefixOrigin == IpPrefixOriginManual ||
1386 ua->PrefixOrigin == IpPrefixOriginDhcp)
1388 ok(ua->ValidLifetime, "expected non-zero value\n");
1389 ok(ua->PreferredLifetime, "expected non-zero value\n");
1390 ok(ua->LeaseLifetime, "expected non-zero\n");
1392 /* Is the address ok in the network (not duplicated)? */
1393 ok(ua->DadState != IpDadStateInvalid && ua->DadState != IpDadStateDuplicate,
1394 "bad address duplication value %d\n", ua->DadState);
1395 trace("\tLength: %u\n", S(U(*ua)).Length);
1396 trace("\tFlags: 0x%08x\n", S(U(*ua)).Flags);
1397 trace("\tNext: %p\n", ua->Next);
1398 trace("\tAddress.lpSockaddr: %p\n", ua->Address.lpSockaddr);
1399 trace("\tAddress.iSockaddrLength: %d\n", ua->Address.iSockaddrLength);
1400 trace("\tPrefixOrigin: %u\n", ua->PrefixOrigin);
1401 trace("\tSuffixOrigin: %u\n", ua->SuffixOrigin);
1402 trace("\tDadState: %u\n", ua->DadState);
1403 trace("\tValidLifetime: %u seconds\n", ua->ValidLifetime);
1404 trace("\tPreferredLifetime: %u seconds\n", ua->PreferredLifetime);
1405 trace("\tLeaseLifetime: %u seconds\n", ua->LeaseLifetime);
1406 trace("\n");
1407 ua = ua->Next;
1409 trace("FirstAnycastAddress: %p\n", aa->FirstAnycastAddress);
1410 trace("FirstMulticastAddress: %p\n", aa->FirstMulticastAddress);
1411 trace("FirstDnsServerAddress: %p\n", aa->FirstDnsServerAddress);
1412 trace("DnsSuffix: %s %p\n", wine_dbgstr_w(aa->DnsSuffix), aa->DnsSuffix);
1413 trace("Description: %s %p\n", wine_dbgstr_w(aa->Description), aa->Description);
1414 trace("FriendlyName: %s %p\n", wine_dbgstr_w(aa->FriendlyName), aa->FriendlyName);
1415 trace("PhysicalAddressLength: %u\n", aa->PhysicalAddressLength);
1416 for (i = 0; i < aa->PhysicalAddressLength; i++)
1417 sprintf(temp + i * 3, "%02X-", aa->PhysicalAddress[i]);
1418 temp[i ? i * 3 - 1 : 0] = '\0';
1419 trace("PhysicalAddress: %s\n", temp);
1420 trace("Flags: 0x%08x\n", aa->Flags);
1421 trace("Mtu: %u\n", aa->Mtu);
1422 trace("IfType: %u\n", aa->IfType);
1423 trace("OperStatus: %u\n", aa->OperStatus);
1424 trace("Ipv6IfIndex: %u\n", aa->Ipv6IfIndex);
1425 for (i = 0, temp[0] = '\0'; i < sizeof(aa->ZoneIndices) / sizeof(aa->ZoneIndices[0]); i++)
1426 sprintf(temp + strlen(temp), "%d ", aa->ZoneIndices[i]);
1427 trace("ZoneIndices: %s\n", temp);
1428 trace("FirstPrefix: %p\n", aa->FirstPrefix);
1430 if (S(U(*aa)).Length < sizeof(IP_ADAPTER_ADDRESSES_LH)) continue;
1431 trace("TransmitLinkSpeed: %s\n", debugstr_longlong(aa->TransmitLinkSpeed));
1432 trace("ReceiveLinkSpeed: %s\n", debugstr_longlong(aa->ReceiveLinkSpeed));
1433 trace("FirstWinsServerAddress:%p\n", aa->FirstWinsServerAddress);
1434 trace("FirstGatewayAddress: %p\n", aa->FirstGatewayAddress);
1435 trace("Ipv4Metric: %u\n", aa->Ipv4Metric);
1436 trace("Ipv6Metric: %u\n", aa->Ipv6Metric);
1437 trace("Luid: %p\n", &aa->Luid);
1438 trace("Dhcpv4Server: %p\n", &aa->Dhcpv4Server);
1439 trace("CompartmentId: %u\n", aa->CompartmentId);
1440 trace("NetworkGuid: %s\n", wine_dbgstr_guid((GUID*) &aa->NetworkGuid));
1441 trace("ConnectionType: %u\n", aa->ConnectionType);
1442 trace("TunnelType: %u\n", aa->TunnelType);
1443 trace("Dhcpv6Server: %p\n", &aa->Dhcpv6Server);
1444 trace("Dhcpv6ClientDuidLength:%u\n", aa->Dhcpv6ClientDuidLength);
1445 trace("Dhcpv6ClientDuid: %p\n", aa->Dhcpv6ClientDuid);
1446 trace("Dhcpv6Iaid: %u\n", aa->Dhcpv6Iaid);
1447 trace("FirstDnsSuffix: %p\n", aa->FirstDnsSuffix);
1448 trace("\n");
1450 HeapFree(GetProcessHeap(), 0, ptr);
1453 static void test_GetExtendedTcpTable(void)
1455 DWORD ret, size;
1456 MIB_TCPTABLE *table;
1457 MIB_TCPTABLE_OWNER_PID *table_pid;
1458 MIB_TCPTABLE_OWNER_MODULE *table_module;
1460 if (!pGetExtendedTcpTable)
1462 win_skip("GetExtendedTcpTable not available\n");
1463 return;
1465 ret = pGetExtendedTcpTable( NULL, NULL, TRUE, AF_INET, TCP_TABLE_BASIC_ALL, 0 );
1466 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
1468 size = 0;
1469 ret = pGetExtendedTcpTable( NULL, &size, TRUE, AF_INET, TCP_TABLE_BASIC_ALL, 0 );
1470 ok( ret == ERROR_INSUFFICIENT_BUFFER, "got %u\n", ret );
1472 table = HeapAlloc( GetProcessHeap(), 0, size );
1473 ret = pGetExtendedTcpTable( table, &size, TRUE, AF_INET, TCP_TABLE_BASIC_ALL, 0 );
1474 ok( ret == ERROR_SUCCESS, "got %u\n", ret );
1475 HeapFree( GetProcessHeap(), 0, table );
1477 size = 0;
1478 ret = pGetExtendedTcpTable( NULL, &size, TRUE, AF_INET, TCP_TABLE_BASIC_LISTENER, 0 );
1479 ok( ret == ERROR_INSUFFICIENT_BUFFER, "got %u\n", ret );
1481 table = HeapAlloc( GetProcessHeap(), 0, size );
1482 ret = pGetExtendedTcpTable( table, &size, TRUE, AF_INET, TCP_TABLE_BASIC_LISTENER, 0 );
1483 ok( ret == ERROR_SUCCESS, "got %u\n", ret );
1484 HeapFree( GetProcessHeap(), 0, table );
1486 size = 0;
1487 ret = pGetExtendedTcpTable( NULL, &size, TRUE, AF_INET, TCP_TABLE_OWNER_PID_ALL, 0 );
1488 ok( ret == ERROR_INSUFFICIENT_BUFFER, "got %u\n", ret );
1490 table_pid = HeapAlloc( GetProcessHeap(), 0, size );
1491 ret = pGetExtendedTcpTable( table_pid, &size, TRUE, AF_INET, TCP_TABLE_OWNER_PID_ALL, 0 );
1492 ok( ret == ERROR_SUCCESS, "got %u\n", ret );
1493 HeapFree( GetProcessHeap(), 0, table_pid );
1495 size = 0;
1496 ret = pGetExtendedTcpTable( NULL, &size, TRUE, AF_INET, TCP_TABLE_OWNER_PID_LISTENER, 0 );
1497 ok( ret == ERROR_INSUFFICIENT_BUFFER, "got %u\n", ret );
1499 table_pid = HeapAlloc( GetProcessHeap(), 0, size );
1500 ret = pGetExtendedTcpTable( table_pid, &size, TRUE, AF_INET, TCP_TABLE_OWNER_PID_LISTENER, 0 );
1501 ok( ret == ERROR_SUCCESS, "got %u\n", ret );
1502 HeapFree( GetProcessHeap(), 0, table_pid );
1504 size = 0;
1505 ret = pGetExtendedTcpTable( NULL, &size, TRUE, AF_INET, TCP_TABLE_OWNER_MODULE_ALL, 0 );
1506 ok( ret == ERROR_INSUFFICIENT_BUFFER, "got %u\n", ret );
1508 table_module = HeapAlloc( GetProcessHeap(), 0, size );
1509 ret = pGetExtendedTcpTable( table_module, &size, TRUE, AF_INET, TCP_TABLE_OWNER_MODULE_ALL, 0 );
1510 ok( ret == ERROR_SUCCESS, "got %u\n", ret );
1511 HeapFree( GetProcessHeap(), 0, table_module );
1513 size = 0;
1514 ret = pGetExtendedTcpTable( NULL, &size, TRUE, AF_INET, TCP_TABLE_OWNER_MODULE_LISTENER, 0 );
1515 ok( ret == ERROR_INSUFFICIENT_BUFFER, "got %u\n", ret );
1517 table_module = HeapAlloc( GetProcessHeap(), 0, size );
1518 ret = pGetExtendedTcpTable( table_module, &size, TRUE, AF_INET, TCP_TABLE_OWNER_MODULE_LISTENER, 0 );
1519 ok( ret == ERROR_SUCCESS, "got %u\n", ret );
1520 HeapFree( GetProcessHeap(), 0, table_module );
1523 static void test_GetExtendedUdpTable(void)
1525 DWORD ret, size;
1526 MIB_UDPTABLE *table;
1527 MIB_UDPTABLE_OWNER_PID *table_pid;
1528 MIB_UDPTABLE_OWNER_MODULE *table_module;
1530 if (!pGetExtendedUdpTable)
1532 win_skip("GetExtendedUdpTable not available\n");
1533 return;
1535 ret = pGetExtendedUdpTable( NULL, NULL, TRUE, AF_INET, UDP_TABLE_BASIC, 0 );
1536 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
1538 size = 0;
1539 ret = pGetExtendedUdpTable( NULL, &size, TRUE, AF_INET, UDP_TABLE_BASIC, 0 );
1540 ok( ret == ERROR_INSUFFICIENT_BUFFER, "got %u\n", ret );
1542 table = HeapAlloc( GetProcessHeap(), 0, size );
1543 ret = pGetExtendedUdpTable( table, &size, TRUE, AF_INET, UDP_TABLE_BASIC, 0 );
1544 ok( ret == ERROR_SUCCESS, "got %u\n", ret );
1545 HeapFree( GetProcessHeap(), 0, table );
1547 size = 0;
1548 ret = pGetExtendedUdpTable( NULL, &size, TRUE, AF_INET, UDP_TABLE_OWNER_PID, 0 );
1549 ok( ret == ERROR_INSUFFICIENT_BUFFER, "got %u\n", ret );
1551 table_pid = HeapAlloc( GetProcessHeap(), 0, size );
1552 ret = pGetExtendedUdpTable( table_pid, &size, TRUE, AF_INET, UDP_TABLE_OWNER_PID, 0 );
1553 ok( ret == ERROR_SUCCESS, "got %u\n", ret );
1554 HeapFree( GetProcessHeap(), 0, table_pid );
1556 size = 0;
1557 ret = pGetExtendedUdpTable( NULL, &size, TRUE, AF_INET, UDP_TABLE_OWNER_MODULE, 0 );
1558 ok( ret == ERROR_INSUFFICIENT_BUFFER, "got %u\n", ret );
1560 table_module = HeapAlloc( GetProcessHeap(), 0, size );
1561 ret = pGetExtendedUdpTable( table_module, &size, TRUE, AF_INET, UDP_TABLE_OWNER_MODULE, 0 );
1562 ok( ret == ERROR_SUCCESS, "got %u\n", ret );
1563 HeapFree( GetProcessHeap(), 0, table_module );
1566 START_TEST(iphlpapi)
1569 loadIPHlpApi();
1570 if (hLibrary) {
1571 HANDLE thread;
1573 testWin98OnlyFunctions();
1574 testWinNT4Functions();
1576 /* run testGetXXXX in two threads at once to make sure we don't crash in that case */
1577 thread = CreateThread(NULL, 0, testWin98Functions, NULL, 0, NULL);
1578 testWin98Functions(NULL);
1579 WaitForSingleObject(thread, INFINITE);
1581 testWin2KFunctions();
1582 test_GetAdaptersAddresses();
1583 test_GetExtendedTcpTable();
1584 test_GetExtendedUdpTable();
1585 freeIPHlpApi();