diff --git a/src/cmd/synergyc/CMakeLists.txt b/src/cmd/synergyc/CMakeLists.txt index 7c58c85c..ec569fce 100644 --- a/src/cmd/synergyc/CMakeLists.txt +++ b/src/cmd/synergyc/CMakeLists.txt @@ -48,6 +48,7 @@ set(inc ../../lib/platform ../../lib/synergy ../../lib/synwinhk + ../../lib/synwinxt ) if (UNIX) diff --git a/src/cmd/synergyp/CMakeLists.txt b/src/cmd/synergyp/CMakeLists.txt index ff91e315..cfa43f8a 100644 --- a/src/cmd/synergyp/CMakeLists.txt +++ b/src/cmd/synergyp/CMakeLists.txt @@ -48,6 +48,7 @@ set(inc ../../lib/synergy ../../lib/server ../../lib/synwinhk + ../../lib/synwinxt ) if (UNIX) diff --git a/src/cmd/synergys/CMakeLists.txt b/src/cmd/synergys/CMakeLists.txt index 17dba47f..d91b6063 100644 --- a/src/cmd/synergys/CMakeLists.txt +++ b/src/cmd/synergys/CMakeLists.txt @@ -48,6 +48,7 @@ set(inc ../../lib/synergy ../../lib/server ../../lib/synwinhk + ../../lib/synwinxt ) if (UNIX) diff --git a/src/lib/platform/CMSWindowsHookLibraryLoader.cpp b/src/lib/platform/CMSWindowsHookLibraryLoader.cpp index 1f9aecb0..4d851284 100644 --- a/src/lib/platform/CMSWindowsHookLibraryLoader.cpp +++ b/src/lib/platform/CMSWindowsHookLibraryLoader.cpp @@ -25,7 +25,8 @@ CMSWindowsHookLibraryLoader::CMSWindowsHookLibraryLoader() : m_cleanup(NULL), m_setSides(NULL), m_setZone(NULL), - m_setMode(NULL) + m_setMode(NULL), + m_getDraggingFileDir(NULL) { } @@ -67,4 +68,25 @@ CMSWindowsHookLibraryLoader::openHookLibrary(const char* name) } return hookLibrary; -} \ No newline at end of file +} + +HINSTANCE +CMSWindowsHookLibraryLoader::openShellLibrary(const char* name) +{ + // load the hook library + HINSTANCE shellLibrary = LoadLibrary(name); + if (shellLibrary == NULL) { + LOG((CLOG_ERR "failed to load shell library, %s.dll is missing or invalid", name)); + throw XScreenOpenFailure(); + } + + // look up functions + m_getDraggingFileDir = (GetDraggingFileDir)GetProcAddress(shellLibrary, "getDraggingFileDir"); + + if (m_getDraggingFileDir == NULL) { + LOG((CLOG_ERR "invalid shell library, use a newer %s.dll", name)); + throw XScreenOpenFailure(); + } + + return shellLibrary; +} diff --git a/src/lib/platform/CMSWindowsHookLibraryLoader.h b/src/lib/platform/CMSWindowsHookLibraryLoader.h index 6592912d..898d321d 100644 --- a/src/lib/platform/CMSWindowsHookLibraryLoader.h +++ b/src/lib/platform/CMSWindowsHookLibraryLoader.h @@ -22,6 +22,7 @@ #define WIN32_LEAN_AND_MEAN #include #include "synwinhk.h" +#include "synwinxt.h" //! Loads Windows hook DLLs. class CMSWindowsHookLibraryLoader @@ -31,6 +32,7 @@ public: virtual ~CMSWindowsHookLibraryLoader(); HINSTANCE openHookLibrary(const char* name); + HINSTANCE openShellLibrary(const char* name); // TODO: either make these private or expose properly InitFunc m_init; @@ -39,8 +41,7 @@ public: SetZoneFunc m_setZone; SetModeFunc m_setMode; -private: - HINSTANCE m_hookLibrary; + GetDraggingFileDir m_getDraggingFileDir; }; #endif \ No newline at end of file diff --git a/src/lib/platform/CMSWindowsScreen.cpp b/src/lib/platform/CMSWindowsScreen.cpp index 96726841..432d86e0 100644 --- a/src/lib/platform/CMSWindowsScreen.cpp +++ b/src/lib/platform/CMSWindowsScreen.cpp @@ -110,9 +110,11 @@ CMSWindowsScreen::CMSWindowsScreen( m_ownClipboard(false), m_desks(NULL), m_hookLibrary(NULL), + m_shellLibrary(NULL), m_keyState(NULL), m_hasMouse(GetSystemMetrics(SM_MOUSEPRESENT) != 0), m_showingMouse(false), + m_startDragging(false), m_events(events) { assert(s_windowInstance != NULL); @@ -122,6 +124,7 @@ CMSWindowsScreen::CMSWindowsScreen( try { if (m_isPrimary && !m_noHooks) { m_hookLibrary = openHookLibrary("synwinhk"); + m_shellLibrary = openShellLibrary("synwinxt"); } m_screensaver = new CMSWindowsScreenSaver(); m_desks = new CMSWindowsDesks( @@ -149,6 +152,9 @@ CMSWindowsScreen::CMSWindowsScreen( if (m_hookLibrary != NULL) closeHookLibrary(m_hookLibrary); + if (m_shellLibrary != NULL) + closeHookLibrary(m_shellLibrary); + s_screen = NULL; throw; } @@ -178,6 +184,9 @@ CMSWindowsScreen::~CMSWindowsScreen() if (m_hookLibrary != NULL) closeHookLibrary(m_hookLibrary); + if (m_shellLibrary != NULL) + closeHookLibrary(m_shellLibrary); + s_screen = NULL; } @@ -751,6 +760,12 @@ 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 { @@ -1261,6 +1276,9 @@ CMSWindowsScreen::onMouseButton(WPARAM wParam, LPARAM lParam) } else { m_buttons[button] = false; + if (m_startDragging && button == kButtonLeft) { + m_startDragging = false; + } } } @@ -1321,6 +1339,15 @@ CMSWindowsScreen::onMouseMove(SInt32 mx, SInt32 my) sendEvent( m_events->forIPrimaryScreen().motionOnPrimary(), CMotionInfo::alloc(m_xCursor, m_yCursor)); + + if (m_buttons[kButtonLeft] == true && m_startDragging == false) { + // temporarily log out dragging file directory + char dir[MAX_PATH]; + m_hookLibraryLoader.m_getDraggingFileDir(dir); + LOG((CLOG_DEBUG "dragging file: %s", dir)); + + m_startDragging = true; + } } else { diff --git a/src/lib/platform/CMSWindowsScreen.h b/src/lib/platform/CMSWindowsScreen.h index 697ea3ed..b32ab54f 100644 --- a/src/lib/platform/CMSWindowsScreen.h +++ b/src/lib/platform/CMSWindowsScreen.h @@ -125,6 +125,7 @@ protected: private: // initialization and shutdown operations HINSTANCE openHookLibrary(const char* name); + HINSTANCE openShellLibrary(const char* name); void closeHookLibrary(HINSTANCE hookLibrary) const; HCURSOR createBlankCursor() const; void destroyCursor(HCURSOR cursor) const; @@ -286,6 +287,7 @@ private: // hook library stuff HINSTANCE m_hookLibrary; + HINSTANCE m_shellLibrary; // keyboard stuff CMSWindowsKeyState* m_keyState; @@ -323,6 +325,8 @@ private: s_screen; IEventQueue* m_events; + + bool m_startDragging; }; #endif diff --git a/src/lib/platform/CMakeLists.txt b/src/lib/platform/CMakeLists.txt index 2a673018..f44f4d28 100644 --- a/src/lib/platform/CMakeLists.txt +++ b/src/lib/platform/CMakeLists.txt @@ -101,6 +101,7 @@ set(inc ../net ../io ../synwinhk + ../synwinxt ) if (UNIX) diff --git a/src/lib/synergy/CMakeLists.txt b/src/lib/synergy/CMakeLists.txt index aa30fd3d..0dac4e72 100644 --- a/src/lib/synergy/CMakeLists.txt +++ b/src/lib/synergy/CMakeLists.txt @@ -105,6 +105,7 @@ set(inc ../server ../synergy ../synwinhk + ../synwinxt ../.. ../../../tools ) diff --git a/src/lib/synwinxt/CDataHandlerExtension.cpp b/src/lib/synwinxt/CDataHandlerExtension.cpp index c338939a..622eb07a 100644 --- a/src/lib/synwinxt/CDataHandlerExtension.cpp +++ b/src/lib/synwinxt/CDataHandlerExtension.cpp @@ -21,6 +21,7 @@ extern LONG g_refCount; extern GUID g_CLSID; +extern void updateDraggingDir(char*); extern void outputDebugStringF(const char *str, ...); CDataHandlerExtension::CDataHandlerExtension() @@ -64,8 +65,11 @@ CDataHandlerExtension::Release() HRESULT STDMETHODCALLTYPE CDataHandlerExtension::Load(__RPC__in LPCOLESTR pszFileName, DWORD dwMode) { - StringCchCopyW(m_selectedFileName, ARRAYSIZE(m_selectedFileName), pszFileName); - outputDebugStringF("DataHandlerDemo: CDataHandlerExtension::Load: m_selectedFileName=%ls", m_selectedFileName); + char selectedFileDir[MAX_PATH]; + StringCchCopyW(m_selectedFileDir, ARRAYSIZE(m_selectedFileDir), pszFileName); + WideCharToMultiByte(CP_ACP, 0, m_selectedFileDir, -1, selectedFileDir, MAX_PATH, NULL, NULL); + updateDraggingDir(selectedFileDir); + return S_OK; } diff --git a/src/lib/synwinxt/CDataHandlerExtension.h b/src/lib/synwinxt/CDataHandlerExtension.h index 2ecd4a27..d1991407 100644 --- a/src/lib/synwinxt/CDataHandlerExtension.h +++ b/src/lib/synwinxt/CDataHandlerExtension.h @@ -53,5 +53,5 @@ public: private: LONG m_refCount; - WCHAR m_selectedFileName[MAX_PATH]; + WCHAR m_selectedFileDir[MAX_PATH]; }; diff --git a/src/lib/synwinxt/CMakeLists.txt b/src/lib/synwinxt/CMakeLists.txt index ea87f68d..f09b909d 100644 --- a/src/lib/synwinxt/CMakeLists.txt +++ b/src/lib/synwinxt/CMakeLists.txt @@ -16,13 +16,14 @@ set(inc CClassFactory.h CDataHandlerExtension.h + synwinxt.h ) set(src CClassFactory.cpp CDataHandlerExtension.cpp + synwinxt.cpp synwinxt.def - Main.cpp ) list(APPEND src diff --git a/src/lib/synwinxt/Main.cpp b/src/lib/synwinxt/synwinxt.cpp similarity index 90% rename from src/lib/synwinxt/Main.cpp rename to src/lib/synwinxt/synwinxt.cpp index 5f5659ac..12e164d2 100644 --- a/src/lib/synwinxt/Main.cpp +++ b/src/lib/synwinxt/synwinxt.cpp @@ -15,6 +15,7 @@ * along with this program. If not, see . */ +#include "synwinxt.h" #include "CClassFactory.h" #include "CArchMiscWindows.h" #include @@ -22,6 +23,17 @@ #pragma comment(lib, "Shlwapi.lib") +#if defined(_MSC_VER) +#pragma comment(linker, "-section:sharedData,rws") +#pragma data_seg("sharedData") +#endif + +static BYTE g_draggingFileDir[MAX_PATH] = { 0 }; + +#if defined(_MSC_VER) +#pragma data_seg() +#endif + // {1BE208B1-BC21-4E39-8BB6-A5DC3F51479E} GUID g_CLSID = {0x1be208b1, 0xbc21, 0x4e39, {0x8b, 0xb6, 0xa5, 0xdc, 0x3f, 0x51, 0x47, 0x9e}}; LONG g_refCount = 0; @@ -217,8 +229,7 @@ unregisterShellExtDataHandler(CHAR* fileType, const CLSID& clsid) CHAR subkey[MAX_PATH]; // Remove the HKCR\\shellex\DataHandler key. - hr = StringCchPrintf(subkey, ARRAYSIZE(subkey), - "%s\\shellex\\DataHandler", fileType); + hr = StringCchPrintf(subkey, ARRAYSIZE(subkey), "%s\\shellex\\DataHandler", fileType); if (SUCCEEDED(hr)) { hr = HRESULT_FROM_WIN32(RegDeleteTree(HKEY_CLASSES_ROOT, subkey)); } @@ -227,7 +238,7 @@ unregisterShellExtDataHandler(CHAR* fileType, const CLSID& clsid) } void -outputDebugStringF(const char *str, ...) +outputDebugStringF(const char* str, ...) { char buf[2048]; @@ -237,3 +248,16 @@ outputDebugStringF(const char *str, ...) OutputDebugStringA(buf); } + +void +updateDraggingDir(char* dir) +{ + memcpy(g_draggingFileDir, dir, MAX_PATH); + outputDebugStringF("draggingFileDir: %s", g_draggingFileDir); +} + +void +getDraggingFileDir(char* dir) +{ + memcpy(dir, g_draggingFileDir, MAX_PATH); +} diff --git a/src/lib/synwinxt/synwinxt.def b/src/lib/synwinxt/synwinxt.def index 718c0232..d2bb952d 100644 --- a/src/lib/synwinxt/synwinxt.def +++ b/src/lib/synwinxt/synwinxt.def @@ -4,3 +4,4 @@ EXPORTS DllCanUnloadNow PRIVATE DllRegisterServer PRIVATE DllUnregisterServer PRIVATE + getDraggingFileDir diff --git a/src/lib/synwinxt/synwinxt.h b/src/lib/synwinxt/synwinxt.h new file mode 100644 index 00000000..12e23b35 --- /dev/null +++ b/src/lib/synwinxt/synwinxt.h @@ -0,0 +1,30 @@ +/* + * synergy -- mouse and keyboard sharing utility + * Copyright (C) 2013 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 . + */ + +#pragma once + +#include + +#if defined(synwinxt_EXPORTS) +#define CSYNERGYSHELLEXE_API __declspec(dllexport) +#else +#define CSYNERGYSHELLEXE_API __declspec(dllimport) +#endif + +typedef void (*GetDraggingFileDir)(CHAR*); + +CSYNERGYSHELLEXE_API void getDraggingFileDir(char*); diff --git a/src/test/integtests/CMakeLists.txt b/src/test/integtests/CMakeLists.txt index 58a93567..90246165 100644 --- a/src/test/integtests/CMakeLists.txt +++ b/src/test/integtests/CMakeLists.txt @@ -60,6 +60,7 @@ set(inc ../../lib/server ../../lib/synergy ../../lib/synwinhk + ../../lib/synwinxt ../../../tools/gtest-1.6.0/include ../../../tools/gmock-1.6.0/include ../unittests