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> | |
| 9 | |
| 10 #include "base/bind.h" | |
| 11 #include "base/callback.h" | |
| 12 #include "base/files/file_path.h" | |
| 13 #include "base/macros.h" | |
| 14 #include "base/memory/ptr_util.h" | |
| 15 #include "base/strings/string_piece.h" | |
| 16 #include "chrome/browser/conflicts/module_database_win.h" | |
| 17 #include "chrome/common/conflicts/module_watcher_win.h" | |
| 18 #include "content/public/browser/browser_thread.h" | |
| 19 #include "mojo/public/cpp/bindings/strong_binding.h" | |
| 20 | |
| 21 ModuleEventSinkImpl::ModuleEventSinkImpl(base::ProcessHandle process, | |
| 22 content::ProcessType process_type, | |
| 23 ModuleDatabase* module_database) | |
| 24 : process_(process), module_database_(module_database), process_id_(0) { | |
| 25 process_id_ = ::GetProcessId(process_); | |
| 26 module_database->OnProcessStarted(process_id_, process_type); | |
| 27 } | |
| 28 | |
| 29 ModuleEventSinkImpl::~ModuleEventSinkImpl() = default; | |
| 30 | |
| 31 // static | |
| 32 void ModuleEventSinkImpl::Create(base::ProcessHandle process, | |
| 33 content::ProcessType process_type, | |
| 34 ModuleDatabase* module_database, | |
| 35 mojom::ModuleEventSinkRequest request) { | |
| 36 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | |
| 37 auto module_event_sink_impl = base::MakeUnique<ModuleEventSinkImpl>( | |
| 38 process, process_type, module_database); | |
| 39 base::Closure error_handler = base::Bind(&ModuleDatabase::OnProcessEnded, | |
| 40 base::Unretained(module_database), | |
| 41 module_event_sink_impl->process_id_); | |
| 42 auto binding = mojo::MakeStrongBinding(std::move(module_event_sink_impl), | |
| 43 std::move(request)); | |
| 44 binding->set_connection_error_handler(error_handler); | |
| 45 } | |
| 46 | |
| 47 void ModuleEventSinkImpl::OnModuleEvent(mojom::ModuleEventType event_type, | |
| 48 uint64_t load_address) { | |
| 49 // Mojo takes care of validating |event_type|, so only |load_address| needs to | |
| 50 // be checked. Load addresses must be aligned with the allocation granularity | |
| 51 // which is at least 64KB on any supported Windows OS. | |
| 52 if (load_address == 0 || load_address % (64 * 1024) != 0) | |
| 53 return; | |
| 54 | |
| 55 switch (event_type) { | |
| 56 case mojom::ModuleEventType::MODULE_ALREADY_LOADED: | |
| 57 case mojom::ModuleEventType::MODULE_LOADED: | |
| 58 return OnModuleLoad(event_type, load_address); | |
| 59 | |
| 60 case mojom::ModuleEventType::MODULE_UNLOADED: | |
| 61 return OnModuleUnload(load_address); | |
| 62 } | |
| 63 } | |
| 64 | |
| 65 void ModuleEventSinkImpl::OnModuleLoad(mojom::ModuleEventType event_type, | |
| 66 uint64_t load_address) { | |
| 67 DCHECK(event_type == mojom::ModuleEventType::MODULE_ALREADY_LOADED || | |
| 68 event_type == mojom::ModuleEventType::MODULE_LOADED); | |
| 69 | |
| 70 // Convert the |load_address| to a module handle. | |
| 71 HMODULE module = | |
| 72 reinterpret_cast<HMODULE>(static_cast<uintptr_t>(load_address)); | |
| 73 | |
| 74 // Get the module path. | |
| 75 wchar_t temp_path[MAX_PATH]; | |
| 76 temp_path[0] = 0; | |
| 77 if (!::GetModuleFileNameEx(process_, module, temp_path, arraysize(temp_path))) | |
| 
 
grt (UTC plus 2)
2016/12/20 21:09:53
MSDN says this truncates the path if the buffer is
 
chrisha
2016/12/21 20:15:00
Done.
 
 | |
| 78 return; | |
| 79 | |
| 80 // Get the module information. | |
| 81 MODULEINFO info = {}; | |
| 82 size_t length = GetModuleInformation(process_, module, &info, sizeof(info)); | |
| 
 
grt (UTC plus 2)
2016/12/20 21:09:53
DWORD |length| should be captured from GetModuleFi
 
chrisha
2016/12/21 20:15:00
Err... oops.
Done.
 
 | |
| 83 if (length == 0) | |
| 84 return; | |
| 85 | |
| 86 // Convert this all to a ModuleEvent and forward this on to the module | |
| 87 // database. | |
| 88 ModuleWatcher::ModuleEvent event( | |
| 89 event_type, base::FilePath(base::StringPiece16(temp_path, length)), | |
| 90 module, info.SizeOfImage); | |
| 91 module_database_->OnModuleEvent(process_id_, event); | |
| 92 } | |
| 93 | |
| 94 void ModuleEventSinkImpl::OnModuleUnload(uint64_t load_address) { | |
| 95 module_database_->OnModuleUnload(process_id_, | |
| 96 static_cast<uintptr_t>(load_address)); | |
| 97 } | |
| OLD | NEW |