#6383 Use CreateProcess when in foreground mode

This commit is contained in:
Nick Bolton 2018-08-02 16:25:10 +01:00
parent 568a008037
commit 026b1f0de1
4 changed files with 142 additions and 102 deletions

View File

@ -49,7 +49,8 @@ const char g_activeDesktop[] = {"activeDesktop:"};
MSWindowsWatchdog::MSWindowsWatchdog( MSWindowsWatchdog::MSWindowsWatchdog(
bool autoDetectCommand, bool autoDetectCommand,
IpcServer& ipcServer, IpcServer& ipcServer,
IpcLogOutputter& ipcLogOutputter) : IpcLogOutputter& ipcLogOutputter,
bool foreground) :
m_thread(NULL), m_thread(NULL),
m_autoDetectCommand(autoDetectCommand), m_autoDetectCommand(autoDetectCommand),
m_monitoring(true), m_monitoring(true),
@ -63,7 +64,8 @@ MSWindowsWatchdog::MSWindowsWatchdog(
m_processRunning(false), m_processRunning(false),
m_fileLogOutputter(NULL), m_fileLogOutputter(NULL),
m_autoElevated(false), m_autoElevated(false),
m_ready(false) m_ready(false),
m_foreground(foreground)
{ {
m_mutex = ARCH->newMutex(); m_mutex = ARCH->newMutex();
m_condVar = ARCH->newCondVar(); m_condVar = ARCH->newCondVar();
@ -200,9 +202,23 @@ MSWindowsWatchdog::mainLoop(void*)
ARCH->sleep(timeout); ARCH->sleep(timeout);
} }
if (!getCommand().empty() && ((m_processFailures != 0) || m_session.hasChanged() || m_commandChanged)) { if (!getCommand().empty()) {
bool startNeeded = false;
if (m_processFailures != 0) {
startNeeded = true;
}
else if (!m_foreground && m_session.hasChanged()) {
startNeeded = true;
}
else if (m_commandChanged) {
startNeeded = true;
}
if (startNeeded) {
startProcess(); startProcess();
} }
}
if (m_processRunning && !isProcessActive()) { if (m_processRunning && !isProcessActive()) {
@ -284,6 +300,13 @@ MSWindowsWatchdog::startProcess()
m_processRunning = false; m_processRunning = false;
} }
BOOL createRet;
if (m_foreground) {
LOG((CLOG_DEBUG "starting command in foreground"));
createRet = startProcessInForeground(m_command);
}
else {
LOG((CLOG_DEBUG "starting command as session user"));
m_session.updateActiveSession(); m_session.updateActiveSession();
SECURITY_ATTRIBUTES sa; SECURITY_ATTRIBUTES sa;
@ -298,14 +321,14 @@ MSWindowsWatchdog::startProcess()
// 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
// http://symless.com/spit/issues/details/3338/#c70
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); createRet = startProcessAsUser(m_command, userToken, &sa);
}
if (!createRet) { if (!createRet) {
LOG((CLOG_ERR "could not launch")); LOG((CLOG_ERR "could not launch command"));
DWORD exitCode = 0; DWORD exitCode = 0;
GetExitCodeProcess(m_processInfo.hProcess, &exitCode); GetExitCodeProcess(m_processInfo.hProcess, &exitCode);
LOG((CLOG_ERR "exit code: %d", exitCode)); LOG((CLOG_ERR "exit code: %d", exitCode));
@ -329,7 +352,21 @@ MSWindowsWatchdog::startProcess()
} }
BOOL BOOL
MSWindowsWatchdog::doStartProcess(String& command, HANDLE userToken, LPSECURITY_ATTRIBUTES sa) MSWindowsWatchdog::startProcessInForeground(String& command)
{
// clear, as we're reusing process info struct
ZeroMemory(&m_processInfo, sizeof(PROCESS_INFORMATION));
STARTUPINFO startupInfo;
ZeroMemory(&startupInfo, sizeof(STARTUPINFO));
return CreateProcess(
NULL, LPSTR(command.c_str()), NULL, NULL,
FALSE, 0, NULL, NULL, &startupInfo, &m_processInfo);
}
BOOL
MSWindowsWatchdog::startProcessAsUser(String& 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));
@ -542,7 +579,7 @@ MSWindowsWatchdog::getActiveDesktop(LPSECURITY_ATTRIBUTES security)
HANDLE userToken = getUserToken(security); HANDLE userToken = getUserToken(security);
m_elevateProcess = elevateProcess; m_elevateProcess = elevateProcess;
BOOL createRet = doStartProcess(syntoolCommand, userToken, security); BOOL createRet = startProcessAsUser(syntoolCommand, userToken, security);
if (!createRet) { if (!createRet) {
DWORD rc = GetLastError(); DWORD rc = GetLastError();

View File

@ -37,7 +37,8 @@ public:
MSWindowsWatchdog( MSWindowsWatchdog(
bool autoDetectCommand, bool autoDetectCommand,
IpcServer& ipcServer, IpcServer& ipcServer,
IpcLogOutputter& ipcLogOutputter); IpcLogOutputter& ipcLogOutputter,
bool foreground);
virtual ~MSWindowsWatchdog(); virtual ~MSWindowsWatchdog();
void startAsync(); void startAsync();
@ -55,7 +56,8 @@ 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(String& command, HANDLE userToken, LPSECURITY_ATTRIBUTES sa); BOOL startProcessAsUser(String& command, HANDLE userToken, LPSECURITY_ATTRIBUTES sa);
BOOL startProcessInForeground(String& command);
void sendSas(); void sendSas();
void getActiveDesktop(LPSECURITY_ATTRIBUTES security); void getActiveDesktop(LPSECURITY_ATTRIBUTES security);
void testOutput(String buffer); void testOutput(String buffer);
@ -81,6 +83,7 @@ private:
ArchMutex m_mutex; ArchMutex m_mutex;
ArchCond m_condVar; ArchCond m_condVar;
bool m_ready; bool m_ready;
bool m_foreground;
}; };
//! Relauncher error //! Relauncher error

