You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Windows下如何获取服务/驱动IO文件的活跃客户端连接数?

如何获取驱动文件的客户端连接数?

用户提供的客户端与驱动通信的伪代码如下:

HANDLE gHandle = CreateFileA("\\\\.\\DriverFile",
    GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING,
    FILE_ATTRIBUTE_NORMAL, NULL);
... 
DeviceIoControl(gHandle, MY_MSG_ID, NULL, 0, &refCount, 
   sizeof(refCount), &length, NULL);
...
CloseHandle(gHandle);

请问是否有办法获知当前有多少客户端与该驱动文件建立了打开连接?

已知一种实现方式是在驱动端处理IRP_MJ_CREATE/IRP_MJ_CLOSE请求,手动维护引用计数,再通过特定消息让客户端获取该计数。有没有无需修改驱动端的实现方法?


无需修改驱动的实现方法

方法一:用系统API直接查询句柄计数

可以调用未公开的NtQueryObject系统API,通过驱动文件的句柄获取对象的基础信息,其中包含当前的句柄总计数。伪代码示例:

#include <windows.h>
#include <ntstatus.h>

typedef NTSTATUS(NTAPI* pNtQueryObject)(
    HANDLE Handle,
    OBJECT_INFORMATION_CLASS ObjectInformationClass,
    PVOID ObjectInformation,
    ULONG ObjectInformationLength,
    PULONG ReturnLength
);

int main() {
    HANDLE gHandle = CreateFileA("\\\\.\\DriverFile", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    if (gHandle == INVALID_HANDLE_VALUE) {
        return 1;
    }

    HMODULE ntdll = GetModuleHandleA("ntdll.dll");
    pNtQueryObject NtQueryObject = (pNtQueryObject)GetProcAddress(ntdll, "NtQueryObject");
    if (!NtQueryObject) {
        CloseHandle(gHandle);
        return 1;
    }

    OBJECT_BASIC_INFORMATION objInfo;
    NTSTATUS status = NtQueryObject(gHandle, ObjectBasicInformation, &objInfo, sizeof(objInfo), NULL);
    if (NT_SUCCESS(status)) {
        printf("当前驱动的打开句柄总数: %lu\n", objInfo.HandleCount);
    }

    CloseHandle(gHandle);
    return 0;
}

注意:这个计数包含所有打开该驱动对象的句柄,包括其他进程的用户态句柄和内核态的内部句柄,如果只需要统计用户态客户端,还需要进一步过滤。

方法二:用Sysinternals工具快速查看

直接用微软Sysinternals套件里的WinObj工具:

  • 打开WinObj后,展开\Device节点,找到对应驱动的设备对象
  • 查看该对象的HandleCount属性,就是当前的打开句柄总数
    和API方法一样,这个数值也包含内核态句柄,需要结合场景判断。

方法三:枚举进程句柄精确统计用户态连接

如果要精确统计用户态客户端的连接数,需要遍历系统中所有进程的句柄,筛选出指向目标驱动的句柄:

  1. 调用NtQuerySystemInformation(指定SystemHandleInformation类型)获取系统中所有句柄的信息
  2. 对每个句柄,打开对应进程(需要PROCESS_DUP_HANDLE权限),把句柄复制到当前进程
  3. 调用NtQueryObject查询复制后的句柄对应的对象名称,判断是否是目标驱动设备
  4. 统计符合条件的句柄数量

这种方法能排除内核态的内部句柄,得到更准确的用户态客户端连接数,但实现起来相对复杂。


总结一下:

  • 只是快速查看或者不需要区分内核/用户态句柄,用WinObj或NtQueryObject最方便
  • 要精确统计用户态客户端,就得用进程句柄枚举的方法

内容的提问来源于stack exchange,提问作者Pavel P

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 05:43:12