SerialFilter.cpp 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. // SerialFilter.cpp - 串口 IRP 拦截实现
  2. // KMDF 过滤驱动模式:通过 WdfDeviceInitAssignWdmIrpPreprocessCallback 注册
  3. // 在预处理回调中注册完成例程,捕获 READ/WRITE 数据
  4. #include <ntddk.h>
  5. #include <wdf.h>
  6. #include "SerialFilter.h"
  7. #include "EventRingBuffer.h"
  8. #include "ClientConnection.h"
  9. #include "DeviceContext.h"
  10. #include "../common/CommKitEvents.h"
  11. namespace commkit_driver {
  12. // 全局原子序列号(所有事件类型共享,保证 Sequence 字段全局唯一递增)
  13. LONG g_sequence_counter = 0;
  14. // 获取当前时间戳(100ns 单位)
  15. static UINT64 GetCurrentTimeStamp() {
  16. return KeQueryInterruptTime();
  17. }
  18. void SerialFilter::CaptureIrpData(PDEVICE_CONTEXT ctx, PIRP irp, ULONG event_type) {
  19. if (!ctx || !ctx->MonitoringEnabled || !ctx->RingBuffer) {
  20. return;
  21. }
  22. PIO_STACK_LOCATION sl = IoGetCurrentIrpStackLocation(irp);
  23. if (!sl) return;
  24. // 仅在 IRP 成功完成时捕获
  25. if (!NT_SUCCESS(irp->IoStatus.Status)) {
  26. return;
  27. }
  28. ULONG data_size = 0;
  29. PVOID data_ptr = nullptr;
  30. // 根据 IRP 类型提取数据
  31. if (event_type == COMMKIT_OP_READ) {
  32. // 实际读取的字节数(IRP 完成后 Information = 读取字节数)
  33. data_size = (ULONG)irp->IoStatus.Information;
  34. if (data_size == 0) return;
  35. // 数据可能在 SystemBuffer / MdlAddress / UserBuffer
  36. if (irp->MdlAddress) {
  37. data_ptr = MmGetSystemAddressForMdlSafe(irp->MdlAddress, NormalPagePriority);
  38. } else if (irp->AssociatedIrp.SystemBuffer) {
  39. data_ptr = irp->AssociatedIrp.SystemBuffer;
  40. }
  41. } else if (event_type == COMMKIT_OP_WRITE) {
  42. data_size = (ULONG)irp->IoStatus.Information;
  43. if (data_size == 0) {
  44. data_size = sl->Parameters.Write.Length;
  45. }
  46. if (data_size == 0) return;
  47. if (irp->MdlAddress) {
  48. data_ptr = MmGetSystemAddressForMdlSafe(irp->MdlAddress, NormalPagePriority);
  49. } else if (irp->AssociatedIrp.SystemBuffer) {
  50. data_ptr = irp->AssociatedIrp.SystemBuffer;
  51. }
  52. }
  53. if (!data_ptr || data_size == 0) {
  54. return;
  55. }
  56. // 推入环形缓冲
  57. LONG seq = InterlockedIncrement(&g_sequence_counter);
  58. auto* ring = (EventRingBuffer*)ctx->RingBuffer;
  59. ring->Push((ULONG)seq, GetCurrentTimeStamp(),
  60. ctx->ComNumber, event_type,
  61. data_size, data_ptr);
  62. }
  63. NTSTATUS SerialFilter::OnReadComplete(PDEVICE_OBJECT dev, PIRP irp, PVOID ctx) {
  64. UNREFERENCED_PARAMETER(dev);
  65. PDEVICE_CONTEXT device_ctx = (PDEVICE_CONTEXT)ctx;
  66. if (device_ctx) {
  67. CaptureIrpData(device_ctx, irp, COMMKIT_OP_READ);
  68. }
  69. // 下层驱动返回 STATUS_PENDING 时需标记 IRP 为 pending
  70. if (irp->PendingReturned) {
  71. IoMarkIrpPending(irp);
  72. }
  73. return STATUS_SUCCESS;
  74. }
  75. NTSTATUS SerialFilter::OnWriteComplete(PDEVICE_OBJECT dev, PIRP irp, PVOID ctx) {
  76. UNREFERENCED_PARAMETER(dev);
  77. PDEVICE_CONTEXT device_ctx = (PDEVICE_CONTEXT)ctx;
  78. if (device_ctx) {
  79. CaptureIrpData(device_ctx, irp, COMMKIT_OP_WRITE);
  80. }
  81. if (irp->PendingReturned) {
  82. IoMarkIrpPending(irp);
  83. }
  84. return STATUS_SUCCESS;
  85. }
  86. NTSTATUS SerialFilter::DispatchRead(WDFDEVICE dev, PIRP irp) {
  87. PDEVICE_CONTEXT ctx = DeviceGetContext(dev);
  88. if (ctx && ctx->MonitoringEnabled && ctx->RingBuffer) {
  89. IoSetCompletionRoutine(irp, OnReadComplete, ctx, TRUE, TRUE, TRUE);
  90. }
  91. return WdfDeviceWdmDispatchPreprocessedIrp(dev, irp);
  92. }
  93. NTSTATUS SerialFilter::DispatchWrite(WDFDEVICE dev, PIRP irp) {
  94. PDEVICE_CONTEXT ctx = DeviceGetContext(dev);
  95. if (ctx && ctx->MonitoringEnabled && ctx->RingBuffer) {
  96. IoSetCompletionRoutine(irp, OnWriteComplete, ctx, TRUE, TRUE, TRUE);
  97. }
  98. return WdfDeviceWdmDispatchPreprocessedIrp(dev, irp);
  99. }
  100. NTSTATUS SerialFilter::DispatchDeviceControl(WDFDEVICE dev, PIRP irp) {
  101. // DeviceControl 透传,不拦截(串口 IOCTL 由应用层处理)
  102. return WdfDeviceWdmDispatchPreprocessedIrp(dev, irp);
  103. }
  104. NTSTATUS SerialFilter::DispatchCreate(WDFDEVICE dev, PIRP irp) {
  105. // CREATE/CLOSE/CLEANUP 直接转发,不做任何处理
  106. DbgPrint("[CommModifyKit] DispatchCreate entered, IRP=%p\n", irp);
  107. NTSTATUS status = WdfDeviceWdmDispatchPreprocessedIrp(dev, irp);
  108. DbgPrint("[CommModifyKit] DispatchCreate returned 0x%08X\n", status);
  109. return status;
  110. }
  111. NTSTATUS SerialFilter::DispatchClose(WDFDEVICE dev, PIRP irp) {
  112. return WdfDeviceWdmDispatchPreprocessedIrp(dev, irp);
  113. }
  114. NTSTATUS SerialFilter::DispatchCleanup(WDFDEVICE dev, PIRP irp) {
  115. return WdfDeviceWdmDispatchPreprocessedIrp(dev, irp);
  116. }
  117. NTSTATUS SerialFilter::CreateAndAttach(WDFDRIVER driver,
  118. PDEVICE_OBJECT serial_pdo,
  119. ULONG com_number,
  120. WDFDEVICE* out_filter_device) {
  121. // 不再使用:过滤设备由 EvtDeviceAdd 自动创建
  122. UNREFERENCED_PARAMETER(driver);
  123. UNREFERENCED_PARAMETER(serial_pdo);
  124. UNREFERENCED_PARAMETER(com_number);
  125. *out_filter_device = nullptr;
  126. return STATUS_NOT_IMPLEMENTED;
  127. }
  128. } // namespace commkit_driver