diff --git a/src/screen_capturer/windows/screen_capturer_win.cpp b/src/screen_capturer/windows/screen_capturer_win.cpp index d3477ee..3a38256 100644 --- a/src/screen_capturer/windows/screen_capturer_win.cpp +++ b/src/screen_capturer/windows/screen_capturer_win.cpp @@ -2,23 +2,22 @@ #include -#include - -#include #include +#include #include #include #include +#include #include #include #include #include #include +#include "interactive_state.h" #include "rd_log.h" #include "screen_capturer_dxgi.h" #include "screen_capturer_gdi.h" -#include "interactive_state.h" #include "service_host.h" #include "session_helper_shared.h" #include "wgc_plugin_api.h" @@ -146,8 +145,7 @@ std::string ExtractPipeTextResponse(const std::vector& response) { bool IsTransientSecureDesktopFrameError(const std::string& error_message) { return error_message.rfind("pipe_unavailable:", 0) == 0 || - error_message.find("\"error\":\"bitblt_failed\"") != - std::string::npos; + error_message.find("\"error\":\"bitblt_failed\"") != std::string::npos; } bool ReadPipeMessage(HANDLE pipe, std::vector* response_out, @@ -266,9 +264,9 @@ bool QuerySecureDesktopServiceStatus(SecureDesktopServiceStatus* status) { status->active_session_id = json.value("active_session_id", 0xFFFFFFFFu); status->helper_running = json.value("secure_input_helper_running", false); status->interactive_stage = json.value("interactive_stage", std::string()); - const bool secure_desktop_active = json.value( - "interactive_secure_desktop_active", - json.value("secure_desktop_active", false)); + const bool secure_desktop_active = + json.value("interactive_secure_desktop_active", + json.value("secure_desktop_active", false)); status->capture_active = status->active_session_id != 0xFFFFFFFF && (secure_desktop_active || @@ -287,7 +285,8 @@ bool QuerySecureDesktopHelperFrame(DWORD session_id, int left, int top, return false; } - const std::wstring pipe_name = GetCrossDeskSecureInputHelperPipeName(session_id); + const std::wstring pipe_name = + GetCrossDeskSecureInputHelperPipeName(session_id); if (!WaitNamedPipeW(pipe_name.c_str(), kSecureDesktopHelperPipeTimeoutMs)) { if (error_out != nullptr) { *error_out = "pipe_unavailable:" + std::to_string(GetLastError()); @@ -416,10 +415,8 @@ int ScreenCapturerWin::Init(const int fps, cb_desktop_data cb) { } int ScreenCapturerWin::Destroy() { - StopSecureCaptureThread(); - running_.store(false, std::memory_order_relaxed); + Stop(); paused_.store(false, std::memory_order_relaxed); - secure_desktop_capture_active_.store(false, std::memory_order_relaxed); if (impl_) { impl_->Destroy(); impl_.reset(); @@ -585,8 +582,8 @@ void ScreenCapturerWin::StopSecureCaptureThread() { } } -bool ScreenCapturerWin::GetCurrentCaptureRegion(int* left, int* top, - int* width, int* height, +bool ScreenCapturerWin::GetCurrentCaptureRegion(int* left, int* top, int* width, + int* height, std::string* display_name) { if (left == nullptr || top == nullptr || width == nullptr || height == nullptr || display_name == nullptr) { @@ -653,11 +650,13 @@ void ScreenCapturerWin::SecureDesktopCaptureLoop() { if (service_changed || service_error_changed) { if (status.service_available) { LOG_INFO( - "Windows capturer secure desktop service available, polling session_id={}", + "Windows capturer secure desktop service available, polling " + "session_id={}", status.active_session_id); } else { LOG_WARN( - "Windows capturer secure desktop service unavailable: error={}, code={}", + "Windows capturer secure desktop service unavailable: " + "error={}, code={}", status.error, status.error_code); } last_service_available = status.service_available; @@ -665,8 +664,7 @@ void ScreenCapturerWin::SecureDesktopCaptureLoop() { } } else if (last_service_available || last_service_error != "invalid_service_status_json") { - LOG_WARN( - "Windows capturer secure desktop service status query failed"); + LOG_WARN("Windows capturer secure desktop service status query failed"); last_service_available = false; last_service_error = "invalid_service_status_json"; } @@ -677,7 +675,8 @@ void ScreenCapturerWin::SecureDesktopCaptureLoop() { status.interactive_stage != last_stage) { capture_stage_started_tick = now; LOG_INFO( - "Windows capturer secure desktop state: active={}, stage='{}', session_id={}", + "Windows capturer secure desktop state: active={}, stage='{}', " + "session_id={}", status.capture_active, status.interactive_stage, status.active_session_id); last_capture_active = status.capture_active; @@ -687,8 +686,8 @@ void ScreenCapturerWin::SecureDesktopCaptureLoop() { } if (!status.capture_active || status.active_session_id == 0xFFFFFFFF) { - std::this_thread::sleep_for(std::chrono::milliseconds( - status.service_available ? 50 : 200)); + std::this_thread::sleep_for( + std::chrono::milliseconds(status.service_available ? 50 : 200)); continue; } @@ -721,22 +720,22 @@ void ScreenCapturerWin::SecureDesktopCaptureLoop() { } else { const bool transient_error = IsTransientSecureDesktopFrameError(error_message); - const bool in_grace_period = - capture_stage_started_tick != 0 && - now - capture_stage_started_tick < kSecureDesktopTransientErrorGraceMs; - const DWORD log_interval = transient_error - ? kSecureDesktopTransientErrorLogIntervalMs - : 1000; + const bool in_grace_period = capture_stage_started_tick != 0 && + now - capture_stage_started_tick < + kSecureDesktopTransientErrorGraceMs; + const DWORD log_interval = + transient_error ? kSecureDesktopTransientErrorLogIntervalMs : 1000; if (transient_error && in_grace_period) { std::this_thread::sleep_for( std::chrono::milliseconds(frame_interval_ms)); continue; } if (now - last_error_tick >= log_interval) { - LOG_WARN( - "Windows capturer secure desktop frame query failed, stage='{}', session_id={}, error={}", - status.interactive_stage, status.active_session_id, error_message); - last_error_tick = now; + LOG_WARN( + "Windows capturer secure desktop frame query failed, stage='{}', " + "session_id={}, error={}", + status.interactive_stage, status.active_session_id, error_message); + last_error_tick = now; } } diff --git a/src/service/windows/interactive_state.h b/src/service/windows/interactive_state.h index 1c36708..8476983 100644 --- a/src/service/windows/interactive_state.h +++ b/src/service/windows/interactive_state.h @@ -12,11 +12,11 @@ inline bool IsSecureDesktopInteractionRequired( } inline bool ShouldNormalizeUnlockToUserDesktop( - bool interactive_lock_screen_visible, - const std::string& interactive_stage, bool session_locked, - bool interactive_logon_ui_visible, bool interactive_secure_desktop_active, - bool credential_ui_visible, bool password_box_visible, - bool unlock_ui_visible, const std::string& last_session_event) { + bool interactive_lock_screen_visible, const std::string& interactive_stage, + bool session_locked, bool interactive_logon_ui_visible, + bool interactive_secure_desktop_active, bool credential_ui_visible, + bool password_box_visible, bool unlock_ui_visible, + const std::string& last_session_event) { if (!interactive_lock_screen_visible && interactive_stage != "lock-screen") { return false; } diff --git a/src/service/windows/main.cpp b/src/service/windows/main.cpp index 8d88458..a8c1a5c 100644 --- a/src/service/windows/main.cpp +++ b/src/service/windows/main.cpp @@ -17,16 +17,17 @@ std::wstring GetExecutablePath() { } void PrintUsage() { - std::cout << "CrossDesk Windows service skeleton\n" - << " --service Run under the Windows Service Control Manager\n" - << " --console Run the service loop in console mode\n" - << " --install Install the service for the current executable\n" - << " --uninstall Remove the installed service\n" - << " --start Start the installed service\n" - << " --stop Stop the installed service\n" - << " --sas Ask the service to send Secure Attention Sequence\n" - << " --ping Ping the running service over named pipe IPC\n" - << " --status Query runtime status over named pipe IPC\n"; + std::cout + << "CrossDesk Windows service skeleton\n" + << " --service Run under the Windows Service Control Manager\n" + << " --console Run the service loop in console mode\n" + << " --install Install the service for the current executable\n" + << " --uninstall Remove the installed service\n" + << " --start Start the installed service\n" + << " --stop Stop the installed service\n" + << " --sas Ask the service to send Secure Attention Sequence\n" + << " --ping Ping the running service over named pipe IPC\n" + << " --status Query runtime status over named pipe IPC\n"; } } // namespace @@ -55,8 +56,7 @@ int main(int argc, char* argv[]) { } if (command == "--uninstall") { bool success = crossdesk::UninstallCrossDeskService(); - std::cout << (success ? "uninstall ok" : "uninstall failed") - << std::endl; + std::cout << (success ? "uninstall ok" : "uninstall failed") << std::endl; return success ? 0 : 1; } if (command == "--start") { diff --git a/src/service/windows/service_host.cpp b/src/service/windows/service_host.cpp index 9b5f4dc..c135f6b 100644 --- a/src/service/windows/service_host.cpp +++ b/src/service/windows/service_host.cpp @@ -1,17 +1,16 @@ #include "service_host.h" -#include - +#include #include #include #include -#include #include #include #include #include #include +#include #include #include #include @@ -26,10 +25,8 @@ namespace { using Json = nlohmann::json; -constexpr char kSecureDesktopKeyboardIpcCommandPrefix[] = - "secure-input-key:"; -constexpr char kSecureDesktopMouseIpcCommandPrefix[] = - "secure-input-mouse:"; +constexpr char kSecureDesktopKeyboardIpcCommandPrefix[] = "secure-input-key:"; +constexpr char kSecureDesktopMouseIpcCommandPrefix[] = "secure-input-mouse:"; using SendSasFunction = VOID(WINAPI*)(BOOL); @@ -231,13 +228,12 @@ std::string BuildSecureDesktopKeyboardIpcCommand(int key_code, bool is_down) { std::string BuildSecureDesktopMouseIpcCommand(int x, int y, int wheel, int flag) { std::ostringstream stream; - stream << kSecureDesktopMouseIpcCommandPrefix << x << ":" << y << ":" - << wheel << ":" << flag; + stream << kSecureDesktopMouseIpcCommandPrefix << x << ":" << y << ":" << wheel + << ":" << flag; return stream.str(); } -std::string BuildSecureInputHelperKeyboardCommand(int key_code, - bool is_down) { +std::string BuildSecureInputHelperKeyboardCommand(int key_code, bool is_down) { std::ostringstream stream; stream << kCrossDeskSecureInputKeyboardCommandPrefix << key_code << ":" << (is_down ? 1 : 0); @@ -487,15 +483,15 @@ std::string WideToUtf8(const std::wstring& value) { return {}; } - int size_needed = WideCharToMultiByte(CP_UTF8, 0, value.c_str(), -1, - nullptr, 0, nullptr, nullptr); + int size_needed = WideCharToMultiByte(CP_UTF8, 0, value.c_str(), -1, nullptr, + 0, nullptr, nullptr); if (size_needed <= 1) { return {}; } std::string result(static_cast(size_needed), '\0'); - WideCharToMultiByte(CP_UTF8, 0, value.c_str(), -1, result.data(), - size_needed, nullptr, nullptr); + WideCharToMultiByte(CP_UTF8, 0, value.c_str(), -1, result.data(), size_needed, + nullptr, nullptr); result.pop_back(); return result; } @@ -519,8 +515,7 @@ bool QuerySoftwareSasGeneration(DWORD* value_out, bool* existed_out) { DWORD value_size = sizeof(value); DWORD type = REG_DWORD; LONG result = RegQueryValueExW(key, L"SoftwareSASGeneration", nullptr, &type, - reinterpret_cast(&value), - &value_size); + reinterpret_cast(&value), &value_size); if (result == ERROR_SUCCESS && type == REG_DWORD) { *value_out = value; *existed_out = true; @@ -542,8 +537,7 @@ bool SetSoftwareSasGeneration(DWORD value) { } result = RegSetValueExW(key, L"SoftwareSASGeneration", 0, REG_DWORD, - reinterpret_cast(&value), - sizeof(value)); + reinterpret_cast(&value), sizeof(value)); RegCloseKey(key); return result == ERROR_SUCCESS; } @@ -552,8 +546,8 @@ bool RestoreSoftwareSasGeneration(DWORD original_value, bool existed_before) { HKEY key = nullptr; constexpr wchar_t kPolicyKey[] = L"Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System"; - LONG result = RegOpenKeyExW(HKEY_LOCAL_MACHINE, kPolicyKey, 0, KEY_SET_VALUE, - &key); + LONG result = + RegOpenKeyExW(HKEY_LOCAL_MACHINE, kPolicyKey, 0, KEY_SET_VALUE, &key); if (result != ERROR_SUCCESS) { return false; } @@ -580,8 +574,8 @@ SasResult SendSasNow() { return result; } - auto* send_sas = reinterpret_cast( - GetProcAddress(sas_module, "SendSAS")); + auto* send_sas = + reinterpret_cast(GetProcAddress(sas_module, "SendSAS")); if (send_sas == nullptr) { result.error = "send_sas_proc_missing"; result.error_code = GetLastError(); @@ -625,8 +619,7 @@ struct PipeSecurityAttributes { } bool Initialize() { - constexpr wchar_t kPipeSddl[] = - L"D:(A;;GA;;;SY)(A;;GA;;;BA)(A;;GRGW;;;AU)"; + constexpr wchar_t kPipeSddl[] = L"D:(A;;GA;;;SY)(A;;GA;;;BA)(A;;GRGW;;;AU)"; if (!ConvertStringSecurityDescriptorToSecurityDescriptorW( kPipeSddl, SDDL_REVISION_1, &security_descriptor_, nullptr)) { return false; @@ -654,8 +647,7 @@ struct KernelObjectSecurityAttributes { } bool Initialize() { - constexpr wchar_t kObjectSddl[] = - L"D:(A;;GA;;;SY)(A;;GA;;;BA)(A;;GA;;;AU)"; + constexpr wchar_t kObjectSddl[] = L"D:(A;;GA;;;SY)(A;;GA;;;BA)(A;;GA;;;AU)"; if (!ConvertStringSecurityDescriptorToSecurityDescriptorW( kObjectSddl, SDDL_REVISION_1, &security_descriptor_, nullptr)) { return false; @@ -726,8 +718,7 @@ DWORD WINAPI CrossDeskServiceHost::ServiceControlHandler( case SERVICE_CONTROL_SESSIONCHANGE: { DWORD session_id = 0xFFFFFFFF; if (event_data != nullptr) { - auto* session = - reinterpret_cast(event_data); + auto* session = reinterpret_cast(event_data); session_id = session->dwSessionId; } instance_->RecordSessionEvent(event_type, session_id); @@ -742,7 +733,8 @@ int CrossDeskServiceHost::RunAsService() { instance_ = this; SERVICE_TABLE_ENTRYW service_table[] = { - {const_cast(kCrossDeskServiceName), &CrossDeskServiceHost::ServiceMain}, + {const_cast(kCrossDeskServiceName), + &CrossDeskServiceHost::ServiceMain}, {nullptr, nullptr}}; if (!StartServiceCtrlDispatcherW(service_table)) { @@ -897,7 +889,8 @@ int CrossDeskServiceHost::RunServiceLoop(bool as_service) { if (console_mode_) { SetConsoleCtrlHandler(&CrossDeskServiceHost::ConsoleControlHandler, TRUE); - std::cout << "CrossDesk service skeleton running in console mode. Press Ctrl+C to stop." + std::cout << "CrossDesk service skeleton running in console mode. Press " + "Ctrl+C to stop." << std::endl; } @@ -932,10 +925,9 @@ void CrossDeskServiceHost::IpcServerLoop() { while (stop_event_ != nullptr && WaitForSingleObject(stop_event_, 0) != WAIT_OBJECT_0) { HANDLE pipe = CreateNamedPipeW( - kCrossDeskServicePipeName, - PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, - PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, - 1, 4096, 4096, 0, pipe_attributes); + kCrossDeskServicePipeName, PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, + PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, 1, 4096, 4096, 0, + pipe_attributes); if (pipe == INVALID_HANDLE_VALUE) { DWORD error = GetLastError(); LOG_ERROR("CreateNamedPipeW failed, error={}", error); @@ -1068,9 +1060,8 @@ bool CrossDeskServiceHost::ShouldKeepSecureInputHelperLocked( return false; } - return HasSecureInputUiLocked() || - (GetEffectiveSessionLockedLocked() && - IsHelperReportingLockScreenLocked()); + return HasSecureInputUiLocked() || (GetEffectiveSessionLockedLocked() && + IsHelperReportingLockScreenLocked()); } std::wstring CrossDeskServiceHost::GetSessionHelperPath() const { @@ -1257,8 +1248,8 @@ bool CrossDeskServiceHost::LaunchSessionHelper(DWORD session_id) { event_attributes = event_security.get(); } - HANDLE stop_event_handle = CreateEventW(event_attributes, TRUE, FALSE, - stop_event_name.c_str()); + HANDLE stop_event_handle = + CreateEventW(event_attributes, TRUE, FALSE, stop_event_name.c_str()); if (stop_event_handle == nullptr) { std::lock_guard lock(state_mutex_); session_helper_last_error_ = "create_helper_stop_event_failed"; @@ -1280,8 +1271,8 @@ bool CrossDeskServiceHost::LaunchSessionHelper(DWORD session_id) { if (console_mode_ && process_session_id_ == session_id) { created = CreateProcessW(helper_path.c_str(), mutable_command_line.data(), - nullptr, nullptr, FALSE, CREATE_NO_WINDOW, - nullptr, nullptr, &startup_info, &process_info); + nullptr, nullptr, FALSE, CREATE_NO_WINDOW, nullptr, + nullptr, &startup_info, &process_info); } else { HANDLE user_token = nullptr; HANDLE primary_token = nullptr; @@ -1315,8 +1306,7 @@ bool CrossDeskServiceHost::LaunchSessionHelper(DWORD session_id) { FALSE); created = CreateProcessAsUserW( primary_token, helper_path.c_str(), mutable_command_line.data(), - nullptr, nullptr, FALSE, - CREATE_UNICODE_ENVIRONMENT | CREATE_NO_WINDOW, + nullptr, nullptr, FALSE, CREATE_UNICODE_ENVIRONMENT | CREATE_NO_WINDOW, environment_block.environment, nullptr, &startup_info, &process_info); DWORD error = created ? ERROR_SUCCESS : GetLastError(); CloseHandle(primary_token); @@ -1364,8 +1354,8 @@ bool CrossDeskServiceHost::LaunchSecureInputHelper(DWORD session_id) { event_attributes = event_security.get(); } - HANDLE stop_event_handle = CreateEventW(event_attributes, TRUE, FALSE, - stop_event_name.c_str()); + HANDLE stop_event_handle = + CreateEventW(event_attributes, TRUE, FALSE, stop_event_name.c_str()); if (stop_event_handle == nullptr) { std::lock_guard lock(state_mutex_); secure_input_helper_last_error_ = @@ -1388,8 +1378,8 @@ bool CrossDeskServiceHost::LaunchSecureInputHelper(DWORD session_id) { if (console_mode_ && process_session_id_ == session_id) { created = CreateProcessW(helper_path.c_str(), mutable_command_line.data(), - nullptr, nullptr, FALSE, CREATE_NO_WINDOW, - nullptr, nullptr, &startup_info, &process_info); + nullptr, nullptr, FALSE, CREATE_NO_WINDOW, nullptr, + nullptr, &startup_info, &process_info); } else { HANDLE primary_token = nullptr; ScopedEnvironmentBlock environment_block; @@ -1397,8 +1387,7 @@ bool CrossDeskServiceHost::LaunchSecureInputHelper(DWORD session_id) { if (!CreateSessionSystemToken(session_id, &primary_token, &error)) { CloseHandle(stop_event_handle); std::lock_guard lock(state_mutex_); - secure_input_helper_last_error_ = - "create_session_system_token_failed"; + secure_input_helper_last_error_ = "create_session_system_token_failed"; secure_input_helper_last_error_code_ = error; return false; } @@ -1407,16 +1396,14 @@ bool CrossDeskServiceHost::LaunchSecureInputHelper(DWORD session_id) { FALSE); created = CreateProcessAsUserW( primary_token, helper_path.c_str(), mutable_command_line.data(), - nullptr, nullptr, FALSE, - CREATE_UNICODE_ENVIRONMENT | CREATE_NO_WINDOW, + nullptr, nullptr, FALSE, CREATE_UNICODE_ENVIRONMENT | CREATE_NO_WINDOW, environment_block.environment, nullptr, &startup_info, &process_info); error = created ? ERROR_SUCCESS : GetLastError(); CloseHandle(primary_token); if (!created) { CloseHandle(stop_event_handle); std::lock_guard lock(state_mutex_); - secure_input_helper_last_error_ = - "create_secure_input_helper_failed"; + secure_input_helper_last_error_ = "create_secure_input_helper_failed"; secure_input_helper_last_error_code_ = error; return false; } @@ -1515,25 +1502,24 @@ void CrossDeskServiceHost::RefreshSessionHelperReportedState() { session_helper_report_session_id_ = json.value("session_id", static_cast(0xFFFFFFFF)); session_helper_report_process_id_ = json.value("process_id", 0u); - session_helper_report_session_locked_ = - json.value("session_locked", false); + session_helper_report_session_locked_ = json.value("session_locked", false); session_helper_report_input_desktop_available_ = json.value("input_desktop_available", false); session_helper_report_input_desktop_error_code_ = json.value("input_desktop_error_code", 0u); session_helper_report_input_desktop_ = json.value("input_desktop", std::string()); - session_helper_report_lock_app_visible_ = + session_helper_report_lock_app_visible_ = json.value("lock_app_visible", false); session_helper_report_logon_ui_visible_ = json.value("logon_ui_visible", false); session_helper_report_secure_desktop_active_ = json.value("secure_desktop_active", false); - session_helper_report_credential_ui_visible_ = + session_helper_report_credential_ui_visible_ = json.value("credential_ui_visible", false); - session_helper_report_unlock_ui_visible_ = + session_helper_report_unlock_ui_visible_ = json.value("unlock_ui_visible", false); - session_helper_report_interactive_stage_ = + session_helper_report_interactive_stage_ = json.value("interactive_stage", std::string()); session_helper_report_state_age_ms_ = json.value("state_age_ms", 0ull); session_helper_report_uptime_ms_ = json.value("uptime_ms", 0ull); @@ -1582,8 +1568,7 @@ void CrossDeskServiceHost::RecordSessionEvent(DWORD event_type, } } -std::string CrossDeskServiceHost::HandleIpcCommand( - const std::string& command) { +std::string CrossDeskServiceHost::HandleIpcCommand(const std::string& command) { std::string normalized = ToLower(Trim(command)); if (normalized == "ping") { return "{\"ok\":true,\"reply\":\"pong\"}"; @@ -1596,8 +1581,7 @@ std::string CrossDeskServiceHost::HandleIpcCommand( } int key_code = 0; bool is_down = false; - if (ParseSecureDesktopKeyboardIpcCommand(normalized, &key_code, - &is_down)) { + if (ParseSecureDesktopKeyboardIpcCommand(normalized, &key_code, &is_down)) { return SendSecureDesktopKeyboardInput(key_code, is_down); } return BuildErrorJson("unknown_command"); @@ -1639,16 +1623,16 @@ std::string CrossDeskServiceHost::BuildStatusResponse() { std::string input_desktop = EscapeJsonString(input_desktop_name_); std::string last_sas_error = EscapeJsonString(last_sas_error_); std::string session_helper_last_error = - EscapeJsonString(session_helper_last_error_); + EscapeJsonString(session_helper_last_error_); std::string session_helper_status_error = EscapeJsonString(session_helper_status_error_); std::string session_helper_path = EscapeJsonString(WideToUtf8(GetSessionHelperPath())); - std::string secure_input_helper_path = + std::string secure_input_helper_path = EscapeJsonString(WideToUtf8(GetSecureInputHelperPath())); std::string helper_input_desktop = EscapeJsonString(session_helper_report_input_desktop_); - std::string secure_input_helper_last_error = + std::string secure_input_helper_last_error = EscapeJsonString(secure_input_helper_last_error_); bool interactive_state_ready = session_helper_status_ok_; const char* interactive_state_source = @@ -1658,9 +1642,9 @@ std::string CrossDeskServiceHost::BuildStatusResponse() { interactive_state_ready ? (effective_session_locked && IsHelperReportingLockScreenLocked()) : false; - bool credential_ui_visible = interactive_state_ready - ? session_helper_report_credential_ui_visible_ - : logon_ui_visible_; + bool credential_ui_visible = + interactive_state_ready ? session_helper_report_credential_ui_visible_ + : logon_ui_visible_; bool unlock_ui_visible = interactive_state_ready ? session_helper_report_unlock_ui_visible_ : (logon_ui_visible_ || secure_desktop_active_); @@ -1670,121 +1654,113 @@ std::string CrossDeskServiceHost::BuildStatusResponse() { bool interactive_logon_ui_visible = interactive_state_ready ? session_helper_report_logon_ui_visible_ : logon_ui_visible_; - bool interactive_session_locked = - effective_session_locked || interactive_lock_screen_visible || - unlock_ui_visible; + bool interactive_session_locked = effective_session_locked || + interactive_lock_screen_visible || + unlock_ui_visible; std::string interactive_input_desktop = EscapeJsonString( interactive_state_ready ? session_helper_report_input_desktop_ : input_desktop_name_); - std::string interactive_stage = EscapeJsonString( - DetermineInteractiveStage(interactive_lock_screen_visible, - credential_ui_visible, - interactive_secure_desktop_active)); + std::string interactive_stage = EscapeJsonString(DetermineInteractiveStage( + interactive_lock_screen_visible, credential_ui_visible, + interactive_secure_desktop_active)); std::ostringstream stream; stream << "{\"ok\":true,\"service\":\"CrossDeskService\"" << ",\"active_session_id\":" << active_session_id_ - << ",\"process_session_id\":" << process_session_id_ + << ",\"process_session_id\":" << process_session_id_ << ",\"session_locked\":" << (session_locked_ ? "true" : "false") - << ",\"interactive_state_ready\":" - << (interactive_state_ready ? "true" : "false") - << ",\"interactive_state_source\":\"" - << interactive_state_source << "\"" - << ",\"interactive_session_locked\":" - << (interactive_session_locked ? "true" : "false") - << ",\"interactive_stage\":\"" << interactive_stage << "\"" - << ",\"interactive_input_desktop\":\"" - << interactive_input_desktop << "\"" - << ",\"interactive_lock_screen_visible\":" - << (interactive_lock_screen_visible ? "true" : "false") - << ",\"interactive_logon_ui_visible\":" - << (interactive_logon_ui_visible ? "true" : "false") - << ",\"interactive_secure_desktop_active\":" - << (interactive_secure_desktop_active ? "true" : "false") - << ",\"unlock_ui_visible\":" - << (unlock_ui_visible ? "true" : "false") - << ",\"credential_ui_visible\":" - << (credential_ui_visible ? "true" : "false") - << ",\"password_box_visible\":" - << (credential_ui_visible ? "true" : "false") - << ",\"logon_ui_visible\":" - << (logon_ui_visible_ ? "true" : "false") + << ",\"interactive_state_ready\":" + << (interactive_state_ready ? "true" : "false") + << ",\"interactive_state_source\":\"" << interactive_state_source + << "\"" + << ",\"interactive_session_locked\":" + << (interactive_session_locked ? "true" : "false") + << ",\"interactive_stage\":\"" << interactive_stage << "\"" + << ",\"interactive_input_desktop\":\"" << interactive_input_desktop + << "\"" + << ",\"interactive_lock_screen_visible\":" + << (interactive_lock_screen_visible ? "true" : "false") + << ",\"interactive_logon_ui_visible\":" + << (interactive_logon_ui_visible ? "true" : "false") + << ",\"interactive_secure_desktop_active\":" + << (interactive_secure_desktop_active ? "true" : "false") + << ",\"unlock_ui_visible\":" << (unlock_ui_visible ? "true" : "false") + << ",\"credential_ui_visible\":" + << (credential_ui_visible ? "true" : "false") + << ",\"password_box_visible\":" + << (credential_ui_visible ? "true" : "false") + << ",\"logon_ui_visible\":" << (logon_ui_visible_ ? "true" : "false") << ",\"secure_desktop_active\":" << (secure_desktop_active_ ? "true" : "false") - << ",\"input_desktop_available\":" - << (input_desktop_available_ ? "true" : "false") - << ",\"input_desktop_error_code\":" << input_desktop_error_code_ + << ",\"input_desktop_available\":" + << (input_desktop_available_ ? "true" : "false") + << ",\"input_desktop_error_code\":" << input_desktop_error_code_ << ",\"input_desktop\":\"" << input_desktop << "\"" << ",\"prelogin\":" << (prelogin_ ? "true" : "false") << ",\"session_user\":\"" << username_utf8 << "\"" - << ",\"session_helper_path\":\"" << session_helper_path << "\"" - << ",\"session_helper_running\":" - << (session_helper_running_ ? "true" : "false") - << ",\"session_helper_pid\":" << session_helper_process_id_ - << ",\"session_helper_session_id\":" - << session_helper_session_id_ - << ",\"session_helper_exit_code\":" << session_helper_exit_code_ - << ",\"session_helper_last_error\":\"" - << session_helper_last_error << "\"" - << ",\"session_helper_last_error_code\":" - << session_helper_last_error_code_ - << ",\"session_helper_status_ok\":" - << (session_helper_status_ok_ ? "true" : "false") - << ",\"session_helper_status_error\":\"" - << session_helper_status_error << "\"" - << ",\"session_helper_status_error_code\":" - << session_helper_status_error_code_ - << ",\"session_helper_report_session_id\":" - << session_helper_report_session_id_ - << ",\"session_helper_report_process_id\":" - << session_helper_report_process_id_ - << ",\"session_helper_report_session_locked\":" - << (session_helper_report_session_locked_ ? "true" : "false") - << ",\"session_helper_report_input_desktop_available\":" - << (session_helper_report_input_desktop_available_ ? "true" : "false") - << ",\"session_helper_report_input_desktop_error_code\":" - << session_helper_report_input_desktop_error_code_ - << ",\"session_helper_report_input_desktop\":\"" - << helper_input_desktop << "\"" - << ",\"session_helper_report_lock_app_visible\":" - << (session_helper_report_lock_app_visible_ ? "true" : "false") - << ",\"session_helper_report_logon_ui_visible\":" - << (session_helper_report_logon_ui_visible_ ? "true" : "false") - << ",\"session_helper_report_secure_desktop_active\":" - << (session_helper_report_secure_desktop_active_ ? "true" : "false") - << ",\"session_helper_report_credential_ui_visible\":" - << (session_helper_report_credential_ui_visible_ ? "true" : "false") - << ",\"session_helper_report_unlock_ui_visible\":" - << (session_helper_report_unlock_ui_visible_ ? "true" : "false") - << ",\"session_helper_report_interactive_stage\":\"" - << EscapeJsonString(session_helper_report_interactive_stage_) << "\"" - << ",\"session_helper_report_state_age_ms\":" - << session_helper_report_state_age_ms_ - << ",\"session_helper_report_uptime_ms\":" - << session_helper_report_uptime_ms_ - << ",\"session_helper_uptime_ms\":" - << (session_helper_started_at_tick_ >= started_at_tick_ - ? (GetTickCount64() - session_helper_started_at_tick_) - : 0) - << ",\"secure_input_helper_path\":\"" - << secure_input_helper_path << "\"" - << ",\"secure_input_helper_running\":" - << (secure_input_helper_running_ ? "true" : "false") - << ",\"secure_input_helper_pid\":" - << secure_input_helper_process_id_ - << ",\"secure_input_helper_session_id\":" - << secure_input_helper_session_id_ - << ",\"secure_input_helper_exit_code\":" - << secure_input_helper_exit_code_ - << ",\"secure_input_helper_last_error\":\"" - << secure_input_helper_last_error << "\"" - << ",\"secure_input_helper_last_error_code\":" - << secure_input_helper_last_error_code_ - << ",\"secure_input_helper_uptime_ms\":" - << (secure_input_helper_started_at_tick_ >= started_at_tick_ - ? (GetTickCount64() - secure_input_helper_started_at_tick_) - : 0) - << ",\"last_sas_success\":" - << (last_sas_success_ ? "true" : "false") + << ",\"session_helper_path\":\"" << session_helper_path << "\"" + << ",\"session_helper_running\":" + << (session_helper_running_ ? "true" : "false") + << ",\"session_helper_pid\":" << session_helper_process_id_ + << ",\"session_helper_session_id\":" << session_helper_session_id_ + << ",\"session_helper_exit_code\":" << session_helper_exit_code_ + << ",\"session_helper_last_error\":\"" << session_helper_last_error + << "\"" + << ",\"session_helper_last_error_code\":" + << session_helper_last_error_code_ << ",\"session_helper_status_ok\":" + << (session_helper_status_ok_ ? "true" : "false") + << ",\"session_helper_status_error\":\"" << session_helper_status_error + << "\"" + << ",\"session_helper_status_error_code\":" + << session_helper_status_error_code_ + << ",\"session_helper_report_session_id\":" + << session_helper_report_session_id_ + << ",\"session_helper_report_process_id\":" + << session_helper_report_process_id_ + << ",\"session_helper_report_session_locked\":" + << (session_helper_report_session_locked_ ? "true" : "false") + << ",\"session_helper_report_input_desktop_available\":" + << (session_helper_report_input_desktop_available_ ? "true" : "false") + << ",\"session_helper_report_input_desktop_error_code\":" + << session_helper_report_input_desktop_error_code_ + << ",\"session_helper_report_input_desktop\":\"" + << helper_input_desktop << "\"" + << ",\"session_helper_report_lock_app_visible\":" + << (session_helper_report_lock_app_visible_ ? "true" : "false") + << ",\"session_helper_report_logon_ui_visible\":" + << (session_helper_report_logon_ui_visible_ ? "true" : "false") + << ",\"session_helper_report_secure_desktop_active\":" + << (session_helper_report_secure_desktop_active_ ? "true" : "false") + << ",\"session_helper_report_credential_ui_visible\":" + << (session_helper_report_credential_ui_visible_ ? "true" : "false") + << ",\"session_helper_report_unlock_ui_visible\":" + << (session_helper_report_unlock_ui_visible_ ? "true" : "false") + << ",\"session_helper_report_interactive_stage\":\"" + << EscapeJsonString(session_helper_report_interactive_stage_) << "\"" + << ",\"session_helper_report_state_age_ms\":" + << session_helper_report_state_age_ms_ + << ",\"session_helper_report_uptime_ms\":" + << session_helper_report_uptime_ms_ << ",\"session_helper_uptime_ms\":" + << (session_helper_started_at_tick_ >= started_at_tick_ + ? (GetTickCount64() - session_helper_started_at_tick_) + : 0) + << ",\"secure_input_helper_path\":\"" << secure_input_helper_path + << "\"" + << ",\"secure_input_helper_running\":" + << (secure_input_helper_running_ ? "true" : "false") + << ",\"secure_input_helper_pid\":" << secure_input_helper_process_id_ + << ",\"secure_input_helper_session_id\":" + << secure_input_helper_session_id_ + << ",\"secure_input_helper_exit_code\":" + << secure_input_helper_exit_code_ + << ",\"secure_input_helper_last_error\":\"" + << secure_input_helper_last_error << "\"" + << ",\"secure_input_helper_last_error_code\":" + << secure_input_helper_last_error_code_ + << ",\"secure_input_helper_uptime_ms\":" + << (secure_input_helper_started_at_tick_ >= started_at_tick_ + ? (GetTickCount64() - secure_input_helper_started_at_tick_) + : 0) + << ",\"last_sas_success\":" << (last_sas_success_ ? "true" : "false") << ",\"last_sas_error\":\"" << last_sas_error << "\"" << ",\"last_sas_error_code\":" << last_sas_error_code_ << ",\"last_sas_uptime_ms\":" @@ -1889,10 +1865,10 @@ bool InstallCrossDeskService(const std::wstring& binary_path) { return false; } - if (!ChangeServiceConfigW( - service, SERVICE_NO_CHANGE, SERVICE_AUTO_START, - SERVICE_NO_CHANGE, service_command.c_str(), nullptr, nullptr, - nullptr, nullptr, nullptr, kCrossDeskServiceDisplayName)) { + if (!ChangeServiceConfigW(service, SERVICE_NO_CHANGE, SERVICE_AUTO_START, + SERVICE_NO_CHANGE, service_command.c_str(), + nullptr, nullptr, nullptr, nullptr, nullptr, + kCrossDeskServiceDisplayName)) { LOG_ERROR("ChangeServiceConfigW failed, error={}", GetLastError()); CloseServiceHandle(service); CloseServiceHandle(manager); @@ -1973,8 +1949,8 @@ bool StopCrossDeskService(DWORD timeout_ms) { DWORD deadline = GetTickCount() + timeout_ms; while (GetTickCount() < deadline) { if (!QueryServiceStatusEx(service, SC_STATUS_PROCESS_INFO, - reinterpret_cast(&status), - sizeof(status), &bytes_needed)) { + reinterpret_cast(&status), sizeof(status), + &bytes_needed)) { LOG_ERROR("QueryServiceStatusEx failed, error={}", GetLastError()); CloseServiceHandle(service); CloseServiceHandle(manager); @@ -2001,8 +1977,9 @@ bool UninstallCrossDeskService() { return false; } - SC_HANDLE service = OpenServiceW(manager, kCrossDeskServiceName, - DELETE | SERVICE_STOP | SERVICE_QUERY_STATUS); + SC_HANDLE service = + OpenServiceW(manager, kCrossDeskServiceName, + DELETE | SERVICE_STOP | SERVICE_QUERY_STATUS); if (service == nullptr) { DWORD error = GetLastError(); CloseServiceHandle(manager); @@ -2037,9 +2014,9 @@ std::string SendCrossDeskSecureDesktopKeyInput(int key_code, bool is_down, } std::string SendCrossDeskSecureDesktopMouseInput(int x, int y, int wheel, - int flag, DWORD timeout_ms) { + int flag, DWORD timeout_ms) { return QueryCrossDeskService( - BuildSecureDesktopMouseIpcCommand(x, y, wheel, flag), timeout_ms); + BuildSecureDesktopMouseIpcCommand(x, y, wheel, flag), timeout_ms); } } // namespace crossdesk \ No newline at end of file diff --git a/src/service/windows/service_host.h b/src/service/windows/service_host.h index 0ded115..726029d 100644 --- a/src/service/windows/service_host.h +++ b/src/service/windows/service_host.h @@ -10,8 +10,7 @@ namespace crossdesk { inline constexpr wchar_t kCrossDeskServiceName[] = L"CrossDeskService"; -inline constexpr wchar_t kCrossDeskServiceDisplayName[] = - L"CrossDesk Service"; +inline constexpr wchar_t kCrossDeskServiceDisplayName[] = L"CrossDesk Service"; inline constexpr wchar_t kCrossDeskServicePipeName[] = L"\\\\.\\pipe\\CrossDeskService"; @@ -59,8 +58,7 @@ class CrossDeskServiceHost { static void WINAPI ServiceMain(DWORD argc, LPWSTR* argv); static BOOL WINAPI ConsoleControlHandler(DWORD control_type); static DWORD WINAPI ServiceControlHandler(DWORD control, DWORD event_type, - LPVOID event_data, - LPVOID context); + LPVOID event_data, LPVOID context); private: SERVICE_STATUS_HANDLE status_handle_ = nullptr; @@ -98,7 +96,7 @@ class CrossDeskServiceHost { bool input_desktop_available_ = false; bool session_helper_running_ = false; bool session_helper_status_ok_ = false; - bool session_helper_report_session_locked_ = false; + bool session_helper_report_session_locked_ = false; bool session_helper_report_input_desktop_available_ = false; bool session_helper_report_lock_app_visible_ = false; bool session_helper_report_logon_ui_visible_ = false; diff --git a/src/service/windows/session_helper_main.cpp b/src/service/windows/session_helper_main.cpp index e986688..126f0ad 100644 --- a/src/service/windows/session_helper_main.cpp +++ b/src/service/windows/session_helper_main.cpp @@ -1,17 +1,14 @@ -#include - -#include - -#include - #include +#include #include +#include #include #include #include #include #include +#include #include #include #include @@ -23,8 +20,8 @@ namespace { -using crossdesk::InitLogger; using crossdesk::get_logger; +using crossdesk::InitLogger; using Json = nlohmann::json; struct InputDesktopInfo { @@ -76,8 +73,7 @@ struct PipeSecurityAttributes { } bool Initialize() { - constexpr wchar_t kPipeSddl[] = - L"D:(A;;GA;;;SY)(A;;GA;;;BA)(A;;GRGW;;;AU)"; + constexpr wchar_t kPipeSddl[] = L"D:(A;;GA;;;SY)(A;;GA;;;BA)(A;;GRGW;;;AU)"; if (!ConvertStringSecurityDescriptorToSecurityDescriptorW( kPipeSddl, SDDL_REVISION_1, &security_descriptor_, nullptr)) { return false; @@ -100,7 +96,8 @@ void InitializeHelperLogger() { static std::once_flag once_flag; std::call_once(once_flag, []() { crossdesk::PathManager path_manager("CrossDesk"); - std::filesystem::path log_path = path_manager.GetLogPath() / "session_helper"; + std::filesystem::path log_path = + path_manager.GetLogPath() / "session_helper"; if (!log_path.empty() && path_manager.CreateDirectories(log_path)) { InitLogger(log_path.string()); return; @@ -114,8 +111,8 @@ std::wstring Utf8ToWide(const std::string& value) { return {}; } - int size_needed = MultiByteToWideChar(CP_UTF8, 0, value.c_str(), -1, - nullptr, 0); + int size_needed = + MultiByteToWideChar(CP_UTF8, 0, value.c_str(), -1, nullptr, 0); if (size_needed <= 1) { return {}; } @@ -132,15 +129,15 @@ std::string WideToUtf8(const std::wstring& value) { return {}; } - int size_needed = WideCharToMultiByte(CP_UTF8, 0, value.c_str(), -1, - nullptr, 0, nullptr, nullptr); + int size_needed = WideCharToMultiByte(CP_UTF8, 0, value.c_str(), -1, nullptr, + 0, nullptr, nullptr); if (size_needed <= 1) { return {}; } std::string result(static_cast(size_needed), '\0'); - WideCharToMultiByte(CP_UTF8, 0, value.c_str(), -1, result.data(), - size_needed, nullptr, nullptr); + WideCharToMultiByte(CP_UTF8, 0, value.c_str(), -1, result.data(), size_needed, + nullptr, nullptr); result.pop_back(); return result; } @@ -179,7 +176,7 @@ InputDesktopInfo GetInputDesktopInfo() { } bool IsProcessRunningInCurrentSession(const wchar_t* executable_name, - DWORD session_id) { + DWORD session_id) { HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if (snapshot == INVALID_HANDLE_VALUE) { return false; @@ -325,15 +322,14 @@ std::string BuildHelperStatusResponse(HelperState* helper_state) { json["lock_app_visible"] = helper_state->lock_app_visible; json["logon_ui_visible"] = helper_state->logon_ui_visible; json["secure_desktop_active"] = helper_state->secure_desktop_active; - json["credential_ui_visible"] = credential_ui_visible; - json["unlock_ui_visible"] = unlock_ui_visible; + json["credential_ui_visible"] = credential_ui_visible; + json["unlock_ui_visible"] = unlock_ui_visible; json["interactive_stage"] = DetermineInteractiveStage( helper_state->lock_app_visible, credential_ui_visible, helper_state->secure_desktop_active); - json["uptime_ms"] = - GetTickCount64() >= helper_state->started_at_tick - ? (GetTickCount64() - helper_state->started_at_tick) - : 0; + json["uptime_ms"] = GetTickCount64() >= helper_state->started_at_tick + ? (GetTickCount64() - helper_state->started_at_tick) + : 0; json["state_age_ms"] = GetTickCount64() >= helper_state->last_update_tick ? (GetTickCount64() - helper_state->last_update_tick) @@ -349,12 +345,14 @@ void HelperIpcServerLoop(HANDLE stop_event, DWORD session_id, pipe_attributes = security_attributes.get(); } - std::wstring pipe_name = crossdesk::GetCrossDeskSessionHelperPipeName(session_id); - while (stop_event == nullptr || WaitForSingleObject(stop_event, 0) != WAIT_OBJECT_0) { + std::wstring pipe_name = + crossdesk::GetCrossDeskSessionHelperPipeName(session_id); + while (stop_event == nullptr || + WaitForSingleObject(stop_event, 0) != WAIT_OBJECT_0) { HANDLE pipe = CreateNamedPipeW( pipe_name.c_str(), PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, - PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, 1, 4096, 4096, - 0, pipe_attributes); + PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, 1, 4096, 4096, 0, + pipe_attributes); if (pipe == INVALID_HANDLE_VALUE) { LOG_ERROR("CreateNamedPipeW failed in helper, error={}", GetLastError()); if (stop_event != nullptr) { @@ -465,10 +463,9 @@ bool EnsureThreadDesktop(const wchar_t* desktop_name, return true; } - HDESK desktop = OpenDesktopW( - desktop_name, 0, FALSE, - DESKTOP_CREATEWINDOW | DESKTOP_WRITEOBJECTS | DESKTOP_READOBJECTS | - DESKTOP_SWITCHDESKTOP); + HDESK desktop = OpenDesktopW(desktop_name, 0, FALSE, + DESKTOP_CREATEWINDOW | DESKTOP_WRITEOBJECTS | + DESKTOP_READOBJECTS | DESKTOP_SWITCHDESKTOP); if (desktop == nullptr) { return false; } @@ -515,14 +512,13 @@ int InjectKeyboardInput(int key_code, bool is_down) { } bool ParseSecureInputKeyboardCommand(const std::string& command, - int* key_code_out, - bool* is_down_out) { + int* key_code_out, bool* is_down_out) { if (key_code_out == nullptr || is_down_out == nullptr) { return false; } - if (command.rfind(crossdesk::kCrossDeskSecureInputKeyboardCommandPrefix, - 0) != 0) { + if (command.rfind(crossdesk::kCrossDeskSecureInputKeyboardCommandPrefix, 0) != + 0) { return false; } @@ -552,7 +548,7 @@ bool ParseSecureInputKeyboardCommand(const std::string& command, } bool ParseSecureInputMouseCommand(const std::string& command, - SecureMouseRequest* request_out) { + SecureMouseRequest* request_out) { if (request_out == nullptr) { return false; } @@ -622,8 +618,7 @@ bool ParseSecureInputCaptureCommand(const std::string& command, for (int index = 0; index < 5; ++index) { const size_t separator = command.find(':', token_begin); const bool is_last = index == 4; - const size_t token_end = - is_last ? command.size() : separator; + const size_t token_end = is_last ? command.size() : separator; if (token_end == std::string::npos || token_end <= token_begin) { return false; } @@ -734,8 +729,7 @@ std::vector CaptureSecureDesktopFrame( const DWORD error = GetLastError(); DeleteDC(mem_dc); ReleaseDC(nullptr, screen_dc); - return BuildTextResponseBytes( - BuildErrorJson("create_dib_failed", error)); + return BuildTextResponseBytes(BuildErrorJson("create_dib_failed", error)); } HGDIOBJ old_bitmap = SelectObject(mem_dc, dib); @@ -746,8 +740,7 @@ std::vector CaptureSecureDesktopFrame( DeleteObject(dib); DeleteDC(mem_dc); ReleaseDC(nullptr, screen_dc); - return BuildTextResponseBytes( - BuildErrorJson("bitblt_failed", error)); + return BuildTextResponseBytes(BuildErrorJson("bitblt_failed", error)); } if (request.show_cursor) { @@ -757,8 +750,8 @@ std::vector CaptureSecureDesktopFrame( cursor_info.hCursor != nullptr) { const int cursor_x = cursor_info.ptScreenPos.x - request.left; const int cursor_y = cursor_info.ptScreenPos.y - request.top; - if (cursor_x >= -64 && cursor_y >= -64 && - cursor_x < request.width + 64 && cursor_y < request.height + 64) { + if (cursor_x >= -64 && cursor_y >= -64 && cursor_x < request.width + 64 && + cursor_y < request.height + 64) { DrawIconEx(mem_dc, cursor_x, cursor_y, cursor_info.hCursor, 0, 0, 0, nullptr, DI_NORMAL); } @@ -790,7 +783,8 @@ std::vector CaptureSecureDesktopFrame( header.top = request.top; header.width = static_cast(request.width); header.height = static_cast(request.height); - header.payload_size = static_cast(capture_buffers->nv12_frame.size()); + header.payload_size = + static_cast(capture_buffers->nv12_frame.size()); std::vector response(sizeof(header) + capture_buffers->nv12_frame.size()); @@ -804,8 +798,7 @@ std::vector CaptureSecureDesktopFrame( } std::vector HandleSecureInputHelperCommand( - const std::string& command, - SecureCaptureBuffers* capture_buffers) { + const std::string& command, SecureCaptureBuffers* capture_buffers) { if (command == "ping") { return BuildTextResponseBytes("{\"ok\":true,\"reply\":\"pong\"}"); } @@ -816,7 +809,8 @@ std::vector HandleSecureInputHelperCommand( const int inject_result = InjectKeyboardInput(key_code, is_down); if (inject_result != 0) { LOG_WARN( - "Secure input helper SendInput failed for key_code={}, is_down={}, err={}", + "Secure input helper SendInput failed for key_code={}, is_down={}, " + "err={}", key_code, is_down, inject_result); return BuildTextResponseBytes(BuildErrorJson( "send_input_failed", static_cast(inject_result))); @@ -836,7 +830,8 @@ std::vector HandleSecureInputHelperCommand( const int inject_result = InjectMouseInput(mouse_request); if (inject_result != 0) { LOG_WARN( - "Secure input helper SendInput failed for mouse x={}, y={}, wheel={}, flag={}, err={}", + "Secure input helper SendInput failed for mouse x={}, y={}, " + "wheel={}, flag={}, err={}", mouse_request.x, mouse_request.y, mouse_request.wheel, mouse_request.flag, inject_result); return BuildTextResponseBytes(BuildErrorJson( @@ -898,10 +893,10 @@ void SecureInputHelperIpcServerLoop(HANDLE stop_event, DWORD session_id) { WaitForSingleObject(stop_event, 0) != WAIT_OBJECT_0) { HANDLE pipe = CreateNamedPipeW( pipe_name.c_str(), PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, - PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, - PIPE_UNLIMITED_INSTANCES, - crossdesk::kCrossDeskSecureInputPipeBufferBytes, 4096, 0, - pipe_attributes); + PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, + PIPE_UNLIMITED_INSTANCES, + crossdesk::kCrossDeskSecureInputPipeBufferBytes, 4096, 0, + pipe_attributes); if (pipe == INVALID_HANDLE_VALUE) { LOG_ERROR("CreateNamedPipeW failed in secure input helper, error={}", GetLastError()); @@ -1010,8 +1005,10 @@ int main(int argc, char* argv[]) { } if (run_secure_input_helper) { - LOG_INFO("Secure input helper starting: pid={}, current_session_id={}, expected_session_id={}", - GetCurrentProcessId(), current_session_id, expected_session_id); + LOG_INFO( + "Secure input helper starting: pid={}, current_session_id={}, " + "expected_session_id={}", + GetCurrentProcessId(), current_session_id, expected_session_id); if (expected_session_id != 0xFFFFFFFF && expected_session_id != current_session_id) { LOG_WARN("Secure input helper session mismatch: expected={}, current={}", @@ -1020,15 +1017,16 @@ int main(int argc, char* argv[]) { HDESK secure_desktop = nullptr; if (!EnsureThreadDesktop(L"Winlogon", &secure_desktop)) { - LOG_ERROR("Failed to switch secure input helper to Winlogon desktop, error={}", - GetLastError()); + LOG_ERROR( + "Failed to switch secure input helper to Winlogon desktop, error={}", + GetLastError()); if (stop_event != nullptr) { CloseHandle(stop_event); } return 1; } - LOG_INFO("Secure input helper desktop: '{}'", + LOG_INFO("Secure input helper desktop: '{}'", WideToUtf8(GetCurrentThreadDesktopNameW())); SecureInputHelperIpcServerLoop(stop_event, current_session_id); @@ -1042,8 +1040,10 @@ int main(int argc, char* argv[]) { return 0; } - LOG_INFO("Session helper starting: pid={}, current_session_id={}, expected_session_id={}", - GetCurrentProcessId(), current_session_id, expected_session_id); + LOG_INFO( + "Session helper starting: pid={}, current_session_id={}, " + "expected_session_id={}", + GetCurrentProcessId(), current_session_id, expected_session_id); HelperState helper_state; helper_state.session_id = current_session_id; @@ -1087,11 +1087,13 @@ int main(int argc, char* argv[]) { session_locked != last_session_locked || lock_app_visible != last_lock_app || logon_ui_running != last_logon_ui || - secure_desktop_active != last_secure_desktop || - stage != last_stage) { - LOG_INFO("Session helper state: session_id={}, input_desktop='{}', session_locked={}, lock_app_visible={}, logon_ui_running={}, secure_desktop_active={}, stage={}", - current_session_id, desktop_name, session_locked, lock_app_visible, - logon_ui_running, secure_desktop_active, stage); + secure_desktop_active != last_secure_desktop || stage != last_stage) { + LOG_INFO( + "Session helper state: session_id={}, input_desktop='{}', " + "session_locked={}, lock_app_visible={}, logon_ui_running={}, " + "secure_desktop_active={}, stage={}", + current_session_id, desktop_name, session_locked, lock_app_visible, + logon_ui_running, secure_desktop_active, stage); last_desktop_name = desktop_name; last_session_locked = session_locked; last_lock_app = lock_app_visible; @@ -1100,8 +1102,9 @@ int main(int argc, char* argv[]) { last_stage = stage; } - DWORD wait_result = - stop_event != nullptr ? WaitForSingleObject(stop_event, 1000) : WAIT_TIMEOUT; + DWORD wait_result = stop_event != nullptr + ? WaitForSingleObject(stop_event, 1000) + : WAIT_TIMEOUT; if (wait_result == WAIT_OBJECT_0) { break; } diff --git a/src/service/windows/session_helper_shared.h b/src/service/windows/session_helper_shared.h index 13a4c35..b68e8f5 100644 --- a/src/service/windows/session_helper_shared.h +++ b/src/service/windows/session_helper_shared.h @@ -11,16 +11,13 @@ namespace crossdesk { inline constexpr wchar_t kCrossDeskSessionHelperPipePrefix[] = L"\\\\.\\pipe\\CrossDeskSessionHelper-"; inline constexpr wchar_t kCrossDeskSecureInputHelperPipePrefix[] = - L"\\\\.\\pipe\\CrossDeskSecureInputHelper-"; + L"\\\\.\\pipe\\CrossDeskSecureInputHelper-"; inline constexpr char kCrossDeskSessionHelperStatusCommand[] = "status"; inline constexpr char kCrossDeskSecureInputKeyboardCommandPrefix[] = - "keyboard:"; -inline constexpr char kCrossDeskSecureInputMouseCommandPrefix[] = - "mouse:"; -inline constexpr char kCrossDeskSecureInputCaptureCommandPrefix[] = - "capture:"; -inline constexpr DWORD kCrossDeskSecureInputPipeBufferBytes = - 16 * 1024 * 1024; + "keyboard:"; +inline constexpr char kCrossDeskSecureInputMouseCommandPrefix[] = "mouse:"; +inline constexpr char kCrossDeskSecureInputCaptureCommandPrefix[] = "capture:"; +inline constexpr DWORD kCrossDeskSecureInputPipeBufferBytes = 16 * 1024 * 1024; inline constexpr uint32_t kCrossDeskSecureDesktopFrameMagic = 0x50444358; inline constexpr uint32_t kCrossDeskSecureDesktopFrameVersion = 1; @@ -43,7 +40,7 @@ inline std::wstring GetCrossDeskSessionHelperPipeName(DWORD session_id) { inline std::wstring GetCrossDeskSecureInputHelperPipeName(DWORD session_id) { return std::wstring(kCrossDeskSecureInputHelperPipePrefix) + - std::to_wstring(session_id); + std::to_wstring(session_id); } } // namespace crossdesk