SYNERGY3-17 Stop on login screen (#7143)
* SYNERGY3-17 Stop on login screen * SYNERGY3-17 Fix code smells * SYNERGY3-17 Update ChangeLog
This commit is contained in:
parent
bf102d4601
commit
d3d7c36f58
12 changed files with 236 additions and 23 deletions
|
|
@ -1,3 +1,9 @@
|
|||
v1.14.4-snapshot
|
||||
===========
|
||||
Enhancements:
|
||||
- #7143 Add ability to stop synergy on the login screen
|
||||
===========
|
||||
|
||||
v1.14.3-snapshot
|
||||
===========
|
||||
Bug fixes:
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ cmake_minimum_required (VERSION 3.4)
|
|||
|
||||
set (SYNERGY_VERSION_MAJOR 1)
|
||||
set (SYNERGY_VERSION_MINOR 14)
|
||||
set (SYNERGY_VERSION_PATCH 3)
|
||||
set (SYNERGY_VERSION_PATCH 4)
|
||||
set (SYNERGY_VERSION_BUILD 1)
|
||||
set (SYNERGY_VERSION_STAGE "snapshot")
|
||||
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
#include "ipc/Ipc.h"
|
||||
|
||||
const char* kIpcMsgHello = "IHEL%1i";
|
||||
const char* kIpcMsgLogLine = "ILOG%s";
|
||||
const char* kIpcMsgCommand = "ICMD%s%1i";
|
||||
const char* kIpcMsgShutdown = "ISDN";
|
||||
const char* kIpcMsgLogLine = "ILOG%s";
|
||||
const char* kIpcMsgCommand = "ICMD%s%1i";
|
||||
const char* kIpcMsgShutdown = "ISDN";
|
||||
const char* kIpcMsgSetting = "SSET%s%s";
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ enum EIpcMessage {
|
|||
kIpcLogLine,
|
||||
kIpcCommand,
|
||||
kIpcShutdown,
|
||||
kIpcSetting
|
||||
};
|
||||
|
||||
enum EIpcClientType {
|
||||
|
|
@ -50,3 +51,8 @@ extern const char* kIpcMsgCommand;
|
|||
// shutdown: daemon -> node
|
||||
// the daemon tells synergys/c to shut down gracefully.
|
||||
extern const char* kIpcMsgShutdown;
|
||||
|
||||
// set setting: gui -> daemon
|
||||
// $1 = setting name
|
||||
// $2 = setting value
|
||||
extern const char* kIpcMsgSetting;
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
#include "ipc/Ipc.h"
|
||||
#include "ipc/IpcMessage.h"
|
||||
#include "ipc/IpcSettingMessage.h"
|
||||
#include "synergy/ProtocolUtil.h"
|
||||
#include "io/IStream.h"
|
||||
#include "arch/Arch.h"
|
||||
|
|
@ -117,6 +118,9 @@ IpcClientProxy::handleData(const Event&, void*)
|
|||
else if (memcmp(code, kIpcMsgCommand, 4) == 0) {
|
||||
m = parseCommand();
|
||||
}
|
||||
else if (memcmp(code, kIpcMsgSetting, 4) == 0) {
|
||||
m = parseSetting();
|
||||
}
|
||||
else {
|
||||
LOG((CLOG_ERR "invalid ipc message"));
|
||||
disconnect();
|
||||
|
|
@ -184,6 +188,18 @@ IpcClientProxy::parseCommand()
|
|||
return new IpcCommandMessage(command, elevate != 0);
|
||||
}
|
||||
|
||||
IpcSettingMessage*
|
||||
IpcClientProxy::parseSetting() const
|
||||
{
|
||||
String name;
|
||||
String value;
|
||||
|
||||
ProtocolUtil::readf(&m_stream, kIpcMsgSetting + 4, &name, &value);
|
||||
|
||||
// must be deleted by event handler.
|
||||
return new IpcSettingMessage(name, value);
|
||||
}
|
||||
|
||||
void
|
||||
IpcClientProxy::disconnect()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
namespace synergy { class IStream; }
|
||||
class IpcMessage;
|
||||
class IpcCommandMessage;
|
||||
class IpcSettingMessage;
|
||||
class IpcHelloMessage;
|
||||
class IEventQueue;
|
||||
|
||||
|
|
@ -47,7 +48,8 @@ private:
|
|||
void handleDisconnect(const Event&, void*);
|
||||
void handleWriteError(const Event&, void*);
|
||||
IpcHelloMessage* parseHello();
|
||||
IpcCommandMessage* parseCommand();
|
||||
IpcCommandMessage* parseCommand();
|
||||
IpcSettingMessage* parseSetting() const;
|
||||
void disconnect();
|
||||
|
||||
private:
|
||||
|
|
|
|||
38
src/lib/ipc/IpcSettingMessage.cpp
Normal file
38
src/lib/ipc/IpcSettingMessage.cpp
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2012-2016 Symless Ltd.
|
||||
* Copyright (C) 2012 Nick Bolton
|
||||
*
|
||||
* 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 LICENSE 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 "IpcSettingMessage.h"
|
||||
|
||||
IpcSettingMessage::IpcSettingMessage(const std::string& name, const std::string& value) :
|
||||
IpcMessage(kIpcSetting),
|
||||
m_name(name),
|
||||
m_value(value)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
const std::string& IpcSettingMessage::getName() const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
const std::string& IpcSettingMessage::getValue() const
|
||||
{
|
||||
return m_value;
|
||||
}
|
||||
|
||||
50
src/lib/ipc/IpcSettingMessage.h
Normal file
50
src/lib/ipc/IpcSettingMessage.h
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2012-2016 Symless Ltd.
|
||||
* Copyright (C) 2012 Nick Bolton
|
||||
*
|
||||
* 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 LICENSE 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 <string>
|
||||
#include "IpcMessage.h"
|
||||
|
||||
class IpcSettingMessage : public IpcMessage
|
||||
{
|
||||
public:
|
||||
//!
|
||||
//! \brief IpcSettingMessage constructor
|
||||
//! \param name - setting name
|
||||
//! \param value - setting value
|
||||
//!
|
||||
IpcSettingMessage(const std::string& name, const std::string& value);
|
||||
|
||||
//!
|
||||
//! \brief getName is a getter for the setting name
|
||||
//! \return setting name
|
||||
//!
|
||||
const std::string& getName() const;
|
||||
|
||||
//!
|
||||
//! \brief getValue is a getter for the setting value
|
||||
//! \return setting value
|
||||
//!
|
||||
const std::string& getValue() const;
|
||||
|
||||
private:
|
||||
std::string m_name;
|
||||
std::string m_value;
|
||||
};
|
||||
|
||||
|
|
@ -39,6 +39,42 @@
|
|||
|
||||
#define CURRENT_PROCESS_ID 0
|
||||
#define MAXIMUM_WAIT_TIME 3
|
||||
|
||||
namespace {
|
||||
std::string
|
||||
trimDesktopName(const std::string& nameFromTraces)
|
||||
{
|
||||
std::string name;
|
||||
|
||||
for (const auto& symbol : nameFromTraces) {
|
||||
if (std::isalpha(symbol)) {
|
||||
name.push_back(symbol);
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
bool
|
||||
isDesktopRunnable(const std::string& desktopName)
|
||||
{
|
||||
const std::string winlogon = "Winlogon";
|
||||
bool isNotLoginScreen = std::strncmp(desktopName.c_str(),
|
||||
winlogon.c_str(),
|
||||
winlogon.length());
|
||||
|
||||
const auto setting = ARCH->setting("runOnLoginScreen");
|
||||
bool runOnLoginScreen = (setting.empty() || setting == "true");
|
||||
|
||||
return (runOnLoginScreen || isNotLoginScreen);
|
||||
}
|
||||
|
||||
}//namespace
|
||||
|
||||
|
||||
enum {
|
||||
kOutputBufferSize = 4096
|
||||
};
|
||||
|
|
@ -315,17 +351,22 @@ MSWindowsWatchdog::startProcess()
|
|||
|
||||
getActiveDesktop(&sa);
|
||||
|
||||
ZeroMemory(&sa, sizeof(SECURITY_ATTRIBUTES));
|
||||
HANDLE userToken = getUserToken(&sa);
|
||||
m_elevateProcess = m_autoElevated ? m_autoElevated : m_elevateProcess;
|
||||
m_autoElevated = false;
|
||||
if (!isDesktopRunnable(m_activeDesktop)) {
|
||||
LOG((CLOG_INFO, "Starting on the login screen is disabled!"));
|
||||
return;
|
||||
}
|
||||
|
||||
// patch by Jack Zhou and Henry Tung
|
||||
// set UIAccess to fix Windows 8 GUI interaction
|
||||
DWORD uiAccess = 1;
|
||||
SetTokenInformation(userToken, TokenUIAccess, &uiAccess, sizeof(DWORD));
|
||||
ZeroMemory(&sa, sizeof(SECURITY_ATTRIBUTES));
|
||||
HANDLE userToken = getUserToken(&sa);
|
||||
m_elevateProcess = m_autoElevated ? m_autoElevated : m_elevateProcess;
|
||||
m_autoElevated = false;
|
||||
|
||||
createRet = startProcessAsUser(m_command, userToken, &sa);
|
||||
// patch by Jack Zhou and Henry Tung
|
||||
// set UIAccess to fix Windows 8 GUI interaction
|
||||
DWORD uiAccess = 1;
|
||||
SetTokenInformation(userToken, TokenUIAccess, &uiAccess, sizeof(DWORD));
|
||||
|
||||
createRet = startProcessAsUser(m_command, userToken, &sa);
|
||||
}
|
||||
|
||||
if (!createRet) {
|
||||
|
|
@ -636,7 +677,7 @@ MSWindowsWatchdog::getActiveDesktop(LPSECURITY_ATTRIBUTES security)
|
|||
ARCH->unlockMutex(m_mutex);
|
||||
closeProcessHandles(pid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MSWindowsWatchdog::testOutput(String buffer)
|
||||
|
|
@ -645,11 +686,11 @@ MSWindowsWatchdog::testOutput(String buffer)
|
|||
size_t i = buffer.find(g_activeDesktop);
|
||||
if (i != String::npos) {
|
||||
size_t s = sizeof(g_activeDesktop);
|
||||
String defaultDesktop("Default");
|
||||
String sub = buffer.substr(i + s - 1, defaultDesktop.size());
|
||||
if (sub != defaultDesktop) {
|
||||
m_autoElevated = true;
|
||||
}
|
||||
std::string defaultScreen = "Default";
|
||||
m_activeDesktop = trimDesktopName(buffer.substr(i + s - 1));
|
||||
m_autoElevated = std::strncmp(m_activeDesktop.c_str(),
|
||||
defaultScreen.c_str(),
|
||||
defaultScreen.length());
|
||||
|
||||
ARCH->lockMutex(m_mutex);
|
||||
m_ready = true;
|
||||
|
|
|
|||
|
|
@ -96,12 +96,13 @@ private:
|
|||
ArchMutex m_mutex;
|
||||
ArchCond m_condVar;
|
||||
bool m_ready;
|
||||
bool m_foreground;
|
||||
bool m_foreground;
|
||||
std::string m_activeDesktop;
|
||||
|
||||
/// @brief Save the info of all process made
|
||||
/// We will use this to track all processes we make and
|
||||
/// kill off handels and children that we no longer need
|
||||
std::map<unsigned long, PROCESS_INFORMATION> m_children;
|
||||
std::map<unsigned long, PROCESS_INFORMATION> m_children;
|
||||
};
|
||||
|
||||
//! Relauncher error
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
#include "synergy/ClientArgs.h"
|
||||
#include "ipc/IpcClientProxy.h"
|
||||
#include "ipc/IpcMessage.h"
|
||||
#include "ipc/IpcSettingMessage.h"
|
||||
#include "ipc/IpcLogOutputter.h"
|
||||
#include "net/SocketMultiplexer.h"
|
||||
#include "arch/XArch.h"
|
||||
|
|
@ -58,6 +59,21 @@
|
|||
|
||||
using namespace std;
|
||||
|
||||
namespace {
|
||||
void
|
||||
updateSetting(const IpcMessage& message)
|
||||
{
|
||||
try {
|
||||
auto setting = static_cast<const IpcSettingMessage&>(message);
|
||||
ARCH->setting(setting.getName(), setting.getValue());
|
||||
}
|
||||
catch (const XArch& e) {
|
||||
LOG((CLOG_ERR "failed to save setting: %s", e.what()));
|
||||
}
|
||||
}
|
||||
|
||||
}//namespace
|
||||
|
||||
DaemonApp* DaemonApp::s_instance = NULL;
|
||||
|
||||
int
|
||||
|
|
@ -362,7 +378,7 @@ DaemonApp::handleIpcMessage(const Event& e, void*)
|
|||
break;
|
||||
}
|
||||
|
||||
case kIpcHello:
|
||||
case kIpcHello: {
|
||||
IpcHelloMessage* hm = static_cast<IpcHelloMessage*>(m);
|
||||
String type;
|
||||
switch (hm->clientType()) {
|
||||
|
|
@ -380,5 +396,10 @@ DaemonApp::handleIpcMessage(const Event& e, void*)
|
|||
|
||||
m_ipcLogOutputter->notifyBuffer();
|
||||
break;
|
||||
}
|
||||
|
||||
case kIpcSetting:
|
||||
updateSetting(*m);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
31
src/test/unittests/ipc/IpcSettingMessageTests.cpp
Normal file
31
src/test/unittests/ipc/IpcSettingMessageTests.cpp
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2015-2022 Symless Ltd.
|
||||
*
|
||||
* 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 LICENSE 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/>.
|
||||
*/
|
||||
|
||||
#define TEST_ENV
|
||||
|
||||
#include "ipc/IpcSettingMessage.h"
|
||||
#include "test/global/gtest.h"
|
||||
|
||||
TEST(IpcSettingMessage, testIpcSettingMessage) {
|
||||
const std::string expected_name = "test";
|
||||
const std::string expected_value = "test_value";
|
||||
|
||||
IpcSettingMessage message("test", "test_value");
|
||||
|
||||
EXPECT_EQ(expected_name, message.getName());
|
||||
EXPECT_EQ(expected_value, message.getValue());
|
||||
}
|
||||
Loading…
Reference in a new issue