// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROME_BROWSER_ENUMERATE_MODULES_MODEL_WIN_H_
#define CHROME_BROWSER_ENUMERATE_MODULES_MODEL_WIN_H_

#include <utility>
#include <vector>

#include "base/gtest_prod_util.h"
#include "base/memory/ref_counted.h"
#include "base/memory/singleton.h"
#include "base/strings/string16.h"
#include "base/timer/timer.h"
#include "content/public/browser/browser_thread.h"
#include "url/gurl.h"

class EnumerateModulesModel;

namespace base {
class FilePath;
class ListValue;
}

// A helper class that implements the enumerate module functionality on the File
// thread.
class ModuleEnumerator : public base::RefCountedThreadSafe<ModuleEnumerator> {
 public:
  // What type of module we are dealing with. Loaded modules are modules we
  // detect as loaded in the process at the time of scanning. The others are
  // modules of interest and may or may not be loaded in the process at the
  // time of scan.
  enum ModuleType {
    LOADED_MODULE               = 1 << 0,
    SHELL_EXTENSION             = 1 << 1,
    WINSOCK_MODULE_REGISTRATION = 1 << 2,
  };

  // The blacklist status of the module. Suspected Bad modules have been
  // partially matched (ie. name matches and location, but not description)
  // whereas Confirmed Bad modules have been identified further (ie.
  // AuthentiCode signer matches).
  enum ModuleStatus {
    // This is returned by the matching function when comparing against the
    // blacklist and the module does not match the current entry in the
    // blacklist.
    NOT_MATCHED,
    // The module is not on the blacklist. Assume it is good.
    GOOD,
    // Module is a suspected bad module.
    SUSPECTED_BAD,
    // Module is a bad bad dog.
    CONFIRMED_BAD,
  };

  // A bitmask with the possible resolutions for bad modules.
  enum RecommendedAction {
    NONE          = 0,
    INVESTIGATING = 1 << 0,
    UNINSTALL     = 1 << 1,
    DISABLE       = 1 << 2,
    UPDATE        = 1 << 3,
    SEE_LINK      = 1 << 4,
    NOTIFY_USER   = 1 << 5,
  };

  // Which Windows OS is affected.
  enum OperatingSystem {
    ALL          = -1,
    XP           = 1 << 0,
  };

  // The structure we populate when enumerating modules.
  struct Module {
    Module();
    Module(const Module& rhs);
    Module(ModuleType type,
           ModuleStatus status,
           const base::string16& location,
           const base::string16& name,
           const base::string16& product_name,
           const base::string16& description,
           const base::string16& version,
           const base::string16& digital_signer,
           RecommendedAction recommended_action);
    ~Module();

    // The type of module found
    ModuleType type;
    // The module status (benign/bad/etc).
    ModuleStatus status;
    // The module path, not including filename.
    base::string16 location;
    // The name of the module (filename).
    base::string16 name;
    // The name of the product the module belongs to.
    base::string16 product_name;
    // The module file description.
    base::string16 description;
    // The module version.
    base::string16 version;
    // The signer of the digital certificate for the module.
    base::string16 digital_signer;
    // The help tips bitmask.
    RecommendedAction recommended_action;
    // The duplicate count within each category of modules.
    int duplicate_count;
    // Whether this module has been normalized (necessary before checking it
    // against blacklist).
    bool normalized;
  };

  // A vector typedef of all modules enumerated.
  typedef std::vector<Module> ModulesVector;

  // A structure we populate with the blacklist entries.
  struct BlacklistEntry {
    const char* filename;
    const char* location;
    const char* desc_or_signer;
    const char* version_from;  // Version where conflict started.
    const char* version_to;    // First version that works.
    OperatingSystem os;  // Bitmask, representing what OS this entry applies to.
    RecommendedAction help_tip;
  };

  // A static function that normalizes the module information in the |module|
  // struct. Module information needs to be normalized before comparing against
  // the blacklist. This is because the same module can be described in many
  // different ways, ie. file paths can be presented in long/short name form,
  // and are not case sensitive on Windows. Also, the version string returned
  // can include appended text, which we don't want to use during comparison
  // against the blacklist.
  static void NormalizeModule(Module* module);

