Merge branch 'jerry-sandbox'

This commit is contained in:
Xinyu Hou 2014-10-28 10:52:47 +00:00
commit e98b3678df
20 changed files with 405 additions and 101 deletions

View File

@ -311,13 +311,6 @@
</property> </property>
</spacer> </spacer>
</item> </item>
<item>
<widget class="QCheckBox" name="m_pElevateCheckBox">
<property name="text">
<string>&amp;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">

View File

@ -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>

View File

@ -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;
}

View File

@ -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[];

View File

@ -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();

View File

@ -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;

View File

@ -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;
}
}
}

View File

@ -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 );

View File

@ -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;
}

View File

@ -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);

View File

@ -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);
}
}

View File

@ -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

View File

@ -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)
{
}

View File

@ -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

View File

@ -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)
{ {

View File

@ -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; }

View File

@ -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;
} }

View File

@ -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;
}; };

View File

@ -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)
{
}

View File

@ -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;
};