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
---
 common/vdcommon.h                    |    1 +
 vdagent.sln                          |   10 +
 vdagent/vdagent.cpp                  |   51 +++++-
 vdagent_helper/vdagent_helper.cpp    |   46 +++++
 vdagent_helper/vdagent_helper.vcproj |  363 ++++++++++++++++++++++++++++++++++
 5 files changed, 470 insertions(+), 1 deletions(-)
 create mode 100644 vdagent_helper/vdagent_helper.cpp
 create mode 100644 vdagent_helper/vdagent_helper.vcproj

diff --git a/common/vdcommon.h b/common/vdcommon.h
index 177721c..5099fdc 100644
--- a/common/vdcommon.h
+++ b/common/vdcommon.h
@@ -34,6 +34,7 @@ typedef CRITICAL_SECTION mutex_t;
 
 #define VD_AGENT_REGISTRY_KEY "SOFTWARE\\Red Hat\\Spice\\vdagent\\"
 #define VD_AGENT_STOP_EVENT   TEXT("Global\\vdagent_stop_event")
+#define VD_AGENT_NAMED_PIPE   TEXT("\\\\.\\pipe\\vdagent")
 
 #if defined __GNUC__
 #define ALIGN_GCC __attribute__ ((packed))
diff --git a/vdagent.sln b/vdagent.sln
index 2622f2e..0848ced 100644
--- a/vdagent.sln
+++ b/vdagent.sln
@@ -5,6 +5,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vdagent", 
"vdagent\vdagent.
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vdservice", 
"vdservice\vdservice.vcproj", "{ADFE5E22-31D0-4343-AE9E-8102CC0051F9}"
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vdagent_helper", 
"vdagent_helper\vdagent_helper.vcproj", "{3E459EA7-0252-48E0-A92B-13A66F5F370B}"
+EndProject
 Global
        GlobalSection(SolutionConfigurationPlatforms) = preSolution
                Debug|Win32 = Debug|Win32
@@ -29,6 +31,14 @@ Global
                {ADFE5E22-31D0-4343-AE9E-8102CC0051F9}.Release|Win32.Build.0 = 
Release|Win32
                {ADFE5E22-31D0-4343-AE9E-8102CC0051F9}.Release|x64.ActiveCfg = 
Release|x64
                {ADFE5E22-31D0-4343-AE9E-8102CC0051F9}.Release|x64.Build.0 = 
