Chromium Code Reviews| OLD | NEW |
|---|---|
| 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/browser/conflicts/module_event_sink_impl_win.h" | 5 #include "chrome/browser/conflicts/module_event_sink_impl_win.h" |
| 6 | 6 |
| 7 #include <windows.h> | 7 #include <windows.h> |
| 8 #include <psapi.h> | 8 #include <psapi.h> |
| 9 | 9 |
| 10 #include <utility> | 10 #include <utility> |
| 11 | 11 |
| 12 #include "base/bind.h" | 12 #include "base/bind.h" |
| 13 #include "base/callback.h" | 13 #include "base/callback.h" |
| 14 #include "base/files/file_path.h" | 14 #include "base/files/file_path.h" |
| 15 #include "base/macros.h" | 15 #include "base/macros.h" |
| 16 #include "base/memory/ptr_util.h" | 16 #include "base/memory/ptr_util.h" |
| 17 #include "base/strings/string_piece.h" | 17 #include "base/strings/string_piece.h" |
| 18 #include "chrome/browser/conflicts/module_database_win.h" | 18 #include "chrome/browser/conflicts/module_database_win.h" |
| 19 #include "chrome/common/conflicts/module_watcher_win.h" | 19 #include "chrome/common/conflicts/module_watcher_win.h" |
| 20 #include "content/public/browser/browser_thread.h" | 20 #include "content/public/browser/browser_thread.h" |
| 21 #include "mojo/public/cpp/bindings/strong_binding.h" | 21 #include "mojo/public/cpp/bindings/strong_binding.h" |
| 22 | 22 |
| 23 namespace { | 23 namespace { |
| 24 | 24 |
| 25 // Gets the process creation time associated with the given process. | |
| 26 bool GetProcessCreationTime(base::ProcessHandle process, | |
| 27 uint64_t* creation_time) { | |
| 28 FILETIME creation_ft = {}; | |
| 29 FILETIME exit_ft = {}; | |
| 30 FILETIME kernel_ft = {}; | |
| 31 FILETIME user_ft = {}; | |
| 32 if (!::GetProcessTimes(process, &creation_ft, &exit_ft, &kernel_ft, | |
| 33 &user_ft)) { | |
| 34 return false; | |
| 35 } | |
| 36 *creation_time = (static_cast<uint64_t>(creation_ft.dwHighDateTime) << 32) | | |
| 37 static_cast<uint64_t>(creation_ft.dwLowDateTime); | |
| 38 return true; | |
| 39 } | |
| 40 | |
| 41 // Gets the path of the module in the provided remote process. Returns true on | 25 // Gets the path of the module in the provided remote process. Returns true on |
| 42 // success, false otherwise. | 26 // success, false otherwise. |
| 43 bool GetModulePath(base::ProcessHandle process, | 27 bool GetModulePath(base::ProcessHandle process, |
| 44 HMODULE module, | 28 HMODULE module, |
| 45 base::FilePath* path) { | 29 base::FilePath* path) { |
| 46 std::vector<wchar_t> temp_path(MAX_PATH); | 30 std::vector<wchar_t> temp_path(MAX_PATH); |
| 47 size_t length = 0; | 31 size_t length = 0; |
| 48 while (true) { | 32 while (true) { |
| 49 length = ::GetModuleFileNameEx(process, module, temp_path.data(), | 33 length = ::GetModuleFileNameEx(process, module, temp_path.data(), |
| 50 temp_path.size()); | 34 temp_path.size()); |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 125 if (!GetProcessCreationTime(process_, &creation_time_)) { | 109 if (!GetProcessCreationTime(process_, &creation_time_)) { |
| 126 in_error_ = true; | 110 in_error_ = true; |
| 127 return; | 111 return; |
| 128 } | 112 } |
| 129 module_database->OnProcessStarted(process_id_, creation_time_, process_type); | 113 module_database->OnProcessStarted(process_id_, creation_time_, process_type); |
| 130 } | 114 } |
| 131 | 115 |
| 132 ModuleEventSinkImpl::~ModuleEventSinkImpl() = default; | 116 ModuleEventSinkImpl::~ModuleEventSinkImpl() = default; |
| 133 | 117 |
| 134 // static | 118 // static |
| 135 void ModuleEventSinkImpl::Create(base::ProcessHandle process, | 119 void ModuleEventSinkImpl::Create( |
| 136 content::ProcessType process_type, | 120 const GetProcessHandleCallback& get_process_handle, |
| 137 ModuleDatabase* module_database, | 121 content::ProcessType process_type, |
| 138 mojom::ModuleEventSinkRequest request) { | 122 ModuleDatabase* module_database, |
| 123 mojom::ModuleEventSinkRequest request) { | |
| 139 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 124 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 125 base::ProcessHandle process = get_process_handle.Run(); | |
|
grt (UTC plus 2)
2017/01/06 09:44:58
std::move(get_process_handle).Run() to "consume" t
chrisha
2017/01/10 21:01:46
I'm fine with that, but have never seen it. Is thi
grt (UTC plus 2)
2017/01/11 15:07:54
I found it in https://chromium.googlesource.com/ch
chrisha
2017/01/11 21:14:11
Acknowledged.
| |
| 140 auto module_event_sink_impl = base::MakeUnique<ModuleEventSinkImpl>( | 126 auto module_event_sink_impl = base::MakeUnique<ModuleEventSinkImpl>( |
| 141 process, process_type, module_database); | 127 process, process_type, module_database); |
| 142 base::Closure error_handler = base::Bind( | 128 base::Closure error_handler = base::Bind( |
| 143 &ModuleDatabase::OnProcessEnded, base::Unretained(module_database), | 129 &ModuleDatabase::OnProcessEnded, base::Unretained(module_database), |
| 144 module_event_sink_impl->process_id_, | 130 module_event_sink_impl->process_id_, |
| 145 module_event_sink_impl->creation_time_); | 131 module_event_sink_impl->creation_time_); |
| 146 auto binding = mojo::MakeStrongBinding(std::move(module_event_sink_impl), | 132 auto binding = mojo::MakeStrongBinding(std::move(module_event_sink_impl), |
| 147 std::move(request)); | 133 std::move(request)); |
| 148 binding->set_connection_error_handler(error_handler); | 134 binding->set_connection_error_handler(error_handler); |
| 149 } | 135 } |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 162 switch (event_type) { | 148 switch (event_type) { |
| 163 case mojom::ModuleEventType::MODULE_ALREADY_LOADED: | 149 case mojom::ModuleEventType::MODULE_ALREADY_LOADED: |
| 164 case mojom::ModuleEventType::MODULE_LOADED: | 150 case mojom::ModuleEventType::MODULE_LOADED: |
| 165 return OnModuleLoad(load_address); | 151 return OnModuleLoad(load_address); |
| 166 | 152 |
| 167 case mojom::ModuleEventType::MODULE_UNLOADED: | 153 case mojom::ModuleEventType::MODULE_UNLOADED: |
| 168 return OnModuleUnload(load_address); | 154 return OnModuleUnload(load_address); |
| 169 } | 155 } |
| 170 } | 156 } |
| 171 | 157 |
| 158 // static | |
| 159 bool ModuleEventSinkImpl::GetProcessCreationTime(base::ProcessHandle process, | |
| 160 uint64_t* creation_time) { | |
| 161 FILETIME creation_ft = {}; | |
| 162 FILETIME exit_ft = {}; | |
| 163 FILETIME kernel_ft = {}; | |
| 164 FILETIME user_ft = {}; | |
| 165 if (!::GetProcessTimes(process, &creation_ft, &exit_ft, &kernel_ft, | |
| 166 &user_ft)) { | |
| 167 return false; | |
| 168 } | |
| 169 *creation_time = (static_cast<uint64_t>(creation_ft.dwHighDateTime) << 32) | | |
| 170 static_cast<uint64_t>(creation_ft.dwLowDateTime); | |
| 171 return true; | |
| 172 } | |
| 173 | |
| 172 void ModuleEventSinkImpl::OnModuleLoad(uint64_t load_address) { | 174 void ModuleEventSinkImpl::OnModuleLoad(uint64_t load_address) { |
| 173 if (in_error_) | 175 if (in_error_) |
| 174 return; | 176 return; |
| 175 | 177 |
| 176 // The |load_address| is a unique key to a module in a remote process. If | 178 // The |load_address| is a unique key to a module in a remote process. If |
| 177 // there is a valid module there then the following queries should all pass. | 179 // there is a valid module there then the following queries should all pass. |
| 178 // If any of them fail then the load event is silently swallowed. The entire | 180 // If any of them fail then the load event is silently swallowed. The entire |
| 179 // channel is not marked as being in an error mode, as later events may be | 181 // channel is not marked as being in an error mode, as later events may be |
| 180 // well formed. | 182 // well formed. |
| 181 | 183 |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 201 module_database_->OnModuleLoad(process_id_, creation_time_, module_path, | 203 module_database_->OnModuleLoad(process_id_, creation_time_, module_path, |
| 202 module_size, module_time_date_stamp, | 204 module_size, module_time_date_stamp, |
| 203 load_address); | 205 load_address); |
| 204 } | 206 } |
| 205 | 207 |
| 206 void ModuleEventSinkImpl::OnModuleUnload(uint64_t load_address) { | 208 void ModuleEventSinkImpl::OnModuleUnload(uint64_t load_address) { |
| 207 // Forward this directly to the module database. | 209 // Forward this directly to the module database. |
| 208 module_database_->OnModuleUnload(process_id_, creation_time_, | 210 module_database_->OnModuleUnload(process_id_, creation_time_, |
| 209 static_cast<uintptr_t>(load_address)); | 211 static_cast<uintptr_t>(load_address)); |
| 210 } | 212 } |
| OLD | NEW |