summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/google_update.cc25
-rw-r--r--chrome/browser/google_update.h13
-rw-r--r--chrome/browser/views/about_chrome_view.cc6
3 files changed, 34 insertions, 10 deletions
diff --git a/chrome/browser/google_update.cc b/chrome/browser/google_update.cc
index fceede8..c6ca0f5 100644
--- a/chrome/browser/google_update.cc
+++ b/chrome/browser/google_update.cc
@@ -18,8 +18,11 @@
#include "chrome/installer/util/google_update_constants.h"
#include "chrome/installer/util/helper.h"
#include "chrome/installer/util/install_util.h"
+#include "chrome/views/window/window.h"
#include "google_update_idl_i.c"
+using views::Window;
+
namespace {
// Check if the currently running instance can be updated by Google Update.
// Returns true only if the instance running is a Google Chrome
@@ -49,8 +52,11 @@ bool CanUpdateCurrentChrome(const std::wstring& chrome_exe_path) {
// Creates an instance of a COM Local Server class using either plain vanilla
// CoCreateInstance, or using the Elevation moniker if running on Vista.
+// hwnd must refer to a foregound window in order to get the UAC prompt
+// showing up in the foreground if running on Vista. It can also be NULL if
+// background UAC prompts are desired.
HRESULT CoCreateInstanceAsAdmin(REFCLSID class_id, REFIID interface_id,
- void** interface_ptr) {
+ HWND hwnd, void** interface_ptr) {
if (!interface_ptr)
return E_POINTER;
@@ -62,13 +68,14 @@ HRESULT CoCreateInstanceAsAdmin(REFCLSID class_id, REFIID interface_id,
arraysize(class_id_as_string));
std::wstring elevation_moniker_name =
- StringPrintf(L"Elevation:Administrator!new:%s", class_id_as_string);
+ StringPrintf(L"Elevation:Administrator!new:%ls", class_id_as_string);
BIND_OPTS3 bind_opts;
memset(&bind_opts, 0, sizeof(bind_opts));
-
bind_opts.cbStruct = sizeof(bind_opts);
bind_opts.dwClassContext = CLSCTX_LOCAL_SERVER;
+ bind_opts.hwnd = hwnd;
+
return CoGetObject(elevation_moniker_name.c_str(), &bind_opts,
interface_id, reinterpret_cast<void**>(interface_ptr));
}
@@ -201,13 +208,13 @@ GoogleUpdate::~GoogleUpdate() {
////////////////////////////////////////////////////////////////////////////////
// GoogleUpdate, views::DialogDelegate implementation:
-void GoogleUpdate::CheckForUpdate(bool install_if_newer) {
+void GoogleUpdate::CheckForUpdate(bool install_if_newer, Window* window) {
// We need to shunt this request over to InitiateGoogleUpdateCheck and have
// it run in the file thread.
MessageLoop* file_loop = g_browser_process->file_thread()->message_loop();
file_loop->PostTask(FROM_HERE, NewRunnableMethod(this,
&GoogleUpdate::InitiateGoogleUpdateCheck,
- install_if_newer, MessageLoop::current()));
+ install_if_newer, window, MessageLoop::current()));
}
// Adds/removes a listener. Only one listener is maintained at the moment.
@@ -225,6 +232,7 @@ void GoogleUpdate::RemoveStatusChangeListener() {
// GoogleUpdate, private:
bool GoogleUpdate::InitiateGoogleUpdateCheck(bool install_if_newer,
+ Window* window,
MessageLoop* main_loop) {
std::wstring chrome_exe_path;
@@ -264,8 +272,13 @@ bool GoogleUpdate::InitiateGoogleUpdateCheck(bool install_if_newer,
if (!install_if_newer) {
hr = on_demand.CoCreateInstance(CLSID_OnDemandMachineAppsClass);
} else {
+ HWND foreground_hwnd = NULL;
+ if (window != NULL) {
+ foreground_hwnd = window->GetNativeWindow();
+ }
+
hr = CoCreateInstanceAsAdmin(CLSID_OnDemandMachineAppsClass,
- IID_IGoogleUpdate,
+ IID_IGoogleUpdate, foreground_hwnd,
reinterpret_cast<void**>(&on_demand));
}
}
diff --git a/chrome/browser/google_update.h b/chrome/browser/google_update.h
index 34007ef..9dee7a3 100644
--- a/chrome/browser/google_update.h
+++ b/chrome/browser/google_update.h
@@ -12,6 +12,9 @@
#include "google_update_idl.h"
class MessageLoop;
+namespace views {
+class Window;
+}
// The status of the upgrade. UPGRADE_STARTED and UPGRADE_CHECK_STARTED are
// internal states and will not be reported as results to the listener.
@@ -84,7 +87,10 @@ class GoogleUpdate : public base::RefCountedThreadSafe<GoogleUpdate> {
// Ask Google Update to see if a new version is available. If the parameter
// |install_if_newer| is true then Google Update will also install that new
// version.
- void CheckForUpdate(bool install_if_newer);
+ // |window| should point to a foreground window. This is needed to ensure
+ // that Vista/Windows 7 UAC prompts show up in the foreground. It may also
+ // be null.
+ void CheckForUpdate(bool install_if_newer, views::Window* window);
// Adds/removes a listener to report status back to. Only one listener is
// maintained at the moment.
@@ -95,7 +101,10 @@ class GoogleUpdate : public base::RefCountedThreadSafe<GoogleUpdate> {
// We need to run the update check on another thread than the main thread, and
// therefore CheckForUpdate will delegate to this function. |main_loop| points
// to the message loop that we want the response to come from.
- bool InitiateGoogleUpdateCheck(bool install_if_newer, MessageLoop* main_loop);
+ // |window| should point to a foreground window. This is needed to ensure that
+ // Vista/Windows 7 UAC prompts show up in the foreground. It may also be null.
+ bool InitiateGoogleUpdateCheck(bool install_if_newer, views::Window* window,
+ MessageLoop* main_loop);
// This function reports the results of the GoogleUpdate operation to the
// listener. If results indicates an error, the error_code will indicate which
diff --git a/chrome/browser/views/about_chrome_view.cc b/chrome/browser/views/about_chrome_view.cc
index 0ef4183..8cfa84f 100644
--- a/chrome/browser/views/about_chrome_view.cc
+++ b/chrome/browser/views/about_chrome_view.cc
@@ -587,7 +587,8 @@ void AboutChromeView::ViewHierarchyChanged(bool is_add,
service_pack_major >= 1) ||
win_util::GetWinVersion() > win_util::WINVERSION_VISTA) {
UpdateStatus(UPGRADE_CHECK_STARTED, GOOGLE_UPDATE_NO_ERROR);
- google_updater_->CheckForUpdate(false); // false=don't upgrade yet.
+ // CheckForUpdate(false, ...) means don't upgrade yet.
+ google_updater_->CheckForUpdate(false, window());
}
} else {
parent->RemoveChildView(&update_label_);
@@ -668,7 +669,8 @@ bool AboutChromeView::Accept() {
DCHECK(!google_updater_);
google_updater_ = new GoogleUpdate();
google_updater_->AddStatusChangeListener(this);
- google_updater_->CheckForUpdate(true); // true=upgrade if new version found.
+ // CheckForUpdate(true,...) means perform the upgrade if new version found.
+ google_updater_->CheckForUpdate(true, window());
return false; // We never allow this button to close the window.
}