// SerialFilter.cpp - 串口 IRP 拦截实现 // 注意:完整 KMDF 上层过滤驱动需要 IoAttachDeviceToDeviceStack + EvtDeviceAdd // 本文件实现 IRP 派遣与完成例程,CreateAndAttach 为简化框架 #include #include #include "SerialFilter.h" #include "EventRingBuffer.h" #include "ClientConnection.h" #include "../common/CommKitEvents.h" namespace commkit_driver { // 全局原子序列号(每个事件递增) static LONG g_sequence_counter = 0; // 获取当前 OLE Automation 日期(简化实现:返回 0,由 DLL 转换为当前时间) static DOUBLE GetCurrentTimeStamp() { return 0.0; } NTSTATUS SerialFilter::CreateAndAttach(WDFDRIVER driver, PDEVICE_OBJECT serial_pdo, ULONG com_number, WDFDEVICE* out_filter_device) { UNREFERENCED_PARAMETER(driver); // 简化实现:完整的 KMDF 上层过滤驱动需要: // 1. WdfDeviceInitAssignName / WdfDeviceInitSetFileObjectConfig // 2. WdfDeviceCreate // 3. IoAttachDeviceToDeviceStack (WDM attach) // 此处给出框架,实际完成时按需补充 *out_filter_device = nullptr; return STATUS_NOT_IMPLEMENTED; } void SerialFilter::CaptureIrpData(PDEVICE_CONTEXT ctx, PIRP irp, ULONG event_type) { if (!ctx || !ctx->MonitoringEnabled || !ctx->RingBuffer) { return; } PIO_STACK_LOCATION sl = IoGetCurrentIrpStackLocation(irp); if (!sl) return; // 仅在 IRP 成功完成时捕获 if (!NT_SUCCESS(irp->IoStatus.Status)) { return; } ULONG data_size = 0; PVOID data_ptr = nullptr; // 根据 IRP 类型提取数据 if (event_type == COMMKIT_OP_READ) { data_size = sl->Parameters.Read.Length; // 实际读取的字节数(IRP 完成后 Information = 读取字节数) data_size = (ULONG)irp->IoStatus.Information; if (data_size == 0) return; // 数据可能在 SystemBuffer / MdlAddress / UserBuffer if (irp->MdlAddress) { data_ptr = MmGetSystemAddressForMdlSafe(irp->MdlAddress, NormalPagePriority); } else if (irp->AssociatedIrp.SystemBuffer) { data_ptr = irp->AssociatedIrp.SystemBuffer; } } else if (event_type == COMMKIT_OP_WRITE) { data_size = (ULONG)irp->IoStatus.Information; if (data_size == 0) { data_size = sl->Parameters.Write.Length; } if (data_size == 0) return; if (irp->MdlAddress) { data_ptr = MmGetSystemAddressForMdlSafe(irp->MdlAddress, NormalPagePriority); } else if (irp->AssociatedIrp.SystemBuffer) { data_ptr = irp->AssociatedIrp.SystemBuffer; } } if (!data_ptr || data_size == 0) { // OP_OPEN / OP_CLOSE 事件无数据,也推送 if (event_type != COMMKIT_OP_READ && event_type != COMMKIT_OP_WRITE) { // 落空,继续推送无数据事件 } else { return; } } // 推入环形缓冲 LONG seq = InterlockedIncrement(&g_sequence_counter); auto* ring = (EventRingBuffer*)ctx->RingBuffer; ring->Push((ULONG)seq, GetCurrentTimeStamp(), ctx->ComNumber, event_type, data_size, data_ptr); } NTSTATUS SerialFilter::OnReadComplete(PDEVICE_OBJECT dev, PIRP irp, PVOID ctx) { UNREFERENCED_PARAMETER(dev); PDEVICE_CONTEXT device_ctx = (PDEVICE_CONTEXT)ctx; if (device_ctx) { CaptureIrpData(device_ctx, irp, COMMKIT_OP_READ); } return STATUS_SUCCESS; } NTSTATUS SerialFilter::OnWriteComplete(PDEVICE_OBJECT dev, PIRP irp, PVOID ctx) { UNREFERENCED_PARAMETER(dev); PDEVICE_CONTEXT device_ctx = (PDEVICE_CONTEXT)ctx; if (device_ctx) { CaptureIrpData(device_ctx, irp, COMMKIT_OP_WRITE); } return STATUS_SUCCESS; } NTSTATUS SerialFilter::DispatchRead(PDEVICE_OBJECT dev, PIRP irp) { PDEVICE_CONTEXT ctx = (PDEVICE_CONTEXT)dev->DeviceExtension; if (ctx && ctx->MonitoringEnabled) { IoMarkIrpPending(irp); IoSetCompletionRoutine(irp, OnReadComplete, ctx, TRUE, TRUE, TRUE); } return IoCallDriver(ctx->LowerDevice, irp); } NTSTATUS SerialFilter::DispatchWrite(PDEVICE_OBJECT dev, PIRP irp) { PDEVICE_CONTEXT ctx = (PDEVICE_CONTEXT)dev->DeviceExtension; if (ctx && ctx->MonitoringEnabled) { IoMarkIrpPending(irp); IoSetCompletionRoutine(irp, OnWriteComplete, ctx, TRUE, TRUE, TRUE); } return IoCallDriver(ctx->LowerDevice, irp); } NTSTATUS SerialFilter::DispatchDeviceControl(PDEVICE_OBJECT dev, PIRP irp) { PDEVICE_CONTEXT ctx = (PDEVICE_CONTEXT)dev->DeviceExtension; if (!ctx) { IoCompleteRequest(irp, STATUS_INVALID_DEVICE_REQUEST); return STATUS_INVALID_DEVICE_REQUEST; } // 透传 DeviceControl 给下层 IoSkipCurrentIrpStackLocation(irp); return IoCallDriver(ctx->LowerDevice, irp); } } // namespace commkit_driver