added "shutdown existing processes" feature to relauncher.

This commit is contained in:
Nick Bolton 2012-07-10 11:54:20 +00:00
parent f9f04034c9
commit e942093407
2 changed files with 67 additions and 8 deletions

View File

@ -233,6 +233,8 @@ CMSWindowsRelauncher::getCurrentUserToken(DWORD sessionId, LPSECURITY_ATTRIBUTES
void void
CMSWindowsRelauncher::mainLoop(void*) CMSWindowsRelauncher::mainLoop(void*)
{ {
shutdownExistingProcesses();
SendSas sendSasFunc = NULL; SendSas sendSasFunc = NULL;
HINSTANCE sasLib = LoadLibrary("sas.dll"); HINSTANCE sasLib = LoadLibrary("sas.dll");
if (sasLib) { if (sasLib) {
@ -274,7 +276,7 @@ CMSWindowsRelauncher::mainLoop(void*)
if (launched) { if (launched) {
LOG((CLOG_DEBUG "closing existing process to make way for new one")); LOG((CLOG_DEBUG "closing existing process to make way for new one"));
shutdownProcess(pi, 10); shutdownProcess(pi.hProcess, pi.dwProcessId, 10);
launched = false; launched = false;
} }
@ -363,7 +365,7 @@ CMSWindowsRelauncher::mainLoop(void*)
if (launched) { if (launched) {
LOG((CLOG_DEBUG "terminated running process on exit")); LOG((CLOG_DEBUG "terminated running process on exit"));
shutdownProcess(pi, 10); shutdownProcess(pi.hProcess, pi.dwProcessId, 10);
} }
LOG((CLOG_DEBUG "relauncher main thread finished")); LOG((CLOG_DEBUG "relauncher main thread finished"));
@ -432,10 +434,10 @@ CMSWindowsRelauncher::outputLoop(void*)
} }
void void
CMSWindowsRelauncher::shutdownProcess(const PROCESS_INFORMATION& pi, int timeout) CMSWindowsRelauncher::shutdownProcess(HANDLE handle, DWORD pid, int timeout)
{ {
DWORD exitCode; DWORD exitCode;
GetExitCodeProcess(pi.hProcess, &exitCode); GetExitCodeProcess(handle, &exitCode);
if (exitCode != STILL_ACTIVE) if (exitCode != STILL_ACTIVE)
return; return;
@ -446,10 +448,10 @@ CMSWindowsRelauncher::shutdownProcess(const PROCESS_INFORMATION& pi, int timeout
double start = ARCH->time(); double start = ARCH->time();
while (true) while (true)
{ {
GetExitCodeProcess(pi.hProcess, &exitCode); GetExitCodeProcess(handle, &exitCode);
if (exitCode != STILL_ACTIVE) { if (exitCode != STILL_ACTIVE) {
// yay, we got a graceful shutdown. there should be no hook in use errors! // yay, we got a graceful shutdown. there should be no hook in use errors!
LOG((CLOG_INFO "process %d was shutdown gracefully", pi.dwProcessId)); LOG((CLOG_INFO "process %d was shutdown gracefully", pid));
break; break;
} }
else { else {
@ -461,7 +463,7 @@ CMSWindowsRelauncher::shutdownProcess(const PROCESS_INFORMATION& pi, int timeout
// it causes the hook DLL to stay loaded in some apps, // it causes the hook DLL to stay loaded in some apps,
// making it impossible to start synergy again. // making it impossible to start synergy again.
LOG((CLOG_WARN "shutdown timed out after %d secs, forcefully terminating", (int)elapsed)); LOG((CLOG_WARN "shutdown timed out after %d secs, forcefully terminating", (int)elapsed));
TerminateProcess(pi.hProcess, kExitSuccess); TerminateProcess(handle, kExitSuccess);
break; break;
} }
@ -469,3 +471,59 @@ CMSWindowsRelauncher::shutdownProcess(const PROCESS_INFORMATION& pi, int timeout
} }
} }
} }
void
CMSWindowsRelauncher::shutdownExistingProcesses()
{
// 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;
}
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;
}
// 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) {
if (_stricmp(entry.szExeFile, "synergyc.exe") == 0 ||
_stricmp(entry.szExeFile, "synergys.exe") == 0) {
HANDLE handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, entry.th32ProcessID);
shutdownProcess(handle, entry.th32ProcessID, 1);
}
}
// 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;
}
}
}
CloseHandle(snapshot);
}

View File

@ -44,7 +44,8 @@ private:
DWORD getSessionId(); DWORD getSessionId();
HANDLE getCurrentUserToken(DWORD sessionId, LPSECURITY_ATTRIBUTES security); HANDLE getCurrentUserToken(DWORD sessionId, LPSECURITY_ATTRIBUTES security);
void outputLoop(void*); void outputLoop(void*);
void shutdownProcess(const PROCESS_INFORMATION& pi, int timeout); void shutdownProcess(HANDLE handle, DWORD pid, int timeout);
void shutdownExistingProcesses();
private: private:
CThread* m_thread; CThread* m_thread;