dmime/tests: Check more notification / dirty messages fields.
[wine.git] / dlls / iphlpapi / tests / iphlpapi.c
blobcd19200334578b9c693b45a0eeb0c23a2e0eff02
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 ANSI 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 "winternl.h"
42 #include "ws2tcpip.h"
43 #include "windns.h"
44 #include "iphlpapi.h"
45 #include "icmpapi.h"
46 #include "iprtrmib.h"
47 #include "netioapi.h"
48 #include "wine/test.h"
49 #include <stdio.h>
50 #include <stdlib.h>
52 #define ICMP_MINLEN 8 /* copied from dlls/iphlpapi/ip_icmp.h file */
54 static HMODULE hLibrary = NULL;
56 static DWORD (WINAPI *pAllocateAndGetTcpExTableFromStack)(void**,BOOL,HANDLE,DWORD,DWORD);
57 static DWORD (WINAPI *pGetTcp6Table)(PMIB_TCP6TABLE,PDWORD,BOOL);
58 static DWORD (WINAPI *pGetUdp6Table)(PMIB_UDP6TABLE,PDWORD,BOOL);
59 static DWORD (WINAPI *pGetUnicastIpAddressEntry)(MIB_UNICASTIPADDRESS_ROW*);
60 static DWORD (WINAPI *pGetUnicastIpAddressTable)(ADDRESS_FAMILY,MIB_UNICASTIPADDRESS_TABLE**);
61 static DWORD (WINAPI *pGetExtendedTcpTable)(PVOID,PDWORD,BOOL,ULONG,TCP_TABLE_CLASS,ULONG);
62 static DWORD (WINAPI *pGetExtendedUdpTable)(PVOID,PDWORD,BOOL,ULONG,UDP_TABLE_CLASS,ULONG);
63 static DWORD (WINAPI *pCreateSortedAddressPairs)(const PSOCKADDR_IN6,ULONG,const PSOCKADDR_IN6,ULONG,ULONG,
64 PSOCKADDR_IN6_PAIR*,ULONG*);
65 static DWORD (WINAPI *pConvertLengthToIpv4Mask)(ULONG,ULONG*);
66 static DWORD (WINAPI *pParseNetworkString)(const WCHAR*,DWORD,NET_ADDRESS_INFO*,USHORT*,BYTE*);
67 static DWORD (WINAPI *pNotifyUnicastIpAddressChange)(ADDRESS_FAMILY, PUNICAST_IPADDRESS_CHANGE_CALLBACK,
68 PVOID, BOOLEAN, HANDLE *);
69 static DWORD (WINAPI *pCancelMibChangeNotify2)(HANDLE);
71 DWORD WINAPI ConvertGuidToStringA( const GUID *, char *, DWORD );
72 DWORD WINAPI ConvertGuidToStringW( const GUID *, WCHAR *, DWORD );
73 DWORD WINAPI ConvertStringToGuidW( const WCHAR *, GUID * );
75 static void loadIPHlpApi(void)
77 hLibrary = LoadLibraryA("iphlpapi.dll");
78 if (hLibrary) {
79 pAllocateAndGetTcpExTableFromStack = (void *)GetProcAddress(hLibrary, "AllocateAndGetTcpExTableFromStack");
80 pGetTcp6Table = (void *)GetProcAddress(hLibrary, "GetTcp6Table");
81 pGetUdp6Table = (void *)GetProcAddress(hLibrary, "GetUdp6Table");
82 pGetUnicastIpAddressEntry = (void *)GetProcAddress(hLibrary, "GetUnicastIpAddressEntry");
83 pGetUnicastIpAddressTable = (void *)GetProcAddress(hLibrary, "GetUnicastIpAddressTable");
84 pGetExtendedTcpTable = (void *)GetProcAddress(hLibrary, "GetExtendedTcpTable");
85 pGetExtendedUdpTable = (void *)GetProcAddress(hLibrary, "GetExtendedUdpTable");
86 pCreateSortedAddressPairs = (void *)GetProcAddress(hLibrary, "CreateSortedAddressPairs");
87 pConvertLengthToIpv4Mask = (void *)GetProcAddress(hLibrary, "ConvertLengthToIpv4Mask");
88 pParseNetworkString = (void *)GetProcAddress(hLibrary, "ParseNetworkString");
89 pNotifyUnicastIpAddressChange = (void *)GetProcAddress(hLibrary, "NotifyUnicastIpAddressChange");
90 pCancelMibChangeNotify2 = (void *)GetProcAddress(hLibrary, "CancelMibChangeNotify2");
94 static void freeIPHlpApi(void)
96 FreeLibrary(hLibrary);
99 /* replacement for inet_ntoa */
100 static const char *ntoa( DWORD ip )
102 static char buffers[4][16];
103 static int i = -1;
105 ip = htonl(ip);
106 i = (i + 1) % ARRAY_SIZE(buffers);
107 sprintf( buffers[i], "%lu.%lu.%lu.%lu", (ip >> 24) & 0xff, (ip >> 16) & 0xff, (ip >> 8) & 0xff, ip & 0xff );
108 return buffers[i];
111 static const char *ntoa6( IN6_ADDR *ip )
113 static char buffers[4][40];
114 static int i = -1;
115 unsigned short *p = ip->u.Word;
117 i = (i + 1) % ARRAY_SIZE(buffers);
118 sprintf( buffers[i], "%x:%x:%x:%x:%x:%x:%x:%x",
119 htons(p[0]), htons(p[1]), htons(p[2]), htons(p[3]), htons(p[4]), htons(p[5]), htons(p[6]), htons(p[7]) );
120 return buffers[i];
123 static DWORD ipv4_addr( BYTE b1, BYTE b2, BYTE b3, BYTE b4 )
125 return htonl( (b1 << 24) | (b2 << 16) | (b3 << 8) | b4 );
129 still-to-be-tested 98-only functions:
130 GetUniDirectionalAdapterInfo
132 static void testWin98OnlyFunctions(void)
136 static void testGetNumberOfInterfaces(void)
138 DWORD apiReturn, numInterfaces;
140 /* Crashes on Vista */
141 if (0) {
142 apiReturn = GetNumberOfInterfaces(NULL);
143 if (apiReturn == ERROR_NOT_SUPPORTED)
144 return;
145 ok(apiReturn == ERROR_INVALID_PARAMETER,
146 "GetNumberOfInterfaces(NULL) returned %ld, expected ERROR_INVALID_PARAMETER\n",
147 apiReturn);
150 apiReturn = GetNumberOfInterfaces(&numInterfaces);
151 ok(apiReturn == NO_ERROR,
152 "GetNumberOfInterfaces returned %ld, expected 0\n", apiReturn);
155 static void testGetIfEntry(DWORD index)
157 DWORD apiReturn;
158 MIB_IFROW row;
160 memset(&row, 0, sizeof(row));
161 apiReturn = GetIfEntry(NULL);
162 if (apiReturn == ERROR_NOT_SUPPORTED) {
163 skip("GetIfEntry is not supported\n");
164 return;
166 ok(apiReturn == ERROR_INVALID_PARAMETER,
167 "GetIfEntry(NULL) returned %ld, expected ERROR_INVALID_PARAMETER\n",
168 apiReturn);
169 row.dwIndex = -1; /* hope that's always bogus! */
170 apiReturn = GetIfEntry(&row);
171 ok(apiReturn == ERROR_INVALID_DATA ||
172 apiReturn == ERROR_FILE_NOT_FOUND /* Vista */,
173 "GetIfEntry(bogus row) returned %ld, expected ERROR_INVALID_DATA or ERROR_FILE_NOT_FOUND\n",
174 apiReturn);
175 row.dwIndex = index;
176 apiReturn = GetIfEntry(&row);
177 ok(apiReturn == NO_ERROR,
178 "GetIfEntry returned %ld, expected NO_ERROR\n", apiReturn);
181 static void testGetIpAddrTable(void)
183 DWORD apiReturn;
184 ULONG dwSize = 0;
186 apiReturn = GetIpAddrTable(NULL, NULL, FALSE);
187 if (apiReturn == ERROR_NOT_SUPPORTED) {
188 skip("GetIpAddrTable is not supported\n");
189 return;
191 ok(apiReturn == ERROR_INVALID_PARAMETER,
192 "GetIpAddrTable(NULL, NULL, FALSE) returned %ld, expected ERROR_INVALID_PARAMETER\n",
193 apiReturn);
194 apiReturn = GetIpAddrTable(NULL, &dwSize, FALSE);
195 ok(apiReturn == ERROR_INSUFFICIENT_BUFFER,
196 "GetIpAddrTable(NULL, &dwSize, FALSE) returned %ld, expected ERROR_INSUFFICIENT_BUFFER\n",
197 apiReturn);
198 if (apiReturn == ERROR_INSUFFICIENT_BUFFER) {
199 PMIB_IPADDRTABLE buf = malloc(dwSize);
201 apiReturn = GetIpAddrTable(buf, &dwSize, FALSE);
202 ok(apiReturn == NO_ERROR,
203 "GetIpAddrTable(buf, &dwSize, FALSE) returned %ld, expected NO_ERROR\n",
204 apiReturn);
205 if (apiReturn == NO_ERROR && buf->dwNumEntries)
207 int i;
208 testGetIfEntry(buf->table[0].dwIndex);
209 for (i = 0; i < buf->dwNumEntries; i++)
211 ok (buf->table[i].wType != 0, "Test[%d]: expected wType > 0\n", i);
212 ok (buf->table[i].dwBCastAddr == 1, "Test[%d]: got %08lx\n", i, buf->table[i].dwBCastAddr);
213 ok (buf->table[i].dwReasmSize == 0xffff, "Test[%d]: got %08lx\n", i, buf->table[i].dwReasmSize);
214 trace("Entry[%d]: addr %s, dwIndex %lu, wType 0x%x\n", i,
215 ntoa(buf->table[i].dwAddr), buf->table[i].dwIndex, buf->table[i].wType);
218 free(buf);
222 static void testGetIfTable(void)
224 DWORD apiReturn;
225 ULONG dwSize = 0;
227 apiReturn = GetIfTable(NULL, NULL, FALSE);
228 if (apiReturn == ERROR_NOT_SUPPORTED) {
229 skip("GetIfTable is not supported\n");
230 return;
232 ok(apiReturn == ERROR_INVALID_PARAMETER,
233 "GetIfTable(NULL, NULL, FALSE) returned %ld, expected ERROR_INVALID_PARAMETER\n",
234 apiReturn);
235 apiReturn = GetIfTable(NULL, &dwSize, FALSE);
236 ok(apiReturn == ERROR_INSUFFICIENT_BUFFER,
237 "GetIfTable(NULL, &dwSize, FALSE) returned %ld, expected ERROR_INSUFFICIENT_BUFFER\n",
238 apiReturn);
239 if (apiReturn == ERROR_INSUFFICIENT_BUFFER) {
240 PMIB_IFTABLE buf = malloc(dwSize);
242 apiReturn = GetIfTable(buf, &dwSize, FALSE);
243 ok(apiReturn == NO_ERROR,
244 "GetIfTable(buf, &dwSize, FALSE) returned %ld, expected NO_ERROR\n\n",
245 apiReturn);
247 if (apiReturn == NO_ERROR)
249 char descr[MAX_INTERFACE_NAME_LEN];
250 WCHAR name[MAX_INTERFACE_NAME_LEN];
251 DWORD i, index;
253 if (winetest_debug > 1) trace( "interface table: %lu entries\n", buf->dwNumEntries );
254 for (i = 0; i < buf->dwNumEntries; i++)
256 MIB_IFROW *row = &buf->table[i];
257 MIB_IF_ROW2 row2;
258 GUID *guid;
260 if (winetest_debug > 1)
262 trace( "%lu: '%s' type %lu mtu %lu speed %lu\n",
263 row->dwIndex, debugstr_w(row->wszName), row->dwType, row->dwMtu, row->dwSpeed );
264 trace( " in: bytes %lu upkts %lu nupkts %lu disc %lu err %lu unk %lu\n",
265 row->dwInOctets, row->dwInUcastPkts, row->dwInNUcastPkts,
266 row->dwInDiscards, row->dwInErrors, row->dwInUnknownProtos );
267 trace( " out: bytes %lu upkts %lu nupkts %lu disc %lu err %lu\n",
268 row->dwOutOctets, row->dwOutUcastPkts, row->dwOutNUcastPkts,
269 row->dwOutDiscards, row->dwOutErrors );
271 apiReturn = GetAdapterIndex( row->wszName, &index );
272 ok( !apiReturn, "got %ld\n", apiReturn );
273 ok( index == row->dwIndex ||
274 broken( index != row->dwIndex && index ), /* Win8 can have identical guids for two different ifaces */
275 "got %ld vs %ld\n", index, row->dwIndex );
276 memset( &row2, 0, sizeof(row2) );
277 row2.InterfaceIndex = row->dwIndex;
278 GetIfEntry2( &row2 );
279 WideCharToMultiByte( CP_ACP, 0, row2.Description, -1, descr, sizeof(descr), NULL, NULL );
280 ok( !strcmp( (char *)row->bDescr, descr ), "got %s vs %s\n", row->bDescr, descr );
281 guid = &row2.InterfaceGuid;
282 swprintf( name, ARRAY_SIZE(name), L"\\DEVICE\\TCPIP_{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
283 guid->Data1, guid->Data2, guid->Data3, guid->Data4[0], guid->Data4[1],
284 guid->Data4[2], guid->Data4[3], guid->Data4[4], guid->Data4[5],
285 guid->Data4[6], guid->Data4[7]);
286 ok( !wcscmp( row->wszName, name ), "got %s vs %s\n", debugstr_w( row->wszName ), debugstr_w( name ) );
289 free(buf);
293 static void testGetIpForwardTable(void)
295 DWORD err, i, j;
296 ULONG size = 0;
297 MIB_IPFORWARDTABLE *buf;
298 MIB_IPFORWARD_TABLE2 *table2;
299 MIB_UNICASTIPADDRESS_TABLE *unicast;
301 err = GetIpForwardTable( NULL, NULL, FALSE );
302 ok( err == ERROR_INVALID_PARAMETER, "got %ld\n", err );
304 err = GetIpForwardTable( NULL, &size, FALSE );
305 ok( err == ERROR_INSUFFICIENT_BUFFER, "got %ld\n", err );
307 buf = malloc( size );
308 err = GetIpForwardTable( buf, &size, FALSE );
309 ok( !err, "got %ld\n", err );
311 err = GetIpForwardTable2( AF_INET, &table2 );
312 ok( !err, "got %ld\n", err );
313 ok( buf->dwNumEntries == table2->NumEntries, "got %ld vs %ld\n",
314 buf->dwNumEntries, table2->NumEntries );
316 err = GetUnicastIpAddressTable( AF_INET, &unicast );
317 ok( !err, "got %ld\n", err );
319 trace( "IP forward table: %lu entries\n", buf->dwNumEntries );
320 for (i = 0; i < buf->dwNumEntries; i++)
322 MIB_IPFORWARDROW *row = buf->table + i;
323 MIB_IPFORWARD_ROW2 *row2 = table2->Table + i;
324 DWORD mask, next_hop;
326 winetest_push_context( "%ld", i );
328 trace( "dest %s mask %s gw %s if %lu type %lu proto %lu\n",
329 ntoa( row->dwForwardDest ), ntoa( row->dwForwardMask ),
330 ntoa( row->dwForwardNextHop ), row->dwForwardIfIndex,
331 row->dwForwardType, row->dwForwardProto );
332 ok( row->dwForwardDest == row2->DestinationPrefix.Prefix.Ipv4.sin_addr.s_addr,
333 "got %08lx vs %08lx\n", row->dwForwardDest, row2->DestinationPrefix.Prefix.Ipv4.sin_addr.s_addr );
334 ConvertLengthToIpv4Mask( row2->DestinationPrefix.PrefixLength, &mask );
335 ok( row->dwForwardMask == mask, "got %08lx vs %08lx\n", row->dwForwardMask, mask );
336 ok( row->dwForwardPolicy == 0, "got %ld\n", row->dwForwardPolicy );
338 next_hop = row2->NextHop.Ipv4.sin_addr.s_addr;
339 if (!next_hop) /* for direct addresses, dwForwardNextHop is set to the address of the appropriate interface */
341 for (j = 0; j < unicast->NumEntries; j++)
343 if (unicast->Table[j].InterfaceLuid.Value == row2->InterfaceLuid.Value)
345 next_hop = unicast->Table[j].Address.Ipv4.sin_addr.s_addr;
346 break;
350 ok( row->dwForwardNextHop == next_hop, "got %08lx vs %08lx\n", row->dwForwardNextHop, next_hop );
352 ok( row->dwForwardIfIndex == row2->InterfaceIndex, "got %ld vs %ld\n", row->dwForwardIfIndex, row2->InterfaceIndex );
353 if (!row2->NextHop.Ipv4.sin_addr.s_addr)
354 ok( buf->table[i].dwForwardType == MIB_IPROUTE_TYPE_DIRECT, "got %ld\n", buf->table[i].dwForwardType );
355 else
356 ok( buf->table[i].dwForwardType == MIB_IPROUTE_TYPE_INDIRECT, "got %ld\n", buf->table[i].dwForwardType );
357 ok( row->dwForwardProto == row2->Protocol, "got %ld vs %d\n", row->dwForwardProto, row2->Protocol );
358 ok( row->dwForwardAge == row2->Age || row->dwForwardAge + 1 == row2->Age,
359 "got %ld vs %ld\n", row->dwForwardAge, row2->Age );
360 ok( row->dwForwardNextHopAS == 0, "got %08lx\n", row->dwForwardNextHopAS );
361 /* FIXME: need to add the interface's metric from GetIpInterfaceTable() */
362 ok( row->dwForwardMetric1 >= row2->Metric, "got %ld vs %ld\n", row->dwForwardMetric1, row2->Metric );
363 ok( row->dwForwardMetric2 == 0, "got %ld\n", row->dwForwardMetric2 );
364 ok( row->dwForwardMetric3 == 0, "got %ld\n", row->dwForwardMetric3 );
365 ok( row->dwForwardMetric4 == 0, "got %ld\n", row->dwForwardMetric4 );
366 ok( row->dwForwardMetric5 == 0, "got %ld\n", row->dwForwardMetric5 );
368 winetest_pop_context();
370 FreeMibTable( unicast );
371 FreeMibTable( table2 );
372 free( buf );
375 static void testGetIpNetTable(void)
377 DWORD apiReturn, ret, prev_idx;
378 BOOL igmp3_found, ssdp_found;
379 DWORD igmp3_addr, ssdp_addr;
380 MIB_IPNET_TABLE2 *table2;
381 ULONG dwSize = 0;
382 unsigned int i;
384 igmp3_addr = ipv4_addr( 224, 0, 0, 22 );
385 ssdp_addr = ipv4_addr( 239, 255, 255, 250 );
387 apiReturn = GetIpNetTable(NULL, NULL, FALSE);
388 if (apiReturn == ERROR_NOT_SUPPORTED) {
389 skip("GetIpNetTable is not supported\n");
390 return;
392 ok(apiReturn == ERROR_INVALID_PARAMETER,
393 "GetIpNetTable(NULL, NULL, FALSE) returned %ld, expected ERROR_INVALID_PARAMETER\n",
394 apiReturn);
395 apiReturn = GetIpNetTable(NULL, &dwSize, FALSE);
396 ok(apiReturn == ERROR_NO_DATA || apiReturn == ERROR_INSUFFICIENT_BUFFER,
397 "GetIpNetTable(NULL, &dwSize, FALSE) returned %ld, expected ERROR_NO_DATA or ERROR_INSUFFICIENT_BUFFER\n",
398 apiReturn);
399 if (apiReturn == ERROR_NO_DATA)
400 ; /* empty ARP table's okay */
401 else if (apiReturn == ERROR_INSUFFICIENT_BUFFER) {
402 PMIB_IPNETTABLE buf = malloc(dwSize);
404 memset(buf, 0xcc, dwSize);
405 apiReturn = GetIpNetTable(buf, &dwSize, TRUE);
406 ok((apiReturn == NO_ERROR && buf->dwNumEntries) || (apiReturn == ERROR_NO_DATA && !buf->dwNumEntries),
407 "got apiReturn %lu, dwSize %lu, buf->dwNumEntries %lu.\n",
408 apiReturn, dwSize, buf->dwNumEntries);
410 if (apiReturn == NO_ERROR)
412 for (i = 0; i < buf->dwNumEntries - 1; ++i)
414 ok( buf->table[i].dwIndex <= buf->table[i + 1].dwIndex,
415 "Entries are not sorted by index, i %u.\n", i );
416 if (buf->table[i].dwIndex == buf->table[i + 1].dwIndex)
417 ok(ntohl(buf->table[i].dwAddr) <= ntohl(buf->table[i + 1].dwAddr),
418 "Entries are not sorted by address, i %u.\n", i );
421 igmp3_found = ssdp_found = FALSE;
422 prev_idx = ~0u;
423 for (i = 0; i < buf->dwNumEntries; ++i)
425 if (buf->table[i].dwIndex != prev_idx)
427 if (prev_idx != ~0u)
429 ok( igmp3_found, "%s not found, iface index %lu.\n", ntoa( igmp3_addr ), prev_idx);
430 ok( ssdp_found || broken(!ssdp_found) /* 239.255.255.250 is always present since Win10 */,
431 "%s not found.\n", ntoa( ssdp_addr ));
433 prev_idx = buf->table[i].dwIndex;
434 igmp3_found = ssdp_found = FALSE;
436 if (buf->table[i].dwAddr == igmp3_addr)
437 igmp3_found = TRUE;
438 else if (buf->table[i].dwAddr == ssdp_addr)
439 ssdp_found = TRUE;
441 ok( igmp3_found, "%s not found.\n", ntoa( igmp3_addr ));
442 ok( ssdp_found || broken(!ssdp_found) /* 239.255.255.250 is always present since Win10 */,
443 "%s not found.\n", ntoa( ssdp_addr ));
445 ret = GetIpNetTable2( AF_INET, &table2 );
446 ok( !ret, "got ret %lu.\n", ret );
447 for (i = 0; i < table2->NumEntries; ++i)
449 MIB_IPNET_ROW2 *row = &table2->Table[i];
450 if (row->Address.Ipv4.sin_addr.s_addr == igmp3_addr
451 || row->Address.Ipv4.sin_addr.s_addr == ssdp_addr)
453 ok( row->State == NlnsPermanent, "got state %d.\n", row->State );
454 ok( !row->IsRouter, "IsRouter is set.\n" );
455 ok( !row->IsUnreachable, "IsUnreachable is set.\n" );
458 FreeMibTable( table2 );
461 if (apiReturn == NO_ERROR && winetest_debug > 1)
463 DWORD i, j;
465 trace( "IP net table: %lu entries\n", buf->dwNumEntries );
466 for (i = 0; i < buf->dwNumEntries; i++)
468 trace( "%lu: idx %lu type %lu addr %s phys",
469 i, buf->table[i].dwIndex, buf->table[i].dwType, ntoa( buf->table[i].dwAddr ));
470 for (j = 0; j < buf->table[i].dwPhysAddrLen; j++)
471 printf( " %02x", buf->table[i].bPhysAddr[j] );
472 printf( "\n" );
475 free(buf);
479 static void testGetIcmpStatistics(void)
481 DWORD apiReturn;
482 MIB_ICMP stats;
484 /* Crashes on Vista */
485 if (0) {
486 apiReturn = GetIcmpStatistics(NULL);
487 if (apiReturn == ERROR_NOT_SUPPORTED)
488 return;
489 ok(apiReturn == ERROR_INVALID_PARAMETER,
490 "GetIcmpStatistics(NULL) returned %ld, expected ERROR_INVALID_PARAMETER\n",
491 apiReturn);
494 apiReturn = GetIcmpStatistics(&stats);
495 if (apiReturn == ERROR_NOT_SUPPORTED)
497 skip("GetIcmpStatistics is not supported\n");
498 return;
500 ok(apiReturn == NO_ERROR,
501 "GetIcmpStatistics returned %ld, expected NO_ERROR\n", apiReturn);
502 if (apiReturn == NO_ERROR && winetest_debug > 1)
504 trace( "ICMP stats: %8s %8s\n", "in", "out" );
505 trace( " dwMsgs: %8lu %8lu\n", stats.stats.icmpInStats.dwMsgs, stats.stats.icmpOutStats.dwMsgs );
506 trace( " dwErrors: %8lu %8lu\n", stats.stats.icmpInStats.dwErrors, stats.stats.icmpOutStats.dwErrors );
507 trace( " dwDestUnreachs: %8lu %8lu\n", stats.stats.icmpInStats.dwDestUnreachs, stats.stats.icmpOutStats.dwDestUnreachs );
508 trace( " dwTimeExcds: %8lu %8lu\n", stats.stats.icmpInStats.dwTimeExcds, stats.stats.icmpOutStats.dwTimeExcds );
509 trace( " dwParmProbs: %8lu %8lu\n", stats.stats.icmpInStats.dwParmProbs, stats.stats.icmpOutStats.dwParmProbs );
510 trace( " dwSrcQuenchs: %8lu %8lu\n", stats.stats.icmpInStats.dwSrcQuenchs, stats.stats.icmpOutStats.dwSrcQuenchs );
511 trace( " dwRedirects: %8lu %8lu\n", stats.stats.icmpInStats.dwRedirects, stats.stats.icmpOutStats.dwRedirects );
512 trace( " dwEchos: %8lu %8lu\n", stats.stats.icmpInStats.dwEchos, stats.stats.icmpOutStats.dwEchos );
513 trace( " dwEchoReps: %8lu %8lu\n", stats.stats.icmpInStats.dwEchoReps, stats.stats.icmpOutStats.dwEchoReps );
514 trace( " dwTimestamps: %8lu %8lu\n", stats.stats.icmpInStats.dwTimestamps, stats.stats.icmpOutStats.dwTimestamps );
515 trace( " dwTimestampReps: %8lu %8lu\n", stats.stats.icmpInStats.dwTimestampReps, stats.stats.icmpOutStats.dwTimestampReps );
516 trace( " dwAddrMasks: %8lu %8lu\n", stats.stats.icmpInStats.dwAddrMasks, stats.stats.icmpOutStats.dwAddrMasks );
517 trace( " dwAddrMaskReps: %8lu %8lu\n", stats.stats.icmpInStats.dwAddrMaskReps, stats.stats.icmpOutStats.dwAddrMaskReps );
521 static void testGetIpStatistics(void)
523 DWORD apiReturn;
524 MIB_IPSTATS stats;
526 apiReturn = GetIpStatistics(NULL);
527 if (apiReturn == ERROR_NOT_SUPPORTED) {
528 skip("GetIpStatistics is not supported\n");
529 return;
531 ok(apiReturn == ERROR_INVALID_PARAMETER,
532 "GetIpStatistics(NULL) returned %ld, expected ERROR_INVALID_PARAMETER\n",
533 apiReturn);
534 apiReturn = GetIpStatistics(&stats);
535 ok(apiReturn == NO_ERROR,
536 "GetIpStatistics returned %ld, expected NO_ERROR\n", apiReturn);
537 if (apiReturn == NO_ERROR && winetest_debug > 1)
539 trace( "IP stats:\n" );
540 trace( " dwForwarding: %lu\n", stats.dwForwarding );
541 trace( " dwDefaultTTL: %lu\n", stats.dwDefaultTTL );
542 trace( " dwInReceives: %lu\n", stats.dwInReceives );
543 trace( " dwInHdrErrors: %lu\n", stats.dwInHdrErrors );
544 trace( " dwInAddrErrors: %lu\n", stats.dwInAddrErrors );
545 trace( " dwForwDatagrams: %lu\n", stats.dwForwDatagrams );
546 trace( " dwInUnknownProtos: %lu\n", stats.dwInUnknownProtos );
547 trace( " dwInDiscards: %lu\n", stats.dwInDiscards );
548 trace( " dwInDelivers: %lu\n", stats.dwInDelivers );
549 trace( " dwOutRequests: %lu\n", stats.dwOutRequests );
550 trace( " dwRoutingDiscards: %lu\n", stats.dwRoutingDiscards );
551 trace( " dwOutDiscards: %lu\n", stats.dwOutDiscards );
552 trace( " dwOutNoRoutes: %lu\n", stats.dwOutNoRoutes );
553 trace( " dwReasmTimeout: %lu\n", stats.dwReasmTimeout );
554 trace( " dwReasmReqds: %lu\n", stats.dwReasmReqds );
555 trace( " dwReasmOks: %lu\n", stats.dwReasmOks );
556 trace( " dwReasmFails: %lu\n", stats.dwReasmFails );
557 trace( " dwFragOks: %lu\n", stats.dwFragOks );
558 trace( " dwFragFails: %lu\n", stats.dwFragFails );
559 trace( " dwFragCreates: %lu\n", stats.dwFragCreates );
560 trace( " dwNumIf: %lu\n", stats.dwNumIf );
561 trace( " dwNumAddr: %lu\n", stats.dwNumAddr );
562 trace( " dwNumRoutes: %lu\n", stats.dwNumRoutes );
566 static void testGetTcpStatistics(void)
568 DWORD apiReturn;
569 MIB_TCPSTATS stats;
571 apiReturn = GetTcpStatistics(NULL);
572 if (apiReturn == ERROR_NOT_SUPPORTED) {
573 skip("GetTcpStatistics is not supported\n");
574 return;
576 ok(apiReturn == ERROR_INVALID_PARAMETER,
577 "GetTcpStatistics(NULL) returned %ld, expected ERROR_INVALID_PARAMETER\n",
578 apiReturn);
579 apiReturn = GetTcpStatistics(&stats);
580 ok(apiReturn == NO_ERROR,
581 "GetTcpStatistics returned %ld, expected NO_ERROR\n", apiReturn);
582 if (apiReturn == NO_ERROR && winetest_debug > 1)
584 trace( "TCP stats:\n" );
585 trace( " dwRtoAlgorithm: %lu\n", stats.dwRtoAlgorithm );
586 trace( " dwRtoMin: %lu\n", stats.dwRtoMin );
587 trace( " dwRtoMax: %lu\n", stats.dwRtoMax );
588 trace( " dwMaxConn: %lu\n", stats.dwMaxConn );
589 trace( " dwActiveOpens: %lu\n", stats.dwActiveOpens );
590 trace( " dwPassiveOpens: %lu\n", stats.dwPassiveOpens );
591 trace( " dwAttemptFails: %lu\n", stats.dwAttemptFails );
592 trace( " dwEstabResets: %lu\n", stats.dwEstabResets );
593 trace( " dwCurrEstab: %lu\n", stats.dwCurrEstab );
594 trace( " dwInSegs: %lu\n", stats.dwInSegs );
595 trace( " dwOutSegs: %lu\n", stats.dwOutSegs );
596 trace( " dwRetransSegs: %lu\n", stats.dwRetransSegs );
597 trace( " dwInErrs: %lu\n", stats.dwInErrs );
598 trace( " dwOutRsts: %lu\n", stats.dwOutRsts );
599 trace( " dwNumConns: %lu\n", stats.dwNumConns );
603 static void testGetUdpStatistics(void)
605 DWORD apiReturn;
606 MIB_UDPSTATS stats;
608 apiReturn = GetUdpStatistics(NULL);
609 if (apiReturn == ERROR_NOT_SUPPORTED) {
610 skip("GetUdpStatistics is not supported\n");
611 return;
613 ok(apiReturn == ERROR_INVALID_PARAMETER,
614 "GetUdpStatistics(NULL) returned %ld, expected ERROR_INVALID_PARAMETER\n",
615 apiReturn);
616 apiReturn = GetUdpStatistics(&stats);
617 ok(apiReturn == NO_ERROR,
618 "GetUdpStatistics returned %ld, expected NO_ERROR\n", apiReturn);
619 if (apiReturn == NO_ERROR && winetest_debug > 1)
621 trace( "UDP stats:\n" );
622 trace( " dwInDatagrams: %lu\n", stats.dwInDatagrams );
623 trace( " dwNoPorts: %lu\n", stats.dwNoPorts );
624 trace( " dwInErrors: %lu\n", stats.dwInErrors );
625 trace( " dwOutDatagrams: %lu\n", stats.dwOutDatagrams );
626 trace( " dwNumAddrs: %lu\n", stats.dwNumAddrs );
630 static void testGetIcmpStatisticsEx(void)
632 DWORD apiReturn;
633 MIB_ICMP_EX stats;
635 /* Crashes on Vista */
636 if (1) {
637 apiReturn = GetIcmpStatisticsEx(NULL, AF_INET);
638 ok(apiReturn == ERROR_INVALID_PARAMETER,
639 "GetIcmpStatisticsEx(NULL, AF_INET) returned %ld, expected ERROR_INVALID_PARAMETER\n", apiReturn);
642 apiReturn = GetIcmpStatisticsEx(&stats, AF_BAN);
643 ok(apiReturn == ERROR_INVALID_PARAMETER,
644 "GetIcmpStatisticsEx(&stats, AF_BAN) returned %ld, expected ERROR_INVALID_PARAMETER\n", apiReturn);
646 apiReturn = GetIcmpStatisticsEx(&stats, AF_INET);
647 ok(apiReturn == NO_ERROR, "GetIcmpStatisticsEx returned %ld, expected NO_ERROR\n", apiReturn);
648 if (apiReturn == NO_ERROR && winetest_debug > 1)
650 INT i;
651 trace( "ICMP IPv4 Ex stats: %8s %8s\n", "in", "out" );
652 trace( " dwMsgs: %8lu %8lu\n", stats.icmpInStats.dwMsgs, stats.icmpOutStats.dwMsgs );
653 trace( " dwErrors: %8lu %8lu\n", stats.icmpInStats.dwErrors, stats.icmpOutStats.dwErrors );
654 for (i = 0; i < 256; i++)
655 trace( " rgdwTypeCount[%3i]: %8lu %8lu\n", i, stats.icmpInStats.rgdwTypeCount[i], stats.icmpOutStats.rgdwTypeCount[i] );
658 apiReturn = GetIcmpStatisticsEx(&stats, AF_INET6);
659 ok(apiReturn == NO_ERROR || broken(apiReturn == ERROR_NOT_SUPPORTED),
660 "GetIcmpStatisticsEx returned %ld, expected NO_ERROR\n", apiReturn);
661 if (apiReturn == NO_ERROR && winetest_debug > 1)
663 INT i;
664 trace( "ICMP IPv6 Ex stats: %8s %8s\n", "in", "out" );
665 trace( " dwMsgs: %8lu %8lu\n", stats.icmpInStats.dwMsgs, stats.icmpOutStats.dwMsgs );
666 trace( " dwErrors: %8lu %8lu\n", stats.icmpInStats.dwErrors, stats.icmpOutStats.dwErrors );
667 for (i = 0; i < 256; i++)
668 trace( " rgdwTypeCount[%3i]: %8lu %8lu\n", i, stats.icmpInStats.rgdwTypeCount[i], stats.icmpOutStats.rgdwTypeCount[i] );
672 static void testGetIpStatisticsEx(void)
674 DWORD apiReturn;
675 MIB_IPSTATS stats;
677 apiReturn = GetIpStatisticsEx(NULL, AF_INET);
678 ok(apiReturn == ERROR_INVALID_PARAMETER,
679 "GetIpStatisticsEx(NULL, AF_INET) returned %ld, expected ERROR_INVALID_PARAMETER\n", apiReturn);
681 apiReturn = GetIpStatisticsEx(&stats, AF_BAN);
682 ok(apiReturn == ERROR_INVALID_PARAMETER,
683 "GetIpStatisticsEx(&stats, AF_BAN) returned %ld, expected ERROR_INVALID_PARAMETER\n", apiReturn);
685 apiReturn = GetIpStatisticsEx(&stats, AF_INET);
686 ok(apiReturn == NO_ERROR, "GetIpStatisticsEx returned %ld, expected NO_ERROR\n", apiReturn);
687 if (apiReturn == NO_ERROR && winetest_debug > 1)
689 trace( "IP IPv4 Ex stats:\n" );
690 trace( " dwForwarding: %lu\n", stats.dwForwarding );
691 trace( " dwDefaultTTL: %lu\n", stats.dwDefaultTTL );
692 trace( " dwInReceives: %lu\n", stats.dwInReceives );
693 trace( " dwInHdrErrors: %lu\n", stats.dwInHdrErrors );
694 trace( " dwInAddrErrors: %lu\n", stats.dwInAddrErrors );
695 trace( " dwForwDatagrams: %lu\n", stats.dwForwDatagrams );
696 trace( " dwInUnknownProtos: %lu\n", stats.dwInUnknownProtos );
697 trace( " dwInDiscards: %lu\n", stats.dwInDiscards );
698 trace( " dwInDelivers: %lu\n", stats.dwInDelivers );
699 trace( " dwOutRequests: %lu\n", stats.dwOutRequests );
700 trace( " dwRoutingDiscards: %lu\n", stats.dwRoutingDiscards );
701 trace( " dwOutDiscards: %lu\n", stats.dwOutDiscards );
702 trace( " dwOutNoRoutes: %lu\n", stats.dwOutNoRoutes );
703 trace( " dwReasmTimeout: %lu\n", stats.dwReasmTimeout );
704 trace( " dwReasmReqds: %lu\n", stats.dwReasmReqds );
705 trace( " dwReasmOks: %lu\n", stats.dwReasmOks );
706 trace( " dwReasmFails: %lu\n", stats.dwReasmFails );
707 trace( " dwFragOks: %lu\n", stats.dwFragOks );
708 trace( " dwFragFails: %lu\n", stats.dwFragFails );
709 trace( " dwFragCreates: %lu\n", stats.dwFragCreates );
710 trace( " dwNumIf: %lu\n", stats.dwNumIf );
711 trace( " dwNumAddr: %lu\n", stats.dwNumAddr );
712 trace( " dwNumRoutes: %lu\n", stats.dwNumRoutes );
715 apiReturn = GetIpStatisticsEx(&stats, AF_INET6);
716 ok(apiReturn == NO_ERROR || broken(apiReturn == ERROR_NOT_SUPPORTED),
717 "GetIpStatisticsEx returned %ld, expected NO_ERROR\n", apiReturn);
718 if (apiReturn == NO_ERROR && winetest_debug > 1)
720 trace( "IP IPv6 Ex stats:\n" );
721 trace( " dwForwarding: %lu\n", stats.dwForwarding );
722 trace( " dwDefaultTTL: %lu\n", stats.dwDefaultTTL );
723 trace( " dwInReceives: %lu\n", stats.dwInReceives );
724 trace( " dwInHdrErrors: %lu\n", stats.dwInHdrErrors );
725 trace( " dwInAddrErrors: %lu\n", stats.dwInAddrErrors );
726 trace( " dwForwDatagrams: %lu\n", stats.dwForwDatagrams );
727 trace( " dwInUnknownProtos: %lu\n", stats.dwInUnknownProtos );
728 trace( " dwInDiscards: %lu\n", stats.dwInDiscards );
729 trace( " dwInDelivers: %lu\n", stats.dwInDelivers );
730 trace( " dwOutRequests: %lu\n", stats.dwOutRequests );
731 trace( " dwRoutingDiscards: %lu\n", stats.dwRoutingDiscards );
732 trace( " dwOutDiscards: %lu\n", stats.dwOutDiscards );
733 trace( " dwOutNoRoutes: %lu\n", stats.dwOutNoRoutes );
734 trace( " dwReasmTimeout: %lu\n", stats.dwReasmTimeout );
735 trace( " dwReasmReqds: %lu\n", stats.dwReasmReqds );
736 trace( " dwReasmOks: %lu\n", stats.dwReasmOks );
737 trace( " dwReasmFails: %lu\n", stats.dwReasmFails );
738 trace( " dwFragOks: %lu\n", stats.dwFragOks );
739 trace( " dwFragFails: %lu\n", stats.dwFragFails );
740 trace( " dwFragCreates: %lu\n", stats.dwFragCreates );
741 trace( " dwNumIf: %lu\n", stats.dwNumIf );
742 trace( " dwNumAddr: %lu\n", stats.dwNumAddr );
743 trace( " dwNumRoutes: %lu\n", stats.dwNumRoutes );
747 static void testGetTcpStatisticsEx(void)
749 DWORD apiReturn;
750 MIB_TCPSTATS stats;
752 apiReturn = GetTcpStatisticsEx(NULL, AF_INET);
753 ok(apiReturn == ERROR_INVALID_PARAMETER,
754 "GetTcpStatisticsEx(NULL, AF_INET); returned %ld, expected ERROR_INVALID_PARAMETER\n", apiReturn);
756 apiReturn = GetTcpStatisticsEx(&stats, AF_BAN);
757 ok(apiReturn == ERROR_INVALID_PARAMETER || apiReturn == ERROR_NOT_SUPPORTED,
758 "GetTcpStatisticsEx(&stats, AF_BAN) returned %ld, expected ERROR_INVALID_PARAMETER\n", apiReturn);
760 apiReturn = GetTcpStatisticsEx(&stats, AF_INET);
761 ok(apiReturn == NO_ERROR, "GetTcpStatisticsEx returned %ld, expected NO_ERROR\n", apiReturn);
762 if (apiReturn == NO_ERROR && winetest_debug > 1)
764 trace( "TCP IPv4 Ex stats:\n" );
765 trace( " dwRtoAlgorithm: %lu\n", stats.dwRtoAlgorithm );
766 trace( " dwRtoMin: %lu\n", stats.dwRtoMin );
767 trace( " dwRtoMax: %lu\n", stats.dwRtoMax );
768 trace( " dwMaxConn: %lu\n", stats.dwMaxConn );
769 trace( " dwActiveOpens: %lu\n", stats.dwActiveOpens );
770 trace( " dwPassiveOpens: %lu\n", stats.dwPassiveOpens );
771 trace( " dwAttemptFails: %lu\n", stats.dwAttemptFails );
772 trace( " dwEstabResets: %lu\n", stats.dwEstabResets );
773 trace( " dwCurrEstab: %lu\n", stats.dwCurrEstab );
774 trace( " dwInSegs: %lu\n", stats.dwInSegs );
775 trace( " dwOutSegs: %lu\n", stats.dwOutSegs );
776 trace( " dwRetransSegs: %lu\n", stats.dwRetransSegs );
777 trace( " dwInErrs: %lu\n", stats.dwInErrs );
778 trace( " dwOutRsts: %lu\n", stats.dwOutRsts );
779 trace( " dwNumConns: %lu\n", stats.dwNumConns );
782 apiReturn = GetTcpStatisticsEx(&stats, AF_INET6);
783 ok(apiReturn == NO_ERROR || broken(apiReturn == ERROR_NOT_SUPPORTED),
784 "GetTcpStatisticsEx returned %ld, expected NO_ERROR\n", apiReturn);
785 if (apiReturn == NO_ERROR && winetest_debug > 1)
787 trace( "TCP IPv6 Ex stats:\n" );
788 trace( " dwRtoAlgorithm: %lu\n", stats.dwRtoAlgorithm );
789 trace( " dwRtoMin: %lu\n", stats.dwRtoMin );
790 trace( " dwRtoMax: %lu\n", stats.dwRtoMax );
791 trace( " dwMaxConn: %lu\n", stats.dwMaxConn );
792 trace( " dwActiveOpens: %lu\n", stats.dwActiveOpens );
793 trace( " dwPassiveOpens: %lu\n", stats.dwPassiveOpens );
794 trace( " dwAttemptFails: %lu\n", stats.dwAttemptFails );
795 trace( " dwEstabResets: %lu\n", stats.dwEstabResets );
796 trace( " dwCurrEstab: %lu\n", stats.dwCurrEstab );
797 trace( " dwInSegs: %lu\n", stats.dwInSegs );
798 trace( " dwOutSegs: %lu\n", stats.dwOutSegs );
799 trace( " dwRetransSegs: %lu\n", stats.dwRetransSegs );
800 trace( " dwInErrs: %lu\n", stats.dwInErrs );
801 trace( " dwOutRsts: %lu\n", stats.dwOutRsts );
802 trace( " dwNumConns: %lu\n", stats.dwNumConns );
806 static void testGetUdpStatisticsEx(void)
808 DWORD apiReturn;
809 MIB_UDPSTATS stats;
811 apiReturn = GetUdpStatisticsEx(NULL, AF_INET);
812 ok(apiReturn == ERROR_INVALID_PARAMETER,
813 "GetUdpStatisticsEx(NULL, AF_INET); returned %ld, expected ERROR_INVALID_PARAMETER\n", apiReturn);
815 apiReturn = GetUdpStatisticsEx(&stats, AF_BAN);
816 ok(apiReturn == ERROR_INVALID_PARAMETER || apiReturn == ERROR_NOT_SUPPORTED,
817 "GetUdpStatisticsEx(&stats, AF_BAN) returned %ld, expected ERROR_INVALID_PARAMETER\n", apiReturn);
819 apiReturn = GetUdpStatisticsEx(&stats, AF_INET);
820 ok(apiReturn == NO_ERROR, "GetUdpStatisticsEx returned %ld, expected NO_ERROR\n", apiReturn);
821 if (apiReturn == NO_ERROR && winetest_debug > 1)
823 trace( "UDP IPv4 Ex stats:\n" );
824 trace( " dwInDatagrams: %lu\n", stats.dwInDatagrams );
825 trace( " dwNoPorts: %lu\n", stats.dwNoPorts );
826 trace( " dwInErrors: %lu\n", stats.dwInErrors );
827 trace( " dwOutDatagrams: %lu\n", stats.dwOutDatagrams );
828 trace( " dwNumAddrs: %lu\n", stats.dwNumAddrs );
831 apiReturn = GetUdpStatisticsEx(&stats, AF_INET6);
832 ok(apiReturn == NO_ERROR || broken(apiReturn == ERROR_NOT_SUPPORTED),
833 "GetUdpStatisticsEx returned %ld, expected NO_ERROR\n", apiReturn);
834 if (apiReturn == NO_ERROR && winetest_debug > 1)
836 trace( "UDP IPv6 Ex stats:\n" );
837 trace( " dwInDatagrams: %lu\n", stats.dwInDatagrams );
838 trace( " dwNoPorts: %lu\n", stats.dwNoPorts );
839 trace( " dwInErrors: %lu\n", stats.dwInErrors );
840 trace( " dwOutDatagrams: %lu\n", stats.dwOutDatagrams );
841 trace( " dwNumAddrs: %lu\n", stats.dwNumAddrs );
845 static void testGetTcpTable(void)
847 DWORD apiReturn;
848 ULONG dwSize = 0;
850 apiReturn = GetTcpTable(NULL, &dwSize, FALSE);
851 if (apiReturn == ERROR_NOT_SUPPORTED) {
852 skip("GetTcpTable is not supported\n");
853 return;
855 ok(apiReturn == ERROR_INSUFFICIENT_BUFFER,
856 "GetTcpTable(NULL, &dwSize, FALSE) returned %ld, expected ERROR_INSUFFICIENT_BUFFER\n",
857 apiReturn);
858 if (apiReturn == ERROR_INSUFFICIENT_BUFFER) {
859 PMIB_TCPTABLE buf = malloc(dwSize);
861 apiReturn = GetTcpTable(buf, &dwSize, FALSE);
862 ok(apiReturn == NO_ERROR,
863 "GetTcpTable(buf, &dwSize, FALSE) returned %ld, expected NO_ERROR\n",
864 apiReturn);
866 if (apiReturn == NO_ERROR && winetest_debug > 1)
868 DWORD i;
869 trace( "TCP table: %lu entries\n", buf->dwNumEntries );
870 for (i = 0; i < buf->dwNumEntries; i++)
872 trace( "%lu: local %s:%u remote %s:%u state %lu\n", i,
873 ntoa(buf->table[i].dwLocalAddr), ntohs(buf->table[i].dwLocalPort),
874 ntoa(buf->table[i].dwRemoteAddr), ntohs(buf->table[i].dwRemotePort),
875 buf->table[i].dwState );
878 free(buf);
882 static void testGetUdpTable(void)
884 DWORD apiReturn;
885 ULONG dwSize = 0;
887 apiReturn = GetUdpTable(NULL, &dwSize, FALSE);
888 if (apiReturn == ERROR_NOT_SUPPORTED) {
889 skip("GetUdpTable is not supported\n");
890 return;
892 ok(apiReturn == ERROR_INSUFFICIENT_BUFFER,
893 "GetUdpTable(NULL, &dwSize, FALSE) returned %ld, expected ERROR_INSUFFICIENT_BUFFER\n",
894 apiReturn);
895 if (apiReturn == ERROR_INSUFFICIENT_BUFFER) {
896 PMIB_UDPTABLE buf = malloc(dwSize);
898 apiReturn = GetUdpTable(buf, &dwSize, FALSE);
899 ok(apiReturn == NO_ERROR,
900 "GetUdpTable(buf, &dwSize, FALSE) returned %ld, expected NO_ERROR\n",
901 apiReturn);
903 if (apiReturn == NO_ERROR && winetest_debug > 1)
905 DWORD i;
906 trace( "UDP table: %lu entries\n", buf->dwNumEntries );
907 for (i = 0; i < buf->dwNumEntries; i++)
908 trace( "%lu: %s:%u\n",
909 i, ntoa( buf->table[i].dwLocalAddr ), ntohs(buf->table[i].dwLocalPort) );
911 free(buf);
915 static void testSetTcpEntry(void)
917 DWORD ret;
918 MIB_TCPROW row;
920 memset(&row, 0, sizeof(row));
921 if(0) /* This test crashes in OS >= VISTA */
923 ret = SetTcpEntry(NULL);
924 ok( ret == ERROR_INVALID_PARAMETER, "got %lu, expected %u\n", ret, ERROR_INVALID_PARAMETER);
927 ret = SetTcpEntry(&row);
928 if (ret == ERROR_NETWORK_ACCESS_DENIED)
930 win_skip("SetTcpEntry failed with access error. Skipping test.\n");
931 return;
933 todo_wine ok( ret == ERROR_INVALID_PARAMETER, "got %lu, expected %u\n", ret, ERROR_INVALID_PARAMETER);
935 row.dwState = MIB_TCP_STATE_DELETE_TCB;
936 ret = SetTcpEntry(&row);
937 todo_wine ok( ret == ERROR_MR_MID_NOT_FOUND || broken(ret == ERROR_INVALID_PARAMETER),
938 "got %lu, expected %u\n", ret, ERROR_MR_MID_NOT_FOUND);
941 static BOOL icmp_send_echo_test_apc_expect;
942 static void WINAPI icmp_send_echo_test_apc_xp(void *context)
944 ok(icmp_send_echo_test_apc_expect, "Unexpected APC execution\n");
945 ok(context == (void*)0xdeadc0de, "Wrong context: %p\n", context);
946 icmp_send_echo_test_apc_expect = FALSE;
949 static void WINAPI icmp_send_echo_test_apc(void *context, IO_STATUS_BLOCK *io_status, ULONG reserved)
951 icmp_send_echo_test_apc_xp(context);
952 ok(io_status->Status == 0, "Got IO Status 0x%08lx\n", io_status->Status);
953 ok(io_status->Information == sizeof(ICMP_ECHO_REPLY) + 32 /* sizeof(senddata) */,
954 "Got IO Information %Iu\n", io_status->Information);
957 static void testIcmpSendEcho(void)
959 /* The APC's signature is different pre-Vista */
960 const PIO_APC_ROUTINE apc = broken(LOBYTE(LOWORD(GetVersion())) < 6)
961 ? (PIO_APC_ROUTINE)icmp_send_echo_test_apc_xp
962 : icmp_send_echo_test_apc;
963 HANDLE icmp;
964 char senddata[32], replydata[sizeof(senddata) + sizeof(ICMP_ECHO_REPLY)];
965 char replydata2[sizeof(replydata) + sizeof(IO_STATUS_BLOCK)];
966 DWORD ret, error, replysz = sizeof(replydata);
967 IPAddr address;
968 ICMP_ECHO_REPLY *reply;
969 HANDLE event;
970 INT i;
972 memset(senddata, 0, sizeof(senddata));
974 address = htonl(INADDR_LOOPBACK);
975 SetLastError(0xdeadbeef);
976 ret = IcmpSendEcho(INVALID_HANDLE_VALUE, address, senddata, sizeof(senddata), NULL, replydata, replysz, 1000);
977 error = GetLastError();
978 ok (!ret, "IcmpSendEcho succeeded unexpectedly\n");
979 ok (error == ERROR_INVALID_PARAMETER
980 || broken(error == ERROR_INVALID_HANDLE) /* <= 2003 */,
981 "expected 87, got %ld\n", error);
983 address = htonl(INADDR_LOOPBACK);
984 SetLastError(0xdeadbeef);
985 ret = IcmpSendEcho2(INVALID_HANDLE_VALUE, NULL, NULL, NULL, address, senddata, sizeof(senddata), NULL, replydata, replysz, 1000);
986 error = GetLastError();
987 ok (!ret, "IcmpSendEcho2 succeeded unexpectedly\n");
988 ok (error == ERROR_INVALID_PARAMETER
989 || broken(error == ERROR_INVALID_HANDLE) /* <= 2003 */,
990 "expected 87, got %ld\n", error);
992 icmp = IcmpCreateFile();
993 ok (icmp != INVALID_HANDLE_VALUE, "IcmpCreateFile failed unexpectedly with error %ld\n", GetLastError());
995 address = 0;
996 SetLastError(0xdeadbeef);
997 ret = IcmpSendEcho(icmp, address, senddata, sizeof(senddata), NULL, replydata, replysz, 1000);
998 error = GetLastError();
999 ok (!ret, "IcmpSendEcho succeeded unexpectedly\n");
1000 ok (error == ERROR_INVALID_NETNAME
1001 || broken(error == IP_BAD_DESTINATION) /* <= 2003 */,
1002 "expected 1214, got %ld\n", error);
1004 address = htonl(INADDR_LOOPBACK);
1005 if (0) /* crashes in XP */
1007 ret = IcmpSendEcho(icmp, address, NULL, sizeof(senddata), NULL, replydata, replysz, 1000);
1008 ok (!ret, "IcmpSendEcho succeeded unexpectedly\n");
1011 SetLastError(0xdeadbeef);
1012 ret = IcmpSendEcho(icmp, address, senddata, 0, NULL, replydata, replysz, 1000);
1013 error = GetLastError();
1014 if (!ret && error == ERROR_ACCESS_DENIED)
1016 skip( "ICMP is not available.\n" );
1017 return;
1019 ok (ret, "IcmpSendEcho failed unexpectedly with error %ld\n", error);
1021 SetLastError(0xdeadbeef);
1022 ret = IcmpSendEcho(icmp, address, NULL, 0, NULL, replydata, replysz, 1000);
1023 error = GetLastError();
1024 ok (ret, "IcmpSendEcho failed unexpectedly with error %ld\n", error);
1026 SetLastError(0xdeadbeef);
1027 ret = IcmpSendEcho(icmp, address, senddata, sizeof(senddata), NULL, NULL, replysz, 1000);
1028 error = GetLastError();
1029 ok (!ret, "IcmpSendEcho succeeded unexpectedly\n");
1030 ok (error == ERROR_INVALID_PARAMETER, "expected 87, got %ld\n", error);
1032 SetLastError(0xdeadbeef);
1033 ret = IcmpSendEcho(icmp, address, senddata, sizeof(senddata), NULL, replydata, 0, 1000);
1034 error = GetLastError();
1035 ok (!ret, "IcmpSendEcho succeeded unexpectedly\n");
1036 ok (error == ERROR_INVALID_PARAMETER
1037 || broken(error == ERROR_INSUFFICIENT_BUFFER) /* <= 2003 */,
1038 "expected 87, got %ld\n", error);
1040 SetLastError(0xdeadbeef);
1041 ret = IcmpSendEcho(icmp, address, senddata, sizeof(senddata), NULL, NULL, 0, 1000);
1042 error = GetLastError();
1043 ok (!ret, "IcmpSendEcho succeeded unexpectedly\n");
1044 ok (error == ERROR_INVALID_PARAMETER
1045 || broken(error == ERROR_INSUFFICIENT_BUFFER) /* <= 2003 */,
1046 "expected 87, got %ld\n", error);
1048 SetLastError(0xdeadbeef);
1049 replysz = sizeof(replydata) - 1;
1050 ret = IcmpSendEcho(icmp, address, senddata, sizeof(senddata), NULL, replydata, replysz, 1000);
1051 error = GetLastError();
1052 ok (!ret, "IcmpSendEcho succeeded unexpectedly\n");
1053 ok (error == IP_GENERAL_FAILURE
1054 || broken(error == IP_BUF_TOO_SMALL) /* <= 2003 */,
1055 "expected 11050, got %ld\n", error);
1057 SetLastError(0xdeadbeef);
1058 replysz = sizeof(ICMP_ECHO_REPLY);
1059 ret = IcmpSendEcho(icmp, address, senddata, 0, NULL, replydata, replysz, 1000);
1060 error = GetLastError();
1061 ok (ret, "IcmpSendEcho failed unexpectedly with error %ld\n", error);
1063 SetLastError(0xdeadbeef);
1064 replysz = sizeof(ICMP_ECHO_REPLY) + ICMP_MINLEN;
1065 ret = IcmpSendEcho(icmp, address, senddata, ICMP_MINLEN, NULL, replydata, replysz, 1000);
1066 error = GetLastError();
1067 ok (ret, "IcmpSendEcho failed unexpectedly with error %ld\n", error);
1069 SetLastError(0xdeadbeef);
1070 replysz = sizeof(ICMP_ECHO_REPLY) + ICMP_MINLEN;
1071 ret = IcmpSendEcho(icmp, address, senddata, ICMP_MINLEN + 1, NULL, replydata, replysz, 1000);
1072 error = GetLastError();
1073 ok (!ret, "IcmpSendEcho succeeded unexpectedly\n");
1074 ok (error == IP_GENERAL_FAILURE
1075 || broken(error == IP_BUF_TOO_SMALL) /* <= 2003 */,
1076 "expected 11050, got %ld\n", error);
1078 SetLastError(0xdeadbeef);
1079 ret = IcmpSendEcho(icmp, address, senddata, ICMP_MINLEN, NULL, replydata, replysz - 1, 1000);
1080 error = GetLastError();
1081 ok (!ret, "IcmpSendEcho succeeded unexpectedly\n");
1082 ok (error == IP_GENERAL_FAILURE
1083 || broken(error == IP_BUF_TOO_SMALL) /* <= 2003 */,
1084 "expected 11050, got %ld\n", error);
1086 /* in windows >= vista the timeout can't be invalid */
1087 SetLastError(0xdeadbeef);
1088 replysz = sizeof(replydata);
1089 ret = IcmpSendEcho(icmp, address, senddata, sizeof(senddata), NULL, replydata, replysz, 0);
1090 error = GetLastError();
1091 if (!ret) ok(error == ERROR_INVALID_PARAMETER, "expected 87, got %ld\n", error);
1093 SetLastError(0xdeadbeef);
1094 ret = IcmpSendEcho(icmp, address, senddata, sizeof(senddata), NULL, replydata, replysz, -1);
1095 error = GetLastError();
1096 if (!ret) ok(error == ERROR_INVALID_PARAMETER, "expected 87, got %ld\n", error);
1098 /* real ping test */
1099 SetLastError(0xdeadbeef);
1100 address = htonl(INADDR_LOOPBACK);
1101 ret = IcmpSendEcho(icmp, address, senddata, sizeof(senddata), NULL, replydata, replysz, 1000);
1102 error = GetLastError();
1103 if (!ret)
1105 skip ("Failed to ping with error %ld, is lo interface down?.\n", error);
1107 else if (winetest_debug > 1)
1109 PICMP_ECHO_REPLY pong = (PICMP_ECHO_REPLY) replydata;
1110 trace ("send addr : %s\n", ntoa(address));
1111 trace ("reply addr : %s\n", ntoa(pong->Address));
1112 trace ("reply size : %lu\n", replysz);
1113 trace ("roundtrip : %lu ms\n", pong->RoundTripTime);
1114 trace ("status : %lu\n", pong->Status);
1115 trace ("recv size : %u\n", pong->DataSize);
1116 trace ("ttl : %u\n", pong->Options.Ttl);
1117 trace ("flags : 0x%x\n", pong->Options.Flags);
1120 /* check reply data */
1121 SetLastError(0xdeadbeef);
1122 address = htonl(INADDR_LOOPBACK);
1123 for (i = 0; i < ARRAY_SIZE(senddata); i++) senddata[i] = i & 0xff;
1124 ret = IcmpSendEcho(icmp, address, senddata, sizeof(senddata), NULL, replydata, replysz, 1000);
1125 error = GetLastError();
1126 reply = (ICMP_ECHO_REPLY *)replydata;
1127 ok(ret, "IcmpSendEcho failed unexpectedly\n");
1128 ok(error == NO_ERROR, "Expect last error:0x%08x, got:0x%08lx\n", NO_ERROR, error);
1129 ok(INADDR_LOOPBACK == ntohl(reply->Address), "Address mismatch, expect:%s, got: %s\n", ntoa(INADDR_LOOPBACK),
1130 ntoa(reply->Address));
1131 ok(reply->Status == IP_SUCCESS, "Expect status:0x%08x, got:0x%08lx\n", IP_SUCCESS, reply->Status);
1132 ok(reply->DataSize == sizeof(senddata), "Got size:%d\n", reply->DataSize);
1133 ok(!memcmp(senddata, reply->Data, min(sizeof(senddata), reply->DataSize)), "Data mismatch\n");
1137 * IcmpSendEcho2
1139 address = 0;
1140 replysz = sizeof(replydata2);
1141 memset(senddata, 0, sizeof(senddata));
1143 SetLastError(0xdeadbeef);
1144 ret = IcmpSendEcho2(icmp, NULL, NULL, NULL, address, senddata, sizeof(senddata), NULL, replydata2, replysz, 1000);
1145 error = GetLastError();
1146 ok(!ret, "IcmpSendEcho2 succeeded unexpectedly\n");
1147 ok(error == ERROR_INVALID_NETNAME
1148 || broken(error == IP_BAD_DESTINATION) /* <= 2003 */,
1149 "expected 1214, got %ld\n", error);
1151 event = CreateEventW(NULL, FALSE, FALSE, NULL);
1152 ok(event != NULL, "CreateEventW failed unexpectedly with error %ld\n", GetLastError());
1154 SetLastError(0xdeadbeef);
1155 ret = IcmpSendEcho2(icmp, event, NULL, NULL, address, senddata, sizeof(senddata), NULL, replydata2, replysz, 1000);
1156 error = GetLastError();
1157 ok(!ret, "IcmpSendEcho2 returned success unexpectedly\n");
1158 ok(error == ERROR_INVALID_NETNAME
1159 || broken(error == ERROR_IO_PENDING) /* <= 2003 */,
1160 "Got last error: 0x%08lx\n", error);
1161 if (error == ERROR_IO_PENDING)
1163 ret = WaitForSingleObjectEx(event, 2000, TRUE);
1164 ok(ret == WAIT_OBJECT_0, "WaitForSingleObjectEx failed unexpectedly with %lu\n", ret);
1167 address = htonl(INADDR_LOOPBACK);
1168 SetLastError(0xdeadbeef);
1169 ret = IcmpSendEcho2(icmp, NULL, NULL, NULL, address, senddata, sizeof(senddata), NULL, NULL, replysz, 1000);
1170 error = GetLastError();
1171 ok(!ret, "IcmpSendEcho2 succeeded unexpectedly\n");
1172 ok(error == ERROR_INVALID_PARAMETER
1173 || broken(error == ERROR_NOACCESS) /* <= 2003 */,
1174 "expected 87, got %ld\n", error);
1176 SetLastError(0xdeadbeef);
1177 ret = IcmpSendEcho2(icmp, event, NULL, NULL, address, senddata, sizeof(senddata), NULL, NULL, replysz, 1000);
1178 error = GetLastError();
1179 ok(!ret, "IcmpSendEcho2 succeeded unexpectedly\n");
1180 ok(error == ERROR_INVALID_PARAMETER
1181 || broken(error == ERROR_NOACCESS) /* <= 2003 */,
1182 "expected 87, got %ld\n", error);
1183 ok(WaitForSingleObjectEx(event, 0, TRUE) == WAIT_TIMEOUT, "Event was unexpectedly signalled.\n");
1185 SetLastError(0xdeadbeef);
1186 ret = IcmpSendEcho2(icmp, NULL, NULL, NULL, address, senddata, sizeof(senddata), NULL, replydata2, 0, 1000);
1187 error = GetLastError();
1188 ok(!ret, "IcmpSendEcho2 succeeded unexpectedly\n");
1189 ok(error == ERROR_INVALID_PARAMETER
1190 || broken(error == ERROR_INSUFFICIENT_BUFFER) /* <= 2003 */,
1191 "expected 87, got %ld\n", error);
1193 SetLastError(0xdeadbeef);
1194 ret = IcmpSendEcho2(icmp, event, NULL, NULL, address, senddata, sizeof(senddata), NULL, replydata2, 0, 1000);
1195 error = GetLastError();
1196 ok(!ret, "IcmpSendEcho2 succeeded unexpectedly\n");
1197 ok(error == ERROR_INVALID_PARAMETER
1198 || broken(error == ERROR_INSUFFICIENT_BUFFER) /* <= 2003 */,
1199 "expected 87, got %ld\n", error);
1200 ok(WaitForSingleObjectEx(event, 0, TRUE) == WAIT_TIMEOUT, "Event was unexpectedly signalled.\n");
1202 SetLastError(0xdeadbeef);
1203 ret = IcmpSendEcho2(icmp, NULL, NULL, NULL, address, senddata, sizeof(senddata), NULL, NULL, 0, 1000);
1204 error = GetLastError();
1205 ok(!ret, "IcmpSendEcho2 succeeded unexpectedly\n");
1206 ok(error == ERROR_INVALID_PARAMETER
1207 || broken(error == ERROR_INSUFFICIENT_BUFFER) /* <= 2003 */,
1208 "expected 87, got %ld\n", error);
1210 SetLastError(0xdeadbeef);
1211 ret = IcmpSendEcho2(icmp, event, NULL, NULL, address, senddata, sizeof(senddata), NULL, NULL, 0, 1000);
1212 error = GetLastError();
1213 ok(!ret, "IcmpSendEcho2 succeeded unexpectedly\n");
1214 ok(error == ERROR_INVALID_PARAMETER
1215 || broken(error == ERROR_INSUFFICIENT_BUFFER) /* <= 2003 */,
1216 "expected 87, got %ld\n", error);
1217 ok(WaitForSingleObjectEx(event, 0, TRUE) == WAIT_TIMEOUT, "Event was unexpectedly signalled.\n");
1219 /* synchronous tests */
1220 SetLastError(0xdeadbeef);
1221 address = htonl(INADDR_LOOPBACK);
1222 replysz = sizeof(ICMP_ECHO_REPLY) + sizeof(IO_STATUS_BLOCK);
1223 ret = IcmpSendEcho2(icmp, NULL, NULL, NULL, address, senddata, 0, NULL, replydata2, replysz, 1000);
1224 ok(ret, "IcmpSendEcho2 failed unexpectedly with error %ld\n", GetLastError());
1226 SetLastError(0xdeadbeef);
1227 ret = IcmpSendEcho2(icmp, NULL, NULL, NULL, address, NULL, 0, NULL, replydata2, replysz, 1000);
1228 ok(ret, "IcmpSendEcho2 failed unexpectedly with error %ld\n", GetLastError());
1230 SetLastError(0xdeadbeef);
1231 ret = IcmpSendEcho2(icmp, NULL, NULL, NULL, address, senddata, 0, NULL, replydata2, replysz, 1000);
1232 ok(ret, "IcmpSendEcho2 failed unexpectedly with error %ld\n", GetLastError());
1234 SetLastError(0xdeadbeef);
1235 replysz = sizeof(ICMP_ECHO_REPLY) + sizeof(IO_STATUS_BLOCK) + ICMP_MINLEN;
1236 ret = IcmpSendEcho2(icmp, NULL, NULL, NULL, address, senddata, ICMP_MINLEN, NULL, replydata2, replysz, 1000);
1237 ok(ret, "IcmpSendEcho2 failed unexpectedly with error %ld\n", GetLastError());
1239 SetLastError(0xdeadbeef);
1240 replysz = sizeof(replydata2);
1241 ret = IcmpSendEcho2(icmp, NULL, NULL, NULL, address, senddata, sizeof(senddata), NULL, replydata2, replysz, 1000);
1242 if (!ret)
1244 error = GetLastError();
1245 skip("Failed to ping with error %ld, is lo interface down?\n", error);
1247 else if (winetest_debug > 1)
1249 reply = (ICMP_ECHO_REPLY*)replydata2;
1250 trace("send addr : %s\n", ntoa(address));
1251 trace("reply addr : %s\n", ntoa(reply->Address));
1252 trace("reply size : %lu\n", replysz);
1253 trace("roundtrip : %lu ms\n", reply->RoundTripTime);
1254 trace("status : %lu\n", reply->Status);
1255 trace("recv size : %u\n", reply->DataSize);
1256 trace("ttl : %u\n", reply->Options.Ttl);
1257 trace("flags : 0x%x\n", reply->Options.Flags);
1260 SetLastError(0xdeadbeef);
1261 for (i = 0; i < ARRAY_SIZE(senddata); i++) senddata[i] = i & 0xff;
1262 ret = IcmpSendEcho2(icmp, NULL, NULL, NULL, address, senddata, sizeof(senddata), NULL, replydata2, replysz, 1000);
1263 error = GetLastError();
1264 reply = (ICMP_ECHO_REPLY*)replydata2;
1265 ok(ret, "IcmpSendEcho2 failed unexpectedly\n");
1266 ok(error == NO_ERROR, "Expect last error: 0x%08x, got: 0x%08lx\n", NO_ERROR, error);
1267 ok(ntohl(reply->Address) == INADDR_LOOPBACK, "Address mismatch, expect: %s, got: %s\n", ntoa(INADDR_LOOPBACK),
1268 ntoa(reply->Address));
1269 ok(reply->Status == IP_SUCCESS, "Expect status: 0x%08x, got: 0x%08lx\n", IP_SUCCESS, reply->Status);
1270 ok(reply->DataSize == sizeof(senddata), "Got size: %d\n", reply->DataSize);
1271 ok(!memcmp(senddata, reply->Data, min(sizeof(senddata), reply->DataSize)), "Data mismatch\n");
1273 /* asynchronous tests with event */
1274 SetLastError(0xdeadbeef);
1275 replysz = sizeof(replydata2);
1276 address = htonl(INADDR_LOOPBACK);
1277 memset(senddata, 0, sizeof(senddata));
1278 ret = IcmpSendEcho2(icmp, event, NULL, NULL, address, senddata, sizeof(senddata), NULL, replydata2, replysz, 1000);
1279 error = GetLastError();
1280 if (!ret && error != ERROR_IO_PENDING)
1282 skip("Failed to ping with error %ld, is lo interface down?\n", error);
1284 else
1286 ok(!ret, "IcmpSendEcho2 returned success unexpectedly\n");
1287 ok(error == ERROR_IO_PENDING, "Expect last error: 0x%08x, got: 0x%08lx\n", ERROR_IO_PENDING, error);
1288 ret = WaitForSingleObjectEx(event, 2000, TRUE);
1289 ok(ret == WAIT_OBJECT_0, "WaitForSingleObjectEx failed unexpectedly with %lu\n", ret);
1290 reply = (ICMP_ECHO_REPLY*)replydata2;
1291 ok(ntohl(reply->Address) == INADDR_LOOPBACK, "Address mismatch, expect: %s, got: %s\n", ntoa(INADDR_LOOPBACK),
1292 ntoa(reply->Address));
1293 ok(reply->Status == IP_SUCCESS, "Expect status: 0x%08x, got: 0x%08lx\n", IP_SUCCESS, reply->Status);
1294 ok(reply->DataSize == sizeof(senddata), "Got size: %d\n", reply->DataSize);
1295 if (winetest_debug > 1)
1297 reply = (ICMP_ECHO_REPLY*)replydata2;
1298 trace("send addr : %s\n", ntoa(address));
1299 trace("reply addr : %s\n", ntoa(reply->Address));
1300 trace("reply size : %lu\n", replysz);
1301 trace("roundtrip : %lu ms\n", reply->RoundTripTime);
1302 trace("status : %lu\n", reply->Status);
1303 trace("recv size : %u\n", reply->DataSize);
1304 trace("ttl : %u\n", reply->Options.Ttl);
1305 trace("flags : 0x%x\n", reply->Options.Flags);
1309 SetLastError(0xdeadbeef);
1310 for (i = 0; i < ARRAY_SIZE(senddata); i++) senddata[i] = i & 0xff;
1311 ret = IcmpSendEcho2(icmp, event, NULL, NULL, address, senddata, sizeof(senddata), NULL, replydata2, replysz, 1000);
1312 error = GetLastError();
1313 ok(!ret, "IcmpSendEcho2 returned success unexpectedly\n");
1314 ok(error == ERROR_IO_PENDING, "Expect last error: 0x%08x, got: 0x%08lx\n", ERROR_IO_PENDING, error);
1315 ret = WaitForSingleObjectEx(event, 2000, TRUE);
1316 ok(ret == WAIT_OBJECT_0, "WaitForSingleObjectEx failed unexpectedly with %lu\n", ret);
1317 reply = (ICMP_ECHO_REPLY*)replydata2;
1318 ok(ntohl(reply->Address) == INADDR_LOOPBACK, "Address mismatch, expect: %s, got: %s\n", ntoa(INADDR_LOOPBACK),
1319 ntoa(reply->Address));
1320 ok(reply->Status == IP_SUCCESS, "Expect status: 0x%08x, got: 0x%08lx\n", IP_SUCCESS, reply->Status);
1321 ok(reply->DataSize == sizeof(senddata), "Got size: %d\n", reply->DataSize);
1322 /* pre-Vista, reply->Data is an offset; otherwise it's a pointer, so hardcode the offset */
1323 ok(!memcmp(senddata, reply + 1, min(sizeof(senddata), reply->DataSize)), "Data mismatch\n");
1325 CloseHandle(event);
1327 /* asynchronous tests with APC */
1328 SetLastError(0xdeadbeef);
1329 replysz = sizeof(replydata2) + 10;
1330 address = htonl(INADDR_LOOPBACK);
1331 for (i = 0; i < ARRAY_SIZE(senddata); i++) senddata[i] = ~i & 0xff;
1332 icmp_send_echo_test_apc_expect = TRUE;
1334 NOTE: Supplying both event and apc has varying behavior across Windows versions, so not tested.
1336 ret = IcmpSendEcho2(icmp, NULL, apc, (void*)0xdeadc0de, address, senddata, sizeof(senddata), NULL, replydata2, replysz, 1000);
1337 error = GetLastError();
1338 ok(!ret, "IcmpSendEcho2 returned success unexpectedly\n");
1339 ok(error == ERROR_IO_PENDING, "Expect last error: 0x%08x, got: 0x%08lx\n", ERROR_IO_PENDING, error);
1340 SleepEx(200, TRUE);
1341 SleepEx(0, TRUE);
1342 ok(icmp_send_echo_test_apc_expect == FALSE, "APC was not executed!\n");
1343 reply = (ICMP_ECHO_REPLY*)replydata2;
1344 ok(ntohl(reply->Address) == INADDR_LOOPBACK, "Address mismatch, expect: %s, got: %s\n", ntoa(INADDR_LOOPBACK),
1345 ntoa(reply->Address));
1346 ok(reply->Status == IP_SUCCESS, "Expect status: 0x%08x, got: 0x%08lx\n", IP_SUCCESS, reply->Status);
1347 ok(reply->DataSize == sizeof(senddata), "Got size: %d\n", reply->DataSize);
1348 /* pre-Vista, reply->Data is an offset; otherwise it's a pointer, so hardcode the offset */
1349 ok(!memcmp(senddata, reply + 1, min(sizeof(senddata), reply->DataSize)), "Data mismatch\n");
1351 IcmpCloseHandle(icmp);
1354 static void testIcmpParseReplies( void )
1356 ICMP_ECHO_REPLY reply = { 0 };
1357 DWORD ret;
1359 SetLastError( 0xdeadbeef );
1360 ret = IcmpParseReplies( &reply, sizeof(reply) );
1361 ok( ret == 0, "ret %ld\n", ret );
1362 ok( GetLastError() == 0, "gle %ld\n", GetLastError() );
1364 reply.Status = 12345;
1365 SetLastError( 0xdeadbeef );
1366 ret = IcmpParseReplies( &reply, sizeof(reply) );
1367 ok( ret == 0, "ret %ld\n", ret );
1368 ok( GetLastError() == 12345, "gle %ld\n", GetLastError() );
1369 ok( reply.Status == 12345, "status %ld\n", reply.Status );
1371 reply.Reserved = 1;
1372 SetLastError( 0xdeadbeef );
1373 ret = IcmpParseReplies( &reply, sizeof(reply) );
1374 ok( ret == 1, "ret %ld\n", ret );
1375 ok( GetLastError() == 0xdeadbeef, "gle %ld\n", GetLastError() );
1376 ok( reply.Status == 12345, "status %ld\n", reply.Status );
1377 ok( !reply.Reserved, "reserved %d\n", reply.Reserved );
1379 reply.Reserved = 3;
1380 SetLastError( 0xdeadbeef );
1381 ret = IcmpParseReplies( &reply, sizeof(reply) );
1382 ok( ret == 3, "ret %ld\n", ret );
1383 ok( GetLastError() == 0xdeadbeef, "gle %ld\n", GetLastError() );
1384 ok( reply.Status == 12345, "status %ld\n", reply.Status );
1385 ok( !reply.Reserved, "reserved %d\n", reply.Reserved );
1388 static void testWinNT4Functions(void)
1390 testGetNumberOfInterfaces();
1391 testGetIpAddrTable();
1392 testGetIfTable();
1393 testGetIpForwardTable();
1394 testGetIpNetTable();
1395 testGetIcmpStatistics();
1396 testGetIpStatistics();
1397 testGetTcpStatistics();
1398 testGetUdpStatistics();
1399 testGetIcmpStatisticsEx();
1400 testGetIpStatisticsEx();
1401 testGetTcpStatisticsEx();
1402 testGetUdpStatisticsEx();
1403 testGetTcpTable();
1404 testGetUdpTable();
1405 testSetTcpEntry();
1406 testIcmpSendEcho();
1407 testIcmpParseReplies();
1410 static void testGetInterfaceInfo(void)
1412 DWORD apiReturn;
1413 ULONG len = 0, i;
1415 apiReturn = GetInterfaceInfo(NULL, NULL);
1416 if (apiReturn == ERROR_NOT_SUPPORTED) {
1417 skip("GetInterfaceInfo is not supported\n");
1418 return;
1420 ok(apiReturn == ERROR_INVALID_PARAMETER,
1421 "GetInterfaceInfo returned %ld, expected ERROR_INVALID_PARAMETER\n",
1422 apiReturn);
1423 apiReturn = GetInterfaceInfo(NULL, &len);
1424 ok(apiReturn == ERROR_INSUFFICIENT_BUFFER,
1425 "GetInterfaceInfo returned %ld, expected ERROR_INSUFFICIENT_BUFFER\n",
1426 apiReturn);
1427 if (apiReturn == ERROR_INSUFFICIENT_BUFFER) {
1428 PIP_INTERFACE_INFO buf = malloc(len);
1430 apiReturn = GetInterfaceInfo(buf, &len);
1431 ok(apiReturn == NO_ERROR,
1432 "GetInterfaceInfo(buf, &dwSize) returned %ld, expected NO_ERROR\n",
1433 apiReturn);
1435 for (i = 0; i < buf->NumAdapters; i++)
1437 MIB_IFROW row = { .dwIndex = buf->Adapter[i].Index };
1438 GetIfEntry( &row );
1439 ok( !wcscmp( buf->Adapter[i].Name, row.wszName ), "got %s vs %s\n",
1440 debugstr_w( buf->Adapter[i].Name ), debugstr_w( row.wszName ) );
1441 ok( row.dwType != IF_TYPE_SOFTWARE_LOOPBACK, "got loopback\n" );
1443 free(buf);
1447 static void testGetAdaptersInfo(void)
1449 IP_ADAPTER_INFO *ptr, *buf;
1450 NET_LUID luid;
1451 GUID guid;
1452 char name[ARRAY_SIZE(ptr->AdapterName)];
1453 DWORD err;
1454 ULONG len = 0;
1455 MIB_IFROW row;
1457 err = GetAdaptersInfo( NULL, NULL );
1458 ok( err == ERROR_INVALID_PARAMETER, "got %ld\n", err );
1459 err = GetAdaptersInfo( NULL, &len );
1460 ok( err == ERROR_NO_DATA || err == ERROR_BUFFER_OVERFLOW, "got %ld\n", err );
1461 if (err == ERROR_NO_DATA) return;
1463 buf = malloc( len );
1464 err = GetAdaptersInfo( buf, &len );
1465 ok( !err, "got %ld\n", err );
1466 ptr = buf;
1467 while (ptr)
1469 trace( "adapter '%s', address %s/%s gateway %s/%s\n", ptr->AdapterName,
1470 ptr->IpAddressList.IpAddress.String, ptr->IpAddressList.IpMask.String,
1471 ptr->GatewayList.IpAddress.String, ptr->GatewayList.IpMask.String );
1472 row.dwIndex = ptr->Index;
1473 GetIfEntry( &row );
1474 ConvertInterfaceIndexToLuid( ptr->Index, &luid );
1475 ConvertInterfaceLuidToGuid( &luid, &guid );
1476 sprintf( name, "{%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
1477 guid.Data1, guid.Data2, guid.Data3, guid.Data4[0], guid.Data4[1],
1478 guid.Data4[2], guid.Data4[3], guid.Data4[4], guid.Data4[5],
1479 guid.Data4[6], guid.Data4[7] );
1480 ok( !strcmp( ptr->AdapterName, name ), "expected '%s' got '%s'\n", ptr->AdapterName, name );
1481 ok( !strcmp( ptr->Description, (char *)row.bDescr ), "got %s vs %s\n", ptr->Description, (char *)row.bDescr );
1482 ok( ptr->AddressLength == row.dwPhysAddrLen, "got %d vs %ld\n", ptr->AddressLength, row.dwPhysAddrLen );
1483 ok( !memcmp(ptr->Address, row.bPhysAddr, ptr->AddressLength ), "mismatch\n" );
1484 ok( ptr->Type == row.dwType, "got %d vs %ld\n", ptr->Type, row.dwType );
1485 ok( ptr->Type != MIB_IF_TYPE_LOOPBACK, "shouldn't get loopback\n" );
1486 ok( ptr->IpAddressList.IpAddress.String[0], "A valid IP address must be present\n" );
1487 ok( ptr->IpAddressList.IpMask.String[0], "A valid mask must be present\n" );
1488 ok( ptr->GatewayList.IpAddress.String[0], "A valid IP address must be present\n" );
1489 ok( ptr->GatewayList.IpMask.String[0], "A valid mask must be present\n" );
1490 ptr = ptr->Next;
1492 free( buf );
1495 static void testGetNetworkParams(void)
1497 DWORD apiReturn;
1498 ULONG len = 0;
1500 apiReturn = GetNetworkParams(NULL, NULL);
1501 if (apiReturn == ERROR_NOT_SUPPORTED) {
1502 skip("GetNetworkParams is not supported\n");
1503 return;
1505 ok(apiReturn == ERROR_INVALID_PARAMETER,
1506 "GetNetworkParams returned %ld, expected ERROR_INVALID_PARAMETER\n",
1507 apiReturn);
1508 apiReturn = GetNetworkParams(NULL, &len);
1509 ok(apiReturn == ERROR_BUFFER_OVERFLOW,
1510 "GetNetworkParams returned %ld, expected ERROR_BUFFER_OVERFLOW\n",
1511 apiReturn);
1512 if (apiReturn == ERROR_BUFFER_OVERFLOW) {
1513 PFIXED_INFO buf = malloc(len);
1515 apiReturn = GetNetworkParams(buf, &len);
1516 ok(apiReturn == NO_ERROR,
1517 "GetNetworkParams(buf, &dwSize) returned %ld, expected NO_ERROR\n",
1518 apiReturn);
1519 free(buf);
1523 static void testGetBestInterface(void)
1525 DWORD apiReturn;
1526 DWORD bestIfIndex;
1528 apiReturn = GetBestInterface( INADDR_ANY, &bestIfIndex );
1529 trace( "GetBestInterface([0.0.0.0], {%lu}) = %lu\n", bestIfIndex, apiReturn );
1530 if (apiReturn == ERROR_NOT_SUPPORTED)
1532 skip( "GetBestInterface is not supported\n" );
1533 return;
1536 apiReturn = GetBestInterface( INADDR_LOOPBACK, NULL );
1537 ok( apiReturn == ERROR_INVALID_PARAMETER,
1538 "GetBestInterface([127.0.0.1], NULL) returned %lu, expected %d\n",
1539 apiReturn, ERROR_INVALID_PARAMETER );
1541 apiReturn = GetBestInterface( INADDR_LOOPBACK, &bestIfIndex );
1542 ok( apiReturn == NO_ERROR,
1543 "GetBestInterface([127.0.0.1], {%lu}) returned %lu, expected %d\n",
1544 bestIfIndex, apiReturn, NO_ERROR );
1547 static void testGetBestInterfaceEx(void)
1549 DWORD apiReturn;
1550 DWORD bestIfIndex = 0;
1551 struct sockaddr_in destAddr;
1553 memset(&destAddr, 0, sizeof(struct sockaddr_in));
1554 destAddr.sin_family = AF_INET;
1555 destAddr.sin_addr.S_un.S_addr = INADDR_ANY;
1556 apiReturn = GetBestInterfaceEx( (struct sockaddr *)&destAddr, &bestIfIndex );
1557 trace( "GetBestInterfaceEx([0.0.0.0], {%lu}) = %lu\n", bestIfIndex, apiReturn );
1558 if (apiReturn == ERROR_NOT_SUPPORTED)
1560 skip( "GetBestInterfaceEx not supported\n" );
1561 return;
1564 apiReturn = GetBestInterfaceEx( NULL, NULL );
1565 ok( apiReturn == ERROR_INVALID_PARAMETER,
1566 "GetBestInterfaceEx(NULL, NULL) returned %lu, expected %d\n",
1567 apiReturn, ERROR_INVALID_PARAMETER );
1569 apiReturn = GetBestInterfaceEx( NULL, &bestIfIndex );
1570 ok( apiReturn == ERROR_INVALID_PARAMETER,
1571 "GetBestInterfaceEx(NULL, {%lu}) returned %lu, expected %d\n",
1572 bestIfIndex, apiReturn, ERROR_INVALID_PARAMETER );
1574 memset(&destAddr, 0, sizeof(struct sockaddr_in));
1575 apiReturn = GetBestInterfaceEx( (struct sockaddr *)&destAddr, NULL );
1576 ok( apiReturn == ERROR_INVALID_PARAMETER,
1577 "GetBestInterfaceEx(<AF_UNSPEC>, NULL) returned %lu, expected %d\n",
1578 apiReturn, ERROR_INVALID_PARAMETER );
1580 memset(&destAddr, -1, sizeof(struct sockaddr_in));
1581 apiReturn = GetBestInterfaceEx( (struct sockaddr *)&destAddr, NULL );
1582 ok( apiReturn == ERROR_INVALID_PARAMETER,
1583 "GetBestInterfaceEx(<INVALID>, NULL) returned %lu, expected %d\n",
1584 apiReturn, ERROR_INVALID_PARAMETER );
1586 memset(&destAddr, 0, sizeof(struct sockaddr_in));
1587 destAddr.sin_family = AF_INET;
1588 destAddr.sin_addr.S_un.S_addr = INADDR_LOOPBACK;
1589 apiReturn = GetBestInterfaceEx( (struct sockaddr *)&destAddr, NULL );
1590 ok( apiReturn == ERROR_INVALID_PARAMETER,
1591 "GetBestInterfaceEx([127.0.0.1], NULL) returned %lu, expected %d\n",
1592 apiReturn, ERROR_INVALID_PARAMETER );
1594 memset(&destAddr, 0, sizeof(struct sockaddr_in));
1595 destAddr.sin_family = AF_INET;
1596 destAddr.sin_addr.S_un.S_addr = INADDR_LOOPBACK;
1597 apiReturn = GetBestInterfaceEx( (struct sockaddr *)&destAddr, &bestIfIndex );
1598 ok( apiReturn == NO_ERROR,
1599 "GetBestInterfaceEx([127.0.0.1], {%lu}) returned %lu, expected %d\n",
1600 bestIfIndex, apiReturn, ERROR_INVALID_PARAMETER );
1603 static void testGetBestRoute(void)
1605 DWORD apiReturn;
1606 MIB_IPFORWARDROW bestRoute;
1608 apiReturn = GetBestRoute( INADDR_ANY, 0, &bestRoute );
1609 trace( "GetBestRoute([0.0.0.0], 0, [...]) = %lu\n", apiReturn );
1610 if (apiReturn == ERROR_NOT_SUPPORTED)
1612 skip( "GetBestRoute is not supported\n" );
1613 return;
1616 apiReturn = GetBestRoute( INADDR_ANY, 0, NULL );
1617 ok( apiReturn == ERROR_INVALID_PARAMETER,
1618 "GetBestRoute([0.0.0.0], 0, NULL) returned %lu, expected %d\n",
1619 apiReturn, ERROR_INVALID_PARAMETER );
1621 apiReturn = GetBestRoute( INADDR_LOOPBACK, 0, &bestRoute );
1622 ok( apiReturn == NO_ERROR,
1623 "GetBestRoute([127.0.0.1], 0, NULL) returned %lu, expected %d\n",
1624 apiReturn, NO_ERROR );
1628 still-to-be-tested 98-onward functions:
1629 IpReleaseAddress
1630 IpRenewAddress
1632 static DWORD CALLBACK testWin98Functions(void *p)
1634 testGetInterfaceInfo();
1635 testGetAdaptersInfo();
1636 testGetNetworkParams();
1637 testGetBestInterface();
1638 testGetBestInterfaceEx();
1639 testGetBestRoute();
1640 return 0;
1643 static void testGetPerAdapterInfo(void)
1645 DWORD ret, needed;
1646 void *buffer;
1648 ret = GetPerAdapterInfo(1, NULL, NULL);
1649 ok( ret == ERROR_INVALID_PARAMETER, "got %lu instead of ERROR_INVALID_PARAMETER\n", ret );
1650 needed = 0xdeadbeef;
1651 ret = GetPerAdapterInfo(1, NULL, &needed);
1652 if (ret == ERROR_NO_DATA) return; /* no such adapter */
1653 ok( ret == ERROR_BUFFER_OVERFLOW, "got %lu instead of ERROR_BUFFER_OVERFLOW\n", ret );
1654 ok( needed != 0xdeadbeef, "needed not set\n" );
1655 buffer = malloc( needed );
1656 ret = GetPerAdapterInfo(1, buffer, &needed);
1657 ok( ret == NO_ERROR, "got %lu instead of NO_ERROR\n", ret );
1658 free( buffer );
1661 static void testNotifyAddrChange(void)
1663 DWORD ret, bytes;
1664 OVERLAPPED overlapped;
1665 HANDLE handle;
1666 BOOL success;
1668 handle = NULL;
1669 ZeroMemory(&overlapped, sizeof(overlapped));
1670 ret = NotifyAddrChange(&handle, &overlapped);
1671 ok(ret == ERROR_IO_PENDING, "NotifyAddrChange returned %ld, expected ERROR_IO_PENDING\n", ret);
1672 ret = GetLastError();
1673 ok(ret == ERROR_IO_PENDING, "GetLastError returned %ld, expected ERROR_IO_PENDING\n", ret);
1674 success = CancelIPChangeNotify(&overlapped);
1675 ok(success == TRUE, "CancelIPChangeNotify returned FALSE, expected TRUE\n");
1676 success = GetOverlappedResult( handle, &overlapped, &bytes, TRUE );
1677 ok( !success && GetLastError() == ERROR_OPERATION_ABORTED, "got bret %d, err %lu.\n", success, GetLastError() );
1679 ZeroMemory(&overlapped, sizeof(overlapped));
1680 success = CancelIPChangeNotify(&overlapped);
1681 ok(success == FALSE, "CancelIPChangeNotify returned TRUE, expected FALSE\n");
1683 handle = NULL;
1684 ZeroMemory(&overlapped, sizeof(overlapped));
1685 overlapped.hEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
1686 ret = NotifyAddrChange(&handle, &overlapped);
1687 ok(ret == ERROR_IO_PENDING, "NotifyAddrChange returned %ld, expected ERROR_IO_PENDING\n", ret);
1688 ok(handle != INVALID_HANDLE_VALUE, "NotifyAddrChange returned invalid file handle\n");
1689 success = GetOverlappedResult(handle, &overlapped, &bytes, FALSE);
1690 ok(success == FALSE, "GetOverlappedResult returned TRUE, expected FALSE\n");
1691 ret = GetLastError();
1692 ok(ret == ERROR_IO_INCOMPLETE, "GetLastError returned %ld, expected ERROR_IO_INCOMPLETE\n", ret);
1693 success = CancelIPChangeNotify(&overlapped);
1694 ok(success == TRUE, "CancelIPChangeNotify returned FALSE, expected TRUE\n");
1695 success = GetOverlappedResult( handle, &overlapped, &bytes, TRUE );
1696 ok( !success && GetLastError() == ERROR_OPERATION_ABORTED, "got bret %d, err %lu.\n", success, GetLastError() );
1698 if (winetest_interactive)
1700 handle = NULL;
1701 ZeroMemory(&overlapped, sizeof(overlapped));
1702 overlapped.hEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
1703 trace("Testing asynchronous ipv4 address change notification. Please "
1704 "change the ipv4 address of one of your network interfaces\n");
1705 ret = NotifyAddrChange(&handle, &overlapped);
1706 ok(ret == ERROR_IO_PENDING, "NotifyAddrChange returned %ld, expected NO_ERROR\n", ret);
1707 success = GetOverlappedResult(handle, &overlapped, &bytes, TRUE);
1708 ok(success == TRUE, "GetOverlappedResult returned FALSE, expected TRUE\n");
1711 /* test synchronous functionality */
1712 if (winetest_interactive)
1714 trace("Testing synchronous ipv4 address change notification. Please "
1715 "change the ipv4 address of one of your network interfaces\n");
1716 ret = NotifyAddrChange(NULL, NULL);
1717 ok(ret == NO_ERROR, "NotifyAddrChange returned %ld, expected NO_ERROR\n", ret);
1722 still-to-be-tested 2K-onward functions:
1723 AddIPAddress
1724 CreateProxyArpEntry
1725 DeleteIPAddress
1726 DeleteProxyArpEntry
1727 EnableRouter
1728 FlushIpNetTable
1729 GetAdapterIndex
1730 NotifyRouteChange + CancelIPChangeNotify
1731 SendARP
1732 UnenableRouter
1734 static void testWin2KFunctions(void)
1736 testGetPerAdapterInfo();
1737 testNotifyAddrChange();
1740 static void test_GetAdaptersAddresses(void)
1742 BOOL dns_eligible_found = FALSE;
1743 ULONG ret, size, osize, i;
1744 IP_ADAPTER_ADDRESSES *aa, *ptr;
1745 IP_ADAPTER_UNICAST_ADDRESS *ua;
1747 ret = GetAdaptersAddresses(AF_UNSPEC, 0, NULL, NULL, NULL);
1748 ok(ret == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER got %lu\n", ret);
1750 /* size should be ignored and overwritten if buffer is NULL */
1751 size = 0x7fffffff;
1752 ret = GetAdaptersAddresses(AF_UNSPEC, 0, NULL, NULL, &size);
1753 ok(ret == ERROR_BUFFER_OVERFLOW, "expected ERROR_BUFFER_OVERFLOW, got %lu\n", ret);
1754 if (ret != ERROR_BUFFER_OVERFLOW) return;
1756 /* GAA_FLAG_SKIP_FRIENDLY_NAME is ignored */
1757 osize = 0x7fffffff;
1758 ret = GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_SKIP_FRIENDLY_NAME, NULL, NULL, &osize);
1759 ok(ret == ERROR_BUFFER_OVERFLOW, "expected ERROR_BUFFER_OVERFLOW, got %lu\n", ret);
1760 ok(osize == size, "expected %ld, got %ld\n", size, osize);
1762 ptr = malloc(size);
1763 ret = GetAdaptersAddresses(AF_UNSPEC, 0, NULL, ptr, &size);
1764 ok(!ret, "expected ERROR_SUCCESS got %lu\n", ret);
1765 free(ptr);
1767 /* higher size must not be changed to lower size */
1768 size *= 2;
1769 osize = size;
1770 ptr = malloc(osize);
1771 ret = GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX | GAA_FLAG_SKIP_FRIENDLY_NAME, NULL, ptr, &osize);
1772 while (ret == ERROR_BUFFER_OVERFLOW)
1774 size = osize * 2;
1775 osize = size;
1776 ptr = realloc(ptr, osize);
1777 ret = GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX | GAA_FLAG_SKIP_FRIENDLY_NAME, NULL, ptr, &osize);
1779 ok(!ret, "expected ERROR_SUCCESS got %lu\n", ret);
1780 ok(osize == size, "expected %ld, got %ld\n", size, osize);
1782 for (aa = ptr; !ret && aa; aa = aa->Next)
1784 char temp[128], buf[39];
1785 IP_ADAPTER_PREFIX *prefix;
1786 DWORD status;
1787 GUID guid;
1789 ok(aa->Length == sizeof(IP_ADAPTER_ADDRESSES_LH) ||
1790 aa->Length == sizeof(IP_ADAPTER_ADDRESSES_XP),
1791 "Unknown structure size of %lu bytes\n", aa->Length);
1792 ok(aa->DnsSuffix != NULL, "DnsSuffix is not a valid pointer\n");
1793 ok(aa->Description != NULL, "Description is not a valid pointer\n");
1794 ok(aa->FriendlyName != NULL, "FriendlyName is not a valid pointer\n");
1796 for (i = 0; i < aa->PhysicalAddressLength; i++)
1797 sprintf(temp + i * 3, "%02X-", aa->PhysicalAddress[i]);
1798 temp[i ? i * 3 - 1 : 0] = '\0';
1799 trace("idx %lu name %s %s dns %s descr %s phys %s mtu %lu flags %08lx type %lu\n",
1800 aa->IfIndex, aa->AdapterName,
1801 wine_dbgstr_w(aa->FriendlyName), wine_dbgstr_w(aa->DnsSuffix),
1802 wine_dbgstr_w(aa->Description), temp, aa->Mtu, aa->Flags, aa->IfType );
1803 ua = aa->FirstUnicastAddress;
1804 while (ua)
1806 ok(ua->Length == sizeof(IP_ADAPTER_UNICAST_ADDRESS_LH) ||
1807 ua->Length == sizeof(IP_ADAPTER_UNICAST_ADDRESS_XP),
1808 "Unknown structure size of %lu bytes\n", ua->Length);
1809 ok(ua->PrefixOrigin != IpPrefixOriginOther,
1810 "bad address config value %d\n", ua->PrefixOrigin);
1811 ok(ua->SuffixOrigin != IpSuffixOriginOther,
1812 "bad address config value %d\n", ua->PrefixOrigin);
1813 /* Address configured manually or from DHCP server? */
1814 if (ua->PrefixOrigin == IpPrefixOriginManual ||
1815 ua->PrefixOrigin == IpPrefixOriginDhcp)
1817 ok(ua->ValidLifetime, "expected non-zero value\n");
1818 ok(ua->PreferredLifetime, "expected non-zero value\n");
1819 ok(ua->LeaseLifetime, "expected non-zero\n");
1821 /* Is the address ok in the network (not duplicated)? */
1822 ok(ua->DadState != IpDadStateInvalid && ua->DadState != IpDadStateDuplicate,
1823 "bad address duplication value %d\n", ua->DadState);
1824 trace(" flags %08lx origin %u/%u state %u lifetime %lu/%lu/%lu prefix %u\n",
1825 ua->Flags, ua->PrefixOrigin, ua->SuffixOrigin, ua->DadState,
1826 ua->ValidLifetime, ua->PreferredLifetime, ua->LeaseLifetime,
1827 ua->Length < sizeof(IP_ADAPTER_UNICAST_ADDRESS_LH) ? 0 : ua->OnLinkPrefixLength);
1829 if (ua->Flags & IP_ADAPTER_ADDRESS_DNS_ELIGIBLE)
1830 dns_eligible_found = TRUE;
1832 if(ua->Address.lpSockaddr->sa_family == AF_INET)
1833 ok(aa->Ipv4Enabled == TRUE, "expected Ipv4Enabled flag to be set in interface %ls\n", aa->FriendlyName);
1834 else if(ua->Address.lpSockaddr->sa_family == AF_INET6)
1835 ok(aa->Ipv6Enabled == TRUE, "expected Ipv6Enabled flag to be set in interface %ls\n", aa->FriendlyName);
1837 ua = ua->Next;
1839 for (i = 0, temp[0] = '\0'; i < ARRAY_SIZE(aa->ZoneIndices); i++)
1840 sprintf(temp + strlen(temp), "%ld ", aa->ZoneIndices[i]);
1841 trace("status %u index %lu zone %s\n", aa->OperStatus, aa->Ipv6IfIndex, temp );
1842 prefix = aa->FirstPrefix;
1843 while (prefix)
1845 trace( " prefix %u/%lu flags %08lx\n", prefix->Address.iSockaddrLength,
1846 prefix->PrefixLength, prefix->Flags );
1847 prefix = prefix->Next;
1850 if (aa->Length < sizeof(IP_ADAPTER_ADDRESSES_LH)) continue;
1851 trace("speed %s/%s metrics %lu/%lu guid %s type %u/%u\n",
1852 wine_dbgstr_longlong(aa->TransmitLinkSpeed),
1853 wine_dbgstr_longlong(aa->ReceiveLinkSpeed),
1854 aa->Ipv4Metric, aa->Ipv6Metric, wine_dbgstr_guid((GUID*) &aa->NetworkGuid),
1855 aa->ConnectionType, aa->TunnelType);
1857 status = ConvertInterfaceLuidToGuid(&aa->Luid, &guid);
1858 ok(!status, "got %lu\n", status);
1859 sprintf(buf, "{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
1860 guid.Data1, guid.Data2, guid.Data3, guid.Data4[0], guid.Data4[1],
1861 guid.Data4[2], guid.Data4[3], guid.Data4[4], guid.Data4[5],
1862 guid.Data4[6], guid.Data4[7]);
1863 ok(!strcasecmp(aa->AdapterName, buf), "expected '%s' got '%s'\n", aa->AdapterName, buf);
1865 ok(dns_eligible_found, "Did not find any dns eligible addresses.\n");
1866 free(ptr);
1869 static DWORD get_extended_tcp_table( ULONG family, TCP_TABLE_CLASS class, void **table )
1871 DWORD ret, size = 0;
1873 *table = NULL;
1874 ret = pGetExtendedTcpTable( NULL, &size, TRUE, family, class, 0 );
1875 if (ret != ERROR_INSUFFICIENT_BUFFER) return ret;
1877 *table = malloc( size );
1878 ret = pGetExtendedTcpTable( *table, &size, TRUE, family, class, 0 );
1879 while (ret == ERROR_INSUFFICIENT_BUFFER)
1881 *table = realloc( *table, size );
1882 ret = pGetExtendedTcpTable( *table, &size, TRUE, family, class, 0 );
1884 return ret;
1887 static void test_GetExtendedTcpTable(void)
1889 DWORD ret;
1890 MIB_TCPTABLE *table;
1891 MIB_TCPTABLE_OWNER_PID *table_pid;
1892 MIB_TCPTABLE_OWNER_MODULE *table_module;
1894 if (!pGetExtendedTcpTable)
1896 win_skip("GetExtendedTcpTable not available\n");
1897 return;
1899 ret = pGetExtendedTcpTable( NULL, NULL, TRUE, AF_INET, TCP_TABLE_BASIC_ALL, 0 );
1900 ok( ret == ERROR_INVALID_PARAMETER, "got %lu\n", ret );
1902 ret = get_extended_tcp_table( AF_INET, TCP_TABLE_BASIC_ALL, (void **)&table );
1903 ok( ret == ERROR_SUCCESS, "got %lu\n", ret );
1904 free( table );
1906 ret = get_extended_tcp_table( AF_INET, TCP_TABLE_BASIC_LISTENER, (void **)&table );
1907 ok( ret == ERROR_SUCCESS, "got %lu\n", ret );
1908 free( table );
1910 ret = get_extended_tcp_table( AF_INET, TCP_TABLE_OWNER_PID_ALL, (void **)&table_pid );
1911 ok( ret == ERROR_SUCCESS, "got %lu\n", ret );
1912 free( table_pid );
1914 ret = get_extended_tcp_table( AF_INET, TCP_TABLE_OWNER_PID_LISTENER, (void **)&table_pid );
1915 ok( ret == ERROR_SUCCESS, "got %lu\n", ret );
1916 free( table_pid );
1918 ret = get_extended_tcp_table( AF_INET, TCP_TABLE_OWNER_MODULE_ALL, (void **)&table_module );
1919 ok( ret == ERROR_SUCCESS, "got %lu\n", ret );
1920 free( table_module );
1922 ret = get_extended_tcp_table( AF_INET, TCP_TABLE_OWNER_MODULE_LISTENER, (void **)&table_module );
1923 ok( ret == ERROR_SUCCESS, "got %lu\n", ret );
1924 free( table_module );
1927 static void test_AllocateAndGetTcpExTableFromStack(void)
1929 DWORD ret;
1930 MIB_TCPTABLE_OWNER_PID *table_ex = NULL;
1932 if (!pAllocateAndGetTcpExTableFromStack)
1934 win_skip("AllocateAndGetTcpExTableFromStack not available\n");
1935 return;
1938 if (0)
1940 /* crashes on native */
1941 ret = pAllocateAndGetTcpExTableFromStack( NULL, FALSE, INVALID_HANDLE_VALUE, 0, 0 );
1942 ok( ret == ERROR_INVALID_PARAMETER, "got %lu\n", ret );
1943 ret = pAllocateAndGetTcpExTableFromStack( (void **)&table_ex, FALSE, INVALID_HANDLE_VALUE, 0, AF_INET );
1944 ok( ret == ERROR_INVALID_PARAMETER, "got %lu\n", ret );
1945 ret = pAllocateAndGetTcpExTableFromStack( NULL, FALSE, GetProcessHeap(), 0, AF_INET );
1946 ok( ret == ERROR_INVALID_PARAMETER, "got %lu\n", ret );
1949 ret = pAllocateAndGetTcpExTableFromStack( (void **)&table_ex, FALSE, GetProcessHeap(), 0, 0 );
1950 ok( ret == ERROR_INVALID_PARAMETER || broken(ret == ERROR_NOT_SUPPORTED) /* win2k */, "got %lu\n", ret );
1952 ret = pAllocateAndGetTcpExTableFromStack( (void **)&table_ex, FALSE, GetProcessHeap(), 0, AF_INET );
1953 ok( ret == ERROR_SUCCESS, "got %lu\n", ret );
1955 if (ret == NO_ERROR && winetest_debug > 1)
1957 DWORD i;
1958 trace( "AllocateAndGetTcpExTableFromStack table: %lu entries\n", table_ex->dwNumEntries );
1959 for (i = 0; i < table_ex->dwNumEntries; i++)
1961 char remote_ip[16];
1963 strcpy(remote_ip, ntoa(table_ex->table[i].dwRemoteAddr));
1964 trace( "%lu: local %s:%u remote %s:%u state %lu pid %lu\n", i,
1965 ntoa(table_ex->table[i].dwLocalAddr), ntohs(table_ex->table[i].dwLocalPort),
1966 remote_ip, ntohs(table_ex->table[i].dwRemotePort),
1967 table_ex->table[i].dwState, table_ex->table[i].dwOwningPid );
1970 HeapFree(GetProcessHeap(), 0, table_ex);
1972 ret = pAllocateAndGetTcpExTableFromStack( (void **)&table_ex, FALSE, GetProcessHeap(), 0, AF_INET6 );
1973 ok( ret == ERROR_NOT_SUPPORTED, "got %lu\n", ret );
1976 static DWORD get_extended_udp_table( ULONG family, UDP_TABLE_CLASS class, void **table )
1978 DWORD ret, size = 0;
1980 *table = NULL;
1981 ret = pGetExtendedUdpTable( NULL, &size, TRUE, family, class, 0 );
1982 if (ret != ERROR_INSUFFICIENT_BUFFER) return ret;
1984 *table = malloc( size );
1985 ret = pGetExtendedUdpTable( *table, &size, TRUE, family, class, 0 );
1986 while (ret == ERROR_INSUFFICIENT_BUFFER)
1988 *table = realloc( *table, size );
1989 ret = pGetExtendedUdpTable( *table, &size, TRUE, family, class, 0 );
1991 return ret;
1994 static void test_GetExtendedUdpTable(void)
1996 DWORD ret;
1997 MIB_UDPTABLE *table;
1998 MIB_UDPTABLE_OWNER_PID *table_pid;
1999 MIB_UDPTABLE_OWNER_MODULE *table_module;
2001 if (!pGetExtendedUdpTable)
2003 win_skip("GetExtendedUdpTable not available\n");
2004 return;
2006 ret = pGetExtendedUdpTable( NULL, NULL, TRUE, AF_INET, UDP_TABLE_BASIC, 0 );
2007 ok( ret == ERROR_INVALID_PARAMETER, "got %lu\n", ret );
2009 ret = get_extended_udp_table( AF_INET, UDP_TABLE_BASIC, (void **)&table );
2010 ok( ret == ERROR_SUCCESS, "got %lu\n", ret );
2011 free( table );
2013 ret = get_extended_udp_table( AF_INET, UDP_TABLE_OWNER_PID, (void **)&table_pid );
2014 ok( ret == ERROR_SUCCESS, "got %lu\n", ret );
2015 free( table_pid );
2017 ret = get_extended_udp_table( AF_INET, UDP_TABLE_OWNER_MODULE, (void **)&table_module );
2018 ok( ret == ERROR_SUCCESS, "got %lu\n", ret );
2019 free( table_module );
2022 static void test_CreateSortedAddressPairs(void)
2024 SOCKADDR_IN6 dst[2];
2025 SOCKADDR_IN6_PAIR *pair;
2026 ULONG pair_count;
2027 DWORD ret;
2029 if (!pCreateSortedAddressPairs)
2031 win_skip( "CreateSortedAddressPairs not available\n" );
2032 return;
2035 memset( dst, 0, sizeof(dst) );
2036 dst[0].sin6_family = AF_INET6;
2037 dst[0].sin6_addr.u.Word[5] = 0xffff;
2038 dst[0].sin6_addr.u.Word[6] = 0x0808;
2039 dst[0].sin6_addr.u.Word[7] = 0x0808;
2041 pair_count = 0xdeadbeef;
2042 ret = pCreateSortedAddressPairs( NULL, 0, dst, 1, 0, NULL, &pair_count );
2043 ok( ret == ERROR_INVALID_PARAMETER, "got %lu\n", ret );
2044 ok( pair_count == 0xdeadbeef, "got %lu\n", pair_count );
2046 pair = (SOCKADDR_IN6_PAIR *)0xdeadbeef;
2047 pair_count = 0xdeadbeef;
2048 ret = pCreateSortedAddressPairs( NULL, 0, NULL, 1, 0, &pair, &pair_count );
2049 ok( ret == ERROR_INVALID_PARAMETER, "got %lu\n", ret );
2050 ok( pair == (SOCKADDR_IN6_PAIR *)0xdeadbeef, "got %p\n", pair );
2051 ok( pair_count == 0xdeadbeef, "got %lu\n", pair_count );
2053 pair = NULL;
2054 pair_count = 0xdeadbeef;
2055 ret = pCreateSortedAddressPairs( NULL, 0, dst, 1, 0, &pair, &pair_count );
2056 ok( ret == NO_ERROR, "got %lu\n", ret );
2057 ok( pair != NULL, "pair not set\n" );
2058 ok( pair_count >= 1, "got %lu\n", pair_count );
2059 ok( pair[0].SourceAddress != NULL, "src address not set\n" );
2060 ok( pair[0].DestinationAddress != NULL, "dst address not set\n" );
2061 FreeMibTable( pair );
2063 dst[1].sin6_family = AF_INET6;
2064 dst[1].sin6_addr.u.Word[5] = 0xffff;
2065 dst[1].sin6_addr.u.Word[6] = 0x0404;
2066 dst[1].sin6_addr.u.Word[7] = 0x0808;
2068 pair = NULL;
2069 pair_count = 0xdeadbeef;
2070 ret = pCreateSortedAddressPairs( NULL, 0, dst, 2, 0, &pair, &pair_count );
2071 ok( ret == NO_ERROR, "got %lu\n", ret );
2072 ok( pair != NULL, "pair not set\n" );
2073 ok( pair_count >= 2, "got %lu\n", pair_count );
2074 ok( pair[0].SourceAddress != NULL, "src address not set\n" );
2075 ok( pair[0].DestinationAddress != NULL, "dst address not set\n" );
2076 ok( pair[1].SourceAddress != NULL, "src address not set\n" );
2077 ok( pair[1].DestinationAddress != NULL, "dst address not set\n" );
2078 FreeMibTable( pair );
2081 static IP_ADAPTER_ADDRESSES *get_adapters( ULONG flags )
2083 ULONG err, size = 4096;
2084 IP_ADAPTER_ADDRESSES *tmp, *ret;
2086 if (!(ret = malloc( size ))) return NULL;
2087 err = GetAdaptersAddresses( AF_UNSPEC, flags, NULL, ret, &size );
2088 while (err == ERROR_BUFFER_OVERFLOW)
2090 if (!(tmp = realloc( ret, size ))) break;
2091 ret = tmp;
2092 err = GetAdaptersAddresses( AF_UNSPEC, flags, NULL, ret, &size );
2094 if (err == ERROR_SUCCESS) return ret;
2095 free( ret );
2096 return NULL;
2099 static DWORD get_interface_index(void)
2101 DWORD ret = 0;
2102 IP_ADAPTER_ADDRESSES *buf, *aa;
2104 buf = get_adapters( 0 );
2105 if (!buf) return 0;
2107 for (aa = buf; aa; aa = aa->Next)
2109 if (aa->IfType == IF_TYPE_ETHERNET_CSMACD)
2111 ret = aa->IfIndex;
2112 break;
2115 free( buf );
2116 return ret;
2119 static void convert_luid_to_name( NET_LUID *luid, WCHAR *expect_nameW, int len )
2121 struct
2123 const WCHAR *prefix;
2124 DWORD type;
2125 } prefixes[] =
2127 { L"other", IF_TYPE_OTHER },
2128 { L"ethernet", IF_TYPE_ETHERNET_CSMACD },
2129 { L"tokenring", IF_TYPE_ISO88025_TOKENRING },
2130 { L"ppp", IF_TYPE_PPP },
2131 { L"loopback", IF_TYPE_SOFTWARE_LOOPBACK },
2132 { L"atm", IF_TYPE_ATM },
2133 { L"wireless", IF_TYPE_IEEE80211 },
2134 { L"tunnel", IF_TYPE_TUNNEL },
2135 { L"ieee1394", IF_TYPE_IEEE1394 }
2137 DWORD i;
2138 const WCHAR *prefix = NULL;
2140 for (i = 0; i < ARRAY_SIZE(prefixes); i++)
2142 if (prefixes[i].type == luid->Info.IfType)
2144 prefix = prefixes[i].prefix;
2145 break;
2148 if (prefix)
2149 swprintf( expect_nameW, len, L"%s_%d", prefix, luid->Info.NetLuidIndex );
2150 else
2151 swprintf( expect_nameW, len, L"iftype%d_%d", luid->Info.IfType, luid->Info.NetLuidIndex );
2154 static void test_interface_identifier_conversion(void)
2156 DWORD ret, i;
2157 NET_LUID luid;
2158 GUID guid;
2159 SIZE_T len;
2160 WCHAR nameW[IF_MAX_STRING_SIZE + 1];
2161 WCHAR alias[IF_MAX_STRING_SIZE + 1];
2162 WCHAR expect_nameW[IF_MAX_STRING_SIZE + 1];
2163 char nameA[IF_MAX_STRING_SIZE + 1], *name;
2164 char expect_nameA[IF_MAX_STRING_SIZE + 1];
2165 NET_IFINDEX index;
2166 MIB_IF_TABLE2 *table;
2168 ret = GetIfTable2( &table );
2169 ok( !ret, "got %ld\n", ret );
2171 for (i = 0; i < table->NumEntries; i++)
2173 MIB_IF_ROW2 *row = table->Table + i;
2175 /* ConvertInterfaceIndexToLuid */
2176 memset( &luid, 0xff, sizeof(luid) );
2177 ret = ConvertInterfaceIndexToLuid( 0, &luid );
2178 ok( ret == ERROR_FILE_NOT_FOUND, "got %lu\n", ret );
2179 ok( !luid.Info.Reserved, "got %x\n", luid.Info.Reserved );
2180 ok( !luid.Info.NetLuidIndex, "got %u\n", luid.Info.NetLuidIndex );
2181 ok( !luid.Info.IfType, "got %u\n", luid.Info.IfType );
2183 luid.Info.Reserved = luid.Info.NetLuidIndex = luid.Info.IfType = 0xdead;
2184 ret = ConvertInterfaceIndexToLuid( row->InterfaceIndex, &luid );
2185 ok( !ret, "got %lu\n", ret );
2186 ok( luid.Value == row->InterfaceLuid.Value, "mismatch\n" );
2188 /* ConvertInterfaceLuidToIndex */
2189 ret = ConvertInterfaceLuidToIndex( &luid, NULL );
2190 ok( ret == ERROR_INVALID_PARAMETER, "got %lu\n", ret );
2192 ret = ConvertInterfaceLuidToIndex( &luid, &index );
2193 ok( !ret, "got %lu\n", ret );
2194 ok( index == row->InterfaceIndex, "mismatch\n" );
2196 /* ConvertInterfaceLuidToGuid */
2197 memset( &guid, 0xff, sizeof(guid) );
2198 ret = ConvertInterfaceLuidToGuid( NULL, &guid );
2199 ok( ret == ERROR_INVALID_PARAMETER, "got %lu\n", ret );
2200 ok( guid.Data1 == 0xffffffff, "got %s\n", debugstr_guid(&guid) );
2202 ret = ConvertInterfaceLuidToGuid( &luid, NULL );
2203 ok( ret == ERROR_INVALID_PARAMETER, "got %lu\n", ret );
2205 memset( &guid, 0, sizeof(guid) );
2206 ret = ConvertInterfaceLuidToGuid( &luid, &guid );
2207 ok( !ret, "got %lu\n", ret );
2208 ok( IsEqualGUID( &guid, &row->InterfaceGuid ), "mismatch\n" );
2210 /* ConvertInterfaceGuidToLuid */
2211 luid.Info.NetLuidIndex = 1;
2212 ret = ConvertInterfaceGuidToLuid( NULL, &luid );
2213 ok( ret == ERROR_INVALID_PARAMETER, "got %lu\n", ret );
2214 ok( luid.Info.NetLuidIndex == 1, "got %u\n", luid.Info.NetLuidIndex );
2216 ret = ConvertInterfaceGuidToLuid( &guid, NULL );
2217 ok( ret == ERROR_INVALID_PARAMETER, "got %lu\n", ret );
2219 luid.Info.Reserved = luid.Info.NetLuidIndex = luid.Info.IfType = 0xdead;
2220 ret = ConvertInterfaceGuidToLuid( &guid, &luid );
2221 ok( !ret, "got %lu\n", ret );
2222 ok( luid.Value == row->InterfaceLuid.Value ||
2223 broken( luid.Value != row->InterfaceLuid.Value), /* Win8 can have identical guids for two different ifaces */
2224 "mismatch\n" );
2225 if (luid.Value != row->InterfaceLuid.Value) continue;
2227 /* ConvertInterfaceLuidToNameW */
2228 ret = ConvertInterfaceLuidToNameW( &luid, NULL, 0 );
2229 ok( ret == ERROR_INVALID_PARAMETER, "got %lu\n", ret );
2231 ret = ConvertInterfaceLuidToNameW( &luid, nameW, 0 );
2232 ok( ret == ERROR_NOT_ENOUGH_MEMORY, "got %lu\n", ret );
2234 nameW[0] = 0;
2235 len = ARRAY_SIZE(nameW);
2236 ret = ConvertInterfaceLuidToNameW( &luid, nameW, len );
2237 ok( !ret, "got %lu\n", ret );
2238 convert_luid_to_name( &luid, expect_nameW, len );
2239 ok( !wcscmp( nameW, expect_nameW ), "got %s vs %s\n", debugstr_w( nameW ), debugstr_w( expect_nameW ) );
2241 /* ConvertInterfaceLuidToNameA */
2242 ret = ConvertInterfaceLuidToNameA( &luid, NULL, 0 );
2243 ok( ret == ERROR_NOT_ENOUGH_MEMORY, "got %lu\n", ret );
2245 ret = ConvertInterfaceLuidToNameA( &luid, nameA, 0 );
2246 ok( ret == ERROR_NOT_ENOUGH_MEMORY, "got %lu\n", ret );
2248 nameA[0] = 0;
2249 len = ARRAY_SIZE(nameA);
2250 ret = ConvertInterfaceLuidToNameA( &luid, nameA, len );
2251 ok( !ret, "got %lu\n", ret );
2252 ok( nameA[0], "name not set\n" );
2254 /* ConvertInterfaceNameToLuidW */
2255 luid.Info.Reserved = luid.Info.NetLuidIndex = luid.Info.IfType = 0xdead;
2256 ret = ConvertInterfaceNameToLuidW( NULL, &luid );
2257 ok( ret == ERROR_INVALID_NAME, "got %lu\n", ret );
2258 ok( !luid.Info.Reserved, "got %x\n", luid.Info.Reserved );
2259 ok( luid.Info.NetLuidIndex != 0xdead, "index not set\n" );
2260 ok( !luid.Info.IfType, "got %u\n", luid.Info.IfType );
2262 ret = ConvertInterfaceNameToLuidW( nameW, NULL );
2263 ok( ret == ERROR_INVALID_PARAMETER, "got %lu\n", ret );
2265 luid.Info.Reserved = luid.Info.NetLuidIndex = luid.Info.IfType = 0xdead;
2266 ret = ConvertInterfaceNameToLuidW( nameW, &luid );
2267 ok( !ret, "got %lu\n", ret );
2268 ok( luid.Value == row->InterfaceLuid.Value, "mismatch\n" );
2270 /* ConvertInterfaceNameToLuidA */
2271 luid.Info.Reserved = luid.Info.NetLuidIndex = luid.Info.IfType = 0xdead;
2272 ret = ConvertInterfaceNameToLuidA( NULL, &luid );
2273 ok( ret == ERROR_INVALID_NAME, "got %lu\n", ret );
2274 ok( luid.Info.Reserved == 0xdead, "reserved set\n" );
2275 ok( luid.Info.NetLuidIndex == 0xdead, "index set\n" );
2276 ok( luid.Info.IfType == 0xdead, "type set\n" );
2278 ret = ConvertInterfaceNameToLuidA( nameA, NULL );
2279 ok( ret == ERROR_INVALID_PARAMETER, "got %lu\n", ret );
2281 luid.Info.Reserved = luid.Info.NetLuidIndex = luid.Info.IfType = 0xdead;
2282 ret = ConvertInterfaceNameToLuidA( nameA, &luid );
2283 ok( !ret, "got %lu\n", ret );
2284 ok( luid.Value == row->InterfaceLuid.Value, "mismatch\n" );
2286 /* ConvertInterfaceAliasToLuid */
2287 ret = ConvertInterfaceAliasToLuid( row->Alias, &luid );
2288 ok( !ret, "got %lu\n", ret );
2289 ok( luid.Value == row->InterfaceLuid.Value, "mismatch\n" );
2291 /* ConvertInterfaceLuidToAlias */
2292 ret = ConvertInterfaceLuidToAlias( &row->InterfaceLuid, alias, ARRAY_SIZE(alias) );
2293 ok( !ret, "got %lu\n", ret );
2294 ok( !wcscmp( alias, row->Alias ), "got %s vs %s\n", wine_dbgstr_w( alias ), wine_dbgstr_w( row->Alias ) );
2296 index = if_nametoindex( nameA );
2297 ok( index == row->InterfaceIndex, "Got index %lu for %s, expected %lu\n", index, nameA, row->InterfaceIndex );
2298 /* Wargaming.net Game Center passes a GUID-like string. */
2299 index = if_nametoindex( "{00000001-0000-0000-0000-000000000000}" );
2300 ok( !index, "Got unexpected index %lu\n", index );
2301 index = if_nametoindex( wine_dbgstr_guid( &guid ) );
2302 ok( !index, "Got unexpected index %lu for input %s\n", index, wine_dbgstr_guid( &guid ) );
2304 /* if_indextoname */
2305 nameA[0] = 0;
2306 name = if_indextoname( row->InterfaceIndex, nameA );
2307 ConvertInterfaceLuidToNameA( &row->InterfaceLuid, expect_nameA, ARRAY_SIZE(expect_nameA) );
2308 ok( name == nameA, "mismatch\n" );
2309 ok( !strcmp( nameA, expect_nameA ), "mismatch\n" );
2311 FreeMibTable( table );
2314 static void test_interface_identifier_conversion_failure(void)
2316 DWORD ret;
2317 WCHAR nameW[IF_MAX_STRING_SIZE + 1];
2318 char nameA[IF_MAX_STRING_SIZE + 1], *name;
2319 NET_IFINDEX index;
2320 NET_LUID luid;
2321 GUID guid;
2322 static const GUID guid_zero;
2323 static const GUID guid_ones = { 0xffffffffUL, 0xffff, 0xffff, { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff } };
2325 /* ConvertInterfaceIndexToLuid */
2326 ret = ConvertInterfaceIndexToLuid( 0, NULL );
2327 ok( ret == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %lu\n", ret );
2329 ret = ConvertInterfaceIndexToLuid( -1, &luid );
2330 ok( ret == ERROR_FILE_NOT_FOUND, "expected ERROR_FILE_NOT_FOUND, got %lu\n", ret );
2332 /* ConvertInterfaceLuidToIndex */
2333 ret = ConvertInterfaceLuidToIndex( NULL, NULL );
2334 ok( ret == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %lu\n", ret );
2336 ret = ConvertInterfaceLuidToIndex( NULL, &index );
2337 ok( ret == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %lu\n", ret );
2339 luid.Value = -1;
2340 index = -1;
2341 ret = ConvertInterfaceLuidToIndex( &luid, &index );
2342 ok( ret == ERROR_FILE_NOT_FOUND, "expected ERROR_FILE_NOT_FOUND, got %lu\n", ret );
2343 ok( index == 0, "index shall be zero (got %lu)\n", index );
2345 /* ConvertInterfaceLuidToGuid */
2346 ret = ConvertInterfaceLuidToGuid( NULL, NULL );
2347 ok( ret == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %lu\n", ret );
2349 luid.Value = -1;
2350 memcpy( &guid, &guid_ones, sizeof(guid) );
2351 ret = ConvertInterfaceLuidToGuid( &luid, &guid );
2352 ok( ret == ERROR_FILE_NOT_FOUND, "expected ERROR_FILE_NOT_FOUND, got %lu\n", ret );
2353 ok( memcmp( &guid, &guid_zero, sizeof(guid) ) == 0, "guid shall be nil\n" );
2355 /* ConvertInterfaceGuidToLuid */
2356 ret = ConvertInterfaceGuidToLuid( NULL, NULL );
2357 ok( ret == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %lu\n", ret );
2359 /* ConvertInterfaceLuidToNameW */
2360 ret = ConvertInterfaceLuidToNameW( NULL, NULL, 0 );
2361 ok( ret == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %lu\n", ret );
2363 memset( nameW, 0, sizeof(nameW) );
2364 ret = ConvertInterfaceLuidToNameW( NULL, nameW, 0 );
2365 ok( ret == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %lu\n", ret );
2366 ok( !nameW[0], "nameW shall not change\n" );
2368 /* ConvertInterfaceLuidToNameA */
2369 ret = ConvertInterfaceLuidToNameA( NULL, NULL, 0 );
2370 ok( ret == ERROR_INVALID_PARAMETER, "got %lu\n", ret );
2372 memset( nameA, 0, sizeof(nameA) );
2373 ret = ConvertInterfaceLuidToNameA( NULL, nameA, 0 );
2374 ok( ret == ERROR_INVALID_PARAMETER, "got %lu\n", ret );
2375 ok( !nameA[0], "nameA shall not change\n" );
2377 /* ConvertInterfaceNameToLuidW */
2378 ret = ConvertInterfaceNameToLuidW( NULL, NULL );
2379 ok( ret == ERROR_INVALID_PARAMETER, "got %lu\n", ret );
2381 /* ConvertInterfaceNameToLuidA */
2382 ret = ConvertInterfaceNameToLuidA( NULL, NULL );
2383 ok( ret == ERROR_INVALID_NAME, "got %lu\n", ret );
2385 /* if_nametoindex */
2386 index = if_nametoindex( NULL );
2387 ok( !index, "Got unexpected index %lu\n", index );
2389 /* if_indextoname */
2390 name = if_indextoname( 0, NULL );
2391 ok( name == NULL, "expected NULL, got %s\n", name );
2393 name = if_indextoname( 0, nameA );
2394 ok( name == NULL, "expected NULL, got %p\n", name );
2396 name = if_indextoname( ~0u, nameA );
2397 ok( name == NULL, "expected NULL, got %p\n", name );
2400 static void test_GetIfEntry2(void)
2402 DWORD ret;
2403 MIB_IF_ROW2 row;
2404 NET_IFINDEX index;
2406 if (!(index = get_interface_index()))
2408 skip( "no suitable interface found\n" );
2409 return;
2412 ret = GetIfEntry2( NULL );
2413 ok( ret == ERROR_INVALID_PARAMETER, "got %lu\n", ret );
2415 memset( &row, 0, sizeof(row) );
2416 ret = GetIfEntry2( &row );
2417 ok( ret == ERROR_INVALID_PARAMETER, "got %lu\n", ret );
2419 memset( &row, 0, sizeof(row) );
2420 row.InterfaceIndex = index;
2421 ret = GetIfEntry2( &row );
2422 ok( ret == NO_ERROR, "got %lu\n", ret );
2423 ok( row.InterfaceIndex == index, "got %lu\n", index );
2426 static void test_GetIfTable2(void)
2428 DWORD ret;
2429 MIB_IF_TABLE2 *table;
2431 table = NULL;
2432 ret = GetIfTable2( &table );
2433 ok( ret == NO_ERROR, "got %lu\n", ret );
2434 ok( table != NULL, "table not set\n" );
2435 FreeMibTable( table );
2438 static void test_GetIfTable2Ex(void)
2440 DWORD ret;
2441 MIB_IF_TABLE2 *table;
2443 table = NULL;
2444 ret = GetIfTable2Ex( MibIfTableNormal, &table );
2445 ok( ret == NO_ERROR, "got %lu\n", ret );
2446 ok( table != NULL, "table not set\n" );
2447 FreeMibTable( table );
2449 table = NULL;
2450 ret = GetIfTable2Ex( MibIfTableRaw, &table );
2451 ok( ret == NO_ERROR, "got %lu\n", ret );
2452 ok( table != NULL, "table not set\n" );
2453 FreeMibTable( table );
2455 table = NULL;
2456 ret = GetIfTable2Ex( MibIfTableNormalWithoutStatistics, &table );
2457 ok( ret == NO_ERROR || broken(ret == ERROR_INVALID_PARAMETER), "got %lu\n", ret );
2458 ok( table != NULL || broken(!table), "table not set\n" );
2459 FreeMibTable( table );
2461 table = NULL;
2462 ret = GetIfTable2Ex( 3, &table );
2463 ok( ret == ERROR_INVALID_PARAMETER, "got %lu\n", ret );
2464 ok( !table, "table should not be set\n" );
2465 FreeMibTable( table );
2468 static void test_GetUnicastIpAddressEntry(void)
2470 IP_ADAPTER_ADDRESSES *aa, *ptr;
2471 MIB_UNICASTIPADDRESS_ROW row;
2472 DWORD ret;
2474 if (!pGetUnicastIpAddressEntry)
2476 win_skip( "GetUnicastIpAddressEntry not available\n" );
2477 return;
2480 ret = pGetUnicastIpAddressEntry( NULL );
2481 ok( ret == ERROR_INVALID_PARAMETER, "got %lu\n", ret );
2483 memset( &row, 0, sizeof(row) );
2484 ret = pGetUnicastIpAddressEntry( &row );
2485 ok( ret == ERROR_INVALID_PARAMETER, "got %lu\n", ret );
2487 memset( &row, 0, sizeof(row) );
2488 row.Address.Ipv4.sin_family = AF_INET;
2489 row.Address.Ipv4.sin_port = 0;
2490 row.Address.Ipv4.sin_addr.S_un.S_addr = 0x01020304;
2491 ret = pGetUnicastIpAddressEntry( &row );
2492 ok( ret == ERROR_FILE_NOT_FOUND, "got %lu\n", ret );
2494 memset( &row, 0, sizeof(row) );
2495 row.InterfaceIndex = 123;
2496 ret = pGetUnicastIpAddressEntry( &row );
2497 ok( ret == ERROR_INVALID_PARAMETER, "got %lu\n", ret );
2499 memset( &row, 0, sizeof(row) );
2500 row.InterfaceIndex = get_interface_index();
2501 row.Address.Ipv4.sin_family = AF_INET;
2502 row.Address.Ipv4.sin_port = 0;
2503 row.Address.Ipv4.sin_addr.S_un.S_addr = 0x01020304;
2504 ret = pGetUnicastIpAddressEntry( &row );
2505 ok( ret == ERROR_NOT_FOUND, "got %lu\n", ret );
2507 memset( &row, 0, sizeof(row) );
2508 row.InterfaceIndex = 123;
2509 row.Address.Ipv4.sin_family = AF_INET;
2510 row.Address.Ipv4.sin_port = 0;
2511 row.Address.Ipv4.sin_addr.S_un.S_addr = 0x01020304;
2512 ret = pGetUnicastIpAddressEntry( &row );
2513 ok( ret == ERROR_FILE_NOT_FOUND, "got %lu\n", ret );
2515 ptr = get_adapters( GAA_FLAG_INCLUDE_ALL_INTERFACES );
2516 ok(ptr != NULL, "can't get adapters\n");
2518 for (aa = ptr; !ret && aa; aa = aa->Next)
2520 IP_ADAPTER_UNICAST_ADDRESS *ua;
2522 ua = aa->FirstUnicastAddress;
2523 while (ua)
2525 /* test with luid */
2526 memset( &row, 0, sizeof(row) );
2527 memcpy(&row.InterfaceLuid, &aa->Luid, sizeof(aa->Luid));
2528 memcpy(&row.Address, ua->Address.lpSockaddr, ua->Address.iSockaddrLength);
2529 ret = pGetUnicastIpAddressEntry( &row );
2530 ok( ret == NO_ERROR, "got %lu\n", ret );
2532 /* test with index */
2533 memset( &row, 0, sizeof(row) );
2534 row.InterfaceIndex = aa->IfIndex;
2535 memcpy(&row.Address, ua->Address.lpSockaddr, ua->Address.iSockaddrLength);
2536 ret = pGetUnicastIpAddressEntry( &row );
2537 ok( ret == NO_ERROR, "got %lu\n", ret );
2538 if (ret == NO_ERROR)
2540 ok(row.InterfaceLuid.Info.Reserved == aa->Luid.Info.Reserved, "Expected %d, got %d\n",
2541 aa->Luid.Info.Reserved, row.InterfaceLuid.Info.Reserved);
2542 ok(row.InterfaceLuid.Info.NetLuidIndex == aa->Luid.Info.NetLuidIndex, "Expected %d, got %d\n",
2543 aa->Luid.Info.NetLuidIndex, row.InterfaceLuid.Info.NetLuidIndex);
2544 ok(row.InterfaceLuid.Info.IfType == aa->Luid.Info.IfType, "Expected %d, got %d\n",
2545 aa->Luid.Info.IfType, row.InterfaceLuid.Info.IfType);
2546 ok(row.InterfaceIndex == aa->IfIndex, "Expected %ld, got %ld\n",
2547 aa->IfIndex, row.InterfaceIndex);
2548 ok(row.PrefixOrigin == ua->PrefixOrigin, "Expected %d, got %d\n",
2549 ua->PrefixOrigin, row.PrefixOrigin);
2550 ok(row.SuffixOrigin == ua->SuffixOrigin, "Expected %d, got %d\n",
2551 ua->SuffixOrigin, row.SuffixOrigin);
2552 ok(row.ValidLifetime == ua->ValidLifetime, "Expected %ld, got %ld\n",
2553 ua->ValidLifetime, row.ValidLifetime);
2554 ok(row.PreferredLifetime == ua->PreferredLifetime, "Expected %ld, got %ld\n",
2555 ua->PreferredLifetime, row.PreferredLifetime);
2556 ok(row.OnLinkPrefixLength == ua->OnLinkPrefixLength, "Expected %d, got %d\n",
2557 ua->OnLinkPrefixLength, row.OnLinkPrefixLength);
2558 ok(row.SkipAsSource == 0, "Expected 0, got %d\n", row.SkipAsSource);
2559 ok(row.DadState == ua->DadState, "Expected %d, got %d\n", ua->DadState, row.DadState);
2560 if (row.Address.si_family == AF_INET6)
2561 ok(row.ScopeId.Value == row.Address.Ipv6.sin6_scope_id, "Expected %ld, got %ld\n",
2562 row.Address.Ipv6.sin6_scope_id, row.ScopeId.Value);
2563 ok(row.CreationTimeStamp.QuadPart, "CreationTimeStamp is 0\n");
2565 ua = ua->Next;
2568 free(ptr);
2571 static void test_GetUnicastIpAddressTable(void)
2573 MIB_UNICASTIPADDRESS_TABLE *table;
2574 DWORD ret;
2575 ULONG i;
2577 if (!pGetUnicastIpAddressTable)
2579 win_skip( "GetUnicastIpAddressTable not available\n" );
2580 return;
2583 ret = pGetUnicastIpAddressTable(AF_UNSPEC, NULL);
2584 ok( ret == ERROR_INVALID_PARAMETER, "got %lu\n", ret );
2586 ret = pGetUnicastIpAddressTable(AF_BAN, &table);
2587 ok( ret == ERROR_INVALID_PARAMETER, "got %lu\n", ret );
2589 ret = pGetUnicastIpAddressTable(AF_INET, &table);
2590 ok( ret == NO_ERROR, "got %lu\n", ret );
2591 trace("GetUnicastIpAddressTable(AF_INET): NumEntries %lu\n", table->NumEntries);
2592 FreeMibTable( table );
2594 ret = pGetUnicastIpAddressTable(AF_INET6, &table);
2595 ok( ret == NO_ERROR, "got %lu\n", ret );
2596 trace("GetUnicastIpAddressTable(AF_INET6): NumEntries %lu\n", table->NumEntries);
2597 FreeMibTable( table );
2599 ret = pGetUnicastIpAddressTable(AF_UNSPEC, &table);
2600 ok( ret == NO_ERROR, "got %lu\n", ret );
2601 trace("GetUnicastIpAddressTable(AF_UNSPEC): NumEntries %lu\n", table->NumEntries);
2602 for (i = 0; i < table->NumEntries && winetest_debug > 1; i++)
2604 trace("Index %lu:\n", i);
2605 trace("Address.si_family: %u\n", table->Table[i].Address.si_family);
2606 trace("InterfaceLuid.Info.Reserved: %u\n", table->Table[i].InterfaceLuid.Info.Reserved);
2607 trace("InterfaceLuid.Info.NetLuidIndex: %u\n", table->Table[i].InterfaceLuid.Info.NetLuidIndex);
2608 trace("InterfaceLuid.Info.IfType: %u\n", table->Table[i].InterfaceLuid.Info.IfType);
2609 trace("InterfaceIndex: %lu\n", table->Table[i].InterfaceIndex);
2610 trace("PrefixOrigin: %u\n", table->Table[i].PrefixOrigin);
2611 trace("SuffixOrigin: %u\n", table->Table[i].SuffixOrigin);
2612 trace("ValidLifetime: %lu seconds\n", table->Table[i].ValidLifetime);
2613 trace("PreferredLifetime: %lu seconds\n", table->Table[i].PreferredLifetime);
2614 trace("OnLinkPrefixLength: %u\n", table->Table[i].OnLinkPrefixLength);
2615 trace("SkipAsSource: %u\n", table->Table[i].SkipAsSource);
2616 trace("DadState: %u\n", table->Table[i].DadState);
2617 trace("ScopeId.Value: %lu\n", table->Table[i].ScopeId.Value);
2618 trace("CreationTimeStamp: %08lx%08lx\n", table->Table[i].CreationTimeStamp.HighPart, table->Table[i].CreationTimeStamp.LowPart);
2621 FreeMibTable( table );
2624 static void test_ConvertLengthToIpv4Mask(void)
2626 DWORD ret;
2627 DWORD n;
2628 ULONG mask;
2629 ULONG expected;
2631 if (!pConvertLengthToIpv4Mask)
2633 win_skip( "ConvertLengthToIpv4Mask not available\n" );
2634 return;
2637 for (n = 0; n <= 32; n++)
2639 mask = 0xdeadbeef;
2640 if (n > 0)
2641 expected = htonl( ~0u << (32 - n) );
2642 else
2643 expected = 0;
2645 ret = pConvertLengthToIpv4Mask( n, &mask );
2646 ok( ret == NO_ERROR, "ConvertLengthToIpv4Mask returned 0x%08lx, expected 0x%08x\n", ret, NO_ERROR );
2647 ok( mask == expected, "ConvertLengthToIpv4Mask mask value 0x%08lx, expected 0x%08lx\n", mask, expected );
2650 /* Testing for out of range. In this case both mask and return are changed to indicate error. */
2651 mask = 0xdeadbeef;
2652 ret = pConvertLengthToIpv4Mask( 33, &mask );
2653 ok( ret == ERROR_INVALID_PARAMETER, "ConvertLengthToIpv4Mask returned 0x%08lx, expected 0x%08x\n", ret, ERROR_INVALID_PARAMETER );
2654 ok( mask == INADDR_NONE, "ConvertLengthToIpv4Mask mask value 0x%08lx, expected 0x%08x\n", mask, INADDR_NONE );
2657 static void test_GetTcp6Table(void)
2659 DWORD ret;
2660 ULONG size = 0;
2661 PMIB_TCP6TABLE buf;
2663 if (!pGetTcp6Table)
2665 win_skip("GetTcp6Table not available\n");
2666 return;
2669 ret = pGetTcp6Table(NULL, &size, FALSE);
2670 if (ret == ERROR_NOT_SUPPORTED)
2672 skip("GetTcp6Table is not supported\n");
2673 return;
2675 ok(ret == ERROR_INSUFFICIENT_BUFFER,
2676 "GetTcp6Table(NULL, &size, FALSE) returned %ld, expected ERROR_INSUFFICIENT_BUFFER\n", ret);
2677 if (ret != ERROR_INSUFFICIENT_BUFFER) return;
2679 buf = malloc(size);
2681 ret = pGetTcp6Table(buf, &size, FALSE);
2682 ok(ret == NO_ERROR,
2683 "GetTcp6Table(buf, &size, FALSE) returned %ld, expected NO_ERROR\n", ret);
2685 if (ret == NO_ERROR && winetest_debug > 1)
2687 DWORD i;
2688 trace("TCP6 table: %lu entries\n", buf->dwNumEntries);
2689 for (i = 0; i < buf->dwNumEntries; i++)
2691 trace("%lu: local %s%%%u:%u remote %s%%%u:%u state %u\n", i,
2692 ntoa6(&buf->table[i].LocalAddr), ntohs(buf->table[i].dwLocalScopeId),
2693 ntohs(buf->table[i].dwLocalPort), ntoa6(&buf->table[i].RemoteAddr),
2694 ntohs(buf->table[i].dwRemoteScopeId), ntohs(buf->table[i].dwRemotePort),
2695 buf->table[i].State);
2699 free(buf);
2702 static void test_GetUdp6Table(void)
2704 DWORD apiReturn;
2705 ULONG dwSize = 0;
2707 if (!pGetUdp6Table) {
2708 win_skip("GetUdp6Table not available\n");
2709 return;
2712 apiReturn = pGetUdp6Table(NULL, &dwSize, FALSE);
2713 if (apiReturn == ERROR_NOT_SUPPORTED) {
2714 skip("GetUdp6Table is not supported\n");
2715 return;
2717 ok(apiReturn == ERROR_INSUFFICIENT_BUFFER,
2718 "GetUdp6Table(NULL, &dwSize, FALSE) returned %ld, expected ERROR_INSUFFICIENT_BUFFER\n",
2719 apiReturn);
2720 if (apiReturn == ERROR_INSUFFICIENT_BUFFER) {
2721 PMIB_UDP6TABLE buf = malloc(dwSize);
2723 apiReturn = pGetUdp6Table(buf, &dwSize, FALSE);
2724 ok(apiReturn == NO_ERROR,
2725 "GetUdp6Table(buf, &dwSize, FALSE) returned %ld, expected NO_ERROR\n",
2726 apiReturn);
2728 if (apiReturn == NO_ERROR && winetest_debug > 1)
2730 DWORD i;
2731 trace( "UDP6 table: %lu entries\n", buf->dwNumEntries );
2732 for (i = 0; i < buf->dwNumEntries; i++)
2733 trace( "%lu: %s%%%u:%u\n",
2734 i, ntoa6(&buf->table[i].dwLocalAddr), ntohs(buf->table[i].dwLocalScopeId), ntohs(buf->table[i].dwLocalPort) );
2736 free(buf);
2740 static void test_ParseNetworkString(void)
2742 struct
2744 char str[32];
2745 IN_ADDR addr;
2746 DWORD ret;
2748 ipv4_address_tests[] =
2750 {"1.2.3.4", {{{1, 2, 3, 4}}}},
2751 {"1.2.3.4a", {}, ERROR_INVALID_PARAMETER},
2752 {"1.2.3.0x4a", {}, ERROR_INVALID_PARAMETER},
2753 {"1.2.3", {}, ERROR_INVALID_PARAMETER},
2754 {"a1.2.3.4", {}, ERROR_INVALID_PARAMETER},
2755 {"0xdeadbeef", {}, ERROR_INVALID_PARAMETER},
2756 {"1.2.3.4:22", {}, ERROR_INVALID_PARAMETER},
2757 {"::1", {}, ERROR_INVALID_PARAMETER},
2758 {"winehq.org", {}, ERROR_INVALID_PARAMETER},
2760 struct
2762 char str[32];
2763 IN_ADDR addr;
2764 DWORD port;
2765 DWORD ret;
2767 ipv4_service_tests[] =
2769 {"1.2.3.4:22", {{{1, 2, 3, 4}}}, 22},
2770 {"winehq.org:22", {}, 0, ERROR_INVALID_PARAMETER},
2771 {"1.2.3.4", {}, 0, ERROR_INVALID_PARAMETER},
2772 {"1.2.3.4:0", {}, 0, ERROR_INVALID_PARAMETER},
2773 {"1.2.3.4:65536", {}, 0, ERROR_INVALID_PARAMETER},
2775 WCHAR wstr[IP6_ADDRESS_STRING_BUFFER_LENGTH] = {'1','2','7','.','0','.','0','.','1',':','2','2',0};
2776 NET_ADDRESS_INFO info;
2777 USHORT port;
2778 BYTE prefix_len;
2779 DWORD ret;
2780 int i;
2782 if (!pParseNetworkString)
2784 win_skip("ParseNetworkString not available\n");
2785 return;
2788 ret = pParseNetworkString(wstr, -1, NULL, NULL, NULL);
2789 ok(ret == ERROR_SUCCESS, "expected success, got %ld\n", ret);
2791 ret = pParseNetworkString(NULL, NET_STRING_IPV4_SERVICE, &info, NULL, NULL);
2792 ok(ret == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %ld\n", ret);
2794 for (i = 0; i < ARRAY_SIZE(ipv4_address_tests); i++)
2796 MultiByteToWideChar(CP_ACP, 0, ipv4_address_tests[i].str, sizeof(ipv4_address_tests[i].str),
2797 wstr, ARRAY_SIZE(wstr));
2798 memset(&info, 0x99, sizeof(info));
2799 port = 0x9999;
2800 prefix_len = 0x99;
2802 ret = pParseNetworkString(wstr, NET_STRING_IPV4_ADDRESS, &info, &port, &prefix_len);
2804 ok(ret == ipv4_address_tests[i].ret,
2805 "%s gave error %ld\n", ipv4_address_tests[i].str, ret);
2806 ok(info.Format == ret ? NET_ADDRESS_FORMAT_UNSPECIFIED : NET_ADDRESS_IPV4,
2807 "%s gave format %d\n", ipv4_address_tests[i].str, info.Format);
2808 ok(info.Ipv4Address.sin_addr.S_un.S_addr == (ret ? 0x99999999 : ipv4_address_tests[i].addr.S_un.S_addr),
2809 "%s gave address %d.%d.%d.%d\n", ipv4_address_tests[i].str,
2810 info.Ipv4Address.sin_addr.S_un.S_un_b.s_b1, info.Ipv4Address.sin_addr.S_un.S_un_b.s_b2,
2811 info.Ipv4Address.sin_addr.S_un.S_un_b.s_b3, info.Ipv4Address.sin_addr.S_un.S_un_b.s_b4);
2812 ok(info.Ipv4Address.sin_port == (ret ? 0x9999 : 0),
2813 "%s gave port %d\n", ipv4_service_tests[i].str, ntohs(info.Ipv4Address.sin_port));
2814 ok(port == (ret ? 0x9999 : 0),
2815 "%s gave port %d\n", ipv4_service_tests[i].str, port);
2816 ok(prefix_len == (ret ? 0x99 : 255),
2817 "%s gave prefix length %d\n", ipv4_service_tests[i].str, prefix_len);
2820 for (i = 0; i < ARRAY_SIZE(ipv4_service_tests); i++)
2822 MultiByteToWideChar(CP_ACP, 0, ipv4_service_tests[i].str, sizeof(ipv4_service_tests[i].str),
2823 wstr, ARRAY_SIZE(wstr));
2824 memset(&info, 0x99, sizeof(info));
2825 port = 0x9999;
2826 prefix_len = 0x99;
2828 ret = pParseNetworkString(wstr, NET_STRING_IPV4_SERVICE, &info, &port, &prefix_len);
2830 ok(ret == ipv4_service_tests[i].ret,
2831 "%s gave error %ld\n", ipv4_service_tests[i].str, ret);
2832 ok(info.Format == ret ? NET_ADDRESS_FORMAT_UNSPECIFIED : NET_ADDRESS_IPV4,
2833 "%s gave format %d\n", ipv4_address_tests[i].str, info.Format);
2834 ok(info.Ipv4Address.sin_addr.S_un.S_addr == (ret ? 0x99999999 : ipv4_service_tests[i].addr.S_un.S_addr),
2835 "%s gave address %d.%d.%d.%d\n", ipv4_service_tests[i].str,
2836 info.Ipv4Address.sin_addr.S_un.S_un_b.s_b1, info.Ipv4Address.sin_addr.S_un.S_un_b.s_b2,
2837 info.Ipv4Address.sin_addr.S_un.S_un_b.s_b3, info.Ipv4Address.sin_addr.S_un.S_un_b.s_b4);
2838 ok(ntohs(info.Ipv4Address.sin_port) == (ret ? 0x9999 : ipv4_service_tests[i].port),
2839 "%s gave port %d\n", ipv4_service_tests[i].str, ntohs(info.Ipv4Address.sin_port));
2840 ok(port == (ret ? 0x9999 : ipv4_service_tests[i].port),
2841 "%s gave port %d\n", ipv4_service_tests[i].str, port);
2842 ok(prefix_len == (ret ? 0x99 : 255),
2843 "%s gave prefix length %d\n", ipv4_service_tests[i].str, prefix_len);
2847 static void WINAPI test_ipaddtess_change_callback(PVOID context, PMIB_UNICASTIPADDRESS_ROW row,
2848 MIB_NOTIFICATION_TYPE notification_type)
2850 BOOL *callback_called = context;
2852 *callback_called = TRUE;
2854 ok(notification_type == MibInitialNotification, "Unexpected notification_type %#x.\n",
2855 notification_type);
2856 ok(!row, "Unexpected row %p.\n", row);
2859 static void test_NotifyUnicastIpAddressChange(void)
2861 BOOL callback_called;
2862 HANDLE handle;
2863 DWORD ret;
2865 if (!pNotifyUnicastIpAddressChange)
2867 win_skip("NotifyUnicastIpAddressChange not available.\n");
2868 return;
2871 callback_called = FALSE;
2872 ret = pNotifyUnicastIpAddressChange(AF_INET, test_ipaddtess_change_callback,
2873 &callback_called, TRUE, &handle);
2874 ok(ret == NO_ERROR, "Unexpected ret %#lx.\n", ret);
2875 ok(callback_called, "Callback was not called.\n");
2877 ret = pCancelMibChangeNotify2(handle);
2878 ok(ret == NO_ERROR, "Unexpected ret %#lx.\n", ret);
2879 ok(!CloseHandle(handle), "CloseHandle() succeeded.\n");
2882 static void test_ConvertGuidToString( void )
2884 DWORD err;
2885 char bufA[39];
2886 WCHAR bufW[39];
2887 GUID guid = { 0xa, 0xb, 0xc, { 0xd, 0, 0xe, 0xf } }, guid2;
2889 err = ConvertGuidToStringA( &guid, bufA, 38 );
2890 ok( err, "got %ld\n", err );
2891 err = ConvertGuidToStringA( &guid, bufA, 39 );
2892 ok( !err, "got %ld\n", err );
2893 ok( !strcmp( bufA, "{0000000A-000B-000C-0D00-0E0F00000000}" ), "got %s\n", bufA );
2895 err = ConvertGuidToStringW( &guid, bufW, 38 );
2896 ok( err, "got %ld\n", err );
2897 err = ConvertGuidToStringW( &guid, bufW, 39 );
2898 ok( !err, "got %ld\n", err );
2899 ok( !wcscmp( bufW, L"{0000000A-000B-000C-0D00-0E0F00000000}" ), "got %s\n", debugstr_w( bufW ) );
2901 err = ConvertStringToGuidW( bufW, &guid2 );
2902 ok( !err, "got %ld\n", err );
2903 ok( IsEqualGUID( &guid, &guid2 ), "guid mismatch\n" );
2905 err = ConvertStringToGuidW( L"foo", &guid2 );
2906 ok( err == ERROR_INVALID_PARAMETER, "got %ld\n", err );
2909 static void test_compartments(void)
2911 NET_IF_COMPARTMENT_ID id;
2913 id = GetCurrentThreadCompartmentId();
2914 ok(id == NET_IF_COMPARTMENT_ID_PRIMARY, "got %u\n", id);
2917 START_TEST(iphlpapi)
2920 loadIPHlpApi();
2921 if (hLibrary) {
2922 HANDLE thread;
2924 testWin98OnlyFunctions();
2925 testWinNT4Functions();
2927 /* run testGetXXXX in two threads at once to make sure we don't crash in that case */
2928 thread = CreateThread(NULL, 0, testWin98Functions, NULL, 0, NULL);
2929 testWin98Functions(NULL);
2930 WaitForSingleObject(thread, INFINITE);
2932 testWin2KFunctions();
2933 test_GetAdaptersAddresses();
2934 test_GetExtendedTcpTable();
2935 test_GetExtendedUdpTable();
2936 test_AllocateAndGetTcpExTableFromStack();
2937 test_CreateSortedAddressPairs();
2938 test_interface_identifier_conversion();
2939 test_interface_identifier_conversion_failure();
2940 test_GetIfEntry2();
2941 test_GetIfTable2();
2942 test_GetIfTable2Ex();
2943 test_GetUnicastIpAddressEntry();
2944 test_GetUnicastIpAddressTable();
2945 test_ConvertLengthToIpv4Mask();
2946 test_GetTcp6Table();
2947 test_GetUdp6Table();
2948 test_ParseNetworkString();
2949 test_NotifyUnicastIpAddressChange();
2950 test_ConvertGuidToString();
2951 test_compartments();
2952 freeIPHlpApi();