// Copyright (c) 2012 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.

#include "chrome/browser/enumerate_modules_model_win.h"

#include <Tlhelp32.h>
#include <wintrust.h>
#include <algorithm>

#include "base/bind.h"
#include "base/command_line.h"
#include "base/environment.h"
#include "base/file_version_info_win.h"
#include "base/files/file_path.h"
#include "base/i18n/case_conversion.h"
#include "base/metrics/histogram.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/time/time.h"
#include "base/values.h"
#include "base/version.h"
#include "base/win/registry.h"
#include "base/win/scoped_handle.h"
#include "base/win/windows_version.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/net/service_providers_win.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_switches.h"
#include "content/public/browser/notification_service.h"
#include "crypto/sha2.h"
#include "grit/generated_resources.h"
#include "grit/google_chrome_strings.h"
#include "ui/base/l10n/l10n_util.h"

using content::BrowserThread;

// The period of time (in milliseconds) to wait until checking to see if any
// incompatible modules exist.
static const int kModuleCheckDelayMs = 45 * 1000;

// The path to the Shell Extension key in the Windows registry.
static const wchar_t kRegPath[] =
    L"Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved";

// Short-hand for things on the blacklist you should simply get rid of.
static const ModuleEnumerator::RecommendedAction kUninstallLink =
    static_cast<ModuleEnumerator::RecommendedAction>(
        ModuleEnumerator::UNINSTALL | ModuleEnumerator::SEE_LINK);

// Short-hand for things on the blacklist we are investigating and have info.
static const ModuleEnumerator::RecommendedAction kInvestigatingLink =
    static_cast<ModuleEnumerator::RecommendedAction>(
        ModuleEnumerator::INVESTIGATING | ModuleEnumerator::SEE_LINK);

// A sort method that sorts by bad modules first, then by full name (including
// path).
static bool ModuleSort(const ModuleEnumerator::Module& a,
                       const ModuleEnumerator::Module& b) {
  if (a.status != b.status)
    return a.status > b.status;

  if (a.location == b.location)
    return a.name < b.name;

  return a.location < b.location;
}

namespace {

// Used to protect the LoadedModuleVector which is accessed
// from both the UI thread and the FILE thread.
base::Lock* lock = NULL;

// A struct to help de-duping modules before adding them to the enumerated
// modules vector.
struct FindModule {
 public:
  explicit FindModule(const ModuleEnumerator::Module& x)
    : module(x) {}
  bool operator()(const ModuleEnumerator::Module& module_in) const {
    return (module.location == module_in.location) &&
           (module.name == module_in.name);
  }

  const ModuleEnumerator::Module& module;
};

// Returns the long path name given a short path name. A short path name is a
// path that follows the 8.3 convention and has ~x in it. If the path is already
// a long path name, the function returns the current path without modification.
bool ConvertToLongPath(const string16& short_path, string16* long_path) {
  wchar_t long_path_buf[MAX_PATH];
  DWORD return_value = GetLongPathName(short_path.c_str(), long_path_buf,
                                       MAX_PATH);
  if (return_value != 0 && return_value < MAX_PATH) {
    *long_path = long_path_buf;
    return true;
  }

  return false;
}

}  // namespace

