[IPHLPAPI_WINETEST] Import htonl and co from ws2_32 instead of hacking things locally...
[reactos.git] / rostests / winetests / iphlpapi / iphlpapi.c
1 /*
2 * iphlpapi dll test
3 *
4 * Copyright (C) 2003 Juan Lang
5 *
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.
10 *
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.
15 *
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
19 */
20
21 /*
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).
28 *
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.
33 *
34 * The DomainName field of FIXED_INFO isn't NULL-terminated on Win98.
35 */
36
37 #include <stdarg.h>
38 #include "winsock2.h"
39 #include "windef.h"
40 #include "winbase.h"
41 #include "ws2tcpip.h"
42 #include "iphlpapi.h"
43 #include "iprtrmib.h"
44 #include "netioapi.h"
45 #include "wine/test.h"
46 #include <stdio.h>
47 #include <stdlib.h>
48
49 #define ICMP_MINLEN 8 /* copied from dlls/iphlpapi/ip_icmp.h file */
50
51 static HMODULE hLibrary = NULL;
52
53 static DWORD (WINAPI *pGetNumberOfInterfaces)(PDWORD);
54 static DWORD (WINAPI *pGetIpAddrTable)(PMIB_IPADDRTABLE,PULONG,BOOL);
55 static DWORD (WINAPI *pGetIfEntry)(PMIB_IFROW);
56 static DWORD (WINAPI *pGetIfEntry2)(PMIB_IF_ROW2);
57 static DWORD (WINAPI *pGetFriendlyIfIndex)(DWORD);
58 static DWORD (WINAPI *pGetIfTable)(PMIB_IFTABLE,PULONG,BOOL);
59 static DWORD (WINAPI *pGetIfTable2)(PMIB_IF_TABLE2*);
60 static DWORD (WINAPI *pGetIpForwardTable)(PMIB_IPFORWARDTABLE,PULONG,BOOL);
61 static DWORD (WINAPI *pGetIpNetTable)(PMIB_IPNETTABLE,PULONG,BOOL);
62 static DWORD (WINAPI *pGetInterfaceInfo)(PIP_INTERFACE_INFO,PULONG);
63 static DWORD (WINAPI *pGetAdaptersInfo)(PIP_ADAPTER_INFO,PULONG);
64 static DWORD (WINAPI *pGetNetworkParams)(PFIXED_INFO,PULONG);
65 static DWORD (WINAPI *pGetIcmpStatistics)(PMIB_ICMP);
66 static DWORD (WINAPI *pGetIpStatistics)(PMIB_IPSTATS);
67 static DWORD (WINAPI *pGetTcpStatistics)(PMIB_TCPSTATS);
68 static DWORD (WINAPI *pGetUdpStatistics)(PMIB_UDPSTATS);
69 static DWORD (WINAPI *pGetIcmpStatisticsEx)(PMIB_ICMP_EX,DWORD);
70 static DWORD (WINAPI *pGetIpStatisticsEx)(PMIB_IPSTATS,DWORD);
71 static DWORD (WINAPI *pGetTcpStatisticsEx)(PMIB_TCPSTATS,DWORD);
72 static DWORD (WINAPI *pGetUdpStatisticsEx)(PMIB_UDPSTATS,DWORD);
73 static DWORD (WINAPI *pGetTcpTable)(PMIB_TCPTABLE,PDWORD,BOOL);
74 static DWORD (WINAPI *pGetUdpTable)(PMIB_UDPTABLE,PDWORD,BOOL);
75 static DWORD (WINAPI *pGetPerAdapterInfo)(ULONG,PIP_PER_ADAPTER_INFO,PULONG);
76 static DWORD (WINAPI *pGetAdaptersAddresses)(ULONG,ULONG,PVOID,PIP_ADAPTER_ADDRESSES,PULONG);
77 static DWORD (WINAPI *pNotifyAddrChange)(PHANDLE,LPOVERLAPPED);
78 static BOOL (WINAPI *pCancelIPChangeNotify)(LPOVERLAPPED);
79 static DWORD (WINAPI *pGetExtendedTcpTable)(PVOID,PDWORD,BOOL,ULONG,TCP_TABLE_CLASS,ULONG);
80 static DWORD (WINAPI *pGetExtendedUdpTable)(PVOID,PDWORD,BOOL,ULONG,UDP_TABLE_CLASS,ULONG);
81 static DWORD (WINAPI *pSetTcpEntry)(PMIB_TCPROW);
82 static HANDLE(WINAPI *pIcmpCreateFile)(VOID);
83 static DWORD (WINAPI *pIcmpSendEcho)(HANDLE,IPAddr,LPVOID,WORD,PIP_OPTION_INFORMATION,LPVOID,DWORD,DWORD);
84 static DWORD (WINAPI *pCreateSortedAddressPairs)(const PSOCKADDR_IN6,ULONG,const PSOCKADDR_IN6,ULONG,ULONG,
85 PSOCKADDR_IN6_PAIR*,ULONG*);
86 static void (WINAPI *pFreeMibTable)(void*);
87 static DWORD (WINAPI *pConvertInterfaceGuidToLuid)(const GUID*,NET_LUID*);
88 static DWORD (WINAPI *pConvertInterfaceIndexToLuid)(NET_IFINDEX,NET_LUID*);
89 static DWORD (WINAPI *pConvertInterfaceLuidToGuid)(const NET_LUID*,GUID*);
90 static DWORD (WINAPI *pConvertInterfaceLuidToIndex)(const NET_LUID*,NET_IFINDEX*);
91 static DWORD (WINAPI *pConvertInterfaceLuidToNameW)(const NET_LUID*,WCHAR*,SIZE_T);
92 static DWORD (WINAPI *pConvertInterfaceLuidToNameA)(const NET_LUID*,char*,SIZE_T);
93 static DWORD (WINAPI *pConvertInterfaceNameToLuidA)(const char*,NET_LUID*);
94 static DWORD (WINAPI *pConvertInterfaceNameToLuidW)(const WCHAR*,NET_LUID*);
95
96 static void loadIPHlpApi(void)
97 {
98 hLibrary = LoadLibraryA("iphlpapi.dll");
99 if (hLibrary) {
100 pGetNumberOfInterfaces = (void *)GetProcAddress(hLibrary, "GetNumberOfInterfaces");
101 pGetIpAddrTable = (void *)GetProcAddress(hLibrary, "GetIpAddrTable");
102 pGetIfEntry = (void *)GetProcAddress(hLibrary, "GetIfEntry");
103 pGetIfEntry2 = (void *)GetProcAddress(hLibrary, "GetIfEntry2");
104 pGetFriendlyIfIndex = (void *)GetProcAddress(hLibrary, "GetFriendlyIfIndex");
105 pGetIfTable = (void *)GetProcAddress(hLibrary, "GetIfTable");
106 pGetIfTable2 = (void *)GetProcAddress(hLibrary, "GetIfTable2");
107 pGetIpForwardTable = (void *)GetProcAddress(hLibrary, "GetIpForwardTable");
108 pGetIpNetTable = (void *)GetProcAddress(hLibrary, "GetIpNetTable");
109 pGetInterfaceInfo = (void *)GetProcAddress(hLibrary, "GetInterfaceInfo");
110 pGetAdaptersInfo = (void *)GetProcAddress(hLibrary, "GetAdaptersInfo");
111 pGetNetworkParams = (void *)GetProcAddress(hLibrary, "GetNetworkParams");
112 pGetIcmpStatistics = (void *)GetProcAddress(hLibrary, "GetIcmpStatistics");
113 pGetIpStatistics = (void *)GetProcAddress(hLibrary, "GetIpStatistics");
114 pGetTcpStatistics = (void *)GetProcAddress(hLibrary, "GetTcpStatistics");
115 pGetUdpStatistics = (void *)GetProcAddress(hLibrary, "GetUdpStatistics");
116 pGetIcmpStatisticsEx = (void *)GetProcAddress(hLibrary, "GetIcmpStatisticsEx");
117 pGetIpStatisticsEx = (void *)GetProcAddress(hLibrary, "GetIpStatisticsEx");
118 pGetTcpStatisticsEx = (void *)GetProcAddress(hLibrary, "GetTcpStatisticsEx");
119 pGetUdpStatisticsEx = (void *)GetProcAddress(hLibrary, "GetUdpStatisticsEx");
120 pGetTcpTable = (void *)GetProcAddress(hLibrary, "GetTcpTable");
121 pGetUdpTable = (void *)GetProcAddress(hLibrary, "GetUdpTable");
122 pGetPerAdapterInfo = (void *)GetProcAddress(hLibrary, "GetPerAdapterInfo");
123 pGetAdaptersAddresses = (void *)GetProcAddress(hLibrary, "GetAdaptersAddresses");
124 pNotifyAddrChange = (void *)GetProcAddress(hLibrary, "NotifyAddrChange");
125 pCancelIPChangeNotify = (void *)GetProcAddress(hLibrary, "CancelIPChangeNotify");
126 pGetExtendedTcpTable = (void *)GetProcAddress(hLibrary, "GetExtendedTcpTable");
127 pGetExtendedUdpTable = (void *)GetProcAddress(hLibrary, "GetExtendedUdpTable");
128 pSetTcpEntry = (void *)GetProcAddress(hLibrary, "SetTcpEntry");
129 pIcmpCreateFile = (void *)GetProcAddress(hLibrary, "IcmpCreateFile");
130 pIcmpSendEcho = (void *)GetProcAddress(hLibrary, "IcmpSendEcho");
131 pCreateSortedAddressPairs = (void *)GetProcAddress(hLibrary, "CreateSortedAddressPairs");
132 pFreeMibTable = (void *)GetProcAddress(hLibrary, "FreeMibTable");
133 pConvertInterfaceGuidToLuid = (void *)GetProcAddress(hLibrary, "ConvertInterfaceGuidToLuid");
134 pConvertInterfaceIndexToLuid = (void *)GetProcAddress(hLibrary, "ConvertInterfaceIndexToLuid");
135 pConvertInterfaceLuidToGuid = (void *)GetProcAddress(hLibrary, "ConvertInterfaceLuidToGuid");
136 pConvertInterfaceLuidToIndex = (void *)GetProcAddress(hLibrary, "ConvertInterfaceLuidToIndex");
137 pConvertInterfaceLuidToNameA = (void *)GetProcAddress(hLibrary, "ConvertInterfaceLuidToNameA");
138 pConvertInterfaceLuidToNameW = (void *)GetProcAddress(hLibrary, "ConvertInterfaceLuidToNameW");
139 pConvertInterfaceNameToLuidA = (void *)GetProcAddress(hLibrary, "ConvertInterfaceNameToLuidA");
140 pConvertInterfaceNameToLuidW = (void *)GetProcAddress(hLibrary, "ConvertInterfaceNameToLuidW");
141 }
142 }
143
144 static void freeIPHlpApi(void)
145 {
146 FreeLibrary(hLibrary);
147 }
148
149 /* replacement for inet_ntoa */
150 static const char *ntoa( DWORD ip )
151 {
152 static char buffer[40];
153
154 ip = htonl(ip);
155 sprintf( buffer, "%u.%u.%u.%u", (ip >> 24) & 0xff, (ip >> 16) & 0xff, (ip >> 8) & 0xff, ip & 0xff );
156 return buffer;
157 }
158
159 static inline const char* debugstr_longlong(ULONGLONG ll)
160 {
161 static char string[17];
162 if (sizeof(ll) > sizeof(unsigned long) && ll >> 32)
163 sprintf(string, "%lx%08lx", (unsigned long)(ll >> 32), (unsigned long)ll);
164 else
165 sprintf(string, "%lx", (unsigned long)ll);
166 return string;
167 }
168
169 /*
170 still-to-be-tested 98-only functions:
171 GetUniDirectionalAdapterInfo
172 */
173 static void testWin98OnlyFunctions(void)
174 {
175 }
176
177 static void testGetNumberOfInterfaces(void)
178 {
179 if (pGetNumberOfInterfaces) {
180 DWORD apiReturn, numInterfaces;
181
182 /* Crashes on Vista */
183 if (0) {
184 apiReturn = pGetNumberOfInterfaces(NULL);
185 if (apiReturn == ERROR_NOT_SUPPORTED)
186 return;
187 ok(apiReturn == ERROR_INVALID_PARAMETER,
188 "GetNumberOfInterfaces(NULL) returned %d, expected ERROR_INVALID_PARAMETER\n",
189 apiReturn);
190 }
191
192 apiReturn = pGetNumberOfInterfaces(&numInterfaces);
193 if (apiReturn == ERROR_NOT_SUPPORTED) {
194 skip("GetNumberOfInterfaces is not supported\n");
195 return;
196 }
197 ok(apiReturn == NO_ERROR,
198 "GetNumberOfInterfaces returned %d, expected 0\n", apiReturn);
199 }
200 }
201
202 static void testGetIfEntry(DWORD index)
203 {
204 if (pGetIfEntry) {
205 DWORD apiReturn;
206 MIB_IFROW row;
207
208 memset(&row, 0, sizeof(row));
209 apiReturn = pGetIfEntry(NULL);
210 if (apiReturn == ERROR_NOT_SUPPORTED) {
211 skip("GetIfEntry is not supported\n");
212 return;
213 }
214 ok(apiReturn == ERROR_INVALID_PARAMETER,
215 "GetIfEntry(NULL) returned %d, expected ERROR_INVALID_PARAMETER\n",
216 apiReturn);
217 row.dwIndex = -1; /* hope that's always bogus! */
218 apiReturn = pGetIfEntry(&row);
219 ok(apiReturn == ERROR_INVALID_DATA ||
220 apiReturn == ERROR_FILE_NOT_FOUND /* Vista */,
221 "GetIfEntry(bogus row) returned %d, expected ERROR_INVALID_DATA or ERROR_FILE_NOT_FOUND\n",
222 apiReturn);
223 row.dwIndex = index;
224 apiReturn = pGetIfEntry(&row);
225 ok(apiReturn == NO_ERROR,
226 "GetIfEntry returned %d, expected NO_ERROR\n", apiReturn);
227 }
228 }
229
230 static void testGetIpAddrTable(void)
231 {
232 if (pGetIpAddrTable) {
233 DWORD apiReturn;
234 ULONG dwSize = 0;
235
236 apiReturn = pGetIpAddrTable(NULL, NULL, FALSE);
237 if (apiReturn == ERROR_NOT_SUPPORTED) {
238 skip("GetIpAddrTable is not supported\n");
239 return;
240 }
241 ok(apiReturn == ERROR_INVALID_PARAMETER,
242 "GetIpAddrTable(NULL, NULL, FALSE) returned %d, expected ERROR_INVALID_PARAMETER\n",
243 apiReturn);
244 apiReturn = pGetIpAddrTable(NULL, &dwSize, FALSE);
245 ok(apiReturn == ERROR_INSUFFICIENT_BUFFER,
246 "GetIpAddrTable(NULL, &dwSize, FALSE) returned %d, expected ERROR_INSUFFICIENT_BUFFER\n",
247 apiReturn);
248 if (apiReturn == ERROR_INSUFFICIENT_BUFFER) {
249 PMIB_IPADDRTABLE buf = HeapAlloc(GetProcessHeap(), 0, dwSize);
250
251 apiReturn = pGetIpAddrTable(buf, &dwSize, FALSE);
252 ok(apiReturn == NO_ERROR,
253 "GetIpAddrTable(buf, &dwSize, FALSE) returned %d, expected NO_ERROR\n",
254 apiReturn);
255 if (apiReturn == NO_ERROR && buf->dwNumEntries)
256 {
257 int i;
258 testGetIfEntry(buf->table[0].dwIndex);
259 for (i = 0; i < buf->dwNumEntries; i++)
260 {
261 ok (buf->table[i].wType != 0, "Test[%d]: expected wType > 0\n", i);
262 trace("Entry[%d]: addr %s, dwIndex %u, wType 0x%x\n", i,
263 ntoa(buf->table[i].dwAddr), buf->table[i].dwIndex, buf->table[i].wType);
264 }
265 }
266 HeapFree(GetProcessHeap(), 0, buf);
267 }
268 }
269 }
270
271 static void testGetIfTable(void)
272 {
273 if (pGetIfTable) {
274 DWORD apiReturn;
275 ULONG dwSize = 0;
276
277 apiReturn = pGetIfTable(NULL, NULL, FALSE);
278 if (apiReturn == ERROR_NOT_SUPPORTED) {
279 skip("GetIfTable is not supported\n");
280 return;
281 }
282 ok(apiReturn == ERROR_INVALID_PARAMETER,
283 "GetIfTable(NULL, NULL, FALSE) returned %d, expected ERROR_INVALID_PARAMETER\n",
284 apiReturn);
285 apiReturn = pGetIfTable(NULL, &dwSize, FALSE);
286 ok(apiReturn == ERROR_INSUFFICIENT_BUFFER,
287 "GetIfTable(NULL, &dwSize, FALSE) returned %d, expected ERROR_INSUFFICIENT_BUFFER\n",
288 apiReturn);
289 if (apiReturn == ERROR_INSUFFICIENT_BUFFER) {
290 PMIB_IFTABLE buf = HeapAlloc(GetProcessHeap(), 0, dwSize);
291
292 apiReturn = pGetIfTable(buf, &dwSize, FALSE);
293 ok(apiReturn == NO_ERROR,
294 "GetIfTable(buf, &dwSize, FALSE) returned %d, expected NO_ERROR\n\n",
295 apiReturn);
296
297 if (apiReturn == NO_ERROR && winetest_debug > 1)
298 {
299 DWORD i, j;
300 char name[MAX_INTERFACE_NAME_LEN];
301
302 trace( "interface table: %u entries\n", buf->dwNumEntries );
303 for (i = 0; i < buf->dwNumEntries; i++)
304 {
305 MIB_IFROW *row = &buf->table[i];
306 WideCharToMultiByte( CP_ACP, 0, row->wszName, -1, name, MAX_INTERFACE_NAME_LEN, NULL, NULL );
307 trace( "%u: '%s' type %u mtu %u speed %u phys",
308 row->dwIndex, name, row->dwType, row->dwMtu, row->dwSpeed );
309 for (j = 0; j < row->dwPhysAddrLen; j++)
310 printf( " %02x", row->bPhysAddr[j] );
311 printf( "\n" );
312 trace( " in: bytes %u upkts %u nupkts %u disc %u err %u unk %u\n",
313 row->dwInOctets, row->dwInUcastPkts, row->dwInNUcastPkts,
314 row->dwInDiscards, row->dwInErrors, row->dwInUnknownProtos );
315 trace( " out: bytes %u upkts %u nupkts %u disc %u err %u\n",
316 row->dwOutOctets, row->dwOutUcastPkts, row->dwOutNUcastPkts,
317 row->dwOutDiscards, row->dwOutErrors );
318 }
319 }
320 HeapFree(GetProcessHeap(), 0, buf);
321 }
322 }
323 }
324
325 static void testGetIpForwardTable(void)
326 {
327 if (pGetIpForwardTable) {
328 DWORD apiReturn;
329 ULONG dwSize = 0;
330
331 apiReturn = pGetIpForwardTable(NULL, NULL, FALSE);
332 if (apiReturn == ERROR_NOT_SUPPORTED) {
333 skip("GetIpForwardTable is not supported\n");
334 return;
335 }
336 ok(apiReturn == ERROR_INVALID_PARAMETER,
337 "GetIpForwardTable(NULL, NULL, FALSE) returned %d, expected ERROR_INVALID_PARAMETER\n",
338 apiReturn);
339 apiReturn = pGetIpForwardTable(NULL, &dwSize, FALSE);
340 ok(apiReturn == ERROR_INSUFFICIENT_BUFFER,
341 "GetIpForwardTable(NULL, &dwSize, FALSE) returned %d, expected ERROR_INSUFFICIENT_BUFFER\n",
342 apiReturn);
343 if (apiReturn == ERROR_INSUFFICIENT_BUFFER) {
344 PMIB_IPFORWARDTABLE buf = HeapAlloc(GetProcessHeap(), 0, dwSize);
345
346 apiReturn = pGetIpForwardTable(buf, &dwSize, FALSE);
347 ok(apiReturn == NO_ERROR,
348 "GetIpForwardTable(buf, &dwSize, FALSE) returned %d, expected NO_ERROR\n",
349 apiReturn);
350
351 if (apiReturn == NO_ERROR && winetest_debug > 1)
352 {
353 DWORD i;
354
355 trace( "IP forward table: %u entries\n", buf->dwNumEntries );
356 for (i = 0; i < buf->dwNumEntries; i++)
357 {
358 char buffer[100];
359 sprintf( buffer, "dest %s", ntoa( buf->table[i].dwForwardDest ));
360 sprintf( buffer + strlen(buffer), " mask %s", ntoa( buf->table[i].dwForwardMask ));
361 trace( "%u: %s gw %s if %u type %u\n", i, buffer,
362 ntoa( buf->table[i].dwForwardNextHop ),
363 buf->table[i].dwForwardIfIndex, U1(buf->table[i]).dwForwardType );
364 }
365 }
366 HeapFree(GetProcessHeap(), 0, buf);
367 }
368 }
369 }
370
371 static void testGetIpNetTable(void)
372 {
373 if (pGetIpNetTable) {
374 DWORD apiReturn;
375 ULONG dwSize = 0;
376
377 apiReturn = pGetIpNetTable(NULL, NULL, FALSE);
378 if (apiReturn == ERROR_NOT_SUPPORTED) {
379 skip("GetIpNetTable is not supported\n");
380 return;
381 }
382 ok(apiReturn == ERROR_INVALID_PARAMETER,
383 "GetIpNetTable(NULL, NULL, FALSE) returned %d, expected ERROR_INVALID_PARAMETER\n",
384 apiReturn);
385 apiReturn = pGetIpNetTable(NULL, &dwSize, FALSE);
386 ok(apiReturn == ERROR_NO_DATA || apiReturn == ERROR_INSUFFICIENT_BUFFER,
387 "GetIpNetTable(NULL, &dwSize, FALSE) returned %d, expected ERROR_NO_DATA or ERROR_INSUFFICIENT_BUFFER\n",
388 apiReturn);
389 if (apiReturn == ERROR_NO_DATA)
390 ; /* empty ARP table's okay */
391 else if (apiReturn == ERROR_INSUFFICIENT_BUFFER) {
392 PMIB_IPNETTABLE buf = HeapAlloc(GetProcessHeap(), 0, dwSize);
393
394 apiReturn = pGetIpNetTable(buf, &dwSize, FALSE);
395 ok(apiReturn == NO_ERROR ||
396 apiReturn == ERROR_NO_DATA, /* empty ARP table's okay */
397 "GetIpNetTable(buf, &dwSize, FALSE) returned %d, expected NO_ERROR\n",
398 apiReturn);
399
400 if (apiReturn == NO_ERROR && winetest_debug > 1)
401 {
402 DWORD i, j;
403
404 trace( "IP net table: %u entries\n", buf->dwNumEntries );
405 for (i = 0; i < buf->dwNumEntries; i++)
406 {
407 trace( "%u: idx %u type %u addr %s phys",
408 i, buf->table[i].dwIndex, U(buf->table[i]).dwType, ntoa( buf->table[i].dwAddr ));
409 for (j = 0; j < buf->table[i].dwPhysAddrLen; j++)
410 printf( " %02x", buf->table[i].bPhysAddr[j] );
411 printf( "\n" );
412 }
413 }
414 HeapFree(GetProcessHeap(), 0, buf);
415 }
416 }
417 }
418
419 static void testGetIcmpStatistics(void)
420 {
421 if (pGetIcmpStatistics) {
422 DWORD apiReturn;
423 MIB_ICMP stats;
424
425 /* Crashes on Vista */
426 if (0) {
427 apiReturn = pGetIcmpStatistics(NULL);
428 if (apiReturn == ERROR_NOT_SUPPORTED)
429 return;
430 ok(apiReturn == ERROR_INVALID_PARAMETER,
431 "GetIcmpStatistics(NULL) returned %d, expected ERROR_INVALID_PARAMETER\n",
432 apiReturn);
433 }
434
435 apiReturn = pGetIcmpStatistics(&stats);
436 if (apiReturn == ERROR_NOT_SUPPORTED)
437 {
438 skip("GetIcmpStatistics is not supported\n");
439 return;
440 }
441 ok(apiReturn == NO_ERROR,
442 "GetIcmpStatistics returned %d, expected NO_ERROR\n", apiReturn);
443 if (apiReturn == NO_ERROR && winetest_debug > 1)
444 {
445 trace( "ICMP stats: %8s %8s\n", "in", "out" );
446 trace( " dwMsgs: %8u %8u\n", stats.stats.icmpInStats.dwMsgs, stats.stats.icmpOutStats.dwMsgs );
447 trace( " dwErrors: %8u %8u\n", stats.stats.icmpInStats.dwErrors, stats.stats.icmpOutStats.dwErrors );
448 trace( " dwDestUnreachs: %8u %8u\n", stats.stats.icmpInStats.dwDestUnreachs, stats.stats.icmpOutStats.dwDestUnreachs );
449 trace( " dwTimeExcds: %8u %8u\n", stats.stats.icmpInStats.dwTimeExcds, stats.stats.icmpOutStats.dwTimeExcds );
450 trace( " dwParmProbs: %8u %8u\n", stats.stats.icmpInStats.dwParmProbs, stats.stats.icmpOutStats.dwParmProbs );
451 trace( " dwSrcQuenchs: %8u %8u\n", stats.stats.icmpInStats.dwSrcQuenchs, stats.stats.icmpOutStats.dwSrcQuenchs );
452 trace( " dwRedirects: %8u %8u\n", stats.stats.icmpInStats.dwRedirects, stats.stats.icmpOutStats.dwRedirects );
453 trace( " dwEchos: %8u %8u\n", stats.stats.icmpInStats.dwEchos, stats.stats.icmpOutStats.dwEchos );
454 trace( " dwEchoReps: %8u %8u\n", stats.stats.icmpInStats.dwEchoReps, stats.stats.icmpOutStats.dwEchoReps );
455 trace( " dwTimestamps: %8u %8u\n", stats.stats.icmpInStats.dwTimestamps, stats.stats.icmpOutStats.dwTimestamps );
456 trace( " dwTimestampReps: %8u %8u\n", stats.stats.icmpInStats.dwTimestampReps, stats.stats.icmpOutStats.dwTimestampReps );
457 trace( " dwAddrMasks: %8u %8u\n", stats.stats.icmpInStats.dwAddrMasks, stats.stats.icmpOutStats.dwAddrMasks );
458 trace( " dwAddrMaskReps: %8u %8u\n", stats.stats.icmpInStats.dwAddrMaskReps, stats.stats.icmpOutStats.dwAddrMaskReps );
459 }
460 }
461 }
462
463 static void testGetIpStatistics(void)
464 {
465 if (pGetIpStatistics) {
466 DWORD apiReturn;
467 MIB_IPSTATS stats;
468
469 apiReturn = pGetIpStatistics(NULL);
470 if (apiReturn == ERROR_NOT_SUPPORTED) {
471 skip("GetIpStatistics is not supported\n");
472 return;
473 }
474 ok(apiReturn == ERROR_INVALID_PARAMETER,
475 "GetIpStatistics(NULL) returned %d, expected ERROR_INVALID_PARAMETER\n",
476 apiReturn);
477 apiReturn = pGetIpStatistics(&stats);
478 ok(apiReturn == NO_ERROR,
479 "GetIpStatistics returned %d, expected NO_ERROR\n", apiReturn);
480 if (apiReturn == NO_ERROR && winetest_debug > 1)
481 {
482 trace( "IP stats:\n" );
483 trace( " dwForwarding: %u\n", U(stats).dwForwarding );
484 trace( " dwDefaultTTL: %u\n", stats.dwDefaultTTL );
485 trace( " dwInReceives: %u\n", stats.dwInReceives );
486 trace( " dwInHdrErrors: %u\n", stats.dwInHdrErrors );
487 trace( " dwInAddrErrors: %u\n", stats.dwInAddrErrors );
488 trace( " dwForwDatagrams: %u\n", stats.dwForwDatagrams );
489 trace( " dwInUnknownProtos: %u\n", stats.dwInUnknownProtos );
490 trace( " dwInDiscards: %u\n", stats.dwInDiscards );
491 trace( " dwInDelivers: %u\n", stats.dwInDelivers );
492 trace( " dwOutRequests: %u\n", stats.dwOutRequests );
493 trace( " dwRoutingDiscards: %u\n", stats.dwRoutingDiscards );
494 trace( " dwOutDiscards: %u\n", stats.dwOutDiscards );
495 trace( " dwOutNoRoutes: %u\n", stats.dwOutNoRoutes );
496 trace( " dwReasmTimeout: %u\n", stats.dwReasmTimeout );
497 trace( " dwReasmReqds: %u\n", stats.dwReasmReqds );
498 trace( " dwReasmOks: %u\n", stats.dwReasmOks );
499 trace( " dwReasmFails: %u\n", stats.dwReasmFails );
500 trace( " dwFragOks: %u\n", stats.dwFragOks );
501 trace( " dwFragFails: %u\n", stats.dwFragFails );
502 trace( " dwFragCreates: %u\n", stats.dwFragCreates );
503 trace( " dwNumIf: %u\n", stats.dwNumIf );
504 trace( " dwNumAddr: %u\n", stats.dwNumAddr );
505 trace( " dwNumRoutes: %u\n", stats.dwNumRoutes );
506 }
507 }
508 }
509
510 static void testGetTcpStatistics(void)
511 {
512 if (pGetTcpStatistics) {
513 DWORD apiReturn;
514 MIB_TCPSTATS stats;
515
516 apiReturn = pGetTcpStatistics(NULL);
517 if (apiReturn == ERROR_NOT_SUPPORTED) {
518 skip("GetTcpStatistics is not supported\n");
519 return;
520 }
521 ok(apiReturn == ERROR_INVALID_PARAMETER,
522 "GetTcpStatistics(NULL) returned %d, expected ERROR_INVALID_PARAMETER\n",
523 apiReturn);
524 apiReturn = pGetTcpStatistics(&stats);
525 ok(apiReturn == NO_ERROR,
526 "GetTcpStatistics returned %d, expected NO_ERROR\n", apiReturn);
527 if (apiReturn == NO_ERROR && winetest_debug > 1)
528 {
529 trace( "TCP stats:\n" );
530 trace( " dwRtoAlgorithm: %u\n", U(stats).dwRtoAlgorithm );
531 trace( " dwRtoMin: %u\n", stats.dwRtoMin );
532 trace( " dwRtoMax: %u\n", stats.dwRtoMax );
533 trace( " dwMaxConn: %u\n", stats.dwMaxConn );
534 trace( " dwActiveOpens: %u\n", stats.dwActiveOpens );
535 trace( " dwPassiveOpens: %u\n", stats.dwPassiveOpens );
536 trace( " dwAttemptFails: %u\n", stats.dwAttemptFails );
537 trace( " dwEstabResets: %u\n", stats.dwEstabResets );
538 trace( " dwCurrEstab: %u\n", stats.dwCurrEstab );
539 trace( " dwInSegs: %u\n", stats.dwInSegs );
540 trace( " dwOutSegs: %u\n", stats.dwOutSegs );
541 trace( " dwRetransSegs: %u\n", stats.dwRetransSegs );
542 trace( " dwInErrs: %u\n", stats.dwInErrs );
543 trace( " dwOutRsts: %u\n", stats.dwOutRsts );
544 trace( " dwNumConns: %u\n", stats.dwNumConns );
545 }
546 }
547 }
548
549 static void testGetUdpStatistics(void)
550 {
551 if (pGetUdpStatistics) {
552 DWORD apiReturn;
553 MIB_UDPSTATS stats;
554
555 apiReturn = pGetUdpStatistics(NULL);
556 if (apiReturn == ERROR_NOT_SUPPORTED) {
557 skip("GetUdpStatistics is not supported\n");
558 return;
559 }
560 ok(apiReturn == ERROR_INVALID_PARAMETER,
561 "GetUdpStatistics(NULL) returned %d, expected ERROR_INVALID_PARAMETER\n",
562 apiReturn);
563 apiReturn = pGetUdpStatistics(&stats);
564 ok(apiReturn == NO_ERROR,
565 "GetUdpStatistics returned %d, expected NO_ERROR\n", apiReturn);
566 if (apiReturn == NO_ERROR && winetest_debug > 1)
567 {
568 trace( "UDP stats:\n" );
569 trace( " dwInDatagrams: %u\n", stats.dwInDatagrams );
570 trace( " dwNoPorts: %u\n", stats.dwNoPorts );
571 trace( " dwInErrors: %u\n", stats.dwInErrors );
572 trace( " dwOutDatagrams: %u\n", stats.dwOutDatagrams );
573 trace( " dwNumAddrs: %u\n", stats.dwNumAddrs );
574 }
575 }
576 }
577
578 static void testGetIcmpStatisticsEx(void)
579 {
580 DWORD apiReturn;
581 MIB_ICMP_EX stats;
582
583 if (!pGetIcmpStatisticsEx)
584 {
585 win_skip( "GetIcmpStatisticsEx not available\n" );
586 return;
587 }
588
589 /* Crashes on Vista */
590 if (1) {
591 apiReturn = pGetIcmpStatisticsEx(NULL, AF_INET);
592 ok(apiReturn == ERROR_INVALID_PARAMETER,
593 "GetIcmpStatisticsEx(NULL, AF_INET) returned %d, expected ERROR_INVALID_PARAMETER\n", apiReturn);
594 }
595
596 apiReturn = pGetIcmpStatisticsEx(&stats, AF_BAN);
597 ok(apiReturn == ERROR_INVALID_PARAMETER,
598 "GetIcmpStatisticsEx(&stats, AF_BAN) returned %d, expected ERROR_INVALID_PARAMETER\n", apiReturn);
599
600 apiReturn = pGetIcmpStatisticsEx(&stats, AF_INET);
601 ok(apiReturn == NO_ERROR, "GetIcmpStatisticsEx returned %d, expected NO_ERROR\n", apiReturn);
602 if (apiReturn == NO_ERROR && winetest_debug > 1)
603 {
604 INT i;
605 trace( "ICMP IPv4 Ex stats: %8s %8s\n", "in", "out" );
606 trace( " dwMsgs: %8u %8u\n", stats.icmpInStats.dwMsgs, stats.icmpOutStats.dwMsgs );
607 trace( " dwErrors: %8u %8u\n", stats.icmpInStats.dwErrors, stats.icmpOutStats.dwErrors );
608 for (i = 0; i < 256; i++)
609 trace( " rgdwTypeCount[%3i]: %8u %8u\n", i, stats.icmpInStats.rgdwTypeCount[i], stats.icmpOutStats.rgdwTypeCount[i] );
610 }
611
612 apiReturn = pGetIcmpStatisticsEx(&stats, AF_INET6);
613 ok(apiReturn == NO_ERROR || broken(apiReturn == ERROR_NOT_SUPPORTED),
614 "GetIcmpStatisticsEx returned %d, expected NO_ERROR\n", apiReturn);
615 if (apiReturn == NO_ERROR && winetest_debug > 1)
616 {
617 INT i;
618 trace( "ICMP IPv6 Ex stats: %8s %8s\n", "in", "out" );
619 trace( " dwMsgs: %8u %8u\n", stats.icmpInStats.dwMsgs, stats.icmpOutStats.dwMsgs );
620 trace( " dwErrors: %8u %8u\n", stats.icmpInStats.dwErrors, stats.icmpOutStats.dwErrors );
621 for (i = 0; i < 256; i++)
622 trace( " rgdwTypeCount[%3i]: %8u %8u\n", i, stats.icmpInStats.rgdwTypeCount[i], stats.icmpOutStats.rgdwTypeCount[i] );
623 }
624 }
625
626 static void testGetIpStatisticsEx(void)
627 {
628 DWORD apiReturn;
629 MIB_IPSTATS stats;
630
631 if (!pGetIpStatisticsEx)
632 {
633 win_skip( "GetIpStatisticsEx not available\n" );
634 return;
635 }
636
637 apiReturn = pGetIpStatisticsEx(NULL, AF_INET);
638 ok(apiReturn == ERROR_INVALID_PARAMETER,
639 "GetIpStatisticsEx(NULL, AF_INET) returned %d, expected ERROR_INVALID_PARAMETER\n", apiReturn);
640
641 apiReturn = pGetIpStatisticsEx(&stats, AF_BAN);
642 ok(apiReturn == ERROR_INVALID_PARAMETER,
643 "GetIpStatisticsEx(&stats, AF_BAN) returned %d, expected ERROR_INVALID_PARAMETER\n", apiReturn);
644
645 apiReturn = pGetIpStatisticsEx(&stats, AF_INET);
646 ok(apiReturn == NO_ERROR, "GetIpStatisticsEx returned %d, expected NO_ERROR\n", apiReturn);
647 if (apiReturn == NO_ERROR && winetest_debug > 1)
648 {
649 trace( "IP IPv4 Ex stats:\n" );
650 trace( " dwForwarding: %u\n", U(stats).dwForwarding );
651 trace( " dwDefaultTTL: %u\n", stats.dwDefaultTTL );
652 trace( " dwInReceives: %u\n", stats.dwInReceives );
653 trace( " dwInHdrErrors: %u\n", stats.dwInHdrErrors );
654 trace( " dwInAddrErrors: %u\n", stats.dwInAddrErrors );
655 trace( " dwForwDatagrams: %u\n", stats.dwForwDatagrams );
656 trace( " dwInUnknownProtos: %u\n", stats.dwInUnknownProtos );
657 trace( " dwInDiscards: %u\n", stats.dwInDiscards );
658 trace( " dwInDelivers: %u\n", stats.dwInDelivers );
659 trace( " dwOutRequests: %u\n", stats.dwOutRequests );
660 trace( " dwRoutingDiscards: %u\n", stats.dwRoutingDiscards );
661 trace( " dwOutDiscards: %u\n", stats.dwOutDiscards );
662 trace( " dwOutNoRoutes: %u\n", stats.dwOutNoRoutes );
663 trace( " dwReasmTimeout: %u\n", stats.dwReasmTimeout );
664 trace( " dwReasmReqds: %u\n", stats.dwReasmReqds );
665 trace( " dwReasmOks: %u\n", stats.dwReasmOks );
666 trace( " dwReasmFails: %u\n", stats.dwReasmFails );
667 trace( " dwFragOks: %u\n", stats.dwFragOks );
668 trace( " dwFragFails: %u\n", stats.dwFragFails );
669 trace( " dwFragCreates: %u\n", stats.dwFragCreates );
670 trace( " dwNumIf: %u\n", stats.dwNumIf );
671 trace( " dwNumAddr: %u\n", stats.dwNumAddr );
672 trace( " dwNumRoutes: %u\n", stats.dwNumRoutes );
673 }
674
675 apiReturn = pGetIpStatisticsEx(&stats, AF_INET6);
676 ok(apiReturn == NO_ERROR || broken(apiReturn == ERROR_NOT_SUPPORTED),
677 "GetIpStatisticsEx returned %d, expected NO_ERROR\n", apiReturn);
678 if (apiReturn == NO_ERROR && winetest_debug > 1)
679 {
680 trace( "IP IPv6 Ex stats:\n" );
681 trace( " dwForwarding: %u\n", U(stats).dwForwarding );
682 trace( " dwDefaultTTL: %u\n", stats.dwDefaultTTL );
683 trace( " dwInReceives: %u\n", stats.dwInReceives );
684 trace( " dwInHdrErrors: %u\n", stats.dwInHdrErrors );
685 trace( " dwInAddrErrors: %u\n", stats.dwInAddrErrors );
686 trace( " dwForwDatagrams: %u\n", stats.dwForwDatagrams );
687 trace( " dwInUnknownProtos: %u\n", stats.dwInUnknownProtos );
688 trace( " dwInDiscards: %u\n", stats.dwInDiscards );
689 trace( " dwInDelivers: %u\n", stats.dwInDelivers );
690 trace( " dwOutRequests: %u\n", stats.dwOutRequests );
691 trace( " dwRoutingDiscards: %u\n", stats.dwRoutingDiscards );
692 trace( " dwOutDiscards: %u\n", stats.dwOutDiscards );
693 trace( " dwOutNoRoutes: %u\n", stats.dwOutNoRoutes );
694 trace( " dwReasmTimeout: %u\n", stats.dwReasmTimeout );
695 trace( " dwReasmReqds: %u\n", stats.dwReasmReqds );
696 trace( " dwReasmOks: %u\n", stats.dwReasmOks );
697 trace( " dwReasmFails: %u\n", stats.dwReasmFails );
698 trace( " dwFragOks: %u\n", stats.dwFragOks );
699 trace( " dwFragFails: %u\n", stats.dwFragFails );
700 trace( " dwFragCreates: %u\n", stats.dwFragCreates );
701 trace( " dwNumIf: %u\n", stats.dwNumIf );
702 trace( " dwNumAddr: %u\n", stats.dwNumAddr );
703 trace( " dwNumRoutes: %u\n", stats.dwNumRoutes );
704 }
705 }
706
707 static void testGetTcpStatisticsEx(void)
708 {
709 DWORD apiReturn;
710 MIB_TCPSTATS stats;
711
712 if (!pGetTcpStatisticsEx)
713 {
714 win_skip( "GetTcpStatisticsEx not available\n" );
715 return;
716 }
717
718 apiReturn = pGetTcpStatisticsEx(NULL, AF_INET);
719 ok(apiReturn == ERROR_INVALID_PARAMETER,
720 "GetTcpStatisticsEx(NULL, AF_INET); returned %d, expected ERROR_INVALID_PARAMETER\n", apiReturn);
721
722 apiReturn = pGetTcpStatisticsEx(&stats, AF_BAN);
723 ok(apiReturn == ERROR_INVALID_PARAMETER || apiReturn == ERROR_NOT_SUPPORTED,
724 "GetTcpStatisticsEx(&stats, AF_BAN) returned %d, expected ERROR_INVALID_PARAMETER\n", apiReturn);
725
726 apiReturn = pGetTcpStatisticsEx(&stats, AF_INET);
727 ok(apiReturn == NO_ERROR, "GetTcpStatisticsEx returned %d, expected NO_ERROR\n", apiReturn);
728 if (apiReturn == NO_ERROR && winetest_debug > 1)
729 {
730 trace( "TCP IPv4 Ex stats:\n" );
731 trace( " dwRtoAlgorithm: %u\n", U(stats).dwRtoAlgorithm );
732 trace( " dwRtoMin: %u\n", stats.dwRtoMin );
733 trace( " dwRtoMax: %u\n", stats.dwRtoMax );
734 trace( " dwMaxConn: %u\n", stats.dwMaxConn );
735 trace( " dwActiveOpens: %u\n", stats.dwActiveOpens );
736 trace( " dwPassiveOpens: %u\n", stats.dwPassiveOpens );
737 trace( " dwAttemptFails: %u\n", stats.dwAttemptFails );
738 trace( " dwEstabResets: %u\n", stats.dwEstabResets );
739 trace( " dwCurrEstab: %u\n", stats.dwCurrEstab );
740 trace( " dwInSegs: %u\n", stats.dwInSegs );
741 trace( " dwOutSegs: %u\n", stats.dwOutSegs );
742 trace( " dwRetransSegs: %u\n", stats.dwRetransSegs );
743 trace( " dwInErrs: %u\n", stats.dwInErrs );
744 trace( " dwOutRsts: %u\n", stats.dwOutRsts );
745 trace( " dwNumConns: %u\n", stats.dwNumConns );
746 }
747
748 apiReturn = pGetTcpStatisticsEx(&stats, AF_INET6);
749 todo_wine ok(apiReturn == NO_ERROR || broken(apiReturn == ERROR_NOT_SUPPORTED),
750 "GetTcpStatisticsEx returned %d, expected NO_ERROR\n", apiReturn);
751 if (apiReturn == NO_ERROR && winetest_debug > 1)
752 {
753 trace( "TCP IPv6 Ex stats:\n" );
754 trace( " dwRtoAlgorithm: %u\n", U(stats).dwRtoAlgorithm );
755 trace( " dwRtoMin: %u\n", stats.dwRtoMin );
756 trace( " dwRtoMax: %u\n", stats.dwRtoMax );
757 trace( " dwMaxConn: %u\n", stats.dwMaxConn );
758 trace( " dwActiveOpens: %u\n", stats.dwActiveOpens );
759 trace( " dwPassiveOpens: %u\n", stats.dwPassiveOpens );
760 trace( " dwAttemptFails: %u\n", stats.dwAttemptFails );
761 trace( " dwEstabResets: %u\n", stats.dwEstabResets );
762 trace( " dwCurrEstab: %u\n", stats.dwCurrEstab );
763 trace( " dwInSegs: %u\n", stats.dwInSegs );
764 trace( " dwOutSegs: %u\n", stats.dwOutSegs );
765 trace( " dwRetransSegs: %u\n", stats.dwRetransSegs );
766 trace( " dwInErrs: %u\n", stats.dwInErrs );
767 trace( " dwOutRsts: %u\n", stats.dwOutRsts );
768 trace( " dwNumConns: %u\n", stats.dwNumConns );
769 }
770 }
771
772 static void testGetUdpStatisticsEx(void)
773 {
774 DWORD apiReturn;
775 MIB_UDPSTATS stats;
776
777 if (!pGetUdpStatisticsEx)
778 {
779 win_skip( "GetUdpStatisticsEx not available\n" );
780 return;
781 }
782
783 apiReturn = pGetUdpStatisticsEx(NULL, AF_INET);
784 ok(apiReturn == ERROR_INVALID_PARAMETER,
785 "GetUdpStatisticsEx(NULL, AF_INET); returned %d, expected ERROR_INVALID_PARAMETER\n", apiReturn);
786
787 apiReturn = pGetUdpStatisticsEx(&stats, AF_BAN);
788 ok(apiReturn == ERROR_INVALID_PARAMETER || apiReturn == ERROR_NOT_SUPPORTED,
789 "GetUdpStatisticsEx(&stats, AF_BAN) returned %d, expected ERROR_INVALID_PARAMETER\n", apiReturn);
790
791 apiReturn = pGetUdpStatisticsEx(&stats, AF_INET);
792 ok(apiReturn == NO_ERROR, "GetUdpStatisticsEx returned %d, expected NO_ERROR\n", apiReturn);
793 if (apiReturn == NO_ERROR && winetest_debug > 1)
794 {
795 trace( "UDP IPv4 Ex stats:\n" );
796 trace( " dwInDatagrams: %u\n", stats.dwInDatagrams );
797 trace( " dwNoPorts: %u\n", stats.dwNoPorts );
798 trace( " dwInErrors: %u\n", stats.dwInErrors );
799 trace( " dwOutDatagrams: %u\n", stats.dwOutDatagrams );
800 trace( " dwNumAddrs: %u\n", stats.dwNumAddrs );
801 }
802
803 apiReturn = pGetUdpStatisticsEx(&stats, AF_INET6);
804 ok(apiReturn == NO_ERROR || broken(apiReturn == ERROR_NOT_SUPPORTED),
805 "GetUdpStatisticsEx returned %d, expected NO_ERROR\n", apiReturn);
806 if (apiReturn == NO_ERROR && winetest_debug > 1)
807 {
808 trace( "UDP IPv6 Ex stats:\n" );
809 trace( " dwInDatagrams: %u\n", stats.dwInDatagrams );
810 trace( " dwNoPorts: %u\n", stats.dwNoPorts );
811 trace( " dwInErrors: %u\n", stats.dwInErrors );
812 trace( " dwOutDatagrams: %u\n", stats.dwOutDatagrams );
813 trace( " dwNumAddrs: %u\n", stats.dwNumAddrs );
814 }
815 }
816
817 static void testGetTcpTable(void)
818 {
819 if (pGetTcpTable) {
820 DWORD apiReturn;
821 ULONG dwSize = 0;
822
823 apiReturn = pGetTcpTable(NULL, &dwSize, FALSE);
824 if (apiReturn == ERROR_NOT_SUPPORTED) {
825 skip("GetTcpTable is not supported\n");
826 return;
827 }
828 ok(apiReturn == ERROR_INSUFFICIENT_BUFFER ||
829 broken(apiReturn == ERROR_NO_DATA), /* win95 */
830 "GetTcpTable(NULL, &dwSize, FALSE) returned %d, expected ERROR_INSUFFICIENT_BUFFER\n",
831 apiReturn);
832 if (apiReturn == ERROR_INSUFFICIENT_BUFFER) {
833 PMIB_TCPTABLE buf = HeapAlloc(GetProcessHeap(), 0, dwSize);
834
835 apiReturn = pGetTcpTable(buf, &dwSize, FALSE);
836 ok(apiReturn == NO_ERROR,
837 "GetTcpTable(buf, &dwSize, FALSE) returned %d, expected NO_ERROR\n",
838 apiReturn);
839
840 if (apiReturn == NO_ERROR && winetest_debug > 1)
841 {
842 DWORD i;
843 trace( "TCP table: %u entries\n", buf->dwNumEntries );
844 for (i = 0; i < buf->dwNumEntries; i++)
845 {
846 char buffer[40];
847 sprintf( buffer, "local %s:%u",
848 ntoa(buf->table[i].dwLocalAddr), ntohs(buf->table[i].dwLocalPort) );
849 trace( "%u: %s remote %s:%u state %u\n",
850 i, buffer, ntoa( buf->table[i].dwRemoteAddr ),
851 ntohs(buf->table[i].dwRemotePort), U(buf->table[i]).dwState );
852 }
853 }
854 HeapFree(GetProcessHeap(), 0, buf);
855 }
856 }
857 }
858
859 static void testGetUdpTable(void)
860 {
861 if (pGetUdpTable) {
862 DWORD apiReturn;
863 ULONG dwSize = 0;
864
865 apiReturn = pGetUdpTable(NULL, &dwSize, FALSE);
866 if (apiReturn == ERROR_NOT_SUPPORTED) {
867 skip("GetUdpTable is not supported\n");
868 return;
869 }
870 ok(apiReturn == ERROR_INSUFFICIENT_BUFFER,
871 "GetUdpTable(NULL, &dwSize, FALSE) returned %d, expected ERROR_INSUFFICIENT_BUFFER\n",
872 apiReturn);
873 if (apiReturn == ERROR_INSUFFICIENT_BUFFER) {
874 PMIB_UDPTABLE buf = HeapAlloc(GetProcessHeap(), 0, dwSize);
875
876 apiReturn = pGetUdpTable(buf, &dwSize, FALSE);
877 ok(apiReturn == NO_ERROR,
878 "GetUdpTable(buf, &dwSize, FALSE) returned %d, expected NO_ERROR\n",
879 apiReturn);
880
881 if (apiReturn == NO_ERROR && winetest_debug > 1)
882 {
883 DWORD i;
884 trace( "UDP table: %u entries\n", buf->dwNumEntries );
885 for (i = 0; i < buf->dwNumEntries; i++)
886 trace( "%u: %s:%u\n",
887 i, ntoa( buf->table[i].dwLocalAddr ), ntohs(buf->table[i].dwLocalPort) );
888 }
889 HeapFree(GetProcessHeap(), 0, buf);
890 }
891 }
892 }
893
894 static void testSetTcpEntry(void)
895 {
896 DWORD ret;
897 MIB_TCPROW row;
898
899 memset(&row, 0, sizeof(row));
900 if(0) /* This test crashes in OS >= VISTA */
901 {
902 ret = pSetTcpEntry(NULL);
903 ok( ret == ERROR_INVALID_PARAMETER, "got %u, expected %u\n", ret, ERROR_INVALID_PARAMETER);
904 }
905
906 ret = pSetTcpEntry(&row);
907 if (ret == ERROR_NETWORK_ACCESS_DENIED)
908 {
909 win_skip("SetTcpEntry failed with access error. Skipping test.\n");
910 return;
911 }
912 todo_wine ok( ret == ERROR_INVALID_PARAMETER, "got %u, expected %u\n", ret, ERROR_INVALID_PARAMETER);
913
914 U(row).dwState = MIB_TCP_STATE_DELETE_TCB;
915 ret = pSetTcpEntry(&row);
916 todo_wine ok( ret == ERROR_MR_MID_NOT_FOUND || broken(ret == ERROR_INVALID_PARAMETER),
917 "got %u, expected %u\n", ret, ERROR_MR_MID_NOT_FOUND);
918 }
919
920 static void testIcmpSendEcho(void)
921 {
922 HANDLE icmp;
923 char senddata[32], replydata[sizeof(senddata) + sizeof(ICMP_ECHO_REPLY)];
924 DWORD ret, error, replysz = sizeof(replydata);
925 IPAddr address;
926
927 if (!pIcmpSendEcho || !pIcmpCreateFile)
928 {
929 win_skip( "IcmpSendEcho or IcmpCreateFile not available\n" );
930 return;
931 }
932 memset(senddata, 0, sizeof(senddata));
933
934 address = htonl(INADDR_LOOPBACK);
935 SetLastError(0xdeadbeef);
936 ret = pIcmpSendEcho(INVALID_HANDLE_VALUE, address, senddata, sizeof(senddata), NULL, replydata, replysz, 1000);
937 error = GetLastError();
938 ok (!ret, "IcmpSendEcho succeeded unexpectedly\n");
939 todo_wine
940 ok (error == ERROR_INVALID_PARAMETER
941 || broken(error == ERROR_INVALID_HANDLE) /* <= 2003 */,
942 "expected 87, got %d\n", error);
943
944 icmp = pIcmpCreateFile();
945 if (icmp == INVALID_HANDLE_VALUE)
946 {
947 error = GetLastError();
948 if (error == ERROR_ACCESS_DENIED)
949 {
950 skip ("ICMP is not available.\n");
951 return;
952 }
953 }
954 ok (icmp != INVALID_HANDLE_VALUE, "IcmpCreateFile failed unexpectedly with error %d\n", GetLastError());
955
956 address = 0;
957 SetLastError(0xdeadbeef);
958 ret = pIcmpSendEcho(icmp, address, senddata, sizeof(senddata), NULL, replydata, replysz, 1000);
959 error = GetLastError();
960 ok (!ret, "IcmpSendEcho succeeded unexpectedly\n");
961 ok (error == ERROR_INVALID_NETNAME
962 || broken(error == IP_BAD_DESTINATION) /* <= 2003 */,
963 "expected 1214, got %d\n", error);
964
965 address = htonl(INADDR_LOOPBACK);
966 if (0) /* crashes in XP */
967 {
968 ret = pIcmpSendEcho(icmp, address, NULL, sizeof(senddata), NULL, replydata, replysz, 1000);
969 ok (!ret, "IcmpSendEcho succeeded unexpectedly\n");
970 }
971
972 SetLastError(0xdeadbeef);
973 ret = pIcmpSendEcho(icmp, address, senddata, 0, NULL, replydata, replysz, 1000);
974 error = GetLastError();
975 ok (ret, "IcmpSendEcho failed unexpectedly with error %d\n", error);
976
977 SetLastError(0xdeadbeef);
978 ret = pIcmpSendEcho(icmp, address, NULL, 0, NULL, replydata, replysz, 1000);
979 error = GetLastError();
980 ok (ret, "IcmpSendEcho failed unexpectedly with error %d\n", error);
981
982 if (0) /* crashes in wine, remove IF when fixed */
983 {
984 SetLastError(0xdeadbeef);
985 ret = pIcmpSendEcho(icmp, address, senddata, sizeof(senddata), NULL, NULL, replysz, 1000);
986 error = GetLastError();
987 ok (!ret, "IcmpSendEcho succeeded unexpectedly\n");
988 ok (error == ERROR_INVALID_PARAMETER, "expected 87, got %d\n", error);
989 }
990
991 SetLastError(0xdeadbeef);
992 ret = pIcmpSendEcho(icmp, address, senddata, sizeof(senddata), NULL, replydata, 0, 1000);
993 error = GetLastError();
994 ok (!ret, "IcmpSendEcho succeeded unexpectedly\n");
995 todo_wine
996 ok (error == ERROR_INVALID_PARAMETER
997 || broken(error == ERROR_INSUFFICIENT_BUFFER) /* <= 2003 */,
998 "expected 87, got %d\n", error);
999
1000 SetLastError(0xdeadbeef);
1001 ret = pIcmpSendEcho(icmp, address, senddata, sizeof(senddata), NULL, NULL, 0, 1000);
1002 error = GetLastError();
1003 ok (!ret, "IcmpSendEcho succeeded unexpectedly\n");
1004 todo_wine
1005 ok (error == ERROR_INVALID_PARAMETER
1006 || broken(error == ERROR_INSUFFICIENT_BUFFER) /* <= 2003 */,
1007 "expected 87, got %d\n", error);
1008
1009 SetLastError(0xdeadbeef);
1010 replysz = sizeof(replydata) - 1;
1011 ret = pIcmpSendEcho(icmp, address, senddata, sizeof(senddata), NULL, replydata, replysz, 1000);
1012 error = GetLastError();
1013 todo_wine {
1014 ok (!ret, "IcmpSendEcho succeeded unexpectedly\n");
1015 ok (error == IP_GENERAL_FAILURE
1016 || broken(error == IP_BUF_TOO_SMALL) /* <= 2003 */,
1017 "expected 11050, got %d\n", error);
1018 }
1019
1020 SetLastError(0xdeadbeef);
1021 replysz = sizeof(ICMP_ECHO_REPLY);
1022 ret = pIcmpSendEcho(icmp, address, senddata, 0, NULL, replydata, replysz, 1000);
1023 error = GetLastError();
1024 todo_wine
1025 ok (ret, "IcmpSendEcho failed unexpectedly with error %d\n", error);
1026
1027 SetLastError(0xdeadbeef);
1028 replysz = sizeof(ICMP_ECHO_REPLY) + ICMP_MINLEN;
1029 ret = pIcmpSendEcho(icmp, address, senddata, ICMP_MINLEN, NULL, replydata, replysz, 1000);
1030 error = GetLastError();
1031 todo_wine
1032 ok (ret, "IcmpSendEcho failed unexpectedly with error %d\n", error);
1033
1034 SetLastError(0xdeadbeef);
1035 replysz = sizeof(ICMP_ECHO_REPLY) + ICMP_MINLEN;
1036 ret = pIcmpSendEcho(icmp, address, senddata, ICMP_MINLEN + 1, NULL, replydata, replysz, 1000);
1037 error = GetLastError();
1038 ok (!ret, "IcmpSendEcho succeeded unexpectedly\n");
1039 todo_wine
1040 ok (error == IP_GENERAL_FAILURE
1041 || broken(error == IP_BUF_TOO_SMALL) /* <= 2003 */,
1042 "expected 11050, got %d\n", error);
1043
1044 SetLastError(0xdeadbeef);
1045 ret = pIcmpSendEcho(icmp, address, senddata, ICMP_MINLEN, NULL, replydata, replysz - 1, 1000);
1046 error = GetLastError();
1047 ok (!ret, "IcmpSendEcho succeeded unexpectedly\n");
1048 todo_wine
1049 ok (error == IP_GENERAL_FAILURE
1050 || broken(error == IP_BUF_TOO_SMALL) /* <= 2003 */,
1051 "expected 11050, got %d\n", error);
1052
1053 /* in windows >= vista the timeout can't be invalid */
1054 SetLastError(0xdeadbeef);
1055 replysz = sizeof(replydata);
1056 ret = pIcmpSendEcho(icmp, address, senddata, sizeof(senddata), NULL, replydata, replysz, 0);
1057 error = GetLastError();
1058 if (!ret) ok(error == ERROR_INVALID_PARAMETER, "expected 87, got %d\n", error);
1059
1060 SetLastError(0xdeadbeef);
1061 ret = pIcmpSendEcho(icmp, address, senddata, sizeof(senddata), NULL, replydata, replysz, -1);
1062 error = GetLastError();
1063 if (!ret) ok(error == ERROR_INVALID_PARAMETER, "expected 87, got %d\n", error);
1064
1065 /* real ping test */
1066 SetLastError(0xdeadbeef);
1067 address = htonl(INADDR_LOOPBACK);
1068 ret = pIcmpSendEcho(icmp, address, senddata, sizeof(senddata), NULL, replydata, replysz, 1000);
1069 error = GetLastError();
1070 if (ret)
1071 {
1072 PICMP_ECHO_REPLY pong = (PICMP_ECHO_REPLY) replydata;
1073 trace ("send addr : %s\n", ntoa(address));
1074 trace ("reply addr : %s\n", ntoa(pong->Address));
1075 trace ("reply size : %u\n", replysz);
1076 trace ("roundtrip : %u ms\n", pong->RoundTripTime);
1077 trace ("status : %u\n", pong->Status);
1078 trace ("recv size : %u\n", pong->DataSize);
1079 trace ("ttl : %u\n", pong->Options.Ttl);
1080 trace ("flags : 0x%x\n", pong->Options.Flags);
1081 }
1082 else
1083 {
1084 skip ("Failed to ping with error %d, is lo interface down?.\n", error);
1085 }
1086 }
1087
1088 /*
1089 still-to-be-tested NT4-onward functions:
1090 CreateIpForwardEntry
1091 DeleteIpForwardEntry
1092 CreateIpNetEntry
1093 DeleteIpNetEntry
1094 GetFriendlyIfIndex
1095 GetRTTAndHopCount
1096 SetIfEntry
1097 SetIpForwardEntry
1098 SetIpNetEntry
1099 SetIpStatistics
1100 SetIpTTL
1101 */
1102 static void testWinNT4Functions(void)
1103 {
1104 testGetNumberOfInterfaces();
1105 testGetIpAddrTable();
1106 testGetIfTable();
1107 testGetIpForwardTable();
1108 testGetIpNetTable();
1109 testGetIcmpStatistics();
1110 testGetIpStatistics();
1111 testGetTcpStatistics();
1112 testGetUdpStatistics();
1113 testGetIcmpStatisticsEx();
1114 testGetIpStatisticsEx();
1115 testGetTcpStatisticsEx();
1116 testGetUdpStatisticsEx();
1117 testGetTcpTable();
1118 testGetUdpTable();
1119 testSetTcpEntry();
1120 testIcmpSendEcho();
1121 }
1122
1123 static void testGetInterfaceInfo(void)
1124 {
1125 if (pGetInterfaceInfo) {
1126 DWORD apiReturn;
1127 ULONG len = 0;
1128
1129 apiReturn = pGetInterfaceInfo(NULL, NULL);
1130 if (apiReturn == ERROR_NOT_SUPPORTED) {
1131 skip("GetInterfaceInfo is not supported\n");
1132 return;
1133 }
1134 ok(apiReturn == ERROR_INVALID_PARAMETER,
1135 "GetInterfaceInfo returned %d, expected ERROR_INVALID_PARAMETER\n",
1136 apiReturn);
1137 apiReturn = pGetInterfaceInfo(NULL, &len);
1138 ok(apiReturn == ERROR_INSUFFICIENT_BUFFER,
1139 "GetInterfaceInfo returned %d, expected ERROR_INSUFFICIENT_BUFFER\n",
1140 apiReturn);
1141 if (apiReturn == ERROR_INSUFFICIENT_BUFFER) {
1142 PIP_INTERFACE_INFO buf = HeapAlloc(GetProcessHeap(), 0, len);
1143
1144 apiReturn = pGetInterfaceInfo(buf, &len);
1145 ok(apiReturn == NO_ERROR,
1146 "GetInterfaceInfo(buf, &dwSize) returned %d, expected NO_ERROR\n",
1147 apiReturn);
1148 HeapFree(GetProcessHeap(), 0, buf);
1149 }
1150 }
1151 }
1152
1153 static void testGetAdaptersInfo(void)
1154 {
1155 if (pGetAdaptersInfo) {
1156 DWORD apiReturn;
1157 ULONG len = 0;
1158
1159 apiReturn = pGetAdaptersInfo(NULL, NULL);
1160 if (apiReturn == ERROR_NOT_SUPPORTED) {
1161 skip("GetAdaptersInfo is not supported\n");
1162 return;
1163 }
1164 ok(apiReturn == ERROR_INVALID_PARAMETER,
1165 "GetAdaptersInfo returned %d, expected ERROR_INVALID_PARAMETER\n",
1166 apiReturn);
1167 apiReturn = pGetAdaptersInfo(NULL, &len);
1168 ok(apiReturn == ERROR_NO_DATA || apiReturn == ERROR_BUFFER_OVERFLOW,
1169 "GetAdaptersInfo returned %d, expected ERROR_NO_DATA or ERROR_BUFFER_OVERFLOW\n",
1170 apiReturn);
1171 if (apiReturn == ERROR_NO_DATA)
1172 ; /* no adapter's, that's okay */
1173 else if (apiReturn == ERROR_BUFFER_OVERFLOW) {
1174 PIP_ADAPTER_INFO ptr, buf = HeapAlloc(GetProcessHeap(), 0, len);
1175
1176 apiReturn = pGetAdaptersInfo(buf, &len);
1177 ok(apiReturn == NO_ERROR,
1178 "GetAdaptersInfo(buf, &dwSize) returned %d, expected NO_ERROR\n",
1179 apiReturn);
1180 ptr = buf;
1181 while (ptr) {
1182 ok(ptr->IpAddressList.IpAddress.String[0], "A valid IP must be present\n");
1183 ok(ptr->IpAddressList.IpMask.String[0], "A valid mask must be present\n");
1184 trace("Adapter '%s', IP %s, Mask %s\n", ptr->AdapterName,
1185 ptr->IpAddressList.IpAddress.String, ptr->IpAddressList.IpMask.String);
1186 ptr = ptr->Next;
1187 }
1188 HeapFree(GetProcessHeap(), 0, buf);
1189 }
1190 }
1191 }
1192
1193 static void testGetNetworkParams(void)
1194 {
1195 if (pGetNetworkParams) {
1196 DWORD apiReturn;
1197 ULONG len = 0;
1198
1199 apiReturn = pGetNetworkParams(NULL, NULL);
1200 if (apiReturn == ERROR_NOT_SUPPORTED) {
1201 skip("GetNetworkParams is not supported\n");
1202 return;
1203 }
1204 ok(apiReturn == ERROR_INVALID_PARAMETER,
1205 "GetNetworkParams returned %d, expected ERROR_INVALID_PARAMETER\n",
1206 apiReturn);
1207 apiReturn = pGetNetworkParams(NULL, &len);
1208 ok(apiReturn == ERROR_BUFFER_OVERFLOW,
1209 "GetNetworkParams returned %d, expected ERROR_BUFFER_OVERFLOW\n",
1210 apiReturn);
1211 if (apiReturn == ERROR_BUFFER_OVERFLOW) {
1212 PFIXED_INFO buf = HeapAlloc(GetProcessHeap(), 0, len);
1213
1214 apiReturn = pGetNetworkParams(buf, &len);
1215 ok(apiReturn == NO_ERROR,
1216 "GetNetworkParams(buf, &dwSize) returned %d, expected NO_ERROR\n",
1217 apiReturn);
1218 HeapFree(GetProcessHeap(), 0, buf);
1219 }
1220 }
1221 }
1222
1223 /*
1224 still-to-be-tested 98-onward functions:
1225 GetBestInterface
1226 GetBestRoute
1227 IpReleaseAddress
1228 IpRenewAddress
1229 */
1230 static DWORD CALLBACK testWin98Functions(void *p)
1231 {
1232 testGetInterfaceInfo();
1233 testGetAdaptersInfo();
1234 testGetNetworkParams();
1235 return 0;
1236 }
1237
1238 static void testGetPerAdapterInfo(void)
1239 {
1240 DWORD ret, needed;
1241 void *buffer;
1242
1243 if (!pGetPerAdapterInfo) return;
1244 ret = pGetPerAdapterInfo(1, NULL, NULL);
1245 if (ret == ERROR_NOT_SUPPORTED) {
1246 skip("GetPerAdapterInfo is not supported\n");
1247 return;
1248 }
1249 ok( ret == ERROR_INVALID_PARAMETER, "got %u instead of ERROR_INVALID_PARAMETER\n", ret );
1250 needed = 0xdeadbeef;
1251 ret = pGetPerAdapterInfo(1, NULL, &needed);
1252 if (ret == ERROR_NO_DATA) return; /* no such adapter */
1253 ok( ret == ERROR_BUFFER_OVERFLOW, "got %u instead of ERROR_BUFFER_OVERFLOW\n", ret );
1254 ok( needed != 0xdeadbeef, "needed not set\n" );
1255 buffer = HeapAlloc( GetProcessHeap(), 0, needed );
1256 ret = pGetPerAdapterInfo(1, buffer, &needed);
1257 ok( ret == NO_ERROR, "got %u instead of NO_ERROR\n", ret );
1258 HeapFree( GetProcessHeap(), 0, buffer );
1259 }
1260
1261 static void testNotifyAddrChange(void)
1262 {
1263 DWORD ret, bytes;
1264 OVERLAPPED overlapped;
1265 HANDLE handle;
1266 BOOL success;
1267
1268 if (!pNotifyAddrChange)
1269 {
1270 win_skip("NotifyAddrChange not present\n");
1271 return;
1272 }
1273 if (!pCancelIPChangeNotify)
1274 {
1275 win_skip("CancelIPChangeNotify not present\n");
1276 return;
1277 }
1278
1279 handle = NULL;
1280 ZeroMemory(&overlapped, sizeof(overlapped));
1281 ret = pNotifyAddrChange(&handle, &overlapped);
1282 if (ret == ERROR_NOT_SUPPORTED)
1283 {
1284 win_skip("NotifyAddrChange is not supported\n");
1285 return;
1286 }
1287 ok(ret == ERROR_IO_PENDING, "NotifyAddrChange returned %d, expected ERROR_IO_PENDING\n", ret);
1288 ret = GetLastError();
1289 todo_wine ok(ret == ERROR_IO_PENDING, "GetLastError returned %d, expected ERROR_IO_PENDING\n", ret);
1290 success = pCancelIPChangeNotify(&overlapped);
1291 todo_wine ok(success == TRUE, "CancelIPChangeNotify returned FALSE, expected TRUE\n");
1292
1293 ZeroMemory(&overlapped, sizeof(overlapped));
1294 success = pCancelIPChangeNotify(&overlapped);
1295 ok(success == FALSE, "CancelIPChangeNotify returned TRUE, expected FALSE\n");
1296
1297 handle = NULL;
1298 ZeroMemory(&overlapped, sizeof(overlapped));
1299 overlapped.hEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
1300 ret = pNotifyAddrChange(&handle, &overlapped);
1301 ok(ret == ERROR_IO_PENDING, "NotifyAddrChange returned %d, expected ERROR_IO_PENDING\n", ret);
1302 todo_wine ok(handle != INVALID_HANDLE_VALUE, "NotifyAddrChange returned invalid file handle\n");
1303 success = GetOverlappedResult(handle, &overlapped, &bytes, FALSE);
1304 ok(success == FALSE, "GetOverlappedResult returned TRUE, expected FALSE\n");
1305 ret = GetLastError();
1306 ok(ret == ERROR_IO_INCOMPLETE, "GetLastError returned %d, expected ERROR_IO_INCOMPLETE\n", ret);
1307 success = pCancelIPChangeNotify(&overlapped);
1308 todo_wine ok(success == TRUE, "CancelIPChangeNotify returned FALSE, expected TRUE\n");
1309
1310 if (winetest_interactive)
1311 {
1312 handle = NULL;
1313 ZeroMemory(&overlapped, sizeof(overlapped));
1314 overlapped.hEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
1315 trace("Testing asynchronous ipv4 address change notification. Please "
1316 "change the ipv4 address of one of your network interfaces\n");
1317 ret = pNotifyAddrChange(&handle, &overlapped);
1318 ok(ret == ERROR_IO_PENDING, "NotifyAddrChange returned %d, expected NO_ERROR\n", ret);
1319 success = GetOverlappedResult(handle, &overlapped, &bytes, TRUE);
1320 ok(success == TRUE, "GetOverlappedResult returned FALSE, expected TRUE\n");
1321 }
1322
1323 /* test synchronous functionality */
1324 if (winetest_interactive)
1325 {
1326 trace("Testing synchronous ipv4 address change notification. Please "
1327 "change the ipv4 address of one of your network interfaces\n");
1328 ret = pNotifyAddrChange(NULL, NULL);
1329 todo_wine ok(ret == NO_ERROR, "NotifyAddrChange returned %d, expected NO_ERROR\n", ret);
1330 }
1331 }
1332
1333 /*
1334 still-to-be-tested 2K-onward functions:
1335 AddIPAddress
1336 CreateProxyArpEntry
1337 DeleteIPAddress
1338 DeleteProxyArpEntry
1339 EnableRouter
1340 FlushIpNetTable
1341 GetAdapterIndex
1342 NotifyRouteChange + CancelIPChangeNotify
1343 SendARP
1344 UnenableRouter
1345 */
1346 static void testWin2KFunctions(void)
1347 {
1348 testGetPerAdapterInfo();
1349 testNotifyAddrChange();
1350 }
1351
1352 static void test_GetAdaptersAddresses(void)
1353 {
1354 ULONG ret, size, osize, i;
1355 IP_ADAPTER_ADDRESSES *aa, *ptr;
1356 IP_ADAPTER_UNICAST_ADDRESS *ua;
1357
1358 if (!pGetAdaptersAddresses)
1359 {
1360 win_skip("GetAdaptersAddresses not present\n");
1361 return;
1362 }
1363
1364 ret = pGetAdaptersAddresses(AF_UNSPEC, 0, NULL, NULL, NULL);
1365 ok(ret == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER got %u\n", ret);
1366
1367 /* size should be ignored and overwritten if buffer is NULL */
1368 size = 0x7fffffff;
1369 ret = pGetAdaptersAddresses(AF_UNSPEC, 0, NULL, NULL, &size);
1370 ok(ret == ERROR_BUFFER_OVERFLOW, "expected ERROR_BUFFER_OVERFLOW, got %u\n", ret);
1371 if (ret != ERROR_BUFFER_OVERFLOW) return;
1372
1373 ptr = HeapAlloc(GetProcessHeap(), 0, size);
1374 ret = pGetAdaptersAddresses(AF_UNSPEC, 0, NULL, ptr, &size);
1375 ok(!ret, "expected ERROR_SUCCESS got %u\n", ret);
1376 HeapFree(GetProcessHeap(), 0, ptr);
1377
1378 /* higher size must not be changed to lower size */
1379 size *= 2;
1380 osize = size;
1381 ptr = HeapAlloc(GetProcessHeap(), 0, osize);
1382 ret = pGetAdaptersAddresses(AF_UNSPEC, 0, NULL, ptr, &osize);
1383 ok(!ret, "expected ERROR_SUCCESS got %u\n", ret);
1384 ok(osize == size, "expected %d, got %d\n", size, osize);
1385
1386 for (aa = ptr; !ret && aa; aa = aa->Next)
1387 {
1388 char temp[128];
1389
1390 ok(S(U(*aa)).Length == sizeof(IP_ADAPTER_ADDRESSES_LH) ||
1391 S(U(*aa)).Length == sizeof(IP_ADAPTER_ADDRESSES_XP),
1392 "Unknown structure size of %u bytes\n", S(U(*aa)).Length);
1393 ok(aa->DnsSuffix != NULL, "DnsSuffix is not a valid pointer\n");
1394 ok(aa->Description != NULL, "Description is not a valid pointer\n");
1395 ok(aa->FriendlyName != NULL, "FriendlyName is not a valid pointer\n");
1396
1397 trace("\n");
1398 trace("Length: %u\n", S(U(*aa)).Length);
1399 trace("IfIndex: %u\n", S(U(*aa)).IfIndex);
1400 trace("Next: %p\n", aa->Next);
1401 trace("AdapterName: %s\n", aa->AdapterName);
1402 trace("FirstUnicastAddress: %p\n", aa->FirstUnicastAddress);
1403 ua = aa->FirstUnicastAddress;
1404 while (ua)
1405 {
1406 ok(ua->PrefixOrigin != IpPrefixOriginOther,
1407 "bad address config value %d\n", ua->PrefixOrigin);
1408 ok(ua->SuffixOrigin != IpSuffixOriginOther,
1409 "bad address config value %d\n", ua->PrefixOrigin);
1410 /* Address configured manually or from DHCP server? */
1411 if (ua->PrefixOrigin == IpPrefixOriginManual ||
1412 ua->PrefixOrigin == IpPrefixOriginDhcp)
1413 {
1414 ok(ua->ValidLifetime, "expected non-zero value\n");
1415 ok(ua->PreferredLifetime, "expected non-zero value\n");
1416 ok(ua->LeaseLifetime, "expected non-zero\n");
1417 }
1418 /* Is the address ok in the network (not duplicated)? */
1419 ok(ua->DadState != IpDadStateInvalid && ua->DadState != IpDadStateDuplicate,
1420 "bad address duplication value %d\n", ua->DadState);
1421 trace("\tLength: %u\n", S(U(*ua)).Length);
1422 trace("\tFlags: 0x%08x\n", S(U(*ua)).Flags);
1423 trace("\tNext: %p\n", ua->Next);
1424 trace("\tAddress.lpSockaddr: %p\n", ua->Address.lpSockaddr);
1425 trace("\tAddress.iSockaddrLength: %d\n", ua->Address.iSockaddrLength);
1426 trace("\tPrefixOrigin: %u\n", ua->PrefixOrigin);
1427 trace("\tSuffixOrigin: %u\n", ua->SuffixOrigin);
1428 trace("\tDadState: %u\n", ua->DadState);
1429 trace("\tValidLifetime: %u seconds\n", ua->ValidLifetime);
1430 trace("\tPreferredLifetime: %u seconds\n", ua->PreferredLifetime);
1431 trace("\tLeaseLifetime: %u seconds\n", ua->LeaseLifetime);
1432 trace("\n");
1433 ua = ua->Next;
1434 }
1435 trace("FirstAnycastAddress: %p\n", aa->FirstAnycastAddress);
1436 trace("FirstMulticastAddress: %p\n", aa->FirstMulticastAddress);
1437 trace("FirstDnsServerAddress: %p\n", aa->FirstDnsServerAddress);
1438 trace("DnsSuffix: %s %p\n", wine_dbgstr_w(aa->DnsSuffix), aa->DnsSuffix);
1439 trace("Description: %s %p\n", wine_dbgstr_w(aa->Description), aa->Description);
1440 trace("FriendlyName: %s %p\n", wine_dbgstr_w(aa->FriendlyName), aa->FriendlyName);
1441 trace("PhysicalAddressLength: %u\n", aa->PhysicalAddressLength);
1442 for (i = 0; i < aa->PhysicalAddressLength; i++)
1443 sprintf(temp + i * 3, "%02X-", aa->PhysicalAddress[i]);
1444 temp[i ? i * 3 - 1 : 0] = '\0';
1445 trace("PhysicalAddress: %s\n", temp);
1446 trace("Flags: 0x%08x\n", aa->Flags);
1447 trace("Mtu: %u\n", aa->Mtu);
1448 trace("IfType: %u\n", aa->IfType);
1449 trace("OperStatus: %u\n", aa->OperStatus);
1450 trace("Ipv6IfIndex: %u\n", aa->Ipv6IfIndex);
1451 for (i = 0, temp[0] = '\0'; i < sizeof(aa->ZoneIndices) / sizeof(aa->ZoneIndices[0]); i++)
1452 sprintf(temp + strlen(temp), "%d ", aa->ZoneIndices[i]);
1453 trace("ZoneIndices: %s\n", temp);
1454 trace("FirstPrefix: %p\n", aa->FirstPrefix);
1455
1456 if (S(U(*aa)).Length < sizeof(IP_ADAPTER_ADDRESSES_LH)) continue;
1457 #ifndef __REACTOS__
1458 trace("TransmitLinkSpeed: %s\n", debugstr_longlong(aa->TransmitLinkSpeed));
1459 trace("ReceiveLinkSpeed: %s\n", debugstr_longlong(aa->ReceiveLinkSpeed));
1460 trace("FirstWinsServerAddress:%p\n", aa->FirstWinsServerAddress);
1461 trace("FirstGatewayAddress: %p\n", aa->FirstGatewayAddress);
1462 trace("Ipv4Metric: %u\n", aa->Ipv4Metric);
1463 trace("Ipv6Metric: %u\n", aa->Ipv6Metric);
1464 trace("Luid: %p\n", &aa->Luid);
1465 trace("Dhcpv4Server: %p\n", &aa->Dhcpv4Server);
1466 trace("CompartmentId: %u\n", aa->CompartmentId);
1467 trace("NetworkGuid: %s\n", wine_dbgstr_guid((GUID*) &aa->NetworkGuid));
1468 trace("ConnectionType: %u\n", aa->ConnectionType);
1469 trace("TunnelType: %u\n", aa->TunnelType);
1470 trace("Dhcpv6Server: %p\n", &aa->Dhcpv6Server);
1471 trace("Dhcpv6ClientDuidLength:%u\n", aa->Dhcpv6ClientDuidLength);
1472 trace("Dhcpv6ClientDuid: %p\n", aa->Dhcpv6ClientDuid);
1473 trace("Dhcpv6Iaid: %u\n", aa->Dhcpv6Iaid);
1474 trace("FirstDnsSuffix: %p\n", aa->FirstDnsSuffix);
1475 trace("\n");
1476 #endif
1477 }
1478 HeapFree(GetProcessHeap(), 0, ptr);
1479 }
1480
1481 static void test_GetExtendedTcpTable(void)
1482 {
1483 DWORD ret, size;
1484 MIB_TCPTABLE *table;
1485 MIB_TCPTABLE_OWNER_PID *table_pid;
1486 MIB_TCPTABLE_OWNER_MODULE *table_module;
1487
1488 if (!pGetExtendedTcpTable)
1489 {
1490 win_skip("GetExtendedTcpTable not available\n");
1491 return;
1492 }
1493 ret = pGetExtendedTcpTable( NULL, NULL, TRUE, AF_INET, TCP_TABLE_BASIC_ALL, 0 );
1494 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
1495
1496 size = 0;
1497 ret = pGetExtendedTcpTable( NULL, &size, TRUE, AF_INET, TCP_TABLE_BASIC_ALL, 0 );
1498 ok( ret == ERROR_INSUFFICIENT_BUFFER, "got %u\n", ret );
1499
1500 table = HeapAlloc( GetProcessHeap(), 0, size );
1501 ret = pGetExtendedTcpTable( table, &size, TRUE, AF_INET, TCP_TABLE_BASIC_ALL, 0 );
1502 ok( ret == ERROR_SUCCESS, "got %u\n", ret );
1503 HeapFree( GetProcessHeap(), 0, table );
1504
1505 size = 0;
1506 ret = pGetExtendedTcpTable( NULL, &size, TRUE, AF_INET, TCP_TABLE_BASIC_LISTENER, 0 );
1507 ok( ret == ERROR_INSUFFICIENT_BUFFER, "got %u\n", ret );
1508
1509 table = HeapAlloc( GetProcessHeap(), 0, size );
1510 ret = pGetExtendedTcpTable( table, &size, TRUE, AF_INET, TCP_TABLE_BASIC_LISTENER, 0 );
1511 ok( ret == ERROR_SUCCESS, "got %u\n", ret );
1512 HeapFree( GetProcessHeap(), 0, table );
1513
1514 size = 0;
1515 ret = pGetExtendedTcpTable( NULL, &size, TRUE, AF_INET, TCP_TABLE_OWNER_PID_ALL, 0 );
1516 ok( ret == ERROR_INSUFFICIENT_BUFFER, "got %u\n", ret );
1517
1518 table_pid = HeapAlloc( GetProcessHeap(), 0, size );
1519 ret = pGetExtendedTcpTable( table_pid, &size, TRUE, AF_INET, TCP_TABLE_OWNER_PID_ALL, 0 );
1520 ok( ret == ERROR_SUCCESS, "got %u\n", ret );
1521 HeapFree( GetProcessHeap(), 0, table_pid );
1522
1523 size = 0;
1524 ret = pGetExtendedTcpTable( NULL, &size, TRUE, AF_INET, TCP_TABLE_OWNER_PID_LISTENER, 0 );
1525 ok( ret == ERROR_INSUFFICIENT_BUFFER, "got %u\n", ret );
1526
1527 table_pid = HeapAlloc( GetProcessHeap(), 0, size );
1528 ret = pGetExtendedTcpTable( table_pid, &size, TRUE, AF_INET, TCP_TABLE_OWNER_PID_LISTENER, 0 );
1529 ok( ret == ERROR_SUCCESS, "got %u\n", ret );
1530 HeapFree( GetProcessHeap(), 0, table_pid );
1531
1532 size = 0;
1533 ret = pGetExtendedTcpTable( NULL, &size, TRUE, AF_INET, TCP_TABLE_OWNER_MODULE_ALL, 0 );
1534 ok( ret == ERROR_INSUFFICIENT_BUFFER, "got %u\n", ret );
1535
1536 table_module = HeapAlloc( GetProcessHeap(), 0, size );
1537 ret = pGetExtendedTcpTable( table_module, &size, TRUE, AF_INET, TCP_TABLE_OWNER_MODULE_ALL, 0 );
1538 ok( ret == ERROR_SUCCESS, "got %u\n", ret );
1539 HeapFree( GetProcessHeap(), 0, table_module );
1540
1541 size = 0;
1542 ret = pGetExtendedTcpTable( NULL, &size, TRUE, AF_INET, TCP_TABLE_OWNER_MODULE_LISTENER, 0 );
1543 ok( ret == ERROR_INSUFFICIENT_BUFFER, "got %u\n", ret );
1544
1545 table_module = HeapAlloc( GetProcessHeap(), 0, size );
1546 ret = pGetExtendedTcpTable( table_module, &size, TRUE, AF_INET, TCP_TABLE_OWNER_MODULE_LISTENER, 0 );
1547 ok( ret == ERROR_SUCCESS, "got %u\n", ret );
1548 HeapFree( GetProcessHeap(), 0, table_module );
1549 }
1550
1551 static void test_GetExtendedUdpTable(void)
1552 {
1553 DWORD ret, size;
1554 MIB_UDPTABLE *table;
1555 MIB_UDPTABLE_OWNER_PID *table_pid;
1556 MIB_UDPTABLE_OWNER_MODULE *table_module;
1557
1558 if (!pGetExtendedUdpTable)
1559 {
1560 win_skip("GetExtendedUdpTable not available\n");
1561 return;
1562 }
1563 ret = pGetExtendedUdpTable( NULL, NULL, TRUE, AF_INET, UDP_TABLE_BASIC, 0 );
1564 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
1565
1566 size = 0;
1567 ret = pGetExtendedUdpTable( NULL, &size, TRUE, AF_INET, UDP_TABLE_BASIC, 0 );
1568 ok( ret == ERROR_INSUFFICIENT_BUFFER, "got %u\n", ret );
1569
1570 table = HeapAlloc( GetProcessHeap(), 0, size );
1571 ret = pGetExtendedUdpTable( table, &size, TRUE, AF_INET, UDP_TABLE_BASIC, 0 );
1572 ok( ret == ERROR_SUCCESS, "got %u\n", ret );
1573 HeapFree( GetProcessHeap(), 0, table );
1574
1575 size = 0;
1576 ret = pGetExtendedUdpTable( NULL, &size, TRUE, AF_INET, UDP_TABLE_OWNER_PID, 0 );
1577 ok( ret == ERROR_INSUFFICIENT_BUFFER, "got %u\n", ret );
1578
1579 table_pid = HeapAlloc( GetProcessHeap(), 0, size );
1580 ret = pGetExtendedUdpTable( table_pid, &size, TRUE, AF_INET, UDP_TABLE_OWNER_PID, 0 );
1581 ok( ret == ERROR_SUCCESS, "got %u\n", ret );
1582 HeapFree( GetProcessHeap(), 0, table_pid );
1583
1584 size = 0;
1585 ret = pGetExtendedUdpTable( NULL, &size, TRUE, AF_INET, UDP_TABLE_OWNER_MODULE, 0 );
1586 ok( ret == ERROR_INSUFFICIENT_BUFFER, "got %u\n", ret );
1587
1588 table_module = HeapAlloc( GetProcessHeap(), 0, size );
1589 ret = pGetExtendedUdpTable( table_module, &size, TRUE, AF_INET, UDP_TABLE_OWNER_MODULE, 0 );
1590 ok( ret == ERROR_SUCCESS, "got %u\n", ret );
1591 HeapFree( GetProcessHeap(), 0, table_module );
1592 }
1593
1594 static void test_CreateSortedAddressPairs(void)
1595 {
1596 SOCKADDR_IN6 dst[2];
1597 SOCKADDR_IN6_PAIR *pair;
1598 ULONG pair_count;
1599 DWORD ret;
1600
1601 if (!pCreateSortedAddressPairs)
1602 {
1603 win_skip( "CreateSortedAddressPairs not available\n" );
1604 return;
1605 }
1606
1607 memset( dst, 0, sizeof(dst) );
1608 dst[0].sin6_family = AF_INET6;
1609 dst[0].sin6_addr.u.Word[5] = 0xffff;
1610 dst[0].sin6_addr.u.Word[6] = 0x0808;
1611 dst[0].sin6_addr.u.Word[7] = 0x0808;
1612
1613 pair_count = 0xdeadbeef;
1614 ret = pCreateSortedAddressPairs( NULL, 0, dst, 1, 0, NULL, &pair_count );
1615 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
1616 ok( pair_count == 0xdeadbeef, "got %u\n", pair_count );
1617
1618 pair = (SOCKADDR_IN6_PAIR *)0xdeadbeef;
1619 pair_count = 0xdeadbeef;
1620 ret = pCreateSortedAddressPairs( NULL, 0, NULL, 1, 0, &pair, &pair_count );
1621 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
1622 ok( pair == (SOCKADDR_IN6_PAIR *)0xdeadbeef, "got %p\n", pair );
1623 ok( pair_count == 0xdeadbeef, "got %u\n", pair_count );
1624
1625 pair = NULL;
1626 pair_count = 0xdeadbeef;
1627 ret = pCreateSortedAddressPairs( NULL, 0, dst, 1, 0, &pair, &pair_count );
1628 ok( ret == NO_ERROR, "got %u\n", ret );
1629 ok( pair != NULL, "pair not set\n" );
1630 ok( pair_count >= 1, "got %u\n", pair_count );
1631 ok( pair[0].SourceAddress != NULL, "src address not set\n" );
1632 ok( pair[0].DestinationAddress != NULL, "dst address not set\n" );
1633 pFreeMibTable( pair );
1634
1635 dst[1].sin6_family = AF_INET6;
1636 dst[1].sin6_addr.u.Word[5] = 0xffff;
1637 dst[1].sin6_addr.u.Word[6] = 0x0404;
1638 dst[1].sin6_addr.u.Word[7] = 0x0808;
1639
1640 pair = NULL;
1641 pair_count = 0xdeadbeef;
1642 ret = pCreateSortedAddressPairs( NULL, 0, dst, 2, 0, &pair, &pair_count );
1643 ok( ret == NO_ERROR, "got %u\n", ret );
1644 ok( pair != NULL, "pair not set\n" );
1645 ok( pair_count >= 2, "got %u\n", pair_count );
1646 ok( pair[0].SourceAddress != NULL, "src address not set\n" );
1647 ok( pair[0].DestinationAddress != NULL, "dst address not set\n" );
1648 ok( pair[1].SourceAddress != NULL, "src address not set\n" );
1649 ok( pair[1].DestinationAddress != NULL, "dst address not set\n" );
1650 pFreeMibTable( pair );
1651 }
1652
1653 static DWORD get_interface_index(void)
1654 {
1655 DWORD size = 0, ret = 0;
1656 IP_ADAPTER_ADDRESSES *buf, *aa;
1657
1658 if (pGetAdaptersAddresses( AF_UNSPEC, 0, NULL, NULL, &size ) != ERROR_BUFFER_OVERFLOW)
1659 return 0;
1660
1661 buf = HeapAlloc( GetProcessHeap(), 0, size );
1662 pGetAdaptersAddresses( AF_UNSPEC, 0, NULL, buf, &size );
1663 for (aa = buf; aa; aa = aa->Next)
1664 {
1665 if (aa->IfType == IF_TYPE_ETHERNET_CSMACD)
1666 {
1667 ret = aa->IfIndex;
1668 break;
1669 }
1670 }
1671 HeapFree( GetProcessHeap(), 0, buf );
1672 return ret;
1673 }
1674
1675 static void test_interface_identifier_conversion(void)
1676 {
1677 DWORD ret;
1678 NET_LUID luid;
1679 GUID guid;
1680 SIZE_T len;
1681 WCHAR nameW[IF_MAX_STRING_SIZE + 1];
1682 char nameA[IF_MAX_STRING_SIZE + 1];
1683 NET_IFINDEX index;
1684
1685 if (!pConvertInterfaceIndexToLuid)
1686 {
1687 win_skip( "ConvertInterfaceIndexToLuid not available\n" );
1688 return;
1689 }
1690 if (!(index = get_interface_index()))
1691 {
1692 skip( "no suitable interface found\n" );
1693 return;
1694 }
1695
1696 /* ConvertInterfaceIndexToLuid */
1697 ret = pConvertInterfaceIndexToLuid( 0, NULL );
1698 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
1699
1700 memset( &luid, 0xff, sizeof(luid) );
1701 ret = pConvertInterfaceIndexToLuid( 0, &luid );
1702 ok( ret == ERROR_FILE_NOT_FOUND, "got %u\n", ret );
1703 ok( !luid.Info.Reserved, "got %x\n", luid.Info.Reserved );
1704 ok( !luid.Info.NetLuidIndex, "got %u\n", luid.Info.NetLuidIndex );
1705 ok( !luid.Info.IfType, "got %u\n", luid.Info.IfType );
1706
1707 luid.Info.Reserved = luid.Info.NetLuidIndex = luid.Info.IfType = 0xdead;
1708 ret = pConvertInterfaceIndexToLuid( index, &luid );
1709 ok( !ret, "got %u\n", ret );
1710 ok( !luid.Info.Reserved, "got %x\n", luid.Info.Reserved );
1711 ok( luid.Info.NetLuidIndex != 0xdead, "index not set\n" );
1712 ok( luid.Info.IfType == IF_TYPE_ETHERNET_CSMACD, "got %u\n", luid.Info.IfType );
1713
1714 /* ConvertInterfaceLuidToIndex */
1715 ret = pConvertInterfaceLuidToIndex( NULL, NULL );
1716 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
1717
1718 ret = pConvertInterfaceLuidToIndex( NULL, &index );
1719 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
1720
1721 ret = pConvertInterfaceLuidToIndex( &luid, NULL );
1722 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
1723
1724 ret = pConvertInterfaceLuidToIndex( &luid, &index );
1725 ok( !ret, "got %u\n", ret );
1726
1727 /* ConvertInterfaceLuidToGuid */
1728 ret = pConvertInterfaceLuidToGuid( NULL, NULL );
1729 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
1730
1731 memset( &guid, 0xff, sizeof(guid) );
1732 ret = pConvertInterfaceLuidToGuid( NULL, &guid );
1733 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
1734 ok( guid.Data1 == 0xffffffff, "got %x\n", guid.Data1 );
1735
1736 ret = pConvertInterfaceLuidToGuid( &luid, NULL );
1737 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
1738
1739 memset( &guid, 0, sizeof(guid) );
1740 ret = pConvertInterfaceLuidToGuid( &luid, &guid );
1741 ok( !ret, "got %u\n", ret );
1742 ok( guid.Data1, "got %x\n", guid.Data1 );
1743
1744 /* ConvertInterfaceGuidToLuid */
1745 ret = pConvertInterfaceGuidToLuid( NULL, NULL );
1746 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
1747
1748 luid.Info.NetLuidIndex = 1;
1749 ret = pConvertInterfaceGuidToLuid( NULL, &luid );
1750 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
1751 ok( luid.Info.NetLuidIndex == 1, "got %u\n", luid.Info.NetLuidIndex );
1752
1753 ret = pConvertInterfaceGuidToLuid( &guid, NULL );
1754 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
1755
1756 luid.Info.Reserved = luid.Info.NetLuidIndex = luid.Info.IfType = 0xdead;
1757 ret = pConvertInterfaceGuidToLuid( &guid, &luid );
1758 ok( !ret, "got %u\n", ret );
1759 ok( !luid.Info.Reserved, "got %x\n", luid.Info.Reserved );
1760 ok( luid.Info.NetLuidIndex != 0xdead, "index not set\n" );
1761 ok( luid.Info.IfType == IF_TYPE_ETHERNET_CSMACD, "got %u\n", luid.Info.IfType );
1762
1763 /* ConvertInterfaceLuidToNameW */
1764 ret = pConvertInterfaceLuidToNameW( NULL, NULL, 0 );
1765 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
1766
1767 ret = pConvertInterfaceLuidToNameW( &luid, NULL, 0 );
1768 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
1769
1770 ret = pConvertInterfaceLuidToNameW( NULL, nameW, 0 );
1771 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
1772
1773 ret = pConvertInterfaceLuidToNameW( &luid, nameW, 0 );
1774 ok( ret == ERROR_NOT_ENOUGH_MEMORY, "got %u\n", ret );
1775
1776 nameW[0] = 0;
1777 len = sizeof(nameW)/sizeof(nameW[0]);
1778 ret = pConvertInterfaceLuidToNameW( &luid, nameW, len );
1779 ok( !ret, "got %u\n", ret );
1780 ok( nameW[0], "name not set\n" );
1781
1782 /* ConvertInterfaceLuidToNameA */
1783 ret = pConvertInterfaceLuidToNameA( NULL, NULL, 0 );
1784 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
1785
1786 ret = pConvertInterfaceLuidToNameA( &luid, NULL, 0 );
1787 ok( ret == ERROR_NOT_ENOUGH_MEMORY, "got %u\n", ret );
1788
1789 ret = pConvertInterfaceLuidToNameA( NULL, nameA, 0 );
1790 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
1791
1792 ret = pConvertInterfaceLuidToNameA( &luid, nameA, 0 );
1793 ok( ret == ERROR_NOT_ENOUGH_MEMORY, "got %u\n", ret );
1794
1795 nameA[0] = 0;
1796 len = sizeof(nameA)/sizeof(nameA[0]);
1797 ret = pConvertInterfaceLuidToNameA( &luid, nameA, len );
1798 ok( !ret, "got %u\n", ret );
1799 ok( nameA[0], "name not set\n" );
1800
1801 /* ConvertInterfaceNameToLuidW */
1802 ret = pConvertInterfaceNameToLuidW( NULL, NULL );
1803 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
1804
1805 luid.Info.Reserved = luid.Info.NetLuidIndex = luid.Info.IfType = 0xdead;
1806 ret = pConvertInterfaceNameToLuidW( NULL, &luid );
1807 ok( ret == ERROR_INVALID_NAME, "got %u\n", ret );
1808 ok( !luid.Info.Reserved, "got %x\n", luid.Info.Reserved );
1809 ok( luid.Info.NetLuidIndex != 0xdead, "index not set\n" );
1810 ok( !luid.Info.IfType, "got %u\n", luid.Info.IfType );
1811
1812 ret = pConvertInterfaceNameToLuidW( nameW, NULL );
1813 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
1814
1815 luid.Info.Reserved = luid.Info.NetLuidIndex = luid.Info.IfType = 0xdead;
1816 ret = pConvertInterfaceNameToLuidW( nameW, &luid );
1817 ok( !ret, "got %u\n", ret );
1818 ok( !luid.Info.Reserved, "got %x\n", luid.Info.Reserved );
1819 ok( luid.Info.NetLuidIndex != 0xdead, "index not set\n" );
1820 ok( luid.Info.IfType == IF_TYPE_ETHERNET_CSMACD, "got %u\n", luid.Info.IfType );
1821
1822 /* ConvertInterfaceNameToLuidA */
1823 ret = pConvertInterfaceNameToLuidA( NULL, NULL );
1824 ok( ret == ERROR_INVALID_NAME, "got %u\n", ret );
1825
1826 luid.Info.Reserved = luid.Info.NetLuidIndex = luid.Info.IfType = 0xdead;
1827 ret = pConvertInterfaceNameToLuidA( NULL, &luid );
1828 ok( ret == ERROR_INVALID_NAME, "got %u\n", ret );
1829 ok( luid.Info.Reserved == 0xdead, "reserved set\n" );
1830 ok( luid.Info.NetLuidIndex == 0xdead, "index set\n" );
1831 ok( luid.Info.IfType == 0xdead, "type set\n" );
1832
1833 ret = pConvertInterfaceNameToLuidA( nameA, NULL );
1834 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
1835
1836 luid.Info.Reserved = luid.Info.NetLuidIndex = luid.Info.IfType = 0xdead;
1837 ret = pConvertInterfaceNameToLuidA( nameA, &luid );
1838 ok( !ret, "got %u\n", ret );
1839 ok( !luid.Info.Reserved, "got %x\n", luid.Info.Reserved );
1840 ok( luid.Info.NetLuidIndex != 0xdead, "index not set\n" );
1841 ok( luid.Info.IfType == IF_TYPE_ETHERNET_CSMACD, "got %u\n", luid.Info.IfType );
1842 }
1843
1844 static void test_GetIfEntry2(void)
1845 {
1846 DWORD ret;
1847 MIB_IF_ROW2 row;
1848 NET_IFINDEX index;
1849
1850 if (!pGetIfEntry2)
1851 {
1852 win_skip( "GetIfEntry2 not available\n" );
1853 return;
1854 }
1855 if (!(index = get_interface_index()))
1856 {
1857 skip( "no suitable interface found\n" );
1858 return;
1859 }
1860
1861 ret = pGetIfEntry2( NULL );
1862 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
1863
1864 memset( &row, 0, sizeof(row) );
1865 ret = pGetIfEntry2( &row );
1866 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
1867
1868 memset( &row, 0, sizeof(row) );
1869 row.InterfaceIndex = index;
1870 ret = pGetIfEntry2( &row );
1871 ok( ret == NO_ERROR, "got %u\n", ret );
1872 ok( row.InterfaceIndex == index, "got %u\n", index );
1873 }
1874
1875 static void test_GetIfTable2(void)
1876 {
1877 DWORD ret;
1878 MIB_IF_TABLE2 *table;
1879
1880 if (!pGetIfTable2)
1881 {
1882 win_skip( "GetIfTable2 not available\n" );
1883 return;
1884 }
1885
1886 table = NULL;
1887 ret = pGetIfTable2( &table );
1888 ok( ret == NO_ERROR, "got %u\n", ret );
1889 ok( table != NULL, "table not set\n" );
1890 pFreeMibTable( table );
1891 }
1892
1893 START_TEST(iphlpapi)
1894 {
1895
1896 loadIPHlpApi();
1897 if (hLibrary) {
1898 HANDLE thread;
1899
1900 testWin98OnlyFunctions();
1901 testWinNT4Functions();
1902
1903 /* run testGetXXXX in two threads at once to make sure we don't crash in that case */
1904 thread = CreateThread(NULL, 0, testWin98Functions, NULL, 0, NULL);
1905 testWin98Functions(NULL);
1906 WaitForSingleObject(thread, INFINITE);
1907
1908 testWin2KFunctions();
1909 test_GetAdaptersAddresses();
1910 test_GetExtendedTcpTable();
1911 test_GetExtendedUdpTable();
1912 test_CreateSortedAddressPairs();
1913 test_interface_identifier_conversion();
1914 test_GetIfEntry2();
1915 test_GetIfTable2();
1916 freeIPHlpApi();
1917 }
1918 }