8000 监控网卡事件 · Issue #94 · holdyounger/ScopeBlog · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content
监控网卡事件 #94
Open
Open
@holdyounger

Description

@holdyounger

监控网卡事件

方法一

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

具体步骤如下:

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

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

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

示例代码:

#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函数注册控制事件处理函数,以便在收到控制事件时可以及时退出程序。

方法二

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

  1. 使用Windows API函数注册网络配置更改通知。使用以下代码:
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 参数,该参数是一个包含有关更改的结构体。 您可以使用以下代码来检查是否禁用了任何网络适配器:
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;

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

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

blog link 监控网卡事件

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      0