// The browser process module blacklist. This lists modules that are known
// to cause compatibility issues within the browser process. When adding to this
// list, make sure that all paths are lower-case, in long pathname form, end
// with a slash and use environments variables (or just look at one of the
// comments below and keep it consistent with that). When adding an entry with
// an environment variable not currently used in the list below, make sure to
// update the list in PreparePathMappings. Filename, Description/Signer, and
// Location must be entered as hashes (see GenerateHash). Filename is mandatory.
// Entries without any Description, Signer info, or Location will never be
// marked as confirmed bad (only as suspicious).
const ModuleEnumerator::BlacklistEntry ModuleEnumerator::kModuleBlacklist[] = {
  // NOTE: Please keep this list sorted by dll name, then location.

  // Version 3.2.1.6 seems to be implicated in most cases (and 3.2.2.2 in some).
  // There is a more recent version available for download.
  // accelerator.dll, "%programfiles%\\speedbit video accelerator\\".
  { "7ba9402f", "c9132d48", "", "", "", ALL, kInvestigatingLink },

  // apiqq0.dll, "%temp%\\".
  { "26134911", "59145acf", "", "", "", ALL, kUninstallLink },

  // arking0.dll, "%systemroot%\\system32\\".
  { "f5d8f549", "23d01d5b", "", "", "", ALL, kUninstallLink },

  // arking1.dll, "%systemroot%\\system32\\".
  { "c60ca062", "23d01d5b", "", "", "", ALL, kUninstallLink },

  // aswjsflt.dll, "%ProgramFiles%\\avast software\\avast\\", "AVAST Software".
  // NOTE: The digital signature of the DLL is double null terminated.
  // Avast Antivirus prior to version 8.0 would kill the Chrome child process
  // when blocked from running.
  { "2ea5422a", "6b3a1b00", "a7db0e0c", "", "8.0", XP,
    static_cast<RecommendedAction>(UPDATE | SEE_LINK | NOTIFY_USER) },

  // aswjsflt.dll, "%ProgramFiles%\\alwil software\\avast5\\", "AVAST Software".
  // NOTE: The digital signature of the DLL is double null terminated.
  // Avast Antivirus prior to version 8.0 would kill the Chrome child process
  // when blocked from running.
  { "2ea5422a", "d8686924", "a7db0e0c", "", "8.0", XP,
    static_cast<RecommendedAction>(UPDATE | SEE_LINK | NOTIFY_USER) },

  // Said to belong to Killer NIC from BigFoot Networks (not verified). Versions
  // 6.0.0.7 and 6.0.0.10 implicated.
  // bfllr.dll, "%systemroot%\\system32\\".
  { "6bb57633", "23d01d5b", "", "", "", ALL, kInvestigatingLink },

  // clickpotatolitesahook.dll, "". Different version each report.
  { "0396e037.dll", "", "", "", "", ALL, kUninstallLink },

  // cvasds0.dll, "%temp%\\".
  { "5ce0037c", "59145acf", "", "", "", ALL, kUninstallLink },

  // cwalsp.dll, "%systemroot%\\system32\\".
  { "e579a039", "23d01d5b", "", "", "", ALL, kUninstallLink },

  // datamngr.dll (1), "%programfiles%\\searchqu toolbar\\datamngr\\".
  { "7add320b", "470a3da3", "", "", "", ALL, kUninstallLink },

  // datamngr.dll (2), "%programfiles%\\windows searchqu toolbar\\".
  { "7add320b", "7a3c8be3", "", "", "", ALL, kUninstallLink },

  // dsoqq0.dll, "%temp%\\".
  { "1c4df325", "59145acf", "", "", "", ALL, kUninstallLink },

  // flt.dll, "%programfiles%\\tueagles\\".
  { "6d01f4a1", "7935e9c2", "", "", "", ALL, kUninstallLink },

  // This looks like a malware edition of a Brazilian Bank plugin, sometimes
  // referred to as Malware.Banc.A.
  // gbieh.dll, "%programfiles%\\gbplugin\\".
  { "4cb4f2e3", "88e4a3b1", "", "", "", ALL, kUninstallLink },

  // hblitesahook.dll. Each report has different version number in location.
  { "5d10b363", "", "", "", "", ALL, kUninstallLink },

  // icf.dll, "%systemroot%\\system32\\".
  { "303825ed", "23d01d5b", "", "", "", ALL, INVESTIGATING },

  // idmmbc.dll (IDM), "%systemroot%\\system32\\". See: http://crbug.com/26892/.
  { "b8dce5c3", "23d01d5b", "", "", "6.03", ALL,
      static_cast<RecommendedAction>(UPDATE | DISABLE) },

  // imon.dll (NOD32), "%systemroot%\\system32\\". See: http://crbug.com/21715.
  { "8f42f22e", "23d01d5b", "", "", "4.0", ALL,
      static_cast<RecommendedAction>(UPDATE | DISABLE) },

  // is3lsp.dll, "%commonprogramfiles%\\is3\\anti-spyware\\".
  { "7ffbdce9", "bc5673f2", "", "", "", ALL,
      static_cast<RecommendedAction>(UPDATE | DISABLE | SEE_LINK) },

  // jsi.dll, "%programfiles%\\profilecraze\\".
  { "f9555eea", "e3548061", "", "", "", ALL, kUninstallLink },

  // kernel.dll, "%programfiles%\\contentwatch\\internet protection\\modules\\".
  { "ead2768e", "4e61ce60", "", "", "", ALL, INVESTIGATING },

  // mgking0.dll, "%systemroot%\\system32\\".
  { "d0893e38", "23d01d5b", "", "", "", ALL, kUninstallLink },

  // mgking0.dll, "%temp%\\".
  { "d0893e38", "59145acf", "", "", "", ALL, kUninstallLink },

  // mgking1.dll, "%systemroot%\\system32\\".
  { "3e837222", "23d01d5b", "", "", "", ALL, kUninstallLink },

  // mgking1.dll, "%temp%\\".
  { "3e837222", "59145acf", "", "", "", ALL, kUninstallLink },

  // mstcipha.ime, "%systemroot%\\system32\\".
  { "5523579e", "23d01d5b", "", "", "", ALL, INVESTIGATING },

  // mwtsp.dll, "%systemroot%\\system32\\".
  { "9830bff6", "23d01d5b", "", "", "", ALL, kUninstallLink },

  // nodqq0.dll, "%temp%\\".
  { "b86ce04d", "59145acf", "", "", "", ALL, kUninstallLink },

  // nProtect GameGuard Anti-cheat system. Every report has a different
  // location, since it is installed into and run from a game folder. Various
  // versions implicated.
  // npggnt.des, no fixed location.
  { "f2c8790d", "", "", "", "", ALL, kInvestigatingLink },

  // nvlsp.dll,
  // "%programfiles%\\nvidia corporation\\networkaccessmanager\\bin32\\".
  { "37f907e2", "3ad0ff23", "", "", "", ALL, INVESTIGATING },

  // post0.dll, "%systemroot%\\system32\\".
  { "7405c0c8", "23d01d5b", "", "", "", ALL, kUninstallLink },

  // questbrwsearch.dll, "%programfiles%\\questbrwsearch\\".
  { "0953ed09", "f0d5eeda", "", "", "", ALL, kUninstallLink },

  // questscan.dll, "%programfiles%\\questscan\\".
  { "f4f3391e", "119d20f7", "", "", "", ALL, kUninstallLink },

  // radhslib.dll (Naomi web filter), "%programfiles%\\rnamfler\\".
  // See http://crbug.com/12517.
  { "7edcd250", "0733dc3e", "", "", "", ALL, INVESTIGATING },

  // rlls.dll, "%programfiles%\\relevantknowledge\\".
  { "a1ed94a7", "ea9d6b36", "", "", "", ALL, kUninstallLink },

  // rooksdol.dll, "%programfiles%\\trusteer\\rapport\\bin\\".
  { "802aefef", "06120e13", "", "", "3.5.1008.40", ALL, UPDATE },

  // scanquery.dll, "%programfiles%\\scanquery\\".
  { "0b52d2ae", "a4cc88b1", "", "", "", ALL, kUninstallLink },

  // sdata.dll, "%programdata%\\srtserv\\".
  { "1936d5cc", "223c44be", "", "", "", ALL, kUninstallLink },

  // searchtree.dll,
  // "%programfiles%\\contentwatch\\internet protection\\modules\\".
  { "f6915a31", "4e61ce60", "", "", "", ALL, INVESTIGATING },

  // sgprxy.dll, "%commonprogramfiles%\\is3\\anti-spyware\\".
  { "005965ea", "bc5673f2", "", "", "", ALL, INVESTIGATING },

  // snxhk.dll, "%ProgramFiles%\\avast software\\avast\\", "AVAST Software".
  // NOTE: The digital signature of the DLL is double null terminated.
  // Avast Antivirus prior to version 8.0 would kill the Chrome child process
  // when blocked from running.
  { "46c16aa8", "6b3a1b00", "a7db0e0c", "", "8.0", XP,
    static_cast<RecommendedAction>(UPDATE | SEE_LINK | NOTIFY_USER) },

  // snxhk.dll, "%ProgramFiles%\\alwil software\\avast5\\", "AVAST Software".
  // NOTE: The digital signature of the DLL is double null terminated.
  // Avast Antivirus prior to version 8.0 would kill the Chrome child process
  // when blocked from running.
  { "46c16aa8", "d8686924", "a7db0e0c", "", "8.0", XP,
    static_cast<RecommendedAction>(UPDATE | SEE_LINK | NOTIFY_USER) },

  // sprotector.dll, "". Different location each report.
  { "24555d74", "", "", "", "", ALL, kUninstallLink },

  // swi_filter_0001.dll (Sophos Web Intelligence),
  // "%programfiles%\\sophos\\sophos anti-virus\\web intelligence\\".
  // A small random sample all showed version 1.0.5.0.
  { "61112d7b", "25fb120f", "", "", "", ALL, kInvestigatingLink },

  // twking0.dll, "%systemroot%\\system32\\".
  { "0355549b", "23d01d5b", "", "", "", ALL, kUninstallLink },

  // twking1.dll, "%systemroot%\\system32\\".
  { "02e44508", "23d01d5b", "", "", "", ALL, kUninstallLink },

  // vksaver.dll, "%systemroot%\\system32\\".
  { "c4a784d5", "23d01d5b", "", "", "", ALL, kUninstallLink },

  // vlsp.dll (Venturi Firewall?), "%systemroot%\\system32\\".
  { "2e4eb93d", "23d01d5b", "", "", "", ALL, INVESTIGATING },

  // vmn3_1dn.dll, "%appdata%\\roaming\\vmndtxtb\\".
  { "bba2037d", "9ab68585", "", "", "", ALL, kUninstallLink },

  // webanalyzer.dll,
  // "%programfiles%\\contentwatch\\internet protection\\modules\\".
  { "c70b697d", "4e61ce60", "", "", "", ALL, INVESTIGATING },

  // wowst0.dll, "%systemroot%\\system32\\".
  { "38ad9963", "23d01d5b", "", "", "", ALL, kUninstallLink },

  // wxbase28u_vc_cw.dll, "%systemroot%\\system32\\".
  { "e967210d", "23d01d5b", "", "", "", ALL, kUninstallLink },
};

