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

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

Issue 10823178: Register Chrome in Open With for File Associations at install on Windows. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: address roberts comments Created 8 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 | Annotate | Revision Log
« no previous file with comments | « chrome/installer/util/shell_util.h ('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"
11 11
12 #include <shlobj.h> 12 #include <shlobj.h>
13 #include <windows.h> 13 #include <windows.h>
14 14
15 #include <limits> 15 #include <limits>
16 #include <list>
17 #include <string> 16 #include <string>
18 17
19 #include "base/command_line.h" 18 #include "base/command_line.h"
20 #include "base/file_path.h" 19 #include "base/file_path.h"
21 #include "base/file_util.h" 20 #include "base/file_util.h"
22 #include "base/lazy_instance.h" 21 #include "base/lazy_instance.h"
23 #include "base/logging.h" 22 #include "base/logging.h"
24 #include "base/md5.h" 23 #include "base/md5.h"
25 #include "base/memory/scoped_ptr.h" 24 #include "base/memory/scoped_ptr.h"
25 #include "base/memory/scoped_vector.h"
26 #include "base/path_service.h" 26 #include "base/path_service.h"
27 #include "base/stl_util.h" 27 #include "base/string16.h"
28 #include "base/string_number_conversions.h" 28 #include "base/string_number_conversions.h"
29 #include "base/string_split.h" 29 #include "base/string_split.h"
30 #include "base/string_util.h" 30 #include "base/string_util.h"
31 #include "base/utf_string_conversions.h" 31 #include "base/utf_string_conversions.h"
32 #include "base/values.h" 32 #include "base/values.h"
33 #include "base/win/registry.h" 33 #include "base/win/registry.h"
34 #include "base/win/scoped_comptr.h" 34 #include "base/win/scoped_comptr.h"
35 #include "base/win/win_util.h" 35 #include "base/win/win_util.h"
36 #include "base/win/windows_version.h" 36 #include "base/win/windows_version.h"
37 #include "chrome/common/chrome_constants.h" 37 #include "chrome/common/chrome_constants.h"
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
197 197
198 // Returns the Windows Default Programs capabilities key for Chrome. For 198 // Returns the Windows Default Programs capabilities key for Chrome. For
199 // example: 199 // example:
200 // "Software\Clients\StartMenuInternet\Chromium[.user]\Capabilities". 200 // "Software\Clients\StartMenuInternet\Chromium[.user]\Capabilities".
201 static string16 GetCapabilitiesKey(BrowserDistribution* dist, 201 static string16 GetCapabilitiesKey(BrowserDistribution* dist,
202 const string16& suffix) { 202 const string16& suffix) {
203 return GetBrowserClientKey(dist, suffix).append(L"\\Capabilities"); 203 return GetBrowserClientKey(dist, suffix).append(L"\\Capabilities");
204 } 204 }
205 205
206 // This method returns a list of all the registry entries that 206 // This method returns a list of all the registry entries that
207 // are needed to register Chromium ProgIds. 207 // are needed to register this installation's ProgId and AppId.
208 // These entries should be registered in HKCU for user-level installs and in 208 // These entries should be registered in HKCU for user-level installs and in
209 // HKLM for system-level installs. 209 // HKLM for system-level installs.
210 static bool GetProgIdEntries(BrowserDistribution* dist, 210 static void GetProgIdEntries(BrowserDistribution* dist,
211 const string16& chrome_exe, 211 const string16& chrome_exe,
212 const string16& suffix, 212 const string16& suffix,
213 std::list<RegistryEntry*>* entries) { 213 ScopedVector<RegistryEntry>* entries) {
214 string16 icon_path(ShellUtil::GetChromeIcon(dist, chrome_exe)); 214 string16 icon_path(ShellUtil::GetChromeIcon(dist, chrome_exe));
215 string16 open_cmd(ShellUtil::GetChromeShellOpenCmd(chrome_exe)); 215 string16 open_cmd(ShellUtil::GetChromeShellOpenCmd(chrome_exe));
216 string16 delegate_command(ShellUtil::GetChromeDelegateCommand(chrome_exe)); 216 string16 delegate_command(ShellUtil::GetChromeDelegateCommand(chrome_exe));
217 // For user-level installs: entries for the app id and DelegateExecute verb 217 // For user-level installs: entries for the app id and DelegateExecute verb
218 // handler will be in HKCU; thus we do not need a suffix on those entries. 218 // handler will be in HKCU; thus we do not need a suffix on those entries.
219 string16 app_id(ShellUtil::GetBrowserModelId(dist, chrome_exe)); 219 string16 app_id(ShellUtil::GetBrowserModelId(dist, chrome_exe));
220 string16 delegate_guid; 220 string16 delegate_guid;
221 // TODO(grt): remove HasDelegateExecuteHandler when the exe is ever-present; 221 // TODO(grt): remove HasDelegateExecuteHandler when the exe is ever-present;
222 // see also install_worker.cc's AddDelegateExecuteWorkItems. 222 // see also install_worker.cc's AddDelegateExecuteWorkItems.
223 bool set_delegate_execute = 223 bool set_delegate_execute =
224 IsChromeMetroSupported() && 224 IsChromeMetroSupported() &&
225 dist->GetDelegateExecuteHandlerData(&delegate_guid, NULL, NULL, NULL) && 225 dist->GetDelegateExecuteHandlerData(&delegate_guid, NULL, NULL, NULL) &&
226 InstallUtil::HasDelegateExecuteHandler(dist, chrome_exe); 226 InstallUtil::HasDelegateExecuteHandler(dist, chrome_exe);
227 227
228 // DelegateExecute ProgId. Needed for Chrome Metro in Windows 8. 228 // DelegateExecute ProgId. Needed for Chrome Metro in Windows 8.
229 if (set_delegate_execute) { 229 if (set_delegate_execute) {
230 string16 model_id_shell(ShellUtil::kRegClasses); 230 string16 model_id_shell(ShellUtil::kRegClasses);
231 model_id_shell.push_back(FilePath::kSeparators[0]); 231 model_id_shell.push_back(FilePath::kSeparators[0]);
232 model_id_shell.append(app_id); 232 model_id_shell.append(app_id);
233 model_id_shell.append(ShellUtil::kRegExePath); 233 model_id_shell.append(ShellUtil::kRegExePath);
234 model_id_shell.append(ShellUtil::kRegShellPath); 234 model_id_shell.append(ShellUtil::kRegShellPath);
235 235
236 // <root hkey>\Software\Classes\<app_id>\.exe\shell @=open 236 // <root hkey>\Software\Classes\<app_id>\.exe\shell @=open
237 entries->push_front(new RegistryEntry(model_id_shell, 237 entries->push_back(new RegistryEntry(model_id_shell,
238 ShellUtil::kRegVerbOpen)); 238 ShellUtil::kRegVerbOpen));
239 239
240 const wchar_t* const verbs[] = { ShellUtil::kRegVerbOpen, 240 const wchar_t* const verbs[] = { ShellUtil::kRegVerbOpen,
241 ShellUtil::kRegVerbOpenNewWindow, 241 ShellUtil::kRegVerbOpenNewWindow,
242 ShellUtil::kRegVerbRun }; 242 ShellUtil::kRegVerbRun };
243 for (size_t i = 0; i < arraysize(verbs); ++i) { 243 for (size_t i = 0; i < arraysize(verbs); ++i) {
244 string16 sub_path(model_id_shell); 244 string16 sub_path(model_id_shell);
245 sub_path.push_back(FilePath::kSeparators[0]); 245 sub_path.push_back(FilePath::kSeparators[0]);
246 sub_path.append(verbs[i]); 246 sub_path.append(verbs[i]);
247 247
248 // <root hkey>\Software\Classes\<app_id>\.exe\shell\<verb> 248 // <root hkey>\Software\Classes\<app_id>\.exe\shell\<verb>
249 entries->push_front(new RegistryEntry( 249 entries->push_back(new RegistryEntry(
250 sub_path, L"CommandId", L"Browser.Launch")); 250 sub_path, L"CommandId", L"Browser.Launch"));
251 251
252 sub_path.push_back(FilePath::kSeparators[0]); 252 sub_path.push_back(FilePath::kSeparators[0]);
253 sub_path.append(ShellUtil::kRegCommand); 253 sub_path.append(ShellUtil::kRegCommand);
254 254
255 // <root hkey>\Software\Classes\<app_id>\.exe\shell\<verb>\command 255 // <root hkey>\Software\Classes\<app_id>\.exe\shell\<verb>\command
256 entries->push_front(new RegistryEntry(sub_path, delegate_command)); 256 entries->push_back(new RegistryEntry(sub_path, delegate_command));
257 entries->push_front(new RegistryEntry( 257 entries->push_back(new RegistryEntry(
258 sub_path, ShellUtil::kRegDelegateExecute, delegate_guid)); 258 sub_path, ShellUtil::kRegDelegateExecute, delegate_guid));
259 } 259 }
260 } 260 }
261 261
262 // File association ProgId 262 // File association ProgId
263 string16 chrome_html_prog_id(ShellUtil::kRegClasses); 263 string16 chrome_html_prog_id(ShellUtil::kRegClasses);
264 chrome_html_prog_id.push_back(FilePath::kSeparators[0]); 264 chrome_html_prog_id.push_back(FilePath::kSeparators[0]);
265 chrome_html_prog_id.append(GetBrowserProgId(suffix)); 265 chrome_html_prog_id.append(GetBrowserProgId(suffix));
266 entries->push_front(new RegistryEntry( 266 entries->push_back(new RegistryEntry(
267 chrome_html_prog_id, ShellUtil::kChromeHTMLProgIdDesc)); 267 chrome_html_prog_id, ShellUtil::kChromeHTMLProgIdDesc));
268 entries->push_front(new RegistryEntry( 268 entries->push_back(new RegistryEntry(
269 chrome_html_prog_id, ShellUtil::kRegUrlProtocol, L"")); 269 chrome_html_prog_id, ShellUtil::kRegUrlProtocol, L""));
270 entries->push_front(new RegistryEntry( 270 entries->push_back(new RegistryEntry(
271 chrome_html_prog_id + ShellUtil::kRegDefaultIcon, icon_path)); 271 chrome_html_prog_id + ShellUtil::kRegDefaultIcon, icon_path));
272 entries->push_front(new RegistryEntry( 272 entries->push_back(new RegistryEntry(
273 chrome_html_prog_id + ShellUtil::kRegShellOpen, open_cmd)); 273 chrome_html_prog_id + ShellUtil::kRegShellOpen, open_cmd));
274 if (set_delegate_execute) { 274 if (set_delegate_execute) {
275 entries->push_front(new RegistryEntry( 275 entries->push_back(new RegistryEntry(
276 chrome_html_prog_id + ShellUtil::kRegShellOpen, 276 chrome_html_prog_id + ShellUtil::kRegShellOpen,
277 ShellUtil::kRegDelegateExecute, delegate_guid)); 277 ShellUtil::kRegDelegateExecute, delegate_guid));
278 } 278 }
279 279
280 // The following entries are required as of Windows 8, but do not 280 // The following entries are required as of Windows 8, but do not
281 // depend on the DelegateExecute verb handler being set. 281 // depend on the DelegateExecute verb handler being set.
282 if (base::win::GetVersion() >= base::win::VERSION_WIN8) { 282 if (base::win::GetVersion() >= base::win::VERSION_WIN8) {
283 entries->push_front(new RegistryEntry( 283 entries->push_back(new RegistryEntry(
284 chrome_html_prog_id, ShellUtil::kRegAppUserModelId, app_id)); 284 chrome_html_prog_id, ShellUtil::kRegAppUserModelId, app_id));
285 285
286 // Add \Software\Classes\ChromeHTML\Application entries 286 // Add \Software\Classes\ChromeHTML\Application entries
287 string16 chrome_application(chrome_html_prog_id + 287 string16 chrome_application(chrome_html_prog_id +
288 ShellUtil::kRegApplication); 288 ShellUtil::kRegApplication);
289 entries->push_front(new RegistryEntry( 289 entries->push_back(new RegistryEntry(
290 chrome_application, ShellUtil::kRegAppUserModelId, app_id)); 290 chrome_application, ShellUtil::kRegAppUserModelId, app_id));
291 entries->push_front(new RegistryEntry( 291 entries->push_back(new RegistryEntry(
292 chrome_application, ShellUtil::kRegApplicationIcon, icon_path)); 292 chrome_application, ShellUtil::kRegApplicationIcon, icon_path));
293 // TODO(grt): http://crbug.com/75152 Write a reference to a localized 293 // TODO(grt): http://crbug.com/75152 Write a reference to a localized
294 // resource for name, description, and company. 294 // resource for name, description, and company.
295 entries->push_front(new RegistryEntry( 295 entries->push_back(new RegistryEntry(
296 chrome_application, ShellUtil::kRegApplicationName, 296 chrome_application, ShellUtil::kRegApplicationName,
297 dist->GetAppShortCutName())); 297 dist->GetAppShortCutName()));
298 entries->push_front(new RegistryEntry( 298 entries->push_back(new RegistryEntry(
299 chrome_application, ShellUtil::kRegApplicationDescription, 299 chrome_application, ShellUtil::kRegApplicationDescription,
300 dist->GetAppDescription())); 300 dist->GetAppDescription()));
301 entries->push_front(new RegistryEntry( 301 entries->push_back(new RegistryEntry(
302 chrome_application, ShellUtil::kRegApplicationCompany, 302 chrome_application, ShellUtil::kRegApplicationCompany,
303 dist->GetPublisherName())); 303 dist->GetPublisherName()));
304 } 304 }
305
306 return true;
307 } 305 }
308 306
309 // This method returns a list of the registry entries needed to declare a 307 // This method returns a list of the registry entries needed to declare a
310 // capability of handling a protocol on Windows. 308 // capability of handling a protocol on Windows.
311 static bool GetProtocolCapabilityEntries(BrowserDistribution* dist, 309 static void GetProtocolCapabilityEntries(
312 const string16& suffix, 310 BrowserDistribution* dist,
313 const string16& protocol, 311 const string16& suffix,
314 std::list<RegistryEntry*>* entries) { 312 const string16& protocol,
315 entries->push_front(new RegistryEntry( 313 ScopedVector<RegistryEntry>* entries) {
314 entries->push_back(new RegistryEntry(
316 GetCapabilitiesKey(dist, suffix).append(L"\\URLAssociations"), 315 GetCapabilitiesKey(dist, suffix).append(L"\\URLAssociations"),
317 protocol, GetBrowserProgId(suffix))); 316 protocol, GetBrowserProgId(suffix)));
318 return true;
319 } 317 }
320 318
321 // This method returns a list of all the registry entries required to fully 319 // This method returns a list of the registry entries required to register
322 // integrate Chrome with Windows (i.e. StartMenuInternet, Default Programs, 320 // this installation in "RegisteredApplications" on Windows (to appear in
323 // AppPaths, etc.). This entries need to be registered in HKLM prior to Win8. 321 // Default Programs, StartMenuInternet, etc.).
324 static bool GetShellIntegrationEntries(BrowserDistribution* dist, 322 // These entries need to be registered in HKLM prior to Win8.
323 // If |suffix| is not empty, these entries are guaranteed to be unique on this
324 // machine.
325 static void GetShellIntegrationEntries(BrowserDistribution* dist,
325 const string16& chrome_exe, 326 const string16& chrome_exe,
326 const string16& suffix, 327 const string16& suffix,
327 std::list<RegistryEntry*>* entries) { 328 ScopedVector<RegistryEntry>* entries) {
328 string16 icon_path = ShellUtil::GetChromeIcon(dist, chrome_exe); 329 const string16 icon_path(ShellUtil::GetChromeIcon(dist, chrome_exe));
329 string16 quoted_exe_path = L"\"" + chrome_exe + L"\""; 330 const string16 quoted_exe_path(L"\"" + chrome_exe + L"\"");
330 331
331 // Register for the Start Menu "Internet" link (pre-Win7). 332 // Register for the Start Menu "Internet" link (pre-Win7).
332 const string16 start_menu_entry(GetBrowserClientKey(dist, suffix)); 333 const string16 start_menu_entry(GetBrowserClientKey(dist, suffix));
333 // Register Chrome's display name. 334 // Register Chrome's display name.
334 // TODO(grt): http://crbug.com/75152 Also set LocalizedString; see 335 // TODO(grt): http://crbug.com/75152 Also set LocalizedString; see
335 // http://msdn.microsoft.com/en-us/library/windows/desktop/cc144109(v=VS.85) .aspx#registering_the_display_name 336 // http://msdn.microsoft.com/en-us/library/windows/desktop/cc144109(v=VS.85) .aspx#registering_the_display_name
336 entries->push_front(new RegistryEntry( 337 entries->push_back(new RegistryEntry(
337 start_menu_entry, dist->GetAppShortCutName())); 338 start_menu_entry, dist->GetAppShortCutName()));
338 // Register the "open" verb for launching Chrome via the "Internet" link. 339 // Register the "open" verb for launching Chrome via the "Internet" link.
339 entries->push_front(new RegistryEntry( 340 entries->push_back(new RegistryEntry(
340 start_menu_entry + ShellUtil::kRegShellOpen, quoted_exe_path)); 341 start_menu_entry + ShellUtil::kRegShellOpen, quoted_exe_path));
341 // Register Chrome's icon for the Start Menu "Internet" link. 342 // Register Chrome's icon for the Start Menu "Internet" link.
342 entries->push_front(new RegistryEntry( 343 entries->push_back(new RegistryEntry(
343 start_menu_entry + ShellUtil::kRegDefaultIcon, icon_path)); 344 start_menu_entry + ShellUtil::kRegDefaultIcon, icon_path));
344 345
345 // Register installation information. 346 // Register installation information.
346 string16 install_info(start_menu_entry + L"\\InstallInfo"); 347 string16 install_info(start_menu_entry + L"\\InstallInfo");
347 // Note: not using CommandLine since it has ambiguous rules for quoting 348 // Note: not using CommandLine since it has ambiguous rules for quoting
348 // strings. 349 // strings.
349 entries->push_front(new RegistryEntry(install_info, kReinstallCommand, 350 entries->push_back(new RegistryEntry(install_info, kReinstallCommand,
350 quoted_exe_path + L" --" + ASCIIToWide(switches::kMakeDefaultBrowser))); 351 quoted_exe_path + L" --" + ASCIIToWide(switches::kMakeDefaultBrowser)));
351 entries->push_front(new RegistryEntry(install_info, L"HideIconsCommand", 352 entries->push_back(new RegistryEntry(install_info, L"HideIconsCommand",
352 quoted_exe_path + L" --" + ASCIIToWide(switches::kHideIcons))); 353 quoted_exe_path + L" --" + ASCIIToWide(switches::kHideIcons)));
353 entries->push_front(new RegistryEntry(install_info, L"ShowIconsCommand", 354 entries->push_back(new RegistryEntry(install_info, L"ShowIconsCommand",
354 quoted_exe_path + L" --" + ASCIIToWide(switches::kShowIcons))); 355 quoted_exe_path + L" --" + ASCIIToWide(switches::kShowIcons)));
355 entries->push_front(new RegistryEntry(install_info, L"IconsVisible", 1)); 356 entries->push_back(new RegistryEntry(install_info, L"IconsVisible", 1));
356 357
357 // Register with Default Programs. 358 // Register with Default Programs.
358 string16 reg_app_name(dist->GetBaseAppName().append(suffix)); 359 const string16 reg_app_name(dist->GetBaseAppName().append(suffix));
359 // Tell Windows where to find Chrome's Default Programs info. 360 // Tell Windows where to find Chrome's Default Programs info.
360 string16 capabilities(GetCapabilitiesKey(dist, suffix)); 361 const string16 capabilities(GetCapabilitiesKey(dist, suffix));
361 entries->push_front(new RegistryEntry(ShellUtil::kRegRegisteredApplications, 362 entries->push_back(new RegistryEntry(ShellUtil::kRegRegisteredApplications,
362 reg_app_name, capabilities)); 363 reg_app_name, capabilities));
363 // Write out Chrome's Default Programs info. 364 // Write out Chrome's Default Programs info.
364 // TODO(grt): http://crbug.com/75152 Write a reference to a localized 365 // TODO(grt): http://crbug.com/75152 Write a reference to a localized
365 // resource rather than this. 366 // resource rather than this.
366 entries->push_front(new RegistryEntry( 367 entries->push_back(new RegistryEntry(
367 capabilities, ShellUtil::kRegApplicationDescription, 368 capabilities, ShellUtil::kRegApplicationDescription,
368 dist->GetLongAppDescription())); 369 dist->GetLongAppDescription()));
369 entries->push_front(new RegistryEntry( 370 entries->push_back(new RegistryEntry(
370 capabilities, ShellUtil::kRegApplicationIcon, icon_path)); 371 capabilities, ShellUtil::kRegApplicationIcon, icon_path));
371 entries->push_front(new RegistryEntry( 372 entries->push_back(new RegistryEntry(
372 capabilities, ShellUtil::kRegApplicationName, 373 capabilities, ShellUtil::kRegApplicationName,
373 dist->GetAppShortCutName())); 374 dist->GetAppShortCutName()));
374 375
375 entries->push_front(new RegistryEntry(capabilities + L"\\Startmenu", 376 entries->push_back(new RegistryEntry(capabilities + L"\\Startmenu",
376 L"StartMenuInternet", reg_app_name)); 377 L"StartMenuInternet", reg_app_name));
377 378
378 string16 html_prog_id(GetBrowserProgId(suffix)); 379 const string16 html_prog_id(GetBrowserProgId(suffix));
379 for (int i = 0; ShellUtil::kFileAssociations[i] != NULL; i++) { 380 for (int i = 0; ShellUtil::kFileAssociations[i] != NULL; i++) {
380 entries->push_front(new RegistryEntry( 381 entries->push_back(new RegistryEntry(
381 capabilities + L"\\FileAssociations", 382 capabilities + L"\\FileAssociations",
382 ShellUtil::kFileAssociations[i], html_prog_id)); 383 ShellUtil::kFileAssociations[i], html_prog_id));
383 } 384 }
384 for (int i = 0; ShellUtil::kPotentialProtocolAssociations[i] != NULL; 385 for (int i = 0; ShellUtil::kPotentialProtocolAssociations[i] != NULL;
385 i++) { 386 i++) {
386 entries->push_front(new RegistryEntry( 387 entries->push_back(new RegistryEntry(
387 capabilities + L"\\URLAssociations", 388 capabilities + L"\\URLAssociations",
388 ShellUtil::kPotentialProtocolAssociations[i], html_prog_id)); 389 ShellUtil::kPotentialProtocolAssociations[i], html_prog_id));
389 } 390 }
391 }
390 392
391 // Application Registration. 393 // This method returns a list of the registry entries required for this
392 FilePath chrome_path(chrome_exe); 394 // installation to be registered in the Windows shell.
395 // In particular:
396 // - App Paths
397 // http://msdn.microsoft.com/en-us/library/windows/desktop/ee872121
398 // - File Associations
399 // http://msdn.microsoft.com/en-us/library/bb166549
400 // These entries should be registered in HKCU for user-level installs and in
401 // HKLM for system-level installs.
402 static void GetAppRegistrationEntries(const string16& chrome_exe,
403 const string16& suffix,
404 ScopedVector<RegistryEntry>* entries) {
405 const FilePath chrome_path(chrome_exe);
393 string16 app_path_key(ShellUtil::kAppPathsRegistryKey); 406 string16 app_path_key(ShellUtil::kAppPathsRegistryKey);
394 app_path_key.push_back(FilePath::kSeparators[0]); 407 app_path_key.push_back(FilePath::kSeparators[0]);
395 app_path_key.append(chrome_path.BaseName().value()); 408 app_path_key.append(chrome_path.BaseName().value());
396 entries->push_front(new RegistryEntry(app_path_key, chrome_exe)); 409 entries->push_back(new RegistryEntry(app_path_key, chrome_exe));
397 entries->push_front(new RegistryEntry(app_path_key, 410 entries->push_back(new RegistryEntry(app_path_key,
398 ShellUtil::kAppPathsRegistryPathName, chrome_path.DirName().value())); 411 ShellUtil::kAppPathsRegistryPathName, chrome_path.DirName().value()));
399 412
400 // TODO: add chrome to open with list (Bug 16726). 413 const string16 html_prog_id(GetBrowserProgId(suffix));
401 return true; 414 for (int i = 0; ShellUtil::kFileAssociations[i] != NULL; i++) {
415 string16 key(ShellUtil::kRegClasses);
416 key.push_back(FilePath::kSeparators[0]);
417 key.append(ShellUtil::kFileAssociations[i]);
418 key.push_back(FilePath::kSeparators[0]);
419 key.append(ShellUtil::kRegOpenWithProgids);
420 entries->push_back(new RegistryEntry(key, html_prog_id, string16()));
421 }
402 } 422 }
403 423
404 // This method returns a list of all the user level registry entries that 424 // This method returns a list of all the user level registry entries that
405 // are needed to make Chromium the default handler for a protocol. 425 // are needed to make Chromium the default handler for a protocol.
406 static bool GetUserProtocolEntries(const string16& protocol, 426 static void GetUserProtocolEntries(const string16& protocol,
407 const string16& chrome_icon, 427 const string16& chrome_icon,
408 const string16& chrome_open, 428 const string16& chrome_open,
409 std::list<RegistryEntry*>* entries) { 429 ScopedVector<RegistryEntry>* entries) {
410 // Protocols associations. 430 // Protocols associations.
411 string16 url_key(ShellUtil::kRegClasses); 431 string16 url_key(ShellUtil::kRegClasses);
412 url_key.push_back(FilePath::kSeparators[0]); 432 url_key.push_back(FilePath::kSeparators[0]);
413 url_key.append(protocol); 433 url_key.append(protocol);
414 434
415 // This registry value tells Windows that this 'class' is a URL scheme 435 // This registry value tells Windows that this 'class' is a URL scheme
416 // so IE, explorer and other apps will route it to our handler. 436 // so IE, explorer and other apps will route it to our handler.
417 // <root hkey>\Software\Classes\<protocol>\URL Protocol 437 // <root hkey>\Software\Classes\<protocol>\URL Protocol
418 entries->push_front(new RegistryEntry(url_key, 438 entries->push_back(new RegistryEntry(url_key,
419 ShellUtil::kRegUrlProtocol, L"")); 439 ShellUtil::kRegUrlProtocol, L""));
420 440
421 // <root hkey>\Software\Classes\<protocol>\DefaultIcon 441 // <root hkey>\Software\Classes\<protocol>\DefaultIcon
422 string16 icon_key = url_key + ShellUtil::kRegDefaultIcon; 442 string16 icon_key = url_key + ShellUtil::kRegDefaultIcon;
423 entries->push_front(new RegistryEntry(icon_key, chrome_icon)); 443 entries->push_back(new RegistryEntry(icon_key, chrome_icon));
424 444
425 // <root hkey>\Software\Classes\<protocol>\shell\open\command 445 // <root hkey>\Software\Classes\<protocol>\shell\open\command
426 string16 shell_key = url_key + ShellUtil::kRegShellOpen; 446 string16 shell_key = url_key + ShellUtil::kRegShellOpen;
427 entries->push_front(new RegistryEntry(shell_key, chrome_open)); 447 entries->push_back(new RegistryEntry(shell_key, chrome_open));
428 448
429 // <root hkey>\Software\Classes\<protocol>\shell\open\ddeexec 449 // <root hkey>\Software\Classes\<protocol>\shell\open\ddeexec
430 string16 dde_key = url_key + L"\\shell\\open\\ddeexec"; 450 string16 dde_key = url_key + L"\\shell\\open\\ddeexec";
431 entries->push_front(new RegistryEntry(dde_key, L"")); 451 entries->push_back(new RegistryEntry(dde_key, L""));
432 452
433 // <root hkey>\Software\Classes\<protocol>\shell\@ 453 // <root hkey>\Software\Classes\<protocol>\shell\@
434 string16 protocol_shell_key = url_key + ShellUtil::kRegShellPath; 454 string16 protocol_shell_key = url_key + ShellUtil::kRegShellPath;
435 entries->push_front(new RegistryEntry(protocol_shell_key, L"open")); 455 entries->push_back(new RegistryEntry(protocol_shell_key, L"open"));
436
437 return true;
438 } 456 }
439 457
440 // This method returns a list of all the user level registry entries that 458 // This method returns a list of all the user level registry entries that
441 // are needed to make Chromium default browser. 459 // are needed to make Chromium default browser.
442 static bool GetUserEntries(BrowserDistribution* dist, 460 // Some of these entries are irrelevant in recent versions of Windows, but
443 const string16& chrome_exe, 461 // we register them anyways as some legacy apps are hardcoded to lookup those
444 const string16& suffix, 462 // values.
445 std::list<RegistryEntry*>* entries) { 463 static void GetDefaultBrowserUserEntries(
464 BrowserDistribution* dist,
465 const string16& chrome_exe,
466 const string16& suffix,
467 ScopedVector<RegistryEntry>* entries) {
446 // File extension associations. 468 // File extension associations.
447 string16 html_prog_id(GetBrowserProgId(suffix)); 469 string16 html_prog_id(GetBrowserProgId(suffix));
448 for (int i = 0; ShellUtil::kFileAssociations[i] != NULL; i++) { 470 for (int i = 0; ShellUtil::kFileAssociations[i] != NULL; i++) {
449 string16 ext_key(ShellUtil::kRegClasses); 471 string16 ext_key(ShellUtil::kRegClasses);
450 ext_key.push_back(FilePath::kSeparators[0]); 472 ext_key.push_back(FilePath::kSeparators[0]);
451 ext_key.append(ShellUtil::kFileAssociations[i]); 473 ext_key.append(ShellUtil::kFileAssociations[i]);
452 entries->push_front(new RegistryEntry(ext_key, html_prog_id)); 474 entries->push_back(new RegistryEntry(ext_key, html_prog_id));
453 } 475 }
454 476
455 // Protocols associations. 477 // Protocols associations.
456 string16 chrome_open = ShellUtil::GetChromeShellOpenCmd(chrome_exe); 478 string16 chrome_open = ShellUtil::GetChromeShellOpenCmd(chrome_exe);
457 string16 chrome_icon = ShellUtil::GetChromeIcon(dist, chrome_exe); 479 string16 chrome_icon = ShellUtil::GetChromeIcon(dist, chrome_exe);
458 for (int i = 0; ShellUtil::kBrowserProtocolAssociations[i] != NULL; i++) { 480 for (int i = 0; ShellUtil::kBrowserProtocolAssociations[i] != NULL; i++) {
459 GetUserProtocolEntries(ShellUtil::kBrowserProtocolAssociations[i], 481 GetUserProtocolEntries(ShellUtil::kBrowserProtocolAssociations[i],
460 chrome_icon, chrome_open, entries); 482 chrome_icon, chrome_open, entries);
461 } 483 }
462 484
463 // start->Internet shortcut. 485 // start->Internet shortcut.
464 string16 start_menu(ShellUtil::kRegStartMenuInternet); 486 string16 start_menu(ShellUtil::kRegStartMenuInternet);
465 string16 app_name = dist->GetBaseAppName() + suffix; 487 string16 app_name = dist->GetBaseAppName() + suffix;
466 entries->push_front(new RegistryEntry(start_menu, app_name)); 488 entries->push_back(new RegistryEntry(start_menu, app_name));
467 return true;
468 } 489 }
469 490
470 // Generate work_item tasks required to create current registry entry and 491 // Generate work_item tasks required to create current registry entry and
471 // add them to the given work item list. 492 // add them to the given work item list.
472 void AddToWorkItemList(HKEY root, WorkItemList *items) const { 493 void AddToWorkItemList(HKEY root, WorkItemList *items) const {
473 items->AddCreateRegKeyWorkItem(root, _key_path); 494 items->AddCreateRegKeyWorkItem(root, _key_path);
474 if (_is_string) { 495 if (_is_string) {
475 items->AddSetRegValueWorkItem(root, _key_path, _name, _value, true); 496 items->AddSetRegValueWorkItem(root, _key_path, _name, _value, true);
476 } else { 497 } else {
477 items->AddSetRegValueWorkItem(root, _key_path, _name, _int_value, true); 498 items->AddSetRegValueWorkItem(root, _key_path, _name, _int_value, true);
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
559 return found ? 580 return found ?
560 (correct_value ? SAME_VALUE : DIFFERENT_VALUE) : DOES_NOT_EXIST; 581 (correct_value ? SAME_VALUE : DIFFERENT_VALUE) : DOES_NOT_EXIST;
561 } 582 }
562 583
563 DISALLOW_COPY_AND_ASSIGN(RegistryEntry); 584 DISALLOW_COPY_AND_ASSIGN(RegistryEntry);
564 }; // class RegistryEntry 585 }; // class RegistryEntry
565 586
566 587
567 // This method converts all the RegistryEntries from the given list to 588 // This method converts all the RegistryEntries from the given list to
568 // Set/CreateRegWorkItems and runs them using WorkItemList. 589 // Set/CreateRegWorkItems and runs them using WorkItemList.
569 bool AddRegistryEntries(HKEY root, const std::list<RegistryEntry*>& entries) { 590 bool AddRegistryEntries(HKEY root, const ScopedVector<RegistryEntry>& entries) {
570 scoped_ptr<WorkItemList> items(WorkItem::CreateWorkItemList()); 591 scoped_ptr<WorkItemList> items(WorkItem::CreateWorkItemList());
571 592
572 for (std::list<RegistryEntry*>::const_iterator itr = entries.begin(); 593 for (ScopedVector<RegistryEntry>::const_iterator itr = entries.begin();
573 itr != entries.end(); ++itr) 594 itr != entries.end(); ++itr)
574 (*itr)->AddToWorkItemList(root, items.get()); 595 (*itr)->AddToWorkItemList(root, items.get());
575 596
576 // Apply all the registry changes and if there is a problem, rollback 597 // Apply all the registry changes and if there is a problem, rollback
577 if (!items->Do()) { 598 if (!items->Do()) {
578 items->Rollback(); 599 items->Rollback();
579 return false; 600 return false;
580 } 601 }
581 return true; 602 return true;
582 } 603 }
583 604
584 // Checks that all |entries| are present on this computer. 605 // Checks that all |entries| are present on this computer.
585 // |look_for_in| is passed to RegistryEntry::ExistsInRegistry(). Documentation 606 // |look_for_in| is passed to RegistryEntry::ExistsInRegistry(). Documentation
586 // for it can be found there. 607 // for it can be found there.
587 bool AreEntriesRegistered(const std::list<RegistryEntry*>& entries, 608 bool AreEntriesRegistered(const ScopedVector<RegistryEntry>& entries,
588 uint32 look_for_in) { 609 uint32 look_for_in) {
589 bool registered = true; 610 bool registered = true;
590 for (std::list<RegistryEntry*>::const_iterator itr = entries.begin(); 611 for (ScopedVector<RegistryEntry>::const_iterator itr = entries.begin();
591 registered && itr != entries.end(); ++itr) { 612 registered && itr != entries.end(); ++itr) {
592 // We do not need registered = registered && ... since the loop condition 613 // We do not need registered = registered && ... since the loop condition
593 // is set to exit early. 614 // is set to exit early.
594 registered = (*itr)->ExistsInRegistry(look_for_in); 615 registered = (*itr)->ExistsInRegistry(look_for_in);
595 } 616 }
596 return registered; 617 return registered;
597 } 618 }
598 619
599 // Checks that all required registry entries for Chrome are already present 620 // Checks that all required registry entries for Chrome are already present
600 // on this computer. 621 // on this computer.
601 bool IsChromeRegistered(BrowserDistribution* dist, 622 bool IsChromeRegistered(BrowserDistribution* dist,
602 const string16& chrome_exe, 623 const string16& chrome_exe,
603 const string16& suffix) { 624 const string16& suffix) {
604 std::list<RegistryEntry*> entries; 625 ScopedVector<RegistryEntry> entries;
605 STLElementDeleter<std::list<RegistryEntry*> > entries_deleter(&entries);
606 RegistryEntry::GetProgIdEntries(dist, chrome_exe, suffix, &entries); 626 RegistryEntry::GetProgIdEntries(dist, chrome_exe, suffix, &entries);
607 RegistryEntry::GetShellIntegrationEntries( 627 RegistryEntry::GetShellIntegrationEntries(dist, chrome_exe, suffix, &entries);
608 dist, chrome_exe, suffix, &entries); 628 RegistryEntry::GetAppRegistrationEntries(chrome_exe, suffix, &entries);
609 return AreEntriesRegistered(entries, RegistryEntry::LOOK_IN_HKCU_THEN_HKLM); 629 return AreEntriesRegistered(entries, RegistryEntry::LOOK_IN_HKCU_THEN_HKLM);
610 } 630 }
611 631
612 // This method checks if Chrome is already registered on the local machine 632 // This method checks if Chrome is already registered on the local machine
613 // for the requested protocol. It just checks the one value required for this. 633 // for the requested protocol. It just checks the one value required for this.
614 bool IsChromeRegisteredForProtocol(BrowserDistribution* dist, 634 bool IsChromeRegisteredForProtocol(BrowserDistribution* dist,
615 const string16& suffix, 635 const string16& suffix,
616 const string16& protocol) { 636 const string16& protocol) {
617 std::list<RegistryEntry*> entries; 637 ScopedVector<RegistryEntry> entries;
618 STLElementDeleter<std::list<RegistryEntry*> > entries_deleter(&entries);
619 RegistryEntry::GetProtocolCapabilityEntries(dist, suffix, protocol, &entries); 638 RegistryEntry::GetProtocolCapabilityEntries(dist, suffix, protocol, &entries);
620 return AreEntriesRegistered(entries, RegistryEntry::LOOK_IN_HKCU_THEN_HKLM); 639 return AreEntriesRegistered(entries, RegistryEntry::LOOK_IN_HKCU_THEN_HKLM);
621 } 640 }
622 641
623 // This method registers Chrome on Vista by launching an elevated setup.exe. 642 // This method registers Chrome on Vista by launching an elevated setup.exe.
624 // That will show the user the standard Vista elevation prompt. If the user 643 // That will show the user the standard Vista elevation prompt. If the user
625 // accepts it the new process will make the necessary changes and return SUCCESS 644 // accepts it the new process will make the necessary changes and return SUCCESS
626 // that we capture and return. 645 // that we capture and return.
627 // If protocol is non-empty we will also register Chrome as being capable of 646 // If protocol is non-empty we will also register Chrome as being capable of
628 // handling the protocol. 647 // handling the protocol.
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after
861 } 880 }
862 881
863 // Returns the root registry key (HKLM or HKCU) into which shell integration 882 // Returns the root registry key (HKLM or HKCU) into which shell integration
864 // registration for default protocols must be placed. As of Windows 8 everything 883 // registration for default protocols must be placed. As of Windows 8 everything
865 // can go in HKCU for per-user installs. 884 // can go in HKCU for per-user installs.
866 HKEY DetermineShellIntegrationRoot(bool is_per_user) { 885 HKEY DetermineShellIntegrationRoot(bool is_per_user) {
867 return is_per_user && base::win::GetVersion() >= base::win::VERSION_WIN8 ? 886 return is_per_user && base::win::GetVersion() >= base::win::VERSION_WIN8 ?
868 HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE; 887 HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE;
869 } 888 }
870 889
890 // Associates Chrome with supported protocols and file associations. This should
891 // not be required on Vista+ but since some applications still read
892 // Software\Classes\http key directly, we have to do this on Vista+ as well.
893 bool RegisterChromeAsDefaultForXP(BrowserDistribution* dist,
894 int shell_change,
895 const string16& chrome_exe) {
896 bool ret = true;
897 ScopedVector<RegistryEntry> entries;
898 RegistryEntry::GetDefaultBrowserUserEntries(
899 dist, chrome_exe,
900 ShellUtil::GetCurrentInstallationSuffix(dist, chrome_exe), &entries);
901
902 // Change the default browser for current user.
903 if ((shell_change & ShellUtil::CURRENT_USER) &&
904 !AddRegistryEntries(HKEY_CURRENT_USER, entries)) {
905 ret = false;
906 LOG(ERROR) << "Could not make Chrome default browser (XP/current user).";
907 }
908
909 // Chrome as default browser at system level.
910 if ((shell_change & ShellUtil::SYSTEM_LEVEL) &&
911 !AddRegistryEntries(HKEY_LOCAL_MACHINE, entries)) {
912 ret = false;
913 LOG(ERROR) << "Could not make Chrome default browser (XP/system level).";
914 }
915
916 return ret;
917 }
918
871 } // namespace 919 } // namespace
872 920
873 const wchar_t* ShellUtil::kRegDefaultIcon = L"\\DefaultIcon"; 921 const wchar_t* ShellUtil::kRegDefaultIcon = L"\\DefaultIcon";
874 const wchar_t* ShellUtil::kRegShellPath = L"\\shell"; 922 const wchar_t* ShellUtil::kRegShellPath = L"\\shell";
875 const wchar_t* ShellUtil::kRegShellOpen = L"\\shell\\open\\command"; 923 const wchar_t* ShellUtil::kRegShellOpen = L"\\shell\\open\\command";
876 const wchar_t* ShellUtil::kRegStartMenuInternet = 924 const wchar_t* ShellUtil::kRegStartMenuInternet =
877 L"Software\\Clients\\StartMenuInternet"; 925 L"Software\\Clients\\StartMenuInternet";
878 const wchar_t* ShellUtil::kRegClasses = L"Software\\Classes"; 926 const wchar_t* ShellUtil::kRegClasses = L"Software\\Classes";
879 const wchar_t* ShellUtil::kRegRegisteredApplications = 927 const wchar_t* ShellUtil::kRegRegisteredApplications =
880 L"Software\\RegisteredApplications"; 928 L"Software\\RegisteredApplications";
(...skipping 26 matching lines...) Expand all
907 L"ApplicationDescription"; 955 L"ApplicationDescription";
908 const wchar_t* ShellUtil::kRegApplicationName = L"ApplicationName"; 956 const wchar_t* ShellUtil::kRegApplicationName = L"ApplicationName";
909 const wchar_t* ShellUtil::kRegApplicationIcon = L"ApplicationIcon"; 957 const wchar_t* ShellUtil::kRegApplicationIcon = L"ApplicationIcon";
910 const wchar_t* ShellUtil::kRegApplicationCompany = L"ApplicationCompany"; 958 const wchar_t* ShellUtil::kRegApplicationCompany = L"ApplicationCompany";
911 const wchar_t* ShellUtil::kRegExePath = L"\\.exe"; 959 const wchar_t* ShellUtil::kRegExePath = L"\\.exe";
912 const wchar_t* ShellUtil::kRegVerbOpen = L"open"; 960 const wchar_t* ShellUtil::kRegVerbOpen = L"open";
913 const wchar_t* ShellUtil::kRegVerbOpenNewWindow = L"opennewwindow"; 961 const wchar_t* ShellUtil::kRegVerbOpenNewWindow = L"opennewwindow";
914 const wchar_t* ShellUtil::kRegVerbRun = L"run"; 962 const wchar_t* ShellUtil::kRegVerbRun = L"run";
915 const wchar_t* ShellUtil::kRegCommand = L"command"; 963 const wchar_t* ShellUtil::kRegCommand = L"command";
916 const wchar_t* ShellUtil::kRegDelegateExecute = L"DelegateExecute"; 964 const wchar_t* ShellUtil::kRegDelegateExecute = L"DelegateExecute";
965 const wchar_t* ShellUtil::kRegOpenWithProgids = L"OpenWithProgids";
917 966
918 bool ShellUtil::QuickIsChromeRegisteredInHKLM(BrowserDistribution* dist, 967 bool ShellUtil::QuickIsChromeRegisteredInHKLM(BrowserDistribution* dist,
919 const string16& chrome_exe, 968 const string16& chrome_exe,
920 const string16& suffix) { 969 const string16& suffix) {
921 return QuickIsChromeRegistered(dist, chrome_exe, suffix, 970 return QuickIsChromeRegistered(dist, chrome_exe, suffix,
922 CONFIRM_SHELL_REGISTRATION_IN_HKLM); 971 CONFIRM_SHELL_REGISTRATION_IN_HKLM);
923 } 972 }
924 973
925 bool ShellUtil::CreateChromeDesktopShortcut(BrowserDistribution* dist, 974 bool ShellUtil::CreateChromeDesktopShortcut(BrowserDistribution* dist,
926 const string16& chrome_exe, 975 const string16& chrome_exe,
(...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after
1281 ShellUtil::kFileAssociations[i], AT_FILEEXTENSION); 1330 ShellUtil::kFileAssociations[i], AT_FILEEXTENSION);
1282 if (!SUCCEEDED(hr)) { 1331 if (!SUCCEEDED(hr)) {
1283 ret = false; 1332 ret = false;
1284 LOG(ERROR) << "Failed to register as default for file extension " 1333 LOG(ERROR) << "Failed to register as default for file extension "
1285 << ShellUtil::kFileAssociations[i] << " (" << hr << ")"; 1334 << ShellUtil::kFileAssociations[i] << " (" << hr << ")";
1286 } 1335 }
1287 } 1336 }
1288 } 1337 }
1289 } 1338 }
1290 1339
1291 // Now use the old way to associate Chrome with supported protocols and file 1340 if (!RegisterChromeAsDefaultForXP(dist, shell_change, chrome_exe))
1292 // associations. This should not be required on Vista but since some
1293 // applications still read Software\Classes\http key directly, we have to do
1294 // this on Vista also.
1295
1296 std::list<RegistryEntry*> entries;
1297 STLElementDeleter<std::list<RegistryEntry*> > entries_deleter(&entries);
1298 RegistryEntry::GetUserEntries(
1299 dist, chrome_exe, GetCurrentInstallationSuffix(dist, chrome_exe),
1300 &entries);
1301 // Change the default browser for current user.
1302 if ((shell_change & ShellUtil::CURRENT_USER) &&
1303 !AddRegistryEntries(HKEY_CURRENT_USER, entries)) {
1304 ret = false; 1341 ret = false;
1305 LOG(ERROR) << "Could not make Chrome default browser (XP/current user).";
1306 }
1307
1308 // Chrome as default browser at system level.
1309 if ((shell_change & ShellUtil::SYSTEM_LEVEL) &&
1310 !AddRegistryEntries(HKEY_LOCAL_MACHINE, entries)) {
1311 ret = false;
1312 LOG(ERROR) << "Could not make Chrome default browser (XP/system level).";
1313 }
1314 1342
1315 // Send Windows notification event so that it can update icons for 1343 // Send Windows notification event so that it can update icons for
1316 // file associations. 1344 // file associations.
1317 SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL); 1345 SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL);
1318 return ret; 1346 return ret;
1319 } 1347 }
1320 1348
1321 bool ShellUtil::ShowMakeChromeDefaultSystemUI(BrowserDistribution* dist, 1349 bool ShellUtil::ShowMakeChromeDefaultSystemUI(BrowserDistribution* dist,
1322 const string16& chrome_exe) { 1350 const string16& chrome_exe) {
1323 DCHECK_GE(base::win::GetVersion(), base::win::VERSION_WIN8); 1351 DCHECK_GE(base::win::GetVersion(), base::win::VERSION_WIN8);
1324 if (!dist->CanSetAsDefault()) 1352 if (!dist->CanSetAsDefault())
1325 return false; 1353 return false;
1326 1354
1327 if (!RegisterChromeBrowser(dist, chrome_exe, string16(), true)) 1355 if (!RegisterChromeBrowser(dist, chrome_exe, string16(), true))
1328 return false; 1356 return false;
1329 1357
1330 // On Windows 8, you can't set yourself as the default handler 1358 // On Windows 8, you can't set yourself as the default handler
1331 // programatically. In other words IApplicationAssociationRegistration 1359 // programatically. In other words IApplicationAssociationRegistration
1332 // has been rendered useless. What you can do is to launch 1360 // has been rendered useless. What you can do is to launch
1333 // "Set Program Associations" section of the "Default Programs" 1361 // "Set Program Associations" section of the "Default Programs"
1334 // control panel, which is a mess, or pop the concise "How you want to open 1362 // control panel, which is a mess, or pop the concise "How you want to open
1335 // webpages?" dialog. We choose the latter. 1363 // webpages?" dialog. We choose the latter.
1336 // Return true only when the user took an action and there was no error. 1364 // Return true only when the user took an action and there was no error.
1337 return LaunchSelectDefaultProtocolHandlerDialog(L"http"); 1365 const bool ret = LaunchSelectDefaultProtocolHandlerDialog(L"http");
1366
1367 if (ret) {
1368 const int shell_change =
1369 InstallUtil::IsPerUserInstall(chrome_exe.c_str()) ? CURRENT_USER :
1370 SYSTEM_LEVEL;
1371 RegisterChromeAsDefaultForXP(dist, shell_change, chrome_exe);
1372 }
1373
1374 return ret;
1338 } 1375 }
1339 1376
1340 bool ShellUtil::MakeChromeDefaultProtocolClient(BrowserDistribution* dist, 1377 bool ShellUtil::MakeChromeDefaultProtocolClient(BrowserDistribution* dist,
1341 const string16& chrome_exe, 1378 const string16& chrome_exe,
1342 const string16& protocol) { 1379 const string16& protocol) {
1343 if (!dist->CanSetAsDefault()) 1380 if (!dist->CanSetAsDefault())
1344 return false; 1381 return false;
1345 1382
1346 ShellUtil::RegisterChromeForProtocol(dist, chrome_exe, L"", protocol, true); 1383 ShellUtil::RegisterChromeForProtocol(dist, chrome_exe, L"", protocol, true);
1347 1384
(...skipping 15 matching lines...) Expand all
1363 ret = false; 1400 ret = false;
1364 LOG(ERROR) << "Could not make Chrome default protocol client (Vista):" 1401 LOG(ERROR) << "Could not make Chrome default protocol client (Vista):"
1365 << " HRESULT=" << hr << "."; 1402 << " HRESULT=" << hr << ".";
1366 } 1403 }
1367 } 1404 }
1368 1405
1369 // Now use the old way to associate Chrome with the desired protocol. This 1406 // Now use the old way to associate Chrome with the desired protocol. This
1370 // should not be required on Vista but since some applications still read 1407 // should not be required on Vista but since some applications still read
1371 // Software\Classes\http key directly, we have to do this on Vista also. 1408 // Software\Classes\http key directly, we have to do this on Vista also.
1372 1409
1373 std::list<RegistryEntry*> entries; 1410 ScopedVector<RegistryEntry> entries;
1374 STLElementDeleter<std::list<RegistryEntry*> > entries_deleter(&entries);
1375 const string16 suffix(GetCurrentInstallationSuffix(dist, chrome_exe)); 1411 const string16 suffix(GetCurrentInstallationSuffix(dist, chrome_exe));
1376 const string16 chrome_open(ShellUtil::GetChromeShellOpenCmd(chrome_exe)); 1412 const string16 chrome_open(ShellUtil::GetChromeShellOpenCmd(chrome_exe));
1377 const string16 chrome_icon(ShellUtil::GetChromeIcon(dist, chrome_exe)); 1413 const string16 chrome_icon(ShellUtil::GetChromeIcon(dist, chrome_exe));
1378 RegistryEntry::GetUserProtocolEntries(protocol, chrome_icon, chrome_open, 1414 RegistryEntry::GetUserProtocolEntries(protocol, chrome_icon, chrome_open,
1379 &entries); 1415 &entries);
1380 // Change the default protocol handler for current user. 1416 // Change the default protocol handler for current user.
1381 if (!AddRegistryEntries(HKEY_CURRENT_USER, entries)) { 1417 if (!AddRegistryEntries(HKEY_CURRENT_USER, entries)) {
1382 ret = false; 1418 ret = false;
1383 LOG(ERROR) << "Could not make Chrome default protocol client (XP)."; 1419 LOG(ERROR) << "Could not make Chrome default protocol client (XP).";
1384 } 1420 }
(...skipping 21 matching lines...) Expand all
1406 // Check if Chromium is already registered with this suffix. 1442 // Check if Chromium is already registered with this suffix.
1407 if (IsChromeRegistered(dist, chrome_exe, suffix)) 1443 if (IsChromeRegistered(dist, chrome_exe, suffix))
1408 return true; 1444 return true;
1409 1445
1410 bool user_level = InstallUtil::IsPerUserInstall(chrome_exe.c_str()); 1446 bool user_level = InstallUtil::IsPerUserInstall(chrome_exe.c_str());
1411 HKEY root = DetermineShellIntegrationRoot(user_level); 1447 HKEY root = DetermineShellIntegrationRoot(user_level);
1412 1448
1413 // Do the full registration if we can do it at user-level or if the user is an 1449 // Do the full registration if we can do it at user-level or if the user is an
1414 // admin. 1450 // admin.
1415 if (root == HKEY_CURRENT_USER || IsUserAnAdmin()) { 1451 if (root == HKEY_CURRENT_USER || IsUserAnAdmin()) {
1416 std::list<RegistryEntry*> progids; 1452 ScopedVector<RegistryEntry> progid_and_appreg_entries;
1417 STLElementDeleter<std::list<RegistryEntry*> > progids_deleter(&progids); 1453 ScopedVector<RegistryEntry> shell_entries;
1418 std::list<RegistryEntry*> shell_entries; 1454 RegistryEntry::GetProgIdEntries(dist, chrome_exe, suffix,
1419 STLElementDeleter<std::list<RegistryEntry*> > shell_deleter(&shell_entries); 1455 &progid_and_appreg_entries);
1420 RegistryEntry::GetProgIdEntries(dist, chrome_exe, suffix, &progids); 1456 RegistryEntry::GetAppRegistrationEntries(chrome_exe, suffix,
1457 &progid_and_appreg_entries);
1421 RegistryEntry::GetShellIntegrationEntries( 1458 RegistryEntry::GetShellIntegrationEntries(
1422 dist, chrome_exe, suffix, &shell_entries); 1459 dist, chrome_exe, suffix, &shell_entries);
1423 return AddRegistryEntries(user_level ? HKEY_CURRENT_USER : 1460 return AddRegistryEntries(user_level ? HKEY_CURRENT_USER :
1424 HKEY_LOCAL_MACHINE, 1461 HKEY_LOCAL_MACHINE,
1425 progids) && 1462 progid_and_appreg_entries) &&
1426 AddRegistryEntries(root, shell_entries); 1463 AddRegistryEntries(root, shell_entries);
1427 } 1464 }
1428 1465
1429 // If the user is not an admin and OS is between Vista and Windows 7 1466 // If the user is not an admin and OS is between Vista and Windows 7
1430 // inclusively, try to elevate and register. This is only intended for 1467 // inclusively, try to elevate and register. This is only intended for
1431 // user-level installs as system-level installs should always be run with 1468 // user-level installs as system-level installs should always be run with
1432 // admin rights. 1469 // admin rights.
1433 if (elevate_if_not_admin && 1470 if (elevate_if_not_admin &&
1434 base::win::GetVersion() >= base::win::VERSION_VISTA && 1471 base::win::GetVersion() >= base::win::VERSION_VISTA &&
1435 ElevateAndRegisterChrome(dist, chrome_exe, suffix, L"")) 1472 ElevateAndRegisterChrome(dist, chrome_exe, suffix, L""))
1436 return true; 1473 return true;
1437 1474
1438 // If we got to this point then all we can do is create ProgIds under HKCU. 1475 // If we got to this point then all we can do is create ProgId and basic app
1439 std::list<RegistryEntry*> entries; 1476 // registrations under HKCU.
1440 STLElementDeleter<std::list<RegistryEntry*> > entries_deleter(&entries); 1477 ScopedVector<RegistryEntry> entries;
1441 RegistryEntry::GetProgIdEntries(dist, chrome_exe, L"", &entries); 1478 RegistryEntry::GetProgIdEntries(dist, chrome_exe, string16(), &entries);
1442 // Prefer to use |suffix|; unless Chrome's ProgIds are already registered with 1479 // Prefer to use |suffix|; unless Chrome's ProgIds are already registered with
1443 // no suffix (as per the old registration style): in which case some other 1480 // no suffix (as per the old registration style): in which case some other
1444 // registry entries could refer to them and since we were not able to set our 1481 // registry entries could refer to them and since we were not able to set our
1445 // HKLM entries above, we are better off not altering these here. 1482 // HKLM entries above, we are better off not altering these here.
1446 if (!AreEntriesRegistered(entries, RegistryEntry::LOOK_IN_HKCU)) { 1483 if (!AreEntriesRegistered(entries, RegistryEntry::LOOK_IN_HKCU)) {
1447 if (!suffix.empty()) { 1484 if (!suffix.empty()) {
1448 STLDeleteElements(&entries); 1485 entries.clear();
1449 RegistryEntry::GetProgIdEntries(dist, chrome_exe, suffix, &entries); 1486 RegistryEntry::GetProgIdEntries(dist, chrome_exe, suffix, &entries);
1487 RegistryEntry::GetAppRegistrationEntries(chrome_exe, suffix, &entries);
1450 } 1488 }
1451 return AddRegistryEntries(HKEY_CURRENT_USER, entries); 1489 return AddRegistryEntries(HKEY_CURRENT_USER, entries);
1490 } else {
1491 // The ProgId is registered unsuffixed in HKCU, also register the app with
1492 // Windows in HKCU (this was not done in the old registration style and
1493 // thus needs to be done after the above check for the unsuffixed
1494 // registration).
1495 entries.clear();
1496 RegistryEntry::GetAppRegistrationEntries(chrome_exe, string16(), &entries);
1497 return AddRegistryEntries(HKEY_CURRENT_USER, entries);
1452 } 1498 }
1453 return true; 1499 return true;
1454 } 1500 }
1455 1501
1456 bool ShellUtil::RegisterChromeForProtocol(BrowserDistribution* dist, 1502 bool ShellUtil::RegisterChromeForProtocol(BrowserDistribution* dist,
1457 const string16& chrome_exe, 1503 const string16& chrome_exe,
1458 const string16& unique_suffix, 1504 const string16& unique_suffix,
1459 const string16& protocol, 1505 const string16& protocol,
1460 bool elevate_if_not_admin) { 1506 bool elevate_if_not_admin) {
1461 if (!dist->CanSetAsDefault()) 1507 if (!dist->CanSetAsDefault())
(...skipping 13 matching lines...) Expand all
1475 HKEY root = DetermineShellIntegrationRoot( 1521 HKEY root = DetermineShellIntegrationRoot(
1476 InstallUtil::IsPerUserInstall(chrome_exe.c_str())); 1522 InstallUtil::IsPerUserInstall(chrome_exe.c_str()));
1477 1523
1478 if (root == HKEY_CURRENT_USER || IsUserAnAdmin()) { 1524 if (root == HKEY_CURRENT_USER || IsUserAnAdmin()) {
1479 // We can do this operation directly. 1525 // We can do this operation directly.
1480 // First, make sure Chrome is fully registered on this machine. 1526 // First, make sure Chrome is fully registered on this machine.
1481 if (!RegisterChromeBrowser(dist, chrome_exe, suffix, false)) 1527 if (!RegisterChromeBrowser(dist, chrome_exe, suffix, false))
1482 return false; 1528 return false;
1483 1529
1484 // Write in the capabillity for the protocol. 1530 // Write in the capabillity for the protocol.
1485 std::list<RegistryEntry*> entries; 1531 ScopedVector<RegistryEntry> entries;
1486 STLElementDeleter<std::list<RegistryEntry*> > entries_deleter(&entries);
1487 RegistryEntry::GetProtocolCapabilityEntries(dist, suffix, protocol, 1532 RegistryEntry::GetProtocolCapabilityEntries(dist, suffix, protocol,
1488 &entries); 1533 &entries);
1489 return AddRegistryEntries(root, entries); 1534 return AddRegistryEntries(root, entries);
1490 } else if (elevate_if_not_admin && 1535 } else if (elevate_if_not_admin &&
1491 base::win::GetVersion() >= base::win::VERSION_VISTA) { 1536 base::win::GetVersion() >= base::win::VERSION_VISTA) {
1492 // Elevate to do the whole job 1537 // Elevate to do the whole job
1493 return ElevateAndRegisterChrome(dist, chrome_exe, suffix, protocol); 1538 return ElevateAndRegisterChrome(dist, chrome_exe, suffix, protocol);
1494 } else { 1539 } else {
1495 // Admin rights are required to register capabilities before Windows 8. 1540 // Admin rights are required to register capabilities before Windows 8.
1496 return false; 1541 return false;
1497 } 1542 }
1498 } 1543 }
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
1672 // are any left...). 1717 // are any left...).
1673 if (free_bits >= 8 && next_byte_index < size) { 1718 if (free_bits >= 8 && next_byte_index < size) {
1674 free_bits -= 8; 1719 free_bits -= 8;
1675 bit_stream += bytes[next_byte_index++] << free_bits; 1720 bit_stream += bytes[next_byte_index++] << free_bits;
1676 } 1721 }
1677 } 1722 }
1678 1723
1679 DCHECK_EQ(ret.length(), encoded_length); 1724 DCHECK_EQ(ret.length(), encoded_length);
1680 return ret; 1725 return ret;
1681 } 1726 }
OLDNEW
« no previous file with comments | « chrome/installer/util/shell_util.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698