summaryrefslogtreecommitdiffstats
path: root/win8/delegate_execute
diff options
context:
space:
mode:
authorzturner@chromium.org <zturner@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-09-13 06:54:27 +0000
committerzturner@chromium.org <zturner@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-09-13 06:54:27 +0000
commit67a8e72bd6e39955c9769f766e3b9b7f2ae846a0 (patch)
tree8edac361a73331502a2c3d29ca2adfa34e0173db /win8/delegate_execute
parent978a2ae248b9c2bc74369e685628542457660198 (diff)
downloadchromium_src-67a8e72bd6e39955c9769f766e3b9b7f2ae846a0.zip
chromium_src-67a8e72bd6e39955c9769f766e3b9b7f2ae846a0.tar.gz
chromium_src-67a8e72bd6e39955c9769f766e3b9b7f2ae846a0.tar.bz2
Give SxS distribution its own registration GUIDs.
See the linked bug for more information about this change. BUG=273248 gab: chrome/installer/* ananta, cpu: win8/ Review URL: https://chromiumcodereview.appspot.com/23258005 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@222987 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'win8/delegate_execute')
-rw-r--r--win8/delegate_execute/chrome_util.cc133
-rw-r--r--win8/delegate_execute/chrome_util.h3
-rw-r--r--win8/delegate_execute/command_execute_impl.cc9
-rw-r--r--win8/delegate_execute/command_execute_impl.h11
-rw-r--r--win8/delegate_execute/delegate_execute.cc59
5 files changed, 72 insertions, 143 deletions
diff --git a/win8/delegate_execute/chrome_util.cc b/win8/delegate_execute/chrome_util.cc
index 6157dd3..dec23f7 100644
--- a/win8/delegate_execute/chrome_util.cc
+++ b/win8/delegate_execute/chrome_util.cc
@@ -24,28 +24,22 @@
#include "base/win/scoped_comptr.h"
#include "base/win/scoped_handle.h"
#include "base/win/win_util.h"
+#include "chrome/installer/util/browser_distribution.h"
+#include "chrome/installer/util/install_util.h"
+#include "chrome/installer/util/util_constants.h"
#include "google_update/google_update_idl.h"
namespace {
#if defined(GOOGLE_CHROME_BUILD)
-const wchar_t kAppUserModelId[] = L"Chrome";
-#else // GOOGLE_CHROME_BUILD
-const wchar_t kAppUserModelId[] = L"Chromium";
-#endif // GOOGLE_CHROME_BUILD
-
-#if defined(GOOGLE_CHROME_BUILD)
// TODO(grt): These constants live in installer_util. Consider moving them
// into common_constants to allow for reuse.
const base::FilePath::CharType kNewChromeExe[] =
FILE_PATH_LITERAL("new_chrome.exe");
const wchar_t kRenameCommandValue[] = L"cmd";
-const wchar_t kChromeAppGuid[] = L"{8A69D345-D564-463c-AFF1-A69D9E530F96}";
-const wchar_t kRegPathChromeClient[] =
- L"Software\\Google\\Update\\Clients\\"
- L"{8A69D345-D564-463c-AFF1-A69D9E530F96}";
-const int kExitCodeRenameSuccessful = 23;
+const wchar_t kRegPathChromeClientBase[] =
+ L"Software\\Google\\Update\\Clients\\";
// Returns the name of the global event used to detect if |chrome_exe| is in
// use by a browser process.
@@ -88,105 +82,16 @@ bool NewChromeExeExists(const base::FilePath& chrome_exe) {
bool GetUpdateCommand(bool is_per_user, string16* update_command) {
const HKEY root = is_per_user ? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE;
- base::win::RegKey key(root, kRegPathChromeClient, KEY_QUERY_VALUE);
+ BrowserDistribution* dist = BrowserDistribution::GetDistribution();
+ string16 reg_path_chrome_client = kRegPathChromeClientBase;
+ reg_path_chrome_client.append(dist->GetAppGuid());
+ base::win::RegKey key(root, reg_path_chrome_client.c_str(), KEY_QUERY_VALUE);
return key.ReadValue(kRenameCommandValue, update_command) == ERROR_SUCCESS;
}
#endif // GOOGLE_CHROME_BUILD
-// TODO(grt): This code also lives in installer_util. Refactor for reuse.
-bool IsPerUserInstall(const base::FilePath& chrome_exe) {
- wchar_t program_files_path[MAX_PATH] = {0};
- if (SUCCEEDED(SHGetFolderPath(NULL, CSIDL_PROGRAM_FILES, NULL,
- SHGFP_TYPE_CURRENT, program_files_path))) {
- return !StartsWith(chrome_exe.value().c_str(), program_files_path, false);
- } else {
- NOTREACHED();
- }
- return true;
-}
-
-// TODO(gab): This code also lives in shell_util. Refactor for reuse.
-string16 ByteArrayToBase32(const uint8* bytes, size_t size) {
- static const char kEncoding[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
-
- // Eliminate special cases first.
- if (size == 0) {
- return string16();
- } else if (size == 1) {
- string16 ret;
- ret.push_back(kEncoding[(bytes[0] & 0xf8) >> 3]);
- ret.push_back(kEncoding[(bytes[0] & 0x07) << 2]);
- return ret;
- } else if (size >= std::numeric_limits<size_t>::max() / 8) {
- // If |size| is too big, the calculation of |encoded_length| below will
- // overflow.
- AtlTrace("%hs. Byte array is too long.\n", __FUNCTION__);
- return string16();
- }
-
- // Overestimate the number of bits in the string by 4 so that dividing by 5
- // is the equivalent of rounding up the actual number of bits divided by 5.
- const size_t encoded_length = (size * 8 + 4) / 5;
-
- string16 ret;
- ret.reserve(encoded_length);
-
- // A bit stream which will be read from the left and appended to from the
- // right as it's emptied.
- uint16 bit_stream = (bytes[0] << 8) + bytes[1];
- size_t next_byte_index = 2;
- int free_bits = 0;
- while (free_bits < 16) {
- // Extract the 5 leftmost bits in the stream
- ret.push_back(kEncoding[(bit_stream & 0xf800) >> 11]);
- bit_stream <<= 5;
- free_bits += 5;
-
- // If there is enough room in the bit stream, inject another byte (if there
- // are any left...).
- if (free_bits >= 8 && next_byte_index < size) {
- free_bits -= 8;
- bit_stream += bytes[next_byte_index++] << free_bits;
- }
- }
-
- if (ret.length() != encoded_length) {
- AtlTrace("%hs. Encoding doesn't match expected length.\n", __FUNCTION__);
- return string16();
- }
- return ret;
-}
-
-// TODO(gab): This code also lives in shell_util. Refactor for reuse.
-bool GetUserSpecificRegistrySuffix(string16* suffix) {
- string16 user_sid;
- if (!base::win::GetUserSidString(&user_sid)) {
- AtlTrace("%hs. GetUserSidString failed.\n", __FUNCTION__);
- return false;
- }
- COMPILE_ASSERT(sizeof(base::MD5Digest) == 16, size_of_MD5_not_as_expected_);
- base::MD5Digest md5_digest;
- std::string user_sid_ascii(UTF16ToASCII(user_sid));
- base::MD5Sum(user_sid_ascii.c_str(), user_sid_ascii.length(), &md5_digest);
- const string16 base32_md5(
- ByteArrayToBase32(md5_digest.a, arraysize(md5_digest.a)));
- // The value returned by the base32 algorithm above must never change and must
- // always be 26 characters long (i.e. if someone ever moves this to base and
- // implements the full base32 algorithm (i.e. with appended '=' signs in the
- // output), they must provide a flag to allow this method to still request
- // the output with no appended '=' signs).
- if (base32_md5.length() != 26U) {
- AtlTrace("%hs. Base32 encoding of md5 hash is incorrect.\n", __FUNCTION__);
- return false;
- }
- suffix->reserve(base32_md5.length() + 1);
- suffix->assign(1, L'.');
- suffix->append(base32_md5);
- return true;
-}
-
} // namespace
namespace delegate_execute {
@@ -200,7 +105,7 @@ void UpdateChromeIfNeeded(const base::FilePath& chrome_exe) {
base::ProcessHandle process_handle = base::kNullProcessHandle;
- if (IsPerUserInstall(chrome_exe)) {
+ if (InstallUtil::IsPerUserInstall(chrome_exe.value().c_str())) {
// Read the update command from the registry.
string16 update_command;
if (!GetUpdateCommand(true, &update_command)) {
@@ -227,8 +132,10 @@ void UpdateChromeIfNeeded(const base::FilePath& chrome_exe) {
__FUNCTION__, hr);
} else {
ULONG_PTR handle = 0;
+ BrowserDistribution* dist = BrowserDistribution::GetDistribution();
hr = process_launcher->LaunchCmdElevated(
- kChromeAppGuid, kRenameCommandValue, GetCurrentProcessId(), &handle);
+ dist->GetAppGuid().c_str(), kRenameCommandValue,
+ GetCurrentProcessId(), &handle);
if (FAILED(hr)) {
AtlTrace("%hs. Failed to launch command to finalize update; "
"hr=0x%X.\n", __FUNCTION__, hr);
@@ -245,7 +152,7 @@ void UpdateChromeIfNeeded(const base::FilePath& chrome_exe) {
if (!base::WaitForExitCode(process_handle, &exit_code)) {
AtlTrace("%hs. Failed to get result when finalizing update.\n",
__FUNCTION__);
- } else if (exit_code != kExitCodeRenameSuccessful) {
+ } else if (exit_code != installer::RENAME_SUCCESSFUL) {
AtlTrace("%hs. Failed to finalize update with exit code %d.\n",
__FUNCTION__, exit_code);
} else {
@@ -255,16 +162,4 @@ void UpdateChromeIfNeeded(const base::FilePath& chrome_exe) {
#endif
}
-// TODO(gab): This code also lives in shell_util. Refactor for reuse.
-string16 GetAppId(const base::FilePath& chrome_exe) {
- string16 app_id(kAppUserModelId);
- string16 suffix;
- if (IsPerUserInstall(chrome_exe) &&
- !GetUserSpecificRegistrySuffix(&suffix)) {
- AtlTrace("%hs. GetUserSpecificRegistrySuffix failed.\n",
- __FUNCTION__);
- }
- return app_id.append(suffix);
-}
-
} // delegate_execute
diff --git a/win8/delegate_execute/chrome_util.h b/win8/delegate_execute/chrome_util.h
index 8fe0a1f..6310c25 100644
--- a/win8/delegate_execute/chrome_util.h
+++ b/win8/delegate_execute/chrome_util.h
@@ -16,9 +16,6 @@ namespace delegate_execute {
// Finalizes a previously updated installation.
void UpdateChromeIfNeeded(const base::FilePath& chrome_exe);
-// Returns the appid of the Chrome pointed to by |chrome_exe|.
-string16 GetAppId(const base::FilePath& chrome_exe);
-
} // namespace delegate_execute
#endif // WIN8_DELEGATE_EXECUTE_CHROME_UTIL_H_
diff --git a/win8/delegate_execute/command_execute_impl.cc b/win8/delegate_execute/command_execute_impl.cc
index bfb1e51..463bbb7 100644
--- a/win8/delegate_execute/command_execute_impl.cc
+++ b/win8/delegate_execute/command_execute_impl.cc
@@ -23,6 +23,9 @@
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
+#include "chrome/installer/util/browser_distribution.h"
+#include "chrome/installer/util/install_util.h"
+#include "chrome/installer/util/shell_util.h"
#include "chrome/installer/util/util_constants.h"
#include "ui/base/clipboard/clipboard_util_win.h"
#include "win8/delegate_execute/chrome_util.h"
@@ -322,7 +325,11 @@ STDMETHODIMP CommandExecuteImpl::Execute() {
return S_OK;
}
- string16 app_id = delegate_execute::GetAppId(chrome_exe_);
+ BrowserDistribution* distribution = BrowserDistribution::GetDistribution();
+ bool is_per_user_install = InstallUtil::IsPerUserInstall(
+ chrome_exe_.value().c_str());
+ string16 app_id = ShellUtil::GetBrowserModelId(
+ distribution, is_per_user_install);
DWORD pid = 0;
if (launch_scheme_ == INTERNET_SCHEME_FILE &&
diff --git a/win8/delegate_execute/command_execute_impl.h b/win8/delegate_execute/command_execute_impl.h
index 313f2dd..7b1490b 100644
--- a/win8/delegate_execute/command_execute_impl.h
+++ b/win8/delegate_execute/command_execute_impl.h
@@ -23,13 +23,12 @@ EXTERN_C const GUID CLSID_CommandExecuteImpl;
// This class implements the IExecuteCommand and related interfaces for
// handling ShellExecute launches of the Chrome browser, i.e. whether to
// launch Chrome in metro mode or desktop mode.
-#if defined(GOOGLE_CHROME_BUILD)
-class ATL_NO_VTABLE DECLSPEC_UUID("5C65F4B0-3651-4514-B207-D10CB699B14B")
+// The CLSID here is a dummy CLSID not used for anything, since we register
+// the class with a dynamic CLSID. However, a static CLSID is necessary
+// so that we can force at least one entry into ATL's object map (it will
+// treat a 0-element object map as an initialization failure case).
+class ATL_NO_VTABLE DECLSPEC_UUID("071BB5F2-85A4-424F-BFE7-5F1609BE4C2C")
CommandExecuteImpl
-#else // GOOGLE_CHROME_BUILD
-class ATL_NO_VTABLE DECLSPEC_UUID("A2DF06F9-A21A-44A8-8A99-8B9C84F29160")
- CommandExecuteImpl
-#endif // GOOGLE_CHROME_BUILD
: public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CommandExecuteImpl, &CLSID_CommandExecuteImpl>,
public IExecuteCommand,
diff --git a/win8/delegate_execute/delegate_execute.cc b/win8/delegate_execute/delegate_execute.cc
index 549716a..ddb9883 100644
--- a/win8/delegate_execute/delegate_execute.cc
+++ b/win8/delegate_execute/delegate_execute.cc
@@ -17,9 +17,11 @@
#include "base/process/kill.h"
#include "base/strings/string16.h"
#include "base/win/scoped_com_initializer.h"
+#include "base/win/scoped_comptr.h"
#include "base/win/scoped_handle.h"
#include "breakpad/src/client/windows/handler/exception_handler.h"
#include "chrome/common/chrome_switches.h"
+#include "chrome/installer/util/browser_distribution.h"
#include "win8/delegate_execute/command_execute_impl.h"
#include "win8/delegate_execute/crash_server_init.h"
#include "win8/delegate_execute/delegate_execute_operation.h"
@@ -27,33 +29,62 @@
using namespace ATL;
+// Usually classes derived from CAtlExeModuleT, or other types of ATL
+// COM module classes statically define their CLSID at compile time through
+// the use of various macros, and ATL internals takes care of creating the
+// class objects and registering them. However, we need to register the same
+// object with different CLSIDs depending on a runtime setting, so we handle
+// that logic here, before the main ATL message loop runs.
class DelegateExecuteModule
: public ATL::CAtlExeModuleT< DelegateExecuteModule > {
public :
typedef ATL::CAtlExeModuleT<DelegateExecuteModule> ParentClass;
+ typedef CComObject<CommandExecuteImpl> ImplType;
- HRESULT RegisterServer(BOOL reg_type_lib) {
- return ParentClass::RegisterServer(FALSE);
+ DelegateExecuteModule()
+ : registration_token_(0) {
}
- virtual HRESULT AddCommonRGSReplacements(IRegistrarBase* registrar) throw() {
- AtlTrace(L"In %hs\n", __FUNCTION__);
- HRESULT hr = ParentClass::AddCommonRGSReplacements(registrar);
+ HRESULT PreMessageLoop(int nShowCmd) {
+ HRESULT hr = S_OK;
+ string16 clsid_string;
+ GUID clsid;
+ BrowserDistribution* dist = BrowserDistribution::GetDistribution();
+ if (!dist->GetCommandExecuteImplClsid(&clsid_string))
+ return E_FAIL;
+ hr = ::CLSIDFromString(clsid_string.c_str(), &clsid);
if (FAILED(hr))
return hr;
- wchar_t delegate_execute_clsid[MAX_PATH] = {0};
- if (!StringFromGUID2(__uuidof(CommandExecuteImpl), delegate_execute_clsid,
- ARRAYSIZE(delegate_execute_clsid))) {
- ATLASSERT(false);
- return E_FAIL;
+ // We use the same class creation logic as ATL itself. See
+ // _ATL_OBJMAP_ENTRY::RegisterClassObject() in atlbase.h
+ hr = ImplType::_ClassFactoryCreatorClass::CreateInstance(
+ ImplType::_CreatorClass::CreateInstance, IID_IUnknown,
+ instance_.ReceiveVoid());
+ if (FAILED(hr))
+ return hr;
+ hr = ::CoRegisterClassObject(clsid, instance_, CLSCTX_LOCAL_SERVER,
+ REGCLS_MULTIPLEUSE | REGCLS_SUSPENDED, &registration_token_);
+ if (FAILED(hr))
+ return hr;
+
+ return ParentClass::PreMessageLoop(nShowCmd);
+ }
+
+ HRESULT PostMessageLoop() {
+ if (registration_token_ != 0) {
+ ::CoRevokeClassObject(registration_token_);
+ registration_token_ = 0;
}
- hr = registrar->AddReplacement(L"DELEGATE_EXECUTE_CLSID",
- delegate_execute_clsid);
- ATLASSERT(SUCCEEDED(hr));
- return hr;
+ instance_.Release();
+
+ return ParentClass::PostMessageLoop();
}
+
+ private:
+ base::win::ScopedComPtr<IUnknown> instance_;
+ DWORD registration_token_;
};
DelegateExecuteModule _AtlModule;