Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright (c) 2012 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/nacl_host/pnacl_file_host.h" | |
| 6 | |
| 7 #include <stdio.h> | |
| 8 | |
| 9 #include "base/bind.h" | |
| 10 #include "base/memory/ref_counted.h" | |
| 11 #include "base/path_service.h" | |
| 12 #include "chrome/common/chrome_paths.h" | |
| 13 #include "chrome/common/render_messages.h" | |
| 14 #include "chrome/browser/renderer_host/chrome_render_message_filter.h" | |
| 15 #include "content/public/browser/browser_thread.h" | |
| 16 #include "native_client/src/shared/imc/nacl_imc.h" | |
| 17 | |
| 18 using content::BrowserThread; | |
| 19 | |
| 20 namespace { | |
| 21 | |
| 22 // Need the DuplicateHandle good to send the handle over to the | |
| 23 // plugin process. | |
| 24 // TODO(jvoung): share some code with nacl_process_host if possible. | |
| 25 bool SendHandleToNaClPlugin( | |
| 26 base::ProcessHandle target_processh, | |
| 27 nacl::Handle sourceh, | |
| 28 bool close_source, | |
| 29 nacl::FileDescriptor* handle_for_plugin) { | |
| 30 #if defined(OS_WIN) | |
| 31 HANDLE channel; | |
| 32 int flags = DUPLICATE_SAME_ACCESS; | |
| 33 if (close_source) | |
| 34 flags |= DUPLICATE_CLOSE_SOURCE; | |
| 35 if (!DuplicateHandle(GetCurrentProcess(), | |
| 36 reinterpret_cast<HANDLE>(sourceh), | |
| 37 target_processh, | |
| 38 &channel, | |
| 39 0, // Unused given DUPLICATE_SAME_ACCESS. | |
| 40 FALSE, | |
| 41 flags)) { | |
| 42 LOG(ERROR) << "DuplicateHandle() failed"; | |
| 43 return false; | |
| 44 } | |
| 45 *handle_for_plugin = reinterpret_cast<nacl::FileDescriptor>(channel); | |
| 46 #else | |
| 47 nacl::FileDescriptor channel; | |
| 48 channel.fd = sourceh; | |
| 49 channel.auto_close = close_source; | |
| 50 *handle_for_plugin = channel; | |
| 51 #endif | |
| 52 return true; | |
| 53 } | |
| 54 | |
| 55 void NotifyRendererOfError( | |
| 56 ChromeRenderMessageFilter* chrome_render_message_filter, | |
| 57 IPC::Message* reply_msg) { | |
| 58 reply_msg->set_reply_error(); | |
| 59 chrome_render_message_filter->Send(reply_msg); | |
| 60 } | |
| 61 | |
| 62 } // namespace | |
| 63 | |
| 64 namespace pnacl_file_host { | |
| 65 | |
| 66 // This only ever runs on the BrowserThread::FILE thread. | |
| 67 void DoOpenPnaclFile(ChromeRenderMessageFilter* chrome_render_message_filter, | |
| 68 const std::string& filename, | |
| 69 IPC::Message* reply_msg); | |
| 70 | |
| 71 | |
| 72 void GetReadonlyPnaclFd( | |
| 73 ChromeRenderMessageFilter* chrome_render_message_filter, | |
| 74 const std::string& filename, | |
| 75 IPC::Message* reply_msg) { | |
| 76 fprintf(stderr, "In GetReadonlyPnaclFd: %s\n", filename.c_str()); | |
| 77 | |
| 78 if (!BrowserThread::PostTask( | |
| 79 BrowserThread::FILE, FROM_HERE, | |
| 80 base::Bind(&DoOpenPnaclFile, | |
| 81 make_scoped_refptr(chrome_render_message_filter), | |
| 82 filename, | |
| 83 reply_msg))) { | |
| 84 NotifyRendererOfError(chrome_render_message_filter, reply_msg); | |
| 85 } | |
| 86 } | |
| 87 | |
| 88 void DoOpenPnaclFile( | |
| 89 ChromeRenderMessageFilter* chrome_render_message_filter, | |
| 90 const std::string& filename, | |
| 91 IPC::Message* reply_msg) { | |
| 92 FilePath filepath; | |
| 93 FilePath pnacl_dir; | |
| 94 base::PlatformFile file_to_open; | |
| 95 | |
| 96 // Do some validation. | |
| 97 // The file must use only ASCII characters. | |
| 98 if (!IsStringASCII(filename)) { | |
| 99 LOG(ERROR) << "Cannot open non-ASCII pnacl files."; | |
| 100 NotifyRendererOfError(chrome_render_message_filter, reply_msg); | |
| 101 return; | |
| 102 } | |
| 103 | |
| 104 #if defined(OS_WIN) | |
| 105 FilePath file_to_find(ASCIIToUTF16(filename)); | |
| 106 #elif defined(OS_POSIX) | |
| 107 FilePath file_to_find(filename); | |
| 108 #endif | |
| 109 | |
| 110 // Disallow peeking outside of the pnacl component directory. | |
| 111 if (file_to_find.ReferencesParent() || file_to_find.IsAbsolute()) { | |
| 112 LOG(ERROR) << "Cannot open a pnacl file referencing a parent dir, etc."; | |
| 113 NotifyRendererOfError(chrome_render_message_filter, reply_msg); | |
| 114 return; | |
| 115 } | |
| 116 | |
| 117 if (!PathService::Get(chrome::DIR_PNACL_COMPONENT, &pnacl_dir)) { | |
| 118 LOG(ERROR) << "Failed to locate the pnacl install directory"; | |
| 119 NotifyRendererOfError(chrome_render_message_filter, reply_msg); | |
| 120 return; | |
| 121 } | |
| 122 | |
| 123 filepath = pnacl_dir.Append(file_to_find); | |
| 124 | |
| 125 fprintf(stderr, "In DoOpenPnaclFile: %s\n", filepath.MaybeAsASCII().c_str()); | |
| 126 | |
| 127 base::PlatformFileError error_code; | |
| 128 file_to_open = base::CreatePlatformFile(filepath, | |
|
Mark Seaborn
2012/02/26 21:02:44
I would expect that won't work properly with autou
| |
| 129 base::PLATFORM_FILE_OPEN | | |
| 130 base::PLATFORM_FILE_READ | | |
| 131 base::PLATFORM_FILE_SHARE_DELETE, | |
| 132 NULL, | |
| 133 &error_code); | |
| 134 if (error_code != base::PLATFORM_FILE_OK) { | |
| 135 LOG(ERROR) << "Failed to open Pnacl file \"" | |
| 136 << filepath.LossyDisplayName() | |
| 137 << "\": " << error_code; | |
| 138 NotifyRendererOfError(chrome_render_message_filter, reply_msg); | |
| 139 return; | |
| 140 } | |
| 141 | |
| 142 // Send the reply! | |
| 143 // Do any DuplicateHandle magic that is necessary first. | |
| 144 nacl::FileDescriptor target_desc; | |
| 145 SendHandleToNaClPlugin(chrome_render_message_filter->peer_handle(), | |
| 146 file_to_open, | |
| 147 true /* Close source */, | |
| 148 &target_desc); | |
| 149 ChromeViewHostMsg_GetReadonlyPnaclFD::WriteReplyParams( | |
| 150 reply_msg, target_desc); | |
| 151 chrome_render_message_filter->Send(reply_msg); | |
| 152 } | |
| 153 | |
| 154 } | |
| OLD | NEW |