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