From: Paul Gofman pgofman@codeweavers.com
--- dlls/iphlpapi/iphlpapi.spec | 2 +- dlls/iphlpapi/iphlpapi_main.c | 27 +++++++++++++++++ dlls/iphlpapi/tests/iphlpapi.c | 53 +++++++++++++++++++++++++++++++--- include/netioapi.h | 1 + 4 files changed, 78 insertions(+), 5 deletions(-)
diff --git a/dlls/iphlpapi/iphlpapi.spec b/dlls/iphlpapi/iphlpapi.spec index facb52e0448..c04560ad656 100644 --- a/dlls/iphlpapi/iphlpapi.spec +++ b/dlls/iphlpapi/iphlpapi.spec @@ -106,7 +106,7 @@ @ stdcall GetIpForwardTable( ptr ptr long ) @ stdcall GetIpForwardTable2( long ptr ) @ stub GetIpForwardTableFromStack -#@ stub GetIpInterfaceEntry +@ stdcall GetIpInterfaceEntry( ptr ) @ stdcall GetIpInterfaceTable( long ptr ) #@ stub GetIpNetEntry2 @ stdcall GetIpNetTable( ptr ptr long ) diff --git a/dlls/iphlpapi/iphlpapi_main.c b/dlls/iphlpapi/iphlpapi_main.c index 4c34318b2ce..94769ed09fe 100644 --- a/dlls/iphlpapi/iphlpapi_main.c +++ b/dlls/iphlpapi/iphlpapi_main.c @@ -4625,6 +4625,33 @@ DWORD WINAPI GetIpInterfaceTable( ADDRESS_FAMILY family, MIB_IPINTERFACE_TABLE * return ERROR_SUCCESS; }
+/****************************************************************** + * GetIpInterfaceEntry (IPHLPAPI.@) + */ +DWORD WINAPI GetIpInterfaceEntry( MIB_IPINTERFACE_ROW *row ) +{ + struct nsi_ip_interface_dynamic dyn; + struct nsi_ip_interface_key key; + struct nsi_ip_interface_rw rw; + DWORD err; + + TRACE( "%p.\n", row ); + + if (!row) return ERROR_INVALID_PARAMETER; + if (row->Family != AF_INET && row->Family != AF_INET6) return ERROR_INVALID_PARAMETER; + + key.luid = row->InterfaceLuid; + if (!key.luid.Value && ConvertInterfaceIndexToLuid( row->InterfaceIndex, &key.luid )) return ERROR_NOT_FOUND; + + err = NsiGetAllParameters( 1, ip_module_id( row->Family ), NSI_IP_INTERFACE_TABLE, + &key, sizeof(key), &rw, sizeof(rw), + &dyn, sizeof(dyn), NULL, 0 ); + if (err) return err; + fill_ip_interface_table_row( row->Family, row, &key, &rw, &dyn ); + return ERROR_SUCCESS; +} + + /****************************************************************** * GetBestRoute2 (IPHLPAPI.@) */ diff --git a/dlls/iphlpapi/tests/iphlpapi.c b/dlls/iphlpapi/tests/iphlpapi.c index dfe067798a6..e189fd795f8 100644 --- a/dlls/iphlpapi/tests/iphlpapi.c +++ b/dlls/iphlpapi/tests/iphlpapi.c @@ -67,6 +67,7 @@ static DWORD (WINAPI *pParseNetworkString)(const WCHAR*,DWORD,NET_ADDRESS_INFO*, static DWORD (WINAPI *pNotifyUnicastIpAddressChange)(ADDRESS_FAMILY, PUNICAST_IPADDRESS_CHANGE_CALLBACK, PVOID, BOOLEAN, HANDLE *); static DWORD (WINAPI *pCancelMibChangeNotify2)(HANDLE); +static DWORD (WINAPI *pGetIpInterfaceEntry)(MIB_IPINTERFACE_ROW*); static DWORD (WINAPI *pGetIpInterfaceTable)(ADDRESS_FAMILY family, MIB_IPINTERFACE_TABLE **table);
DWORD WINAPI ConvertGuidToStringA( const GUID *, char *, DWORD ); @@ -90,6 +91,7 @@ static void loadIPHlpApi(void) pNotifyUnicastIpAddressChange = (void *)GetProcAddress(hLibrary, "NotifyUnicastIpAddressChange"); pCancelMibChangeNotify2 = (void *)GetProcAddress(hLibrary, "CancelMibChangeNotify2"); pGetIpInterfaceTable = (void *)GetProcAddress(hLibrary, "GetIpInterfaceTable"); + pGetIpInterfaceEntry = (void *)GetProcAddress(hLibrary, "GetIpInterfaceEntry"); } }
@@ -3108,8 +3110,9 @@ static void test_compartments(void) ok(id == NET_IF_COMPARTMENT_ID_PRIMARY, "got %u\n", id); }
-static void test_GetIpInterfaceTable(void) +static void test_GetIpInterface(void) { + MIB_IPINTERFACE_ROW entry_row; MIB_IPINTERFACE_TABLE *table; MIB_IF_ROW2 *if_info = NULL; MIB_IPINTERFACE_ROW *row; @@ -3118,9 +3121,9 @@ static void test_GetIpInterfaceTable(void) BOOL connected, is_loopback, loopback_found = FALSE; DWORD err;
- if (!pGetIpInterfaceTable) + if (!pGetIpInterfaceTable || !pGetIpInterfaceEntry) { - win_skip( "GetIpInterfaceTable is not available\n" ); + win_skip( "GetIpInterfaceTable or GetIpInterfaceEntry is not available\n" ); return; }
@@ -3158,6 +3161,48 @@ static void test_GetIpInterfaceTable(void) todo_wine ok( row->NlMtu == ~0u, "got %lu.\n", row->NlMtu ); connected = (if_info->MediaConnectState == MediaConnectStateConnected); ok( row->Connected == connected, "got %d, expected %d.\n", row->Connected, connected ); + + err = GetIpInterfaceEntry( NULL ); + ok( err == ERROR_INVALID_PARAMETER, "got %ld\n", err ); + + memset( &entry_row, 0, sizeof(entry_row) ); + entry_row.Family = AF_UNSPEC; + entry_row.InterfaceLuid = row->InterfaceLuid; + err = GetIpInterfaceEntry( &entry_row ); + ok( err == ERROR_INVALID_PARAMETER, "got %ld\n", err ); + + memset( &entry_row, 0xcc, sizeof(entry_row) ); + entry_row.Family = row->Family; + entry_row.InterfaceLuid = row->InterfaceLuid; + err = pGetIpInterfaceEntry( &entry_row ); + ok( !err, "got %ld\n", err ); + ok( entry_row.Family == row->Family, "got %d, expected %d.\n", entry_row.Family, row->Family ); + ok( entry_row.InterfaceLuid.Value == row->InterfaceLuid.Value, "got %#I64x, expected %#I64x.\n", + entry_row.InterfaceLuid.Value, row->InterfaceLuid.Value ); + ok( entry_row.InterfaceIndex == row->InterfaceIndex, "got %lu, expected %lu.\n", + entry_row.InterfaceIndex, row->InterfaceIndex ); + ok( entry_row.BaseReachableTime == row->BaseReachableTime, "got %lu, expected %lu.\n", + entry_row.BaseReachableTime, row->BaseReachableTime ); + + memset( &entry_row, 0xcc, sizeof(entry_row) ); + entry_row.Family = row->Family; + entry_row.InterfaceIndex = row->InterfaceIndex; + err = GetIpInterfaceEntry( &entry_row ); + ok( err == ERROR_NOT_FOUND, "got %ld\n", err ); + + memset( &entry_row, 0xcc, sizeof(entry_row) ); + entry_row.Family = row->Family; + entry_row.InterfaceLuid.Value = 0; + entry_row.InterfaceIndex = row->InterfaceIndex; + err = GetIpInterfaceEntry( &entry_row ); + ok( !err, "got %ld\n", err ); + ok( entry_row.Family == row->Family, "got %d, expected %d.\n", entry_row.Family, row->Family ); + ok( entry_row.InterfaceLuid.Value == row->InterfaceLuid.Value, "got %#I64x, expected %#I64x.\n", + entry_row.InterfaceLuid.Value, row->InterfaceLuid.Value ); + ok( entry_row.InterfaceIndex == row->InterfaceIndex, "got %lu, expected %lu.\n", + entry_row.InterfaceIndex, row->InterfaceIndex ); + ok( entry_row.BaseReachableTime == row->BaseReachableTime, "got %lu, expected %lu.\n", + entry_row.BaseReachableTime, row->BaseReachableTime ); } ok( loopback_found, "loopback not found.\n" ); FreeMibTable( table ); @@ -3205,7 +3250,7 @@ START_TEST(iphlpapi) test_NotifyUnicastIpAddressChange(); test_ConvertGuidToString(); test_compartments(); - test_GetIpInterfaceTable(); + test_GetIpInterface(); freeIPHlpApi(); }
diff --git a/include/netioapi.h b/include/netioapi.h index 9a9cff8ca79..09824f946e4 100644 --- a/include/netioapi.h +++ b/include/netioapi.h @@ -276,6 +276,7 @@ IPHLPAPI_DLL_LINKAGE DWORD WINAPI GetIfTable2(MIB_IF_TABLE2**); IPHLPAPI_DLL_LINKAGE DWORD WINAPI GetIfTable2Ex(MIB_IF_TABLE_LEVEL,MIB_IF_TABLE2**); IPHLPAPI_DLL_LINKAGE DWORD WINAPI GetIpForwardEntry2(MIB_IPFORWARD_ROW2*); IPHLPAPI_DLL_LINKAGE DWORD WINAPI GetIpForwardTable2(ADDRESS_FAMILY,MIB_IPFORWARD_TABLE2**); +IPHLPAPI_DLL_LINKAGE DWORD WINAPI GetIpInterfaceEntry(MIB_IPINTERFACE_ROW*); IPHLPAPI_DLL_LINKAGE DWORD WINAPI GetIpInterfaceTable(ADDRESS_FAMILY,MIB_IPINTERFACE_TABLE**); IPHLPAPI_DLL_LINKAGE DWORD WINAPI GetIpNetEntry2(MIB_IPNET_ROW2*); IPHLPAPI_DLL_LINKAGE DWORD WINAPI GetIpNetTable2(ADDRESS_FAMILY,MIB_IPNET_TABLE2**);