Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(69)

Side by Side Diff: chrome/browser/renderer_host/file_utilities_dispatcher_host.cc

Issue 5698008: Switch a bunch of remaining filters to derive from BrowserMessageFilters so t... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 10 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2010 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/renderer_host/file_utilities_dispatcher_host.h"
6
7 #include "base/file_util.h"
8 #include "base/platform_file.h"
9 #include "chrome/browser/child_process_security_policy.h"
10 #include "chrome/browser/browser_thread.h"
11 #include "chrome/common/render_messages.h"
12 #include "chrome/common/render_messages_params.h"
13
14 namespace {
15
16 void WriteFileSize(IPC::Message* reply_msg,
17 const base::PlatformFileInfo& file_info) {
18 ViewHostMsg_GetFileSize::WriteReplyParams(reply_msg, file_info.size);
19 }
20
21 void WriteFileModificationTime(IPC::Message* reply_msg,
22 const base::PlatformFileInfo& file_info) {
23 ViewHostMsg_GetFileModificationTime::WriteReplyParams(
24 reply_msg, file_info.last_modified);
25 }
26
27 } // namespace
28
29 FileUtilitiesDispatcherHost::FileUtilitiesDispatcherHost(
30 IPC::Message::Sender* sender, int process_id)
31 : message_sender_(sender),
32 process_id_(process_id),
33 process_handle_(0),
34 shutdown_(false) {
35 DCHECK(message_sender_);
36 }
37
38 FileUtilitiesDispatcherHost::~FileUtilitiesDispatcherHost() {
39 }
40
41 void FileUtilitiesDispatcherHost::Init(base::ProcessHandle process_handle) {
42 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
43 DCHECK(!shutdown_);
44 DCHECK(!process_handle_);
45 DCHECK(process_handle);
46 process_handle_ = process_handle;
47 }
48
49 void FileUtilitiesDispatcherHost::Shutdown() {
50 message_sender_ = NULL;
51 shutdown_ = true;
52 }
53
54 bool FileUtilitiesDispatcherHost::OnMessageReceived(
55 const IPC::Message& message) {
56 DCHECK(!shutdown_);
57 bool handled = true;
58 IPC_BEGIN_MESSAGE_MAP(FileUtilitiesDispatcherHost, message)
59 IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_GetFileSize, OnGetFileSize)
60 IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_GetFileModificationTime,
61 OnGetFileModificationTime)
62 IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_OpenFile, OnOpenFile)
63 IPC_MESSAGE_UNHANDLED((handled = false))
64 IPC_END_MESSAGE_MAP()
65 return handled;
66 }
67
68 void FileUtilitiesDispatcherHost::OnGetFileSize(
69 const FilePath& path, IPC::Message* reply_msg) {
70 // Get file size only when the child process has been granted permission to
71 // upload the file.
72 if (!ChildProcessSecurityPolicy::GetInstance()->CanReadFile(
73 process_id_, path)) {
74 ViewHostMsg_GetFileSize::WriteReplyParams(
75 reply_msg, static_cast<int64>(-1));
76 Send(reply_msg);
77 return;
78 }
79
80 // Getting file size could take long time if it lives on a network share,
81 // so run it on FILE thread.
82 BrowserThread::PostTask(
83 BrowserThread::FILE, FROM_HERE,
84 NewRunnableMethod(
85 this, &FileUtilitiesDispatcherHost::OnGetFileInfoOnFileThread, path,
86 reply_msg, &WriteFileSize));
87 }
88
89 void FileUtilitiesDispatcherHost::OnGetFileModificationTime(
90 const FilePath& path, IPC::Message* reply_msg) {
91 // Get file modification time only when the child process has been granted
92 // permission to upload the file.
93 if (!ChildProcessSecurityPolicy::GetInstance()->CanReadFile(
94 process_id_, path)) {
95 ViewHostMsg_GetFileModificationTime::WriteReplyParams(reply_msg,
96 base::Time());
97 Send(reply_msg);
98 return;
99 }
100
101 // Getting file modification time could take a long time if it lives on a
102 // network share, so run it on the FILE thread.
103 BrowserThread::PostTask(
104 BrowserThread::FILE, FROM_HERE,
105 NewRunnableMethod(
106 this, &FileUtilitiesDispatcherHost::OnGetFileInfoOnFileThread,
107 path, reply_msg, &WriteFileModificationTime));
108 }
109
110 void FileUtilitiesDispatcherHost::OnGetFileInfoOnFileThread(
111 const FilePath& path,
112 IPC::Message* reply_msg,
113 FileInfoWriteFunc write_func) {
114 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
115
116 base::PlatformFileInfo file_info;
117 file_info.size = 0;
118 file_util::GetFileInfo(path, &file_info);
119
120 (*write_func)(reply_msg, file_info);
121
122 BrowserThread::PostTask(
123 BrowserThread::IO, FROM_HERE,
124 NewRunnableMethod(this, &FileUtilitiesDispatcherHost::Send, reply_msg));
125 }
126
127 void FileUtilitiesDispatcherHost::OnOpenFile(
128 const FilePath& path, int mode, IPC::Message* reply_msg) {
129 // Open the file only when the child process has been granted permission to
130 // upload the file.
131 // TODO(jianli): Do we need separate permission to control opening the file?
132 if (!ChildProcessSecurityPolicy::GetInstance()->CanReadFile(
133 process_id_, path)) {
134 ViewHostMsg_OpenFile::WriteReplyParams(
135 reply_msg,
136 #if defined(OS_WIN)
137 base::kInvalidPlatformFileValue
138 #elif defined(OS_POSIX)
139 base::FileDescriptor(base::kInvalidPlatformFileValue, true)
140 #endif
141 );
142 Send(reply_msg);
143 return;
144 }
145
146 // Opening the file could take a long time if it lives on a network share,
147 // so run it on the FILE thread.
148 BrowserThread::PostTask(
149 BrowserThread::FILE, FROM_HERE,
150 NewRunnableMethod(
151 this, &FileUtilitiesDispatcherHost::OnOpenFileOnFileThread,
152 path, mode, reply_msg));
153 }
154
155 void FileUtilitiesDispatcherHost::OnOpenFileOnFileThread(
156 const FilePath& path, int mode, IPC::Message* reply_msg) {
157 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
158
159 base::PlatformFile file_handle = base::CreatePlatformFile(
160 path,
161 (mode == 0) ? (base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ)
162 : (base::PLATFORM_FILE_CREATE_ALWAYS |
163 base::PLATFORM_FILE_WRITE),
164 NULL, NULL);
165
166 base::PlatformFile target_file_handle;
167 #if defined(OS_WIN)
168 // Duplicate the file handle so that the renderer process can access the file.
169 if (!DuplicateHandle(GetCurrentProcess(), file_handle,
170 process_handle_, &target_file_handle, 0, false,
171 DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) {
172 // file_handle is closed whether or not DuplicateHandle succeeds.
173 target_file_handle = INVALID_HANDLE_VALUE;
174 }
175 #else
176 target_file_handle = file_handle;
177 #endif
178
179 ViewHostMsg_OpenFile::WriteReplyParams(
180 reply_msg,
181 #if defined(OS_WIN)
182 target_file_handle
183 #elif defined(OS_POSIX)
184 base::FileDescriptor(target_file_handle, true)
185 #endif
186 );
187
188 BrowserThread::PostTask(
189 BrowserThread::IO, FROM_HERE,
190 NewRunnableMethod(this, &FileUtilitiesDispatcherHost::Send, reply_msg));
191 }
192
193 void FileUtilitiesDispatcherHost::Send(IPC::Message* message) {
194 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
195 if (!shutdown_ && message_sender_)
196 message_sender_->Send(message);
197 else
198 delete message;
199 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698