// Generates an 8 digit hash from the input given.
static void GenerateHash(const std::string& input, std::string* output) {
  if (input.empty()) {
    *output = "";
    return;
  }

  uint8 hash[4];
  crypto::SHA256HashString(input, hash, sizeof(hash));
  *output = StringToLowerASCII(base::HexEncode(hash, sizeof(hash)));
}

// -----------------------------------------------------------------------------

// static
void ModuleEnumerator::NormalizeModule(Module* module) {
  string16 path = module->location;
  if (!ConvertToLongPath(path, &module->location))
    module->location = path;

  module->location = base::i18n::ToLower(module->location);

  // Location contains the filename, so the last slash is where the path
  // ends.
  size_t last_slash = module->location.find_last_of(L"\\");
  if (last_slash != string16::npos) {
    module->name = module->location.substr(last_slash + 1);
    module->location = module->location.substr(0, last_slash + 1);
  } else {
    module->name = module->location;
    module->location.clear();
  }

  // Some version strings have things like (win7_rtm.090713-1255) appended
  // to them. Remove that.
  size_t first_space = module->version.find_first_of(L" ");
  if (first_space != string16::npos)
    module->version = module->version.substr(0, first_space);

  module->normalized = true;
}

// static
ModuleEnumerator::ModuleStatus ModuleEnumerator::Match(
    const ModuleEnumerator::Module& module,
    const ModuleEnumerator::BlacklistEntry& blacklisted) {
  // All modules must be normalized before matching against blacklist.
  DCHECK(module.normalized);
  // Filename is mandatory and version should not contain spaces.
  DCHECK(strlen(blacklisted.filename) > 0);
  DCHECK(!strstr(blacklisted.version_from, " "));
  DCHECK(!strstr(blacklisted.version_to, " "));

  base::win::Version version = base::win::GetVersion();
  switch (version) {
     case base::win::VERSION_XP:
      if (!(blacklisted.os & XP)) return NOT_MATCHED;
      break;
    default:
      break;
  }

  std::string filename_hash, location_hash;
  GenerateHash(WideToUTF8(module.name), &filename_hash);
  GenerateHash(WideToUTF8(module.location), &location_hash);

  // Filenames are mandatory. Location is mandatory if given.
  if (filename_hash == blacklisted.filename &&
          (std::string(blacklisted.location).empty() ||
          location_hash == blacklisted.location)) {
    // We have a name match against the blacklist (and possibly location match
    // also), so check version.
    Version module_version(UTF16ToASCII(module.version));
    Version version_min(blacklisted.version_from);
    Version version_max(blacklisted.version_to);
    bool version_ok = !version_min.IsValid() && !version_max.IsValid();
    if (!version_ok) {
      bool too_low = version_min.IsValid() &&
          (!module_version.IsValid() ||
          module_version.CompareTo(version_min) < 0);
      bool too_high = version_max.IsValid() &&
          (!module_version.IsValid() ||
          module_version.CompareTo(version_max) >= 0);
      version_ok = !too_low && !too_high;
    }

    if (version_ok) {
      // At this point, the names match and there is no version specified
      // or the versions also match.

      std::string desc_or_signer(blacklisted.desc_or_signer);
      std::string signer_hash, description_hash;
      GenerateHash(WideToUTF8(module.digital_signer), &signer_hash);
      GenerateHash(WideToUTF8(module.description), &description_hash);

      // If signatures match (or both are empty), then we have a winner.
      if (signer_hash == desc_or_signer)
        return CONFIRMED_BAD;

      // 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;

      // We are not sure, but it is likely bad.
      return SUSPECTED_BAD;
    }
  }

  return NOT_MATCHED;
}

