Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(39)

Side by Side Diff: chrome/common/conflicts/module_watcher_win.cc

Issue 2576843002: [win] Create ModuleDatabase and ModuleEventSinkImpl. (Closed)
Patch Set: Moar comments, fix typos. Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/common/conflicts/module_watcher_win.h" 5 #include "chrome/common/conflicts/module_watcher_win.h"
6 6
7 #include <windows.h> 7 #include <windows.h>
8 #include <tlhelp32.h> 8 #include <tlhelp32.h>
9 #include <winternl.h> // For UNICODE_STRING. 9 #include <winternl.h> // For UNICODE_STRING.
10 10
11 #include <string> 11 #include <string>
12 12
13 #include "base/lazy_instance.h" 13 #include "base/lazy_instance.h"
14 #include "base/memory/ptr_util.h" 14 #include "base/memory/ptr_util.h"
15 #include "base/strings/string_piece.h"
15 #include "base/strings/utf_string_conversions.h" 16 #include "base/strings/utf_string_conversions.h"
16 #include "base/synchronization/lock.h" 17 #include "base/synchronization/lock.h"
17 #include "base/win/scoped_handle.h" 18 #include "base/win/scoped_handle.h"
18 19
19 // These structures and functions are documented in MSDN, see 20 // These structures and functions are documented in MSDN, see
20 // http://msdn.microsoft.com/en-us/library/gg547638(v=vs.85).aspx 21 // http://msdn.microsoft.com/en-us/library/gg547638(v=vs.85).aspx
21 // there are however no headers or import libraries available in the 22 // there are however no headers or import libraries available in the
22 // Platform SDK. They are declared outside of the anonymous namespace to 23 // Platform SDK. They are declared outside of the anonymous namespace to
23 // allow them to be forward declared in the header file. 24 // allow them to be forward declared in the header file.
24 enum { 25 enum {
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
89 // Global pointer to the singleton ModuleWatcher, if one exists. Under 90 // Global pointer to the singleton ModuleWatcher, if one exists. Under
90 // |module_watcher_lock|. 91 // |module_watcher_lock|.
91 ModuleWatcher* g_module_watcher_instance = nullptr; 92 ModuleWatcher* g_module_watcher_instance = nullptr;
92 93
93 // Names of the DLL notification registration functions. These are exported by 94 // Names of the DLL notification registration functions. These are exported by
94 // ntdll. 95 // ntdll.
95 constexpr wchar_t kNtDll[] = L"ntdll.dll"; 96 constexpr wchar_t kNtDll[] = L"ntdll.dll";
96 constexpr char kLdrRegisterDllNotification[] = "LdrRegisterDllNotification"; 97 constexpr char kLdrRegisterDllNotification[] = "LdrRegisterDllNotification";
97 constexpr char kLdrUnregisterDllNotification[] = "LdrUnregisterDllNotification"; 98 constexpr char kLdrUnregisterDllNotification[] = "LdrUnregisterDllNotification";
98 99
99 // Helper function for converting a UNICODE_STRING to a UTF8 std::string. 100 // Helper function for converting a UNICODE_STRING to a FilePath.
100 std::string ToString(const UNICODE_STRING* str) { 101 base::FilePath ToFilePath(const UNICODE_STRING* str) {
101 std::string s; 102 return base::FilePath(
102 base::WideToUTF8(str->Buffer, str->Length / sizeof(wchar_t), &s); 103 base::StringPiece16(str->Buffer, str->Length / sizeof(wchar_t)));
103 return s;
104 } 104 }
105 105
106 template <typename NotificationDataType> 106 template <typename NotificationDataType>
107 void OnModuleEvent(mojom::ModuleEventType event_type, 107 void OnModuleEvent(mojom::ModuleEventType event_type,
108 const NotificationDataType& notification_data, 108 const NotificationDataType& notification_data,
109 const ModuleWatcher::OnModuleEventCallback& callback) { 109 const ModuleWatcher::OnModuleEventCallback& callback) {
110 mojom::ModuleEvent event; 110 ModuleWatcher::ModuleEvent event(
111 event.event_type = event_type; 111 event_type, ToFilePath(notification_data.FullDllName),
112 event.module_path = ToString(notification_data.FullDllName); 112 notification_data.DllBase, notification_data.SizeOfImage);
113 event.load_address = reinterpret_cast<uintptr_t>(notification_data.DllBase);
114 event.size = notification_data.SizeOfImage;
115 callback.Run(event); 113 callback.Run(event);
116 } 114 }
117 115
118 } // namespace 116 } // namespace
119 117
120 // static 118 // static
121 std::unique_ptr<ModuleWatcher> ModuleWatcher::Create( 119 std::unique_ptr<ModuleWatcher> ModuleWatcher::Create(
122 const OnModuleEventCallback& callback) { 120 OnModuleEventCallback callback) {
123 // If a ModuleWatcher already exists then bail out. 121 // If a ModuleWatcher already exists then bail out.
124 base::AutoLock lock(g_module_watcher_lock.Get()); 122 base::AutoLock lock(g_module_watcher_lock.Get());
125 if (g_module_watcher_instance) 123 if (g_module_watcher_instance)
126 return nullptr; 124 return nullptr;
127 125
128 // This thread acquired the right to create a ModuleWatcher, so do so. 126 // This thread acquired the right to create a ModuleWatcher, so do so.
129 g_module_watcher_instance = new ModuleWatcher(callback); 127 g_module_watcher_instance = new ModuleWatcher(callback);
grt (UTC plus 2) 2016/12/22 14:19:07 std::move the callback (and #include <utility>)
chrisha 2017/01/03 21:34:48 Done.
130 return base::WrapUnique(g_module_watcher_instance); 128 return base::WrapUnique(g_module_watcher_instance);
131 } 129 }
132 130
133 ModuleWatcher::~ModuleWatcher() { 131 ModuleWatcher::~ModuleWatcher() {
134 // As soon as |g_module_watcher_instance| is null any dispatched callbacks 132 // As soon as |g_module_watcher_instance| is null any dispatched callbacks
135 // will be silently absorbed by LoaderNotificationCallback. 133 // will be silently absorbed by LoaderNotificationCallback.
136 base::AutoLock lock(g_module_watcher_lock.Get()); 134 base::AutoLock lock(g_module_watcher_lock.Get());
137 DCHECK_EQ(g_module_watcher_instance, this); 135 DCHECK_EQ(g_module_watcher_instance, this);
138 g_module_watcher_instance = nullptr; 136 g_module_watcher_instance = nullptr;
139 UnregisterDllNotificationCallback(); 137 UnregisterDllNotificationCallback();
(...skipping 27 matching lines...) Expand all
167 if (snap.IsValid()) 165 if (snap.IsValid())
168 break; 166 break;
169 if (::GetLastError() != ERROR_BAD_LENGTH) 167 if (::GetLastError() != ERROR_BAD_LENGTH)
170 return; 168 return;
171 } 169 }
172 if (!snap.IsValid()) 170 if (!snap.IsValid())
173 return; 171 return;
174 172
175 // Walk the module list. 173 // Walk the module list.
176 MODULEENTRY32 module = {sizeof(module)}; 174 MODULEENTRY32 module = {sizeof(module)};
177 std::string path;
178 for (BOOL result = ::Module32First(snap.Get(), &module); result != FALSE; 175 for (BOOL result = ::Module32First(snap.Get(), &module); result != FALSE;
179 result = ::Module32Next(snap.Get(), &module)) { 176 result = ::Module32Next(snap.Get(), &module)) {
180 base::WideToUTF8(module.szExePath, ::wcslen(module.szExePath), &path); 177 ModuleEvent event(mojom::ModuleEventType::MODULE_ALREADY_LOADED,
181 mojom::ModuleEvent event; 178 base::FilePath(module.szExePath), module.modBaseAddr,
182 event.event_type = mojom::ModuleEventType::MODULE_ALREADY_LOADED; 179 module.modBaseSize);
183 event.module_path = path;
184 event.load_address = reinterpret_cast<uintptr_t>(module.modBaseAddr);
185 event.size = module.modBaseSize;
186 callback_.Run(event); 180 callback_.Run(event);
187 } 181 }
188 182
189 return; 183 return;
190 } 184 }
191 185
192 // static 186 // static
193 ModuleWatcher::OnModuleEventCallback ModuleWatcher::GetCallbackForContext( 187 ModuleWatcher::OnModuleEventCallback ModuleWatcher::GetCallbackForContext(
194 void* context) { 188 void* context) {
195 base::AutoLock lock(g_module_watcher_lock.Get()); 189 base::AutoLock lock(g_module_watcher_lock.Get());
(...skipping 22 matching lines...) Expand all
218 notification_data->Unloaded, callback); 212 notification_data->Unloaded, callback);
219 break; 213 break;
220 214
221 default: 215 default:
222 // This is unexpected, but not a reason to crash. 216 // This is unexpected, but not a reason to crash.
223 NOTREACHED() << "Unknown LDR_DLL_NOTIFICATION_REASON: " 217 NOTREACHED() << "Unknown LDR_DLL_NOTIFICATION_REASON: "
224 << notification_reason; 218 << notification_reason;
225 } 219 }
226 } 220 }
227 221
228 ModuleWatcher::ModuleWatcher(const OnModuleEventCallback& callback) 222 ModuleWatcher::ModuleWatcher(OnModuleEventCallback callback)
229 : callback_(callback) { 223 : callback_(callback) {
grt (UTC plus 2) 2016/12/22 14:19:07 std::move
chrisha 2017/01/03 21:34:48 Done.
230 RegisterDllNotificationCallback(); 224 RegisterDllNotificationCallback();
231 EnumerateAlreadyLoadedModules(); 225 EnumerateAlreadyLoadedModules();
232 } 226 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698