Jonathan Potter
Jonathan Potter

Reputation: 37192

Equivalent in C++ of WMI associator Path_ script member

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

Answers (1)

RbMm
RbMm

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

Related Questions