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

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

Issue 1294863006: Do not register Chrome's DelegateExecute on Win10+. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@d1_fix_debug_versioninfo
Patch Set: Created 5 years, 4 months 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 | « chrome/installer/setup/install_worker.cc ('k') | 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 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
70 // Note: Shell registration implies ProgId registration. 70 // Note: Shell registration implies ProgId registration.
71 CONFIRM_SHELL_REGISTRATION, 71 CONFIRM_SHELL_REGISTRATION,
72 // Same as CONFIRM_SHELL_REGISTRATION, but only look in HKLM (used when 72 // Same as CONFIRM_SHELL_REGISTRATION, but only look in HKLM (used when
73 // uninstalling to know whether elevation is required to clean up the 73 // uninstalling to know whether elevation is required to clean up the
74 // registry). 74 // registry).
75 CONFIRM_SHELL_REGISTRATION_IN_HKLM, 75 CONFIRM_SHELL_REGISTRATION_IN_HKLM,
76 }; 76 };
77 77
78 const wchar_t kReinstallCommand[] = L"ReinstallCommand"; 78 const wchar_t kReinstallCommand[] = L"ReinstallCommand";
79 79
80 // Returns true if Chrome Metro is supported on this OS (Win 8 8370 or greater). 80 // Returns true if Chrome Metro is supported on this version of Windows
81 // TODO(gab): Change this to a simple check for Win 8 once old Win8 builds 81 // (supported as of Win8; deprecated as of Win10).
82 // become irrelevant.
83 bool IsChromeMetroSupported() { 82 bool IsChromeMetroSupported() {
84 OSVERSIONINFOEX min_version_info = {}; 83 const base::win::Version win_version = base::win::GetVersion();
85 min_version_info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); 84 return win_version >= base::win::VERSION_WIN8 &&
86 min_version_info.dwMajorVersion = 6; 85 win_version < base::win::VERSION_WIN10;
87 min_version_info.dwMinorVersion = 2;
88 min_version_info.dwBuildNumber = 8370;
89 min_version_info.wServicePackMajor = 0;
90 min_version_info.wServicePackMinor = 0;
91
92 DWORDLONG condition_mask = 0;
93 VER_SET_CONDITION(condition_mask, VER_MAJORVERSION, VER_GREATER_EQUAL);
94 VER_SET_CONDITION(condition_mask, VER_MINORVERSION, VER_GREATER_EQUAL);
95 VER_SET_CONDITION(condition_mask, VER_BUILDNUMBER, VER_GREATER_EQUAL);
96 VER_SET_CONDITION(condition_mask, VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL);
97 VER_SET_CONDITION(condition_mask, VER_SERVICEPACKMINOR, VER_GREATER_EQUAL);
98
99 DWORD type_mask = VER_MAJORVERSION | VER_MINORVERSION | VER_BUILDNUMBER |
100 VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR;
101
102 return VerifyVersionInfo(&min_version_info, type_mask, condition_mask) != 0;
103 } 86 }
104 87
105 // Returns the current (or installed) browser's ProgId (e.g. 88 // Returns the current (or installed) browser's ProgId (e.g.
106 // "ChromeHTML|suffix|"). 89 // "ChromeHTML|suffix|").
107 // |suffix| can be the empty string. 90 // |suffix| can be the empty string.
108 base::string16 GetBrowserProgId(const base::string16& suffix) { 91 base::string16 GetBrowserProgId(const base::string16& suffix) {
109 BrowserDistribution* dist = BrowserDistribution::GetDistribution(); 92 BrowserDistribution* dist = BrowserDistribution::GetDistribution();
110 base::string16 chrome_html(dist->GetBrowserProgIdPrefix()); 93 base::string16 chrome_html(dist->GetBrowserProgIdPrefix());
111 chrome_html.append(suffix); 94 chrome_html.append(suffix);
112 95
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
185 // class. 168 // class.
186 class RegistryEntry { 169 class RegistryEntry {
187 public: 170 public:
188 // A bit-field enum of places to look for this key in the Windows registry. 171 // A bit-field enum of places to look for this key in the Windows registry.
189 enum LookForIn { 172 enum LookForIn {
190 LOOK_IN_HKCU = 1 << 0, 173 LOOK_IN_HKCU = 1 << 0,
191 LOOK_IN_HKLM = 1 << 1, 174 LOOK_IN_HKLM = 1 << 1,
192 LOOK_IN_HKCU_THEN_HKLM = LOOK_IN_HKCU | LOOK_IN_HKLM, 175 LOOK_IN_HKCU_THEN_HKLM = LOOK_IN_HKCU | LOOK_IN_HKLM,
193 }; 176 };
194 177
178 // Identifies the type of removal this RegistryEntry is flagged for if any.
grt (UTC plus 2) 2015/08/24 15:08:20 "...for, if any."
gab 2015/08/27 20:51:07 Done.
179 enum class RemovalFlag {
180 // Default case, no flag.
grt (UTC plus 2) 2015/08/24 15:08:19 // Default case: install the key/value.
gab 2015/08/27 20:51:07 Done.
181 NONE,
182 // Registry value under |key_path_|\|name_| is flagged for deletion.
183 VALUE,
184 // Registry key under |key_path_| is flag for deletion.
185 KEY,
186 };
187
195 // Details about a Windows application, to be entered into the registry for 188 // Details about a Windows application, to be entered into the registry for
196 // the purpose of file associations. 189 // the purpose of file associations.
197 struct ApplicationInfo { 190 struct ApplicationInfo {
198 ApplicationInfo() : file_type_icon_index(0), application_icon_index(0) {} 191 ApplicationInfo() : file_type_icon_index(0), application_icon_index(0) {}
199 192
200 // The ProgId used by Windows for file associations with this application. 193 // The ProgId used by Windows for file associations with this application.
201 // Must not be empty or start with a '.'. 194 // Must not be empty or start with a '.'.
202 base::string16 prog_id; 195 base::string16 prog_id;
203 // The friendly name, and the path of the icon that will be used for files 196 // The friendly name, and the path of the icon that will be used for files
204 // of these types when associated with this application by default. (They 197 // of these types when associated with this application by default. (They
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
244 } 237 }
245 238
246 // Returns the Windows Default Programs capabilities key for Chrome. For 239 // Returns the Windows Default Programs capabilities key for Chrome. For
247 // example: 240 // example:
248 // "Software\Clients\StartMenuInternet\Chromium[.user]\Capabilities". 241 // "Software\Clients\StartMenuInternet\Chromium[.user]\Capabilities".
249 static base::string16 GetCapabilitiesKey(BrowserDistribution* dist, 242 static base::string16 GetCapabilitiesKey(BrowserDistribution* dist,
250 const base::string16& suffix) { 243 const base::string16& suffix) {
251 return GetBrowserClientKey(dist, suffix).append(L"\\Capabilities"); 244 return GetBrowserClientKey(dist, suffix).append(L"\\Capabilities");
252 } 245 }
253 246
247 // DelegateExecute ProgId. Needed for Chrome Metro in Windows 8. This is
248 // only needed for registring a web browser, not for general associations.
249 static ScopedVector<RegistryEntry> GetChromeDelegateExecuteEntries(
250 const base::FilePath& chrome_exe,
251 const ApplicationInfo& app_info) {
252 ScopedVector<RegistryEntry> entries;
253
254 base::string16 app_id_shell_key(ShellUtil::kRegClasses);
255 app_id_shell_key.push_back(base::FilePath::kSeparators[0]);
256 app_id_shell_key.append(app_info.app_id);
257 app_id_shell_key.append(ShellUtil::kRegExePath);
258 app_id_shell_key.append(ShellUtil::kRegShellPath);
259
260 // <root hkey>\Software\Classes\<app_id>\.exe\shell @=open
261 entries.push_back(
262 new RegistryEntry(app_id_shell_key, ShellUtil::kRegVerbOpen));
263
264 // The command to execute when opening this application via the Metro UI.
265 const base::string16 delegate_command(
266 ShellUtil::GetChromeDelegateCommand(chrome_exe));
267
268 // Each of Chrome's shortcuts has an appid; which, as of Windows 8, is
269 // registered to handle some verbs. This registration has the side-effect
270 // that these verbs now show up in the shortcut's context menu. We
271 // mitigate this side-effect by making the context menu entries
272 // user readable/localized strings. See relevant MSDN article:
273 // http://msdn.microsoft.com/en-US/library/windows/desktop/cc144171.aspx
274 const struct {
275 const wchar_t* verb;
276 int name_id;
277 } verbs[] = {
278 {ShellUtil::kRegVerbOpen, -1},
279 {ShellUtil::kRegVerbOpenNewWindow, IDS_SHORTCUT_NEW_WINDOW_BASE},
280 };
281 for (size_t i = 0; i < arraysize(verbs); ++i) {
grt (UTC plus 2) 2015/08/24 15:08:19 nit: for (const auto verb_and_id& : verbs) {
gab 2015/08/27 20:51:07 Woohoo C++11 in shell_util :-)!
282 base::string16 sub_path(app_id_shell_key);
283 sub_path.push_back(base::FilePath::kSeparators[0]);
284 sub_path.append(verbs[i].verb);
285
286 // <root hkey>\Software\Classes\<app_id>\.exe\shell\<verb>
287 if (verbs[i].name_id != -1) {
288 // TODO(grt): http://crbug.com/75152 Write a reference to a localized
289 // resource.
290 const base::string16 verb_name(
291 installer::GetLocalizedString(verbs[i].name_id));
292 entries.push_back(new RegistryEntry(sub_path, verb_name.c_str()));
293 }
294 entries.push_back(
295 new RegistryEntry(sub_path, L"CommandId", L"Browser.Launch"));
296
297 sub_path.push_back(base::FilePath::kSeparators[0]);
298 sub_path.append(ShellUtil::kRegCommand);
299
300 // <root hkey>\Software\Classes\<app_id>\.exe\shell\<verb>\command
301 entries.push_back(new RegistryEntry(sub_path, delegate_command));
302 entries.push_back(new RegistryEntry(
303 sub_path, ShellUtil::kRegDelegateExecute, app_info.delegate_clsid));
304 }
305
306 return entries.Pass();
307 }
308
254 // This method returns a list of all the registry entries that 309 // This method returns a list of all the registry entries that
255 // are needed to register this installation's ProgId and AppId. 310 // are needed to register this installation's ProgId and AppId.
256 // These entries need to be registered in HKLM prior to Win8. 311 // These entries need to be registered in HKLM prior to Win8.
257 static void GetChromeProgIdEntries(BrowserDistribution* dist, 312 static void GetChromeProgIdEntries(BrowserDistribution* dist,
258 const base::FilePath& chrome_exe, 313 const base::FilePath& chrome_exe,
259 const base::string16& suffix, 314 const base::string16& suffix,
260 ScopedVector<RegistryEntry>* entries) { 315 ScopedVector<RegistryEntry>* entries) {
261 int chrome_icon_index = 316 int chrome_icon_index =
262 dist->GetIconIndex(BrowserDistribution::SHORTCUT_CHROME); 317 dist->GetIconIndex(BrowserDistribution::SHORTCUT_CHROME);
263 318
264 ApplicationInfo app_info; 319 ApplicationInfo app_info;
265 app_info.prog_id = GetBrowserProgId(suffix); 320 app_info.prog_id = GetBrowserProgId(suffix);
266 app_info.file_type_name = dist->GetBrowserProgIdDesc(); 321 app_info.file_type_name = dist->GetBrowserProgIdDesc();
267 // File types associated with Chrome are just given the Chrome icon. 322 // File types associated with Chrome are just given the Chrome icon.
268 app_info.file_type_icon_path = chrome_exe; 323 app_info.file_type_icon_path = chrome_exe;
269 app_info.file_type_icon_index = chrome_icon_index; 324 app_info.file_type_icon_index = chrome_icon_index;
270 app_info.command_line = ShellUtil::GetChromeShellOpenCmd(chrome_exe); 325 app_info.command_line = ShellUtil::GetChromeShellOpenCmd(chrome_exe);
271 // For user-level installs: entries for the app id will be in HKCU; thus we 326 // For user-level installs: entries for the app id will be in HKCU; thus we
272 // do not need a suffix on those entries. 327 // do not need a suffix on those entries.
273 app_info.app_id = ShellUtil::GetBrowserModelId( 328 app_info.app_id = ShellUtil::GetBrowserModelId(
274 dist, InstallUtil::IsPerUserInstall(chrome_exe)); 329 dist, InstallUtil::IsPerUserInstall(chrome_exe));
275 330
276 // The command to execute when opening this application via the Metro UI. 331 dist->GetCommandExecuteImplClsid(&app_info.delegate_clsid);
277 base::string16 delegate_command(
278 ShellUtil::GetChromeDelegateCommand(chrome_exe));
279 bool set_delegate_execute =
280 IsChromeMetroSupported() &&
281 dist->GetCommandExecuteImplClsid(&app_info.delegate_clsid);
282 332
283 // TODO(grt): http://crbug.com/75152 Write a reference to a localized 333 // TODO(grt): http://crbug.com/75152 Write a reference to a localized
284 // resource for name, description, and company. 334 // resource for name, description, and company.
285 app_info.application_name = dist->GetDisplayName(); 335 app_info.application_name = dist->GetDisplayName();
286 app_info.application_icon_path = chrome_exe; 336 app_info.application_icon_path = chrome_exe;
287 app_info.application_icon_index = chrome_icon_index; 337 app_info.application_icon_index = chrome_icon_index;
288 app_info.application_description = dist->GetAppDescription(); 338 app_info.application_description = dist->GetAppDescription();
289 app_info.publisher_name = dist->GetPublisherName(); 339 app_info.publisher_name = dist->GetPublisherName();
290 340
291 GetProgIdEntries(app_info, entries); 341 GetProgIdEntries(app_info, entries);
292 342
293 // DelegateExecute ProgId. Needed for Chrome Metro in Windows 8. This is 343 if (!app_info.delegate_clsid.empty()) {
grt (UTC plus 2) 2015/08/24 15:08:19 if (dist->GetCommandExecuteImplClsid(&app_info.del
gab 2015/08/27 20:51:07 Done.
gab 2015/08/27 21:48:53 Actually, no, GetProgIdEntries() needs app_info.de
grt (UTC plus 2) 2015/08/29 01:38:41 Ah! Subtle!
gab 2015/08/29 14:39:30 Ok will do.
294 // only needed for registring a web browser, not for general associations. 344 ScopedVector<RegistryEntry> delegate_execute_entries =
295 if (set_delegate_execute) { 345 GetChromeDelegateExecuteEntries(chrome_exe, app_info);
296 base::string16 model_id_shell(ShellUtil::kRegClasses); 346 if (!IsChromeMetroSupported()) {
297 model_id_shell.push_back(base::FilePath::kSeparators[0]); 347 for (RegistryEntry* entry : delegate_execute_entries) {
298 model_id_shell.append(app_info.app_id); 348 // Need to get rid of the DelegateExecute keys (verbs, etc.)
grt (UTC plus 2) 2015/08/24 15:08:19 nit: move the comment out of the loop body so the
gab 2015/08/27 20:51:07 Done.
299 model_id_shell.append(ShellUtil::kRegExePath); 349 // themselves (not only their values) or Chrome fails to launch as
300 model_id_shell.append(ShellUtil::kRegShellPath); 350 // Windows finds a registered verb hierarchy with no registered
301 351 // commands underneath and reports "This file does not have a program
302 // <root hkey>\Software\Classes\<app_id>\.exe\shell @=open 352 // associated with it for performing this action. Please install a
303 entries->push_back(new RegistryEntry(model_id_shell, 353 // program or, if one is already installed, create an association in
304 ShellUtil::kRegVerbOpen)); 354 // the Default Programs control panel."
305 355 entry->set_removal_flag(RemovalFlag::KEY);
306 // Each of Chrome's shortcuts has an appid; which, as of Windows 8, is
307 // registered to handle some verbs. This registration has the side-effect
308 // that these verbs now show up in the shortcut's context menu. We
309 // mitigate this side-effect by making the context menu entries
310 // user readable/localized strings. See relevant MSDN article:
311 // http://msdn.microsoft.com/en-US/library/windows/desktop/cc144171.aspx
312 const struct {
313 const wchar_t* verb;
314 int name_id;
315 } verbs[] = {
316 { ShellUtil::kRegVerbOpen, -1 },
317 { ShellUtil::kRegVerbOpenNewWindow, IDS_SHORTCUT_NEW_WINDOW_BASE },
318 };
319 for (size_t i = 0; i < arraysize(verbs); ++i) {
320 base::string16 sub_path(model_id_shell);
321 sub_path.push_back(base::FilePath::kSeparators[0]);
322 sub_path.append(verbs[i].verb);
323
324 // <root hkey>\Software\Classes\<app_id>\.exe\shell\<verb>
325 if (verbs[i].name_id != -1) {
326 // TODO(grt): http://crbug.com/75152 Write a reference to a localized
327 // resource.
328 base::string16 verb_name(
329 installer::GetLocalizedString(verbs[i].name_id));
330 entries->push_back(new RegistryEntry(sub_path, verb_name.c_str()));
331 } 356 }
332 entries->push_back(new RegistryEntry(
333 sub_path, L"CommandId", L"Browser.Launch"));
334
335 sub_path.push_back(base::FilePath::kSeparators[0]);
336 sub_path.append(ShellUtil::kRegCommand);
337
338 // <root hkey>\Software\Classes\<app_id>\.exe\shell\<verb>\command
339 entries->push_back(new RegistryEntry(sub_path, delegate_command));
340 entries->push_back(new RegistryEntry(
341 sub_path, ShellUtil::kRegDelegateExecute, app_info.delegate_clsid));
342 } 357 }
358 // Move |delegate_execute_entries| to |entries|.
359 entries->insert(entries->end(), delegate_execute_entries.begin(),
360 delegate_execute_entries.end());
361 delegate_execute_entries.weak_clear();
343 } 362 }
344 } 363 }
345 364
346 // Gets the registry entries to register an application in the Windows 365 // Gets the registry entries to register an application in the Windows
347 // registry. |app_info| provides all of the information needed. 366 // registry. |app_info| provides all of the information needed.
348 static void GetProgIdEntries(const ApplicationInfo& app_info, 367 static void GetProgIdEntries(const ApplicationInfo& app_info,
349 ScopedVector<RegistryEntry>* entries) { 368 ScopedVector<RegistryEntry>* entries) {
350 // Basic sanity checks. 369 // Basic sanity checks.
351 DCHECK(!app_info.prog_id.empty()); 370 DCHECK(!app_info.prog_id.empty());
352 DCHECK_NE(L'.', app_info.prog_id[0]); 371 DCHECK_NE(L'.', app_info.prog_id[0]);
353 372
354 // File association ProgId 373 // File association ProgId
355 base::string16 prog_id_path(ShellUtil::kRegClasses); 374 base::string16 prog_id_path(ShellUtil::kRegClasses);
356 prog_id_path.push_back(base::FilePath::kSeparators[0]); 375 prog_id_path.push_back(base::FilePath::kSeparators[0]);
357 prog_id_path.append(app_info.prog_id); 376 prog_id_path.append(app_info.prog_id);
358 entries->push_back( 377 entries->push_back(
359 new RegistryEntry(prog_id_path, app_info.file_type_name)); 378 new RegistryEntry(prog_id_path, app_info.file_type_name));
360 entries->push_back(new RegistryEntry( 379 entries->push_back(new RegistryEntry(
361 prog_id_path + ShellUtil::kRegDefaultIcon, 380 prog_id_path + ShellUtil::kRegDefaultIcon,
362 ShellUtil::FormatIconLocation(app_info.file_type_icon_path, 381 ShellUtil::FormatIconLocation(app_info.file_type_icon_path,
363 app_info.file_type_icon_index))); 382 app_info.file_type_icon_index)));
364 entries->push_back(new RegistryEntry( 383 entries->push_back(new RegistryEntry(
365 prog_id_path + ShellUtil::kRegShellOpen, app_info.command_line)); 384 prog_id_path + ShellUtil::kRegShellOpen, app_info.command_line));
366 if (!app_info.delegate_clsid.empty()) { 385 if (!app_info.delegate_clsid.empty()) {
367 entries->push_back( 386 scoped_ptr<RegistryEntry> delegate_execute_entry(
368 new RegistryEntry(prog_id_path + ShellUtil::kRegShellOpen, 387 new RegistryEntry(prog_id_path + ShellUtil::kRegShellOpen,
369 ShellUtil::kRegDelegateExecute, 388 ShellUtil::kRegDelegateExecute,
370 app_info.delegate_clsid)); 389 app_info.delegate_clsid));
390 if (!IsChromeMetroSupported())
391 delegate_execute_entry->set_removal_flag(RemovalFlag::VALUE);
grt (UTC plus 2) 2015/08/24 15:08:20 do away with the delegate_execute_entry local var
gab 2015/08/27 20:51:07 Done.
392 entries->push_back(delegate_execute_entry.Pass());
371 } 393 }
372 394
373 // The following entries are required as of Windows 8, but do not 395 // The following entries are required as of Windows 8, but do not
374 // depend on the DelegateExecute verb handler being set. 396 // depend on the DelegateExecute verb handler being set.
375 if (base::win::GetVersion() >= base::win::VERSION_WIN8) { 397 if (base::win::GetVersion() >= base::win::VERSION_WIN8) {
376 if (!app_info.app_id.empty()) { 398 if (!app_info.app_id.empty()) {
377 entries->push_back(new RegistryEntry( 399 entries->push_back(new RegistryEntry(
378 prog_id_path, ShellUtil::kRegAppUserModelId, app_info.app_id)); 400 prog_id_path, ShellUtil::kRegAppUserModelId, app_info.app_id));
379 } 401 }
380 402
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after
639 GetXPStyleUserProtocolEntries(ShellUtil::kBrowserProtocolAssociations[i], 661 GetXPStyleUserProtocolEntries(ShellUtil::kBrowserProtocolAssociations[i],
640 chrome_icon, chrome_open, entries); 662 chrome_icon, chrome_open, entries);
641 } 663 }
642 664
643 // start->Internet shortcut. 665 // start->Internet shortcut.
644 base::string16 start_menu(ShellUtil::kRegStartMenuInternet); 666 base::string16 start_menu(ShellUtil::kRegStartMenuInternet);
645 base::string16 app_name = dist->GetBaseAppName() + suffix; 667 base::string16 app_name = dist->GetBaseAppName() + suffix;
646 entries->push_back(new RegistryEntry(start_menu, app_name)); 668 entries->push_back(new RegistryEntry(start_menu, app_name));
647 } 669 }
648 670
649 // Generate work_item tasks required to create current registry entry and 671 // Flags this RegistryKey with |removal_flag|, indicating that it should be
650 // add them to the given work item list. 672 // removed rather than created. Note that this will not result in cleaning up
673 // the entire registry hierarchy below RegistryEntry even if it is left empty
674 // by this operation (this should thus not be used for uninstall, but only to
675 // unregister keys that should explicitly no longer be active in the current
676 // configuration).
677 void set_removal_flag(RemovalFlag removal_flag) {
678 removal_flag_ = removal_flag;
679 }
680
681 // Generate work_item tasks required to create (or potentially delete based on
grt (UTC plus 2) 2015/08/24 15:08:19 nit: Generates...
gab 2015/08/27 20:51:07 Done.
682 // |removal_flag_|) the current RegistryEntry and add them to the given
683 // work item list.
651 void AddToWorkItemList(HKEY root, WorkItemList *items) const { 684 void AddToWorkItemList(HKEY root, WorkItemList *items) const {
652 items->AddCreateRegKeyWorkItem(root, key_path_, WorkItem::kWow64Default); 685 if (removal_flag_ == RemovalFlag::VALUE) {
653 if (is_string_) { 686 items->AddDeleteRegValueWorkItem(root, key_path_, WorkItem::kWow64Default,
654 items->AddSetRegValueWorkItem( 687 name_);
grt (UTC plus 2) 2015/08/24 15:08:20 this should be best-effort, no?
gab 2015/08/27 20:51:07 I don't think so, when I was figuring out what sho
grt (UTC plus 2) 2015/08/29 01:38:41 It looks like DeleteRegValueWorkItemTest.DeleteNon
gab 2015/08/29 14:39:30 Done in follow-up CL @ https://codereview.chromium
655 root, key_path_, WorkItem::kWow64Default, name_, value_, true); 688 } else if (removal_flag_ == RemovalFlag::KEY) {
689 items->AddDeleteRegKeyWorkItem(root, key_path_, WorkItem::kWow64Default);
grt (UTC plus 2) 2015/08/24 15:08:19 and this?
gab 2015/08/27 20:51:07 Same thing.
656 } else { 690 } else {
657 items->AddSetRegValueWorkItem( 691 DCHECK(removal_flag_ == RemovalFlag::NONE);
658 root, key_path_, WorkItem::kWow64Default, name_, int_value_, true); 692 items->AddCreateRegKeyWorkItem(root, key_path_, WorkItem::kWow64Default);
693 if (is_string_) {
694 items->AddSetRegValueWorkItem(root, key_path_, WorkItem::kWow64Default,
695 name_, value_, true);
696 } else {
697 items->AddSetRegValueWorkItem(root, key_path_, WorkItem::kWow64Default,
698 name_, int_value_, true);
699 }
659 } 700 }
660 } 701 }
661 702
662 // Checks if the current registry entry exists in HKCU\|key_path_|\|name_| 703 // Checks if the current registry entry exists in HKCU\|key_path_|\|name_|
663 // and value is |value_|. If the key does NOT exist in HKCU, checks for 704 // and value is |value_|. If the key does NOT exist in HKCU, checks for
664 // the correct name and value in HKLM. 705 // the correct name and value in HKLM.
665 // |look_for_in| specifies roots (HKCU and/or HKLM) in which to look for the 706 // |look_for_in| specifies roots (HKCU and/or HKLM) in which to look for the
666 // key, unspecified roots are not looked into (i.e. the the key is assumed not 707 // key, unspecified roots are not looked into (i.e. the the key is assumed not
667 // to exist in them). 708 // to exist in them).
668 // |look_for_in| must at least specify one root to look into. 709 // |look_for_in| must at least specify one root to look into.
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
703 // |name_| does not exist in the registry 744 // |name_| does not exist in the registry
704 DOES_NOT_EXIST, 745 DOES_NOT_EXIST,
705 // |name_| exists, but its value != |value_| 746 // |name_| exists, but its value != |value_|
706 DIFFERENT_VALUE, 747 DIFFERENT_VALUE,
707 // |name_| exists and its value is |value_| 748 // |name_| exists and its value is |value_|
708 SAME_VALUE, 749 SAME_VALUE,
709 }; 750 };
710 751
711 // Create a object that represent default value of a key 752 // Create a object that represent default value of a key
712 RegistryEntry(const base::string16& key_path, const base::string16& value) 753 RegistryEntry(const base::string16& key_path, const base::string16& value)
713 : key_path_(key_path), name_(), 754 : key_path_(key_path),
714 is_string_(true), value_(value), int_value_(0) { 755 name_(),
715 } 756 is_string_(true),
757 value_(value),
758 int_value_(0),
759 removal_flag_(RemovalFlag::NONE) {}
716 760
717 // Create a object that represent a key of type REG_SZ 761 // Create a object that represent a key of type REG_SZ
718 RegistryEntry(const base::string16& key_path, const base::string16& name, 762 RegistryEntry(const base::string16& key_path,
763 const base::string16& name,
719 const base::string16& value) 764 const base::string16& value)
720 : key_path_(key_path), name_(name), 765 : key_path_(key_path),
721 is_string_(true), value_(value), int_value_(0) { 766 name_(name),
722 } 767 is_string_(true),
768 value_(value),
769 int_value_(0),
770 removal_flag_(RemovalFlag::NONE) {}
723 771
724 // Create a object that represent a key of integer type 772 // Create a object that represent a key of integer type
725 RegistryEntry(const base::string16& key_path, const base::string16& name, 773 RegistryEntry(const base::string16& key_path,
774 const base::string16& name,
726 DWORD value) 775 DWORD value)
727 : key_path_(key_path), name_(name), 776 : key_path_(key_path),
728 is_string_(false), value_(), int_value_(value) { 777 name_(name),
729 } 778 is_string_(false),
779 value_(),
780 int_value_(value),
781 removal_flag_(RemovalFlag::NONE) {}
730 782
731 base::string16 key_path_; // key path for the registry entry 783 base::string16 key_path_; // key path for the registry entry
732 base::string16 name_; // name of the registry entry 784 base::string16 name_; // name of the registry entry
733 bool is_string_; // true if current registry entry is of type REG_SZ 785 bool is_string_; // true if current registry entry is of type REG_SZ
734 base::string16 value_; // string value (useful if is_string_ = true) 786 base::string16 value_; // string value (useful if is_string_ = true)
735 DWORD int_value_; // integer value (useful if is_string_ = false) 787 DWORD int_value_; // integer value (useful if is_string_ = false)
736 788
789 // Identifies whether this RegistryEntry is flagged for removal (i.e. no
790 // longer relevant on the configuration it was created under).
791 RemovalFlag removal_flag_;
792
737 // Helper function for ExistsInRegistry(). 793 // Helper function for ExistsInRegistry().
738 // Returns the RegistryStatus of the current registry entry in 794 // Returns the RegistryStatus of the current registry entry in
739 // |root|\|key_path_|\|name_|. 795 // |root|\|key_path_|\|name_|.
740 RegistryStatus StatusInRegistryUnderRoot(HKEY root) const { 796 RegistryStatus StatusInRegistryUnderRoot(HKEY root) const {
741 RegKey key(root, key_path_.c_str(), KEY_QUERY_VALUE); 797 RegKey key(root, key_path_.c_str(), KEY_QUERY_VALUE);
742 bool found = false; 798 bool found = false;
743 bool correct_value = false; 799 bool correct_value = false;
744 if (is_string_) { 800 if (is_string_) {
745 base::string16 read_value; 801 base::string16 read_value;
746 found = key.ReadValue(name_.c_str(), &read_value) == ERROR_SUCCESS; 802 found = key.ReadValue(name_.c_str(), &read_value) == ERROR_SUCCESS;
(...skipping 401 matching lines...) Expand 10 before | Expand all | Expand 10 after
1148 if (properties.has_dual_mode()) 1204 if (properties.has_dual_mode())
1149 shortcut_properties.set_dual_mode(properties.dual_mode); 1205 shortcut_properties.set_dual_mode(properties.dual_mode);
1150 1206
1151 return shortcut_properties; 1207 return shortcut_properties;
1152 } 1208 }
1153 1209
1154 // Cleans up an old verb (run) we used to register in 1210 // Cleans up an old verb (run) we used to register in
1155 // <root>\Software\Classes\Chrome<.suffix>\.exe\shell\run on Windows 8. 1211 // <root>\Software\Classes\Chrome<.suffix>\.exe\shell\run on Windows 8.
1156 void RemoveRunVerbOnWindows8(BrowserDistribution* dist, 1212 void RemoveRunVerbOnWindows8(BrowserDistribution* dist,
1157 const base::FilePath& chrome_exe) { 1213 const base::FilePath& chrome_exe) {
1158 if (IsChromeMetroSupported()) { 1214 if (base::win::GetVersion() >= base::win::VERSION_WIN8) {
1159 bool is_per_user_install = InstallUtil::IsPerUserInstall(chrome_exe); 1215 bool is_per_user_install = InstallUtil::IsPerUserInstall(chrome_exe);
1160 HKEY root_key = DetermineRegistrationRoot(is_per_user_install); 1216 HKEY root_key = DetermineRegistrationRoot(is_per_user_install);
1161 // There's no need to rollback, so forgo the usual work item lists and just 1217 // There's no need to rollback, so forgo the usual work item lists and just
1162 // remove the key from the registry. 1218 // remove the key from the registry.
1163 base::string16 run_verb_key(ShellUtil::kRegClasses); 1219 base::string16 run_verb_key(ShellUtil::kRegClasses);
1164 run_verb_key.push_back(base::FilePath::kSeparators[0]); 1220 run_verb_key.push_back(base::FilePath::kSeparators[0]);
1165 run_verb_key.append(ShellUtil::GetBrowserModelId( 1221 run_verb_key.append(ShellUtil::GetBrowserModelId(
1166 dist, is_per_user_install)); 1222 dist, is_per_user_install));
1167 run_verb_key.append(ShellUtil::kRegExePath); 1223 run_verb_key.append(ShellUtil::kRegExePath);
1168 run_verb_key.append(ShellUtil::kRegShellPath); 1224 run_verb_key.append(ShellUtil::kRegShellPath);
(...skipping 1343 matching lines...) Expand 10 before | Expand all | Expand 10 after
2512 base::string16 key_path(ShellUtil::kRegClasses); 2568 base::string16 key_path(ShellUtil::kRegClasses);
2513 key_path.push_back(base::FilePath::kSeparators[0]); 2569 key_path.push_back(base::FilePath::kSeparators[0]);
2514 key_path.append(prog_id); 2570 key_path.append(prog_id);
2515 return InstallUtil::DeleteRegistryKey( 2571 return InstallUtil::DeleteRegistryKey(
2516 HKEY_CURRENT_USER, key_path, WorkItem::kWow64Default); 2572 HKEY_CURRENT_USER, key_path, WorkItem::kWow64Default);
2517 2573
2518 // TODO(mgiuca): Remove the extension association entries. This requires that 2574 // TODO(mgiuca): Remove the extension association entries. This requires that
2519 // the extensions associated with a particular prog_id are stored in that 2575 // the extensions associated with a particular prog_id are stored in that
2520 // prog_id's key. 2576 // prog_id's key.
2521 } 2577 }
OLDNEW
« no previous file with comments | « chrome/installer/setup/install_worker.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698