1 // Copyright 2019 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/chrome_cleaner/engines/broker/engine_file_requests_impl.h"
6
7 #include <map>
8 #include <string>
9 #include <utility>
10
11 #include "base/callback.h"
12 #include "base/strings/string_number_conversions.h"
13 #include "base/strings/utf_string_conversions.h"
14 #include "base/task/post_task.h"
15 #include "base/task/thread_pool.h"
16 #include "chrome/chrome_cleaner/engines/broker/scanner_sandbox_interface.h"
17
18 namespace chrome_cleaner {
19
20 namespace {
21
FindDataToMojoStruct(LPWIN32_FIND_DATAW data)22 mojom::FindFileDataPtr FindDataToMojoStruct(LPWIN32_FIND_DATAW data) {
23 auto find_data_ptr = mojom::FindFileData::New();
24 find_data_ptr->data.resize(sizeof(WIN32_FIND_DATAW));
25 memcpy(find_data_ptr->data.data(), data, sizeof(WIN32_FIND_DATAW));
26
27 return find_data_ptr;
28 }
29
30 } // namespace
31
32 // TODO(joenotcharles): Log the parameters of all the calls on this file.
EngineFileRequestsImpl(scoped_refptr<MojoTaskRunner> mojo_task_runner,InterfaceMetadataObserver * metadata_observer)33 EngineFileRequestsImpl::EngineFileRequestsImpl(
34 scoped_refptr<MojoTaskRunner> mojo_task_runner,
35 InterfaceMetadataObserver* metadata_observer)
36 : mojo_task_runner_(mojo_task_runner),
37 metadata_observer_(metadata_observer) {}
38
Bind(mojo::PendingAssociatedRemote<mojom::EngineFileRequests> * remote)39 void EngineFileRequestsImpl::Bind(
40 mojo::PendingAssociatedRemote<mojom::EngineFileRequests>* remote) {
41 receiver_.reset();
42
43 receiver_.Bind(remote->InitWithNewEndpointAndPassReceiver());
44 // There's no need to call set_disconnect_handler on this since it's an
45 // associated interface. Any errors will be handled on the main EngineCommands
46 // interface.
47 }
48
49 EngineFileRequestsImpl::~EngineFileRequestsImpl() = default;
50
SandboxFindFirstFile(const base::FilePath & file_name,SandboxFindFirstFileCallback result_callback)51 void EngineFileRequestsImpl::SandboxFindFirstFile(
52 const base::FilePath& file_name,
53 SandboxFindFirstFileCallback result_callback) {
54 // Execute the request off of the Mojo thread to unblock it for other calls.
55 base::ThreadPool::PostTask(
56 FROM_HERE, {base::MayBlock()},
57 base::BindOnce(&EngineFileRequestsImpl::FindFirstFile,
58 base::Unretained(this), file_name,
59 std::move(result_callback)));
60 }
61
FindFirstFile(const base::FilePath & file_name,SandboxFindFirstFileCallback result_callback)62 void EngineFileRequestsImpl::FindFirstFile(
63 const base::FilePath& file_name,
64 SandboxFindFirstFileCallback result_callback) {
65 WIN32_FIND_DATAW find_file_data;
66 HANDLE handle;
67 uint32_t result = chrome_cleaner_sandbox::SandboxFindFirstFile(
68 file_name, &find_file_data, &handle);
69 if (metadata_observer_) {
70 std::map<std::string, std::string> arguments = {
71 {"file_name", base::WideToUTF8(file_name.value())},
72 {"result", base::NumberToString(result)},
73 {"handle", base::NumberToString(reinterpret_cast<size_t>(handle))},
74 };
75 metadata_observer_->ObserveCall(CURRENT_FILE_AND_METHOD, arguments);
76 }
77
78 auto find_data_ptr = FindDataToMojoStruct(&find_file_data);
79
80 auto find_handle_ptr = mojom::FindHandle::New();
81 find_handle_ptr->find_handle =
82 reinterpret_cast<int64_t>(HandleToHandle64(handle));
83
84 // Execute the result callback on the Mojo thread.
85 mojo_task_runner_->PostTask(
86 FROM_HERE,
87 base::BindOnce(std::move(result_callback), result,
88 std::move(find_data_ptr), std::move(find_handle_ptr)));
89 }
90
SandboxFindNextFile(mojom::FindHandlePtr handle_ptr,SandboxFindNextFileCallback result_callback)91 void EngineFileRequestsImpl::SandboxFindNextFile(
92 mojom::FindHandlePtr handle_ptr,
93 SandboxFindNextFileCallback result_callback) {
94 base::ThreadPool::PostTask(
95 FROM_HERE, {base::MayBlock()},
96 base::BindOnce(&EngineFileRequestsImpl::FindNextFile,
97 base::Unretained(this), std::move(handle_ptr),
98 std::move(result_callback)));
99 }
100
FindNextFile(mojom::FindHandlePtr handle_ptr,SandboxFindNextFileCallback result_callback)101 void EngineFileRequestsImpl::FindNextFile(
102 mojom::FindHandlePtr handle_ptr,
103 SandboxFindNextFileCallback result_callback) {
104 HANDLE handle =
105 Handle64ToHandle(reinterpret_cast<void*>(handle_ptr->find_handle));
106 WIN32_FIND_DATAW find_file_data;
107 uint32_t result =
108 chrome_cleaner_sandbox::SandboxFindNextFile(handle, &find_file_data);
109 if (metadata_observer_) {
110 std::map<std::string, std::string> arguments = {
111 {"result", base::NumberToString(result)},
112 {"handle", base::NumberToString(reinterpret_cast<size_t>(handle))},
113 };
114 metadata_observer_->ObserveCall(CURRENT_FILE_AND_METHOD, arguments);
115 }
116
117 auto find_data_ptr = FindDataToMojoStruct(&find_file_data);
118
119 mojo_task_runner_->PostTask(FROM_HERE,
120 base::BindOnce(std::move(result_callback), result,
121 std::move(find_data_ptr)));
122 }
123
SandboxFindClose(mojom::FindHandlePtr handle_ptr,SandboxFindCloseCallback result_callback)124 void EngineFileRequestsImpl::SandboxFindClose(
125 mojom::FindHandlePtr handle_ptr,
126 SandboxFindCloseCallback result_callback) {
127 base::ThreadPool::PostTask(
128 FROM_HERE, {base::MayBlock()},
129 base::BindOnce(&EngineFileRequestsImpl::FindClose, base::Unretained(this),
130 std::move(handle_ptr), std::move(result_callback)));
131 }
132
FindClose(mojom::FindHandlePtr handle_ptr,SandboxFindCloseCallback result_callback)133 void EngineFileRequestsImpl::FindClose(
134 mojom::FindHandlePtr handle_ptr,
135 SandboxFindCloseCallback result_callback) {
136 HANDLE handle =
137 Handle64ToHandle(reinterpret_cast<void*>(handle_ptr->find_handle));
138 uint32_t result = chrome_cleaner_sandbox::SandboxFindClose(handle);
139 if (metadata_observer_) {
140 std::map<std::string, std::string> arguments = {
141 {"result", base::NumberToString(result)},
142 {"handle", base::NumberToString(reinterpret_cast<size_t>(handle))},
143 };
144 metadata_observer_->ObserveCall(CURRENT_FILE_AND_METHOD, arguments);
145 }
146
147 mojo_task_runner_->PostTask(
148 FROM_HERE, base::BindOnce(std::move(result_callback), result));
149 }
150
SandboxOpenReadOnlyFile(const base::FilePath & file_name,uint32_t dwFlagsAndAttribute,SandboxOpenReadOnlyFileCallback result_callback)151 void EngineFileRequestsImpl::SandboxOpenReadOnlyFile(
152 const base::FilePath& file_name,
153 uint32_t dwFlagsAndAttribute,
154 SandboxOpenReadOnlyFileCallback result_callback) {
155 base::ThreadPool::PostTask(
156 FROM_HERE, {base::MayBlock()},
157 base::BindOnce(&EngineFileRequestsImpl::OpenReadOnlyFile,
158 base::Unretained(this), file_name, dwFlagsAndAttribute,
159 std::move(result_callback)));
160 }
161
OpenReadOnlyFile(const base::FilePath & file_name,uint32_t dwFlagsAndAttribute,SandboxOpenReadOnlyFileCallback result_callback)162 void EngineFileRequestsImpl::OpenReadOnlyFile(
163 const base::FilePath& file_name,
164 uint32_t dwFlagsAndAttribute,
165 SandboxOpenReadOnlyFileCallback result_callback) {
166 if (metadata_observer_)
167 metadata_observer_->ObserveCall(CURRENT_FILE_AND_METHOD);
168 base::win::ScopedHandle handle =
169 chrome_cleaner_sandbox::SandboxOpenReadOnlyFile(file_name,
170 dwFlagsAndAttribute);
171 mojo_task_runner_->PostTask(
172 FROM_HERE, base::BindOnce(std::move(result_callback),
173 mojo::PlatformHandle(std::move(handle))));
174 }
175
176 } // namespace chrome_cleaner
177