Merge branch 'jerry-sandbox'
This commit is contained in:
commit
e98b3678df
|
@ -311,13 +311,6 @@
|
||||||
</property>
|
</property>
|
||||||
</spacer>
|
</spacer>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
|
||||||
<widget class="QCheckBox" name="m_pElevateCheckBox">
|
|
||||||
<property name="text">
|
|
||||||
<string>&Elevate</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="m_pButtonApply">
|
<widget class="QPushButton" name="m_pButtonApply">
|
||||||
<property name="enabled">
|
<property name="enabled">
|
||||||
|
|
|
@ -114,6 +114,13 @@
|
||||||
<item row="0" column="1">
|
<item row="0" column="1">
|
||||||
<widget class="QComboBox" name="m_pComboLanguage"/>
|
<widget class="QComboBox" name="m_pComboLanguage"/>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="4" column="0">
|
||||||
|
<widget class="QCheckBox" name="m_pCheckBoxElevateMode">
|
||||||
|
<property name="text">
|
||||||
|
<string>Elevate mode</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
|
|
@ -54,7 +54,8 @@ AppConfig::AppConfig(QSettings* settings) :
|
||||||
m_WizardLastRun(0),
|
m_WizardLastRun(0),
|
||||||
m_CryptoPass(),
|
m_CryptoPass(),
|
||||||
m_ProcessMode(DEFAULT_PROCESS_MODE),
|
m_ProcessMode(DEFAULT_PROCESS_MODE),
|
||||||
m_AutoConnect(true)
|
m_AutoConnect(true),
|
||||||
|
m_ElevateMode(false)
|
||||||
{
|
{
|
||||||
Q_ASSERT(m_pSettings);
|
Q_ASSERT(m_pSettings);
|
||||||
|
|
||||||
|
@ -123,6 +124,7 @@ void AppConfig::loadSettings()
|
||||||
m_Language = settings().value("language", QLocale::system().name()).toString();
|
m_Language = settings().value("language", QLocale::system().name()).toString();
|
||||||
m_StartedBefore = settings().value("startedBefore", false).toBool();
|
m_StartedBefore = settings().value("startedBefore", false).toBool();
|
||||||
m_AutoConnect = settings().value("autoConnect", true).toBool();
|
m_AutoConnect = settings().value("autoConnect", true).toBool();
|
||||||
|
m_ElevateMode = settings().value("elevateMode", false).toBool();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AppConfig::saveSettings()
|
void AppConfig::saveSettings()
|
||||||
|
@ -139,6 +141,7 @@ void AppConfig::saveSettings()
|
||||||
settings().setValue("language", m_Language);
|
settings().setValue("language", m_Language);
|
||||||
settings().setValue("startedBefore", m_StartedBefore);
|
settings().setValue("startedBefore", m_StartedBefore);
|
||||||
settings().setValue("autoConnect", m_AutoConnect);
|
settings().setValue("autoConnect", m_AutoConnect);
|
||||||
|
settings().setValue("elevateMode", m_ElevateMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AppConfig::setCryptoPass(const QString &s)
|
void AppConfig::setCryptoPass(const QString &s)
|
||||||
|
@ -161,3 +164,8 @@ void AppConfig::setAutoConnect(bool autoConnect)
|
||||||
{
|
{
|
||||||
m_AutoConnect = autoConnect;
|
m_AutoConnect = autoConnect;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool AppConfig::elevateMode()
|
||||||
|
{
|
||||||
|
return m_ElevateMode;
|
||||||
|
}
|
||||||
|
|
|
@ -78,6 +78,7 @@ class AppConfig
|
||||||
|
|
||||||
bool detectPath(const QString& name, QString& path);
|
bool detectPath(const QString& name, QString& path);
|
||||||
void persistLogDir();
|
void persistLogDir();
|
||||||
|
bool elevateMode();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QSettings& settings() { return *m_pSettings; }
|
QSettings& settings() { return *m_pSettings; }
|
||||||
|
@ -91,6 +92,7 @@ class AppConfig
|
||||||
void setWizardHasRun() { m_WizardLastRun = kWizardVersion; }
|
void setWizardHasRun() { m_WizardLastRun = kWizardVersion; }
|
||||||
void setLanguage(const QString language) { m_Language = language; }
|
void setLanguage(const QString language) { m_Language = language; }
|
||||||
void setStartedBefore(bool b) { m_StartedBefore = b; }
|
void setStartedBefore(bool b) { m_StartedBefore = b; }
|
||||||
|
void setElevateMode(bool b) { m_ElevateMode = b; }
|
||||||
|
|
||||||
void loadSettings();
|
void loadSettings();
|
||||||
void saveSettings();
|
void saveSettings();
|
||||||
|
@ -112,6 +114,7 @@ class AppConfig
|
||||||
QString m_Language;
|
QString m_Language;
|
||||||
bool m_StartedBefore;
|
bool m_StartedBefore;
|
||||||
bool m_AutoConnect;
|
bool m_AutoConnect;
|
||||||
|
bool m_ElevateMode;
|
||||||
|
|
||||||
static const char m_SynergysName[];
|
static const char m_SynergysName[];
|
||||||
static const char m_SynergycName[];
|
static const char m_SynergycName[];
|
||||||
|
|
|
@ -70,8 +70,6 @@ MainWindow::MainWindow(QSettings& settings, AppConfig& appConfig) :
|
||||||
m_pTrayIcon(NULL),
|
m_pTrayIcon(NULL),
|
||||||
m_pTrayIconMenu(NULL),
|
m_pTrayIconMenu(NULL),
|
||||||
m_AlreadyHidden(false),
|
m_AlreadyHidden(false),
|
||||||
m_ElevateProcess(false),
|
|
||||||
m_SuppressElevateWarning(false),
|
|
||||||
m_pMenuBar(NULL),
|
m_pMenuBar(NULL),
|
||||||
m_pMenuFile(NULL),
|
m_pMenuFile(NULL),
|
||||||
m_pMenuEdit(NULL),
|
m_pMenuEdit(NULL),
|
||||||
|
@ -96,9 +94,6 @@ MainWindow::MainWindow(QSettings& settings, AppConfig& appConfig) :
|
||||||
connect(&m_IpcClient, SIGNAL(errorMessage(const QString&)), this, SLOT(appendLogError(const QString&)));
|
connect(&m_IpcClient, SIGNAL(errorMessage(const QString&)), this, SLOT(appendLogError(const QString&)));
|
||||||
connect(&m_IpcClient, SIGNAL(infoMessage(const QString&)), this, SLOT(appendLogNote(const QString&)));
|
connect(&m_IpcClient, SIGNAL(infoMessage(const QString&)), this, SLOT(appendLogNote(const QString&)));
|
||||||
m_IpcClient.connectToHost();
|
m_IpcClient.connectToHost();
|
||||||
#else
|
|
||||||
// elevate checkbox is only useful on ms windows.
|
|
||||||
m_pElevateCheckBox->hide();
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// change default size based on os
|
// change default size based on os
|
||||||
|
@ -162,8 +157,6 @@ void MainWindow::onModeChanged(bool startDesktop, bool applyService)
|
||||||
stopService();
|
stopService();
|
||||||
startSynergy();
|
startSynergy();
|
||||||
}
|
}
|
||||||
|
|
||||||
m_pElevateCheckBox->setEnabled(appConfig().processMode() == Service);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::setStatus(const QString &status)
|
void MainWindow::setStatus(const QString &status)
|
||||||
|
@ -245,10 +238,6 @@ void MainWindow::loadSettings()
|
||||||
m_pLineEditConfigFile->setText(settings().value("configFile", QDir::homePath() + "/" + synergyConfigName).toString());
|
m_pLineEditConfigFile->setText(settings().value("configFile", QDir::homePath() + "/" + synergyConfigName).toString());
|
||||||
m_pGroupClient->setChecked(settings().value("groupClientChecked", true).toBool());
|
m_pGroupClient->setChecked(settings().value("groupClientChecked", true).toBool());
|
||||||
m_pLineEditHostname->setText(settings().value("serverHostname").toString());
|
m_pLineEditHostname->setText(settings().value("serverHostname").toString());
|
||||||
|
|
||||||
m_SuppressElevateWarning = true;
|
|
||||||
m_pElevateCheckBox->setChecked(settings().value("elevateChecked", false).toBool());
|
|
||||||
m_SuppressElevateWarning = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::initConnections()
|
void MainWindow::initConnections()
|
||||||
|
@ -476,7 +465,7 @@ void MainWindow::startSynergy()
|
||||||
if (serviceMode)
|
if (serviceMode)
|
||||||
{
|
{
|
||||||
QString command(app + " " + args.join(" "));
|
QString command(app + " " + args.join(" "));
|
||||||
m_IpcClient.sendCommand(command, m_ElevateProcess);
|
m_IpcClient.sendCommand(command, appConfig().elevateMode());
|
||||||
}
|
}
|
||||||
|
|
||||||
appConfig().setStartedBefore(true);
|
appConfig().setStartedBefore(true);
|
||||||
|
@ -624,7 +613,7 @@ void MainWindow::stopSynergy()
|
||||||
void MainWindow::stopService()
|
void MainWindow::stopService()
|
||||||
{
|
{
|
||||||
// send empty command to stop service from laucning anything.
|
// send empty command to stop service from laucning anything.
|
||||||
m_IpcClient.sendCommand("", m_ElevateProcess);
|
m_IpcClient.sendCommand("", appConfig().elevateMode());
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::stopDesktop()
|
void MainWindow::stopDesktop()
|
||||||
|
@ -896,28 +885,6 @@ void MainWindow::on_m_pActionWizard_triggered()
|
||||||
wizard.exec();
|
wizard.exec();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::on_m_pElevateCheckBox_toggled(bool checked)
|
|
||||||
{
|
|
||||||
if (checked && !m_SuppressElevateWarning) {
|
|
||||||
int r = QMessageBox::warning(
|
|
||||||
this, tr("Elevate Synergy"),
|
|
||||||
tr("Are you sure you want to elevate Synergy?\n\n"
|
|
||||||
"This allows Synergy to interact with elevated processes "
|
|
||||||
"and the UAC dialog, but can cause problems with non-elevated "
|
|
||||||
"processes. Elevate Synergy only if you really need to."),
|
|
||||||
QMessageBox::Yes | QMessageBox::No);
|
|
||||||
|
|
||||||
if (r != QMessageBox::Yes) {
|
|
||||||
m_pElevateCheckBox->setChecked(false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_ElevateProcess = checked;
|
|
||||||
settings().setValue("elevateChecked", checked);
|
|
||||||
settings().sync();
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::on_m_pButtonApply_clicked()
|
void MainWindow::on_m_pButtonApply_clicked()
|
||||||
{
|
{
|
||||||
startSynergy();
|
startSynergy();
|
||||||
|
|
|
@ -114,7 +114,6 @@ class MainWindow : public QMainWindow, public Ui::MainWindowBase
|
||||||
void on_m_pActionAbout_triggered();
|
void on_m_pActionAbout_triggered();
|
||||||
void on_m_pActionSettings_triggered();
|
void on_m_pActionSettings_triggered();
|
||||||
void on_m_pActionWizard_triggered();
|
void on_m_pActionWizard_triggered();
|
||||||
void on_m_pElevateCheckBox_toggled(bool checked);
|
|
||||||
void synergyFinished(int exitCode, QProcess::ExitStatus);
|
void synergyFinished(int exitCode, QProcess::ExitStatus);
|
||||||
void trayActivated(QSystemTrayIcon::ActivationReason reason);
|
void trayActivated(QSystemTrayIcon::ActivationReason reason);
|
||||||
void stopSynergy();
|
void stopSynergy();
|
||||||
|
@ -160,8 +159,6 @@ class MainWindow : public QMainWindow, public Ui::MainWindowBase
|
||||||
bool m_AlreadyHidden;
|
bool m_AlreadyHidden;
|
||||||
VersionChecker m_VersionChecker;
|
VersionChecker m_VersionChecker;
|
||||||
IpcClient m_IpcClient;
|
IpcClient m_IpcClient;
|
||||||
bool m_ElevateProcess;
|
|
||||||
bool m_SuppressElevateWarning;
|
|
||||||
QMenuBar* m_pMenuBar;
|
QMenuBar* m_pMenuBar;
|
||||||
QMenu* m_pMenuFile;
|
QMenu* m_pMenuFile;
|
||||||
QMenu* m_pMenuEdit;
|
QMenu* m_pMenuEdit;
|
||||||
|
|
|
@ -30,7 +30,8 @@
|
||||||
SettingsDialog::SettingsDialog(QWidget* parent, AppConfig& config) :
|
SettingsDialog::SettingsDialog(QWidget* parent, AppConfig& config) :
|
||||||
QDialog(parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint),
|
QDialog(parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint),
|
||||||
Ui::SettingsDialogBase(),
|
Ui::SettingsDialogBase(),
|
||||||
m_AppConfig(config)
|
m_AppConfig(config),
|
||||||
|
m_SuppressElevateWarning(false)
|
||||||
{
|
{
|
||||||
setupUi(this);
|
setupUi(this);
|
||||||
|
|
||||||
|
@ -48,6 +49,15 @@ SettingsDialog::SettingsDialog(QWidget* parent, AppConfig& config) :
|
||||||
{
|
{
|
||||||
m_pLineEditCryptoPass->setText(appConfig().cryptoPass());
|
m_pLineEditCryptoPass->setText(appConfig().cryptoPass());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(Q_OS_WIN)
|
||||||
|
m_SuppressElevateWarning = true;
|
||||||
|
m_pCheckBoxElevateMode->setChecked(appConfig().elevateMode());
|
||||||
|
m_SuppressElevateWarning = false;
|
||||||
|
#else
|
||||||
|
// elevate checkbox is only useful on ms windows.
|
||||||
|
m_pCheckBoxElevateMode->hide();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void SettingsDialog::accept()
|
void SettingsDialog::accept()
|
||||||
|
@ -73,6 +83,7 @@ void SettingsDialog::accept()
|
||||||
appConfig().setCryptoEnabled(cryptoEnabled);
|
appConfig().setCryptoEnabled(cryptoEnabled);
|
||||||
appConfig().setCryptoPass(cryptoPass);
|
appConfig().setCryptoPass(cryptoPass);
|
||||||
appConfig().setLanguage(m_pComboLanguage->itemData(m_pComboLanguage->currentIndex()).toString());
|
appConfig().setLanguage(m_pComboLanguage->itemData(m_pComboLanguage->currentIndex()).toString());
|
||||||
|
appConfig().setElevateMode(m_pCheckBoxElevateMode->isChecked());
|
||||||
appConfig().saveSettings();
|
appConfig().saveSettings();
|
||||||
QDialog::accept();
|
QDialog::accept();
|
||||||
}
|
}
|
||||||
|
@ -144,3 +155,21 @@ void SettingsDialog::on_m_pComboLanguage_currentIndexChanged(int index)
|
||||||
QString ietfCode = m_pComboLanguage->itemData(index).toString();
|
QString ietfCode = m_pComboLanguage->itemData(index).toString();
|
||||||
QSynergyApplication::getInstance()->switchTranslator(ietfCode);
|
QSynergyApplication::getInstance()->switchTranslator(ietfCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SettingsDialog::on_m_pCheckBoxElevateMode_toggled(bool checked)
|
||||||
|
{
|
||||||
|
if (checked && !m_SuppressElevateWarning) {
|
||||||
|
int r = QMessageBox::warning(
|
||||||
|
this, tr("Elevate Synergy"),
|
||||||
|
tr("Are you sure you want to elevate Synergy?\n\n"
|
||||||
|
"This allows Synergy to interact with elevated processes "
|
||||||
|
"and the UAC dialog, but can cause problems with non-elevated "
|
||||||
|
"processes. Elevate Synergy only if you really need to."),
|
||||||
|
QMessageBox::Yes | QMessageBox::No);
|
||||||
|
|
||||||
|
if (r != QMessageBox::Yes) {
|
||||||
|
m_pCheckBoxElevateMode->setChecked(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -44,8 +44,10 @@ class SettingsDialog : public QDialog, public Ui::SettingsDialogBase
|
||||||
private:
|
private:
|
||||||
AppConfig& m_AppConfig;
|
AppConfig& m_AppConfig;
|
||||||
SynergyLocale m_Locale;
|
SynergyLocale m_Locale;
|
||||||
|
bool m_SuppressElevateWarning;
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
void on_m_pCheckBoxElevateMode_toggled(bool checked);
|
||||||
void on_m_pCheckBoxEnableCrypto_stateChanged(int );
|
void on_m_pCheckBoxEnableCrypto_stateChanged(int );
|
||||||
void on_m_pComboLanguage_currentIndexChanged(int index);
|
void on_m_pComboLanguage_currentIndexChanged(int index);
|
||||||
void on_m_pCheckBoxLogToFile_stateChanged(int );
|
void on_m_pCheckBoxLogToFile_stateChanged(int );
|
||||||
|
|
|
@ -171,3 +171,21 @@ CMSWindowsSession::nextProcessEntry(HANDLE snapshot, LPPROCESSENTRY32 entry)
|
||||||
|
|
||||||
return gotEntry;
|
return gotEntry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CString
|
||||||
|
CMSWindowsSession::getActiveDesktopName()
|
||||||
|
{
|
||||||
|
CString result;
|
||||||
|
|
||||||
|
HDESK hd = OpenInputDesktop(0, TRUE, GENERIC_READ);
|
||||||
|
if (hd != NULL) {
|
||||||
|
DWORD size;
|
||||||
|
GetUserObjectInformation(hd, UOI_NAME, NULL, 0, &size);
|
||||||
|
TCHAR* name = (TCHAR*)alloca(size + sizeof(TCHAR));
|
||||||
|
GetUserObjectInformation(hd, UOI_NAME, name, size, &size);
|
||||||
|
result = name;
|
||||||
|
CloseDesktop(hd);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
|
@ -17,6 +17,8 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "base/String.h"
|
||||||
|
|
||||||
#define WIN32_LEAN_AND_MEAN
|
#define WIN32_LEAN_AND_MEAN
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
#include <Tlhelp32.h>
|
#include <Tlhelp32.h>
|
||||||
|
@ -40,6 +42,8 @@ public:
|
||||||
|
|
||||||
void updateActiveSession();
|
void updateActiveSession();
|
||||||
|
|
||||||
|
CString getActiveDesktopName();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BOOL nextProcessEntry(HANDLE snapshot, LPPROCESSENTRY32 entry);
|
BOOL nextProcessEntry(HANDLE snapshot, LPPROCESSENTRY32 entry);
|
||||||
|
|
||||||
|
|
|
@ -43,6 +43,8 @@ enum {
|
||||||
|
|
||||||
typedef VOID (WINAPI *SendSas)(BOOL asUser);
|
typedef VOID (WINAPI *SendSas)(BOOL asUser);
|
||||||
|
|
||||||
|
const char g_activeDesktop[] = {"activeDesktop:"};
|
||||||
|
|
||||||
CMSWindowsWatchdog::CMSWindowsWatchdog(
|
CMSWindowsWatchdog::CMSWindowsWatchdog(
|
||||||
bool autoDetectCommand,
|
bool autoDetectCommand,
|
||||||
CIpcServer& ipcServer,
|
CIpcServer& ipcServer,
|
||||||
|
@ -58,12 +60,23 @@ CMSWindowsWatchdog::CMSWindowsWatchdog(
|
||||||
m_elevateProcess(false),
|
m_elevateProcess(false),
|
||||||
m_processFailures(0),
|
m_processFailures(0),
|
||||||
m_processRunning(false),
|
m_processRunning(false),
|
||||||
m_fileLogOutputter(NULL)
|
m_fileLogOutputter(NULL),
|
||||||
|
m_autoElevated(false),
|
||||||
|
m_ready(false)
|
||||||
{
|
{
|
||||||
|
m_mutex = ARCH->newMutex();
|
||||||
|
m_condVar = ARCH->newCondVar();
|
||||||
}
|
}
|
||||||
|
|
||||||
CMSWindowsWatchdog::~CMSWindowsWatchdog()
|
CMSWindowsWatchdog::~CMSWindowsWatchdog()
|
||||||
{
|
{
|
||||||
|
if (m_condVar != NULL) {
|
||||||
|
ARCH->closeCondVar(m_condVar);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_mutex != NULL) {
|
||||||
|
ARCH->closeMutex(m_mutex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -126,7 +139,9 @@ CMSWindowsWatchdog::getUserToken(LPSECURITY_ATTRIBUTES security)
|
||||||
// elevate for the uac dialog (consent.exe) but this would be pointless,
|
// elevate for the uac dialog (consent.exe) but this would be pointless,
|
||||||
// since synergy would re-launch as non-elevated after the desk switch,
|
// since synergy would re-launch as non-elevated after the desk switch,
|
||||||
// and so would be unusable with the new elevated process taking focus.
|
// and so would be unusable with the new elevated process taking focus.
|
||||||
if (m_elevateProcess || m_session.isProcessInSession("logonui.exe", NULL)) {
|
if (m_elevateProcess
|
||||||
|
|| m_autoElevated
|
||||||
|
|| m_session.isProcessInSession("logonui.exe", NULL)) {
|
||||||
|
|
||||||
LOG((CLOG_DEBUG "getting elevated token, %s",
|
LOG((CLOG_DEBUG "getting elevated token, %s",
|
||||||
(m_elevateProcess ? "elevation required" : "at login screen")));
|
(m_elevateProcess ? "elevation required" : "at login screen")));
|
||||||
|
@ -273,7 +288,11 @@ CMSWindowsWatchdog::startProcess()
|
||||||
SECURITY_ATTRIBUTES sa;
|
SECURITY_ATTRIBUTES sa;
|
||||||
ZeroMemory(&sa, sizeof(SECURITY_ATTRIBUTES));
|
ZeroMemory(&sa, sizeof(SECURITY_ATTRIBUTES));
|
||||||
|
|
||||||
|
getActiveDesktop(&sa);
|
||||||
|
|
||||||
|
ZeroMemory(&sa, sizeof(SECURITY_ATTRIBUTES));
|
||||||
HANDLE userToken = getUserToken(&sa);
|
HANDLE userToken = getUserToken(&sa);
|
||||||
|
m_autoElevated = false;
|
||||||
|
|
||||||
// patch by Jack Zhou and Henry Tung
|
// patch by Jack Zhou and Henry Tung
|
||||||
// set UIAccess to fix Windows 8 GUI interaction
|
// set UIAccess to fix Windows 8 GUI interaction
|
||||||
|
@ -281,6 +300,33 @@ CMSWindowsWatchdog::startProcess()
|
||||||
DWORD uiAccess = 1;
|
DWORD uiAccess = 1;
|
||||||
SetTokenInformation(userToken, TokenUIAccess, &uiAccess, sizeof(DWORD));
|
SetTokenInformation(userToken, TokenUIAccess, &uiAccess, sizeof(DWORD));
|
||||||
|
|
||||||
|
BOOL createRet = doStartProcess(m_command, userToken, &sa);
|
||||||
|
|
||||||
|
if (!createRet) {
|
||||||
|
LOG((CLOG_ERR "could not launch"));
|
||||||
|
DWORD exitCode = 0;
|
||||||
|
GetExitCodeProcess(m_processInfo.hProcess, &exitCode);
|
||||||
|
LOG((CLOG_ERR "exit code: %d", exitCode));
|
||||||
|
throw XArch(new XArchEvalWindows);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// wait for program to fail.
|
||||||
|
ARCH->sleep(1);
|
||||||
|
if (!isProcessActive()) {
|
||||||
|
throw XMSWindowsWatchdogError("process immediately stopped");
|
||||||
|
}
|
||||||
|
|
||||||
|
m_processRunning = true;
|
||||||
|
m_processFailures = 0;
|
||||||
|
|
||||||
|
LOG((CLOG_DEBUG "started process, session=%i, command=%s",
|
||||||
|
m_session.getActiveSessionId(), m_command.c_str()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
CMSWindowsWatchdog::doStartProcess(CString& command, HANDLE userToken, LPSECURITY_ATTRIBUTES sa)
|
||||||
|
{
|
||||||
// clear, as we're reusing process info struct
|
// clear, as we're reusing process info struct
|
||||||
ZeroMemory(&m_processInfo, sizeof(PROCESS_INFORMATION));
|
ZeroMemory(&m_processInfo, sizeof(PROCESS_INFORMATION));
|
||||||
|
|
||||||
|
@ -307,30 +353,14 @@ CMSWindowsWatchdog::startProcess()
|
||||||
// re-launch in current active user session
|
// re-launch in current active user session
|
||||||
LOG((CLOG_INFO "starting new process"));
|
LOG((CLOG_INFO "starting new process"));
|
||||||
BOOL createRet = CreateProcessAsUser(
|
BOOL createRet = CreateProcessAsUser(
|
||||||
userToken, NULL, LPSTR(m_command.c_str()),
|
userToken, NULL, LPSTR(command.c_str()),
|
||||||
&sa, NULL, TRUE, creationFlags,
|
sa, NULL, TRUE, creationFlags,
|
||||||
environment, NULL, &si, &m_processInfo);
|
environment, NULL, &si, &m_processInfo);
|
||||||
|
|
||||||
DestroyEnvironmentBlock(environment);
|
DestroyEnvironmentBlock(environment);
|
||||||
CloseHandle(userToken);
|
CloseHandle(userToken);
|
||||||
|
|
||||||
if (!createRet) {
|
return createRet;
|
||||||
LOG((CLOG_ERR "could not launch"));
|
|
||||||
throw XArch(new XArchEvalWindows);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// wait for program to fail.
|
|
||||||
ARCH->sleep(1);
|
|
||||||
if (!isProcessActive()) {
|
|
||||||
throw XMSWindowsWatchdogError("process immediately stopped");
|
|
||||||
}
|
|
||||||
|
|
||||||
m_processRunning = true;
|
|
||||||
m_processFailures = 0;
|
|
||||||
|
|
||||||
LOG((CLOG_DEBUG "started process, session=%i, command=%s",
|
|
||||||
m_session.getActiveSessionId(), m_command.c_str()));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -388,6 +418,8 @@ CMSWindowsWatchdog::outputLoop(void*)
|
||||||
else {
|
else {
|
||||||
buffer[bytesRead] = '\0';
|
buffer[bytesRead] = '\0';
|
||||||
|
|
||||||
|
testOutput(buffer);
|
||||||
|
|
||||||
// send process output over IPC to GUI, and force it to be sent
|
// send process output over IPC to GUI, and force it to be sent
|
||||||
// which bypasses the ipc logging anti-recursion mechanism.
|
// which bypasses the ipc logging anti-recursion mechanism.
|
||||||
m_ipcLogOutputter.write(kINFO, buffer, true);
|
m_ipcLogOutputter.write(kINFO, buffer, true);
|
||||||
|
@ -492,3 +524,57 @@ CMSWindowsWatchdog::shutdownExistingProcesses()
|
||||||
CloseHandle(snapshot);
|
CloseHandle(snapshot);
|
||||||
m_processRunning = false;
|
m_processRunning = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CMSWindowsWatchdog::getActiveDesktop(LPSECURITY_ATTRIBUTES security)
|
||||||
|
{
|
||||||
|
CString installedDir = ARCH->getInstalledDirectory();
|
||||||
|
if (!installedDir.empty()) {
|
||||||
|
CString syntoolCommand;
|
||||||
|
syntoolCommand.append("\"").append(installedDir).append("\\").append("syntool").append("\"");
|
||||||
|
syntoolCommand.append(" --get-active-desktop");
|
||||||
|
|
||||||
|
m_session.updateActiveSession();
|
||||||
|
bool elevateProcess = m_elevateProcess;
|
||||||
|
m_elevateProcess = true;
|
||||||
|
HANDLE userToken = getUserToken(security);
|
||||||
|
m_elevateProcess = elevateProcess;
|
||||||
|
|
||||||
|
BOOL createRet = doStartProcess(syntoolCommand, userToken, security);
|
||||||
|
|
||||||
|
if (!createRet) {
|
||||||
|
DWORD rc = GetLastError();
|
||||||
|
RevertToSelf();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
LOG((CLOG_DEBUG "launched syntool to check active desktop"));
|
||||||
|
}
|
||||||
|
|
||||||
|
ARCH->lockMutex(m_mutex);
|
||||||
|
while (!m_ready) {
|
||||||
|
ARCH->waitCondVar(m_condVar, m_mutex, 1.0);
|
||||||
|
}
|
||||||
|
m_ready = false;
|
||||||
|
ARCH->unlockMutex(m_mutex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CMSWindowsWatchdog::testOutput(CString buffer)
|
||||||
|
{
|
||||||
|
// HACK: check standard output seems hacky.
|
||||||
|
size_t i = buffer.find(g_activeDesktop);
|
||||||
|
if (i != CString::npos) {
|
||||||
|
size_t s = sizeof(g_activeDesktop);
|
||||||
|
CString defaultDesktop("Default");
|
||||||
|
CString sub = buffer.substr(s - 1, defaultDesktop.size());
|
||||||
|
if (sub != defaultDesktop) {
|
||||||
|
m_autoElevated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
ARCH->lockMutex(m_mutex);
|
||||||
|
m_ready = true;
|
||||||
|
ARCH->broadcastCondVar(m_condVar);
|
||||||
|
ARCH->unlockMutex(m_mutex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
|
|
||||||
#include "platform/MSWindowsSession.h"
|
#include "platform/MSWindowsSession.h"
|
||||||
#include "synergy/XSynergy.h"
|
#include "synergy/XSynergy.h"
|
||||||
|
#include "arch/IArchMultithread.h"
|
||||||
|
|
||||||
#define WIN32_LEAN_AND_MEAN
|
#define WIN32_LEAN_AND_MEAN
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
|
@ -54,7 +55,10 @@ private:
|
||||||
HANDLE duplicateProcessToken(HANDLE process, LPSECURITY_ATTRIBUTES security);
|
HANDLE duplicateProcessToken(HANDLE process, LPSECURITY_ATTRIBUTES security);
|
||||||
HANDLE getUserToken(LPSECURITY_ATTRIBUTES security);
|
HANDLE getUserToken(LPSECURITY_ATTRIBUTES security);
|
||||||
void startProcess();
|
void startProcess();
|
||||||
|
BOOL doStartProcess(CString& command, HANDLE userToken, LPSECURITY_ATTRIBUTES sa);
|
||||||
void sendSas();
|
void sendSas();
|
||||||
|
void getActiveDesktop(LPSECURITY_ATTRIBUTES security);
|
||||||
|
void testOutput(CString buffer);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CThread* m_thread;
|
CThread* m_thread;
|
||||||
|
@ -73,6 +77,10 @@ private:
|
||||||
int m_processFailures;
|
int m_processFailures;
|
||||||
bool m_processRunning;
|
bool m_processRunning;
|
||||||
CFileLogOutputter* m_fileLogOutputter;
|
CFileLogOutputter* m_fileLogOutputter;
|
||||||
|
bool m_autoElevated;
|
||||||
|
CArchMutex m_mutex;
|
||||||
|
CArchCond m_condVar;
|
||||||
|
bool m_ready;
|
||||||
};
|
};
|
||||||
|
|
||||||
//! Relauncher error
|
//! Relauncher error
|
||||||
|
|
|
@ -244,3 +244,80 @@ CApp::runEventsLoop(void*)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// CMinimalApp
|
||||||
|
//
|
||||||
|
|
||||||
|
CMinimalApp::CMinimalApp() :
|
||||||
|
CApp(NULL, NULL, new CArgsBase())
|
||||||
|
{
|
||||||
|
setEvents(m_events);
|
||||||
|
}
|
||||||
|
|
||||||
|
CMinimalApp::~CMinimalApp()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
CMinimalApp::standardStartup(int argc, char** argv)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
CMinimalApp::runInner(int argc, char** argv, ILogOutputter* outputter, StartupFunc startup)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CMinimalApp::startNode()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
CMinimalApp::mainLoop()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
CMinimalApp::foregroundStartup(int argc, char** argv)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
CScreen*
|
||||||
|
CMinimalApp::createScreen()
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CMinimalApp::loadConfig()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
CMinimalApp::loadConfig(const CString& pathname)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char*
|
||||||
|
CMinimalApp::daemonInfo() const
|
||||||
|
{
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
const char*
|
||||||
|
CMinimalApp::daemonName() const
|
||||||
|
{
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CMinimalApp::parseArgs(int argc, const char* const* argv)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
|
@ -18,10 +18,12 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "common/common.h"
|
|
||||||
#include "base/String.h"
|
|
||||||
#include "synergy/IApp.h"
|
|
||||||
#include "ipc/IpcClient.h"
|
#include "ipc/IpcClient.h"
|
||||||
|
#include "synergy/IApp.h"
|
||||||
|
#include "base/String.h"
|
||||||
|
#include "base/Log.h"
|
||||||
|
#include "base/EventQueue.h"
|
||||||
|
#include "common/common.h"
|
||||||
|
|
||||||
#if SYSAPI_WIN32
|
#if SYSAPI_WIN32
|
||||||
#include "synergy/win32/AppUtilWindows.h"
|
#include "synergy/win32/AppUtilWindows.h"
|
||||||
|
@ -96,6 +98,8 @@ public:
|
||||||
void setSocketMultiplexer(CSocketMultiplexer* sm) { m_socketMultiplexer = sm; }
|
void setSocketMultiplexer(CSocketMultiplexer* sm) { m_socketMultiplexer = sm; }
|
||||||
CSocketMultiplexer* getSocketMultiplexer() const { return m_socketMultiplexer; }
|
CSocketMultiplexer* getSocketMultiplexer() const { return m_socketMultiplexer; }
|
||||||
|
|
||||||
|
void setEvents(CEventQueue& events) { m_events = &events; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void handleIpcMessage(const CEvent&, void*);
|
void handleIpcMessage(const CEvent&, void*);
|
||||||
|
|
||||||
|
@ -118,6 +122,30 @@ private:
|
||||||
CSocketMultiplexer* m_socketMultiplexer;
|
CSocketMultiplexer* m_socketMultiplexer;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class CMinimalApp : public CApp {
|
||||||
|
public:
|
||||||
|
CMinimalApp();
|
||||||
|
virtual ~CMinimalApp();
|
||||||
|
|
||||||
|
// IApp overrides
|
||||||
|
virtual int standardStartup(int argc, char** argv);
|
||||||
|
virtual int runInner(int argc, char** argv, ILogOutputter* outputter, StartupFunc startup);
|
||||||
|
virtual void startNode();
|
||||||
|
virtual int mainLoop();
|
||||||
|
virtual int foregroundStartup(int argc, char** argv);
|
||||||
|
virtual CScreen* createScreen();
|
||||||
|
virtual void loadConfig();
|
||||||
|
virtual bool loadConfig(const CString& pathname);
|
||||||
|
virtual const char* daemonInfo() const;
|
||||||
|
virtual const char* daemonName() const;
|
||||||
|
virtual void parseArgs(int argc, const char* const* argv);
|
||||||
|
|
||||||
|
private:
|
||||||
|
CArch m_arch;
|
||||||
|
CLog m_log;
|
||||||
|
CEventQueue m_events;
|
||||||
|
};
|
||||||
|
|
||||||
#if WINAPI_MSWINDOWS
|
#if WINAPI_MSWINDOWS
|
||||||
#define DAEMON_RUNNING(running_) CArchMiscWindows::daemonRunning(running_)
|
#define DAEMON_RUNNING(running_) CArchMiscWindows::daemonRunning(running_)
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include "synergy/App.h"
|
#include "synergy/App.h"
|
||||||
#include "synergy/ServerArgs.h"
|
#include "synergy/ServerArgs.h"
|
||||||
#include "synergy/ClientArgs.h"
|
#include "synergy/ClientArgs.h"
|
||||||
|
#include "synergy/ToolArgs.h"
|
||||||
#include "synergy/ArgsBase.h"
|
#include "synergy/ArgsBase.h"
|
||||||
#include "base/Log.h"
|
#include "base/Log.h"
|
||||||
|
|
||||||
|
@ -155,6 +156,23 @@ CArgParser::parsePlatformArg(CArgsBase& argsBase, const int& argc, const char* c
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
CArgParser::parseToolArgs(CToolArgs& args, int argc, const char* const* argv)
|
||||||
|
{
|
||||||
|
for (int i = 1; i < argc; ++i) {
|
||||||
|
if (isArg(i, argc, argv, NULL, "--get-active-desktop", 0)) {
|
||||||
|
args.m_printActiveDesktopName = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
CArgParser::parseGenericArgs(int argc, const char* const* argv, int& i)
|
CArgParser::parseGenericArgs(int argc, const char* const* argv, int& i)
|
||||||
{
|
{
|
||||||
|
|
|
@ -34,6 +34,7 @@ public:
|
||||||
bool parseServerArgs(CServerArgs& args, int argc, const char* const* argv);
|
bool parseServerArgs(CServerArgs& args, int argc, const char* const* argv);
|
||||||
bool parseClientArgs(CClientArgs& args, int argc, const char* const* argv);
|
bool parseClientArgs(CClientArgs& args, int argc, const char* const* argv);
|
||||||
bool parsePlatformArg(CArgsBase& argsBase, const int& argc, const char* const* argv, int& i);
|
bool parsePlatformArg(CArgsBase& argsBase, const int& argc, const char* const* argv, int& i);
|
||||||
|
bool parseToolArgs(CToolArgs& args, int argc, const char* const* argv);
|
||||||
bool parseGenericArgs(int argc, const char* const* argv, int& i);
|
bool parseGenericArgs(int argc, const char* const* argv, int& i);
|
||||||
void setArgsBase(CArgsBase& argsBase) { m_argsBase = &argsBase; }
|
void setArgsBase(CArgsBase& argsBase) { m_argsBase = &argsBase; }
|
||||||
|
|
||||||
|
|
|
@ -16,14 +16,18 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "synergy/ToolApp.h"
|
#include "synergy/ToolApp.h"
|
||||||
|
|
||||||
|
#include "synergy/ArgParser.h"
|
||||||
#include "arch/Arch.h"
|
#include "arch/Arch.h"
|
||||||
|
#include "base/Log.h"
|
||||||
#include "base/String.h"
|
#include "base/String.h"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
//#define PREMIUM_AUTH_URL "http://localhost/synergy/premium/json/auth/"
|
#if SYSAPI_WIN32
|
||||||
#define PREMIUM_AUTH_URL "https://synergy-project.org/premium/json/auth/"
|
#include "platform/MSWindowsSession.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
kErrorOk,
|
kErrorOk,
|
||||||
|
@ -41,43 +45,43 @@ CToolApp::run(int argc, char** argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
for (int i = 1; i < argc; i++) {
|
CArgParser argParser(this);
|
||||||
if (strcmp(argv[i], "--premium-auth") == 0) {
|
bool result = argParser.parseToolArgs(m_args, argc, argv);
|
||||||
premiumAuth();
|
|
||||||
return kErrorOk;
|
if (!result) {
|
||||||
|
m_bye(kExitArgs);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_args.m_printActiveDesktopName) {
|
||||||
|
#if SYSAPI_WIN32
|
||||||
|
CMSWindowsSession session;
|
||||||
|
CString name = session.getActiveDesktopName();
|
||||||
|
if (name.empty()) {
|
||||||
|
LOG((CLOG_CRIT "failed to get active desktop name"));
|
||||||
|
return kExitFailed;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
std::cerr << "unknown arg: " << argv[i] << std::endl;
|
std::cout << "activeDesktop:" << name.c_str() << std::endl;
|
||||||
return kErrorArgs;
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw XSynergy("Nothing to do");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (std::exception& e) {
|
catch (std::exception& e) {
|
||||||
std::cerr << e.what() << std::endl;
|
LOG((CLOG_CRIT "An error occurred: %s\n", e.what()));
|
||||||
return kErrorException;
|
return kExitFailed;
|
||||||
}
|
}
|
||||||
catch (...) {
|
catch (...) {
|
||||||
std::cerr << "unknown error" << std::endl;
|
LOG((CLOG_CRIT "An unknown error occurred.\n"));
|
||||||
return kErrorUnknown;
|
return kExitFailed;
|
||||||
}
|
}
|
||||||
|
|
||||||
return kErrorOk;
|
return kErrorOk;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
CToolApp::premiumAuth()
|
CToolApp::help()
|
||||||
{
|
{
|
||||||
CString credentials;
|
|
||||||
std::cin >> credentials;
|
|
||||||
|
|
||||||
size_t separator = credentials.find(':');
|
|
||||||
CString email = credentials.substr(0, separator);
|
|
||||||
CString password = credentials.substr(separator + 1, credentials.length());
|
|
||||||
|
|
||||||
std::stringstream ss;
|
|
||||||
ss << PREMIUM_AUTH_URL;
|
|
||||||
ss << "?email=" << ARCH->internet().urlEncode(email);
|
|
||||||
ss << "&password=" << password;
|
|
||||||
|
|
||||||
std::cout << ARCH->internet().get(ss.str()) << std::endl;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,12 +17,15 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "synergy/App.h"
|
||||||
|
#include "synergy/ToolArgs.h"
|
||||||
#include "common/basic_types.h"
|
#include "common/basic_types.h"
|
||||||
|
|
||||||
class CToolApp {
|
class CToolApp : public CMinimalApp
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
UInt32 run(int argc, char** argv);
|
UInt32 run(int argc, char** argv);
|
||||||
|
void help();
|
||||||
private:
|
private:
|
||||||
void premiumAuth();
|
CToolArgs m_args;
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
/*
|
||||||
|
* synergy -- mouse and keyboard sharing utility
|
||||||
|
* Copyright (C) 2014 Synergy Si, Inc.
|
||||||
|
*
|
||||||
|
* This package is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* found in the file COPYING that should have accompanied this file.
|
||||||
|
*
|
||||||
|
* This package is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "synergy/ToolArgs.h"
|
||||||
|
|
||||||
|
CToolArgs::CToolArgs() :
|
||||||
|
m_printActiveDesktopName(false)
|
||||||
|
{
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
/*
|
||||||
|
* synergy -- mouse and keyboard sharing utility
|
||||||
|
* Copyright (C) 2014 Synergy Si, Inc.
|
||||||
|
*
|
||||||
|
* This package is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* found in the file COPYING that should have accompanied this file.
|
||||||
|
*
|
||||||
|
* This package is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "base/String.h"
|
||||||
|
|
||||||
|
class CToolArgs {
|
||||||
|
public:
|
||||||
|
CToolArgs();
|
||||||
|
|
||||||
|
public:
|
||||||
|
bool m_printActiveDesktopName;
|
||||||
|
};
|
Loading…
Reference in New Issue