summaryrefslogtreecommitdiffstats
path: root/chrome/installer
diff options
context:
space:
mode:
authortommi@chromium.org <tommi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-11-11 17:37:05 +0000
committertommi@chromium.org <tommi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-11-11 17:37:05 +0000
commit82a5648222234f6a02f2d7332ca5b478760cd0b2 (patch)
tree428422d8a1d83be494f1fca28eca3eed5aa59a73 /chrome/installer
parent0b3f82a4229ba3c275046ac5189485ebe34b5b88 (diff)
downloadchromium_src-82a5648222234f6a02f2d7332ca5b478760cd0b2.zip
chromium_src-82a5648222234f6a02f2d7332ca5b478760cd0b2.tar.gz
chromium_src-82a5648222234f6a02f2d7332ca5b478760cd0b2.tar.bz2
Wait a bit for the helper to exit before continuing with removing files.
Also adding a bit of logging for easier diagnostics when we can't remove a folder due to files being in use on uninstall. TEST=Should improve our chances of being able to uninstall without needing to reboot. BUG=61609 Review URL: http://codereview.chromium.org/4773002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@65814 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/installer')
-rw-r--r--chrome/installer/setup/uninstall.cc35
-rw-r--r--chrome/installer/util/delete_after_reboot_helper.cc19
2 files changed, 48 insertions, 6 deletions
diff --git a/chrome/installer/setup/uninstall.cc b/chrome/installer/setup/uninstall.cc
index 1517946..7a3ca1d 100644
--- a/chrome/installer/setup/uninstall.cc
+++ b/chrome/installer/setup/uninstall.cc
@@ -8,6 +8,7 @@
#include "base/file_util.h"
#include "base/path_service.h"
+#include "base/scoped_handle.h"
#include "base/string_number_conversions.h"
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
@@ -69,10 +70,35 @@ void CloseAllChromeProcesses() {
// Attempts to close the Chrome Frame helper process by sending WM_CLOSE
// messages to its window, or just killing it if that doesn't work.
-void CloseAllChromeFrameHelperProcesses() {
+void CloseChromeFrameHelperProcess() {
HWND window = FindWindow(installer_util::kChromeFrameHelperWndClass, NULL);
- if (window &&
- !SendMessageTimeout(window, WM_CLOSE, 0, 0, SMTO_BLOCK, 3000, NULL)) {
+ if (!::IsWindow(window))
+ return;
+
+ const DWORD kWaitMs = 3000;
+
+ DWORD pid = 0;
+ ::GetWindowThreadProcessId(window, &pid);
+ DCHECK_NE(pid, 0U);
+ ScopedHandle process(::OpenProcess(SYNCHRONIZE, FALSE, pid));
+ PLOG_IF(INFO, !process) << "Failed to open process: " << pid;
+
+ bool kill = true;
+ if (SendMessageTimeout(window, WM_CLOSE, 0, 0, SMTO_BLOCK, kWaitMs, NULL) &&
+ process) {
+ VLOG(1) << "Waiting for " << installer_util::kChromeFrameHelperExe;
+ DWORD wait = ::WaitForSingleObject(process, kWaitMs);
+ if (wait != WAIT_OBJECT_0) {
+ LOG(WARNING) << "Wait for " << installer_util::kChromeFrameHelperExe
+ << " to exit failed or timed out.";
+ } else {
+ kill = false;
+ VLOG(1) << installer_util::kChromeFrameHelperExe << " exited normally.";
+ }
+ }
+
+ if (kill) {
+ VLOG(1) << installer_util::kChromeFrameHelperExe << " hung. Killing.";
base::CleanupProcesses(installer_util::kChromeFrameHelperExe, 0,
ResultCodes::HUNG, NULL);
}
@@ -563,7 +589,8 @@ installer_util::InstallStatus installer_setup::UninstallChrome(
// Close any Chrome Frame helper processes that may be running.
if (InstallUtil::IsChromeFrameProcess()) {
- CloseAllChromeFrameHelperProcesses();
+ VLOG(1) << "Closing the Chrome Frame helper process";
+ CloseChromeFrameHelperProcess();
}
if (!installed_version.get())
diff --git a/chrome/installer/util/delete_after_reboot_helper.cc b/chrome/installer/util/delete_after_reboot_helper.cc
index e2449e7..075a6a9 100644
--- a/chrome/installer/util/delete_after_reboot_helper.cc
+++ b/chrome/installer/util/delete_after_reboot_helper.cc
@@ -57,7 +57,7 @@ bool ScheduleFileSystemEntityForDeletion(const wchar_t* path) {
// Check if the file exists, return false if not.
WIN32_FILE_ATTRIBUTE_DATA attrs = {0};
if (!::GetFileAttributesEx(path, ::GetFileExInfoStandard, &attrs)) {
- LOG(ERROR) << path << " for deletion does not exist." << GetLastError();
+ PLOG(WARNING) << path << " does not exist.";
return false;
}
@@ -68,10 +68,25 @@ bool ScheduleFileSystemEntityForDeletion(const wchar_t* path) {
}
if (!::MoveFileEx(path, NULL, flags)) {
- LOG(ERROR) << "Could not schedule " << path << " for deletion.";
+ PLOG(ERROR) << "Could not schedule " << path << " for deletion.";
return false;
}
+#ifndef NDEBUG
+ // Useful debugging code to track down what files are in use.
+ if (flags & MOVEFILE_REPLACE_EXISTING) {
+ // Attempt to open the file exclusively.
+ HANDLE file = ::CreateFileW(path, GENERIC_READ | GENERIC_WRITE, 0, NULL,
+ OPEN_EXISTING, 0, NULL);
+ if (file != INVALID_HANDLE_VALUE) {
+ PLOG(INFO) << " file not in use: " << path;
+ ::CloseHandle(file);
+ } else {
+ PLOG(INFO) << " file in use (or not found?): " << path;
+ }
+ }
+#endif
+
VLOG(1) << "Scheduled for deletion: " << path;
return true;
}