// CommKitIoctl.h - 用户态/内核态共享的 IOCTL 码与数据结构定义 // 被 dll/ 与 driver/ 共同包含,确保双方契约一致 #pragma once // 内核模式:CTL_CODE 由 wdm.h/ntddk.h 提供 // 用户模式:CTL_CODE 由 winioctl.h 提供 #ifndef _NTDDK_ #include #endif // ============================================================================ // 用户态 CreateFile 使用的设备名(\\.\CommModifyKit) // ============================================================================ #define COMMKIT_USER_DEVICE_NAME L"\\\\.\\CommModifyKit" #define COMMKIT_DEVICE_DOS_NAME L"\\DosDevices\\CommModifyKit" #define COMMKIT_DEVICE_NAME L"\\Device\\CommModifyKit" // ============================================================================ // IOCTL 设备类型与控制码 // 设备类型 0x8000 表示用户自定义设备类型 // ============================================================================ #define COMMKIT_DEVICE_TYPE 0x8000 // InitMonitor 调用:注册用户态回调管道(DLL 启动事件循环线程) #define IOCTL_COMMKIT_REGISTER_CALLBACK \ CTL_CODE(COMMKIT_DEVICE_TYPE, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS) // Monitor 调用:绑定(启用监控)指定串口编号 #define IOCTL_COMMKIT_ATTACH_PORT \ CTL_CODE(COMMKIT_DEVICE_TYPE, 0x801, METHOD_BUFFERED, FILE_ANY_ACCESS) // Stop 调用:解绑(停止监控)指定串口编号 #define IOCTL_COMMKIT_DETACH_PORT \ CTL_CODE(COMMKIT_DEVICE_TYPE, 0x802, METHOD_BUFFERED, FILE_ANY_ACCESS) // SetWrite_Data 调用:向指定串口下发写 IRP(数据由驱动透传给下层串口) // 使用 METHOD_BUFFERED:COMMKIT_DATA_REQUEST + 变长 Data 在同一个 SystemBuffer 中传递, // 驱动通过 WdfRequestRetrieveInputBuffer 即可获取完整数据(含柔性数组 Data[]) #define IOCTL_COMMKIT_WRITE_PORT \ CTL_CODE(COMMKIT_DEVICE_TYPE, 0x803, METHOD_BUFFERED, FILE_WRITE_DATA) // SetRead_Data 调用:从指定串口发起异步读请求(结果通过回调 OP_READ 上抛) // 使用 METHOD_BUFFERED:与驱动访问方式一致,避免 METHOD_IN_DIRECT 语义下 // SystemBuffer 不复制回用户缓冲导致数据丢失 #define IOCTL_COMMKIT_READ_PORT \ CTL_CODE(COMMKIT_DEVICE_TYPE, 0x804, METHOD_BUFFERED, FILE_READ_DATA) // DLL 工作线程调用:从驱动批量读取捕获的事件(阻塞或返回 0 条) #define IOCTL_COMMKIT_READ_EVENTS \ CTL_CODE(COMMKIT_DEVICE_TYPE, 0x805, METHOD_OUT_DIRECT, FILE_READ_DATA) // FreeMonitor 调用:解绑所有端口、清空事件队列(不卸载驱动服务) #define IOCTL_COMMKIT_FREE_ALL \ CTL_CODE(COMMKIT_DEVICE_TYPE, 0x806, METHOD_BUFFERED, FILE_ANY_ACCESS) // ============================================================================ // 单条事件结构(内核态 → 用户态) // 注意:字段对齐使用 1 字节 pack,便于跨位数(WOW64)传递 // TimeStamp: 100ns 单位,从 1601-01-01 起算(与 FILETIME 相同) // ============================================================================ #define COMMKIT_MAX_DATA 4096 // 单条事件最大数据字节数 #define COMMKIT_EVENT_BATCH 16 // 单次 IOCTL 最多返回事件数 #define COMMKIT_RING_CAPACITY 256 // 内核态每端口环形缓冲容量 #pragma pack(push, 1) typedef struct _COMMKIT_EVENT { INT32 Sequence; // 递增序列号(每次回调递增) UINT64 TimeStamp; // 100ns 单位时间戳(0=用当前时间) UINT32 ComNumber; // 串口编号(COM n 的 n) UINT32 EventType; // 事件类型(见 CommKitEvents.h) UINT32 DataSize; // 有效数据字节数(<= COMMKIT_MAX_DATA) CHAR Data[COMMKIT_MAX_DATA]; // 内联数据缓冲 } COMMKIT_EVENT, *PCOMMKIT_EVENT; #pragma pack(pop) // IOCTL_COMMKIT_ATTACH_PORT / DETACH_PORT 输入参数 #pragma pack(push, 1) typedef struct _COMMKIT_PORT_REQUEST { UINT32 ComNumber; // 串口编号 } COMMKIT_PORT_REQUEST, *PCOMMKIT_PORT_REQUEST; #pragma pack(pop) // IOCTL_COMMKIT_WRITE_PORT / READ_PORT 输入参数(METHOD_BUFFERED,Data 为变长柔性数组) #pragma pack(push, 1) typedef struct _COMMKIT_DATA_REQUEST { UINT32 ComNumber; // 串口编号 UINT32 DataLen; // 数据长度(字节数) CHAR Data[1]; // 变长数据,实际长度由 DataLen 决定 } COMMKIT_DATA_REQUEST, *PCOMMKIT_DATA_REQUEST; #pragma pack(pop)