| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330 |
- // MonitorManager.cpp - 管理器实现
- #include "pch.h"
- #include "MonitorManager.h"
- #include "Logger.h"
- #include "ErrorStore.h"
- #include <shellapi.h>
- namespace commkit {
- // 驱动服务名(与 INF 中匹配)
- static const wchar_t* kDriverServiceName = L"CommModifyKit";
- // 驱动文件路径(相对 %SystemRoot%\System32\drivers\)
- static const wchar_t* kDriverBinaryPath = L"System32\\drivers\\CommModifyKit.sys";
- MonitorManager::MonitorManager() {}
- MonitorManager::~MonitorManager() {
- FreeAll();
- }
- MonitorManager& GetMonitorManager() {
- static MonitorManager instance;
- return instance;
- }
- bool MonitorManager::IsElevated() const {
- // 通过检查进程 token 是否在管理员组来判断
- BOOL is_admin = FALSE;
- HANDLE token = nullptr;
- if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token)) {
- TOKEN_ELEVATION elevation;
- DWORD size = sizeof(elevation);
- if (GetTokenInformation(token, TokenElevation, &elevation, sizeof(elevation), &size)) {
- is_admin = elevation.TokenIsElevated;
- }
- CloseHandle(token);
- }
- return is_admin != FALSE;
- }
- void MonitorManager::SetLastError(int code) const {
- ErrorStore::Set(code);
- }
- bool MonitorManager::EnsureDriverReady() {
- OutputDebugStringA("[MonitorManager::EnsureDriverReady] enter");
- // 1. 检查管理员权限(首次安装需管理员,对应错误码 -254)
- if (!IsElevated()) {
- LOG_ERROR("Process not elevated; first-time install requires admin");
- SetLastError(-254);
- OutputDebugStringA("[MonitorManager::EnsureDriverReady] not elevated");
- return false;
- }
- OutputDebugStringA("[MonitorManager::EnsureDriverReady] elevated check passed");
- // 2. 检查驱动服务是否已存在并运行
- OutputDebugStringA("[MonitorManager::EnsureDriverReady] calling OpenSCManager...");
- SC_HANDLE scm = OpenSCManagerW(nullptr, nullptr, SC_MANAGER_ALL_ACCESS);
- if (!scm) {
- DWORD err = ::GetLastError();
- LOG_ERROR("OpenSCManager failed, error=" + std::to_string(err));
- SetLastError(-241); // 安装驱动失败
- OutputDebugStringA("[MonitorManager::EnsureDriverReady] OpenSCManager FAILED");
- return false;
- }
- OutputDebugStringA("[MonitorManager::EnsureDriverReady] OpenSCManager succeeded");
- OutputDebugStringA("[MonitorManager::EnsureDriverReady] calling OpenService...");
- SC_HANDLE svc = OpenServiceW(scm, kDriverServiceName, SERVICE_ALL_ACCESS);
- if (!svc) {
- // 服务不存在:尝试创建并启动
- DWORD err = ::GetLastError();
- OutputDebugStringA("[MonitorManager::EnsureDriverReady] OpenService FAILED, creating service...");
- wchar_t sys_dir[MAX_PATH] = {0};
- GetSystemDirectoryW(sys_dir, MAX_PATH);
- std::wstring full_path = std::wstring(sys_dir) + L"\\drivers\\CommModifyKit.sys";
- svc = CreateServiceW(
- scm, kDriverServiceName, kDriverServiceName,
- SERVICE_ALL_ACCESS, SERVICE_KERNEL_DRIVER,
- SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL,
- full_path.c_str(),
- nullptr, nullptr, nullptr, nullptr, nullptr);
- if (!svc) {
- err = ::GetLastError();
- LOG_ERROR("CreateService failed, error=" + std::to_string(err));
- CloseServiceHandle(scm);
- SetLastError(-241); // 安装驱动失败
- OutputDebugStringA("[MonitorManager::EnsureDriverReady] CreateService FAILED");
- return false;
- }
- LOG_INFO("Driver service created");
- OutputDebugStringA("[MonitorManager::EnsureDriverReady] CreateService succeeded");
- }
- OutputDebugStringA("[MonitorManager::EnsureDriverReady] service handle acquired");
- // 3. 启动服务(如果未运行)
- SERVICE_STATUS status = {0};
- if (QueryServiceStatus(svc, &status)) {
- if (status.dwCurrentState != SERVICE_RUNNING) {
- OutputDebugStringA("[MonitorManager::EnsureDriverReady] service not running, checking driver file...");
- // 检查驱动文件是否存在,避免 StartServiceW 因 SCM 超时阻塞 30 秒
- wchar_t sys_dir[MAX_PATH] = {0};
- GetSystemDirectoryW(sys_dir, MAX_PATH);
- std::wstring driver_path = std::wstring(sys_dir) + L"\\drivers\\CommModifyKit.sys";
- DWORD attr = GetFileAttributesW(driver_path.c_str());
- if (attr == INVALID_FILE_ATTRIBUTES || (attr & FILE_ATTRIBUTE_DIRECTORY)) {
- LOG_ERROR("Driver file not found: CommModifyKit.sys (expected in System32\\drivers\\)");
- CloseServiceHandle(svc);
- CloseServiceHandle(scm);
- SetLastError(-244); // 驱动文件
- OutputDebugStringA("[MonitorManager::EnsureDriverReady] driver file not found");
- return false;
- }
- OutputDebugStringA("[MonitorManager::EnsureDriverReady] driver file exists, calling StartService...");
- if (StartServiceW(svc, 0, nullptr)) {
- LOG_INFO("Driver service started");
- OutputDebugStringA("[MonitorManager::EnsureDriverReady] StartService succeeded");
- } else {
- DWORD err = ::GetLastError();
- if (err != ERROR_SERVICE_ALREADY_RUNNING) {
- LOG_ERROR("StartService failed, error=" + std::to_string(err));
- CloseServiceHandle(svc);
- CloseServiceHandle(scm);
- SetLastError(-253); // 启动驱动服务失败
- OutputDebugStringA("[MonitorManager::EnsureDriverReady] StartService FAILED");
- return false;
- }
- }
- } else {
- OutputDebugStringA("[MonitorManager::EnsureDriverReady] service already running");
- }
- }
- CloseServiceHandle(svc);
- CloseServiceHandle(scm);
- OutputDebugStringA("[MonitorManager::EnsureDriverReady] complete, returning true");
- return true;
- }
- bool MonitorManager::InitMonitor(const std::wstring& key, TOnData callback) {
- std::lock_guard<std::mutex> lock(mutex_);
- // 启用文件日志,便于诊断(输出到 %TEMP%\CommModifyKit.log)
- Logger::Instance().EnableFileOutput(true);
- Logger::Instance().SetLevel(Logger::Level::Debug);
- OutputDebugStringA("[MonitorManager::InitMonitor] enter");
- if (initialized_) {
- // 已初始化:视为成功
- SetLastError(0);
- OutputDebugStringA("[MonitorManager::InitMonitor] already initialized");
- return true;
- }
- if (!callback) {
- LOG_ERROR("InitMonitor: callback is null");
- SetLastError(-1);
- OutputDebugStringA("[MonitorManager::InitMonitor] callback is null");
- return false;
- }
- // 校验 key(占位:非空且长度>0 即可)
- if (key.empty()) {
- LOG_ERROR("InitMonitor: key is empty");
- SetLastError(-252); // 请检查 Key 是否有效
- OutputDebugStringA("[MonitorManager::InitMonitor] key is empty");
- return false;
- }
- key_ = key;
- callback_ = callback;
- // 1. 检查并启动驱动服务(若未安装则创建)
- OutputDebugStringA("[MonitorManager::InitMonitor] calling EnsureDriverReady...");
- if (!EnsureDriverReady()) {
- // 错误码已在 EnsureDriverReady 中设置
- OutputDebugStringA("[MonitorManager::InitMonitor] EnsureDriverReady FAILED");
- return false;
- }
- OutputDebugStringA("[MonitorManager::InitMonitor] EnsureDriverReady succeeded");
- // 2. 打开驱动控制设备
- OutputDebugStringA("[MonitorManager::InitMonitor] opening driver device...");
- if (!driver_client_.Open()) {
- LOG_ERROR("InitMonitor: failed to open driver device");
- SetLastError(-244); // 驱动文件
- OutputDebugStringA("[MonitorManager::InitMonitor] driver_client_.Open FAILED");
- return false;
- }
- OutputDebugStringA("[MonitorManager::InitMonitor] driver device opened");
- // 3. 注册回调管道
- if (!driver_client_.RegisterCallback()) {
- LOG_ERROR("InitMonitor: RegisterCallback failed");
- SetLastError(-243); // 其他错误
- return false;
- }
- // 4. 启动事件循环线程(读取事件 → 调用回调)
- if (!event_loop_.Start(driver_client_.GetHandle(), callback_)) {
- LOG_ERROR("InitMonitor: EventLoop start failed");
- SetLastError(-243);
- return false;
- }
- initialized_ = true;
- SetLastError(0);
- LOG_INFO("InitMonitor succeeded");
- return true;
- }
- bool MonitorManager::MonitorPort(DWORD com_number) {
- std::lock_guard<std::mutex> lock(mutex_);
- if (!initialized_) {
- LOG_ERROR("Monitor: not initialized");
- SetLastError(-1);
- return false;
- }
- if (attached_ports_.count(com_number) > 0) {
- // 已绑定:视为成功
- SetLastError(0);
- return true;
- }
- if (!driver_client_.AttachPort(com_number)) {
- LOG_ERROR("Monitor: AttachPort failed for COM" + std::to_string(com_number));
- SetLastError(-255); // 绑定串口失败
- return false;
- }
- attached_ports_.insert(com_number);
- SetLastError(0);
- LOG_INFO("Monitor: attached COM" + std::to_string(com_number));
- return true;
- }
- bool MonitorManager::StopPort(DWORD com_number) {
- std::lock_guard<std::mutex> lock(mutex_);
- if (!initialized_) {
- LOG_ERROR("Stop: not initialized");
- SetLastError(-1);
- return false;
- }
- if (!driver_client_.DetachPort(com_number)) {
- LOG_ERROR("Stop: DetachPort failed for COM" + std::to_string(com_number));
- SetLastError(-243);
- return false;
- }
- attached_ports_.erase(com_number);
- SetLastError(0);
- LOG_INFO("Stop: detached COM" + std::to_string(com_number));
- return true;
- }
- bool MonitorManager::WriteData(DWORD com_number, const char* buffer, int len) {
- std::lock_guard<std::mutex> lock(mutex_);
- if (!initialized_) {
- LOG_ERROR("WriteData: not initialized");
- SetLastError(-1);
- return false;
- }
- if (!driver_client_.WritePort(com_number, buffer, len)) {
- LOG_ERROR("WriteData: WritePort failed for COM" + std::to_string(com_number));
- SetLastError(4); // 串口写入失败
- return false;
- }
- SetLastError(0);
- return true;
- }
- bool MonitorManager::ReadData(DWORD com_number, const char* buffer, int len) {
- std::lock_guard<std::mutex> lock(mutex_);
- if (!initialized_) {
- LOG_ERROR("ReadData: not initialized");
- SetLastError(-1);
- return false;
- }
- if (!driver_client_.ReadPort(com_number, buffer, len)) {
- LOG_ERROR("ReadData: ReadPort failed for COM" + std::to_string(com_number));
- SetLastError(3); // 串口读取失败
- return false;
- }
- SetLastError(0);
- return true;
- }
- void MonitorManager::FreeAll() {
- std::lock_guard<std::mutex> lock(mutex_);
- if (!initialized_) {
- return;
- }
- // 1. 停止事件循环
- event_loop_.Stop();
- // 2. 通知驱动解绑所有端口
- driver_client_.FreeAll();
- // 3. 关闭驱动设备
- driver_client_.Close();
- // 4. 清空状态
- attached_ports_.clear();
- callback_ = nullptr;
- initialized_ = false;
- LOG_INFO("FreeMonitor: all resources released");
- }
- int MonitorManager::GetLastError() const {
- return ErrorStore::Get();
- }
- } // namespace commkit
|