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" |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 147 | 147 |
| 148 bool UserSpecificRegistrySuffix::GetSuffix(base::string16* suffix) { | 148 bool UserSpecificRegistrySuffix::GetSuffix(base::string16* suffix) { |
| 149 if (suffix_.empty()) { | 149 if (suffix_.empty()) { |
| 150 NOTREACHED(); | 150 NOTREACHED(); |
| 151 return false; | 151 return false; |
| 152 } | 152 } |
| 153 suffix->assign(suffix_); | 153 suffix->assign(suffix_); |
| 154 return true; | 154 return true; |
| 155 } | 155 } |
| 156 | 156 |
| 157 // Details about a Windows application, to be entered into the registry for the | |
| 158 // purpose of file associations. | |
| 159 struct ApplicationInfo { | |
| 160 ApplicationInfo() : file_type_icon_index(0), application_icon_index(0) {} | |
| 161 | |
| 162 // The ProgId used by Windows for file associations with this application. | |
| 163 // Must not be empty or start with a '.'. | |
| 164 base::string16 prog_id; | |
| 165 // The friendly name, and the path of the icon that will be used for files of | |
| 166 // these types when associated with this application by default. (They are NOT | |
| 167 // the name/icon that will represent the application under the Open With | |
| 168 // menu.) | |
| 169 base::string16 file_type_name; | |
| 170 base::FilePath file_type_icon_path; | |
| 171 int file_type_icon_index; | |
| 172 // The command to execute when opening a file via this association. It should | |
| 173 // contain "%1" (to tell Windows to pass the filename as an argument). | |
| 174 // TODO(mgiuca): |command_line| should be a base::CommandLine. | |
| 175 base::string16 command_line; | |
| 176 // The AppUserModelId used by Windows 8 for this application. Distinct from | |
| 177 // |prog_id|. | |
| 178 base::string16 app_id; | |
| 179 | |
| 180 // User-visible details about this application. Any of these may be empty. | |
| 181 base::string16 application_name; | |
| 182 base::FilePath application_icon_path; | |
| 183 int application_icon_index; | |
| 184 base::string16 application_description; | |
| 185 base::string16 publisher_name; | |
| 186 | |
| 187 // The CLSID for the application's DelegateExecute handler. May be empty. | |
| 188 base::string16 delegate_clsid; | |
| 189 }; | |
| 190 | |
| 157 // This class represents a single registry entry (a key and its value). A | 191 // This class represents a single registry entry (a key and its value). A |
| 158 // collection of registry entries should be collected into a list and written | 192 // collection of registry entries should be collected into a list and written |
| 159 // atomically using a WorkItemList. This is preferred to writing to the registry | 193 // atomically using a WorkItemList. This is preferred to writing to the registry |
| 160 // directly, because if anything goes wrong, they can be rolled back atomically. | 194 // directly, because if anything goes wrong, they can be rolled back atomically. |
| 161 class RegistryEntry { | 195 class RegistryEntry { |
| 162 public: | 196 public: |
| 163 // A bit-field enum of places to look for this key in the Windows registry. | 197 // A bit-field enum of places to look for this key in the Windows registry. |
| 164 enum LookForIn { | 198 enum LookForIn { |
| 165 LOOK_IN_HKCU = 1 << 0, | 199 LOOK_IN_HKCU = 1 << 0, |
| 166 LOOK_IN_HKLM = 1 << 1, | 200 LOOK_IN_HKLM = 1 << 1, |
| 167 LOOK_IN_HKCU_THEN_HKLM = LOOK_IN_HKCU | LOOK_IN_HKLM, | 201 LOOK_IN_HKCU_THEN_HKLM = LOOK_IN_HKCU | LOOK_IN_HKLM, |
| 168 }; | 202 }; |
| 169 | 203 |
| 170 // Identifies the type of removal this RegistryEntry is flagged for, if any. | 204 // Identifies the type of removal this RegistryEntry is flagged for, if any. |
| 171 enum class RemovalFlag { | 205 enum class RemovalFlag { |
| 172 // Default case: install the key/value. | 206 // Default case: install the key/value. |
| 173 NONE, | 207 NONE, |
| 174 // Registry value under |key_path_|\|name_| is flagged for deletion. | 208 // Registry value under |key_path_|\|name_| is flagged for deletion. |
| 175 VALUE, | 209 VALUE, |
| 176 // Registry key under |key_path_| is flag for deletion. | 210 // Registry key under |key_path_| is flag for deletion. |
| 177 KEY, | 211 KEY, |
| 178 }; | 212 }; |
| 179 | 213 |
| 180 // Details about a Windows application, to be entered into the registry for | |
| 181 // the purpose of file associations. | |
| 182 struct ApplicationInfo { | |
| 183 ApplicationInfo() : file_type_icon_index(0), application_icon_index(0) {} | |
| 184 | |
| 185 // The ProgId used by Windows for file associations with this application. | |
| 186 // Must not be empty or start with a '.'. | |
| 187 base::string16 prog_id; | |
| 188 // The friendly name, and the path of the icon that will be used for files | |
| 189 // of these types when associated with this application by default. (They | |
| 190 // are NOT the name/icon that will represent the application under the Open | |
| 191 // With menu.) | |
| 192 base::string16 file_type_name; | |
| 193 base::FilePath file_type_icon_path; | |
| 194 int file_type_icon_index; | |
| 195 // The command to execute when opening a file via this association. It | |
| 196 // should contain "%1" (to tell Windows to pass the filename as an | |
| 197 // argument). | |
| 198 // TODO(mgiuca): |command_line| should be a base::CommandLine. | |
| 199 base::string16 command_line; | |
| 200 // The AppUserModelId used by Windows 8 for this application. Distinct from | |
| 201 // |prog_id|. | |
| 202 base::string16 app_id; | |
| 203 | |
| 204 // User-visible details about this application. Any of these may be empty. | |
| 205 base::string16 application_name; | |
| 206 base::FilePath application_icon_path; | |
| 207 int application_icon_index; | |
| 208 base::string16 application_description; | |
| 209 base::string16 publisher_name; | |
| 210 | |
| 211 // The CLSID for the application's DelegateExecute handler. May be empty. | |
| 212 base::string16 delegate_clsid; | |
| 213 }; | |
| 214 | |
| 215 // Create a object that represent default value of a key | 214 // Create a object that represent default value of a key |
| 216 RegistryEntry(const base::string16& key_path, const base::string16& value); | 215 RegistryEntry(const base::string16& key_path, const base::string16& value); |
| 217 | 216 |
| 218 // Create a object that represent a key of type REG_SZ | 217 // Create a object that represent a key of type REG_SZ |
| 219 RegistryEntry(const base::string16& key_path, | 218 RegistryEntry(const base::string16& key_path, |
| 220 const base::string16& name, | 219 const base::string16& name, |
| 221 const base::string16& value); | 220 const base::string16& value); |
| 222 | 221 |
| 223 // Create a object that represent a key of integer type | 222 // Create a object that represent a key of integer type |
| 224 RegistryEntry(const base::string16& key_path, | 223 RegistryEntry(const base::string16& key_path, |
| 225 const base::string16& name, | 224 const base::string16& name, |
| 226 DWORD value); | 225 DWORD value); |
| 227 | 226 |
| 228 // Returns the Windows browser client registration key for Chrome. For | |
| 229 // example: "Software\Clients\StartMenuInternet\Chromium[.user]". Strictly | |
| 230 // speaking, we should use the name of the executable (e.g., "chrome.exe"), | |
| 231 // but that ship has sailed. The cost of switching now is re-prompting users | |
| 232 // to make Chrome their default browser, which isn't polite. |suffix| is the | |
| 233 // user-specific registration suffix; see GetUserSpecificDefaultBrowserSuffix | |
| 234 // in shell_util.h for details. | |
| 235 static base::string16 GetBrowserClientKey(BrowserDistribution* dist, | |
| 236 const base::string16& suffix); | |
| 237 | |
| 238 // Returns the Windows Default Programs capabilities key for Chrome. For | |
| 239 // example: | |
| 240 // "Software\Clients\StartMenuInternet\Chromium[.user]\Capabilities". | |
| 241 static base::string16 GetCapabilitiesKey(BrowserDistribution* dist, | |
| 242 const base::string16& suffix); | |
| 243 | |
| 244 // DelegateExecute ProgId. Needed for Chrome Metro in Windows 8. This is | |
| 245 // only needed for registring a web browser, not for general associations. | |
| 246 static ScopedVector<RegistryEntry> GetChromeDelegateExecuteEntries( | |
| 247 const base::FilePath& chrome_exe, | |
| 248 const ApplicationInfo& app_info); | |
| 249 | |
| 250 // This method returns a list of all the registry entries that | |
| 251 // are needed to register this installation's ProgId and AppId. | |
| 252 // These entries need to be registered in HKLM prior to Win8. | |
| 253 static void GetChromeProgIdEntries(BrowserDistribution* dist, | |
| 254 const base::FilePath& chrome_exe, | |
| 255 const base::string16& suffix, | |
| 256 ScopedVector<RegistryEntry>* entries); | |
| 257 | |
| 258 // Gets the registry entries to register an application in the Windows | |
| 259 // registry. |app_info| provides all of the information needed. | |
| 260 static void GetProgIdEntries(const ApplicationInfo& app_info, | |
| 261 ScopedVector<RegistryEntry>* entries); | |
| 262 | |
| 263 // This method returns a list of the registry entries needed to declare a | |
| 264 // capability of handling a protocol on Windows. | |
| 265 static void GetProtocolCapabilityEntries( | |
| 266 BrowserDistribution* dist, | |
| 267 const base::string16& suffix, | |
| 268 const base::string16& protocol, | |
| 269 ScopedVector<RegistryEntry>* entries); | |
| 270 | |
| 271 // This method returns a list of the registry entries required to register | |
| 272 // this installation in "RegisteredApplications" on Windows (to appear in | |
| 273 // Default Programs, StartMenuInternet, etc.). | |
| 274 // These entries need to be registered in HKLM prior to Win8. | |
| 275 // If |suffix| is not empty, these entries are guaranteed to be unique on this | |
| 276 // machine. | |
| 277 static void GetShellIntegrationEntries(BrowserDistribution* dist, | |
| 278 const base::FilePath& chrome_exe, | |
| 279 const base::string16& suffix, | |
| 280 ScopedVector<RegistryEntry>* entries); | |
| 281 | |
| 282 // This method returns a list of the registry entries required for this | |
| 283 // installation to be registered in the Windows shell. | |
| 284 // In particular: | |
| 285 // - App Paths | |
| 286 // http://msdn.microsoft.com/en-us/library/windows/desktop/ee872121 | |
| 287 // - File Associations | |
| 288 // http://msdn.microsoft.com/en-us/library/bb166549 | |
| 289 // These entries need to be registered in HKLM prior to Win8. | |
| 290 static void GetChromeAppRegistrationEntries( | |
| 291 const base::FilePath& chrome_exe, | |
| 292 const base::string16& suffix, | |
| 293 ScopedVector<RegistryEntry>* entries); | |
| 294 | |
| 295 // Gets the registry entries to register an application as a handler for a | |
| 296 // particular file extension. |prog_id| is the ProgId used by Windows for the | |
| 297 // application. |ext| is the file extension, which must begin with a '.'. | |
| 298 static void GetAppExtRegistrationEntries( | |
| 299 const base::string16& prog_id, | |
| 300 const base::string16& ext, | |
| 301 ScopedVector<RegistryEntry>* entries); | |
| 302 | |
| 303 // Gets the registry entries to register an application as the default handler | |
| 304 // for a particular file extension. |prog_id| is the ProgId used by Windows | |
| 305 // for the application. |ext| is the file extension, which must begin with a | |
| 306 // '.'. If |overwrite_existing|, always sets the default handler; otherwise | |
| 307 // only sets if there is no existing default. | |
| 308 // | |
| 309 // This has no effect on Windows 8. Windows 8 ignores the default and lets the | |
| 310 // user choose. If there is only one handler for a file, it will automatically | |
| 311 // become the default. Otherwise, the first time the user opens a file, they | |
| 312 // are presented with the dialog to set the default handler. (This is roughly | |
| 313 // equivalent to being called with |overwrite_existing| false.) | |
| 314 static void GetAppDefaultRegistrationEntries( | |
| 315 const base::string16& prog_id, | |
| 316 const base::string16& ext, | |
| 317 bool overwrite_existing, | |
| 318 ScopedVector<RegistryEntry>* entries); | |
| 319 | |
| 320 // This method returns a list of all the user level registry entries that | |
| 321 // are needed to make Chromium the default handler for a protocol on XP. | |
| 322 static void GetXPStyleUserProtocolEntries( | |
| 323 const base::string16& protocol, | |
| 324 const base::string16& chrome_icon, | |
| 325 const base::string16& chrome_open, | |
| 326 ScopedVector<RegistryEntry>* entries); | |
| 327 | |
| 328 // This method returns a list of all the user level registry entries that | |
| 329 // are needed to make Chromium default browser on XP. | |
| 330 // Some of these entries are irrelevant in recent versions of Windows, but | |
| 331 // we register them anyways as some legacy apps are hardcoded to lookup those | |
| 332 // values. | |
| 333 static void GetXPStyleDefaultBrowserUserEntries( | |
| 334 BrowserDistribution* dist, | |
| 335 const base::FilePath& chrome_exe, | |
| 336 const base::string16& suffix, | |
| 337 ScopedVector<RegistryEntry>* entries); | |
| 338 | |
| 339 // Flags this RegistryKey with |removal_flag|, indicating that it should be | 227 // Flags this RegistryKey with |removal_flag|, indicating that it should be |
| 340 // removed rather than created. Note that this will not result in cleaning up | 228 // removed rather than created. Note that this will not result in cleaning up |
| 341 // the entire registry hierarchy below RegistryEntry even if it is left empty | 229 // the entire registry hierarchy below RegistryEntry even if it is left empty |
| 342 // by this operation (this should thus not be used for uninstall, but only to | 230 // by this operation (this should thus not be used for uninstall, but only to |
| 343 // unregister keys that should explicitly no longer be active in the current | 231 // unregister keys that should explicitly no longer be active in the current |
| 344 // configuration). | 232 // configuration). |
| 345 void set_removal_flag(RemovalFlag removal_flag) { | 233 void set_removal_flag(RemovalFlag removal_flag) { |
| 346 removal_flag_ = removal_flag; | 234 removal_flag_ = removal_flag; |
| 347 } | 235 } |
| 348 | 236 |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 427 RegistryEntry::RegistryEntry(const base::string16& key_path, | 315 RegistryEntry::RegistryEntry(const base::string16& key_path, |
| 428 const base::string16& name, | 316 const base::string16& name, |
| 429 DWORD value) | 317 DWORD value) |
| 430 : key_path_(key_path), | 318 : key_path_(key_path), |
| 431 name_(name), | 319 name_(name), |
| 432 is_string_(false), | 320 is_string_(false), |
| 433 value_(), | 321 value_(), |
| 434 int_value_(value), | 322 int_value_(value), |
| 435 removal_flag_(RemovalFlag::NONE) {} | 323 removal_flag_(RemovalFlag::NONE) {} |
| 436 | 324 |
| 437 // static | 325 void RegistryEntry::AddToWorkItemList(HKEY root, WorkItemList* items) const { |
|
Matt Giuca
2015/11/30 03:11:09
Note: These method definitions were moved up so th
| |
| 438 base::string16 RegistryEntry::GetBrowserClientKey( | 326 if (removal_flag_ == RemovalFlag::VALUE) { |
| 439 BrowserDistribution* dist, | 327 items->AddDeleteRegValueWorkItem(root, key_path_, WorkItem::kWow64Default, |
| 440 const base::string16& suffix) { | 328 name_); |
| 329 } else if (removal_flag_ == RemovalFlag::KEY) { | |
| 330 items->AddDeleteRegKeyWorkItem(root, key_path_, WorkItem::kWow64Default); | |
| 331 } else { | |
| 332 DCHECK(removal_flag_ == RemovalFlag::NONE); | |
| 333 items->AddCreateRegKeyWorkItem(root, key_path_, WorkItem::kWow64Default); | |
| 334 if (is_string_) { | |
| 335 items->AddSetRegValueWorkItem(root, key_path_, WorkItem::kWow64Default, | |
| 336 name_, value_, true); | |
| 337 } else { | |
| 338 items->AddSetRegValueWorkItem(root, key_path_, WorkItem::kWow64Default, | |
| 339 name_, int_value_, true); | |
| 340 } | |
| 341 } | |
| 342 } | |
| 343 | |
| 344 bool RegistryEntry::ExistsInRegistry(uint32 look_for_in) const { | |
| 345 DCHECK(look_for_in); | |
| 346 | |
| 347 RegistryStatus status = DOES_NOT_EXIST; | |
| 348 if (look_for_in & LOOK_IN_HKCU) | |
| 349 status = StatusInRegistryUnderRoot(HKEY_CURRENT_USER); | |
| 350 if (status == DOES_NOT_EXIST && (look_for_in & LOOK_IN_HKLM)) | |
| 351 status = StatusInRegistryUnderRoot(HKEY_LOCAL_MACHINE); | |
| 352 return status == SAME_VALUE; | |
| 353 } | |
| 354 | |
| 355 bool RegistryEntry::KeyExistsInRegistry(uint32 look_for_in) const { | |
| 356 DCHECK(look_for_in); | |
| 357 | |
| 358 RegistryStatus status = DOES_NOT_EXIST; | |
| 359 if (look_for_in & LOOK_IN_HKCU) | |
| 360 status = StatusInRegistryUnderRoot(HKEY_CURRENT_USER); | |
| 361 if (status == DOES_NOT_EXIST && (look_for_in & LOOK_IN_HKLM)) | |
| 362 status = StatusInRegistryUnderRoot(HKEY_LOCAL_MACHINE); | |
| 363 return status != DOES_NOT_EXIST; | |
| 364 } | |
| 365 | |
| 366 RegistryEntry::RegistryStatus RegistryEntry::StatusInRegistryUnderRoot( | |
| 367 HKEY root) const { | |
| 368 RegKey key(root, key_path_.c_str(), KEY_QUERY_VALUE); | |
| 369 bool found = false; | |
| 370 bool correct_value = false; | |
| 371 if (is_string_) { | |
| 372 base::string16 read_value; | |
| 373 found = key.ReadValue(name_.c_str(), &read_value) == ERROR_SUCCESS; | |
| 374 if (found) { | |
| 375 correct_value = | |
| 376 read_value.size() == value_.size() && | |
| 377 ::CompareString( | |
| 378 LOCALE_USER_DEFAULT, NORM_IGNORECASE, read_value.data(), | |
| 379 base::saturated_cast<int>(read_value.size()), value_.data(), | |
| 380 base::saturated_cast<int>(value_.size())) == CSTR_EQUAL; | |
| 381 } | |
| 382 } else { | |
| 383 DWORD read_value; | |
| 384 found = key.ReadValueDW(name_.c_str(), &read_value) == ERROR_SUCCESS; | |
| 385 if (found) | |
| 386 correct_value = read_value == int_value_; | |
| 387 } | |
| 388 return found ? (correct_value ? SAME_VALUE : DIFFERENT_VALUE) | |
| 389 : DOES_NOT_EXIST; | |
| 390 } | |
| 391 | |
| 392 // Returns the Windows browser client registration key for Chrome. For example: | |
| 393 // "Software\Clients\StartMenuInternet\Chromium[.user]". Strictly speaking, we | |
| 394 // should use the name of the executable (e.g., "chrome.exe"), but that ship has | |
| 395 // sailed. The cost of switching now is re-prompting users to make Chrome their | |
| 396 // default browser, which isn't polite. |suffix| is the user-specific | |
| 397 // registration suffix; see GetUserSpecificDefaultBrowserSuffix in shell_util.h | |
| 398 // for details. | |
| 399 base::string16 GetBrowserClientKey(BrowserDistribution* dist, | |
| 400 const base::string16& suffix) { | |
| 441 DCHECK(suffix.empty() || suffix[0] == L'.'); | 401 DCHECK(suffix.empty() || suffix[0] == L'.'); |
| 442 return base::string16(ShellUtil::kRegStartMenuInternet) | 402 return base::string16(ShellUtil::kRegStartMenuInternet) |
| 443 .append(1, L'\\') | 403 .append(1, L'\\') |
| 444 .append(dist->GetBaseAppName()) | 404 .append(dist->GetBaseAppName()) |
| 445 .append(suffix); | 405 .append(suffix); |
| 446 } | 406 } |
| 447 | 407 |
| 448 // static | 408 // Returns the Windows Default Programs capabilities key for Chrome. For |
| 449 base::string16 RegistryEntry::GetCapabilitiesKey(BrowserDistribution* dist, | 409 // example: |
| 450 const base::string16& suffix) { | 410 // "Software\Clients\StartMenuInternet\Chromium[.user]\Capabilities". |
| 411 base::string16 GetCapabilitiesKey(BrowserDistribution* dist, | |
| 412 const base::string16& suffix) { | |
| 451 return GetBrowserClientKey(dist, suffix).append(L"\\Capabilities"); | 413 return GetBrowserClientKey(dist, suffix).append(L"\\Capabilities"); |
| 452 } | 414 } |
| 453 | 415 |
| 454 // static | 416 // DelegateExecute ProgId. Needed for Chrome Metro in Windows 8. This is only |
| 455 ScopedVector<RegistryEntry> RegistryEntry::GetChromeDelegateExecuteEntries( | 417 // needed for registring a web browser, not for general associations. |
| 418 ScopedVector<RegistryEntry> GetChromeDelegateExecuteEntries( | |
| 456 const base::FilePath& chrome_exe, | 419 const base::FilePath& chrome_exe, |
| 457 const RegistryEntry::ApplicationInfo& app_info) { | 420 const ApplicationInfo& app_info) { |
| 458 ScopedVector<RegistryEntry> entries; | 421 ScopedVector<RegistryEntry> entries; |
| 459 | 422 |
| 460 base::string16 app_id_shell_key(ShellUtil::kRegClasses); | 423 base::string16 app_id_shell_key(ShellUtil::kRegClasses); |
| 461 app_id_shell_key.push_back(base::FilePath::kSeparators[0]); | 424 app_id_shell_key.push_back(base::FilePath::kSeparators[0]); |
| 462 app_id_shell_key.append(app_info.app_id); | 425 app_id_shell_key.append(app_info.app_id); |
| 463 app_id_shell_key.append(ShellUtil::kRegExePath); | 426 app_id_shell_key.append(ShellUtil::kRegExePath); |
| 464 app_id_shell_key.append(ShellUtil::kRegShellPath); | 427 app_id_shell_key.append(ShellUtil::kRegShellPath); |
| 465 | 428 |
| 466 // <root hkey>\Software\Classes\<app_id>\.exe\shell @=open | 429 // <root hkey>\Software\Classes\<app_id>\.exe\shell @=open |
| 467 entries.push_back( | 430 entries.push_back( |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 505 | 468 |
| 506 // <root hkey>\Software\Classes\<app_id>\.exe\shell\<verb>\command | 469 // <root hkey>\Software\Classes\<app_id>\.exe\shell\<verb>\command |
| 507 entries.push_back(new RegistryEntry(sub_path, delegate_command)); | 470 entries.push_back(new RegistryEntry(sub_path, delegate_command)); |
| 508 entries.push_back(new RegistryEntry( | 471 entries.push_back(new RegistryEntry( |
| 509 sub_path, ShellUtil::kRegDelegateExecute, app_info.delegate_clsid)); | 472 sub_path, ShellUtil::kRegDelegateExecute, app_info.delegate_clsid)); |
| 510 } | 473 } |
| 511 | 474 |
| 512 return entries.Pass(); | 475 return entries.Pass(); |
| 513 } | 476 } |
| 514 | 477 |
| 515 // static | 478 // Gets the registry entries to register an application in the Windows registry. |
| 516 void RegistryEntry::GetChromeProgIdEntries( | 479 // |app_info| provides all of the information needed. |
| 517 BrowserDistribution* dist, | 480 void GetProgIdEntries(const ApplicationInfo& app_info, |
|
Matt Giuca
2015/11/30 03:11:09
Note: This function got swapped with GetChromeProg
| |
| 518 const base::FilePath& chrome_exe, | 481 ScopedVector<RegistryEntry>* entries) { |
| 519 const base::string16& suffix, | |
| 520 ScopedVector<RegistryEntry>* entries) { | |
| 521 int chrome_icon_index = | |
| 522 dist->GetIconIndex(BrowserDistribution::SHORTCUT_CHROME); | |
| 523 | |
| 524 ApplicationInfo app_info; | |
| 525 app_info.prog_id = GetBrowserProgId(suffix); | |
| 526 app_info.file_type_name = dist->GetBrowserProgIdDesc(); | |
| 527 // File types associated with Chrome are just given the Chrome icon. | |
| 528 app_info.file_type_icon_path = chrome_exe; | |
| 529 app_info.file_type_icon_index = chrome_icon_index; | |
| 530 app_info.command_line = ShellUtil::GetChromeShellOpenCmd(chrome_exe); | |
| 531 // For user-level installs: entries for the app id will be in HKCU; thus we | |
| 532 // do not need a suffix on those entries. | |
| 533 app_info.app_id = ShellUtil::GetBrowserModelId( | |
| 534 dist, InstallUtil::IsPerUserInstall(chrome_exe)); | |
| 535 | |
| 536 // TODO(grt): http://crbug.com/75152 Write a reference to a localized | |
| 537 // resource for name, description, and company. | |
| 538 app_info.application_name = dist->GetDisplayName(); | |
| 539 app_info.application_icon_path = chrome_exe; | |
| 540 app_info.application_icon_index = chrome_icon_index; | |
| 541 app_info.application_description = dist->GetAppDescription(); | |
| 542 app_info.publisher_name = dist->GetPublisherName(); | |
| 543 | |
| 544 app_info.delegate_clsid = dist->GetCommandExecuteImplClsid(); | |
| 545 | |
| 546 GetProgIdEntries(app_info, entries); | |
| 547 | |
| 548 if (!app_info.delegate_clsid.empty()) { | |
| 549 ScopedVector<RegistryEntry> delegate_execute_entries = | |
| 550 GetChromeDelegateExecuteEntries(chrome_exe, app_info); | |
| 551 if (!base::win::IsChromeMetroSupported()) { | |
| 552 // Remove the keys (not only their values) so that Windows will continue | |
| 553 // to launch Chrome without a pesky association error. | |
| 554 for (RegistryEntry* entry : delegate_execute_entries) | |
| 555 entry->set_removal_flag(RemovalFlag::KEY); | |
| 556 } | |
| 557 // Move |delegate_execute_entries| to |entries|. | |
| 558 entries->insert(entries->end(), delegate_execute_entries.begin(), | |
| 559 delegate_execute_entries.end()); | |
| 560 delegate_execute_entries.weak_clear(); | |
| 561 } | |
| 562 } | |
| 563 | |
| 564 // static | |
| 565 void RegistryEntry::GetProgIdEntries( | |
| 566 const RegistryEntry::ApplicationInfo& app_info, | |
| 567 ScopedVector<RegistryEntry>* entries) { | |
| 568 // Basic sanity checks. | 482 // Basic sanity checks. |
| 569 DCHECK(!app_info.prog_id.empty()); | 483 DCHECK(!app_info.prog_id.empty()); |
| 570 DCHECK_NE(L'.', app_info.prog_id[0]); | 484 DCHECK_NE(L'.', app_info.prog_id[0]); |
| 571 | 485 |
| 572 // File association ProgId | 486 // File association ProgId |
| 573 base::string16 prog_id_path(ShellUtil::kRegClasses); | 487 base::string16 prog_id_path(ShellUtil::kRegClasses); |
| 574 prog_id_path.push_back(base::FilePath::kSeparators[0]); | 488 prog_id_path.push_back(base::FilePath::kSeparators[0]); |
| 575 prog_id_path.append(app_info.prog_id); | 489 prog_id_path.append(app_info.prog_id); |
| 576 entries->push_back(new RegistryEntry(prog_id_path, app_info.file_type_name)); | 490 entries->push_back(new RegistryEntry(prog_id_path, app_info.file_type_name)); |
| 577 entries->push_back(new RegistryEntry( | 491 entries->push_back(new RegistryEntry( |
| 578 prog_id_path + ShellUtil::kRegDefaultIcon, | 492 prog_id_path + ShellUtil::kRegDefaultIcon, |
| 579 ShellUtil::FormatIconLocation(app_info.file_type_icon_path, | 493 ShellUtil::FormatIconLocation(app_info.file_type_icon_path, |
| 580 app_info.file_type_icon_index))); | 494 app_info.file_type_icon_index))); |
| 581 entries->push_back(new RegistryEntry(prog_id_path + ShellUtil::kRegShellOpen, | 495 entries->push_back(new RegistryEntry(prog_id_path + ShellUtil::kRegShellOpen, |
| 582 app_info.command_line)); | 496 app_info.command_line)); |
| 583 if (!app_info.delegate_clsid.empty()) { | 497 if (!app_info.delegate_clsid.empty()) { |
| 584 entries->push_back(new RegistryEntry( | 498 entries->push_back(new RegistryEntry( |
| 585 prog_id_path + ShellUtil::kRegShellOpen, ShellUtil::kRegDelegateExecute, | 499 prog_id_path + ShellUtil::kRegShellOpen, ShellUtil::kRegDelegateExecute, |
| 586 app_info.delegate_clsid)); | 500 app_info.delegate_clsid)); |
| 587 // If Metro is not supported, remove the DelegateExecute entry instead of | 501 // If Metro is not supported, remove the DelegateExecute entry instead of |
| 588 // adding it. | 502 // adding it. |
| 589 if (!base::win::IsChromeMetroSupported()) | 503 if (!base::win::IsChromeMetroSupported()) |
| 590 entries->back()->set_removal_flag(RemovalFlag::VALUE); | 504 entries->back()->set_removal_flag(RegistryEntry::RemovalFlag::VALUE); |
| 591 } | 505 } |
| 592 | 506 |
| 593 // The following entries are required as of Windows 8, but do not | 507 // The following entries are required as of Windows 8, but do not |
| 594 // depend on the DelegateExecute verb handler being set. | 508 // depend on the DelegateExecute verb handler being set. |
| 595 if (base::win::GetVersion() >= base::win::VERSION_WIN8) { | 509 if (base::win::GetVersion() >= base::win::VERSION_WIN8) { |
| 596 if (!app_info.app_id.empty()) { | 510 if (!app_info.app_id.empty()) { |
| 597 entries->push_back(new RegistryEntry( | 511 entries->push_back(new RegistryEntry( |
| 598 prog_id_path, ShellUtil::kRegAppUserModelId, app_info.app_id)); | 512 prog_id_path, ShellUtil::kRegAppUserModelId, app_info.app_id)); |
| 599 } | 513 } |
| 600 | 514 |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 621 app_info.application_description)); | 535 app_info.application_description)); |
| 622 } | 536 } |
| 623 if (!app_info.publisher_name.empty()) { | 537 if (!app_info.publisher_name.empty()) { |
| 624 entries->push_back(new RegistryEntry(application_path, | 538 entries->push_back(new RegistryEntry(application_path, |
| 625 ShellUtil::kRegApplicationCompany, | 539 ShellUtil::kRegApplicationCompany, |
| 626 app_info.publisher_name)); | 540 app_info.publisher_name)); |
| 627 } | 541 } |
| 628 } | 542 } |
| 629 } | 543 } |
| 630 | 544 |
| 631 // static | 545 // This method returns a list of all the registry entries that are needed to |
| 632 void RegistryEntry::GetProtocolCapabilityEntries( | 546 // register this installation's ProgId and AppId. These entries need to be |
| 633 BrowserDistribution* dist, | 547 // registered in HKLM prior to Win8. |
| 634 const base::string16& suffix, | 548 void GetChromeProgIdEntries(BrowserDistribution* dist, |
| 635 const base::string16& protocol, | 549 const base::FilePath& chrome_exe, |
| 636 ScopedVector<RegistryEntry>* entries) { | 550 const base::string16& suffix, |
| 551 ScopedVector<RegistryEntry>* entries) { | |
| 552 int chrome_icon_index = | |
| 553 dist->GetIconIndex(BrowserDistribution::SHORTCUT_CHROME); | |
| 554 | |
| 555 ApplicationInfo app_info; | |
| 556 app_info.prog_id = GetBrowserProgId(suffix); | |
| 557 app_info.file_type_name = dist->GetBrowserProgIdDesc(); | |
| 558 // File types associated with Chrome are just given the Chrome icon. | |
| 559 app_info.file_type_icon_path = chrome_exe; | |
| 560 app_info.file_type_icon_index = chrome_icon_index; | |
| 561 app_info.command_line = ShellUtil::GetChromeShellOpenCmd(chrome_exe); | |
| 562 // For user-level installs: entries for the app id will be in HKCU; thus we | |
| 563 // do not need a suffix on those entries. | |
| 564 app_info.app_id = ShellUtil::GetBrowserModelId( | |
| 565 dist, InstallUtil::IsPerUserInstall(chrome_exe)); | |
| 566 | |
| 567 // TODO(grt): http://crbug.com/75152 Write a reference to a localized | |
| 568 // resource for name, description, and company. | |
| 569 app_info.application_name = dist->GetDisplayName(); | |
| 570 app_info.application_icon_path = chrome_exe; | |
| 571 app_info.application_icon_index = chrome_icon_index; | |
| 572 app_info.application_description = dist->GetAppDescription(); | |
| 573 app_info.publisher_name = dist->GetPublisherName(); | |
| 574 | |
| 575 app_info.delegate_clsid = dist->GetCommandExecuteImplClsid(); | |
| 576 | |
| 577 GetProgIdEntries(app_info, entries); | |
| 578 | |
| 579 if (!app_info.delegate_clsid.empty()) { | |
| 580 ScopedVector<RegistryEntry> delegate_execute_entries = | |
| 581 GetChromeDelegateExecuteEntries(chrome_exe, app_info); | |
| 582 if (!base::win::IsChromeMetroSupported()) { | |
| 583 // Remove the keys (not only their values) so that Windows will continue | |
| 584 // to launch Chrome without a pesky association error. | |
| 585 for (RegistryEntry* entry : delegate_execute_entries) | |
| 586 entry->set_removal_flag(RegistryEntry::RemovalFlag::KEY); | |
| 587 } | |
| 588 // Move |delegate_execute_entries| to |entries|. | |
| 589 entries->insert(entries->end(), delegate_execute_entries.begin(), | |
| 590 delegate_execute_entries.end()); | |
| 591 delegate_execute_entries.weak_clear(); | |
| 592 } | |
| 593 } | |
| 594 | |
| 595 // This method returns a list of the registry entries needed to declare a | |
| 596 // capability of handling a protocol on Windows. | |
| 597 void GetProtocolCapabilityEntries(BrowserDistribution* dist, | |
| 598 const base::string16& suffix, | |
| 599 const base::string16& protocol, | |
| 600 ScopedVector<RegistryEntry>* entries) { | |
| 637 entries->push_back(new RegistryEntry( | 601 entries->push_back(new RegistryEntry( |
| 638 GetCapabilitiesKey(dist, suffix).append(L"\\URLAssociations"), protocol, | 602 GetCapabilitiesKey(dist, suffix).append(L"\\URLAssociations"), protocol, |
| 639 GetBrowserProgId(suffix))); | 603 GetBrowserProgId(suffix))); |
| 640 } | 604 } |
| 641 | 605 |
| 642 // static | 606 // This method returns a list of the registry entries required to register this |
| 643 void RegistryEntry::GetShellIntegrationEntries( | 607 // installation in "RegisteredApplications" on Windows (to appear in Default |
| 644 BrowserDistribution* dist, | 608 // Programs, StartMenuInternet, etc.). These entries need to be registered in |
| 645 const base::FilePath& chrome_exe, | 609 // HKLM prior to Win8. If |suffix| is not empty, these entries are guaranteed to |
| 646 const base::string16& suffix, | 610 // be unique on this machine. |
| 647 ScopedVector<RegistryEntry>* entries) { | 611 void GetShellIntegrationEntries(BrowserDistribution* dist, |
| 612 const base::FilePath& chrome_exe, | |
| 613 const base::string16& suffix, | |
| 614 ScopedVector<RegistryEntry>* entries) { | |
| 648 const base::string16 icon_path(ShellUtil::FormatIconLocation( | 615 const base::string16 icon_path(ShellUtil::FormatIconLocation( |
| 649 chrome_exe, dist->GetIconIndex(BrowserDistribution::SHORTCUT_CHROME))); | 616 chrome_exe, dist->GetIconIndex(BrowserDistribution::SHORTCUT_CHROME))); |
| 650 const base::string16 quoted_exe_path(L"\"" + chrome_exe.value() + L"\""); | 617 const base::string16 quoted_exe_path(L"\"" + chrome_exe.value() + L"\""); |
| 651 | 618 |
| 652 // Register for the Start Menu "Internet" link (pre-Win7). | 619 // Register for the Start Menu "Internet" link (pre-Win7). |
| 653 const base::string16 start_menu_entry(GetBrowserClientKey(dist, suffix)); | 620 const base::string16 start_menu_entry(GetBrowserClientKey(dist, suffix)); |
| 654 // Register Chrome's display name. | 621 // Register Chrome's display name. |
| 655 // TODO(grt): http://crbug.com/75152 Also set LocalizedString; see | 622 // TODO(grt): http://crbug.com/75152 Also set LocalizedString; see |
| 656 // http://msdn.microsoft.com/en-us/library/windows/desktop/cc144109(v=VS.85).a spx#registering_the_display_name | 623 // http://msdn.microsoft.com/en-us/library/windows/desktop/cc144109(v=VS.85).a spx#registering_the_display_name |
| 657 entries->push_back( | 624 entries->push_back( |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 705 capabilities + L"\\FileAssociations", | 672 capabilities + L"\\FileAssociations", |
| 706 ShellUtil::kPotentialFileAssociations[i], html_prog_id)); | 673 ShellUtil::kPotentialFileAssociations[i], html_prog_id)); |
| 707 } | 674 } |
| 708 for (int i = 0; ShellUtil::kPotentialProtocolAssociations[i] != NULL; i++) { | 675 for (int i = 0; ShellUtil::kPotentialProtocolAssociations[i] != NULL; i++) { |
| 709 entries->push_back(new RegistryEntry( | 676 entries->push_back(new RegistryEntry( |
| 710 capabilities + L"\\URLAssociations", | 677 capabilities + L"\\URLAssociations", |
| 711 ShellUtil::kPotentialProtocolAssociations[i], html_prog_id)); | 678 ShellUtil::kPotentialProtocolAssociations[i], html_prog_id)); |
| 712 } | 679 } |
| 713 } | 680 } |
| 714 | 681 |
| 715 // static | 682 // Gets the registry entries to register an application as a handler for a |
| 716 void RegistryEntry::GetChromeAppRegistrationEntries( | 683 // particular file extension. |prog_id| is the ProgId used by Windows for the |
| 717 const base::FilePath& chrome_exe, | 684 // application. |ext| is the file extension, which must begin with a '.'. |
| 718 const base::string16& suffix, | 685 void GetAppExtRegistrationEntries(const base::string16& prog_id, |
|
Matt Giuca
2015/11/30 03:11:09
Note: This function got swapped with GetChromeAppR
| |
| 719 ScopedVector<RegistryEntry>* entries) { | 686 const base::string16& ext, |
| 687 ScopedVector<RegistryEntry>* entries) { | |
| 688 // In HKEY_CURRENT_USER\Software\Classes\EXT\OpenWithProgids, create an | |
| 689 // empty value with this class's ProgId. | |
| 690 base::string16 key_name(ShellUtil::kRegClasses); | |
| 691 key_name.push_back(base::FilePath::kSeparators[0]); | |
| 692 key_name.append(ext); | |
| 693 key_name.push_back(base::FilePath::kSeparators[0]); | |
| 694 key_name.append(ShellUtil::kRegOpenWithProgids); | |
| 695 entries->push_back(new RegistryEntry(key_name, prog_id, base::string16())); | |
| 696 } | |
| 697 | |
| 698 // This method returns a list of the registry entries required for this | |
| 699 // installation to be registered in the Windows shell. | |
| 700 // In particular: | |
| 701 // - App Paths | |
| 702 // http://msdn.microsoft.com/en-us/library/windows/desktop/ee872121 | |
| 703 // - File Associations | |
| 704 // http://msdn.microsoft.com/en-us/library/bb166549 | |
| 705 // These entries need to be registered in HKLM prior to Win8. | |
| 706 void GetChromeAppRegistrationEntries(const base::FilePath& chrome_exe, | |
| 707 const base::string16& suffix, | |
| 708 ScopedVector<RegistryEntry>* entries) { | |
| 720 base::string16 app_path_key(ShellUtil::kAppPathsRegistryKey); | 709 base::string16 app_path_key(ShellUtil::kAppPathsRegistryKey); |
| 721 app_path_key.push_back(base::FilePath::kSeparators[0]); | 710 app_path_key.push_back(base::FilePath::kSeparators[0]); |
| 722 app_path_key.append(chrome_exe.BaseName().value()); | 711 app_path_key.append(chrome_exe.BaseName().value()); |
| 723 entries->push_back(new RegistryEntry(app_path_key, chrome_exe.value())); | 712 entries->push_back(new RegistryEntry(app_path_key, chrome_exe.value())); |
| 724 entries->push_back(new RegistryEntry(app_path_key, | 713 entries->push_back(new RegistryEntry(app_path_key, |
| 725 ShellUtil::kAppPathsRegistryPathName, | 714 ShellUtil::kAppPathsRegistryPathName, |
| 726 chrome_exe.DirName().value())); | 715 chrome_exe.DirName().value())); |
| 727 | 716 |
| 728 const base::string16 html_prog_id(GetBrowserProgId(suffix)); | 717 const base::string16 html_prog_id(GetBrowserProgId(suffix)); |
| 729 for (int i = 0; ShellUtil::kPotentialFileAssociations[i] != NULL; i++) { | 718 for (int i = 0; ShellUtil::kPotentialFileAssociations[i] != NULL; i++) { |
| 730 GetAppExtRegistrationEntries( | 719 GetAppExtRegistrationEntries( |
| 731 html_prog_id, ShellUtil::kPotentialFileAssociations[i], entries); | 720 html_prog_id, ShellUtil::kPotentialFileAssociations[i], entries); |
| 732 } | 721 } |
| 733 } | 722 } |
| 734 | 723 |
| 735 // static | 724 // Gets the registry entries to register an application as the default handler |
| 736 void RegistryEntry::GetAppExtRegistrationEntries( | 725 // for a particular file extension. |prog_id| is the ProgId used by Windows for |
| 737 const base::string16& prog_id, | 726 // the application. |ext| is the file extension, which must begin with a '.'. If |
| 738 const base::string16& ext, | 727 // |overwrite_existing|, always sets the default handler; otherwise only sets if |
| 739 ScopedVector<RegistryEntry>* entries) { | 728 // there is no existing default. |
| 740 // In HKEY_CURRENT_USER\Software\Classes\EXT\OpenWithProgids, create an | 729 // |
| 741 // empty value with this class's ProgId. | 730 // This has no effect on Windows 8. Windows 8 ignores the default and lets the |
| 742 base::string16 key_name(ShellUtil::kRegClasses); | 731 // user choose. If there is only one handler for a file, it will automatically |
| 743 key_name.push_back(base::FilePath::kSeparators[0]); | 732 // become the default. Otherwise, the first time the user opens a file, they are |
| 744 key_name.append(ext); | 733 // presented with the dialog to set the default handler. (This is roughly |
| 745 key_name.push_back(base::FilePath::kSeparators[0]); | 734 // equivalent to being called with |overwrite_existing| false.) |
| 746 key_name.append(ShellUtil::kRegOpenWithProgids); | 735 void GetAppDefaultRegistrationEntries(const base::string16& prog_id, |
| 747 entries->push_back(new RegistryEntry(key_name, prog_id, base::string16())); | 736 const base::string16& ext, |
| 748 } | 737 bool overwrite_existing, |
| 749 | 738 ScopedVector<RegistryEntry>* entries) { |
| 750 // static | |
| 751 void RegistryEntry::GetAppDefaultRegistrationEntries( | |
| 752 const base::string16& prog_id, | |
| 753 const base::string16& ext, | |
| 754 bool overwrite_existing, | |
| 755 ScopedVector<RegistryEntry>* entries) { | |
| 756 // Set the default value of HKEY_CURRENT_USER\Software\Classes\EXT to this | 739 // Set the default value of HKEY_CURRENT_USER\Software\Classes\EXT to this |
| 757 // class's name. | 740 // class's name. |
| 758 base::string16 key_name(ShellUtil::kRegClasses); | 741 base::string16 key_name(ShellUtil::kRegClasses); |
| 759 key_name.push_back(base::FilePath::kSeparators[0]); | 742 key_name.push_back(base::FilePath::kSeparators[0]); |
| 760 key_name.append(ext); | 743 key_name.append(ext); |
| 761 scoped_ptr<RegistryEntry> default_association( | 744 scoped_ptr<RegistryEntry> default_association( |
| 762 new RegistryEntry(key_name, prog_id)); | 745 new RegistryEntry(key_name, prog_id)); |
| 763 if (overwrite_existing || | 746 if (overwrite_existing || |
| 764 !default_association->KeyExistsInRegistry(RegistryEntry::LOOK_IN_HKCU)) { | 747 !default_association->KeyExistsInRegistry(RegistryEntry::LOOK_IN_HKCU)) { |
| 765 entries->push_back(default_association.release()); | 748 entries->push_back(default_association.release()); |
| 766 } | 749 } |
| 767 } | 750 } |
| 768 | 751 |
| 769 // static | 752 // This method returns a list of all the user level registry entries that are |
| 770 void RegistryEntry::GetXPStyleUserProtocolEntries( | 753 // needed to make Chromium the default handler for a protocol on XP. |
| 771 const base::string16& protocol, | 754 void GetXPStyleUserProtocolEntries(const base::string16& protocol, |
| 772 const base::string16& chrome_icon, | 755 const base::string16& chrome_icon, |
| 773 const base::string16& chrome_open, | 756 const base::string16& chrome_open, |
| 774 ScopedVector<RegistryEntry>* entries) { | 757 ScopedVector<RegistryEntry>* entries) { |
| 775 // Protocols associations. | 758 // Protocols associations. |
| 776 base::string16 url_key(ShellUtil::kRegClasses); | 759 base::string16 url_key(ShellUtil::kRegClasses); |
| 777 url_key.push_back(base::FilePath::kSeparators[0]); | 760 url_key.push_back(base::FilePath::kSeparators[0]); |
| 778 url_key.append(protocol); | 761 url_key.append(protocol); |
| 779 | 762 |
| 780 // This registry value tells Windows that this 'class' is a URL scheme | 763 // This registry value tells Windows that this 'class' is a URL scheme |
| 781 // so IE, explorer and other apps will route it to our handler. | 764 // so IE, explorer and other apps will route it to our handler. |
| 782 // <root hkey>\Software\Classes\<protocol>\URL Protocol | 765 // <root hkey>\Software\Classes\<protocol>\URL Protocol |
| 783 entries->push_back( | 766 entries->push_back( |
| 784 new RegistryEntry(url_key, ShellUtil::kRegUrlProtocol, base::string16())); | 767 new RegistryEntry(url_key, ShellUtil::kRegUrlProtocol, base::string16())); |
| 785 | 768 |
| 786 // <root hkey>\Software\Classes\<protocol>\DefaultIcon | 769 // <root hkey>\Software\Classes\<protocol>\DefaultIcon |
| 787 base::string16 icon_key = url_key + ShellUtil::kRegDefaultIcon; | 770 base::string16 icon_key = url_key + ShellUtil::kRegDefaultIcon; |
| 788 entries->push_back(new RegistryEntry(icon_key, chrome_icon)); | 771 entries->push_back(new RegistryEntry(icon_key, chrome_icon)); |
| 789 | 772 |
| 790 // <root hkey>\Software\Classes\<protocol>\shell\open\command | 773 // <root hkey>\Software\Classes\<protocol>\shell\open\command |
| 791 base::string16 shell_key = url_key + ShellUtil::kRegShellOpen; | 774 base::string16 shell_key = url_key + ShellUtil::kRegShellOpen; |
| 792 entries->push_back(new RegistryEntry(shell_key, chrome_open)); | 775 entries->push_back(new RegistryEntry(shell_key, chrome_open)); |
| 793 | 776 |
| 794 // <root hkey>\Software\Classes\<protocol>\shell\open\ddeexec | 777 // <root hkey>\Software\Classes\<protocol>\shell\open\ddeexec |
| 795 base::string16 dde_key = url_key + L"\\shell\\open\\ddeexec"; | 778 base::string16 dde_key = url_key + L"\\shell\\open\\ddeexec"; |
| 796 entries->push_back(new RegistryEntry(dde_key, base::string16())); | 779 entries->push_back(new RegistryEntry(dde_key, base::string16())); |
| 797 | 780 |
| 798 // <root hkey>\Software\Classes\<protocol>\shell\@ | 781 // <root hkey>\Software\Classes\<protocol>\shell\@ |
| 799 base::string16 protocol_shell_key = url_key + ShellUtil::kRegShellPath; | 782 base::string16 protocol_shell_key = url_key + ShellUtil::kRegShellPath; |
| 800 entries->push_back(new RegistryEntry(protocol_shell_key, L"open")); | 783 entries->push_back(new RegistryEntry(protocol_shell_key, L"open")); |
| 801 } | 784 } |
| 802 | 785 |
| 803 // static | 786 // This method returns a list of all the user level registry entries that are |
| 804 void RegistryEntry::GetXPStyleDefaultBrowserUserEntries( | 787 // needed to make Chromium default browser on XP. Some of these entries are |
| 805 BrowserDistribution* dist, | 788 // irrelevant in recent versions of Windows, but we register them anyways as |
| 806 const base::FilePath& chrome_exe, | 789 // some legacy apps are hardcoded to lookup those values. |
| 807 const base::string16& suffix, | 790 void GetXPStyleDefaultBrowserUserEntries(BrowserDistribution* dist, |
| 808 ScopedVector<RegistryEntry>* entries) { | 791 const base::FilePath& chrome_exe, |
| 792 const base::string16& suffix, | |
| 793 ScopedVector<RegistryEntry>* entries) { | |
| 809 // File extension associations. | 794 // File extension associations. |
| 810 base::string16 html_prog_id(GetBrowserProgId(suffix)); | 795 base::string16 html_prog_id(GetBrowserProgId(suffix)); |
| 811 for (int i = 0; ShellUtil::kDefaultFileAssociations[i] != NULL; i++) { | 796 for (int i = 0; ShellUtil::kDefaultFileAssociations[i] != NULL; i++) { |
| 812 GetAppDefaultRegistrationEntries( | 797 GetAppDefaultRegistrationEntries( |
| 813 html_prog_id, ShellUtil::kDefaultFileAssociations[i], true, entries); | 798 html_prog_id, ShellUtil::kDefaultFileAssociations[i], true, entries); |
| 814 } | 799 } |
| 815 | 800 |
| 816 // Protocols associations. | 801 // Protocols associations. |
| 817 base::string16 chrome_open = ShellUtil::GetChromeShellOpenCmd(chrome_exe); | 802 base::string16 chrome_open = ShellUtil::GetChromeShellOpenCmd(chrome_exe); |
| 818 base::string16 chrome_icon = ShellUtil::FormatIconLocation( | 803 base::string16 chrome_icon = ShellUtil::FormatIconLocation( |
| 819 chrome_exe, dist->GetIconIndex(BrowserDistribution::SHORTCUT_CHROME)); | 804 chrome_exe, dist->GetIconIndex(BrowserDistribution::SHORTCUT_CHROME)); |
| 820 for (int i = 0; ShellUtil::kBrowserProtocolAssociations[i] != NULL; i++) { | 805 for (int i = 0; ShellUtil::kBrowserProtocolAssociations[i] != NULL; i++) { |
| 821 GetXPStyleUserProtocolEntries(ShellUtil::kBrowserProtocolAssociations[i], | 806 GetXPStyleUserProtocolEntries(ShellUtil::kBrowserProtocolAssociations[i], |
| 822 chrome_icon, chrome_open, entries); | 807 chrome_icon, chrome_open, entries); |
| 823 } | 808 } |
| 824 | 809 |
| 825 // start->Internet shortcut. | 810 // start->Internet shortcut. |
| 826 base::string16 start_menu(ShellUtil::kRegStartMenuInternet); | 811 base::string16 start_menu(ShellUtil::kRegStartMenuInternet); |
| 827 base::string16 app_name = dist->GetBaseAppName() + suffix; | 812 base::string16 app_name = dist->GetBaseAppName() + suffix; |
| 828 entries->push_back(new RegistryEntry(start_menu, app_name)); | 813 entries->push_back(new RegistryEntry(start_menu, app_name)); |
| 829 } | 814 } |
| 830 | 815 |
| 831 void RegistryEntry::AddToWorkItemList(HKEY root, WorkItemList* items) const { | |
| 832 if (removal_flag_ == RemovalFlag::VALUE) { | |
| 833 items->AddDeleteRegValueWorkItem(root, key_path_, WorkItem::kWow64Default, | |
| 834 name_); | |
| 835 } else if (removal_flag_ == RemovalFlag::KEY) { | |
| 836 items->AddDeleteRegKeyWorkItem(root, key_path_, WorkItem::kWow64Default); | |
| 837 } else { | |
| 838 DCHECK(removal_flag_ == RemovalFlag::NONE); | |
| 839 items->AddCreateRegKeyWorkItem(root, key_path_, WorkItem::kWow64Default); | |
| 840 if (is_string_) { | |
| 841 items->AddSetRegValueWorkItem(root, key_path_, WorkItem::kWow64Default, | |
| 842 name_, value_, true); | |
| 843 } else { | |
| 844 items->AddSetRegValueWorkItem(root, key_path_, WorkItem::kWow64Default, | |
| 845 name_, int_value_, true); | |
| 846 } | |
| 847 } | |
| 848 } | |
| 849 | |
| 850 bool RegistryEntry::ExistsInRegistry(uint32 look_for_in) const { | |
| 851 DCHECK(look_for_in); | |
| 852 | |
| 853 RegistryStatus status = DOES_NOT_EXIST; | |
| 854 if (look_for_in & LOOK_IN_HKCU) | |
| 855 status = StatusInRegistryUnderRoot(HKEY_CURRENT_USER); | |
| 856 if (status == DOES_NOT_EXIST && (look_for_in & LOOK_IN_HKLM)) | |
| 857 status = StatusInRegistryUnderRoot(HKEY_LOCAL_MACHINE); | |
| 858 return status == SAME_VALUE; | |
| 859 } | |
| 860 | |
| 861 bool RegistryEntry::KeyExistsInRegistry(uint32 look_for_in) const { | |
| 862 DCHECK(look_for_in); | |
| 863 | |
| 864 RegistryStatus status = DOES_NOT_EXIST; | |
| 865 if (look_for_in & LOOK_IN_HKCU) | |
| 866 status = StatusInRegistryUnderRoot(HKEY_CURRENT_USER); | |
| 867 if (status == DOES_NOT_EXIST && (look_for_in & LOOK_IN_HKLM)) | |
| 868 status = StatusInRegistryUnderRoot(HKEY_LOCAL_MACHINE); | |
| 869 return status != DOES_NOT_EXIST; | |
| 870 } | |
| 871 | |
| 872 RegistryEntry::RegistryStatus RegistryEntry::StatusInRegistryUnderRoot( | |
| 873 HKEY root) const { | |
| 874 RegKey key(root, key_path_.c_str(), KEY_QUERY_VALUE); | |
| 875 bool found = false; | |
| 876 bool correct_value = false; | |
| 877 if (is_string_) { | |
| 878 base::string16 read_value; | |
| 879 found = key.ReadValue(name_.c_str(), &read_value) == ERROR_SUCCESS; | |
| 880 if (found) { | |
| 881 correct_value = | |
| 882 read_value.size() == value_.size() && | |
| 883 ::CompareString( | |
| 884 LOCALE_USER_DEFAULT, NORM_IGNORECASE, read_value.data(), | |
| 885 base::saturated_cast<int>(read_value.size()), value_.data(), | |
| 886 base::saturated_cast<int>(value_.size())) == CSTR_EQUAL; | |
| 887 } | |
| 888 } else { | |
| 889 DWORD read_value; | |
| 890 found = key.ReadValueDW(name_.c_str(), &read_value) == ERROR_SUCCESS; | |
| 891 if (found) | |
| 892 correct_value = read_value == int_value_; | |
| 893 } | |
| 894 return found ? (correct_value ? SAME_VALUE : DIFFERENT_VALUE) | |
| 895 : DOES_NOT_EXIST; | |
| 896 } | |
| 897 | |
| 898 // This method converts all the RegistryEntries from the given list to | 816 // This method converts all the RegistryEntries from the given list to |
| 899 // Set/CreateRegWorkItems and runs them using WorkItemList. | 817 // Set/CreateRegWorkItems and runs them using WorkItemList. |
| 900 bool AddRegistryEntries(HKEY root, const ScopedVector<RegistryEntry>& entries) { | 818 bool AddRegistryEntries(HKEY root, const ScopedVector<RegistryEntry>& entries) { |
| 901 scoped_ptr<WorkItemList> items(WorkItem::CreateWorkItemList()); | 819 scoped_ptr<WorkItemList> items(WorkItem::CreateWorkItemList()); |
| 902 | 820 |
| 903 for (ScopedVector<RegistryEntry>::const_iterator itr = entries.begin(); | 821 for (ScopedVector<RegistryEntry>::const_iterator itr = entries.begin(); |
| 904 itr != entries.end(); ++itr) | 822 itr != entries.end(); ++itr) |
| 905 (*itr)->AddToWorkItemList(root, items.get()); | 823 (*itr)->AddToWorkItemList(root, items.get()); |
| 906 | 824 |
| 907 // Apply all the registry changes and if there is a problem, rollback | 825 // Apply all the registry changes and if there is a problem, rollback |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 932 // under a single registry root. Not doing so caused http://crbug.com/144910 for | 850 // under a single registry root. Not doing so caused http://crbug.com/144910 for |
| 933 // users who first-installed Chrome in that revision range (those users are | 851 // users who first-installed Chrome in that revision range (those users are |
| 934 // still impacted by http://crbug.com/144910). This method will keep returning | 852 // still impacted by http://crbug.com/144910). This method will keep returning |
| 935 // true for affected users (i.e. who have all the registrations, but over both | 853 // true for affected users (i.e. who have all the registrations, but over both |
| 936 // registry roots). | 854 // registry roots). |
| 937 bool IsChromeRegistered(BrowserDistribution* dist, | 855 bool IsChromeRegistered(BrowserDistribution* dist, |
| 938 const base::FilePath& chrome_exe, | 856 const base::FilePath& chrome_exe, |
| 939 const base::string16& suffix, | 857 const base::string16& suffix, |
| 940 uint32 look_for_in) { | 858 uint32 look_for_in) { |
| 941 ScopedVector<RegistryEntry> entries; | 859 ScopedVector<RegistryEntry> entries; |
| 942 RegistryEntry::GetChromeProgIdEntries(dist, chrome_exe, suffix, &entries); | 860 GetChromeProgIdEntries(dist, chrome_exe, suffix, &entries); |
| 943 RegistryEntry::GetShellIntegrationEntries(dist, chrome_exe, suffix, &entries); | 861 GetShellIntegrationEntries(dist, chrome_exe, suffix, &entries); |
| 944 RegistryEntry::GetChromeAppRegistrationEntries(chrome_exe, suffix, &entries); | 862 GetChromeAppRegistrationEntries(chrome_exe, suffix, &entries); |
| 945 return AreEntriesAsDesired(entries, look_for_in); | 863 return AreEntriesAsDesired(entries, look_for_in); |
| 946 } | 864 } |
| 947 | 865 |
| 948 // This method checks if Chrome is already registered on the local machine | 866 // This method checks if Chrome is already registered on the local machine |
| 949 // for the requested protocol. It just checks the one value required for this. | 867 // for the requested protocol. It just checks the one value required for this. |
| 950 // See RegistryEntry::ExistsInRegistry for the behavior of |look_for_in|. | 868 // See RegistryEntry::ExistsInRegistry for the behavior of |look_for_in|. |
| 951 bool IsChromeRegisteredForProtocol(BrowserDistribution* dist, | 869 bool IsChromeRegisteredForProtocol(BrowserDistribution* dist, |
| 952 const base::string16& suffix, | 870 const base::string16& suffix, |
| 953 const base::string16& protocol, | 871 const base::string16& protocol, |
| 954 uint32 look_for_in) { | 872 uint32 look_for_in) { |
| 955 ScopedVector<RegistryEntry> entries; | 873 ScopedVector<RegistryEntry> entries; |
| 956 RegistryEntry::GetProtocolCapabilityEntries(dist, suffix, protocol, &entries); | 874 GetProtocolCapabilityEntries(dist, suffix, protocol, &entries); |
| 957 return AreEntriesAsDesired(entries, look_for_in); | 875 return AreEntriesAsDesired(entries, look_for_in); |
| 958 } | 876 } |
| 959 | 877 |
| 960 // This method registers Chrome on Vista by launching an elevated setup.exe. | 878 // This method registers Chrome on Vista by launching an elevated setup.exe. |
| 961 // That will show the user the standard Vista elevation prompt. If the user | 879 // That will show the user the standard Vista elevation prompt. If the user |
| 962 // accepts it the new process will make the necessary changes and return SUCCESS | 880 // accepts it the new process will make the necessary changes and return SUCCESS |
| 963 // that we capture and return. | 881 // that we capture and return. |
| 964 // If protocol is non-empty we will also register Chrome as being capable of | 882 // If protocol is non-empty we will also register Chrome as being capable of |
| 965 // handling the protocol. | 883 // handling the protocol. |
| 966 bool ElevateAndRegisterChrome(BrowserDistribution* dist, | 884 bool ElevateAndRegisterChrome(BrowserDistribution* dist, |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1067 case CONFIRM_PROGID_REGISTRATION: | 985 case CONFIRM_PROGID_REGISTRATION: |
| 1068 // Software\Classes\ChromeHTML|suffix| | 986 // Software\Classes\ChromeHTML|suffix| |
| 1069 reg_key = ShellUtil::kRegClasses; | 987 reg_key = ShellUtil::kRegClasses; |
| 1070 reg_key.push_back(base::FilePath::kSeparators[0]); | 988 reg_key.push_back(base::FilePath::kSeparators[0]); |
| 1071 reg_key.append(dist->GetBrowserProgIdPrefix()); | 989 reg_key.append(dist->GetBrowserProgIdPrefix()); |
| 1072 reg_key.append(suffix); | 990 reg_key.append(suffix); |
| 1073 break; | 991 break; |
| 1074 case CONFIRM_SHELL_REGISTRATION: | 992 case CONFIRM_SHELL_REGISTRATION: |
| 1075 case CONFIRM_SHELL_REGISTRATION_IN_HKLM: | 993 case CONFIRM_SHELL_REGISTRATION_IN_HKLM: |
| 1076 // Software\Clients\StartMenuInternet\Google Chrome|suffix| | 994 // Software\Clients\StartMenuInternet\Google Chrome|suffix| |
| 1077 reg_key = RegistryEntry::GetBrowserClientKey(dist, suffix); | 995 reg_key = GetBrowserClientKey(dist, suffix); |
| 1078 break; | 996 break; |
| 1079 default: | 997 default: |
| 1080 NOTREACHED(); | 998 NOTREACHED(); |
| 1081 break; | 999 break; |
| 1082 } | 1000 } |
| 1083 reg_key.append(ShellUtil::kRegShellOpen); | 1001 reg_key.append(ShellUtil::kRegShellOpen); |
| 1084 | 1002 |
| 1085 // ProgId registrations are allowed to reside in HKCU for user-level installs | 1003 // ProgId registrations are allowed to reside in HKCU for user-level installs |
| 1086 // (and values there have priority over values in HKLM). The same is true for | 1004 // (and values there have priority over values in HKLM). The same is true for |
| 1087 // shell integration entries as of Windows 8. | 1005 // shell integration entries as of Windows 8. |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1149 } | 1067 } |
| 1150 | 1068 |
| 1151 // Associates Chrome with supported protocols and file associations. This should | 1069 // Associates Chrome with supported protocols and file associations. This should |
| 1152 // not be required on Vista+ but since some applications still read | 1070 // not be required on Vista+ but since some applications still read |
| 1153 // Software\Classes\http key directly, we have to do this on Vista+ as well. | 1071 // Software\Classes\http key directly, we have to do this on Vista+ as well. |
| 1154 bool RegisterChromeAsDefaultXPStyle(BrowserDistribution* dist, | 1072 bool RegisterChromeAsDefaultXPStyle(BrowserDistribution* dist, |
| 1155 int shell_change, | 1073 int shell_change, |
| 1156 const base::FilePath& chrome_exe) { | 1074 const base::FilePath& chrome_exe) { |
| 1157 bool ret = true; | 1075 bool ret = true; |
| 1158 ScopedVector<RegistryEntry> entries; | 1076 ScopedVector<RegistryEntry> entries; |
| 1159 RegistryEntry::GetXPStyleDefaultBrowserUserEntries( | 1077 GetXPStyleDefaultBrowserUserEntries( |
| 1160 dist, chrome_exe, | 1078 dist, chrome_exe, |
| 1161 ShellUtil::GetCurrentInstallationSuffix(dist, chrome_exe), &entries); | 1079 ShellUtil::GetCurrentInstallationSuffix(dist, chrome_exe), &entries); |
| 1162 | 1080 |
| 1163 // Change the default browser for current user. | 1081 // Change the default browser for current user. |
| 1164 if ((shell_change & ShellUtil::CURRENT_USER) && | 1082 if ((shell_change & ShellUtil::CURRENT_USER) && |
| 1165 !AddRegistryEntries(HKEY_CURRENT_USER, entries)) { | 1083 !AddRegistryEntries(HKEY_CURRENT_USER, entries)) { |
| 1166 ret = false; | 1084 ret = false; |
| 1167 LOG(ERROR) << "Could not make Chrome default browser (XP/current user)."; | 1085 LOG(ERROR) << "Could not make Chrome default browser (XP/current user)."; |
| 1168 } | 1086 } |
| 1169 | 1087 |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 1185 BrowserDistribution* dist, | 1103 BrowserDistribution* dist, |
| 1186 const base::FilePath& chrome_exe, | 1104 const base::FilePath& chrome_exe, |
| 1187 const base::string16& protocol) { | 1105 const base::string16& protocol) { |
| 1188 ScopedVector<RegistryEntry> entries; | 1106 ScopedVector<RegistryEntry> entries; |
| 1189 const base::string16 chrome_open( | 1107 const base::string16 chrome_open( |
| 1190 ShellUtil::GetChromeShellOpenCmd(chrome_exe)); | 1108 ShellUtil::GetChromeShellOpenCmd(chrome_exe)); |
| 1191 const base::string16 chrome_icon( | 1109 const base::string16 chrome_icon( |
| 1192 ShellUtil::FormatIconLocation( | 1110 ShellUtil::FormatIconLocation( |
| 1193 chrome_exe, | 1111 chrome_exe, |
| 1194 dist->GetIconIndex(BrowserDistribution::SHORTCUT_CHROME))); | 1112 dist->GetIconIndex(BrowserDistribution::SHORTCUT_CHROME))); |
| 1195 RegistryEntry::GetXPStyleUserProtocolEntries(protocol, chrome_icon, | 1113 GetXPStyleUserProtocolEntries(protocol, chrome_icon, chrome_open, &entries); |
| 1196 chrome_open, &entries); | |
| 1197 // Change the default protocol handler for current user. | 1114 // Change the default protocol handler for current user. |
| 1198 if (!AddRegistryEntries(HKEY_CURRENT_USER, entries)) { | 1115 if (!AddRegistryEntries(HKEY_CURRENT_USER, entries)) { |
| 1199 LOG(ERROR) << "Could not make Chrome default protocol client (XP)."; | 1116 LOG(ERROR) << "Could not make Chrome default protocol client (XP)."; |
| 1200 return false; | 1117 return false; |
| 1201 } | 1118 } |
| 1202 | 1119 |
| 1203 return true; | 1120 return true; |
| 1204 } | 1121 } |
| 1205 | 1122 |
| 1206 // Returns |properties.shortcut_name| if the property is set, otherwise it | 1123 // Returns |properties.shortcut_name| if the property is set, otherwise it |
| (...skipping 1105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2312 // Check if chrome is already registered with this suffix. | 2229 // Check if chrome is already registered with this suffix. |
| 2313 if (IsChromeRegistered(dist, chrome_exe, suffix, look_for_in)) | 2230 if (IsChromeRegistered(dist, chrome_exe, suffix, look_for_in)) |
| 2314 return true; | 2231 return true; |
| 2315 | 2232 |
| 2316 bool result = true; | 2233 bool result = true; |
| 2317 if (root == HKEY_CURRENT_USER || IsUserAnAdmin()) { | 2234 if (root == HKEY_CURRENT_USER || IsUserAnAdmin()) { |
| 2318 // Do the full registration if we can do it at user-level or if the user is | 2235 // Do the full registration if we can do it at user-level or if the user is |
| 2319 // an admin. | 2236 // an admin. |
| 2320 ScopedVector<RegistryEntry> progid_and_appreg_entries; | 2237 ScopedVector<RegistryEntry> progid_and_appreg_entries; |
| 2321 ScopedVector<RegistryEntry> shell_entries; | 2238 ScopedVector<RegistryEntry> shell_entries; |
| 2322 RegistryEntry::GetChromeProgIdEntries( | 2239 GetChromeProgIdEntries(dist, chrome_exe, suffix, |
| 2323 dist, chrome_exe, suffix, &progid_and_appreg_entries); | 2240 &progid_and_appreg_entries); |
| 2324 RegistryEntry::GetChromeAppRegistrationEntries( | 2241 GetChromeAppRegistrationEntries(chrome_exe, suffix, |
| 2325 chrome_exe, suffix, &progid_and_appreg_entries); | 2242 &progid_and_appreg_entries); |
| 2326 RegistryEntry::GetShellIntegrationEntries( | 2243 GetShellIntegrationEntries(dist, chrome_exe, suffix, &shell_entries); |
| 2327 dist, chrome_exe, suffix, &shell_entries); | |
| 2328 result = (AddRegistryEntries(root, progid_and_appreg_entries) && | 2244 result = (AddRegistryEntries(root, progid_and_appreg_entries) && |
| 2329 AddRegistryEntries(root, shell_entries)); | 2245 AddRegistryEntries(root, shell_entries)); |
| 2330 } else if (elevate_if_not_admin && | 2246 } else if (elevate_if_not_admin && |
| 2331 base::win::GetVersion() >= base::win::VERSION_VISTA && | 2247 base::win::GetVersion() >= base::win::VERSION_VISTA && |
| 2332 ElevateAndRegisterChrome(dist, chrome_exe, suffix, base::string16())) { | 2248 ElevateAndRegisterChrome(dist, chrome_exe, suffix, base::string16())) { |
| 2333 // If the user is not an admin and OS is between Vista and Windows 7 | 2249 // If the user is not an admin and OS is between Vista and Windows 7 |
| 2334 // inclusively, try to elevate and register. This is only intended for | 2250 // inclusively, try to elevate and register. This is only intended for |
| 2335 // user-level installs as system-level installs should always be run with | 2251 // user-level installs as system-level installs should always be run with |
| 2336 // admin rights. | 2252 // admin rights. |
| 2337 result = true; | 2253 result = true; |
| 2338 } else { | 2254 } else { |
| 2339 // If we got to this point then all we can do is create ProgId and basic app | 2255 // If we got to this point then all we can do is create ProgId and basic app |
| 2340 // registrations under HKCU. | 2256 // registrations under HKCU. |
| 2341 ScopedVector<RegistryEntry> entries; | 2257 ScopedVector<RegistryEntry> entries; |
| 2342 RegistryEntry::GetChromeProgIdEntries( | 2258 GetChromeProgIdEntries(dist, chrome_exe, base::string16(), &entries); |
| 2343 dist, chrome_exe, base::string16(), &entries); | |
| 2344 // Prefer to use |suffix|; unless Chrome's ProgIds are already registered | 2259 // Prefer to use |suffix|; unless Chrome's ProgIds are already registered |
| 2345 // with no suffix (as per the old registration style): in which case some | 2260 // with no suffix (as per the old registration style): in which case some |
| 2346 // other registry entries could refer to them and since we were not able to | 2261 // other registry entries could refer to them and since we were not able to |
| 2347 // set our HKLM entries above, we are better off not altering these here. | 2262 // set our HKLM entries above, we are better off not altering these here. |
| 2348 if (!AreEntriesAsDesired(entries, RegistryEntry::LOOK_IN_HKCU)) { | 2263 if (!AreEntriesAsDesired(entries, RegistryEntry::LOOK_IN_HKCU)) { |
| 2349 if (!suffix.empty()) { | 2264 if (!suffix.empty()) { |
| 2350 entries.clear(); | 2265 entries.clear(); |
| 2351 RegistryEntry::GetChromeProgIdEntries( | 2266 GetChromeProgIdEntries(dist, chrome_exe, suffix, &entries); |
| 2352 dist, chrome_exe, suffix, &entries); | 2267 GetChromeAppRegistrationEntries(chrome_exe, suffix, &entries); |
| 2353 RegistryEntry::GetChromeAppRegistrationEntries( | |
| 2354 chrome_exe, suffix, &entries); | |
| 2355 } | 2268 } |
| 2356 result = AddRegistryEntries(HKEY_CURRENT_USER, entries); | 2269 result = AddRegistryEntries(HKEY_CURRENT_USER, entries); |
| 2357 } else { | 2270 } else { |
| 2358 // The ProgId is registered unsuffixed in HKCU, also register the app with | 2271 // The ProgId is registered unsuffixed in HKCU, also register the app with |
| 2359 // Windows in HKCU (this was not done in the old registration style and | 2272 // Windows in HKCU (this was not done in the old registration style and |
| 2360 // thus needs to be done after the above check for the unsuffixed | 2273 // thus needs to be done after the above check for the unsuffixed |
| 2361 // registration). | 2274 // registration). |
| 2362 entries.clear(); | 2275 entries.clear(); |
| 2363 RegistryEntry::GetChromeAppRegistrationEntries( | 2276 GetChromeAppRegistrationEntries(chrome_exe, base::string16(), &entries); |
| 2364 chrome_exe, base::string16(), &entries); | |
| 2365 result = AddRegistryEntries(HKEY_CURRENT_USER, entries); | 2277 result = AddRegistryEntries(HKEY_CURRENT_USER, entries); |
| 2366 } | 2278 } |
| 2367 } | 2279 } |
| 2368 SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL); | 2280 SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL); |
| 2369 return result; | 2281 return result; |
| 2370 } | 2282 } |
| 2371 | 2283 |
| 2372 bool ShellUtil::RegisterChromeForProtocol(BrowserDistribution* dist, | 2284 bool ShellUtil::RegisterChromeForProtocol(BrowserDistribution* dist, |
| 2373 const base::FilePath& chrome_exe, | 2285 const base::FilePath& chrome_exe, |
| 2374 const base::string16& unique_suffix, | 2286 const base::string16& unique_suffix, |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 2401 return true; | 2313 return true; |
| 2402 | 2314 |
| 2403 if (root == HKEY_CURRENT_USER || IsUserAnAdmin()) { | 2315 if (root == HKEY_CURRENT_USER || IsUserAnAdmin()) { |
| 2404 // We can do this operation directly. | 2316 // We can do this operation directly. |
| 2405 // First, make sure Chrome is fully registered on this machine. | 2317 // First, make sure Chrome is fully registered on this machine. |
| 2406 if (!RegisterChromeBrowser(dist, chrome_exe, suffix, false)) | 2318 if (!RegisterChromeBrowser(dist, chrome_exe, suffix, false)) |
| 2407 return false; | 2319 return false; |
| 2408 | 2320 |
| 2409 // Write in the capabillity for the protocol. | 2321 // Write in the capabillity for the protocol. |
| 2410 ScopedVector<RegistryEntry> entries; | 2322 ScopedVector<RegistryEntry> entries; |
| 2411 RegistryEntry::GetProtocolCapabilityEntries(dist, suffix, protocol, | 2323 GetProtocolCapabilityEntries(dist, suffix, protocol, &entries); |
| 2412 &entries); | |
| 2413 return AddRegistryEntries(root, entries); | 2324 return AddRegistryEntries(root, entries); |
| 2414 } else if (elevate_if_not_admin && | 2325 } else if (elevate_if_not_admin && |
| 2415 base::win::GetVersion() >= base::win::VERSION_VISTA) { | 2326 base::win::GetVersion() >= base::win::VERSION_VISTA) { |
| 2416 // Elevate to do the whole job | 2327 // Elevate to do the whole job |
| 2417 return ElevateAndRegisterChrome(dist, chrome_exe, suffix, protocol); | 2328 return ElevateAndRegisterChrome(dist, chrome_exe, suffix, protocol); |
| 2418 } else { | 2329 } else { |
| 2419 // Admin rights are required to register capabilities before Windows 8. | 2330 // Admin rights are required to register capabilities before Windows 8. |
| 2420 return false; | 2331 return false; |
| 2421 } | 2332 } |
| 2422 } | 2333 } |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2555 // static | 2466 // static |
| 2556 bool ShellUtil::AddFileAssociations( | 2467 bool ShellUtil::AddFileAssociations( |
| 2557 const base::string16& prog_id, | 2468 const base::string16& prog_id, |
| 2558 const base::CommandLine& command_line, | 2469 const base::CommandLine& command_line, |
| 2559 const base::string16& file_type_name, | 2470 const base::string16& file_type_name, |
| 2560 const base::FilePath& icon_path, | 2471 const base::FilePath& icon_path, |
| 2561 const std::set<base::string16>& file_extensions) { | 2472 const std::set<base::string16>& file_extensions) { |
| 2562 ScopedVector<RegistryEntry> entries; | 2473 ScopedVector<RegistryEntry> entries; |
| 2563 | 2474 |
| 2564 // Create a class for this app. | 2475 // Create a class for this app. |
| 2565 RegistryEntry::ApplicationInfo app_info; | 2476 ApplicationInfo app_info; |
| 2566 app_info.prog_id = prog_id; | 2477 app_info.prog_id = prog_id; |
| 2567 app_info.file_type_name = file_type_name; | 2478 app_info.file_type_name = file_type_name; |
| 2568 app_info.file_type_icon_path = icon_path; | 2479 app_info.file_type_icon_path = icon_path; |
| 2569 app_info.file_type_icon_index = 0; | 2480 app_info.file_type_icon_index = 0; |
| 2570 app_info.command_line = command_line.GetCommandLineStringWithPlaceholders(); | 2481 app_info.command_line = command_line.GetCommandLineStringWithPlaceholders(); |
| 2571 RegistryEntry::GetProgIdEntries(app_info, &entries); | 2482 GetProgIdEntries(app_info, &entries); |
| 2572 | 2483 |
| 2573 // Associate each extension that the app can handle with the class. Set this | 2484 // Associate each extension that the app can handle with the class. Set this |
| 2574 // app as the default handler if and only if there is no existing default. | 2485 // app as the default handler if and only if there is no existing default. |
| 2575 for (std::set<base::string16>::const_iterator it = file_extensions.begin(); | 2486 for (std::set<base::string16>::const_iterator it = file_extensions.begin(); |
| 2576 it != file_extensions.end(); | 2487 it != file_extensions.end(); |
| 2577 ++it) { | 2488 ++it) { |
| 2578 // Do not allow empty file extensions, or extensions beginning with a '.'. | 2489 // Do not allow empty file extensions, or extensions beginning with a '.'. |
| 2579 DCHECK(!it->empty()); | 2490 DCHECK(!it->empty()); |
| 2580 DCHECK_NE(L'.', (*it)[0]); | 2491 DCHECK_NE(L'.', (*it)[0]); |
| 2581 base::string16 ext(1, L'.'); | 2492 base::string16 ext(1, L'.'); |
| 2582 ext.append(*it); | 2493 ext.append(*it); |
| 2583 RegistryEntry::GetAppExtRegistrationEntries(prog_id, ext, &entries); | 2494 GetAppExtRegistrationEntries(prog_id, ext, &entries); |
| 2584 | 2495 |
| 2585 // Regstering as the default will have no effect on Windows 8 (see | 2496 // Regstering as the default will have no effect on Windows 8 (see |
| 2586 // documentation for GetAppDefaultRegistrationEntries). However, if our app | 2497 // documentation for GetAppDefaultRegistrationEntries). However, if our app |
| 2587 // is the only handler, it will automatically become the default, so the | 2498 // is the only handler, it will automatically become the default, so the |
| 2588 // same effect is achieved. | 2499 // same effect is achieved. |
| 2589 RegistryEntry::GetAppDefaultRegistrationEntries( | 2500 GetAppDefaultRegistrationEntries(prog_id, ext, false, &entries); |
| 2590 prog_id, ext, false, &entries); | |
| 2591 } | 2501 } |
| 2592 | 2502 |
| 2593 return AddRegistryEntries(HKEY_CURRENT_USER, entries); | 2503 return AddRegistryEntries(HKEY_CURRENT_USER, entries); |
| 2594 } | 2504 } |
| 2595 | 2505 |
| 2596 // static | 2506 // static |
| 2597 bool ShellUtil::DeleteFileAssociations(const base::string16& prog_id) { | 2507 bool ShellUtil::DeleteFileAssociations(const base::string16& prog_id) { |
| 2598 // Delete the key HKEY_CURRENT_USER\Software\Classes\PROGID. | 2508 // Delete the key HKEY_CURRENT_USER\Software\Classes\PROGID. |
| 2599 base::string16 key_path(ShellUtil::kRegClasses); | 2509 base::string16 key_path(ShellUtil::kRegClasses); |
| 2600 key_path.push_back(base::FilePath::kSeparators[0]); | 2510 key_path.push_back(base::FilePath::kSeparators[0]); |
| 2601 key_path.append(prog_id); | 2511 key_path.append(prog_id); |
| 2602 return InstallUtil::DeleteRegistryKey( | 2512 return InstallUtil::DeleteRegistryKey( |
| 2603 HKEY_CURRENT_USER, key_path, WorkItem::kWow64Default); | 2513 HKEY_CURRENT_USER, key_path, WorkItem::kWow64Default); |
| 2604 | 2514 |
| 2605 // TODO(mgiuca): Remove the extension association entries. This requires that | 2515 // TODO(mgiuca): Remove the extension association entries. This requires that |
| 2606 // the extensions associated with a particular prog_id are stored in that | 2516 // the extensions associated with a particular prog_id are stored in that |
| 2607 // prog_id's key. | 2517 // prog_id's key. |
| 2608 } | 2518 } |
| OLD | NEW |