#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(
bool autoDetectCommand,
IpcServer& ipcServer,
IpcLogOutputter& ipcLogOutputter) :
IpcLogOutputter& ipcLogOutputter,
bool foreground) :
m_thread(NULL),
m_autoDetectCommand(autoDetectCommand),
m_monitoring(true),
@ -63,7 +64,8 @@ MSWindowsWatchdog::MSWindowsWatchdog(
m_processRunning(false),
m_fileLogOutputter(NULL),
m_autoElevated(false),
m_ready(false)
m_ready(false),
m_foreground(foreground)
{
m_mutex = ARCH->newMutex();
m_condVar = ARCH->newCondVar();
@ -200,9 +202,23 @@ MSWindowsWatchdog::mainLoop(void*)
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();
}
}
if (m_processRunning && !isProcessActive()) {
@ -284,6 +300,13 @@ MSWindowsWatchdog::startProcess()
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();
SECURITY_ATTRIBUTES sa;
@ -298,14 +321,14 @@ MSWindowsWatchdog::startProcess()
// patch by Jack Zhou and Henry Tung
// set UIAccess to fix Windows 8 GUI interaction
// http://symless.com/spit/issues/details/3338/#c70
DWORD uiAccess = 1;
SetTokenInformation(userToken, TokenUIAccess, &uiAccess, sizeof(DWORD));
BOOL createRet = doStartProcess(m_command, userToken, &sa);
createRet = startProcessAsUser(m_command, userToken, &sa);
}
if (!createRet) {
LOG((CLOG_ERR "could not launch"));
LOG((CLOG_ERR "could not launch command"));
DWORD exitCode = 0;
GetExitCodeProcess(m_processInfo.hProcess, &exitCode);
LOG((CLOG_ERR "exit code: %d", exitCode));
@ -329,7 +352,21 @@ MSWindowsWatchdog::startProcess()
}
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
ZeroMemory(&m_processInfo, sizeof(PROCESS_INFORMATION));
@ -542,7 +579,7 @@ MSWindowsWatchdog::getActiveDesktop(LPSECURITY_ATTRIBUTES security)
HANDLE userToken = getUserToken(security);
m_elevateProcess = elevateProcess;
BOOL createRet = doStartProcess(syntoolCommand, userToken, security);
BOOL createRet = startProcessAsUser(syntoolCommand, userToken, security);
if (!createRet) {
DWORD rc = GetLastError();

View File

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

View File

@ -155,7 +155,7 @@ DaemonApp::run(int argc, char** argv)
if (foreground) {
// run process in foreground instead of daemonizing.
// useful for debugging.
mainLoop(false);
mainLoop(false, foreground);
}
else {
#if SYSAPI_WIN32
@ -192,7 +192,7 @@ DaemonApp::run(int argc, char** argv)
}
void
DaemonApp::mainLoop(bool logToFile)
DaemonApp::mainLoop(bool logToFile, bool foreground)
{
try
{
@ -215,7 +215,7 @@ DaemonApp::mainLoop(bool logToFile)
CLOG->insert(m_ipcLogOutputter);
#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);
#endif

View File

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