summaryrefslogtreecommitdiffstats
path: root/chrome/installer
diff options
context:
space:
mode:
authorrobertshield@chromium.org <robertshield@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-06-30 00:16:56 +0000
committerrobertshield@chromium.org <robertshield@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-06-30 00:16:56 +0000
commit18eb4534219b1b96f68f9cda4cd220b8c73766ff (patch)
tree39790363cf869f6e0e1d68b82e39196e2501e50d /chrome/installer
parente3280d6cedb73ee9fb2a8b4aa9f74d72c7456d83 (diff)
downloadchromium_src-18eb4534219b1b96f68f9cda4cd220b8c73766ff.zip
chromium_src-18eb4534219b1b96f68f9cda4cd220b8c73766ff.tar.gz
chromium_src-18eb4534219b1b96f68f9cda4cd220b8c73766ff.tar.bz2
When using ShellExecuteEx to elevate, create a foreground window and pass that as the parent window to ShellExecuteEx. This should ensure two things:
If we have focus, the UAC prompt will show up in the foreground. When the UAC task completes since we have a window, we may get focus back again. BUG=NONE TEST=NONE Review URL: http://codereview.chromium.org/7282009 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@91060 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/installer')
-rw-r--r--chrome/installer/util/install_util.cc63
1 files changed, 54 insertions, 9 deletions
diff --git a/chrome/installer/util/install_util.cc b/chrome/installer/util/install_util.cc
index 15a9dab..8406c3b 100644
--- a/chrome/installer/util/install_util.cc
+++ b/chrome/installer/util/install_util.cc
@@ -75,6 +75,42 @@ const wchar_t* const kStages[] = {
COMPILE_ASSERT(installer::NUM_STAGES == arraysize(kStages),
kStages_disagrees_with_Stage_comma_they_must_match_bang);
+// Creates a zero-sized non-decorated foreground window that doesn't appear
+// in the taskbar. This is used as a parent window for calls to ShellExecuteEx
+// in order for the UAC dialog to appear in the foreground and for focus
+// to be returned to this process once the UAC task is dismissed. Returns
+// NULL on failure, a handle to the UAC window on success.
+HWND CreateUACForegroundWindow() {
+ HWND foreground_window = ::CreateWindowEx(WS_EX_TOOLWINDOW,
+ L"STATIC",
+ NULL,
+ WS_POPUP | WS_VISIBLE,
+ 0, 0, 0, 0,
+ NULL, NULL,
+ ::GetModuleHandle(NULL),
+ NULL);
+ if (foreground_window) {
+ HMONITOR monitor = ::MonitorFromWindow(foreground_window,
+ MONITOR_DEFAULTTONEAREST);
+ if (monitor) {
+ MONITORINFO mi = {0};
+ mi.cbSize = sizeof(mi);
+ ::GetMonitorInfo(monitor, &mi);
+ RECT screen_rect = mi.rcWork;
+ int x_offset = (screen_rect.right - screen_rect.left) / 2;
+ int y_offset = (screen_rect.bottom - screen_rect.top) / 2;
+ ::MoveWindow(foreground_window,
+ screen_rect.left + x_offset,
+ screen_rect.top + y_offset,
+ 0, 0, FALSE);
+ } else {
+ NOTREACHED() << "Unable to get default monitor";
+ }
+ ::SetForegroundWindow(foreground_window);
+ }
+ return foreground_window;
+}
+
} // namespace
bool InstallUtil::ExecuteExeAsAdmin(const CommandLine& cmd, DWORD* exit_code) {
@@ -94,24 +130,33 @@ bool InstallUtil::ExecuteExeAsAdmin(const CommandLine& cmd, DWORD* exit_code) {
TrimWhitespace(params, TRIM_ALL, &params);
+ HWND uac_foreground_window = CreateUACForegroundWindow();
+
SHELLEXECUTEINFO info = {0};
info.cbSize = sizeof(SHELLEXECUTEINFO);
info.fMask = SEE_MASK_NOCLOSEPROCESS;
+ info.hwnd = uac_foreground_window;
info.lpVerb = L"runas";
info.lpFile = program.c_str();
info.lpParameters = params.c_str();
info.nShow = SW_SHOW;
- if (::ShellExecuteEx(&info) == FALSE)
- return false;
- ::WaitForSingleObject(info.hProcess, INFINITE);
- DWORD ret_val = 0;
- if (!::GetExitCodeProcess(info.hProcess, &ret_val))
- return false;
+ bool success = false;
+ if (::ShellExecuteEx(&info) == TRUE) {
+ ::WaitForSingleObject(info.hProcess, INFINITE);
+ DWORD ret_val = 0;
+ if (::GetExitCodeProcess(info.hProcess, &ret_val)) {
+ success = true;
+ if (exit_code)
+ *exit_code = ret_val;
+ }
+ }
- if (exit_code)
- *exit_code = ret_val;
- return true;
+ if (uac_foreground_window) {
+ DestroyWindow(uac_foreground_window);
+ }
+
+ return success;
}
CommandLine InstallUtil::GetChromeUninstallCmd(