| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233 |
- // ClientConnection.cpp - 用户态连接管理实现
- #include <ntddk.h>
- #include <wdf.h>
- #include "ClientConnection.h"
- #include "EventRingBuffer.h"
- #include "../common/CommKitIoctl.h"
- #include "../common/CommKitEvents.h"
- namespace commkit_driver {
- ClientConnection::ClientConnection()
- : ports_count_(0), control_device_(nullptr), callback_registered_(FALSE) {
- KeInitializeSpinLock(&ports_lock_);
- RtlZeroMemory(ports_table_, sizeof(ports_table_));
- }
- ClientConnection::~ClientConnection() {
- Cleanup();
- }
- ClientConnection& GetClientConnection() {
- static ClientConnection instance;
- return instance;
- }
- NTSTATUS ClientConnection::Initialize(WDFDRIVER driver) {
- UNREFERENCED_PARAMETER(driver);
- // 控制设备创建详见 QueueCallback.cpp / DriverEntry.cpp
- return STATUS_SUCCESS;
- }
- void ClientConnection::Cleanup() {
- // 释放所有端口的环形缓冲
- KIRQL old_irql;
- KeAcquireSpinLock(&ports_lock_, &old_irql);
- for (ULONG i = 0; i < ports_count_; ++i) {
- PDEVICE_CONTEXT ctx = ports_table_[i].Context;
- if (ctx && ctx->RingBuffer) {
- EventRingBuffer* ring = (EventRingBuffer*)ctx->RingBuffer;
- ring->Cleanup();
- ExFreePoolWithTag(ring, 'RBCK');
- ctx->RingBuffer = nullptr;
- }
- }
- ports_count_ = 0;
- KeReleaseSpinLock(&ports_lock_, old_irql);
- }
- void ClientConnection::RegisterFilterDevice(ULONG com_number, WDFDEVICE device) {
- KIRQL old_irql;
- KeAcquireSpinLock(&ports_lock_, &old_irql);
- if (ports_count_ < 256) {
- PDEVICE_CONTEXT ctx = DeviceGetContext(device);
- ports_table_[ports_count_].ComNumber = com_number;
- ports_table_[ports_count_].Context = ctx;
- ports_count_++;
- ctx->ComNumber = com_number;
- ctx->MonitoringEnabled = FALSE;
- ctx->WdfDevice = device;
- }
- KeReleaseSpinLock(&ports_lock_, old_irql);
- }
- void ClientConnection::UnregisterFilterDevice(ULONG com_number) {
- KIRQL old_irql;
- KeAcquireSpinLock(&ports_lock_, &old_irql);
- for (ULONG i = 0; i < ports_count_; ++i) {
- if (ports_table_[i].ComNumber == com_number) {
- // 移动最后一个元素到当前位置
- PDEVICE_CONTEXT ctx = ports_table_[i].Context;
- if (ctx && ctx->RingBuffer) {
- EventRingBuffer* ring = (EventRingBuffer*)ctx->RingBuffer;
- ring->Cleanup();
- ExFreePoolWithTag(ring, 'RBCK');
- ctx->RingBuffer = nullptr;
- }
- ports_table_[i] = ports_table_[ports_count_ - 1];
- ports_count_--;
- break;
- }
- }
- KeReleaseSpinLock(&ports_lock_, old_irql);
- }
- PDEVICE_CONTEXT ClientConnection::FindPortContext(ULONG com_number) {
- PDEVICE_CONTEXT result = nullptr;
- KIRQL old_irql;
- KeAcquireSpinLock(&ports_lock_, &old_irql);
- for (ULONG i = 0; i < ports_count_; ++i) {
- if (ports_table_[i].ComNumber == com_number) {
- result = ports_table_[i].Context;
- break;
- }
- }
- KeReleaseSpinLock(&ports_lock_, old_irql);
- return result;
- }
- NTSTATUS ClientConnection::HandleRegisterCallback() {
- callback_registered_ = TRUE;
- return STATUS_SUCCESS;
- }
- NTSTATUS ClientConnection::HandleAttachPort(ULONG com_number) {
- PDEVICE_CONTEXT ctx = FindPortContext(com_number);
- if (!ctx) {
- return STATUS_DEVICE_DOES_NOT_EXIST;
- }
- // 如果未分配环形缓冲,先分配
- if (!ctx->RingBuffer) {
- EventRingBuffer* ring = (EventRingBuffer*)ExAllocatePool2(
- POOL_FLAG_NON_PAGED, sizeof(EventRingBuffer), 'RBCK');
- if (!ring) {
- return STATUS_INSUFFICIENT_RESOURCES;
- }
- // placement new 等价:手动调用构造
- RtlZeroMemory(ring, sizeof(EventRingBuffer));
- NTSTATUS status = ring->Initialize();
- if (!NT_SUCCESS(status)) {
- ring->Cleanup();
- ExFreePoolWithTag(ring, 'RBCK');
- return status;
- }
- ctx->RingBuffer = ring;
- }
- // 推入 OP_OPEN 事件(序列号由全局计数器递增)
- EventRingBuffer* ring = (EventRingBuffer*)ctx->RingBuffer;
- static LONG seq = 0;
- LONG cur = InterlockedIncrement(&seq);
- ring->Push((ULONG)cur, 0.0, com_number, COMMKIT_OP_OPEN, 0, nullptr);
- ctx->MonitoringEnabled = TRUE;
- return STATUS_SUCCESS;
- }
- NTSTATUS ClientConnection::HandleDetachPort(ULONG com_number) {
- PDEVICE_CONTEXT ctx = FindPortContext(com_number);
- if (!ctx) {
- return STATUS_DEVICE_DOES_NOT_EXIST;
- }
- ctx->MonitoringEnabled = FALSE;
- // 推入 OP_CLOSE 事件
- if (ctx->RingBuffer) {
- EventRingBuffer* ring = (EventRingBuffer*)ctx->RingBuffer;
- static LONG seq = 0;
- LONG cur = InterlockedIncrement(&seq);
- ring->Push((ULONG)cur, 0.0, com_number, COMMKIT_OP_CLOSE, 0, nullptr);
- }
- return STATUS_SUCCESS;
- }
- NTSTATUS ClientConnection::HandleWritePort(ULONG com_number, PVOID data, ULONG len) {
- UNREFERENCED_PARAMETER(data);
- UNREFERENCED_PARAMETER(len);
- // 简化实现:直接调用下层串口的 Write IRP
- // 完整实现需要查找端口上下文,构造 IRP 发送给下层设备
- PDEVICE_CONTEXT ctx = FindPortContext(com_number);
- if (!ctx) {
- return STATUS_DEVICE_DOES_NOT_EXIST;
- }
- // 注:完整的写数据流通过过滤驱动 IRP_MJ_WRITE 派遣完成
- // 这里仅返回成功;实际数据发送由用户态通过 CreateFile(COMx) 直接写入
- return STATUS_SUCCESS;
- }
- NTSTATUS ClientConnection::HandleReadPort(ULONG com_number, PVOID data, ULONG len) {
- UNREFERENCED_PARAMETER(data);
- UNREFERENCED_PARAMETER(len);
- PDEVICE_CONTEXT ctx = FindPortContext(com_number);
- if (!ctx) {
- return STATUS_DEVICE_DOES_NOT_EXIST;
- }
- return STATUS_SUCCESS;
- }
- NTSTATUS ClientConnection::HandleReadEvents(PVOID out_buf, ULONG out_size, PULONG returned) {
- *returned = 0;
- if (!callback_registered_) {
- return STATUS_DEVICE_NOT_READY;
- }
- PCOMMKIT_EVENT events = (PCOMMKIT_EVENT)out_buf;
- ULONG max_count = out_size / sizeof(COMMKIT_EVENT);
- if (max_count == 0) {
- return STATUS_BUFFER_TOO_SMALL;
- }
- ULONG total_popped = 0;
- KIRQL old_irql;
- KeAcquireSpinLock(&ports_lock_, &old_irql);
- for (ULONG i = 0; i < ports_count_ && total_popped < max_count; ++i) {
- PDEVICE_CONTEXT ctx = ports_table_[i].Context;
- if (!ctx || !ctx->RingBuffer || !ctx->MonitoringEnabled) {
- continue;
- }
- EventRingBuffer* ring = (EventRingBuffer*)ctx->RingBuffer;
- LONG popped = ring->PopBatch(events + total_popped, max_count - total_popped);
- total_popped += (ULONG)popped;
- }
- KeReleaseSpinLock(&ports_lock_, old_irql);
- *returned = total_popped * sizeof(COMMKIT_EVENT);
- return STATUS_SUCCESS;
- }
- NTSTATUS ClientConnection::HandleFreeAll() {
- KIRQL old_irql;
- KeAcquireSpinLock(&ports_lock_, &old_irql);
- for (ULONG i = 0; i < ports_count_; ++i) {
- PDEVICE_CONTEXT ctx = ports_table_[i].Context;
- if (ctx) {
- ctx->MonitoringEnabled = FALSE;
- if (ctx->RingBuffer) {
- ((EventRingBuffer*)ctx->RingBuffer)->Clear();
- }
- }
- }
- KeReleaseSpinLock(&ports_lock_, old_irql);
- callback_registered_ = FALSE;
- return STATUS_SUCCESS;
- }
- } // namespace commkit_driver
|