Task #3961 - Remove Windows 95 support

This commit is contained in:
Nick Bolton 2014-03-17 16:30:27 +00:00
parent 1b5cdecc60
commit 3ddb7ef9e3
19 changed files with 265 additions and 880 deletions

View File

@ -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;
}

View File

@ -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;

View File

@ -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;
//@}

View File

@ -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) {
assert(s_daemon != NULL);
throw XArchDaemonRunFailed(result);
}
}
void
@ -89,36 +79,8 @@ 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);
}
// windows NT family services
else {
// open service manager
SC_HANDLE mgr = OpenSCManager(NULL, NULL, GENERIC_WRITE);
if (mgr == NULL) {
@ -127,12 +89,12 @@ CArchDaemonWindows::installDaemon(const char* name,
}
// create the service
SC_HANDLE service = CreateService(mgr,
SC_HANDLE service = CreateService(
mgr,
name,
name,
0,
SERVICE_WIN32_OWN_PROCESS |
SERVICE_INTERACTIVE_PROCESS,
SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
SERVICE_AUTO_START,
SERVICE_ERROR_NORMAL,
pathname,
@ -141,6 +103,7 @@ CArchDaemonWindows::installDaemon(const char* name,
dependencies,
NULL,
NULL);
if (service == NULL) {
// can't create service
DWORD err = GetLastError();
@ -164,7 +127,7 @@ CArchDaemonWindows::installDaemon(const char* name,
// can't open key
DWORD err = GetLastError();
try {
uninstallDaemon(name, allUsers);
uninstallDaemon(name);
}
catch (...) {
// ignore
@ -182,7 +145,7 @@ CArchDaemonWindows::installDaemon(const char* name,
DWORD err = GetLastError();
CArchMiscWindows::closeKey(key);
try {
uninstallDaemon(name, allUsers);
uninstallDaemon(name);
}
catch (...) {
// ignore
@ -193,32 +156,11 @@ CArchDaemonWindows::installDaemon(const char* name,
// 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
CArchMiscWindows::closeKey(key);
}
// windows NT family services
else {
// remove parameters for this service. ignore failures.
HKEY key = openNTServicesKey();
key = CArchMiscWindows::openKey(key, name);
@ -262,7 +204,7 @@ CArchDaemonWindows::uninstallDaemon(const char* name, bool allUsers)
ARCH->sleep(1);
// handle failure. ignore error if service isn't installed anymore.
if (!okay && isDaemonInstalled(name, allUsers)) {
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
@ -278,7 +220,6 @@ CArchDaemonWindows::uninstallDaemon(const char* name, bool allUsers)
}
throw XArchDaemonUninstallNotInstalled(new XArchEvalWindows(err));
}
}
}
int
@ -287,40 +228,6 @@ 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);
// 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<RegisterServiceProcessT>(
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;
@ -342,24 +249,11 @@ CArchDaemonWindows::daemonize(const char* name, DaemonFunc func)
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);
}
// 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) {
@ -369,16 +263,13 @@ CArchDaemonWindows::canInstallDaemon(const char* /*name*/, bool allUsers)
// 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);
}
}
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);
}
}

View File

@ -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);

View File

@ -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);
}
}

View File

@ -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

View File

@ -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.

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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,19 +495,6 @@ 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.
@ -539,29 +504,6 @@ CMSWindowsDesks::deskMouseMove(SInt32 x, SInt32 y) const
(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);
}
}
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);

View File

@ -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;

View File

@ -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,7 +805,6 @@ 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
@ -826,12 +820,7 @@ CMSWindowsKeyState::fakeCtrlAltDel()
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<CMSWindowsKeyState>(
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<KeyID>(ascii & 0xffu);
}
else {
WCHAR unicode[2];
n = m_ToUnicodeEx(virtualKey, button, keyState,
unicode, sizeof(unicode) / sizeof(unicode[0]),
0, hkl);
id = static_cast<KeyID>(unicode[0]);
}
int n = m_ToUnicodeEx(
virtualKey, button, keyState, unicode,
sizeof(unicode) / sizeof(unicode[0]), 0, hkl);
KeyID id = static_cast<KeyID>(unicode[0]);
switch (n) {
case -1:
return CKeyMap::getDeadKey(id);

View File

@ -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<HKL, SInt32> GroupMap;
typedef std::map<KeyID, UINT> KeyToVKMap;
bool m_is95Family;
void* m_eventTarget;
CMSWindowsDesks* m_desks;
HKL m_keyLayout;

View File

@ -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<KeyButton>((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();
}

View File

@ -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;

View File

@ -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,23 +85,6 @@ 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).
@ -134,8 +98,6 @@ CMSWindowsScreenSaver::checkStarted(UINT msg, WPARAM wParam, LPARAM lParam)
}
watchDesktop();
}
return true;
}
@ -193,7 +155,7 @@ 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);
@ -203,7 +165,6 @@ CMSWindowsScreenSaver::deactivate()
reinterpret_cast<LPARAM>(&killed));
CloseDesktop(desktop);
}
}
// if above failed or wasn't tried, try the windows 95 way
if (!killed) {
@ -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<LPARAM>(&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<CFindScreenSaverInfo*>(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 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,42 +267,11 @@ 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;
}
}
// send screen saver deactivation message
m_active = false;
@ -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;

View File

@ -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;

View File

@ -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 <sstream>
#include <iostream>
@ -156,6 +156,15 @@ 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));