ModuleEnumerator::ModuleEnumerator(EnumerateModulesModel* observer)
    : enumerated_modules_(NULL),
      observer_(observer),
      limited_mode_(false),
      callback_thread_id_(BrowserThread::ID_COUNT) {
}

ModuleEnumerator::~ModuleEnumerator() {
}

void ModuleEnumerator::ScanNow(ModulesVector* list, bool limited_mode) {
  enumerated_modules_ = list;

  limited_mode_ = limited_mode;

  if (!limited_mode_) {
    CHECK(BrowserThread::GetCurrentThreadIdentifier(&callback_thread_id_));
    BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
                            base::Bind(&ModuleEnumerator::ScanImpl, this));
  } else {
    // Run it synchronously.
    ScanImpl();
  }
}

void ModuleEnumerator::ScanImpl() {
  base::TimeTicks start_time = base::TimeTicks::Now();

  enumerated_modules_->clear();

  // Make sure the path mapping vector is setup so we can collapse paths.
  PreparePathMappings();

  // Enumerating loaded modules must happen first since the other types of
  // modules check for duplication against the loaded modules.
  base::TimeTicks checkpoint = base::TimeTicks::Now();
  EnumerateLoadedModules();
  base::TimeTicks checkpoint2 = base::TimeTicks::Now();
  UMA_HISTOGRAM_TIMES("Conflicts.EnumerateLoadedModules",
                      checkpoint2 - checkpoint);

  checkpoint = checkpoint2;
  EnumerateShellExtensions();
  checkpoint2 = base::TimeTicks::Now();
  UMA_HISTOGRAM_TIMES("Conflicts.EnumerateShellExtensions",
                      checkpoint2 - checkpoint);

  checkpoint = checkpoint2;
  EnumerateWinsockModules();
  checkpoint2 = base::TimeTicks::Now();
  UMA_HISTOGRAM_TIMES("Conflicts.EnumerateWinsockModules",
                      checkpoint2 - checkpoint);

  MatchAgainstBlacklist();

  std::sort(enumerated_modules_->begin(),
            enumerated_modules_->end(), ModuleSort);

  if (!limited_mode_) {
    // Send a reply back on the UI thread.
    BrowserThread::PostTask(callback_thread_id_, FROM_HERE,
                            base::Bind(&ModuleEnumerator::ReportBack, this));
  } else {
    // We are on the main thread already.
    ReportBack();
  }

  UMA_HISTOGRAM_TIMES("Conflicts.EnumerationTotalTime",
                      base::TimeTicks::Now() - start_time);
}

