Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #ifndef CHROME_COMMON_CONFLICTS_MODULE_WATCHER_WIN_H_ | |
| 6 #define CHROME_COMMON_CONFLICTS_MODULE_WATCHER_WIN_H_ | |
| 7 | |
| 8 #include "base/callback.h" | |
| 9 #include "base/files/file_path.h" | |
| 10 #include "base/memory/ref_counted.h" | |
| 11 #include "base/synchronization/lock.h" | |
| 12 | |
| 13 namespace base { | |
| 14 template <class ObserverType> | |
| 15 class ObserverListThreadSafe; | |
| 16 } // namespace base | |
| 17 | |
| 18 namespace conflicts { | |
| 19 | |
| 20 class ModuleWatcherTest; | |
| 21 | |
| 22 // This class observes modules as they are loaded and unloaded into a processes | |
| 23 // address space. It works by installing a DllNotification callback, and | |
| 24 // also enumerating all currently loaded modules at the time of its creation. | |
| 25 class ModuleWatcher { | |
| 26 public: | |
| 27 // The types of events that are observed by the watcher. | |
| 28 enum EventType { | |
| 29 // The module was already loaded at the time of creation of the | |
| 30 // ModuleWatcher. | |
| 31 MODULE_ALREADY_LOADED, | |
| 32 // The module was not loaded at the time of creation of the ModuleWatcher | |
| 33 // and is being loaded. | |
| 34 MODULE_LOADED, | |
| 35 // The module is being unloaded. | |
| 36 MODULE_UNLOADED, | |
| 37 }; | |
| 38 | |
| 39 // A notification about a module being loaded or unloaded. | |
| 40 struct ModuleEvent { | |
| 41 // The type of event. | |
| 42 EventType event_type; | |
| 43 // The full path to the module being loaded or unloaded. | |
| 44 base::FilePath module_path; | |
| 45 // The load address of the module. | |
| 46 void* load_address; | |
| 47 // The size of the module in memory, in bytes. | |
| 48 size_t size; | |
| 49 }; | |
| 50 | |
| 51 // Clients may register callbacks with the following type in order to receive | |
| 52 // notifications. | |
| 53 using OnModuleEventCallback = base::Callback<void(const ModuleEvent& event)>; | |
| 54 class Observer; | |
| 55 | |
| 56 ModuleWatcher(); | |
| 57 ~ModuleWatcher(); | |
| 58 | |
| 59 // Registers a callback with this ModuleWatcher. The thread on which the | |
| 60 // callback is registered is the thread on which the callback will be invoked. | |
| 61 // To unregister the callback simply delete the resulting Observer object. | |
| 62 // Note that the observer must be destroyed on the same thread on which it | |
| 63 // was created. (See ObserverListThreadSafe::RemoveObserver for details.) | |
| 64 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
| |
| 65 const OnModuleEventCallback& callback); | |
| 66 | |
| 67 // Starts the watcher. This enumerates all loaded modules and registers a | |
| 68 // DllNotification callback for continued notifications. This is threadsafe. | |
| 69 // Note that it is possible to receive duplicate notifications for some | |
| 70 // modules as the initial loaded module enumerations is racy with the | |
| 71 // installation of the callback. In this case you will receive both a | |
| 72 // MODULE_LOADED and a MODULE_ALREADY_LOADED event for the same module. Since | |
| 73 // the callback is installed first no modules will be missed. | |
| 74 void Start(); | |
| 75 | |
| 76 // Stops the watcher. The watcher may subsequently be restarted. Doesn't | |
| 77 // need to be called explicitly as ~ModuleWatcher will do so as well. This | |
| 78 // is thread-safe. | |
| 79 void Stop(); | |
| 80 | |
| 81 // Returns true if the watcher is currently running, false otherwise. | |
| 82 bool IsRunning(); | |
| 83 | |
| 84 protected: | |
| 85 // Used as a bridge between the operating system notifications and this class. | |
| 86 class Bridge; | |
| 87 | |
| 88 // The Bridge requires access to Notify. | |
| 89 friend class Bridge; | |
| 90 // For unittesting. | |
| 91 friend class ModuleWatcherTest; | |
| 92 // Observers require access to |observer_list_|. | |
| 93 friend class Observer; | |
| 94 | |
| 95 // Registers a Dll Notification callback with the OS. Returns true on success, | |
| 96 // false otherwise. Modifies |dll_notification_cookie_|. | |
| 97 bool RegisterDllNotificationCallback(); | |
| 98 | |
| 99 // Removes the installed Dll Notification callback. This should only | |
| 100 // be called if InstallDllNotificationCallback returned true. Returns true on | |
| 101 // success, false otherwise. | |
| 102 bool UnregisterDllNotificationCallback(); | |
| 103 | |
| 104 // Enumerates all currently loaded modules, firing off callbacks. Returns | |
| 105 // true on success, false otherwise. | |
| 106 bool EnumerateAlreadyLoadedModules(); | |
| 107 | |
| 108 // Invoked by ModuleWatcherHelper. Dispatches the provided ModuleEvent to all | |
| 109 // registered observers. | |
| 110 void Notify(const ModuleEvent& event); | |
| 111 | |
| 112 // The list of registered observers. This is directly modified by | |
| 113 // ModuleWatcher::Observer. | |
| 114 scoped_refptr<base::ObserverListThreadSafe<Observer>> observer_list_; | |
| 115 | |
| 116 private: | |
| 117 base::Lock lock_; | |
| 118 // Indicates whether or not the ModuleWatcher is currently started. Under | |
| 119 // lock_. | |
| 120 bool started_; | |
| 121 // Used by the DllNotification mechanism. Under lock_. | |
| 122 void* dll_notification_cookie_; | |
| 123 | |
| 124 DISALLOW_COPY_AND_ASSIGN(ModuleWatcher); | |
| 125 }; | |
| 126 | |
| 127 // Observer class. This is all implementation detail, plumbing callbacks to | |
| 128 // an ObserverListThreadSafe and handling automatic unregistration. Nothing to | |
| 129 // see here. | |
| 130 class ModuleWatcher::Observer { | |
| 131 public: | |
| 132 ~Observer(); | |
| 133 | |
| 134 protected: | |
| 135 friend ModuleWatcher; | |
| 136 | |
| 137 // Constructor. To actually create one of these use | |
| 138 // ModuleWatcher::RegisterCallback | |
| 139 Observer(const OnModuleEventCallback& callback, | |
| 140 ModuleWatcher* module_watcher); | |
| 141 | |
| 142 // Used by ModuleWatcher to dispatch events to this observer. | |
| 143 void Notify(const ModuleEvent& event); | |
| 144 | |
| 145 // The bound callback. | |
| 146 OnModuleEventCallback callback_; | |
| 147 // The parent ModuleWatcher to which this observer belongs. | |
| 148 ModuleWatcher* module_watcher_; | |
| 149 | |
| 150 private: | |
| 151 DISALLOW_COPY_AND_ASSIGN(Observer); | |
| 152 }; | |
| 153 | |
| 154 } // namespace conflicts | |
| 155 | |
| 156 #endif // CHROME_COMMON_CONFLICTS_MODULE_WATCHER_WIN_H_ | |
| OLD | NEW |