MonitorManager.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330
  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. // 启用文件日志,便于诊断(输出到 %TEMP%\CommModifyKit.log)
  130. Logger::Instance().EnableFileOutput(true);
  131. Logger::Instance().SetLevel(Logger::Level::Debug);
  132. OutputDebugStringA("[MonitorManager::InitMonitor] enter");
  133. if (initialized_) {
  134. // 已初始化:视为成功
  135. SetLastError(0);
  136. OutputDebugStringA("[MonitorManager::InitMonitor] already initialized");
  137. return true;
  138. }
  139. if (!callback) {
  140. LOG_ERROR("InitMonitor: callback is null");
  141. SetLastError(-1);
  142. OutputDebugStringA("[MonitorManager::InitMonitor] callback is null");
  143. return false;
  144. }
  145. // 校验 key(占位:非空且长度>0 即可)
  146. if (key.empty()) {
  147. LOG_ERROR("InitMonitor: key is empty");
  148. SetLastError(-252); // 请检查 Key 是否有效
  149. OutputDebugStringA("[MonitorManager::InitMonitor] key is empty");
  150. return false;
  151. }
  152. key_ = key;
  153. callback_ = callback;
  154. // 1. 检查并启动驱动服务(若未安装则创建)
  155. OutputDebugStringA("[MonitorManager::InitMonitor] calling EnsureDriverReady...");
  156. if (!EnsureDriverReady()) {
  157. // 错误码已在 EnsureDriverReady 中设置
  158. OutputDebugStringA("[MonitorManager::InitMonitor] EnsureDriverReady FAILED");
  159. return false;
  160. }
  161. OutputDebugStringA("[MonitorManager::InitMonitor] EnsureDriverReady succeeded");
  162. // 2. 打开驱动控制设备
  163. OutputDebugStringA("[MonitorManager::InitMonitor] opening driver device...");
  164. if (!driver_client_.Open()) {
  165. LOG_ERROR("InitMonitor: failed to open driver device");
  166. SetLastError(-244); // 驱动文件
  167. OutputDebugStringA("[MonitorManager::InitMonitor] driver_client_.Open FAILED");
  168. return false;
  169. }
  170. OutputDebugStringA("[MonitorManager::InitMonitor] driver device opened");
  171. // 3. 注册回调管道
  172. if (!driver_client_.RegisterCallback()) {
  173. LOG_ERROR("InitMonitor: RegisterCallback failed");
  174. SetLastError(-243); // 其他错误
  175. return false;
  176. }
  177. // 4. 启动事件循环线程(读取事件 → 调用回调)
  178. if (!event_loop_.Start(driver_client_.GetHandle(), callback_)) {
  179. LOG_ERROR("InitMonitor: EventLoop start failed");
  180. SetLastError(-243);
  181. return false;
  182. }
  183. initialized_ = true;
  184. SetLastError(0);
  185. LOG_INFO("InitMonitor succeeded");
  186. return true;
  187. }
  188. bool MonitorManager::MonitorPort(DWORD com_number) {
  189. std::lock_guard<std::mutex> lock(mutex_);
  190. if (!initialized_) {
  191. LOG_ERROR("Monitor: not initialized");
  192. SetLastError(-1);
  193. return false;
  194. }
  195. if (attached_ports_.count(com_number) > 0) {
  196. // 已绑定:视为成功
  197. SetLastError(0);
  198. return true;
  199. }
  200. if (!driver_client_.AttachPort(com_number)) {
  201. LOG_ERROR("Monitor: AttachPort failed for COM" + std::to_string(com_number));
  202. SetLastError(-255); // 绑定串口失败
  203. return false;
  204. }
  205. attached_ports_.insert(com_number);
  206. SetLastError(0);
  207. LOG_INFO("Monitor: attached COM" + std::to_string(com_number));
  208. return true;
  209. }
  210. bool MonitorManager::StopPort(DWORD com_number) {
  211. std::lock_guard<std::mutex> lock(mutex_);
  212. if (!initialized_) {
  213. LOG_ERROR("Stop: not initialized");
  214. SetLastError(-1);
  215. return false;
  216. }
  217. if (!driver_client_.DetachPort(com_number)) {
  218. LOG_ERROR("Stop: DetachPort failed for COM" + std::to_string(com_number));
  219. SetLastError(-243);
  220. return false;
  221. }
  222. attached_ports_.erase(com_number);
  223. SetLastError(0);
  224. LOG_INFO("Stop: detached COM" + std::to_string(com_number));
  225. return true;
  226. }
  227. bool MonitorManager::WriteData(DWORD com_number, const char* buffer, int len) {
  228. std::lock_guard<std::mutex> lock(mutex_);
  229. if (!initialized_) {
  230. LOG_ERROR("WriteData: not initialized");
  231. SetLastError(-1);
  232. return false;
  233. }
  234. if (!driver_client_.WritePort(com_number, buffer, len)) {
  235. LOG_ERROR("WriteData: WritePort failed for COM" + std::to_string(com_number));
  236. SetLastError(4); // 串口写入失败
  237. return false;
  238. }
  239. SetLastError(0);
  240. return true;
  241. }
  242. bool MonitorManager::ReadData(DWORD com_number, const char* buffer, int len) {
  243. std::lock_guard<std::mutex> lock(mutex_);
  244. if (!initialized_) {
  245. LOG_ERROR("ReadData: not initialized");
  246. SetLastError(-1);
  247. return false;
  248. }
  249. if (!driver_client_.ReadPort(com_number, buffer, len)) {
  250. LOG_ERROR("ReadData: ReadPort failed for COM" + std::to_string(com_number));
  251. SetLastError(3); // 串口读取失败
  252. return false;
  253. }
  254. SetLastError(0);
  255. return true;
  256. }
  257. void MonitorManager::FreeAll() {
  258. std::lock_guard<std::mutex> lock(mutex_);
  259. if (!initialized_) {
  260. return;
  261. }
  262. // 1. 停止事件循环
  263. event_loop_.Stop();
  264. // 2. 通知驱动解绑所有端口
  265. driver_client_.FreeAll();
  266. // 3. 关闭驱动设备
  267. driver_client_.Close();
  268. // 4. 清空状态
  269. attached_ports_.clear();
  270. callback_ = nullptr;
  271. initialized_ = false;
  272. LOG_INFO("FreeMonitor: all resources released");
  273. }
  274. int MonitorManager::GetLastError() const {
  275. return ErrorStore::Get();
  276. }
  277. } // namespace commkit