概述:监控网卡被禁用事件。
方法一
可以使用Win32 API中的 NotifySubscribeCallouts 和 NotifyRegisterNetEvent api 函数来监控网络适配器状态的改变,包括被禁用的事件。
具体步骤如下:
-
使用NotifySubscribeCallouts函数来注册一个回调函数,当网络适配器状态改变时会调用该函数。
-
在回调函数中使用NotifyRegisterNetEvent函数来注册一个网络事件,比如网络适配器被禁用。
-
监听回调函数中传递的事件类型,当事件类型为被禁用时,执行自己的逻辑处理。
示例代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
| #include <iostream> #include <windows.h> #include <ipexport.h>
using namespace std;
BOOL WINAPI HandlerRoutine(DWORD dwCtrlType);
void CALLBACK NetEventCallback(PVOID pCallerContext, ULONG NotificationType, PVOID Notification);
int main() { SetConsoleCtrlHandler(HandlerRoutine, TRUE);
HANDLE hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); HANDLE hWaitableHandle[2] = { hEvent, INVALID_HANDLE_VALUE };
DWORD dwFlags = NOTIFY_FILTER_INTERFACE_CHANGE | NOTIFY_FILTER_DRIVER_LOADED; HMODULE hModule = NULL; PVOID pCallerContext = (PVOID)hEvent; HANDLE hNotifyObject = NULL; NotifySubscribeCallouts(dwFlags, NetEventCallback, pCallerContext, hModule, &hNotifyObject);
DWORD dwWaitResult; do { dwWaitResult = WaitForMultipleObjects(2, hWaitableHandle, FALSE, INFINITE);
} while (dwWaitResult != WAIT_OBJECT_0);
NotifyUnsubscribeCallouts(hNotifyObject); CloseHandle(hEvent);
return 0; }
BOOL WINAPI HandlerRoutine(DWORD dwCtrlType) { switch (dwCtrlType) { case CTRL_CLOSE_EVENT: printf(" Close signal received."); return TRUE;
default: return FALSE; } }
void CALLBACK NetEventCallback(PVOID pCallerContext, ULONG NotificationType, PVOID Notification) { switch (NotificationType) { case NOTIFY_INTERFACE_ARRIVAL: printf(" Interface arrival."); break;
case NOTIFY_INTERFACE_REMOVAL: printf(" Interface removal."); break;
case NOTIFY_INTERFACE_ENABLED: printf(" Interface enabled."); break;
case NOTIFY_INTERFACE_DISABLED: printf(" Interface disabled."); break;
default: printf(" Unknown notification type."); break; }
PIP_INTERFACE_INFO pIfInfo = (PIP_INTERFACE_INFO)Notification;
if (NotificationType == NOTIFY_INTERFACE_DISABLED) { printf(" Interface % ws has been disabled.", pIfInfo->Adapter[0].Name); } }
|
注意事项:
-
如果需要使用NotifyRegisterNetEvent函数,需要将应用程序编译为驱动程序或系统服务,因为这个函数需要管理员权限。
-
回调函数中不能阻塞或进行耗时操作,因为这会影响系统功能的正常运作。
-
可以使用SetConsoleCtrlHandler函数注册控制事件处理函数,以便在收到控制事件时可以及时退出程序。
方法二
参考注册设备通知 - Win32 apps | Microsoft Learn
要获取 Windows 网卡被禁用事件,您可以使用以下步骤:
- 使用 Windows API 函数注册网络配置更改通知。使用以下代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| HANDLE hNotify = NULL; HDEVNOTIFY hDevNotify = NULL;
hNotify = FindFirstChangeNotificationW( HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Control\\Network", FALSE, FILE_NOTIFY_CHANGE_LAST_WRITE);
if (hNotify == INVALID_HANDLE_VALUE) { }
hDevNotify = RegisterDeviceNotification( hwnd, &filter, DEVICE_NOTIFY_WINDOW_HANDLE);
if (hDevNotify == NULL) { }
|
其中,HWND是接收通知的窗口句柄,filter是一些条件,例如通知类型,设备范围等。
- 在您的窗口过程函数中处理通知消息。 它将提供一个 lParam 参数,该参数是一个包含有关更改的结构体。 您可以使用以下代码来检查是否禁用了任何网络适配器:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| case WM_DEVICECHANGE: PDEV_BROADCAST_HDR pHdr = (PDEV_BROADCAST_HDR)lParam; if (pHdr->dbch_devicetype == DBT_DEVTYP_VOLUME) { PDEV_BROADCAST_VOLUME pVol = (PDEV_BROADCAST_VOLUME)pHdr; if (pVol->dbcv_flags & DBTF_MEDIA) { DWORD dwDriveMask = pVol->dbcv_unitmask; if (dwDriveMask != 0) { for (int i = 0; i < 26; i++) { if ((dwDriveMask & 0x01) == 0x01) { char szDrive[4] = { 'A' + i, ':', '\\', '\0' }; if (GetDriveType(szDrive) == DRIVE_CDROM) { } } dwDriveMask >> = 1; } } } } return TRUE;
|
这段代码检查网络适配器是否被禁用,并根据需要执行操作。
请注意,这些代码只是一种参考。要使它们正常工作,您需要将它们植入到您的代码中,并根据需要进行修改。