parent
2d305ba93c
commit
b9016bc1ae
|
@ -31,10 +31,8 @@
|
||||||
#include "CIpcMessage.h"
|
#include "CIpcMessage.h"
|
||||||
#include "Ipc.h"
|
#include "Ipc.h"
|
||||||
|
|
||||||
#include <Tlhelp32.h>
|
|
||||||
#include <UserEnv.h>
|
#include <UserEnv.h>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <Wtsapi32.h>
|
|
||||||
#include <Shellapi.h>
|
#include <Shellapi.h>
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
@ -85,110 +83,6 @@ CMSWindowsRelauncher::stop()
|
||||||
delete m_outputThread;
|
delete m_outputThread;
|
||||||
}
|
}
|
||||||
|
|
||||||
// this still gets the physical session (the one the keyboard and
|
|
||||||
// mouse is connected to), sometimes this returns -1 but not sure why
|
|
||||||
DWORD
|
|
||||||
CMSWindowsRelauncher::getSessionId()
|
|
||||||
{
|
|
||||||
return WTSGetActiveConsoleSessionId();
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOL
|
|
||||||
CMSWindowsRelauncher::isProcessInSession(const char* name, DWORD sessionId, PHANDLE process = NULL)
|
|
||||||
{
|
|
||||||
// first we need to take a snapshot of the running processes
|
|
||||||
HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
|
|
||||||
if (snapshot == INVALID_HANDLE_VALUE) {
|
|
||||||
LOG((CLOG_ERR "could not get process snapshot (error: %i)",
|
|
||||||
GetLastError()));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
PROCESSENTRY32 entry;
|
|
||||||
entry.dwSize = sizeof(PROCESSENTRY32);
|
|
||||||
|
|
||||||
// get the first process, and if we can't do that then it's
|
|
||||||
// unlikely we can go any further
|
|
||||||
BOOL gotEntry = Process32First(snapshot, &entry);
|
|
||||||
if (!gotEntry) {
|
|
||||||
LOG((CLOG_ERR "could not get first process entry (error: %i)",
|
|
||||||
GetLastError()));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// used to record process names for debug info
|
|
||||||
std::list<std::string> nameList;
|
|
||||||
|
|
||||||
// now just iterate until we can find winlogon.exe pid
|
|
||||||
DWORD pid = 0;
|
|
||||||
while(gotEntry) {
|
|
||||||
|
|
||||||
// make sure we're not checking the system process
|
|
||||||
if (entry.th32ProcessID != 0) {
|
|
||||||
|
|
||||||
DWORD processSessionId;
|
|
||||||
BOOL pidToSidRet = ProcessIdToSessionId(
|
|
||||||
entry.th32ProcessID, &processSessionId);
|
|
||||||
|
|
||||||
if (!pidToSidRet) {
|
|
||||||
LOG((CLOG_ERR "could not get session id for process id %i (error: %i)",
|
|
||||||
entry.th32ProcessID, GetLastError()));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// only pay attention to processes in the active session
|
|
||||||
if (processSessionId == sessionId) {
|
|
||||||
|
|
||||||
// store the names so we can record them for debug
|
|
||||||
nameList.push_back(entry.szExeFile);
|
|
||||||
|
|
||||||
if (_stricmp(entry.szExeFile, name) == 0) {
|
|
||||||
pid = entry.th32ProcessID;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// now move on to the next entry (if we're not at the end)
|
|
||||||
gotEntry = Process32Next(snapshot, &entry);
|
|
||||||
if (!gotEntry) {
|
|
||||||
|
|
||||||
DWORD err = GetLastError();
|
|
||||||
if (err != ERROR_NO_MORE_FILES) {
|
|
||||||
|
|
||||||
// only worry about error if it's not the end of the snapshot
|
|
||||||
LOG((CLOG_ERR "could not get subsiquent process entry (error: %i)",
|
|
||||||
GetLastError()));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string nameListJoin;
|
|
||||||
for(std::list<std::string>::iterator it = nameList.begin();
|
|
||||||
it != nameList.end(); it++) {
|
|
||||||
nameListJoin.append(*it);
|
|
||||||
nameListJoin.append(", ");
|
|
||||||
}
|
|
||||||
|
|
||||||
LOG((CLOG_DEBUG "processes in session %d: %s",
|
|
||||||
sessionId, nameListJoin.c_str()));
|
|
||||||
|
|
||||||
CloseHandle(snapshot);
|
|
||||||
|
|
||||||
if (pid) {
|
|
||||||
if (process != NULL) {
|
|
||||||
// now get the process so we can get the process, with which
|
|
||||||
// we'll use to get the process token.
|
|
||||||
LOG((CLOG_DEBUG "found %s in session %i", name, sessionId));
|
|
||||||
*process = OpenProcess(MAXIMUM_ALLOWED, FALSE, pid);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
HANDLE
|
HANDLE
|
||||||
CMSWindowsRelauncher::duplicateProcessToken(HANDLE process, LPSECURITY_ATTRIBUTES security)
|
CMSWindowsRelauncher::duplicateProcessToken(HANDLE process, LPSECURITY_ATTRIBUTES security)
|
||||||
{
|
{
|
||||||
|
@ -222,54 +116,31 @@ CMSWindowsRelauncher::duplicateProcessToken(HANDLE process, LPSECURITY_ATTRIBUTE
|
||||||
}
|
}
|
||||||
|
|
||||||
HANDLE
|
HANDLE
|
||||||
CMSWindowsRelauncher::getUserToken(DWORD sessionId, LPSECURITY_ATTRIBUTES security)
|
CMSWindowsRelauncher::getUserToken(LPSECURITY_ATTRIBUTES security)
|
||||||
{
|
{
|
||||||
// always elevate if we are at the vista/7 login screen. we could also
|
// always elevate if we are at the vista/7 login screen. we could also
|
||||||
// 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 || isProcessInSession("logonui.exe", sessionId)) {
|
if (m_elevateProcess || 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")));
|
||||||
|
|
||||||
HANDLE process;
|
HANDLE process;
|
||||||
if (isProcessInSession("winlogon.exe", sessionId, &process)) {
|
if (m_session.isProcessInSession("winlogon.exe", &process)) {
|
||||||
return duplicateProcessToken(process, security);
|
return duplicateProcessToken(process, security);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
LOG((CLOG_ERR "could not find winlogon in session %i", sessionId));
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
LOG((CLOG_DEBUG "getting non-elevated token"));
|
LOG((CLOG_DEBUG "getting non-elevated token"));
|
||||||
return getSessionToken(sessionId, security);
|
return m_session.getUserToken(security);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HANDLE
|
|
||||||
CMSWindowsRelauncher::getSessionToken(DWORD sessionId, LPSECURITY_ATTRIBUTES security)
|
|
||||||
{
|
|
||||||
HANDLE sourceToken;
|
|
||||||
if (!WTSQueryUserToken(sessionId, &sourceToken)) {
|
|
||||||
LOG((CLOG_ERR "could not get token from session %d (error: %i)", sessionId, GetLastError()));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
HANDLE newToken;
|
|
||||||
if (!DuplicateTokenEx(
|
|
||||||
sourceToken, TOKEN_ASSIGN_PRIMARY | TOKEN_ALL_ACCESS, security,
|
|
||||||
SecurityImpersonation, TokenPrimary, &newToken)) {
|
|
||||||
|
|
||||||
LOG((CLOG_ERR "could not duplicate token (error: %i)", GetLastError()));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
LOG((CLOG_DEBUG "duplicated, new token: %i", newToken));
|
|
||||||
return newToken;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
CMSWindowsRelauncher::mainLoop(void*)
|
CMSWindowsRelauncher::mainLoop(void*)
|
||||||
{
|
{
|
||||||
|
@ -282,7 +153,6 @@ CMSWindowsRelauncher::mainLoop(void*)
|
||||||
sendSasFunc = (SendSas)GetProcAddress(sasLib, "SendSAS");
|
sendSasFunc = (SendSas)GetProcAddress(sasLib, "SendSAS");
|
||||||
}
|
}
|
||||||
|
|
||||||
DWORD sessionId = -1;
|
|
||||||
bool launched = false;
|
bool launched = false;
|
||||||
|
|
||||||
SECURITY_ATTRIBUTES saAttr;
|
SECURITY_ATTRIBUTES saAttr;
|
||||||
|
@ -308,7 +178,7 @@ CMSWindowsRelauncher::mainLoop(void*)
|
||||||
sendSasEvent = CreateEvent(NULL, FALSE, FALSE, "Global\\SendSAS");
|
sendSasEvent = CreateEvent(NULL, FALSE, FALSE, "Global\\SendSAS");
|
||||||
}
|
}
|
||||||
|
|
||||||
DWORD newSessionId = getSessionId();
|
m_session.updateNewSessionId();
|
||||||
|
|
||||||
bool running = false;
|
bool running = false;
|
||||||
if (launched) {
|
if (launched) {
|
||||||
|
@ -336,14 +206,12 @@ CMSWindowsRelauncher::mainLoop(void*)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// only enter here when id changes, and the session isn't -1, which
|
|
||||||
// may mean that there is no active session.
|
|
||||||
bool sessionChanged = ((newSessionId != sessionId) && (newSessionId != -1));
|
|
||||||
|
|
||||||
// relaunch if it was running but has stopped unexpectedly.
|
// relaunch if it was running but has stopped unexpectedly.
|
||||||
bool stoppedRunning = (launched && !running);
|
bool stoppedRunning = (launched && !running);
|
||||||
|
|
||||||
if (stoppedRunning || sessionChanged || m_commandChanged) {
|
if (stoppedRunning || m_session.hasChanged() || m_commandChanged) {
|
||||||
|
|
||||||
m_commandChanged = false;
|
m_commandChanged = false;
|
||||||
|
|
||||||
|
@ -354,12 +222,12 @@ CMSWindowsRelauncher::mainLoop(void*)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ok, this is now the active session (forget the old one if any)
|
// ok, this is now the active session (forget the old one if any)
|
||||||
sessionId = newSessionId;
|
m_session.updateActiveSession();
|
||||||
|
|
||||||
SECURITY_ATTRIBUTES sa;
|
SECURITY_ATTRIBUTES sa;
|
||||||
ZeroMemory(&sa, sizeof(SECURITY_ATTRIBUTES));
|
ZeroMemory(&sa, sizeof(SECURITY_ATTRIBUTES));
|
||||||
|
|
||||||
HANDLE userToken = getUserToken(sessionId, &sa);
|
HANDLE userToken = getUserToken(&sa);
|
||||||
if (userToken == NULL) {
|
if (userToken == NULL) {
|
||||||
// HACK: trigger retry mechanism.
|
// HACK: trigger retry mechanism.
|
||||||
launched = true;
|
launched = true;
|
||||||
|
@ -415,7 +283,7 @@ CMSWindowsRelauncher::mainLoop(void*)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
LOG((CLOG_DEBUG "launched in session %i (cmd: %s)",
|
LOG((CLOG_DEBUG "launched in session %i (cmd: %s)",
|
||||||
sessionId, cmd.c_str()));
|
m_session.getActiveSessionId(), cmd.c_str()));
|
||||||
launched = true;
|
launched = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#define WIN32_LEAN_AND_MEAN
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#include "CMSWindowsSession.h"
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <list>
|
#include <list>
|
||||||
|
@ -34,32 +35,31 @@ public:
|
||||||
CIpcServer& ipcServer,
|
CIpcServer& ipcServer,
|
||||||
CIpcLogOutputter& ipcLogOutputter);
|
CIpcLogOutputter& ipcLogOutputter);
|
||||||
virtual ~CMSWindowsRelauncher();
|
virtual ~CMSWindowsRelauncher();
|
||||||
void startAsync();
|
|
||||||
std::string command() const;
|
void startAsync();
|
||||||
void command(const std::string& command, bool elevate);
|
std::string command() const;
|
||||||
void stop();
|
void command(const std::string& command, bool elevate);
|
||||||
|
void stop();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void mainLoop(void*);
|
void mainLoop(void*);
|
||||||
BOOL isProcessInSession(const char* name, DWORD sessionId, PHANDLE process);
|
void outputLoop(void*);
|
||||||
DWORD getSessionId();
|
void shutdownProcess(HANDLE handle, DWORD pid, int timeout);
|
||||||
void outputLoop(void*);
|
void shutdownExistingProcesses();
|
||||||
void shutdownProcess(HANDLE handle, DWORD pid, int timeout);
|
|
||||||
void shutdownExistingProcesses();
|
|
||||||
HANDLE duplicateProcessToken(HANDLE process, LPSECURITY_ATTRIBUTES security);
|
HANDLE duplicateProcessToken(HANDLE process, LPSECURITY_ATTRIBUTES security);
|
||||||
HANDLE getSessionToken(DWORD sessionId, LPSECURITY_ATTRIBUTES security);
|
HANDLE getUserToken(LPSECURITY_ATTRIBUTES security);
|
||||||
HANDLE getUserToken(DWORD sessionId, LPSECURITY_ATTRIBUTES security);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CThread* m_thread;
|
CThread* m_thread;
|
||||||
bool m_autoDetectCommand;
|
bool m_autoDetectCommand;
|
||||||
std::string m_command;
|
std::string m_command;
|
||||||
bool m_running;
|
bool m_running;
|
||||||
bool m_commandChanged;
|
bool m_commandChanged;
|
||||||
HANDLE m_stdOutWrite;
|
HANDLE m_stdOutWrite;
|
||||||
HANDLE m_stdOutRead;
|
HANDLE m_stdOutRead;
|
||||||
CThread* m_outputThread;
|
CThread* m_outputThread;
|
||||||
CIpcServer& m_ipcServer;
|
CIpcServer& m_ipcServer;
|
||||||
CIpcLogOutputter& m_ipcLogOutputter;
|
CIpcLogOutputter& m_ipcLogOutputter;
|
||||||
bool m_elevateProcess;
|
bool m_elevateProcess;
|
||||||
|
CMSWindowsSession m_session;
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,182 @@
|
||||||
|
/*
|
||||||
|
* synergy -- mouse and keyboard sharing utility
|
||||||
|
* Copyright (C) 2013 Bolton Software 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 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 "CMSWindowsSession.h"
|
||||||
|
#include "CLog.h"
|
||||||
|
#include <Tlhelp32.h>
|
||||||
|
#include <Wtsapi32.h>
|
||||||
|
|
||||||
|
CMSWindowsSession::CMSWindowsSession() :
|
||||||
|
m_sessionId(-1),
|
||||||
|
m_newSessionId(-1)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
CMSWindowsSession::~CMSWindowsSession()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD
|
||||||
|
CMSWindowsSession::getSessionId()
|
||||||
|
{
|
||||||
|
return WTSGetActiveConsoleSessionId();
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
CMSWindowsSession::isProcessInSession(const char* name, PHANDLE process = NULL)
|
||||||
|
{
|
||||||
|
BOOL result = isProcessInSession_(name, process);
|
||||||
|
if (!result) {
|
||||||
|
LOG((CLOG_ERR "could not find winlogon in session %i", m_sessionId));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
CMSWindowsSession::isProcessInSession_(const char* name, PHANDLE process = NULL)
|
||||||
|
{
|
||||||
|
// first we need to take a snapshot of the running processes
|
||||||
|
HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
|
||||||
|
if (snapshot == INVALID_HANDLE_VALUE) {
|
||||||
|
LOG((CLOG_ERR "could not get process snapshot (error: %i)",
|
||||||
|
GetLastError()));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
PROCESSENTRY32 entry;
|
||||||
|
entry.dwSize = sizeof(PROCESSENTRY32);
|
||||||
|
|
||||||
|
// get the first process, and if we can't do that then it's
|
||||||
|
// unlikely we can go any further
|
||||||
|
BOOL gotEntry = Process32First(snapshot, &entry);
|
||||||
|
if (!gotEntry) {
|
||||||
|
LOG((CLOG_ERR "could not get first process entry (error: %i)",
|
||||||
|
GetLastError()));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// used to record process names for debug info
|
||||||
|
std::list<std::string> nameList;
|
||||||
|
|
||||||
|
// now just iterate until we can find winlogon.exe pid
|
||||||
|
DWORD pid = 0;
|
||||||
|
while(gotEntry) {
|
||||||
|
|
||||||
|
// make sure we're not checking the system process
|
||||||
|
if (entry.th32ProcessID != 0) {
|
||||||
|
|
||||||
|
DWORD processSessionId;
|
||||||
|
BOOL pidToSidRet = ProcessIdToSessionId(
|
||||||
|
entry.th32ProcessID, &processSessionId);
|
||||||
|
|
||||||
|
if (!pidToSidRet) {
|
||||||
|
LOG((CLOG_ERR "could not get session id for process id %i (error: %i)",
|
||||||
|
entry.th32ProcessID, GetLastError()));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// only pay attention to processes in the active session
|
||||||
|
if (processSessionId == m_sessionId) {
|
||||||
|
|
||||||
|
// store the names so we can record them for debug
|
||||||
|
nameList.push_back(entry.szExeFile);
|
||||||
|
|
||||||
|
if (_stricmp(entry.szExeFile, name) == 0) {
|
||||||
|
pid = entry.th32ProcessID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// now move on to the next entry (if we're not at the end)
|
||||||
|
gotEntry = Process32Next(snapshot, &entry);
|
||||||
|
if (!gotEntry) {
|
||||||
|
|
||||||
|
DWORD err = GetLastError();
|
||||||
|
if (err != ERROR_NO_MORE_FILES) {
|
||||||
|
|
||||||
|
// only worry about error if it's not the end of the snapshot
|
||||||
|
LOG((CLOG_ERR "could not get subsiquent process entry (error: %i)",
|
||||||
|
GetLastError()));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string nameListJoin;
|
||||||
|
for(std::list<std::string>::iterator it = nameList.begin();
|
||||||
|
it != nameList.end(); it++) {
|
||||||
|
nameListJoin.append(*it);
|
||||||
|
nameListJoin.append(", ");
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG((CLOG_DEBUG "processes in session %d: %s",
|
||||||
|
m_sessionId, nameListJoin.c_str()));
|
||||||
|
|
||||||
|
CloseHandle(snapshot);
|
||||||
|
|
||||||
|
if (pid) {
|
||||||
|
if (process != NULL) {
|
||||||
|
// now get the process, which we'll use to get the process token.
|
||||||
|
LOG((CLOG_DEBUG "found %s in session %i", name, m_sessionId));
|
||||||
|
*process = OpenProcess(MAXIMUM_ALLOWED, FALSE, pid);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HANDLE
|
||||||
|
CMSWindowsSession::getUserToken(LPSECURITY_ATTRIBUTES security)
|
||||||
|
{
|
||||||
|
HANDLE sourceToken;
|
||||||
|
if (!WTSQueryUserToken(m_sessionId, &sourceToken)) {
|
||||||
|
LOG((CLOG_ERR "could not get token from session %d (error: %i)", m_sessionId, GetLastError()));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
HANDLE newToken;
|
||||||
|
if (!DuplicateTokenEx(
|
||||||
|
sourceToken, TOKEN_ASSIGN_PRIMARY | TOKEN_ALL_ACCESS, security,
|
||||||
|
SecurityImpersonation, TokenPrimary, &newToken)) {
|
||||||
|
|
||||||
|
LOG((CLOG_ERR "could not duplicate token (error: %i)", GetLastError()));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG((CLOG_DEBUG "duplicated, new token: %i", newToken));
|
||||||
|
return newToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
CMSWindowsSession::hasChanged()
|
||||||
|
{
|
||||||
|
return ((m_newSessionId != m_sessionId) && (m_newSessionId != -1));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CMSWindowsSession::updateNewSessionId()
|
||||||
|
{
|
||||||
|
m_newSessionId = getSessionId();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CMSWindowsSession::updateActiveSession()
|
||||||
|
{
|
||||||
|
m_sessionId = m_newSessionId;
|
||||||
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
/*
|
||||||
|
* synergy -- mouse and keyboard sharing utility
|
||||||
|
* Copyright (C) 2013 Bolton Software 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 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
|
||||||
|
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#include <Windows.h>
|
||||||
|
|
||||||
|
class CMSWindowsSession {
|
||||||
|
public:
|
||||||
|
CMSWindowsSession();
|
||||||
|
~CMSWindowsSession();
|
||||||
|
|
||||||
|
//! Get session ID from Windows
|
||||||
|
/*!
|
||||||
|
This gets the physical session (the one the keyboard and
|
||||||
|
mouse is connected to), sometimes this returns -1.
|
||||||
|
*/
|
||||||
|
DWORD getSessionId();
|
||||||
|
|
||||||
|
BOOL isProcessInSession(const char* name, PHANDLE process);
|
||||||
|
HANDLE getUserToken(LPSECURITY_ATTRIBUTES security);
|
||||||
|
DWORD getActiveSessionId() { return m_sessionId; }
|
||||||
|
|
||||||
|
//!
|
||||||
|
/*!
|
||||||
|
only enter here when id changes, and the session isn't -1, which
|
||||||
|
may mean that there is no active session.
|
||||||
|
*/
|
||||||
|
BOOL hasChanged();
|
||||||
|
|
||||||
|
void updateNewSessionId();
|
||||||
|
void updateActiveSession();
|
||||||
|
|
||||||
|
private:
|
||||||
|
BOOL isProcessInSession_(const char* name, PHANDLE process);
|
||||||
|
|
||||||
|
private:
|
||||||
|
DWORD m_sessionId;
|
||||||
|
DWORD m_newSessionId;
|
||||||
|
};
|
|
@ -33,6 +33,7 @@ if (WIN32)
|
||||||
CMSWindowsHookLibraryLoader.h
|
CMSWindowsHookLibraryLoader.h
|
||||||
IMSWindowsClipboardFacade.h
|
IMSWindowsClipboardFacade.h
|
||||||
CMSWindowsDebugOutputter.h
|
CMSWindowsDebugOutputter.h
|
||||||
|
CMSWindowsSession.h
|
||||||
)
|
)
|
||||||
|
|
||||||
set(src
|
set(src
|
||||||
|
@ -52,6 +53,7 @@ if (WIN32)
|
||||||
CMSWindowsRelauncher.cpp
|
CMSWindowsRelauncher.cpp
|
||||||
CMSWindowsHookLibraryLoader.cpp
|
CMSWindowsHookLibraryLoader.cpp
|
||||||
CMSWindowsDebugOutputter.cpp
|
CMSWindowsDebugOutputter.cpp
|
||||||
|
CMSWindowsSession.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
list(APPEND src
|
list(APPEND src
|
||||||
|
|
Loading…
Reference in New Issue