// 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 base::string16& short_path,
                       base::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) {
  base::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 != base::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 != base::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;
    }
    base::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<base::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<base::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;
  base::string16 location = entry->location;
  for (PathMapping::const_iterator mapping = path_mapping_.begin();
       mapping != path_mapping_.end(); ++mapping) {
    base::string16 prefix = mapping->first;
    if (StartsWith(location, prefix, false)) {
      base::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();
}

base::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 base::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 base::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 base::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 base::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 base::string16();
  }

  base::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 base::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);
    base::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.
      base::string16 actions;
      base::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);
      }
      base::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);

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