View File

@ -155,7 +155,7 @@ DaemonApp::run(int argc, char** argv)
if (foreground) { if (foreground) {
// run process in foreground instead of daemonizing. // run process in foreground instead of daemonizing.
// useful for debugging. // useful for debugging.
mainLoop(false); mainLoop(false, foreground);
} }
else { else {
#if SYSAPI_WIN32 #if SYSAPI_WIN32
@ -192,7 +192,7 @@ DaemonApp::run(int argc, char** argv)
} }
void void
DaemonApp::mainLoop(bool logToFile) DaemonApp::mainLoop(bool logToFile, bool foreground)
{ {
try try
{ {
@ -215,7 +215,7 @@ DaemonApp::mainLoop(bool logToFile)
CLOG->insert(m_ipcLogOutputter); CLOG->insert(m_ipcLogOutputter);
#if SYSAPI_WIN32 #if SYSAPI_WIN32
m_watchdog = new MSWindowsWatchdog(false, *m_ipcServer, *m_ipcLogOutputter); m_watchdog = new MSWindowsWatchdog(false, *m_ipcServer, *m_ipcLogOutputter, foreground);
m_watchdog->setFileLogOutputter(m_fileLogOutputter); m_watchdog->setFileLogOutputter(m_fileLogOutputter);
#endif #endif

View File

@ -37,7 +37,7 @@ public:
DaemonApp(); DaemonApp();
virtual ~DaemonApp(); virtual ~DaemonApp();
int run(int argc, char** argv); int run(int argc, char** argv);
void mainLoop(bool logToFile); void mainLoop(bool logToFile, bool foreground = false);
private: private:
void daemonize(); void daemonize();