diff options
author | Arnon Gilboa <agilboa@redhat.com> | 2013-03-18 13:16:22 +0200 |
---|---|---|
committer | Arnon Gilboa <agilboa@redhat.com> | 2013-03-18 13:16:22 +0200 |
commit | 482a4980f4a162787baa46aaffe989796e2dfd1a (patch) | |
tree | 409a18ae5ca6fdcbede5046b7b609bf00ff6fb09 /vdagent | |
parent | 877e52386e6a98ec5c5bd54af13a984b571674ea (diff) |
vdagent: for Win7 class, use ClipboardFormatListener api
(Win7 class includes Win8/Vista/Server2012/Server2008/R2)
This new api was introduced in Vista/2K8 to keep track of clipboard changes,
without the need to trust the (mis)behavior of other applications registered
to the clipboard.
If the issue is reproduced on XP as well, it can be hacked by a periodic call
to ChangeClipboardChain & SetClipboardViewer as described in
http://social.msdn.microsoft.com/Forums/en-US/csharplanguage/thread/
521183dc-7872-472e-8104-8c0d75b1bf53
rhbz #919451
Diffstat (limited to 'vdagent')
-rw-r--r-- | vdagent/vdagent.cpp | 40 | ||||
-rw-r--r-- | vdagent/vdagent.vcproj | 4 |
2 files changed, 42 insertions, 2 deletions
diff --git a/vdagent/vdagent.cpp b/vdagent/vdagent.cpp index 1dcfd1a..b5d65cd 100644 --- a/vdagent/vdagent.cpp +++ b/vdagent/vdagent.cpp @@ -65,6 +65,8 @@ typedef struct ALIGN_VC VDIChunk { #define VD_MESSAGE_HEADER_SIZE (sizeof(VDIChunk) + sizeof(VDAgentMessage)) #define VD_READ_BUF_SIZE (sizeof(VDIChunk) + VD_AGENT_MAX_DATA_SIZE) +typedef BOOL (WINAPI *PCLIPBOARD_OP)(HWND); + class VDAgent { public: static VDAgent* get(); @@ -120,6 +122,10 @@ private: static VDAgent* _singleton; HWND _hwnd; HWND _hwnd_next_viewer; + HMODULE _user_lib; + PCLIPBOARD_OP _add_clipboard_listener; + PCLIPBOARD_OP _remove_clipboard_listener; + int _system_version; int _clipboard_owner; DWORD _clipboard_tick; DWORD _buttons_state; @@ -174,6 +180,9 @@ VDAgent* VDAgent::get() VDAgent::VDAgent() : _hwnd (NULL) , _hwnd_next_viewer (NULL) + , _user_lib (NULL) + , _add_clipboard_listener (NULL) + , _remove_clipboard_listener (NULL) , _clipboard_owner (owner_none) , _clipboard_tick (0) , _buttons_state (0) @@ -201,6 +210,7 @@ VDAgent::VDAgent() TCHAR log_path[MAX_PATH]; TCHAR temp_path[MAX_PATH]; + _system_version = supported_system_version(); if (GetTempPath(MAX_PATH, temp_path)) { swprintf_s(log_path, MAX_PATH, VD_AGENT_LOG_PATH, temp_path); _log = VDLog::get(log_path); @@ -262,6 +272,22 @@ bool VDAgent::run() if (!SetProcessShutdownParameters(0x100, 0)) { vd_printf("SetProcessShutdownParameters failed %lu", GetLastError()); } + if (_system_version == SYS_VER_WIN_7_CLASS) { + _user_lib = LoadLibrary(L"User32.dll"); + if (!_user_lib) { + vd_printf("LoadLibrary failed %lu", GetLastError()); + return false; + } + _add_clipboard_listener = + (PCLIPBOARD_OP)GetProcAddress(_user_lib, "AddClipboardFormatListener"); + _remove_clipboard_listener = + (PCLIPBOARD_OP)GetProcAddress(_user_lib, "RemoveClipboardFormatListener"); + if (!_add_clipboard_listener || !_remove_clipboard_listener) { + vd_printf("GetProcAddress failed %lu", GetLastError()); + cleanup(); + return false; + } + } _control_event = CreateEvent(NULL, FALSE, FALSE, NULL); if (!_control_event) { vd_printf("CreateEvent() failed: %lu", GetLastError()); @@ -320,6 +346,7 @@ bool VDAgent::run() void VDAgent::cleanup() { + FreeLibrary(_user_lib); CloseHandle(_stop_event); CloseHandle(_control_event); CloseHandle(_vio_serial); @@ -420,7 +447,11 @@ void VDAgent::input_desktop_message_loop() if (!WTSRegisterSessionNotification(_hwnd, NOTIFY_FOR_ALL_SESSIONS)) { vd_printf("WTSRegisterSessionNotification() failed: %lu", GetLastError()); } - _hwnd_next_viewer = SetClipboardViewer(_hwnd); + if (_system_version == SYS_VER_WIN_7_CLASS) { + _add_clipboard_listener(_hwnd);
+ } else { + _hwnd_next_viewer = SetClipboardViewer(_hwnd); + } while (_running && !_desktop_switch) { event_dispatcher(INFINITE, QS_ALLINPUT); } @@ -429,7 +460,11 @@ void VDAgent::input_desktop_message_loop() KillTimer(_hwnd, VD_TIMER_ID); _pending_input = false; } - ChangeClipboardChain(_hwnd, _hwnd_next_viewer); + if (_system_version == SYS_VER_WIN_7_CLASS) { + _remove_clipboard_listener(_hwnd);
+ } else { + ChangeClipboardChain(_hwnd, _hwnd_next_viewer); + } WTSUnRegisterSessionNotification(_hwnd); DestroyWindow(_hwnd); CloseDesktop(hdesk); @@ -1343,6 +1378,7 @@ LRESULT CALLBACK VDAgent::wnd_proc(HWND hwnd, UINT message, WPARAM wparam, LPARA SendMessage(a->_hwnd_next_viewer, message, wparam, lparam); } break; + case WM_CLIPBOARDUPDATE: case WM_DRAWCLIPBOARD: if (a->_hwnd != GetClipboardOwner()) { a->set_clipboard_owner(a->owner_none); diff --git a/vdagent/vdagent.vcproj b/vdagent/vdagent.vcproj index 5e7bb43..ed8c58d 100644 --- a/vdagent/vdagent.vcproj +++ b/vdagent/vdagent.vcproj @@ -354,6 +354,10 @@ >
</File>
<File
+ RelativePath="..\common\vdcommon.cpp"
+ >
+ </File>
+ <File
RelativePath="..\common\vdlog.cpp"
>
</File>
|