diff --git a/src/lib/arch/ArchDaemonNone.cpp b/src/lib/arch/ArchDaemonNone.cpp index 4493851c..47e589a3 100644 --- a/src/lib/arch/ArchDaemonNone.cpp +++ b/src/lib/arch/ArchDaemonNone.cpp @@ -37,14 +37,13 @@ CArchDaemonNone::installDaemon(const char*, const char*, const char*, const char*, - const char*, - bool) + const char*) { // do nothing } void -CArchDaemonNone::uninstallDaemon(const char*, bool) +CArchDaemonNone::uninstallDaemon(const char*) { // do nothing } @@ -58,13 +57,13 @@ CArchDaemonNone::daemonize(const char* name, DaemonFunc func) } bool -CArchDaemonNone::canInstallDaemon(const char*, bool) +CArchDaemonNone::canInstallDaemon(const char*) { return false; } bool -CArchDaemonNone::isDaemonInstalled(const char*, bool) +CArchDaemonNone::isDaemonInstalled(const char*) { return false; } diff --git a/src/lib/arch/ArchDaemonNone.h b/src/lib/arch/ArchDaemonNone.h index 22b6c432..765b15b6 100644 --- a/src/lib/arch/ArchDaemonNone.h +++ b/src/lib/arch/ArchDaemonNone.h @@ -39,12 +39,11 @@ public: const char* description, const char* pathname, const char* commandLine, - const char* dependencies, - bool allUsers); - virtual void uninstallDaemon(const char* name, bool allUsers); + const char* dependencies); + virtual void uninstallDaemon(const char* name); virtual int daemonize(const char* name, DaemonFunc func); - virtual bool canInstallDaemon(const char* name, bool allUsers); - virtual bool isDaemonInstalled(const char* name, bool allUsers); + virtual bool canInstallDaemon(const char* name); + virtual bool isDaemonInstalled(const char* name); virtual void installDaemon(); virtual void uninstallDaemon(); virtual std::string commandLine() const; diff --git a/src/lib/arch/IArchDaemon.h b/src/lib/arch/IArchDaemon.h index 6822fd9d..1d63cbf5 100644 --- a/src/lib/arch/IArchDaemon.h +++ b/src/lib/arch/IArchDaemon.h @@ -51,14 +51,13 @@ public: const char* description, const char* pathname, const char* commandLine, - const char* dependencies, - bool allUsers) = 0; + const char* dependencies) = 0; //! Uninstall daemon /*! Uninstall a daemon. Throws an \c XArchDaemon on failure. */ - virtual void uninstallDaemon(const char* name, bool allUsers) = 0; + virtual void uninstallDaemon(const char* name) = 0; //! Install daemon /*! @@ -109,13 +108,13 @@ public: may still fail. This method ignores whether or not the service is already installed. */ - virtual bool canInstallDaemon(const char* name, bool allUsers) = 0; + virtual bool canInstallDaemon(const char* name) = 0; //! Check if the daemon is installed /*! Returns true iff the daemon is installed. */ - virtual bool isDaemonInstalled(const char* name, bool allUsers) = 0; + virtual bool isDaemonInstalled(const char* name) = 0; //@} diff --git a/src/lib/arch/win32/ArchDaemonWindows.cpp b/src/lib/arch/win32/ArchDaemonWindows.cpp index 91a202ed..6e5d33e0 100644 --- a/src/lib/arch/win32/ArchDaemonWindows.cpp +++ b/src/lib/arch/win32/ArchDaemonWindows.cpp @@ -45,17 +45,12 @@ int CArchDaemonWindows::runDaemon(RunFunc runFunc) { assert(s_daemon != NULL); - return s_daemon->doRunDaemon(runFunc); } void CArchDaemonWindows::daemonRunning(bool running) { - // if s_daemon is NULL we assume we're running on the windows - // 95 family and we just ignore this call so the caller doesn't - // have to go through the trouble of not calling it on the - // windows 95 family. if (s_daemon != NULL) { s_daemon->doDaemonRunning(running); } @@ -75,13 +70,8 @@ CArchDaemonWindows::getDaemonQuitMessage() void CArchDaemonWindows::daemonFailed(int result) { - // if s_daemon is NULL we assume we're running on the windows - // 95 family and we just ignore this call so the caller doesn't - // have to go through the trouble of not calling it on the - // windows 95 family. - if (s_daemon != NULL) { - throw XArchDaemonRunFailed(result); - } + assert(s_daemon != NULL); + throw XArchDaemonRunFailed(result); } void @@ -89,195 +79,146 @@ CArchDaemonWindows::installDaemon(const char* name, const char* description, const char* pathname, const char* commandLine, - const char* dependencies, - bool allUsers) + const char* dependencies) { - // if not for all users then use the user's autostart registry. - // key. if windows 95 family then use windows 95 services key. - if (!allUsers || CArchMiscWindows::isWindows95Family()) { - // open registry - HKEY key = (allUsers && CArchMiscWindows::isWindows95Family()) ? - open95ServicesKey() : openUserStartupKey(); - if (key == NULL) { - // can't open key - throw XArchDaemonInstallFailed(new XArchEvalWindows); - } - - // construct entry - std::string value; - value += "\""; - value += pathname; - value += "\" "; - value += commandLine; - - // install entry - CArchMiscWindows::setValue(key, name, value); - - // clean up - CArchMiscWindows::closeKey(key); + // open service manager + SC_HANDLE mgr = OpenSCManager(NULL, NULL, GENERIC_WRITE); + if (mgr == NULL) { + // can't open service manager + throw XArchDaemonInstallFailed(new XArchEvalWindows); } - // windows NT family services + // create the service + SC_HANDLE service = CreateService( + mgr, + name, + name, + 0, + SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS, + SERVICE_AUTO_START, + SERVICE_ERROR_NORMAL, + pathname, + NULL, + NULL, + dependencies, + NULL, + NULL); + + if (service == NULL) { + // can't create service + DWORD err = GetLastError(); + if (err != ERROR_SERVICE_EXISTS) { + CloseServiceHandle(mgr); + throw XArchDaemonInstallFailed(new XArchEvalWindows(err)); + } + } else { - // open service manager - SC_HANDLE mgr = OpenSCManager(NULL, NULL, GENERIC_WRITE); - if (mgr == NULL) { - // can't open service manager - throw XArchDaemonInstallFailed(new XArchEvalWindows); - } - - // create the service - SC_HANDLE service = CreateService(mgr, - name, - name, - 0, - SERVICE_WIN32_OWN_PROCESS | - SERVICE_INTERACTIVE_PROCESS, - SERVICE_AUTO_START, - SERVICE_ERROR_NORMAL, - pathname, - NULL, - NULL, - dependencies, - NULL, - NULL); - if (service == NULL) { - // can't create service - DWORD err = GetLastError(); - if (err != ERROR_SERVICE_EXISTS) { - CloseServiceHandle(mgr); - throw XArchDaemonInstallFailed(new XArchEvalWindows(err)); - } - } - else { - // done with service (but only try to close if not null) - CloseServiceHandle(service); - } - - // done with manager - CloseServiceHandle(mgr); - - // open the registry key for this service - HKEY key = openNTServicesKey(); - key = CArchMiscWindows::addKey(key, name); - if (key == NULL) { - // can't open key - DWORD err = GetLastError(); - try { - uninstallDaemon(name, allUsers); - } - catch (...) { - // ignore - } - throw XArchDaemonInstallFailed(new XArchEvalWindows(err)); - } - - // set the description - CArchMiscWindows::setValue(key, _T("Description"), description); - - // set command line - key = CArchMiscWindows::addKey(key, _T("Parameters")); - if (key == NULL) { - // can't open key - DWORD err = GetLastError(); - CArchMiscWindows::closeKey(key); - try { - uninstallDaemon(name, allUsers); - } - catch (...) { - // ignore - } - throw XArchDaemonInstallFailed(new XArchEvalWindows(err)); - } - CArchMiscWindows::setValue(key, _T("CommandLine"), commandLine); - - // done with registry - CArchMiscWindows::closeKey(key); + // done with service (but only try to close if not null) + CloseServiceHandle(service); } + + // done with manager + CloseServiceHandle(mgr); + + // open the registry key for this service + HKEY key = openNTServicesKey(); + key = CArchMiscWindows::addKey(key, name); + if (key == NULL) { + // can't open key + DWORD err = GetLastError(); + try { + uninstallDaemon(name); + } + catch (...) { + // ignore + } + throw XArchDaemonInstallFailed(new XArchEvalWindows(err)); + } + + // set the description + CArchMiscWindows::setValue(key, _T("Description"), description); + + // set command line + key = CArchMiscWindows::addKey(key, _T("Parameters")); + if (key == NULL) { + // can't open key + DWORD err = GetLastError(); + CArchMiscWindows::closeKey(key); + try { + uninstallDaemon(name); + } + catch (...) { + // ignore + } + throw XArchDaemonInstallFailed(new XArchEvalWindows(err)); + } + CArchMiscWindows::setValue(key, _T("CommandLine"), commandLine); + + // done with registry + CArchMiscWindows::closeKey(key); } void -CArchDaemonWindows::uninstallDaemon(const char* name, bool allUsers) +CArchDaemonWindows::uninstallDaemon(const char* name) { - // if not for all users then use the user's autostart registry. - // key. if windows 95 family then use windows 95 services key. - if (!allUsers || CArchMiscWindows::isWindows95Family()) { - // open registry - HKEY key = (allUsers && CArchMiscWindows::isWindows95Family()) ? - open95ServicesKey() : openUserStartupKey(); - if (key == NULL) { - // can't open key. daemon is probably not installed. - throw XArchDaemonUninstallNotInstalled(new XArchEvalWindows); - } - - // remove entry - CArchMiscWindows::deleteValue(key, name); - - // clean up + // remove parameters for this service. ignore failures. + HKEY key = openNTServicesKey(); + key = CArchMiscWindows::openKey(key, name); + if (key != NULL) { + CArchMiscWindows::deleteKey(key, _T("Parameters")); CArchMiscWindows::closeKey(key); } - // windows NT family services - else { - // remove parameters for this service. ignore failures. - HKEY key = openNTServicesKey(); - key = CArchMiscWindows::openKey(key, name); - if (key != NULL) { - CArchMiscWindows::deleteKey(key, _T("Parameters")); - CArchMiscWindows::closeKey(key); - } + // open service manager + SC_HANDLE mgr = OpenSCManager(NULL, NULL, GENERIC_WRITE); + if (mgr == NULL) { + // can't open service manager + throw XArchDaemonUninstallFailed(new XArchEvalWindows); + } - // open service manager - SC_HANDLE mgr = OpenSCManager(NULL, NULL, GENERIC_WRITE); - if (mgr == NULL) { - // can't open service manager - throw XArchDaemonUninstallFailed(new XArchEvalWindows); - } - - // open the service. oddly, you must open a service to delete it. - SC_HANDLE service = OpenService(mgr, name, DELETE | SERVICE_STOP); - if (service == NULL) { - DWORD err = GetLastError(); - CloseServiceHandle(mgr); - if (err != ERROR_SERVICE_DOES_NOT_EXIST) { - throw XArchDaemonUninstallFailed(new XArchEvalWindows(err)); - } - throw XArchDaemonUninstallNotInstalled(new XArchEvalWindows(err)); - } - - // stop the service. we don't care if we fail. - SERVICE_STATUS status; - ControlService(service, SERVICE_CONTROL_STOP, &status); - - // delete the service - const bool okay = (DeleteService(service) == 0); - const DWORD err = GetLastError(); - - // clean up - CloseServiceHandle(service); + // open the service. oddly, you must open a service to delete it. + SC_HANDLE service = OpenService(mgr, name, DELETE | SERVICE_STOP); + if (service == NULL) { + DWORD err = GetLastError(); CloseServiceHandle(mgr); - - // give windows a chance to remove the service before - // we check if it still exists. - ARCH->sleep(1); - - // handle failure. ignore error if service isn't installed anymore. - if (!okay && isDaemonInstalled(name, allUsers)) { - if (err == ERROR_SUCCESS) { - // this seems to occur even though the uninstall was successful. - // it could be a timing issue, i.e., isDaemonInstalled is - // called too soon. i've added a sleep to try and stop this. - return; - } - if (err == ERROR_IO_PENDING) { - // this seems to be a spurious error - return; - } - if (err != ERROR_SERVICE_MARKED_FOR_DELETE) { - throw XArchDaemonUninstallFailed(new XArchEvalWindows(err)); - } - throw XArchDaemonUninstallNotInstalled(new XArchEvalWindows(err)); + if (err != ERROR_SERVICE_DOES_NOT_EXIST) { + throw XArchDaemonUninstallFailed(new XArchEvalWindows(err)); } + throw XArchDaemonUninstallNotInstalled(new XArchEvalWindows(err)); + } + + // stop the service. we don't care if we fail. + SERVICE_STATUS status; + ControlService(service, SERVICE_CONTROL_STOP, &status); + + // delete the service + const bool okay = (DeleteService(service) == 0); + const DWORD err = GetLastError(); + + // clean up + CloseServiceHandle(service); + CloseServiceHandle(mgr); + + // give windows a chance to remove the service before + // we check if it still exists. + ARCH->sleep(1); + + // handle failure. ignore error if service isn't installed anymore. + if (!okay && isDaemonInstalled(name)) { + if (err == ERROR_SUCCESS) { + // this seems to occur even though the uninstall was successful. + // it could be a timing issue, i.e., isDaemonInstalled is + // called too soon. i've added a sleep to try and stop this. + return; + } + if (err == ERROR_IO_PENDING) { + // this seems to be a spurious error + return; + } + if (err != ERROR_SERVICE_MARKED_FOR_DELETE) { + throw XArchDaemonUninstallFailed(new XArchEvalWindows(err)); + } + throw XArchDaemonUninstallNotInstalled(new XArchEvalWindows(err)); } } @@ -287,98 +228,48 @@ CArchDaemonWindows::daemonize(const char* name, DaemonFunc func) assert(name != NULL); assert(func != NULL); - // windows 95 family services - if (CArchMiscWindows::isWindows95Family()) { - typedef DWORD (WINAPI *RegisterServiceProcessT)(DWORD, DWORD); + // save daemon function + m_daemonFunc = func; - // mark this process as a service so it's not killed when the - // user logs off. - HINSTANCE kernel = LoadLibrary("kernel32.dll"); - if (kernel == NULL) { - throw XArchDaemonFailed(new XArchEvalWindows); - } - RegisterServiceProcessT RegisterServiceProcess = - reinterpret_cast( - GetProcAddress(kernel, - "RegisterServiceProcess")); - if (RegisterServiceProcess == NULL) { - // missing RegisterServiceProcess function - DWORD err = GetLastError(); - FreeLibrary(kernel); - throw XArchDaemonFailed(new XArchEvalWindows(err)); - } - if (RegisterServiceProcess(0, 1) == 0) { - // RegisterServiceProcess failed - DWORD err = GetLastError(); - FreeLibrary(kernel); - throw XArchDaemonFailed(new XArchEvalWindows(err)); - } - FreeLibrary(kernel); - - // now simply call the daemon function - return func(1, &name); - } - - // windows NT family services - else { - // save daemon function - m_daemonFunc = func; - - // construct the service entry - SERVICE_TABLE_ENTRY entry[2]; - entry[0].lpServiceName = const_cast(name); - entry[0].lpServiceProc = &CArchDaemonWindows::serviceMainEntry; - entry[1].lpServiceName = NULL; - entry[1].lpServiceProc = NULL; - - // hook us up to the service control manager. this won't return - // (if successful) until the processes have terminated. - s_daemon = this; - if (StartServiceCtrlDispatcher(entry) == 0) { - // StartServiceCtrlDispatcher failed - s_daemon = NULL; - throw XArchDaemonFailed(new XArchEvalWindows); - } + // construct the service entry + SERVICE_TABLE_ENTRY entry[2]; + entry[0].lpServiceName = const_cast(name); + entry[0].lpServiceProc = &CArchDaemonWindows::serviceMainEntry; + entry[1].lpServiceName = NULL; + entry[1].lpServiceProc = NULL; + // hook us up to the service control manager. this won't return + // (if successful) until the processes have terminated. + s_daemon = this; + if (StartServiceCtrlDispatcher(entry) == 0) { + // StartServiceCtrlDispatcher failed s_daemon = NULL; - return m_daemonResult; + throw XArchDaemonFailed(new XArchEvalWindows); } + + s_daemon = NULL; + return m_daemonResult; } bool -CArchDaemonWindows::canInstallDaemon(const char* /*name*/, bool allUsers) +CArchDaemonWindows::canInstallDaemon(const char* /*name*/) { - // if not for all users then use the user's autostart registry. - // key. if windows 95 family then use windows 95 services key. - if (!allUsers || CArchMiscWindows::isWindows95Family()) { - // check if we can open the registry key - HKEY key = (allUsers && CArchMiscWindows::isWindows95Family()) ? - open95ServicesKey() : openUserStartupKey(); - CArchMiscWindows::closeKey(key); - return (key != NULL); + // check if we can open service manager for write + SC_HANDLE mgr = OpenSCManager(NULL, NULL, GENERIC_WRITE); + if (mgr == NULL) { + return false; } + CloseServiceHandle(mgr); - // windows NT family services - else { - // check if we can open service manager for write - SC_HANDLE mgr = OpenSCManager(NULL, NULL, GENERIC_WRITE); - if (mgr == NULL) { - return false; - } - CloseServiceHandle(mgr); + // check if we can open the registry key + HKEY key = openNTServicesKey(); + CArchMiscWindows::closeKey(key); - // check if we can open the registry key - HKEY key = openNTServicesKey(); -// key = CArchMiscWindows::addKey(key, name); -// key = CArchMiscWindows::addKey(key, _T("Parameters")); - CArchMiscWindows::closeKey(key); - - return (key != NULL); - } + return (key != NULL); } bool -CArchDaemonWindows::isDaemonInstalled(const char* name, bool allUsers) +CArchDaemonWindows::isDaemonInstalled(const char* name) { // open service manager SC_HANDLE mgr = OpenSCManager(NULL, NULL, GENERIC_READ); @@ -411,36 +302,6 @@ CArchDaemonWindows::openNTServicesKey() return CArchMiscWindows::addKey(HKEY_LOCAL_MACHINE, s_keyNames); } -HKEY -CArchDaemonWindows::open95ServicesKey() -{ - static const char* s_keyNames[] = { - _T("Software"), - _T("Microsoft"), - _T("Windows"), - _T("CurrentVersion"), - _T("RunServices"), - NULL - }; - - return CArchMiscWindows::addKey(HKEY_LOCAL_MACHINE, s_keyNames); -} - -HKEY -CArchDaemonWindows::openUserStartupKey() -{ - static const char* s_keyNames[] = { - _T("Software"), - _T("Microsoft"), - _T("Windows"), - _T("CurrentVersion"), - _T("Run"), - NULL - }; - - return CArchMiscWindows::addKey(HKEY_CURRENT_USER, s_keyNames); -} - bool CArchDaemonWindows::isRunState(DWORD state) { @@ -817,7 +678,7 @@ void CArchDaemonWindows::installDaemon() { // install default daemon if not already installed. - if (!isDaemonInstalled(DEFAULT_DAEMON_NAME, true)) { + if (!isDaemonInstalled(DEFAULT_DAEMON_NAME)) { char path[MAX_PATH]; GetModuleFileName(CArchMiscWindows::instanceWin32(), path, MAX_PATH); @@ -827,7 +688,7 @@ CArchDaemonWindows::installDaemon() ss << path; ss << '"'; - installDaemon(DEFAULT_DAEMON_NAME, DEFAULT_DAEMON_INFO, ss.str().c_str(), "", "", true); + installDaemon(DEFAULT_DAEMON_NAME, DEFAULT_DAEMON_INFO, ss.str().c_str(), "", ""); } start(DEFAULT_DAEMON_NAME); @@ -837,15 +698,15 @@ void CArchDaemonWindows::uninstallDaemon() { // remove legacy services if installed. - if (isDaemonInstalled(LEGACY_SERVER_DAEMON_NAME, true)) { - uninstallDaemon(LEGACY_SERVER_DAEMON_NAME, true); + if (isDaemonInstalled(LEGACY_SERVER_DAEMON_NAME)) { + uninstallDaemon(LEGACY_SERVER_DAEMON_NAME); } - if (isDaemonInstalled(LEGACY_CLIENT_DAEMON_NAME, true)) { - uninstallDaemon(LEGACY_CLIENT_DAEMON_NAME, true); + if (isDaemonInstalled(LEGACY_CLIENT_DAEMON_NAME)) { + uninstallDaemon(LEGACY_CLIENT_DAEMON_NAME); } // remove new service if installed. - if (isDaemonInstalled(DEFAULT_DAEMON_NAME, true)) { - uninstallDaemon(DEFAULT_DAEMON_NAME, true); + if (isDaemonInstalled(DEFAULT_DAEMON_NAME)) { + uninstallDaemon(DEFAULT_DAEMON_NAME); } } diff --git a/src/lib/arch/win32/ArchDaemonWindows.h b/src/lib/arch/win32/ArchDaemonWindows.h index 2af9785b..a51dcc94 100644 --- a/src/lib/arch/win32/ArchDaemonWindows.h +++ b/src/lib/arch/win32/ArchDaemonWindows.h @@ -79,20 +79,17 @@ public: const char* description, const char* pathname, const char* commandLine, - const char* dependencies, - bool allUsers); - virtual void uninstallDaemon(const char* name, bool allUsers); + const char* dependencies); + virtual void uninstallDaemon(const char* name); virtual void installDaemon(); virtual void uninstallDaemon(); virtual int daemonize(const char* name, DaemonFunc func); - virtual bool canInstallDaemon(const char* name, bool allUsers); - virtual bool isDaemonInstalled(const char* name, bool allUsers); + virtual bool canInstallDaemon(const char* name); + virtual bool isDaemonInstalled(const char* name); std::string commandLine() const { return m_commandLine; } private: static HKEY openNTServicesKey(); - static HKEY open95ServicesKey(); - static HKEY openUserStartupKey(); int doRunDaemon(RunFunc runFunc); void doDaemonRunning(bool running); diff --git a/src/lib/arch/win32/ArchLogWindows.cpp b/src/lib/arch/win32/ArchLogWindows.cpp index 6919b779..16fea305 100644 --- a/src/lib/arch/win32/ArchLogWindows.cpp +++ b/src/lib/arch/win32/ArchLogWindows.cpp @@ -38,7 +38,7 @@ CArchLogWindows::~CArchLogWindows() void CArchLogWindows::openLog(const char* name) { - if (m_eventLog == NULL && !CArchMiscWindows::isWindows95Family()) { + if (m_eventLog == NULL) { m_eventLog = RegisterEventSource(NULL, name); } } diff --git a/src/lib/arch/win32/ArchMiscWindows.cpp b/src/lib/arch/win32/ArchMiscWindows.cpp index 307f6a90..d71b0cd1 100644 --- a/src/lib/arch/win32/ArchMiscWindows.cpp +++ b/src/lib/arch/win32/ArchMiscWindows.cpp @@ -61,53 +61,6 @@ void CArchMiscWindows::init() { s_dialogs = new CDialogs; - isWindows95Family(); -} - -bool -CArchMiscWindows::isWindows95Family() -{ - static bool init = false; - static bool result = false; - - if (!init) { - OSVERSIONINFO version; - version.dwOSVersionInfoSize = sizeof(version); - if (GetVersionEx(&version) == 0) { - // cannot determine OS; assume windows 95 family - result = true; - } - else { - result = (version.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS); - } - init = true; - } - return result; -} - -bool -CArchMiscWindows::isWindowsModern() -{ - static bool init = false; - static bool result = false; - - if (!init) { - OSVERSIONINFO version; - version.dwOSVersionInfoSize = sizeof(version); - if (GetVersionEx(&version) == 0) { - // cannot determine OS; assume not modern - result = false; - } - else { - result = ((version.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS && - version.dwMajorVersion == 4 && - version.dwMinorVersion > 0) || - (version.dwPlatformId == VER_PLATFORM_WIN32_NT && - version.dwMajorVersion > 4)); - } - init = true; - } - return result; } void diff --git a/src/lib/arch/win32/ArchMiscWindows.h b/src/lib/arch/win32/ArchMiscWindows.h index 3b97a271..7431409a 100644 --- a/src/lib/arch/win32/ArchMiscWindows.h +++ b/src/lib/arch/win32/ArchMiscWindows.h @@ -51,19 +51,6 @@ public: //! Delete memory static void cleanup(); - //! Test if windows 95, et al. - /*! - Returns true iff the platform is win95/98/me. - */ - static bool isWindows95Family(); - - //! Test if windows 95, et al. - /*! - Returns true iff the platform is win98 or win2k or higher (i.e. - not windows 95 or windows NT). - */ - static bool isWindowsModern(); - //! Set the application icons /*! Set the application icons. diff --git a/src/lib/arch/win32/ArchSystemWindows.cpp b/src/lib/arch/win32/ArchSystemWindows.cpp index 0f739b86..c37a2099 100644 --- a/src/lib/arch/win32/ArchSystemWindows.cpp +++ b/src/lib/arch/win32/ArchSystemWindows.cpp @@ -83,36 +83,11 @@ CArchSystemWindows::getOSName() const if (info.dwMajorVersion == 5 && info.dwMinorVersion == 0) { return "Microsoft Windows Server 2000"; } - if (info.dwMajorVersion <= 4) { - return "Microsoft Windows NT"; - } char buffer[100]; sprintf(buffer, "Microsoft Windows %d.%d", info.dwMajorVersion, info.dwMinorVersion); return buffer; - case VER_PLATFORM_WIN32_WINDOWS: - if (info.dwMajorVersion == 4 && info.dwMinorVersion == 0) { - if (info.szCSDVersion[1] == 'C' || - info.szCSDVersion[1] == 'B') { - return "Microsoft Windows 95 OSR2"; - } - return "Microsoft Windows 95"; - } - if (info.dwMajorVersion == 4 && info.dwMinorVersion == 10) { - if (info.szCSDVersion[1] == 'A') { - return "Microsoft Windows 98 SE"; - } - return "Microsoft Windows 98"; - } - if (info.dwMajorVersion == 4 && info.dwMinorVersion == 90) { - return "Microsoft Windows ME"; - } - if (info.dwMajorVersion == 4) { - return "Microsoft Windows unknown 95 family"; - } - break; - default: break; } diff --git a/src/lib/platform/MSWindowsClipboard.cpp b/src/lib/platform/MSWindowsClipboard.cpp index 49f1dc8d..c0ca8634 100644 --- a/src/lib/platform/MSWindowsClipboard.cpp +++ b/src/lib/platform/MSWindowsClipboard.cpp @@ -40,11 +40,6 @@ CMSWindowsClipboard::CMSWindowsClipboard(HWND window) : { // add converters, most desired first m_converters.push_back(new CMSWindowsClipboardUTF16Converter); - if (CArchMiscWindows::isWindows95Family()) { - // windows nt family converts to/from unicode automatically. - // let it do so to avoid text encoding issues. - m_converters.push_back(new CMSWindowsClipboardTextConverter); - } m_converters.push_back(new CMSWindowsClipboardBitmapConverter); m_converters.push_back(new CMSWindowsClipboardHTMLConverter); } diff --git a/src/lib/platform/MSWindowsDesks.cpp b/src/lib/platform/MSWindowsDesks.cpp index 6d0e7f78..b007a122 100644 --- a/src/lib/platform/MSWindowsDesks.cpp +++ b/src/lib/platform/MSWindowsDesks.cpp @@ -98,8 +98,6 @@ CMSWindowsDesks::CMSWindowsDesks( IJob* updateKeys, bool stopOnDeskSwitch) : m_isPrimary(isPrimary), m_noHooks(noHooks), - m_is95Family(CArchMiscWindows::isWindows95Family()), - m_isModernFamily(CArchMiscWindows::isWindowsModern()), m_isOnScreen(m_isPrimary), m_x(0), m_y(0), m_w(0), m_h(0), @@ -253,26 +251,6 @@ CMSWindowsDesks::fakeKeyEvent( KeyButton button, UINT virtualKey, bool press, bool /*isAutoRepeat*/) const { - // win 95 family doesn't understand handed modifier virtual keys - if (m_is95Family) { - switch (virtualKey) { - case VK_LSHIFT: - case VK_RSHIFT: - virtualKey = VK_SHIFT; - break; - - case VK_LCONTROL: - case VK_RCONTROL: - virtualKey = VK_CONTROL; - break; - - case VK_LMENU: - case VK_RMENU: - virtualKey = VK_MENU; - break; - } - } - // synthesize event DWORD flags = 0; if (((button & 0x100u) != 0)) { @@ -517,51 +495,15 @@ CMSWindowsDesks::secondaryDeskProc( void CMSWindowsDesks::deskMouseMove(SInt32 x, SInt32 y) const { - // motion is simple (i.e. it's on the primary monitor) if there - // is only one monitor. it's also simple if we're not on the - // windows 95 family since those platforms don't have a broken - // mouse_event() function (see the comment below). - bool simple = (!m_multimon || !m_is95Family); - if (!simple) { - // also simple if motion is within the primary monitor - simple = (x >= 0 && x < GetSystemMetrics(SM_CXSCREEN) && - y >= 0 && y < GetSystemMetrics(SM_CYSCREEN)); - } - - // move the mouse directly to target position if motion is simple - if (simple) { - // when using absolute positioning with mouse_event(), - // the normalized device coordinates range over only - // the primary screen. - SInt32 w = GetSystemMetrics(SM_CXSCREEN); - SInt32 h = GetSystemMetrics(SM_CYSCREEN); - mouse_event(MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE, - (DWORD)((65535.0f * x) / (w - 1) + 0.5f), - (DWORD)((65535.0f * y) / (h - 1) + 0.5f), - 0, 0); - } - - // windows 98 and Me are broken. you cannot set the absolute - // position of the mouse except on the primary monitor but you - // can do relative moves onto any monitor. this is, in microsoft's - // words, "by design." apparently the designers of windows 2000 - // we're a little less lazy and did it right. - // - // microsoft recommends in Q193003 to absolute position the cursor - // somewhere on the primary monitor then relative move to the - // desired location. this doesn't work for us because when the - // user drags a scrollbar, a window, etc. it causes the dragged - // item to jump back and forth between the position on the primary - // monitor and the desired position. while it always ends up in - // the right place, the effect is disconcerting. - // - // instead we'll get the cursor's current position and do just a - // relative move from there to the desired position. - else { - POINT pos; - GetCursorPos(&pos); - deskMouseRelativeMove(x - pos.x, y - pos.y); - } + // when using absolute positioning with mouse_event(), + // the normalized device coordinates range over only + // the primary screen. + SInt32 w = GetSystemMetrics(SM_CXSCREEN); + SInt32 h = GetSystemMetrics(SM_CYSCREEN); + mouse_event(MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE, + (DWORD)((65535.0f * x) / (w - 1) + 0.5f), + (DWORD)((65535.0f * y) / (h - 1) + 0.5f), + 0, 0); } void @@ -993,7 +935,7 @@ CMSWindowsDesks::handleCheckDesk(const CEvent&, void*) // also check if screen saver is running if on a modern OS and // this is the primary screen. - if (m_isPrimary && m_isModernFamily) { + if (m_isPrimary) { BOOL running; SystemParametersInfo(SPI_GETSCREENSAVERRUNNING, 0, &running, FALSE); PostThreadMessage(m_threadID, SYNERGY_MSG_SCREEN_SAVER, running, 0); @@ -1003,24 +945,15 @@ CMSWindowsDesks::handleCheckDesk(const CEvent&, void*) HDESK CMSWindowsDesks::openInputDesktop() { - if (m_is95Family) { - // there's only one desktop on windows 95 et al. - return GetThreadDesktop(GetCurrentThreadId()); - } - else { - return OpenInputDesktop(DF_ALLOWOTHERACCOUNTHOOK, TRUE, - DESKTOP_CREATEWINDOW | - DESKTOP_HOOKCONTROL | - GENERIC_WRITE); - } + return OpenInputDesktop( + DF_ALLOWOTHERACCOUNTHOOK, TRUE, + DESKTOP_CREATEWINDOW | DESKTOP_HOOKCONTROL | GENERIC_WRITE); } void CMSWindowsDesks::closeDesktop(HDESK desk) { - // on 95/98/me we don't need to close the desktop returned by - // openInputDesktop(). - if (desk != NULL && !m_is95Family) { + if (desk != NULL) { CloseDesktop(desk); } } @@ -1031,9 +964,6 @@ CMSWindowsDesks::getDesktopName(HDESK desk) if (desk == NULL) { return CString(); } - else if (m_is95Family) { - return "desktop"; - } else { DWORD size; GetUserObjectInformation(desk, UOI_NAME, NULL, 0, &size); diff --git a/src/lib/platform/MSWindowsDesks.h b/src/lib/platform/MSWindowsDesks.h index ceedc70c..d514487d 100644 --- a/src/lib/platform/MSWindowsDesks.h +++ b/src/lib/platform/MSWindowsDesks.h @@ -251,12 +251,6 @@ private: // true if hooks are not to be installed (useful for debugging) bool m_noHooks; - // true if windows 95/98/me - bool m_is95Family; - - // true if windows 98/2k or higher (i.e. not 95/nt) - bool m_isModernFamily; - // true if mouse has entered the screen bool m_isOnScreen; diff --git a/src/lib/platform/MSWindowsKeyState.cpp b/src/lib/platform/MSWindowsKeyState.cpp index 3bda48e5..f73c76b1 100644 --- a/src/lib/platform/MSWindowsKeyState.cpp +++ b/src/lib/platform/MSWindowsKeyState.cpp @@ -579,7 +579,6 @@ static const CWin32Modifiers s_modifiers[] = CMSWindowsKeyState::CMSWindowsKeyState( CMSWindowsDesks* desks, void* eventTarget, IEventQueue* events) : CKeyState(events), - m_is95Family(CArchMiscWindows::isWindows95Family()), m_eventTarget(eventTarget), m_desks(desks), m_keyLayout(GetKeyboardLayout(0)), @@ -596,7 +595,6 @@ CMSWindowsKeyState::CMSWindowsKeyState( CMSWindowsKeyState::CMSWindowsKeyState( CMSWindowsDesks* desks, void* eventTarget, IEventQueue* events, CKeyMap& keyMap) : CKeyState(events, keyMap), - m_is95Family(CArchMiscWindows::isWindows95Family()), m_eventTarget(eventTarget), m_desks(desks), m_keyLayout(GetKeyboardLayout(0)), @@ -761,10 +759,7 @@ CMSWindowsKeyState::mapKeyToVirtualKey(KeyID key) const void CMSWindowsKeyState::onKey(KeyButton button, bool down, KeyModifierMask newState) { - // handle win32 brokenness and forward to superclass - fixKeys(); CKeyState::onKey(button, down, newState); - fixKeys(); } void @@ -810,28 +805,22 @@ CMSWindowsKeyState::fakeKeyRepeat(KeyID id, KeyModifierMask mask, bool CMSWindowsKeyState::fakeCtrlAltDel() { - if (!m_is95Family) { - // to fake ctrl+alt+del on the NT family we broadcast a suitable - // hotkey to all windows on the winlogon desktop. however, the - // current thread must be on that desktop to do the broadcast - // and we can't switch just any thread because some own windows - // or hooks. so start a new thread to do the real work. - HANDLE hEvtSendSas = OpenEvent( EVENT_MODIFY_STATE, FALSE, "Global\\SendSAS" ); - if ( hEvtSendSas ) { - LOG((CLOG_DEBUG "found the SendSAS event - signaling my launcher to simulate ctrl+alt+del")); - SetEvent( hEvtSendSas ); - CloseHandle( hEvtSendSas ); - } - else { + // to fake ctrl+alt+del on the NT family we broadcast a suitable + // hotkey to all windows on the winlogon desktop. however, the + // current thread must be on that desktop to do the broadcast + // and we can't switch just any thread because some own windows + // or hooks. so start a new thread to do the real work. + HANDLE hEvtSendSas = OpenEvent( EVENT_MODIFY_STATE, FALSE, "Global\\SendSAS" ); + if ( hEvtSendSas ) { + LOG((CLOG_DEBUG "found the SendSAS event - signaling my launcher to simulate ctrl+alt+del")); + SetEvent( hEvtSendSas ); + CloseHandle( hEvtSendSas ); + } + else { CThread cad(new CFunctionJob(&CMSWindowsKeyState::ctrlAltDelThread)); cad.wait(); } - } - else { - // simulate ctrl+alt+del - fakeKeyDown(kKeyDelete, KeyModifierControl | KeyModifierAlt, - virtualKeyToButton(VK_DELETE)); - } + return true; } @@ -1006,11 +995,6 @@ CMSWindowsKeyState::getKeyMap(CKeyMap& keyMap) case VK_LWIN: case VK_RWIN: - // add extended key only for these on 95 family - if (m_is95Family) { - m_buttonToVK[i | 0x100u] = vk; - continue; - } break; case VK_RETURN: @@ -1351,77 +1335,6 @@ CMSWindowsKeyState::setWindowGroup(SInt32 group) Sleep(100); } -void -CMSWindowsKeyState::fixKeys() -{ - // fake key releases for the windows keys if we think they're - // down but they're really up. we have to do this because if the - // user presses and releases a windows key without pressing any - // other key while it's down then the system will eat the key - // release. if we don't detect that and synthesize the release - // then the client won't take the usual windows key release action - // (which on windows is to show the start menu). - // - // only check on the windows 95 family since the NT family reports - // the key releases as usual. - if (!m_is95Family) { - return; - } - - KeyButton leftButton = virtualKeyToButton(VK_LWIN); - KeyButton rightButton = virtualKeyToButton(VK_RWIN); - bool leftDown = isKeyDown(leftButton); - bool rightDown = isKeyDown(rightButton); - bool fix = (leftDown || rightDown); - if (fix) { - // check if either button is not really down - bool leftAsyncDown = ((GetAsyncKeyState(VK_LWIN) & 0x8000) != 0); - bool rightAsyncDown = ((GetAsyncKeyState(VK_RWIN) & 0x8000) != 0); - - if (leftAsyncDown != leftDown || rightAsyncDown != rightDown) { - KeyModifierMask state = getActiveModifiers(); - if (!leftAsyncDown && !rightAsyncDown) { - // no win keys are down so remove super modifier - state &= ~KeyModifierSuper; - } - - // report up events - if (leftDown && !leftAsyncDown) { - LOG((CLOG_DEBUG1 "event: fake key release left windows key (0x%03x)", leftButton)); - CKeyState::onKey(leftButton, false, state); - CKeyState::sendKeyEvent(m_eventTarget, false, false, - kKeySuper_L, state, 1, leftButton); - } - if (rightDown && !rightAsyncDown) { - LOG((CLOG_DEBUG1 "event: fake key release right windows key (0x%03x)", rightButton)); - CKeyState::onKey(rightButton, false, state); - CKeyState::sendKeyEvent(m_eventTarget, false, false, - kKeySuper_R, state, 1, rightButton); - } - } - } - - if (fix && m_fixTimer == NULL) { - // schedule check - m_fixTimer = m_events->newTimer(0.1, NULL); - m_events->adoptHandler(CEvent::kTimer, m_fixTimer, - new TMethodEventJob( - this, &CMSWindowsKeyState::handleFixKeys)); - } - else if (!fix && m_fixTimer != NULL) { - // remove scheduled check - m_events->removeHandler(CEvent::kTimer, m_fixTimer); - m_events->deleteTimer(m_fixTimer); - m_fixTimer = NULL; - } -} - -void -CMSWindowsKeyState::handleFixKeys(const CEvent&, void*) -{ - fixKeys(); -} - KeyID CMSWindowsKeyState::getKeyID(UINT virtualKey, KeyButton button) { @@ -1436,21 +1349,12 @@ CMSWindowsKeyState::getIDForKey(CKeyMap::KeyItem& item, KeyButton button, UINT virtualKey, PBYTE keyState, HKL hkl) const { - int n; - KeyID id; - if (m_is95Family) { - // XXX -- how do we get characters not in Latin-1? - WORD ascii; - n = ToAsciiEx(virtualKey, button, keyState, &ascii, 0, hkl); - id = static_cast(ascii & 0xffu); - } - else { - WCHAR unicode[2]; - n = m_ToUnicodeEx(virtualKey, button, keyState, - unicode, sizeof(unicode) / sizeof(unicode[0]), - 0, hkl); - id = static_cast(unicode[0]); - } + WCHAR unicode[2]; + int n = m_ToUnicodeEx( + virtualKey, button, keyState, unicode, + sizeof(unicode) / sizeof(unicode[0]), 0, hkl); + KeyID id = static_cast(unicode[0]); + switch (n) { case -1: return CKeyMap::getDeadKey(id); diff --git a/src/lib/platform/MSWindowsKeyState.h b/src/lib/platform/MSWindowsKeyState.h index d4d5c69c..27b992a2 100644 --- a/src/lib/platform/MSWindowsKeyState.h +++ b/src/lib/platform/MSWindowsKeyState.h @@ -167,9 +167,6 @@ private: bool getGroups(GroupList&) const; void setWindowGroup(SInt32 group); - void fixKeys(); - void handleFixKeys(const CEvent&, void*); - KeyID getIDForKey(CKeyMap::KeyItem& item, KeyButton button, UINT virtualKey, PBYTE keyState, HKL hkl) const; @@ -187,7 +184,6 @@ private: typedef std::map GroupMap; typedef std::map KeyToVKMap; - bool m_is95Family; void* m_eventTarget; CMSWindowsDesks* m_desks; HKL m_keyLayout; diff --git a/src/lib/platform/MSWindowsScreen.cpp b/src/lib/platform/MSWindowsScreen.cpp index eadd61d3..08489400 100644 --- a/src/lib/platform/MSWindowsScreen.cpp +++ b/src/lib/platform/MSWindowsScreen.cpp @@ -97,7 +97,6 @@ CMSWindowsScreen::CMSWindowsScreen( CPlatformScreen(events), m_isPrimary(isPrimary), m_noHooks(noHooks), - m_is95Family(CArchMiscWindows::isWindows95Family()), m_isOnScreen(m_isPrimary), m_class(0), m_x(0), m_y(0), @@ -1007,22 +1006,6 @@ CMSWindowsScreen::onEvent(HWND, UINT msg, WPARAM wParam, LPARAM lParam, LRESULT* result) { switch (msg) { - case WM_QUERYENDSESSION: - if (m_is95Family) { - *result = TRUE; - return true; - } - break; - - case WM_ENDSESSION: - if (m_is95Family) { - if (wParam == TRUE && lParam == 0) { - m_events->addEvent(CEvent(CEvent::kQuit)); - } - return true; - } - break; - case WM_DRAWCLIPBOARD: // first pass on the message if (m_nextClipboardWindow != NULL) { @@ -1183,37 +1166,6 @@ CMSWindowsScreen::onKey(WPARAM wParam, LPARAM lParam) KeyID key = m_keyState->mapKeyFromEvent(wParam, lParam, &mask); button = static_cast((lParam & 0x01ff0000u) >> 16); if (key != kKeyNone) { - // fix key up. if the key isn't down according to - // our table then we never got the key press event - // for it. if it's not a modifier key then we'll - // synthesize the press first. only do this on - // the windows 95 family, which eats certain special - // keys like alt+tab, ctrl+esc, etc. - if (m_is95Family && !wasDown && !down) { - switch (virtKey) { - case VK_SHIFT: - case VK_LSHIFT: - case VK_RSHIFT: - case VK_CONTROL: - case VK_LCONTROL: - case VK_RCONTROL: - case VK_MENU: - case VK_LMENU: - case VK_RMENU: - case VK_LWIN: - case VK_RWIN: - case VK_CAPITAL: - case VK_NUMLOCK: - case VK_SCROLL: - break; - - default: - m_keyState->sendKeyEvent(getEventTarget(), - true, false, key, mask, 1, button); - break; - } - } - // do it m_keyState->sendKeyEvent(getEventTarget(), ((lParam & 0x80000000u) == 0), @@ -1617,15 +1569,6 @@ CMSWindowsScreen::fixClipboardViewer() void CMSWindowsScreen::enableSpecialKeys(bool enable) const { - // enable/disable ctrl+alt+del, alt+tab, etc on win95 family. - // since the win95 family doesn't support low-level hooks, we - // use this undocumented feature to suppress normal handling - // of certain key combinations. - if (m_is95Family) { - DWORD dummy = 0; - SystemParametersInfo(SPI_SETSCREENSAVERRUNNING, - enable ? FALSE : TRUE, &dummy, 0); - } } ButtonID @@ -1865,7 +1808,7 @@ CMSWindowsScreen::getDraggingFilename() void CMSWindowsScreen::clearDraggingFilename() { - LOG((CLOG_DEBUG "clearing stored dragging file name")); + LOG((CLOG_DEBUG1 "clearing stored dragging file name")); m_shellEx.clearDraggingFilename(); } diff --git a/src/lib/platform/MSWindowsScreen.h b/src/lib/platform/MSWindowsScreen.h index af811d71..2df94811 100644 --- a/src/lib/platform/MSWindowsScreen.h +++ b/src/lib/platform/MSWindowsScreen.h @@ -237,9 +237,6 @@ private: // true if hooks are not to be installed (useful for debugging) bool m_noHooks; - // true if windows 95/98/me - bool m_is95Family; - // true if mouse has entered the screen bool m_isOnScreen; diff --git a/src/lib/platform/MSWindowsScreenSaver.cpp b/src/lib/platform/MSWindowsScreenSaver.cpp index 68ce3396..233eb826 100644 --- a/src/lib/platform/MSWindowsScreenSaver.cpp +++ b/src/lib/platform/MSWindowsScreenSaver.cpp @@ -52,25 +52,6 @@ CMSWindowsScreenSaver::CMSWindowsScreenSaver() : m_threadID(0), m_active(false) { - // detect OS - m_is95Family = false; - m_is95 = false; - m_isNT = false; - OSVERSIONINFO info; - info.dwOSVersionInfoSize = sizeof(info); - if (GetVersionEx(&info)) { - m_is95Family = (info.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS); - if (info.dwPlatformId == VER_PLATFORM_WIN32_NT && - info.dwMajorVersion <= 4) { - m_isNT = true; - } - else if (info.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS && - info.dwMajorVersion == 4 && - info.dwMinorVersion == 0) { - m_is95 = true; - } - } - // check if screen saver is enabled SystemParametersInfo(SPI_GETSCREENSAVEACTIVE, 0, &m_wasEnabled, 0); } @@ -104,38 +85,19 @@ CMSWindowsScreenSaver::checkStarted(UINT msg, WPARAM wParam, LPARAM lParam) m_wParam = wParam; m_lParam = lParam; - // we handle the screen saver differently for the windows - // 95 and nt families. - if (m_is95Family) { - // on windows 95 we wait for the screen saver process - // to terminate. get the process. - DWORD processID = findScreenSaver(); - HANDLE process = OpenProcess(SYNCHRONIZE, FALSE, processID); - if (process == NULL) { - // didn't start - LOG((CLOG_DEBUG2 "can't open screen saver process")); - return false; - } - - // watch for the process to exit - watchProcess(process); - } - else { - // on the windows nt family we wait for the desktop to - // change until it's neither the Screen-Saver desktop - // nor a desktop we can't open (the login desktop). - // since windows will send the request-to-start-screen- - // saver message even when the screen saver is disabled - // we first check that the screen saver is indeed active - // before watching for it to stop. - if (!isActive()) { - LOG((CLOG_DEBUG2 "can't open screen saver desktop")); - return false; - } - - watchDesktop(); + // on the windows nt family we wait for the desktop to + // change until it's neither the Screen-Saver desktop + // nor a desktop we can't open (the login desktop). + // since windows will send the request-to-start-screen- + // saver message even when the screen saver is disabled + // we first check that the screen saver is indeed active + // before watching for it to stop. + if (!isActive()) { + LOG((CLOG_DEBUG2 "can't open screen saver desktop")); + return false; } + watchDesktop(); return true; } @@ -193,16 +155,15 @@ void CMSWindowsScreenSaver::deactivate() { bool killed = false; - if (!m_is95Family) { - // NT runs screen saver in another desktop - HDESK desktop = OpenDesktop("Screen-saver", 0, FALSE, - DESKTOP_READOBJECTS | DESKTOP_WRITEOBJECTS); - if (desktop != NULL) { - EnumDesktopWindows(desktop, - &CMSWindowsScreenSaver::killScreenSaverFunc, - reinterpret_cast(&killed)); - CloseDesktop(desktop); - } + + // NT runs screen saver in another desktop + HDESK desktop = OpenDesktop("Screen-saver", 0, FALSE, + DESKTOP_READOBJECTS | DESKTOP_WRITEOBJECTS); + if (desktop != NULL) { + EnumDesktopWindows(desktop, + &CMSWindowsScreenSaver::killScreenSaverFunc, + reinterpret_cast(&killed)); + CloseDesktop(desktop); } // if above failed or wasn't tried, try the windows 95 way @@ -232,68 +193,9 @@ CMSWindowsScreenSaver::deactivate() bool CMSWindowsScreenSaver::isActive() const { - if (m_is95) { - return (FindWindow("WindowsScreenSaverClass", NULL) != NULL); - } - else if (m_isNT) { - // screen saver runs on a separate desktop - HDESK desktop = OpenDesktop("Screen-saver", 0, FALSE, MAXIMUM_ALLOWED); - if (desktop == NULL && GetLastError() != ERROR_ACCESS_DENIED) { - // desktop doesn't exist so screen saver is not running - return false; - } - - // desktop exists. this should indicate that the screen saver - // is running but an OS bug can cause a valid handle to be - // returned even if the screen saver isn't running (Q230117). - // we'll try to enumerate the windows on the desktop and, if - // there are any, we assume the screen saver is running. (note - // that if we don't have permission to enumerate then we'll - // assume that the screen saver is not running.) that'd be - // easy enough except there's another OS bug (Q198590) that can - // cause EnumDesktopWindows() to enumerate the windows of - // another desktop if the requested desktop has no windows. to - // work around that we have to verify that the enumerated - // windows are, in fact, on the expected desktop. - CFindScreenSaverInfo info; - info.m_desktop = desktop; - info.m_window = NULL; - EnumDesktopWindows(desktop, - &CMSWindowsScreenSaver::findScreenSaverFunc, - reinterpret_cast(&info)); - - // done with desktop - CloseDesktop(desktop); - - // screen saver is running if a window was found - return (info.m_window != NULL); - } - else { - BOOL running; - SystemParametersInfo(SPI_GETSCREENSAVERRUNNING, 0, &running, 0); - return (running != FALSE); - } -} - -BOOL CALLBACK -CMSWindowsScreenSaver::findScreenSaverFunc(HWND hwnd, LPARAM arg) -{ - CFindScreenSaverInfo* info = reinterpret_cast(arg); - - if (info->m_desktop != NULL) { - DWORD threadID = GetWindowThreadProcessId(hwnd, NULL); - HDESK desktop = GetThreadDesktop(threadID); - if (desktop != NULL && desktop != info->m_desktop) { - // stop enumerating -- wrong desktop - return FALSE; - } - } - - // found a window - info->m_window = hwnd; - - // don't need to enumerate further - return FALSE; + BOOL running; + SystemParametersInfo(SPI_GETSCREENSAVERRUNNING, 0, &running, 0); + return (running != FALSE); } BOOL CALLBACK @@ -309,23 +211,6 @@ CMSWindowsScreenSaver::killScreenSaverFunc(HWND hwnd, LPARAM arg) return TRUE; } -DWORD -CMSWindowsScreenSaver::findScreenSaver() -{ - // try windows 95 way - HWND hwnd = FindWindow("WindowsScreenSaverClass", NULL); - - // get process ID of process that owns the window, if found - if (hwnd != NULL) { - DWORD processID; - GetWindowThreadProcessId(hwnd, &processID); - return processID; - } - - // not found - return 0; -} - void CMSWindowsScreenSaver::watchDesktop() { @@ -382,41 +267,10 @@ CMSWindowsScreenSaver::watchDesktopThread(void*) // wait a bit ARCH->sleep(0.2); - if (m_isNT) { - // get current desktop - HDESK desk = OpenInputDesktop(0, FALSE, GENERIC_READ); - if (desk == NULL) { - // can't open desktop so keep waiting - continue; - } - - // get current desktop name length - DWORD size; - GetUserObjectInformation(desk, UOI_NAME, NULL, 0, &size); - - // allocate more space for the name, if necessary - if (size > reserved) { - reserved = size; - name = (TCHAR*)alloca(reserved + sizeof(TCHAR)); - } - - // get current desktop name - GetUserObjectInformation(desk, UOI_NAME, name, size, &size); - CloseDesktop(desk); - - // compare name to screen saver desktop name - if (_tcsicmp(name, TEXT("Screen-saver")) == 0) { - // still the screen saver desktop so keep waiting - continue; - } - } - else { - // 2000/XP have a sane way to detect a runnin screensaver. - BOOL running; - SystemParametersInfo(SPI_GETSCREENSAVERRUNNING, 0, &running, 0); - if (running) { - continue; - } + BOOL running; + SystemParametersInfo(SPI_GETSCREENSAVERRUNNING, 0, &running, 0); + if (running) { + continue; } // send screen saver deactivation message @@ -452,12 +306,11 @@ CMSWindowsScreenSaver::setSecure(bool secure, bool saveSecureAsInt) return; } - const TCHAR* isSecure = m_is95Family ? g_isSecure9x : g_isSecureNT; if (saveSecureAsInt) { - CArchMiscWindows::setValue(hkey, isSecure, secure ? 1 : 0); + CArchMiscWindows::setValue(hkey, g_isSecureNT, secure ? 1 : 0); } else { - CArchMiscWindows::setValue(hkey, isSecure, secure ? "1" : "0"); + CArchMiscWindows::setValue(hkey, g_isSecureNT, secure ? "1" : "0"); } CArchMiscWindows::closeKey(hkey); @@ -476,15 +329,14 @@ CMSWindowsScreenSaver::isSecure(bool* wasSecureFlagAnInt) const // get the value. the value may be an int or a string, depending // on the version of windows. bool result; - const TCHAR* isSecure = m_is95Family ? g_isSecure9x : g_isSecureNT; - switch (CArchMiscWindows::typeOfValue(hkey, isSecure)) { + switch (CArchMiscWindows::typeOfValue(hkey, g_isSecureNT)) { default: result = false; break; case CArchMiscWindows::kUINT: { DWORD value = - CArchMiscWindows::readValueInt(hkey, isSecure); + CArchMiscWindows::readValueInt(hkey, g_isSecureNT); *wasSecureFlagAnInt = true; result = (value != 0); break; @@ -492,7 +344,7 @@ CMSWindowsScreenSaver::isSecure(bool* wasSecureFlagAnInt) const case CArchMiscWindows::kSTRING: { std::string value = - CArchMiscWindows::readValueString(hkey, isSecure); + CArchMiscWindows::readValueString(hkey, g_isSecureNT); *wasSecureFlagAnInt = false; result = (value != "0"); break; diff --git a/src/lib/platform/MSWindowsScreenSaver.h b/src/lib/platform/MSWindowsScreenSaver.h index 4e159bea..3ca60f4b 100644 --- a/src/lib/platform/MSWindowsScreenSaver.h +++ b/src/lib/platform/MSWindowsScreenSaver.h @@ -60,10 +60,8 @@ private: HWND m_window; }; - static BOOL CALLBACK findScreenSaverFunc(HWND hwnd, LPARAM lParam); static BOOL CALLBACK killScreenSaverFunc(HWND hwnd, LPARAM lParam); - DWORD findScreenSaver(); void watchDesktop(); void watchProcess(HANDLE process); void unwatchProcess(); @@ -74,9 +72,6 @@ private: bool isSecure(bool* wasSecureAnInt) const; private: - bool m_is95Family; - bool m_is95; - bool m_isNT; BOOL m_wasEnabled; bool m_wasSecure; bool m_wasSecureAnInt; diff --git a/src/lib/synergy/win32/AppUtilWindows.cpp b/src/lib/synergy/win32/AppUtilWindows.cpp index 421bfe96..72e94766 100644 --- a/src/lib/synergy/win32/AppUtilWindows.cpp +++ b/src/lib/synergy/win32/AppUtilWindows.cpp @@ -17,20 +17,20 @@ */ #include "synergy/win32/AppUtilWindows.h" -#include "common/Version.h" -#include "base/Log.h" -#include "arch/win32/XArchWindows.h" -#include "arch/win32/ArchMiscWindows.h" -#include "synergy/App.h" -#include "base/log_outputters.h" -#include "platform/MSWindowsScreen.h" -#include "synergy/XSynergy.h" -#include "arch/IArchTaskBarReceiver.h" #include "synergy/Screen.h" #include "synergy/ArgsBase.h" +#include "synergy/App.h" +#include "synergy/XSynergy.h" +#include "platform/MSWindowsScreen.h" +#include "arch/win32/XArchWindows.h" +#include "arch/win32/ArchMiscWindows.h" +#include "arch/IArchTaskBarReceiver.h" +#include "base/Log.h" +#include "base/log_outputters.h" #include "base/IEventQueue.h" #include "base/Event.h" #include "base/EventQueue.h" +#include "common/Version.h" #include #include @@ -155,7 +155,16 @@ CAppUtilWindows::beforeAppExit() int CAppUtilWindows::run(int argc, char** argv) -{ +{ + OSVERSIONINFO osvi; + ZeroMemory(&osvi, sizeof(OSVERSIONINFO)); + osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + GetVersionEx(&osvi); + + if (osvi.dwMajorVersion < 5 || (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion < 1)) { + throw std::runtime_error("synergy only supports windows xp and above."); + } + // record window instance for tray icon, etc CArchMiscWindows::setInstanceWin32(GetModuleHandle(NULL));