  // A static function that checks whether |module| has been |blacklisted|.
  static ModuleStatus Match(const Module& module,
                            const BlacklistEntry& blacklisted);

  explicit ModuleEnumerator(EnumerateModulesModel* observer);

  // Start scanning the loaded module list (if a scan is not already in
  // progress). This function does not block while reading the module list
  // (unless we are in limited_mode, see below), and will notify when done
  // through the MODULE_LIST_ENUMERATED notification.
  // The process will also send MODULE_INCOMPATIBILITY_BADGE_CHANGE to let
  // observers know when it is time to update the wrench menu badge.
  // When in |limited_mode|, this function will not leverage the File thread
  // to run asynchronously and will therefore block until scanning is done
  // (and will also not send out any notifications).
  void ScanNow(ModulesVector* list, bool limited_mode);

 private:
  FRIEND_TEST_ALL_PREFIXES(EnumerateModulesTest, CollapsePath);

  friend class base::RefCountedThreadSafe<ModuleEnumerator>;
  ~ModuleEnumerator();

  // The (currently) hard coded blacklist of known bad modules.
  static const BlacklistEntry kModuleBlacklist[];

  // This function does the actual file scanning work on the FILE thread (or
  // block the main thread when in limited_mode). It enumerates all loaded
  // modules in the process and other modules of interest, such as the
  // registered Winsock LSP modules and stores them in |enumerated_modules_|.
  // It then normalizes the module info and matches them against a blacklist
  // of known bad modules. Finally, it calls ReportBack to let the observer
  // know we are done.
  void ScanImpl();

  // Enumerate all modules loaded into the Chrome process.
  void EnumerateLoadedModules();

  // Enumerate all registered Windows shell extensions.
  void EnumerateShellExtensions();

  // Enumerate all registered Winsock LSP modules.
  void EnumerateWinsockModules();

  // Reads the registered shell extensions found under |parent| key in the
  // registry.
  void ReadShellExtensions(HKEY parent);

  // Given a |module|, initializes the structure and loads additional
  // information using the location field of the module.
  void PopulateModuleInformation(Module* module);

  // Checks the module list to see if a |module| of the same type, location
  // and name has been added before and if so, increments its duplication
  // counter. If it doesn't appear in the list, it is added.
  void AddToListWithoutDuplicating(const Module&);

  // Builds up a vector of path values mapping to environment variable,
  // with pairs like [c:\windows\, %systemroot%]. This is later used to
  // collapse paths like c:\windows\system32 into %systemroot%\system32, which
  // we can use for comparison against our blacklist (which uses only env vars).
  // NOTE: The vector will not contain an exhaustive list of environment
  // variables, only the ones currently found on the blacklist or ones that are
  // likely to appear there.
  void PreparePathMappings();

  // For a given |module|, collapse the path from c:\windows to %systemroot%,
  // based on the |path_mapping_| vector.
  void CollapsePath(Module* module);

  // Takes each module in the |enumerated_modules_| vector and matches it
  // against a fixed blacklist of bad and suspected bad modules.
  void MatchAgainstBlacklist();

  // This function executes on the UI thread when the scanning and matching
  // process is done. It notifies the observer.
  void ReportBack();

  // Given a filename, returns the Subject (who signed it) retrieved from
  // the digital signature (Authenticode).
  base::string16 GetSubjectNameFromDigitalSignature(
      const base::FilePath& filename);

  // The typedef for the vector that maps a regular file path to %env_var%.
  typedef std::vector< std::pair<base::string16, base::string16> > PathMapping;

  // The vector of paths to %env_var%, used to account for differences in
  // where people keep there files, c:\windows vs. d:\windows, etc.
  PathMapping path_mapping_;

  // The vector containing all the enumerated modules (loaded and modules of
  // interest).
  ModulesVector* enumerated_modules_;

  // The observer, who needs to be notified when we are done.
  EnumerateModulesModel* observer_;

  // See limited_mode below.
  bool limited_mode_;

  // The thread that we need to call back on to report that we are done.
  content::BrowserThread::ID callback_thread_id_;

  DISALLOW_COPY_AND_ASSIGN(ModuleEnumerator);
};

