summaryrefslogtreecommitdiffstats
path: root/chrome/installer
diff options
context:
space:
mode:
authorrobertshield@chromium.org <robertshield@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-12-05 20:56:10 +0000
committerrobertshield@chromium.org <robertshield@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-12-05 20:56:10 +0000
commit0b5a90621e6bba8549c50cd99fd44ed07e8e30f8 (patch)
treee939c413e2074f29abf1542aec9e19d5cd3c3cae /chrome/installer
parent52b03a6600169de2382951882f25653706332ad9 (diff)
downloadchromium_src-0b5a90621e6bba8549c50cd99fd44ed07e8e30f8.zip
chromium_src-0b5a90621e6bba8549c50cd99fd44ed07e8e30f8.tar.gz
chromium_src-0b5a90621e6bba8549c50cd99fd44ed07e8e30f8.tar.bz2
Fix up GCAPI's LaunchGoogleChrome() method to use the current way of finding the path to chrome.exe.
Fix LaunchGoogleChromeWithDimensions such that it looks for the correctly named window for current Chromes. Add an in_background parameter to LaunchGoogleChromeWithDimensions() that will place the launched Chrome window behind all other windows. Remove usage of ATL (was pulled in only for CComPtr). BUG=NONE TEST=NONE Review URL: http://codereview.chromium.org/8776038 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@113016 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/installer')
-rw-r--r--chrome/installer/gcapi/gcapi.cc102
-rw-r--r--chrome/installer/gcapi/gcapi.h17
2 files changed, 77 insertions, 42 deletions
diff --git a/chrome/installer/gcapi/gcapi.cc b/chrome/installer/gcapi/gcapi.cc
index 9982d55..58f8875 100644
--- a/chrome/installer/gcapi/gcapi.cc
+++ b/chrome/installer/gcapi/gcapi.cc
@@ -10,8 +10,6 @@
#include "chrome/installer/gcapi/gcapi.h"
-#include <atlbase.h>
-#include <atlcom.h>
#include <sddl.h>
#define STRSAFE_NO_DEPRECATE
#include <strsafe.h>
@@ -23,13 +21,26 @@
#include <string>
#include "base/basictypes.h"
+#include "base/file_path.h"
+#include "base/file_util.h"
#include "base/string_number_conversions.h"
#include "base/time.h"
#include "base/win/registry.h"
+#include "base/win/scoped_com_initializer.h"
+#include "base/win/scoped_comptr.h"
+#include "base/win/scoped_handle.h"
#include "chrome/installer/util/google_update_constants.h"
+#include "chrome/installer/util/util_constants.h"
#include "google_update_idl.h" // NOLINT
+using base::Time;
+using base::TimeDelta;
+using base::win::RegKey;
+using base::win::ScopedCOMInitializer;
+using base::win::ScopedComPtr;
+using base::win::ScopedHandle;
+
namespace {
const wchar_t kChromeRegClientsKey[] =
@@ -48,6 +59,8 @@ const wchar_t kChromeRegVersion[] = L"pv";
const wchar_t kNoChromeOfferUntil[] =
L"SOFTWARE\\Google\\No Chrome Offer Until";
+const wchar_t kChromeWindowClass[] = L"Chrome_WidgetWin_0";
+
// Return the company name specified in the file version info resource.
bool GetCompanyName(const wchar_t* filename, wchar_t* buffer, DWORD out_len) {
wchar_t file_version_info[8192];
@@ -339,29 +352,49 @@ BOOL __stdcall GoogleChromeCompatibilityCheck(BOOL set_flag, DWORD* reasons) {
}
BOOL __stdcall LaunchGoogleChrome() {
- wchar_t launch_cmd[MAX_PATH];
- size_t size = _countof(launch_cmd);
- if (!ReadValueFromRegistry(HKEY_LOCAL_MACHINE, kChromeRegClientStateKey,
- kChromeRegLastLaunchCmd, launch_cmd, &size)) {
- size = _countof(launch_cmd);
- if (!ReadValueFromRegistry(HKEY_LOCAL_MACHINE, kChromeRegClientStateKey,
- kChromeRegLaunchCmd, launch_cmd, &size)) {
+ // Check to make sure we have a valid Chrome installation.
+ HKEY install_key = HKEY_LOCAL_MACHINE;
+ if (!IsChromeInstalled(install_key)) {
+ install_key = HKEY_CURRENT_USER;
+ if (!IsChromeInstalled(install_key)) {
return false;
}
}
- HRESULT hr = ::CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
- if (hr != S_OK) {
- if (hr == S_FALSE)
- ::CoUninitialize();
+ // Now grab the uninstall string from the appropriate ClientState key
+ // and use that as the base for a path to chrome.exe.
+ FilePath chrome_exe_path;
+ RegKey client_state(install_key, kChromeRegClientStateKey, KEY_QUERY_VALUE);
+ if (client_state.Valid()) {
+ std::wstring uninstall_string;
+ if (client_state.ReadValue(installer::kUninstallStringField,
+ &uninstall_string) == ERROR_SUCCESS) {
+ // The uninstall path contains the path to setup.exe which is two levels
+ // down from chrome.exe. Move up two levels (plus one to drop the file
+ // name) and look for chrome.exe from there.
+ FilePath uninstall_path(uninstall_string);
+ chrome_exe_path = uninstall_path.DirName()
+ .DirName()
+ .DirName()
+ .Append(installer::kChromeExe);
+ if (!file_util::PathExists(chrome_exe_path)) {
+ // By way of mild future proofing, look up one to see if there's a
+ // chrome.exe in the version directory
+ chrome_exe_path =
+ uninstall_path.DirName().DirName().Append(installer::kChromeExe);
+ }
+ }
+ }
+
+ if (!file_util::PathExists(chrome_exe_path)) {
return false;
}
+ ScopedCOMInitializer com_initializer;
if (::CoInitializeSecurity(NULL, -1, NULL, NULL,
RPC_C_AUTHN_LEVEL_PKT_PRIVACY,
RPC_C_IMP_LEVEL_IDENTIFY, NULL,
EOAC_DYNAMIC_CLOAKING, NULL) != S_OK) {
- ::CoUninitialize();
return false;
}
@@ -369,7 +402,6 @@ BOOL __stdcall LaunchGoogleChrome() {
if (IsRunningElevated()) {
wchar_t* curr_proc_sid;
if (!GetUserIdForProcess(GetCurrentProcessId(), &curr_proc_sid)) {
- ::CoUninitialize();
return false;
}
@@ -377,16 +409,17 @@ BOOL __stdcall LaunchGoogleChrome() {
::GetWindowThreadProcessId(::GetShellWindow(), &pid);
if (pid <= 0) {
::LocalFree(curr_proc_sid);
- ::CoUninitialize();
return false;
}
wchar_t* exp_proc_sid;
if (GetUserIdForProcess(pid, &exp_proc_sid)) {
if (_wcsicmp(curr_proc_sid, exp_proc_sid) == 0) {
- HANDLE process_handle = ::OpenProcess(
- PROCESS_DUP_HANDLE | PROCESS_QUERY_INFORMATION, TRUE, pid);
- if (process_handle != NULL) {
+ ScopedHandle process_handle(
+ ::OpenProcess(PROCESS_DUP_HANDLE | PROCESS_QUERY_INFORMATION,
+ TRUE,
+ pid));
+ if (process_handle.IsValid()) {
HANDLE process_token = NULL;
HANDLE user_token = NULL;
if (::OpenProcessToken(process_handle, TOKEN_DUPLICATE | TOKEN_QUERY,
@@ -403,7 +436,6 @@ BOOL __stdcall LaunchGoogleChrome() {
::CloseHandle(user_token);
if (process_token)
::CloseHandle(process_token);
- ::CloseHandle(process_handle);
}
}
::LocalFree(exp_proc_sid);
@@ -411,30 +443,30 @@ BOOL __stdcall LaunchGoogleChrome() {
::LocalFree(curr_proc_sid);
if (!impersonation_success) {
- ::CoUninitialize();
return false;
}
}
bool ret = false;
- CComPtr<IProcessLauncher> ipl;
- if (!FAILED(ipl.CoCreateInstance(__uuidof(ProcessLauncherClass), NULL,
+ ScopedComPtr<IProcessLauncher> ipl;
+ if (SUCCEEDED(ipl.CreateInstance(__uuidof(ProcessLauncherClass),
+ NULL,
CLSCTX_LOCAL_SERVER))) {
- if (!FAILED(ipl->LaunchCmdLine(launch_cmd)))
+ if (SUCCEEDED(ipl->LaunchCmdLine(chrome_exe_path.value().c_str())))
ret = true;
ipl.Release();
}
if (impersonation_success)
::RevertToSelf();
- ::CoUninitialize();
return ret;
}
BOOL __stdcall LaunchGoogleChromeWithDimensions(int x,
int y,
int width,
- int height) {
+ int height,
+ bool in_background) {
if (!LaunchGoogleChrome())
return false;
@@ -445,7 +477,7 @@ BOOL __stdcall LaunchGoogleChromeWithDimensions(int x,
// yet. Wait for it to appear for 10 seconds, but exit if it takes longer
// than that.
while (!handle && seconds_elapsed < 10) {
- handle = FindWindowEx(NULL, handle, L"Chrome_WindowImpl_0", NULL);
+ handle = FindWindowEx(NULL, handle, kChromeWindowClass, NULL);
if (!handle) {
Sleep(1000);
seconds_elapsed++;
@@ -459,21 +491,21 @@ BOOL __stdcall LaunchGoogleChromeWithDimensions(int x,
// but we only want the window that has child windows.
// This loop iterates through all of the top-level Windows named
- // Chrome_WindowImpl_0, and looks for the first one with any children.
- while (handle && !FindWindowEx(handle, NULL, L"Chrome_WindowImpl_0", NULL)) {
+ // kChromeWindowClass, and looks for the first one with any children.
+ while (handle && !FindWindowEx(handle, NULL, kChromeWindowClass, NULL)) {
// Get the next top-level Chrome window.
- handle = FindWindowEx(NULL, handle, L"Chrome_WindowImpl_0", NULL);
+ handle = FindWindowEx(NULL, handle, kChromeWindowClass, NULL);
}
+ HWND set_window_hwnd_insert_after = in_background ? HWND_BOTTOM : NULL;
+ DWORD set_window_flags = in_background ? SWP_NOACTIVATE : SWP_NOZORDER;
+
return (handle &&
- SetWindowPos(handle, 0, x, y, width, height, SWP_NOZORDER));
+ SetWindowPos(handle, set_window_hwnd_insert_after, x, y,
+ width, height, set_window_flags));
}
int __stdcall GoogleChromeDaysSinceLastRun() {
- using base::win::RegKey;
- using base::Time;
- using base::TimeDelta;
-
int days_since_last_run = std::numeric_limits<int>::max();
struct {
diff --git a/chrome/installer/gcapi/gcapi.h b/chrome/installer/gcapi/gcapi.h
index b61e315..a9fd040 100644
--- a/chrome/installer/gcapi/gcapi.h
+++ b/chrome/installer/gcapi/gcapi.h
@@ -27,20 +27,23 @@ extern "C" {
BOOL __stdcall GoogleChromeCompatibilityCheck(BOOL set_flag, DWORD* reasons);
// This function launches Google Chrome after a successful install. Make
-// sure COM library is NOT initalized before you call this function (so if
+// sure COM library is NOT initialized before you call this function (so if
// you called CoInitialize, call CoUninitialize before calling this function).
BOOL __stdcall LaunchGoogleChrome();
// This function launches Google Chrome after a successful install at the
-// given x,y coordinates with size height,length. Make
-// sure COM library is NOT initalized before you call this function (so if
-// you called CoInitialize, call CoUninitialize before calling this function).
+// given x,y coordinates with size height,length. Set in_background to true
+// to move Google Chrome behind all other windows or false to have it appear
+// at the default z-order. Make sure that COM is NOT initialized before you call
+// this function (so if you called CoInitialize, call CoUninitialize before
+// calling this function).
// This call is synchronous, meaning it waits for Chrome to launch and appear
// to resize it before returning.
BOOL __stdcall LaunchGoogleChromeWithDimensions(int x,
- int y,
- int width,
- int height);
+ int y,
+ int width,
+ int height,
+ bool in_background);
// This function returns the number of days since Google Chrome was last run by
// the current user. If both user-level and machine-wide installations are