void ModuleEnumerator::EnumerateLoadedModules() {
  // Get all modules in the current process.
  base::win::ScopedHandle snap(::CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,
                               ::GetCurrentProcessId()));
  if (!snap.Get())
    return;

  // Walk the module list.
  MODULEENTRY32 module = { sizeof(module) };
  if (!::Module32First(snap.Get(), &module))
    return;

  do {
    // It would be weird to present chrome.exe as a loaded module.
    if (_wcsicmp(chrome::kBrowserProcessExecutableName, module.szModule) == 0)
      continue;

    Module entry;
    entry.type = LOADED_MODULE;
    entry.location = module.szExePath;
    PopulateModuleInformation(&entry);

    NormalizeModule(&entry);
    CollapsePath(&entry);
    enumerated_modules_->push_back(entry);
  } while (::Module32Next(snap.Get(), &module));
}

void ModuleEnumerator::EnumerateShellExtensions() {
  ReadShellExtensions(HKEY_LOCAL_MACHINE);
  ReadShellExtensions(HKEY_CURRENT_USER);
}

void ModuleEnumerator::ReadShellExtensions(HKEY parent) {
  base::win::RegistryValueIterator registration(parent, kRegPath);
  while (registration.Valid()) {
    std::wstring key(std::wstring(L"CLSID\\") + registration.Name() +
        L"\\InProcServer32");
    base::win::RegKey clsid;
    if (clsid.Open(HKEY_CLASSES_ROOT, key.c_str(), KEY_READ) != ERROR_SUCCESS) {
      ++registration;
      continue;
    }
    string16 dll;
    if (clsid.ReadValue(L"", &dll) != ERROR_SUCCESS) {
      ++registration;
      continue;
    }
    clsid.Close();

    Module entry;
    entry.type = SHELL_EXTENSION;
    entry.location = dll;
    PopulateModuleInformation(&entry);

    NormalizeModule(&entry);
    CollapsePath(&entry);
    AddToListWithoutDuplicating(entry);

    ++registration;
  }
}

void ModuleEnumerator::EnumerateWinsockModules() {
  // Add to this list the Winsock LSP DLLs.
  WinsockLayeredServiceProviderList layered_providers;
  GetWinsockLayeredServiceProviders(&layered_providers);
  for (size_t i = 0; i < layered_providers.size(); ++i) {
    Module entry;
    entry.type = WINSOCK_MODULE_REGISTRATION;
    entry.status = NOT_MATCHED;
    entry.normalized = false;
    entry.location = layered_providers[i].path;
    entry.description = layered_providers[i].name;
    entry.recommended_action = NONE;
    entry.duplicate_count = 0;

    wchar_t expanded[MAX_PATH];
    DWORD size = ExpandEnvironmentStrings(
        entry.location.c_str(), expanded, MAX_PATH);
    if (size != 0 && size <= MAX_PATH) {
      entry.digital_signer =
          GetSubjectNameFromDigitalSignature(base::FilePath(expanded));
    }
    entry.version = base::IntToString16(layered_providers[i].version);

    // Paths have already been collapsed.
    NormalizeModule(&entry);
    AddToListWithoutDuplicating(entry);
  }
}

void ModuleEnumerator::PopulateModuleInformation(Module* module) {
  module->status = NOT_MATCHED;
  module->duplicate_count = 0;
  module->normalized = false;
  module->digital_signer =
      GetSubjectNameFromDigitalSignature(base::FilePath(module->location));
  module->recommended_action = NONE;
  scoped_ptr<FileVersionInfo> version_info(
      FileVersionInfo::CreateFileVersionInfo(base::FilePath(module->location)));
  if (version_info.get()) {
    FileVersionInfoWin* version_info_win =
        static_cast<FileVersionInfoWin*>(version_info.get());

    VS_FIXEDFILEINFO* fixed_file_info = version_info_win->fixed_file_info();
    if (fixed_file_info) {
      module->description = version_info_win->file_description();
      module->version = version_info_win->file_version();
      module->product_name = version_info_win->product_name();
    }
  }
}

