2012-06-10 16:50:54 +00:00
|
|
|
/*
|
2024-09-17 19:00:25 +00:00
|
|
|
* Deskflow -- mouse and keyboard sharing utility
|
2025-02-10 20:27:49 +00:00
|
|
|
* SPDX-FileCopyrightText: (C) 2012 - 2025 Symless Ltd.
|
2025-01-24 00:11:17 +00:00
|
|
|
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
|
2012-06-10 16:50:54 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
|
2025-02-13 17:37:58 +00:00
|
|
|
#include "platform/MSWindowsProcess.h"
|
2014-02-28 12:36:45 +00:00
|
|
|
#include "platform/MSWindowsSession.h"
|
2025-03-03 12:11:06 +00:00
|
|
|
|
2012-06-10 16:50:54 +00:00
|
|
|
#define WIN32_LEAN_AND_MEAN
|
|
|
|
|
#include <Windows.h>
|
|
|
|
|
|
2025-02-13 17:37:58 +00:00
|
|
|
#include <memory>
|
2025-03-03 13:34:45 +00:00
|
|
|
#include <mutex>
|
2025-03-03 11:03:21 +00:00
|
|
|
#include <optional>
|
2025-02-13 17:37:58 +00:00
|
|
|
#include <string>
|
|
|
|
|
|
2025-03-03 11:38:14 +00:00
|
|
|
typedef VOID(WINAPI *SendSas)(BOOL asUser);
|
|
|
|
|
|
2014-11-11 13:51:47 +00:00
|
|
|
class Thread;
|
|
|
|
|
class FileLogOutputter;
|
2012-06-10 16:50:54 +00:00
|
|
|
|
2025-03-03 12:27:28 +00:00
|
|
|
/**
|
|
|
|
|
* @brief Monitors and controls a core process on Windows, elevating if necessary.
|
|
|
|
|
*/
|
2024-10-17 18:04:35 +00:00
|
|
|
class MSWindowsWatchdog
|
|
|
|
|
{
|
2025-03-03 11:03:21 +00:00
|
|
|
enum class ProcessState
|
|
|
|
|
{
|
|
|
|
|
Idle,
|
|
|
|
|
StartScheduled,
|
|
|
|
|
StartPending,
|
|
|
|
|
StopPending,
|
|
|
|
|
Running
|
|
|
|
|
};
|
|
|
|
|
|
2012-06-10 16:50:54 +00:00
|
|
|
public:
|
2025-03-05 15:40:23 +00:00
|
|
|
explicit MSWindowsWatchdog(bool foreground, FileLogOutputter &fileLogOutputter);
|
2025-03-03 11:03:21 +00:00
|
|
|
~MSWindowsWatchdog() = default;
|
2013-10-10 16:06:13 +00:00
|
|
|
|
2025-03-03 12:27:28 +00:00
|
|
|
/**
|
|
|
|
|
* @brief Start threads for main loop and and output loop.
|
|
|
|
|
*/
|
2024-07-02 19:07:06 +00:00
|
|
|
void startAsync();
|
2025-03-03 12:27:28 +00:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Set the command to run and whether to elevate the process.
|
|
|
|
|
*/
|
2025-03-03 12:00:31 +00:00
|
|
|
void setProcessConfig(const std::string_view &command, bool elevate);
|
2025-03-03 12:27:28 +00:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Stop the main loop and output loop threads.
|
|
|
|
|
*/
|
2024-07-02 19:07:06 +00:00
|
|
|
void stop();
|
2025-03-03 12:27:28 +00:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @return True if the process is running.
|
|
|
|
|
*/
|
2025-02-13 17:37:58 +00:00
|
|
|
bool isProcessRunning();
|
2025-03-03 12:27:28 +00:00
|
|
|
|
2012-06-10 16:50:54 +00:00
|
|
|
private:
|
2025-03-03 12:27:28 +00:00
|
|
|
/**
|
|
|
|
|
* @brief Monitor the process state and start/stop the process as necessary.
|
|
|
|
|
*/
|
2025-05-23 20:52:46 +00:00
|
|
|
void mainLoop(const void *);
|
2025-03-03 12:27:28 +00:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Monitor the process standard out/error and write to the file log outputter.
|
|
|
|
|
*/
|
2025-05-23 20:52:46 +00:00
|
|
|
void outputLoop(const void *);
|
2025-03-03 12:27:28 +00:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Duplicates the process token for the given process.
|
|
|
|
|
*
|
|
|
|
|
* Required for starting a process in the user session; when we start an elevated process
|
|
|
|
|
* to ensure that it has access to secure processes, such as the login screen, we duplicate
|
|
|
|
|
* the token of an existing process that has the necessary access such as `winlogon.exe`.
|
|
|
|
|
*
|
|
|
|
|
* @param process The process to duplicate the token from (typically `winlogon.exe`).
|
|
|
|
|
*/
|
2024-07-02 19:07:06 +00:00
|
|
|
HANDLE duplicateProcessToken(HANDLE process, LPSECURITY_ATTRIBUTES security);
|
2025-03-03 12:27:28 +00:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Get a security token for the user session.
|
|
|
|
|
*
|
|
|
|
|
* Checks to see if logonui.exe is running or if the `elevatedToken` arg is true,
|
|
|
|
|
* which indicates either we're in a secure user session or we need an elevated token.
|
|
|
|
|
* If either case is true, it duplicates the token from `winlogon.exe`.
|
|
|
|
|
*/
|
2025-02-13 17:37:58 +00:00
|
|
|
HANDLE getUserToken(LPSECURITY_ATTRIBUTES security, bool elevatedToken);
|
2025-03-03 12:27:28 +00:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Start the core process, elevating if necessary.
|
|
|
|
|
*/
|
2024-07-02 19:07:06 +00:00
|
|
|
void startProcess();
|
2025-03-03 12:27:28 +00:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Controls whether the process should restart immediately or delay start.
|
|
|
|
|
*/
|
2025-04-15 22:14:58 +00:00
|
|
|
ProcessState handleStartError(const std::string_view &message = "");
|
2025-03-03 12:27:28 +00:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Init the output read pipe for standard out/error.
|
|
|
|
|
*/
|
2025-03-03 11:38:14 +00:00
|
|
|
void initOutputReadPipe();
|
2025-03-03 12:27:28 +00:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Init the SendSAS function, used for Ctrl+Alt+Del emulation.
|
|
|
|
|
*/
|
2025-03-03 11:38:14 +00:00
|
|
|
void initSasFunc();
|
2025-03-03 12:27:28 +00:00
|
|
|
|
2025-03-10 14:13:43 +00:00
|
|
|
/**
|
|
|
|
|
* @brief Allows the SendSAS function to be called from other processes.
|
|
|
|
|
*
|
|
|
|
|
* SendSAS sends a SAS (Secure Attention Sequence) for Ctrl+Alt+Del emulation.
|
|
|
|
|
*/
|
2025-05-23 20:52:46 +00:00
|
|
|
void sasLoop(const void *);
|
2025-03-10 14:13:43 +00:00
|
|
|
|
2025-03-03 12:27:28 +00:00
|
|
|
/**
|
|
|
|
|
* @brief Convert the process state enum to a string (useful for logging).
|
|
|
|
|
*/
|
2025-03-03 11:38:14 +00:00
|
|
|
static std::string processStateToString(ProcessState state);
|
|
|
|
|
|
2025-03-10 13:45:18 +00:00
|
|
|
/**
|
|
|
|
|
* @brief Stops any core processes which were not started by the watchdog.
|
|
|
|
|
*/
|
|
|
|
|
static void shutdownExistingProcesses();
|
|
|
|
|
|
2012-06-10 16:50:54 +00:00
|
|
|
private:
|
2025-03-03 11:53:24 +00:00
|
|
|
bool m_running = true;
|
2025-03-10 14:13:43 +00:00
|
|
|
std::unique_ptr<Thread> m_mainThread;
|
|
|
|
|
std::unique_ptr<Thread> m_outputThread;
|
|
|
|
|
std::unique_ptr<Thread> m_sasThread;
|
2025-03-03 11:53:24 +00:00
|
|
|
HANDLE m_outputWritePipe = nullptr;
|
|
|
|
|
HANDLE m_outputReadPipe = nullptr;
|
|
|
|
|
bool m_elevateProcess = false;
|
2024-07-02 19:07:06 +00:00
|
|
|
MSWindowsSession m_session;
|
2025-03-03 11:53:24 +00:00
|
|
|
int m_startFailures = 0;
|
2025-03-05 15:40:23 +00:00
|
|
|
FileLogOutputter &m_fileLogOutputter;
|
2025-03-03 12:26:13 +00:00
|
|
|
bool m_foreground = false;
|
2025-05-30 22:26:02 +00:00
|
|
|
std::wstring m_activeDesktop = {};
|
2025-02-13 17:37:58 +00:00
|
|
|
std::unique_ptr<deskflow::platform::MSWindowsProcess> m_process;
|
2025-03-03 11:03:21 +00:00
|
|
|
std::optional<double> m_nextStartTime = std::nullopt;
|
|
|
|
|
ProcessState m_processState = ProcessState::Idle;
|
2025-05-30 22:26:02 +00:00
|
|
|
std::wstring m_command = {};
|
2025-03-03 11:38:14 +00:00
|
|
|
SendSas m_sendSasFunc = nullptr;
|
2025-03-03 13:34:45 +00:00
|
|
|
std::mutex m_processStateMutex;
|
2012-06-10 16:50:54 +00:00
|
|
|
};
|