| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165 |
- // DriverClient.cpp - 驱动通信封装实现
- #include "pch.h"
- #include "DriverClient.h"
- #include "Logger.h"
- namespace commkit {
- DriverClient::DriverClient() {}
- DriverClient::~DriverClient() {
- Close();
- }
- bool DriverClient::Open() {
- if (IsOpen()) {
- return true;
- }
- // 打开驱动控制设备 \\.\CommModifyKit
- handle_ = CreateFileW(
- COMMKIT_USER_DEVICE_NAME,
- GENERIC_READ | GENERIC_WRITE,
- 0,
- nullptr,
- OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL,
- nullptr);
- if (handle_ == INVALID_HANDLE_VALUE) {
- DWORD err = ::GetLastError();
- LOG_ERROR("DriverClient::Open failed, Win32 error=" + std::to_string(err));
- return false;
- }
- LOG_INFO("DriverClient opened \\\\.\\CommModifyKit");
- return true;
- }
- void DriverClient::Close() {
- if (handle_ != INVALID_HANDLE_VALUE) {
- CloseHandle(handle_);
- handle_ = INVALID_HANDLE_VALUE;
- LOG_INFO("DriverClient closed");
- }
- }
- bool DriverClient::SyncIoctl(DWORD ioctl_code, void* in_buf, DWORD in_size,
- void* out_buf, DWORD out_size, DWORD* returned) {
- if (!IsOpen()) {
- LOG_ERROR("SyncIoctl: driver not open");
- return false;
- }
- DWORD bytes_returned = 0;
- BOOL ok = DeviceIoControl(
- handle_,
- ioctl_code,
- in_buf, in_size,
- out_buf, out_size,
- &bytes_returned,
- nullptr);
- if (!ok) {
- DWORD err = ::GetLastError();
- LOG_ERROR("SyncIoctl 0x" + std::to_string(ioctl_code) +
- " failed, Win32 error=" + std::to_string(err));
- return false;
- }
- if (returned) {
- *returned = bytes_returned;
- }
- return true;
- }
- bool DriverClient::RegisterCallback() {
- // 注册回调管道:无输入输出参数,仅通知驱动开始工作
- return SyncIoctl(IOCTL_COMMKIT_REGISTER_CALLBACK, nullptr, 0, nullptr, 0, nullptr);
- }
- bool DriverClient::AttachPort(DWORD com_number) {
- COMMKIT_PORT_REQUEST req;
- req.ComNumber = com_number;
- return SyncIoctl(IOCTL_COMMKIT_ATTACH_PORT, &req, sizeof(req), nullptr, 0, nullptr);
- }
- bool DriverClient::DetachPort(DWORD com_number) {
- COMMKIT_PORT_REQUEST req;
- req.ComNumber = com_number;
- return SyncIoctl(IOCTL_COMMKIT_DETACH_PORT, &req, sizeof(req), nullptr, 0, nullptr);
- }
- bool DriverClient::WritePort(DWORD com_number, const void* data, int len) {
- if (len < 0 || (!data && len > 0)) {
- return false;
- }
- // METHOD_BUFFERED:输入缓冲为 COMMKIT_DATA_REQUEST + 数据
- // 总长度 = 固定头部 + 数据长度(Data 字段为 1,已含 1 字节)
- DWORD total_size = sizeof(COMMKIT_DATA_REQUEST) - 1 + static_cast<DWORD>(len);
- std::vector<BYTE> buf(total_size);
- auto* req = reinterpret_cast<COMMKIT_DATA_REQUEST*>(buf.data());
- req->ComNumber = com_number;
- req->DataLen = static_cast<UINT32>(len);
- if (len > 0) {
- memcpy(req->Data, data, len);
- }
- return SyncIoctl(IOCTL_COMMKIT_WRITE_PORT, buf.data(), total_size, nullptr, 0, nullptr);
- }
- bool DriverClient::ReadPort(DWORD com_number, const void* data, int len) {
- if (len < 0) {
- return false;
- }
- // METHOD_BUFFERED:发起读请求,数据通过 OP_READ 事件回调上抛
- DWORD total_size = sizeof(COMMKIT_DATA_REQUEST) - 1 + static_cast<DWORD>(len);
- std::vector<BYTE> buf(total_size);
- auto* req = reinterpret_cast<COMMKIT_DATA_REQUEST*>(buf.data());
- req->ComNumber = com_number;
- req->DataLen = static_cast<UINT32>(len);
- if (len > 0 && data) {
- memcpy(req->Data, data, len);
- }
- return SyncIoctl(IOCTL_COMMKIT_READ_PORT, buf.data(), total_size, nullptr, 0, nullptr);
- }
- int DriverClient::ReadEvents(COMMKIT_EVENT* events_out, int max_count) {
- if (!IsOpen() || !events_out || max_count <= 0) {
- return -1;
- }
- DWORD out_size = static_cast<DWORD>(sizeof(COMMKIT_EVENT) * max_count);
- DWORD returned = 0;
- BOOL ok = DeviceIoControl(
- handle_,
- IOCTL_COMMKIT_READ_EVENTS,
- nullptr, 0,
- events_out, out_size,
- &returned,
- nullptr);
- if (!ok) {
- DWORD err = ::GetLastError();
- // ERROR_NO_DATA 等可视为"暂无事件",返回 0
- if (err == ERROR_NO_DATA) {
- return 0;
- }
- LOG_ERROR("ReadEvents failed, Win32 error=" + std::to_string(err));
- return -1;
- }
- return static_cast<int>(returned / sizeof(COMMKIT_EVENT));
- }
- bool DriverClient::FreeAll() {
- return SyncIoctl(IOCTL_COMMKIT_FREE_ALL, nullptr, 0, nullptr, 0, nullptr);
- }
- } // namespace commkit
|