fixed handling of calling init() when a previous process did not

call cleanup().  if that process still appears to exist then the
init() fails.  otherwise some cleanup is performed and the init()
proceeds.  a synergy server started while another is running will
now exit immediately without interfering the original server.
This commit is contained in:
crs 2002-07-18 17:03:10 +00:00
parent 635c3d1c62
commit cf71aec730
2 changed files with 42 additions and 15 deletions

View File

@ -33,7 +33,7 @@ typedef struct tagMOUSEHOOKSTRUCTWin2000 {
// all data in this shared section *must* be initialized // all data in this shared section *must* be initialized
static HINSTANCE g_hinstance = NULL; static HINSTANCE g_hinstance = NULL;
static DWORD g_process = NULL; static DWORD g_processID = 0;
static EWheelSupport g_wheelSupport = kWheelNone; static EWheelSupport g_wheelSupport = kWheelNone;
static UINT g_wmMouseWheel = 0; static UINT g_wmMouseWheel = 0;
static DWORD g_threadID = 0; static DWORD g_threadID = 0;
@ -438,17 +438,19 @@ BOOL WINAPI
DllMain(HINSTANCE instance, DWORD reason, LPVOID) DllMain(HINSTANCE instance, DWORD reason, LPVOID)
{ {
if (reason == DLL_PROCESS_ATTACH) { if (reason == DLL_PROCESS_ATTACH) {
if (g_hinstance == NULL) { DisableThreadLibraryCalls(instance);
if (g_processID == 0) {
g_hinstance = instance; g_hinstance = instance;
g_process = GetCurrentProcessId(); g_processID = GetCurrentProcessId();
} }
} }
else if (reason == DLL_PROCESS_DETACH) { else if (reason == DLL_PROCESS_DETACH) {
if (g_process == GetCurrentProcessId()) { if (g_processID == GetCurrentProcessId()) {
if (g_keyboard != NULL || g_mouse != NULL || g_cbt != NULL) { if (g_keyboard != NULL || g_mouse != NULL || g_cbt != NULL) {
uninstall(); uninstall();
} }
g_process = NULL; g_processID = 0;
g_hinstance = NULL;
} }
} }
return TRUE; return TRUE;
@ -461,18 +463,39 @@ init(DWORD threadID)
{ {
assert(g_hinstance != NULL); assert(g_hinstance != NULL);
// see if already initialized. if it is we'll shut down and // try to open process that last called init() to see if it's
// reinitialize. this allows the hook DLL to be reclaimed by // still running or if it died without cleaning up.
// a new synergyd if the previous one died unexpectedly. if (g_processID != 0 && g_processID != GetCurrentProcessId()) {
if (g_threadID != 0) { HANDLE process = OpenProcess(STANDARD_RIGHTS_REQUIRED,
uninstallScreenSaver(); FALSE, g_processID);
uninstall(); if (process != NULL) {
cleanup(); // old process (probably) still exists so refuse to
// reinitialize this DLL (and thus steal it from the
// old process).
CloseHandle(process);
return 0;
}
// clean up after old process. the system should've already
// removed the hooks so we just need to reset our state.
g_hinstance = GetModuleHandle("synrgyhk");
g_processID = GetCurrentProcessId();
g_wheelSupport = kWheelNone;
g_threadID = 0;
g_keyboard = NULL;
g_mouse = NULL;
g_cbt = NULL;
g_getMessage = NULL;
g_keyHookThread = NULL;
g_keyHookThreadID = 0;
g_keyHookEvent = NULL;
g_keyboardLL = NULL;
g_screenSaver = false;
} }
// save thread id. we'll post messages to this thread's // save thread id. we'll post messages to this thread's
// message queue. // message queue.
g_threadID = threadID; g_threadID = threadID;
// set defaults // set defaults
g_relay = false; g_relay = false;
@ -493,7 +516,9 @@ cleanup(void)
{ {
assert(g_hinstance != NULL); assert(g_hinstance != NULL);
g_threadID = 0; if (g_processID == GetCurrentProcessId()) {
g_threadID = 0;
}
return 1; return 1;
} }

View File

@ -398,7 +398,9 @@ CMSWindowsPrimaryScreen::onPreOpen()
// initialize hook library // initialize hook library
m_threadID = GetCurrentThreadId(); m_threadID = GetCurrentThreadId();
m_init(m_threadID); if (m_init(m_threadID) == 0) {
throw XScreenOpenFailure();
}
} }
void void