| OLD | NEW | 
|---|
|  | (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 } |  | 
| OLD | NEW | 
|---|