void ModuleEnumerator::AddToListWithoutDuplicating(const Module& module) {
  DCHECK(module.normalized);
  // These are registered modules, not loaded modules so the same module
  // can be registered multiple times, often dozens of times. There is no need
  // to list each registration, so we just increment the count for each module
  // that is counted multiple times.
  ModulesVector::iterator iter;
  iter = std::find_if(enumerated_modules_->begin(),
                      enumerated_modules_->end(),
                      FindModule(module));
  if (iter != enumerated_modules_->end()) {
    iter->duplicate_count++;
    iter->type = static_cast<ModuleType>(iter->type | module.type);
  } else {
    enumerated_modules_->push_back(module);
  }
}

void ModuleEnumerator::PreparePathMappings() {
  path_mapping_.clear();

  scoped_ptr<base::Environment> environment(base::Environment::Create());
  std::vector<string16> env_vars;
  env_vars.push_back(L"LOCALAPPDATA");
  env_vars.push_back(L"ProgramFiles");
  env_vars.push_back(L"ProgramData");
  env_vars.push_back(L"USERPROFILE");
  env_vars.push_back(L"SystemRoot");
  env_vars.push_back(L"TEMP");
  env_vars.push_back(L"TMP");
  env_vars.push_back(L"CommonProgramFiles");
  for (std::vector<string16>::const_iterator variable = env_vars.begin();
       variable != env_vars.end(); ++variable) {
    std::string path;
    if (environment->GetVar(WideToASCII(*variable).c_str(), &path)) {
      path_mapping_.push_back(
          std::make_pair(base::i18n::ToLower(UTF8ToUTF16(path)) + L"\\",
                         L"%" + base::i18n::ToLower(*variable) + L"%"));
    }
  }
}

void ModuleEnumerator::CollapsePath(Module* entry) {
  // Take the path and see if we can use any of the substitution values
  // from the vector constructed above to replace c:\windows with, for
  // example, %systemroot%. The most collapsed path (the one with the
  // minimum length) wins.
  size_t min_length = MAXINT;
  string16 location = entry->location;
  for (PathMapping::const_iterator mapping = path_mapping_.begin();
       mapping != path_mapping_.end(); ++mapping) {
    string16 prefix = mapping->first;
    if (StartsWith(location, prefix, false)) {
      string16 new_location = mapping->second +
                              location.substr(prefix.length() - 1);
      size_t length = new_location.length() - mapping->second.length();
      if (length < min_length) {
        entry->location = new_location;
        min_length = length;
      }
    }
  }
}

void ModuleEnumerator::MatchAgainstBlacklist() {
  for (size_t m = 0; m < enumerated_modules_->size(); ++m) {
    // Match this module against the blacklist.
    Module* module = &(*enumerated_modules_)[m];
    module->status = GOOD;  // We change this below potentially.
    for (size_t i = 0; i < arraysize(kModuleBlacklist); ++i) {
      #if !defined(NDEBUG)
        // This saves time when constructing the blacklist.
        std::string hashes(kModuleBlacklist[i].filename);
        std::string hash1, hash2, hash3;
        GenerateHash(kModuleBlacklist[i].filename, &hash1);
        hashes += " - " + hash1;
        GenerateHash(kModuleBlacklist[i].location, &hash2);
        hashes += " - " + hash2;
        GenerateHash(kModuleBlacklist[i].desc_or_signer, &hash3);
        hashes += " - " + hash3;
      #endif

      ModuleStatus status = Match(*module, kModuleBlacklist[i]);
      if (status != NOT_MATCHED) {
        // We have a match against the blacklist. Mark it as such.
        module->status = status;
        module->recommended_action = kModuleBlacklist[i].help_tip;
        break;
      }
    }

    // Modules loaded from these locations are frequently malicious
    // and notorious for changing frequently so they are not good candidates
    // for blacklisting individually. Mark them as suspicious if we haven't
    // classified them as bad yet.
    if (module->status == NOT_MATCHED || module->status == GOOD) {
      if (StartsWith(module->location, L"%temp%", false) ||
          StartsWith(module->location, L"%tmp%", false)) {
        module->status = SUSPECTED_BAD;
      }
    }
  }
}

void ModuleEnumerator::ReportBack() {
  if (!limited_mode_)
    DCHECK(BrowserThread::CurrentlyOn(callback_thread_id_));
  observer_->DoneScanning();
}

