SerialFilter.cpp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. // SerialFilter.cpp - 串口 IRP 拦截实现
  2. // 注意:完整 KMDF 上层过滤驱动需要 IoAttachDeviceToDeviceStack + EvtDeviceAdd
  3. // 本文件实现 IRP 派遣与完成例程,CreateAndAttach 为简化框架
  4. #include <ntddk.h>
  5. #include <wdf.h>
  6. #include "SerialFilter.h"
  7. #include "EventRingBuffer.h"
  8. #include "ClientConnection.h"
  9. #include "../common/CommKitEvents.h"
  10. namespace commkit_driver {
  11. // 全局原子序列号(每个事件递增)
  12. static LONG g_sequence_counter = 0;
  13. // 获取当前 OLE Automation 日期(简化实现:返回 0,由 DLL 转换为当前时间)
  14. static DOUBLE GetCurrentTimeStamp() {
  15. return 0.0;
  16. }
  17. NTSTATUS SerialFilter::CreateAndAttach(WDFDRIVER driver,
  18. PDEVICE_OBJECT serial_pdo,
  19. ULONG com_number,
  20. WDFDEVICE* out_filter_device) {
  21. UNREFERENCED_PARAMETER(driver);
  22. // 简化实现:完整的 KMDF 上层过滤驱动需要:
  23. // 1. WdfDeviceInitAssignName / WdfDeviceInitSetFileObjectConfig
  24. // 2. WdfDeviceCreate
  25. // 3. IoAttachDeviceToDeviceStack (WDM attach)
  26. // 此处给出框架,实际完成时按需补充
  27. *out_filter_device = nullptr;
  28. return STATUS_NOT_IMPLEMENTED;
  29. }
  30. void SerialFilter::CaptureIrpData(PDEVICE_CONTEXT ctx, PIRP irp, ULONG event_type) {
  31. if (!ctx || !ctx->MonitoringEnabled || !ctx->RingBuffer) {
  32. return;
  33. }
  34. PIO_STACK_LOCATION sl = IoGetCurrentIrpStackLocation(irp);
  35. if (!sl) return;
  36. // 仅在 IRP 成功完成时捕获
  37. if (!NT_SUCCESS(irp->IoStatus.Status)) {
  38. return;
  39. }
  40. ULONG data_size = 0;
  41. PVOID data_ptr = nullptr;
  42. // 根据 IRP 类型提取数据
  43. if (event_type == COMMKIT_OP_READ) {
  44. data_size = sl->Parameters.Read.Length;
  45. // 实际读取的字节数(IRP 完成后 Information = 读取字节数)
  46. data_size = (ULONG)irp->IoStatus.Information;
  47. if (data_size == 0) return;
  48. // 数据可能在 SystemBuffer / MdlAddress / UserBuffer
  49. if (irp->MdlAddress) {
  50. data_ptr = MmGetSystemAddressForMdlSafe(irp->MdlAddress, NormalPagePriority);
  51. } else if (irp->AssociatedIrp.SystemBuffer) {
  52. data_ptr = irp->AssociatedIrp.SystemBuffer;
  53. }
  54. } else if (event_type == COMMKIT_OP_WRITE) {
  55. data_size = (ULONG)irp->IoStatus.Information;
  56. if (data_size == 0) {
  57. data_size = sl->Parameters.Write.Length;
  58. }
  59. if (data_size == 0) return;
  60. if (irp->MdlAddress) {
  61. data_ptr = MmGetSystemAddressForMdlSafe(irp->MdlAddress, NormalPagePriority);
  62. } else if (irp->AssociatedIrp.SystemBuffer) {
  63. data_ptr = irp->AssociatedIrp.SystemBuffer;
  64. }
  65. }
  66. if (!data_ptr || data_size == 0) {
  67. // OP_OPEN / OP_CLOSE 事件无数据,也推送
  68. if (event_type != COMMKIT_OP_READ && event_type != COMMKIT_OP_WRITE) {
  69. // 落空,继续推送无数据事件
  70. } else {
  71. return;
  72. }
  73. }
  74. // 推入环形缓冲
  75. LONG seq = InterlockedIncrement(&g_sequence_counter);
  76. auto* ring = (EventRingBuffer*)ctx->RingBuffer;
  77. ring->Push((ULONG)seq, GetCurrentTimeStamp(),
  78. ctx->ComNumber, event_type,
  79. data_size, data_ptr);
  80. }
  81. NTSTATUS SerialFilter::OnReadComplete(PDEVICE_OBJECT dev, PIRP irp, PVOID ctx) {
  82. UNREFERENCED_PARAMETER(dev);
  83. PDEVICE_CONTEXT device_ctx = (PDEVICE_CONTEXT)ctx;
  84. if (device_ctx) {
  85. CaptureIrpData(device_ctx, irp, COMMKIT_OP_READ);
  86. }
  87. return STATUS_SUCCESS;
  88. }
  89. NTSTATUS SerialFilter::OnWriteComplete(PDEVICE_OBJECT dev, PIRP irp, PVOID ctx) {
  90. UNREFERENCED_PARAMETER(dev);
  91. PDEVICE_CONTEXT device_ctx = (PDEVICE_CONTEXT)ctx;
  92. if (device_ctx) {
  93. CaptureIrpData(device_ctx, irp, COMMKIT_OP_WRITE);
  94. }
  95. return STATUS_SUCCESS;
  96. }
  97. NTSTATUS SerialFilter::DispatchRead(PDEVICE_OBJECT dev, PIRP irp) {
  98. PDEVICE_CONTEXT ctx = (PDEVICE_CONTEXT)dev->DeviceExtension;
  99. if (ctx && ctx->MonitoringEnabled) {
  100. IoMarkIrpPending(irp);
  101. IoSetCompletionRoutine(irp, OnReadComplete, ctx, TRUE, TRUE, TRUE);
  102. }
  103. return IoCallDriver(ctx->LowerDevice, irp);
  104. }
  105. NTSTATUS SerialFilter::DispatchWrite(PDEVICE_OBJECT dev, PIRP irp) {
  106. PDEVICE_CONTEXT ctx = (PDEVICE_CONTEXT)dev->DeviceExtension;
  107. if (ctx && ctx->MonitoringEnabled) {
  108. IoMarkIrpPending(irp);
  109. IoSetCompletionRoutine(irp, OnWriteComplete, ctx, TRUE, TRUE, TRUE);
  110. }
  111. return IoCallDriver(ctx->LowerDevice, irp);
  112. }
  113. NTSTATUS SerialFilter::DispatchDeviceControl(PDEVICE_OBJECT dev, PIRP irp) {
  114. PDEVICE_CONTEXT ctx = (PDEVICE_CONTEXT)dev->DeviceExtension;
  115. if (!ctx) {
  116. IoCompleteRequest(irp, STATUS_INVALID_DEVICE_REQUEST);
  117. return STATUS_INVALID_DEVICE_REQUEST;
  118. }
  119. // 透传 DeviceControl 给下层
  120. IoSkipCurrentIrpStackLocation(irp);
  121. return IoCallDriver(ctx->LowerDevice, irp);
  122. }
  123. } // namespace commkit_driver