mirror of
https://gitlab.uni-freiburg.de/opensourcevdi/win32-vd_agent
synced 2025-12-27 14:54:11 +00:00
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
This commit is contained in:
parent
877e52386e
commit
482a4980f4
@ -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);
|
||||
|
||||
@ -353,6 +353,10 @@
|
||||
RelativePath=".\vdagent.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\common\vdcommon.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\common\vdlog.cpp"
|
||||
>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user