string16 ModuleEnumerator::GetSubjectNameFromDigitalSignature(
    const base::FilePath& filename) {
  HCERTSTORE store = NULL;
  HCRYPTMSG message = NULL;

  // Find the crypto message for this filename.
  bool result = !!CryptQueryObject(CERT_QUERY_OBJECT_FILE,
                                   filename.value().c_str(),
                                   CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED,
                                   CERT_QUERY_FORMAT_FLAG_BINARY,
                                   0,
                                   NULL,
                                   NULL,
                                   NULL,
                                   &store,
                                   &message,
                                   NULL);
  if (!result)
    return string16();

  // Determine the size of the signer info data.
  DWORD signer_info_size = 0;
  result = !!CryptMsgGetParam(message,
                              CMSG_SIGNER_INFO_PARAM,
                              0,
                              NULL,
                              &signer_info_size);
  if (!result)
    return string16();

  // Allocate enough space to hold the signer info.
  scoped_ptr<BYTE[]> signer_info_buffer(new BYTE[signer_info_size]);
  CMSG_SIGNER_INFO* signer_info =
      reinterpret_cast<CMSG_SIGNER_INFO*>(signer_info_buffer.get());

  // Obtain the signer info.
  result = !!CryptMsgGetParam(message,
                              CMSG_SIGNER_INFO_PARAM,
                              0,
                              signer_info,
                              &signer_info_size);
  if (!result)
    return string16();

  // Search for the signer certificate.
  CERT_INFO CertInfo = {0};
  PCCERT_CONTEXT cert_context = NULL;
  CertInfo.Issuer = signer_info->Issuer;
  CertInfo.SerialNumber = signer_info->SerialNumber;

  cert_context = CertFindCertificateInStore(
      store,
      X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
      0,
      CERT_FIND_SUBJECT_CERT,
      &CertInfo,
      NULL);
  if (!cert_context)
    return string16();

  // Determine the size of the Subject name.
  DWORD subject_name_size = 0;
  if (!(subject_name_size = CertGetNameString(cert_context,
                                              CERT_NAME_SIMPLE_DISPLAY_TYPE,
                                              0,
                                              NULL,
                                              NULL,
                                              0))) {
    return string16();
  }

  string16 subject_name;
  subject_name.resize(subject_name_size);

  // Get subject name.
  if (!(CertGetNameString(cert_context,
                          CERT_NAME_SIMPLE_DISPLAY_TYPE,
                          0,
                          NULL,
                          const_cast<LPWSTR>(subject_name.c_str()),
                          subject_name_size))) {
    return string16();
  }

  return subject_name;
}

//  ----------------------------------------------------------------------------

// static
EnumerateModulesModel* EnumerateModulesModel::GetInstance() {
  return Singleton<EnumerateModulesModel>::get();
}

// static
void EnumerateModulesModel::RecordLearnMoreStat(bool from_menu) {
  UMA_HISTOGRAM_ENUMERATION("ConflictingModule.UserSelection",
      from_menu ? ACTION_MENU_LEARN_MORE : ACTION_BUBBLE_LEARN_MORE,
      ACTION_BOUNDARY);
}

bool EnumerateModulesModel::ShouldShowConflictWarning() const {
  // If the user has acknowledged the conflict notification, then we don't need
  // to show it again (because the scanning only happens once per the lifetime
  // of the process). If we were to run the scanning more than once, then we'd
  // need to clear the flag somewhere when we are ready to show it again.
  if (conflict_notification_acknowledged_)
    return false;

  return confirmed_bad_modules_detected_ > 0;
}

void EnumerateModulesModel::AcknowledgeConflictNotification() {
  if (!conflict_notification_acknowledged_) {
    conflict_notification_acknowledged_ = true;
    content::NotificationService::current()->Notify(
        chrome::NOTIFICATION_MODULE_INCOMPATIBILITY_BADGE_CHANGE,
        content::Source<EnumerateModulesModel>(this),
        content::NotificationService::NoDetails());
  }
}

void EnumerateModulesModel::ScanNow() {
  if (scanning_)
    return;  // A scan is already in progress.

  lock->Acquire();  // Balanced in DoneScanning();

  scanning_ = true;

  // Instruct the ModuleEnumerator class to load this on the File thread.
  // ScanNow does not block.
  if (!module_enumerator_)
    module_enumerator_ = new ModuleEnumerator(this);
  module_enumerator_->ScanNow(&enumerated_modules_, limited_mode_);
}

ListValue* EnumerateModulesModel::GetModuleList() const {
  if (scanning_)
    return NULL;

  lock->Acquire();

  if (enumerated_modules_.empty()) {
    lock->Release();
    return NULL;
  }

  ListValue* list = new ListValue();

  for (ModuleEnumerator::ModulesVector::const_iterator module =
           enumerated_modules_.begin();
       module != enumerated_modules_.end(); ++module) {
    DictionaryValue* data = new DictionaryValue();
    data->SetInteger("type", module->type);
    string16 type_string;
    if ((module->type & ModuleEnumerator::LOADED_MODULE) == 0) {
      // Module is not loaded, denote type of module.
      if (module->type & ModuleEnumerator::SHELL_EXTENSION)
        type_string = ASCIIToWide("Shell Extension");
      if (module->type & ModuleEnumerator::WINSOCK_MODULE_REGISTRATION) {
        if (!type_string.empty())
          type_string += ASCIIToWide(", ");
        type_string += ASCIIToWide("Winsock");
      }
      // Must be one of the above type.
      DCHECK(!type_string.empty());
      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);
    data->SetString("location", module->location);
    data->SetString("name", module->name);
    data->SetString("product_name", module->product_name);
    data->SetString("description", module->description);
    data->SetString("version", module->version);
    data->SetString("digital_signer", module->digital_signer);

    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);
      }
      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);
  }

  lock->Release();
  return list;
}

