[PATCH 1/6] iphlpapi: Implement GetIfTable2Ex() on top of nsi.
Huw Davies
huw at codeweavers.com
Thu Jul 8 02:59:57 CDT 2021
Signed-off-by: Huw Davies <huw at codeweavers.com>
---
dlls/iphlpapi/iphlpapi_main.c | 106 +++++++++++++++++++++++++++-------
1 file changed, 86 insertions(+), 20 deletions(-)
diff --git a/dlls/iphlpapi/iphlpapi_main.c b/dlls/iphlpapi/iphlpapi_main.c
index 13bfb81e7c9..dd2b9d7035c 100644
--- a/dlls/iphlpapi/iphlpapi_main.c
+++ b/dlls/iphlpapi/iphlpapi_main.c
@@ -61,6 +61,7 @@
#include "wine/nsi.h"
#include "wine/debug.h"
#include "wine/unicode.h"
+#include "wine/heap.h"
WINE_DEFAULT_DEBUG_CHANNEL(iphlpapi);
@@ -1919,14 +1920,78 @@ DWORD WINAPI GetIfTable(PMIB_IFTABLE pIfTable, PULONG pdwSize, BOOL bOrder)
return ret;
}
+static void if_counted_string_copy( WCHAR *dst, unsigned int len, IF_COUNTED_STRING *src )
+{
+ unsigned int copy = src->Length;
+
+ if (copy >= len * sizeof(WCHAR)) copy = 0;
+ memcpy( dst, src->String, copy );
+ memset( (char *)dst + copy, 0, len * sizeof(WCHAR) - copy );
+}
+
+static void if_row2_fill( MIB_IF_ROW2 *row, struct nsi_ndis_ifinfo_rw *rw, struct nsi_ndis_ifinfo_dynamic *dyn,
+ struct nsi_ndis_ifinfo_static *stat )
+{
+ row->InterfaceIndex = stat->if_index;
+ row->InterfaceGuid = stat->if_guid;
+ if_counted_string_copy( row->Alias, ARRAY_SIZE(row->Alias), &rw->alias );
+ if_counted_string_copy( row->Description, ARRAY_SIZE(row->Description), &stat->descr );
+ row->PhysicalAddressLength = rw->phys_addr.Length;
+ if (row->PhysicalAddressLength > sizeof(row->PhysicalAddress)) row->PhysicalAddressLength = 0;
+ memcpy( row->PhysicalAddress, rw->phys_addr.Address, row->PhysicalAddressLength );
+ memcpy( row->PermanentPhysicalAddress, stat->perm_phys_addr.Address, row->PhysicalAddressLength );
+ row->Mtu = dyn->mtu;
+ row->Type = stat->type;
+ row->TunnelType = TUNNEL_TYPE_NONE; /* fixme */
+ row->MediaType = stat->media_type;
+ row->PhysicalMediumType = stat->phys_medium_type;
+ row->AccessType = stat->access_type;
+ row->DirectionType = NET_IF_DIRECTION_SENDRECEIVE; /* fixme */
+ row->InterfaceAndOperStatusFlags.HardwareInterface = stat->flags.hw;
+ row->InterfaceAndOperStatusFlags.FilterInterface = stat->flags.filter;
+ row->InterfaceAndOperStatusFlags.ConnectorPresent = !!stat->conn_present;
+ row->InterfaceAndOperStatusFlags.NotAuthenticated = 0; /* fixme */
+ row->InterfaceAndOperStatusFlags.NotMediaConnected = dyn->flags.not_media_conn;
+ row->InterfaceAndOperStatusFlags.Paused = 0; /* fixme */
+ row->InterfaceAndOperStatusFlags.LowPower = 0; /* fixme */
+ row->InterfaceAndOperStatusFlags.EndPointInterface = 0; /* fixme */
+ row->OperStatus = dyn->oper_status;
+ row->AdminStatus = rw->admin_status;
+ row->MediaConnectState = dyn->media_conn_state;
+ row->NetworkGuid = rw->network_guid;
+ row->ConnectionType = stat->conn_type;
+ row->TransmitLinkSpeed = dyn->xmit_speed;
+ row->ReceiveLinkSpeed = dyn->rcv_speed;
+ row->InOctets = dyn->in_octets;
+ row->InUcastPkts = dyn->in_ucast_pkts;
+ row->InNUcastPkts = dyn->in_bcast_pkts + dyn->in_mcast_pkts;
+ row->InDiscards = dyn->in_discards;
+ row->InErrors = dyn->in_errors;
+ row->InUnknownProtos = 0; /* fixme */
+ row->InUcastOctets = dyn->in_ucast_octs;
+ row->InMulticastOctets = dyn->in_mcast_octs;
+ row->InBroadcastOctets = dyn->in_bcast_octs;
+ row->OutOctets = dyn->out_octets;
+ row->OutUcastPkts = dyn->out_ucast_pkts;
+ row->OutNUcastPkts = dyn->out_bcast_pkts + dyn->out_mcast_pkts;
+ row->OutDiscards = dyn->out_discards;
+ row->OutErrors = dyn->out_errors;
+ row->OutUcastOctets = dyn->out_ucast_octs;
+ row->OutMulticastOctets = dyn->out_mcast_octs;
+ row->OutBroadcastOctets = dyn->out_bcast_octs;
+ row->OutQLen = 0; /* fixme */
+}
+
/******************************************************************
* GetIfTable2Ex (IPHLPAPI.@)
*/
DWORD WINAPI GetIfTable2Ex( MIB_IF_TABLE_LEVEL level, MIB_IF_TABLE2 **table )
{
- DWORD i, nb_interfaces, size = sizeof(MIB_IF_TABLE2);
- InterfaceIndexTable *index_table;
- MIB_IF_TABLE2 *ret;
+ DWORD i, count, size, err;
+ NET_LUID *keys;
+ struct nsi_ndis_ifinfo_rw *rw;
+ struct nsi_ndis_ifinfo_dynamic *dyn;
+ struct nsi_ndis_ifinfo_static *stat;
TRACE( "level %u, table %p\n", level, table );
@@ -1936,29 +2001,30 @@ DWORD WINAPI GetIfTable2Ex( MIB_IF_TABLE_LEVEL level, MIB_IF_TABLE2 **table )
if (level != MibIfTableNormal)
FIXME("level %u not fully supported\n", level);
- if ((nb_interfaces = get_interface_indices( FALSE, NULL )) > 1)
- size += (nb_interfaces - 1) * sizeof(MIB_IF_ROW2);
+ err = NsiAllocateAndGetTable( 1, &NPI_MS_NDIS_MODULEID, NSI_NDIS_IFINFO_TABLE, (void **)&keys, sizeof(*keys),
+ (void **)&rw, sizeof(*rw), (void **)&dyn, sizeof(*dyn),
+ (void **)&stat, sizeof(*stat), &count, 0 );
+ if (err) return err;
- if (!(ret = HeapAlloc( GetProcessHeap(), 0, size ))) return ERROR_OUTOFMEMORY;
+ size = FIELD_OFFSET( MIB_IF_TABLE2, Table[count] );
- get_interface_indices( FALSE, &index_table );
- if (!index_table)
+ if (!(*table = heap_alloc_zero( size )))
{
- HeapFree( GetProcessHeap(), 0, ret );
- return ERROR_OUTOFMEMORY;
+ err = ERROR_OUTOFMEMORY;
+ goto err;
}
- ret->NumEntries = 0;
- for (i = 0; i < index_table->numIndexes; i++)
+ (*table)->NumEntries = count;
+ for (i = 0; i < count; i++)
{
- ret->Table[i].InterfaceIndex = index_table->indexes[i];
- GetIfEntry2( &ret->Table[i] );
- ret->NumEntries++;
- }
+ MIB_IF_ROW2 *row = (*table)->Table + i;
- HeapFree( GetProcessHeap(), 0, index_table );
- *table = ret;
- return NO_ERROR;
+ row->InterfaceLuid.Value = keys[i].Value;
+ if_row2_fill( row, rw + i, dyn + i, stat + i );
+ }
+err:
+ NsiFreeTable( keys, rw, dyn, stat );
+ return err;
}
/******************************************************************
@@ -1967,7 +2033,7 @@ DWORD WINAPI GetIfTable2Ex( MIB_IF_TABLE_LEVEL level, MIB_IF_TABLE2 **table )
DWORD WINAPI GetIfTable2( MIB_IF_TABLE2 **table )
{
TRACE( "table %p\n", table );
- return GetIfTable2Ex(MibIfTableNormal, table);
+ return GetIfTable2Ex( MibIfTableNormal, table );
}
/******************************************************************
--
2.23.0
More information about the wine-devel
mailing list