// This is a singleton class that enumerates all modules loaded into Chrome,
// both currently loaded modules (called DLLs on Windows) and modules 'of
// interest', such as WinSock LSP modules. This class also marks each module
// as benign or suspected bad or outright bad, using a supplied blacklist that
// is currently hard-coded.
//
// To use this class, grab the singleton pointer and call ScanNow().
// Then wait to get notified through MODULE_LIST_ENUMERATED when the list is
// ready.
//
// This class can be used on the UI thread as it asynchronously offloads the
// file work over to the FILE thread and reports back to the caller with a
// notification.
class EnumerateModulesModel {
 public:
  // UMA histogram constants.
  enum UmaModuleConflictHistogramOptions {
    ACTION_BUBBLE_SHOWN = 0,
    ACTION_BUBBLE_LEARN_MORE,
    ACTION_MENU_LEARN_MORE,
    ACTION_BOUNDARY, // Must be the last value.
  };

  static EnumerateModulesModel* GetInstance();

  // Returns true if we should show the conflict notification. The conflict
  // notification is only shown once during the lifetime of the process.
  bool ShouldShowConflictWarning() const;

  // Called when the user has acknowledged the conflict notification.
  void AcknowledgeConflictNotification();

  // Returns the number of suspected bad modules found in the last scan.
  // Returns 0 if no scan has taken place yet.
  int suspected_bad_modules_detected() const {
    return suspected_bad_modules_detected_;
  }

  // Returns the number of confirmed bad modules found in the last scan.
  // Returns 0 if no scan has taken place yet.
  int confirmed_bad_modules_detected() const {
    return confirmed_bad_modules_detected_;
  }

  // Returns how many modules to notify the user about.
  int modules_to_notify_about() const {
    return modules_to_notify_about_;
  }

  // Set to true when we the scanning process can not rely on certain Chrome
  // services to exists.
  void set_limited_mode(bool limited_mode) {
    limited_mode_ = limited_mode;
  }

  // Checks to see if a scanning task should be started and sets one off, if so.
  void MaybePostScanningTask();

  // Asynchronously start the scan for the loaded module list, except when in
  // limited_mode (in which case it blocks).
  void ScanNow();

  // Gets the whole module list as a ListValue.
  base::ListValue* GetModuleList() const;

  // Gets the Help Center URL for the first *notable* conflict module that we've
  // elected to notify the user about.
  GURL GetFirstNotableConflict();

 private:
  friend struct base::DefaultSingletonTraits<EnumerateModulesModel>;
  friend class ModuleEnumerator;

  EnumerateModulesModel();
  virtual ~EnumerateModulesModel();

  // Called on the UI thread when the helper class is done scanning.
  void DoneScanning();

  // Constructs a Help Center article URL for help with a particular module.
  // The module must have the SEE_LINK attribute for |recommended_action| set,
  // otherwise this returns a blank string.
  GURL ConstructHelpCenterUrl(const ModuleEnumerator::Module& module) const;

  // The vector containing all the modules enumerated. Will be normalized and
  // any bad modules will be marked.
  ModuleEnumerator::ModulesVector enumerated_modules_;

  // The object responsible for enumerating the modules on the File thread.
  scoped_refptr<ModuleEnumerator> module_enumerator_;

  // When this singleton object is constructed we go and fire off this timer to
  // start scanning for modules after a certain amount of time has passed.
  base::OneShotTimer check_modules_timer_;

  // While normally |false|, this mode can be set to indicate that the scanning
  // process should not rely on certain services normally available to Chrome,
  // such as the resource bundle and the notification system, not to mention
  // having multiple threads. This mode is useful during diagnostics, which
  // runs without firing up all necessary Chrome services first.
  bool limited_mode_;

  // True if we are currently scanning for modules.
  bool scanning_;

  // Whether the conflict notification has been acknowledged by the user.
  bool conflict_notification_acknowledged_;

  // The number of confirmed bad modules (not including suspected bad ones)
  // found during last scan.
  int confirmed_bad_modules_detected_;

  // The number of bad modules the user needs to be aggressively notified about.
  int modules_to_notify_about_;

  // The number of suspected bad modules (not including confirmed bad ones)
  // found during last scan.
  int suspected_bad_modules_detected_;

  DISALLOW_COPY_AND_ASSIGN(EnumerateModulesModel);
};

#endif  // CHROME_BROWSER_ENUMERATE_MODULES_MODEL_WIN_H_
