Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 // | 4 // |
| 5 // This file defines functions that integrate Chrome in Windows shell. These | 5 // This file defines functions that integrate Chrome in Windows shell. These |
| 6 // functions can be used by Chrome as well as Chrome installer. All of the | 6 // functions can be used by Chrome as well as Chrome installer. All of the |
| 7 // work is done by the local functions defined in anonymous namespace in | 7 // work is done by the local functions defined in anonymous namespace in |
| 8 // this class. | 8 // this class. |
| 9 | 9 |
| 10 #include "chrome/installer/util/shell_util.h" | 10 #include "chrome/installer/util/shell_util.h" |
| 11 | 11 |
| 12 #include <windows.h> | 12 #include <windows.h> |
| 13 #include <shlobj.h> | 13 #include <shlobj.h> |
| 14 #include <shobjidl.h> | 14 #include <shobjidl.h> |
| 15 | 15 |
| 16 #include <algorithm> | |
| 17 #include <iterator> | |
| 16 #include <limits> | 18 #include <limits> |
| 17 #include <memory> | 19 #include <memory> |
| 18 #include <string> | 20 #include <string> |
| 19 | 21 |
| 20 #include "base/bind.h" | 22 #include "base/bind.h" |
| 21 #include "base/command_line.h" | 23 #include "base/command_line.h" |
| 22 #include "base/files/file_enumerator.h" | 24 #include "base/files/file_enumerator.h" |
| 23 #include "base/files/file_path.h" | 25 #include "base/files/file_path.h" |
| 24 #include "base/files/file_util.h" | 26 #include "base/files/file_util.h" |
| 25 #include "base/lazy_instance.h" | 27 #include "base/lazy_instance.h" |
| 26 #include "base/logging.h" | 28 #include "base/logging.h" |
| 27 #include "base/macros.h" | 29 #include "base/macros.h" |
| 28 #include "base/md5.h" | 30 #include "base/md5.h" |
| 29 #include "base/memory/scoped_vector.h" | 31 #include "base/memory/ptr_util.h" |
| 30 #include "base/metrics/histogram_macros.h" | 32 #include "base/metrics/histogram_macros.h" |
| 31 #include "base/path_service.h" | 33 #include "base/path_service.h" |
| 32 #include "base/strings/string16.h" | 34 #include "base/strings/string16.h" |
| 33 #include "base/strings/string_number_conversions.h" | 35 #include "base/strings/string_number_conversions.h" |
| 34 #include "base/strings/string_piece.h" | 36 #include "base/strings/string_piece.h" |
| 35 #include "base/strings/string_split.h" | 37 #include "base/strings/string_split.h" |
| 36 #include "base/strings/string_util.h" | 38 #include "base/strings/string_util.h" |
| 37 #include "base/strings/stringprintf.h" | 39 #include "base/strings/stringprintf.h" |
| 38 #include "base/strings/utf_string_conversions.h" | 40 #include "base/strings/utf_string_conversions.h" |
| 39 #include "base/synchronization/cancellation_flag.h" | 41 #include "base/synchronization/cancellation_flag.h" |
| (...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 217 | 219 |
| 218 // Returns the Windows Default Programs capabilities key for Chrome. For | 220 // Returns the Windows Default Programs capabilities key for Chrome. For |
| 219 // example: | 221 // example: |
| 220 // "Software\Clients\StartMenuInternet\Chromium[.user]\Capabilities". | 222 // "Software\Clients\StartMenuInternet\Chromium[.user]\Capabilities". |
| 221 base::string16 GetCapabilitiesKey(const base::string16& suffix) { | 223 base::string16 GetCapabilitiesKey(const base::string16& suffix) { |
| 222 return GetBrowserClientKey(suffix).append(L"\\Capabilities"); | 224 return GetBrowserClientKey(suffix).append(L"\\Capabilities"); |
| 223 } | 225 } |
| 224 | 226 |
| 225 // DelegateExecute ProgId. Needed for Chrome Metro in Windows 8. This is only | 227 // DelegateExecute ProgId. Needed for Chrome Metro in Windows 8. This is only |
| 226 // needed for registring a web browser, not for general associations. | 228 // needed for registring a web browser, not for general associations. |
| 227 ScopedVector<RegistryEntry> GetChromeDelegateExecuteEntries( | 229 std::vector<std::unique_ptr<RegistryEntry>> GetChromeDelegateExecuteEntries( |
| 228 const base::FilePath& chrome_exe, | 230 const base::FilePath& chrome_exe, |
| 229 const ApplicationInfo& app_info) { | 231 const ApplicationInfo& app_info) { |
| 230 ScopedVector<RegistryEntry> entries; | 232 std::vector<std::unique_ptr<RegistryEntry>> entries; |
| 231 | 233 |
| 232 base::string16 app_id_shell_key(ShellUtil::kRegClasses); | 234 base::string16 app_id_shell_key(ShellUtil::kRegClasses); |
| 233 app_id_shell_key.push_back(base::FilePath::kSeparators[0]); | 235 app_id_shell_key.push_back(base::FilePath::kSeparators[0]); |
| 234 app_id_shell_key.append(app_info.app_id); | 236 app_id_shell_key.append(app_info.app_id); |
| 235 app_id_shell_key.append(ShellUtil::kRegExePath); | 237 app_id_shell_key.append(ShellUtil::kRegExePath); |
| 236 app_id_shell_key.append(ShellUtil::kRegShellPath); | 238 app_id_shell_key.append(ShellUtil::kRegShellPath); |
| 237 | 239 |
| 238 // <root hkey>\Software\Classes\<app_id>\.exe\shell @=open | 240 // <root hkey>\Software\Classes\<app_id>\.exe\shell @=open |
| 239 entries.push_back( | 241 entries.push_back(base::MakeUnique<RegistryEntry>(app_id_shell_key, |
| 240 new RegistryEntry(app_id_shell_key, ShellUtil::kRegVerbOpen)); | 242 ShellUtil::kRegVerbOpen)); |
| 241 | 243 |
| 242 // The command to execute when opening this application via the Metro UI. | 244 // The command to execute when opening this application via the Metro UI. |
| 243 const base::string16 delegate_command( | 245 const base::string16 delegate_command( |
| 244 ShellUtil::GetChromeDelegateCommand(chrome_exe)); | 246 ShellUtil::GetChromeDelegateCommand(chrome_exe)); |
| 245 | 247 |
| 246 // Each of Chrome's shortcuts has an appid; which, as of Windows 8, is | 248 // Each of Chrome's shortcuts has an appid; which, as of Windows 8, is |
| 247 // registered to handle some verbs. This registration has the side-effect | 249 // registered to handle some verbs. This registration has the side-effect |
| 248 // that these verbs now show up in the shortcut's context menu. We | 250 // that these verbs now show up in the shortcut's context menu. We |
| 249 // mitigate this side-effect by making the context menu entries | 251 // mitigate this side-effect by making the context menu entries |
| 250 // user readable/localized strings. See relevant MSDN article: | 252 // user readable/localized strings. See relevant MSDN article: |
| 251 // http://msdn.microsoft.com/en-US/library/windows/desktop/cc144171.aspx | 253 // http://msdn.microsoft.com/en-US/library/windows/desktop/cc144171.aspx |
| 252 static const struct { | 254 static const struct { |
| 253 const wchar_t* verb; | 255 const wchar_t* verb; |
| 254 int name_id; | 256 int name_id; |
| 255 } verbs[] = { | 257 } verbs[] = { |
| 256 {ShellUtil::kRegVerbOpen, -1}, | 258 {ShellUtil::kRegVerbOpen, -1}, |
| 257 {ShellUtil::kRegVerbOpenNewWindow, IDS_SHORTCUT_NEW_WINDOW_BASE}, | 259 {ShellUtil::kRegVerbOpenNewWindow, IDS_SHORTCUT_NEW_WINDOW_BASE}, |
| 258 }; | 260 }; |
| 259 for (const auto& verb_and_id : verbs) { | 261 for (const auto& verb_and_id : verbs) { |
| 260 base::string16 sub_path(app_id_shell_key); | 262 base::string16 sub_path(app_id_shell_key); |
| 261 sub_path.push_back(base::FilePath::kSeparators[0]); | 263 sub_path.push_back(base::FilePath::kSeparators[0]); |
| 262 sub_path.append(verb_and_id.verb); | 264 sub_path.append(verb_and_id.verb); |
| 263 | 265 |
| 264 // <root hkey>\Software\Classes\<app_id>\.exe\shell\<verb> | 266 // <root hkey>\Software\Classes\<app_id>\.exe\shell\<verb> |
| 265 if (verb_and_id.name_id != -1) { | 267 if (verb_and_id.name_id != -1) { |
| 266 // TODO(grt): http://crbug.com/75152 Write a reference to a localized | 268 // TODO(grt): http://crbug.com/75152 Write a reference to a localized |
| 267 // resource. | 269 // resource. |
| 268 const base::string16 verb_name( | 270 const base::string16 verb_name( |
| 269 installer::GetLocalizedString(verb_and_id.name_id)); | 271 installer::GetLocalizedString(verb_and_id.name_id)); |
| 270 entries.push_back(new RegistryEntry(sub_path, verb_name.c_str())); | 272 entries.push_back( |
| 273 base::MakeUnique<RegistryEntry>(sub_path, verb_name.c_str())); | |
| 271 } | 274 } |
| 272 entries.push_back( | 275 entries.push_back(base::MakeUnique<RegistryEntry>(sub_path, L"CommandId", |
| 273 new RegistryEntry(sub_path, L"CommandId", L"Browser.Launch")); | 276 L"Browser.Launch")); |
| 274 | 277 |
| 275 sub_path.push_back(base::FilePath::kSeparators[0]); | 278 sub_path.push_back(base::FilePath::kSeparators[0]); |
| 276 sub_path.append(ShellUtil::kRegCommand); | 279 sub_path.append(ShellUtil::kRegCommand); |
| 277 | 280 |
| 278 // <root hkey>\Software\Classes\<app_id>\.exe\shell\<verb>\command | 281 // <root hkey>\Software\Classes\<app_id>\.exe\shell\<verb>\command |
| 279 entries.push_back(new RegistryEntry(sub_path, delegate_command)); | 282 entries.push_back( |
| 280 entries.push_back(new RegistryEntry( | 283 base::MakeUnique<RegistryEntry>(sub_path, delegate_command)); |
| 284 entries.push_back(base::MakeUnique<RegistryEntry>( | |
| 281 sub_path, ShellUtil::kRegDelegateExecute, app_info.delegate_clsid)); | 285 sub_path, ShellUtil::kRegDelegateExecute, app_info.delegate_clsid)); |
| 282 } | 286 } |
| 283 | 287 |
| 284 return entries; | 288 return entries; |
| 285 } | 289 } |
| 286 | 290 |
| 287 // Gets the registry entries to register an application in the Windows registry. | 291 // Gets the registry entries to register an application in the Windows registry. |
| 288 // |app_info| provides all of the information needed. | 292 // |app_info| provides all of the information needed. |
| 289 void GetProgIdEntries(const ApplicationInfo& app_info, | 293 void GetProgIdEntries(const ApplicationInfo& app_info, |
| 290 ScopedVector<RegistryEntry>* entries) { | 294 std::vector<std::unique_ptr<RegistryEntry>>* entries) { |
| 291 // Basic sanity checks. | 295 // Basic sanity checks. |
| 292 DCHECK(!app_info.prog_id.empty()); | 296 DCHECK(!app_info.prog_id.empty()); |
| 293 DCHECK_NE(L'.', app_info.prog_id[0]); | 297 DCHECK_NE(L'.', app_info.prog_id[0]); |
| 294 | 298 |
| 295 // File association ProgId | 299 // File association ProgId |
| 296 base::string16 prog_id_path(ShellUtil::kRegClasses); | 300 base::string16 prog_id_path(ShellUtil::kRegClasses); |
| 297 prog_id_path.push_back(base::FilePath::kSeparators[0]); | 301 prog_id_path.push_back(base::FilePath::kSeparators[0]); |
| 298 prog_id_path.append(app_info.prog_id); | 302 prog_id_path.append(app_info.prog_id); |
| 299 entries->push_back(new RegistryEntry(prog_id_path, app_info.file_type_name)); | 303 entries->push_back( |
| 300 entries->push_back(new RegistryEntry( | 304 base::MakeUnique<RegistryEntry>(prog_id_path, app_info.file_type_name)); |
| 305 entries->push_back(base::MakeUnique<RegistryEntry>( | |
| 301 prog_id_path + ShellUtil::kRegDefaultIcon, | 306 prog_id_path + ShellUtil::kRegDefaultIcon, |
| 302 ShellUtil::FormatIconLocation(app_info.file_type_icon_path, | 307 ShellUtil::FormatIconLocation(app_info.file_type_icon_path, |
| 303 app_info.file_type_icon_index))); | 308 app_info.file_type_icon_index))); |
| 304 entries->push_back(new RegistryEntry(prog_id_path + ShellUtil::kRegShellOpen, | 309 entries->push_back(base::MakeUnique<RegistryEntry>( |
| 305 app_info.command_line)); | 310 prog_id_path + ShellUtil::kRegShellOpen, app_info.command_line)); |
| 306 if (!app_info.delegate_clsid.empty()) { | 311 if (!app_info.delegate_clsid.empty()) { |
| 307 entries->push_back(new RegistryEntry( | 312 entries->push_back(base::MakeUnique<RegistryEntry>( |
| 308 prog_id_path + ShellUtil::kRegShellOpen, ShellUtil::kRegDelegateExecute, | 313 prog_id_path + ShellUtil::kRegShellOpen, ShellUtil::kRegDelegateExecute, |
| 309 app_info.delegate_clsid)); | 314 app_info.delegate_clsid)); |
| 310 // TODO(scottmg): Simplify after Metro removal. https://crbug.com/558054. | 315 // TODO(scottmg): Simplify after Metro removal. https://crbug.com/558054. |
| 311 entries->back()->set_removal_flag(RegistryEntry::RemovalFlag::VALUE); | 316 entries->back()->set_removal_flag(RegistryEntry::RemovalFlag::VALUE); |
| 312 } | 317 } |
| 313 | 318 |
| 314 // The following entries are required as of Windows 8, but do not | 319 // The following entries are required as of Windows 8, but do not |
| 315 // depend on the DelegateExecute verb handler being set. | 320 // depend on the DelegateExecute verb handler being set. |
| 316 if (base::win::GetVersion() >= base::win::VERSION_WIN8) { | 321 if (base::win::GetVersion() >= base::win::VERSION_WIN8) { |
| 317 if (!app_info.app_id.empty()) { | 322 if (!app_info.app_id.empty()) { |
| 318 entries->push_back(new RegistryEntry( | 323 entries->push_back(base::MakeUnique<RegistryEntry>( |
| 319 prog_id_path, ShellUtil::kRegAppUserModelId, app_info.app_id)); | 324 prog_id_path, ShellUtil::kRegAppUserModelId, app_info.app_id)); |
| 320 } | 325 } |
| 321 | 326 |
| 322 // Add \Software\Classes\<prog_id>\Application entries | 327 // Add \Software\Classes\<prog_id>\Application entries |
| 323 base::string16 application_path(prog_id_path + ShellUtil::kRegApplication); | 328 base::string16 application_path(prog_id_path + ShellUtil::kRegApplication); |
| 324 if (!app_info.app_id.empty()) { | 329 if (!app_info.app_id.empty()) { |
| 325 entries->push_back(new RegistryEntry( | 330 entries->push_back(base::MakeUnique<RegistryEntry>( |
| 326 application_path, ShellUtil::kRegAppUserModelId, app_info.app_id)); | 331 application_path, ShellUtil::kRegAppUserModelId, app_info.app_id)); |
| 327 } | 332 } |
| 328 if (!app_info.application_icon_path.empty()) { | 333 if (!app_info.application_icon_path.empty()) { |
| 329 entries->push_back(new RegistryEntry( | 334 entries->push_back(base::MakeUnique<RegistryEntry>( |
| 330 application_path, ShellUtil::kRegApplicationIcon, | 335 application_path, ShellUtil::kRegApplicationIcon, |
| 331 ShellUtil::FormatIconLocation(app_info.application_icon_path, | 336 ShellUtil::FormatIconLocation(app_info.application_icon_path, |
| 332 app_info.application_icon_index))); | 337 app_info.application_icon_index))); |
| 333 } | 338 } |
| 334 if (!app_info.application_name.empty()) { | 339 if (!app_info.application_name.empty()) { |
| 335 entries->push_back(new RegistryEntry(application_path, | 340 entries->push_back(base::MakeUnique<RegistryEntry>( |
| 336 ShellUtil::kRegApplicationName, | 341 application_path, ShellUtil::kRegApplicationName, |
| 337 app_info.application_name)); | 342 app_info.application_name)); |
| 338 } | 343 } |
| 339 if (!app_info.application_description.empty()) { | 344 if (!app_info.application_description.empty()) { |
| 340 entries->push_back(new RegistryEntry( | 345 entries->push_back(base::MakeUnique<RegistryEntry>( |
| 341 application_path, ShellUtil::kRegApplicationDescription, | 346 application_path, ShellUtil::kRegApplicationDescription, |
| 342 app_info.application_description)); | 347 app_info.application_description)); |
| 343 } | 348 } |
| 344 if (!app_info.publisher_name.empty()) { | 349 if (!app_info.publisher_name.empty()) { |
| 345 entries->push_back(new RegistryEntry(application_path, | 350 entries->push_back(base::MakeUnique<RegistryEntry>( |
| 346 ShellUtil::kRegApplicationCompany, | 351 application_path, ShellUtil::kRegApplicationCompany, |
| 347 app_info.publisher_name)); | 352 app_info.publisher_name)); |
| 348 } | 353 } |
| 349 } | 354 } |
| 350 } | 355 } |
| 351 | 356 |
| 352 // This method returns a list of all the registry entries that are needed to | 357 // This method returns a list of all the registry entries that are needed to |
| 353 // register this installation's ProgId and AppId. These entries need to be | 358 // register this installation's ProgId and AppId. These entries need to be |
| 354 // registered in HKLM prior to Win8. | 359 // registered in HKLM prior to Win8. |
| 355 void GetChromeProgIdEntries(BrowserDistribution* dist, | 360 void GetChromeProgIdEntries( |
| 356 const base::FilePath& chrome_exe, | 361 BrowserDistribution* dist, |
| 357 const base::string16& suffix, | 362 const base::FilePath& chrome_exe, |
| 358 ScopedVector<RegistryEntry>* entries) { | 363 const base::string16& suffix, |
| 364 std::vector<std::unique_ptr<RegistryEntry>>* entries) { | |
| 359 int chrome_icon_index = install_static::GetIconResourceIndex(); | 365 int chrome_icon_index = install_static::GetIconResourceIndex(); |
| 360 | 366 |
| 361 ApplicationInfo app_info; | 367 ApplicationInfo app_info; |
| 362 app_info.prog_id = GetBrowserProgId(suffix); | 368 app_info.prog_id = GetBrowserProgId(suffix); |
| 363 app_info.file_type_name = install_static::GetProgIdDescription(); | 369 app_info.file_type_name = install_static::GetProgIdDescription(); |
| 364 // File types associated with Chrome are just given the Chrome icon. | 370 // File types associated with Chrome are just given the Chrome icon. |
| 365 app_info.file_type_icon_path = chrome_exe; | 371 app_info.file_type_icon_path = chrome_exe; |
| 366 app_info.file_type_icon_index = chrome_icon_index; | 372 app_info.file_type_icon_index = chrome_icon_index; |
| 367 app_info.command_line = ShellUtil::GetChromeShellOpenCmd(chrome_exe); | 373 app_info.command_line = ShellUtil::GetChromeShellOpenCmd(chrome_exe); |
| 368 // For user-level installs: entries for the app id will be in HKCU; thus we | 374 // For user-level installs: entries for the app id will be in HKCU; thus we |
| 369 // do not need a suffix on those entries. | 375 // do not need a suffix on those entries. |
| 370 app_info.app_id = | 376 app_info.app_id = |
| 371 ShellUtil::GetBrowserModelId(InstallUtil::IsPerUserInstall()); | 377 ShellUtil::GetBrowserModelId(InstallUtil::IsPerUserInstall()); |
| 372 | 378 |
| 373 // TODO(grt): http://crbug.com/75152 Write a reference to a localized | 379 // TODO(grt): http://crbug.com/75152 Write a reference to a localized |
| 374 // resource for name, description, and company. | 380 // resource for name, description, and company. |
| 375 app_info.application_name = dist->GetDisplayName(); | 381 app_info.application_name = dist->GetDisplayName(); |
| 376 app_info.application_icon_path = chrome_exe; | 382 app_info.application_icon_path = chrome_exe; |
| 377 app_info.application_icon_index = chrome_icon_index; | 383 app_info.application_icon_index = chrome_icon_index; |
| 378 app_info.application_description = dist->GetAppDescription(); | 384 app_info.application_description = dist->GetAppDescription(); |
| 379 app_info.publisher_name = dist->GetPublisherName(); | 385 app_info.publisher_name = dist->GetPublisherName(); |
| 380 app_info.delegate_clsid = install_static::GetLegacyCommandExecuteImplClsid(); | 386 app_info.delegate_clsid = install_static::GetLegacyCommandExecuteImplClsid(); |
| 381 | 387 |
| 382 GetProgIdEntries(app_info, entries); | 388 GetProgIdEntries(app_info, entries); |
| 383 | 389 |
| 384 if (!app_info.delegate_clsid.empty()) { | 390 if (!app_info.delegate_clsid.empty()) { |
| 385 ScopedVector<RegistryEntry> delegate_execute_entries = | 391 auto delegate_execute_entries = |
| 386 GetChromeDelegateExecuteEntries(chrome_exe, app_info); | 392 GetChromeDelegateExecuteEntries(chrome_exe, app_info); |
| 387 // Remove the keys (not only their values) so that Windows will continue | 393 // Remove the keys (not only their values) so that Windows will continue |
| 388 // to launch Chrome without a pesky association error. | 394 // to launch Chrome without a pesky association error. |
| 389 // TODO(scottmg): Simplify after Metro removal. https://crbug.com/558054. | 395 // TODO(scottmg): Simplify after Metro removal. https://crbug.com/558054. |
| 390 for (RegistryEntry* entry : delegate_execute_entries) | 396 for (const auto& entry : delegate_execute_entries) |
| 391 entry->set_removal_flag(RegistryEntry::RemovalFlag::KEY); | 397 entry->set_removal_flag(RegistryEntry::RemovalFlag::KEY); |
| 392 // Move |delegate_execute_entries| to |entries|. | 398 // Move |delegate_execute_entries| to |entries|. |
| 393 entries->insert(entries->end(), delegate_execute_entries.begin(), | 399 std::move(delegate_execute_entries.begin(), delegate_execute_entries.end(), |
|
gab
2017/04/06 15:00:54
#include <utility>
leonhsl(Using Gerrit)
2017/04/07 01:45:48
Done.
| |
| 394 delegate_execute_entries.end()); | 400 std::back_inserter(*entries)); |
| 395 delegate_execute_entries.weak_clear(); | |
| 396 } | 401 } |
| 397 } | 402 } |
| 398 | 403 |
| 399 // This method returns a list of the registry entries needed to declare a | 404 // This method returns a list of the registry entries needed to declare a |
| 400 // capability of handling a protocol on Windows. | 405 // capability of handling a protocol on Windows. |
| 401 void GetProtocolCapabilityEntries(const base::string16& suffix, | 406 void GetProtocolCapabilityEntries( |
| 402 const base::string16& protocol, | 407 const base::string16& suffix, |
| 403 ScopedVector<RegistryEntry>* entries) { | 408 const base::string16& protocol, |
| 404 entries->push_back( | 409 std::vector<std::unique_ptr<RegistryEntry>>* entries) { |
| 405 new RegistryEntry(GetCapabilitiesKey(suffix).append(L"\\URLAssociations"), | 410 entries->push_back(base::MakeUnique<RegistryEntry>( |
| 406 protocol, GetBrowserProgId(suffix))); | 411 GetCapabilitiesKey(suffix).append(L"\\URLAssociations"), protocol, |
| 412 GetBrowserProgId(suffix))); | |
| 407 } | 413 } |
| 408 | 414 |
| 409 // This method returns a list of the registry entries required to register this | 415 // This method returns a list of the registry entries required to register this |
| 410 // installation in "RegisteredApplications" on Windows (to appear in Default | 416 // installation in "RegisteredApplications" on Windows (to appear in Default |
| 411 // Programs, StartMenuInternet, etc.). These entries need to be registered in | 417 // Programs, StartMenuInternet, etc.). These entries need to be registered in |
| 412 // HKLM prior to Win8. If |suffix| is not empty, these entries are guaranteed to | 418 // HKLM prior to Win8. If |suffix| is not empty, these entries are guaranteed to |
| 413 // be unique on this machine. | 419 // be unique on this machine. |
| 414 void GetShellIntegrationEntries(BrowserDistribution* dist, | 420 void GetShellIntegrationEntries( |
| 415 const base::FilePath& chrome_exe, | 421 BrowserDistribution* dist, |
| 416 const base::string16& suffix, | 422 const base::FilePath& chrome_exe, |
| 417 ScopedVector<RegistryEntry>* entries) { | 423 const base::string16& suffix, |
| 424 std::vector<std::unique_ptr<RegistryEntry>>* entries) { | |
| 418 const base::string16 icon_path(ShellUtil::FormatIconLocation( | 425 const base::string16 icon_path(ShellUtil::FormatIconLocation( |
| 419 chrome_exe, install_static::GetIconResourceIndex())); | 426 chrome_exe, install_static::GetIconResourceIndex())); |
| 420 const base::string16 quoted_exe_path(L"\"" + chrome_exe.value() + L"\""); | 427 const base::string16 quoted_exe_path(L"\"" + chrome_exe.value() + L"\""); |
| 421 | 428 |
| 422 // Register for the Start Menu "Internet" link (pre-Win7). | 429 // Register for the Start Menu "Internet" link (pre-Win7). |
| 423 const base::string16 start_menu_entry(GetBrowserClientKey(suffix)); | 430 const base::string16 start_menu_entry(GetBrowserClientKey(suffix)); |
| 424 // Register Chrome's display name. | 431 // Register Chrome's display name. |
| 425 // TODO(grt): http://crbug.com/75152 Also set LocalizedString; see | 432 // TODO(grt): http://crbug.com/75152 Also set LocalizedString; see |
| 426 // http://msdn.microsoft.com/en-us/library/windows/desktop/cc144109(v=VS.85).a spx#registering_the_display_name | 433 // http://msdn.microsoft.com/en-us/library/windows/desktop/cc144109(v=VS.85).a spx#registering_the_display_name |
| 427 entries->push_back( | 434 entries->push_back(base::MakeUnique<RegistryEntry>(start_menu_entry, |
| 428 new RegistryEntry(start_menu_entry, dist->GetDisplayName())); | 435 dist->GetDisplayName())); |
| 429 // Register the "open" verb for launching Chrome via the "Internet" link. | 436 // Register the "open" verb for launching Chrome via the "Internet" link. |
| 430 entries->push_back(new RegistryEntry( | 437 entries->push_back(base::MakeUnique<RegistryEntry>( |
| 431 start_menu_entry + ShellUtil::kRegShellOpen, quoted_exe_path)); | 438 start_menu_entry + ShellUtil::kRegShellOpen, quoted_exe_path)); |
| 432 // Register Chrome's icon for the Start Menu "Internet" link. | 439 // Register Chrome's icon for the Start Menu "Internet" link. |
| 433 entries->push_back(new RegistryEntry( | 440 entries->push_back(base::MakeUnique<RegistryEntry>( |
| 434 start_menu_entry + ShellUtil::kRegDefaultIcon, icon_path)); | 441 start_menu_entry + ShellUtil::kRegDefaultIcon, icon_path)); |
| 435 | 442 |
| 436 // Register installation information. | 443 // Register installation information. |
| 437 base::string16 install_info(start_menu_entry + L"\\InstallInfo"); | 444 base::string16 install_info(start_menu_entry + L"\\InstallInfo"); |
| 438 // Note: not using CommandLine since it has ambiguous rules for quoting | 445 // Note: not using CommandLine since it has ambiguous rules for quoting |
| 439 // strings. | 446 // strings. |
| 440 entries->push_back( | 447 entries->push_back(base::MakeUnique<RegistryEntry>( |
| 441 new RegistryEntry(install_info, kReinstallCommand, | 448 install_info, kReinstallCommand, |
| 442 quoted_exe_path + L" --" + | 449 quoted_exe_path + L" --" + |
| 443 base::ASCIIToUTF16(switches::kMakeDefaultBrowser))); | 450 base::ASCIIToUTF16(switches::kMakeDefaultBrowser))); |
| 444 entries->push_back(new RegistryEntry( | 451 entries->push_back(base::MakeUnique<RegistryEntry>( |
| 445 install_info, L"HideIconsCommand", | 452 install_info, L"HideIconsCommand", |
| 446 quoted_exe_path + L" --" + base::ASCIIToUTF16(switches::kHideIcons))); | 453 quoted_exe_path + L" --" + base::ASCIIToUTF16(switches::kHideIcons))); |
| 447 entries->push_back(new RegistryEntry( | 454 entries->push_back(base::MakeUnique<RegistryEntry>( |
| 448 install_info, L"ShowIconsCommand", | 455 install_info, L"ShowIconsCommand", |
| 449 quoted_exe_path + L" --" + base::ASCIIToUTF16(switches::kShowIcons))); | 456 quoted_exe_path + L" --" + base::ASCIIToUTF16(switches::kShowIcons))); |
| 450 entries->push_back(new RegistryEntry(install_info, L"IconsVisible", 1)); | 457 entries->push_back( |
| 458 base::MakeUnique<RegistryEntry>(install_info, L"IconsVisible", 1)); | |
| 451 | 459 |
| 452 // Register with Default Programs. | 460 // Register with Default Programs. |
| 453 const base::string16 reg_app_name( | 461 const base::string16 reg_app_name( |
| 454 install_static::GetBaseAppName().append(suffix)); | 462 install_static::GetBaseAppName().append(suffix)); |
| 455 // Tell Windows where to find Chrome's Default Programs info. | 463 // Tell Windows where to find Chrome's Default Programs info. |
| 456 const base::string16 capabilities(GetCapabilitiesKey(suffix)); | 464 const base::string16 capabilities(GetCapabilitiesKey(suffix)); |
| 457 entries->push_back(new RegistryEntry(ShellUtil::kRegRegisteredApplications, | 465 entries->push_back(base::MakeUnique<RegistryEntry>( |
| 458 reg_app_name, capabilities)); | 466 ShellUtil::kRegRegisteredApplications, reg_app_name, capabilities)); |
| 459 // Write out Chrome's Default Programs info. | 467 // Write out Chrome's Default Programs info. |
| 460 // TODO(grt): http://crbug.com/75152 Write a reference to a localized | 468 // TODO(grt): http://crbug.com/75152 Write a reference to a localized |
| 461 // resource rather than this. | 469 // resource rather than this. |
| 462 entries->push_back(new RegistryEntry(capabilities, | 470 entries->push_back(base::MakeUnique<RegistryEntry>( |
| 463 ShellUtil::kRegApplicationDescription, | 471 capabilities, ShellUtil::kRegApplicationDescription, |
| 464 dist->GetLongAppDescription())); | 472 dist->GetLongAppDescription())); |
| 465 entries->push_back(new RegistryEntry( | 473 entries->push_back(base::MakeUnique<RegistryEntry>( |
| 466 capabilities, ShellUtil::kRegApplicationIcon, icon_path)); | 474 capabilities, ShellUtil::kRegApplicationIcon, icon_path)); |
| 467 entries->push_back(new RegistryEntry( | 475 entries->push_back(base::MakeUnique<RegistryEntry>( |
| 468 capabilities, ShellUtil::kRegApplicationName, dist->GetDisplayName())); | 476 capabilities, ShellUtil::kRegApplicationName, dist->GetDisplayName())); |
| 469 | 477 |
| 470 entries->push_back(new RegistryEntry(capabilities + L"\\Startmenu", | 478 entries->push_back(base::MakeUnique<RegistryEntry>( |
| 471 L"StartMenuInternet", reg_app_name)); | 479 capabilities + L"\\Startmenu", L"StartMenuInternet", reg_app_name)); |
| 472 | 480 |
| 473 const base::string16 html_prog_id(GetBrowserProgId(suffix)); | 481 const base::string16 html_prog_id(GetBrowserProgId(suffix)); |
| 474 for (int i = 0; ShellUtil::kPotentialFileAssociations[i] != NULL; i++) { | 482 for (int i = 0; ShellUtil::kPotentialFileAssociations[i] != NULL; i++) { |
| 475 entries->push_back(new RegistryEntry( | 483 entries->push_back(base::MakeUnique<RegistryEntry>( |
| 476 capabilities + L"\\FileAssociations", | 484 capabilities + L"\\FileAssociations", |
| 477 ShellUtil::kPotentialFileAssociations[i], html_prog_id)); | 485 ShellUtil::kPotentialFileAssociations[i], html_prog_id)); |
| 478 } | 486 } |
| 479 for (int i = 0; ShellUtil::kPotentialProtocolAssociations[i] != NULL; i++) { | 487 for (int i = 0; ShellUtil::kPotentialProtocolAssociations[i] != NULL; i++) { |
| 480 entries->push_back(new RegistryEntry( | 488 entries->push_back(base::MakeUnique<RegistryEntry>( |
| 481 capabilities + L"\\URLAssociations", | 489 capabilities + L"\\URLAssociations", |
| 482 ShellUtil::kPotentialProtocolAssociations[i], html_prog_id)); | 490 ShellUtil::kPotentialProtocolAssociations[i], html_prog_id)); |
| 483 } | 491 } |
| 484 } | 492 } |
| 485 | 493 |
| 486 // Gets the registry entries to register an application as a handler for a | 494 // Gets the registry entries to register an application as a handler for a |
| 487 // particular file extension. |prog_id| is the ProgId used by Windows for the | 495 // particular file extension. |prog_id| is the ProgId used by Windows for the |
| 488 // application. |ext| is the file extension, which must begin with a '.'. | 496 // application. |ext| is the file extension, which must begin with a '.'. |
| 489 void GetAppExtRegistrationEntries(const base::string16& prog_id, | 497 void GetAppExtRegistrationEntries( |
| 490 const base::string16& ext, | 498 const base::string16& prog_id, |
| 491 ScopedVector<RegistryEntry>* entries) { | 499 const base::string16& ext, |
| 500 std::vector<std::unique_ptr<RegistryEntry>>* entries) { | |
| 492 // In HKEY_CURRENT_USER\Software\Classes\EXT\OpenWithProgids, create an | 501 // In HKEY_CURRENT_USER\Software\Classes\EXT\OpenWithProgids, create an |
| 493 // empty value with this class's ProgId. | 502 // empty value with this class's ProgId. |
| 494 base::string16 key_name(ShellUtil::kRegClasses); | 503 base::string16 key_name(ShellUtil::kRegClasses); |
| 495 key_name.push_back(base::FilePath::kSeparators[0]); | 504 key_name.push_back(base::FilePath::kSeparators[0]); |
| 496 key_name.append(ext); | 505 key_name.append(ext); |
| 497 key_name.push_back(base::FilePath::kSeparators[0]); | 506 key_name.push_back(base::FilePath::kSeparators[0]); |
| 498 key_name.append(ShellUtil::kRegOpenWithProgids); | 507 key_name.append(ShellUtil::kRegOpenWithProgids); |
| 499 entries->push_back(new RegistryEntry(key_name, prog_id, base::string16())); | 508 entries->push_back( |
| 509 base::MakeUnique<RegistryEntry>(key_name, prog_id, base::string16())); | |
| 500 } | 510 } |
| 501 | 511 |
| 502 // This method returns a list of the registry entries required for this | 512 // This method returns a list of the registry entries required for this |
| 503 // installation to be registered in the Windows shell. | 513 // installation to be registered in the Windows shell. |
| 504 // In particular: | 514 // In particular: |
| 505 // - App Paths | 515 // - App Paths |
| 506 // http://msdn.microsoft.com/en-us/library/windows/desktop/ee872121 | 516 // http://msdn.microsoft.com/en-us/library/windows/desktop/ee872121 |
| 507 // - File Associations | 517 // - File Associations |
| 508 // http://msdn.microsoft.com/en-us/library/bb166549 | 518 // http://msdn.microsoft.com/en-us/library/bb166549 |
| 509 // These entries need to be registered in HKLM prior to Win8. | 519 // These entries need to be registered in HKLM prior to Win8. |
| 510 void GetChromeAppRegistrationEntries(const base::FilePath& chrome_exe, | 520 void GetChromeAppRegistrationEntries( |
| 511 const base::string16& suffix, | 521 const base::FilePath& chrome_exe, |
| 512 ScopedVector<RegistryEntry>* entries) { | 522 const base::string16& suffix, |
| 523 std::vector<std::unique_ptr<RegistryEntry>>* entries) { | |
| 513 base::string16 app_path_key(ShellUtil::kAppPathsRegistryKey); | 524 base::string16 app_path_key(ShellUtil::kAppPathsRegistryKey); |
| 514 app_path_key.push_back(base::FilePath::kSeparators[0]); | 525 app_path_key.push_back(base::FilePath::kSeparators[0]); |
| 515 app_path_key.append(chrome_exe.BaseName().value()); | 526 app_path_key.append(chrome_exe.BaseName().value()); |
| 516 entries->push_back(new RegistryEntry(app_path_key, chrome_exe.value())); | 527 entries->push_back( |
| 517 entries->push_back(new RegistryEntry(app_path_key, | 528 base::MakeUnique<RegistryEntry>(app_path_key, chrome_exe.value())); |
| 518 ShellUtil::kAppPathsRegistryPathName, | 529 entries->push_back(base::MakeUnique<RegistryEntry>( |
| 519 chrome_exe.DirName().value())); | 530 app_path_key, ShellUtil::kAppPathsRegistryPathName, |
| 531 chrome_exe.DirName().value())); | |
| 520 | 532 |
| 521 const base::string16 html_prog_id(GetBrowserProgId(suffix)); | 533 const base::string16 html_prog_id(GetBrowserProgId(suffix)); |
| 522 for (int i = 0; ShellUtil::kPotentialFileAssociations[i] != NULL; i++) { | 534 for (int i = 0; ShellUtil::kPotentialFileAssociations[i] != NULL; i++) { |
| 523 GetAppExtRegistrationEntries( | 535 GetAppExtRegistrationEntries( |
| 524 html_prog_id, ShellUtil::kPotentialFileAssociations[i], entries); | 536 html_prog_id, ShellUtil::kPotentialFileAssociations[i], entries); |
| 525 } | 537 } |
| 526 } | 538 } |
| 527 | 539 |
| 528 // Gets the registry entries to register an application as the default handler | 540 // Gets the registry entries to register an application as the default handler |
| 529 // for a particular file extension. |prog_id| is the ProgId used by Windows for | 541 // for a particular file extension. |prog_id| is the ProgId used by Windows for |
| 530 // the application. |ext| is the file extension, which must begin with a '.'. If | 542 // the application. |ext| is the file extension, which must begin with a '.'. If |
| 531 // |overwrite_existing|, always sets the default handler; otherwise only sets if | 543 // |overwrite_existing|, always sets the default handler; otherwise only sets if |
| 532 // there is no existing default. | 544 // there is no existing default. |
| 533 // | 545 // |
| 534 // This has no effect on Windows 8. Windows 8 ignores the default and lets the | 546 // This has no effect on Windows 8. Windows 8 ignores the default and lets the |
| 535 // user choose. If there is only one handler for a file, it will automatically | 547 // user choose. If there is only one handler for a file, it will automatically |
| 536 // become the default. Otherwise, the first time the user opens a file, they are | 548 // become the default. Otherwise, the first time the user opens a file, they are |
| 537 // presented with the dialog to set the default handler. (This is roughly | 549 // presented with the dialog to set the default handler. (This is roughly |
| 538 // equivalent to being called with |overwrite_existing| false.) | 550 // equivalent to being called with |overwrite_existing| false.) |
| 539 void GetAppDefaultRegistrationEntries(const base::string16& prog_id, | 551 void GetAppDefaultRegistrationEntries( |
| 540 const base::string16& ext, | 552 const base::string16& prog_id, |
| 541 bool overwrite_existing, | 553 const base::string16& ext, |
| 542 ScopedVector<RegistryEntry>* entries) { | 554 bool overwrite_existing, |
| 555 std::vector<std::unique_ptr<RegistryEntry>>* entries) { | |
| 543 // Set the default value of HKEY_CURRENT_USER\Software\Classes\EXT to this | 556 // Set the default value of HKEY_CURRENT_USER\Software\Classes\EXT to this |
| 544 // class's name. | 557 // class's name. |
| 545 base::string16 key_name(ShellUtil::kRegClasses); | 558 base::string16 key_name(ShellUtil::kRegClasses); |
| 546 key_name.push_back(base::FilePath::kSeparators[0]); | 559 key_name.push_back(base::FilePath::kSeparators[0]); |
| 547 key_name.append(ext); | 560 key_name.append(ext); |
| 548 std::unique_ptr<RegistryEntry> default_association( | 561 auto default_association = base::MakeUnique<RegistryEntry>(key_name, prog_id); |
| 549 new RegistryEntry(key_name, prog_id)); | |
| 550 if (overwrite_existing || | 562 if (overwrite_existing || |
| 551 !default_association->KeyExistsInRegistry(RegistryEntry::LOOK_IN_HKCU)) { | 563 !default_association->KeyExistsInRegistry(RegistryEntry::LOOK_IN_HKCU)) { |
| 552 entries->push_back(default_association.release()); | 564 entries->push_back(std::move(default_association)); |
| 553 } | 565 } |
| 554 } | 566 } |
| 555 | 567 |
| 556 // This method returns a list of all the user level registry entries that are | 568 // This method returns a list of all the user level registry entries that are |
| 557 // needed to make Chromium the default handler for a protocol on XP. | 569 // needed to make Chromium the default handler for a protocol on XP. |
| 558 void GetXPStyleUserProtocolEntries(const base::string16& protocol, | 570 void GetXPStyleUserProtocolEntries( |
| 559 const base::string16& chrome_icon, | 571 const base::string16& protocol, |
| 560 const base::string16& chrome_open, | 572 const base::string16& chrome_icon, |
| 561 ScopedVector<RegistryEntry>* entries) { | 573 const base::string16& chrome_open, |
| 574 std::vector<std::unique_ptr<RegistryEntry>>* entries) { | |
| 562 // Protocols associations. | 575 // Protocols associations. |
| 563 base::string16 url_key(ShellUtil::kRegClasses); | 576 base::string16 url_key(ShellUtil::kRegClasses); |
| 564 url_key.push_back(base::FilePath::kSeparators[0]); | 577 url_key.push_back(base::FilePath::kSeparators[0]); |
| 565 url_key.append(protocol); | 578 url_key.append(protocol); |
| 566 | 579 |
| 567 // This registry value tells Windows that this 'class' is a URL scheme | 580 // This registry value tells Windows that this 'class' is a URL scheme |
| 568 // so IE, explorer and other apps will route it to our handler. | 581 // so IE, explorer and other apps will route it to our handler. |
| 569 // <root hkey>\Software\Classes\<protocol>\URL Protocol | 582 // <root hkey>\Software\Classes\<protocol>\URL Protocol |
| 570 entries->push_back( | 583 entries->push_back(base::MakeUnique<RegistryEntry>( |
| 571 new RegistryEntry(url_key, ShellUtil::kRegUrlProtocol, base::string16())); | 584 url_key, ShellUtil::kRegUrlProtocol, base::string16())); |
| 572 | 585 |
| 573 // <root hkey>\Software\Classes\<protocol>\DefaultIcon | 586 // <root hkey>\Software\Classes\<protocol>\DefaultIcon |
| 574 base::string16 icon_key = url_key + ShellUtil::kRegDefaultIcon; | 587 base::string16 icon_key = url_key + ShellUtil::kRegDefaultIcon; |
| 575 entries->push_back(new RegistryEntry(icon_key, chrome_icon)); | 588 entries->push_back(base::MakeUnique<RegistryEntry>(icon_key, chrome_icon)); |
| 576 | 589 |
| 577 // <root hkey>\Software\Classes\<protocol>\shell\open\command | 590 // <root hkey>\Software\Classes\<protocol>\shell\open\command |
| 578 base::string16 shell_key = url_key + ShellUtil::kRegShellOpen; | 591 base::string16 shell_key = url_key + ShellUtil::kRegShellOpen; |
| 579 entries->push_back(new RegistryEntry(shell_key, chrome_open)); | 592 entries->push_back(base::MakeUnique<RegistryEntry>(shell_key, chrome_open)); |
| 580 | 593 |
| 581 // <root hkey>\Software\Classes\<protocol>\shell\open\ddeexec | 594 // <root hkey>\Software\Classes\<protocol>\shell\open\ddeexec |
| 582 base::string16 dde_key = url_key + L"\\shell\\open\\ddeexec"; | 595 base::string16 dde_key = url_key + L"\\shell\\open\\ddeexec"; |
| 583 entries->push_back(new RegistryEntry(dde_key, base::string16())); | 596 entries->push_back( |
| 597 base::MakeUnique<RegistryEntry>(dde_key, base::string16())); | |
| 584 | 598 |
| 585 // <root hkey>\Software\Classes\<protocol>\shell\@ | 599 // <root hkey>\Software\Classes\<protocol>\shell\@ |
| 586 base::string16 protocol_shell_key = url_key + ShellUtil::kRegShellPath; | 600 base::string16 protocol_shell_key = url_key + ShellUtil::kRegShellPath; |
| 587 entries->push_back(new RegistryEntry(protocol_shell_key, L"open")); | 601 entries->push_back( |
| 602 base::MakeUnique<RegistryEntry>(protocol_shell_key, L"open")); | |
| 588 } | 603 } |
| 589 | 604 |
| 590 // This method returns a list of all the user level registry entries that are | 605 // This method returns a list of all the user level registry entries that are |
| 591 // needed to make Chromium default browser on XP. Some of these entries are | 606 // needed to make Chromium default browser on XP. Some of these entries are |
| 592 // irrelevant in recent versions of Windows, but we register them anyways as | 607 // irrelevant in recent versions of Windows, but we register them anyways as |
| 593 // some legacy apps are hardcoded to lookup those values. | 608 // some legacy apps are hardcoded to lookup those values. |
| 594 void GetXPStyleDefaultBrowserUserEntries(const base::FilePath& chrome_exe, | 609 void GetXPStyleDefaultBrowserUserEntries( |
| 595 const base::string16& suffix, | 610 const base::FilePath& chrome_exe, |
| 596 ScopedVector<RegistryEntry>* entries) { | 611 const base::string16& suffix, |
| 612 std::vector<std::unique_ptr<RegistryEntry>>* entries) { | |
| 597 // File extension associations. | 613 // File extension associations. |
| 598 base::string16 html_prog_id(GetBrowserProgId(suffix)); | 614 base::string16 html_prog_id(GetBrowserProgId(suffix)); |
| 599 for (int i = 0; ShellUtil::kDefaultFileAssociations[i] != NULL; i++) { | 615 for (int i = 0; ShellUtil::kDefaultFileAssociations[i] != NULL; i++) { |
| 600 GetAppDefaultRegistrationEntries( | 616 GetAppDefaultRegistrationEntries( |
| 601 html_prog_id, ShellUtil::kDefaultFileAssociations[i], true, entries); | 617 html_prog_id, ShellUtil::kDefaultFileAssociations[i], true, entries); |
| 602 } | 618 } |
| 603 | 619 |
| 604 // Protocols associations. | 620 // Protocols associations. |
| 605 base::string16 chrome_open = ShellUtil::GetChromeShellOpenCmd(chrome_exe); | 621 base::string16 chrome_open = ShellUtil::GetChromeShellOpenCmd(chrome_exe); |
| 606 base::string16 chrome_icon = ShellUtil::FormatIconLocation( | 622 base::string16 chrome_icon = ShellUtil::FormatIconLocation( |
| 607 chrome_exe, install_static::GetIconResourceIndex()); | 623 chrome_exe, install_static::GetIconResourceIndex()); |
| 608 for (int i = 0; ShellUtil::kBrowserProtocolAssociations[i] != NULL; i++) { | 624 for (int i = 0; ShellUtil::kBrowserProtocolAssociations[i] != NULL; i++) { |
| 609 GetXPStyleUserProtocolEntries(ShellUtil::kBrowserProtocolAssociations[i], | 625 GetXPStyleUserProtocolEntries(ShellUtil::kBrowserProtocolAssociations[i], |
| 610 chrome_icon, chrome_open, entries); | 626 chrome_icon, chrome_open, entries); |
| 611 } | 627 } |
| 612 | 628 |
| 613 // start->Internet shortcut. | 629 // start->Internet shortcut. |
| 614 base::string16 start_menu(ShellUtil::kRegStartMenuInternet); | 630 base::string16 start_menu(ShellUtil::kRegStartMenuInternet); |
| 615 base::string16 app_name = install_static::GetBaseAppName().append(suffix); | 631 base::string16 app_name = install_static::GetBaseAppName().append(suffix); |
| 616 entries->push_back(new RegistryEntry(start_menu, app_name)); | 632 entries->push_back(base::MakeUnique<RegistryEntry>(start_menu, app_name)); |
| 617 } | 633 } |
| 618 | 634 |
| 619 // Checks that all |entries| are present on this computer (or absent if their | 635 // Checks that all |entries| are present on this computer (or absent if their |
| 620 // |removal_flag_| is set). |look_for_in| is passed to | 636 // |removal_flag_| is set). |look_for_in| is passed to |
| 621 // RegistryEntry::ExistsInRegistry(). Documentation for it can be found there. | 637 // RegistryEntry::ExistsInRegistry(). Documentation for it can be found there. |
| 622 bool AreEntriesAsDesired(const ScopedVector<RegistryEntry>& entries, | 638 bool AreEntriesAsDesired( |
| 623 uint32_t look_for_in) { | 639 const std::vector<std::unique_ptr<RegistryEntry>>& entries, |
| 624 for (const auto* entry : entries) { | 640 uint32_t look_for_in) { |
| 641 for (const auto& entry : entries) { | |
| 625 if (entry->ExistsInRegistry(look_for_in) != !entry->IsFlaggedForRemoval()) | 642 if (entry->ExistsInRegistry(look_for_in) != !entry->IsFlaggedForRemoval()) |
| 626 return false; | 643 return false; |
| 627 } | 644 } |
| 628 return true; | 645 return true; |
| 629 } | 646 } |
| 630 | 647 |
| 631 // Checks that all required registry entries for Chrome are already present on | 648 // Checks that all required registry entries for Chrome are already present on |
| 632 // this computer (or absent if their |removal_flag_| is set). | 649 // this computer (or absent if their |removal_flag_| is set). |
| 633 // See RegistryEntry::ExistsInRegistry for the behavior of |look_for_in|. | 650 // See RegistryEntry::ExistsInRegistry for the behavior of |look_for_in|. |
| 634 // Note: between r133333 and r154145 we were registering parts of Chrome in HKCU | 651 // Note: between r133333 and r154145 we were registering parts of Chrome in HKCU |
| 635 // and parts in HKLM for user-level installs; we now always register everything | 652 // and parts in HKLM for user-level installs; we now always register everything |
| 636 // under a single registry root. Not doing so caused http://crbug.com/144910 for | 653 // under a single registry root. Not doing so caused http://crbug.com/144910 for |
| 637 // users who first-installed Chrome in that revision range (those users are | 654 // users who first-installed Chrome in that revision range (those users are |
| 638 // still impacted by http://crbug.com/144910). This method will keep returning | 655 // still impacted by http://crbug.com/144910). This method will keep returning |
| 639 // true for affected users (i.e. who have all the registrations, but over both | 656 // true for affected users (i.e. who have all the registrations, but over both |
| 640 // registry roots). | 657 // registry roots). |
| 641 bool IsChromeRegistered(BrowserDistribution* dist, | 658 bool IsChromeRegistered(BrowserDistribution* dist, |
| 642 const base::FilePath& chrome_exe, | 659 const base::FilePath& chrome_exe, |
| 643 const base::string16& suffix, | 660 const base::string16& suffix, |
| 644 uint32_t look_for_in) { | 661 uint32_t look_for_in) { |
| 645 ScopedVector<RegistryEntry> entries; | 662 std::vector<std::unique_ptr<RegistryEntry>> entries; |
| 646 GetChromeProgIdEntries(dist, chrome_exe, suffix, &entries); | 663 GetChromeProgIdEntries(dist, chrome_exe, suffix, &entries); |
| 647 GetShellIntegrationEntries(dist, chrome_exe, suffix, &entries); | 664 GetShellIntegrationEntries(dist, chrome_exe, suffix, &entries); |
| 648 GetChromeAppRegistrationEntries(chrome_exe, suffix, &entries); | 665 GetChromeAppRegistrationEntries(chrome_exe, suffix, &entries); |
| 649 return AreEntriesAsDesired(entries, look_for_in); | 666 return AreEntriesAsDesired(entries, look_for_in); |
| 650 } | 667 } |
| 651 | 668 |
| 652 // This method checks if Chrome is already registered on the local machine | 669 // This method checks if Chrome is already registered on the local machine |
| 653 // for the requested protocol. It just checks the one value required for this. | 670 // for the requested protocol. It just checks the one value required for this. |
| 654 // See RegistryEntry::ExistsInRegistry for the behavior of |look_for_in|. | 671 // See RegistryEntry::ExistsInRegistry for the behavior of |look_for_in|. |
| 655 bool IsChromeRegisteredForProtocol(const base::string16& suffix, | 672 bool IsChromeRegisteredForProtocol(const base::string16& suffix, |
| 656 const base::string16& protocol, | 673 const base::string16& protocol, |
| 657 uint32_t look_for_in) { | 674 uint32_t look_for_in) { |
| 658 ScopedVector<RegistryEntry> entries; | 675 std::vector<std::unique_ptr<RegistryEntry>> entries; |
| 659 GetProtocolCapabilityEntries(suffix, protocol, &entries); | 676 GetProtocolCapabilityEntries(suffix, protocol, &entries); |
| 660 return AreEntriesAsDesired(entries, look_for_in); | 677 return AreEntriesAsDesired(entries, look_for_in); |
| 661 } | 678 } |
| 662 | 679 |
| 663 // This method registers Chrome by launching an elevated setup.exe. That will | 680 // This method registers Chrome by launching an elevated setup.exe. That will |
| 664 // show the user the standard elevation prompt. If the user accepts it the new | 681 // show the user the standard elevation prompt. If the user accepts it the new |
| 665 // process will make the necessary changes and return SUCCESS that we capture | 682 // process will make the necessary changes and return SUCCESS that we capture |
| 666 // and return. If protocol is non-empty we will also register Chrome as being | 683 // and return. If protocol is non-empty we will also register Chrome as being |
| 667 // capable of handling the protocol. This is most commonly used on per-user | 684 // capable of handling the protocol. This is most commonly used on per-user |
| 668 // installs on Windows 7 where setup.exe did not have permission to register | 685 // installs on Windows 7 where setup.exe did not have permission to register |
| (...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 881 return is_per_user && base::win::GetVersion() >= base::win::VERSION_WIN8 ? | 898 return is_per_user && base::win::GetVersion() >= base::win::VERSION_WIN8 ? |
| 882 HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE; | 899 HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE; |
| 883 } | 900 } |
| 884 | 901 |
| 885 // Associates Chrome with supported protocols and file associations. This should | 902 // Associates Chrome with supported protocols and file associations. This should |
| 886 // not be required on Vista+ but since some applications still read | 903 // not be required on Vista+ but since some applications still read |
| 887 // Software\Classes\http key directly, we have to do this on Vista+ as well. | 904 // Software\Classes\http key directly, we have to do this on Vista+ as well. |
| 888 bool RegisterChromeAsDefaultXPStyle(int shell_change, | 905 bool RegisterChromeAsDefaultXPStyle(int shell_change, |
| 889 const base::FilePath& chrome_exe) { | 906 const base::FilePath& chrome_exe) { |
| 890 bool ret = true; | 907 bool ret = true; |
| 891 ScopedVector<RegistryEntry> entries; | 908 std::vector<std::unique_ptr<RegistryEntry>> entries; |
| 892 GetXPStyleDefaultBrowserUserEntries( | 909 GetXPStyleDefaultBrowserUserEntries( |
| 893 chrome_exe, ShellUtil::GetCurrentInstallationSuffix(chrome_exe), | 910 chrome_exe, ShellUtil::GetCurrentInstallationSuffix(chrome_exe), |
| 894 &entries); | 911 &entries); |
| 895 | 912 |
| 896 // Change the default browser for current user. | 913 // Change the default browser for current user. |
| 897 if ((shell_change & ShellUtil::CURRENT_USER) && | 914 if ((shell_change & ShellUtil::CURRENT_USER) && |
| 898 !ShellUtil::AddRegistryEntries(HKEY_CURRENT_USER, entries)) { | 915 !ShellUtil::AddRegistryEntries(HKEY_CURRENT_USER, entries)) { |
| 899 ret = false; | 916 ret = false; |
| 900 LOG(ERROR) << "Could not make Chrome default browser (XP/current user)."; | 917 LOG(ERROR) << "Could not make Chrome default browser (XP/current user)."; |
| 901 } | 918 } |
| 902 | 919 |
| 903 // Chrome as default browser at system level. | 920 // Chrome as default browser at system level. |
| 904 if ((shell_change & ShellUtil::SYSTEM_LEVEL) && | 921 if ((shell_change & ShellUtil::SYSTEM_LEVEL) && |
| 905 !ShellUtil::AddRegistryEntries(HKEY_LOCAL_MACHINE, entries)) { | 922 !ShellUtil::AddRegistryEntries(HKEY_LOCAL_MACHINE, entries)) { |
| 906 ret = false; | 923 ret = false; |
| 907 LOG(ERROR) << "Could not make Chrome default browser (XP/system level)."; | 924 LOG(ERROR) << "Could not make Chrome default browser (XP/system level)."; |
| 908 } | 925 } |
| 909 | 926 |
| 910 return ret; | 927 return ret; |
| 911 } | 928 } |
| 912 | 929 |
| 913 // Associates Chrome with |protocol| in the registry. This should not be | 930 // Associates Chrome with |protocol| in the registry. This should not be |
| 914 // required on Vista+ but since some applications still read these registry | 931 // required on Vista+ but since some applications still read these registry |
| 915 // keys directly, we have to do this on Vista+ as well. | 932 // keys directly, we have to do this on Vista+ as well. |
| 916 // See http://msdn.microsoft.com/library/aa767914.aspx for more details. | 933 // See http://msdn.microsoft.com/library/aa767914.aspx for more details. |
| 917 bool RegisterChromeAsDefaultProtocolClientXPStyle( | 934 bool RegisterChromeAsDefaultProtocolClientXPStyle( |
| 918 const base::FilePath& chrome_exe, | 935 const base::FilePath& chrome_exe, |
| 919 const base::string16& protocol) { | 936 const base::string16& protocol) { |
| 920 ScopedVector<RegistryEntry> entries; | 937 std::vector<std::unique_ptr<RegistryEntry>> entries; |
| 921 const base::string16 chrome_open( | 938 const base::string16 chrome_open( |
| 922 ShellUtil::GetChromeShellOpenCmd(chrome_exe)); | 939 ShellUtil::GetChromeShellOpenCmd(chrome_exe)); |
| 923 const base::string16 chrome_icon(ShellUtil::FormatIconLocation( | 940 const base::string16 chrome_icon(ShellUtil::FormatIconLocation( |
| 924 chrome_exe, install_static::GetIconResourceIndex())); | 941 chrome_exe, install_static::GetIconResourceIndex())); |
| 925 GetXPStyleUserProtocolEntries(protocol, chrome_icon, chrome_open, &entries); | 942 GetXPStyleUserProtocolEntries(protocol, chrome_icon, chrome_open, &entries); |
| 926 // Change the default protocol handler for current user. | 943 // Change the default protocol handler for current user. |
| 927 if (!ShellUtil::AddRegistryEntries(HKEY_CURRENT_USER, entries)) { | 944 if (!ShellUtil::AddRegistryEntries(HKEY_CURRENT_USER, entries)) { |
| 928 LOG(ERROR) << "Could not make Chrome default protocol client (XP)."; | 945 LOG(ERROR) << "Could not make Chrome default protocol client (XP)."; |
| 929 return false; | 946 return false; |
| 930 } | 947 } |
| (...skipping 1136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2067 : RegistryEntry::LOOK_IN_HKLM; | 2084 : RegistryEntry::LOOK_IN_HKLM; |
| 2068 | 2085 |
| 2069 // Check if chrome is already registered with this suffix. | 2086 // Check if chrome is already registered with this suffix. |
| 2070 if (IsChromeRegistered(dist, chrome_exe, suffix, look_for_in)) | 2087 if (IsChromeRegistered(dist, chrome_exe, suffix, look_for_in)) |
| 2071 return true; | 2088 return true; |
| 2072 | 2089 |
| 2073 bool result = true; | 2090 bool result = true; |
| 2074 if (root == HKEY_CURRENT_USER || IsUserAnAdmin()) { | 2091 if (root == HKEY_CURRENT_USER || IsUserAnAdmin()) { |
| 2075 // Do the full registration if we can do it at user-level or if the user is | 2092 // Do the full registration if we can do it at user-level or if the user is |
| 2076 // an admin. | 2093 // an admin. |
| 2077 ScopedVector<RegistryEntry> progid_and_appreg_entries; | 2094 std::vector<std::unique_ptr<RegistryEntry>> progid_and_appreg_entries; |
| 2078 ScopedVector<RegistryEntry> shell_entries; | 2095 std::vector<std::unique_ptr<RegistryEntry>> shell_entries; |
| 2079 GetChromeProgIdEntries(dist, chrome_exe, suffix, | 2096 GetChromeProgIdEntries(dist, chrome_exe, suffix, |
| 2080 &progid_and_appreg_entries); | 2097 &progid_and_appreg_entries); |
| 2081 GetChromeAppRegistrationEntries(chrome_exe, suffix, | 2098 GetChromeAppRegistrationEntries(chrome_exe, suffix, |
| 2082 &progid_and_appreg_entries); | 2099 &progid_and_appreg_entries); |
| 2083 GetShellIntegrationEntries(dist, chrome_exe, suffix, &shell_entries); | 2100 GetShellIntegrationEntries(dist, chrome_exe, suffix, &shell_entries); |
| 2084 result = (AddRegistryEntries(root, progid_and_appreg_entries) && | 2101 result = (AddRegistryEntries(root, progid_and_appreg_entries) && |
| 2085 AddRegistryEntries(root, shell_entries)); | 2102 AddRegistryEntries(root, shell_entries)); |
| 2086 } else if (elevate_if_not_admin && | 2103 } else if (elevate_if_not_admin && |
| 2087 base::win::GetVersion() >= base::win::VERSION_VISTA && | 2104 base::win::GetVersion() >= base::win::VERSION_VISTA && |
| 2088 ElevateAndRegisterChrome(dist, chrome_exe, suffix, base::string16())) { | 2105 ElevateAndRegisterChrome(dist, chrome_exe, suffix, base::string16())) { |
| 2089 // If the user is not an admin and OS is between Vista and Windows 7 | 2106 // If the user is not an admin and OS is between Vista and Windows 7 |
| 2090 // inclusively, try to elevate and register. This is only intended for | 2107 // inclusively, try to elevate and register. This is only intended for |
| 2091 // user-level installs as system-level installs should always be run with | 2108 // user-level installs as system-level installs should always be run with |
| 2092 // admin rights. | 2109 // admin rights. |
| 2093 result = true; | 2110 result = true; |
| 2094 } else { | 2111 } else { |
| 2095 // If we got to this point then all we can do is create ProgId and basic app | 2112 // If we got to this point then all we can do is create ProgId and basic app |
| 2096 // registrations under HKCU. | 2113 // registrations under HKCU. |
| 2097 ScopedVector<RegistryEntry> entries; | 2114 std::vector<std::unique_ptr<RegistryEntry>> entries; |
| 2098 GetChromeProgIdEntries(dist, chrome_exe, base::string16(), &entries); | 2115 GetChromeProgIdEntries(dist, chrome_exe, base::string16(), &entries); |
| 2099 // Prefer to use |suffix|; unless Chrome's ProgIds are already registered | 2116 // Prefer to use |suffix|; unless Chrome's ProgIds are already registered |
| 2100 // with no suffix (as per the old registration style): in which case some | 2117 // with no suffix (as per the old registration style): in which case some |
| 2101 // other registry entries could refer to them and since we were not able to | 2118 // other registry entries could refer to them and since we were not able to |
| 2102 // set our HKLM entries above, we are better off not altering these here. | 2119 // set our HKLM entries above, we are better off not altering these here. |
| 2103 if (!AreEntriesAsDesired(entries, RegistryEntry::LOOK_IN_HKCU)) { | 2120 if (!AreEntriesAsDesired(entries, RegistryEntry::LOOK_IN_HKCU)) { |
| 2104 if (!suffix.empty()) { | 2121 if (!suffix.empty()) { |
| 2105 entries.clear(); | 2122 entries.clear(); |
| 2106 GetChromeProgIdEntries(dist, chrome_exe, suffix, &entries); | 2123 GetChromeProgIdEntries(dist, chrome_exe, suffix, &entries); |
| 2107 GetChromeAppRegistrationEntries(chrome_exe, suffix, &entries); | 2124 GetChromeAppRegistrationEntries(chrome_exe, suffix, &entries); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2150 if (IsChromeRegisteredForProtocol(suffix, protocol, look_for_in)) | 2167 if (IsChromeRegisteredForProtocol(suffix, protocol, look_for_in)) |
| 2151 return true; | 2168 return true; |
| 2152 | 2169 |
| 2153 if (root == HKEY_CURRENT_USER || IsUserAnAdmin()) { | 2170 if (root == HKEY_CURRENT_USER || IsUserAnAdmin()) { |
| 2154 // We can do this operation directly. | 2171 // We can do this operation directly. |
| 2155 // First, make sure Chrome is fully registered on this machine. | 2172 // First, make sure Chrome is fully registered on this machine. |
| 2156 if (!RegisterChromeBrowser(dist, chrome_exe, suffix, false)) | 2173 if (!RegisterChromeBrowser(dist, chrome_exe, suffix, false)) |
| 2157 return false; | 2174 return false; |
| 2158 | 2175 |
| 2159 // Write in the capabillity for the protocol. | 2176 // Write in the capabillity for the protocol. |
| 2160 ScopedVector<RegistryEntry> entries; | 2177 std::vector<std::unique_ptr<RegistryEntry>> entries; |
| 2161 GetProtocolCapabilityEntries(suffix, protocol, &entries); | 2178 GetProtocolCapabilityEntries(suffix, protocol, &entries); |
| 2162 return AddRegistryEntries(root, entries); | 2179 return AddRegistryEntries(root, entries); |
| 2163 } else if (elevate_if_not_admin && | 2180 } else if (elevate_if_not_admin && |
| 2164 base::win::GetVersion() >= base::win::VERSION_VISTA) { | 2181 base::win::GetVersion() >= base::win::VERSION_VISTA) { |
| 2165 // Elevate to do the whole job | 2182 // Elevate to do the whole job |
| 2166 return ElevateAndRegisterChrome(dist, chrome_exe, suffix, protocol); | 2183 return ElevateAndRegisterChrome(dist, chrome_exe, suffix, protocol); |
| 2167 } else { | 2184 } else { |
| 2168 // Admin rights are required to register capabilities before Windows 8. | 2185 // Admin rights are required to register capabilities before Windows 8. |
| 2169 return false; | 2186 return false; |
| 2170 } | 2187 } |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2262 return true; | 2279 return true; |
| 2263 } | 2280 } |
| 2264 | 2281 |
| 2265 // static | 2282 // static |
| 2266 bool ShellUtil::AddFileAssociations( | 2283 bool ShellUtil::AddFileAssociations( |
| 2267 const base::string16& prog_id, | 2284 const base::string16& prog_id, |
| 2268 const base::CommandLine& command_line, | 2285 const base::CommandLine& command_line, |
| 2269 const base::string16& file_type_name, | 2286 const base::string16& file_type_name, |
| 2270 const base::FilePath& icon_path, | 2287 const base::FilePath& icon_path, |
| 2271 const std::set<base::string16>& file_extensions) { | 2288 const std::set<base::string16>& file_extensions) { |
| 2272 ScopedVector<RegistryEntry> entries; | 2289 std::vector<std::unique_ptr<RegistryEntry>> entries; |
| 2273 | 2290 |
| 2274 // Create a class for this app. | 2291 // Create a class for this app. |
| 2275 ApplicationInfo app_info; | 2292 ApplicationInfo app_info; |
| 2276 app_info.prog_id = prog_id; | 2293 app_info.prog_id = prog_id; |
| 2277 app_info.file_type_name = file_type_name; | 2294 app_info.file_type_name = file_type_name; |
| 2278 app_info.file_type_icon_path = icon_path; | 2295 app_info.file_type_icon_path = icon_path; |
| 2279 app_info.file_type_icon_index = 0; | 2296 app_info.file_type_icon_index = 0; |
| 2280 app_info.command_line = command_line.GetCommandLineStringWithPlaceholders(); | 2297 app_info.command_line = command_line.GetCommandLineStringWithPlaceholders(); |
| 2281 GetProgIdEntries(app_info, &entries); | 2298 GetProgIdEntries(app_info, &entries); |
| 2282 | 2299 |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 2310 key_path.append(prog_id); | 2327 key_path.append(prog_id); |
| 2311 return InstallUtil::DeleteRegistryKey( | 2328 return InstallUtil::DeleteRegistryKey( |
| 2312 HKEY_CURRENT_USER, key_path, WorkItem::kWow64Default); | 2329 HKEY_CURRENT_USER, key_path, WorkItem::kWow64Default); |
| 2313 | 2330 |
| 2314 // TODO(mgiuca): Remove the extension association entries. This requires that | 2331 // TODO(mgiuca): Remove the extension association entries. This requires that |
| 2315 // the extensions associated with a particular prog_id are stored in that | 2332 // the extensions associated with a particular prog_id are stored in that |
| 2316 // prog_id's key. | 2333 // prog_id's key. |
| 2317 } | 2334 } |
| 2318 | 2335 |
| 2319 // static | 2336 // static |
| 2320 bool ShellUtil::AddRegistryEntries(HKEY root, | 2337 bool ShellUtil::AddRegistryEntries( |
| 2321 const ScopedVector<RegistryEntry>& entries) { | 2338 HKEY root, |
| 2339 const std::vector<std::unique_ptr<RegistryEntry>>& entries) { | |
| 2322 std::unique_ptr<WorkItemList> items(WorkItem::CreateWorkItemList()); | 2340 std::unique_ptr<WorkItemList> items(WorkItem::CreateWorkItemList()); |
| 2323 | 2341 |
| 2324 for (ScopedVector<RegistryEntry>::const_iterator itr = entries.begin(); | 2342 for (const auto& entry : entries) |
| 2325 itr != entries.end(); ++itr) | 2343 entry->AddToWorkItemList(root, items.get()); |
| 2326 (*itr)->AddToWorkItemList(root, items.get()); | |
| 2327 | 2344 |
| 2328 // Apply all the registry changes and if there is a problem, rollback | 2345 // Apply all the registry changes and if there is a problem, rollback |
| 2329 if (!items->Do()) { | 2346 if (!items->Do()) { |
| 2330 items->Rollback(); | 2347 items->Rollback(); |
| 2331 return false; | 2348 return false; |
| 2332 } | 2349 } |
| 2333 return true; | 2350 return true; |
| 2334 } | 2351 } |
| OLD | NEW |