MonitorManager.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326
  1. // MonitorManager.cpp - 管理器实现
  2. #include "pch.h"
  3. #include "MonitorManager.h"
  4. #include "Logger.h"
  5. #include "ErrorStore.h"
  6. #include <shellapi.h>
  7. namespace commkit {
  8. // 驱动服务名(与 INF 中匹配)
  9. static const wchar_t* kDriverServiceName = L"CommModifyKit";
  10. // 驱动文件路径(相对 %SystemRoot%\System32\drivers\)
  11. static const wchar_t* kDriverBinaryPath = L"System32\\drivers\\CommModifyKit.sys";
  12. MonitorManager::MonitorManager() {}
  13. MonitorManager::~MonitorManager() {
  14. FreeAll();
  15. }
  16. MonitorManager& GetMonitorManager() {
  17. static MonitorManager instance;
  18. return instance;
  19. }
  20. bool MonitorManager::IsElevated() const {
  21. // 通过检查进程 token 是否在管理员组来判断
  22. BOOL is_admin = FALSE;
  23. HANDLE token = nullptr;
  24. if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token)) {
  25. TOKEN_ELEVATION elevation;
  26. DWORD size = sizeof(elevation);
  27. if (GetTokenInformation(token, TokenElevation, &elevation, sizeof(elevation), &size)) {
  28. is_admin = elevation.TokenIsElevated;
  29. }
  30. CloseHandle(token);
  31. }
  32. return is_admin != FALSE;
  33. }
  34. void MonitorManager::SetLastError(int code) const {
  35. ErrorStore::Set(code);
  36. }
  37. bool MonitorManager::EnsureDriverReady() {
  38. OutputDebugStringA("[MonitorManager::EnsureDriverReady] enter");
  39. // 1. 检查管理员权限(首次安装需管理员,对应错误码 -254)
  40. if (!IsElevated()) {
  41. LOG_ERROR("Process not elevated; first-time install requires admin");
  42. SetLastError(-254);
  43. OutputDebugStringA("[MonitorManager::EnsureDriverReady] not elevated");
  44. return false;
  45. }
  46. OutputDebugStringA("[MonitorManager::EnsureDriverReady] elevated check passed");
  47. // 2. 检查驱动服务是否已存在并运行
  48. OutputDebugStringA("[MonitorManager::EnsureDriverReady] calling OpenSCManager...");
  49. SC_HANDLE scm = OpenSCManagerW(nullptr, nullptr, SC_MANAGER_ALL_ACCESS);
  50. if (!scm) {
  51. DWORD err = ::GetLastError();
  52. LOG_ERROR("OpenSCManager failed, error=" + std::to_string(err));
  53. SetLastError(-241); // 安装驱动失败
  54. OutputDebugStringA("[MonitorManager::EnsureDriverReady] OpenSCManager FAILED");
  55. return false;
  56. }
  57. OutputDebugStringA("[MonitorManager::EnsureDriverReady] OpenSCManager succeeded");
  58. OutputDebugStringA("[MonitorManager::EnsureDriverReady] calling OpenService...");
  59. SC_HANDLE svc = OpenServiceW(scm, kDriverServiceName, SERVICE_ALL_ACCESS);
  60. if (!svc) {
  61. // 服务不存在:尝试创建并启动
  62. DWORD err = ::GetLastError();
  63. OutputDebugStringA("[MonitorManager::EnsureDriverReady] OpenService FAILED, creating service...");
  64. wchar_t sys_dir[MAX_PATH] = {0};
  65. GetSystemDirectoryW(sys_dir, MAX_PATH);
  66. std::wstring full_path = std::wstring(sys_dir) + L"\\drivers\\CommModifyKit.sys";
  67. svc = CreateServiceW(
  68. scm, kDriverServiceName, kDriverServiceName,
  69. SERVICE_ALL_ACCESS, SERVICE_KERNEL_DRIVER,
  70. SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL,
  71. full_path.c_str(),
  72. nullptr, nullptr, nullptr, nullptr, nullptr);
  73. if (!svc) {
  74. err = ::GetLastError();
  75. LOG_ERROR("CreateService failed, error=" + std::to_string(err));
  76. CloseServiceHandle(scm);
  77. SetLastError(-241); // 安装驱动失败
  78. OutputDebugStringA("[MonitorManager::EnsureDriverReady] CreateService FAILED");
  79. return false;
  80. }
  81. LOG_INFO("Driver service created");
  82. OutputDebugStringA("[MonitorManager::EnsureDriverReady] CreateService succeeded");
  83. }
  84. OutputDebugStringA("[MonitorManager::EnsureDriverReady] service handle acquired");
  85. // 3. 启动服务(如果未运行)
  86. SERVICE_STATUS status = {0};
  87. if (QueryServiceStatus(svc, &status)) {
  88. if (status.dwCurrentState != SERVICE_RUNNING) {
  89. OutputDebugStringA("[MonitorManager::EnsureDriverReady] service not running, checking driver file...");
  90. // 检查驱动文件是否存在,避免 StartServiceW 因 SCM 超时阻塞 30 秒
  91. wchar_t sys_dir[MAX_PATH] = {0};
  92. GetSystemDirectoryW(sys_dir, MAX_PATH);
  93. std::wstring driver_path = std::wstring(sys_dir) + L"\\drivers\\CommModifyKit.sys";
  94. DWORD attr = GetFileAttributesW(driver_path.c_str());
  95. if (attr == INVALID_FILE_ATTRIBUTES || (attr & FILE_ATTRIBUTE_DIRECTORY)) {
  96. LOG_ERROR("Driver file not found: CommModifyKit.sys (expected in System32\\drivers\\)");
  97. CloseServiceHandle(svc);
  98. CloseServiceHandle(scm);
  99. SetLastError(-244); // 驱动文件
  100. OutputDebugStringA("[MonitorManager::EnsureDriverReady] driver file not found");
  101. return false;
  102. }
  103. OutputDebugStringA("[MonitorManager::EnsureDriverReady] driver file exists, calling StartService...");
  104. if (StartServiceW(svc, 0, nullptr)) {
  105. LOG_INFO("Driver service started");
  106. OutputDebugStringA("[MonitorManager::EnsureDriverReady] StartService succeeded");
  107. } else {
  108. DWORD err = ::GetLastError();
  109. if (err != ERROR_SERVICE_ALREADY_RUNNING) {
  110. LOG_ERROR("StartService failed, error=" + std::to_string(err));
  111. CloseServiceHandle(svc);
  112. CloseServiceHandle(scm);
  113. SetLastError(-253); // 启动驱动服务失败
  114. OutputDebugStringA("[MonitorManager::EnsureDriverReady] StartService FAILED");
  115. return false;
  116. }
  117. }
  118. } else {
  119. OutputDebugStringA("[MonitorManager::EnsureDriverReady] service already running");
  120. }
  121. }
  122. CloseServiceHandle(svc);
  123. CloseServiceHandle(scm);
  124. OutputDebugStringA("[MonitorManager::EnsureDriverReady] complete, returning true");
  125. return true;
  126. }
  127. bool MonitorManager::InitMonitor(const std::wstring& key, TOnData callback) {
  128. std::lock_guard<std::mutex> lock(mutex_);
  129. OutputDebugStringA("[MonitorManager::InitMonitor] enter");
  130. if (initialized_) {
  131. // 已初始化:视为成功
  132. SetLastError(0);
  133. OutputDebugStringA("[MonitorManager::InitMonitor] already initialized");
  134. return true;
  135. }
  136. if (!callback) {
  137. LOG_ERROR("InitMonitor: callback is null");
  138. SetLastError(-1);
  139. OutputDebugStringA("[MonitorManager::InitMonitor] callback is null");
  140. return false;
  141. }
  142. // 校验 key(占位:非空且长度>0 即可)
  143. if (key.empty()) {
  144. LOG_ERROR("InitMonitor: key is empty");
  145. SetLastError(-252); // 请检查 Key 是否有效
  146. OutputDebugStringA("[MonitorManager::InitMonitor] key is empty");
  147. return false;
  148. }
  149. key_ = key;
  150. callback_ = callback;
  151. // 1. 检查并启动驱动服务(若未安装则创建)
  152. OutputDebugStringA("[MonitorManager::InitMonitor] calling EnsureDriverReady...");
  153. if (!EnsureDriverReady()) {
  154. // 错误码已在 EnsureDriverReady 中设置
  155. OutputDebugStringA("[MonitorManager::InitMonitor] EnsureDriverReady FAILED");
  156. return false;
  157. }
  158. OutputDebugStringA("[MonitorManager::InitMonitor] EnsureDriverReady succeeded");
  159. // 2. 打开驱动控制设备
  160. OutputDebugStringA("[MonitorManager::InitMonitor] opening driver device...");
  161. if (!driver_client_.Open()) {
  162. LOG_ERROR("InitMonitor: failed to open driver device");
  163. SetLastError(-244); // 驱动文件
  164. OutputDebugStringA("[MonitorManager::InitMonitor] driver_client_.Open FAILED");
  165. return false;
  166. }
  167. OutputDebugStringA("[MonitorManager::InitMonitor] driver device opened");
  168. // 3. 注册回调管道
  169. if (!driver_client_.RegisterCallback()) {
  170. LOG_ERROR("InitMonitor: RegisterCallback failed");
  171. SetLastError(-243); // 其他错误
  172. return false;
  173. }
  174. // 4. 启动事件循环线程(读取事件 → 调用回调)
  175. if (!event_loop_.Start(driver_client_.GetHandle(), callback_)) {
  176. LOG_ERROR("InitMonitor: EventLoop start failed");
  177. SetLastError(-243);
  178. return false;
  179. }
  180. initialized_ = true;
  181. SetLastError(0);
  182. LOG_INFO("InitMonitor succeeded");
  183. return true;
  184. }
  185. bool MonitorManager::MonitorPort(DWORD com_number) {
  186. std::lock_guard<std::mutex> lock(mutex_);
  187. if (!initialized_) {
  188. LOG_ERROR("Monitor: not initialized");
  189. SetLastError(-1);
  190. return false;
  191. }
  192. if (attached_ports_.count(com_number) > 0) {
  193. // 已绑定:视为成功
  194. SetLastError(0);
  195. return true;
  196. }
  197. if (!driver_client_.AttachPort(com_number)) {
  198. LOG_ERROR("Monitor: AttachPort failed for COM" + std::to_string(com_number));
  199. SetLastError(-255); // 绑定串口失败
  200. return false;
  201. }
  202. attached_ports_.insert(com_number);
  203. SetLastError(0);
  204. LOG_INFO("Monitor: attached COM" + std::to_string(com_number));
  205. return true;
  206. }
  207. bool MonitorManager::StopPort(DWORD com_number) {
  208. std::lock_guard<std::mutex> lock(mutex_);
  209. if (!initialized_) {
  210. LOG_ERROR("Stop: not initialized");
  211. SetLastError(-1);
  212. return false;
  213. }
  214. if (!driver_client_.DetachPort(com_number)) {
  215. LOG_ERROR("Stop: DetachPort failed for COM" + std::to_string(com_number));
  216. SetLastError(-243);
  217. return false;
  218. }
  219. attached_ports_.erase(com_number);
  220. SetLastError(0);
  221. LOG_INFO("Stop: detached COM" + std::to_string(com_number));
  222. return true;
  223. }
  224. bool MonitorManager::WriteData(DWORD com_number, const char* buffer, int len) {
  225. std::lock_guard<std::mutex> lock(mutex_);
  226. if (!initialized_) {
  227. LOG_ERROR("WriteData: not initialized");
  228. SetLastError(-1);
  229. return false;
  230. }
  231. if (!driver_client_.WritePort(com_number, buffer, len)) {
  232. LOG_ERROR("WriteData: WritePort failed for COM" + std::to_string(com_number));
  233. SetLastError(4); // 串口写入失败
  234. return false;
  235. }
  236. SetLastError(0);
  237. return true;
  238. }
  239. bool MonitorManager::ReadData(DWORD com_number, const char* buffer, int len) {
  240. std::lock_guard<std::mutex> lock(mutex_);
  241. if (!initialized_) {
  242. LOG_ERROR("ReadData: not initialized");
  243. SetLastError(-1);
  244. return false;
  245. }
  246. if (!driver_client_.ReadPort(com_number, buffer, len)) {
  247. LOG_ERROR("ReadData: ReadPort failed for COM" + std::to_string(com_number));
  248. SetLastError(3); // 串口读取失败
  249. return false;
  250. }
  251. SetLastError(0);
  252. return true;
  253. }
  254. void MonitorManager::FreeAll() {
  255. std::lock_guard<std::mutex> lock(mutex_);
  256. if (!initialized_) {
  257. return;
  258. }
  259. // 1. 停止事件循环
  260. event_loop_.Stop();
  261. // 2. 通知驱动解绑所有端口
  262. driver_client_.FreeAll();
  263. // 3. 关闭驱动设备
  264. driver_client_.Close();
  265. // 4. 清空状态
  266. attached_ports_.clear();
  267. callback_ = nullptr;
  268. initialized_ = false;
  269. LOG_INFO("FreeMonitor: all resources released");
  270. }
  271. int MonitorManager::GetLastError() const {
  272. return ErrorStore::Get();
  273. }
  274. } // namespace commkit