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 |