#c #windows #winapi #networking #wmi
#c #Windows #winapi #сеть #wmi
Вопрос:
Я хотел бы знать, когда интерфейс был отключен.
Если я захожу в диспетчер Windows и отключаю одно из 2 включенных подключений, GetIfTable () возвращает статус только для 1 интерфейса, он больше не видит отключенный. (Возвращает 1 таблицу)
Как я могу заставить что-то возвращать, что отключенный интерфейс все еще существует, но в настоящее время отключен?
Спасибо.
http://msdn.microsoft.com/en-us/library/aa365943(VS.85).aspx
Ответ №1:
Я думаю, вам просто нужно будет прочитать реестр.
Например, это фрагмент, найденный в Интернете, о том, как все должно выглядеть:
[HKEY_LOCAL_MACHINESYSTEMControlSet001ControlNetwork{4D36E972-E325-11CE-BFC1-08002BE10318}{1E6AF554-25FF-40FC-9CEE-EB899472C5A3}Connection]
"PnpInstanceID"="PCI\VEN_14E4amp;DEV_1696amp;SUBSYS_12BC103Camp;REV_03\4amp;3A321F38amp;0amp;10F0"
"MediaSubType"=dword:00000001
"Name"="Lan Name"
"ShowIcon"=dword:00000000
"IpCheckingEnabled"=dword:00000001
[HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlNetwork{4D36E972-E325-11CE-BFC1-08002BE10318}{1E6AF554-25FF-40FC-9CEE-EB899472C5A3}Connection]
"PnpInstanceID"="PCI\VEN_14E4amp;DEV_1696amp;SUBSYS_12BC103Camp;REV_03\4amp;3A321F38amp;0amp;10F0"
"MediaSubType"=dword:00000001
"Name"="Lan Name"
"ShowIcon"=dword:00000000
"IpCheckingEnabled"=dword:00000001
Комментарии:
1. В каком поле здесь указан статус dis / enabled?
2. Я не знаю по памяти, и я не нахожусь рядом ни с одним ПК с Windows. Я надеюсь, вы сможете найти дополнительную информацию по этому указателю… пока об этом умолчим
3. Я думаю, основываясь на информации из PnpInstanceId, вы должны найти информацию о драйвере в HKEY_LOCAL_MACHINE SYSTEM CurrentControlSet Enum PCI и там вы должны увидеть ключ ConfigFlags. Если установлено значение 0, сетевая карта включена, если значение 1 отключено.
4. Я плохо это помню, но я думаю, что сначала вы должны вызвать функцию RegOpenKeyEx для получения ключа, а затем с этим ключом вы должны вызвать RegQueryValueEx для получения определенного значения. Пожалуйста, ознакомьтесь со старыми вопросами SO и документацией MSDN о том, как именно вызывать эти функции msdn.microsoft.com/en-us/library/ms724875 (v = против 85).aspx
Ответ №2:
Как насчет использования интерфейсов из, netcon.h
как показано в этом примере? Код в этом примере включает и отключает интерфейс программно, но я внес некоторые изменения, чтобы вместо этого вы могли запрашивать статус:
#include <netcon.h>
// wszName is the name of the connection as appears in Network Connections folder
// set bEnable to true to enable and to false to disable
bool GetConnectionStatus(LPCWSTR wszName, bool *status)
{
bool result = false;
if (!status)
return false;
typedef void (__stdcall * LPNcFreeNetconProperties)(NETCON_PROPERTIES* pProps);
HMODULE hmod = LoadLibrary("netshell.dll");
if (!hmod)
return false;
LPNcFreeNetconProperties NcFreeNetconProperties =
(LPNcFreeNetconProperties)GetProcAddress(hmod, "NcFreeNetconProperties");
if (!NcFreeNetconProperties )
return false;
INetConnectionManager * pMan = 0;
HRESULT hres = CoCreateInstance(CLSID_ConnectionManager,
0,
CLSCTX_ALL,
__uuidof(INetConnectionManager),
(void**)amp;pMan);
if (SUCCEEDED(hres))
{
IEnumNetConnection * pEnum = 0;
hres = pMan->EnumConnections(NCME_DEFAULT, amp;pEnum);
if (SUCCEEDED(hres))
{
INetConnection * pCon = 0;
ULONG count;
while (pEnum->Next(1, amp;pCon, amp;count) == S_OK amp;amp; !done)
{
NETCON_PROPERTIES * pProps = 0;
hres = pCon->GetProperties(amp;pProps);
if (SUCCEEDED(hres))
{
if (wcscmp(pProps->pszwName,wszName) == 0)
{
*status = pProps->Status == NCS_CONNECTED;
}
NcFreeNetconProperties(pProps);
}
pCon->Release();
}
pEnum->Release();
}
pMan->Release();
}
FreeLibrary(hmod);
return resu<
}
Комментарии:
1. переменная ‘done’ не используется в цикле — проблема с копированием / вставкой 🙂
Ответ №3:
Другой вариант — использовать Win32_NetworkAdapter
класс WMI, проверить свойства NetConnectionStatus
и NetEnabled
.
Комментарии:
1. Если вы обнаружите, что этот класс WMI присваивает вам нужный статус, обратите внимание, что WMI предоставляет вам «службу опроса», чтобы периодически проверять, изменились ли значения. Взгляните на __InstanceModificationEvent (но если вы встраиваете это в приложение, будьте осторожны, поскольку опрос WMI может показаться вам слишком сложным, несмотря на его кажущуюся простоту.)
Ответ №4:
Структура IP_ADAPTER_ADDRESSES содержит элемент OperStatus. Смотрите документацию MSDN
Я думаю, что это можно использовать для обнаружения отключенных сетевых адаптеров. Я не пытался.
Вот тестовый код:
ULONG nFlags= 0;
if (WINVER>=0x0600) // flag supported in Vista and later
nFlags= 0x0100; // GAA_FLAG_INCLUDE_ALL_INTERFACES
// during system initialization, GetAdaptersAddresses may return ERROR_BUFFER_OVERFLOW and supply nLen,
// but in a subsequent call it may return ERROR_BUFFER_OVERFLOW and supply greater nLen !
ULONG nLen= sizeof (IP_ADAPTER_ADDRESSES);
BYTE* pBuf= NULL;
DWORD nErr= 0 ;
do
{
delete[] pBuf;
pBuf= new BYTE[nLen];
nErr= ::GetAdaptersAddresses(AF_INET, nFlags, NULL, (IP_ADAPTER_ADDRESSES*amp;)pBuf, amp;nLen);
}
while (ERROR_BUFFER_OVERFLOW == nErr);
if (NO_ERROR != nErr)
{
delete[] pBuf;
TCHAR czErr[300]= _T("GetAdaptersAddresses failed. ");
REPORT(REP_ERROR, _T("GetAdapterInfo"), GetSysErrStr(nErr, czErr, 300));
return false;
}
const IP_ADAPTER_ADDRESSES* pAdaptersAddresses= (IP_ADAPTER_ADDRESSES*amp;)pBuf;
while (pAdaptersAddresses) // for each adapter
{
TCHAR czAdapterName [500]; str_cpy(czAdapterName , 500, pAdaptersAddresses->AdapterName );
TCHAR czDesc [500]; str_cpy(czDesc , 500, pAdaptersAddresses->Description );
TCHAR czFriendlyName[500]; str_cpy(czFriendlyName, 500, pAdaptersAddresses->FriendlyName);
const IF_OPER_STATUSamp; Stat= pAdaptersAddresses->OperStatus; // 1:up, 2:down...
...
pAdaptersAddresses= pAdaptersAddresses->Next;
}
Комментарии:
1. К сожалению, здесь ничто не указывает на то, что включено. Я попробовал этот метод, и он ведет себя так же, как GetIfTable (), возвращая только статус (связанный список) для одной сетевой карты … Я ожидал, что, по крайней мере, верну информацию с IF_OPER_STATUS….
Ответ №5:
Согласно этому сообщению на форуме CodeGuru, вы можете запросить WMI для получения этой информации (там приведен код C #).
Чтобы запросить WMI с помощью C , смотрите эти две ссылки:
Ответ №6:
командная строка:
wmic NIC where(ConfigManagerErrorCode=22)get Description,Index,NetConnectionID,PNPDeviceID
Вывод:
Description Index NetConnectionID PNPDeviceID
Broadcom 802.11g Network Adapter 8 WiFi PCIVEN_14E4amp;DEV_4320amp;SUBSYS_041814E4amp;REV_034amp;31B6CD7amp;0amp;00F0
1394 Net Adapter 13 1394 V1394NIC13941B9E0F31E8C00
TAP-Win32 Adapter V9 14 Steganos Internet Anonym 2012 VPN Adapter ROOTNET0000
VirtualBox Host-Only Ethernet Adapter 24 VirtualBox Host-Only Network ROOTNET0001