15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2011 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef CHROME_BROWSER_ENUMERATE_MODULES_MODEL_WIN_H_
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CHROME_BROWSER_ENUMERATE_MODULES_MODEL_WIN_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <utility>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector>
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/gtest_prod_util.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/singleton.h"
14868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string16.h"
15eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/timer/timer.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h"
17eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "url/gurl.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class EnumerateModulesModel;
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace base {
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class FilePath;
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ListValue;
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A helper class that implements the enumerate module functionality on the File
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// thread.
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ModuleEnumerator : public base::RefCountedThreadSafe<ModuleEnumerator> {
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // What type of module we are dealing with. Loaded modules are modules we
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // detect as loaded in the process at the time of scanning. The others are
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // modules of interest and may or may not be loaded in the process at the
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // time of scan.
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum ModuleType {
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOADED_MODULE               = 1 << 0,
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SHELL_EXTENSION             = 1 << 1,
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WINSOCK_MODULE_REGISTRATION = 1 << 2,
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The blacklist status of the module. Suspected Bad modules have been
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // partially matched (ie. name matches and location, but not description)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // whereas Confirmed Bad modules have been identified further (ie.
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // AuthentiCode signer matches).
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum ModuleStatus {
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // This is returned by the matching function when comparing against the
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // blacklist and the module does not match the current entry in the
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // blacklist.
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOT_MATCHED,
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The module is not on the blacklist. Assume it is good.
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GOOD,
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Module is a suspected bad module.
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SUSPECTED_BAD,
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Module is a bad bad dog.
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CONFIRMED_BAD,
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // A bitmask with the possible resolutions for bad modules.
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum RecommendedAction {
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NONE          = 0,
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    INVESTIGATING = 1 << 0,
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    UNINSTALL     = 1 << 1,
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DISABLE       = 1 << 2,
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    UPDATE        = 1 << 3,
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SEE_LINK      = 1 << 4,
65868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    NOTIFY_USER   = 1 << 5,
66868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  };
67868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
68868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Which Windows OS is affected.
69868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  enum OperatingSystem {
70868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    ALL          = -1,
71868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    XP           = 1 << 0,
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The structure we populate when enumerating modules.
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct Module {
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The type of module found
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ModuleType type;
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The module status (benign/bad/etc).
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ModuleStatus status;
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The module path, not including filename.
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    string16 location;
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The name of the module (filename).
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    string16 name;
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The name of the product the module belongs to.
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    string16 product_name;
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The module file description.
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    string16 description;
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The module version.
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    string16 version;
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The signer of the digital certificate for the module.
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    string16 digital_signer;
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The help tips bitmask.
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RecommendedAction recommended_action;
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The duplicate count within each category of modules.
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int duplicate_count;
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Whether this module has been normalized (necessary before checking it
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // against blacklist).
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool normalized;
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // A vector typedef of all modules enumerated.
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef std::vector<Module> ModulesVector;
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // A structure we populate with the blacklist entries.
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct BlacklistEntry {
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* filename;
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* location;
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* desc_or_signer;
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* version_from;  // Version where conflict started.
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* version_to;    // First version that works.
111868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    OperatingSystem os;  // Bitmask, representing what OS this entry applies to.
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RecommendedAction help_tip;
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // A static function that normalizes the module information in the |module|
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // struct. Module information needs to be normalized before comparing against
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the blacklist. This is because the same module can be described in many
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // different ways, ie. file paths can be presented in long/short name form,
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // and are not case sensitive on Windows. Also, the version string returned
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // can include appended text, which we don't want to use during comparison
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // against the blacklist.
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void NormalizeModule(Module* module);
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // A static function that checks whether |module| has been |blacklisted|.
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static ModuleStatus Match(const Module& module,
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            const BlacklistEntry& blacklisted);
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit ModuleEnumerator(EnumerateModulesModel* observer);
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~ModuleEnumerator();
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Start scanning the loaded module list (if a scan is not already in
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // progress). This function does not block while reading the module list
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (unless we are in limited_mode, see below), and will notify when done
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // through the MODULE_LIST_ENUMERATED notification.
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The process will also send MODULE_INCOMPATIBILITY_BADGE_CHANGE to let
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // observers know when it is time to update the wrench menu badge.
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // When in |limited_mode|, this function will not leverage the File thread
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to run asynchronously and will therefore block until scanning is done
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (and will also not send out any notifications).
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ScanNow(ModulesVector* list, bool limited_mode);
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FRIEND_TEST_ALL_PREFIXES(EnumerateModulesTest, CollapsePath);
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The (currently) hard coded blacklist of known bad modules.
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const BlacklistEntry kModuleBlacklist[];
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This function does the actual file scanning work on the FILE thread (or
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // block the main thread when in limited_mode). It enumerates all loaded
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // modules in the process and other modules of interest, such as the
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // registered Winsock LSP modules and stores them in |enumerated_modules_|.
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // It then normalizes the module info and matches them against a blacklist
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // of known bad modules. Finally, it calls ReportBack to let the observer
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // know we are done.
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ScanImpl();
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Enumerate all modules loaded into the Chrome process.
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void EnumerateLoadedModules();
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Enumerate all registered Windows shell extensions.
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void EnumerateShellExtensions();
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Enumerate all registered Winsock LSP modules.
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void EnumerateWinsockModules();
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Reads the registered shell extensions found under |parent| key in the
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // registry.
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ReadShellExtensions(HKEY parent);
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Given a |module|, initializes the structure and loads additional
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // information using the location field of the module.
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void PopulateModuleInformation(Module* module);
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Checks the module list to see if a |module| of the same type, location
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // and name has been added before and if so, increments its duplication
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // counter. If it doesn't appear in the list, it is added.
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void AddToListWithoutDuplicating(const Module&);
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Builds up a vector of path values mapping to environment variable,
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // with pairs like [c:\windows\, %systemroot%]. This is later used to
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // collapse paths like c:\windows\system32 into %systemroot%\system32, which
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // we can use for comparison against our blacklist (which uses only env vars).
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // NOTE: The vector will not contain an exhaustive list of environment
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // variables, only the ones currently found on the blacklist or ones that are
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // likely to appear there.
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void PreparePathMappings();
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // For a given |module|, collapse the path from c:\windows to %systemroot%,
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // based on the |path_mapping_| vector.
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void CollapsePath(Module* module);
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Takes each module in the |enumerated_modules_| vector and matches it
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // against a fixed blacklist of bad and suspected bad modules.
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void MatchAgainstBlacklist();
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This function executes on the UI thread when the scanning and matching
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // process is done. It notifies the observer.
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ReportBack();
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Given a filename, returns the Subject (who signed it) retrieved from
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the digital signature (Authenticode).
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  string16 GetSubjectNameFromDigitalSignature(const base::FilePath& filename);
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The typedef for the vector that maps a regular file path to %env_var%.
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef std::vector< std::pair<string16, string16> > PathMapping;
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The vector of paths to %env_var%, used to account for differences in
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // where people keep there files, c:\windows vs. d:\windows, etc.
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PathMapping path_mapping_;
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The vector containing all the enumerated modules (loaded and modules of
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // interest).
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ModulesVector* enumerated_modules_;
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The observer, who needs to be notified when we are done.
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EnumerateModulesModel* observer_;
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // See limited_mode below.
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool limited_mode_;
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The thread that we need to call back on to report that we are done.
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::BrowserThread::ID callback_thread_id_;
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ModuleEnumerator);
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This is a singleton class that enumerates all modules loaded into Chrome,
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// both currently loaded modules (called DLLs on Windows) and modules 'of
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// interest', such as WinSock LSP modules. This class also marks each module
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// as benign or suspected bad or outright bad, using a supplied blacklist that
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// is currently hard-coded.
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// To use this class, grab the singleton pointer and call ScanNow().
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Then wait to get notified through MODULE_LIST_ENUMERATED when the list is
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ready.
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This class can be used on the UI thread as it asynchronously offloads the
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// file work over to the FILE thread and reports back to the caller with a
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// notification.
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class EnumerateModulesModel {
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
242868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // UMA histogram constants.
243868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  enum UmaModuleConflictHistogramOptions {
244868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    ACTION_BUBBLE_SHOWN = 0,
245868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    ACTION_BUBBLE_LEARN_MORE,
246868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    ACTION_MENU_LEARN_MORE,
247868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    ACTION_BOUNDARY, // Must be the last value.
248868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  };
249868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static EnumerateModulesModel* GetInstance();
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
252868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Record via UMA what the user selected.
253868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  static void RecordLearnMoreStat(bool from_menu);
254868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns true if we should show the conflict notification. The conflict
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // notification is only shown once during the lifetime of the process.
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool ShouldShowConflictWarning() const;
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called when the user has acknowledged the conflict notification.
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void AcknowledgeConflictNotification();
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns the number of suspected bad modules found in the last scan.
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns 0 if no scan has taken place yet.
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int suspected_bad_modules_detected() const {
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return suspected_bad_modules_detected_;
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns the number of confirmed bad modules found in the last scan.
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns 0 if no scan has taken place yet.
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int confirmed_bad_modules_detected() const {
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return confirmed_bad_modules_detected_;
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
274868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Returns how many modules to notify the user about.
275868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  int modules_to_notify_about() const {
276868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return modules_to_notify_about_;
277868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
278868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set to true when we the scanning process can not rely on certain Chrome
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // services to exists.
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void set_limited_mode(bool limited_mode) {
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    limited_mode_ = limited_mode;
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Checks to see if a scanning task should be started and sets one off, if so.
286868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  void MaybePostScanningTask();
287868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Asynchronously start the scan for the loaded module list, except when in
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // limited_mode (in which case it blocks).
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ScanNow();
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Gets the whole module list as a ListValue.
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::ListValue* GetModuleList() const;
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Gets the Help Center URL for the first *notable* conflict module that we've
296868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // elected to notify the user about.
297868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  GURL GetFirstNotableConflict();
298868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend struct DefaultSingletonTraits<EnumerateModulesModel>;
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend class ModuleEnumerator;
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EnumerateModulesModel();
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~EnumerateModulesModel();
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called on the UI thread when the helper class is done scanning.
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void DoneScanning();
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Constructs a Help Center article URL for help with a particular module.
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The module must have the SEE_LINK attribute for |recommended_action| set,
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // otherwise this returns a blank string.
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL ConstructHelpCenterUrl(const ModuleEnumerator::Module& module) const;
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The vector containing all the modules enumerated. Will be normalized and
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // any bad modules will be marked.
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ModuleEnumerator::ModulesVector enumerated_modules_;
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The object responsible for enumerating the modules on the File thread.
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<ModuleEnumerator> module_enumerator_;
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // When this singleton object is constructed we go and fire off this timer to
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // start scanning for modules after a certain amount of time has passed.
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::OneShotTimer<EnumerateModulesModel> check_modules_timer_;
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // While normally |false|, this mode can be set to indicate that the scanning
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // process should not rely on certain services normally available to Chrome,
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // such as the resource bundle and the notification system, not to mention
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // having multiple threads. This mode is useful during diagnostics, which
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // runs without firing up all necessary Chrome services first.
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool limited_mode_;
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // True if we are currently scanning for modules.
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool scanning_;
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Whether the conflict notification has been acknowledged by the user.
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool conflict_notification_acknowledged_;
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The number of confirmed bad modules (not including suspected bad ones)
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // found during last scan.
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int confirmed_bad_modules_detected_;
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
342868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // The number of bad modules the user needs to be aggressively notified about.
343868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  int modules_to_notify_about_;
344868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The number of suspected bad modules (not including confirmed bad ones)
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // found during last scan.
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int suspected_bad_modules_detected_;
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(EnumerateModulesModel);
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // CHROME_BROWSER_ENUMERATE_MODULES_MODEL_WIN_H_
353