Introduction
This sample snippet shows how to retrieve the list of all network adapters on your machine, plus a lot of infos about each of them. The information you can retrieve are all the members of the structure MIB_IFROW
as shown in this MSDN snippet
typedef struct _MIB_IFROW {
WCHAR wszName[MAX_INTERFACE_NAME_LEN];
DWORD dwIndex;
DWORD dwType;
DWORD dwMtu;
DWORD dwSpeed;
DWORD dwPhysAddrLen;
BYTE bPhysAddr[MAXLEN_PHYSADDR];
DWORD dwAdminStatus;
DWORD dwOperStatus;
DWORD dwLastChange;
DWORD dwInOctets;
DWORD dwInUcastPkts;
DWORD dwInNUcastPkts;
DWORD dwInDiscards;
DWORD dwInErrors;
DWORD dwInUnknownProtos;
DWORD dwOutOctets;
DWORD dwOutUcastPkts;
DWORD dwOutNUcastPkts;
DWORD dwOutDiscards;
DWORD dwOutErrors;
DWORD dwOutQLen;
DWORD dwDescrLen;
BYTE bDescr[MAXLEN_IFDESCR];
} MIB_IFROW,*PMIB_IFROW;
After wasted lot of time trying to reach the performance counter stuff I found this DLL. And now you can use it without having to look around anymore :)
Using the code
In my working environment I don't have the right headers and libs to include in the project, so I used the functions inside the DLL using the LoadLibrary
and GetProcAddress
, like this:
typedef DWORD (_stdcall *TGetIfTable) (
MIB_IFTABLE *pIfTable,
ULONG *pdwSize,
BOOL bOrder
);
...
TGetIfTable pGetIfTable;
...
pGetIfTable=(TGetIfTable)GetProcAddress(LoadLibrary("Iphlpapi.dll"),
"GetIfTable");
The key function of the DLL is GetIfTable
. You have to call this function twice, first time to know how much memory space allocate, and then to fill the structure with the return values. In the OnInitDialog
I get the right size of the adapters-table and I can fill the combo box with all the adapters descriptions
...
m_pTable=NULL;
m_dwAdapters=0;
ULONG uRetCode=pGetIfTable(m_pTable,&m_dwAdapters,TRUE);
if (uRetCode == 122 )
{
m_pTable=new MIB_IFTABLE[m_dwAdapters];
pGetIfTable(m_pTable,&m_dwAdapters,TRUE);
for (UINT i=0;i<m_pTable->dwNumEntries;i++)
{
MIB_IFROW Row=m_pTable->table[i];
char szDescr[MAXLEN_IFDESCR];
memcpy(szDescr,Row.bDescr,Row.dwDescrLen);
szDescr[Row.dwDescrLen]=0;
m_ctlCBAdapters.AddString(szDescr);
}
}
...
if everything has gone right a timer starts, and the UpdateCounters
get called every 100ms
void CP01Dlg::UpdateCounters()
{
int nIndex=m_ctlCBAdapters.GetCurSel();
if (nIndex!=CB_ERR)
{
pGetIfTable(m_pTable,&m_dwAdapters,TRUE);
MIB_IFROW Row=m_pTable->table[nIndex];
m_strInfo.Format("Received %d, Sent %d",Row.dwInOctets,
Row.dwOutOctets);
UpdateData(FALSE);
}
}
That's all
I hope this snippet can save you some time. See you in my next article.