There are alot of ways of determining the status of a network connection! All of the functions below will tell you the status of a network connection. Microsoft has provided us with many alternatives.
You could also use the IP Helper[^] tools to query the status something like this:
#include "Iphlpapi.h"
#pragma comment(lib, "iphlpapi.lib")
VOID PrintOperationalEthernet()
{
BYTE *pBuf=NULL;
DWORD dwSize=0;
DWORD dwResult=0;
BOOL bConnected=FALSE;
PMIB_IFTABLE pMIBTable;
CString str;
GetIfTable(NULL,&dwSize,FALSE);
pBuf=new BYTE[dwSize];
pMIBTable=reinterpret_cast<PMIB_IFTABLE>(pBuf);
if(NO_ERROR == GetIfTable(pMIBTable,&dwSize,FALSE))
{
for(UINT i=0; i < pMIBTable->dwNumEntries; ++i)
{
if(MIB_IF_TYPE_ETHERNET == pMIBTable->table[i].dwType)
{
bConnected = MIB_IF_OPER_STATUS_OPERATIONAL == pMIBTable->table[i].dwOperStatus;
char szBuf[MAX_PATH];
sprintf(szBuf,"%s is %s\n",pMIBTable->table[i].bDescr,
TRUE == bConnected?"Connected":"Offline");
TRACE(szBuf);
}
}
}
delete []pBuf;
}
You could also use the lower level DeviceIOControl[^] to query the device status directly from the network card like this:
#include <winioctl.h>
typedef ULONG NDIS_OID, *PNDIS_OID;
#define _NDIS_CONTROL_CODE(request,method) CTL_CODE(FILE_DEVICE_PHYSICAL_NETCARD, request, method, FILE_ANY_ACCESS)
#define IOCTL_NDIS_QUERY_GLOBAL_STATS _NDIS_CONTROL_CODE(0,METHOD_OUT_DIRECT)
#define OID_GEN_MEDIA_CONNECT_STATUS 0x00010114
typedef enum _NDIS_MEDIA_STATE
{
NdisMediaStateConnected,
NdisMediaStateDisconnected
} NDIS_MEDIA_STATE,*PNDIS_MEDIA_STATE;
VOID PrintOperationalEthernet()
{
int index =0;
DWORD dwType =0;
HKEY key;
HKEY cardkey;
CString str;
HANDLE hDevice;
NDIS_OID OidCode = OID_GEN_MEDIA_CONNECT_STATUS;
ULONG status=0;
ULONG dwRet=0;
TCHAR szCardVal[CHAR_MAX];
TCHAR szDescription[MAX_PATH];
TCHAR szDevice[MAX_PATH];
str.Format(_T("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\NetworkCards\\"));
if(ERROR_SUCCESS == RegOpenKey(HKEY_LOCAL_MACHINE,str,&key))
{
while(ERROR_SUCCESS == RegEnumKey(key,index++,szCardVal,CHAR_MAX))
{
str.Format(_T("%s\\%d"),str,_ttoi(szCardVal));
if(ERROR_SUCCESS == RegOpenKey(HKEY_LOCAL_MACHINE,str,&cardkey))
{
str = str.Left(str.ReverseFind('\\'));
DWORD dwLen = CHAR_MAX * sizeof(TCHAR);
if(ERROR_SUCCESS == RegQueryValueEx(cardkey,_T("ServiceName"),NULL,
&dwType,(LPBYTE)szCardVal,&dwLen))
{
RegQueryValueEx(cardkey,_T("Description"),NULL,
&dwType,(LPBYTE)szDescription,&dwLen);
_stprintf(szDevice,_T("\\\\.\\%s"),szCardVal);
hDevice = CreateFile(szDevice,GENERIC_READ,FILE_SHARE_READ|
FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,0);
if(DeviceIoControl(hDevice,IOCTL_NDIS_QUERY_GLOBAL_STATS,
&OidCode,sizeof(NDIS_OID),&status,
sizeof(ULONG),&dwRet,NULL))
{
TCHAR szBuf[MAX_PATH];
_stprintf(szBuf,_T("%s is %s\n"),szCardVal,
NdisMediaStateConnected == status?_T("Connected"):_T("Offline"));
TRACE(szBuf);
CloseHandle(hDevice);
}
RegCloseKey(cardkey);
}
}
}
RegCloseKey(key);
}
}
You could also use the Internet Connection Firewall API[^] to determine the status of the network card such as below:
#include <netcon.h>
#define _WIN32_DCOM 1
typedef void(__stdcall *LPNcFreeNetconProperties)(NETCON_PROPERTIES *pProps);
VOID PrintOperationalEthernet()
{
HRESULT hr = CoInitializeEx(0, COINIT_MULTITHREADED);
hr = CoInitializeSecurity(NULL, -1, NULL, NULL,
RPC_C_AUTHN_LEVEL_CONNECT,
RPC_C_IMP_LEVEL_IDENTIFY,
NULL, EOAC_NONE, 0
);
HMODULE hmod=LoadLibrary(_T("netshell.dll"));
if(hmod)
{
LPNcFreeNetconProperties NcFreeNetconProperties=(LPNcFreeNetconProperties)\
GetProcAddress(hmod,"NcFreeNetconProperties");
INetConnectionManager *pMan=0;
HRESULT hres=CoCreateInstance(CLSID_ConnectionManager,0,CLSCTX_ALL,\
__uuidof(INetConnectionManager),(void **) &pMan);
if(SUCCEEDED(hres))
{
IEnumNetConnection *pEnum=0;
HRESULT hres=pMan->EnumConnections(NCME_DEFAULT,&pEnum);
if(SUCCEEDED(hres))
{
INetConnection *pCon=0;
ULONG count;
bool done=FALSE;
while(pEnum->Next(1,&pCon,&count) == S_OK && !done)
{
NETCON_PROPERTIES *pProps=0;
hres=pCon->GetProperties(&pProps);
if(SUCCEEDED(hres))
{
wchar_t wszBuf[MAX_PATH];
wsprintf(wszBuf,_T("%s is %s\n"),pProps->pszwName,
NCS_CONNECTED == pProps->Status?_T("Connected"):_T("Offline"));
TRACE(wszBuf);
NcFreeNetconProperties(pProps);
}
pCon->Release();
}
pEnum->Release();
}
pMan->Release();
}
FreeLibrary(hmod);
}
CoUninitialize();
}
As was previously mentioned the WMI Win32_NetworkAdapter Class[^] can be used to determine device state by checking the NetConnectionStatus member. Sorry... no WMI sample... I absolutely hate WMI.
Best Wishes,
David Delaune
|