OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 the methods useful for uninstalling Chrome. | 5 // This file defines the methods useful for uninstalling Chrome. |
6 | 6 |
7 #include "chrome/installer/setup/uninstall.h" | 7 #include "chrome/installer/setup/uninstall.h" |
8 | 8 |
9 #include "base/file_util.h" | 9 #include "base/file_util.h" |
10 #include "base/path_service.h" | 10 #include "base/path_service.h" |
(...skipping 14 matching lines...) Expand all Loading... |
25 #include "chrome/installer/util/install_util.h" | 25 #include "chrome/installer/util/install_util.h" |
26 #include "chrome/installer/util/logging_installer.h" | 26 #include "chrome/installer/util/logging_installer.h" |
27 #include "chrome/installer/util/shell_util.h" | 27 #include "chrome/installer/util/shell_util.h" |
28 #include "chrome/installer/util/util_constants.h" | 28 #include "chrome/installer/util/util_constants.h" |
29 #include "chrome/installer/util/version.h" | 29 #include "chrome/installer/util/version.h" |
30 | 30 |
31 // Build-time generated include file. | 31 // Build-time generated include file. |
32 #include "registered_dlls.h" // NOLINT | 32 #include "registered_dlls.h" // NOLINT |
33 | 33 |
34 using base::win::RegKey; | 34 using base::win::RegKey; |
35 using installer::InstallStatus; | 35 using installer_util::InstallStatus; |
36 | 36 |
37 namespace installer { | 37 namespace installer { |
38 | 38 |
39 // This functions checks for any Chrome instances that are | 39 // This functions checks for any Chrome instances that are |
40 // running and first asks them to close politely by sending a Windows message. | 40 // running and first asks them to close politely by sending a Windows message. |
41 // If there is an error while sending message or if there are still Chrome | 41 // If there is an error while sending message or if there are still Chrome |
42 // procesess active after the message has been sent, this function will try | 42 // procesess active after the message has been sent, this function will try |
43 // to kill them. | 43 // to kill them. |
44 void CloseAllChromeProcesses() { | 44 void CloseAllChromeProcesses() { |
45 for (int j = 0; j < 4; ++j) { | 45 for (int j = 0; j < 4; ++j) { |
46 std::wstring wnd_class(L"Chrome_WidgetWin_"); | 46 std::wstring wnd_class(L"Chrome_WidgetWin_"); |
47 wnd_class.append(base::IntToString16(j)); | 47 wnd_class.append(base::IntToString16(j)); |
48 HWND window = FindWindowEx(NULL, NULL, wnd_class.c_str(), NULL); | 48 HWND window = FindWindowEx(NULL, NULL, wnd_class.c_str(), NULL); |
49 while (window) { | 49 while (window) { |
50 HWND tmpWnd = window; | 50 HWND tmpWnd = window; |
51 window = FindWindowEx(NULL, window, wnd_class.c_str(), NULL); | 51 window = FindWindowEx(NULL, window, wnd_class.c_str(), NULL); |
52 if (!SendMessageTimeout(tmpWnd, WM_CLOSE, 0, 0, SMTO_BLOCK, 3000, NULL) && | 52 if (!SendMessageTimeout(tmpWnd, WM_CLOSE, 0, 0, SMTO_BLOCK, 3000, NULL) && |
53 (GetLastError() == ERROR_TIMEOUT)) { | 53 (GetLastError() == ERROR_TIMEOUT)) { |
54 base::CleanupProcesses(installer::kChromeExe, 0, | 54 base::CleanupProcesses(installer_util::kChromeExe, 0, |
55 ResultCodes::HUNG, NULL); | 55 ResultCodes::HUNG, NULL); |
56 base::CleanupProcesses(installer::kNaClExe, 0, | 56 base::CleanupProcesses(installer_util::kNaClExe, 0, |
57 ResultCodes::HUNG, NULL); | 57 ResultCodes::HUNG, NULL); |
58 return; | 58 return; |
59 } | 59 } |
60 } | 60 } |
61 } | 61 } |
62 | 62 |
63 // If asking politely didn't work, wait for 15 seconds and then kill all | 63 // If asking politely didn't work, wait for 15 seconds and then kill all |
64 // chrome.exe. This check is just in case Chrome is ignoring WM_CLOSE | 64 // chrome.exe. This check is just in case Chrome is ignoring WM_CLOSE |
65 // messages. | 65 // messages. |
66 base::CleanupProcesses(installer::kChromeExe, 15000, | 66 base::CleanupProcesses(installer_util::kChromeExe, 15000, |
67 ResultCodes::HUNG, NULL); | 67 ResultCodes::HUNG, NULL); |
68 base::CleanupProcesses(installer::kNaClExe, 15000, | 68 base::CleanupProcesses(installer_util::kNaClExe, 15000, |
69 ResultCodes::HUNG, NULL); | 69 ResultCodes::HUNG, NULL); |
70 } | 70 } |
71 | 71 |
72 // Attempts to close the Chrome Frame helper process by sending WM_CLOSE | 72 // Attempts to close the Chrome Frame helper process by sending WM_CLOSE |
73 // messages to its window, or just killing it if that doesn't work. | 73 // messages to its window, or just killing it if that doesn't work. |
74 void CloseChromeFrameHelperProcess() { | 74 void CloseChromeFrameHelperProcess() { |
75 HWND window = FindWindow(installer::kChromeFrameHelperWndClass, NULL); | 75 HWND window = FindWindow(installer_util::kChromeFrameHelperWndClass, NULL); |
76 if (!::IsWindow(window)) | 76 if (!::IsWindow(window)) |
77 return; | 77 return; |
78 | 78 |
79 const DWORD kWaitMs = 3000; | 79 const DWORD kWaitMs = 3000; |
80 | 80 |
81 DWORD pid = 0; | 81 DWORD pid = 0; |
82 ::GetWindowThreadProcessId(window, &pid); | 82 ::GetWindowThreadProcessId(window, &pid); |
83 DCHECK_NE(pid, 0U); | 83 DCHECK_NE(pid, 0U); |
84 ScopedHandle process(::OpenProcess(SYNCHRONIZE, FALSE, pid)); | 84 ScopedHandle process(::OpenProcess(SYNCHRONIZE, FALSE, pid)); |
85 PLOG_IF(INFO, !process) << "Failed to open process: " << pid; | 85 PLOG_IF(INFO, !process) << "Failed to open process: " << pid; |
86 | 86 |
87 bool kill = true; | 87 bool kill = true; |
88 if (SendMessageTimeout(window, WM_CLOSE, 0, 0, SMTO_BLOCK, kWaitMs, NULL) && | 88 if (SendMessageTimeout(window, WM_CLOSE, 0, 0, SMTO_BLOCK, kWaitMs, NULL) && |
89 process) { | 89 process) { |
90 VLOG(1) << "Waiting for " << installer::kChromeFrameHelperExe; | 90 VLOG(1) << "Waiting for " << installer_util::kChromeFrameHelperExe; |
91 DWORD wait = ::WaitForSingleObject(process, kWaitMs); | 91 DWORD wait = ::WaitForSingleObject(process, kWaitMs); |
92 if (wait != WAIT_OBJECT_0) { | 92 if (wait != WAIT_OBJECT_0) { |
93 LOG(WARNING) << "Wait for " << installer::kChromeFrameHelperExe | 93 LOG(WARNING) << "Wait for " << installer_util::kChromeFrameHelperExe |
94 << " to exit failed or timed out."; | 94 << " to exit failed or timed out."; |
95 } else { | 95 } else { |
96 kill = false; | 96 kill = false; |
97 VLOG(1) << installer::kChromeFrameHelperExe << " exited normally."; | 97 VLOG(1) << installer_util::kChromeFrameHelperExe << " exited normally."; |
98 } | 98 } |
99 } | 99 } |
100 | 100 |
101 if (kill) { | 101 if (kill) { |
102 VLOG(1) << installer::kChromeFrameHelperExe << " hung. Killing."; | 102 VLOG(1) << installer_util::kChromeFrameHelperExe << " hung. Killing."; |
103 base::CleanupProcesses(installer::kChromeFrameHelperExe, 0, | 103 base::CleanupProcesses(installer_util::kChromeFrameHelperExe, 0, |
104 ResultCodes::HUNG, NULL); | 104 ResultCodes::HUNG, NULL); |
105 } | 105 } |
106 } | 106 } |
107 | 107 |
108 // This method tries to figure out if current user has registered Chrome. | 108 // This method tries to figure out if current user has registered Chrome. |
109 // It returns true iff: | 109 // It returns true iff: |
110 // - Software\Clients\StartMenuInternet\Chromium\"" key has a valid value. | 110 // - Software\Clients\StartMenuInternet\Chromium\"" key has a valid value. |
111 // - The value is same as chrome.exe path for the current installation. | 111 // - The value is same as chrome.exe path for the current installation. |
112 bool CurrentUserHasDefaultBrowser(const Product& product) { | 112 bool CurrentUserHasDefaultBrowser(const Product& product) { |
113 std::wstring reg_key(ShellUtil::kRegStartMenuInternet); | 113 std::wstring reg_key(ShellUtil::kRegStartMenuInternet); |
114 reg_key.append(L"\\" + product.distribution()->GetApplicationName() + | 114 reg_key.append(L"\\" + product.distribution()->GetApplicationName() + |
115 ShellUtil::kRegShellOpen); | 115 ShellUtil::kRegShellOpen); |
116 RegKey key(HKEY_LOCAL_MACHINE, reg_key.c_str(), KEY_READ); | 116 RegKey key(HKEY_LOCAL_MACHINE, reg_key.c_str(), KEY_READ); |
117 std::wstring reg_exe; | 117 std::wstring reg_exe; |
118 if (key.ReadValue(L"", ®_exe) && reg_exe.length() > 2) { | 118 if (key.ReadValue(L"", ®_exe) && reg_exe.length() > 2) { |
119 FilePath chrome_exe(product.package().path() | 119 FilePath chrome_exe(product.package().path() |
120 .Append(installer::kChromeExe)); | 120 .Append(installer_util::kChromeExe)); |
121 // The path in the registry will always have quotes. | 121 // The path in the registry will always have quotes. |
122 reg_exe = reg_exe.substr(1, reg_exe.length() - 2); | 122 reg_exe = reg_exe.substr(1, reg_exe.length() - 2); |
123 if (FilePath::CompareEqualIgnoreCase(reg_exe, chrome_exe.value())) | 123 if (FilePath::CompareEqualIgnoreCase(reg_exe, chrome_exe.value())) |
124 return true; | 124 return true; |
125 } | 125 } |
126 | 126 |
127 return false; | 127 return false; |
128 } | 128 } |
129 | 129 |
130 // This method deletes Chrome shortcut folder from Windows Start menu. It | 130 // This method deletes Chrome shortcut folder from Windows Start menu. It |
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
334 } | 334 } |
335 return result; | 335 return result; |
336 } | 336 } |
337 | 337 |
338 // This method checks if Chrome is currently running or if the user has | 338 // This method checks if Chrome is currently running or if the user has |
339 // cancelled the uninstall operation by clicking Cancel on the confirmation | 339 // cancelled the uninstall operation by clicking Cancel on the confirmation |
340 // box that Chrome pops up. | 340 // box that Chrome pops up. |
341 InstallStatus IsChromeActiveOrUserCancelled(const Product& product) { | 341 InstallStatus IsChromeActiveOrUserCancelled(const Product& product) { |
342 int32 exit_code = ResultCodes::NORMAL_EXIT; | 342 int32 exit_code = ResultCodes::NORMAL_EXIT; |
343 CommandLine options(CommandLine::NO_PROGRAM); | 343 CommandLine options(CommandLine::NO_PROGRAM); |
344 options.AppendSwitch(installer::switches::kUninstall); | 344 options.AppendSwitch(installer_util::switches::kUninstall); |
345 | 345 |
346 // Here we want to save user from frustration (in case of Chrome crashes) | 346 // Here we want to save user from frustration (in case of Chrome crashes) |
347 // and continue with the uninstallation as long as chrome.exe process exit | 347 // and continue with the uninstallation as long as chrome.exe process exit |
348 // code is NOT one of the following: | 348 // code is NOT one of the following: |
349 // - UNINSTALL_CHROME_ALIVE - chrome.exe is currently running | 349 // - UNINSTALL_CHROME_ALIVE - chrome.exe is currently running |
350 // - UNINSTALL_USER_CANCEL - User cancelled uninstallation | 350 // - UNINSTALL_USER_CANCEL - User cancelled uninstallation |
351 // - HUNG - chrome.exe was killed by HuntForZombieProcesses() (until we can | 351 // - HUNG - chrome.exe was killed by HuntForZombieProcesses() (until we can |
352 // give this method some brains and not kill chrome.exe launched | 352 // give this method some brains and not kill chrome.exe launched |
353 // by us, we will not uninstall if we get this return code). | 353 // by us, we will not uninstall if we get this return code). |
354 VLOG(1) << "Launching Chrome to do uninstall tasks."; | 354 VLOG(1) << "Launching Chrome to do uninstall tasks."; |
355 if (product.LaunchChromeAndWait(options, &exit_code)) { | 355 if (product.LaunchChromeAndWait(options, &exit_code)) { |
356 VLOG(1) << "chrome.exe launched for uninstall confirmation returned: " | 356 VLOG(1) << "chrome.exe launched for uninstall confirmation returned: " |
357 << exit_code; | 357 << exit_code; |
358 if ((exit_code == ResultCodes::UNINSTALL_CHROME_ALIVE) || | 358 if ((exit_code == ResultCodes::UNINSTALL_CHROME_ALIVE) || |
359 (exit_code == ResultCodes::UNINSTALL_USER_CANCEL) || | 359 (exit_code == ResultCodes::UNINSTALL_USER_CANCEL) || |
360 (exit_code == ResultCodes::HUNG)) | 360 (exit_code == ResultCodes::HUNG)) |
361 return installer::UNINSTALL_CANCELLED; | 361 return installer_util::UNINSTALL_CANCELLED; |
362 | 362 |
363 if (exit_code == ResultCodes::UNINSTALL_DELETE_PROFILE) | 363 if (exit_code == ResultCodes::UNINSTALL_DELETE_PROFILE) |
364 return installer::UNINSTALL_DELETE_PROFILE; | 364 return installer_util::UNINSTALL_DELETE_PROFILE; |
365 } else { | 365 } else { |
366 PLOG(ERROR) << "Failed to launch chrome.exe for uninstall confirmation."; | 366 PLOG(ERROR) << "Failed to launch chrome.exe for uninstall confirmation."; |
367 } | 367 } |
368 | 368 |
369 return installer::UNINSTALL_CONFIRMED; | 369 return installer_util::UNINSTALL_CONFIRMED; |
370 } | 370 } |
371 | 371 |
372 bool ShouldDeleteProfile(const CommandLine& cmd_line, InstallStatus status, | 372 bool ShouldDeleteProfile(const CommandLine& cmd_line, InstallStatus status, |
373 const Product& product) { | 373 const Product& product) { |
374 bool should_delete = false; | 374 bool should_delete = false; |
375 | 375 |
376 // Chrome Frame uninstallations always want to delete the profile (we have no | 376 // Chrome Frame uninstallations always want to delete the profile (we have no |
377 // UI to prompt otherwise and the profile stores no useful data anyway) | 377 // UI to prompt otherwise and the profile stores no useful data anyway) |
378 // unless they are managed by MSI. MSI uninstalls will explicitly include | 378 // unless they are managed by MSI. MSI uninstalls will explicitly include |
379 // the --delete-profile flag to distinguish them from MSI upgrades. | 379 // the --delete-profile flag to distinguish them from MSI upgrades. |
380 if (product.distribution()->GetType() != | 380 if (product.distribution()->GetType() != |
381 BrowserDistribution::CHROME_BROWSER && !product.IsMsi()) { | 381 BrowserDistribution::CHROME_BROWSER && !product.IsMsi()) { |
382 should_delete = true; | 382 should_delete = true; |
383 } else { | 383 } else { |
384 should_delete = | 384 should_delete = |
385 status == installer::UNINSTALL_DELETE_PROFILE || | 385 status == installer_util::UNINSTALL_DELETE_PROFILE || |
386 cmd_line.HasSwitch(installer::switches::kDeleteProfile); | 386 cmd_line.HasSwitch(installer_util::switches::kDeleteProfile); |
387 } | 387 } |
388 | 388 |
389 return should_delete; | 389 return should_delete; |
390 } | 390 } |
391 | 391 |
392 bool DeleteChromeRegistrationKeys(BrowserDistribution* dist, HKEY root, | 392 bool DeleteChromeRegistrationKeys(BrowserDistribution* dist, HKEY root, |
393 const std::wstring& browser_entry_suffix, | 393 const std::wstring& browser_entry_suffix, |
394 InstallStatus& exit_code) { | 394 InstallStatus& exit_code) { |
395 if (!dist->CanSetAsDefault()) { | 395 if (!dist->CanSetAsDefault()) { |
396 // We should have never set those keys. | 396 // We should have never set those keys. |
(...skipping 14 matching lines...) Expand all Loading... |
411 // Delete Software\Clients\StartMenuInternet\Chromium | 411 // Delete Software\Clients\StartMenuInternet\Chromium |
412 std::wstring set_access_key(ShellUtil::kRegStartMenuInternet); | 412 std::wstring set_access_key(ShellUtil::kRegStartMenuInternet); |
413 file_util::AppendToPath(&set_access_key, dist->GetApplicationName()); | 413 file_util::AppendToPath(&set_access_key, dist->GetApplicationName()); |
414 set_access_key.append(browser_entry_suffix); | 414 set_access_key.append(browser_entry_suffix); |
415 InstallUtil::DeleteRegistryKey(key, set_access_key); | 415 InstallUtil::DeleteRegistryKey(key, set_access_key); |
416 | 416 |
417 // We have renamed the StartMenuInternet\chrome.exe to | 417 // We have renamed the StartMenuInternet\chrome.exe to |
418 // StartMenuInternet\Chromium so for old users we still need to delete | 418 // StartMenuInternet\Chromium so for old users we still need to delete |
419 // the old key. | 419 // the old key. |
420 std::wstring old_set_access_key(ShellUtil::kRegStartMenuInternet); | 420 std::wstring old_set_access_key(ShellUtil::kRegStartMenuInternet); |
421 file_util::AppendToPath(&old_set_access_key, installer::kChromeExe); | 421 file_util::AppendToPath(&old_set_access_key, installer_util::kChromeExe); |
422 InstallUtil::DeleteRegistryKey(key, old_set_access_key); | 422 InstallUtil::DeleteRegistryKey(key, old_set_access_key); |
423 | 423 |
424 // Delete Software\RegisteredApplications\Chromium | 424 // Delete Software\RegisteredApplications\Chromium |
425 InstallUtil::DeleteRegistryValue(root, ShellUtil::kRegRegisteredApplications, | 425 InstallUtil::DeleteRegistryValue(root, ShellUtil::kRegRegisteredApplications, |
426 dist->GetApplicationName() + browser_entry_suffix); | 426 dist->GetApplicationName() + browser_entry_suffix); |
427 | 427 |
428 // Delete Software\Classes\Applications\chrome.exe | 428 // Delete Software\Classes\Applications\chrome.exe |
429 std::wstring app_key(ShellUtil::kRegClasses); | 429 std::wstring app_key(ShellUtil::kRegClasses); |
430 file_util::AppendToPath(&app_key, L"Applications"); | 430 file_util::AppendToPath(&app_key, L"Applications"); |
431 file_util::AppendToPath(&app_key, installer::kChromeExe); | 431 file_util::AppendToPath(&app_key, installer_util::kChromeExe); |
432 InstallUtil::DeleteRegistryKey(key, app_key); | 432 InstallUtil::DeleteRegistryKey(key, app_key); |
433 | 433 |
434 // Delete the App Paths key that lets explorer find Chrome. | 434 // Delete the App Paths key that lets explorer find Chrome. |
435 std::wstring app_path_key(ShellUtil::kAppPathsRegistryKey); | 435 std::wstring app_path_key(ShellUtil::kAppPathsRegistryKey); |
436 file_util::AppendToPath(&app_path_key, installer::kChromeExe); | 436 file_util::AppendToPath(&app_path_key, installer_util::kChromeExe); |
437 InstallUtil::DeleteRegistryKey(key, app_path_key); | 437 InstallUtil::DeleteRegistryKey(key, app_path_key); |
438 | 438 |
439 // Cleanup OpenWithList | 439 // Cleanup OpenWithList |
440 for (int i = 0; ShellUtil::kFileAssociations[i] != NULL; i++) { | 440 for (int i = 0; ShellUtil::kFileAssociations[i] != NULL; i++) { |
441 std::wstring open_with_key(ShellUtil::kRegClasses); | 441 std::wstring open_with_key(ShellUtil::kRegClasses); |
442 file_util::AppendToPath(&open_with_key, ShellUtil::kFileAssociations[i]); | 442 file_util::AppendToPath(&open_with_key, ShellUtil::kFileAssociations[i]); |
443 file_util::AppendToPath(&open_with_key, L"OpenWithList"); | 443 file_util::AppendToPath(&open_with_key, L"OpenWithList"); |
444 file_util::AppendToPath(&open_with_key, installer::kChromeExe); | 444 file_util::AppendToPath(&open_with_key, installer_util::kChromeExe); |
445 InstallUtil::DeleteRegistryKey(key, open_with_key); | 445 InstallUtil::DeleteRegistryKey(key, open_with_key); |
446 } | 446 } |
447 | 447 |
448 key.Close(); | 448 key.Close(); |
449 exit_code = installer::UNINSTALL_SUCCESSFUL; | 449 exit_code = installer_util::UNINSTALL_SUCCESSFUL; |
450 return true; | 450 return true; |
451 } | 451 } |
452 | 452 |
453 void RemoveLegacyRegistryKeys(BrowserDistribution* dist) { | 453 void RemoveLegacyRegistryKeys(BrowserDistribution* dist) { |
454 // We used to register Chrome to handle crx files, but this turned out | 454 // We used to register Chrome to handle crx files, but this turned out |
455 // to be not worth the hassle. Remove these old registry entries if | 455 // to be not worth the hassle. Remove these old registry entries if |
456 // they exist. See: http://codereview.chromium.org/210007 | 456 // they exist. See: http://codereview.chromium.org/210007 |
457 | 457 |
458 #if defined(GOOGLE_CHROME_BUILD) | 458 #if defined(GOOGLE_CHROME_BUILD) |
459 const wchar_t kChromeExtProgId[] = L"ChromeExt"; | 459 const wchar_t kChromeExtProgId[] = L"ChromeExt"; |
(...skipping 22 matching lines...) Expand all Loading... |
482 ext_association.append(chrome::kExtensionFileExtension); | 482 ext_association.append(chrome::kExtensionFileExtension); |
483 InstallUtil::DeleteRegistryKey(key, ext_association); | 483 InstallUtil::DeleteRegistryKey(key, ext_association); |
484 } | 484 } |
485 } | 485 } |
486 | 486 |
487 InstallStatus UninstallChrome(const FilePath& setup_path, | 487 InstallStatus UninstallChrome(const FilePath& setup_path, |
488 const Product& product, | 488 const Product& product, |
489 bool remove_all, | 489 bool remove_all, |
490 bool force_uninstall, | 490 bool force_uninstall, |
491 const CommandLine& cmd_line) { | 491 const CommandLine& cmd_line) { |
492 InstallStatus status = installer::UNINSTALL_CONFIRMED; | 492 InstallStatus status = installer_util::UNINSTALL_CONFIRMED; |
493 std::wstring suffix; | 493 std::wstring suffix; |
494 if (!ShellUtil::GetUserSpecificDefaultBrowserSuffix(product.distribution(), | 494 if (!ShellUtil::GetUserSpecificDefaultBrowserSuffix(product.distribution(), |
495 &suffix)) | 495 &suffix)) |
496 suffix = L""; | 496 suffix = L""; |
497 | 497 |
498 BrowserDistribution* browser_dist = product.distribution(); | 498 BrowserDistribution* browser_dist = product.distribution(); |
499 bool is_chrome = (browser_dist->GetType() == | 499 bool is_chrome = (browser_dist->GetType() == |
500 BrowserDistribution::CHROME_BROWSER); | 500 BrowserDistribution::CHROME_BROWSER); |
501 | 501 |
502 VLOG(1) << "UninstallChrome: " << browser_dist->GetApplicationName(); | 502 VLOG(1) << "UninstallChrome: " << browser_dist->GetApplicationName(); |
503 | 503 |
504 if (force_uninstall) { | 504 if (force_uninstall) { |
505 // Since --force-uninstall command line option is used, we are going to | 505 // Since --force-uninstall command line option is used, we are going to |
506 // do silent uninstall. Try to close all running Chrome instances. | 506 // do silent uninstall. Try to close all running Chrome instances. |
507 // NOTE: We don't do this for Chrome Frame or CEEE. | 507 // NOTE: We don't do this for Chrome Frame or CEEE. |
508 if (is_chrome) | 508 if (is_chrome) |
509 CloseAllChromeProcesses(); | 509 CloseAllChromeProcesses(); |
510 } else if (is_chrome) { | 510 } else if (is_chrome) { |
511 // no --force-uninstall so lets show some UI dialog boxes. | 511 // no --force-uninstall so lets show some UI dialog boxes. |
512 status = IsChromeActiveOrUserCancelled(product); | 512 status = IsChromeActiveOrUserCancelled(product); |
513 if (status != installer::UNINSTALL_CONFIRMED && | 513 if (status != installer_util::UNINSTALL_CONFIRMED && |
514 status != installer::UNINSTALL_DELETE_PROFILE) | 514 status != installer_util::UNINSTALL_DELETE_PROFILE) |
515 return status; | 515 return status; |
516 | 516 |
517 // Check if we need admin rights to cleanup HKLM. If we do, try to launch | 517 // Check if we need admin rights to cleanup HKLM. If we do, try to launch |
518 // another uninstaller (silent) in elevated mode to do HKLM cleanup. | 518 // another uninstaller (silent) in elevated mode to do HKLM cleanup. |
519 // And continue uninstalling in the current process also to do HKCU cleanup. | 519 // And continue uninstalling in the current process also to do HKCU cleanup. |
520 if (remove_all && | 520 if (remove_all && |
521 (!suffix.empty() || CurrentUserHasDefaultBrowser(product)) && | 521 (!suffix.empty() || CurrentUserHasDefaultBrowser(product)) && |
522 !::IsUserAnAdmin() && | 522 !::IsUserAnAdmin() && |
523 base::win::GetVersion() >= base::win::VERSION_VISTA && | 523 base::win::GetVersion() >= base::win::VERSION_VISTA && |
524 !cmd_line.HasSwitch(installer::switches::kRunAsAdmin)) { | 524 !cmd_line.HasSwitch(installer_util::switches::kRunAsAdmin)) { |
525 CommandLine new_cmd(CommandLine::NO_PROGRAM); | 525 CommandLine new_cmd(CommandLine::NO_PROGRAM); |
526 new_cmd.AppendArguments(cmd_line, true); | 526 new_cmd.AppendArguments(cmd_line, true); |
527 // Append --run-as-admin flag to let the new instance of setup.exe know | 527 // Append --run-as-admin flag to let the new instance of setup.exe know |
528 // that we already tried to launch ourselves as admin. | 528 // that we already tried to launch ourselves as admin. |
529 new_cmd.AppendSwitch(installer::switches::kRunAsAdmin); | 529 new_cmd.AppendSwitch(installer_util::switches::kRunAsAdmin); |
530 // Append --remove-chrome-registration to remove registry keys only. | 530 // Append --remove-chrome-registration to remove registry keys only. |
531 new_cmd.AppendSwitch(installer::switches::kRemoveChromeRegistration); | 531 new_cmd.AppendSwitch(installer_util::switches::kRemoveChromeRegistration); |
532 if (!suffix.empty()) { | 532 if (!suffix.empty()) { |
533 new_cmd.AppendSwitchNative( | 533 new_cmd.AppendSwitchNative( |
534 installer::switches::kRegisterChromeBrowserSuffix, suffix); | 534 installer_util::switches::kRegisterChromeBrowserSuffix, suffix); |
535 } | 535 } |
536 DWORD exit_code = installer::UNKNOWN_STATUS; | 536 DWORD exit_code = installer_util::UNKNOWN_STATUS; |
537 InstallUtil::ExecuteExeAsAdmin(new_cmd, &exit_code); | 537 InstallUtil::ExecuteExeAsAdmin(new_cmd, &exit_code); |
538 } | 538 } |
539 } | 539 } |
540 | 540 |
541 // Get the version of installed Chrome (if any) | 541 // Get the version of installed Chrome (if any) |
542 scoped_ptr<installer::Version> | 542 scoped_ptr<installer::Version> |
543 installed_version(InstallUtil::GetChromeVersion(browser_dist, | 543 installed_version(InstallUtil::GetChromeVersion(browser_dist, |
544 product.system_level())); | 544 product.system_level())); |
545 | 545 |
546 // Chrome is not in use so lets uninstall Chrome by deleting various files | 546 // Chrome is not in use so lets uninstall Chrome by deleting various files |
(...skipping 16 matching lines...) Expand all Loading... |
563 InstallUtil::DeleteRegistryKey(key, browser_dist->GetUninstallRegPath()); | 563 InstallUtil::DeleteRegistryKey(key, browser_dist->GetUninstallRegPath()); |
564 InstallUtil::DeleteRegistryKey(key, browser_dist->GetVersionKey()); | 564 InstallUtil::DeleteRegistryKey(key, browser_dist->GetVersionKey()); |
565 | 565 |
566 // Also try to delete the MSI value in the ClientState key (it might not be | 566 // Also try to delete the MSI value in the ClientState key (it might not be |
567 // there). This is due to a Google Update behaviour where an uninstall and a | 567 // there). This is due to a Google Update behaviour where an uninstall and a |
568 // rapid reinstall might result in stale values from the old ClientState key | 568 // rapid reinstall might result in stale values from the old ClientState key |
569 // being picked up on reinstall. | 569 // being picked up on reinstall. |
570 product.SetMsiMarker(false); | 570 product.SetMsiMarker(false); |
571 | 571 |
572 // Remove all Chrome registration keys. | 572 // Remove all Chrome registration keys. |
573 InstallStatus ret = installer::UNKNOWN_STATUS; | 573 InstallStatus ret = installer_util::UNKNOWN_STATUS; |
574 DeleteChromeRegistrationKeys(product.distribution(), reg_root, suffix, ret); | 574 DeleteChromeRegistrationKeys(product.distribution(), reg_root, suffix, ret); |
575 | 575 |
576 // For user level install also we end up creating some keys in HKLM if user | 576 // For user level install also we end up creating some keys in HKLM if user |
577 // sets Chrome as default browser. So delete those as well (needs admin). | 577 // sets Chrome as default browser. So delete those as well (needs admin). |
578 if (remove_all && !product.system_level() && | 578 if (remove_all && !product.system_level() && |
579 (!suffix.empty() || CurrentUserHasDefaultBrowser(product))) { | 579 (!suffix.empty() || CurrentUserHasDefaultBrowser(product))) { |
580 DeleteChromeRegistrationKeys(product.distribution(), HKEY_LOCAL_MACHINE, | 580 DeleteChromeRegistrationKeys(product.distribution(), HKEY_LOCAL_MACHINE, |
581 suffix, ret); | 581 suffix, ret); |
582 } | 582 } |
583 | 583 |
584 // Delete shared registry keys as well (these require admin rights) if | 584 // Delete shared registry keys as well (these require admin rights) if |
585 // remove_all option is specified. | 585 // remove_all option is specified. |
586 if (remove_all) { | 586 if (remove_all) { |
587 if (!InstallUtil::IsChromeSxSProcess() && is_chrome) { | 587 if (!InstallUtil::IsChromeSxSProcess() && is_chrome) { |
588 // Delete media player registry key that exists only in HKLM. | 588 // Delete media player registry key that exists only in HKLM. |
589 // We don't delete this key in SxS uninstall or Chrome Frame uninstall | 589 // We don't delete this key in SxS uninstall or Chrome Frame uninstall |
590 // as we never set the key for those products. | 590 // as we never set the key for those products. |
591 RegKey hklm_key(HKEY_LOCAL_MACHINE, L"", KEY_ALL_ACCESS); | 591 RegKey hklm_key(HKEY_LOCAL_MACHINE, L"", KEY_ALL_ACCESS); |
592 std::wstring reg_path(installer::kMediaPlayerRegPath); | 592 std::wstring reg_path(installer::kMediaPlayerRegPath); |
593 file_util::AppendToPath(®_path, installer::kChromeExe); | 593 file_util::AppendToPath(®_path, installer_util::kChromeExe); |
594 InstallUtil::DeleteRegistryKey(hklm_key, reg_path); | 594 InstallUtil::DeleteRegistryKey(hklm_key, reg_path); |
595 hklm_key.Close(); | 595 hklm_key.Close(); |
596 } | 596 } |
597 | 597 |
598 // Unregister any dll servers that we may have registered for Chrome Frame | 598 // Unregister any dll servers that we may have registered for Chrome Frame |
599 // and CEEE builds only. | 599 // and CEEE builds only. |
600 // TODO(tommi): We should only do this when the folder itself is | 600 // TODO(tommi): We should only do this when the folder itself is |
601 // being removed and we know that the DLLs were previously registered. | 601 // being removed and we know that the DLLs were previously registered. |
602 // Simplest would be to always register them. | 602 // Simplest would be to always register them. |
603 if (installed_version.get() && !is_chrome) { | 603 if (installed_version.get() && !is_chrome) { |
604 RegisterComDllList(product.package().path().Append( | 604 RegisterComDllList(product.package().path().Append( |
605 installed_version->GetString()), | 605 installed_version->GetString()), |
606 product.system_level(), false, false); | 606 product.system_level(), false, false); |
607 } | 607 } |
608 } | 608 } |
609 | 609 |
610 // Close any Chrome Frame helper processes that may be running. | 610 // Close any Chrome Frame helper processes that may be running. |
611 if (product.distribution()->GetType() == BrowserDistribution::CHROME_FRAME) { | 611 if (product.distribution()->GetType() == BrowserDistribution::CHROME_FRAME) { |
612 VLOG(1) << "Closing the Chrome Frame helper process"; | 612 VLOG(1) << "Closing the Chrome Frame helper process"; |
613 CloseChromeFrameHelperProcess(); | 613 CloseChromeFrameHelperProcess(); |
614 } | 614 } |
615 | 615 |
616 if (!installed_version.get()) | 616 if (!installed_version.get()) |
617 return installer::UNINSTALL_SUCCESSFUL; | 617 return installer_util::UNINSTALL_SUCCESSFUL; |
618 | 618 |
619 // Finally delete all the files from Chrome folder after moving setup.exe | 619 // Finally delete all the files from Chrome folder after moving setup.exe |
620 // and the user's Local State to a temp location. | 620 // and the user's Local State to a temp location. |
621 bool delete_profile = ShouldDeleteProfile(cmd_line, status, product); | 621 bool delete_profile = ShouldDeleteProfile(cmd_line, status, product); |
622 ret = installer::UNINSTALL_SUCCESSFUL; | 622 ret = installer_util::UNINSTALL_SUCCESSFUL; |
623 | 623 |
624 // In order to be able to remove the folder in which we're running, we | 624 // In order to be able to remove the folder in which we're running, we |
625 // need to move setup.exe out of the install folder. | 625 // need to move setup.exe out of the install folder. |
626 // TODO(tommi): What if the temp folder is on a different volume? | 626 // TODO(tommi): What if the temp folder is on a different volume? |
627 MoveSetupOutOfInstallFolder(product.package(), setup_path, | 627 MoveSetupOutOfInstallFolder(product.package(), setup_path, |
628 *installed_version); | 628 *installed_version); |
629 | 629 |
630 FilePath backup_state_file(BackupLocalStateFile( | 630 FilePath backup_state_file(BackupLocalStateFile( |
631 GetLocalStateFolder(product))); | 631 GetLocalStateFolder(product))); |
632 | 632 |
633 // TODO(tommi): We should only do this when the last distribution is being | 633 // TODO(tommi): We should only do this when the last distribution is being |
634 // uninstalled. | 634 // uninstalled. |
635 DeleteResult delete_result = DeleteFilesAndFolders(product.package(), | 635 DeleteResult delete_result = DeleteFilesAndFolders(product.package(), |
636 *installed_version); | 636 *installed_version); |
637 | 637 |
638 if (delete_profile) | 638 if (delete_profile) |
639 DeleteLocalState(product); | 639 DeleteLocalState(product); |
640 | 640 |
641 if (delete_result == DELETE_FAILED) { | 641 if (delete_result == DELETE_FAILED) { |
642 ret = installer::UNINSTALL_FAILED; | 642 ret = installer_util::UNINSTALL_FAILED; |
643 } else if (delete_result == DELETE_REQUIRES_REBOOT) { | 643 } else if (delete_result == DELETE_REQUIRES_REBOOT) { |
644 ret = installer::UNINSTALL_REQUIRES_REBOOT; | 644 ret = installer_util::UNINSTALL_REQUIRES_REBOOT; |
645 } | 645 } |
646 | 646 |
647 if (!force_uninstall) { | 647 if (!force_uninstall) { |
648 VLOG(1) << "Uninstallation complete. Launching Uninstall survey."; | 648 VLOG(1) << "Uninstallation complete. Launching Uninstall survey."; |
649 browser_dist->DoPostUninstallOperations(*installed_version, | 649 browser_dist->DoPostUninstallOperations(*installed_version, |
650 backup_state_file, distribution_data); | 650 backup_state_file, distribution_data); |
651 } | 651 } |
652 | 652 |
653 // Try and delete the preserved local state once the post-install | 653 // Try and delete the preserved local state once the post-install |
654 // operations are complete. | 654 // operations are complete. |
655 if (!backup_state_file.empty()) | 655 if (!backup_state_file.empty()) |
656 file_util::Delete(backup_state_file, false); | 656 file_util::Delete(backup_state_file, false); |
657 | 657 |
658 return ret; | 658 return ret; |
659 } | 659 } |
660 | 660 |
661 } // namespace installer | 661 } // namespace installer |
662 | 662 |
OLD | NEW |