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 skip ("Failed to ping with error %d, is lo interface down?.\n", error
);
1003 else if (winetest_debug
> 1)
1005 PICMP_ECHO_REPLY pong
= (PICMP_ECHO_REPLY
) replydata
;
1006 trace ("send addr : %s\n", ntoa(address
));
1007 trace ("reply addr : %s\n", ntoa(pong
->Address
));
1008 trace ("reply size : %u\n", replysz
);
1009 trace ("roundtrip : %u ms\n", pong
->RoundTripTime
);
1010 trace ("status : %u\n", pong
->Status
);
1011 trace ("recv size : %u\n", pong
->DataSize
);
1012 trace ("ttl : %u\n", pong
->Options
.Ttl
);
1013 trace ("flags : 0x%x\n", pong
->Options
.Flags
);
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");
1031 IcmpCloseHandle(icmp
);
1035 still-to-be-tested NT4-onward functions:
1036 CreateIpForwardEntry
1037 DeleteIpForwardEntry
1048 static void testWinNT4Functions(void)
1050 testGetNumberOfInterfaces();
1051 testGetIpAddrTable();
1053 testGetIpForwardTable();
1054 testGetIpNetTable();
1055 testGetIcmpStatistics();
1056 testGetIpStatistics();
1057 testGetTcpStatistics();
1058 testGetUdpStatistics();
1059 testGetIcmpStatisticsEx();
1060 testGetIpStatisticsEx();
1061 testGetTcpStatisticsEx();
1062 testGetUdpStatisticsEx();
1069 static void testGetInterfaceInfo(void)
1074 apiReturn
= GetInterfaceInfo(NULL
, NULL
);
1075 if (apiReturn
== ERROR_NOT_SUPPORTED
) {
1076 skip("GetInterfaceInfo is not supported\n");
1079 ok(apiReturn
== ERROR_INVALID_PARAMETER
,
1080 "GetInterfaceInfo returned %d, expected ERROR_INVALID_PARAMETER\n",
1082 apiReturn
= GetInterfaceInfo(NULL
, &len
);
1083 ok(apiReturn
== ERROR_INSUFFICIENT_BUFFER
,
1084 "GetInterfaceInfo returned %d, expected ERROR_INSUFFICIENT_BUFFER\n",
1086 if (apiReturn
== ERROR_INSUFFICIENT_BUFFER
) {
1087 PIP_INTERFACE_INFO buf
= HeapAlloc(GetProcessHeap(), 0, len
);
1089 apiReturn
= GetInterfaceInfo(buf
, &len
);
1090 ok(apiReturn
== NO_ERROR
,
1091 "GetInterfaceInfo(buf, &dwSize) returned %d, expected NO_ERROR\n",
1093 HeapFree(GetProcessHeap(), 0, buf
);
1097 static void testGetAdaptersInfo(void)
1102 apiReturn
= GetAdaptersInfo(NULL
, NULL
);
1103 if (apiReturn
== ERROR_NOT_SUPPORTED
) {
1104 skip("GetAdaptersInfo is not supported\n");
1107 ok(apiReturn
== ERROR_INVALID_PARAMETER
,
1108 "GetAdaptersInfo returned %d, expected ERROR_INVALID_PARAMETER\n",
1110 apiReturn
= GetAdaptersInfo(NULL
, &len
);
1111 ok(apiReturn
== ERROR_NO_DATA
|| apiReturn
== ERROR_BUFFER_OVERFLOW
,
1112 "GetAdaptersInfo returned %d, expected ERROR_NO_DATA or ERROR_BUFFER_OVERFLOW\n",
1114 if (apiReturn
== ERROR_NO_DATA
)
1115 ; /* no adapter's, that's okay */
1116 else if (apiReturn
== ERROR_BUFFER_OVERFLOW
) {
1117 PIP_ADAPTER_INFO ptr
, buf
= HeapAlloc(GetProcessHeap(), 0, len
);
1119 apiReturn
= GetAdaptersInfo(buf
, &len
);
1120 ok(apiReturn
== NO_ERROR
,
1121 "GetAdaptersInfo(buf, &dwSize) returned %d, expected NO_ERROR\n",
1125 ok(ptr
->IpAddressList
.IpAddress
.String
[0], "A valid IP address must be present\n");
1126 ok(ptr
->IpAddressList
.IpMask
.String
[0], "A valid mask must be present\n");
1127 ok(ptr
->GatewayList
.IpAddress
.String
[0], "A valid IP address must be present\n");
1128 ok(ptr
->GatewayList
.IpMask
.String
[0], "A valid mask must be present\n");
1129 trace("adapter '%s', address %s/%s gateway %s/%s\n", ptr
->AdapterName
,
1130 ptr
->IpAddressList
.IpAddress
.String
, ptr
->IpAddressList
.IpMask
.String
,
1131 ptr
->GatewayList
.IpAddress
.String
, ptr
->GatewayList
.IpMask
.String
);
1134 HeapFree(GetProcessHeap(), 0, buf
);
1138 static void testGetNetworkParams(void)
1143 apiReturn
= GetNetworkParams(NULL
, NULL
);
1144 if (apiReturn
== ERROR_NOT_SUPPORTED
) {
1145 skip("GetNetworkParams is not supported\n");
1148 ok(apiReturn
== ERROR_INVALID_PARAMETER
,
1149 "GetNetworkParams returned %d, expected ERROR_INVALID_PARAMETER\n",
1151 apiReturn
= GetNetworkParams(NULL
, &len
);
1152 ok(apiReturn
== ERROR_BUFFER_OVERFLOW
,
1153 "GetNetworkParams returned %d, expected ERROR_BUFFER_OVERFLOW\n",
1155 if (apiReturn
== ERROR_BUFFER_OVERFLOW
) {
1156 PFIXED_INFO buf
= HeapAlloc(GetProcessHeap(), 0, len
);
1158 apiReturn
= GetNetworkParams(buf
, &len
);
1159 ok(apiReturn
== NO_ERROR
,
1160 "GetNetworkParams(buf, &dwSize) returned %d, expected NO_ERROR\n",
1162 HeapFree(GetProcessHeap(), 0, buf
);
1167 still-to-be-tested 98-onward functions:
1173 static DWORD CALLBACK
testWin98Functions(void *p
)
1175 testGetInterfaceInfo();
1176 testGetAdaptersInfo();
1177 testGetNetworkParams();
1181 static void testGetPerAdapterInfo(void)
1186 ret
= GetPerAdapterInfo(1, NULL
, NULL
);
1187 if (ret
== ERROR_NOT_SUPPORTED
) {
1188 skip("GetPerAdapterInfo is not supported\n");
1191 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u instead of ERROR_INVALID_PARAMETER\n", ret
);
1192 needed
= 0xdeadbeef;
1193 ret
= GetPerAdapterInfo(1, NULL
, &needed
);
1194 if (ret
== ERROR_NO_DATA
) return; /* no such adapter */
1195 ok( ret
== ERROR_BUFFER_OVERFLOW
, "got %u instead of ERROR_BUFFER_OVERFLOW\n", ret
);
1196 ok( needed
!= 0xdeadbeef, "needed not set\n" );
1197 buffer
= HeapAlloc( GetProcessHeap(), 0, needed
);
1198 ret
= GetPerAdapterInfo(1, buffer
, &needed
);
1199 ok( ret
== NO_ERROR
, "got %u instead of NO_ERROR\n", ret
);
1200 HeapFree( GetProcessHeap(), 0, buffer
);
1203 static void testNotifyAddrChange(void)
1206 OVERLAPPED overlapped
;
1211 ZeroMemory(&overlapped
, sizeof(overlapped
));
1212 ret
= NotifyAddrChange(&handle
, &overlapped
);
1213 ok(ret
== ERROR_IO_PENDING
, "NotifyAddrChange returned %d, expected ERROR_IO_PENDING\n", ret
);
1214 ret
= GetLastError();
1215 todo_wine
ok(ret
== ERROR_IO_PENDING
, "GetLastError returned %d, expected ERROR_IO_PENDING\n", ret
);
1216 success
= CancelIPChangeNotify(&overlapped
);
1217 todo_wine
ok(success
== TRUE
, "CancelIPChangeNotify returned FALSE, expected TRUE\n");
1219 ZeroMemory(&overlapped
, sizeof(overlapped
));
1220 success
= CancelIPChangeNotify(&overlapped
);
1221 ok(success
== FALSE
, "CancelIPChangeNotify returned TRUE, expected FALSE\n");
1224 ZeroMemory(&overlapped
, sizeof(overlapped
));
1225 overlapped
.hEvent
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
1226 ret
= NotifyAddrChange(&handle
, &overlapped
);
1227 ok(ret
== ERROR_IO_PENDING
, "NotifyAddrChange returned %d, expected ERROR_IO_PENDING\n", ret
);
1228 todo_wine
ok(handle
!= INVALID_HANDLE_VALUE
, "NotifyAddrChange returned invalid file handle\n");
1229 success
= GetOverlappedResult(handle
, &overlapped
, &bytes
, FALSE
);
1230 ok(success
== FALSE
, "GetOverlappedResult returned TRUE, expected FALSE\n");
1231 ret
= GetLastError();
1232 ok(ret
== ERROR_IO_INCOMPLETE
, "GetLastError returned %d, expected ERROR_IO_INCOMPLETE\n", ret
);
1233 success
= CancelIPChangeNotify(&overlapped
);
1234 todo_wine
ok(success
== TRUE
, "CancelIPChangeNotify returned FALSE, expected TRUE\n");
1236 if (winetest_interactive
)
1239 ZeroMemory(&overlapped
, sizeof(overlapped
));
1240 overlapped
.hEvent
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
1241 trace("Testing asynchronous ipv4 address change notification. Please "
1242 "change the ipv4 address of one of your network interfaces\n");
1243 ret
= NotifyAddrChange(&handle
, &overlapped
);
1244 ok(ret
== ERROR_IO_PENDING
, "NotifyAddrChange returned %d, expected NO_ERROR\n", ret
);
1245 success
= GetOverlappedResult(handle
, &overlapped
, &bytes
, TRUE
);
1246 ok(success
== TRUE
, "GetOverlappedResult returned FALSE, expected TRUE\n");
1249 /* test synchronous functionality */
1250 if (winetest_interactive
)
1252 trace("Testing synchronous ipv4 address change notification. Please "
1253 "change the ipv4 address of one of your network interfaces\n");
1254 ret
= NotifyAddrChange(NULL
, NULL
);
1255 todo_wine
ok(ret
== NO_ERROR
, "NotifyAddrChange returned %d, expected NO_ERROR\n", ret
);
1260 still-to-be-tested 2K-onward functions:
1268 NotifyRouteChange + CancelIPChangeNotify
1272 static void testWin2KFunctions(void)
1274 testGetPerAdapterInfo();
1275 testNotifyAddrChange();
1278 static void test_GetAdaptersAddresses(void)
1280 BOOL dns_eligible_found
= FALSE
;
1281 ULONG ret
, size
, osize
, i
;
1282 IP_ADAPTER_ADDRESSES
*aa
, *ptr
;
1283 IP_ADAPTER_UNICAST_ADDRESS
*ua
;
1285 ret
= GetAdaptersAddresses(AF_UNSPEC
, 0, NULL
, NULL
, NULL
);
1286 ok(ret
== ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER got %u\n", ret
);
1288 /* size should be ignored and overwritten if buffer is NULL */
1290 ret
= GetAdaptersAddresses(AF_UNSPEC
, 0, NULL
, NULL
, &size
);
1291 ok(ret
== ERROR_BUFFER_OVERFLOW
, "expected ERROR_BUFFER_OVERFLOW, got %u\n", ret
);
1292 if (ret
!= ERROR_BUFFER_OVERFLOW
) return;
1294 ptr
= HeapAlloc(GetProcessHeap(), 0, size
);
1295 ret
= GetAdaptersAddresses(AF_UNSPEC
, 0, NULL
, ptr
, &size
);
1296 ok(!ret
, "expected ERROR_SUCCESS got %u\n", ret
);
1297 HeapFree(GetProcessHeap(), 0, ptr
);
1299 /* higher size must not be changed to lower size */
1302 ptr
= HeapAlloc(GetProcessHeap(), 0, osize
);
1303 ret
= GetAdaptersAddresses(AF_UNSPEC
, GAA_FLAG_INCLUDE_PREFIX
, NULL
, ptr
, &osize
);
1304 ok(!ret
, "expected ERROR_SUCCESS got %u\n", ret
);
1305 ok(osize
== size
, "expected %d, got %d\n", size
, osize
);
1307 for (aa
= ptr
; !ret
&& aa
; aa
= aa
->Next
)
1309 char temp
[128], buf
[39];
1310 IP_ADAPTER_PREFIX
*prefix
;
1314 ok(S(U(*aa
)).Length
== sizeof(IP_ADAPTER_ADDRESSES_LH
) ||
1315 S(U(*aa
)).Length
== sizeof(IP_ADAPTER_ADDRESSES_XP
),
1316 "Unknown structure size of %u bytes\n", S(U(*aa
)).Length
);
1317 ok(aa
->DnsSuffix
!= NULL
, "DnsSuffix is not a valid pointer\n");
1318 ok(aa
->Description
!= NULL
, "Description is not a valid pointer\n");
1319 ok(aa
->FriendlyName
!= NULL
, "FriendlyName is not a valid pointer\n");
1321 for (i
= 0; i
< aa
->PhysicalAddressLength
; i
++)
1322 sprintf(temp
+ i
* 3, "%02X-", aa
->PhysicalAddress
[i
]);
1323 temp
[i
? i
* 3 - 1 : 0] = '\0';
1324 trace("idx %u name %s %s dns %s descr %s phys %s mtu %u flags %08x type %u\n",
1325 S(U(*aa
)).IfIndex
, aa
->AdapterName
,
1326 wine_dbgstr_w(aa
->FriendlyName
), wine_dbgstr_w(aa
->DnsSuffix
),
1327 wine_dbgstr_w(aa
->Description
), temp
, aa
->Mtu
, aa
->Flags
, aa
->IfType
);
1328 ua
= aa
->FirstUnicastAddress
;
1331 ok(S(U(*ua
)).Length
== sizeof(IP_ADAPTER_UNICAST_ADDRESS_LH
) ||
1332 S(U(*ua
)).Length
== sizeof(IP_ADAPTER_UNICAST_ADDRESS_XP
),
1333 "Unknown structure size of %u bytes\n", S(U(*ua
)).Length
);
1334 ok(ua
->PrefixOrigin
!= IpPrefixOriginOther
,
1335 "bad address config value %d\n", ua
->PrefixOrigin
);
1336 ok(ua
->SuffixOrigin
!= IpSuffixOriginOther
,
1337 "bad address config value %d\n", ua
->PrefixOrigin
);
1338 /* Address configured manually or from DHCP server? */
1339 if (ua
->PrefixOrigin
== IpPrefixOriginManual
||
1340 ua
->PrefixOrigin
== IpPrefixOriginDhcp
)
1342 ok(ua
->ValidLifetime
, "expected non-zero value\n");
1343 ok(ua
->PreferredLifetime
, "expected non-zero value\n");
1344 ok(ua
->LeaseLifetime
, "expected non-zero\n");
1346 /* Is the address ok in the network (not duplicated)? */
1347 ok(ua
->DadState
!= IpDadStateInvalid
&& ua
->DadState
!= IpDadStateDuplicate
,
1348 "bad address duplication value %d\n", ua
->DadState
);
1349 trace(" flags %08x origin %u/%u state %u lifetime %u/%u/%u prefix %u\n",
1350 S(U(*ua
)).Flags
, ua
->PrefixOrigin
, ua
->SuffixOrigin
, ua
->DadState
,
1351 ua
->ValidLifetime
, ua
->PreferredLifetime
, ua
->LeaseLifetime
,
1352 S(U(*ua
)).Length
< sizeof(IP_ADAPTER_UNICAST_ADDRESS_LH
) ? 0 : ua
->OnLinkPrefixLength
);
1354 if (ua
->Flags
& IP_ADAPTER_ADDRESS_DNS_ELIGIBLE
)
1355 dns_eligible_found
= TRUE
;
1359 for (i
= 0, temp
[0] = '\0'; i
< ARRAY_SIZE(aa
->ZoneIndices
); i
++)
1360 sprintf(temp
+ strlen(temp
), "%d ", aa
->ZoneIndices
[i
]);
1361 trace("status %u index %u zone %s\n", aa
->OperStatus
, aa
->Ipv6IfIndex
, temp
);
1362 prefix
= aa
->FirstPrefix
;
1365 trace( " prefix %u/%u flags %08x\n", prefix
->Address
.iSockaddrLength
,
1366 prefix
->PrefixLength
, S(U(*prefix
)).Flags
);
1367 prefix
= prefix
->Next
;
1370 if (S(U(*aa
)).Length
< sizeof(IP_ADAPTER_ADDRESSES_LH
)) continue;
1371 trace("speed %s/%s metrics %u/%u guid %s type %u/%u\n",
1372 wine_dbgstr_longlong(aa
->TransmitLinkSpeed
),
1373 wine_dbgstr_longlong(aa
->ReceiveLinkSpeed
),
1374 aa
->Ipv4Metric
, aa
->Ipv6Metric
, wine_dbgstr_guid((GUID
*) &aa
->NetworkGuid
),
1375 aa
->ConnectionType
, aa
->TunnelType
);
1377 if (pConvertInterfaceLuidToGuid
)
1379 status
= pConvertInterfaceLuidToGuid(&aa
->Luid
, &guid
);
1380 ok(!status
, "got %u\n", status
);
1381 sprintf(buf
, "{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
1382 guid
.Data1
, guid
.Data2
, guid
.Data3
, guid
.Data4
[0], guid
.Data4
[1],
1383 guid
.Data4
[2], guid
.Data4
[3], guid
.Data4
[4], guid
.Data4
[5],
1384 guid
.Data4
[6], guid
.Data4
[7]);
1385 ok(!strcasecmp(aa
->AdapterName
, buf
), "expected '%s' got '%s'\n", aa
->AdapterName
, buf
);
1388 ok(dns_eligible_found
, "Did not find any dns eligible addresses.\n");
1389 HeapFree(GetProcessHeap(), 0, ptr
);
1392 static void test_GetExtendedTcpTable(void)
1395 MIB_TCPTABLE
*table
;
1396 MIB_TCPTABLE_OWNER_PID
*table_pid
;
1397 MIB_TCPTABLE_OWNER_MODULE
*table_module
;
1399 if (!pGetExtendedTcpTable
)
1401 win_skip("GetExtendedTcpTable not available\n");
1404 ret
= pGetExtendedTcpTable( NULL
, NULL
, TRUE
, AF_INET
, TCP_TABLE_BASIC_ALL
, 0 );
1405 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
1408 ret
= pGetExtendedTcpTable( NULL
, &size
, TRUE
, AF_INET
, TCP_TABLE_BASIC_ALL
, 0 );
1409 ok( ret
== ERROR_INSUFFICIENT_BUFFER
, "got %u\n", ret
);
1411 table
= HeapAlloc( GetProcessHeap(), 0, size
);
1412 ret
= pGetExtendedTcpTable( table
, &size
, TRUE
, AF_INET
, TCP_TABLE_BASIC_ALL
, 0 );
1413 ok( ret
== ERROR_SUCCESS
, "got %u\n", ret
);
1414 HeapFree( GetProcessHeap(), 0, table
);
1417 ret
= pGetExtendedTcpTable( NULL
, &size
, TRUE
, AF_INET
, TCP_TABLE_BASIC_LISTENER
, 0 );
1418 ok( ret
== ERROR_INSUFFICIENT_BUFFER
, "got %u\n", ret
);
1420 table
= HeapAlloc( GetProcessHeap(), 0, size
);
1421 ret
= pGetExtendedTcpTable( table
, &size
, TRUE
, AF_INET
, TCP_TABLE_BASIC_LISTENER
, 0 );
1422 ok( ret
== ERROR_SUCCESS
, "got %u\n", ret
);
1423 HeapFree( GetProcessHeap(), 0, table
);
1426 ret
= pGetExtendedTcpTable( NULL
, &size
, TRUE
, AF_INET
, TCP_TABLE_OWNER_PID_ALL
, 0 );
1427 ok( ret
== ERROR_INSUFFICIENT_BUFFER
, "got %u\n", ret
);
1429 table_pid
= HeapAlloc( GetProcessHeap(), 0, size
);
1430 ret
= pGetExtendedTcpTable( table_pid
, &size
, TRUE
, AF_INET
, TCP_TABLE_OWNER_PID_ALL
, 0 );
1431 ok( ret
== ERROR_SUCCESS
, "got %u\n", ret
);
1432 HeapFree( GetProcessHeap(), 0, table_pid
);
1435 ret
= pGetExtendedTcpTable( NULL
, &size
, TRUE
, AF_INET
, TCP_TABLE_OWNER_PID_LISTENER
, 0 );
1436 ok( ret
== ERROR_INSUFFICIENT_BUFFER
, "got %u\n", ret
);
1438 table_pid
= HeapAlloc( GetProcessHeap(), 0, size
);
1439 ret
= pGetExtendedTcpTable( table_pid
, &size
, TRUE
, AF_INET
, TCP_TABLE_OWNER_PID_LISTENER
, 0 );
1440 ok( ret
== ERROR_SUCCESS
, "got %u\n", ret
);
1441 HeapFree( GetProcessHeap(), 0, table_pid
);
1444 ret
= pGetExtendedTcpTable( NULL
, &size
, TRUE
, AF_INET
, TCP_TABLE_OWNER_MODULE_ALL
, 0 );
1445 ok( ret
== ERROR_INSUFFICIENT_BUFFER
, "got %u\n", ret
);
1447 table_module
= HeapAlloc( GetProcessHeap(), 0, size
);
1448 ret
= pGetExtendedTcpTable( table_module
, &size
, TRUE
, AF_INET
, TCP_TABLE_OWNER_MODULE_ALL
, 0 );
1449 ok( ret
== ERROR_SUCCESS
, "got %u\n", ret
);
1450 HeapFree( GetProcessHeap(), 0, table_module
);
1453 ret
= pGetExtendedTcpTable( NULL
, &size
, TRUE
, AF_INET
, TCP_TABLE_OWNER_MODULE_LISTENER
, 0 );
1454 ok( ret
== ERROR_INSUFFICIENT_BUFFER
, "got %u\n", ret
);
1456 table_module
= HeapAlloc( GetProcessHeap(), 0, size
);
1457 ret
= pGetExtendedTcpTable( table_module
, &size
, TRUE
, AF_INET
, TCP_TABLE_OWNER_MODULE_LISTENER
, 0 );
1458 ok( ret
== ERROR_SUCCESS
, "got %u\n", ret
);
1459 HeapFree( GetProcessHeap(), 0, table_module
);
1462 static void test_AllocateAndGetTcpExTableFromStack(void)
1465 MIB_TCPTABLE_OWNER_PID
*table_ex
= NULL
;
1467 if (!pAllocateAndGetTcpExTableFromStack
)
1469 skip("AllocateAndGetTcpExTableFromStack not available\n");
1475 /* crashes on native */
1476 ret
= pAllocateAndGetTcpExTableFromStack( NULL
, FALSE
, INVALID_HANDLE_VALUE
, 0, 0 );
1477 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
1478 ret
= pAllocateAndGetTcpExTableFromStack( (void **)&table_ex
, FALSE
, INVALID_HANDLE_VALUE
, 0, AF_INET
);
1479 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
1480 ret
= pAllocateAndGetTcpExTableFromStack( NULL
, FALSE
, GetProcessHeap(), 0, AF_INET
);
1481 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
1484 ret
= pAllocateAndGetTcpExTableFromStack( (void **)&table_ex
, FALSE
, GetProcessHeap(), 0, 0 );
1485 ok( ret
== ERROR_INVALID_PARAMETER
|| broken(ret
== ERROR_NOT_SUPPORTED
) /* win2k */, "got %u\n", ret
);
1487 ret
= pAllocateAndGetTcpExTableFromStack( (void **)&table_ex
, FALSE
, GetProcessHeap(), 0, AF_INET
);
1488 ok( ret
== ERROR_SUCCESS
, "got %u\n", ret
);
1490 if (ret
== NO_ERROR
&& winetest_debug
> 1)
1493 trace( "AllocateAndGetTcpExTableFromStack table: %u entries\n", table_ex
->dwNumEntries
);
1494 for (i
= 0; i
< table_ex
->dwNumEntries
; i
++)
1498 strcpy(remote_ip
, ntoa(table_ex
->table
[i
].dwRemoteAddr
));
1499 trace( "%u: local %s:%u remote %s:%u state %u pid %u\n", i
,
1500 ntoa(table_ex
->table
[i
].dwLocalAddr
), ntohs(table_ex
->table
[i
].dwLocalPort
),
1501 remote_ip
, ntohs(table_ex
->table
[i
].dwRemotePort
),
1502 U(table_ex
->table
[i
]).dwState
, table_ex
->table
[i
].dwOwningPid
);
1505 HeapFree(GetProcessHeap(), 0, table_ex
);
1507 ret
= pAllocateAndGetTcpExTableFromStack( (void **)&table_ex
, FALSE
, GetProcessHeap(), 0, AF_INET6
);
1508 ok( ret
== ERROR_NOT_SUPPORTED
, "got %u\n", ret
);
1511 static void test_GetExtendedUdpTable(void)
1514 MIB_UDPTABLE
*table
;
1515 MIB_UDPTABLE_OWNER_PID
*table_pid
;
1516 MIB_UDPTABLE_OWNER_MODULE
*table_module
;
1518 if (!pGetExtendedUdpTable
)
1520 win_skip("GetExtendedUdpTable not available\n");
1523 ret
= pGetExtendedUdpTable( NULL
, NULL
, TRUE
, AF_INET
, UDP_TABLE_BASIC
, 0 );
1524 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
1527 ret
= pGetExtendedUdpTable( NULL
, &size
, TRUE
, AF_INET
, UDP_TABLE_BASIC
, 0 );
1528 ok( ret
== ERROR_INSUFFICIENT_BUFFER
, "got %u\n", ret
);
1530 table
= HeapAlloc( GetProcessHeap(), 0, size
);
1531 ret
= pGetExtendedUdpTable( table
, &size
, TRUE
, AF_INET
, UDP_TABLE_BASIC
, 0 );
1532 ok( ret
== ERROR_SUCCESS
, "got %u\n", ret
);
1533 HeapFree( GetProcessHeap(), 0, table
);
1536 ret
= pGetExtendedUdpTable( NULL
, &size
, TRUE
, AF_INET
, UDP_TABLE_OWNER_PID
, 0 );
1537 ok( ret
== ERROR_INSUFFICIENT_BUFFER
, "got %u\n", ret
);
1539 table_pid
= HeapAlloc( GetProcessHeap(), 0, size
);
1540 ret
= pGetExtendedUdpTable( table_pid
, &size
, TRUE
, AF_INET
, UDP_TABLE_OWNER_PID
, 0 );
1541 ok( ret
== ERROR_SUCCESS
, "got %u\n", ret
);
1542 HeapFree( GetProcessHeap(), 0, table_pid
);
1545 ret
= pGetExtendedUdpTable( NULL
, &size
, TRUE
, AF_INET
, UDP_TABLE_OWNER_MODULE
, 0 );
1546 ok( ret
== ERROR_INSUFFICIENT_BUFFER
, "got %u\n", ret
);
1548 table_module
= HeapAlloc( GetProcessHeap(), 0, size
);
1549 ret
= pGetExtendedUdpTable( table_module
, &size
, TRUE
, AF_INET
, UDP_TABLE_OWNER_MODULE
, 0 );
1550 ok( ret
== ERROR_SUCCESS
, "got %u\n", ret
);
1551 HeapFree( GetProcessHeap(), 0, table_module
);
1554 static void test_CreateSortedAddressPairs(void)
1556 SOCKADDR_IN6 dst
[2];
1557 SOCKADDR_IN6_PAIR
*pair
;
1561 if (!pCreateSortedAddressPairs
)
1563 win_skip( "CreateSortedAddressPairs not available\n" );
1567 memset( dst
, 0, sizeof(dst
) );
1568 dst
[0].sin6_family
= AF_INET6
;
1569 dst
[0].sin6_addr
.u
.Word
[5] = 0xffff;
1570 dst
[0].sin6_addr
.u
.Word
[6] = 0x0808;
1571 dst
[0].sin6_addr
.u
.Word
[7] = 0x0808;
1573 pair_count
= 0xdeadbeef;
1574 ret
= pCreateSortedAddressPairs( NULL
, 0, dst
, 1, 0, NULL
, &pair_count
);
1575 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
1576 ok( pair_count
== 0xdeadbeef, "got %u\n", pair_count
);
1578 pair
= (SOCKADDR_IN6_PAIR
*)0xdeadbeef;
1579 pair_count
= 0xdeadbeef;
1580 ret
= pCreateSortedAddressPairs( NULL
, 0, NULL
, 1, 0, &pair
, &pair_count
);
1581 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
1582 ok( pair
== (SOCKADDR_IN6_PAIR
*)0xdeadbeef, "got %p\n", pair
);
1583 ok( pair_count
== 0xdeadbeef, "got %u\n", pair_count
);
1586 pair_count
= 0xdeadbeef;
1587 ret
= pCreateSortedAddressPairs( NULL
, 0, dst
, 1, 0, &pair
, &pair_count
);
1588 ok( ret
== NO_ERROR
, "got %u\n", ret
);
1589 ok( pair
!= NULL
, "pair not set\n" );
1590 ok( pair_count
>= 1, "got %u\n", pair_count
);
1591 ok( pair
[0].SourceAddress
!= NULL
, "src address not set\n" );
1592 ok( pair
[0].DestinationAddress
!= NULL
, "dst address not set\n" );
1593 pFreeMibTable( pair
);
1595 dst
[1].sin6_family
= AF_INET6
;
1596 dst
[1].sin6_addr
.u
.Word
[5] = 0xffff;
1597 dst
[1].sin6_addr
.u
.Word
[6] = 0x0404;
1598 dst
[1].sin6_addr
.u
.Word
[7] = 0x0808;
1601 pair_count
= 0xdeadbeef;
1602 ret
= pCreateSortedAddressPairs( NULL
, 0, dst
, 2, 0, &pair
, &pair_count
);
1603 ok( ret
== NO_ERROR
, "got %u\n", ret
);
1604 ok( pair
!= NULL
, "pair not set\n" );
1605 ok( pair_count
>= 2, "got %u\n", pair_count
);
1606 ok( pair
[0].SourceAddress
!= NULL
, "src address not set\n" );
1607 ok( pair
[0].DestinationAddress
!= NULL
, "dst address not set\n" );
1608 ok( pair
[1].SourceAddress
!= NULL
, "src address not set\n" );
1609 ok( pair
[1].DestinationAddress
!= NULL
, "dst address not set\n" );
1610 pFreeMibTable( pair
);
1613 static DWORD
get_interface_index(void)
1615 DWORD size
= 0, ret
= 0;
1616 IP_ADAPTER_ADDRESSES
*buf
, *aa
;
1618 if (GetAdaptersAddresses( AF_UNSPEC
, 0, NULL
, NULL
, &size
) != ERROR_BUFFER_OVERFLOW
)
1621 buf
= HeapAlloc( GetProcessHeap(), 0, size
);
1622 GetAdaptersAddresses( AF_UNSPEC
, 0, NULL
, buf
, &size
);
1623 for (aa
= buf
; aa
; aa
= aa
->Next
)
1625 if (aa
->IfType
== IF_TYPE_ETHERNET_CSMACD
)
1631 HeapFree( GetProcessHeap(), 0, buf
);
1635 static void test_interface_identifier_conversion(void)
1641 WCHAR nameW
[IF_MAX_STRING_SIZE
+ 1];
1642 char nameA
[IF_MAX_STRING_SIZE
+ 1], *name
;
1643 NET_IFINDEX index
, index2
;
1645 if (!pConvertInterfaceIndexToLuid
)
1647 win_skip( "ConvertInterfaceIndexToLuid not available\n" );
1650 if (!(index
= get_interface_index()))
1652 skip( "no suitable interface found\n" );
1656 /* ConvertInterfaceIndexToLuid */
1657 ret
= pConvertInterfaceIndexToLuid( 0, NULL
);
1658 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
1660 memset( &luid
, 0xff, sizeof(luid
) );
1661 ret
= pConvertInterfaceIndexToLuid( 0, &luid
);
1662 ok( ret
== ERROR_FILE_NOT_FOUND
, "got %u\n", ret
);
1663 ok( !luid
.Info
.Reserved
, "got %x\n", luid
.Info
.Reserved
);
1664 ok( !luid
.Info
.NetLuidIndex
, "got %u\n", luid
.Info
.NetLuidIndex
);
1665 ok( !luid
.Info
.IfType
, "got %u\n", luid
.Info
.IfType
);
1667 luid
.Info
.Reserved
= luid
.Info
.NetLuidIndex
= luid
.Info
.IfType
= 0xdead;
1668 ret
= pConvertInterfaceIndexToLuid( index
, &luid
);
1669 ok( !ret
, "got %u\n", ret
);
1670 ok( !luid
.Info
.Reserved
, "got %x\n", luid
.Info
.Reserved
);
1671 ok( luid
.Info
.NetLuidIndex
!= 0xdead, "index not set\n" );
1672 ok( luid
.Info
.IfType
== IF_TYPE_ETHERNET_CSMACD
, "got %u\n", luid
.Info
.IfType
);
1674 /* ConvertInterfaceLuidToIndex */
1675 ret
= pConvertInterfaceLuidToIndex( NULL
, NULL
);
1676 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
1678 ret
= pConvertInterfaceLuidToIndex( NULL
, &index
);
1679 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
1681 ret
= pConvertInterfaceLuidToIndex( &luid
, NULL
);
1682 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
1684 ret
= pConvertInterfaceLuidToIndex( &luid
, &index
);
1685 ok( !ret
, "got %u\n", ret
);
1687 /* ConvertInterfaceLuidToGuid */
1688 ret
= pConvertInterfaceLuidToGuid( NULL
, NULL
);
1689 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
1691 memset( &guid
, 0xff, sizeof(guid
) );
1692 ret
= pConvertInterfaceLuidToGuid( NULL
, &guid
);
1693 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
1694 ok( guid
.Data1
== 0xffffffff, "got %x\n", guid
.Data1
);
1696 ret
= pConvertInterfaceLuidToGuid( &luid
, NULL
);
1697 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
1699 memset( &guid
, 0, sizeof(guid
) );
1700 ret
= pConvertInterfaceLuidToGuid( &luid
, &guid
);
1701 ok( !ret
, "got %u\n", ret
);
1702 ok( guid
.Data1
, "got %x\n", guid
.Data1
);
1704 /* ConvertInterfaceGuidToLuid */
1705 ret
= pConvertInterfaceGuidToLuid( NULL
, NULL
);
1706 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
1708 luid
.Info
.NetLuidIndex
= 1;
1709 ret
= pConvertInterfaceGuidToLuid( NULL
, &luid
);
1710 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
1711 ok( luid
.Info
.NetLuidIndex
== 1, "got %u\n", luid
.Info
.NetLuidIndex
);
1713 ret
= pConvertInterfaceGuidToLuid( &guid
, NULL
);
1714 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
1716 luid
.Info
.Reserved
= luid
.Info
.NetLuidIndex
= luid
.Info
.IfType
= 0xdead;
1717 ret
= pConvertInterfaceGuidToLuid( &guid
, &luid
);
1718 ok( !ret
, "got %u\n", ret
);
1719 ok( !luid
.Info
.Reserved
, "got %x\n", luid
.Info
.Reserved
);
1720 ok( luid
.Info
.NetLuidIndex
!= 0xdead, "index not set\n" );
1721 ok( luid
.Info
.IfType
== IF_TYPE_ETHERNET_CSMACD
, "got %u\n", luid
.Info
.IfType
);
1723 /* ConvertInterfaceLuidToNameW */
1724 ret
= pConvertInterfaceLuidToNameW( NULL
, NULL
, 0 );
1725 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
1727 ret
= pConvertInterfaceLuidToNameW( &luid
, NULL
, 0 );
1728 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
1730 ret
= pConvertInterfaceLuidToNameW( NULL
, nameW
, 0 );
1731 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
1733 ret
= pConvertInterfaceLuidToNameW( &luid
, nameW
, 0 );
1734 ok( ret
== ERROR_NOT_ENOUGH_MEMORY
, "got %u\n", ret
);
1737 len
= ARRAY_SIZE(nameW
);
1738 ret
= pConvertInterfaceLuidToNameW( &luid
, nameW
, len
);
1739 ok( !ret
, "got %u\n", ret
);
1740 ok( nameW
[0], "name not set\n" );
1742 /* ConvertInterfaceLuidToNameA */
1743 ret
= pConvertInterfaceLuidToNameA( NULL
, NULL
, 0 );
1744 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
1746 ret
= pConvertInterfaceLuidToNameA( &luid
, NULL
, 0 );
1747 ok( ret
== ERROR_NOT_ENOUGH_MEMORY
, "got %u\n", ret
);
1749 ret
= pConvertInterfaceLuidToNameA( NULL
, nameA
, 0 );
1750 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
1752 ret
= pConvertInterfaceLuidToNameA( &luid
, nameA
, 0 );
1753 ok( ret
== ERROR_NOT_ENOUGH_MEMORY
, "got %u\n", ret
);
1756 len
= ARRAY_SIZE(nameA
);
1757 ret
= pConvertInterfaceLuidToNameA( &luid
, nameA
, len
);
1758 ok( !ret
, "got %u\n", ret
);
1759 ok( nameA
[0], "name not set\n" );
1761 /* ConvertInterfaceNameToLuidW */
1762 ret
= pConvertInterfaceNameToLuidW( NULL
, NULL
);
1763 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
1765 luid
.Info
.Reserved
= luid
.Info
.NetLuidIndex
= luid
.Info
.IfType
= 0xdead;
1766 ret
= pConvertInterfaceNameToLuidW( NULL
, &luid
);
1767 ok( ret
== ERROR_INVALID_NAME
, "got %u\n", ret
);
1768 ok( !luid
.Info
.Reserved
, "got %x\n", luid
.Info
.Reserved
);
1769 ok( luid
.Info
.NetLuidIndex
!= 0xdead, "index not set\n" );
1770 ok( !luid
.Info
.IfType
, "got %u\n", luid
.Info
.IfType
);
1772 ret
= pConvertInterfaceNameToLuidW( nameW
, NULL
);
1773 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
1775 luid
.Info
.Reserved
= luid
.Info
.NetLuidIndex
= luid
.Info
.IfType
= 0xdead;
1776 ret
= pConvertInterfaceNameToLuidW( nameW
, &luid
);
1777 ok( !ret
, "got %u\n", ret
);
1778 ok( !luid
.Info
.Reserved
, "got %x\n", luid
.Info
.Reserved
);
1779 ok( luid
.Info
.NetLuidIndex
!= 0xdead, "index not set\n" );
1780 ok( luid
.Info
.IfType
== IF_TYPE_ETHERNET_CSMACD
, "got %u\n", luid
.Info
.IfType
);
1782 /* ConvertInterfaceNameToLuidA */
1783 ret
= pConvertInterfaceNameToLuidA( NULL
, NULL
);
1784 ok( ret
== ERROR_INVALID_NAME
, "got %u\n", ret
);
1786 luid
.Info
.Reserved
= luid
.Info
.NetLuidIndex
= luid
.Info
.IfType
= 0xdead;
1787 ret
= pConvertInterfaceNameToLuidA( NULL
, &luid
);
1788 ok( ret
== ERROR_INVALID_NAME
, "got %u\n", ret
);
1789 ok( luid
.Info
.Reserved
== 0xdead, "reserved set\n" );
1790 ok( luid
.Info
.NetLuidIndex
== 0xdead, "index set\n" );
1791 ok( luid
.Info
.IfType
== 0xdead, "type set\n" );
1793 ret
= pConvertInterfaceNameToLuidA( nameA
, NULL
);
1794 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
1796 luid
.Info
.Reserved
= luid
.Info
.NetLuidIndex
= luid
.Info
.IfType
= 0xdead;
1797 ret
= pConvertInterfaceNameToLuidA( nameA
, &luid
);
1798 ok( !ret
, "got %u\n", ret
);
1799 ok( !luid
.Info
.Reserved
, "got %x\n", luid
.Info
.Reserved
);
1800 ok( luid
.Info
.NetLuidIndex
!= 0xdead, "index not set\n" );
1801 ok( luid
.Info
.IfType
== IF_TYPE_ETHERNET_CSMACD
, "got %u\n", luid
.Info
.IfType
);
1803 if (!pif_nametoindex
|| !pif_indextoname
)
1805 skip("if_nametoindex/if_indextoname not supported\n");
1809 index2
= pif_nametoindex( NULL
);
1810 ok( !index2
, "Got unexpected index %u\n", index2
);
1811 index2
= pif_nametoindex( nameA
);
1812 ok( index2
== index
, "Got index %u for %s, expected %u\n", index2
, nameA
, index
);
1813 /* Wargaming.net Game Center passes a GUID-like string. */
1814 index2
= pif_nametoindex( "{00000001-0000-0000-0000-000000000000}" );
1815 ok( !index2
, "Got unexpected index %u\n", index2
);
1816 index2
= pif_nametoindex( wine_dbgstr_guid( &guid
) );
1817 ok( !index2
, "Got unexpected index %u for input %s\n", index2
, wine_dbgstr_guid( &guid
) );
1819 name
= pif_indextoname( 0, NULL
);
1820 ok( name
== NULL
, "got %s\n", name
);
1822 name
= pif_indextoname( 0, nameA
);
1823 ok( name
== NULL
, "got %p\n", name
);
1825 name
= pif_indextoname( ~0u, nameA
);
1826 ok( name
== NULL
, "got %p\n", name
);
1829 name
= pif_indextoname( 1, nameA
);
1832 ok( name
[0], "empty name\n" );
1833 ok( name
== nameA
, "got %p\n", name
);
1837 static void test_GetIfEntry2(void)
1845 win_skip( "GetIfEntry2 not available\n" );
1848 if (!(index
= get_interface_index()))
1850 skip( "no suitable interface found\n" );
1854 ret
= pGetIfEntry2( NULL
);
1855 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
1857 memset( &row
, 0, sizeof(row
) );
1858 ret
= pGetIfEntry2( &row
);
1859 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
1861 memset( &row
, 0, sizeof(row
) );
1862 row
.InterfaceIndex
= index
;
1863 ret
= pGetIfEntry2( &row
);
1864 ok( ret
== NO_ERROR
, "got %u\n", ret
);
1865 ok( row
.InterfaceIndex
== index
, "got %u\n", index
);
1868 static void test_GetIfTable2(void)
1871 MIB_IF_TABLE2
*table
;
1875 win_skip( "GetIfTable2 not available\n" );
1880 ret
= pGetIfTable2( &table
);
1881 ok( ret
== NO_ERROR
, "got %u\n", ret
);
1882 ok( table
!= NULL
, "table not set\n" );
1883 pFreeMibTable( table
);
1886 static void test_GetIfTable2Ex(void)
1889 MIB_IF_TABLE2
*table
;
1891 if (!pGetIfTable2Ex
)
1893 win_skip( "GetIfTable2Ex not available\n" );
1898 ret
= pGetIfTable2Ex( MibIfTableNormal
, &table
);
1899 ok( ret
== NO_ERROR
, "got %u\n", ret
);
1900 ok( table
!= NULL
, "table not set\n" );
1901 pFreeMibTable( table
);
1904 ret
= pGetIfTable2Ex( MibIfTableRaw
, &table
);
1905 ok( ret
== NO_ERROR
, "got %u\n", ret
);
1906 ok( table
!= NULL
, "table not set\n" );
1907 pFreeMibTable( table
);
1910 ret
= pGetIfTable2Ex( MibIfTableNormalWithoutStatistics
, &table
);
1911 ok( ret
== NO_ERROR
|| broken(ret
== ERROR_INVALID_PARAMETER
), "got %u\n", ret
);
1912 ok( table
!= NULL
|| broken(!table
), "table not set\n" );
1913 pFreeMibTable( table
);
1916 ret
= pGetIfTable2Ex( 3, &table
);
1917 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
1918 ok( !table
, "table should not be set\n" );
1919 pFreeMibTable( table
);
1922 static void test_GetUnicastIpAddressEntry(void)
1924 IP_ADAPTER_ADDRESSES
*aa
, *ptr
;
1925 MIB_UNICASTIPADDRESS_ROW row
;
1928 if (!pGetUnicastIpAddressEntry
)
1930 win_skip( "GetUnicastIpAddressEntry not available\n" );
1934 ret
= pGetUnicastIpAddressEntry( NULL
);
1935 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
1937 memset( &row
, 0, sizeof(row
) );
1938 ret
= pGetUnicastIpAddressEntry( &row
);
1939 todo_wine
ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
1941 memset( &row
, 0, sizeof(row
) );
1942 row
.Address
.Ipv4
.sin_family
= AF_INET
;
1943 row
.Address
.Ipv4
.sin_port
= 0;
1944 row
.Address
.Ipv4
.sin_addr
.S_un
.S_addr
= 0x01020304;
1945 ret
= pGetUnicastIpAddressEntry( &row
);
1946 ok( ret
== ERROR_FILE_NOT_FOUND
, "got %u\n", ret
);
1948 memset( &row
, 0, sizeof(row
) );
1949 row
.InterfaceIndex
= 123;
1950 ret
= pGetUnicastIpAddressEntry( &row
);
1951 todo_wine
ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
1953 memset( &row
, 0, sizeof(row
) );
1954 row
.InterfaceIndex
= get_interface_index();
1955 row
.Address
.Ipv4
.sin_family
= AF_INET
;
1956 row
.Address
.Ipv4
.sin_port
= 0;
1957 row
.Address
.Ipv4
.sin_addr
.S_un
.S_addr
= 0x01020304;
1958 ret
= pGetUnicastIpAddressEntry( &row
);
1959 ok( ret
== ERROR_NOT_FOUND
, "got %u\n", ret
);
1961 memset( &row
, 0, sizeof(row
) );
1962 row
.InterfaceIndex
= 123;
1963 row
.Address
.Ipv4
.sin_family
= AF_INET
;
1964 row
.Address
.Ipv4
.sin_port
= 0;
1965 row
.Address
.Ipv4
.sin_addr
.S_un
.S_addr
= 0x01020304;
1966 ret
= pGetUnicastIpAddressEntry( &row
);
1967 ok( ret
== ERROR_FILE_NOT_FOUND
, "got %u\n", ret
);
1969 ret
= GetAdaptersAddresses(AF_UNSPEC
, GAA_FLAG_INCLUDE_ALL_INTERFACES
, NULL
, NULL
, &size
);
1970 ok(ret
== ERROR_BUFFER_OVERFLOW
, "expected ERROR_BUFFER_OVERFLOW, got %u\n", ret
);
1971 if (ret
!= ERROR_BUFFER_OVERFLOW
) return;
1973 ptr
= HeapAlloc(GetProcessHeap(), 0, size
);
1974 ret
= GetAdaptersAddresses(AF_UNSPEC
, GAA_FLAG_INCLUDE_ALL_INTERFACES
, NULL
, ptr
, &size
);
1975 ok(!ret
, "expected ERROR_SUCCESS got %u\n", ret
);
1977 for (aa
= ptr
; !ret
&& aa
; aa
= aa
->Next
)
1979 IP_ADAPTER_UNICAST_ADDRESS
*ua
;
1981 ua
= aa
->FirstUnicastAddress
;
1984 /* test with luid */
1985 memset( &row
, 0, sizeof(row
) );
1986 memcpy(&row
.InterfaceLuid
, &aa
->Luid
, sizeof(aa
->Luid
));
1987 memcpy(&row
.Address
, ua
->Address
.lpSockaddr
, ua
->Address
.iSockaddrLength
);
1988 ret
= pGetUnicastIpAddressEntry( &row
);
1989 ok( ret
== NO_ERROR
, "got %u\n", ret
);
1991 /* test with index */
1992 memset( &row
, 0, sizeof(row
) );
1993 row
.InterfaceIndex
= S(U(*aa
)).IfIndex
;
1994 memcpy(&row
.Address
, ua
->Address
.lpSockaddr
, ua
->Address
.iSockaddrLength
);
1995 ret
= pGetUnicastIpAddressEntry( &row
);
1996 ok( ret
== NO_ERROR
, "got %u\n", ret
);
1997 if (ret
== NO_ERROR
)
1999 ok(row
.InterfaceLuid
.Info
.Reserved
== aa
->Luid
.Info
.Reserved
, "Expected %d, got %d\n",
2000 aa
->Luid
.Info
.Reserved
, row
.InterfaceLuid
.Info
.Reserved
);
2001 ok(row
.InterfaceLuid
.Info
.NetLuidIndex
== aa
->Luid
.Info
.NetLuidIndex
, "Expected %d, got %d\n",
2002 aa
->Luid
.Info
.NetLuidIndex
, row
.InterfaceLuid
.Info
.NetLuidIndex
);
2003 ok(row
.InterfaceLuid
.Info
.IfType
== aa
->Luid
.Info
.IfType
, "Expected %d, got %d\n",
2004 aa
->Luid
.Info
.IfType
, row
.InterfaceLuid
.Info
.IfType
);
2005 ok(row
.InterfaceIndex
== S(U(*aa
)).IfIndex
, "Expected %d, got %d\n",
2006 S(U(*aa
)).IfIndex
, row
.InterfaceIndex
);
2007 ok(row
.PrefixOrigin
== ua
->PrefixOrigin
, "Expected %d, got %d\n",
2008 ua
->PrefixOrigin
, row
.PrefixOrigin
);
2009 ok(row
.SuffixOrigin
== ua
->SuffixOrigin
, "Expected %d, got %d\n",
2010 ua
->SuffixOrigin
, row
.SuffixOrigin
);
2011 ok(row
.ValidLifetime
== ua
->ValidLifetime
, "Expected %d, got %d\n",
2012 ua
->ValidLifetime
, row
.ValidLifetime
);
2013 ok(row
.PreferredLifetime
== ua
->PreferredLifetime
, "Expected %d, got %d\n",
2014 ua
->PreferredLifetime
, row
.PreferredLifetime
);
2015 ok(row
.OnLinkPrefixLength
== ua
->OnLinkPrefixLength
, "Expected %d, got %d\n",
2016 ua
->OnLinkPrefixLength
, row
.OnLinkPrefixLength
);
2017 ok(row
.SkipAsSource
== 0, "Expected 0, got %d\n", row
.SkipAsSource
);
2018 ok(row
.DadState
== ua
->DadState
, "Expected %d, got %d\n", ua
->DadState
, row
.DadState
);
2019 if (row
.Address
.si_family
== AF_INET6
)
2020 ok(row
.ScopeId
.Value
== row
.Address
.Ipv6
.sin6_scope_id
, "Expected %d, got %d\n",
2021 row
.Address
.Ipv6
.sin6_scope_id
, row
.ScopeId
.Value
);
2022 ok(row
.CreationTimeStamp
.QuadPart
, "CreationTimeStamp is 0\n");
2027 HeapFree(GetProcessHeap(), 0, ptr
);
2030 static void test_GetUnicastIpAddressTable(void)
2032 MIB_UNICASTIPADDRESS_TABLE
*table
;
2036 if (!pGetUnicastIpAddressTable
)
2038 win_skip( "GetUnicastIpAddressTable not available\n" );
2042 ret
= pGetUnicastIpAddressTable(AF_UNSPEC
, NULL
);
2043 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
2045 ret
= pGetUnicastIpAddressTable(AF_BAN
, &table
);
2046 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
2048 ret
= pGetUnicastIpAddressTable(AF_INET
, &table
);
2049 ok( ret
== NO_ERROR
, "got %u\n", ret
);
2050 trace("GetUnicastIpAddressTable(AF_INET): NumEntries %u\n", table
->NumEntries
);
2051 pFreeMibTable(table
);
2053 ret
= pGetUnicastIpAddressTable(AF_INET6
, &table
);
2054 ok( ret
== NO_ERROR
, "got %u\n", ret
);
2055 trace("GetUnicastIpAddressTable(AF_INET6): NumEntries %u\n", table
->NumEntries
);
2056 pFreeMibTable(table
);
2058 ret
= pGetUnicastIpAddressTable(AF_UNSPEC
, &table
);
2059 ok( ret
== NO_ERROR
, "got %u\n", ret
);
2060 trace("GetUnicastIpAddressTable(AF_UNSPEC): NumEntries %u\n", table
->NumEntries
);
2061 for (i
= 0; i
< table
->NumEntries
&& winetest_debug
> 1; i
++)
2063 trace("Index %u:\n", i
);
2064 trace("Address.si_family: %u\n", table
->Table
[i
].Address
.si_family
);
2065 trace("InterfaceLuid.Info.Reserved: %u\n", table
->Table
[i
].InterfaceLuid
.Info
.Reserved
);
2066 trace("InterfaceLuid.Info.NetLuidIndex: %u\n", table
->Table
[i
].InterfaceLuid
.Info
.NetLuidIndex
);
2067 trace("InterfaceLuid.Info.IfType: %u\n", table
->Table
[i
].InterfaceLuid
.Info
.IfType
);
2068 trace("InterfaceIndex: %u\n", table
->Table
[i
].InterfaceIndex
);
2069 trace("PrefixOrigin: %u\n", table
->Table
[i
].PrefixOrigin
);
2070 trace("SuffixOrigin: %u\n", table
->Table
[i
].SuffixOrigin
);
2071 trace("ValidLifetime: %u seconds\n", table
->Table
[i
].ValidLifetime
);
2072 trace("PreferredLifetime: %u seconds\n", table
->Table
[i
].PreferredLifetime
);
2073 trace("OnLinkPrefixLength: %u\n", table
->Table
[i
].OnLinkPrefixLength
);
2074 trace("SkipAsSource: %u\n", table
->Table
[i
].SkipAsSource
);
2075 trace("DadState: %u\n", table
->Table
[i
].DadState
);
2076 trace("ScopeId.Value: %u\n", table
->Table
[i
].ScopeId
.Value
);
2077 trace("CreationTimeStamp: %08x%08x\n", table
->Table
[i
].CreationTimeStamp
.HighPart
, table
->Table
[i
].CreationTimeStamp
.LowPart
);
2080 pFreeMibTable(table
);
2083 static void test_ConvertLengthToIpv4Mask(void)
2090 if (!pConvertLengthToIpv4Mask
)
2092 win_skip( "ConvertLengthToIpv4Mask not available\n" );
2096 for (n
= 0; n
<= 32; n
++)
2100 expected
= htonl( ~0u << (32 - n
) );
2104 ret
= pConvertLengthToIpv4Mask( n
, &mask
);
2105 ok( ret
== NO_ERROR
, "ConvertLengthToIpv4Mask returned 0x%08x, expected 0x%08x\n", ret
, NO_ERROR
);
2106 ok( mask
== expected
, "ConvertLengthToIpv4Mask mask value 0x%08x, expected 0x%08x\n", mask
, expected
);
2109 /* Testing for out of range. In this case both mask and return are changed to indicate error. */
2111 ret
= pConvertLengthToIpv4Mask( 33, &mask
);
2112 ok( ret
== ERROR_INVALID_PARAMETER
, "ConvertLengthToIpv4Mask returned 0x%08x, expected 0x%08x\n", ret
, ERROR_INVALID_PARAMETER
);
2113 ok( mask
== INADDR_NONE
, "ConvertLengthToIpv4Mask mask value 0x%08x, expected 0x%08x\n", mask
, INADDR_NONE
);
2116 static void test_GetTcp6Table(void)
2124 win_skip("GetTcp6Table not available\n");
2128 ret
= pGetTcp6Table(NULL
, &size
, FALSE
);
2129 if (ret
== ERROR_NOT_SUPPORTED
)
2131 skip("GetTcp6Table is not supported\n");
2134 ok(ret
== ERROR_INSUFFICIENT_BUFFER
,
2135 "GetTcp6Table(NULL, &size, FALSE) returned %d, expected ERROR_INSUFFICIENT_BUFFER\n", ret
);
2136 if (ret
!= ERROR_INSUFFICIENT_BUFFER
) return;
2138 buf
= HeapAlloc(GetProcessHeap(), 0, size
);
2140 ret
= pGetTcp6Table(buf
, &size
, FALSE
);
2142 "GetTcp6Table(buf, &size, FALSE) returned %d, expected NO_ERROR\n", ret
);
2144 if (ret
== NO_ERROR
&& winetest_debug
> 1)
2147 trace("TCP6 table: %u entries\n", buf
->dwNumEntries
);
2148 for (i
= 0; i
< buf
->dwNumEntries
; i
++)
2150 trace("%u: local %s%%%u:%u remote %s%%%u:%u state %u\n", i
,
2151 ntoa6(&buf
->table
[i
].LocalAddr
), ntohs(buf
->table
[i
].dwLocalScopeId
),
2152 ntohs(buf
->table
[i
].dwLocalPort
), ntoa6(&buf
->table
[i
].RemoteAddr
),
2153 ntohs(buf
->table
[i
].dwRemoteScopeId
), ntohs(buf
->table
[i
].dwRemotePort
),
2154 buf
->table
[i
].State
);
2158 HeapFree(GetProcessHeap(), 0, buf
);
2161 static void test_GetUdp6Table(void)
2166 if (!pGetUdp6Table
) {
2167 win_skip("GetUdp6Table not available\n");
2171 apiReturn
= pGetUdp6Table(NULL
, &dwSize
, FALSE
);
2172 if (apiReturn
== ERROR_NOT_SUPPORTED
) {
2173 skip("GetUdp6Table is not supported\n");
2176 ok(apiReturn
== ERROR_INSUFFICIENT_BUFFER
,
2177 "GetUdp6Table(NULL, &dwSize, FALSE) returned %d, expected ERROR_INSUFFICIENT_BUFFER\n",
2179 if (apiReturn
== ERROR_INSUFFICIENT_BUFFER
) {
2180 PMIB_UDP6TABLE buf
= HeapAlloc(GetProcessHeap(), 0, dwSize
);
2182 apiReturn
= pGetUdp6Table(buf
, &dwSize
, FALSE
);
2183 ok(apiReturn
== NO_ERROR
,
2184 "GetUdp6Table(buf, &dwSize, FALSE) returned %d, expected NO_ERROR\n",
2187 if (apiReturn
== NO_ERROR
&& winetest_debug
> 1)
2190 trace( "UDP6 table: %u entries\n", buf
->dwNumEntries
);
2191 for (i
= 0; i
< buf
->dwNumEntries
; i
++)
2192 trace( "%u: %s%%%u:%u\n",
2193 i
, ntoa6(&buf
->table
[i
].dwLocalAddr
), ntohs(buf
->table
[i
].dwLocalScopeId
), ntohs(buf
->table
[i
].dwLocalPort
) );
2195 HeapFree(GetProcessHeap(), 0, buf
);
2199 static void test_ParseNetworkString(void)
2207 ipv4_address_tests
[] =
2209 {"1.2.3.4", {{{1, 2, 3, 4}}}},
2210 {"1.2.3.4a", {}, ERROR_INVALID_PARAMETER
},
2211 {"1.2.3.0x4a", {}, ERROR_INVALID_PARAMETER
},
2212 {"1.2.3", {}, ERROR_INVALID_PARAMETER
},
2213 {"a1.2.3.4", {}, ERROR_INVALID_PARAMETER
},
2214 {"0xdeadbeef", {}, ERROR_INVALID_PARAMETER
},
2215 {"1.2.3.4:22", {}, ERROR_INVALID_PARAMETER
},
2216 {"::1", {}, ERROR_INVALID_PARAMETER
},
2217 {"winehq.org", {}, ERROR_INVALID_PARAMETER
},
2226 ipv4_service_tests
[] =
2228 {"1.2.3.4:22", {{{1, 2, 3, 4}}}, 22},
2229 {"winehq.org:22", {}, 0, ERROR_INVALID_PARAMETER
},
2230 {"1.2.3.4", {}, 0, ERROR_INVALID_PARAMETER
},
2231 {"1.2.3.4:0", {}, 0, ERROR_INVALID_PARAMETER
},
2232 {"1.2.3.4:65536", {}, 0, ERROR_INVALID_PARAMETER
},
2234 WCHAR wstr
[IP6_ADDRESS_STRING_BUFFER_LENGTH
] = {'1','2','7','.','0','.','0','.','1',':','2','2',0};
2235 NET_ADDRESS_INFO info
;
2241 if (!pParseNetworkString
)
2243 win_skip("ParseNetworkString not available\n");
2247 ret
= pParseNetworkString(wstr
, -1, NULL
, NULL
, NULL
);
2248 ok(ret
== ERROR_SUCCESS
, "expected success, got %d\n", ret
);
2250 ret
= pParseNetworkString(NULL
, NET_STRING_IPV4_SERVICE
, &info
, NULL
, NULL
);
2251 ok(ret
== ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER, got %d\n", ret
);
2253 for (i
= 0; i
< ARRAY_SIZE(ipv4_address_tests
); i
++)
2255 MultiByteToWideChar(CP_ACP
, 0, ipv4_address_tests
[i
].str
, sizeof(ipv4_address_tests
[i
].str
),
2256 wstr
, ARRAY_SIZE(wstr
));
2257 memset(&info
, 0x99, sizeof(info
));
2261 ret
= pParseNetworkString(wstr
, NET_STRING_IPV4_ADDRESS
, &info
, &port
, &prefix_len
);
2263 ok(ret
== ipv4_address_tests
[i
].ret
,
2264 "%s gave error %d\n", ipv4_address_tests
[i
].str
, ret
);
2265 ok(info
.Format
== ret
? NET_ADDRESS_FORMAT_UNSPECIFIED
: NET_ADDRESS_IPV4
,
2266 "%s gave format %d\n", ipv4_address_tests
[i
].str
, info
.Format
);
2267 ok(info
.Ipv4Address
.sin_addr
.S_un
.S_addr
== (ret
? 0x99999999 : ipv4_address_tests
[i
].addr
.S_un
.S_addr
),
2268 "%s gave address %d.%d.%d.%d\n", ipv4_address_tests
[i
].str
,
2269 info
.Ipv4Address
.sin_addr
.S_un
.S_un_b
.s_b1
, info
.Ipv4Address
.sin_addr
.S_un
.S_un_b
.s_b2
,
2270 info
.Ipv4Address
.sin_addr
.S_un
.S_un_b
.s_b3
, info
.Ipv4Address
.sin_addr
.S_un
.S_un_b
.s_b4
);
2271 ok(info
.Ipv4Address
.sin_port
== (ret
? 0x9999 : 0),
2272 "%s gave port %d\n", ipv4_service_tests
[i
].str
, ntohs(info
.Ipv4Address
.sin_port
));
2273 ok(port
== (ret
? 0x9999 : 0),
2274 "%s gave port %d\n", ipv4_service_tests
[i
].str
, port
);
2275 ok(prefix_len
== (ret
? 0x99 : 255),
2276 "%s gave prefix length %d\n", ipv4_service_tests
[i
].str
, prefix_len
);
2279 for (i
= 0; i
< ARRAY_SIZE(ipv4_service_tests
); i
++)
2281 MultiByteToWideChar(CP_ACP
, 0, ipv4_service_tests
[i
].str
, sizeof(ipv4_service_tests
[i
].str
),
2282 wstr
, ARRAY_SIZE(wstr
));
2283 memset(&info
, 0x99, sizeof(info
));
2287 ret
= pParseNetworkString(wstr
, NET_STRING_IPV4_SERVICE
, &info
, &port
, &prefix_len
);
2289 ok(ret
== ipv4_service_tests
[i
].ret
,
2290 "%s gave error %d\n", ipv4_service_tests
[i
].str
, ret
);
2291 ok(info
.Format
== ret
? NET_ADDRESS_FORMAT_UNSPECIFIED
: NET_ADDRESS_IPV4
,
2292 "%s gave format %d\n", ipv4_address_tests
[i
].str
, info
.Format
);
2293 ok(info
.Ipv4Address
.sin_addr
.S_un
.S_addr
== (ret
? 0x99999999 : ipv4_service_tests
[i
].addr
.S_un
.S_addr
),
2294 "%s gave address %d.%d.%d.%d\n", ipv4_service_tests
[i
].str
,
2295 info
.Ipv4Address
.sin_addr
.S_un
.S_un_b
.s_b1
, info
.Ipv4Address
.sin_addr
.S_un
.S_un_b
.s_b2
,
2296 info
.Ipv4Address
.sin_addr
.S_un
.S_un_b
.s_b3
, info
.Ipv4Address
.sin_addr
.S_un
.S_un_b
.s_b4
);
2297 ok(ntohs(info
.Ipv4Address
.sin_port
) == (ret
? 0x9999 : ipv4_service_tests
[i
].port
),
2298 "%s gave port %d\n", ipv4_service_tests
[i
].str
, ntohs(info
.Ipv4Address
.sin_port
));
2299 ok(port
== (ret
? 0x9999 : ipv4_service_tests
[i
].port
),
2300 "%s gave port %d\n", ipv4_service_tests
[i
].str
, port
);
2301 ok(prefix_len
== (ret
? 0x99 : 255),
2302 "%s gave prefix length %d\n", ipv4_service_tests
[i
].str
, prefix_len
);
2306 static void WINAPI
test_ipaddtess_change_callback(PVOID context
, PMIB_UNICASTIPADDRESS_ROW row
,
2307 MIB_NOTIFICATION_TYPE notification_type
)
2309 BOOL
*callback_called
= context
;
2311 *callback_called
= TRUE
;
2313 ok(notification_type
== MibInitialNotification
, "Unexpected notification_type %#x.\n",
2315 ok(!row
, "Unexpected row %p.\n", row
);
2318 static void test_NotifyUnicastIpAddressChange(void)
2320 BOOL callback_called
;
2324 if (!pNotifyUnicastIpAddressChange
)
2326 win_skip("NotifyUnicastIpAddressChange not available.\n");
2330 callback_called
= FALSE
;
2331 ret
= pNotifyUnicastIpAddressChange(AF_INET
, test_ipaddtess_change_callback
,
2332 &callback_called
, TRUE
, &handle
);
2333 ok(ret
== NO_ERROR
, "Unexpected ret %#x.\n", ret
);
2334 ok(callback_called
, "Callback was not called.\n");
2336 ret
= pCancelMibChangeNotify2(handle
);
2337 ok(ret
== NO_ERROR
, "Unexpected ret %#x.\n", ret
);
2338 ok(!CloseHandle(handle
), "CloseHandle() succeeded.\n");
2341 START_TEST(iphlpapi
)
2348 testWin98OnlyFunctions();
2349 testWinNT4Functions();
2351 /* run testGetXXXX in two threads at once to make sure we don't crash in that case */
2352 thread
= CreateThread(NULL
, 0, testWin98Functions
, NULL
, 0, NULL
);
2353 testWin98Functions(NULL
);
2354 WaitForSingleObject(thread
, INFINITE
);
2356 testWin2KFunctions();
2357 test_GetAdaptersAddresses();
2358 test_GetExtendedTcpTable();
2359 test_GetExtendedUdpTable();
2360 test_AllocateAndGetTcpExTableFromStack();
2361 test_CreateSortedAddressPairs();
2362 test_interface_identifier_conversion();
2365 test_GetIfTable2Ex();
2366 test_GetUnicastIpAddressEntry();
2367 test_GetUnicastIpAddressTable();
2368 test_ConvertLengthToIpv4Mask();
2369 test_GetTcp6Table();
2370 test_GetUdp6Table();
2371 test_ParseNetworkString();
2372 test_NotifyUnicastIpAddressChange();