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 #include "chrome/browser/conflicts/module_event_sink_impl_win.h" | |
| 6 | |
| 7 #include <windows.h> | |
| 8 #include <psapi.h> | |
|
grt (UTC plus 2)
2016/12/20 11:11:34
should we set PSAPI_VERSION=2 explicitly somewhere
chrisha
2016/12/20 19:46:24
We want PSAPI_VERSION=1, and we set it globally in
grt (UTC plus 2)
2016/12/20 21:09:53
Why 1? My brief read of MSDN made me think that ve
chrisha
2016/12/21 20:14:59
I think this is a discussion for the mailing list.
| |
| 9 | |
| 10 #include "base/bind.h" | |
| 11 #include "base/files/file_path.h" | |
| 12 #include "base/memory/ptr_util.h" | |
| 13 #include "chrome/browser/conflicts/module_database_win.h" | |
| 14 #include "chrome/common/conflicts/module_watcher_win.h" | |
| 15 #include "content/public/browser/browser_thread.h" | |
| 16 #include "mojo/public/cpp/bindings/strong_binding.h" | |
| 17 | |
| 18 ModuleEventSinkImpl::ModuleEventSinkImpl(base::ProcessHandle process, | |
| 19 content::ProcessType process_type, | |
| 20 ModuleDatabase* module_database) | |
| 21 : process_(process), module_database_(module_database), process_id_(0) { | |
| 22 process_id_ = ::GetProcessId(process_); | |
| 23 module_database->OnProcessStarted(process_id_, process_type); | |
| 24 } | |
| 25 | |
| 26 ModuleEventSinkImpl::~ModuleEventSinkImpl() = default; | |
| 27 | |
| 28 // static | |
| 29 void ModuleEventSinkImpl::Create(base::ProcessHandle process, | |
| 30 content::ProcessType process_type, | |
| 31 ModuleDatabase* module_database, | |
| 32 mojom::ModuleEventSinkRequest request) { | |
| 33 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | |
| 34 std::unique_ptr<ModuleEventSinkImpl> module_event_sink_impl = | |
|
grt (UTC plus 2)
2016/12/20 11:11:34
nit: i think "auto" is appropriate here since the
chrisha
2016/12/20 19:46:24
Done.
| |
| 35 base::MakeUnique<ModuleEventSinkImpl>(process, process_type, | |
| 36 module_database); | |
| 37 base::Closure error_handler = base::Bind(&ModuleDatabase::OnProcessEnded, | |
|
grt (UTC plus 2)
2016/12/20 11:11:34
#include "base/callback.h" for base::Closure (whic
chrisha
2016/12/20 19:46:24
Done.
| |
| 38 base::Unretained(module_database), | |
| 39 module_event_sink_impl->process_id_); | |
| 40 auto binding = mojo::MakeStrongBinding(std::move(module_event_sink_impl), | |
| 41 std::move(request)); | |
| 42 binding->set_connection_error_handler(error_handler); | |
| 43 } | |
| 44 | |
| 45 void ModuleEventSinkImpl::OnModuleEvent(mojom::ModuleEventType event_type, | |
| 46 uint64_t load_address) { | |
| 47 // Mojo takes care of validating |event_type|, so only |load_address| needs to | |
| 48 // be checked. Load addresses must be aligned with the allocation granularity | |
| 49 // which is at least 64KB on any supported Windows OS. | |
| 50 if (load_address == 0 || load_address % (64 * 1024) != 0) | |
| 51 return; | |
| 52 | |
| 53 switch (event_type) { | |
| 54 case mojom::ModuleEventType::MODULE_ALREADY_LOADED: | |
| 55 case mojom::ModuleEventType::MODULE_LOADED: | |
| 56 return OnModuleLoad(event_type, load_address); | |
| 57 | |
| 58 case mojom::ModuleEventType::MODULE_UNLOADED: | |
| 59 return OnModuleUnload(load_address); | |
| 60 | |
| 61 default: | |
|
grt (UTC plus 2)
2016/12/20 11:11:34
remove default case so that compilation fails if/w
chrisha
2016/12/20 19:46:24
Done.
| |
| 62 NOTREACHED() << "Unknown ModuleEventType: " << event_type; | |
| 63 } | |
| 64 } | |
| 65 | |
| 66 void ModuleEventSinkImpl::OnModuleLoad(mojom::ModuleEventType event_type, | |
| 67 uint64_t load_address) { | |
| 68 DCHECK(event_type == mojom::ModuleEventType::MODULE_ALREADY_LOADED || | |
| 69 event_type == mojom::ModuleEventType::MODULE_LOADED); | |
| 70 | |
| 71 // Convert the |load_address| to a module handle. | |
| 72 HMODULE module = | |
| 73 reinterpret_cast<HMODULE>(static_cast<uintptr_t>(load_address)); | |
| 74 | |
| 75 // Get the module path. | |
| 76 WCHAR temp_path[MAX_PATH] = {}; | |
|
grt (UTC plus 2)
2016/12/20 11:11:35
nit: wchar_t
consider not zero-initialzing the who
chrisha
2016/12/20 19:46:24
Done.
| |
| 77 if (!::GetModuleFileNameEx(process_, module, temp_path, MAX_PATH)) | |
|
grt (UTC plus 2)
2016/12/20 11:11:34
MAX_PATH -> arraysize(temp_path) (and #include "b
chrisha
2016/12/20 19:46:24
Done.
| |
| 78 return; | |
| 79 | |
| 80 // Get the module information. | |
| 81 MODULEINFO info = {}; | |
| 82 if (!::GetModuleInformation(process_, module, &info, sizeof(info))) | |
| 83 return; | |
| 84 | |
| 85 // Convert this all to a ModuleEvent and forward this on to the module | |
| 86 // database. | |
| 87 ModuleWatcher::ModuleEvent event(event_type, base::FilePath(temp_path), | |
|
grt (UTC plus 2)
2016/12/20 11:11:34
temp_path -> base::StringPiece16(temp_path, len-fr
chrisha
2016/12/20 19:46:24
Good catch with the potentially missing trailing n
grt (UTC plus 2)
2016/12/20 21:09:53
I didn't check whether |length| would include the
chrisha
2016/12/21 20:15:00
It could be omitted in the case that the buffer is
| |
| 88 module, info.SizeOfImage); | |
| 89 module_database_->OnModuleEvent(process_id_, event); | |
| 90 } | |
| 91 | |
| 92 void ModuleEventSinkImpl::OnModuleUnload(uint64_t load_address) { | |
| 93 module_database_->OnModuleUnload(process_id_, | |
| 94 static_cast<uintptr_t>(load_address)); | |
| 95 } | |
| OLD | NEW |