| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143 |
- // SerialFilter.cpp - 串口 IRP 拦截实现
- // 注意:完整 KMDF 上层过滤驱动需要 IoAttachDeviceToDeviceStack + EvtDeviceAdd
- // 本文件实现 IRP 派遣与完成例程,CreateAndAttach 为简化框架
- #include <ntddk.h>
- #include <wdf.h>
- #include "SerialFilter.h"
- #include "EventRingBuffer.h"
- #include "ClientConnection.h"
- #include "../common/CommKitEvents.h"
- namespace commkit_driver {
- // 全局原子序列号(每个事件递增)
- static LONG g_sequence_counter = 0;
- // 获取当前时间戳(100ns 单位)
- static UINT64 GetCurrentTimeStamp() {
- return KeQueryInterruptTime();
- }
- 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) {
- irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
- irp->IoStatus.Information = 0;
- IoCompleteRequest(irp, IO_NO_INCREMENT);
- return STATUS_INVALID_DEVICE_REQUEST;
- }
- // 透传 DeviceControl 给下层
- IoSkipCurrentIrpStackLocation(irp);
- return IoCallDriver(ctx->LowerDevice, irp);
- }
- } // namespace commkit_driver
|