diff options
author | zturner@chromium.org <zturner@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-09-13 06:54:27 +0000 |
---|---|---|
committer | zturner@chromium.org <zturner@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-09-13 06:54:27 +0000 |
commit | 67a8e72bd6e39955c9769f766e3b9b7f2ae846a0 (patch) | |
tree | 8edac361a73331502a2c3d29ca2adfa34e0173db /win8/delegate_execute | |
parent | 978a2ae248b9c2bc74369e685628542457660198 (diff) | |
download | chromium_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.cc | 133 | ||||
-rw-r--r-- | win8/delegate_execute/chrome_util.h | 3 | ||||
-rw-r--r-- | win8/delegate_execute/command_execute_impl.cc | 9 | ||||
-rw-r--r-- | win8/delegate_execute/command_execute_impl.h | 11 | ||||
-rw-r--r-- | win8/delegate_execute/delegate_execute.cc | 59 |
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, ®istration_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; |