ripped out rest of shitty named pipes ipc stuff.
fixed the byte to int reader on the gui ipc (unsigned chars, argh!!!). retry on fail for gui ipc connect.
This commit is contained in:
parent
a8ce3418fe
commit
4e268760b3
|
@ -36,7 +36,6 @@ SOURCES += src/main.cpp \
|
|||
src/QSynergyApplication.cpp \
|
||||
src/VersionChecker.cpp \
|
||||
src/SetupWizard.cpp \
|
||||
src/IpcLogReader.cpp \
|
||||
src/IpcClient.cpp
|
||||
HEADERS += src/MainWindow.h \
|
||||
src/AboutDialog.h \
|
||||
|
@ -60,7 +59,6 @@ HEADERS += src/MainWindow.h \
|
|||
src/QSynergyApplication.h \
|
||||
src/VersionChecker.h \
|
||||
src/SetupWizard.h \
|
||||
src/IpcLogReader.h \
|
||||
src/IpcClient.h
|
||||
RESOURCES += res/Synergy.qrc
|
||||
RC_FILE = res/win/Synergy.rc
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include <QTcpSocket>
|
||||
#include <QHostAddress>
|
||||
#include <iostream>
|
||||
#include <QTimer>
|
||||
|
||||
IpcClient::IpcClient()
|
||||
{
|
||||
|
@ -33,6 +34,7 @@ IpcClient::~IpcClient()
|
|||
|
||||
void IpcClient::connectToHost()
|
||||
{
|
||||
infoMessage("connecting to background service...");
|
||||
m_Socket->connectToHost(QHostAddress(QHostAddress::LocalHost), IPC_PORT);
|
||||
}
|
||||
|
||||
|
@ -47,28 +49,19 @@ void IpcClient::read()
|
|||
|
||||
switch (codeBuf[0]) {
|
||||
case kIpcLogLine: {
|
||||
// TODO: qt must have a built in way of converting bytes to int.
|
||||
char lenBuf[2];
|
||||
stream.readRawData(lenBuf, 2);
|
||||
int len = (lenBuf[0] << 8) + lenBuf[1];
|
||||
int len = bytesToInt(lenBuf, 2);
|
||||
|
||||
// HACK: sometimes the size is wrong (probably a bug in the above code)
|
||||
// but the following text always seems to be valid, so just read a large
|
||||
// amount from the buffer and put a \0 at the end if the number looks
|
||||
// valid (ugh, this sucks).
|
||||
char* data = new char[1024];
|
||||
stream.readRawData(data, 1024);
|
||||
if (len > -1) {
|
||||
data[len] = '\0';
|
||||
}
|
||||
char* data = new char[len];
|
||||
stream.readRawData(data, len);
|
||||
|
||||
QString s = QString::fromUtf8(data);
|
||||
readLogLine(s);
|
||||
readLogLine(QString::fromUtf8(data, len));
|
||||
}
|
||||
break;
|
||||
|
||||
default: {
|
||||
std::cerr << "invalid code: " << codeBuf[0] << std::endl;
|
||||
default: {
|
||||
std::cout << "invalid code: " << codeBuf[0] << std::endl;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -77,7 +70,16 @@ void IpcClient::read()
|
|||
|
||||
void IpcClient::error(QAbstractSocket::SocketError error)
|
||||
{
|
||||
errorMessage(QString("ERROR: could not connect to background service, code=%1").arg(error));
|
||||
QString text;
|
||||
switch (error) {
|
||||
case 0: text = "connection refused"; break;
|
||||
case 1: text = "remote host closed"; break;
|
||||
default: text = QString("code=%1").arg(error); break;
|
||||
}
|
||||
|
||||
errorMessage(QString("ipc connection error, %1").arg(text));
|
||||
|
||||
QTimer::singleShot(1000, this, SLOT(connectToHost()));
|
||||
}
|
||||
|
||||
void IpcClient::write(unsigned char code, unsigned char length, const char* data)
|
||||
|
@ -90,14 +92,36 @@ void IpcClient::write(unsigned char code, unsigned char length, const char* data
|
|||
|
||||
switch (code) {
|
||||
case kIpcCommand: {
|
||||
// TODO: qt must have a built in way of converting int to bytes.
|
||||
char lenBuf[2];
|
||||
lenBuf[0] = (length >> 8) & 0xff;
|
||||
lenBuf[1] = length & 0xff;
|
||||
intToBytes(length, lenBuf, 2);
|
||||
stream.writeRawData(lenBuf, 2);
|
||||
|
||||
stream.writeRawData(data, length);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: qt must have a built in way of converting bytes to int.
|
||||
int IpcClient::bytesToInt(const char *buffer, int size)
|
||||
{
|
||||
if (size == 2) {
|
||||
return (((unsigned char)buffer[0]) << 8)
|
||||
+ (unsigned char)buffer[1];
|
||||
}
|
||||
else {
|
||||
// TODO: other sizes, if needed.
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: qt must have a built in way of converting int to bytes.
|
||||
void IpcClient::intToBytes(int value, char *buffer, int size)
|
||||
{
|
||||
if (size == 2) {
|
||||
buffer[0] = (value >> 8) & 0xff;
|
||||
buffer[1] = value & 0xff;
|
||||
}
|
||||
else {
|
||||
// TODO: other sizes, if needed.
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,15 +32,22 @@ public:
|
|||
IpcClient();
|
||||
virtual ~IpcClient();
|
||||
|
||||
void connectToHost();
|
||||
void write(unsigned char code, unsigned char length, const char* data);
|
||||
|
||||
public slots:
|
||||
void connectToHost();
|
||||
|
||||
private:
|
||||
int bytesToInt(const char* buffer, int size);
|
||||
void intToBytes(int value, char* buffer, int size);
|
||||
|
||||
private slots:
|
||||
void read();
|
||||
void error(QAbstractSocket::SocketError error);
|
||||
|
||||
signals:
|
||||
void readLogLine(const QString& text);
|
||||
void infoMessage(const QString& text);
|
||||
void errorMessage(const QString& text);
|
||||
|
||||
private:
|
||||
|
|
|
@ -1,67 +0,0 @@
|
|||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* 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 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 "IpcLogReader.h"
|
||||
|
||||
#if defined(Q_OS_WIN)
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <Windows.h>
|
||||
#endif
|
||||
|
||||
IpcLogReader::IpcLogReader()
|
||||
{
|
||||
}
|
||||
|
||||
IpcLogReader::~IpcLogReader()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
IpcLogReader::run()
|
||||
{
|
||||
#if defined(Q_OS_WIN)
|
||||
|
||||
const WCHAR* name = L"\\\\.\\pipe\\SynergyLog";
|
||||
|
||||
HANDLE pipe = CreateFile(
|
||||
name, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
|
||||
|
||||
if (pipe == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
receivedLine(
|
||||
QString("ERROR: could not connect to service log, error: ") +
|
||||
QString::number(GetLastError()));
|
||||
return;
|
||||
}
|
||||
|
||||
char buffer[1024];
|
||||
DWORD bytesRead;
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (!ReadFile(pipe, buffer, sizeof(buffer), &bytesRead, NULL)) {
|
||||
break;
|
||||
}
|
||||
|
||||
buffer[bytesRead] = '\0';
|
||||
|
||||
QString text = QString::fromAscii(buffer, bytesRead);
|
||||
text = text.trimmed().append("\n");
|
||||
receivedLine(text);
|
||||
}
|
||||
#endif
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* 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 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 <QThread>
|
||||
#include <string>
|
||||
|
||||
class IpcLogReader : public QThread
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
IpcLogReader();
|
||||
virtual ~IpcLogReader();
|
||||
void run();
|
||||
signals:
|
||||
void receivedLine(const QString& text);
|
||||
};
|
|
@ -90,10 +90,10 @@ MainWindow::MainWindow(QSettings& settings, AppConfig& appConfig) :
|
|||
|
||||
if (appConfig.processMode() == Service)
|
||||
{
|
||||
connect(&m_IpcClient, SIGNAL(readLogLine(const QString&)), this, SLOT(appendLog(const QString&)));
|
||||
connect(&m_IpcClient, SIGNAL(errorMessage(const QString&)), this, SLOT(appendLog(const QString&)));
|
||||
connect(&m_IpcClient, SIGNAL(readLogLine(const QString&)), this, SLOT(appendLogRaw(const QString&)));
|
||||
connect(&m_IpcClient, SIGNAL(errorMessage(const QString&)), this, SLOT(appendLogError(const QString&)));
|
||||
connect(&m_IpcClient, SIGNAL(infoMessage(const QString&)), this, SLOT(appendLogInfo(const QString&)));
|
||||
m_IpcClient.connectToHost();
|
||||
appendLog("INFO: connecting to background service...");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -260,7 +260,7 @@ void MainWindow::logOutput()
|
|||
{
|
||||
if (!line.isEmpty())
|
||||
{
|
||||
appendLog(line);
|
||||
appendLogRaw(line);
|
||||
if (line.contains("has connected") ||
|
||||
line.contains("connected to server"))
|
||||
{
|
||||
|
@ -285,7 +285,7 @@ void MainWindow::logError()
|
|||
{
|
||||
if (m_pSynergy)
|
||||
{
|
||||
appendLog(m_pSynergy->readAllStandardError());
|
||||
appendLogRaw(m_pSynergy->readAllStandardError());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -298,7 +298,17 @@ void MainWindow::updateFound(const QString &version)
|
|||
.arg(version).arg("http://synergy-foss.org"));
|
||||
}
|
||||
|
||||
void MainWindow::appendLog(const QString& text)
|
||||
void MainWindow::appendLogInfo(const QString& text)
|
||||
{
|
||||
appendLogRaw("INFO: " + text);
|
||||
}
|
||||
|
||||
void MainWindow::appendLogError(const QString& text)
|
||||
{
|
||||
appendLogRaw("ERROR: " + text);
|
||||
}
|
||||
|
||||
void MainWindow::appendLogRaw(const QString& text)
|
||||
{
|
||||
foreach(QString line, text.split(QRegExp("\r|\n|\r\n")))
|
||||
if (!line.isEmpty())
|
||||
|
@ -379,28 +389,28 @@ void MainWindow::startSynergy()
|
|||
|
||||
// put a space between last log output and new instance.
|
||||
if (!m_pLogOutput->toPlainText().isEmpty())
|
||||
appendLog("");
|
||||
appendLogRaw("");
|
||||
|
||||
if (desktopMode)
|
||||
{
|
||||
appendLog("starting " + QString(synergyType() == synergyServer ? "server" : "client"));
|
||||
appendLogInfo("starting " + QString(synergyType() == synergyServer ? "server" : "client"));
|
||||
}
|
||||
|
||||
if (serviceMode)
|
||||
{
|
||||
appendLog("applying service mode: " + QString(synergyType() == synergyServer ? "server" : "client"));
|
||||
appendLogInfo("applying service mode: " + QString(synergyType() == synergyServer ? "server" : "client"));
|
||||
}
|
||||
|
||||
// show command if debug log level...
|
||||
if (appConfig().logLevel() >= 4) {
|
||||
appendLog(QString("command: %1 %2").arg(app, args.join(" ")));
|
||||
appendLogInfo(QString("command: %1 %2").arg(app, args.join(" ")));
|
||||
}
|
||||
|
||||
appendLog("config file: " + configFilename());
|
||||
appendLog("log level: " + appConfig().logLevelText());
|
||||
appendLogInfo("config file: " + configFilename());
|
||||
appendLogInfo("log level: " + appConfig().logLevelText());
|
||||
|
||||
if (appConfig().logToFile())
|
||||
appendLog("log file: " + appConfig().logFilename());
|
||||
appendLogInfo("log file: " + appConfig().logFilename());
|
||||
|
||||
if (desktopMode)
|
||||
{
|
||||
|
@ -523,7 +533,7 @@ void MainWindow::stopSynergy()
|
|||
{
|
||||
if (synergyProcess())
|
||||
{
|
||||
appendLog("stopping synergy");
|
||||
appendLogInfo("stopping synergy");
|
||||
|
||||
if (synergyProcess()->isOpen())
|
||||
synergyProcess()->close();
|
||||
|
|
|
@ -73,6 +73,11 @@ class MainWindow : public QMainWindow, public Ui::MainWindowBase
|
|||
Command = 1
|
||||
};
|
||||
|
||||
enum qLevel {
|
||||
Error,
|
||||
Info
|
||||
};
|
||||
|
||||
public:
|
||||
MainWindow(QSettings& settings, AppConfig& appConfig);
|
||||
~MainWindow();
|
||||
|
@ -89,7 +94,9 @@ class MainWindow : public QMainWindow, public Ui::MainWindowBase
|
|||
void clearLog();
|
||||
|
||||
public slots:
|
||||
void appendLog(const QString& text);
|
||||
void appendLogRaw(const QString& text);
|
||||
void appendLogInfo(const QString& text);
|
||||
void appendLogError(const QString& text);
|
||||
|
||||
protected slots:
|
||||
void on_m_pGroupClient_toggled(bool on) { m_pGroupServer->setChecked(!on); }
|
||||
|
|
|
@ -419,8 +419,6 @@ CMSWindowsRelauncher::shutdownProcess(const PROCESS_INFORMATION& pi, int timeout
|
|||
if (exitCode != STILL_ACTIVE)
|
||||
return;
|
||||
|
||||
sendIpcMessage(kIpcShutdown, "");
|
||||
|
||||
// wait for process to exit gracefully.
|
||||
double start = ARCH->time();
|
||||
while (true)
|
||||
|
@ -446,45 +444,3 @@ CMSWindowsRelauncher::shutdownProcess(const PROCESS_INFORMATION& pi, int timeout
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: put this in an IPC client class.
|
||||
void
|
||||
CMSWindowsRelauncher::sendIpcMessage(int type, const char* data)
|
||||
{
|
||||
char message[1024];
|
||||
message[0] = type;
|
||||
char* messagePtr = message;
|
||||
messagePtr++;
|
||||
strcpy(messagePtr, data);
|
||||
|
||||
HANDLE pipe = CreateFile(
|
||||
_T("\\\\.\\pipe\\SynergyNode"),
|
||||
GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
|
||||
|
||||
if (pipe == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
LOG((CLOG_ERR "could not connect to node, error: %d", GetLastError()));
|
||||
return;
|
||||
}
|
||||
|
||||
DWORD dwMode = PIPE_READMODE_MESSAGE;
|
||||
BOOL stateSuccess = SetNamedPipeHandleState(pipe, &dwMode, NULL, NULL);
|
||||
|
||||
if (!stateSuccess)
|
||||
{
|
||||
LOG((CLOG_ERR "could not set node pipe state, error: %d", GetLastError()));
|
||||
return;
|
||||
}
|
||||
|
||||
DWORD written;
|
||||
BOOL writeSuccess = WriteFile(
|
||||
pipe, message, (DWORD)strlen(message), &written, NULL);
|
||||
|
||||
if (!writeSuccess)
|
||||
{
|
||||
LOG((CLOG_ERR "could not write to node pipe, error: %d", GetLastError()));
|
||||
return;
|
||||
}
|
||||
|
||||
CloseHandle(pipe);
|
||||
}
|
||||
|
|
|
@ -40,7 +40,6 @@ private:
|
|||
DWORD getSessionId();
|
||||
HANDLE getCurrentUserToken(DWORD sessionId, LPSECURITY_ATTRIBUTES security);
|
||||
void outputLoop(void*);
|
||||
void sendIpcMessage(int type, const char* data);
|
||||
void shutdownProcess(const PROCESS_INFORMATION& pi, int timeout);
|
||||
|
||||
public:
|
||||
|
|
|
@ -317,11 +317,6 @@ CApp::initApp(int argc, const char** argv)
|
|||
// parse command line
|
||||
parseArgs(argc, argv);
|
||||
|
||||
#if SYSAPI_WIN32
|
||||
CThread pipeThread(new TMethodJob<CApp>(
|
||||
this, &CApp::pipeThread, nullptr));
|
||||
#endif
|
||||
|
||||
// setup file logging after parsing args
|
||||
setupFileLogging();
|
||||
|
||||
|
@ -340,71 +335,3 @@ CApp::initApp(int argc, const char** argv)
|
|||
m_taskBarReceiver = m_createTaskBarReceiver(logBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef SYSAPI_WIN32
|
||||
|
||||
void
|
||||
CApp::pipeThread(void*)
|
||||
{
|
||||
// TODO: move this to an IPC server class.
|
||||
while (true) {
|
||||
|
||||
// grant access to everyone.
|
||||
SECURITY_DESCRIPTOR sd;
|
||||
InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
|
||||
SetSecurityDescriptorDacl(&sd, TRUE, static_cast<PACL>(0), FALSE);
|
||||
|
||||
SECURITY_ATTRIBUTES sa;
|
||||
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
|
||||
sa.lpSecurityDescriptor = &sd;
|
||||
|
||||
HANDLE pipe = CreateNamedPipe(
|
||||
_T("\\\\.\\pipe\\SynergyNode"),
|
||||
PIPE_ACCESS_DUPLEX,
|
||||
PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
|
||||
PIPE_UNLIMITED_INSTANCES,
|
||||
1024, 1024, 0, &sa);
|
||||
|
||||
if (pipe == INVALID_HANDLE_VALUE)
|
||||
XArch("could not create named pipe.");
|
||||
|
||||
LOG((CLOG_DEBUG "opened node pipe: %d", pipe));
|
||||
BOOL connectResult = ConnectNamedPipe(pipe, NULL);
|
||||
|
||||
char buffer[1024];
|
||||
DWORD bytesRead;
|
||||
|
||||
while (true) {
|
||||
if (!ReadFile(pipe, buffer, sizeof(buffer), &bytesRead, NULL)) {
|
||||
break;
|
||||
}
|
||||
|
||||
buffer[bytesRead] = '\0';
|
||||
LOG((CLOG_DEBUG "ipc node server read: %s", buffer));
|
||||
|
||||
handlePipeMessage(buffer);
|
||||
}
|
||||
|
||||
DisconnectNamedPipe(pipe);
|
||||
CloseHandle(pipe);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CApp::handlePipeMessage(char* buffer)
|
||||
{
|
||||
switch (buffer[0]) {
|
||||
case kIpcShutdown:
|
||||
{
|
||||
LOG((CLOG_INFO "queueing quit event"));
|
||||
EVENTQUEUE->addEvent(CEvent(CEvent::kQuit));
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG((CLOG_WARN "unrecognized ipc message: %d", buffer[0]));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -105,11 +105,6 @@ private:
|
|||
CFileLogOutputter* m_fileLog;
|
||||
CreateTaskBarReceiverFunc m_createTaskBarReceiver;
|
||||
ARCH_APP_UTIL m_appUtil;
|
||||
|
||||
#if SYSAPI_WIN32
|
||||
void pipeThread(void*);
|
||||
void handlePipeMessage(char* buffer);
|
||||
#endif
|
||||
};
|
||||
|
||||
#define BYE "\nTry `%s --help' for more information."
|
||||
|
@ -176,7 +171,3 @@ private:
|
|||
HELP_GAME_DEVICE
|
||||
|
||||
#endif
|
||||
|
||||
enum {
|
||||
kIpcShutdown = 1
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue