172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file. 4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/platform_util.h" 6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <commdlg.h> 8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <dwmapi.h> 9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <shellapi.h> 10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <shlobj.h> 11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 123f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "app/win/scoped_co_mem.h" 133f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "app/win/shell.h" 14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/file_path.h" 15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/file_util.h" 16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/logging.h" 17ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/path_service.h" 18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/string_util.h" 193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/utf_string_conversions.h" 20731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "base/win/registry.h" 21ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/win/scoped_comptr.h" 22ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/installer/util/browser_distribution.h" 23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/installer/util/google_update_constants.h" 24ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/installer/util/google_update_settings.h" 25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/installer/util/install_util.h" 26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "googleurl/src/gurl.h" 2772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/message_box_win.h" 2872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/gfx/native_widget_types.h" 29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace platform_util { 31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ShowItemInFolder(const FilePath& full_path) { 33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch FilePath dir = full_path.DirName(); 34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // ParseDisplayName will fail if the directory is "C:", it must be "C:\\". 35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (dir.value() == L"" || !file_util::EnsureEndsWithSeparator(&dir)) 36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch typedef HRESULT (WINAPI *SHOpenFolderAndSelectItemsFuncPtr)( 39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PCIDLIST_ABSOLUTE pidl_Folder, 40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch UINT cidl, 41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PCUITEMID_CHILD_ARRAY pidls, 42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DWORD flags); 43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static SHOpenFolderAndSelectItemsFuncPtr open_folder_and_select_itemsPtr = 45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NULL; 46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static bool initialize_open_folder_proc = true; 47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (initialize_open_folder_proc) { 48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch initialize_open_folder_proc = false; 49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The SHOpenFolderAndSelectItems API is exposed by shell32 version 6 50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // and does not exist in Win2K. We attempt to retrieve this function export 51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // from shell32 and if it does not exist, we just invoke ShellExecute to 52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // open the folder thus losing the functionality to select the item in 53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // the process. 54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HMODULE shell32_base = GetModuleHandle(L"shell32.dll"); 55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!shell32_base) { 5672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen NOTREACHED() << " " << __FUNCTION__ << "(): Can't open shell32.dll"; 57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch open_folder_and_select_itemsPtr = 60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch reinterpret_cast<SHOpenFolderAndSelectItemsFuncPtr> 61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch (GetProcAddress(shell32_base, "SHOpenFolderAndSelectItems")); 62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!open_folder_and_select_itemsPtr) { 6472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ShellExecute(NULL, L"open", dir.value().c_str(), NULL, NULL, SW_SHOW); 65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 68ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen base::win::ScopedComPtr<IShellFolder> desktop; 69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HRESULT hr = SHGetDesktopFolder(desktop.Receive()); 70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (FAILED(hr)) 71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 733f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen app::win::ScopedCoMem<ITEMIDLIST> dir_item; 74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch hr = desktop->ParseDisplayName(NULL, NULL, 75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const_cast<wchar_t *>(dir.value().c_str()), 76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NULL, &dir_item, NULL); 77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (FAILED(hr)) 78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 803f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen app::win::ScopedCoMem<ITEMIDLIST> file_item; 81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch hr = desktop->ParseDisplayName(NULL, NULL, 82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const_cast<wchar_t *>(full_path.value().c_str()), 83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NULL, &file_item, NULL); 84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (FAILED(hr)) 85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const ITEMIDLIST* highlight[] = { 88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch {file_item}, 89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 9072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 9172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen hr = (*open_folder_and_select_itemsPtr)(dir_item, arraysize(highlight), 9272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen highlight, NULL); 9372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 9472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (FAILED(hr)) { 9572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // On some systems, the above call mysteriously fails with "file not 9672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // found" even though the file is there. In these cases, ShellExecute() 9772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // seems to work as a fallback (although it won't select the file). 9872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (hr == ERROR_FILE_NOT_FOUND) { 9972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ShellExecute(NULL, L"open", dir.value().c_str(), NULL, NULL, SW_SHOW); 10072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } else { 10172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen LPTSTR message = NULL; 10272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen DWORD message_length = FormatMessage( 10372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, 10472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 0, hr, 0, reinterpret_cast<LPTSTR>(&message), 0, NULL); 10572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen LOG(WARNING) << " " << __FUNCTION__ 10672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen << "(): Can't open full_path = \"" 10772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen << full_path.value() << "\"" 10872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen << " hr = " << hr 10972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen << " " << reinterpret_cast<LPTSTR>(&message); 11072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (message) 11172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen LocalFree(message); 11272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 11372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid OpenItem(const FilePath& full_path) { 1173f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen app::win::OpenItemViaShell(full_path); 118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid OpenExternal(const GURL& url) { 121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Quote the input scheme to be sure that the command does not have 122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // parameters unexpected by the external program. This url should already 123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // have been escaped. 124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string escaped_url = url.spec(); 125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch escaped_url.insert(0, "\""); 126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch escaped_url += "\""; 127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // According to Mozilla in uriloader/exthandler/win/nsOSHelperAppService.cpp: 129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // "Some versions of windows (Win2k before SP3, Win XP before SP1) crash in 130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // ShellExecute on long URLs (bug 161357 on bugzilla.mozilla.org). IE 5 and 6 131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // support URLS of 2083 chars in length, 2K is safe." 132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const size_t kMaxUrlLength = 2048; 133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (escaped_url.length() > kMaxUrlLength) { 134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NOTREACHED(); 135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 138731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick base::win::RegKey key; 139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::wstring registry_path = ASCIIToWide(url.scheme()) + 140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch L"\\shell\\open\\command"; 1413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick key.Open(HKEY_CLASSES_ROOT, registry_path.c_str(), KEY_READ); 142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (key.Valid()) { 143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DWORD size = 0; 1443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick key.ReadValue(NULL, NULL, &size, NULL); 145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (size <= 2) { 146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // ShellExecute crashes the process when the command is empty. 147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We check for "2" because it always returns the trailing NULL. 148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // TODO(nsylvain): we should also add a dialog to warn on errors. See 149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // bug 1136923. 150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (reinterpret_cast<ULONG_PTR>(ShellExecuteA(NULL, "open", 155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch escaped_url.c_str(), NULL, NULL, 156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SW_SHOWNORMAL)) <= 32) { 157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We fail to execute the call. We could display a message to the user. 158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // TODO(nsylvain): we should also add a dialog to warn on errors. See 159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // bug 1136923. 160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochgfx::NativeWindow GetTopLevel(gfx::NativeView view) { 165513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return ::GetAncestor(view, GA_ROOT); 166513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 167513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 168513209b27ff55e2841eac0e4120199c23acce758Ben Murdochgfx::NativeView GetParent(gfx::NativeView view) { 169513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return ::GetParent(view); 170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool IsWindowActive(gfx::NativeWindow window) { 173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return ::GetForegroundWindow() == window; 174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ActivateWindow(gfx::NativeWindow window) { 177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ::SetForegroundWindow(window); 178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool IsVisible(gfx::NativeView view) { 181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // MSVC complains if we don't include != 0. 182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return ::IsWindowVisible(view) != 0; 183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid SimpleErrorBox(gfx::NativeWindow parent, 186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const string16& title, 187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const string16& message) { 188ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ui::MessageBox(parent, message, title, 189ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen MB_OK | MB_SETFOREGROUND | MB_ICONWARNING | MB_TOPMOST); 190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool SimpleYesNoBox(gfx::NativeWindow parent, 193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const string16& title, 194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const string16& message) { 19572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return ui::MessageBox(parent, message.c_str(), title.c_str(), 196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MB_YESNO | MB_ICONWARNING | MB_SETFOREGROUND) == IDYES; 197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickstd::string GetVersionStringModifier() { 200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(GOOGLE_CHROME_BUILD) 201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch FilePath module; 202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch string16 channel; 203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (PathService::Get(base::FILE_MODULE, &module)) { 204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool is_system_install = 205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch !InstallUtil::IsPerUserInstall(module.value().c_str()); 206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GoogleUpdateSettings::GetChromeChannel(is_system_install, &channel); 208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 2093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return UTF16ToASCII(channel); 210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#else 2113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return std::string(); 212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif 213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 215ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool CanSetAsDefaultBrowser() { 216ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return BrowserDistribution::GetDistribution()->CanSetAsDefault(); 217ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 218ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} // namespace platform_util 220