GURL EnumerateModulesModel::GetFirstNotableConflict() {
  lock->Acquire();
  GURL url;

  if (enumerated_modules_.empty()) {
    lock->Release();
    return GURL();
  }

  for (ModuleEnumerator::ModulesVector::const_iterator module =
           enumerated_modules_.begin();
       module != enumerated_modules_.end(); ++module) {
    if (!(module->recommended_action & ModuleEnumerator::NOTIFY_USER))
      continue;

    url = ConstructHelpCenterUrl(*module);
    DCHECK(url.is_valid());
    break;
  }

  lock->Release();
  return url;
}


EnumerateModulesModel::EnumerateModulesModel()
    : limited_mode_(false),
      scanning_(false),
      conflict_notification_acknowledged_(false),
      confirmed_bad_modules_detected_(0),
      suspected_bad_modules_detected_(0),
      modules_to_notify_about_(0) {
  lock = new base::Lock();
}

EnumerateModulesModel::~EnumerateModulesModel() {
  delete lock;
}

void EnumerateModulesModel::MaybePostScanningTask() {
  static bool done = false;
  if (!done) {
    done = true;

    const CommandLine& cmd_line = *CommandLine::ForCurrentProcess();
    if (cmd_line.HasSwitch(switches::kConflictingModulesCheck) ||
        base::win::GetVersion() == base::win::VERSION_XP) {
      check_modules_timer_.Start(FROM_HERE,
          base::TimeDelta::FromMilliseconds(kModuleCheckDelayMs),
          this, &EnumerateModulesModel::ScanNow);
    }
  }
}

void EnumerateModulesModel::DoneScanning() {
  confirmed_bad_modules_detected_ = 0;
  suspected_bad_modules_detected_ = 0;
  modules_to_notify_about_ = 0;
  for (ModuleEnumerator::ModulesVector::const_iterator module =
       enumerated_modules_.begin();
       module != enumerated_modules_.end(); ++module) {
    if (module->status == ModuleEnumerator::CONFIRMED_BAD) {
      ++confirmed_bad_modules_detected_;
      if (module->recommended_action & ModuleEnumerator::NOTIFY_USER)
        ++modules_to_notify_about_;
    } else if (module->status == ModuleEnumerator::SUSPECTED_BAD) {
      ++suspected_bad_modules_detected_;
      if (module->recommended_action & ModuleEnumerator::NOTIFY_USER)
        ++modules_to_notify_about_;
    }
  }

  scanning_ = false;
  lock->Release();

  UMA_HISTOGRAM_COUNTS_100("Conflicts.SuspectedBadModules",
                           suspected_bad_modules_detected_);
  UMA_HISTOGRAM_COUNTS_100("Conflicts.ConfirmedBadModules",
                           confirmed_bad_modules_detected_);

  // Notifications are not available in limited mode.
  if (limited_mode_)
    return;

  content::NotificationService::current()->Notify(
      chrome::NOTIFICATION_MODULE_LIST_ENUMERATED,
      content::Source<EnumerateModulesModel>(this),
      content::NotificationService::NoDetails());

  // Command line flag must be enabled for the notification to get sent out.
  // Otherwise we'd get the badge (while the feature is disabled) when we
  // navigate to about:conflicts and find confirmed matches.
  const CommandLine& cmd_line = *CommandLine::ForCurrentProcess();
  if (!cmd_line.HasSwitch(switches::kConflictingModulesCheck))
    return;

  content::NotificationService::current()->Notify(
      chrome::NOTIFICATION_MODULE_INCOMPATIBILITY_BADGE_CHANGE,
      content::Source<EnumerateModulesModel>(this),
      content::NotificationService::NoDetails());
}

GURL EnumerateModulesModel::ConstructHelpCenterUrl(
    const ModuleEnumerator::Module& module) const {
  if (!(module.recommended_action & ModuleEnumerator::SEE_LINK) &&
      !(module.recommended_action & ModuleEnumerator::NOTIFY_USER))
    return GURL();

  // Construct the needed hashes.
  std::string filename, location, description, signer;
  GenerateHash(WideToUTF8(module.name), &filename);
  GenerateHash(WideToUTF8(module.location), &location);
  GenerateHash(WideToUTF8(module.description), &description);
  GenerateHash(WideToUTF8(module.digital_signer), &signer);

  string16 url = l10n_util::GetStringFUTF16(IDS_HELP_CENTER_VIEW_CONFLICTS,
      ASCIIToUTF16(filename), ASCIIToUTF16(location),
      ASCIIToUTF16(description), ASCIIToUTF16(signer));
  return GURL(UTF16ToUTF8(url));
}
