DriverClient.cpp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. // DriverClient.cpp - 驱动通信封装实现
  2. #include "pch.h"
  3. #include "DriverClient.h"
  4. #include "Logger.h"
  5. namespace commkit {
  6. DriverClient::DriverClient() {}
  7. DriverClient::~DriverClient() {
  8. Close();
  9. }
  10. bool DriverClient::Open() {
  11. if (IsOpen()) {
  12. return true;
  13. }
  14. // 打开驱动控制设备 \\.\CommModifyKit
  15. handle_ = CreateFileW(
  16. COMMKIT_USER_DEVICE_NAME,
  17. GENERIC_READ | GENERIC_WRITE,
  18. 0,
  19. nullptr,
  20. OPEN_EXISTING,
  21. FILE_ATTRIBUTE_NORMAL,
  22. nullptr);
  23. if (handle_ == INVALID_HANDLE_VALUE) {
  24. DWORD err = ::GetLastError();
  25. LOG_ERROR("DriverClient::Open failed, Win32 error=" + std::to_string(err));
  26. return false;
  27. }
  28. LOG_INFO("DriverClient opened \\\\.\\CommModifyKit");
  29. return true;
  30. }
  31. void DriverClient::Close() {
  32. if (handle_ != INVALID_HANDLE_VALUE) {
  33. CloseHandle(handle_);
  34. handle_ = INVALID_HANDLE_VALUE;
  35. LOG_INFO("DriverClient closed");
  36. }
  37. }
  38. bool DriverClient::SyncIoctl(DWORD ioctl_code, void* in_buf, DWORD in_size,
  39. void* out_buf, DWORD out_size, DWORD* returned) {
  40. if (!IsOpen()) {
  41. LOG_ERROR("SyncIoctl: driver not open");
  42. return false;
  43. }
  44. DWORD bytes_returned = 0;
  45. BOOL ok = DeviceIoControl(
  46. handle_,
  47. ioctl_code,
  48. in_buf, in_size,
  49. out_buf, out_size,
  50. &bytes_returned,
  51. nullptr);
  52. if (!ok) {
  53. DWORD err = ::GetLastError();
  54. LOG_ERROR("SyncIoctl 0x" + std::to_string(ioctl_code) +
  55. " failed, Win32 error=" + std::to_string(err));
  56. return false;
  57. }
  58. if (returned) {
  59. *returned = bytes_returned;
  60. }
  61. return true;
  62. }
  63. bool DriverClient::RegisterCallback() {
  64. // 注册回调管道:无输入输出参数,仅通知驱动开始工作
  65. return SyncIoctl(IOCTL_COMMKIT_REGISTER_CALLBACK, nullptr, 0, nullptr, 0, nullptr);
  66. }
  67. bool DriverClient::AttachPort(DWORD com_number) {
  68. COMMKIT_PORT_REQUEST req;
  69. req.ComNumber = com_number;
  70. return SyncIoctl(IOCTL_COMMKIT_ATTACH_PORT, &req, sizeof(req), nullptr, 0, nullptr);
  71. }
  72. bool DriverClient::DetachPort(DWORD com_number) {
  73. COMMKIT_PORT_REQUEST req;
  74. req.ComNumber = com_number;
  75. return SyncIoctl(IOCTL_COMMKIT_DETACH_PORT, &req, sizeof(req), nullptr, 0, nullptr);
  76. }
  77. bool DriverClient::WritePort(DWORD com_number, const void* data, int len) {
  78. if (len < 0 || (!data && len > 0)) {
  79. return false;
  80. }
  81. // METHOD_BUFFERED:输入缓冲为 COMMKIT_DATA_REQUEST + 数据
  82. // 总长度 = 固定头部 + 数据长度(Data 字段为 1,已含 1 字节)
  83. DWORD total_size = sizeof(COMMKIT_DATA_REQUEST) - 1 + static_cast<DWORD>(len);
  84. std::vector<BYTE> buf(total_size);
  85. auto* req = reinterpret_cast<COMMKIT_DATA_REQUEST*>(buf.data());
  86. req->ComNumber = com_number;
  87. req->DataLen = static_cast<UINT32>(len);
  88. if (len > 0) {
  89. memcpy(req->Data, data, len);
  90. }
  91. return SyncIoctl(IOCTL_COMMKIT_WRITE_PORT, buf.data(), total_size, nullptr, 0, nullptr);
  92. }
  93. bool DriverClient::ReadPort(DWORD com_number, const void* data, int len) {
  94. if (len < 0) {
  95. return false;
  96. }
  97. // METHOD_BUFFERED:发起读请求,数据通过 OP_READ 事件回调上抛
  98. DWORD total_size = sizeof(COMMKIT_DATA_REQUEST) - 1 + static_cast<DWORD>(len);
  99. std::vector<BYTE> buf(total_size);
  100. auto* req = reinterpret_cast<COMMKIT_DATA_REQUEST*>(buf.data());
  101. req->ComNumber = com_number;
  102. req->DataLen = static_cast<UINT32>(len);
  103. if (len > 0 && data) {
  104. memcpy(req->Data, data, len);
  105. }
  106. return SyncIoctl(IOCTL_COMMKIT_READ_PORT, buf.data(), total_size, nullptr, 0, nullptr);
  107. }
  108. int DriverClient::ReadEvents(COMMKIT_EVENT* events_out, int max_count) {
  109. if (!IsOpen() || !events_out || max_count <= 0) {
  110. return -1;
  111. }
  112. DWORD out_size = static_cast<DWORD>(sizeof(COMMKIT_EVENT) * max_count);
  113. DWORD returned = 0;
  114. BOOL ok = DeviceIoControl(
  115. handle_,
  116. IOCTL_COMMKIT_READ_EVENTS,
  117. nullptr, 0,
  118. events_out, out_size,
  119. &returned,
  120. nullptr);
  121. if (!ok) {
  122. DWORD err = ::GetLastError();
  123. // ERROR_NO_DATA 等可视为"暂无事件",返回 0
  124. if (err == ERROR_NO_DATA) {
  125. return 0;
  126. }
  127. LOG_ERROR("ReadEvents failed, Win32 error=" + std::to_string(err));
  128. return -1;
  129. }
  130. return static_cast<int>(returned / sizeof(COMMKIT_EVENT));
  131. }
  132. bool DriverClient::FreeAll() {
  133. return SyncIoctl(IOCTL_COMMKIT_FREE_ALL, nullptr, 0, nullptr, 0, nullptr);
  134. }
  135. } // namespace commkit