Forráskód Böngészése

实现监控指定端口

Gogs 2 hete
szülő
commit
9d2adc3a01
4 módosított fájl, 67 hozzáadás és 42 törlés
  1. 14 0
      driver/ClientConnection.cpp
  2. 9 0
      driver/ClientConnection.h
  3. 28 42
      driver/DriverEntry.cpp
  4. 16 0
      installer/install.ps1

+ 14 - 0
driver/ClientConnection.cpp

@@ -7,6 +7,15 @@
 #include "../common/CommKitIoctl.h"
 #include "../common/CommKitEvents.h"
 
+// 诊断计数器(全局命名空间)
+volatile LONG g_diag_evt_device_add_count = 0;
+volatile LONG g_diag_prepare_hardware_count = 0;
+volatile LONG g_diag_register_filter_count = 0;
+volatile LONG g_diag_irp_preprocess_ok = 0;
+volatile LONG g_diag_sddl_ok = 0;
+volatile LONG g_diag_device_create_ok = 0;
+volatile LONG g_diag_last_failure_status = 0;
+
 namespace commkit_driver {
 
 // 全局实例
@@ -38,6 +47,7 @@ void ClientConnection::Cleanup() {
 }
 
 void ClientConnection::RegisterFilterDevice(WDFDEVICE device) {
+    InterlockedIncrement(&g_diag_register_filter_count);
     KIRQL old_irql;
     KeAcquireSpinLock(&ports_lock_, &old_irql);
 
@@ -124,6 +134,10 @@ NTSTATUS ClientConnection::HandleAttachPort(ULONG com_number) {
     if (!ctx) {
         DbgPrint("[CommModifyKit] HandleAttachPort: COM%u NOT in ports_table (count=%u)\n",
                  com_number, ports_count_);
+        DbgPrint("[CommModifyKit] DIAG: EvtDeviceAdd=%ld, IRPpreproc=%ld, SDDL=%ld, DevCreate=%ld, Register=%ld, PrepHW=%ld, LastFail=0x%lX\n",
+                 g_diag_evt_device_add_count, g_diag_irp_preprocess_ok, g_diag_sddl_ok,
+                 g_diag_device_create_ok, g_diag_register_filter_count, g_diag_prepare_hardware_count,
+                 g_diag_last_failure_status);
         // 打印 ports_table_ 里所有已注册的 COM 编号,便于诊断
         KIRQL old_irql;
         KeAcquireSpinLock(&ports_lock_, &old_irql);

+ 9 - 0
driver/ClientConnection.h

@@ -85,3 +85,12 @@ inline ClientConnection& GetClientConnection() {
 }
 
 } // namespace commkit_driver
+
+// 诊断计数器(全局命名空间,不依赖 DbgPrint,可在 HandleAttachPort 中输出)
+extern volatile LONG g_diag_evt_device_add_count;
+extern volatile LONG g_diag_prepare_hardware_count;
+extern volatile LONG g_diag_register_filter_count;
+extern volatile LONG g_diag_irp_preprocess_ok;    // 所有 IRP preprocess 注册成功次数
+extern volatile LONG g_diag_sddl_ok;               // SDDL 赋值成功次数
+extern volatile LONG g_diag_device_create_ok;       // WdfDeviceCreate 成功次数
+extern volatile LONG g_diag_last_failure_status;   // 最后一次失败的 NTSTATUS

+ 28 - 42
driver/DriverEntry.cpp

@@ -33,6 +33,7 @@ static WDFDRIVER g_wdf_driver = nullptr;
 
 extern "C" NTSTATUS DriverEntry(PDRIVER_OBJECT driver_object,
                                   PUNICODE_STRING registry_path) {
+    DbgPrint("[CommModifyKit] DriverEntry ENTERED\n");
     NTSTATUS status;
     WDF_DRIVER_CONFIG cfg;
 
@@ -54,83 +55,68 @@ extern "C" NTSTATUS DriverEntry(PDRIVER_OBJECT driver_object,
     // 初始化 ClientConnection(创建控制设备)
     status = commkit_driver::CreateControlDevice(commkit_driver::g_wdf_driver);
     if (!NT_SUCCESS(status)) {
+        DbgPrint("[CommModifyKit] CreateControlDevice FAILED 0x%08X\n", status);
         return status;
     }
 
+    DbgPrint("[CommModifyKit] DriverEntry OK, EvtDeviceAdd registered\n");
     return STATUS_SUCCESS;
 }
 
 extern "C" NTSTATUS EvtDeviceAdd(WDFDRIVER driver, PWDFDEVICE_INIT init) {
     UNREFERENCED_PARAMETER(driver);
 
+    InterlockedIncrement(&g_diag_evt_device_add_count);
+
     NTSTATUS status;
 
     // 1. 标记为过滤设备
     WdfFdoInitSetFilter(init);
 
-    // 2. 注册 PnP 电源回调(EvtDevicePrepareHardware 解析 COM 编号)
+    // 2. 注册 PnP 电源回调
     WDF_PNPPOWER_EVENT_CALLBACKS pnp_callbacks;
     WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnp_callbacks);
     pnp_callbacks.EvtDevicePrepareHardware = EvtDevicePrepareHardware;
     WdfDeviceInitSetPnpPowerEventCallbacks(init, &pnp_callbacks);
 
-    // 3. 注册 WDM IRP 预处理回调(拦截 READ/WRITE/DEVICE_CONTROL)
+    // 3. 注册 WDM IRP 预处理回调
     status = WdfDeviceInitAssignWdmIrpPreprocessCallback(
         init, commkit_driver::SerialFilter::DispatchRead,
         IRP_MJ_READ, nullptr, 0);
-    if (!NT_SUCCESS(status)) {
-        return status;
-    }
+    if (!NT_SUCCESS(status)) { InterlockedExchange(&g_diag_last_failure_status, status); return status; }
 
     status = WdfDeviceInitAssignWdmIrpPreprocessCallback(
         init, commkit_driver::SerialFilter::DispatchWrite,
         IRP_MJ_WRITE, nullptr, 0);
-    if (!NT_SUCCESS(status)) {
-        return status;
-    }
+    if (!NT_SUCCESS(status)) { InterlockedExchange(&g_diag_last_failure_status, status); return status; }
 
     status = WdfDeviceInitAssignWdmIrpPreprocessCallback(
         init, commkit_driver::SerialFilter::DispatchDeviceControl,
         IRP_MJ_DEVICE_CONTROL, nullptr, 0);
-    if (!NT_SUCCESS(status)) {
-        return status;
-    }
+    if (!NT_SUCCESS(status)) { InterlockedExchange(&g_diag_last_failure_status, status); return status; }
 
-    // 注册 CREATE/CLOSE/CLEANUP 预处理回调(确保正确转发)
     status = WdfDeviceInitAssignWdmIrpPreprocessCallback(
         init, commkit_driver::SerialFilter::DispatchCreate,
         IRP_MJ_CREATE, nullptr, 0);
-    if (!NT_SUCCESS(status)) {
-        return status;
-    }
+    if (!NT_SUCCESS(status)) { InterlockedExchange(&g_diag_last_failure_status, status); return status; }
 
     status = WdfDeviceInitAssignWdmIrpPreprocessCallback(
         init, commkit_driver::SerialFilter::DispatchClose,
         IRP_MJ_CLOSE, nullptr, 0);
-    if (!NT_SUCCESS(status)) {
-        return status;
-    }
+    if (!NT_SUCCESS(status)) { InterlockedExchange(&g_diag_last_failure_status, status); return status; }
 
     status = WdfDeviceInitAssignWdmIrpPreprocessCallback(
         init, commkit_driver::SerialFilter::DispatchCleanup,
         IRP_MJ_CLEANUP, nullptr, 0);
-    if (!NT_SUCCESS(status)) {
-        return status;
-    }
+    if (!NT_SUCCESS(status)) { InterlockedExchange(&g_diag_last_failure_status, status); return status; }
 
-    // 4. 设置宽松 SDDL(匹配 serial.sys 行为)
-    // WDF 默认 SDDL 仅 System+Administrators,会导致非 elevated 进程
-    // 无法打开 \\.\COMx(即使 Administrator 账户在 filtered token 下也失败)
-    // AU=Authenticated Users, WD=Everyone 给读写权限
-    static DECLARE_CONST_UNICODE_STRING(
-        sddl_filter,
-        L"D:P(A;;GA;;;SY)(A;;GA;;;BA)(A;;GRGW;;;AU)(A;;GRGW;;;WD)");
-    status = WdfDeviceInitAssignSDDLString(init, &sddl_filter);
-    if (!NT_SUCCESS(status)) {
-        DbgPrint("[CommModifyKit] WdfDeviceInitAssignSDDLString failed 0x%08X\n", status);
-        return status;
-    }
-    DbgPrint("[CommModifyKit] SDDL assigned OK\n");
+    InterlockedIncrement(&g_diag_irp_preprocess_ok);
+
+    // 4. SDDL: WDF filter device 不支持 WdfDeviceInitAssignSDDLString
+    //    它会返回 STATUS_INVALID_SECURITY_DESCR (0xC0000079)
+    //    Filter device 会继承下层设备 (serial.sys) 的安全描述符
+    //    不需要显式设置 SDDL
+    InterlockedIncrement(&g_diag_sddl_ok);
 
     // 5. 创建 WDF 设备
     WDFDEVICE device;
@@ -139,21 +125,19 @@ extern "C" NTSTATUS EvtDeviceAdd(WDFDRIVER driver, PWDFDEVICE_INIT init) {
     attrs.EvtCleanupCallback = EvtDeviceContextCleanup;
 
     status = WdfDeviceCreate(&init, &attrs, &device);
-    if (!NT_SUCCESS(status)) {
-        DbgPrint("[CommModifyKit] WdfDeviceCreate failed 0x%08X\n", status);
-        return status;
-    }
-    DbgPrint("[CommModifyKit] WdfDeviceCreate OK\n");
+    if (!NT_SUCCESS(status)) { InterlockedExchange(&g_diag_last_failure_status, status); return status; }
+
+    InterlockedIncrement(&g_diag_device_create_ok);
 
-    // 5. 初始化设备上下文
+    // 6. 初始化设备上下文
     PDEVICE_CONTEXT ctx = DeviceGetContext(device);
-    ctx->ComNumber = 0;          // 延迟到 EvtDevicePrepareHardware 解析
+    ctx->ComNumber = 0;
     ctx->MonitoringEnabled = FALSE;
     ctx->RingBuffer = nullptr;
     ctx->WdfDevice = device;
     ctx->LowerDevice = WdfDeviceWdmGetAttachedDevice(device);
 
-    // 6. 注册到全局端口表(com_number 暂为 0,PrepareHardware 时更新)
+    // 7. 注册到全局端口表
     commkit_driver::GetClientConnection().RegisterFilterDevice(device);
 
     return STATUS_SUCCESS;
@@ -168,6 +152,8 @@ NTSTATUS EvtDevicePrepareHardware(WDFDEVICE device,
     NTSTATUS status;
     PDEVICE_CONTEXT ctx = DeviceGetContext(device);
 
+    InterlockedIncrement(&g_diag_prepare_hardware_count);
+
     // 从 PnP 属性解析 COM 编号
     // 方式:获取 DevicePropertyFriendlyName 或 DevicePropertyDeviceDescription,
     // 匹配 "COM%d" 模式

+ 16 - 0
installer/install.ps1

@@ -357,6 +357,22 @@ if ($svcState -ne 'Running') {
         $newFilters = @($currentFilters) + "CommModifyKit"
         Set-ItemProperty -Path $ClassKey -Name "UpperFilters" -Value $newFilters -Type MultiString
         Write-Host "已将 CommModifyKit 添加到 Ports 类 UpperFilters" -ForegroundColor Green
+
+        # 设置 Ports 类的 Security 值
+        # WDF filter device 不支持 WdfDeviceInitAssignSDDLString(返回 STATUS_INVALID_SECURITY_DESCR)
+        # Filter device 会继承类键的 Security 值。如果不设置,使用 WDF 默认 SDDL
+        # (仅 System+Admins),导致非 elevated 进程无法打开 \\.\COMx
+        try {
+            $sd = New-Object System.Security.AccessControl.CommonSecurityDescriptor(
+                $false, $false,
+                "D:P(A;;GA;;;SY)(A;;GA;;;BA)(A;;GRGW;;;AU)(A;;GRGW;;;WD)")
+            $binary = New-Object byte[] $sd.BinaryLength
+            $sd.GetBinaryForm($binary, 0)
+            Set-ItemProperty -Path $ClassKey -Name "Security" -Value $binary -Type Binary
+            Write-Host "已设置 Ports 类 Security 值(允许 Authenticated Users 读写)" -ForegroundColor Green
+        } catch {
+            Write-Warning "设置 Ports 类 Security 值失败: $($_.Exception.Message)"
+        }
         # 重新枚举设备使 UpperFilter 生效
         pnputil /scan-devices | Out-Null
         Write-Host "已触发设备重新枚举" -ForegroundColor Green