OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 // | 4 // |
5 // This file defines functions that integrate Chrome in Windows shell. These | 5 // This file defines functions that integrate Chrome in Windows shell. These |
6 // functions can be used by Chrome as well as Chrome installer. All of the | 6 // functions can be used by Chrome as well as Chrome installer. All of the |
7 // work is done by the local functions defined in anonymous namespace in | 7 // work is done by the local functions defined in anonymous namespace in |
8 // this class. | 8 // this class. |
9 | 9 |
10 #include "chrome/installer/util/shell_util.h" | 10 #include "chrome/installer/util/shell_util.h" |
11 | 11 |
12 #include <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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 } |
OLD | NEW |