【网络编程】【Windows】监控网卡事件

概述:监控网卡被禁用事件。

方法一

可以使用Win32 API中的 NotifySubscribeCallouts 和 NotifyRegisterNetEvent api 函数来监控网络适配器状态的改变,包括被禁用的事件。

具体步骤如下:

  1. 使用NotifySubscribeCallouts函数来注册一个回调函数,当网络适配器状态改变时会调用该函数。

  2. 在回调函数中使用NotifyRegisterNetEvent函数来注册一个网络事件,比如网络适配器被禁用。

  3. 监听回调函数中传递的事件类型,当事件类型为被禁用时,执行自己的逻辑处理。

示例代码:

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);
}
}

注意事项:

  1. 如果需要使用NotifyRegisterNetEvent函数,需要将应用程序编译为驱动程序或系统服务,因为这个函数需要管理员权限。

  2. 回调函数中不能阻塞或进行耗时操作,因为这会影响系统功能的正常运作。

  3. 可以使用SetConsoleCtrlHandler函数注册控制事件处理函数,以便在收到控制事件时可以及时退出程序。

方法二

参考注册设备通知 - Win32 apps | Microsoft Learn

要获取 Windows 网卡被禁用事件,您可以使用以下步骤:

  1. 使用 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)
{
// Handle error
}

hDevNotify = RegisterDeviceNotification(
hwnd,
&filter,
DEVICE_NOTIFY_WINDOW_HANDLE);

if (hDevNotify == NULL)
{
// Handle error
}

其中,HWND是接收通知的窗口句柄,filter是一些条件,例如通知类型,设备范围等。

  1. 在您的窗口过程函数中处理通知消息。 它将提供一个 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;
// Check if network adapter is disabled
if (pVol->dbcv_flags & DBTF_MEDIA) // Media is removed
{
// Check if any network adapter is disabled
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)
{
// Network adapter on this drive is disabled
}
}
dwDriveMask >> = 1;
}
}
}
}
return TRUE;

这段代码检查网络适配器是否被禁用,并根据需要执行操作。

请注意,这些代码只是一种参考。要使它们正常工作,您需要将它们植入到您的代码中,并根据需要进行修改。


【网络编程】【Windows】监控网卡事件
https://hodlyounger.github.io/A_OS/Windows/网络helper/【网络编程】监控网卡禁用事件/
作者
mingming
发布于
2023年10月27日
许可协议