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 ok (ret, "IcmpSendEcho failed unexpectedly with error %d\n", error); 1032 1033 SetLastError(0xdeadbeef); 1034 replysz = sizeof(ICMP_ECHO_REPLY) + ICMP_MINLEN; 1035 ret = pIcmpSendEcho(icmp, address, senddata, ICMP_MINLEN + 1, NULL, replydata, replysz, 1000); 1036 error = GetLastError(); 1037 todo_wine 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, GAA_FLAG_INCLUDE_PREFIX, 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 IP_ADAPTER_PREFIX *prefix; 1390 1391 ok(S(U(*aa)).Length == sizeof(IP_ADAPTER_ADDRESSES_LH) || 1392 S(U(*aa)).Length == sizeof(IP_ADAPTER_ADDRESSES_XP), 1393 "Unknown structure size of %u bytes\n", S(U(*aa)).Length); 1394 ok(aa->DnsSuffix != NULL, "DnsSuffix is not a valid pointer\n"); 1395 ok(aa->Description != NULL, "Description is not a valid pointer\n"); 1396 ok(aa->FriendlyName != NULL, "FriendlyName is not a valid pointer\n"); 1397 1398 trace("\n"); 1399 trace("Length: %u\n", S(U(*aa)).Length); 1400 trace("IfIndex: %u\n", S(U(*aa)).IfIndex); 1401 trace("Next: %p\n", aa->Next); 1402 trace("AdapterName: %s\n", aa->AdapterName); 1403 trace("FirstUnicastAddress: %p\n", aa->FirstUnicastAddress); 1404 ua = aa->FirstUnicastAddress; 1405 while (ua) 1406 { 1407 ok(ua->PrefixOrigin != IpPrefixOriginOther, 1408 "bad address config value %d\n", ua->PrefixOrigin); 1409 ok(ua->SuffixOrigin != IpSuffixOriginOther, 1410 "bad address config value %d\n", ua->PrefixOrigin); 1411 /* Address configured manually or from DHCP server? */ 1412 if (ua->PrefixOrigin == IpPrefixOriginManual || 1413 ua->PrefixOrigin == IpPrefixOriginDhcp) 1414 { 1415 ok(ua->ValidLifetime, "expected non-zero value\n"); 1416 ok(ua->PreferredLifetime, "expected non-zero value\n"); 1417 ok(ua->LeaseLifetime, "expected non-zero\n"); 1418 } 1419 /* Is the address ok in the network (not duplicated)? */ 1420 ok(ua->DadState != IpDadStateInvalid && ua->DadState != IpDadStateDuplicate, 1421 "bad address duplication value %d\n", ua->DadState); 1422 trace("\tLength: %u\n", S(U(*ua)).Length); 1423 trace("\tFlags: 0x%08x\n", S(U(*ua)).Flags); 1424 trace("\tNext: %p\n", ua->Next); 1425 trace("\tAddress.lpSockaddr: %p\n", ua->Address.lpSockaddr); 1426 trace("\tAddress.iSockaddrLength: %d\n", ua->Address.iSockaddrLength); 1427 trace("\tPrefixOrigin: %u\n", ua->PrefixOrigin); 1428 trace("\tSuffixOrigin: %u\n", ua->SuffixOrigin); 1429 trace("\tDadState: %u\n", ua->DadState); 1430 trace("\tValidLifetime: %u seconds\n", ua->ValidLifetime); 1431 trace("\tPreferredLifetime: %u seconds\n", ua->PreferredLifetime); 1432 trace("\tLeaseLifetime: %u seconds\n", ua->LeaseLifetime); 1433 trace("\n"); 1434 ua = ua->Next; 1435 } 1436 trace("FirstAnycastAddress: %p\n", aa->FirstAnycastAddress); 1437 trace("FirstMulticastAddress: %p\n", aa->FirstMulticastAddress); 1438 trace("FirstDnsServerAddress: %p\n", aa->FirstDnsServerAddress); 1439 trace("DnsSuffix: %s %p\n", wine_dbgstr_w(aa->DnsSuffix), aa->DnsSuffix); 1440 trace("Description: %s %p\n", wine_dbgstr_w(aa->Description), aa->Description); 1441 trace("FriendlyName: %s %p\n", wine_dbgstr_w(aa->FriendlyName), aa->FriendlyName); 1442 trace("PhysicalAddressLength: %u\n", aa->PhysicalAddressLength); 1443 for (i = 0; i < aa->PhysicalAddressLength; i++) 1444 sprintf(temp + i * 3, "%02X-", aa->PhysicalAddress[i]); 1445 temp[i ? i * 3 - 1 : 0] = '\0'; 1446 trace("PhysicalAddress: %s\n", temp); 1447 trace("Flags: 0x%08x\n", aa->Flags); 1448 trace("Mtu: %u\n", aa->Mtu); 1449 trace("IfType: %u\n", aa->IfType); 1450 trace("OperStatus: %u\n", aa->OperStatus); 1451 trace("Ipv6IfIndex: %u\n", aa->Ipv6IfIndex); 1452 for (i = 0, temp[0] = '\0'; i < sizeof(aa->ZoneIndices) / sizeof(aa->ZoneIndices[0]); i++) 1453 sprintf(temp + strlen(temp), "%d ", aa->ZoneIndices[i]); 1454 trace("ZoneIndices: %s\n", temp); 1455 trace("FirstPrefix: %p\n", aa->FirstPrefix); 1456 prefix = aa->FirstPrefix; 1457 while (prefix) 1458 { 1459 trace("\tLength: %u\n", S(U(*prefix)).Length); 1460 trace("\tFlags: 0x%08x\n", S(U(*prefix)).Flags); 1461 trace("\tNext: %p\n", prefix->Next); 1462 trace("\tAddress.lpSockaddr: %p\n", prefix->Address.lpSockaddr); 1463 trace("\tAddress.iSockaddrLength: %d\n", prefix->Address.iSockaddrLength); 1464 trace("\tPrefixLength: %u\n", prefix->PrefixLength); 1465 trace("\n"); 1466 prefix = prefix->Next; 1467 } 1468 1469 if (S(U(*aa)).Length < sizeof(IP_ADAPTER_ADDRESSES_LH)) continue; 1470 #ifndef __REACTOS__ 1471 trace("TransmitLinkSpeed: %s\n", debugstr_longlong(aa->TransmitLinkSpeed)); 1472 trace("ReceiveLinkSpeed: %s\n", debugstr_longlong(aa->ReceiveLinkSpeed)); 1473 trace("FirstWinsServerAddress:%p\n", aa->FirstWinsServerAddress); 1474 trace("FirstGatewayAddress: %p\n", aa->FirstGatewayAddress); 1475 trace("Ipv4Metric: %u\n", aa->Ipv4Metric); 1476 trace("Ipv6Metric: %u\n", aa->Ipv6Metric); 1477 trace("Luid: %p\n", &aa->Luid); 1478 trace("Dhcpv4Server: %p\n", &aa->Dhcpv4Server); 1479 trace("CompartmentId: %u\n", aa->CompartmentId); 1480 trace("NetworkGuid: %s\n", wine_dbgstr_guid((GUID*) &aa->NetworkGuid)); 1481 trace("ConnectionType: %u\n", aa->ConnectionType); 1482 trace("TunnelType: %u\n", aa->TunnelType); 1483 trace("Dhcpv6Server: %p\n", &aa->Dhcpv6Server); 1484 trace("Dhcpv6ClientDuidLength:%u\n", aa->Dhcpv6ClientDuidLength); 1485 trace("Dhcpv6ClientDuid: %p\n", aa->Dhcpv6ClientDuid); 1486 trace("Dhcpv6Iaid: %u\n", aa->Dhcpv6Iaid); 1487 trace("FirstDnsSuffix: %p\n", aa->FirstDnsSuffix); 1488 trace("\n"); 1489 #endif 1490 } 1491 HeapFree(GetProcessHeap(), 0, ptr); 1492 } 1493 1494 static void test_GetExtendedTcpTable(void) 1495 { 1496 DWORD ret, size; 1497 MIB_TCPTABLE *table; 1498 MIB_TCPTABLE_OWNER_PID *table_pid; 1499 MIB_TCPTABLE_OWNER_MODULE *table_module; 1500 1501 if (!pGetExtendedTcpTable) 1502 { 1503 win_skip("GetExtendedTcpTable not available\n"); 1504 return; 1505 } 1506 ret = pGetExtendedTcpTable( NULL, NULL, TRUE, AF_INET, TCP_TABLE_BASIC_ALL, 0 ); 1507 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret ); 1508 1509 size = 0; 1510 ret = pGetExtendedTcpTable( NULL, &size, TRUE, AF_INET, TCP_TABLE_BASIC_ALL, 0 ); 1511 ok( ret == ERROR_INSUFFICIENT_BUFFER, "got %u\n", ret ); 1512 1513 table = HeapAlloc( GetProcessHeap(), 0, size ); 1514 ret = pGetExtendedTcpTable( table, &size, TRUE, AF_INET, TCP_TABLE_BASIC_ALL, 0 ); 1515 ok( ret == ERROR_SUCCESS, "got %u\n", ret ); 1516 HeapFree( GetProcessHeap(), 0, table ); 1517 1518 size = 0; 1519 ret = pGetExtendedTcpTable( NULL, &size, TRUE, AF_INET, TCP_TABLE_BASIC_LISTENER, 0 ); 1520 ok( ret == ERROR_INSUFFICIENT_BUFFER, "got %u\n", ret ); 1521 1522 table = HeapAlloc( GetProcessHeap(), 0, size ); 1523 ret = pGetExtendedTcpTable( table, &size, TRUE, AF_INET, TCP_TABLE_BASIC_LISTENER, 0 ); 1524 ok( ret == ERROR_SUCCESS, "got %u\n", ret ); 1525 HeapFree( GetProcessHeap(), 0, table ); 1526 1527 size = 0; 1528 ret = pGetExtendedTcpTable( NULL, &size, TRUE, AF_INET, TCP_TABLE_OWNER_PID_ALL, 0 ); 1529 ok( ret == ERROR_INSUFFICIENT_BUFFER, "got %u\n", ret ); 1530 1531 table_pid = HeapAlloc( GetProcessHeap(), 0, size ); 1532 ret = pGetExtendedTcpTable( table_pid, &size, TRUE, AF_INET, TCP_TABLE_OWNER_PID_ALL, 0 ); 1533 ok( ret == ERROR_SUCCESS, "got %u\n", ret ); 1534 HeapFree( GetProcessHeap(), 0, table_pid ); 1535 1536 size = 0; 1537 ret = pGetExtendedTcpTable( NULL, &size, TRUE, AF_INET, TCP_TABLE_OWNER_PID_LISTENER, 0 ); 1538 ok( ret == ERROR_INSUFFICIENT_BUFFER, "got %u\n", ret ); 1539 1540 table_pid = HeapAlloc( GetProcessHeap(), 0, size ); 1541 ret = pGetExtendedTcpTable( table_pid, &size, TRUE, AF_INET, TCP_TABLE_OWNER_PID_LISTENER, 0 ); 1542 ok( ret == ERROR_SUCCESS, "got %u\n", ret ); 1543 HeapFree( GetProcessHeap(), 0, table_pid ); 1544 1545 size = 0; 1546 ret = pGetExtendedTcpTable( NULL, &size, TRUE, AF_INET, TCP_TABLE_OWNER_MODULE_ALL, 0 ); 1547 ok( ret == ERROR_INSUFFICIENT_BUFFER, "got %u\n", ret ); 1548 1549 table_module = HeapAlloc( GetProcessHeap(), 0, size ); 1550 ret = pGetExtendedTcpTable( table_module, &size, TRUE, AF_INET, TCP_TABLE_OWNER_MODULE_ALL, 0 ); 1551 ok( ret == ERROR_SUCCESS, "got %u\n", ret ); 1552 HeapFree( GetProcessHeap(), 0, table_module ); 1553 1554 size = 0; 1555 ret = pGetExtendedTcpTable( NULL, &size, TRUE, AF_INET, TCP_TABLE_OWNER_MODULE_LISTENER, 0 ); 1556 ok( ret == ERROR_INSUFFICIENT_BUFFER, "got %u\n", ret ); 1557 1558 table_module = HeapAlloc( GetProcessHeap(), 0, size ); 1559 ret = pGetExtendedTcpTable( table_module, &size, TRUE, AF_INET, TCP_TABLE_OWNER_MODULE_LISTENER, 0 ); 1560 ok( ret == ERROR_SUCCESS, "got %u\n", ret ); 1561 HeapFree( GetProcessHeap(), 0, table_module ); 1562 } 1563 1564 static void test_GetExtendedUdpTable(void) 1565 { 1566 DWORD ret, size; 1567 MIB_UDPTABLE *table; 1568 MIB_UDPTABLE_OWNER_PID *table_pid; 1569 MIB_UDPTABLE_OWNER_MODULE *table_module; 1570 1571 if (!pGetExtendedUdpTable) 1572 { 1573 win_skip("GetExtendedUdpTable not available\n"); 1574 return; 1575 } 1576 ret = pGetExtendedUdpTable( NULL, NULL, TRUE, AF_INET, UDP_TABLE_BASIC, 0 ); 1577 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret ); 1578 1579 size = 0; 1580 ret = pGetExtendedUdpTable( NULL, &size, TRUE, AF_INET, UDP_TABLE_BASIC, 0 ); 1581 ok( ret == ERROR_INSUFFICIENT_BUFFER, "got %u\n", ret ); 1582 1583 table = HeapAlloc( GetProcessHeap(), 0, size ); 1584 ret = pGetExtendedUdpTable( table, &size, TRUE, AF_INET, UDP_TABLE_BASIC, 0 ); 1585 ok( ret == ERROR_SUCCESS, "got %u\n", ret ); 1586 HeapFree( GetProcessHeap(), 0, table ); 1587 1588 size = 0; 1589 ret = pGetExtendedUdpTable( NULL, &size, TRUE, AF_INET, UDP_TABLE_OWNER_PID, 0 ); 1590 ok( ret == ERROR_INSUFFICIENT_BUFFER, "got %u\n", ret ); 1591 1592 table_pid = HeapAlloc( GetProcessHeap(), 0, size ); 1593 ret = pGetExtendedUdpTable( table_pid, &size, TRUE, AF_INET, UDP_TABLE_OWNER_PID, 0 ); 1594 ok( ret == ERROR_SUCCESS, "got %u\n", ret ); 1595 HeapFree( GetProcessHeap(), 0, table_pid ); 1596 1597 size = 0; 1598 ret = pGetExtendedUdpTable( NULL, &size, TRUE, AF_INET, UDP_TABLE_OWNER_MODULE, 0 ); 1599 ok( ret == ERROR_INSUFFICIENT_BUFFER, "got %u\n", ret ); 1600 1601 table_module = HeapAlloc( GetProcessHeap(), 0, size ); 1602 ret = pGetExtendedUdpTable( table_module, &size, TRUE, AF_INET, UDP_TABLE_OWNER_MODULE, 0 ); 1603 ok( ret == ERROR_SUCCESS, "got %u\n", ret ); 1604 HeapFree( GetProcessHeap(), 0, table_module ); 1605 } 1606 1607 static void test_CreateSortedAddressPairs(void) 1608 { 1609 SOCKADDR_IN6 dst[2]; 1610 SOCKADDR_IN6_PAIR *pair; 1611 ULONG pair_count; 1612 DWORD ret; 1613 1614 if (!pCreateSortedAddressPairs) 1615 { 1616 win_skip( "CreateSortedAddressPairs not available\n" ); 1617 return; 1618 } 1619 1620 memset( dst, 0, sizeof(dst) ); 1621 dst[0].sin6_family = AF_INET6; 1622 dst[0].sin6_addr.u.Word[5] = 0xffff; 1623 dst[0].sin6_addr.u.Word[6] = 0x0808; 1624 dst[0].sin6_addr.u.Word[7] = 0x0808; 1625 1626 pair_count = 0xdeadbeef; 1627 ret = pCreateSortedAddressPairs( NULL, 0, dst, 1, 0, NULL, &pair_count ); 1628 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret ); 1629 ok( pair_count == 0xdeadbeef, "got %u\n", pair_count ); 1630 1631 pair = (SOCKADDR_IN6_PAIR *)0xdeadbeef; 1632 pair_count = 0xdeadbeef; 1633 ret = pCreateSortedAddressPairs( NULL, 0, NULL, 1, 0, &pair, &pair_count ); 1634 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret ); 1635 ok( pair == (SOCKADDR_IN6_PAIR *)0xdeadbeef, "got %p\n", pair ); 1636 ok( pair_count == 0xdeadbeef, "got %u\n", pair_count ); 1637 1638 pair = NULL; 1639 pair_count = 0xdeadbeef; 1640 ret = pCreateSortedAddressPairs( NULL, 0, dst, 1, 0, &pair, &pair_count ); 1641 ok( ret == NO_ERROR, "got %u\n", ret ); 1642 ok( pair != NULL, "pair not set\n" ); 1643 ok( pair_count >= 1, "got %u\n", pair_count ); 1644 ok( pair[0].SourceAddress != NULL, "src address not set\n" ); 1645 ok( pair[0].DestinationAddress != NULL, "dst address not set\n" ); 1646 pFreeMibTable( pair ); 1647 1648 dst[1].sin6_family = AF_INET6; 1649 dst[1].sin6_addr.u.Word[5] = 0xffff; 1650 dst[1].sin6_addr.u.Word[6] = 0x0404; 1651 dst[1].sin6_addr.u.Word[7] = 0x0808; 1652 1653 pair = NULL; 1654 pair_count = 0xdeadbeef; 1655 ret = pCreateSortedAddressPairs( NULL, 0, dst, 2, 0, &pair, &pair_count ); 1656 ok( ret == NO_ERROR, "got %u\n", ret ); 1657 ok( pair != NULL, "pair not set\n" ); 1658 ok( pair_count >= 2, "got %u\n", pair_count ); 1659 ok( pair[0].SourceAddress != NULL, "src address not set\n" ); 1660 ok( pair[0].DestinationAddress != NULL, "dst address not set\n" ); 1661 ok( pair[1].SourceAddress != NULL, "src address not set\n" ); 1662 ok( pair[1].DestinationAddress != NULL, "dst address not set\n" ); 1663 pFreeMibTable( pair ); 1664 } 1665 1666 static DWORD get_interface_index(void) 1667 { 1668 DWORD size = 0, ret = 0; 1669 IP_ADAPTER_ADDRESSES *buf, *aa; 1670 1671 if (pGetAdaptersAddresses( AF_UNSPEC, 0, NULL, NULL, &size ) != ERROR_BUFFER_OVERFLOW) 1672 return 0; 1673 1674 buf = HeapAlloc( GetProcessHeap(), 0, size ); 1675 pGetAdaptersAddresses( AF_UNSPEC, 0, NULL, buf, &size ); 1676 for (aa = buf; aa; aa = aa->Next) 1677 { 1678 if (aa->IfType == IF_TYPE_ETHERNET_CSMACD) 1679 { 1680 ret = aa->IfIndex; 1681 break; 1682 } 1683 } 1684 HeapFree( GetProcessHeap(), 0, buf ); 1685 return ret; 1686 } 1687 1688 static void test_interface_identifier_conversion(void) 1689 { 1690 DWORD ret; 1691 NET_LUID luid; 1692 GUID guid; 1693 SIZE_T len; 1694 WCHAR nameW[IF_MAX_STRING_SIZE + 1]; 1695 char nameA[IF_MAX_STRING_SIZE + 1]; 1696 NET_IFINDEX index; 1697 1698 if (!pConvertInterfaceIndexToLuid) 1699 { 1700 win_skip( "ConvertInterfaceIndexToLuid not available\n" ); 1701 return; 1702 } 1703 if (!(index = get_interface_index())) 1704 { 1705 skip( "no suitable interface found\n" ); 1706 return; 1707 } 1708 1709 /* ConvertInterfaceIndexToLuid */ 1710 ret = pConvertInterfaceIndexToLuid( 0, NULL ); 1711 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret ); 1712 1713 memset( &luid, 0xff, sizeof(luid) ); 1714 ret = pConvertInterfaceIndexToLuid( 0, &luid ); 1715 ok( ret == ERROR_FILE_NOT_FOUND, "got %u\n", ret ); 1716 ok( !luid.Info.Reserved, "got %x\n", luid.Info.Reserved ); 1717 ok( !luid.Info.NetLuidIndex, "got %u\n", luid.Info.NetLuidIndex ); 1718 ok( !luid.Info.IfType, "got %u\n", luid.Info.IfType ); 1719 1720 luid.Info.Reserved = luid.Info.NetLuidIndex = luid.Info.IfType = 0xdead; 1721 ret = pConvertInterfaceIndexToLuid( index, &luid ); 1722 ok( !ret, "got %u\n", ret ); 1723 ok( !luid.Info.Reserved, "got %x\n", luid.Info.Reserved ); 1724 ok( luid.Info.NetLuidIndex != 0xdead, "index not set\n" ); 1725 ok( luid.Info.IfType == IF_TYPE_ETHERNET_CSMACD, "got %u\n", luid.Info.IfType ); 1726 1727 /* ConvertInterfaceLuidToIndex */ 1728 ret = pConvertInterfaceLuidToIndex( NULL, NULL ); 1729 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret ); 1730 1731 ret = pConvertInterfaceLuidToIndex( NULL, &index ); 1732 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret ); 1733 1734 ret = pConvertInterfaceLuidToIndex( &luid, NULL ); 1735 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret ); 1736 1737 ret = pConvertInterfaceLuidToIndex( &luid, &index ); 1738 ok( !ret, "got %u\n", ret ); 1739 1740 /* ConvertInterfaceLuidToGuid */ 1741 ret = pConvertInterfaceLuidToGuid( NULL, NULL ); 1742 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret ); 1743 1744 memset( &guid, 0xff, sizeof(guid) ); 1745 ret = pConvertInterfaceLuidToGuid( NULL, &guid ); 1746 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret ); 1747 ok( guid.Data1 == 0xffffffff, "got %x\n", guid.Data1 ); 1748 1749 ret = pConvertInterfaceLuidToGuid( &luid, NULL ); 1750 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret ); 1751 1752 memset( &guid, 0, sizeof(guid) ); 1753 ret = pConvertInterfaceLuidToGuid( &luid, &guid ); 1754 ok( !ret, "got %u\n", ret ); 1755 ok( guid.Data1, "got %x\n", guid.Data1 ); 1756 1757 /* ConvertInterfaceGuidToLuid */ 1758 ret = pConvertInterfaceGuidToLuid( NULL, NULL ); 1759 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret ); 1760 1761 luid.Info.NetLuidIndex = 1; 1762 ret = pConvertInterfaceGuidToLuid( NULL, &luid ); 1763 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret ); 1764 ok( luid.Info.NetLuidIndex == 1, "got %u\n", luid.Info.NetLuidIndex ); 1765 1766 ret = pConvertInterfaceGuidToLuid( &guid, NULL ); 1767 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret ); 1768 1769 luid.Info.Reserved = luid.Info.NetLuidIndex = luid.Info.IfType = 0xdead; 1770 ret = pConvertInterfaceGuidToLuid( &guid, &luid ); 1771 ok( !ret, "got %u\n", ret ); 1772 ok( !luid.Info.Reserved, "got %x\n", luid.Info.Reserved ); 1773 ok( luid.Info.NetLuidIndex != 0xdead, "index not set\n" ); 1774 ok( luid.Info.IfType == IF_TYPE_ETHERNET_CSMACD, "got %u\n", luid.Info.IfType ); 1775 1776 /* ConvertInterfaceLuidToNameW */ 1777 ret = pConvertInterfaceLuidToNameW( NULL, NULL, 0 ); 1778 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret ); 1779 1780 ret = pConvertInterfaceLuidToNameW( &luid, NULL, 0 ); 1781 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret ); 1782 1783 ret = pConvertInterfaceLuidToNameW( NULL, nameW, 0 ); 1784 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret ); 1785 1786 ret = pConvertInterfaceLuidToNameW( &luid, nameW, 0 ); 1787 ok( ret == ERROR_NOT_ENOUGH_MEMORY, "got %u\n", ret ); 1788 1789 nameW[0] = 0; 1790 len = sizeof(nameW)/sizeof(nameW[0]); 1791 ret = pConvertInterfaceLuidToNameW( &luid, nameW, len ); 1792 ok( !ret, "got %u\n", ret ); 1793 ok( nameW[0], "name not set\n" ); 1794 1795 /* ConvertInterfaceLuidToNameA */ 1796 ret = pConvertInterfaceLuidToNameA( NULL, NULL, 0 ); 1797 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret ); 1798 1799 ret = pConvertInterfaceLuidToNameA( &luid, NULL, 0 ); 1800 ok( ret == ERROR_NOT_ENOUGH_MEMORY, "got %u\n", ret ); 1801 1802 ret = pConvertInterfaceLuidToNameA( NULL, nameA, 0 ); 1803 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret ); 1804 1805 ret = pConvertInterfaceLuidToNameA( &luid, nameA, 0 ); 1806 ok( ret == ERROR_NOT_ENOUGH_MEMORY, "got %u\n", ret ); 1807 1808 nameA[0] = 0; 1809 len = sizeof(nameA)/sizeof(nameA[0]); 1810 ret = pConvertInterfaceLuidToNameA( &luid, nameA, len ); 1811 ok( !ret, "got %u\n", ret ); 1812 ok( nameA[0], "name not set\n" ); 1813 1814 /* ConvertInterfaceNameToLuidW */ 1815 ret = pConvertInterfaceNameToLuidW( NULL, NULL ); 1816 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret ); 1817 1818 luid.Info.Reserved = luid.Info.NetLuidIndex = luid.Info.IfType = 0xdead; 1819 ret = pConvertInterfaceNameToLuidW( NULL, &luid ); 1820 ok( ret == ERROR_INVALID_NAME, "got %u\n", ret ); 1821 ok( !luid.Info.Reserved, "got %x\n", luid.Info.Reserved ); 1822 ok( luid.Info.NetLuidIndex != 0xdead, "index not set\n" ); 1823 ok( !luid.Info.IfType, "got %u\n", luid.Info.IfType ); 1824 1825 ret = pConvertInterfaceNameToLuidW( nameW, NULL ); 1826 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret ); 1827 1828 luid.Info.Reserved = luid.Info.NetLuidIndex = luid.Info.IfType = 0xdead; 1829 ret = pConvertInterfaceNameToLuidW( nameW, &luid ); 1830 ok( !ret, "got %u\n", ret ); 1831 ok( !luid.Info.Reserved, "got %x\n", luid.Info.Reserved ); 1832 ok( luid.Info.NetLuidIndex != 0xdead, "index not set\n" ); 1833 ok( luid.Info.IfType == IF_TYPE_ETHERNET_CSMACD, "got %u\n", luid.Info.IfType ); 1834 1835 /* ConvertInterfaceNameToLuidA */ 1836 ret = pConvertInterfaceNameToLuidA( NULL, NULL ); 1837 ok( ret == ERROR_INVALID_NAME, "got %u\n", ret ); 1838 1839 luid.Info.Reserved = luid.Info.NetLuidIndex = luid.Info.IfType = 0xdead; 1840 ret = pConvertInterfaceNameToLuidA( NULL, &luid ); 1841 ok( ret == ERROR_INVALID_NAME, "got %u\n", ret ); 1842 ok( luid.Info.Reserved == 0xdead, "reserved set\n" ); 1843 ok( luid.Info.NetLuidIndex == 0xdead, "index set\n" ); 1844 ok( luid.Info.IfType == 0xdead, "type set\n" ); 1845 1846 ret = pConvertInterfaceNameToLuidA( nameA, NULL ); 1847 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret ); 1848 1849 luid.Info.Reserved = luid.Info.NetLuidIndex = luid.Info.IfType = 0xdead; 1850 ret = pConvertInterfaceNameToLuidA( nameA, &luid ); 1851 ok( !ret, "got %u\n", ret ); 1852 ok( !luid.Info.Reserved, "got %x\n", luid.Info.Reserved ); 1853 ok( luid.Info.NetLuidIndex != 0xdead, "index not set\n" ); 1854 ok( luid.Info.IfType == IF_TYPE_ETHERNET_CSMACD, "got %u\n", luid.Info.IfType ); 1855 } 1856 1857 static void test_GetIfEntry2(void) 1858 { 1859 DWORD ret; 1860 MIB_IF_ROW2 row; 1861 NET_IFINDEX index; 1862 1863 if (!pGetIfEntry2) 1864 { 1865 win_skip( "GetIfEntry2 not available\n" ); 1866 return; 1867 } 1868 if (!(index = get_interface_index())) 1869 { 1870 skip( "no suitable interface found\n" ); 1871 return; 1872 } 1873 1874 ret = pGetIfEntry2( NULL ); 1875 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret ); 1876 1877 memset( &row, 0, sizeof(row) ); 1878 ret = pGetIfEntry2( &row ); 1879 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret ); 1880 1881 memset( &row, 0, sizeof(row) ); 1882 row.InterfaceIndex = index; 1883 ret = pGetIfEntry2( &row ); 1884 ok( ret == NO_ERROR, "got %u\n", ret ); 1885 ok( row.InterfaceIndex == index, "got %u\n", index ); 1886 } 1887 1888 static void test_GetIfTable2(void) 1889 { 1890 DWORD ret; 1891 MIB_IF_TABLE2 *table; 1892 1893 if (!pGetIfTable2) 1894 { 1895 win_skip( "GetIfTable2 not available\n" ); 1896 return; 1897 } 1898 1899 table = NULL; 1900 ret = pGetIfTable2( &table ); 1901 ok( ret == NO_ERROR, "got %u\n", ret ); 1902 ok( table != NULL, "table not set\n" ); 1903 pFreeMibTable( table ); 1904 } 1905 1906 START_TEST(iphlpapi) 1907 { 1908 1909 loadIPHlpApi(); 1910 if (hLibrary) { 1911 HANDLE thread; 1912 1913 testWin98OnlyFunctions(); 1914 testWinNT4Functions(); 1915 1916 /* run testGetXXXX in two threads at once to make sure we don't crash in that case */ 1917 thread = CreateThread(NULL, 0, testWin98Functions, NULL, 0, NULL); 1918 testWin98Functions(NULL); 1919 WaitForSingleObject(thread, INFINITE); 1920 1921 testWin2KFunctions(); 1922 test_GetAdaptersAddresses(); 1923 test_GetExtendedTcpTable(); 1924 test_GetExtendedUdpTable(); 1925 test_CreateSortedAddressPairs(); 1926 test_interface_identifier_conversion(); 1927 test_GetIfEntry2(); 1928 test_GetIfTable2(); 1929 freeIPHlpApi(); 1930 } 1931 } 1932