Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(12)

Side by Side Diff: chrome/installer/util/shell_util.cc

Issue 1486513002: RegistryEntry: Moved ApplicationInfo and static methods out of class. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@shell_util-registryentry-public-ctors
Patch Set: Re-wrap comments for methods that were moved. Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698