4 * Copyright (C) 2003 Juan Lang
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 * Some observations that an automated test can't produce:
23 * An adapter index is a key for an adapter. That is, if an index is returned
24 * from one API, that same index may be used successfully in another API, as
25 * long as the adapter remains present.
26 * If the adapter is removed and reinserted, however, the index may change (and
27 * indeed it does change on Win2K).
29 * The Name field of the IP_ADAPTER_INDEX_MAP entries returned by
30 * GetInterfaceInfo is declared as a wide string, but the bytes are actually
31 * an ASCII string on some versions of the IP helper API under Win9x. This was
32 * apparently an MS bug, it's corrected in later versions.
34 * The DomainName field of FIXED_INFO isn't NULL-terminated on Win98.
47 #include "wine/test.h"
51 #define ICMP_MINLEN 8 /* copied from dlls/iphlpapi/ip_icmp.h file */
53 static HMODULE hLibrary
= NULL
;
55 static DWORD (WINAPI
*pAllocateAndGetTcpExTableFromStack
)(void**,BOOL
,HANDLE
,DWORD
,DWORD
);
56 static DWORD (WINAPI
*pGetIfEntry2
)(PMIB_IF_ROW2
);
57 static DWORD (WINAPI
*pGetIfTable2
)(PMIB_IF_TABLE2
*);
58 static DWORD (WINAPI
*pGetIfTable2Ex
)(MIB_IF_TABLE_LEVEL
,PMIB_IF_TABLE2
*);
59 static DWORD (WINAPI
*pGetTcp6Table
)(PMIB_TCP6TABLE
,PDWORD
,BOOL
);
60 static DWORD (WINAPI
*pGetUdp6Table
)(PMIB_UDP6TABLE
,PDWORD
,BOOL
);
61 static DWORD (WINAPI
*pGetUnicastIpAddressEntry
)(MIB_UNICASTIPADDRESS_ROW
*);
62 static DWORD (WINAPI
*pGetUnicastIpAddressTable
)(ADDRESS_FAMILY
,MIB_UNICASTIPADDRESS_TABLE
**);
63 static DWORD (WINAPI
*pGetExtendedTcpTable
)(PVOID
,PDWORD
,BOOL
,ULONG
,TCP_TABLE_CLASS
,ULONG
);
64 static DWORD (WINAPI
*pGetExtendedUdpTable
)(PVOID
,PDWORD
,BOOL
,ULONG
,UDP_TABLE_CLASS
,ULONG
);
65 static DWORD (WINAPI
*pCreateSortedAddressPairs
)(const PSOCKADDR_IN6
,ULONG
,const PSOCKADDR_IN6
,ULONG
,ULONG
,
66 PSOCKADDR_IN6_PAIR
*,ULONG
*);
67 static void (WINAPI
*pFreeMibTable
)(void*);
68 static DWORD (WINAPI
*pConvertInterfaceGuidToLuid
)(const GUID
*,NET_LUID
*);
69 static DWORD (WINAPI
*pConvertInterfaceIndexToLuid
)(NET_IFINDEX
,NET_LUID
*);
70 static DWORD (WINAPI
*pConvertInterfaceLuidToGuid
)(const NET_LUID
*,GUID
*);
71 static DWORD (WINAPI
*pConvertInterfaceLuidToIndex
)(const NET_LUID
*,NET_IFINDEX
*);
72 static DWORD (WINAPI
*pConvertInterfaceLuidToNameW
)(const NET_LUID
*,WCHAR
*,SIZE_T
);
73 static DWORD (WINAPI
*pConvertInterfaceLuidToNameA
)(const NET_LUID
*,char*,SIZE_T
);
74 static DWORD (WINAPI
*pConvertInterfaceNameToLuidA
)(const char*,NET_LUID
*);
75 static DWORD (WINAPI
*pConvertInterfaceNameToLuidW
)(const WCHAR
*,NET_LUID
*);
76 static DWORD (WINAPI
*pConvertLengthToIpv4Mask
)(ULONG
,ULONG
*);
77 static DWORD (WINAPI
*pParseNetworkString
)(const WCHAR
*,DWORD
,NET_ADDRESS_INFO
*,USHORT
*,BYTE
*);
78 static DWORD (WINAPI
*pNotifyUnicastIpAddressChange
)(ADDRESS_FAMILY
, PUNICAST_IPADDRESS_CHANGE_CALLBACK
,
79 PVOID
, BOOLEAN
, HANDLE
*);
80 static DWORD (WINAPI
*pCancelMibChangeNotify2
)(HANDLE
);
82 static PCHAR (WINAPI
*pif_indextoname
)(NET_IFINDEX
,PCHAR
);
83 static NET_IFINDEX (WINAPI
*pif_nametoindex
)(const char*);
85 static void loadIPHlpApi(void)
87 hLibrary
= LoadLibraryA("iphlpapi.dll");
89 pAllocateAndGetTcpExTableFromStack
= (void *)GetProcAddress(hLibrary
, "AllocateAndGetTcpExTableFromStack");
90 pGetIfEntry2
= (void *)GetProcAddress(hLibrary
, "GetIfEntry2");
91 pGetIfTable2
= (void *)GetProcAddress(hLibrary
, "GetIfTable2");
92 pGetIfTable2Ex
= (void *)GetProcAddress(hLibrary
, "GetIfTable2Ex");
93 pGetTcp6Table
= (void *)GetProcAddress(hLibrary
, "GetTcp6Table");
94 pGetUdp6Table
= (void *)GetProcAddress(hLibrary
, "GetUdp6Table");
95 pGetUnicastIpAddressEntry
= (void *)GetProcAddress(hLibrary
, "GetUnicastIpAddressEntry");
96 pGetUnicastIpAddressTable
= (void *)GetProcAddress(hLibrary
, "GetUnicastIpAddressTable");
97 pGetExtendedTcpTable
= (void *)GetProcAddress(hLibrary
, "GetExtendedTcpTable");
98 pGetExtendedUdpTable
= (void *)GetProcAddress(hLibrary
, "GetExtendedUdpTable");
99 pCreateSortedAddressPairs
= (void *)GetProcAddress(hLibrary
, "CreateSortedAddressPairs");
100 pFreeMibTable
= (void *)GetProcAddress(hLibrary
, "FreeMibTable");
101 pConvertInterfaceGuidToLuid
= (void *)GetProcAddress(hLibrary
, "ConvertInterfaceGuidToLuid");
102 pConvertInterfaceIndexToLuid
= (void *)GetProcAddress(hLibrary
, "ConvertInterfaceIndexToLuid");
103 pConvertInterfaceLuidToGuid
= (void *)GetProcAddress(hLibrary
, "ConvertInterfaceLuidToGuid");
104 pConvertInterfaceLuidToIndex
= (void *)GetProcAddress(hLibrary
, "ConvertInterfaceLuidToIndex");
105 pConvertInterfaceLuidToNameA
= (void *)GetProcAddress(hLibrary
, "ConvertInterfaceLuidToNameA");
106 pConvertInterfaceLuidToNameW
= (void *)GetProcAddress(hLibrary
, "ConvertInterfaceLuidToNameW");
107 pConvertInterfaceNameToLuidA
= (void *)GetProcAddress(hLibrary
, "ConvertInterfaceNameToLuidA");
108 pConvertInterfaceNameToLuidW
= (void *)GetProcAddress(hLibrary
, "ConvertInterfaceNameToLuidW");
109 pConvertLengthToIpv4Mask
= (void *)GetProcAddress(hLibrary
, "ConvertLengthToIpv4Mask");
110 pParseNetworkString
= (void *)GetProcAddress(hLibrary
, "ParseNetworkString");
111 pif_indextoname
= (void *)GetProcAddress(hLibrary
, "if_indextoname");
112 pif_nametoindex
= (void *)GetProcAddress(hLibrary
, "if_nametoindex");
113 pNotifyUnicastIpAddressChange
= (void *)GetProcAddress(hLibrary
, "NotifyUnicastIpAddressChange");
114 pCancelMibChangeNotify2
= (void *)GetProcAddress(hLibrary
, "CancelMibChangeNotify2");
118 static void freeIPHlpApi(void)
120 FreeLibrary(hLibrary
);
123 /* replacement for inet_ntoa */
124 static const char *ntoa( DWORD ip
)
126 static char buffers
[4][16];
130 i
= (i
+ 1) % ARRAY_SIZE(buffers
);
131 sprintf( buffers
[i
], "%u.%u.%u.%u", (ip
>> 24) & 0xff, (ip
>> 16) & 0xff, (ip
>> 8) & 0xff, ip
& 0xff );
135 static const char *ntoa6( IN6_ADDR
*ip
)
137 static char buffers
[4][40];
139 unsigned short *p
= ip
->u
.Word
;
141 i
= (i
+ 1) % ARRAY_SIZE(buffers
);
142 sprintf( buffers
[i
], "%x:%x:%x:%x:%x:%x:%x:%x",
143 htons(p
[0]), htons(p
[1]), htons(p
[2]), htons(p
[3]), htons(p
[4]), htons(p
[5]), htons(p
[6]), htons(p
[7]) );
148 still-to-be-tested 98-only functions:
149 GetUniDirectionalAdapterInfo
151 static void testWin98OnlyFunctions(void)
155 static void testGetNumberOfInterfaces(void)
157 DWORD apiReturn
, numInterfaces
;
159 /* Crashes on Vista */
161 apiReturn
= GetNumberOfInterfaces(NULL
);
162 if (apiReturn
== ERROR_NOT_SUPPORTED
)
164 ok(apiReturn
== ERROR_INVALID_PARAMETER
,
165 "GetNumberOfInterfaces(NULL) returned %d, expected ERROR_INVALID_PARAMETER\n",
169 apiReturn
= GetNumberOfInterfaces(&numInterfaces
);
170 if (apiReturn
== ERROR_NOT_SUPPORTED
) {
171 skip("GetNumberOfInterfaces is not supported\n");
174 ok(apiReturn
== NO_ERROR
,
175 "GetNumberOfInterfaces returned %d, expected 0\n", apiReturn
);
178 static void testGetIfEntry(DWORD index
)
183 memset(&row
, 0, sizeof(row
));
184 apiReturn
= GetIfEntry(NULL
);
185 if (apiReturn
== ERROR_NOT_SUPPORTED
) {
186 skip("GetIfEntry is not supported\n");
189 ok(apiReturn
== ERROR_INVALID_PARAMETER
,
190 "GetIfEntry(NULL) returned %d, expected ERROR_INVALID_PARAMETER\n",
192 row
.dwIndex
= -1; /* hope that's always bogus! */
193 apiReturn
= GetIfEntry(&row
);
194 ok(apiReturn
== ERROR_INVALID_DATA
||
195 apiReturn
== ERROR_FILE_NOT_FOUND
/* Vista */,
196 "GetIfEntry(bogus row) returned %d, expected ERROR_INVALID_DATA or ERROR_FILE_NOT_FOUND\n",
199 apiReturn
= GetIfEntry(&row
);
200 ok(apiReturn
== NO_ERROR
,
201 "GetIfEntry returned %d, expected NO_ERROR\n", apiReturn
);
204 static void testGetIpAddrTable(void)
209 apiReturn
= GetIpAddrTable(NULL
, NULL
, FALSE
);
210 if (apiReturn
== ERROR_NOT_SUPPORTED
) {
211 skip("GetIpAddrTable is not supported\n");
214 ok(apiReturn
== ERROR_INVALID_PARAMETER
,
215 "GetIpAddrTable(NULL, NULL, FALSE) returned %d, expected ERROR_INVALID_PARAMETER\n",
217 apiReturn
= GetIpAddrTable(NULL
, &dwSize
, FALSE
);
218 ok(apiReturn
== ERROR_INSUFFICIENT_BUFFER
,
219 "GetIpAddrTable(NULL, &dwSize, FALSE) returned %d, expected ERROR_INSUFFICIENT_BUFFER\n",
221 if (apiReturn
== ERROR_INSUFFICIENT_BUFFER
) {
222 PMIB_IPADDRTABLE buf
= HeapAlloc(GetProcessHeap(), 0, dwSize
);
224 apiReturn
= GetIpAddrTable(buf
, &dwSize
, FALSE
);
225 ok(apiReturn
== NO_ERROR
,
226 "GetIpAddrTable(buf, &dwSize, FALSE) returned %d, expected NO_ERROR\n",
228 if (apiReturn
== NO_ERROR
&& buf
->dwNumEntries
)
231 testGetIfEntry(buf
->table
[0].dwIndex
);
232 for (i
= 0; i
< buf
->dwNumEntries
; i
++)
234 ok (buf
->table
[i
].wType
!= 0, "Test[%d]: expected wType > 0\n", i
);
235 trace("Entry[%d]: addr %s, dwIndex %u, wType 0x%x\n", i
,
236 ntoa(buf
->table
[i
].dwAddr
), buf
->table
[i
].dwIndex
, buf
->table
[i
].wType
);
239 HeapFree(GetProcessHeap(), 0, buf
);
243 static void testGetIfTable(void)
248 apiReturn
= GetIfTable(NULL
, NULL
, FALSE
);
249 if (apiReturn
== ERROR_NOT_SUPPORTED
) {
250 skip("GetIfTable is not supported\n");
253 ok(apiReturn
== ERROR_INVALID_PARAMETER
,
254 "GetIfTable(NULL, NULL, FALSE) returned %d, expected ERROR_INVALID_PARAMETER\n",
256 apiReturn
= GetIfTable(NULL
, &dwSize
, FALSE
);
257 ok(apiReturn
== ERROR_INSUFFICIENT_BUFFER
,
258 "GetIfTable(NULL, &dwSize, FALSE) returned %d, expected ERROR_INSUFFICIENT_BUFFER\n",
260 if (apiReturn
== ERROR_INSUFFICIENT_BUFFER
) {
261 PMIB_IFTABLE buf
= HeapAlloc(GetProcessHeap(), 0, dwSize
);
263 apiReturn
= GetIfTable(buf
, &dwSize
, FALSE
);
264 ok(apiReturn
== NO_ERROR
,
265 "GetIfTable(buf, &dwSize, FALSE) returned %d, expected NO_ERROR\n\n",
268 if (apiReturn
== NO_ERROR
&& winetest_debug
> 1)
271 char name
[MAX_INTERFACE_NAME_LEN
];
273 trace( "interface table: %u entries\n", buf
->dwNumEntries
);
274 for (i
= 0; i
< buf
->dwNumEntries
; i
++)
276 MIB_IFROW
*row
= &buf
->table
[i
];
277 WideCharToMultiByte( CP_ACP
, 0, row
->wszName
, -1, name
, MAX_INTERFACE_NAME_LEN
, NULL
, NULL
);
278 trace( "%u: '%s' type %u mtu %u speed %u phys",
279 row
->dwIndex
, name
, row
->dwType
, row
->dwMtu
, row
->dwSpeed
);
280 for (j
= 0; j
< row
->dwPhysAddrLen
; j
++)
281 printf( " %02x", row
->bPhysAddr
[j
] );
283 trace( " in: bytes %u upkts %u nupkts %u disc %u err %u unk %u\n",
284 row
->dwInOctets
, row
->dwInUcastPkts
, row
->dwInNUcastPkts
,
285 row
->dwInDiscards
, row
->dwInErrors
, row
->dwInUnknownProtos
);
286 trace( " out: bytes %u upkts %u nupkts %u disc %u err %u\n",
287 row
->dwOutOctets
, row
->dwOutUcastPkts
, row
->dwOutNUcastPkts
,
288 row
->dwOutDiscards
, row
->dwOutErrors
);
291 HeapFree(GetProcessHeap(), 0, buf
);
295 static void testGetIpForwardTable(void)
300 apiReturn
= GetIpForwardTable(NULL
, NULL
, FALSE
);
301 if (apiReturn
== ERROR_NOT_SUPPORTED
) {
302 skip("GetIpForwardTable is not supported\n");
305 ok(apiReturn
== ERROR_INVALID_PARAMETER
,
306 "GetIpForwardTable(NULL, NULL, FALSE) returned %d, expected ERROR_INVALID_PARAMETER\n",
308 apiReturn
= GetIpForwardTable(NULL
, &dwSize
, FALSE
);
309 ok(apiReturn
== ERROR_INSUFFICIENT_BUFFER
,
310 "GetIpForwardTable(NULL, &dwSize, FALSE) returned %d, expected ERROR_INSUFFICIENT_BUFFER\n",
312 if (apiReturn
== ERROR_INSUFFICIENT_BUFFER
) {
313 PMIB_IPFORWARDTABLE buf
= HeapAlloc(GetProcessHeap(), 0, dwSize
);
315 apiReturn
= GetIpForwardTable(buf
, &dwSize
, FALSE
);
316 ok(apiReturn
== NO_ERROR
,
317 "GetIpForwardTable(buf, &dwSize, FALSE) returned %d, expected NO_ERROR\n",
320 if (apiReturn
== NO_ERROR
)
324 trace( "IP forward table: %u entries\n", buf
->dwNumEntries
);
325 for (i
= 0; i
< buf
->dwNumEntries
; i
++)
327 if (!U1(buf
->table
[i
]).dwForwardDest
) /* Default route */
330 ok (U1(buf
->table
[i
]).dwForwardProto
== MIB_IPPROTO_NETMGMT
,
331 "Unexpected dwForwardProto %d\n", U1(buf
->table
[i
]).dwForwardProto
);
332 ok (U1(buf
->table
[i
]).dwForwardType
== MIB_IPROUTE_TYPE_INDIRECT
,
333 "Unexpected dwForwardType %d\n", U1(buf
->table
[i
]).dwForwardType
);
337 /* In general we should get MIB_IPPROTO_LOCAL but does not work
338 * for Vista, 2008 and 7. */
339 ok (U1(buf
->table
[i
]).dwForwardProto
== MIB_IPPROTO_LOCAL
||
340 broken(U1(buf
->table
[i
]).dwForwardProto
== MIB_IPPROTO_NETMGMT
),
341 "Unexpected dwForwardProto %d\n", U1(buf
->table
[i
]).dwForwardProto
);
342 /* The forward type varies depending on the address and gateway
343 * value so it is not worth testing in this case. */
346 trace( "%u: dest %s mask %s gw %s if %u type %u proto %u\n", i
,
347 ntoa( buf
->table
[i
].dwForwardDest
), ntoa( buf
->table
[i
].dwForwardMask
),
348 ntoa( buf
->table
[i
].dwForwardNextHop
), buf
->table
[i
].dwForwardIfIndex
,
349 U1(buf
->table
[i
]).dwForwardType
, U1(buf
->table
[i
]).dwForwardProto
);
352 HeapFree(GetProcessHeap(), 0, buf
);
356 static void testGetIpNetTable(void)
361 apiReturn
= GetIpNetTable(NULL
, NULL
, FALSE
);
362 if (apiReturn
== ERROR_NOT_SUPPORTED
) {
363 skip("GetIpNetTable is not supported\n");
366 ok(apiReturn
== ERROR_INVALID_PARAMETER
,
367 "GetIpNetTable(NULL, NULL, FALSE) returned %d, expected ERROR_INVALID_PARAMETER\n",
369 apiReturn
= GetIpNetTable(NULL
, &dwSize
, FALSE
);
370 ok(apiReturn
== ERROR_NO_DATA
|| apiReturn
== ERROR_INSUFFICIENT_BUFFER
,
371 "GetIpNetTable(NULL, &dwSize, FALSE) returned %d, expected ERROR_NO_DATA or ERROR_INSUFFICIENT_BUFFER\n",
373 if (apiReturn
== ERROR_NO_DATA
)
374 ; /* empty ARP table's okay */
375 else if (apiReturn
== ERROR_INSUFFICIENT_BUFFER
) {
376 PMIB_IPNETTABLE buf
= HeapAlloc(GetProcessHeap(), 0, dwSize
);
378 apiReturn
= GetIpNetTable(buf
, &dwSize
, FALSE
);
379 ok(apiReturn
== NO_ERROR
||
380 apiReturn
== ERROR_NO_DATA
, /* empty ARP table's okay */
381 "GetIpNetTable(buf, &dwSize, FALSE) returned %d, expected NO_ERROR\n",
384 if (apiReturn
== NO_ERROR
&& winetest_debug
> 1)
388 trace( "IP net table: %u entries\n", buf
->dwNumEntries
);
389 for (i
= 0; i
< buf
->dwNumEntries
; i
++)
391 trace( "%u: idx %u type %u addr %s phys",
392 i
, buf
->table
[i
].dwIndex
, U(buf
->table
[i
]).dwType
, ntoa( buf
->table
[i
].dwAddr
));
393 for (j
= 0; j
< buf
->table
[i
].dwPhysAddrLen
; j
++)
394 printf( " %02x", buf
->table
[i
].bPhysAddr
[j
] );
398 HeapFree(GetProcessHeap(), 0, buf
);
402 static void testGetIcmpStatistics(void)
407 /* Crashes on Vista */
409 apiReturn
= GetIcmpStatistics(NULL
);
410 if (apiReturn
== ERROR_NOT_SUPPORTED
)
412 ok(apiReturn
== ERROR_INVALID_PARAMETER
,
413 "GetIcmpStatistics(NULL) returned %d, expected ERROR_INVALID_PARAMETER\n",
417 apiReturn
= GetIcmpStatistics(&stats
);
418 if (apiReturn
== ERROR_NOT_SUPPORTED
)
420 skip("GetIcmpStatistics is not supported\n");
423 ok(apiReturn
== NO_ERROR
,
424 "GetIcmpStatistics returned %d, expected NO_ERROR\n", apiReturn
);
425 if (apiReturn
== NO_ERROR
&& winetest_debug
> 1)
427 trace( "ICMP stats: %8s %8s\n", "in", "out" );
428 trace( " dwMsgs: %8u %8u\n", stats
.stats
.icmpInStats
.dwMsgs
, stats
.stats
.icmpOutStats
.dwMsgs
);
429 trace( " dwErrors: %8u %8u\n", stats
.stats
.icmpInStats
.dwErrors
, stats
.stats
.icmpOutStats
.dwErrors
);
430 trace( " dwDestUnreachs: %8u %8u\n", stats
.stats
.icmpInStats
.dwDestUnreachs
, stats
.stats
.icmpOutStats
.dwDestUnreachs
);
431 trace( " dwTimeExcds: %8u %8u\n", stats
.stats
.icmpInStats
.dwTimeExcds
, stats
.stats
.icmpOutStats
.dwTimeExcds
);
432 trace( " dwParmProbs: %8u %8u\n", stats
.stats
.icmpInStats
.dwParmProbs
, stats
.stats
.icmpOutStats
.dwParmProbs
);
433 trace( " dwSrcQuenchs: %8u %8u\n", stats
.stats
.icmpInStats
.dwSrcQuenchs
, stats
.stats
.icmpOutStats
.dwSrcQuenchs
);
434 trace( " dwRedirects: %8u %8u\n", stats
.stats
.icmpInStats
.dwRedirects
, stats
.stats
.icmpOutStats
.dwRedirects
);
435 trace( " dwEchos: %8u %8u\n", stats
.stats
.icmpInStats
.dwEchos
, stats
.stats
.icmpOutStats
.dwEchos
);
436 trace( " dwEchoReps: %8u %8u\n", stats
.stats
.icmpInStats
.dwEchoReps
, stats
.stats
.icmpOutStats
.dwEchoReps
);
437 trace( " dwTimestamps: %8u %8u\n", stats
.stats
.icmpInStats
.dwTimestamps
, stats
.stats
.icmpOutStats
.dwTimestamps
);
438 trace( " dwTimestampReps: %8u %8u\n", stats
.stats
.icmpInStats
.dwTimestampReps
, stats
.stats
.icmpOutStats
.dwTimestampReps
);
439 trace( " dwAddrMasks: %8u %8u\n", stats
.stats
.icmpInStats
.dwAddrMasks
, stats
.stats
.icmpOutStats
.dwAddrMasks
);
440 trace( " dwAddrMaskReps: %8u %8u\n", stats
.stats
.icmpInStats
.dwAddrMaskReps
, stats
.stats
.icmpOutStats
.dwAddrMaskReps
);
444 static void testGetIpStatistics(void)
449 apiReturn
= GetIpStatistics(NULL
);
450 if (apiReturn
== ERROR_NOT_SUPPORTED
) {
451 skip("GetIpStatistics is not supported\n");
454 ok(apiReturn
== ERROR_INVALID_PARAMETER
,
455 "GetIpStatistics(NULL) returned %d, expected ERROR_INVALID_PARAMETER\n",
457 apiReturn
= GetIpStatistics(&stats
);
458 ok(apiReturn
== NO_ERROR
,
459 "GetIpStatistics returned %d, expected NO_ERROR\n", apiReturn
);
460 if (apiReturn
== NO_ERROR
&& winetest_debug
> 1)
462 trace( "IP stats:\n" );
463 trace( " dwForwarding: %u\n", U(stats
).dwForwarding
);
464 trace( " dwDefaultTTL: %u\n", stats
.dwDefaultTTL
);
465 trace( " dwInReceives: %u\n", stats
.dwInReceives
);
466 trace( " dwInHdrErrors: %u\n", stats
.dwInHdrErrors
);
467 trace( " dwInAddrErrors: %u\n", stats
.dwInAddrErrors
);
468 trace( " dwForwDatagrams: %u\n", stats
.dwForwDatagrams
);
469 trace( " dwInUnknownProtos: %u\n", stats
.dwInUnknownProtos
);
470 trace( " dwInDiscards: %u\n", stats
.dwInDiscards
);
471 trace( " dwInDelivers: %u\n", stats
.dwInDelivers
);
472 trace( " dwOutRequests: %u\n", stats
.dwOutRequests
);
473 trace( " dwRoutingDiscards: %u\n", stats
.dwRoutingDiscards
);
474 trace( " dwOutDiscards: %u\n", stats
.dwOutDiscards
);
475 trace( " dwOutNoRoutes: %u\n", stats
.dwOutNoRoutes
);
476 trace( " dwReasmTimeout: %u\n", stats
.dwReasmTimeout
);
477 trace( " dwReasmReqds: %u\n", stats
.dwReasmReqds
);
478 trace( " dwReasmOks: %u\n", stats
.dwReasmOks
);
479 trace( " dwReasmFails: %u\n", stats
.dwReasmFails
);
480 trace( " dwFragOks: %u\n", stats
.dwFragOks
);
481 trace( " dwFragFails: %u\n", stats
.dwFragFails
);
482 trace( " dwFragCreates: %u\n", stats
.dwFragCreates
);
483 trace( " dwNumIf: %u\n", stats
.dwNumIf
);
484 trace( " dwNumAddr: %u\n", stats
.dwNumAddr
);
485 trace( " dwNumRoutes: %u\n", stats
.dwNumRoutes
);
489 static void testGetTcpStatistics(void)
494 apiReturn
= GetTcpStatistics(NULL
);
495 if (apiReturn
== ERROR_NOT_SUPPORTED
) {
496 skip("GetTcpStatistics is not supported\n");
499 ok(apiReturn
== ERROR_INVALID_PARAMETER
,
500 "GetTcpStatistics(NULL) returned %d, expected ERROR_INVALID_PARAMETER\n",
502 apiReturn
= GetTcpStatistics(&stats
);
503 ok(apiReturn
== NO_ERROR
,
504 "GetTcpStatistics returned %d, expected NO_ERROR\n", apiReturn
);
505 if (apiReturn
== NO_ERROR
&& winetest_debug
> 1)
507 trace( "TCP stats:\n" );
508 trace( " dwRtoAlgorithm: %u\n", U(stats
).dwRtoAlgorithm
);
509 trace( " dwRtoMin: %u\n", stats
.dwRtoMin
);
510 trace( " dwRtoMax: %u\n", stats
.dwRtoMax
);
511 trace( " dwMaxConn: %u\n", stats
.dwMaxConn
);
512 trace( " dwActiveOpens: %u\n", stats
.dwActiveOpens
);
513 trace( " dwPassiveOpens: %u\n", stats
.dwPassiveOpens
);
514 trace( " dwAttemptFails: %u\n", stats
.dwAttemptFails
);
515 trace( " dwEstabResets: %u\n", stats
.dwEstabResets
);
516 trace( " dwCurrEstab: %u\n", stats
.dwCurrEstab
);
517 trace( " dwInSegs: %u\n", stats
.dwInSegs
);
518 trace( " dwOutSegs: %u\n", stats
.dwOutSegs
);
519 trace( " dwRetransSegs: %u\n", stats
.dwRetransSegs
);
520 trace( " dwInErrs: %u\n", stats
.dwInErrs
);
521 trace( " dwOutRsts: %u\n", stats
.dwOutRsts
);
522 trace( " dwNumConns: %u\n", stats
.dwNumConns
);
526 static void testGetUdpStatistics(void)
531 apiReturn
= GetUdpStatistics(NULL
);
532 if (apiReturn
== ERROR_NOT_SUPPORTED
) {
533 skip("GetUdpStatistics is not supported\n");
536 ok(apiReturn
== ERROR_INVALID_PARAMETER
,
537 "GetUdpStatistics(NULL) returned %d, expected ERROR_INVALID_PARAMETER\n",
539 apiReturn
= GetUdpStatistics(&stats
);
540 ok(apiReturn
== NO_ERROR
,
541 "GetUdpStatistics returned %d, expected NO_ERROR\n", apiReturn
);
542 if (apiReturn
== NO_ERROR
&& winetest_debug
> 1)
544 trace( "UDP stats:\n" );
545 trace( " dwInDatagrams: %u\n", stats
.dwInDatagrams
);
546 trace( " dwNoPorts: %u\n", stats
.dwNoPorts
);
547 trace( " dwInErrors: %u\n", stats
.dwInErrors
);
548 trace( " dwOutDatagrams: %u\n", stats
.dwOutDatagrams
);
549 trace( " dwNumAddrs: %u\n", stats
.dwNumAddrs
);
553 static void testGetIcmpStatisticsEx(void)
558 /* Crashes on Vista */
560 apiReturn
= GetIcmpStatisticsEx(NULL
, AF_INET
);
561 ok(apiReturn
== ERROR_INVALID_PARAMETER
,
562 "GetIcmpStatisticsEx(NULL, AF_INET) returned %d, expected ERROR_INVALID_PARAMETER\n", apiReturn
);
565 apiReturn
= GetIcmpStatisticsEx(&stats
, AF_BAN
);
566 ok(apiReturn
== ERROR_INVALID_PARAMETER
,
567 "GetIcmpStatisticsEx(&stats, AF_BAN) returned %d, expected ERROR_INVALID_PARAMETER\n", apiReturn
);
569 apiReturn
= GetIcmpStatisticsEx(&stats
, AF_INET
);
570 ok(apiReturn
== NO_ERROR
, "GetIcmpStatisticsEx returned %d, expected NO_ERROR\n", apiReturn
);
571 if (apiReturn
== NO_ERROR
&& winetest_debug
> 1)
574 trace( "ICMP IPv4 Ex stats: %8s %8s\n", "in", "out" );
575 trace( " dwMsgs: %8u %8u\n", stats
.icmpInStats
.dwMsgs
, stats
.icmpOutStats
.dwMsgs
);
576 trace( " dwErrors: %8u %8u\n", stats
.icmpInStats
.dwErrors
, stats
.icmpOutStats
.dwErrors
);
577 for (i
= 0; i
< 256; i
++)
578 trace( " rgdwTypeCount[%3i]: %8u %8u\n", i
, stats
.icmpInStats
.rgdwTypeCount
[i
], stats
.icmpOutStats
.rgdwTypeCount
[i
] );
581 apiReturn
= GetIcmpStatisticsEx(&stats
, AF_INET6
);
582 ok(apiReturn
== NO_ERROR
|| broken(apiReturn
== ERROR_NOT_SUPPORTED
),
583 "GetIcmpStatisticsEx returned %d, expected NO_ERROR\n", apiReturn
);
584 if (apiReturn
== NO_ERROR
&& winetest_debug
> 1)
587 trace( "ICMP IPv6 Ex stats: %8s %8s\n", "in", "out" );
588 trace( " dwMsgs: %8u %8u\n", stats
.icmpInStats
.dwMsgs
, stats
.icmpOutStats
.dwMsgs
);
589 trace( " dwErrors: %8u %8u\n", stats
.icmpInStats
.dwErrors
, stats
.icmpOutStats
.dwErrors
);
590 for (i
= 0; i
< 256; i
++)
591 trace( " rgdwTypeCount[%3i]: %8u %8u\n", i
, stats
.icmpInStats
.rgdwTypeCount
[i
], stats
.icmpOutStats
.rgdwTypeCount
[i
] );
595 static void testGetIpStatisticsEx(void)
600 apiReturn
= GetIpStatisticsEx(NULL
, AF_INET
);
601 ok(apiReturn
== ERROR_INVALID_PARAMETER
,
602 "GetIpStatisticsEx(NULL, AF_INET) returned %d, expected ERROR_INVALID_PARAMETER\n", apiReturn
);
604 apiReturn
= GetIpStatisticsEx(&stats
, AF_BAN
);
605 ok(apiReturn
== ERROR_INVALID_PARAMETER
,
606 "GetIpStatisticsEx(&stats, AF_BAN) returned %d, expected ERROR_INVALID_PARAMETER\n", apiReturn
);
608 apiReturn
= GetIpStatisticsEx(&stats
, AF_INET
);
609 ok(apiReturn
== NO_ERROR
, "GetIpStatisticsEx returned %d, expected NO_ERROR\n", apiReturn
);
610 if (apiReturn
== NO_ERROR
&& winetest_debug
> 1)
612 trace( "IP IPv4 Ex stats:\n" );
613 trace( " dwForwarding: %u\n", U(stats
).dwForwarding
);
614 trace( " dwDefaultTTL: %u\n", stats
.dwDefaultTTL
);
615 trace( " dwInReceives: %u\n", stats
.dwInReceives
);
616 trace( " dwInHdrErrors: %u\n", stats
.dwInHdrErrors
);
617 trace( " dwInAddrErrors: %u\n", stats
.dwInAddrErrors
);
618 trace( " dwForwDatagrams: %u\n", stats
.dwForwDatagrams
);
619 trace( " dwInUnknownProtos: %u\n", stats
.dwInUnknownProtos
);
620 trace( " dwInDiscards: %u\n", stats
.dwInDiscards
);
621 trace( " dwInDelivers: %u\n", stats
.dwInDelivers
);
622 trace( " dwOutRequests: %u\n", stats
.dwOutRequests
);
623 trace( " dwRoutingDiscards: %u\n", stats
.dwRoutingDiscards
);
624 trace( " dwOutDiscards: %u\n", stats
.dwOutDiscards
);
625 trace( " dwOutNoRoutes: %u\n", stats
.dwOutNoRoutes
);
626 trace( " dwReasmTimeout: %u\n", stats
.dwReasmTimeout
);
627 trace( " dwReasmReqds: %u\n", stats
.dwReasmReqds
);
628 trace( " dwReasmOks: %u\n", stats
.dwReasmOks
);
629 trace( " dwReasmFails: %u\n", stats
.dwReasmFails
);
630 trace( " dwFragOks: %u\n", stats
.dwFragOks
);
631 trace( " dwFragFails: %u\n", stats
.dwFragFails
);
632 trace( " dwFragCreates: %u\n", stats
.dwFragCreates
);
633 trace( " dwNumIf: %u\n", stats
.dwNumIf
);
634 trace( " dwNumAddr: %u\n", stats
.dwNumAddr
);
635 trace( " dwNumRoutes: %u\n", stats
.dwNumRoutes
);
638 apiReturn
= GetIpStatisticsEx(&stats
, AF_INET6
);
639 ok(apiReturn
== NO_ERROR
|| broken(apiReturn
== ERROR_NOT_SUPPORTED
),
640 "GetIpStatisticsEx returned %d, expected NO_ERROR\n", apiReturn
);
641 if (apiReturn
== NO_ERROR
&& winetest_debug
> 1)
643 trace( "IP IPv6 Ex stats:\n" );
644 trace( " dwForwarding: %u\n", U(stats
).dwForwarding
);
645 trace( " dwDefaultTTL: %u\n", stats
.dwDefaultTTL
);
646 trace( " dwInReceives: %u\n", stats
.dwInReceives
);
647 trace( " dwInHdrErrors: %u\n", stats
.dwInHdrErrors
);
648 trace( " dwInAddrErrors: %u\n", stats
.dwInAddrErrors
);
649 trace( " dwForwDatagrams: %u\n", stats
.dwForwDatagrams
);
650 trace( " dwInUnknownProtos: %u\n", stats
.dwInUnknownProtos
);
651 trace( " dwInDiscards: %u\n", stats
.dwInDiscards
);
652 trace( " dwInDelivers: %u\n", stats
.dwInDelivers
);
653 trace( " dwOutRequests: %u\n", stats
.dwOutRequests
);
654 trace( " dwRoutingDiscards: %u\n", stats
.dwRoutingDiscards
);
655 trace( " dwOutDiscards: %u\n", stats
.dwOutDiscards
);
656 trace( " dwOutNoRoutes: %u\n", stats
.dwOutNoRoutes
);
657 trace( " dwReasmTimeout: %u\n", stats
.dwReasmTimeout
);
658 trace( " dwReasmReqds: %u\n", stats
.dwReasmReqds
);
659 trace( " dwReasmOks: %u\n", stats
.dwReasmOks
);
660 trace( " dwReasmFails: %u\n", stats
.dwReasmFails
);
661 trace( " dwFragOks: %u\n", stats
.dwFragOks
);
662 trace( " dwFragFails: %u\n", stats
.dwFragFails
);
663 trace( " dwFragCreates: %u\n", stats
.dwFragCreates
);
664 trace( " dwNumIf: %u\n", stats
.dwNumIf
);
665 trace( " dwNumAddr: %u\n", stats
.dwNumAddr
);
666 trace( " dwNumRoutes: %u\n", stats
.dwNumRoutes
);
670 static void testGetTcpStatisticsEx(void)
675 apiReturn
= GetTcpStatisticsEx(NULL
, AF_INET
);
676 ok(apiReturn
== ERROR_INVALID_PARAMETER
,
677 "GetTcpStatisticsEx(NULL, AF_INET); returned %d, expected ERROR_INVALID_PARAMETER\n", apiReturn
);
679 apiReturn
= GetTcpStatisticsEx(&stats
, AF_BAN
);
680 ok(apiReturn
== ERROR_INVALID_PARAMETER
|| apiReturn
== ERROR_NOT_SUPPORTED
,
681 "GetTcpStatisticsEx(&stats, AF_BAN) returned %d, expected ERROR_INVALID_PARAMETER\n", apiReturn
);
683 apiReturn
= GetTcpStatisticsEx(&stats
, AF_INET
);
684 ok(apiReturn
== NO_ERROR
, "GetTcpStatisticsEx returned %d, expected NO_ERROR\n", apiReturn
);
685 if (apiReturn
== NO_ERROR
&& winetest_debug
> 1)
687 trace( "TCP IPv4 Ex stats:\n" );
688 trace( " dwRtoAlgorithm: %u\n", U(stats
).dwRtoAlgorithm
);
689 trace( " dwRtoMin: %u\n", stats
.dwRtoMin
);
690 trace( " dwRtoMax: %u\n", stats
.dwRtoMax
);
691 trace( " dwMaxConn: %u\n", stats
.dwMaxConn
);
692 trace( " dwActiveOpens: %u\n", stats
.dwActiveOpens
);
693 trace( " dwPassiveOpens: %u\n", stats
.dwPassiveOpens
);
694 trace( " dwAttemptFails: %u\n", stats
.dwAttemptFails
);
695 trace( " dwEstabResets: %u\n", stats
.dwEstabResets
);
696 trace( " dwCurrEstab: %u\n", stats
.dwCurrEstab
);
697 trace( " dwInSegs: %u\n", stats
.dwInSegs
);
698 trace( " dwOutSegs: %u\n", stats
.dwOutSegs
);
699 trace( " dwRetransSegs: %u\n", stats
.dwRetransSegs
);
700 trace( " dwInErrs: %u\n", stats
.dwInErrs
);
701 trace( " dwOutRsts: %u\n", stats
.dwOutRsts
);
702 trace( " dwNumConns: %u\n", stats
.dwNumConns
);
705 apiReturn
= GetTcpStatisticsEx(&stats
, AF_INET6
);
706 todo_wine
ok(apiReturn
== NO_ERROR
|| broken(apiReturn
== ERROR_NOT_SUPPORTED
),
707 "GetTcpStatisticsEx returned %d, expected NO_ERROR\n", apiReturn
);
708 if (apiReturn
== NO_ERROR
&& winetest_debug
> 1)
710 trace( "TCP IPv6 Ex stats:\n" );
711 trace( " dwRtoAlgorithm: %u\n", U(stats
).dwRtoAlgorithm
);
712 trace( " dwRtoMin: %u\n", stats
.dwRtoMin
);
713 trace( " dwRtoMax: %u\n", stats
.dwRtoMax
);
714 trace( " dwMaxConn: %u\n", stats
.dwMaxConn
);
715 trace( " dwActiveOpens: %u\n", stats
.dwActiveOpens
);
716 trace( " dwPassiveOpens: %u\n", stats
.dwPassiveOpens
);
717 trace( " dwAttemptFails: %u\n", stats
.dwAttemptFails
);
718 trace( " dwEstabResets: %u\n", stats
.dwEstabResets
);
719 trace( " dwCurrEstab: %u\n", stats
.dwCurrEstab
);
720 trace( " dwInSegs: %u\n", stats
.dwInSegs
);
721 trace( " dwOutSegs: %u\n", stats
.dwOutSegs
);
722 trace( " dwRetransSegs: %u\n", stats
.dwRetransSegs
);
723 trace( " dwInErrs: %u\n", stats
.dwInErrs
);
724 trace( " dwOutRsts: %u\n", stats
.dwOutRsts
);
725 trace( " dwNumConns: %u\n", stats
.dwNumConns
);
729 static void testGetUdpStatisticsEx(void)
734 apiReturn
= GetUdpStatisticsEx(NULL
, AF_INET
);
735 ok(apiReturn
== ERROR_INVALID_PARAMETER
,
736 "GetUdpStatisticsEx(NULL, AF_INET); returned %d, expected ERROR_INVALID_PARAMETER\n", apiReturn
);
738 apiReturn
= GetUdpStatisticsEx(&stats
, AF_BAN
);
739 ok(apiReturn
== ERROR_INVALID_PARAMETER
|| apiReturn
== ERROR_NOT_SUPPORTED
,
740 "GetUdpStatisticsEx(&stats, AF_BAN) returned %d, expected ERROR_INVALID_PARAMETER\n", apiReturn
);
742 apiReturn
= GetUdpStatisticsEx(&stats
, AF_INET
);
743 ok(apiReturn
== NO_ERROR
, "GetUdpStatisticsEx returned %d, expected NO_ERROR\n", apiReturn
);
744 if (apiReturn
== NO_ERROR
&& winetest_debug
> 1)
746 trace( "UDP IPv4 Ex stats:\n" );
747 trace( " dwInDatagrams: %u\n", stats
.dwInDatagrams
);
748 trace( " dwNoPorts: %u\n", stats
.dwNoPorts
);
749 trace( " dwInErrors: %u\n", stats
.dwInErrors
);
750 trace( " dwOutDatagrams: %u\n", stats
.dwOutDatagrams
);
751 trace( " dwNumAddrs: %u\n", stats
.dwNumAddrs
);
754 apiReturn
= GetUdpStatisticsEx(&stats
, AF_INET6
);
755 ok(apiReturn
== NO_ERROR
|| broken(apiReturn
== ERROR_NOT_SUPPORTED
),
756 "GetUdpStatisticsEx returned %d, expected NO_ERROR\n", apiReturn
);
757 if (apiReturn
== NO_ERROR
&& winetest_debug
> 1)
759 trace( "UDP IPv6 Ex stats:\n" );
760 trace( " dwInDatagrams: %u\n", stats
.dwInDatagrams
);
761 trace( " dwNoPorts: %u\n", stats
.dwNoPorts
);
762 trace( " dwInErrors: %u\n", stats
.dwInErrors
);
763 trace( " dwOutDatagrams: %u\n", stats
.dwOutDatagrams
);
764 trace( " dwNumAddrs: %u\n", stats
.dwNumAddrs
);
768 static void testGetTcpTable(void)
773 apiReturn
= GetTcpTable(NULL
, &dwSize
, FALSE
);
774 if (apiReturn
== ERROR_NOT_SUPPORTED
) {
775 skip("GetTcpTable is not supported\n");
778 ok(apiReturn
== ERROR_INSUFFICIENT_BUFFER
,
779 "GetTcpTable(NULL, &dwSize, FALSE) returned %d, expected ERROR_INSUFFICIENT_BUFFER\n",
781 if (apiReturn
== ERROR_INSUFFICIENT_BUFFER
) {
782 PMIB_TCPTABLE buf
= HeapAlloc(GetProcessHeap(), 0, dwSize
);
784 apiReturn
= GetTcpTable(buf
, &dwSize
, FALSE
);
785 ok(apiReturn
== NO_ERROR
,
786 "GetTcpTable(buf, &dwSize, FALSE) returned %d, expected NO_ERROR\n",
789 if (apiReturn
== NO_ERROR
&& winetest_debug
> 1)
792 trace( "TCP table: %u entries\n", buf
->dwNumEntries
);
793 for (i
= 0; i
< buf
->dwNumEntries
; i
++)
795 trace( "%u: local %s:%u remote %s:%u state %u\n", i
,
796 ntoa(buf
->table
[i
].dwLocalAddr
), ntohs(buf
->table
[i
].dwLocalPort
),
797 ntoa(buf
->table
[i
].dwRemoteAddr
), ntohs(buf
->table
[i
].dwRemotePort
),
798 U(buf
->table
[i
]).dwState
);
801 HeapFree(GetProcessHeap(), 0, buf
);
805 static void testGetUdpTable(void)
810 apiReturn
= GetUdpTable(NULL
, &dwSize
, FALSE
);
811 if (apiReturn
== ERROR_NOT_SUPPORTED
) {
812 skip("GetUdpTable is not supported\n");
815 ok(apiReturn
== ERROR_INSUFFICIENT_BUFFER
,
816 "GetUdpTable(NULL, &dwSize, FALSE) returned %d, expected ERROR_INSUFFICIENT_BUFFER\n",
818 if (apiReturn
== ERROR_INSUFFICIENT_BUFFER
) {
819 PMIB_UDPTABLE buf
= HeapAlloc(GetProcessHeap(), 0, dwSize
);
821 apiReturn
= GetUdpTable(buf
, &dwSize
, FALSE
);
822 ok(apiReturn
== NO_ERROR
,
823 "GetUdpTable(buf, &dwSize, FALSE) returned %d, expected NO_ERROR\n",
826 if (apiReturn
== NO_ERROR
&& winetest_debug
> 1)
829 trace( "UDP table: %u entries\n", buf
->dwNumEntries
);
830 for (i
= 0; i
< buf
->dwNumEntries
; i
++)
831 trace( "%u: %s:%u\n",
832 i
, ntoa( buf
->table
[i
].dwLocalAddr
), ntohs(buf
->table
[i
].dwLocalPort
) );
834 HeapFree(GetProcessHeap(), 0, buf
);
838 static void testSetTcpEntry(void)
843 memset(&row
, 0, sizeof(row
));
844 if(0) /* This test crashes in OS >= VISTA */
846 ret
= SetTcpEntry(NULL
);
847 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u, expected %u\n", ret
, ERROR_INVALID_PARAMETER
);
850 ret
= SetTcpEntry(&row
);
851 if (ret
== ERROR_NETWORK_ACCESS_DENIED
)
853 win_skip("SetTcpEntry failed with access error. Skipping test.\n");
856 todo_wine
ok( ret
== ERROR_INVALID_PARAMETER
, "got %u, expected %u\n", ret
, ERROR_INVALID_PARAMETER
);
858 U(row
).dwState
= MIB_TCP_STATE_DELETE_TCB
;
859 ret
= SetTcpEntry(&row
);
860 todo_wine
ok( ret
== ERROR_MR_MID_NOT_FOUND
|| broken(ret
== ERROR_INVALID_PARAMETER
),
861 "got %u, expected %u\n", ret
, ERROR_MR_MID_NOT_FOUND
);
864 static void testIcmpSendEcho(void)
867 char senddata
[32], replydata
[sizeof(senddata
) + sizeof(ICMP_ECHO_REPLY
)];
868 DWORD ret
, error
, replysz
= sizeof(replydata
);
870 ICMP_ECHO_REPLY
*reply
;
873 memset(senddata
, 0, sizeof(senddata
));
875 address
= htonl(INADDR_LOOPBACK
);
876 SetLastError(0xdeadbeef);
877 ret
= IcmpSendEcho(INVALID_HANDLE_VALUE
, address
, senddata
, sizeof(senddata
), NULL
, replydata
, replysz
, 1000);
878 error
= GetLastError();
879 ok (!ret
, "IcmpSendEcho succeeded unexpectedly\n");
880 ok (error
== ERROR_INVALID_PARAMETER
881 || broken(error
== ERROR_INVALID_HANDLE
) /* <= 2003 */,
882 "expected 87, got %d\n", error
);
884 icmp
= IcmpCreateFile();
885 if (icmp
== INVALID_HANDLE_VALUE
)
887 error
= GetLastError();
888 if (error
== ERROR_ACCESS_DENIED
)
890 skip ("ICMP is not available.\n");
894 ok (icmp
!= INVALID_HANDLE_VALUE
, "IcmpCreateFile failed unexpectedly with error %d\n", GetLastError());
897 SetLastError(0xdeadbeef);
898 ret
= IcmpSendEcho(icmp
, address
, senddata
, sizeof(senddata
), NULL
, replydata
, replysz
, 1000);
899 error
= GetLastError();
900 ok (!ret
, "IcmpSendEcho succeeded unexpectedly\n");
901 ok (error
== ERROR_INVALID_NETNAME
902 || broken(error
== IP_BAD_DESTINATION
) /* <= 2003 */,
903 "expected 1214, got %d\n", error
);
905 address
= htonl(INADDR_LOOPBACK
);
906 if (0) /* crashes in XP */
908 ret
= IcmpSendEcho(icmp
, address
, NULL
, sizeof(senddata
), NULL
, replydata
, replysz
, 1000);
909 ok (!ret
, "IcmpSendEcho succeeded unexpectedly\n");
912 SetLastError(0xdeadbeef);
913 ret
= IcmpSendEcho(icmp
, address
, senddata
, 0, NULL
, replydata
, replysz
, 1000);
914 error
= GetLastError();
915 ok (ret
, "IcmpSendEcho failed unexpectedly with error %d\n", error
);
917 SetLastError(0xdeadbeef);
918 ret
= IcmpSendEcho(icmp
, address
, NULL
, 0, NULL
, replydata
, replysz
, 1000);
919 error
= GetLastError();
920 ok (ret
, "IcmpSendEcho failed unexpectedly with error %d\n", error
);
922 SetLastError(0xdeadbeef);
923 ret
= IcmpSendEcho(icmp
, address
, senddata
, sizeof(senddata
), NULL
, NULL
, replysz
, 1000);
924 error
= GetLastError();
925 ok (!ret
, "IcmpSendEcho succeeded unexpectedly\n");
926 ok (error
== ERROR_INVALID_PARAMETER
, "expected 87, got %d\n", error
);
928 SetLastError(0xdeadbeef);
929 ret
= IcmpSendEcho(icmp
, address
, senddata
, sizeof(senddata
), NULL
, replydata
, 0, 1000);
930 error
= GetLastError();
931 ok (!ret
, "IcmpSendEcho succeeded unexpectedly\n");
932 ok (error
== ERROR_INVALID_PARAMETER
933 || broken(error
== ERROR_INSUFFICIENT_BUFFER
) /* <= 2003 */,
934 "expected 87, got %d\n", error
);
936 SetLastError(0xdeadbeef);
937 ret
= IcmpSendEcho(icmp
, address
, senddata
, sizeof(senddata
), NULL
, NULL
, 0, 1000);
938 error
= GetLastError();
939 ok (!ret
, "IcmpSendEcho succeeded unexpectedly\n");
940 ok (error
== ERROR_INVALID_PARAMETER
941 || broken(error
== ERROR_INSUFFICIENT_BUFFER
) /* <= 2003 */,
942 "expected 87, got %d\n", error
);
944 SetLastError(0xdeadbeef);
945 replysz
= sizeof(replydata
) - 1;
946 ret
= IcmpSendEcho(icmp
, address
, senddata
, sizeof(senddata
), NULL
, replydata
, replysz
, 1000);
947 error
= GetLastError();
948 ok (!ret
, "IcmpSendEcho succeeded unexpectedly\n");
949 ok (error
== IP_GENERAL_FAILURE
950 || broken(error
== IP_BUF_TOO_SMALL
) /* <= 2003 */,
951 "expected 11050, got %d\n", error
);
953 SetLastError(0xdeadbeef);
954 replysz
= sizeof(ICMP_ECHO_REPLY
);
955 ret
= IcmpSendEcho(icmp
, address
, senddata
, 0, NULL
, replydata
, replysz
, 1000);
956 error
= GetLastError();
957 ok (ret
, "IcmpSendEcho failed unexpectedly with error %d\n", error
);
959 SetLastError(0xdeadbeef);
960 replysz
= sizeof(ICMP_ECHO_REPLY
) + ICMP_MINLEN
;
961 ret
= IcmpSendEcho(icmp
, address
, senddata
, ICMP_MINLEN
, NULL
, replydata
, replysz
, 1000);
962 error
= GetLastError();
963 ok (ret
, "IcmpSendEcho failed unexpectedly with error %d\n", error
);
965 SetLastError(0xdeadbeef);
966 replysz
= sizeof(ICMP_ECHO_REPLY
) + ICMP_MINLEN
;
967 ret
= IcmpSendEcho(icmp
, address
, senddata
, ICMP_MINLEN
+ 1, NULL
, replydata
, replysz
, 1000);
968 error
= GetLastError();
969 ok (!ret
, "IcmpSendEcho succeeded unexpectedly\n");
970 ok (error
== IP_GENERAL_FAILURE
971 || broken(error
== IP_BUF_TOO_SMALL
) /* <= 2003 */,
972 "expected 11050, got %d\n", error
);
974 SetLastError(0xdeadbeef);
975 ret
= IcmpSendEcho(icmp
, address
, senddata
, ICMP_MINLEN
, NULL
, replydata
, replysz
- 1, 1000);
976 error
= GetLastError();
977 ok (!ret
, "IcmpSendEcho succeeded unexpectedly\n");
978 ok (error
== IP_GENERAL_FAILURE
979 || broken(error
== IP_BUF_TOO_SMALL
) /* <= 2003 */,
980 "expected 11050, got %d\n", error
);
982 /* in windows >= vista the timeout can't be invalid */
983 SetLastError(0xdeadbeef);
984 replysz
= sizeof(replydata
);
985 ret
= IcmpSendEcho(icmp
, address
, senddata
, sizeof(senddata
), NULL
, replydata
, replysz
, 0);
986 error
= GetLastError();
987 if (!ret
) ok(error
== ERROR_INVALID_PARAMETER
, "expected 87, got %d\n", error
);
989 SetLastError(0xdeadbeef);
990 ret
= IcmpSendEcho(icmp
, address
, senddata
, sizeof(senddata
), NULL
, replydata
, replysz
, -1);
991 error
= GetLastError();
992 if (!ret
) ok(error
== ERROR_INVALID_PARAMETER
, "expected 87, got %d\n", error
);
995 SetLastError(0xdeadbeef);
996 address
= htonl(INADDR_LOOPBACK
);
997 ret
= IcmpSendEcho(icmp
, address
, senddata
, sizeof(senddata
), NULL
, replydata
, replysz
, 1000);
998 error
= GetLastError();
1001 PICMP_ECHO_REPLY pong
= (PICMP_ECHO_REPLY
) replydata
;
1002 trace ("send addr : %s\n", ntoa(address
));
1003 trace ("reply addr : %s\n", ntoa(pong
->Address
));
1004 trace ("reply size : %u\n", replysz
);
1005 trace ("roundtrip : %u ms\n", pong
->RoundTripTime
);
1006 trace ("status : %u\n", pong
->Status
);
1007 trace ("recv size : %u\n", pong
->DataSize
);
1008 trace ("ttl : %u\n", pong
->Options
.Ttl
);
1009 trace ("flags : 0x%x\n", pong
->Options
.Flags
);
1013 skip ("Failed to ping with error %d, is lo interface down?.\n", error
);
1016 /* check reply data */
1017 SetLastError(0xdeadbeef);
1018 address
= htonl(INADDR_LOOPBACK
);
1019 for (i
= 0; i
< ARRAY_SIZE(senddata
); i
++) senddata
[i
] = i
& 0xff;
1020 ret
= IcmpSendEcho(icmp
, address
, senddata
, sizeof(senddata
), NULL
, replydata
, replysz
, 1000);
1021 error
= GetLastError();
1022 reply
= (ICMP_ECHO_REPLY
*)replydata
;
1023 ok(ret
, "IcmpSendEcho failed unexpectedly\n");
1024 ok(error
== NO_ERROR
, "Expect last error:0x%08x, got:0x%08x\n", NO_ERROR
, error
);
1025 ok(INADDR_LOOPBACK
== ntohl(reply
->Address
), "Address mismatch, expect:%s, got: %s\n", ntoa(INADDR_LOOPBACK
),
1026 ntoa(reply
->Address
));
1027 ok(reply
->Status
== IP_SUCCESS
, "Expect status:0x%08x, got:0x%08x\n", IP_SUCCESS
, reply
->Status
);
1028 ok(reply
->DataSize
== sizeof(senddata
), "Got size:%d\n", reply
->DataSize
);
1029 ok(!memcmp(senddata
, reply
->Data
, min(sizeof(senddata
), reply
->DataSize
)), "Data mismatch\n");
1033 still-to-be-tested NT4-onward functions:
1034 CreateIpForwardEntry
1035 DeleteIpForwardEntry
1046 static void testWinNT4Functions(void)
1048 testGetNumberOfInterfaces();
1049 testGetIpAddrTable();
1051 testGetIpForwardTable();
1052 testGetIpNetTable();
1053 testGetIcmpStatistics();
1054 testGetIpStatistics();
1055 testGetTcpStatistics();
1056 testGetUdpStatistics();
1057 testGetIcmpStatisticsEx();
1058 testGetIpStatisticsEx();
1059 testGetTcpStatisticsEx();
1060 testGetUdpStatisticsEx();
1067 static void testGetInterfaceInfo(void)
1072 apiReturn
= GetInterfaceInfo(NULL
, NULL
);
1073 if (apiReturn
== ERROR_NOT_SUPPORTED
) {
1074 skip("GetInterfaceInfo is not supported\n");
1077 ok(apiReturn
== ERROR_INVALID_PARAMETER
,
1078 "GetInterfaceInfo returned %d, expected ERROR_INVALID_PARAMETER\n",
1080 apiReturn
= GetInterfaceInfo(NULL
, &len
);
1081 ok(apiReturn
== ERROR_INSUFFICIENT_BUFFER
,
1082 "GetInterfaceInfo returned %d, expected ERROR_INSUFFICIENT_BUFFER\n",
1084 if (apiReturn
== ERROR_INSUFFICIENT_BUFFER
) {
1085 PIP_INTERFACE_INFO buf
= HeapAlloc(GetProcessHeap(), 0, len
);
1087 apiReturn
= GetInterfaceInfo(buf
, &len
);
1088 ok(apiReturn
== NO_ERROR
,
1089 "GetInterfaceInfo(buf, &dwSize) returned %d, expected NO_ERROR\n",
1091 HeapFree(GetProcessHeap(), 0, buf
);
1095 static void testGetAdaptersInfo(void)
1100 apiReturn
= GetAdaptersInfo(NULL
, NULL
);
1101 if (apiReturn
== ERROR_NOT_SUPPORTED
) {
1102 skip("GetAdaptersInfo is not supported\n");
1105 ok(apiReturn
== ERROR_INVALID_PARAMETER
,
1106 "GetAdaptersInfo returned %d, expected ERROR_INVALID_PARAMETER\n",
1108 apiReturn
= GetAdaptersInfo(NULL
, &len
);
1109 ok(apiReturn
== ERROR_NO_DATA
|| apiReturn
== ERROR_BUFFER_OVERFLOW
,
1110 "GetAdaptersInfo returned %d, expected ERROR_NO_DATA or ERROR_BUFFER_OVERFLOW\n",
1112 if (apiReturn
== ERROR_NO_DATA
)
1113 ; /* no adapter's, that's okay */
1114 else if (apiReturn
== ERROR_BUFFER_OVERFLOW
) {
1115 PIP_ADAPTER_INFO ptr
, buf
= HeapAlloc(GetProcessHeap(), 0, len
);
1117 apiReturn
= GetAdaptersInfo(buf
, &len
);
1118 ok(apiReturn
== NO_ERROR
,
1119 "GetAdaptersInfo(buf, &dwSize) returned %d, expected NO_ERROR\n",
1123 ok(ptr
->IpAddressList
.IpAddress
.String
[0], "A valid IP must be present\n");
1124 ok(ptr
->IpAddressList
.IpMask
.String
[0], "A valid mask must be present\n");
1125 trace("Adapter '%s', IP %s, Mask %s\n", ptr
->AdapterName
,
1126 ptr
->IpAddressList
.IpAddress
.String
, ptr
->IpAddressList
.IpMask
.String
);
1129 HeapFree(GetProcessHeap(), 0, buf
);
1133 static void testGetNetworkParams(void)
1138 apiReturn
= GetNetworkParams(NULL
, NULL
);
1139 if (apiReturn
== ERROR_NOT_SUPPORTED
) {
1140 skip("GetNetworkParams is not supported\n");
1143 ok(apiReturn
== ERROR_INVALID_PARAMETER
,
1144 "GetNetworkParams returned %d, expected ERROR_INVALID_PARAMETER\n",
1146 apiReturn
= GetNetworkParams(NULL
, &len
);
1147 ok(apiReturn
== ERROR_BUFFER_OVERFLOW
,
1148 "GetNetworkParams returned %d, expected ERROR_BUFFER_OVERFLOW\n",
1150 if (apiReturn
== ERROR_BUFFER_OVERFLOW
) {
1151 PFIXED_INFO buf
= HeapAlloc(GetProcessHeap(), 0, len
);
1153 apiReturn
= GetNetworkParams(buf
, &len
);
1154 ok(apiReturn
== NO_ERROR
,
1155 "GetNetworkParams(buf, &dwSize) returned %d, expected NO_ERROR\n",
1157 HeapFree(GetProcessHeap(), 0, buf
);
1162 still-to-be-tested 98-onward functions:
1168 static DWORD CALLBACK
testWin98Functions(void *p
)
1170 testGetInterfaceInfo();
1171 testGetAdaptersInfo();
1172 testGetNetworkParams();
1176 static void testGetPerAdapterInfo(void)
1181 ret
= GetPerAdapterInfo(1, NULL
, NULL
);
1182 if (ret
== ERROR_NOT_SUPPORTED
) {
1183 skip("GetPerAdapterInfo is not supported\n");
1186 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u instead of ERROR_INVALID_PARAMETER\n", ret
);
1187 needed
= 0xdeadbeef;
1188 ret
= GetPerAdapterInfo(1, NULL
, &needed
);
1189 if (ret
== ERROR_NO_DATA
) return; /* no such adapter */
1190 ok( ret
== ERROR_BUFFER_OVERFLOW
, "got %u instead of ERROR_BUFFER_OVERFLOW\n", ret
);
1191 ok( needed
!= 0xdeadbeef, "needed not set\n" );
1192 buffer
= HeapAlloc( GetProcessHeap(), 0, needed
);
1193 ret
= GetPerAdapterInfo(1, buffer
, &needed
);
1194 ok( ret
== NO_ERROR
, "got %u instead of NO_ERROR\n", ret
);
1195 HeapFree( GetProcessHeap(), 0, buffer
);
1198 static void testNotifyAddrChange(void)
1201 OVERLAPPED overlapped
;
1206 ZeroMemory(&overlapped
, sizeof(overlapped
));
1207 ret
= NotifyAddrChange(&handle
, &overlapped
);
1208 ok(ret
== ERROR_IO_PENDING
, "NotifyAddrChange returned %d, expected ERROR_IO_PENDING\n", ret
);
1209 ret
= GetLastError();
1210 todo_wine
ok(ret
== ERROR_IO_PENDING
, "GetLastError returned %d, expected ERROR_IO_PENDING\n", ret
);
1211 success
= CancelIPChangeNotify(&overlapped
);
1212 todo_wine
ok(success
== TRUE
, "CancelIPChangeNotify returned FALSE, expected TRUE\n");
1214 ZeroMemory(&overlapped
, sizeof(overlapped
));
1215 success
= CancelIPChangeNotify(&overlapped
);
1216 ok(success
== FALSE
, "CancelIPChangeNotify returned TRUE, expected FALSE\n");
1219 ZeroMemory(&overlapped
, sizeof(overlapped
));
1220 overlapped
.hEvent
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
1221 ret
= NotifyAddrChange(&handle
, &overlapped
);
1222 ok(ret
== ERROR_IO_PENDING
, "NotifyAddrChange returned %d, expected ERROR_IO_PENDING\n", ret
);
1223 todo_wine
ok(handle
!= INVALID_HANDLE_VALUE
, "NotifyAddrChange returned invalid file handle\n");
1224 success
= GetOverlappedResult(handle
, &overlapped
, &bytes
, FALSE
);
1225 ok(success
== FALSE
, "GetOverlappedResult returned TRUE, expected FALSE\n");
1226 ret
= GetLastError();
1227 ok(ret
== ERROR_IO_INCOMPLETE
, "GetLastError returned %d, expected ERROR_IO_INCOMPLETE\n", ret
);
1228 success
= CancelIPChangeNotify(&overlapped
);
1229 todo_wine
ok(success
== TRUE
, "CancelIPChangeNotify returned FALSE, expected TRUE\n");
1231 if (winetest_interactive
)
1234 ZeroMemory(&overlapped
, sizeof(overlapped
));
1235 overlapped
.hEvent
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
1236 trace("Testing asynchronous ipv4 address change notification. Please "
1237 "change the ipv4 address of one of your network interfaces\n");
1238 ret
= NotifyAddrChange(&handle
, &overlapped
);
1239 ok(ret
== ERROR_IO_PENDING
, "NotifyAddrChange returned %d, expected NO_ERROR\n", ret
);
1240 success
= GetOverlappedResult(handle
, &overlapped
, &bytes
, TRUE
);
1241 ok(success
== TRUE
, "GetOverlappedResult returned FALSE, expected TRUE\n");
1244 /* test synchronous functionality */
1245 if (winetest_interactive
)
1247 trace("Testing synchronous ipv4 address change notification. Please "
1248 "change the ipv4 address of one of your network interfaces\n");
1249 ret
= NotifyAddrChange(NULL
, NULL
);
1250 todo_wine
ok(ret
== NO_ERROR
, "NotifyAddrChange returned %d, expected NO_ERROR\n", ret
);
1255 still-to-be-tested 2K-onward functions:
1263 NotifyRouteChange + CancelIPChangeNotify
1267 static void testWin2KFunctions(void)
1269 testGetPerAdapterInfo();
1270 testNotifyAddrChange();
1273 static void test_GetAdaptersAddresses(void)
1275 ULONG ret
, size
, osize
, i
;
1276 IP_ADAPTER_ADDRESSES
*aa
, *ptr
;
1277 IP_ADAPTER_UNICAST_ADDRESS
*ua
;
1279 ret
= GetAdaptersAddresses(AF_UNSPEC
, 0, NULL
, NULL
, NULL
);
1280 ok(ret
== ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER got %u\n", ret
);
1282 /* size should be ignored and overwritten if buffer is NULL */
1284 ret
= GetAdaptersAddresses(AF_UNSPEC
, 0, NULL
, NULL
, &size
);
1285 ok(ret
== ERROR_BUFFER_OVERFLOW
, "expected ERROR_BUFFER_OVERFLOW, got %u\n", ret
);
1286 if (ret
!= ERROR_BUFFER_OVERFLOW
) return;
1288 ptr
= HeapAlloc(GetProcessHeap(), 0, size
);
1289 ret
= GetAdaptersAddresses(AF_UNSPEC
, 0, NULL
, ptr
, &size
);
1290 ok(!ret
, "expected ERROR_SUCCESS got %u\n", ret
);
1291 HeapFree(GetProcessHeap(), 0, ptr
);
1293 /* higher size must not be changed to lower size */
1296 ptr
= HeapAlloc(GetProcessHeap(), 0, osize
);
1297 ret
= GetAdaptersAddresses(AF_UNSPEC
, GAA_FLAG_INCLUDE_PREFIX
, NULL
, ptr
, &osize
);
1298 ok(!ret
, "expected ERROR_SUCCESS got %u\n", ret
);
1299 ok(osize
== size
, "expected %d, got %d\n", size
, osize
);
1301 for (aa
= ptr
; !ret
&& aa
; aa
= aa
->Next
)
1303 char temp
[128], buf
[39];
1304 IP_ADAPTER_PREFIX
*prefix
;
1308 ok(S(U(*aa
)).Length
== sizeof(IP_ADAPTER_ADDRESSES_LH
) ||
1309 S(U(*aa
)).Length
== sizeof(IP_ADAPTER_ADDRESSES_XP
),
1310 "Unknown structure size of %u bytes\n", S(U(*aa
)).Length
);
1311 ok(aa
->DnsSuffix
!= NULL
, "DnsSuffix is not a valid pointer\n");
1312 ok(aa
->Description
!= NULL
, "Description is not a valid pointer\n");
1313 ok(aa
->FriendlyName
!= NULL
, "FriendlyName is not a valid pointer\n");
1315 for (i
= 0; i
< aa
->PhysicalAddressLength
; i
++)
1316 sprintf(temp
+ i
* 3, "%02X-", aa
->PhysicalAddress
[i
]);
1317 temp
[i
? i
* 3 - 1 : 0] = '\0';
1318 trace("idx %u name %s %s dns %s descr %s phys %s mtu %u flags %08x type %u\n",
1319 S(U(*aa
)).IfIndex
, aa
->AdapterName
,
1320 wine_dbgstr_w(aa
->FriendlyName
), wine_dbgstr_w(aa
->DnsSuffix
),
1321 wine_dbgstr_w(aa
->Description
), temp
, aa
->Mtu
, aa
->Flags
, aa
->IfType
);
1322 ua
= aa
->FirstUnicastAddress
;
1325 ok(S(U(*ua
)).Length
== sizeof(IP_ADAPTER_UNICAST_ADDRESS_LH
) ||
1326 S(U(*ua
)).Length
== sizeof(IP_ADAPTER_UNICAST_ADDRESS_XP
),
1327 "Unknown structure size of %u bytes\n", S(U(*ua
)).Length
);
1328 ok(ua
->PrefixOrigin
!= IpPrefixOriginOther
,
1329 "bad address config value %d\n", ua
->PrefixOrigin
);
1330 ok(ua
->SuffixOrigin
!= IpSuffixOriginOther
,
1331 "bad address config value %d\n", ua
->PrefixOrigin
);
1332 /* Address configured manually or from DHCP server? */
1333 if (ua
->PrefixOrigin
== IpPrefixOriginManual
||
1334 ua
->PrefixOrigin
== IpPrefixOriginDhcp
)
1336 ok(ua
->ValidLifetime
, "expected non-zero value\n");
1337 ok(ua
->PreferredLifetime
, "expected non-zero value\n");
1338 ok(ua
->LeaseLifetime
, "expected non-zero\n");
1340 /* Is the address ok in the network (not duplicated)? */
1341 ok(ua
->DadState
!= IpDadStateInvalid
&& ua
->DadState
!= IpDadStateDuplicate
,
1342 "bad address duplication value %d\n", ua
->DadState
);
1343 trace(" flags %08x origin %u/%u state %u lifetime %u/%u/%u prefix %u\n",
1344 S(U(*ua
)).Flags
, ua
->PrefixOrigin
, ua
->SuffixOrigin
, ua
->DadState
,
1345 ua
->ValidLifetime
, ua
->PreferredLifetime
, ua
->LeaseLifetime
,
1346 S(U(*ua
)).Length
< sizeof(IP_ADAPTER_UNICAST_ADDRESS_LH
) ? 0 : ua
->OnLinkPrefixLength
);
1349 for (i
= 0, temp
[0] = '\0'; i
< ARRAY_SIZE(aa
->ZoneIndices
); i
++)
1350 sprintf(temp
+ strlen(temp
), "%d ", aa
->ZoneIndices
[i
]);
1351 trace("status %u index %u zone %s\n", aa
->OperStatus
, aa
->Ipv6IfIndex
, temp
);
1352 prefix
= aa
->FirstPrefix
;
1355 trace( " prefix %u/%u flags %08x\n", prefix
->Address
.iSockaddrLength
,
1356 prefix
->PrefixLength
, S(U(*prefix
)).Flags
);
1357 prefix
= prefix
->Next
;
1360 if (S(U(*aa
)).Length
< sizeof(IP_ADAPTER_ADDRESSES_LH
)) continue;
1361 trace("speed %s/%s metrics %u/%u guid %s type %u/%u\n",
1362 wine_dbgstr_longlong(aa
->TransmitLinkSpeed
),
1363 wine_dbgstr_longlong(aa
->ReceiveLinkSpeed
),
1364 aa
->Ipv4Metric
, aa
->Ipv6Metric
, wine_dbgstr_guid((GUID
*) &aa
->NetworkGuid
),
1365 aa
->ConnectionType
, aa
->TunnelType
);
1367 if (pConvertInterfaceLuidToGuid
)
1369 status
= pConvertInterfaceLuidToGuid(&aa
->Luid
, &guid
);
1370 ok(!status
, "got %u\n", status
);
1371 sprintf(buf
, "{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
1372 guid
.Data1
, guid
.Data2
, guid
.Data3
, guid
.Data4
[0], guid
.Data4
[1],
1373 guid
.Data4
[2], guid
.Data4
[3], guid
.Data4
[4], guid
.Data4
[5],
1374 guid
.Data4
[6], guid
.Data4
[7]);
1375 ok(!strcasecmp(aa
->AdapterName
, buf
), "expected '%s' got '%s'\n", aa
->AdapterName
, buf
);
1378 HeapFree(GetProcessHeap(), 0, ptr
);
1381 static void test_GetExtendedTcpTable(void)
1384 MIB_TCPTABLE
*table
;
1385 MIB_TCPTABLE_OWNER_PID
*table_pid
;
1386 MIB_TCPTABLE_OWNER_MODULE
*table_module
;
1388 if (!pGetExtendedTcpTable
)
1390 win_skip("GetExtendedTcpTable not available\n");
1393 ret
= pGetExtendedTcpTable( NULL
, NULL
, TRUE
, AF_INET
, TCP_TABLE_BASIC_ALL
, 0 );
1394 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
1397 ret
= pGetExtendedTcpTable( NULL
, &size
, TRUE
, AF_INET
, TCP_TABLE_BASIC_ALL
, 0 );
1398 ok( ret
== ERROR_INSUFFICIENT_BUFFER
, "got %u\n", ret
);
1400 table
= HeapAlloc( GetProcessHeap(), 0, size
);
1401 ret
= pGetExtendedTcpTable( table
, &size
, TRUE
, AF_INET
, TCP_TABLE_BASIC_ALL
, 0 );
1402 ok( ret
== ERROR_SUCCESS
, "got %u\n", ret
);
1403 HeapFree( GetProcessHeap(), 0, table
);
1406 ret
= pGetExtendedTcpTable( NULL
, &size
, TRUE
, AF_INET
, TCP_TABLE_BASIC_LISTENER
, 0 );
1407 ok( ret
== ERROR_INSUFFICIENT_BUFFER
, "got %u\n", ret
);
1409 table
= HeapAlloc( GetProcessHeap(), 0, size
);
1410 ret
= pGetExtendedTcpTable( table
, &size
, TRUE
, AF_INET
, TCP_TABLE_BASIC_LISTENER
, 0 );
1411 ok( ret
== ERROR_SUCCESS
, "got %u\n", ret
);
1412 HeapFree( GetProcessHeap(), 0, table
);
1415 ret
= pGetExtendedTcpTable( NULL
, &size
, TRUE
, AF_INET
, TCP_TABLE_OWNER_PID_ALL
, 0 );
1416 ok( ret
== ERROR_INSUFFICIENT_BUFFER
, "got %u\n", ret
);
1418 table_pid
= HeapAlloc( GetProcessHeap(), 0, size
);
1419 ret
= pGetExtendedTcpTable( table_pid
, &size
, TRUE
, AF_INET
, TCP_TABLE_OWNER_PID_ALL
, 0 );
1420 ok( ret
== ERROR_SUCCESS
, "got %u\n", ret
);
1421 HeapFree( GetProcessHeap(), 0, table_pid
);
1424 ret
= pGetExtendedTcpTable( NULL
, &size
, TRUE
, AF_INET
, TCP_TABLE_OWNER_PID_LISTENER
, 0 );
1425 ok( ret
== ERROR_INSUFFICIENT_BUFFER
, "got %u\n", ret
);
1427 table_pid
= HeapAlloc( GetProcessHeap(), 0, size
);
1428 ret
= pGetExtendedTcpTable( table_pid
, &size
, TRUE
, AF_INET
, TCP_TABLE_OWNER_PID_LISTENER
, 0 );
1429 ok( ret
== ERROR_SUCCESS
, "got %u\n", ret
);
1430 HeapFree( GetProcessHeap(), 0, table_pid
);
1433 ret
= pGetExtendedTcpTable( NULL
, &size
, TRUE
, AF_INET
, TCP_TABLE_OWNER_MODULE_ALL
, 0 );
1434 ok( ret
== ERROR_INSUFFICIENT_BUFFER
, "got %u\n", ret
);
1436 table_module
= HeapAlloc( GetProcessHeap(), 0, size
);
1437 ret
= pGetExtendedTcpTable( table_module
, &size
, TRUE
, AF_INET
, TCP_TABLE_OWNER_MODULE_ALL
, 0 );
1438 ok( ret
== ERROR_SUCCESS
, "got %u\n", ret
);
1439 HeapFree( GetProcessHeap(), 0, table_module
);
1442 ret
= pGetExtendedTcpTable( NULL
, &size
, TRUE
, AF_INET
, TCP_TABLE_OWNER_MODULE_LISTENER
, 0 );
1443 ok( ret
== ERROR_INSUFFICIENT_BUFFER
, "got %u\n", ret
);
1445 table_module
= HeapAlloc( GetProcessHeap(), 0, size
);
1446 ret
= pGetExtendedTcpTable( table_module
, &size
, TRUE
, AF_INET
, TCP_TABLE_OWNER_MODULE_LISTENER
, 0 );
1447 ok( ret
== ERROR_SUCCESS
, "got %u\n", ret
);
1448 HeapFree( GetProcessHeap(), 0, table_module
);
1451 static void test_AllocateAndGetTcpExTableFromStack(void)
1454 MIB_TCPTABLE_OWNER_PID
*table_ex
= NULL
;
1456 if (!pAllocateAndGetTcpExTableFromStack
)
1458 skip("AllocateAndGetTcpExTableFromStack not available\n");
1464 /* crashes on native */
1465 ret
= pAllocateAndGetTcpExTableFromStack( NULL
, FALSE
, INVALID_HANDLE_VALUE
, 0, 0 );
1466 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
1467 ret
= pAllocateAndGetTcpExTableFromStack( (void **)&table_ex
, FALSE
, INVALID_HANDLE_VALUE
, 0, AF_INET
);
1468 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
1469 ret
= pAllocateAndGetTcpExTableFromStack( NULL
, FALSE
, GetProcessHeap(), 0, AF_INET
);
1470 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
1473 ret
= pAllocateAndGetTcpExTableFromStack( (void **)&table_ex
, FALSE
, GetProcessHeap(), 0, 0 );
1474 ok( ret
== ERROR_INVALID_PARAMETER
|| broken(ret
== ERROR_NOT_SUPPORTED
) /* win2k */, "got %u\n", ret
);
1476 ret
= pAllocateAndGetTcpExTableFromStack( (void **)&table_ex
, FALSE
, GetProcessHeap(), 0, AF_INET
);
1477 ok( ret
== ERROR_SUCCESS
, "got %u\n", ret
);
1479 if (ret
== NO_ERROR
&& winetest_debug
> 1)
1482 trace( "AllocateAndGetTcpExTableFromStack table: %u entries\n", table_ex
->dwNumEntries
);
1483 for (i
= 0; i
< table_ex
->dwNumEntries
; i
++)
1487 strcpy(remote_ip
, ntoa(table_ex
->table
[i
].dwRemoteAddr
));
1488 trace( "%u: local %s:%u remote %s:%u state %u pid %u\n", i
,
1489 ntoa(table_ex
->table
[i
].dwLocalAddr
), ntohs(table_ex
->table
[i
].dwLocalPort
),
1490 remote_ip
, ntohs(table_ex
->table
[i
].dwRemotePort
),
1491 U(table_ex
->table
[i
]).dwState
, table_ex
->table
[i
].dwOwningPid
);
1494 HeapFree(GetProcessHeap(), 0, table_ex
);
1496 ret
= pAllocateAndGetTcpExTableFromStack( (void **)&table_ex
, FALSE
, GetProcessHeap(), 0, AF_INET6
);
1497 ok( ret
== ERROR_NOT_SUPPORTED
, "got %u\n", ret
);
1500 static void test_GetExtendedUdpTable(void)
1503 MIB_UDPTABLE
*table
;
1504 MIB_UDPTABLE_OWNER_PID
*table_pid
;
1505 MIB_UDPTABLE_OWNER_MODULE
*table_module
;
1507 if (!pGetExtendedUdpTable
)
1509 win_skip("GetExtendedUdpTable not available\n");
1512 ret
= pGetExtendedUdpTable( NULL
, NULL
, TRUE
, AF_INET
, UDP_TABLE_BASIC
, 0 );
1513 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
1516 ret
= pGetExtendedUdpTable( NULL
, &size
, TRUE
, AF_INET
, UDP_TABLE_BASIC
, 0 );
1517 ok( ret
== ERROR_INSUFFICIENT_BUFFER
, "got %u\n", ret
);
1519 table
= HeapAlloc( GetProcessHeap(), 0, size
);
1520 ret
= pGetExtendedUdpTable( table
, &size
, TRUE
, AF_INET
, UDP_TABLE_BASIC
, 0 );
1521 ok( ret
== ERROR_SUCCESS
, "got %u\n", ret
);
1522 HeapFree( GetProcessHeap(), 0, table
);
1525 ret
= pGetExtendedUdpTable( NULL
, &size
, TRUE
, AF_INET
, UDP_TABLE_OWNER_PID
, 0 );
1526 ok( ret
== ERROR_INSUFFICIENT_BUFFER
, "got %u\n", ret
);
1528 table_pid
= HeapAlloc( GetProcessHeap(), 0, size
);
1529 ret
= pGetExtendedUdpTable( table_pid
, &size
, TRUE
, AF_INET
, UDP_TABLE_OWNER_PID
, 0 );
1530 ok( ret
== ERROR_SUCCESS
, "got %u\n", ret
);
1531 HeapFree( GetProcessHeap(), 0, table_pid
);
1534 ret
= pGetExtendedUdpTable( NULL
, &size
, TRUE
, AF_INET
, UDP_TABLE_OWNER_MODULE
, 0 );
1535 ok( ret
== ERROR_INSUFFICIENT_BUFFER
, "got %u\n", ret
);
1537 table_module
= HeapAlloc( GetProcessHeap(), 0, size
);
1538 ret
= pGetExtendedUdpTable( table_module
, &size
, TRUE
, AF_INET
, UDP_TABLE_OWNER_MODULE
, 0 );
1539 ok( ret
== ERROR_SUCCESS
, "got %u\n", ret
);
1540 HeapFree( GetProcessHeap(), 0, table_module
);
1543 static void test_CreateSortedAddressPairs(void)
1545 SOCKADDR_IN6 dst
[2];
1546 SOCKADDR_IN6_PAIR
*pair
;
1550 if (!pCreateSortedAddressPairs
)
1552 win_skip( "CreateSortedAddressPairs not available\n" );
1556 memset( dst
, 0, sizeof(dst
) );
1557 dst
[0].sin6_family
= AF_INET6
;
1558 dst
[0].sin6_addr
.u
.Word
[5] = 0xffff;
1559 dst
[0].sin6_addr
.u
.Word
[6] = 0x0808;
1560 dst
[0].sin6_addr
.u
.Word
[7] = 0x0808;
1562 pair_count
= 0xdeadbeef;
1563 ret
= pCreateSortedAddressPairs( NULL
, 0, dst
, 1, 0, NULL
, &pair_count
);
1564 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
1565 ok( pair_count
== 0xdeadbeef, "got %u\n", pair_count
);
1567 pair
= (SOCKADDR_IN6_PAIR
*)0xdeadbeef;
1568 pair_count
= 0xdeadbeef;
1569 ret
= pCreateSortedAddressPairs( NULL
, 0, NULL
, 1, 0, &pair
, &pair_count
);
1570 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
1571 ok( pair
== (SOCKADDR_IN6_PAIR
*)0xdeadbeef, "got %p\n", pair
);
1572 ok( pair_count
== 0xdeadbeef, "got %u\n", pair_count
);
1575 pair_count
= 0xdeadbeef;
1576 ret
= pCreateSortedAddressPairs( NULL
, 0, dst
, 1, 0, &pair
, &pair_count
);
1577 ok( ret
== NO_ERROR
, "got %u\n", ret
);
1578 ok( pair
!= NULL
, "pair not set\n" );
1579 ok( pair_count
>= 1, "got %u\n", pair_count
);
1580 ok( pair
[0].SourceAddress
!= NULL
, "src address not set\n" );
1581 ok( pair
[0].DestinationAddress
!= NULL
, "dst address not set\n" );
1582 pFreeMibTable( pair
);
1584 dst
[1].sin6_family
= AF_INET6
;
1585 dst
[1].sin6_addr
.u
.Word
[5] = 0xffff;
1586 dst
[1].sin6_addr
.u
.Word
[6] = 0x0404;
1587 dst
[1].sin6_addr
.u
.Word
[7] = 0x0808;
1590 pair_count
= 0xdeadbeef;
1591 ret
= pCreateSortedAddressPairs( NULL
, 0, dst
, 2, 0, &pair
, &pair_count
);
1592 ok( ret
== NO_ERROR
, "got %u\n", ret
);
1593 ok( pair
!= NULL
, "pair not set\n" );
1594 ok( pair_count
>= 2, "got %u\n", pair_count
);
1595 ok( pair
[0].SourceAddress
!= NULL
, "src address not set\n" );
1596 ok( pair
[0].DestinationAddress
!= NULL
, "dst address not set\n" );
1597 ok( pair
[1].SourceAddress
!= NULL
, "src address not set\n" );
1598 ok( pair
[1].DestinationAddress
!= NULL
, "dst address not set\n" );
1599 pFreeMibTable( pair
);
1602 static DWORD
get_interface_index(void)
1604 DWORD size
= 0, ret
= 0;
1605 IP_ADAPTER_ADDRESSES
*buf
, *aa
;
1607 if (GetAdaptersAddresses( AF_UNSPEC
, 0, NULL
, NULL
, &size
) != ERROR_BUFFER_OVERFLOW
)
1610 buf
= HeapAlloc( GetProcessHeap(), 0, size
);
1611 GetAdaptersAddresses( AF_UNSPEC
, 0, NULL
, buf
, &size
);
1612 for (aa
= buf
; aa
; aa
= aa
->Next
)
1614 if (aa
->IfType
== IF_TYPE_ETHERNET_CSMACD
)
1620 HeapFree( GetProcessHeap(), 0, buf
);
1624 static void test_interface_identifier_conversion(void)
1630 WCHAR nameW
[IF_MAX_STRING_SIZE
+ 1];
1631 char nameA
[IF_MAX_STRING_SIZE
+ 1], *name
;
1632 NET_IFINDEX index
, index2
;
1634 if (!pConvertInterfaceIndexToLuid
)
1636 win_skip( "ConvertInterfaceIndexToLuid not available\n" );
1639 if (!(index
= get_interface_index()))
1641 skip( "no suitable interface found\n" );
1645 /* ConvertInterfaceIndexToLuid */
1646 ret
= pConvertInterfaceIndexToLuid( 0, NULL
);
1647 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
1649 memset( &luid
, 0xff, sizeof(luid
) );
1650 ret
= pConvertInterfaceIndexToLuid( 0, &luid
);
1651 ok( ret
== ERROR_FILE_NOT_FOUND
, "got %u\n", ret
);
1652 ok( !luid
.Info
.Reserved
, "got %x\n", luid
.Info
.Reserved
);
1653 ok( !luid
.Info
.NetLuidIndex
, "got %u\n", luid
.Info
.NetLuidIndex
);
1654 ok( !luid
.Info
.IfType
, "got %u\n", luid
.Info
.IfType
);
1656 luid
.Info
.Reserved
= luid
.Info
.NetLuidIndex
= luid
.Info
.IfType
= 0xdead;
1657 ret
= pConvertInterfaceIndexToLuid( index
, &luid
);
1658 ok( !ret
, "got %u\n", ret
);
1659 ok( !luid
.Info
.Reserved
, "got %x\n", luid
.Info
.Reserved
);
1660 ok( luid
.Info
.NetLuidIndex
!= 0xdead, "index not set\n" );
1661 ok( luid
.Info
.IfType
== IF_TYPE_ETHERNET_CSMACD
, "got %u\n", luid
.Info
.IfType
);
1663 /* ConvertInterfaceLuidToIndex */
1664 ret
= pConvertInterfaceLuidToIndex( NULL
, NULL
);
1665 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
1667 ret
= pConvertInterfaceLuidToIndex( NULL
, &index
);
1668 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
1670 ret
= pConvertInterfaceLuidToIndex( &luid
, NULL
);
1671 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
1673 ret
= pConvertInterfaceLuidToIndex( &luid
, &index
);
1674 ok( !ret
, "got %u\n", ret
);
1676 /* ConvertInterfaceLuidToGuid */
1677 ret
= pConvertInterfaceLuidToGuid( NULL
, NULL
);
1678 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
1680 memset( &guid
, 0xff, sizeof(guid
) );
1681 ret
= pConvertInterfaceLuidToGuid( NULL
, &guid
);
1682 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
1683 ok( guid
.Data1
== 0xffffffff, "got %x\n", guid
.Data1
);
1685 ret
= pConvertInterfaceLuidToGuid( &luid
, NULL
);
1686 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
1688 memset( &guid
, 0, sizeof(guid
) );
1689 ret
= pConvertInterfaceLuidToGuid( &luid
, &guid
);
1690 ok( !ret
, "got %u\n", ret
);
1691 ok( guid
.Data1
, "got %x\n", guid
.Data1
);
1693 /* ConvertInterfaceGuidToLuid */
1694 ret
= pConvertInterfaceGuidToLuid( NULL
, NULL
);
1695 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
1697 luid
.Info
.NetLuidIndex
= 1;
1698 ret
= pConvertInterfaceGuidToLuid( NULL
, &luid
);
1699 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
1700 ok( luid
.Info
.NetLuidIndex
== 1, "got %u\n", luid
.Info
.NetLuidIndex
);
1702 ret
= pConvertInterfaceGuidToLuid( &guid
, NULL
);
1703 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
1705 luid
.Info
.Reserved
= luid
.Info
.NetLuidIndex
= luid
.Info
.IfType
= 0xdead;
1706 ret
= pConvertInterfaceGuidToLuid( &guid
, &luid
);
1707 ok( !ret
, "got %u\n", ret
);
1708 ok( !luid
.Info
.Reserved
, "got %x\n", luid
.Info
.Reserved
);
1709 ok( luid
.Info
.NetLuidIndex
!= 0xdead, "index not set\n" );
1710 ok( luid
.Info
.IfType
== IF_TYPE_ETHERNET_CSMACD
, "got %u\n", luid
.Info
.IfType
);
1712 /* ConvertInterfaceLuidToNameW */
1713 ret
= pConvertInterfaceLuidToNameW( NULL
, NULL
, 0 );
1714 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
1716 ret
= pConvertInterfaceLuidToNameW( &luid
, NULL
, 0 );
1717 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
1719 ret
= pConvertInterfaceLuidToNameW( NULL
, nameW
, 0 );
1720 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
1722 ret
= pConvertInterfaceLuidToNameW( &luid
, nameW
, 0 );
1723 ok( ret
== ERROR_NOT_ENOUGH_MEMORY
, "got %u\n", ret
);
1726 len
= ARRAY_SIZE(nameW
);
1727 ret
= pConvertInterfaceLuidToNameW( &luid
, nameW
, len
);
1728 ok( !ret
, "got %u\n", ret
);
1729 ok( nameW
[0], "name not set\n" );
1731 /* ConvertInterfaceLuidToNameA */
1732 ret
= pConvertInterfaceLuidToNameA( NULL
, NULL
, 0 );
1733 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
1735 ret
= pConvertInterfaceLuidToNameA( &luid
, NULL
, 0 );
1736 ok( ret
== ERROR_NOT_ENOUGH_MEMORY
, "got %u\n", ret
);
1738 ret
= pConvertInterfaceLuidToNameA( NULL
, nameA
, 0 );
1739 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
1741 ret
= pConvertInterfaceLuidToNameA( &luid
, nameA
, 0 );
1742 ok( ret
== ERROR_NOT_ENOUGH_MEMORY
, "got %u\n", ret
);
1745 len
= ARRAY_SIZE(nameA
);
1746 ret
= pConvertInterfaceLuidToNameA( &luid
, nameA
, len
);
1747 ok( !ret
, "got %u\n", ret
);
1748 ok( nameA
[0], "name not set\n" );
1750 /* ConvertInterfaceNameToLuidW */
1751 ret
= pConvertInterfaceNameToLuidW( NULL
, NULL
);
1752 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
1754 luid
.Info
.Reserved
= luid
.Info
.NetLuidIndex
= luid
.Info
.IfType
= 0xdead;
1755 ret
= pConvertInterfaceNameToLuidW( NULL
, &luid
);
1756 ok( ret
== ERROR_INVALID_NAME
, "got %u\n", ret
);
1757 ok( !luid
.Info
.Reserved
, "got %x\n", luid
.Info
.Reserved
);
1758 ok( luid
.Info
.NetLuidIndex
!= 0xdead, "index not set\n" );
1759 ok( !luid
.Info
.IfType
, "got %u\n", luid
.Info
.IfType
);
1761 ret
= pConvertInterfaceNameToLuidW( nameW
, NULL
);
1762 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
1764 luid
.Info
.Reserved
= luid
.Info
.NetLuidIndex
= luid
.Info
.IfType
= 0xdead;
1765 ret
= pConvertInterfaceNameToLuidW( nameW
, &luid
);
1766 ok( !ret
, "got %u\n", ret
);
1767 ok( !luid
.Info
.Reserved
, "got %x\n", luid
.Info
.Reserved
);
1768 ok( luid
.Info
.NetLuidIndex
!= 0xdead, "index not set\n" );
1769 ok( luid
.Info
.IfType
== IF_TYPE_ETHERNET_CSMACD
, "got %u\n", luid
.Info
.IfType
);
1771 /* ConvertInterfaceNameToLuidA */
1772 ret
= pConvertInterfaceNameToLuidA( NULL
, NULL
);
1773 ok( ret
== ERROR_INVALID_NAME
, "got %u\n", ret
);
1775 luid
.Info
.Reserved
= luid
.Info
.NetLuidIndex
= luid
.Info
.IfType
= 0xdead;
1776 ret
= pConvertInterfaceNameToLuidA( NULL
, &luid
);
1777 ok( ret
== ERROR_INVALID_NAME
, "got %u\n", ret
);
1778 ok( luid
.Info
.Reserved
== 0xdead, "reserved set\n" );
1779 ok( luid
.Info
.NetLuidIndex
== 0xdead, "index set\n" );
1780 ok( luid
.Info
.IfType
== 0xdead, "type set\n" );
1782 ret
= pConvertInterfaceNameToLuidA( nameA
, NULL
);
1783 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
1785 luid
.Info
.Reserved
= luid
.Info
.NetLuidIndex
= luid
.Info
.IfType
= 0xdead;
1786 ret
= pConvertInterfaceNameToLuidA( nameA
, &luid
);
1787 ok( !ret
, "got %u\n", ret
);
1788 ok( !luid
.Info
.Reserved
, "got %x\n", luid
.Info
.Reserved
);
1789 ok( luid
.Info
.NetLuidIndex
!= 0xdead, "index not set\n" );
1790 ok( luid
.Info
.IfType
== IF_TYPE_ETHERNET_CSMACD
, "got %u\n", luid
.Info
.IfType
);
1792 if (!pif_nametoindex
|| !pif_indextoname
)
1794 skip("if_nametoindex/if_indextoname not supported\n");
1798 index2
= pif_nametoindex( NULL
);
1799 ok( !index2
, "Got unexpected index %u\n", index2
);
1800 index2
= pif_nametoindex( nameA
);
1801 ok( index2
== index
, "Got index %u for %s, expected %u\n", index2
, nameA
, index
);
1802 /* Wargaming.net Game Center passes a GUID-like string. */
1803 index2
= pif_nametoindex( "{00000001-0000-0000-0000-000000000000}" );
1804 ok( !index2
, "Got unexpected index %u\n", index2
);
1805 index2
= pif_nametoindex( wine_dbgstr_guid( &guid
) );
1806 ok( !index2
, "Got unexpected index %u for input %s\n", index2
, wine_dbgstr_guid( &guid
) );
1808 name
= pif_indextoname( 0, NULL
);
1809 ok( name
== NULL
, "got %s\n", name
);
1811 name
= pif_indextoname( 0, nameA
);
1812 ok( name
== NULL
, "got %p\n", name
);
1814 name
= pif_indextoname( ~0u, nameA
);
1815 ok( name
== NULL
, "got %p\n", name
);
1818 name
= pif_indextoname( 1, nameA
);
1821 ok( name
[0], "empty name\n" );
1822 ok( name
== nameA
, "got %p\n", name
);
1826 static void test_GetIfEntry2(void)
1834 win_skip( "GetIfEntry2 not available\n" );
1837 if (!(index
= get_interface_index()))
1839 skip( "no suitable interface found\n" );
1843 ret
= pGetIfEntry2( NULL
);
1844 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
1846 memset( &row
, 0, sizeof(row
) );
1847 ret
= pGetIfEntry2( &row
);
1848 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
1850 memset( &row
, 0, sizeof(row
) );
1851 row
.InterfaceIndex
= index
;
1852 ret
= pGetIfEntry2( &row
);
1853 ok( ret
== NO_ERROR
, "got %u\n", ret
);
1854 ok( row
.InterfaceIndex
== index
, "got %u\n", index
);
1857 static void test_GetIfTable2(void)
1860 MIB_IF_TABLE2
*table
;
1864 win_skip( "GetIfTable2 not available\n" );
1869 ret
= pGetIfTable2( &table
);
1870 ok( ret
== NO_ERROR
, "got %u\n", ret
);
1871 ok( table
!= NULL
, "table not set\n" );
1872 pFreeMibTable( table
);
1875 static void test_GetIfTable2Ex(void)
1878 MIB_IF_TABLE2
*table
;
1880 if (!pGetIfTable2Ex
)
1882 win_skip( "GetIfTable2Ex not available\n" );
1887 ret
= pGetIfTable2Ex( MibIfTableNormal
, &table
);
1888 ok( ret
== NO_ERROR
, "got %u\n", ret
);
1889 ok( table
!= NULL
, "table not set\n" );
1890 pFreeMibTable( table
);
1893 ret
= pGetIfTable2Ex( MibIfTableRaw
, &table
);
1894 ok( ret
== NO_ERROR
, "got %u\n", ret
);
1895 ok( table
!= NULL
, "table not set\n" );
1896 pFreeMibTable( table
);
1899 ret
= pGetIfTable2Ex( MibIfTableNormalWithoutStatistics
, &table
);
1900 ok( ret
== NO_ERROR
|| broken(ret
== ERROR_INVALID_PARAMETER
), "got %u\n", ret
);
1901 ok( table
!= NULL
|| broken(!table
), "table not set\n" );
1902 pFreeMibTable( table
);
1905 ret
= pGetIfTable2Ex( 3, &table
);
1906 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
1907 ok( !table
, "table should not be set\n" );
1908 pFreeMibTable( table
);
1911 static void test_GetUnicastIpAddressEntry(void)
1913 IP_ADAPTER_ADDRESSES
*aa
, *ptr
;
1914 MIB_UNICASTIPADDRESS_ROW row
;
1917 if (!pGetUnicastIpAddressEntry
)
1919 win_skip( "GetUnicastIpAddressEntry not available\n" );
1923 ret
= pGetUnicastIpAddressEntry( NULL
);
1924 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
1926 memset( &row
, 0, sizeof(row
) );
1927 ret
= pGetUnicastIpAddressEntry( &row
);
1928 todo_wine
ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
1930 memset( &row
, 0, sizeof(row
) );
1931 row
.Address
.Ipv4
.sin_family
= AF_INET
;
1932 row
.Address
.Ipv4
.sin_port
= 0;
1933 row
.Address
.Ipv4
.sin_addr
.S_un
.S_addr
= 0x01020304;
1934 ret
= pGetUnicastIpAddressEntry( &row
);
1935 ok( ret
== ERROR_FILE_NOT_FOUND
, "got %u\n", ret
);
1937 memset( &row
, 0, sizeof(row
) );
1938 row
.InterfaceIndex
= 123;
1939 ret
= pGetUnicastIpAddressEntry( &row
);
1940 todo_wine
ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
1942 memset( &row
, 0, sizeof(row
) );
1943 row
.InterfaceIndex
= get_interface_index();
1944 row
.Address
.Ipv4
.sin_family
= AF_INET
;
1945 row
.Address
.Ipv4
.sin_port
= 0;
1946 row
.Address
.Ipv4
.sin_addr
.S_un
.S_addr
= 0x01020304;
1947 ret
= pGetUnicastIpAddressEntry( &row
);
1948 ok( ret
== ERROR_NOT_FOUND
, "got %u\n", ret
);
1950 memset( &row
, 0, sizeof(row
) );
1951 row
.InterfaceIndex
= 123;
1952 row
.Address
.Ipv4
.sin_family
= AF_INET
;
1953 row
.Address
.Ipv4
.sin_port
= 0;
1954 row
.Address
.Ipv4
.sin_addr
.S_un
.S_addr
= 0x01020304;
1955 ret
= pGetUnicastIpAddressEntry( &row
);
1956 ok( ret
== ERROR_FILE_NOT_FOUND
, "got %u\n", ret
);
1958 ret
= GetAdaptersAddresses(AF_UNSPEC
, GAA_FLAG_INCLUDE_ALL_INTERFACES
, NULL
, NULL
, &size
);
1959 ok(ret
== ERROR_BUFFER_OVERFLOW
, "expected ERROR_BUFFER_OVERFLOW, got %u\n", ret
);
1960 if (ret
!= ERROR_BUFFER_OVERFLOW
) return;
1962 ptr
= HeapAlloc(GetProcessHeap(), 0, size
);
1963 ret
= GetAdaptersAddresses(AF_UNSPEC
, GAA_FLAG_INCLUDE_ALL_INTERFACES
, NULL
, ptr
, &size
);
1964 ok(!ret
, "expected ERROR_SUCCESS got %u\n", ret
);
1966 for (aa
= ptr
; !ret
&& aa
; aa
= aa
->Next
)
1968 IP_ADAPTER_UNICAST_ADDRESS
*ua
;
1970 ua
= aa
->FirstUnicastAddress
;
1973 /* test with luid */
1974 memset( &row
, 0, sizeof(row
) );
1975 memcpy(&row
.InterfaceLuid
, &aa
->Luid
, sizeof(aa
->Luid
));
1976 memcpy(&row
.Address
, ua
->Address
.lpSockaddr
, ua
->Address
.iSockaddrLength
);
1977 ret
= pGetUnicastIpAddressEntry( &row
);
1978 ok( ret
== NO_ERROR
, "got %u\n", ret
);
1980 /* test with index */
1981 memset( &row
, 0, sizeof(row
) );
1982 row
.InterfaceIndex
= S(U(*aa
)).IfIndex
;
1983 memcpy(&row
.Address
, ua
->Address
.lpSockaddr
, ua
->Address
.iSockaddrLength
);
1984 ret
= pGetUnicastIpAddressEntry( &row
);
1985 ok( ret
== NO_ERROR
, "got %u\n", ret
);
1986 if (ret
== NO_ERROR
)
1988 ok(row
.InterfaceLuid
.Info
.Reserved
== aa
->Luid
.Info
.Reserved
, "Expected %d, got %d\n",
1989 aa
->Luid
.Info
.Reserved
, row
.InterfaceLuid
.Info
.Reserved
);
1990 ok(row
.InterfaceLuid
.Info
.NetLuidIndex
== aa
->Luid
.Info
.NetLuidIndex
, "Expected %d, got %d\n",
1991 aa
->Luid
.Info
.NetLuidIndex
, row
.InterfaceLuid
.Info
.NetLuidIndex
);
1992 ok(row
.InterfaceLuid
.Info
.IfType
== aa
->Luid
.Info
.IfType
, "Expected %d, got %d\n",
1993 aa
->Luid
.Info
.IfType
, row
.InterfaceLuid
.Info
.IfType
);
1994 ok(row
.InterfaceIndex
== S(U(*aa
)).IfIndex
, "Expected %d, got %d\n",
1995 S(U(*aa
)).IfIndex
, row
.InterfaceIndex
);
1996 ok(row
.PrefixOrigin
== ua
->PrefixOrigin
, "Expected %d, got %d\n",
1997 ua
->PrefixOrigin
, row
.PrefixOrigin
);
1998 ok(row
.SuffixOrigin
== ua
->SuffixOrigin
, "Expected %d, got %d\n",
1999 ua
->SuffixOrigin
, row
.SuffixOrigin
);
2000 ok(row
.ValidLifetime
== ua
->ValidLifetime
, "Expected %d, got %d\n",
2001 ua
->ValidLifetime
, row
.ValidLifetime
);
2002 ok(row
.PreferredLifetime
== ua
->PreferredLifetime
, "Expected %d, got %d\n",
2003 ua
->PreferredLifetime
, row
.PreferredLifetime
);
2004 ok(row
.OnLinkPrefixLength
== ua
->OnLinkPrefixLength
, "Expected %d, got %d\n",
2005 ua
->OnLinkPrefixLength
, row
.OnLinkPrefixLength
);
2006 ok(row
.SkipAsSource
== 0, "Expected 0, got %d\n", row
.SkipAsSource
);
2007 ok(row
.DadState
== ua
->DadState
, "Expected %d, got %d\n", ua
->DadState
, row
.DadState
);
2008 if (row
.Address
.si_family
== AF_INET6
)
2009 ok(row
.ScopeId
.Value
== row
.Address
.Ipv6
.sin6_scope_id
, "Expected %d, got %d\n",
2010 row
.Address
.Ipv6
.sin6_scope_id
, row
.ScopeId
.Value
);
2011 ok(row
.CreationTimeStamp
.QuadPart
, "CreationTimeStamp is 0\n");
2016 HeapFree(GetProcessHeap(), 0, ptr
);
2019 static void test_GetUnicastIpAddressTable(void)
2021 MIB_UNICASTIPADDRESS_TABLE
*table
;
2025 if (!pGetUnicastIpAddressTable
)
2027 win_skip( "GetUnicastIpAddressTable not available\n" );
2031 ret
= pGetUnicastIpAddressTable(AF_UNSPEC
, NULL
);
2032 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
2034 ret
= pGetUnicastIpAddressTable(AF_BAN
, &table
);
2035 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
2037 ret
= pGetUnicastIpAddressTable(AF_INET
, &table
);
2038 ok( ret
== NO_ERROR
, "got %u\n", ret
);
2039 trace("GetUnicastIpAddressTable(AF_INET): NumEntries %u\n", table
->NumEntries
);
2040 pFreeMibTable(table
);
2042 ret
= pGetUnicastIpAddressTable(AF_INET6
, &table
);
2043 ok( ret
== NO_ERROR
, "got %u\n", ret
);
2044 trace("GetUnicastIpAddressTable(AF_INET6): NumEntries %u\n", table
->NumEntries
);
2045 pFreeMibTable(table
);
2047 ret
= pGetUnicastIpAddressTable(AF_UNSPEC
, &table
);
2048 ok( ret
== NO_ERROR
, "got %u\n", ret
);
2049 trace("GetUnicastIpAddressTable(AF_UNSPEC): NumEntries %u\n", table
->NumEntries
);
2050 for (i
= 0; i
< table
->NumEntries
&& winetest_debug
> 1; i
++)
2052 trace("Index %u:\n", i
);
2053 trace("Address.si_family: %u\n", table
->Table
[i
].Address
.si_family
);
2054 trace("InterfaceLuid.Info.Reserved: %u\n", table
->Table
[i
].InterfaceLuid
.Info
.Reserved
);
2055 trace("InterfaceLuid.Info.NetLuidIndex: %u\n", table
->Table
[i
].InterfaceLuid
.Info
.NetLuidIndex
);
2056 trace("InterfaceLuid.Info.IfType: %u\n", table
->Table
[i
].InterfaceLuid
.Info
.IfType
);
2057 trace("InterfaceIndex: %u\n", table
->Table
[i
].InterfaceIndex
);
2058 trace("PrefixOrigin: %u\n", table
->Table
[i
].PrefixOrigin
);
2059 trace("SuffixOrigin: %u\n", table
->Table
[i
].SuffixOrigin
);
2060 trace("ValidLifetime: %u seconds\n", table
->Table
[i
].ValidLifetime
);
2061 trace("PreferredLifetime: %u seconds\n", table
->Table
[i
].PreferredLifetime
);
2062 trace("OnLinkPrefixLength: %u\n", table
->Table
[i
].OnLinkPrefixLength
);
2063 trace("SkipAsSource: %u\n", table
->Table
[i
].SkipAsSource
);
2064 trace("DadState: %u\n", table
->Table
[i
].DadState
);
2065 trace("ScopeId.Value: %u\n", table
->Table
[i
].ScopeId
.Value
);
2066 trace("CreationTimeStamp: %08x%08x\n", table
->Table
[i
].CreationTimeStamp
.HighPart
, table
->Table
[i
].CreationTimeStamp
.LowPart
);
2069 pFreeMibTable(table
);
2072 static void test_ConvertLengthToIpv4Mask(void)
2079 if (!pConvertLengthToIpv4Mask
)
2081 win_skip( "ConvertLengthToIpv4Mask not available\n" );
2085 for (n
= 0; n
<= 32; n
++)
2089 expected
= htonl( ~0u << (32 - n
) );
2093 ret
= pConvertLengthToIpv4Mask( n
, &mask
);
2094 ok( ret
== NO_ERROR
, "ConvertLengthToIpv4Mask returned 0x%08x, expected 0x%08x\n", ret
, NO_ERROR
);
2095 ok( mask
== expected
, "ConvertLengthToIpv4Mask mask value 0x%08x, expected 0x%08x\n", mask
, expected
);
2098 /* Testing for out of range. In this case both mask and return are changed to indicate error. */
2100 ret
= pConvertLengthToIpv4Mask( 33, &mask
);
2101 ok( ret
== ERROR_INVALID_PARAMETER
, "ConvertLengthToIpv4Mask returned 0x%08x, expected 0x%08x\n", ret
, ERROR_INVALID_PARAMETER
);
2102 ok( mask
== INADDR_NONE
, "ConvertLengthToIpv4Mask mask value 0x%08x, expected 0x%08x\n", mask
, INADDR_NONE
);
2105 static void test_GetTcp6Table(void)
2113 win_skip("GetTcp6Table not available\n");
2117 ret
= pGetTcp6Table(NULL
, &size
, FALSE
);
2118 if (ret
== ERROR_NOT_SUPPORTED
)
2120 skip("GetTcp6Table is not supported\n");
2123 ok(ret
== ERROR_INSUFFICIENT_BUFFER
,
2124 "GetTcp6Table(NULL, &size, FALSE) returned %d, expected ERROR_INSUFFICIENT_BUFFER\n", ret
);
2125 if (ret
!= ERROR_INSUFFICIENT_BUFFER
) return;
2127 buf
= HeapAlloc(GetProcessHeap(), 0, size
);
2129 ret
= pGetTcp6Table(buf
, &size
, FALSE
);
2131 "GetTcp6Table(buf, &size, FALSE) returned %d, expected NO_ERROR\n", ret
);
2133 if (ret
== NO_ERROR
&& winetest_debug
> 1)
2136 trace("TCP6 table: %u entries\n", buf
->dwNumEntries
);
2137 for (i
= 0; i
< buf
->dwNumEntries
; i
++)
2139 trace("%u: local %s%%%u:%u remote %s%%%u:%u state %u\n", i
,
2140 ntoa6(&buf
->table
[i
].LocalAddr
), ntohs(buf
->table
[i
].dwLocalScopeId
),
2141 ntohs(buf
->table
[i
].dwLocalPort
), ntoa6(&buf
->table
[i
].RemoteAddr
),
2142 ntohs(buf
->table
[i
].dwRemoteScopeId
), ntohs(buf
->table
[i
].dwRemotePort
),
2143 buf
->table
[i
].State
);
2147 HeapFree(GetProcessHeap(), 0, buf
);
2150 static void test_GetUdp6Table(void)
2155 if (!pGetUdp6Table
) {
2156 win_skip("GetUdp6Table not available\n");
2160 apiReturn
= pGetUdp6Table(NULL
, &dwSize
, FALSE
);
2161 if (apiReturn
== ERROR_NOT_SUPPORTED
) {
2162 skip("GetUdp6Table is not supported\n");
2165 ok(apiReturn
== ERROR_INSUFFICIENT_BUFFER
,
2166 "GetUdp6Table(NULL, &dwSize, FALSE) returned %d, expected ERROR_INSUFFICIENT_BUFFER\n",
2168 if (apiReturn
== ERROR_INSUFFICIENT_BUFFER
) {
2169 PMIB_UDP6TABLE buf
= HeapAlloc(GetProcessHeap(), 0, dwSize
);
2171 apiReturn
= pGetUdp6Table(buf
, &dwSize
, FALSE
);
2172 ok(apiReturn
== NO_ERROR
,
2173 "GetUdp6Table(buf, &dwSize, FALSE) returned %d, expected NO_ERROR\n",
2176 if (apiReturn
== NO_ERROR
&& winetest_debug
> 1)
2179 trace( "UDP6 table: %u entries\n", buf
->dwNumEntries
);
2180 for (i
= 0; i
< buf
->dwNumEntries
; i
++)
2181 trace( "%u: %s%%%u:%u\n",
2182 i
, ntoa6(&buf
->table
[i
].dwLocalAddr
), ntohs(buf
->table
[i
].dwLocalScopeId
), ntohs(buf
->table
[i
].dwLocalPort
) );
2184 HeapFree(GetProcessHeap(), 0, buf
);
2188 static void test_ParseNetworkString(void)
2196 ipv4_address_tests
[] =
2198 {"1.2.3.4", {{{1, 2, 3, 4}}}},
2199 {"1.2.3.4a", {}, ERROR_INVALID_PARAMETER
},
2200 {"1.2.3.0x4a", {}, ERROR_INVALID_PARAMETER
},
2201 {"1.2.3", {}, ERROR_INVALID_PARAMETER
},
2202 {"a1.2.3.4", {}, ERROR_INVALID_PARAMETER
},
2203 {"0xdeadbeef", {}, ERROR_INVALID_PARAMETER
},
2204 {"1.2.3.4:22", {}, ERROR_INVALID_PARAMETER
},
2205 {"::1", {}, ERROR_INVALID_PARAMETER
},
2206 {"winehq.org", {}, ERROR_INVALID_PARAMETER
},
2215 ipv4_service_tests
[] =
2217 {"1.2.3.4:22", {{{1, 2, 3, 4}}}, 22},
2218 {"winehq.org:22", {}, 0, ERROR_INVALID_PARAMETER
},
2219 {"1.2.3.4", {}, 0, ERROR_INVALID_PARAMETER
},
2220 {"1.2.3.4:0", {}, 0, ERROR_INVALID_PARAMETER
},
2221 {"1.2.3.4:65536", {}, 0, ERROR_INVALID_PARAMETER
},
2223 WCHAR wstr
[IP6_ADDRESS_STRING_BUFFER_LENGTH
] = {'1','2','7','.','0','.','0','.','1',':','2','2',0};
2224 NET_ADDRESS_INFO info
;
2230 if (!pParseNetworkString
)
2232 win_skip("ParseNetworkString not available\n");
2236 ret
= pParseNetworkString(wstr
, -1, NULL
, NULL
, NULL
);
2237 ok(ret
== ERROR_SUCCESS
, "expected success, got %d\n", ret
);
2239 ret
= pParseNetworkString(NULL
, NET_STRING_IPV4_SERVICE
, &info
, NULL
, NULL
);
2240 ok(ret
== ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER, got %d\n", ret
);
2242 for (i
= 0; i
< ARRAY_SIZE(ipv4_address_tests
); i
++)
2244 MultiByteToWideChar(CP_ACP
, 0, ipv4_address_tests
[i
].str
, sizeof(ipv4_address_tests
[i
].str
),
2245 wstr
, ARRAY_SIZE(wstr
));
2246 memset(&info
, 0x99, sizeof(info
));
2250 ret
= pParseNetworkString(wstr
, NET_STRING_IPV4_ADDRESS
, &info
, &port
, &prefix_len
);
2252 ok(ret
== ipv4_address_tests
[i
].ret
,
2253 "%s gave error %d\n", ipv4_address_tests
[i
].str
, ret
);
2254 ok(info
.Format
== ret
? NET_ADDRESS_FORMAT_UNSPECIFIED
: NET_ADDRESS_IPV4
,
2255 "%s gave format %d\n", ipv4_address_tests
[i
].str
, info
.Format
);
2256 ok(info
.Ipv4Address
.sin_addr
.S_un
.S_addr
== (ret
? 0x99999999 : ipv4_address_tests
[i
].addr
.S_un
.S_addr
),
2257 "%s gave address %d.%d.%d.%d\n", ipv4_address_tests
[i
].str
,
2258 info
.Ipv4Address
.sin_addr
.S_un
.S_un_b
.s_b1
, info
.Ipv4Address
.sin_addr
.S_un
.S_un_b
.s_b2
,
2259 info
.Ipv4Address
.sin_addr
.S_un
.S_un_b
.s_b3
, info
.Ipv4Address
.sin_addr
.S_un
.S_un_b
.s_b4
);
2260 ok(info
.Ipv4Address
.sin_port
== (ret
? 0x9999 : 0),
2261 "%s gave port %d\n", ipv4_service_tests
[i
].str
, ntohs(info
.Ipv4Address
.sin_port
));
2262 ok(port
== (ret
? 0x9999 : 0),
2263 "%s gave port %d\n", ipv4_service_tests
[i
].str
, port
);
2264 ok(prefix_len
== (ret
? 0x99 : 255),
2265 "%s gave prefix length %d\n", ipv4_service_tests
[i
].str
, prefix_len
);
2268 for (i
= 0; i
< ARRAY_SIZE(ipv4_service_tests
); i
++)
2270 MultiByteToWideChar(CP_ACP
, 0, ipv4_service_tests
[i
].str
, sizeof(ipv4_service_tests
[i
].str
),
2271 wstr
, ARRAY_SIZE(wstr
));
2272 memset(&info
, 0x99, sizeof(info
));
2276 ret
= pParseNetworkString(wstr
, NET_STRING_IPV4_SERVICE
, &info
, &port
, &prefix_len
);
2278 ok(ret
== ipv4_service_tests
[i
].ret
,
2279 "%s gave error %d\n", ipv4_service_tests
[i
].str
, ret
);
2280 ok(info
.Format
== ret
? NET_ADDRESS_FORMAT_UNSPECIFIED
: NET_ADDRESS_IPV4
,
2281 "%s gave format %d\n", ipv4_address_tests
[i
].str
, info
.Format
);
2282 ok(info
.Ipv4Address
.sin_addr
.S_un
.S_addr
== (ret
? 0x99999999 : ipv4_service_tests
[i
].addr
.S_un
.S_addr
),
2283 "%s gave address %d.%d.%d.%d\n", ipv4_service_tests
[i
].str
,
2284 info
.Ipv4Address
.sin_addr
.S_un
.S_un_b
.s_b1
, info
.Ipv4Address
.sin_addr
.S_un
.S_un_b
.s_b2
,
2285 info
.Ipv4Address
.sin_addr
.S_un
.S_un_b
.s_b3
, info
.Ipv4Address
.sin_addr
.S_un
.S_un_b
.s_b4
);
2286 ok(ntohs(info
.Ipv4Address
.sin_port
) == (ret
? 0x9999 : ipv4_service_tests
[i
].port
),
2287 "%s gave port %d\n", ipv4_service_tests
[i
].str
, ntohs(info
.Ipv4Address
.sin_port
));
2288 ok(port
== (ret
? 0x9999 : ipv4_service_tests
[i
].port
),
2289 "%s gave port %d\n", ipv4_service_tests
[i
].str
, port
);
2290 ok(prefix_len
== (ret
? 0x99 : 255),
2291 "%s gave prefix length %d\n", ipv4_service_tests
[i
].str
, prefix_len
);
2295 static void WINAPI
test_ipaddtess_change_callback(PVOID context
, PMIB_UNICASTIPADDRESS_ROW row
,
2296 MIB_NOTIFICATION_TYPE notification_type
)
2298 BOOL
*callback_called
= context
;
2300 *callback_called
= TRUE
;
2302 ok(notification_type
== MibInitialNotification
, "Unexpected notification_type %#x.\n",
2304 ok(!row
, "Unexpected row %p.\n", row
);
2307 static void test_NotifyUnicastIpAddressChange(void)
2309 BOOL callback_called
;
2313 if (!pNotifyUnicastIpAddressChange
)
2315 win_skip("NotifyUnicastIpAddressChange not available.\n");
2319 callback_called
= FALSE
;
2320 ret
= pNotifyUnicastIpAddressChange(AF_INET
, test_ipaddtess_change_callback
,
2321 &callback_called
, TRUE
, &handle
);
2322 ok(ret
== NO_ERROR
, "Unexpected ret %#x.\n", ret
);
2323 ok(callback_called
, "Callback was not called.\n");
2325 ret
= pCancelMibChangeNotify2(handle
);
2326 ok(ret
== NO_ERROR
, "Unexpected ret %#x.\n", ret
);
2327 ok(!CloseHandle(handle
), "CloseHandle() succeeded.\n");
2330 START_TEST(iphlpapi
)
2337 testWin98OnlyFunctions();
2338 testWinNT4Functions();
2340 /* run testGetXXXX in two threads at once to make sure we don't crash in that case */
2341 thread
= CreateThread(NULL
, 0, testWin98Functions
, NULL
, 0, NULL
);
2342 testWin98Functions(NULL
);
2343 WaitForSingleObject(thread
, INFINITE
);
2345 testWin2KFunctions();
2346 test_GetAdaptersAddresses();
2347 test_GetExtendedTcpTable();
2348 test_GetExtendedUdpTable();
2349 test_AllocateAndGetTcpExTableFromStack();
2350 test_CreateSortedAddressPairs();
2351 test_interface_identifier_conversion();
2354 test_GetIfTable2Ex();
2355 test_GetUnicastIpAddressEntry();
2356 test_GetUnicastIpAddressTable();
2357 test_ConvertLengthToIpv4Mask();
2358 test_GetTcp6Table();
2359 test_GetUdp6Table();
2360 test_ParseNetworkString();
2361 test_NotifyUnicastIpAddressChange();