Task #3960 - Split CMSWindowsHookLibraryLoader into hook and shellex loaders

- reordered include order for winsock2.h (more robust)
- removed Windows.h include from synwinxt.h (not needed)
This commit is contained in:
Nick Bolton 2014-03-17 14:34:13 +00:00
parent 407378fbc5
commit 1b5cdecc60
10 changed files with 311 additions and 220 deletions

View File

@ -25,9 +25,9 @@
#include "arch/IArchNetwork.h"
#include "arch/IArchMultithread.h"
#include <WinSock2.h>
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <winsock2.h>
#include <list>
#define ARCH_NETWORK CArchNetworkWinsock

View File

@ -0,0 +1,128 @@
/*
* synergy -- mouse and keyboard sharing utility
* Copyright (C) 2012 Bolton Software Ltd.
* Copyright (C) 2011 Chris Schoeneman
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file COPYING that should have accompanied this file.
*
* This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "platform/MSWindowsHook.h"
#include "synergy/XScreen.h"
#include "base/Log.h"
static const char* g_name = "synwinhk";
CMSWindowsHook::CMSWindowsHook() :
m_initFunc(NULL),
m_cleanupFunc(NULL),
m_setSidesFunc(NULL),
m_setZoneFunc(NULL),
m_setModeFunc(NULL),
m_instance(NULL)
{
}
CMSWindowsHook::~CMSWindowsHook()
{
cleanup();
if (m_instance != NULL) {
FreeLibrary(m_instance);
}
}
void
CMSWindowsHook::loadLibrary()
{
// load library
m_instance = LoadLibrary(g_name);
if (m_instance == NULL) {
LOG((CLOG_ERR "failed to load hook library, %s.dll is missing or invalid", g_name));
throw XScreenOpenFailure();
}
// look up functions
m_setSidesFunc = (SetSidesFunc)GetProcAddress(m_instance, "setSides");
m_setZoneFunc = (SetZoneFunc)GetProcAddress(m_instance, "setZone");
m_setModeFunc = (SetModeFunc)GetProcAddress(m_instance, "setMode");
m_initFunc = (InitFunc)GetProcAddress(m_instance, "init");
m_cleanupFunc = (CleanupFunc)GetProcAddress(m_instance, "cleanup");
if (m_setSidesFunc == NULL ||
m_setZoneFunc == NULL ||
m_setModeFunc == NULL ||
m_initFunc == NULL ||
m_cleanupFunc == NULL) {
LOG((CLOG_ERR "failed to load hook function, %s.dll could be out of date", g_name));
throw XScreenOpenFailure();
}
// initialize library
if (init(GetCurrentThreadId()) == 0) {
LOG((CLOG_ERR "failed to init %s.dll, another program may be using it", g_name));
LOG((CLOG_INFO "restarting your computer may solve this error"));
throw XScreenOpenFailure();
}
}
HINSTANCE
CMSWindowsHook::getInstance() const
{
return m_instance;
}
int
CMSWindowsHook::init(DWORD threadID)
{
if (m_initFunc == NULL) {
return NULL;
}
return m_initFunc(threadID);
}
int
CMSWindowsHook::cleanup()
{
if (m_cleanupFunc == NULL) {
return NULL;
}
return m_cleanupFunc();
}
void
CMSWindowsHook::setSides(UInt32 sides)
{
if (m_setSidesFunc == NULL) {
return;
}
m_setSidesFunc(sides);
}
void
CMSWindowsHook::setZone(SInt32 x, SInt32 y, SInt32 w, SInt32 h, SInt32 jumpZoneSize)
{
if (m_setZoneFunc == NULL) {
return;
}
m_setZoneFunc(x, y, w, h, jumpZoneSize);
}
void
CMSWindowsHook::setMode(EHookMode mode)
{
if (m_setModeFunc == NULL) {
return;
}
m_setModeFunc(mode);
}

View File

@ -19,30 +19,30 @@
#pragma once
#include "synwinhk/synwinhk.h"
#include "synwinxt/synwinxt.h"
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
//! Loads Windows hook DLLs.
class CMSWindowsHookLibraryLoader
//! Loads and provides functions for the Windows hook
class CMSWindowsHook
{
public:
CMSWindowsHookLibraryLoader();
virtual ~CMSWindowsHookLibraryLoader();
CMSWindowsHook();
virtual ~CMSWindowsHook();
HINSTANCE openHookLibrary(const char* name);
HINSTANCE openShellLibrary(const char* name);
void loadLibrary();
HINSTANCE getInstance() const;
int init(DWORD threadID);
int cleanup();
void setSides(UInt32 sides);
void setZone(SInt32 x, SInt32 y, SInt32 w, SInt32 h, SInt32 jumpZoneSize);
void setMode(EHookMode mode);
// TODO: either make these private or expose properly
InitFunc m_init;
CleanupFunc m_cleanup;
SetSidesFunc m_setSides;
SetZoneFunc m_setZone;
SetModeFunc m_setMode;
GetDraggingFilenameFunc
m_getDraggingFilename;
ClearDraggingFilenameFunc
m_clearDraggingFilename;
private:
InitFunc m_initFunc;
CleanupFunc m_cleanupFunc;
SetSidesFunc m_setSidesFunc;
SetZoneFunc m_setZoneFunc;
SetModeFunc m_setModeFunc;
HINSTANCE m_instance;
};

View File

@ -1,107 +0,0 @@
/*
* synergy -- mouse and keyboard sharing utility
* Copyright (C) 2012 Bolton Software Ltd.
* Copyright (C) 2011 Chris Schoeneman
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file COPYING that should have accompanied this file.
*
* This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "platform/MSWindowsHookLibraryLoader.h"
#include "synergy/XScreen.h"
#include "base/Log.h"
CMSWindowsHookLibraryLoader::CMSWindowsHookLibraryLoader() :
m_init(NULL),
m_cleanup(NULL),
m_setSides(NULL),
m_setZone(NULL),
m_setMode(NULL),
m_getDraggingFilename(NULL),
m_clearDraggingFilename(NULL)
{
}
CMSWindowsHookLibraryLoader::~CMSWindowsHookLibraryLoader()
{
// TODO: take ownership of m_ and delete them.
}
HINSTANCE
CMSWindowsHookLibraryLoader::openHookLibrary(const char* name)
{
// load the hook library
HINSTANCE hookLibrary = LoadLibrary(name);
if (hookLibrary == NULL) {
LOG((CLOG_ERR "failed to load hook library, %s.dll is missing or invalid", name));
throw XScreenOpenFailure();
}
// look up functions
m_setSides = (SetSidesFunc)GetProcAddress(hookLibrary, "setSides");
m_setZone = (SetZoneFunc)GetProcAddress(hookLibrary, "setZone");
m_setMode = (SetModeFunc)GetProcAddress(hookLibrary, "setMode");
m_init = (InitFunc)GetProcAddress(hookLibrary, "init");
m_cleanup = (CleanupFunc)GetProcAddress(hookLibrary, "cleanup");
if (m_setSides == NULL ||
m_setZone == NULL ||
m_setMode == NULL ||
m_init == NULL ||
m_cleanup == NULL) {
LOG((CLOG_ERR "failed to load hook function, %s.dll could be out of date", name));
throw XScreenOpenFailure();
}
// initialize hook library
if (m_init(GetCurrentThreadId()) == 0) {
LOG((CLOG_ERR "failed to init %s.dll, another program may be using it", name));
LOG((CLOG_INFO "restarting your computer may solve this error"));
throw XScreenOpenFailure();
}
return hookLibrary;
}
HINSTANCE
CMSWindowsHookLibraryLoader::openShellLibrary(const char* name)
{
OSVERSIONINFO osvi;
ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
GetVersionEx(&osvi);
if (osvi.dwMajorVersion < 6) {
LOG((CLOG_INFO "skipping shell extension library load, %s.dll not supported before vista", name));
return NULL;
}
// load the hook library
HINSTANCE shellLibrary = LoadLibrary(name);
if (shellLibrary == NULL) {
LOG((CLOG_ERR "failed to load shell extension library, %s.dll is missing or invalid", name));
throw XScreenOpenFailure();
}
// look up functions
m_getDraggingFilename = (GetDraggingFilenameFunc)GetProcAddress(shellLibrary, "getDraggingFilename");
m_clearDraggingFilename = (ClearDraggingFilenameFunc)GetProcAddress(shellLibrary, "clearDraggingFilename");
if (m_getDraggingFilename == NULL ||
m_clearDraggingFilename == NULL) {
LOG((CLOG_ERR "failed to load shell extension function, %s.dll could be out of date", name));
throw XScreenOpenFailure();
}
return shellLibrary;
}

View File

@ -117,8 +117,6 @@ CMSWindowsScreen::CMSWindowsScreen(
m_nextClipboardWindow(NULL),
m_ownClipboard(false),
m_desks(NULL),
m_hookLibrary(NULL),
m_shellLibrary(NULL),
m_keyState(NULL),
m_hasMouse(GetSystemMetrics(SM_MOUSEPRESENT) != 0),
m_showingMouse(false),
@ -130,17 +128,19 @@ CMSWindowsScreen::CMSWindowsScreen(
s_screen = this;
try {
if (m_isPrimary && !m_noHooks) {
m_hookLibrary = openHookLibrary("synwinhk");
m_hook.loadLibrary();
}
m_shellLibrary = openShellLibrary("synwinxt");
m_shellEx.loadLibrary();
m_screensaver = new CMSWindowsScreenSaver();
m_desks = new CMSWindowsDesks(
m_isPrimary, m_noHooks,
m_hookLibrary, m_screensaver,
m_isPrimary,
m_noHooks,
m_hook.getInstance(),
m_screensaver,
m_events,
new TMethodJob<CMSWindowsScreen>(this,
&CMSWindowsScreen::updateKeysCB),
new TMethodJob<CMSWindowsScreen>(
this, &CMSWindowsScreen::updateKeysCB),
stopOnDeskSwitch);
m_keyState = new CMSWindowsKeyState(m_desks, getEventTarget(), m_events);
updateScreenShape();
@ -166,13 +166,6 @@ CMSWindowsScreen::CMSWindowsScreen(
delete m_screensaver;
destroyWindow(m_window);
destroyClass(m_class);
if (m_hookLibrary != NULL)
closeHookLibrary(m_hookLibrary);
if (m_shellLibrary != NULL)
closeShellLibrary(m_shellLibrary);
s_screen = NULL;
throw;
}
@ -199,12 +192,6 @@ CMSWindowsScreen::~CMSWindowsScreen()
destroyWindow(m_window);
destroyClass(m_class);
if (m_hookLibrary != NULL)
closeHookLibrary(m_hookLibrary);
if (m_shellLibrary != NULL)
closeShellLibrary(m_shellLibrary);
s_screen = NULL;
}
@ -241,13 +228,11 @@ CMSWindowsScreen::enable()
m_desks->enable();
if (m_isPrimary) {
if (m_hookLibrary != NULL) {
// set jump zones
m_hookLibraryLoader.m_setZone(m_x, m_y, m_w, m_h, getJumpZoneSize());
// set jump zones
m_hook.setZone(m_x, m_y, m_w, m_h, getJumpZoneSize());
// watch jump zones
m_hookLibraryLoader.m_setMode(kHOOK_WATCH_JUMP_ZONE);
}
// watch jump zones
m_hook.setMode(kHOOK_WATCH_JUMP_ZONE);
}
else {
// prevent the system from entering power saving modes. if
@ -264,10 +249,8 @@ CMSWindowsScreen::disable()
m_desks->disable();
if (m_isPrimary) {
if (m_hookLibrary != NULL) {
// disable hooks
m_hookLibraryLoader.m_setMode(kHOOK_DISABLE);
}
// disable hooks
m_hook.setMode(kHOOK_DISABLE);
// enable special key sequences on win95 family
enableSpecialKeys(true);
@ -304,10 +287,8 @@ CMSWindowsScreen::enter()
// enable special key sequences on win95 family
enableSpecialKeys(true);
if (m_hookLibrary != NULL) {
// watch jump zones
m_hookLibraryLoader.m_setMode(kHOOK_WATCH_JUMP_ZONE);
}
// watch jump zones
m_hook.setMode(kHOOK_WATCH_JUMP_ZONE);
// all messages prior to now are invalid
nextMark();
@ -359,10 +340,7 @@ CMSWindowsScreen::leave()
// reflected in the internal keyboard state.
m_keyState->saveModifiers();
if (m_hookLibrary != NULL) {
// capture events
m_hookLibraryLoader.m_setMode(kHOOK_RELAY_EVENTS);
}
m_hook.setMode(kHOOK_RELAY_EVENTS);
}
// now off screen
@ -541,9 +519,7 @@ CMSWindowsScreen::reconfigure(UInt32 activeSides)
assert(m_isPrimary);
LOG((CLOG_DEBUG "active sides: %x", activeSides));
if (m_hookLibrary != NULL)
m_hookLibraryLoader.m_setSides(activeSides);
m_hook.setSides(activeSides);
}
void
@ -812,35 +788,6 @@ CMSWindowsScreen::fakeAllKeysUp()
updateForceShowCursor();
}
HINSTANCE
CMSWindowsScreen::openHookLibrary(const char* name)
{
return m_hookLibraryLoader.openHookLibrary(name);
}
HINSTANCE
CMSWindowsScreen::openShellLibrary(const char* name)
{
return m_hookLibraryLoader.openShellLibrary(name);
}
void
CMSWindowsScreen::closeHookLibrary(HINSTANCE hookLibrary) const
{
if (hookLibrary != NULL) {
m_hookLibraryLoader.m_cleanup();
FreeLibrary(hookLibrary);
}
}
void
CMSWindowsScreen::closeShellLibrary(HINSTANCE shellLibrary) const
{
if (shellLibrary != NULL) {
FreeLibrary(shellLibrary);
}
}
HCURSOR
CMSWindowsScreen::createBlankCursor() const
{
@ -1517,7 +1464,7 @@ CMSWindowsScreen::onDisplayChange()
// tell hook about resize if on screen
else {
m_hookLibraryLoader.m_setZone(m_x, m_y, m_w, m_h, getJumpZoneSize());
m_hook.setZone(m_x, m_y, m_w, m_h, getJumpZoneSize());
}
}
@ -1908,7 +1855,7 @@ CMSWindowsScreen::getDraggingFilename()
{
if (m_draggingStarted) {
char filename[MAX_PATH];
m_hookLibraryLoader.m_getDraggingFilename(filename);
m_shellEx.getDraggingFilename(filename);
m_draggingFilename = filename;
}
@ -1919,7 +1866,7 @@ void
CMSWindowsScreen::clearDraggingFilename()
{
LOG((CLOG_DEBUG "clearing stored dragging file name"));
m_hookLibraryLoader.m_clearDraggingFilename();
m_shellEx.clearDraggingFilename();
}
const CString&

View File

@ -18,7 +18,8 @@
#pragma once
#include "platform/MSWindowsHookLibraryLoader.h"
#include "platform/MSWindowsShellEx.h"
#include "platform/MSWindowsHook.h"
#include "synergy/PlatformScreen.h"
#include "synwinhk/synwinhk.h"
#include "mt/CondVar.h"
@ -128,10 +129,6 @@ protected:
private:
// initialization and shutdown operations
HINSTANCE openHookLibrary(const char* name);
HINSTANCE openShellLibrary(const char* name);
void closeHookLibrary(HINSTANCE hookLibrary) const;
void closeShellLibrary(HINSTANCE shellLibrary) const;
HCURSOR createBlankCursor() const;
void destroyCursor(HCURSOR cursor) const;
ATOM createWindowClass() const;
@ -290,10 +287,6 @@ private:
// one desk per desktop and a cond var to communicate with it
CMSWindowsDesks* m_desks;
// hook library stuff
HINSTANCE m_hookLibrary;
HINSTANCE m_shellLibrary;
// keyboard stuff
CMSWindowsKeyState* m_keyState;
@ -321,10 +314,9 @@ private:
bool m_gotOldMouseKeys;
MOUSEKEYS m_mouseKeys;
MOUSEKEYS m_oldMouseKeys;
// loads synwinhk.dll
CMSWindowsHookLibraryLoader
m_hookLibraryLoader;
CMSWindowsHook m_hook;
CMSWindowsShellEx m_shellEx;
static CMSWindowsScreen*
s_screen;

View File

@ -0,0 +1,92 @@
/*
* synergy -- mouse and keyboard sharing utility
* Copyright (C) 2014 Bolton Software Ltd.
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file COPYING that should have accompanied this file.
*
* This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "platform/MSWindowsShellEx.h"
#include "synergy/XScreen.h"
#include "base/Log.h"
static const char* g_name = "synwinxt";
CMSWindowsShellEx::CMSWindowsShellEx() :
m_getDraggingFilenameFunc(NULL),
m_clearDraggingFilenameFunc(NULL),
m_instance(NULL)
{
}
CMSWindowsShellEx::~CMSWindowsShellEx()
{
if (m_instance != NULL) {
FreeLibrary(m_instance);
}
}
void
CMSWindowsShellEx::loadLibrary()
{
OSVERSIONINFO osvi;
ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
GetVersionEx(&osvi);
if (osvi.dwMajorVersion < 6) {
LOG((CLOG_INFO "skipping shell extension library load, %s.dll not supported before vista", g_name));
return;
}
// load library
m_instance = LoadLibrary(g_name);
if (m_instance == NULL) {
LOG((CLOG_ERR "failed to load shell extension library, %s.dll is missing or invalid", g_name));
throw XScreenOpenFailure();
}
// look up functions
m_getDraggingFilenameFunc = (GetDraggingFilenameFunc)GetProcAddress(m_instance, "getDraggingFilename");
m_clearDraggingFilenameFunc = (ClearDraggingFilenameFunc)GetProcAddress(m_instance, "clearDraggingFilename");
if (m_getDraggingFilenameFunc == NULL ||
m_clearDraggingFilenameFunc == NULL) {
LOG((CLOG_ERR "failed to load shell extension function, %s.dll could be out of date", g_name));
throw XScreenOpenFailure();
}
}
HINSTANCE
CMSWindowsShellEx::getInstance() const
{
return m_instance;
}
void
CMSWindowsShellEx::getDraggingFilename(char* filename) const
{
if (m_getDraggingFilenameFunc == NULL) {
return;
}
m_getDraggingFilenameFunc(filename);
}
void
CMSWindowsShellEx::clearDraggingFilename()
{
if (m_getDraggingFilenameFunc == NULL) {
return;
}
m_clearDraggingFilenameFunc();
}

View File

@ -0,0 +1,43 @@
/*
* synergy -- mouse and keyboard sharing utility
* Copyright (C) 2014 Bolton Software Ltd.
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file COPYING that should have accompanied this file.
*
* This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "synwinxt/synwinxt.h"
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
//! Loads and provides functions for the Windows shell extension
class CMSWindowsShellEx
{
public:
CMSWindowsShellEx();
virtual ~CMSWindowsShellEx();
void loadLibrary();
HINSTANCE getInstance() const;
void getDraggingFilename(char* filename) const;
void clearDraggingFilename();
private:
HINSTANCE m_instance;
GetDraggingFilenameFunc
m_getDraggingFilenameFunc;
ClearDraggingFilenameFunc
m_clearDraggingFilenameFunc;
};

View File

@ -17,8 +17,6 @@
#pragma once
#include <Windows.h>
#if defined(synwinxt_EXPORTS)
#define CSYNERGYSHELLEXE_API __declspec(dllexport)
#else

View File

@ -40,8 +40,7 @@ class CMSWindowsKeyStateTests : public ::testing::Test
protected:
virtual void SetUp()
{
// load synwinhk.dll
m_hookLibrary = m_hookLibraryLoader.openHookLibrary("synwinhk");
m_hook.loadLibrary();
m_screensaver = new CMSWindowsScreenSaver();
}
@ -53,7 +52,7 @@ protected:
CMSWindowsDesks* newDesks(IEventQueue* eventQueue)
{
return new CMSWindowsDesks(
true, false, m_hookLibrary, m_screensaver, eventQueue,
true, false, m_hook.getInstance(), m_screensaver, eventQueue,
new TMethodJob<CMSWindowsKeyStateTests>(
this, &CMSWindowsKeyStateTests::updateKeysCB), false);
}
@ -65,9 +64,8 @@ protected:
private:
void updateKeysCB(void*) { }
HINSTANCE m_hookLibrary;
IScreenSaver* m_screensaver;
CMSWindowsHookLibraryLoader m_hookLibraryLoader;
CMSWindowsHook m_hook;
};
TEST_F(CMSWindowsKeyStateTests, disable_nonWin95OS_eventQueueNotUsed)