Reputation: 37192
I'm trying to use WMI to identify physical network adapters rather than logical/software adapters. I came across this VBScript, which does what I need:
'WQL Query constants
const QRY_ALL_NIC = "select * from win32_networkadapter"
const QRY_NIC_ASSOC = "associators of {Win32_NetworkAdapter.DeviceID='"
const QRY_NIC_ASSOC2 = "'}"
const IRQCLASS = "Win32_IRQResource"
const DEVMEMCLASS = "Win32_DeviceMemoryAddress"
const PORTCLASS = "Win32_PortResource"
Set wmisrv_cimv2 = GetObject("winmgmts:root/cimv2")
'get a collection of all win32_networkadapters. We query the
'associators of each nic and see if
'any of the associator classes indicate they are physical adapters ie
'do they use memory addresses,'io port or IRQ resources.
set colNics = wmisrv_cimv2.execquery(QRY_ALL_NIC)
for each nic in colNics
set colassoc = wmisrv_cimv2.execquery(QRY_NIC_ASSOC & nic.DeviceID & QRY_NIC_ASSOC2)
for each assoc in colassoc
select case assoc.Path_.Class ' <---- what does Path_ correspond to?
case IRQCLASS, DEVMEMCLASS, PORTCLASS
wscript.echo "Network adapter " & nic.name & " : " & nic.MACAddress & vbcrlf
exit for
case else
end select
next
next
I've been trying to implement this in C++, but I can't work out what the Path_
member of the associator
entry corresponds to.
I've enumerated all the properties that each associator
returns using IWbemClassObject::GetNames()
and none of them are called Path_
. There's one called __PATH
, but this just seems to provide the full path of the associator
in the WMI namespace (and doesn't have a Class
member in any event).
Upvotes: 1
Views: 43
Reputation: 33754
we can use GetIfTable2 and check for MIB_IF_ROW2::InterfaceAndOperStatusFlags::ConnectorPresent
ConnectorPresent
Set if a connector is present on the network interface. This value is set if there is a physical network adapter.
PMIB_IF_TABLE2 Table;
if (NOERROR == GetIfTable2(&Table))
{
if (ULONG NumEntries = Table->NumEntries)
{
PMIB_IF_ROW2 ptb = Table->Table;
do
{
if (ptb->InterfaceAndOperStatusFlags.ConnectorPresent)
{
WCHAR sz[32];
ULONG cch = _countof(sz);
CryptBinaryToStringW(ptb->PhysicalAddress,
ptb->PhysicalAddressLength,
CRYPT_STRING_HEXRAW|CRYPT_STRING_NOCRLF,
sz, &cch);
DbgPrint("%ws: %ws [%ws]\n", sz, ptb->Description, ptb->Alias);
}
} while (ptb++, --NumEntries);
}
FreeMibTable(Table);
}
also we can use this in conjunction with GetAdaptersAddresses for get more info, if need
PMIB_IF_ROW2 IsPhysicalAdapter(_In_ PMIB_IF_ROW2 Table,
_In_ ULONG NumEntries,
_In_ NET_IFINDEX InterfaceIndex)
{
do
{
if (Table->InterfaceIndex == InterfaceIndex)
{
return Table;
}
} while (Table++, --NumEntries);
return 0;
}
void demo()
{
DWORD cb = 0x2000, err;
do
{
if (PVOID buf = LocalAlloc(LMEM_FIXED, cb))
{
PIP_ADAPTER_ADDRESSES AdapterAddresses = (PIP_ADAPTER_ADDRESSES)buf;
if (NOERROR == (err = GetAdaptersAddresses(AF_INET, GAA_FLAG_INCLUDE_PREFIX, 0, AdapterAddresses, &cb)))
{
PMIB_IF_TABLE2 Table;
if (NOERROR == (err = GetIfTable2(&Table)))
{
if (ULONG NumEntries = Table->NumEntries)
{
PMIB_IF_ROW2 ptb = Table->Table;
do
{
if (
AdapterAddresses->OperStatus == IfOperStatusUp &&
AdapterAddresses->IfType == IF_TYPE_ETHERNET_CSMACD
)
{
if (PMIB_IF_ROW2 p = IsPhysicalAdapter(ptb, NumEntries,
AdapterAddresses->IfIndex))
{
if (p->InterfaceAndOperStatusFlags.ConnectorPresent)
{
WCHAR sz[32];
ULONG cch = _countof(sz);
CryptBinaryToStringW(AdapterAddresses->PhysicalAddress,
AdapterAddresses->PhysicalAddressLength,
CRYPT_STRING_HEXRAW|CRYPT_STRING_NOCRLF,
sz, &cch);
DbgPrint("%ws: \"%ws\" \"%ws\"\n",
sz,
AdapterAddresses->FriendlyName,
AdapterAddresses->Description );
}
}
}
} while (AdapterAddresses = AdapterAddresses->Next);
}
FreeMibTable(Table);
}
}
LocalFree(buf);
}
else
{
err = ERROR_OUTOFMEMORY;
break;
}
} while (ERROR_BUFFER_OVERFLOW == err);
}
Upvotes: 1