summaryrefslogtreecommitdiff
path: root/vdagent
diff options
context:
space:
mode:
authorArnon Gilboa <agilboa@redhat.com>2013-03-18 15:38:20 +0200
committerArnon Gilboa <agilboa@redhat.com>2013-03-18 15:38:20 +0200
commitdd9d1f41cace5e73bfd847ff8d0cfa303e141b1c (patch)
treeee9ff1191591b352082d16f0662f7d83d5ebfa48 /vdagent
parent136c8d3c9467326b5cd47bfb47241e065a7c72d2 (diff)
vdagent: add vdagent_helper to support mouse when UAC dialog takes focus
Running the helper with ShellExecute(..."runas"...) is the way to SendInput() to the UAC dialog in Windows Vista and above. http://stackoverflow.com/questions/2426594/starting-a-uac-elevated-process- from-a-non-interactive-service-win32-net-power http://www.microsoft-questions.com/microsoft/Platform-SDK-Security/29620442/ how-to-proper-use-sendinput-to-a-elevated-window-from-a-service.aspx rhbz #908422
Diffstat (limited to 'vdagent')
-rw-r--r--vdagent/vdagent.cpp51
1 files changed, 50 insertions, 1 deletions
diff --git a/vdagent/vdagent.cpp b/vdagent/vdagent.cpp
index f254d55..24fe1f7 100644
--- a/vdagent/vdagent.cpp
+++ b/vdagent/vdagent.cpp
@@ -111,6 +111,7 @@ private:
bool write_message(uint32_t type, uint32_t size, void* data);
bool write_clipboard(VDAgentMessage* msg, uint32_t size);
bool init_vio_serial();
+ bool launch_helper();
bool send_input();
void set_display_depth(uint32_t depth);
void load_display_setting();
@@ -133,6 +134,7 @@ private:
ULONG _mouse_y;
INPUT _input;
DWORD _input_time;
+ HANDLE _helper_pipe;
HANDLE _control_event;
HANDLE _stop_event;
VDAgentMessage* _in_msg;
@@ -189,6 +191,7 @@ VDAgent::VDAgent()
, _mouse_x (0)
, _mouse_y (0)
, _input_time (0)
+ , _helper_pipe (NULL)
, _control_event (NULL)
, _stop_event (NULL)
, _in_msg (NULL)
@@ -287,6 +290,10 @@ bool VDAgent::run()
cleanup();
return false;
}
+ if (!launch_helper()) {
+ cleanup();
+ return false;
+ }
}
_control_event = CreateEvent(NULL, FALSE, FALSE, NULL);
if (!_control_event) {
@@ -342,6 +349,7 @@ bool VDAgent::run()
void VDAgent::cleanup()
{
FreeLibrary(_user_lib);
+ CloseHandle(_helper_pipe);
CloseHandle(_stop_event);
CloseHandle(_control_event);
CloseHandle(_vio_serial);
@@ -393,6 +401,37 @@ void VDAgent::handle_control_event()
MUTEX_UNLOCK(_control_mutex);
}
+bool VDAgent::launch_helper()
+{
+ HINSTANCE helper;
+ TCHAR helper_path[MAX_PATH];
+ TCHAR* slash;
+
+ if (!GetModuleFileName(NULL, helper_path, MAX_PATH) ||
+ !(slash = wcsrchr(helper_path, TCHAR('\\')))) {
+ vd_printf("Cannot get file path: %lu", GetLastError());
+ }
+ wcscpy(slash + 1, L"vdagent_helper.exe");
+ helper = ShellExecute(NULL, L"runas", helper_path, NULL, NULL, SW_HIDE);
+ if (helper <= (HINSTANCE)32) {
+ vd_printf("ShellExecute: %lu", helper);
+ return false;
+ }
+ _helper_pipe = CreateNamedPipe(VD_AGENT_NAMED_PIPE, PIPE_ACCESS_OUTBOUND,
+ PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
+ 1, 1024, 1024, 0, NULL);
+ if (_helper_pipe == INVALID_HANDLE_VALUE) {
+ vd_printf("CreateNamedPipe() failed: %lu", GetLastError());
+ return false;
+ }
+ if (!ConnectNamedPipe(_helper_pipe, NULL) && GetLastError() != ERROR_PIPE_CONNECTED) {
+ vd_printf("ConnectNamedPipe() failed: %lu", GetLastError());
+ CloseHandle(_helper_pipe);
+ return false;
+ }
+ return true;
+}
+
void VDAgent::input_desktop_message_loop()
{
TCHAR desktop_name[MAX_PATH];
@@ -511,6 +550,8 @@ DWORD VDAgent::get_buttons_change(DWORD last_buttons_state, DWORD new_buttons_st
bool VDAgent::send_input()
{
bool ret = true;
+ DWORD bytes;
+
_desktop_layout->lock();
if (_pending_input) {
if (KillTimer(_hwnd, VD_TIMER_ID)) {
@@ -522,7 +563,14 @@ bool VDAgent::send_input()
return false;
}
}
- if (!SendInput(1, &_input, sizeof(INPUT))) {
+
+ if (_system_version == SYS_VER_WIN_7_CLASS) {
+ if (!WriteFile(_helper_pipe, &_input, sizeof(_input), &bytes, NULL) ||
+ sizeof(_input) != bytes) {
+ vd_printf("Write to pipe failed: %lu", GetLastError());
+ ret = _running = false;
+ }
+ } else if (!SendInput(1, &_input, sizeof(INPUT))) {
DWORD err = GetLastError();
// Don't stop agent due to UIPI blocking, which is usually only for specific windows
// of system security applications (anti-viruses etc.)
@@ -531,6 +579,7 @@ bool VDAgent::send_input()
ret = _running = false;
}
}
+
_input_time = GetTickCount();
_desktop_layout->unlock();
return ret;