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