diff options
-rw-r--r-- | chrome/browser/google_update.cc | 25 | ||||
-rw-r--r-- | chrome/browser/google_update.h | 13 | ||||
-rw-r--r-- | chrome/browser/views/about_chrome_view.cc | 6 |
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. } |