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.
45 #include "wine/test.h"
49 #define ICMP_MINLEN 8 /* copied from dlls/iphlpapi/ip_icmp.h file */
51 static HMODULE hLibrary
= NULL
;
53 static DWORD (WINAPI
*pAllocateAndGetTcpExTableFromStack
)(void**,BOOL
,HANDLE
,DWORD
,DWORD
);
54 static DWORD (WINAPI
*pGetNumberOfInterfaces
)(PDWORD
);
55 static DWORD (WINAPI
*pGetIpAddrTable
)(PMIB_IPADDRTABLE
,PULONG
,BOOL
);
56 static DWORD (WINAPI
*pGetIfEntry
)(PMIB_IFROW
);
57 static DWORD (WINAPI
*pGetIfEntry2
)(PMIB_IF_ROW2
);
58 static DWORD (WINAPI
*pGetFriendlyIfIndex
)(DWORD
);
59 static DWORD (WINAPI
*pGetIfTable
)(PMIB_IFTABLE
,PULONG
,BOOL
);
60 static DWORD (WINAPI
*pGetIfTable2
)(PMIB_IF_TABLE2
*);
61 static DWORD (WINAPI
*pGetIpForwardTable
)(PMIB_IPFORWARDTABLE
,PULONG
,BOOL
);
62 static DWORD (WINAPI
*pGetIpNetTable
)(PMIB_IPNETTABLE
,PULONG
,BOOL
);
63 static DWORD (WINAPI
*pGetInterfaceInfo
)(PIP_INTERFACE_INFO
,PULONG
);
64 static DWORD (WINAPI
*pGetAdaptersInfo
)(PIP_ADAPTER_INFO
,PULONG
);
65 static DWORD (WINAPI
*pGetNetworkParams
)(PFIXED_INFO
,PULONG
);
66 static DWORD (WINAPI
*pGetIcmpStatistics
)(PMIB_ICMP
);
67 static DWORD (WINAPI
*pGetIpStatistics
)(PMIB_IPSTATS
);
68 static DWORD (WINAPI
*pGetTcpStatistics
)(PMIB_TCPSTATS
);
69 static DWORD (WINAPI
*pGetUdpStatistics
)(PMIB_UDPSTATS
);
70 static DWORD (WINAPI
*pGetIcmpStatisticsEx
)(PMIB_ICMP_EX
,DWORD
);
71 static DWORD (WINAPI
*pGetIpStatisticsEx
)(PMIB_IPSTATS
,DWORD
);
72 static DWORD (WINAPI
*pGetTcpStatisticsEx
)(PMIB_TCPSTATS
,DWORD
);
73 static DWORD (WINAPI
*pGetUdpStatisticsEx
)(PMIB_UDPSTATS
,DWORD
);
74 static DWORD (WINAPI
*pGetTcpTable
)(PMIB_TCPTABLE
,PDWORD
,BOOL
);
75 static DWORD (WINAPI
*pGetUdpTable
)(PMIB_UDPTABLE
,PDWORD
,BOOL
);
76 static DWORD (WINAPI
*pGetPerAdapterInfo
)(ULONG
,PIP_PER_ADAPTER_INFO
,PULONG
);
77 static DWORD (WINAPI
*pGetAdaptersAddresses
)(ULONG
,ULONG
,PVOID
,PIP_ADAPTER_ADDRESSES
,PULONG
);
78 static DWORD (WINAPI
*pGetUnicastIpAddressEntry
)(MIB_UNICASTIPADDRESS_ROW
*);
79 static DWORD (WINAPI
*pGetUnicastIpAddressTable
)(ADDRESS_FAMILY
,MIB_UNICASTIPADDRESS_TABLE
**);
80 static DWORD (WINAPI
*pNotifyAddrChange
)(PHANDLE
,LPOVERLAPPED
);
81 static BOOL (WINAPI
*pCancelIPChangeNotify
)(LPOVERLAPPED
);
82 static DWORD (WINAPI
*pGetExtendedTcpTable
)(PVOID
,PDWORD
,BOOL
,ULONG
,TCP_TABLE_CLASS
,ULONG
);
83 static DWORD (WINAPI
*pGetExtendedUdpTable
)(PVOID
,PDWORD
,BOOL
,ULONG
,UDP_TABLE_CLASS
,ULONG
);
84 static DWORD (WINAPI
*pSetTcpEntry
)(PMIB_TCPROW
);
85 static HANDLE(WINAPI
*pIcmpCreateFile
)(VOID
);
86 static DWORD (WINAPI
*pIcmpSendEcho
)(HANDLE
,IPAddr
,LPVOID
,WORD
,PIP_OPTION_INFORMATION
,LPVOID
,DWORD
,DWORD
);
87 static DWORD (WINAPI
*pCreateSortedAddressPairs
)(const PSOCKADDR_IN6
,ULONG
,const PSOCKADDR_IN6
,ULONG
,ULONG
,
88 PSOCKADDR_IN6_PAIR
*,ULONG
*);
89 static void (WINAPI
*pFreeMibTable
)(void*);
90 static DWORD (WINAPI
*pConvertInterfaceGuidToLuid
)(const GUID
*,NET_LUID
*);
91 static DWORD (WINAPI
*pConvertInterfaceIndexToLuid
)(NET_IFINDEX
,NET_LUID
*);
92 static DWORD (WINAPI
*pConvertInterfaceLuidToGuid
)(const NET_LUID
*,GUID
*);
93 static DWORD (WINAPI
*pConvertInterfaceLuidToIndex
)(const NET_LUID
*,NET_IFINDEX
*);
94 static DWORD (WINAPI
*pConvertInterfaceLuidToNameW
)(const NET_LUID
*,WCHAR
*,SIZE_T
);
95 static DWORD (WINAPI
*pConvertInterfaceLuidToNameA
)(const NET_LUID
*,char*,SIZE_T
);
96 static DWORD (WINAPI
*pConvertInterfaceNameToLuidA
)(const char*,NET_LUID
*);
97 static DWORD (WINAPI
*pConvertInterfaceNameToLuidW
)(const WCHAR
*,NET_LUID
*);
99 static NET_IFINDEX (WINAPI
*pif_nametoindex
)(const char*);
101 static void loadIPHlpApi(void)
103 hLibrary
= LoadLibraryA("iphlpapi.dll");
105 pAllocateAndGetTcpExTableFromStack
= (void *)GetProcAddress(hLibrary
, "AllocateAndGetTcpExTableFromStack");
106 pGetNumberOfInterfaces
= (void *)GetProcAddress(hLibrary
, "GetNumberOfInterfaces");
107 pGetIpAddrTable
= (void *)GetProcAddress(hLibrary
, "GetIpAddrTable");
108 pGetIfEntry
= (void *)GetProcAddress(hLibrary
, "GetIfEntry");
109 pGetIfEntry2
= (void *)GetProcAddress(hLibrary
, "GetIfEntry2");
110 pGetFriendlyIfIndex
= (void *)GetProcAddress(hLibrary
, "GetFriendlyIfIndex");
111 pGetIfTable
= (void *)GetProcAddress(hLibrary
, "GetIfTable");
112 pGetIfTable2
= (void *)GetProcAddress(hLibrary
, "GetIfTable2");
113 pGetIpForwardTable
= (void *)GetProcAddress(hLibrary
, "GetIpForwardTable");
114 pGetIpNetTable
= (void *)GetProcAddress(hLibrary
, "GetIpNetTable");
115 pGetInterfaceInfo
= (void *)GetProcAddress(hLibrary
, "GetInterfaceInfo");
116 pGetAdaptersInfo
= (void *)GetProcAddress(hLibrary
, "GetAdaptersInfo");
117 pGetNetworkParams
= (void *)GetProcAddress(hLibrary
, "GetNetworkParams");
118 pGetIcmpStatistics
= (void *)GetProcAddress(hLibrary
, "GetIcmpStatistics");
119 pGetIpStatistics
= (void *)GetProcAddress(hLibrary
, "GetIpStatistics");
120 pGetTcpStatistics
= (void *)GetProcAddress(hLibrary
, "GetTcpStatistics");
121 pGetUdpStatistics
= (void *)GetProcAddress(hLibrary
, "GetUdpStatistics");
122 pGetIcmpStatisticsEx
= (void *)GetProcAddress(hLibrary
, "GetIcmpStatisticsEx");
123 pGetIpStatisticsEx
= (void *)GetProcAddress(hLibrary
, "GetIpStatisticsEx");
124 pGetTcpStatisticsEx
= (void *)GetProcAddress(hLibrary
, "GetTcpStatisticsEx");
125 pGetUdpStatisticsEx
= (void *)GetProcAddress(hLibrary
, "GetUdpStatisticsEx");
126 pGetTcpTable
= (void *)GetProcAddress(hLibrary
, "GetTcpTable");
127 pGetUdpTable
= (void *)GetProcAddress(hLibrary
, "GetUdpTable");
128 pGetPerAdapterInfo
= (void *)GetProcAddress(hLibrary
, "GetPerAdapterInfo");
129 pGetAdaptersAddresses
= (void *)GetProcAddress(hLibrary
, "GetAdaptersAddresses");
130 pGetUnicastIpAddressEntry
= (void *)GetProcAddress(hLibrary
, "GetUnicastIpAddressEntry");
131 pGetUnicastIpAddressTable
= (void *)GetProcAddress(hLibrary
, "GetUnicastIpAddressTable");
132 pNotifyAddrChange
= (void *)GetProcAddress(hLibrary
, "NotifyAddrChange");
133 pCancelIPChangeNotify
= (void *)GetProcAddress(hLibrary
, "CancelIPChangeNotify");
134 pGetExtendedTcpTable
= (void *)GetProcAddress(hLibrary
, "GetExtendedTcpTable");
135 pGetExtendedUdpTable
= (void *)GetProcAddress(hLibrary
, "GetExtendedUdpTable");
136 pSetTcpEntry
= (void *)GetProcAddress(hLibrary
, "SetTcpEntry");
137 pIcmpCreateFile
= (void *)GetProcAddress(hLibrary
, "IcmpCreateFile");
138 pIcmpSendEcho
= (void *)GetProcAddress(hLibrary
, "IcmpSendEcho");
139 pCreateSortedAddressPairs
= (void *)GetProcAddress(hLibrary
, "CreateSortedAddressPairs");
140 pFreeMibTable
= (void *)GetProcAddress(hLibrary
, "FreeMibTable");
141 pConvertInterfaceGuidToLuid
= (void *)GetProcAddress(hLibrary
, "ConvertInterfaceGuidToLuid");
142 pConvertInterfaceIndexToLuid
= (void *)GetProcAddress(hLibrary
, "ConvertInterfaceIndexToLuid");
143 pConvertInterfaceLuidToGuid
= (void *)GetProcAddress(hLibrary
, "ConvertInterfaceLuidToGuid");
144 pConvertInterfaceLuidToIndex
= (void *)GetProcAddress(hLibrary
, "ConvertInterfaceLuidToIndex");
145 pConvertInterfaceLuidToNameA
= (void *)GetProcAddress(hLibrary
, "ConvertInterfaceLuidToNameA");
146 pConvertInterfaceLuidToNameW
= (void *)GetProcAddress(hLibrary
, "ConvertInterfaceLuidToNameW");
147 pConvertInterfaceNameToLuidA
= (void *)GetProcAddress(hLibrary
, "ConvertInterfaceNameToLuidA");
148 pConvertInterfaceNameToLuidW
= (void *)GetProcAddress(hLibrary
, "ConvertInterfaceNameToLuidW");
149 pif_nametoindex
= (void *)GetProcAddress(hLibrary
, "if_nametoindex");
153 static void freeIPHlpApi(void)
155 FreeLibrary(hLibrary
);
158 /* replacement for inet_ntoa */
159 static const char *ntoa( DWORD ip
)
161 static char buffer
[40];
164 sprintf( buffer
, "%u.%u.%u.%u", (ip
>> 24) & 0xff, (ip
>> 16) & 0xff, (ip
>> 8) & 0xff, ip
& 0xff );
168 static inline const char* debugstr_longlong(ULONGLONG ll
)
170 static char string
[17];
171 if (sizeof(ll
) > sizeof(unsigned long) && ll
>> 32)
172 sprintf(string
, "%lx%08lx", (unsigned long)(ll
>> 32), (unsigned long)ll
);
174 sprintf(string
, "%lx", (unsigned long)ll
);
179 still-to-be-tested 98-only functions:
180 GetUniDirectionalAdapterInfo
182 static void testWin98OnlyFunctions(void)
186 static void testGetNumberOfInterfaces(void)
188 if (pGetNumberOfInterfaces
) {
189 DWORD apiReturn
, numInterfaces
;
191 /* Crashes on Vista */
193 apiReturn
= pGetNumberOfInterfaces(NULL
);
194 if (apiReturn
== ERROR_NOT_SUPPORTED
)
196 ok(apiReturn
== ERROR_INVALID_PARAMETER
,
197 "GetNumberOfInterfaces(NULL) returned %d, expected ERROR_INVALID_PARAMETER\n",
201 apiReturn
= pGetNumberOfInterfaces(&numInterfaces
);
202 if (apiReturn
== ERROR_NOT_SUPPORTED
) {
203 skip("GetNumberOfInterfaces is not supported\n");
206 ok(apiReturn
== NO_ERROR
,
207 "GetNumberOfInterfaces returned %d, expected 0\n", apiReturn
);
211 static void testGetIfEntry(DWORD index
)
217 memset(&row
, 0, sizeof(row
));
218 apiReturn
= pGetIfEntry(NULL
);
219 if (apiReturn
== ERROR_NOT_SUPPORTED
) {
220 skip("GetIfEntry is not supported\n");
223 ok(apiReturn
== ERROR_INVALID_PARAMETER
,
224 "GetIfEntry(NULL) returned %d, expected ERROR_INVALID_PARAMETER\n",
226 row
.dwIndex
= -1; /* hope that's always bogus! */
227 apiReturn
= pGetIfEntry(&row
);
228 ok(apiReturn
== ERROR_INVALID_DATA
||
229 apiReturn
== ERROR_FILE_NOT_FOUND
/* Vista */,
230 "GetIfEntry(bogus row) returned %d, expected ERROR_INVALID_DATA or ERROR_FILE_NOT_FOUND\n",
233 apiReturn
= pGetIfEntry(&row
);
234 ok(apiReturn
== NO_ERROR
,
235 "GetIfEntry returned %d, expected NO_ERROR\n", apiReturn
);
239 static void testGetIpAddrTable(void)
241 if (pGetIpAddrTable
) {
245 apiReturn
= pGetIpAddrTable(NULL
, NULL
, FALSE
);
246 if (apiReturn
== ERROR_NOT_SUPPORTED
) {
247 skip("GetIpAddrTable is not supported\n");
250 ok(apiReturn
== ERROR_INVALID_PARAMETER
,
251 "GetIpAddrTable(NULL, NULL, FALSE) returned %d, expected ERROR_INVALID_PARAMETER\n",
253 apiReturn
= pGetIpAddrTable(NULL
, &dwSize
, FALSE
);
254 ok(apiReturn
== ERROR_INSUFFICIENT_BUFFER
,
255 "GetIpAddrTable(NULL, &dwSize, FALSE) returned %d, expected ERROR_INSUFFICIENT_BUFFER\n",
257 if (apiReturn
== ERROR_INSUFFICIENT_BUFFER
) {
258 PMIB_IPADDRTABLE buf
= HeapAlloc(GetProcessHeap(), 0, dwSize
);
260 apiReturn
= pGetIpAddrTable(buf
, &dwSize
, FALSE
);
261 ok(apiReturn
== NO_ERROR
,
262 "GetIpAddrTable(buf, &dwSize, FALSE) returned %d, expected NO_ERROR\n",
264 if (apiReturn
== NO_ERROR
&& buf
->dwNumEntries
)
267 testGetIfEntry(buf
->table
[0].dwIndex
);
268 for (i
= 0; i
< buf
->dwNumEntries
; i
++)
270 ok (buf
->table
[i
].wType
!= 0, "Test[%d]: expected wType > 0\n", i
);
271 trace("Entry[%d]: addr %s, dwIndex %u, wType 0x%x\n", i
,
272 ntoa(buf
->table
[i
].dwAddr
), buf
->table
[i
].dwIndex
, buf
->table
[i
].wType
);
273 /* loopback must never be the first when more than one interface is found */
274 if (buf
->table
[i
].dwAddr
== htonl(INADDR_LOOPBACK
))
275 ok(buf
->dwNumEntries
== 1 || i
, "Loopback interface in wrong first position\n");
278 HeapFree(GetProcessHeap(), 0, buf
);
283 static void testGetIfTable(void)
289 apiReturn
= pGetIfTable(NULL
, NULL
, FALSE
);
290 if (apiReturn
== ERROR_NOT_SUPPORTED
) {
291 skip("GetIfTable is not supported\n");
294 ok(apiReturn
== ERROR_INVALID_PARAMETER
,
295 "GetIfTable(NULL, NULL, FALSE) returned %d, expected ERROR_INVALID_PARAMETER\n",
297 apiReturn
= pGetIfTable(NULL
, &dwSize
, FALSE
);
298 ok(apiReturn
== ERROR_INSUFFICIENT_BUFFER
,
299 "GetIfTable(NULL, &dwSize, FALSE) returned %d, expected ERROR_INSUFFICIENT_BUFFER\n",
301 if (apiReturn
== ERROR_INSUFFICIENT_BUFFER
) {
302 PMIB_IFTABLE buf
= HeapAlloc(GetProcessHeap(), 0, dwSize
);
304 apiReturn
= pGetIfTable(buf
, &dwSize
, FALSE
);
305 ok(apiReturn
== NO_ERROR
,
306 "GetIfTable(buf, &dwSize, FALSE) returned %d, expected NO_ERROR\n\n",
309 if (apiReturn
== NO_ERROR
&& winetest_debug
> 1)
312 char name
[MAX_INTERFACE_NAME_LEN
];
314 trace( "interface table: %u entries\n", buf
->dwNumEntries
);
315 for (i
= 0; i
< buf
->dwNumEntries
; i
++)
317 MIB_IFROW
*row
= &buf
->table
[i
];
318 WideCharToMultiByte( CP_ACP
, 0, row
->wszName
, -1, name
, MAX_INTERFACE_NAME_LEN
, NULL
, NULL
);
319 trace( "%u: '%s' type %u mtu %u speed %u phys",
320 row
->dwIndex
, name
, row
->dwType
, row
->dwMtu
, row
->dwSpeed
);
321 for (j
= 0; j
< row
->dwPhysAddrLen
; j
++)
322 printf( " %02x", row
->bPhysAddr
[j
] );
324 trace( " in: bytes %u upkts %u nupkts %u disc %u err %u unk %u\n",
325 row
->dwInOctets
, row
->dwInUcastPkts
, row
->dwInNUcastPkts
,
326 row
->dwInDiscards
, row
->dwInErrors
, row
->dwInUnknownProtos
);
327 trace( " out: bytes %u upkts %u nupkts %u disc %u err %u\n",
328 row
->dwOutOctets
, row
->dwOutUcastPkts
, row
->dwOutNUcastPkts
,
329 row
->dwOutDiscards
, row
->dwOutErrors
);
332 HeapFree(GetProcessHeap(), 0, buf
);
337 static void testGetIpForwardTable(void)
339 if (pGetIpForwardTable
) {
343 apiReturn
= pGetIpForwardTable(NULL
, NULL
, FALSE
);
344 if (apiReturn
== ERROR_NOT_SUPPORTED
) {
345 skip("GetIpForwardTable is not supported\n");
348 ok(apiReturn
== ERROR_INVALID_PARAMETER
,
349 "GetIpForwardTable(NULL, NULL, FALSE) returned %d, expected ERROR_INVALID_PARAMETER\n",
351 apiReturn
= pGetIpForwardTable(NULL
, &dwSize
, FALSE
);
352 ok(apiReturn
== ERROR_INSUFFICIENT_BUFFER
,
353 "GetIpForwardTable(NULL, &dwSize, FALSE) returned %d, expected ERROR_INSUFFICIENT_BUFFER\n",
355 if (apiReturn
== ERROR_INSUFFICIENT_BUFFER
) {
356 PMIB_IPFORWARDTABLE buf
= HeapAlloc(GetProcessHeap(), 0, dwSize
);
358 apiReturn
= pGetIpForwardTable(buf
, &dwSize
, FALSE
);
359 ok(apiReturn
== NO_ERROR
,
360 "GetIpForwardTable(buf, &dwSize, FALSE) returned %d, expected NO_ERROR\n",
363 if (apiReturn
== NO_ERROR
)
367 trace( "IP forward table: %u entries\n", buf
->dwNumEntries
);
368 for (i
= 0; i
< buf
->dwNumEntries
; i
++)
372 if (!U1(buf
->table
[i
]).dwForwardDest
) /* Default route */
375 ok (U1(buf
->table
[i
]).dwForwardProto
== MIB_IPPROTO_NETMGMT
,
376 "Unexpected dwForwardProto %d\n", U1(buf
->table
[i
]).dwForwardProto
);
377 ok (U1(buf
->table
[i
]).dwForwardType
== MIB_IPROUTE_TYPE_INDIRECT
,
378 "Unexpected dwForwardType %d\n", U1(buf
->table
[i
]).dwForwardType
);
382 /* In general we should get MIB_IPPROTO_LOCAL but does not work
383 * for Vista, 2008 and 7. */
384 ok (U1(buf
->table
[i
]).dwForwardProto
== MIB_IPPROTO_LOCAL
||
385 broken(U1(buf
->table
[i
]).dwForwardProto
== MIB_IPPROTO_NETMGMT
),
386 "Unexpected dwForwardProto %d\n", U1(buf
->table
[i
]).dwForwardProto
);
387 /* The forward type varies depending on the address and gateway
388 * value so it is not worth testing in this case. */
391 sprintf( buffer
, "dest %s", ntoa( buf
->table
[i
].dwForwardDest
));
392 sprintf( buffer
+ strlen(buffer
), " mask %s", ntoa( buf
->table
[i
].dwForwardMask
));
393 trace( "%u: %s gw %s if %u type %u proto %u\n", i
, buffer
,
394 ntoa( buf
->table
[i
].dwForwardNextHop
), buf
->table
[i
].dwForwardIfIndex
,
395 U1(buf
->table
[i
]).dwForwardType
, U1(buf
->table
[i
]).dwForwardProto
);
398 HeapFree(GetProcessHeap(), 0, buf
);
403 static void testGetIpNetTable(void)
405 if (pGetIpNetTable
) {
409 apiReturn
= pGetIpNetTable(NULL
, NULL
, FALSE
);
410 if (apiReturn
== ERROR_NOT_SUPPORTED
) {
411 skip("GetIpNetTable is not supported\n");
414 ok(apiReturn
== ERROR_INVALID_PARAMETER
,
415 "GetIpNetTable(NULL, NULL, FALSE) returned %d, expected ERROR_INVALID_PARAMETER\n",
417 apiReturn
= pGetIpNetTable(NULL
, &dwSize
, FALSE
);
418 ok(apiReturn
== ERROR_NO_DATA
|| apiReturn
== ERROR_INSUFFICIENT_BUFFER
,
419 "GetIpNetTable(NULL, &dwSize, FALSE) returned %d, expected ERROR_NO_DATA or ERROR_INSUFFICIENT_BUFFER\n",
421 if (apiReturn
== ERROR_NO_DATA
)
422 ; /* empty ARP table's okay */
423 else if (apiReturn
== ERROR_INSUFFICIENT_BUFFER
) {
424 PMIB_IPNETTABLE buf
= HeapAlloc(GetProcessHeap(), 0, dwSize
);
426 apiReturn
= pGetIpNetTable(buf
, &dwSize
, FALSE
);
427 ok(apiReturn
== NO_ERROR
||
428 apiReturn
== ERROR_NO_DATA
, /* empty ARP table's okay */
429 "GetIpNetTable(buf, &dwSize, FALSE) returned %d, expected NO_ERROR\n",
432 if (apiReturn
== NO_ERROR
&& winetest_debug
> 1)
436 trace( "IP net table: %u entries\n", buf
->dwNumEntries
);
437 for (i
= 0; i
< buf
->dwNumEntries
; i
++)
439 trace( "%u: idx %u type %u addr %s phys",
440 i
, buf
->table
[i
].dwIndex
, U(buf
->table
[i
]).dwType
, ntoa( buf
->table
[i
].dwAddr
));
441 for (j
= 0; j
< buf
->table
[i
].dwPhysAddrLen
; j
++)
442 printf( " %02x", buf
->table
[i
].bPhysAddr
[j
] );
446 HeapFree(GetProcessHeap(), 0, buf
);
451 static void testGetIcmpStatistics(void)
453 if (pGetIcmpStatistics
) {
457 /* Crashes on Vista */
459 apiReturn
= pGetIcmpStatistics(NULL
);
460 if (apiReturn
== ERROR_NOT_SUPPORTED
)
462 ok(apiReturn
== ERROR_INVALID_PARAMETER
,
463 "GetIcmpStatistics(NULL) returned %d, expected ERROR_INVALID_PARAMETER\n",
467 apiReturn
= pGetIcmpStatistics(&stats
);
468 if (apiReturn
== ERROR_NOT_SUPPORTED
)
470 skip("GetIcmpStatistics is not supported\n");
473 ok(apiReturn
== NO_ERROR
,
474 "GetIcmpStatistics returned %d, expected NO_ERROR\n", apiReturn
);
475 if (apiReturn
== NO_ERROR
&& winetest_debug
> 1)
477 trace( "ICMP stats: %8s %8s\n", "in", "out" );
478 trace( " dwMsgs: %8u %8u\n", stats
.stats
.icmpInStats
.dwMsgs
, stats
.stats
.icmpOutStats
.dwMsgs
);
479 trace( " dwErrors: %8u %8u\n", stats
.stats
.icmpInStats
.dwErrors
, stats
.stats
.icmpOutStats
.dwErrors
);
480 trace( " dwDestUnreachs: %8u %8u\n", stats
.stats
.icmpInStats
.dwDestUnreachs
, stats
.stats
.icmpOutStats
.dwDestUnreachs
);
481 trace( " dwTimeExcds: %8u %8u\n", stats
.stats
.icmpInStats
.dwTimeExcds
, stats
.stats
.icmpOutStats
.dwTimeExcds
);
482 trace( " dwParmProbs: %8u %8u\n", stats
.stats
.icmpInStats
.dwParmProbs
, stats
.stats
.icmpOutStats
.dwParmProbs
);
483 trace( " dwSrcQuenchs: %8u %8u\n", stats
.stats
.icmpInStats
.dwSrcQuenchs
, stats
.stats
.icmpOutStats
.dwSrcQuenchs
);
484 trace( " dwRedirects: %8u %8u\n", stats
.stats
.icmpInStats
.dwRedirects
, stats
.stats
.icmpOutStats
.dwRedirects
);
485 trace( " dwEchos: %8u %8u\n", stats
.stats
.icmpInStats
.dwEchos
, stats
.stats
.icmpOutStats
.dwEchos
);
486 trace( " dwEchoReps: %8u %8u\n", stats
.stats
.icmpInStats
.dwEchoReps
, stats
.stats
.icmpOutStats
.dwEchoReps
);
487 trace( " dwTimestamps: %8u %8u\n", stats
.stats
.icmpInStats
.dwTimestamps
, stats
.stats
.icmpOutStats
.dwTimestamps
);
488 trace( " dwTimestampReps: %8u %8u\n", stats
.stats
.icmpInStats
.dwTimestampReps
, stats
.stats
.icmpOutStats
.dwTimestampReps
);
489 trace( " dwAddrMasks: %8u %8u\n", stats
.stats
.icmpInStats
.dwAddrMasks
, stats
.stats
.icmpOutStats
.dwAddrMasks
);
490 trace( " dwAddrMaskReps: %8u %8u\n", stats
.stats
.icmpInStats
.dwAddrMaskReps
, stats
.stats
.icmpOutStats
.dwAddrMaskReps
);
495 static void testGetIpStatistics(void)
497 if (pGetIpStatistics
) {
501 apiReturn
= pGetIpStatistics(NULL
);
502 if (apiReturn
== ERROR_NOT_SUPPORTED
) {
503 skip("GetIpStatistics is not supported\n");
506 ok(apiReturn
== ERROR_INVALID_PARAMETER
,
507 "GetIpStatistics(NULL) returned %d, expected ERROR_INVALID_PARAMETER\n",
509 apiReturn
= pGetIpStatistics(&stats
);
510 ok(apiReturn
== NO_ERROR
,
511 "GetIpStatistics returned %d, expected NO_ERROR\n", apiReturn
);
512 if (apiReturn
== NO_ERROR
&& winetest_debug
> 1)
514 trace( "IP stats:\n" );
515 trace( " dwForwarding: %u\n", U(stats
).dwForwarding
);
516 trace( " dwDefaultTTL: %u\n", stats
.dwDefaultTTL
);
517 trace( " dwInReceives: %u\n", stats
.dwInReceives
);
518 trace( " dwInHdrErrors: %u\n", stats
.dwInHdrErrors
);
519 trace( " dwInAddrErrors: %u\n", stats
.dwInAddrErrors
);
520 trace( " dwForwDatagrams: %u\n", stats
.dwForwDatagrams
);
521 trace( " dwInUnknownProtos: %u\n", stats
.dwInUnknownProtos
);
522 trace( " dwInDiscards: %u\n", stats
.dwInDiscards
);
523 trace( " dwInDelivers: %u\n", stats
.dwInDelivers
);
524 trace( " dwOutRequests: %u\n", stats
.dwOutRequests
);
525 trace( " dwRoutingDiscards: %u\n", stats
.dwRoutingDiscards
);
526 trace( " dwOutDiscards: %u\n", stats
.dwOutDiscards
);
527 trace( " dwOutNoRoutes: %u\n", stats
.dwOutNoRoutes
);
528 trace( " dwReasmTimeout: %u\n", stats
.dwReasmTimeout
);
529 trace( " dwReasmReqds: %u\n", stats
.dwReasmReqds
);
530 trace( " dwReasmOks: %u\n", stats
.dwReasmOks
);
531 trace( " dwReasmFails: %u\n", stats
.dwReasmFails
);
532 trace( " dwFragOks: %u\n", stats
.dwFragOks
);
533 trace( " dwFragFails: %u\n", stats
.dwFragFails
);
534 trace( " dwFragCreates: %u\n", stats
.dwFragCreates
);
535 trace( " dwNumIf: %u\n", stats
.dwNumIf
);
536 trace( " dwNumAddr: %u\n", stats
.dwNumAddr
);
537 trace( " dwNumRoutes: %u\n", stats
.dwNumRoutes
);
542 static void testGetTcpStatistics(void)
544 if (pGetTcpStatistics
) {
548 apiReturn
= pGetTcpStatistics(NULL
);
549 if (apiReturn
== ERROR_NOT_SUPPORTED
) {
550 skip("GetTcpStatistics is not supported\n");
553 ok(apiReturn
== ERROR_INVALID_PARAMETER
,
554 "GetTcpStatistics(NULL) returned %d, expected ERROR_INVALID_PARAMETER\n",
556 apiReturn
= pGetTcpStatistics(&stats
);
557 ok(apiReturn
== NO_ERROR
,
558 "GetTcpStatistics returned %d, expected NO_ERROR\n", apiReturn
);
559 if (apiReturn
== NO_ERROR
&& winetest_debug
> 1)
561 trace( "TCP stats:\n" );
562 trace( " dwRtoAlgorithm: %u\n", U(stats
).dwRtoAlgorithm
);
563 trace( " dwRtoMin: %u\n", stats
.dwRtoMin
);
564 trace( " dwRtoMax: %u\n", stats
.dwRtoMax
);
565 trace( " dwMaxConn: %u\n", stats
.dwMaxConn
);
566 trace( " dwActiveOpens: %u\n", stats
.dwActiveOpens
);
567 trace( " dwPassiveOpens: %u\n", stats
.dwPassiveOpens
);
568 trace( " dwAttemptFails: %u\n", stats
.dwAttemptFails
);
569 trace( " dwEstabResets: %u\n", stats
.dwEstabResets
);
570 trace( " dwCurrEstab: %u\n", stats
.dwCurrEstab
);
571 trace( " dwInSegs: %u\n", stats
.dwInSegs
);
572 trace( " dwOutSegs: %u\n", stats
.dwOutSegs
);
573 trace( " dwRetransSegs: %u\n", stats
.dwRetransSegs
);
574 trace( " dwInErrs: %u\n", stats
.dwInErrs
);
575 trace( " dwOutRsts: %u\n", stats
.dwOutRsts
);
576 trace( " dwNumConns: %u\n", stats
.dwNumConns
);
581 static void testGetUdpStatistics(void)
583 if (pGetUdpStatistics
) {
587 apiReturn
= pGetUdpStatistics(NULL
);
588 if (apiReturn
== ERROR_NOT_SUPPORTED
) {
589 skip("GetUdpStatistics is not supported\n");
592 ok(apiReturn
== ERROR_INVALID_PARAMETER
,
593 "GetUdpStatistics(NULL) returned %d, expected ERROR_INVALID_PARAMETER\n",
595 apiReturn
= pGetUdpStatistics(&stats
);
596 ok(apiReturn
== NO_ERROR
,
597 "GetUdpStatistics returned %d, expected NO_ERROR\n", apiReturn
);
598 if (apiReturn
== NO_ERROR
&& winetest_debug
> 1)
600 trace( "UDP stats:\n" );
601 trace( " dwInDatagrams: %u\n", stats
.dwInDatagrams
);
602 trace( " dwNoPorts: %u\n", stats
.dwNoPorts
);
603 trace( " dwInErrors: %u\n", stats
.dwInErrors
);
604 trace( " dwOutDatagrams: %u\n", stats
.dwOutDatagrams
);
605 trace( " dwNumAddrs: %u\n", stats
.dwNumAddrs
);
610 static void testGetIcmpStatisticsEx(void)
615 if (!pGetIcmpStatisticsEx
)
617 win_skip( "GetIcmpStatisticsEx not available\n" );
621 /* Crashes on Vista */
623 apiReturn
= pGetIcmpStatisticsEx(NULL
, AF_INET
);
624 ok(apiReturn
== ERROR_INVALID_PARAMETER
,
625 "GetIcmpStatisticsEx(NULL, AF_INET) returned %d, expected ERROR_INVALID_PARAMETER\n", apiReturn
);
628 apiReturn
= pGetIcmpStatisticsEx(&stats
, AF_BAN
);
629 ok(apiReturn
== ERROR_INVALID_PARAMETER
,
630 "GetIcmpStatisticsEx(&stats, AF_BAN) returned %d, expected ERROR_INVALID_PARAMETER\n", apiReturn
);
632 apiReturn
= pGetIcmpStatisticsEx(&stats
, AF_INET
);
633 ok(apiReturn
== NO_ERROR
, "GetIcmpStatisticsEx returned %d, expected NO_ERROR\n", apiReturn
);
634 if (apiReturn
== NO_ERROR
&& winetest_debug
> 1)
637 trace( "ICMP IPv4 Ex stats: %8s %8s\n", "in", "out" );
638 trace( " dwMsgs: %8u %8u\n", stats
.icmpInStats
.dwMsgs
, stats
.icmpOutStats
.dwMsgs
);
639 trace( " dwErrors: %8u %8u\n", stats
.icmpInStats
.dwErrors
, stats
.icmpOutStats
.dwErrors
);
640 for (i
= 0; i
< 256; i
++)
641 trace( " rgdwTypeCount[%3i]: %8u %8u\n", i
, stats
.icmpInStats
.rgdwTypeCount
[i
], stats
.icmpOutStats
.rgdwTypeCount
[i
] );
644 apiReturn
= pGetIcmpStatisticsEx(&stats
, AF_INET6
);
645 ok(apiReturn
== NO_ERROR
|| broken(apiReturn
== ERROR_NOT_SUPPORTED
),
646 "GetIcmpStatisticsEx returned %d, expected NO_ERROR\n", apiReturn
);
647 if (apiReturn
== NO_ERROR
&& winetest_debug
> 1)
650 trace( "ICMP IPv6 Ex stats: %8s %8s\n", "in", "out" );
651 trace( " dwMsgs: %8u %8u\n", stats
.icmpInStats
.dwMsgs
, stats
.icmpOutStats
.dwMsgs
);
652 trace( " dwErrors: %8u %8u\n", stats
.icmpInStats
.dwErrors
, stats
.icmpOutStats
.dwErrors
);
653 for (i
= 0; i
< 256; i
++)
654 trace( " rgdwTypeCount[%3i]: %8u %8u\n", i
, stats
.icmpInStats
.rgdwTypeCount
[i
], stats
.icmpOutStats
.rgdwTypeCount
[i
] );
658 static void testGetIpStatisticsEx(void)
663 if (!pGetIpStatisticsEx
)
665 win_skip( "GetIpStatisticsEx not available\n" );
669 apiReturn
= pGetIpStatisticsEx(NULL
, AF_INET
);
670 ok(apiReturn
== ERROR_INVALID_PARAMETER
,
671 "GetIpStatisticsEx(NULL, AF_INET) returned %d, expected ERROR_INVALID_PARAMETER\n", apiReturn
);
673 apiReturn
= pGetIpStatisticsEx(&stats
, AF_BAN
);
674 ok(apiReturn
== ERROR_INVALID_PARAMETER
,
675 "GetIpStatisticsEx(&stats, AF_BAN) returned %d, expected ERROR_INVALID_PARAMETER\n", apiReturn
);
677 apiReturn
= pGetIpStatisticsEx(&stats
, AF_INET
);
678 ok(apiReturn
== NO_ERROR
, "GetIpStatisticsEx returned %d, expected NO_ERROR\n", apiReturn
);
679 if (apiReturn
== NO_ERROR
&& winetest_debug
> 1)
681 trace( "IP IPv4 Ex stats:\n" );
682 trace( " dwForwarding: %u\n", U(stats
).dwForwarding
);
683 trace( " dwDefaultTTL: %u\n", stats
.dwDefaultTTL
);
684 trace( " dwInReceives: %u\n", stats
.dwInReceives
);
685 trace( " dwInHdrErrors: %u\n", stats
.dwInHdrErrors
);
686 trace( " dwInAddrErrors: %u\n", stats
.dwInAddrErrors
);
687 trace( " dwForwDatagrams: %u\n", stats
.dwForwDatagrams
);
688 trace( " dwInUnknownProtos: %u\n", stats
.dwInUnknownProtos
);
689 trace( " dwInDiscards: %u\n", stats
.dwInDiscards
);
690 trace( " dwInDelivers: %u\n", stats
.dwInDelivers
);
691 trace( " dwOutRequests: %u\n", stats
.dwOutRequests
);
692 trace( " dwRoutingDiscards: %u\n", stats
.dwRoutingDiscards
);
693 trace( " dwOutDiscards: %u\n", stats
.dwOutDiscards
);
694 trace( " dwOutNoRoutes: %u\n", stats
.dwOutNoRoutes
);
695 trace( " dwReasmTimeout: %u\n", stats
.dwReasmTimeout
);
696 trace( " dwReasmReqds: %u\n", stats
.dwReasmReqds
);
697 trace( " dwReasmOks: %u\n", stats
.dwReasmOks
);
698 trace( " dwReasmFails: %u\n", stats
.dwReasmFails
);
699 trace( " dwFragOks: %u\n", stats
.dwFragOks
);
700 trace( " dwFragFails: %u\n", stats
.dwFragFails
);
701 trace( " dwFragCreates: %u\n", stats
.dwFragCreates
);
702 trace( " dwNumIf: %u\n", stats
.dwNumIf
);
703 trace( " dwNumAddr: %u\n", stats
.dwNumAddr
);
704 trace( " dwNumRoutes: %u\n", stats
.dwNumRoutes
);
707 apiReturn
= pGetIpStatisticsEx(&stats
, AF_INET6
);
708 ok(apiReturn
== NO_ERROR
|| broken(apiReturn
== ERROR_NOT_SUPPORTED
),
709 "GetIpStatisticsEx returned %d, expected NO_ERROR\n", apiReturn
);
710 if (apiReturn
== NO_ERROR
&& winetest_debug
> 1)
712 trace( "IP IPv6 Ex stats:\n" );
713 trace( " dwForwarding: %u\n", U(stats
).dwForwarding
);
714 trace( " dwDefaultTTL: %u\n", stats
.dwDefaultTTL
);
715 trace( " dwInReceives: %u\n", stats
.dwInReceives
);
716 trace( " dwInHdrErrors: %u\n", stats
.dwInHdrErrors
);
717 trace( " dwInAddrErrors: %u\n", stats
.dwInAddrErrors
);
718 trace( " dwForwDatagrams: %u\n", stats
.dwForwDatagrams
);
719 trace( " dwInUnknownProtos: %u\n", stats
.dwInUnknownProtos
);
720 trace( " dwInDiscards: %u\n", stats
.dwInDiscards
);
721 trace( " dwInDelivers: %u\n", stats
.dwInDelivers
);
722 trace( " dwOutRequests: %u\n", stats
.dwOutRequests
);
723 trace( " dwRoutingDiscards: %u\n", stats
.dwRoutingDiscards
);
724 trace( " dwOutDiscards: %u\n", stats
.dwOutDiscards
);
725 trace( " dwOutNoRoutes: %u\n", stats
.dwOutNoRoutes
);
726 trace( " dwReasmTimeout: %u\n", stats
.dwReasmTimeout
);
727 trace( " dwReasmReqds: %u\n", stats
.dwReasmReqds
);
728 trace( " dwReasmOks: %u\n", stats
.dwReasmOks
);
729 trace( " dwReasmFails: %u\n", stats
.dwReasmFails
);
730 trace( " dwFragOks: %u\n", stats
.dwFragOks
);
731 trace( " dwFragFails: %u\n", stats
.dwFragFails
);
732 trace( " dwFragCreates: %u\n", stats
.dwFragCreates
);
733 trace( " dwNumIf: %u\n", stats
.dwNumIf
);
734 trace( " dwNumAddr: %u\n", stats
.dwNumAddr
);
735 trace( " dwNumRoutes: %u\n", stats
.dwNumRoutes
);
739 static void testGetTcpStatisticsEx(void)
744 if (!pGetTcpStatisticsEx
)
746 win_skip( "GetTcpStatisticsEx not available\n" );
750 apiReturn
= pGetTcpStatisticsEx(NULL
, AF_INET
);
751 ok(apiReturn
== ERROR_INVALID_PARAMETER
,
752 "GetTcpStatisticsEx(NULL, AF_INET); returned %d, expected ERROR_INVALID_PARAMETER\n", apiReturn
);
754 apiReturn
= pGetTcpStatisticsEx(&stats
, AF_BAN
);
755 ok(apiReturn
== ERROR_INVALID_PARAMETER
|| apiReturn
== ERROR_NOT_SUPPORTED
,
756 "GetTcpStatisticsEx(&stats, AF_BAN) returned %d, expected ERROR_INVALID_PARAMETER\n", apiReturn
);
758 apiReturn
= pGetTcpStatisticsEx(&stats
, AF_INET
);
759 ok(apiReturn
== NO_ERROR
, "GetTcpStatisticsEx returned %d, expected NO_ERROR\n", apiReturn
);
760 if (apiReturn
== NO_ERROR
&& winetest_debug
> 1)
762 trace( "TCP IPv4 Ex stats:\n" );
763 trace( " dwRtoAlgorithm: %u\n", U(stats
).dwRtoAlgorithm
);
764 trace( " dwRtoMin: %u\n", stats
.dwRtoMin
);
765 trace( " dwRtoMax: %u\n", stats
.dwRtoMax
);
766 trace( " dwMaxConn: %u\n", stats
.dwMaxConn
);
767 trace( " dwActiveOpens: %u\n", stats
.dwActiveOpens
);
768 trace( " dwPassiveOpens: %u\n", stats
.dwPassiveOpens
);
769 trace( " dwAttemptFails: %u\n", stats
.dwAttemptFails
);
770 trace( " dwEstabResets: %u\n", stats
.dwEstabResets
);
771 trace( " dwCurrEstab: %u\n", stats
.dwCurrEstab
);
772 trace( " dwInSegs: %u\n", stats
.dwInSegs
);
773 trace( " dwOutSegs: %u\n", stats
.dwOutSegs
);
774 trace( " dwRetransSegs: %u\n", stats
.dwRetransSegs
);
775 trace( " dwInErrs: %u\n", stats
.dwInErrs
);
776 trace( " dwOutRsts: %u\n", stats
.dwOutRsts
);
777 trace( " dwNumConns: %u\n", stats
.dwNumConns
);
780 apiReturn
= pGetTcpStatisticsEx(&stats
, AF_INET6
);
781 todo_wine
ok(apiReturn
== NO_ERROR
|| broken(apiReturn
== ERROR_NOT_SUPPORTED
),
782 "GetTcpStatisticsEx returned %d, expected NO_ERROR\n", apiReturn
);
783 if (apiReturn
== NO_ERROR
&& winetest_debug
> 1)
785 trace( "TCP IPv6 Ex stats:\n" );
786 trace( " dwRtoAlgorithm: %u\n", U(stats
).dwRtoAlgorithm
);
787 trace( " dwRtoMin: %u\n", stats
.dwRtoMin
);
788 trace( " dwRtoMax: %u\n", stats
.dwRtoMax
);
789 trace( " dwMaxConn: %u\n", stats
.dwMaxConn
);
790 trace( " dwActiveOpens: %u\n", stats
.dwActiveOpens
);
791 trace( " dwPassiveOpens: %u\n", stats
.dwPassiveOpens
);
792 trace( " dwAttemptFails: %u\n", stats
.dwAttemptFails
);
793 trace( " dwEstabResets: %u\n", stats
.dwEstabResets
);
794 trace( " dwCurrEstab: %u\n", stats
.dwCurrEstab
);
795 trace( " dwInSegs: %u\n", stats
.dwInSegs
);
796 trace( " dwOutSegs: %u\n", stats
.dwOutSegs
);
797 trace( " dwRetransSegs: %u\n", stats
.dwRetransSegs
);
798 trace( " dwInErrs: %u\n", stats
.dwInErrs
);
799 trace( " dwOutRsts: %u\n", stats
.dwOutRsts
);
800 trace( " dwNumConns: %u\n", stats
.dwNumConns
);
804 static void testGetUdpStatisticsEx(void)
809 if (!pGetUdpStatisticsEx
)
811 win_skip( "GetUdpStatisticsEx not available\n" );
815 apiReturn
= pGetUdpStatisticsEx(NULL
, AF_INET
);
816 ok(apiReturn
== ERROR_INVALID_PARAMETER
,
817 "GetUdpStatisticsEx(NULL, AF_INET); returned %d, expected ERROR_INVALID_PARAMETER\n", apiReturn
);
819 apiReturn
= pGetUdpStatisticsEx(&stats
, AF_BAN
);
820 ok(apiReturn
== ERROR_INVALID_PARAMETER
|| apiReturn
== ERROR_NOT_SUPPORTED
,
821 "GetUdpStatisticsEx(&stats, AF_BAN) returned %d, expected ERROR_INVALID_PARAMETER\n", apiReturn
);
823 apiReturn
= pGetUdpStatisticsEx(&stats
, AF_INET
);
824 ok(apiReturn
== NO_ERROR
, "GetUdpStatisticsEx returned %d, expected NO_ERROR\n", apiReturn
);
825 if (apiReturn
== NO_ERROR
&& winetest_debug
> 1)
827 trace( "UDP IPv4 Ex stats:\n" );
828 trace( " dwInDatagrams: %u\n", stats
.dwInDatagrams
);
829 trace( " dwNoPorts: %u\n", stats
.dwNoPorts
);
830 trace( " dwInErrors: %u\n", stats
.dwInErrors
);
831 trace( " dwOutDatagrams: %u\n", stats
.dwOutDatagrams
);
832 trace( " dwNumAddrs: %u\n", stats
.dwNumAddrs
);
835 apiReturn
= pGetUdpStatisticsEx(&stats
, AF_INET6
);
836 ok(apiReturn
== NO_ERROR
|| broken(apiReturn
== ERROR_NOT_SUPPORTED
),
837 "GetUdpStatisticsEx returned %d, expected NO_ERROR\n", apiReturn
);
838 if (apiReturn
== NO_ERROR
&& winetest_debug
> 1)
840 trace( "UDP IPv6 Ex stats:\n" );
841 trace( " dwInDatagrams: %u\n", stats
.dwInDatagrams
);
842 trace( " dwNoPorts: %u\n", stats
.dwNoPorts
);
843 trace( " dwInErrors: %u\n", stats
.dwInErrors
);
844 trace( " dwOutDatagrams: %u\n", stats
.dwOutDatagrams
);
845 trace( " dwNumAddrs: %u\n", stats
.dwNumAddrs
);
849 static void testGetTcpTable(void)
855 apiReturn
= pGetTcpTable(NULL
, &dwSize
, FALSE
);
856 if (apiReturn
== ERROR_NOT_SUPPORTED
) {
857 skip("GetTcpTable is not supported\n");
860 ok(apiReturn
== ERROR_INSUFFICIENT_BUFFER
||
861 broken(apiReturn
== ERROR_NO_DATA
), /* win95 */
862 "GetTcpTable(NULL, &dwSize, FALSE) returned %d, expected ERROR_INSUFFICIENT_BUFFER\n",
864 if (apiReturn
== ERROR_INSUFFICIENT_BUFFER
) {
865 PMIB_TCPTABLE buf
= HeapAlloc(GetProcessHeap(), 0, dwSize
);
867 apiReturn
= pGetTcpTable(buf
, &dwSize
, FALSE
);
868 ok(apiReturn
== NO_ERROR
,
869 "GetTcpTable(buf, &dwSize, FALSE) returned %d, expected NO_ERROR\n",
872 if (apiReturn
== NO_ERROR
&& winetest_debug
> 1)
875 trace( "TCP table: %u entries\n", buf
->dwNumEntries
);
876 for (i
= 0; i
< buf
->dwNumEntries
; i
++)
879 sprintf( buffer
, "local %s:%u",
880 ntoa(buf
->table
[i
].dwLocalAddr
), ntohs(buf
->table
[i
].dwLocalPort
) );
881 trace( "%u: %s remote %s:%u state %u\n",
882 i
, buffer
, ntoa( buf
->table
[i
].dwRemoteAddr
),
883 ntohs(buf
->table
[i
].dwRemotePort
), U(buf
->table
[i
]).dwState
);
886 HeapFree(GetProcessHeap(), 0, buf
);
891 static void testGetUdpTable(void)
897 apiReturn
= pGetUdpTable(NULL
, &dwSize
, FALSE
);
898 if (apiReturn
== ERROR_NOT_SUPPORTED
) {
899 skip("GetUdpTable is not supported\n");
902 ok(apiReturn
== ERROR_INSUFFICIENT_BUFFER
,
903 "GetUdpTable(NULL, &dwSize, FALSE) returned %d, expected ERROR_INSUFFICIENT_BUFFER\n",
905 if (apiReturn
== ERROR_INSUFFICIENT_BUFFER
) {
906 PMIB_UDPTABLE buf
= HeapAlloc(GetProcessHeap(), 0, dwSize
);
908 apiReturn
= pGetUdpTable(buf
, &dwSize
, FALSE
);
909 ok(apiReturn
== NO_ERROR
,
910 "GetUdpTable(buf, &dwSize, FALSE) returned %d, expected NO_ERROR\n",
913 if (apiReturn
== NO_ERROR
&& winetest_debug
> 1)
916 trace( "UDP table: %u entries\n", buf
->dwNumEntries
);
917 for (i
= 0; i
< buf
->dwNumEntries
; i
++)
918 trace( "%u: %s:%u\n",
919 i
, ntoa( buf
->table
[i
].dwLocalAddr
), ntohs(buf
->table
[i
].dwLocalPort
) );
921 HeapFree(GetProcessHeap(), 0, buf
);
926 static void testSetTcpEntry(void)
931 memset(&row
, 0, sizeof(row
));
932 if(0) /* This test crashes in OS >= VISTA */
934 ret
= pSetTcpEntry(NULL
);
935 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u, expected %u\n", ret
, ERROR_INVALID_PARAMETER
);
938 ret
= pSetTcpEntry(&row
);
939 if (ret
== ERROR_NETWORK_ACCESS_DENIED
)
941 win_skip("SetTcpEntry failed with access error. Skipping test.\n");
944 todo_wine
ok( ret
== ERROR_INVALID_PARAMETER
, "got %u, expected %u\n", ret
, ERROR_INVALID_PARAMETER
);
946 U(row
).dwState
= MIB_TCP_STATE_DELETE_TCB
;
947 ret
= pSetTcpEntry(&row
);
948 todo_wine
ok( ret
== ERROR_MR_MID_NOT_FOUND
|| broken(ret
== ERROR_INVALID_PARAMETER
),
949 "got %u, expected %u\n", ret
, ERROR_MR_MID_NOT_FOUND
);
952 static void testIcmpSendEcho(void)
955 char senddata
[32], replydata
[sizeof(senddata
) + sizeof(ICMP_ECHO_REPLY
)];
956 DWORD ret
, error
, replysz
= sizeof(replydata
);
959 if (!pIcmpSendEcho
|| !pIcmpCreateFile
)
961 win_skip( "IcmpSendEcho or IcmpCreateFile not available\n" );
964 memset(senddata
, 0, sizeof(senddata
));
966 address
= htonl(INADDR_LOOPBACK
);
967 SetLastError(0xdeadbeef);
968 ret
= pIcmpSendEcho(INVALID_HANDLE_VALUE
, address
, senddata
, sizeof(senddata
), NULL
, replydata
, replysz
, 1000);
969 error
= GetLastError();
970 ok (!ret
, "IcmpSendEcho succeeded unexpectedly\n");
972 ok (error
== ERROR_INVALID_PARAMETER
973 || broken(error
== ERROR_INVALID_HANDLE
) /* <= 2003 */,
974 "expected 87, got %d\n", error
);
976 icmp
= pIcmpCreateFile();
977 if (icmp
== INVALID_HANDLE_VALUE
)
979 error
= GetLastError();
980 if (error
== ERROR_ACCESS_DENIED
)
982 skip ("ICMP is not available.\n");
986 ok (icmp
!= INVALID_HANDLE_VALUE
, "IcmpCreateFile failed unexpectedly with error %d\n", GetLastError());
989 SetLastError(0xdeadbeef);
990 ret
= pIcmpSendEcho(icmp
, address
, senddata
, sizeof(senddata
), NULL
, replydata
, replysz
, 1000);
991 error
= GetLastError();
992 ok (!ret
, "IcmpSendEcho succeeded unexpectedly\n");
993 ok (error
== ERROR_INVALID_NETNAME
994 || broken(error
== IP_BAD_DESTINATION
) /* <= 2003 */,
995 "expected 1214, got %d\n", error
);
997 address
= htonl(INADDR_LOOPBACK
);
998 if (0) /* crashes in XP */
1000 ret
= pIcmpSendEcho(icmp
, address
, NULL
, sizeof(senddata
), NULL
, replydata
, replysz
, 1000);
1001 ok (!ret
, "IcmpSendEcho succeeded unexpectedly\n");
1004 SetLastError(0xdeadbeef);
1005 ret
= pIcmpSendEcho(icmp
, address
, senddata
, 0, NULL
, replydata
, replysz
, 1000);
1006 error
= GetLastError();
1007 ok (ret
, "IcmpSendEcho failed unexpectedly with error %d\n", error
);
1009 SetLastError(0xdeadbeef);
1010 ret
= pIcmpSendEcho(icmp
, address
, NULL
, 0, NULL
, replydata
, replysz
, 1000);
1011 error
= GetLastError();
1012 ok (ret
, "IcmpSendEcho failed unexpectedly with error %d\n", error
);
1014 if (0) /* crashes in wine, remove IF when fixed */
1016 SetLastError(0xdeadbeef);
1017 ret
= pIcmpSendEcho(icmp
, address
, senddata
, sizeof(senddata
), NULL
, NULL
, replysz
, 1000);
1018 error
= GetLastError();
1019 ok (!ret
, "IcmpSendEcho succeeded unexpectedly\n");
1020 ok (error
== ERROR_INVALID_PARAMETER
, "expected 87, got %d\n", error
);
1023 SetLastError(0xdeadbeef);
1024 ret
= pIcmpSendEcho(icmp
, address
, senddata
, sizeof(senddata
), NULL
, replydata
, 0, 1000);
1025 error
= GetLastError();
1026 ok (!ret
, "IcmpSendEcho succeeded unexpectedly\n");
1028 ok (error
== ERROR_INVALID_PARAMETER
1029 || broken(error
== ERROR_INSUFFICIENT_BUFFER
) /* <= 2003 */,
1030 "expected 87, got %d\n", error
);
1032 SetLastError(0xdeadbeef);
1033 ret
= pIcmpSendEcho(icmp
, address
, senddata
, sizeof(senddata
), NULL
, NULL
, 0, 1000);
1034 error
= GetLastError();
1035 ok (!ret
, "IcmpSendEcho succeeded unexpectedly\n");
1037 ok (error
== ERROR_INVALID_PARAMETER
1038 || broken(error
== ERROR_INSUFFICIENT_BUFFER
) /* <= 2003 */,
1039 "expected 87, got %d\n", error
);
1041 SetLastError(0xdeadbeef);
1042 replysz
= sizeof(replydata
) - 1;
1043 ret
= pIcmpSendEcho(icmp
, address
, senddata
, sizeof(senddata
), NULL
, replydata
, replysz
, 1000);
1044 error
= GetLastError();
1046 ok (!ret
, "IcmpSendEcho succeeded unexpectedly\n");
1047 ok (error
== IP_GENERAL_FAILURE
1048 || broken(error
== IP_BUF_TOO_SMALL
) /* <= 2003 */,
1049 "expected 11050, got %d\n", error
);
1052 SetLastError(0xdeadbeef);
1053 replysz
= sizeof(ICMP_ECHO_REPLY
);
1054 ret
= pIcmpSendEcho(icmp
, address
, senddata
, 0, NULL
, replydata
, replysz
, 1000);
1055 error
= GetLastError();
1057 ok (ret
, "IcmpSendEcho failed unexpectedly with error %d\n", error
);
1059 SetLastError(0xdeadbeef);
1060 replysz
= sizeof(ICMP_ECHO_REPLY
) + ICMP_MINLEN
;
1061 ret
= pIcmpSendEcho(icmp
, address
, senddata
, ICMP_MINLEN
, NULL
, replydata
, replysz
, 1000);
1062 error
= GetLastError();
1064 ok (ret
, "IcmpSendEcho failed unexpectedly with error %d\n", error
);
1066 SetLastError(0xdeadbeef);
1067 replysz
= sizeof(ICMP_ECHO_REPLY
) + ICMP_MINLEN
;
1068 ret
= pIcmpSendEcho(icmp
, address
, senddata
, ICMP_MINLEN
+ 1, NULL
, replydata
, replysz
, 1000);
1069 error
= GetLastError();
1070 ok (!ret
, "IcmpSendEcho succeeded unexpectedly\n");
1072 ok (error
== IP_GENERAL_FAILURE
1073 || broken(error
== IP_BUF_TOO_SMALL
) /* <= 2003 */,
1074 "expected 11050, got %d\n", error
);
1076 SetLastError(0xdeadbeef);
1077 ret
= pIcmpSendEcho(icmp
, address
, senddata
, ICMP_MINLEN
, NULL
, replydata
, replysz
- 1, 1000);
1078 error
= GetLastError();
1079 ok (!ret
, "IcmpSendEcho succeeded unexpectedly\n");
1081 ok (error
== IP_GENERAL_FAILURE
1082 || broken(error
== IP_BUF_TOO_SMALL
) /* <= 2003 */,
1083 "expected 11050, got %d\n", error
);
1085 /* in windows >= vista the timeout can't be invalid */
1086 SetLastError(0xdeadbeef);
1087 replysz
= sizeof(replydata
);
1088 ret
= pIcmpSendEcho(icmp
, address
, senddata
, sizeof(senddata
), NULL
, replydata
, replysz
, 0);
1089 error
= GetLastError();
1090 if (!ret
) ok(error
== ERROR_INVALID_PARAMETER
, "expected 87, got %d\n", error
);
1092 SetLastError(0xdeadbeef);
1093 ret
= pIcmpSendEcho(icmp
, address
, senddata
, sizeof(senddata
), NULL
, replydata
, replysz
, -1);
1094 error
= GetLastError();
1095 if (!ret
) ok(error
== ERROR_INVALID_PARAMETER
, "expected 87, got %d\n", error
);
1097 /* real ping test */
1098 SetLastError(0xdeadbeef);
1099 address
= htonl(INADDR_LOOPBACK
);
1100 ret
= pIcmpSendEcho(icmp
, address
, senddata
, sizeof(senddata
), NULL
, replydata
, replysz
, 1000);
1101 error
= GetLastError();
1104 PICMP_ECHO_REPLY pong
= (PICMP_ECHO_REPLY
) replydata
;
1105 trace ("send addr : %s\n", ntoa(address
));
1106 trace ("reply addr : %s\n", ntoa(pong
->Address
));
1107 trace ("reply size : %u\n", replysz
);
1108 trace ("roundtrip : %u ms\n", pong
->RoundTripTime
);
1109 trace ("status : %u\n", pong
->Status
);
1110 trace ("recv size : %u\n", pong
->DataSize
);
1111 trace ("ttl : %u\n", pong
->Options
.Ttl
);
1112 trace ("flags : 0x%x\n", pong
->Options
.Flags
);
1116 skip ("Failed to ping with error %d, is lo interface down?.\n", error
);
1121 still-to-be-tested NT4-onward functions:
1122 CreateIpForwardEntry
1123 DeleteIpForwardEntry
1134 static void testWinNT4Functions(void)
1136 testGetNumberOfInterfaces();
1137 testGetIpAddrTable();
1139 testGetIpForwardTable();
1140 testGetIpNetTable();
1141 testGetIcmpStatistics();
1142 testGetIpStatistics();
1143 testGetTcpStatistics();
1144 testGetUdpStatistics();
1145 testGetIcmpStatisticsEx();
1146 testGetIpStatisticsEx();
1147 testGetTcpStatisticsEx();
1148 testGetUdpStatisticsEx();
1155 static void testGetInterfaceInfo(void)
1157 if (pGetInterfaceInfo
) {
1161 apiReturn
= pGetInterfaceInfo(NULL
, NULL
);
1162 if (apiReturn
== ERROR_NOT_SUPPORTED
) {
1163 skip("GetInterfaceInfo is not supported\n");
1166 ok(apiReturn
== ERROR_INVALID_PARAMETER
,
1167 "GetInterfaceInfo returned %d, expected ERROR_INVALID_PARAMETER\n",
1169 apiReturn
= pGetInterfaceInfo(NULL
, &len
);
1170 ok(apiReturn
== ERROR_INSUFFICIENT_BUFFER
,
1171 "GetInterfaceInfo returned %d, expected ERROR_INSUFFICIENT_BUFFER\n",
1173 if (apiReturn
== ERROR_INSUFFICIENT_BUFFER
) {
1174 PIP_INTERFACE_INFO buf
= HeapAlloc(GetProcessHeap(), 0, len
);
1176 apiReturn
= pGetInterfaceInfo(buf
, &len
);
1177 ok(apiReturn
== NO_ERROR
,
1178 "GetInterfaceInfo(buf, &dwSize) returned %d, expected NO_ERROR\n",
1180 HeapFree(GetProcessHeap(), 0, buf
);
1185 static void testGetAdaptersInfo(void)
1187 if (pGetAdaptersInfo
) {
1191 apiReturn
= pGetAdaptersInfo(NULL
, NULL
);
1192 if (apiReturn
== ERROR_NOT_SUPPORTED
) {
1193 skip("GetAdaptersInfo is not supported\n");
1196 ok(apiReturn
== ERROR_INVALID_PARAMETER
,
1197 "GetAdaptersInfo returned %d, expected ERROR_INVALID_PARAMETER\n",
1199 apiReturn
= pGetAdaptersInfo(NULL
, &len
);
1200 ok(apiReturn
== ERROR_NO_DATA
|| apiReturn
== ERROR_BUFFER_OVERFLOW
,
1201 "GetAdaptersInfo returned %d, expected ERROR_NO_DATA or ERROR_BUFFER_OVERFLOW\n",
1203 if (apiReturn
== ERROR_NO_DATA
)
1204 ; /* no adapter's, that's okay */
1205 else if (apiReturn
== ERROR_BUFFER_OVERFLOW
) {
1206 PIP_ADAPTER_INFO ptr
, buf
= HeapAlloc(GetProcessHeap(), 0, len
);
1208 apiReturn
= pGetAdaptersInfo(buf
, &len
);
1209 ok(apiReturn
== NO_ERROR
,
1210 "GetAdaptersInfo(buf, &dwSize) returned %d, expected NO_ERROR\n",
1214 ok(ptr
->IpAddressList
.IpAddress
.String
[0], "A valid IP must be present\n");
1215 ok(ptr
->IpAddressList
.IpMask
.String
[0], "A valid mask must be present\n");
1216 trace("Adapter '%s', IP %s, Mask %s\n", ptr
->AdapterName
,
1217 ptr
->IpAddressList
.IpAddress
.String
, ptr
->IpAddressList
.IpMask
.String
);
1220 HeapFree(GetProcessHeap(), 0, buf
);
1225 static void testGetNetworkParams(void)
1227 if (pGetNetworkParams
) {
1231 apiReturn
= pGetNetworkParams(NULL
, NULL
);
1232 if (apiReturn
== ERROR_NOT_SUPPORTED
) {
1233 skip("GetNetworkParams is not supported\n");
1236 ok(apiReturn
== ERROR_INVALID_PARAMETER
,
1237 "GetNetworkParams returned %d, expected ERROR_INVALID_PARAMETER\n",
1239 apiReturn
= pGetNetworkParams(NULL
, &len
);
1240 ok(apiReturn
== ERROR_BUFFER_OVERFLOW
,
1241 "GetNetworkParams returned %d, expected ERROR_BUFFER_OVERFLOW\n",
1243 if (apiReturn
== ERROR_BUFFER_OVERFLOW
) {
1244 PFIXED_INFO buf
= HeapAlloc(GetProcessHeap(), 0, len
);
1246 apiReturn
= pGetNetworkParams(buf
, &len
);
1247 ok(apiReturn
== NO_ERROR
,
1248 "GetNetworkParams(buf, &dwSize) returned %d, expected NO_ERROR\n",
1250 HeapFree(GetProcessHeap(), 0, buf
);
1256 still-to-be-tested 98-onward functions:
1262 static DWORD CALLBACK
testWin98Functions(void *p
)
1264 testGetInterfaceInfo();
1265 testGetAdaptersInfo();
1266 testGetNetworkParams();
1270 static void testGetPerAdapterInfo(void)
1275 if (!pGetPerAdapterInfo
) return;
1276 ret
= pGetPerAdapterInfo(1, NULL
, NULL
);
1277 if (ret
== ERROR_NOT_SUPPORTED
) {
1278 skip("GetPerAdapterInfo is not supported\n");
1281 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u instead of ERROR_INVALID_PARAMETER\n", ret
);
1282 needed
= 0xdeadbeef;
1283 ret
= pGetPerAdapterInfo(1, NULL
, &needed
);
1284 if (ret
== ERROR_NO_DATA
) return; /* no such adapter */
1285 ok( ret
== ERROR_BUFFER_OVERFLOW
, "got %u instead of ERROR_BUFFER_OVERFLOW\n", ret
);
1286 ok( needed
!= 0xdeadbeef, "needed not set\n" );
1287 buffer
= HeapAlloc( GetProcessHeap(), 0, needed
);
1288 ret
= pGetPerAdapterInfo(1, buffer
, &needed
);
1289 ok( ret
== NO_ERROR
, "got %u instead of NO_ERROR\n", ret
);
1290 HeapFree( GetProcessHeap(), 0, buffer
);
1293 static void testNotifyAddrChange(void)
1296 OVERLAPPED overlapped
;
1300 if (!pNotifyAddrChange
)
1302 win_skip("NotifyAddrChange not present\n");
1305 if (!pCancelIPChangeNotify
)
1307 win_skip("CancelIPChangeNotify not present\n");
1312 ZeroMemory(&overlapped
, sizeof(overlapped
));
1313 ret
= pNotifyAddrChange(&handle
, &overlapped
);
1314 if (ret
== ERROR_NOT_SUPPORTED
)
1316 win_skip("NotifyAddrChange is not supported\n");
1319 ok(ret
== ERROR_IO_PENDING
, "NotifyAddrChange returned %d, expected ERROR_IO_PENDING\n", ret
);
1320 ret
= GetLastError();
1321 todo_wine
ok(ret
== ERROR_IO_PENDING
, "GetLastError returned %d, expected ERROR_IO_PENDING\n", ret
);
1322 success
= pCancelIPChangeNotify(&overlapped
);
1323 todo_wine
ok(success
== TRUE
, "CancelIPChangeNotify returned FALSE, expected TRUE\n");
1325 ZeroMemory(&overlapped
, sizeof(overlapped
));
1326 success
= pCancelIPChangeNotify(&overlapped
);
1327 ok(success
== FALSE
, "CancelIPChangeNotify returned TRUE, expected FALSE\n");
1330 ZeroMemory(&overlapped
, sizeof(overlapped
));
1331 overlapped
.hEvent
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
1332 ret
= pNotifyAddrChange(&handle
, &overlapped
);
1333 ok(ret
== ERROR_IO_PENDING
, "NotifyAddrChange returned %d, expected ERROR_IO_PENDING\n", ret
);
1334 todo_wine
ok(handle
!= INVALID_HANDLE_VALUE
, "NotifyAddrChange returned invalid file handle\n");
1335 success
= GetOverlappedResult(handle
, &overlapped
, &bytes
, FALSE
);
1336 ok(success
== FALSE
, "GetOverlappedResult returned TRUE, expected FALSE\n");
1337 ret
= GetLastError();
1338 ok(ret
== ERROR_IO_INCOMPLETE
, "GetLastError returned %d, expected ERROR_IO_INCOMPLETE\n", ret
);
1339 success
= pCancelIPChangeNotify(&overlapped
);
1340 todo_wine
ok(success
== TRUE
, "CancelIPChangeNotify returned FALSE, expected TRUE\n");
1342 if (winetest_interactive
)
1345 ZeroMemory(&overlapped
, sizeof(overlapped
));
1346 overlapped
.hEvent
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
1347 trace("Testing asynchronous ipv4 address change notification. Please "
1348 "change the ipv4 address of one of your network interfaces\n");
1349 ret
= pNotifyAddrChange(&handle
, &overlapped
);
1350 ok(ret
== ERROR_IO_PENDING
, "NotifyAddrChange returned %d, expected NO_ERROR\n", ret
);
1351 success
= GetOverlappedResult(handle
, &overlapped
, &bytes
, TRUE
);
1352 ok(success
== TRUE
, "GetOverlappedResult returned FALSE, expected TRUE\n");
1355 /* test synchronous functionality */
1356 if (winetest_interactive
)
1358 trace("Testing synchronous ipv4 address change notification. Please "
1359 "change the ipv4 address of one of your network interfaces\n");
1360 ret
= pNotifyAddrChange(NULL
, NULL
);
1361 todo_wine
ok(ret
== NO_ERROR
, "NotifyAddrChange returned %d, expected NO_ERROR\n", ret
);
1366 still-to-be-tested 2K-onward functions:
1374 NotifyRouteChange + CancelIPChangeNotify
1378 static void testWin2KFunctions(void)
1380 testGetPerAdapterInfo();
1381 testNotifyAddrChange();
1384 static void test_GetAdaptersAddresses(void)
1386 ULONG ret
, size
, osize
, i
;
1387 IP_ADAPTER_ADDRESSES
*aa
, *ptr
;
1388 IP_ADAPTER_UNICAST_ADDRESS
*ua
;
1390 if (!pGetAdaptersAddresses
)
1392 win_skip("GetAdaptersAddresses not present\n");
1396 ret
= pGetAdaptersAddresses(AF_UNSPEC
, 0, NULL
, NULL
, NULL
);
1397 ok(ret
== ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER got %u\n", ret
);
1399 /* size should be ignored and overwritten if buffer is NULL */
1401 ret
= pGetAdaptersAddresses(AF_UNSPEC
, 0, NULL
, NULL
, &size
);
1402 ok(ret
== ERROR_BUFFER_OVERFLOW
, "expected ERROR_BUFFER_OVERFLOW, got %u\n", ret
);
1403 if (ret
!= ERROR_BUFFER_OVERFLOW
) return;
1405 ptr
= HeapAlloc(GetProcessHeap(), 0, size
);
1406 ret
= pGetAdaptersAddresses(AF_UNSPEC
, 0, NULL
, ptr
, &size
);
1407 ok(!ret
, "expected ERROR_SUCCESS got %u\n", ret
);
1408 HeapFree(GetProcessHeap(), 0, ptr
);
1410 /* higher size must not be changed to lower size */
1413 ptr
= HeapAlloc(GetProcessHeap(), 0, osize
);
1414 ret
= pGetAdaptersAddresses(AF_UNSPEC
, GAA_FLAG_INCLUDE_PREFIX
, NULL
, ptr
, &osize
);
1415 ok(!ret
, "expected ERROR_SUCCESS got %u\n", ret
);
1416 ok(osize
== size
, "expected %d, got %d\n", size
, osize
);
1418 for (aa
= ptr
; !ret
&& aa
; aa
= aa
->Next
)
1420 char temp
[128], buf
[39];
1421 IP_ADAPTER_PREFIX
*prefix
;
1425 ok(S(U(*aa
)).Length
== sizeof(IP_ADAPTER_ADDRESSES_LH
) ||
1426 S(U(*aa
)).Length
== sizeof(IP_ADAPTER_ADDRESSES_XP
),
1427 "Unknown structure size of %u bytes\n", S(U(*aa
)).Length
);
1428 ok(aa
->DnsSuffix
!= NULL
, "DnsSuffix is not a valid pointer\n");
1429 ok(aa
->Description
!= NULL
, "Description is not a valid pointer\n");
1430 ok(aa
->FriendlyName
!= NULL
, "FriendlyName is not a valid pointer\n");
1433 trace("Length: %u\n", S(U(*aa
)).Length
);
1434 trace("IfIndex: %u\n", S(U(*aa
)).IfIndex
);
1435 trace("Next: %p\n", aa
->Next
);
1436 trace("AdapterName: %s\n", aa
->AdapterName
);
1437 trace("FirstUnicastAddress: %p\n", aa
->FirstUnicastAddress
);
1438 ua
= aa
->FirstUnicastAddress
;
1441 ok(S(U(*ua
)).Length
== sizeof(IP_ADAPTER_UNICAST_ADDRESS_LH
) ||
1442 S(U(*ua
)).Length
== sizeof(IP_ADAPTER_UNICAST_ADDRESS_XP
),
1443 "Unknown structure size of %u bytes\n", S(U(*ua
)).Length
);
1444 ok(ua
->PrefixOrigin
!= IpPrefixOriginOther
,
1445 "bad address config value %d\n", ua
->PrefixOrigin
);
1446 ok(ua
->SuffixOrigin
!= IpSuffixOriginOther
,
1447 "bad address config value %d\n", ua
->PrefixOrigin
);
1448 /* Address configured manually or from DHCP server? */
1449 if (ua
->PrefixOrigin
== IpPrefixOriginManual
||
1450 ua
->PrefixOrigin
== IpPrefixOriginDhcp
)
1452 ok(ua
->ValidLifetime
, "expected non-zero value\n");
1453 ok(ua
->PreferredLifetime
, "expected non-zero value\n");
1454 ok(ua
->LeaseLifetime
, "expected non-zero\n");
1456 /* Is the address ok in the network (not duplicated)? */
1457 ok(ua
->DadState
!= IpDadStateInvalid
&& ua
->DadState
!= IpDadStateDuplicate
,
1458 "bad address duplication value %d\n", ua
->DadState
);
1459 trace("\tLength: %u\n", S(U(*ua
)).Length
);
1460 trace("\tFlags: 0x%08x\n", S(U(*ua
)).Flags
);
1461 trace("\tNext: %p\n", ua
->Next
);
1462 trace("\tAddress.lpSockaddr: %p\n", ua
->Address
.lpSockaddr
);
1463 trace("\tAddress.iSockaddrLength: %d\n", ua
->Address
.iSockaddrLength
);
1464 trace("\tPrefixOrigin: %u\n", ua
->PrefixOrigin
);
1465 trace("\tSuffixOrigin: %u\n", ua
->SuffixOrigin
);
1466 trace("\tDadState: %u\n", ua
->DadState
);
1467 trace("\tValidLifetime: %u seconds\n", ua
->ValidLifetime
);
1468 trace("\tPreferredLifetime: %u seconds\n", ua
->PreferredLifetime
);
1469 trace("\tLeaseLifetime: %u seconds\n", ua
->LeaseLifetime
);
1470 if (S(U(*ua
)).Length
< sizeof(IP_ADAPTER_UNICAST_ADDRESS_LH
))
1476 trace("\tOnLinkPrefixLength: %u\n", ua
->OnLinkPrefixLength
);
1480 trace("FirstAnycastAddress: %p\n", aa
->FirstAnycastAddress
);
1481 trace("FirstMulticastAddress: %p\n", aa
->FirstMulticastAddress
);
1482 trace("FirstDnsServerAddress: %p\n", aa
->FirstDnsServerAddress
);
1483 trace("DnsSuffix: %s %p\n", wine_dbgstr_w(aa
->DnsSuffix
), aa
->DnsSuffix
);
1484 trace("Description: %s %p\n", wine_dbgstr_w(aa
->Description
), aa
->Description
);
1485 trace("FriendlyName: %s %p\n", wine_dbgstr_w(aa
->FriendlyName
), aa
->FriendlyName
);
1486 trace("PhysicalAddressLength: %u\n", aa
->PhysicalAddressLength
);
1487 for (i
= 0; i
< aa
->PhysicalAddressLength
; i
++)
1488 sprintf(temp
+ i
* 3, "%02X-", aa
->PhysicalAddress
[i
]);
1489 temp
[i
? i
* 3 - 1 : 0] = '\0';
1490 trace("PhysicalAddress: %s\n", temp
);
1491 trace("Flags: 0x%08x\n", aa
->Flags
);
1492 trace("Mtu: %u\n", aa
->Mtu
);
1493 trace("IfType: %u\n", aa
->IfType
);
1494 trace("OperStatus: %u\n", aa
->OperStatus
);
1495 trace("Ipv6IfIndex: %u\n", aa
->Ipv6IfIndex
);
1496 for (i
= 0, temp
[0] = '\0'; i
< sizeof(aa
->ZoneIndices
) / sizeof(aa
->ZoneIndices
[0]); i
++)
1497 sprintf(temp
+ strlen(temp
), "%d ", aa
->ZoneIndices
[i
]);
1498 trace("ZoneIndices: %s\n", temp
);
1499 trace("FirstPrefix: %p\n", aa
->FirstPrefix
);
1500 prefix
= aa
->FirstPrefix
;
1503 trace("\tLength: %u\n", S(U(*prefix
)).Length
);
1504 trace("\tFlags: 0x%08x\n", S(U(*prefix
)).Flags
);
1505 trace("\tNext: %p\n", prefix
->Next
);
1506 trace("\tAddress.lpSockaddr: %p\n", prefix
->Address
.lpSockaddr
);
1507 trace("\tAddress.iSockaddrLength: %d\n", prefix
->Address
.iSockaddrLength
);
1508 trace("\tPrefixLength: %u\n", prefix
->PrefixLength
);
1510 prefix
= prefix
->Next
;
1513 if (S(U(*aa
)).Length
< sizeof(IP_ADAPTER_ADDRESSES_LH
)) continue;
1514 trace("TransmitLinkSpeed: %s\n", debugstr_longlong(aa
->TransmitLinkSpeed
));
1515 trace("ReceiveLinkSpeed: %s\n", debugstr_longlong(aa
->ReceiveLinkSpeed
));
1516 trace("FirstWinsServerAddress:%p\n", aa
->FirstWinsServerAddress
);
1517 trace("FirstGatewayAddress: %p\n", aa
->FirstGatewayAddress
);
1518 trace("Ipv4Metric: %u\n", aa
->Ipv4Metric
);
1519 trace("Ipv6Metric: %u\n", aa
->Ipv6Metric
);
1520 trace("Luid: %p\n", &aa
->Luid
);
1521 trace("Dhcpv4Server: %p\n", &aa
->Dhcpv4Server
);
1522 trace("CompartmentId: %u\n", aa
->CompartmentId
);
1523 trace("NetworkGuid: %s\n", wine_dbgstr_guid((GUID
*) &aa
->NetworkGuid
));
1524 trace("ConnectionType: %u\n", aa
->ConnectionType
);
1525 trace("TunnelType: %u\n", aa
->TunnelType
);
1526 trace("Dhcpv6Server: %p\n", &aa
->Dhcpv6Server
);
1527 trace("Dhcpv6ClientDuidLength:%u\n", aa
->Dhcpv6ClientDuidLength
);
1528 trace("Dhcpv6ClientDuid: %p\n", aa
->Dhcpv6ClientDuid
);
1529 trace("Dhcpv6Iaid: %u\n", aa
->Dhcpv6Iaid
);
1530 trace("FirstDnsSuffix: %p\n", aa
->FirstDnsSuffix
);
1533 if (pConvertInterfaceLuidToGuid
)
1535 status
= pConvertInterfaceLuidToGuid(&aa
->Luid
, &guid
);
1536 ok(!status
, "got %u\n", status
);
1537 sprintf(buf
, "{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
1538 guid
.Data1
, guid
.Data2
, guid
.Data3
, guid
.Data4
[0], guid
.Data4
[1],
1539 guid
.Data4
[2], guid
.Data4
[3], guid
.Data4
[4], guid
.Data4
[5],
1540 guid
.Data4
[6], guid
.Data4
[7]);
1541 ok(!strcasecmp(aa
->AdapterName
, buf
), "expected '%s' got '%s'\n", aa
->AdapterName
, buf
);
1544 HeapFree(GetProcessHeap(), 0, ptr
);
1547 static void test_GetExtendedTcpTable(void)
1550 MIB_TCPTABLE
*table
;
1551 MIB_TCPTABLE_OWNER_PID
*table_pid
;
1552 MIB_TCPTABLE_OWNER_MODULE
*table_module
;
1554 if (!pGetExtendedTcpTable
)
1556 win_skip("GetExtendedTcpTable not available\n");
1559 ret
= pGetExtendedTcpTable( NULL
, NULL
, TRUE
, AF_INET
, TCP_TABLE_BASIC_ALL
, 0 );
1560 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
1563 ret
= pGetExtendedTcpTable( NULL
, &size
, TRUE
, AF_INET
, TCP_TABLE_BASIC_ALL
, 0 );
1564 ok( ret
== ERROR_INSUFFICIENT_BUFFER
, "got %u\n", ret
);
1566 table
= HeapAlloc( GetProcessHeap(), 0, size
);
1567 ret
= pGetExtendedTcpTable( table
, &size
, TRUE
, AF_INET
, TCP_TABLE_BASIC_ALL
, 0 );
1568 ok( ret
== ERROR_SUCCESS
, "got %u\n", ret
);
1569 HeapFree( GetProcessHeap(), 0, table
);
1572 ret
= pGetExtendedTcpTable( NULL
, &size
, TRUE
, AF_INET
, TCP_TABLE_BASIC_LISTENER
, 0 );
1573 ok( ret
== ERROR_INSUFFICIENT_BUFFER
, "got %u\n", ret
);
1575 table
= HeapAlloc( GetProcessHeap(), 0, size
);
1576 ret
= pGetExtendedTcpTable( table
, &size
, TRUE
, AF_INET
, TCP_TABLE_BASIC_LISTENER
, 0 );
1577 ok( ret
== ERROR_SUCCESS
, "got %u\n", ret
);
1578 HeapFree( GetProcessHeap(), 0, table
);
1581 ret
= pGetExtendedTcpTable( NULL
, &size
, TRUE
, AF_INET
, TCP_TABLE_OWNER_PID_ALL
, 0 );
1582 ok( ret
== ERROR_INSUFFICIENT_BUFFER
, "got %u\n", ret
);
1584 table_pid
= HeapAlloc( GetProcessHeap(), 0, size
);
1585 ret
= pGetExtendedTcpTable( table_pid
, &size
, TRUE
, AF_INET
, TCP_TABLE_OWNER_PID_ALL
, 0 );
1586 ok( ret
== ERROR_SUCCESS
, "got %u\n", ret
);
1587 HeapFree( GetProcessHeap(), 0, table_pid
);
1590 ret
= pGetExtendedTcpTable( NULL
, &size
, TRUE
, AF_INET
, TCP_TABLE_OWNER_PID_LISTENER
, 0 );
1591 ok( ret
== ERROR_INSUFFICIENT_BUFFER
, "got %u\n", ret
);
1593 table_pid
= HeapAlloc( GetProcessHeap(), 0, size
);
1594 ret
= pGetExtendedTcpTable( table_pid
, &size
, TRUE
, AF_INET
, TCP_TABLE_OWNER_PID_LISTENER
, 0 );
1595 ok( ret
== ERROR_SUCCESS
, "got %u\n", ret
);
1596 HeapFree( GetProcessHeap(), 0, table_pid
);
1599 ret
= pGetExtendedTcpTable( NULL
, &size
, TRUE
, AF_INET
, TCP_TABLE_OWNER_MODULE_ALL
, 0 );
1600 ok( ret
== ERROR_INSUFFICIENT_BUFFER
, "got %u\n", ret
);
1602 table_module
= HeapAlloc( GetProcessHeap(), 0, size
);
1603 ret
= pGetExtendedTcpTable( table_module
, &size
, TRUE
, AF_INET
, TCP_TABLE_OWNER_MODULE_ALL
, 0 );
1604 ok( ret
== ERROR_SUCCESS
, "got %u\n", ret
);
1605 HeapFree( GetProcessHeap(), 0, table_module
);
1608 ret
= pGetExtendedTcpTable( NULL
, &size
, TRUE
, AF_INET
, TCP_TABLE_OWNER_MODULE_LISTENER
, 0 );
1609 ok( ret
== ERROR_INSUFFICIENT_BUFFER
, "got %u\n", ret
);
1611 table_module
= HeapAlloc( GetProcessHeap(), 0, size
);
1612 ret
= pGetExtendedTcpTable( table_module
, &size
, TRUE
, AF_INET
, TCP_TABLE_OWNER_MODULE_LISTENER
, 0 );
1613 ok( ret
== ERROR_SUCCESS
, "got %u\n", ret
);
1614 HeapFree( GetProcessHeap(), 0, table_module
);
1617 static void test_AllocateAndGetTcpExTableFromStack(void)
1620 MIB_TCPTABLE_OWNER_PID
*table_ex
= NULL
;
1622 if (!pAllocateAndGetTcpExTableFromStack
)
1624 skip("AllocateAndGetTcpExTableFromStack not available\n");
1630 /* crashes on native */
1631 ret
= pAllocateAndGetTcpExTableFromStack( NULL
, FALSE
, INVALID_HANDLE_VALUE
, 0, 0 );
1632 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
1633 ret
= pAllocateAndGetTcpExTableFromStack( (void **)&table_ex
, FALSE
, INVALID_HANDLE_VALUE
, 0, AF_INET
);
1634 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
1635 ret
= pAllocateAndGetTcpExTableFromStack( NULL
, FALSE
, GetProcessHeap(), 0, AF_INET
);
1636 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
1639 ret
= pAllocateAndGetTcpExTableFromStack( (void **)&table_ex
, FALSE
, GetProcessHeap(), 0, 0 );
1640 ok( ret
== ERROR_INVALID_PARAMETER
|| broken(ret
== ERROR_NOT_SUPPORTED
) /* win2k */, "got %u\n", ret
);
1642 ret
= pAllocateAndGetTcpExTableFromStack( (void **)&table_ex
, FALSE
, GetProcessHeap(), 0, AF_INET
);
1643 ok( ret
== ERROR_SUCCESS
, "got %u\n", ret
);
1645 if (ret
== NO_ERROR
&& winetest_debug
> 1)
1648 trace( "AllocateAndGetTcpExTableFromStack table: %u entries\n", table_ex
->dwNumEntries
);
1649 for (i
= 0; i
< table_ex
->dwNumEntries
; i
++)
1653 strcpy(remote_ip
, ntoa(table_ex
->table
[i
].dwRemoteAddr
));
1654 trace( "%u: local %s:%u remote %s:%u state %u pid %u\n", i
,
1655 ntoa(table_ex
->table
[i
].dwLocalAddr
), ntohs(table_ex
->table
[i
].dwLocalPort
),
1656 remote_ip
, ntohs(table_ex
->table
[i
].dwRemotePort
),
1657 U(table_ex
->table
[i
]).dwState
, table_ex
->table
[i
].dwOwningPid
);
1660 HeapFree(GetProcessHeap(), 0, table_ex
);
1662 ret
= pAllocateAndGetTcpExTableFromStack( (void **)&table_ex
, FALSE
, GetProcessHeap(), 0, AF_INET6
);
1663 ok( ret
== ERROR_NOT_SUPPORTED
, "got %u\n", ret
);
1666 static void test_GetExtendedUdpTable(void)
1669 MIB_UDPTABLE
*table
;
1670 MIB_UDPTABLE_OWNER_PID
*table_pid
;
1671 MIB_UDPTABLE_OWNER_MODULE
*table_module
;
1673 if (!pGetExtendedUdpTable
)
1675 win_skip("GetExtendedUdpTable not available\n");
1678 ret
= pGetExtendedUdpTable( NULL
, NULL
, TRUE
, AF_INET
, UDP_TABLE_BASIC
, 0 );
1679 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
1682 ret
= pGetExtendedUdpTable( NULL
, &size
, TRUE
, AF_INET
, UDP_TABLE_BASIC
, 0 );
1683 ok( ret
== ERROR_INSUFFICIENT_BUFFER
, "got %u\n", ret
);
1685 table
= HeapAlloc( GetProcessHeap(), 0, size
);
1686 ret
= pGetExtendedUdpTable( table
, &size
, TRUE
, AF_INET
, UDP_TABLE_BASIC
, 0 );
1687 ok( ret
== ERROR_SUCCESS
, "got %u\n", ret
);
1688 HeapFree( GetProcessHeap(), 0, table
);
1691 ret
= pGetExtendedUdpTable( NULL
, &size
, TRUE
, AF_INET
, UDP_TABLE_OWNER_PID
, 0 );
1692 ok( ret
== ERROR_INSUFFICIENT_BUFFER
, "got %u\n", ret
);
1694 table_pid
= HeapAlloc( GetProcessHeap(), 0, size
);
1695 ret
= pGetExtendedUdpTable( table_pid
, &size
, TRUE
, AF_INET
, UDP_TABLE_OWNER_PID
, 0 );
1696 ok( ret
== ERROR_SUCCESS
, "got %u\n", ret
);
1697 HeapFree( GetProcessHeap(), 0, table_pid
);
1700 ret
= pGetExtendedUdpTable( NULL
, &size
, TRUE
, AF_INET
, UDP_TABLE_OWNER_MODULE
, 0 );
1701 ok( ret
== ERROR_INSUFFICIENT_BUFFER
, "got %u\n", ret
);
1703 table_module
= HeapAlloc( GetProcessHeap(), 0, size
);
1704 ret
= pGetExtendedUdpTable( table_module
, &size
, TRUE
, AF_INET
, UDP_TABLE_OWNER_MODULE
, 0 );
1705 ok( ret
== ERROR_SUCCESS
, "got %u\n", ret
);
1706 HeapFree( GetProcessHeap(), 0, table_module
);
1709 static void test_CreateSortedAddressPairs(void)
1711 SOCKADDR_IN6 dst
[2];
1712 SOCKADDR_IN6_PAIR
*pair
;
1716 if (!pCreateSortedAddressPairs
)
1718 win_skip( "CreateSortedAddressPairs not available\n" );
1722 memset( dst
, 0, sizeof(dst
) );
1723 dst
[0].sin6_family
= AF_INET6
;
1724 dst
[0].sin6_addr
.u
.Word
[5] = 0xffff;
1725 dst
[0].sin6_addr
.u
.Word
[6] = 0x0808;
1726 dst
[0].sin6_addr
.u
.Word
[7] = 0x0808;
1728 pair_count
= 0xdeadbeef;
1729 ret
= pCreateSortedAddressPairs( NULL
, 0, dst
, 1, 0, NULL
, &pair_count
);
1730 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
1731 ok( pair_count
== 0xdeadbeef, "got %u\n", pair_count
);
1733 pair
= (SOCKADDR_IN6_PAIR
*)0xdeadbeef;
1734 pair_count
= 0xdeadbeef;
1735 ret
= pCreateSortedAddressPairs( NULL
, 0, NULL
, 1, 0, &pair
, &pair_count
);
1736 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
1737 ok( pair
== (SOCKADDR_IN6_PAIR
*)0xdeadbeef, "got %p\n", pair
);
1738 ok( pair_count
== 0xdeadbeef, "got %u\n", pair_count
);
1741 pair_count
= 0xdeadbeef;
1742 ret
= pCreateSortedAddressPairs( NULL
, 0, dst
, 1, 0, &pair
, &pair_count
);
1743 ok( ret
== NO_ERROR
, "got %u\n", ret
);
1744 ok( pair
!= NULL
, "pair not set\n" );
1745 ok( pair_count
>= 1, "got %u\n", pair_count
);
1746 ok( pair
[0].SourceAddress
!= NULL
, "src address not set\n" );
1747 ok( pair
[0].DestinationAddress
!= NULL
, "dst address not set\n" );
1748 pFreeMibTable( pair
);
1750 dst
[1].sin6_family
= AF_INET6
;
1751 dst
[1].sin6_addr
.u
.Word
[5] = 0xffff;
1752 dst
[1].sin6_addr
.u
.Word
[6] = 0x0404;
1753 dst
[1].sin6_addr
.u
.Word
[7] = 0x0808;
1756 pair_count
= 0xdeadbeef;
1757 ret
= pCreateSortedAddressPairs( NULL
, 0, dst
, 2, 0, &pair
, &pair_count
);
1758 ok( ret
== NO_ERROR
, "got %u\n", ret
);
1759 ok( pair
!= NULL
, "pair not set\n" );
1760 ok( pair_count
>= 2, "got %u\n", pair_count
);
1761 ok( pair
[0].SourceAddress
!= NULL
, "src address not set\n" );
1762 ok( pair
[0].DestinationAddress
!= NULL
, "dst address not set\n" );
1763 ok( pair
[1].SourceAddress
!= NULL
, "src address not set\n" );
1764 ok( pair
[1].DestinationAddress
!= NULL
, "dst address not set\n" );
1765 pFreeMibTable( pair
);
1768 static DWORD
get_interface_index(void)
1770 DWORD size
= 0, ret
= 0;
1771 IP_ADAPTER_ADDRESSES
*buf
, *aa
;
1773 if (pGetAdaptersAddresses( AF_UNSPEC
, 0, NULL
, NULL
, &size
) != ERROR_BUFFER_OVERFLOW
)
1776 buf
= HeapAlloc( GetProcessHeap(), 0, size
);
1777 pGetAdaptersAddresses( AF_UNSPEC
, 0, NULL
, buf
, &size
);
1778 for (aa
= buf
; aa
; aa
= aa
->Next
)
1780 if (aa
->IfType
== IF_TYPE_ETHERNET_CSMACD
)
1786 HeapFree( GetProcessHeap(), 0, buf
);
1790 static void test_interface_identifier_conversion(void)
1796 WCHAR nameW
[IF_MAX_STRING_SIZE
+ 1];
1797 char nameA
[IF_MAX_STRING_SIZE
+ 1];
1798 NET_IFINDEX index
, index2
;
1800 if (!pConvertInterfaceIndexToLuid
)
1802 win_skip( "ConvertInterfaceIndexToLuid not available\n" );
1805 if (!(index
= get_interface_index()))
1807 skip( "no suitable interface found\n" );
1811 /* ConvertInterfaceIndexToLuid */
1812 ret
= pConvertInterfaceIndexToLuid( 0, NULL
);
1813 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
1815 memset( &luid
, 0xff, sizeof(luid
) );
1816 ret
= pConvertInterfaceIndexToLuid( 0, &luid
);
1817 ok( ret
== ERROR_FILE_NOT_FOUND
, "got %u\n", ret
);
1818 ok( !luid
.Info
.Reserved
, "got %x\n", luid
.Info
.Reserved
);
1819 ok( !luid
.Info
.NetLuidIndex
, "got %u\n", luid
.Info
.NetLuidIndex
);
1820 ok( !luid
.Info
.IfType
, "got %u\n", luid
.Info
.IfType
);
1822 luid
.Info
.Reserved
= luid
.Info
.NetLuidIndex
= luid
.Info
.IfType
= 0xdead;
1823 ret
= pConvertInterfaceIndexToLuid( index
, &luid
);
1824 ok( !ret
, "got %u\n", ret
);
1825 ok( !luid
.Info
.Reserved
, "got %x\n", luid
.Info
.Reserved
);
1826 ok( luid
.Info
.NetLuidIndex
!= 0xdead, "index not set\n" );
1827 ok( luid
.Info
.IfType
== IF_TYPE_ETHERNET_CSMACD
, "got %u\n", luid
.Info
.IfType
);
1829 /* ConvertInterfaceLuidToIndex */
1830 ret
= pConvertInterfaceLuidToIndex( NULL
, NULL
);
1831 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
1833 ret
= pConvertInterfaceLuidToIndex( NULL
, &index
);
1834 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
1836 ret
= pConvertInterfaceLuidToIndex( &luid
, NULL
);
1837 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
1839 ret
= pConvertInterfaceLuidToIndex( &luid
, &index
);
1840 ok( !ret
, "got %u\n", ret
);
1842 /* ConvertInterfaceLuidToGuid */
1843 ret
= pConvertInterfaceLuidToGuid( NULL
, NULL
);
1844 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
1846 memset( &guid
, 0xff, sizeof(guid
) );
1847 ret
= pConvertInterfaceLuidToGuid( NULL
, &guid
);
1848 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
1849 ok( guid
.Data1
== 0xffffffff, "got %x\n", guid
.Data1
);
1851 ret
= pConvertInterfaceLuidToGuid( &luid
, NULL
);
1852 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
1854 memset( &guid
, 0, sizeof(guid
) );
1855 ret
= pConvertInterfaceLuidToGuid( &luid
, &guid
);
1856 ok( !ret
, "got %u\n", ret
);
1857 ok( guid
.Data1
, "got %x\n", guid
.Data1
);
1859 /* ConvertInterfaceGuidToLuid */
1860 ret
= pConvertInterfaceGuidToLuid( NULL
, NULL
);
1861 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
1863 luid
.Info
.NetLuidIndex
= 1;
1864 ret
= pConvertInterfaceGuidToLuid( NULL
, &luid
);
1865 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
1866 ok( luid
.Info
.NetLuidIndex
== 1, "got %u\n", luid
.Info
.NetLuidIndex
);
1868 ret
= pConvertInterfaceGuidToLuid( &guid
, NULL
);
1869 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
1871 luid
.Info
.Reserved
= luid
.Info
.NetLuidIndex
= luid
.Info
.IfType
= 0xdead;
1872 ret
= pConvertInterfaceGuidToLuid( &guid
, &luid
);
1873 ok( !ret
, "got %u\n", ret
);
1874 ok( !luid
.Info
.Reserved
, "got %x\n", luid
.Info
.Reserved
);
1875 ok( luid
.Info
.NetLuidIndex
!= 0xdead, "index not set\n" );
1876 ok( luid
.Info
.IfType
== IF_TYPE_ETHERNET_CSMACD
, "got %u\n", luid
.Info
.IfType
);
1878 /* ConvertInterfaceLuidToNameW */
1879 ret
= pConvertInterfaceLuidToNameW( NULL
, NULL
, 0 );
1880 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
1882 ret
= pConvertInterfaceLuidToNameW( &luid
, NULL
, 0 );
1883 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
1885 ret
= pConvertInterfaceLuidToNameW( NULL
, nameW
, 0 );
1886 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
1888 ret
= pConvertInterfaceLuidToNameW( &luid
, nameW
, 0 );
1889 ok( ret
== ERROR_NOT_ENOUGH_MEMORY
, "got %u\n", ret
);
1892 len
= sizeof(nameW
)/sizeof(nameW
[0]);
1893 ret
= pConvertInterfaceLuidToNameW( &luid
, nameW
, len
);
1894 ok( !ret
, "got %u\n", ret
);
1895 ok( nameW
[0], "name not set\n" );
1897 /* ConvertInterfaceLuidToNameA */
1898 ret
= pConvertInterfaceLuidToNameA( NULL
, NULL
, 0 );
1899 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
1901 ret
= pConvertInterfaceLuidToNameA( &luid
, NULL
, 0 );
1902 ok( ret
== ERROR_NOT_ENOUGH_MEMORY
, "got %u\n", ret
);
1904 ret
= pConvertInterfaceLuidToNameA( NULL
, nameA
, 0 );
1905 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
1907 ret
= pConvertInterfaceLuidToNameA( &luid
, nameA
, 0 );
1908 ok( ret
== ERROR_NOT_ENOUGH_MEMORY
, "got %u\n", ret
);
1911 len
= sizeof(nameA
)/sizeof(nameA
[0]);
1912 ret
= pConvertInterfaceLuidToNameA( &luid
, nameA
, len
);
1913 ok( !ret
, "got %u\n", ret
);
1914 ok( nameA
[0], "name not set\n" );
1916 /* ConvertInterfaceNameToLuidW */
1917 ret
= pConvertInterfaceNameToLuidW( NULL
, NULL
);
1918 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
1920 luid
.Info
.Reserved
= luid
.Info
.NetLuidIndex
= luid
.Info
.IfType
= 0xdead;
1921 ret
= pConvertInterfaceNameToLuidW( NULL
, &luid
);
1922 ok( ret
== ERROR_INVALID_NAME
, "got %u\n", ret
);
1923 ok( !luid
.Info
.Reserved
, "got %x\n", luid
.Info
.Reserved
);
1924 ok( luid
.Info
.NetLuidIndex
!= 0xdead, "index not set\n" );
1925 ok( !luid
.Info
.IfType
, "got %u\n", luid
.Info
.IfType
);
1927 ret
= pConvertInterfaceNameToLuidW( nameW
, NULL
);
1928 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
1930 luid
.Info
.Reserved
= luid
.Info
.NetLuidIndex
= luid
.Info
.IfType
= 0xdead;
1931 ret
= pConvertInterfaceNameToLuidW( nameW
, &luid
);
1932 ok( !ret
, "got %u\n", ret
);
1933 ok( !luid
.Info
.Reserved
, "got %x\n", luid
.Info
.Reserved
);
1934 ok( luid
.Info
.NetLuidIndex
!= 0xdead, "index not set\n" );
1935 ok( luid
.Info
.IfType
== IF_TYPE_ETHERNET_CSMACD
, "got %u\n", luid
.Info
.IfType
);
1937 /* ConvertInterfaceNameToLuidA */
1938 ret
= pConvertInterfaceNameToLuidA( NULL
, NULL
);
1939 ok( ret
== ERROR_INVALID_NAME
, "got %u\n", ret
);
1941 luid
.Info
.Reserved
= luid
.Info
.NetLuidIndex
= luid
.Info
.IfType
= 0xdead;
1942 ret
= pConvertInterfaceNameToLuidA( NULL
, &luid
);
1943 ok( ret
== ERROR_INVALID_NAME
, "got %u\n", ret
);
1944 ok( luid
.Info
.Reserved
== 0xdead, "reserved set\n" );
1945 ok( luid
.Info
.NetLuidIndex
== 0xdead, "index set\n" );
1946 ok( luid
.Info
.IfType
== 0xdead, "type set\n" );
1948 ret
= pConvertInterfaceNameToLuidA( nameA
, NULL
);
1949 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
1951 luid
.Info
.Reserved
= luid
.Info
.NetLuidIndex
= luid
.Info
.IfType
= 0xdead;
1952 ret
= pConvertInterfaceNameToLuidA( nameA
, &luid
);
1953 ok( !ret
, "got %u\n", ret
);
1954 ok( !luid
.Info
.Reserved
, "got %x\n", luid
.Info
.Reserved
);
1955 ok( luid
.Info
.NetLuidIndex
!= 0xdead, "index not set\n" );
1956 ok( luid
.Info
.IfType
== IF_TYPE_ETHERNET_CSMACD
, "got %u\n", luid
.Info
.IfType
);
1958 /* if_nametoindex */
1959 if (pif_nametoindex
)
1961 index2
= pif_nametoindex( NULL
);
1962 ok( !index2
, "Got unexpected index %u\n", index2
);
1963 index2
= pif_nametoindex( nameA
);
1964 ok( index2
== index
, "Got index %u for %s, expected %u\n", index2
, nameA
, index
);
1965 /* Wargaming.net Game Center passes a GUID-like string. */
1966 index2
= pif_nametoindex( "{00000001-0000-0000-0000-000000000000}" );
1967 ok( !index2
, "Got unexpected index %u\n", index2
);
1968 index2
= pif_nametoindex( wine_dbgstr_guid( &guid
) );
1969 ok( !index2
, "Got unexpected index %u for input %s\n", index2
, wine_dbgstr_guid( &guid
) );
1973 skip("if_nametoindex not supported\n");
1977 static void test_GetIfEntry2(void)
1985 win_skip( "GetIfEntry2 not available\n" );
1988 if (!(index
= get_interface_index()))
1990 skip( "no suitable interface found\n" );
1994 ret
= pGetIfEntry2( NULL
);
1995 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
1997 memset( &row
, 0, sizeof(row
) );
1998 ret
= pGetIfEntry2( &row
);
1999 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
2001 memset( &row
, 0, sizeof(row
) );
2002 row
.InterfaceIndex
= index
;
2003 ret
= pGetIfEntry2( &row
);
2004 ok( ret
== NO_ERROR
, "got %u\n", ret
);
2005 ok( row
.InterfaceIndex
== index
, "got %u\n", index
);
2008 static void test_GetIfTable2(void)
2011 MIB_IF_TABLE2
*table
;
2015 win_skip( "GetIfTable2 not available\n" );
2020 ret
= pGetIfTable2( &table
);
2021 ok( ret
== NO_ERROR
, "got %u\n", ret
);
2022 ok( table
!= NULL
, "table not set\n" );
2023 pFreeMibTable( table
);
2026 static void test_GetUnicastIpAddressEntry(void)
2028 IP_ADAPTER_ADDRESSES
*aa
, *ptr
;
2029 MIB_UNICASTIPADDRESS_ROW row
;
2032 if (!pGetUnicastIpAddressEntry
)
2034 win_skip( "GetUnicastIpAddressEntry not available\n" );
2038 ret
= pGetUnicastIpAddressEntry( NULL
);
2039 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
2041 memset( &row
, 0, sizeof(row
) );
2042 ret
= pGetUnicastIpAddressEntry( &row
);
2043 todo_wine
ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
2045 memset( &row
, 0, sizeof(row
) );
2046 row
.Address
.Ipv4
.sin_family
= AF_INET
;
2047 row
.Address
.Ipv4
.sin_port
= 0;
2048 row
.Address
.Ipv4
.sin_addr
.S_un
.S_addr
= 0x01020304;
2049 ret
= pGetUnicastIpAddressEntry( &row
);
2050 ok( ret
== ERROR_FILE_NOT_FOUND
, "got %u\n", ret
);
2052 memset( &row
, 0, sizeof(row
) );
2053 row
.InterfaceIndex
= 123;
2054 ret
= pGetUnicastIpAddressEntry( &row
);
2055 todo_wine
ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
2057 memset( &row
, 0, sizeof(row
) );
2058 row
.InterfaceIndex
= get_interface_index();
2059 row
.Address
.Ipv4
.sin_family
= AF_INET
;
2060 row
.Address
.Ipv4
.sin_port
= 0;
2061 row
.Address
.Ipv4
.sin_addr
.S_un
.S_addr
= 0x01020304;
2062 ret
= pGetUnicastIpAddressEntry( &row
);
2063 ok( ret
== ERROR_NOT_FOUND
, "got %u\n", ret
);
2065 memset( &row
, 0, sizeof(row
) );
2066 row
.InterfaceIndex
= 123;
2067 row
.Address
.Ipv4
.sin_family
= AF_INET
;
2068 row
.Address
.Ipv4
.sin_port
= 0;
2069 row
.Address
.Ipv4
.sin_addr
.S_un
.S_addr
= 0x01020304;
2070 ret
= pGetUnicastIpAddressEntry( &row
);
2071 ok( ret
== ERROR_FILE_NOT_FOUND
, "got %u\n", ret
);
2073 ret
= pGetAdaptersAddresses(AF_UNSPEC
, GAA_FLAG_INCLUDE_ALL_INTERFACES
, NULL
, NULL
, &size
);
2074 ok(ret
== ERROR_BUFFER_OVERFLOW
, "expected ERROR_BUFFER_OVERFLOW, got %u\n", ret
);
2075 if (ret
!= ERROR_BUFFER_OVERFLOW
) return;
2077 ptr
= HeapAlloc(GetProcessHeap(), 0, size
);
2078 ret
= pGetAdaptersAddresses(AF_UNSPEC
, GAA_FLAG_INCLUDE_ALL_INTERFACES
, NULL
, ptr
, &size
);
2079 ok(!ret
, "expected ERROR_SUCCESS got %u\n", ret
);
2081 for (aa
= ptr
; !ret
&& aa
; aa
= aa
->Next
)
2083 IP_ADAPTER_UNICAST_ADDRESS
*ua
;
2085 ua
= aa
->FirstUnicastAddress
;
2088 /* test with luid */
2089 memset( &row
, 0, sizeof(row
) );
2090 memcpy(&row
.InterfaceLuid
, &aa
->Luid
, sizeof(aa
->Luid
));
2091 memcpy(&row
.Address
, ua
->Address
.lpSockaddr
, ua
->Address
.iSockaddrLength
);
2092 ret
= pGetUnicastIpAddressEntry( &row
);
2093 ok( ret
== NO_ERROR
, "got %u\n", ret
);
2095 /* test with index */
2096 memset( &row
, 0, sizeof(row
) );
2097 row
.InterfaceIndex
= S(U(*aa
)).IfIndex
;
2098 memcpy(&row
.Address
, ua
->Address
.lpSockaddr
, ua
->Address
.iSockaddrLength
);
2099 ret
= pGetUnicastIpAddressEntry( &row
);
2100 ok( ret
== NO_ERROR
, "got %u\n", ret
);
2101 if (ret
== NO_ERROR
)
2103 ok(row
.InterfaceLuid
.Info
.Reserved
== aa
->Luid
.Info
.Reserved
, "Expected %d, got %d\n",
2104 aa
->Luid
.Info
.Reserved
, row
.InterfaceLuid
.Info
.Reserved
);
2105 ok(row
.InterfaceLuid
.Info
.NetLuidIndex
== aa
->Luid
.Info
.NetLuidIndex
, "Expected %d, got %d\n",
2106 aa
->Luid
.Info
.NetLuidIndex
, row
.InterfaceLuid
.Info
.NetLuidIndex
);
2107 ok(row
.InterfaceLuid
.Info
.IfType
== aa
->Luid
.Info
.IfType
, "Expected %d, got %d\n",
2108 aa
->Luid
.Info
.IfType
, row
.InterfaceLuid
.Info
.IfType
);
2109 ok(row
.InterfaceIndex
== S(U(*aa
)).IfIndex
, "Expected %d, got %d\n",
2110 S(U(*aa
)).IfIndex
, row
.InterfaceIndex
);
2111 ok(row
.PrefixOrigin
== ua
->PrefixOrigin
, "Expected %d, got %d\n",
2112 ua
->PrefixOrigin
, row
.PrefixOrigin
);
2113 ok(row
.SuffixOrigin
== ua
->SuffixOrigin
, "Expected %d, got %d\n",
2114 ua
->SuffixOrigin
, row
.SuffixOrigin
);
2115 ok(row
.ValidLifetime
== ua
->ValidLifetime
, "Expected %d, got %d\n",
2116 ua
->ValidLifetime
, row
.ValidLifetime
);
2117 ok(row
.PreferredLifetime
== ua
->PreferredLifetime
, "Expected %d, got %d\n",
2118 ua
->PreferredLifetime
, row
.PreferredLifetime
);
2119 ok(row
.OnLinkPrefixLength
== ua
->OnLinkPrefixLength
, "Expected %d, got %d\n",
2120 ua
->OnLinkPrefixLength
, row
.OnLinkPrefixLength
);
2121 ok(row
.SkipAsSource
== 0, "Expected 0, got %d\n", row
.SkipAsSource
);
2122 ok(row
.DadState
== ua
->DadState
, "Expected %d, got %d\n", ua
->DadState
, row
.DadState
);
2123 if (row
.Address
.si_family
== AF_INET6
)
2124 ok(row
.ScopeId
.Value
== row
.Address
.Ipv6
.sin6_scope_id
, "Expected %d, got %d\n",
2125 row
.Address
.Ipv6
.sin6_scope_id
, row
.ScopeId
.Value
);
2126 ok(row
.CreationTimeStamp
.QuadPart
, "CreationTimeStamp is 0\n");
2131 HeapFree(GetProcessHeap(), 0, ptr
);
2134 static void test_GetUnicastIpAddressTable(void)
2136 MIB_UNICASTIPADDRESS_TABLE
*table
;
2140 if (!pGetUnicastIpAddressTable
)
2142 win_skip( "GetUnicastIpAddressTable not available\n" );
2146 ret
= pGetUnicastIpAddressTable(AF_UNSPEC
, NULL
);
2147 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
2149 ret
= pGetUnicastIpAddressTable(AF_BAN
, &table
);
2150 ok( ret
== ERROR_INVALID_PARAMETER
, "got %u\n", ret
);
2152 ret
= pGetUnicastIpAddressTable(AF_INET
, &table
);
2153 ok( ret
== NO_ERROR
, "got %u\n", ret
);
2154 trace("GetUnicastIpAddressTable(AF_INET): NumEntries %u\n", table
->NumEntries
);
2155 pFreeMibTable(table
);
2157 ret
= pGetUnicastIpAddressTable(AF_INET6
, &table
);
2158 ok( ret
== NO_ERROR
, "got %u\n", ret
);
2159 trace("GetUnicastIpAddressTable(AF_INET6): NumEntries %u\n", table
->NumEntries
);
2160 pFreeMibTable(table
);
2162 ret
= pGetUnicastIpAddressTable(AF_UNSPEC
, &table
);
2163 ok( ret
== NO_ERROR
, "got %u\n", ret
);
2164 trace("GetUnicastIpAddressTable(AF_UNSPEC): NumEntries %u\n", table
->NumEntries
);
2165 for (i
= 0; i
< table
->NumEntries
&& winetest_debug
> 1; i
++)
2167 trace("Index %u:\n", i
);
2168 trace("Address.si_family: %u\n", table
->Table
[i
].Address
.si_family
);
2169 trace("InterfaceLuid.Info.Reserved: %u\n", table
->Table
[i
].InterfaceLuid
.Info
.Reserved
);
2170 trace("InterfaceLuid.Info.NetLuidIndex: %u\n", table
->Table
[i
].InterfaceLuid
.Info
.NetLuidIndex
);
2171 trace("InterfaceLuid.Info.IfType: %u\n", table
->Table
[i
].InterfaceLuid
.Info
.IfType
);
2172 trace("InterfaceIndex: %u\n", table
->Table
[i
].InterfaceIndex
);
2173 trace("PrefixOrigin: %u\n", table
->Table
[i
].PrefixOrigin
);
2174 trace("SuffixOrigin: %u\n", table
->Table
[i
].SuffixOrigin
);
2175 trace("ValidLifetime: %u seconds\n", table
->Table
[i
].ValidLifetime
);
2176 trace("PreferredLifetime: %u seconds\n", table
->Table
[i
].PreferredLifetime
);
2177 trace("OnLinkPrefixLength: %u\n", table
->Table
[i
].OnLinkPrefixLength
);
2178 trace("SkipAsSource: %u\n", table
->Table
[i
].SkipAsSource
);
2179 trace("DadState: %u\n", table
->Table
[i
].DadState
);
2180 trace("ScopeId.Value: %u\n", table
->Table
[i
].ScopeId
.Value
);
2181 trace("CreationTimeStamp: %08x%08x\n", table
->Table
[i
].CreationTimeStamp
.HighPart
, table
->Table
[i
].CreationTimeStamp
.LowPart
);
2184 pFreeMibTable(table
);
2187 START_TEST(iphlpapi
)
2194 testWin98OnlyFunctions();
2195 testWinNT4Functions();
2197 /* run testGetXXXX in two threads at once to make sure we don't crash in that case */
2198 thread
= CreateThread(NULL
, 0, testWin98Functions
, NULL
, 0, NULL
);
2199 testWin98Functions(NULL
);
2200 WaitForSingleObject(thread
, INFINITE
);
2202 testWin2KFunctions();
2203 test_GetAdaptersAddresses();
2204 test_GetExtendedTcpTable();
2205 test_GetExtendedUdpTable();
2206 test_AllocateAndGetTcpExTableFromStack();
2207 test_CreateSortedAddressPairs();
2208 test_interface_identifier_conversion();
2211 test_GetUnicastIpAddressEntry();
2212 test_GetUnicastIpAddressTable();