summaryrefslogtreecommitdiffstats
path: root/chrome/browser
diff options
context:
space:
mode:
authorfinnur@chromium.org <finnur@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-01-06 08:57:45 +0000
committerfinnur@chromium.org <finnur@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-01-06 08:57:45 +0000
commitd80268a511216fb8b0f815e50f415046a7320b7f (patch)
treec73482c104ec4605d47c7e9e0b20639fc4c6946c /chrome/browser
parentf2b94f97aded3c9e93116bcac143bf2ccb653d46 (diff)
downloadchromium_src-d80268a511216fb8b0f815e50f415046a7320b7f.zip
chromium_src-d80268a511216fb8b0f815e50f415046a7320b7f.tar.gz
chromium_src-d80268a511216fb8b0f815e50f415046a7320b7f.tar.bz2
Integrate about:conflicts with --diagnostics
This should enable the user to find conflicting dlls that are crashing Chrome on startup. This changelist introduces a limited_mode for scanning, since the diagnostics tests run without the help of many Chrome services, so we can't use the File thread for asynchronous scanning or the notification system. Also changed the scanning so that if no signature/description is given in the blacklist, then we mark the DLL as a confirmed match if the name and the location match (before we used to match it as a 'suspected' match). A very sizable chunk of the blacklist is malware, which has no signature, so this gives us the ability to trigger the wrench badge on finding malware (that part remains opt-in through about:flags). Also added failure count to diagnostics output (sometimes the error scrolls off screen, so having a note at the bottom helps). BUG=51105 TEST=All diagnostics tests run as part of the unit tests. Review URL: http://codereview.chromium.org/6098004 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@70600 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser')
-rw-r--r--chrome/browser/diagnostics/diagnostics_main.cc20
-rw-r--r--chrome/browser/diagnostics/diagnostics_model.cc3
-rw-r--r--chrome/browser/diagnostics/diagnostics_model.h8
-rw-r--r--chrome/browser/diagnostics/diagnostics_model_unittest.cc4
-rw-r--r--chrome/browser/diagnostics/diagnostics_test.h6
-rw-r--r--chrome/browser/diagnostics/recon_diagnostics.cc73
-rw-r--r--chrome/browser/diagnostics/recon_diagnostics.h3
-rw-r--r--chrome/browser/enumerate_modules_model_unittest_win.cc18
-rw-r--r--chrome/browser/enumerate_modules_model_win.cc149
-rw-r--r--chrome/browser/enumerate_modules_model_win.h47
-rw-r--r--chrome/browser/resources/about_conflicts.html78
11 files changed, 273 insertions, 136 deletions
diff --git a/chrome/browser/diagnostics/diagnostics_main.cc b/chrome/browser/diagnostics/diagnostics_main.cc
index 2f654c2..059dd59 100644
--- a/chrome/browser/diagnostics/diagnostics_main.cc
+++ b/chrome/browser/diagnostics/diagnostics_main.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -204,9 +204,14 @@ class TestWriter {
public:
// The |console| must be valid and properly initialized. This
// class does not own it.
- explicit TestWriter(SimpleConsole* console) : console_(console) {
+ explicit TestWriter(SimpleConsole* console)
+ : console_(console),
+ failures_(0) {
}
+ // How many tests reported failure.
+ int failures() { return failures_; }
+
// Write an informational line of text in white over black.
bool WriteInfoText(const std::wstring& txt) {
console_->SetColor(SimpleConsole::DEFAULT);
@@ -224,6 +229,7 @@ class TestWriter {
} else {
console_->SetColor(SimpleConsole::RED);
console_->Write(L"[FAIL] ");
+ failures_++;
}
WriteInfoText(name + L"\n");
std::wstring second_line(L" ");
@@ -235,6 +241,9 @@ class TestWriter {
SimpleConsole* console_;
+ // Keeps track of how many tests reported failure.
+ int failures_;
+
DISALLOW_COPY_AND_ASSIGN(TestWriter);
};
@@ -290,7 +299,12 @@ class TestController : public DiagnosticsModel::Observer {
}
virtual void OnDoneAll(DiagnosticsModel* model) {
- writer_->WriteInfoText(L"DONE\n\n");
+ if (writer_->failures() > 0) {
+ writer_->WriteInfoText(StringPrintf(L"DONE. %d failure(s)\n\n",
+ writer_->failures()));
+ } else {
+ writer_->WriteInfoText(L"DONE\n\n");
+ }
}
private:
diff --git a/chrome/browser/diagnostics/diagnostics_model.cc b/chrome/browser/diagnostics/diagnostics_model.cc
index b71f337d..209e342 100644
--- a/chrome/browser/diagnostics/diagnostics_model.cc
+++ b/chrome/browser/diagnostics/diagnostics_model.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -83,6 +83,7 @@ class DiagnosticsModelWin : public DiagnosticsModelImpl {
public:
DiagnosticsModelWin() {
tests_.push_back(MakeOperatingSystemTest());
+ tests_.push_back(MakeConflictingDllsTest());
tests_.push_back(MakeInstallTypeTest());
tests_.push_back(MakeVersionTest());
tests_.push_back(MakeUserDirTest());
diff --git a/chrome/browser/diagnostics/diagnostics_model.h b/chrome/browser/diagnostics/diagnostics_model.h
index 45c46e9..9b1e08a 100644
--- a/chrome/browser/diagnostics/diagnostics_model.h
+++ b/chrome/browser/diagnostics/diagnostics_model.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -12,7 +12,7 @@ class CommandLine;
// The chrome diagnostics system is a model-view-controller system. The Model
// responsible for holding and running the individual tests and providing a
-// uniform interface for quering the outcome.
+// uniform interface for querying the outcome.
// TODO(cpu): The view and the controller are not yet built.
class DiagnosticsModel {
public:
@@ -33,7 +33,7 @@ class DiagnosticsModel {
public:
virtual ~Observer() {}
// Called once upon test start with |percent| = 0 and periodically as the
- // test progresses. There is no cancelation method.
+ // test progresses. There is no cancellation method.
virtual void OnProgress(int id, int percent, DiagnosticsModel* model) = 0;
// Called if the test in question cannot be run.
virtual void OnSkipped(int id, DiagnosticsModel* model) = 0;
@@ -62,7 +62,7 @@ class DiagnosticsModel {
virtual int GetTestRunCount() = 0;
// Returns how many tests are available. This value never changes.
virtual int GetTestAvailableCount() =0;
- // Runs all the availabe tests, the |observer| callbacks will be called as
+ // Runs all the available tests, the |observer| callbacks will be called as
// the test progress and thus cannot be null.
virtual void RunAll(DiagnosticsModel::Observer* observer) = 0;
// Get the information for a particular test. Do not keep a pointer to the
diff --git a/chrome/browser/diagnostics/diagnostics_model_unittest.cc b/chrome/browser/diagnostics/diagnostics_model_unittest.cc
index ee80a09..823ef9d 100644
--- a/chrome/browser/diagnostics/diagnostics_model_unittest.cc
+++ b/chrome/browser/diagnostics/diagnostics_model_unittest.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -78,7 +78,7 @@ class UTObserver: public DiagnosticsModel::Observer {
// We currently have more tests operational on windows.
#if defined(OS_WIN)
-const int kDiagnosticsTestCount = 18;
+const int kDiagnosticsTestCount = 19;
#elif defined(OS_MACOSX)
const int kDiagnosticsTestCount = 16;
#elif defined(OS_POSIX)
diff --git a/chrome/browser/diagnostics/diagnostics_test.h b/chrome/browser/diagnostics/diagnostics_test.h
index 70d7eb7..298d5a2 100644
--- a/chrome/browser/diagnostics/diagnostics_test.h
+++ b/chrome/browser/diagnostics/diagnostics_test.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -16,7 +16,7 @@ class FilePath;
// It also Implements the TestInfo interface providing the storage
// for the outcome of the test.
// Specific tests need (minimally) only to:
-// 1- override ExecuteImpl() to imnplement the test.
+// 1- override ExecuteImpl() to implement the test.
// 2- call RecordStopFailure() or RecordFailure() or RecordSuccess()
// at the end of the test.
// 3- Optionally call observer->OnProgress() if the test is long.
@@ -58,7 +58,7 @@ class DiagnosticTest : public DiagnosticsModel::TestInfo {
static FilePath GetUserDefaultProfileDir();
protected:
- // The id needs to be overriden by derived classes and must uniquely
+ // The id needs to be overridden by derived classes and must uniquely
// identify this test so other test can refer to it.
virtual int GetId() = 0;
// Derived classes override this method do perform the actual test.
diff --git a/chrome/browser/diagnostics/recon_diagnostics.cc b/chrome/browser/diagnostics/recon_diagnostics.cc
index f657fef..2cacd86 100644
--- a/chrome/browser/diagnostics/recon_diagnostics.cc
+++ b/chrome/browser/diagnostics/recon_diagnostics.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -22,6 +22,7 @@
#if defined(OS_WIN)
#include "base/win/windows_version.h"
+#include "chrome/browser/enumerate_modules_model_win.h"
#include "chrome/installer/util/install_util.h"
#endif
@@ -29,7 +30,7 @@
// diagnostic tests. Here we check for the existence of critical files.
// TODO(cpu): Define if it makes sense to localize strings.
-// TODO(cpu): There are a few maxium file sizes hardcoded in this file
+// TODO(cpu): There are a few maximum file sizes hardcoded in this file
// that have little or no theoretical or experimental ground. Find a way
// to justify them.
@@ -61,7 +62,7 @@ class OperatingSystemTest : public DiagnosticTest {
return false;
}
#else
- // TODO(port): define the OS criteria for linux and mac.
+ // TODO(port): define the OS criteria for Linux and Mac.
#endif // defined(OS_WIN)
RecordSuccess(ASCIIToUTF16(StringPrintf("%s %s (%d [%d:%d])",
base::SysInfo::OperatingSystemName().c_str(),
@@ -74,6 +75,60 @@ class OperatingSystemTest : public DiagnosticTest {
DISALLOW_COPY_AND_ASSIGN(OperatingSystemTest);
};
+// Check if any conflicting DLLs are loaded.
+class ConflictingDllsTest : public DiagnosticTest {
+ public:
+ ConflictingDllsTest() : DiagnosticTest(ASCIIToUTF16("Conflicting modules")) {}
+
+ virtual int GetId() { return 0; }
+
+ virtual bool ExecuteImpl(DiagnosticsModel::Observer* observer) {
+#if defined(OS_WIN)
+ EnumerateModulesModel* model = EnumerateModulesModel::GetInstance();
+ model->set_limited_mode(true);
+ model->ScanNow();
+ ListValue* list = model->GetModuleList();
+ if (!model->confirmed_bad_modules_detected() &&
+ !model->suspected_bad_modules_detected()) {
+ RecordSuccess(ASCIIToUTF16("No conflicting modules found"));
+ return true;
+ }
+
+ string16 failures = ASCIIToUTF16("Possibly conflicting modules:");
+ DictionaryValue* dictionary;
+ for (size_t i = 0; i < list->GetSize(); ++i) {
+ list->GetDictionary(i, &dictionary);
+ int status;
+ string16 location;
+ string16 name;
+ if (!dictionary->GetInteger("status", &status))
+ RecordFailure(ASCIIToUTF16("No 'status' field found"));
+ if (status < ModuleEnumerator::SUSPECTED_BAD)
+ continue;
+
+ if (!dictionary->GetString("location", &location)) {
+ RecordFailure(ASCIIToUTF16("No 'location' field found"));
+ return true;
+ }
+ if (!dictionary->GetString("name", &name)) {
+ RecordFailure(ASCIIToUTF16("No 'name' field found"));
+ return true;
+ }
+
+ failures += ASCIIToUTF16("\n") + location + name;
+ }
+ RecordFailure(failures);
+ return true;
+#else
+ RecordFailure(ASCIIToUTF16("Not implemented"));
+ return true;
+#endif // defined(OS_WIN)
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ConflictingDllsTest);
+};
+
// Check if it is system install or per-user install.
class InstallTypeTest : public DiagnosticTest {
public:
@@ -163,9 +218,9 @@ const TestPathInfo kPathsToTest[] = {
true, false, false, 0}
};
-// Check that the user's data directory exists and the paths are writeable.
-// If it is a systemwide install some paths are not expected to be writeable.
-// This test depends on |InstallTypeTest| having run succesfuly.
+// Check that the user's data directory exists and the paths are writable.
+// If it is a systemwide install some paths are not expected to be writable.
+// This test depends on |InstallTypeTest| having run successfully.
class PathTest : public DiagnosticTest {
public:
explicit PathTest(const TestPathInfo& path_info)
@@ -227,7 +282,7 @@ class PathTest : public DiagnosticTest {
};
// Check that the disk space in the volume where the user data dir normally
-// lives is not dangerosly low.
+// lives is not dangerously low.
class DiskSpaceTest : public DiagnosticTest {
public:
DiskSpaceTest() : DiagnosticTest(ASCIIToUTF16("Disk Space")) {}
@@ -337,6 +392,10 @@ DiagnosticTest* MakeOperatingSystemTest() {
return new OperatingSystemTest();
}
+DiagnosticTest* MakeConflictingDllsTest() {
+ return new ConflictingDllsTest();
+}
+
DiagnosticTest* MakeInstallTypeTest() {
return new InstallTypeTest();
}
diff --git a/chrome/browser/diagnostics/recon_diagnostics.h b/chrome/browser/diagnostics/recon_diagnostics.h
index d7c52e9..8a20d4d 100644
--- a/chrome/browser/diagnostics/recon_diagnostics.h
+++ b/chrome/browser/diagnostics/recon_diagnostics.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -9,6 +9,7 @@
#include "chrome/browser/diagnostics/diagnostics_test.h"
DiagnosticTest* MakeOperatingSystemTest();
+DiagnosticTest* MakeConflictingDllsTest();
DiagnosticTest* MakeInstallTypeTest();
DiagnosticTest* MakeVersionTest();
DiagnosticTest* MakeUserDirTest();
diff --git a/chrome/browser/enumerate_modules_model_unittest_win.cc b/chrome/browser/enumerate_modules_model_unittest_win.cc
index 7aa6b63..1992e7a 100644
--- a/chrome/browser/enumerate_modules_model_unittest_win.cc
+++ b/chrome/browser/enumerate_modules_model_unittest_win.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -78,6 +78,12 @@ TEST_F(EnumerateModulesTest, NormalizeEntry) {
const ModuleEnumerator::Module kStandardModule =
{ kType, kStatus, L"c:\\foo\\bar.dll", L"", L"Prod", L"Desc", L"1.0", L"Sig",
ModuleEnumerator::NONE };
+const ModuleEnumerator::Module kStandardModuleNoDescription =
+ { kType, kStatus, L"c:\\foo\\bar.dll", L"", L"Prod", L"", L"1.0", L"Sig",
+ ModuleEnumerator::NONE };
+const ModuleEnumerator::Module kStandardModuleNoSignature =
+ { kType, kStatus, L"c:\\foo\\bar.dll", L"", L"Prod", L"Desc", L"1.0", L"",
+ ModuleEnumerator::NONE };
// Name, location, description and signature are compared by hashing.
static const char kMatchName[] = "88e8c9e0"; // "bar.dll".
@@ -120,6 +126,16 @@ const struct MatchingEntryList {
kStandardModule,
{ kMatchName, kMatchLocation, kEmpty, kEmpty, kEmpty,
ModuleEnumerator::SEE_LINK }
+ }, { // Matches: Name, location, (description not given) => Confirmed match.
+ ModuleEnumerator::CONFIRMED_BAD,
+ kStandardModuleNoDescription, // Note: No description.
+ { kMatchName, kMatchLocation, kEmpty, kEmpty, kEmpty,
+ ModuleEnumerator::SEE_LINK }
+ }, { // Matches: Name, location, (signature not given) => Confirmed match.
+ ModuleEnumerator::CONFIRMED_BAD,
+ kStandardModuleNoSignature, // Note: No signature.
+ { kMatchName, kMatchLocation, kEmpty, kEmpty, kEmpty,
+ ModuleEnumerator::SEE_LINK }
}, { // Matches: Name, location (not version) => Not a match.
ModuleEnumerator::NOT_MATCHED,
kStandardModule,
diff --git a/chrome/browser/enumerate_modules_model_win.cc b/chrome/browser/enumerate_modules_model_win.cc
index ab3821a..ead91ea 100644
--- a/chrome/browser/enumerate_modules_model_win.cc
+++ b/chrome/browser/enumerate_modules_model_win.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -126,7 +126,8 @@ const ModuleEnumerator::BlacklistEntry ModuleEnumerator::kModuleBlacklist[] = {
static_cast<RecommendedAction>(UPDATE | DISABLE) },
// is3lsp.dll, "%commonprogramfiles%\\is3\\anti-spyware\\".
- { "7ffbdce9", "bc5673f2", "", "", "", INVESTIGATING },
+ { "7ffbdce9", "bc5673f2", "", "", "",
+ static_cast<RecommendedAction>(UPDATE | DISABLE | SEE_LINK) },
// jsi.dll, "%programfiles%\\profilecraze\\".
{ "f9555eea", "e3548061", "", "", "", kUninstallLink },
@@ -291,12 +292,13 @@ ModuleEnumerator::ModuleStatus ModuleEnumerator::Match(
GenerateHash(WideToUTF8(module.digital_signer), &signer_hash);
GenerateHash(WideToUTF8(module.description), &description_hash);
- // If signatures match, we have a winner.
- if (!desc_or_signer.empty() && signer_hash == desc_or_signer)
+ // If signatures match (or both are empty), then we have a winner.
+ if (signer_hash == desc_or_signer)
return CONFIRMED_BAD;
- // If description matches and location, then we also have a match.
- if (!desc_or_signer.empty() && description_hash == desc_or_signer &&
+ // If descriptions match (or both are empty) and the locations match, then
+ // we also have a confirmed match.
+ if (description_hash == desc_or_signer &&
!location_hash.empty() && location_hash == blacklisted.location) {
return CONFIRMED_BAD;
}
@@ -311,22 +313,31 @@ ModuleEnumerator::ModuleStatus ModuleEnumerator::Match(
ModuleEnumerator::ModuleEnumerator(EnumerateModulesModel* observer)
: observer_(observer),
+ limited_mode_(false),
callback_thread_id_(BrowserThread::ID_COUNT) {
}
ModuleEnumerator::~ModuleEnumerator() {
}
-void ModuleEnumerator::ScanNow(ModulesVector* list) {
- CHECK(BrowserThread::GetCurrentThreadIdentifier(&callback_thread_id_));
- DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::FILE));
+void ModuleEnumerator::ScanNow(ModulesVector* list, bool limited_mode) {
enumerated_modules_ = list;
- BrowserThread::PostTask(
- BrowserThread::FILE, FROM_HERE,
- NewRunnableMethod(this, &ModuleEnumerator::ScanOnFileThread));
+
+ limited_mode_ = limited_mode;
+
+ if (!limited_mode_) {
+ CHECK(BrowserThread::GetCurrentThreadIdentifier(&callback_thread_id_));
+ DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::FILE));
+ BrowserThread::PostTask(
+ BrowserThread::FILE, FROM_HERE,
+ NewRunnableMethod(this, &ModuleEnumerator::ScanImpl));
+ } else {
+ // Run it synchronously.
+ ScanImpl();
+ }
}
-void ModuleEnumerator::ScanOnFileThread() {
+void ModuleEnumerator::ScanImpl() {
base::TimeTicks start_time = base::TimeTicks::Now();
enumerated_modules_->clear();
@@ -357,10 +368,15 @@ void ModuleEnumerator::ScanOnFileThread() {
std::sort(enumerated_modules_->begin(),
enumerated_modules_->end(), ModuleSort);
- // Send a reply back on the UI thread.
- BrowserThread::PostTask(
- callback_thread_id_, FROM_HERE,
- NewRunnableMethod(this, &ModuleEnumerator::ReportBack));
+ if (!limited_mode_) {
+ // Send a reply back on the UI thread.
+ BrowserThread::PostTask(
+ callback_thread_id_, FROM_HERE,
+ NewRunnableMethod(this, &ModuleEnumerator::ReportBack));
+ } else {
+ // We are on the main thread already.
+ ReportBack();
+ }
HISTOGRAM_TIMES("Conflicts.EnumerationTotalTime",
base::TimeTicks::Now() - start_time);
@@ -584,7 +600,8 @@ void ModuleEnumerator::MatchAgainstBlacklist() {
}
void ModuleEnumerator::ReportBack() {
- DCHECK(BrowserThread::CurrentlyOn(callback_thread_id_));
+ if (!limited_mode_)
+ DCHECK(BrowserThread::CurrentlyOn(callback_thread_id_));
observer_->DoneScanning();
}
@@ -694,7 +711,7 @@ void EnumerateModulesModel::ScanNow() {
// ScanNow does not block.
if (!module_enumerator_)
module_enumerator_ = new ModuleEnumerator(this);
- module_enumerator_->ScanNow(&enumerated_modules_);
+ module_enumerator_->ScanNow(&enumerated_modules_, limited_mode_);
}
ListValue* EnumerateModulesModel::GetModuleList() {
@@ -727,8 +744,10 @@ ListValue* EnumerateModulesModel::GetModuleList() {
}
// Must be one of the above type.
DCHECK(!type_string.empty());
- type_string += ASCIIToWide(" -- ");
- type_string += l10n_util::GetStringUTF16(IDS_CONFLICTS_NOT_LOADED_YET);
+ if (!limited_mode_) {
+ type_string += ASCIIToWide(" -- ");
+ type_string += l10n_util::GetStringUTF16(IDS_CONFLICTS_NOT_LOADED_YET);
+ }
}
data->SetString("type_description", type_string);
data->SetInteger("status", module->status);
@@ -739,40 +758,43 @@ ListValue* EnumerateModulesModel::GetModuleList() {
data->SetString("version", module->version);
data->SetString("digital_signer", module->digital_signer);
- // Figure out the possible resolution help string.
- string16 actions;
- string16 separator = ASCIIToWide(" ") + l10n_util::GetStringUTF16(
- IDS_CONFLICTS_CHECK_POSSIBLE_ACTION_SEPERATOR) +
- ASCIIToWide(" ");
+ if (!limited_mode_) {
+ // Figure out the possible resolution help string.
+ string16 actions;
+ string16 separator = ASCIIToWide(" ") + l10n_util::GetStringUTF16(
+ IDS_CONFLICTS_CHECK_POSSIBLE_ACTION_SEPERATOR) +
+ ASCIIToWide(" ");
- if (module->recommended_action & ModuleEnumerator::NONE) {
- actions = l10n_util::GetStringUTF16(
- IDS_CONFLICTS_CHECK_INVESTIGATING);
- }
- if (module->recommended_action & ModuleEnumerator::UNINSTALL) {
- if (!actions.empty())
- actions += separator;
- actions = l10n_util::GetStringUTF16(
- IDS_CONFLICTS_CHECK_POSSIBLE_ACTION_UNINSTALL);
- }
- if (module->recommended_action & ModuleEnumerator::UPDATE) {
- if (!actions.empty())
- actions += separator;
- actions += l10n_util::GetStringUTF16(
- IDS_CONFLICTS_CHECK_POSSIBLE_ACTION_UPDATE);
- }
- if (module->recommended_action & ModuleEnumerator::DISABLE) {
- if (!actions.empty())
- actions += separator;
- actions += l10n_util::GetStringUTF16(
- IDS_CONFLICTS_CHECK_POSSIBLE_ACTION_DISABLE);
+ if (module->recommended_action & ModuleEnumerator::NONE) {
+ actions = l10n_util::GetStringUTF16(
+ IDS_CONFLICTS_CHECK_INVESTIGATING);
+ }
+ if (module->recommended_action & ModuleEnumerator::UNINSTALL) {
+ if (!actions.empty())
+ actions += separator;
+ actions = l10n_util::GetStringUTF16(
+ IDS_CONFLICTS_CHECK_POSSIBLE_ACTION_UNINSTALL);
+ }
+ if (module->recommended_action & ModuleEnumerator::UPDATE) {
+ if (!actions.empty())
+ actions += separator;
+ actions += l10n_util::GetStringUTF16(
+ IDS_CONFLICTS_CHECK_POSSIBLE_ACTION_UPDATE);
+ }
+ if (module->recommended_action & ModuleEnumerator::DISABLE) {
+ if (!actions.empty())
+ actions += separator;
+ actions += l10n_util::GetStringUTF16(
+ IDS_CONFLICTS_CHECK_POSSIBLE_ACTION_DISABLE);
+ }
+ string16 possible_resolution = actions.empty() ? ASCIIToWide("") :
+ l10n_util::GetStringUTF16(IDS_CONFLICTS_CHECK_POSSIBLE_ACTIONS) +
+ ASCIIToWide(" ") +
+ actions;
+ data->SetString("possibleResolution", possible_resolution);
+ data->SetString("help_url",
+ ConstructHelpCenterUrl(*module).spec().c_str());
}
- string16 possible_resolution = actions.empty() ? ASCIIToWide("") :
- l10n_util::GetStringUTF16(IDS_CONFLICTS_CHECK_POSSIBLE_ACTIONS) +
- ASCIIToWide(" ") +
- actions;
- data->SetString("possibleResolution", possible_resolution);
- data->SetString("help_url", ConstructHelpCenterUrl(*module).spec().c_str());
list->Append(data);
}
@@ -783,6 +805,7 @@ ListValue* EnumerateModulesModel::GetModuleList() {
EnumerateModulesModel::EnumerateModulesModel()
: scanning_(false),
+ limited_mode_(false),
confirmed_bad_modules_detected_(0),
suspected_bad_modules_detected_(0) {
const CommandLine& cmd_line = *CommandLine::ForCurrentProcess();
@@ -819,17 +842,19 @@ void EnumerateModulesModel::DoneScanning() {
HISTOGRAM_COUNTS_100("Conflicts.ConfirmedBadModules",
confirmed_bad_modules_detected_);
- NotificationService::current()->Notify(
- NotificationType::MODULE_LIST_ENUMERATED,
- Source<EnumerateModulesModel>(this),
- NotificationService::NoDetails());
-
- if (suspected_bad_modules_detected_ || confirmed_bad_modules_detected_) {
- bool found_confirmed_bad_modules = confirmed_bad_modules_detected_ > 0;
+ if (!limited_mode_) {
NotificationService::current()->Notify(
- NotificationType::MODULE_INCOMPATIBILITY_DETECTED,
+ NotificationType::MODULE_LIST_ENUMERATED,
Source<EnumerateModulesModel>(this),
- Details<bool>(&found_confirmed_bad_modules));
+ NotificationService::NoDetails());
+
+ if (suspected_bad_modules_detected_ || confirmed_bad_modules_detected_) {
+ bool found_confirmed_bad_modules = confirmed_bad_modules_detected_ > 0;
+ NotificationService::current()->Notify(
+ NotificationType::MODULE_INCOMPATIBILITY_DETECTED,
+ Source<EnumerateModulesModel>(this),
+ Details<bool>(&found_confirmed_bad_modules));
+ }
}
}
diff --git a/chrome/browser/enumerate_modules_model_win.h b/chrome/browser/enumerate_modules_model_win.h
index 1f524c8..4364bb6 100644
--- a/chrome/browser/enumerate_modules_model_win.h
+++ b/chrome/browser/enumerate_modules_model_win.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -119,11 +119,15 @@ class ModuleEnumerator : public base::RefCountedThreadSafe<ModuleEnumerator> {
~ModuleEnumerator();
// Start scanning the loaded module list (if a scan is not already in
- // progress). This function does not block while reading the module list, but
- // will notify when done through the MODULE_LIST_ENUMERATED notification.
+ // progress). This function does not block while reading the module list
+ // (unless we are in limited_mode, see below), and will notify when done
+ // through the MODULE_LIST_ENUMERATED notification.
// The process will also send MODULE_INCOMPATIBILITY_DETECTED if an
// incompatible module was detected.
- void ScanNow(ModulesVector* list);
+ // When in |limited_mode|, this function will not leverage the File thread
+ // to run asynchronously and will therefore block until scanning is done
+ // (and will also not send out any notifications).
+ void ScanNow(ModulesVector* list, bool limited_mode);
private:
FRIEND_TEST_ALL_PREFIXES(EnumerateModulesTest, CollapsePath);
@@ -131,13 +135,14 @@ class ModuleEnumerator : public base::RefCountedThreadSafe<ModuleEnumerator> {
// The (currently) hard coded blacklist of known bad modules.
static const BlacklistEntry kModuleBlacklist[];
- // This function does the actual file scanning work on the FILE thread. It
- // enumerates all loaded modules in the process and other modules of
- // interest, such as the registered Winsock LSP modules and stores them in
- // |enumerated_modules_|. It then normalizes the module info and matches
- // them against a blacklist of known bad modules. Finally, it calls
- // ReportBack to let the observer know we are done.
- void ScanOnFileThread();
+ // This function does the actual file scanning work on the FILE thread (or
+ // block the main thread when in limited_mode). It enumerates all loaded
+ // modules in the process and other modules of interest, such as the
+ // registered Winsock LSP modules and stores them in |enumerated_modules_|.
+ // It then normalizes the module info and matches them against a blacklist
+ // of known bad modules. Finally, it calls ReportBack to let the observer
+ // know we are done.
+ void ScanImpl();
// Enumerate all modules loaded into the Chrome process.
void EnumerateLoadedModules();
@@ -200,6 +205,9 @@ class ModuleEnumerator : public base::RefCountedThreadSafe<ModuleEnumerator> {
// The observer, who needs to be notified when we are done.
EnumerateModulesModel* observer_;
+ // See limited_mode below.
+ bool limited_mode_;
+
// The thread that we need to call back on to report that we are done.
BrowserThread::ID callback_thread_id_;
@@ -235,8 +243,14 @@ class EnumerateModulesModel {
return confirmed_bad_modules_detected_;
}
- // Asynchronously start the scan for the loaded module list.
- // When the list is ready.
+ // Set to true when we the scanning process can not rely on certain Chrome
+ // services to exists.
+ void set_limited_mode(bool limited_mode) {
+ limited_mode_ = limited_mode;
+ }
+
+ // Asynchronously start the scan for the loaded module list, except when in
+ // limited_mode (in which case it blocks).
void ScanNow();
// Gets the whole module list as a ListValue.
@@ -268,6 +282,13 @@ class EnumerateModulesModel {
// start scanning for modules after a certain amount of time has passed.
base::OneShotTimer<EnumerateModulesModel> check_modules_timer_;
+ // While normally |false|, this mode can be set to indicate that the scanning
+ // process should not rely on certain services normally available to Chrome,
+ // such as the resource bundle and the notification system, not to mention
+ // having multiple threads. This mode is useful during diagnostics, which
+ // runs without firing up all necessary Chrome services first.
+ bool limited_mode_;
+
// True if we are currently scanning for modules.
bool scanning_;
diff --git a/chrome/browser/resources/about_conflicts.html b/chrome/browser/resources/about_conflicts.html
index 301fb49..e82ac99 100644
--- a/chrome/browser/resources/about_conflicts.html
+++ b/chrome/browser/resources/about_conflicts.html
@@ -144,65 +144,65 @@ html[dir=rtl] .clearing {
border-bottom: 1px solid #aaa;
}
</style>
-<script>
-
+<script>
+
/**
* This variable structure is here to document the structure that the template
* expects to correctly populate the page.
- */
- var moduleListDataFormat = {
- 'moduleList': [
- {
- 'type': 'The type of module found',
- 'type_description':
- 'The type of module (string), defaults to blank for regular modules',
- 'status': 'The module status',
- 'location': 'The module path, not including filename',
+ */
+ var moduleListDataFormat = {
+ 'moduleList': [
+ {
+ 'type': 'The type of module found',
+ 'type_description':
+ 'The type of module (string), defaults to blank for regular modules',
+ 'status': 'The module status',
+ 'location': 'The module path, not including filename',
'name': 'The name of the module',
'product_name': 'The name of the product the module belongs to',
'description': 'The module description',
'version': 'The module version',
- 'digital_signer': 'The signer of the digital certificate for the module',
- 'recommended_action': 'The help tips bitmask',
- 'possible_resolution': 'The help tips in string form',
+ 'digital_signer': 'The signer of the digital certificate for the module',
+ 'recommended_action': 'The help tips bitmask',
+ 'possible_resolution': 'The help tips in string form',
'help_url': 'The link to the Help Center article'
- }
- ]
- };
-
+ }
+ ]
+ };
+
/**
* Takes the |moduleListData| input argument which represents data about
* the currently available modules and populates the html jstemplate
* with that data. It expects an object structure like the above.
* @param {Object} moduleListData Information about available modules
- */
- function renderTemplate(moduleListData) {
- // This is the javascript code that processes the template:
- var input = new JsEvalContext(moduleListData);
- var output = document.getElementById('modulesTemplate');
- jstProcess(input, output);
- }
-
+ */
+ function renderTemplate(moduleListData) {
+ // This is the javascript code that processes the template:
+ var input = new JsEvalContext(moduleListData);
+ var output = document.getElementById('modulesTemplate');
+ jstProcess(input, output);
+ }
+
/**
* Asks the C++ ConflictsDOMHandler to get details about the available modules
* and return detailed data about the configuration. The ConflictsDOMHandler
* should reply to returnModuleList() (below).
- */
- function requestModuleListData() {
- chrome.send('requestModuleList', []);
- }
-
+ */
+ function requestModuleListData() {
+ chrome.send('requestModuleList', []);
+ }
+
/**
* Called by the dom_ui to re-populate the page with data representing the
* current state of installed modules.
- */
- function returnModuleList(moduleListData) {
- var bodyContainer = document.getElementById('body-container');
- renderTemplate(moduleListData);
- bodyContainer.style.visibility = 'visible';
- }
-
- // Get data and have it displayed upon loading.
+ */
+ function returnModuleList(moduleListData) {
+ var bodyContainer = document.getElementById('body-container');
+ renderTemplate(moduleListData);
+ bodyContainer.style.visibility = 'visible';
+ }
+
+ // Get data and have it displayed upon loading.
document.addEventListener('DOMContentLoaded', requestModuleListData);
</script>