Chromium Code Reviews| Index: chrome/common/conflicts/module_watcher_win.h |
| diff --git a/chrome/common/conflicts/module_watcher_win.h b/chrome/common/conflicts/module_watcher_win.h |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..fd7c4bc20fa7c2fb4b25b84462ebc5c00d58b27a |
| --- /dev/null |
| +++ b/chrome/common/conflicts/module_watcher_win.h |
| @@ -0,0 +1,156 @@ |
| +// Copyright 2016 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_COMMON_CONFLICTS_MODULE_WATCHER_WIN_H_ |
| +#define CHROME_COMMON_CONFLICTS_MODULE_WATCHER_WIN_H_ |
| + |
| +#include "base/callback.h" |
| +#include "base/files/file_path.h" |
| +#include "base/memory/ref_counted.h" |
| +#include "base/synchronization/lock.h" |
| + |
| +namespace base { |
| +template <class ObserverType> |
| +class ObserverListThreadSafe; |
| +} // namespace base |
| + |
| +namespace conflicts { |
| + |
| +class ModuleWatcherTest; |
| + |
| +// This class observes modules as they are loaded and unloaded into a processes |
| +// address space. It works by installing a DllNotification callback, and |
| +// also enumerating all currently loaded modules at the time of its creation. |
| +class ModuleWatcher { |
| + public: |
| + // The types of events that are observed by the watcher. |
| + enum EventType { |
| + // The module was already loaded at the time of creation of the |
| + // ModuleWatcher. |
| + MODULE_ALREADY_LOADED, |
| + // The module was not loaded at the time of creation of the ModuleWatcher |
| + // and is being loaded. |
| + MODULE_LOADED, |
| + // The module is being unloaded. |
| + MODULE_UNLOADED, |
| + }; |
| + |
| + // A notification about a module being loaded or unloaded. |
| + struct ModuleEvent { |
| + // The type of event. |
| + EventType event_type; |
| + // The full path to the module being loaded or unloaded. |
| + base::FilePath module_path; |
| + // The load address of the module. |
| + void* load_address; |
| + // The size of the module in memory, in bytes. |
| + size_t size; |
| + }; |
| + |
| + // Clients may register callbacks with the following type in order to receive |
| + // notifications. |
| + using OnModuleEventCallback = base::Callback<void(const ModuleEvent& event)>; |
| + class Observer; |
| + |
| + ModuleWatcher(); |
| + ~ModuleWatcher(); |
| + |
| + // Registers a callback with this ModuleWatcher. The thread on which the |
| + // callback is registered is the thread on which the callback will be invoked. |
| + // To unregister the callback simply delete the resulting Observer object. |
| + // Note that the observer must be destroyed on the same thread on which it |
| + // was created. (See ObserverListThreadSafe::RemoveObserver for details.) |
| + std::unique_ptr<Observer> RegisterCallback( |
|
Patrick Monette
2016/11/03 20:18:15
Seems like you are implementing base::CallbackList
chrisha
2016/11/04 15:32:42
I am indeed. I'm not sure if anybody else needs th
|
| + const OnModuleEventCallback& callback); |
| + |
| + // Starts the watcher. This enumerates all loaded modules and registers a |
| + // DllNotification callback for continued notifications. This is threadsafe. |
| + // Note that it is possible to receive duplicate notifications for some |
| + // modules as the initial loaded module enumerations is racy with the |
| + // installation of the callback. In this case you will receive both a |
| + // MODULE_LOADED and a MODULE_ALREADY_LOADED event for the same module. Since |
| + // the callback is installed first no modules will be missed. |
| + void Start(); |
| + |
| + // Stops the watcher. The watcher may subsequently be restarted. Doesn't |
| + // need to be called explicitly as ~ModuleWatcher will do so as well. This |
| + // is thread-safe. |
| + void Stop(); |
| + |
| + // Returns true if the watcher is currently running, false otherwise. |
| + bool IsRunning(); |
| + |
| + protected: |
| + // Used as a bridge between the operating system notifications and this class. |
| + class Bridge; |
| + |
| + // The Bridge requires access to Notify. |
| + friend class Bridge; |
| + // For unittesting. |
| + friend class ModuleWatcherTest; |
| + // Observers require access to |observer_list_|. |
| + friend class Observer; |
| + |
| + // Registers a Dll Notification callback with the OS. Returns true on success, |
| + // false otherwise. Modifies |dll_notification_cookie_|. |
| + bool RegisterDllNotificationCallback(); |
| + |
| + // Removes the installed Dll Notification callback. This should only |
| + // be called if InstallDllNotificationCallback returned true. Returns true on |
| + // success, false otherwise. |
| + bool UnregisterDllNotificationCallback(); |
| + |
| + // Enumerates all currently loaded modules, firing off callbacks. Returns |
| + // true on success, false otherwise. |
| + bool EnumerateAlreadyLoadedModules(); |
| + |
| + // Invoked by ModuleWatcherHelper. Dispatches the provided ModuleEvent to all |
| + // registered observers. |
| + void Notify(const ModuleEvent& event); |
| + |
| + // The list of registered observers. This is directly modified by |
| + // ModuleWatcher::Observer. |
| + scoped_refptr<base::ObserverListThreadSafe<Observer>> observer_list_; |
| + |
| + private: |
| + base::Lock lock_; |
| + // Indicates whether or not the ModuleWatcher is currently started. Under |
| + // lock_. |
| + bool started_; |
| + // Used by the DllNotification mechanism. Under lock_. |
| + void* dll_notification_cookie_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(ModuleWatcher); |
| +}; |
| + |
| +// Observer class. This is all implementation detail, plumbing callbacks to |
| +// an ObserverListThreadSafe and handling automatic unregistration. Nothing to |
| +// see here. |
| +class ModuleWatcher::Observer { |
| + public: |
| + ~Observer(); |
| + |
| + protected: |
| + friend ModuleWatcher; |
| + |
| + // Constructor. To actually create one of these use |
| + // ModuleWatcher::RegisterCallback |
| + Observer(const OnModuleEventCallback& callback, |
| + ModuleWatcher* module_watcher); |
| + |
| + // Used by ModuleWatcher to dispatch events to this observer. |
| + void Notify(const ModuleEvent& event); |
| + |
| + // The bound callback. |
| + OnModuleEventCallback callback_; |
| + // The parent ModuleWatcher to which this observer belongs. |
| + ModuleWatcher* module_watcher_; |
| + |
| + private: |
| + DISALLOW_COPY_AND_ASSIGN(Observer); |
| +}; |
| + |
| +} // namespace conflicts |
| + |
| +#endif // CHROME_COMMON_CONFLICTS_MODULE_WATCHER_WIN_H_ |