mirror of
https://gitlab.uni-freiburg.de/opensourcevdi/win32-vd_agent
synced 2025-12-26 13:26:00 +00:00
vdservice stops vdagent via event
Terminate agent politely instead of ugly TerminateProcess(), so now VD_AGENT_CLIPBOARD_RELEASE is sent (if guest owned the clipboard), followed by cleanup. rhbz #903379
This commit is contained in:
parent
05af7a9786
commit
2d03cc5c2c
@ -33,6 +33,7 @@ typedef CRITICAL_SECTION mutex_t;
|
||||
#define MUTEX_UNLOCK(mutex) LeaveCriticalSection(&mutex)
|
||||
|
||||
#define VD_AGENT_REGISTRY_KEY "SOFTWARE\\Red Hat\\Spice\\vdagent\\"
|
||||
#define VD_AGENT_STOP_EVENT TEXT("Global\\vdagent_stop_event")
|
||||
|
||||
#if defined __GNUC__
|
||||
#define ALIGN_GCC __attribute__ ((packed))
|
||||
|
||||
@ -128,6 +128,7 @@ private:
|
||||
INPUT _input;
|
||||
DWORD _input_time;
|
||||
HANDLE _control_event;
|
||||
HANDLE _stop_event;
|
||||
VDAgentMessage* _in_msg;
|
||||
uint32_t _in_msg_pos;
|
||||
bool _pending_input;
|
||||
@ -180,6 +181,7 @@ VDAgent::VDAgent()
|
||||
, _mouse_y (0)
|
||||
, _input_time (0)
|
||||
, _control_event (NULL)
|
||||
, _stop_event (NULL)
|
||||
, _in_msg (NULL)
|
||||
, _in_msg_pos (0)
|
||||
, _pending_input (false)
|
||||
@ -266,6 +268,12 @@ bool VDAgent::run()
|
||||
cleanup();
|
||||
return false;
|
||||
}
|
||||
_stop_event = OpenEvent(SYNCHRONIZE, FALSE, VD_AGENT_STOP_EVENT);
|
||||
if (!_stop_event) {
|
||||
vd_printf("OpenEvent() failed: %lu", GetLastError());
|
||||
cleanup();
|
||||
return false;
|
||||
}
|
||||
memset(&wcls, 0, sizeof(wcls));
|
||||
wcls.lpfnWndProc = &VDAgent::wnd_proc;
|
||||
wcls.lpszClassName = VD_AGENT_WINCLASS_NAME;
|
||||
@ -312,6 +320,7 @@ bool VDAgent::run()
|
||||
|
||||
void VDAgent::cleanup()
|
||||
{
|
||||
CloseHandle(_stop_event);
|
||||
CloseHandle(_control_event);
|
||||
CloseHandle(_vio_serial);
|
||||
delete _desktop_layout;
|
||||
@ -428,15 +437,20 @@ void VDAgent::input_desktop_message_loop()
|
||||
|
||||
void VDAgent::event_dispatcher(DWORD timeout, DWORD wake_mask)
|
||||
{
|
||||
HANDLE events[] = {_control_event, _stop_event};
|
||||
const DWORD event_count = sizeof(events) / sizeof(events[0]);
|
||||
DWORD wait_ret;
|
||||
MSG msg;
|
||||
|
||||
wait_ret = MsgWaitForMultipleObjectsEx(1, &_control_event, timeout, wake_mask, MWMO_ALERTABLE);
|
||||
wait_ret = MsgWaitForMultipleObjectsEx(event_count, events, timeout, wake_mask, MWMO_ALERTABLE);
|
||||
switch (wait_ret) {
|
||||
case WAIT_OBJECT_0:
|
||||
handle_control_event();
|
||||
break;
|
||||
case WAIT_OBJECT_0 + 1:
|
||||
_running = false;
|
||||
break;
|
||||
case WAIT_OBJECT_0 + event_count:
|
||||
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
|
||||
@ -92,6 +92,7 @@ private:
|
||||
SERVICE_STATUS_HANDLE _status_handle;
|
||||
PROCESS_INFORMATION _agent_proc_info;
|
||||
HANDLE _control_event;
|
||||
HANDLE _agent_stop_event;
|
||||
HANDLE* _events;
|
||||
TCHAR _agent_path[MAX_PATH];
|
||||
VDControlQueue _control_queue;
|
||||
@ -157,6 +158,7 @@ VDService::VDService()
|
||||
ZeroMemory(&_agent_proc_info, sizeof(_agent_proc_info));
|
||||
_system_version = supported_system_version();
|
||||
_control_event = CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||
_agent_stop_event = CreateEvent(NULL, FALSE, FALSE, VD_AGENT_STOP_EVENT);
|
||||
_agent_path[0] = wchar_t('\0');
|
||||
MUTEX_INIT(_agent_mutex);
|
||||
MUTEX_INIT(_control_mutex);
|
||||
@ -165,6 +167,7 @@ VDService::VDService()
|
||||
|
||||
VDService::~VDService()
|
||||
{
|
||||
CloseHandle(_agent_stop_event);
|
||||
CloseHandle(_control_event);
|
||||
delete _events;
|
||||
delete _log;
|
||||
@ -777,7 +780,7 @@ bool VDService::kill_agent()
|
||||
_agent_alive = false;
|
||||
proc_handle = _agent_proc_info.hProcess;
|
||||
_agent_proc_info.hProcess = 0;
|
||||
TerminateProcess(proc_handle, 0);
|
||||
SetEvent(_agent_stop_event);
|
||||
if (GetProcessId(proc_handle)) {
|
||||
wait_ret = WaitForSingleObject(proc_handle, VD_AGENT_TIMEOUT);
|
||||
switch (wait_ret) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user