diff --git a/src/gui/res/MainWindowBase.ui b/src/gui/res/MainWindowBase.ui
index 1706b293..a428a6a4 100644
--- a/src/gui/res/MainWindowBase.ui
+++ b/src/gui/res/MainWindowBase.ui
@@ -311,13 +311,6 @@
- -
-
-
- &Elevate
-
-
-
-
diff --git a/src/gui/res/SettingsDialogBase.ui b/src/gui/res/SettingsDialogBase.ui
index c37020a6..d45b69bc 100644
--- a/src/gui/res/SettingsDialogBase.ui
+++ b/src/gui/res/SettingsDialogBase.ui
@@ -114,6 +114,13 @@
-
+ -
+
+
+ Elevate mode
+
+
+
diff --git a/src/gui/src/AppConfig.cpp b/src/gui/src/AppConfig.cpp
index d5db337a..4f85ea65 100644
--- a/src/gui/src/AppConfig.cpp
+++ b/src/gui/src/AppConfig.cpp
@@ -54,7 +54,8 @@ AppConfig::AppConfig(QSettings* settings) :
m_WizardLastRun(0),
m_CryptoPass(),
m_ProcessMode(DEFAULT_PROCESS_MODE),
- m_AutoConnect(true)
+ m_AutoConnect(true),
+ m_ElevateMode(false)
{
Q_ASSERT(m_pSettings);
@@ -123,6 +124,7 @@ void AppConfig::loadSettings()
m_Language = settings().value("language", QLocale::system().name()).toString();
m_StartedBefore = settings().value("startedBefore", false).toBool();
m_AutoConnect = settings().value("autoConnect", true).toBool();
+ m_ElevateMode = settings().value("elevateMode", false).toBool();
}
void AppConfig::saveSettings()
@@ -139,6 +141,7 @@ void AppConfig::saveSettings()
settings().setValue("language", m_Language);
settings().setValue("startedBefore", m_StartedBefore);
settings().setValue("autoConnect", m_AutoConnect);
+ settings().setValue("elevateMode", m_ElevateMode);
}
void AppConfig::setCryptoPass(const QString &s)
@@ -161,3 +164,8 @@ void AppConfig::setAutoConnect(bool autoConnect)
{
m_AutoConnect = autoConnect;
}
+
+bool AppConfig::elevateMode()
+{
+ return m_ElevateMode;
+}
diff --git a/src/gui/src/AppConfig.h b/src/gui/src/AppConfig.h
index 2e716cfb..3b6bb622 100644
--- a/src/gui/src/AppConfig.h
+++ b/src/gui/src/AppConfig.h
@@ -78,6 +78,7 @@ class AppConfig
bool detectPath(const QString& name, QString& path);
void persistLogDir();
+ bool elevateMode();
protected:
QSettings& settings() { return *m_pSettings; }
@@ -91,6 +92,7 @@ class AppConfig
void setWizardHasRun() { m_WizardLastRun = kWizardVersion; }
void setLanguage(const QString language) { m_Language = language; }
void setStartedBefore(bool b) { m_StartedBefore = b; }
+ void setElevateMode(bool b) { m_ElevateMode = b; }
void loadSettings();
void saveSettings();
@@ -112,6 +114,7 @@ class AppConfig
QString m_Language;
bool m_StartedBefore;
bool m_AutoConnect;
+ bool m_ElevateMode;
static const char m_SynergysName[];
static const char m_SynergycName[];
diff --git a/src/gui/src/MainWindow.cpp b/src/gui/src/MainWindow.cpp
index f728c578..0c86a0e3 100644
--- a/src/gui/src/MainWindow.cpp
+++ b/src/gui/src/MainWindow.cpp
@@ -70,8 +70,6 @@ MainWindow::MainWindow(QSettings& settings, AppConfig& appConfig) :
m_pTrayIcon(NULL),
m_pTrayIconMenu(NULL),
m_AlreadyHidden(false),
- m_ElevateProcess(false),
- m_SuppressElevateWarning(false),
m_pMenuBar(NULL),
m_pMenuFile(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(infoMessage(const QString&)), this, SLOT(appendLogNote(const QString&)));
m_IpcClient.connectToHost();
-#else
- // elevate checkbox is only useful on ms windows.
- m_pElevateCheckBox->hide();
#endif
// change default size based on os
@@ -162,8 +157,6 @@ void MainWindow::onModeChanged(bool startDesktop, bool applyService)
stopService();
startSynergy();
}
-
- m_pElevateCheckBox->setEnabled(appConfig().processMode() == Service);
}
void MainWindow::setStatus(const QString &status)
@@ -245,10 +238,6 @@ void MainWindow::loadSettings()
m_pLineEditConfigFile->setText(settings().value("configFile", QDir::homePath() + "/" + synergyConfigName).toString());
m_pGroupClient->setChecked(settings().value("groupClientChecked", true).toBool());
m_pLineEditHostname->setText(settings().value("serverHostname").toString());
-
- m_SuppressElevateWarning = true;
- m_pElevateCheckBox->setChecked(settings().value("elevateChecked", false).toBool());
- m_SuppressElevateWarning = false;
}
void MainWindow::initConnections()
@@ -476,7 +465,7 @@ void MainWindow::startSynergy()
if (serviceMode)
{
QString command(app + " " + args.join(" "));
- m_IpcClient.sendCommand(command, m_ElevateProcess);
+ m_IpcClient.sendCommand(command, appConfig().elevateMode());
}
appConfig().setStartedBefore(true);
@@ -624,7 +613,7 @@ void MainWindow::stopSynergy()
void MainWindow::stopService()
{
// send empty command to stop service from laucning anything.
- m_IpcClient.sendCommand("", m_ElevateProcess);
+ m_IpcClient.sendCommand("", appConfig().elevateMode());
}
void MainWindow::stopDesktop()
@@ -896,28 +885,6 @@ void MainWindow::on_m_pActionWizard_triggered()
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()
{
startSynergy();
diff --git a/src/gui/src/MainWindow.h b/src/gui/src/MainWindow.h
index 560a81cd..48192342 100644
--- a/src/gui/src/MainWindow.h
+++ b/src/gui/src/MainWindow.h
@@ -114,7 +114,6 @@ class MainWindow : public QMainWindow, public Ui::MainWindowBase
void on_m_pActionAbout_triggered();
void on_m_pActionSettings_triggered();
void on_m_pActionWizard_triggered();
- void on_m_pElevateCheckBox_toggled(bool checked);
void synergyFinished(int exitCode, QProcess::ExitStatus);
void trayActivated(QSystemTrayIcon::ActivationReason reason);
void stopSynergy();
@@ -160,8 +159,6 @@ class MainWindow : public QMainWindow, public Ui::MainWindowBase
bool m_AlreadyHidden;
VersionChecker m_VersionChecker;
IpcClient m_IpcClient;
- bool m_ElevateProcess;
- bool m_SuppressElevateWarning;
QMenuBar* m_pMenuBar;
QMenu* m_pMenuFile;
QMenu* m_pMenuEdit;
diff --git a/src/gui/src/SettingsDialog.cpp b/src/gui/src/SettingsDialog.cpp
index 434dcd74..5983b362 100644
--- a/src/gui/src/SettingsDialog.cpp
+++ b/src/gui/src/SettingsDialog.cpp
@@ -30,7 +30,8 @@
SettingsDialog::SettingsDialog(QWidget* parent, AppConfig& config) :
QDialog(parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint),
Ui::SettingsDialogBase(),
- m_AppConfig(config)
+ m_AppConfig(config),
+ m_SuppressElevateWarning(false)
{
setupUi(this);
@@ -48,6 +49,15 @@ SettingsDialog::SettingsDialog(QWidget* parent, AppConfig& config) :
{
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()
@@ -73,6 +83,7 @@ void SettingsDialog::accept()
appConfig().setCryptoEnabled(cryptoEnabled);
appConfig().setCryptoPass(cryptoPass);
appConfig().setLanguage(m_pComboLanguage->itemData(m_pComboLanguage->currentIndex()).toString());
+ appConfig().setElevateMode(m_pCheckBoxElevateMode->isChecked());
appConfig().saveSettings();
QDialog::accept();
}
@@ -144,3 +155,21 @@ void SettingsDialog::on_m_pComboLanguage_currentIndexChanged(int index)
QString ietfCode = m_pComboLanguage->itemData(index).toString();
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;
+ }
+ }
+}
diff --git a/src/gui/src/SettingsDialog.h b/src/gui/src/SettingsDialog.h
index e107f79e..a0b6c6cf 100644
--- a/src/gui/src/SettingsDialog.h
+++ b/src/gui/src/SettingsDialog.h
@@ -44,8 +44,10 @@ class SettingsDialog : public QDialog, public Ui::SettingsDialogBase
private:
AppConfig& m_AppConfig;
SynergyLocale m_Locale;
+ bool m_SuppressElevateWarning;
private slots:
+ void on_m_pCheckBoxElevateMode_toggled(bool checked);
void on_m_pCheckBoxEnableCrypto_stateChanged(int );
void on_m_pComboLanguage_currentIndexChanged(int index);
void on_m_pCheckBoxLogToFile_stateChanged(int );
diff --git a/src/lib/platform/MSWindowsSession.cpp b/src/lib/platform/MSWindowsSession.cpp
index b9001a8d..a902bf16 100644
--- a/src/lib/platform/MSWindowsSession.cpp
+++ b/src/lib/platform/MSWindowsSession.cpp
@@ -171,3 +171,21 @@ CMSWindowsSession::nextProcessEntry(HANDLE snapshot, LPPROCESSENTRY32 entry)
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;
+}
diff --git a/src/lib/platform/MSWindowsSession.h b/src/lib/platform/MSWindowsSession.h
index d30ce0b4..b4f21243 100644
--- a/src/lib/platform/MSWindowsSession.h
+++ b/src/lib/platform/MSWindowsSession.h
@@ -17,6 +17,8 @@
#pragma once
+#include "base/String.h"
+
#define WIN32_LEAN_AND_MEAN
#include
#include
@@ -40,6 +42,8 @@ public:
void updateActiveSession();
+ CString getActiveDesktopName();
+
private:
BOOL nextProcessEntry(HANDLE snapshot, LPPROCESSENTRY32 entry);
diff --git a/src/lib/platform/MSWindowsWatchdog.cpp b/src/lib/platform/MSWindowsWatchdog.cpp
index 0dc020f2..8bf98b3c 100644
--- a/src/lib/platform/MSWindowsWatchdog.cpp
+++ b/src/lib/platform/MSWindowsWatchdog.cpp
@@ -43,6 +43,8 @@ enum {
typedef VOID (WINAPI *SendSas)(BOOL asUser);
+const char g_activeDesktop[] = {"activeDesktop:"};
+
CMSWindowsWatchdog::CMSWindowsWatchdog(
bool autoDetectCommand,
CIpcServer& ipcServer,
@@ -58,12 +60,23 @@ CMSWindowsWatchdog::CMSWindowsWatchdog(
m_elevateProcess(false),
m_processFailures(0),
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()
{
+ if (m_condVar != NULL) {
+ ARCH->closeCondVar(m_condVar);
+ }
+
+ if (m_mutex != NULL) {
+ ARCH->closeMutex(m_mutex);
+ }
}
void
@@ -126,7 +139,9 @@ CMSWindowsWatchdog::getUserToken(LPSECURITY_ATTRIBUTES security)
// elevate for the uac dialog (consent.exe) but this would be pointless,
// since synergy would re-launch as non-elevated after the desk switch,
// 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",
(m_elevateProcess ? "elevation required" : "at login screen")));
@@ -273,7 +288,11 @@ CMSWindowsWatchdog::startProcess()
SECURITY_ATTRIBUTES sa;
ZeroMemory(&sa, sizeof(SECURITY_ATTRIBUTES));
+ getActiveDesktop(&sa);
+
+ ZeroMemory(&sa, sizeof(SECURITY_ATTRIBUTES));
HANDLE userToken = getUserToken(&sa);
+ m_autoElevated = false;
// patch by Jack Zhou and Henry Tung
// set UIAccess to fix Windows 8 GUI interaction
@@ -281,6 +300,33 @@ CMSWindowsWatchdog::startProcess()
DWORD uiAccess = 1;
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
ZeroMemory(&m_processInfo, sizeof(PROCESS_INFORMATION));
@@ -307,30 +353,14 @@ CMSWindowsWatchdog::startProcess()
// re-launch in current active user session
LOG((CLOG_INFO "starting new process"));
BOOL createRet = CreateProcessAsUser(
- userToken, NULL, LPSTR(m_command.c_str()),
- &sa, NULL, TRUE, creationFlags,
+ userToken, NULL, LPSTR(command.c_str()),
+ sa, NULL, TRUE, creationFlags,
environment, NULL, &si, &m_processInfo);
DestroyEnvironmentBlock(environment);
CloseHandle(userToken);
- if (!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()));
- }
+ return createRet;
}
void
@@ -388,6 +418,8 @@ CMSWindowsWatchdog::outputLoop(void*)
else {
buffer[bytesRead] = '\0';
+ testOutput(buffer);
+
// send process output over IPC to GUI, and force it to be sent
// which bypasses the ipc logging anti-recursion mechanism.
m_ipcLogOutputter.write(kINFO, buffer, true);
@@ -492,3 +524,57 @@ CMSWindowsWatchdog::shutdownExistingProcesses()
CloseHandle(snapshot);
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);
+ }
+}
diff --git a/src/lib/platform/MSWindowsWatchdog.h b/src/lib/platform/MSWindowsWatchdog.h
index 9dd60285..4d2b1166 100644
--- a/src/lib/platform/MSWindowsWatchdog.h
+++ b/src/lib/platform/MSWindowsWatchdog.h
@@ -20,6 +20,7 @@
#include "platform/MSWindowsSession.h"
#include "synergy/XSynergy.h"
+#include "arch/IArchMultithread.h"
#define WIN32_LEAN_AND_MEAN
#include
@@ -54,7 +55,10 @@ private:
HANDLE duplicateProcessToken(HANDLE process, LPSECURITY_ATTRIBUTES security);
HANDLE getUserToken(LPSECURITY_ATTRIBUTES security);
void startProcess();
+ BOOL doStartProcess(CString& command, HANDLE userToken, LPSECURITY_ATTRIBUTES sa);
void sendSas();
+ void getActiveDesktop(LPSECURITY_ATTRIBUTES security);
+ void testOutput(CString buffer);
private:
CThread* m_thread;
@@ -73,6 +77,10 @@ private:
int m_processFailures;
bool m_processRunning;
CFileLogOutputter* m_fileLogOutputter;
+ bool m_autoElevated;
+ CArchMutex m_mutex;
+ CArchCond m_condVar;
+ bool m_ready;
};
//! Relauncher error
diff --git a/src/lib/synergy/App.cpp b/src/lib/synergy/App.cpp
index 7f7d4305..bbfc20cd 100644
--- a/src/lib/synergy/App.cpp
+++ b/src/lib/synergy/App.cpp
@@ -244,3 +244,80 @@ CApp::runEventsLoop(void*)
#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)
+{
+}
diff --git a/src/lib/synergy/App.h b/src/lib/synergy/App.h
index e389aa23..6f7f28c0 100644
--- a/src/lib/synergy/App.h
+++ b/src/lib/synergy/App.h
@@ -18,10 +18,12 @@
#pragma once
-#include "common/common.h"
-#include "base/String.h"
-#include "synergy/IApp.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
#include "synergy/win32/AppUtilWindows.h"
@@ -96,6 +98,8 @@ public:
void setSocketMultiplexer(CSocketMultiplexer* sm) { m_socketMultiplexer = sm; }
CSocketMultiplexer* getSocketMultiplexer() const { return m_socketMultiplexer; }
+ void setEvents(CEventQueue& events) { m_events = &events; }
+
private:
void handleIpcMessage(const CEvent&, void*);
@@ -118,6 +122,30 @@ private:
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
#define DAEMON_RUNNING(running_) CArchMiscWindows::daemonRunning(running_)
#else
diff --git a/src/lib/synergy/ArgParser.cpp b/src/lib/synergy/ArgParser.cpp
index c7ae05f3..3b8ff6f3 100644
--- a/src/lib/synergy/ArgParser.cpp
+++ b/src/lib/synergy/ArgParser.cpp
@@ -20,6 +20,7 @@
#include "synergy/App.h"
#include "synergy/ServerArgs.h"
#include "synergy/ClientArgs.h"
+#include "synergy/ToolArgs.h"
#include "synergy/ArgsBase.h"
#include "base/Log.h"
@@ -155,6 +156,23 @@ CArgParser::parsePlatformArg(CArgsBase& argsBase, const int& argc, const char* c
#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
CArgParser::parseGenericArgs(int argc, const char* const* argv, int& i)
{
diff --git a/src/lib/synergy/ArgParser.h b/src/lib/synergy/ArgParser.h
index a9cc04eb..0fc56546 100644
--- a/src/lib/synergy/ArgParser.h
+++ b/src/lib/synergy/ArgParser.h
@@ -34,6 +34,7 @@ public:
bool parseServerArgs(CServerArgs& 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 parseToolArgs(CToolArgs& args, int argc, const char* const* argv);
bool parseGenericArgs(int argc, const char* const* argv, int& i);
void setArgsBase(CArgsBase& argsBase) { m_argsBase = &argsBase; }
diff --git a/src/lib/synergy/ToolApp.cpp b/src/lib/synergy/ToolApp.cpp
index 83ee58c2..03035c61 100644
--- a/src/lib/synergy/ToolApp.cpp
+++ b/src/lib/synergy/ToolApp.cpp
@@ -16,14 +16,18 @@
*/
#include "synergy/ToolApp.h"
+
+#include "synergy/ArgParser.h"
#include "arch/Arch.h"
+#include "base/Log.h"
#include "base/String.h"
#include
#include
-
-//#define PREMIUM_AUTH_URL "http://localhost/synergy/premium/json/auth/"
-#define PREMIUM_AUTH_URL "https://synergy-project.org/premium/json/auth/"
+
+#if SYSAPI_WIN32
+#include "platform/MSWindowsSession.h"
+#endif
enum {
kErrorOk,
@@ -41,43 +45,43 @@ CToolApp::run(int argc, char** argv)
}
try {
- for (int i = 1; i < argc; i++) {
- if (strcmp(argv[i], "--premium-auth") == 0) {
- premiumAuth();
- return kErrorOk;
+ CArgParser argParser(this);
+ bool result = argParser.parseToolArgs(m_args, argc, argv);
+
+ 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 {
- std::cerr << "unknown arg: " << argv[i] << std::endl;
- return kErrorArgs;
+ std::cout << "activeDesktop:" << name.c_str() << std::endl;
}
+#endif
+ }
+ else {
+ throw XSynergy("Nothing to do");
}
}
catch (std::exception& e) {
- std::cerr << e.what() << std::endl;
- return kErrorException;
+ LOG((CLOG_CRIT "An error occurred: %s\n", e.what()));
+ return kExitFailed;
}
catch (...) {
- std::cerr << "unknown error" << std::endl;
- return kErrorUnknown;
+ LOG((CLOG_CRIT "An unknown error occurred.\n"));
+ return kExitFailed;
}
return kErrorOk;
}
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;
}
diff --git a/src/lib/synergy/ToolApp.h b/src/lib/synergy/ToolApp.h
index a28b74f7..ebca6798 100644
--- a/src/lib/synergy/ToolApp.h
+++ b/src/lib/synergy/ToolApp.h
@@ -17,12 +17,15 @@
#pragma once
+#include "synergy/App.h"
+#include "synergy/ToolArgs.h"
#include "common/basic_types.h"
-class CToolApp {
+class CToolApp : public CMinimalApp
+{
public:
UInt32 run(int argc, char** argv);
-
+ void help();
private:
- void premiumAuth();
+ CToolArgs m_args;
};
diff --git a/src/lib/synergy/ToolArgs.cpp b/src/lib/synergy/ToolArgs.cpp
new file mode 100644
index 00000000..006a1dfb
--- /dev/null
+++ b/src/lib/synergy/ToolArgs.cpp
@@ -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 .
+ */
+
+#include "synergy/ToolArgs.h"
+
+CToolArgs::CToolArgs() :
+ m_printActiveDesktopName(false)
+{
+}
diff --git a/src/lib/synergy/ToolArgs.h b/src/lib/synergy/ToolArgs.h
new file mode 100644
index 00000000..ca0a9ce0
--- /dev/null
+++ b/src/lib/synergy/ToolArgs.h
@@ -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 .
+ */
+
+#pragma once
+
+#include "base/String.h"
+
+class CToolArgs {
+public:
+ CToolArgs();
+
+public:
+ bool m_printActiveDesktopName;
+};