Release|x64
+               {3E459EA7-0252-48E0-A92B-13A66F5F370B}.Debug|Win32.ActiveCfg = 
Debug|Win32
+               {3E459EA7-0252-48E0-A92B-13A66F5F370B}.Debug|Win32.Build.0 = 
Debug|Win32
+               {3E459EA7-0252-48E0-A92B-13A66F5F370B}.Debug|x64.ActiveCfg = 
Debug|x64
+               {3E459EA7-0252-48E0-A92B-13A66F5F370B}.Debug|x64.Build.0 = 
Debug|x64
+               {3E459EA7-0252-48E0-A92B-13A66F5F370B}.Release|Win32.ActiveCfg 
= Release|Win32
+               {3E459EA7-0252-48E0-A92B-13A66F5F370B}.Release|Win32.Build.0 = 
Release|Win32
+               {3E459EA7-0252-48E0-A92B-13A66F5F370B}.Release|x64.ActiveCfg = 
Release|x64
+               {3E459EA7-0252-48E0-A92B-13A66F5F370B}.Release|x64.Build.0 = 
Release|x64
        EndGlobalSection
        GlobalSection(SolutionProperties) = preSolution
                HideSolutionNode = FALSE
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;
diff --git a/vdagent_helper/vdagent_helper.cpp 
b/vdagent_helper/vdagent_helper.cpp
new file mode 100644
index 0000000..ebeb77b
--- /dev/null
+++ b/vdagent_helper/vdagent_helper.cpp
@@ -0,0 +1,46 @@
+#include <windows.h>
+#include <stdio.h>
+#include <vdlog.h>
+
+int main(int argc,char **argv)
+{
+    TCHAR log_path[MAX_PATH];
+    HANDLE pipe;
+    INPUT input;
+    HDESK hdesk;
+    DWORD bytes;
+    DWORD err = 0;
+    VDLog* log;
+
+    if (GetTempPath(MAX_PATH, log_path)) {
+        wcscat(log_path, L"vdagent_helper.log");
+        log = VDLog::get(log_path);
+    }
+    vd_printf("***vdagent_helper started***");
+    pipe = CreateFile(VD_AGENT_NAMED_PIPE, GENERIC_READ, 0, NULL, 
OPEN_EXISTING, 0, NULL);
+    if (pipe == INVALID_HANDLE_VALUE) {
+        vd_printf("Cannot open pipe %S: %lu", VD_AGENT_NAMED_PIPE, 
GetLastError());
+        goto fin;
+    }
+    while (ReadFile(pipe, &input, sizeof(input), &bytes, NULL) && bytes == 
sizeof(input)) {
+        hdesk = OpenInputDesktop(0, FALSE, GENERIC_ALL);
+        if (!hdesk) {
+            vd_printf("OpenInputDesktop() failed: %lu", GetLastError());
+            break;
+        }
+        if (!SetThreadDesktop(hdesk)) {
+            vd_printf("SetThreadDesktop() failed: %lu", GetLastError());
+            CloseDesktop(hdesk);
+            break;
+        }
+        if (!SendInput(1, &input, sizeof(input)) && err != GetLastError()) {
+            err = GetLastError();
+            vd_printf("SendInput() failed: %lu", err);
+        }
+        CloseDesktop(hdesk);
+    }
+    CloseHandle(pipe);
+fin:
+    delete log;
+    return 0;
+}
\ No newline at end of file
diff --git a/vdagent_helper/vdagent_helper.vcproj 
b/vdagent_helper/vdagent_helper.vcproj
new file mode 100644
index 0000000..47ccb79
--- /dev/null
+++ b/vdagent_helper/vdagent_helper.vcproj
@@ -0,0 +1,363 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+       ProjectType="Visual C++"
+       Version="9.00"
+       Name="vdagent_helper"
+       ProjectGUID="{3E459EA7-0252-48E0-A92B-13A66F5F370B}"
+       RootNamespace="cheese"
+       Keyword="Win32Proj"
+       TargetFrameworkVersion="196613"
+       >
+       <Platforms>
+               <Platform
+                       Name="Win32"
+               />
+               <Platform
+                       Name="x64"
+               />
+       </Platforms>
+       <ToolFiles>
+       </ToolFiles>
+       <Configurations>
+               <Configuration
+                       Name="Debug|Win32"
+                       OutputDirectory="$(ConfigurationName)"
+                       IntermediateDirectory="$(ConfigurationName)"
+                       ConfigurationType="1"
+                       CharacterSet="1"
+                       >
+                       <Tool
+                               Name="VCPreBuildEventTool"
+                       />
+                       <Tool
+                               Name="VCCustomBuildTool"
+                       />
+                       <Tool
+                               Name="VCXMLDataGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCWebServiceProxyGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCMIDLTool"
+                       />
+                       <Tool
+                               Name="VCCLCompilerTool"
+                               Optimization="0"
+                               
AdditionalIncludeDirectories="..\common;$(SPICE_PROTOCOL_DIR)"
+                               PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
+                               MinimalRebuild="true"
+                               BasicRuntimeChecks="3"
+                               RuntimeLibrary="1"
+                               UsePrecompiledHeader="0"
+                               WarningLevel="3"
+                               DebugInformationFormat="4"
+                       />
+                       <Tool
+                               Name="VCManagedResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCPreLinkEventTool"
+                       />
+                       <Tool
+                               Name="VCLinkerTool"
+                               AdditionalDependencies="Version.lib"
+                               LinkIncremental="2"
+                               UACUIAccess="false"
+                               GenerateDebugInformation="true"
+                               SubSystem="1"
+                               TargetMachine="1"
+                       />
+                       <Tool
+                               Name="VCALinkTool"
+                       />
+                       <Tool
+                               Name="VCManifestTool"
+                       />
+                       <Tool
+                               Name="VCXDCMakeTool"
+                       />
+                       <Tool
+                               Name="VCBscMakeTool"
+                       />
+                       <Tool
+                               Name="VCFxCopTool"
+                       />
+                       <Tool
+                               Name="VCAppVerifierTool"
+                       />
+                       <Tool
+                               Name="VCPostBuildEventTool"
+                       />
+               </Configuration>
+               <Configuration
+                       Name="Debug|x64"
+                       OutputDirectory="$(PlatformName)\$(ConfigurationName)"
+                       
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
+                       ConfigurationType="1"
+                       CharacterSet="1"
+                       >
+                       <Tool
+                               Name="VCPreBuildEventTool"
+                       />
+                       <Tool
+                               Name="VCCustomBuildTool"
+                       />
+                       <Tool
+                               Name="VCXMLDataGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCWebServiceProxyGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCMIDLTool"
+                               TargetEnvironment="3"
+                       />
+                       <Tool
+                               Name="VCCLCompilerTool"
+                               Optimization="0"
+                               
AdditionalIncludeDirectories="..\common;$(SPICE_PROTOCOL_DIR)"
+                               PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
+                               MinimalRebuild="true"
+                               BasicRuntimeChecks="3"
+                               RuntimeLibrary="1"
+                               UsePrecompiledHeader="0"
+                               WarningLevel="3"
+                               DebugInformationFormat="3"
+                       />
+                       <Tool
+                               Name="VCManagedResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCPreLinkEventTool"
+                       />
+                       <Tool
+                               Name="VCLinkerTool"
+                               AdditionalDependencies="Version.lib"
+                               LinkIncremental="2"
+                               UACUIAccess="false"
+                               GenerateDebugInformation="true"
+                               SubSystem="1"
+                               TargetMachine="17"
+                       />
+                       <Tool
+                               Name="VCALinkTool"
+                       />
+                       <Tool
+                               Name="VCManifestTool"
+                       />
+                       <Tool
+                               Name="VCXDCMakeTool"
+                       />
+                       <Tool
+                               Name="VCBscMakeTool"
+                       />
+                       <Tool
+                               Name="VCFxCopTool"
+                       />
+                       <Tool
+                               Name="VCAppVerifierTool"
+                       />
+                       <Tool
+                               Name="VCPostBuildEventTool"
+                       />
+               </Configuration>
+               <Configuration
+                       Name="Release|Win32"
+                       OutputDirectory="$(ConfigurationName)"
+                       IntermediateDirectory="$(ConfigurationName)"
+                       ConfigurationType="1"
+                       CharacterSet="1"
+                       WholeProgramOptimization="1"
+                       >
+                       <Tool
+                               Name="VCPreBuildEventTool"
+                       />
+                       <Tool
+                               Name="VCCustomBuildTool"
+                       />
+                       <Tool
+                               Name="VCXMLDataGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCWebServiceProxyGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCMIDLTool"
+                       />
+                       <Tool
+                               Name="VCCLCompilerTool"
+                               Optimization="2"
+                               EnableIntrinsicFunctions="true"
+                               
AdditionalIncludeDirectories="..\common;$(SPICE_PROTOCOL_DIR)"
+                               PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+                               RuntimeLibrary="0"
+                               EnableFunctionLevelLinking="true"
+                               UsePrecompiledHeader="0"
+                               WarningLevel="3"
+                               DebugInformationFormat="3"
+                       />
+                       <Tool
+                               Name="VCManagedResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCPreLinkEventTool"
+                       />
+                       <Tool
+                               Name="VCLinkerTool"
+                               AdditionalDependencies="Version.lib"
+                               LinkIncremental="1"
+                               UACUIAccess="false"
+                               GenerateDebugInformation="true"
+                               SubSystem="1"
+                               OptimizeReferences="2"
+                               EnableCOMDATFolding="2"
+                               TargetMachine="1"
+                       />
+                       <Tool
+                               Name="VCALinkTool"
+                       />
+                       <Tool
+                               Name="VCManifestTool"
+                       />
+                       <Tool
+                               Name="VCXDCMakeTool"
+                       />
+                       <Tool
+                               Name="VCBscMakeTool"
+                       />
+                       <Tool
+                               Name="VCFxCopTool"
+                       />
+                       <Tool
+                               Name="VCAppVerifierTool"
+                       />
+                       <Tool
+                               Name="VCPostBuildEventTool"
+                       />
+               </Configuration>
+               <Configuration
+                       Name="Release|x64"
+                       OutputDirectory="$(PlatformName)\$(ConfigurationName)"
+                       
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
+                       ConfigurationType="1"
+                       CharacterSet="1"
+                       WholeProgramOptimization="1"
+                       >
+                       <Tool
+                               Name="VCPreBuildEventTool"
+                       />
+                       <Tool
+                               Name="VCCustomBuildTool"
+                       />
+                       <Tool
+                               Name="VCXMLDataGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCWebServiceProxyGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCMIDLTool"
+                               TargetEnvironment="3"
+                       />
+                       <Tool
+                               Name="VCCLCompilerTool"
+                               Optimization="2"
+                               EnableIntrinsicFunctions="true"
+                               
AdditionalIncludeDirectories="..\common;$(SPICE_PROTOCOL_DIR)"
+                               PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+                               RuntimeLibrary="0"
+                               EnableFunctionLevelLinking="true"
+                               UsePrecompiledHeader="0"
+                               WarningLevel="3"
+                               DebugInformationFormat="3"
+                       />
+                       <Tool
+                               Name="VCManagedResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCPreLinkEventTool"
+                       />
+                       <Tool
+                               Name="VCLinkerTool"
+                               AdditionalDependencies="Version.lib"
+                               LinkIncremental="1"
+                               UACUIAccess="false"
+                               GenerateDebugInformation="true"
+                               SubSystem="1"
+                               OptimizeReferences="2"
+                               EnableCOMDATFolding="2"
+                               TargetMachine="17"
+                       />
+                       <Tool
+                               Name="VCALinkTool"
+                       />
+                       <Tool
+                               Name="VCManifestTool"
+                       />
+                       <Tool
+                               Name="VCXDCMakeTool"
+                       />
+                       <Tool
+                               Name="VCBscMakeTool"
+                       />
+                       <Tool
+                               Name="VCFxCopTool"
+                       />
+                       <Tool
+                               Name="VCAppVerifierTool"
+                       />
+                       <Tool
+                               Name="VCPostBuildEventTool"
+                       />
+               </Configuration>
+       </Configurations>
+       <References>
+       </References>
+       <Files>
+               <Filter
+                       Name="Source Files"
+                       Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+                       
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+                       >
+                       <File
+                               RelativePath=".\vdagent_helper.cpp"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\common\vdlog.cpp"
+                               >
+                       </File>
+               </Filter>
+               <Filter
+                       Name="Header Files"
+                       Filter="h;hpp;hxx;hm;inl;inc;xsd"
+                       
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+                       >
+                       <File
+                               RelativePath="..\common\vdlog.h"
+                               >
+                       </File>
+               </Filter>
+               <Filter
+                       Name="Resource Files"
+                       
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+                       
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+                       >
+               </Filter>
+       </Files>
+       <Globals>
+       </Globals>
+</VisualStudioProject>
-- 
1.7.7.6

_______________________________________________
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/spice-devel

Reply via email to