Add ICU message format support
[chromium-blink-merge.git] / sandbox / win / src / filesystem_dispatcher.cc
blobd4ef79637c8578b5e4c99abee448dfcfbb5a618b
1 // Copyright (c) 2006-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.
5 #include "sandbox/win/src/filesystem_dispatcher.h"
7 #include "sandbox/win/src/crosscall_client.h"
8 #include "sandbox/win/src/filesystem_interception.h"
9 #include "sandbox/win/src/filesystem_policy.h"
10 #include "sandbox/win/src/interception.h"
11 #include "sandbox/win/src/interceptors.h"
12 #include "sandbox/win/src/ipc_tags.h"
13 #include "sandbox/win/src/policy_broker.h"
14 #include "sandbox/win/src/policy_params.h"
15 #include "sandbox/win/src/sandbox.h"
16 #include "sandbox/win/src/sandbox_nt_util.h"
18 namespace sandbox {
20 FilesystemDispatcher::FilesystemDispatcher(PolicyBase* policy_base)
21 : policy_base_(policy_base) {
22 static const IPCCall create_params = {
23 {IPC_NTCREATEFILE_TAG,
24 {WCHAR_TYPE,
25 UINT32_TYPE,
26 UINT32_TYPE,
27 UINT32_TYPE,
28 UINT32_TYPE,
29 UINT32_TYPE,
30 UINT32_TYPE}},
31 reinterpret_cast<CallbackGeneric>(&FilesystemDispatcher::NtCreateFile)};
33 static const IPCCall open_file = {
34 {IPC_NTOPENFILE_TAG,
35 {WCHAR_TYPE, UINT32_TYPE, UINT32_TYPE, UINT32_TYPE, UINT32_TYPE}},
36 reinterpret_cast<CallbackGeneric>(&FilesystemDispatcher::NtOpenFile)};
38 static const IPCCall attribs = {
39 {IPC_NTQUERYATTRIBUTESFILE_TAG, {WCHAR_TYPE, UINT32_TYPE, INOUTPTR_TYPE}},
40 reinterpret_cast<CallbackGeneric>(
41 &FilesystemDispatcher::NtQueryAttributesFile)};
43 static const IPCCall full_attribs = {
44 {IPC_NTQUERYFULLATTRIBUTESFILE_TAG,
45 {WCHAR_TYPE, UINT32_TYPE, INOUTPTR_TYPE}},
46 reinterpret_cast<CallbackGeneric>(
47 &FilesystemDispatcher::NtQueryFullAttributesFile)};
49 static const IPCCall set_info = {
50 {IPC_NTSETINFO_RENAME_TAG,
51 {VOIDPTR_TYPE, INOUTPTR_TYPE, INOUTPTR_TYPE, UINT32_TYPE, UINT32_TYPE}},
52 reinterpret_cast<CallbackGeneric>(
53 &FilesystemDispatcher::NtSetInformationFile)};
55 ipc_calls_.push_back(create_params);
56 ipc_calls_.push_back(open_file);
57 ipc_calls_.push_back(attribs);
58 ipc_calls_.push_back(full_attribs);
59 ipc_calls_.push_back(set_info);
62 bool FilesystemDispatcher::SetupService(InterceptionManager* manager,
63 int service) {
64 switch (service) {
65 case IPC_NTCREATEFILE_TAG:
66 return INTERCEPT_NT(manager, NtCreateFile, CREATE_FILE_ID, 48);
68 case IPC_NTOPENFILE_TAG:
69 return INTERCEPT_NT(manager, NtOpenFile, OPEN_FILE_ID, 28);
71 case IPC_NTQUERYATTRIBUTESFILE_TAG:
72 return INTERCEPT_NT(manager, NtQueryAttributesFile, QUERY_ATTRIB_FILE_ID,
73 12);
75 case IPC_NTQUERYFULLATTRIBUTESFILE_TAG:
76 return INTERCEPT_NT(manager, NtQueryFullAttributesFile,
77 QUERY_FULL_ATTRIB_FILE_ID, 12);
79 case IPC_NTSETINFO_RENAME_TAG:
80 return INTERCEPT_NT(manager, NtSetInformationFile, SET_INFO_FILE_ID, 24);
82 default:
83 return false;
87 bool FilesystemDispatcher::NtCreateFile(IPCInfo* ipc,
88 base::string16* name,
89 uint32 attributes,
90 uint32 desired_access,
91 uint32 file_attributes,
92 uint32 share_access,
93 uint32 create_disposition,
94 uint32 create_options) {
95 if (!PreProcessName(name)) {
96 // The path requested might contain a reparse point.
97 ipc->return_info.nt_status = STATUS_ACCESS_DENIED;
98 return true;
101 const wchar_t* filename = name->c_str();
103 uint32 broker = TRUE;
104 CountedParameterSet<OpenFile> params;
105 params[OpenFile::NAME] = ParamPickerMake(filename);
106 params[OpenFile::ACCESS] = ParamPickerMake(desired_access);
107 params[OpenFile::DISPOSITION] = ParamPickerMake(create_disposition);
108 params[OpenFile::OPTIONS] = ParamPickerMake(create_options);
109 params[OpenFile::BROKER] = ParamPickerMake(broker);
111 // To evaluate the policy we need to call back to the policy object. We
112 // are just middlemen in the operation since is the FileSystemPolicy which
113 // knows what to do.
114 EvalResult result = policy_base_->EvalPolicy(IPC_NTCREATEFILE_TAG,
115 params.GetBase());
116 HANDLE handle;
117 ULONG_PTR io_information = 0;
118 NTSTATUS nt_status;
119 if (!FileSystemPolicy::CreateFileAction(result, *ipc->client_info, *name,
120 attributes, desired_access,
121 file_attributes, share_access,
122 create_disposition, create_options,
123 &handle, &nt_status,
124 &io_information)) {
125 ipc->return_info.nt_status = STATUS_ACCESS_DENIED;
126 return true;
128 // Return operation status on the IPC.
129 ipc->return_info.extended[0].ulong_ptr = io_information;
130 ipc->return_info.nt_status = nt_status;
131 ipc->return_info.handle = handle;
132 return true;
135 bool FilesystemDispatcher::NtOpenFile(IPCInfo* ipc,
136 base::string16* name,
137 uint32 attributes,
138 uint32 desired_access,
139 uint32 share_access,
140 uint32 open_options) {
141 if (!PreProcessName(name)) {
142 // The path requested might contain a reparse point.
143 ipc->return_info.nt_status = STATUS_ACCESS_DENIED;
144 return true;
147 const wchar_t* filename = name->c_str();
149 uint32 broker = TRUE;
150 uint32 create_disposition = FILE_OPEN;
151 CountedParameterSet<OpenFile> params;
152 params[OpenFile::NAME] = ParamPickerMake(filename);
153 params[OpenFile::ACCESS] = ParamPickerMake(desired_access);
154 params[OpenFile::DISPOSITION] = ParamPickerMake(create_disposition);
155 params[OpenFile::OPTIONS] = ParamPickerMake(open_options);
156 params[OpenFile::BROKER] = ParamPickerMake(broker);
158 // To evaluate the policy we need to call back to the policy object. We
159 // are just middlemen in the operation since is the FileSystemPolicy which
160 // knows what to do.
161 EvalResult result = policy_base_->EvalPolicy(IPC_NTOPENFILE_TAG,
162 params.GetBase());
163 HANDLE handle;
164 ULONG_PTR io_information = 0;
165 NTSTATUS nt_status;
166 if (!FileSystemPolicy::OpenFileAction(result, *ipc->client_info, *name,
167 attributes, desired_access,
168 share_access, open_options, &handle,
169 &nt_status, &io_information)) {
170 ipc->return_info.nt_status = STATUS_ACCESS_DENIED;
171 return true;
173 // Return operation status on the IPC.
174 ipc->return_info.extended[0].ulong_ptr = io_information;
175 ipc->return_info.nt_status = nt_status;
176 ipc->return_info.handle = handle;
177 return true;
180 bool FilesystemDispatcher::NtQueryAttributesFile(IPCInfo* ipc,
181 base::string16* name,
182 uint32 attributes,
183 CountedBuffer* info) {
184 if (sizeof(FILE_BASIC_INFORMATION) != info->Size())
185 return false;
187 if (!PreProcessName(name)) {
188 // The path requested might contain a reparse point.
189 ipc->return_info.nt_status = STATUS_ACCESS_DENIED;
190 return true;
193 uint32 broker = TRUE;
194 const wchar_t* filename = name->c_str();
195 CountedParameterSet<FileName> params;
196 params[FileName::NAME] = ParamPickerMake(filename);
197 params[FileName::BROKER] = ParamPickerMake(broker);
199 // To evaluate the policy we need to call back to the policy object. We
200 // are just middlemen in the operation since is the FileSystemPolicy which
201 // knows what to do.
202 EvalResult result = policy_base_->EvalPolicy(IPC_NTQUERYATTRIBUTESFILE_TAG,
203 params.GetBase());
205 FILE_BASIC_INFORMATION* information =
206 reinterpret_cast<FILE_BASIC_INFORMATION*>(info->Buffer());
207 NTSTATUS nt_status;
208 if (!FileSystemPolicy::QueryAttributesFileAction(result, *ipc->client_info,
209 *name, attributes,
210 information, &nt_status)) {
211 ipc->return_info.nt_status = STATUS_ACCESS_DENIED;
212 return true;
215 // Return operation status on the IPC.
216 ipc->return_info.nt_status = nt_status;
217 return true;
220 bool FilesystemDispatcher::NtQueryFullAttributesFile(IPCInfo* ipc,
221 base::string16* name,
222 uint32 attributes,
223 CountedBuffer* info) {
224 if (sizeof(FILE_NETWORK_OPEN_INFORMATION) != info->Size())
225 return false;
227 if (!PreProcessName(name)) {
228 // The path requested might contain a reparse point.
229 ipc->return_info.nt_status = STATUS_ACCESS_DENIED;
230 return true;
233 uint32 broker = TRUE;
234 const wchar_t* filename = name->c_str();
235 CountedParameterSet<FileName> params;
236 params[FileName::NAME] = ParamPickerMake(filename);
237 params[FileName::BROKER] = ParamPickerMake(broker);
239 // To evaluate the policy we need to call back to the policy object. We
240 // are just middlemen in the operation since is the FileSystemPolicy which
241 // knows what to do.
242 EvalResult result = policy_base_->EvalPolicy(
243 IPC_NTQUERYFULLATTRIBUTESFILE_TAG, params.GetBase());
245 FILE_NETWORK_OPEN_INFORMATION* information =
246 reinterpret_cast<FILE_NETWORK_OPEN_INFORMATION*>(info->Buffer());
247 NTSTATUS nt_status;
248 if (!FileSystemPolicy::QueryFullAttributesFileAction(result,
249 *ipc->client_info,
250 *name, attributes,
251 information,
252 &nt_status)) {
253 ipc->return_info.nt_status = STATUS_ACCESS_DENIED;
254 return true;
257 // Return operation status on the IPC.
258 ipc->return_info.nt_status = nt_status;
259 return true;
262 bool FilesystemDispatcher::NtSetInformationFile(IPCInfo* ipc,
263 HANDLE handle,
264 CountedBuffer* status,
265 CountedBuffer* info,
266 uint32 length,
267 uint32 info_class) {
268 if (sizeof(IO_STATUS_BLOCK) != status->Size())
269 return false;
270 if (length != info->Size())
271 return false;
273 FILE_RENAME_INFORMATION* rename_info =
274 reinterpret_cast<FILE_RENAME_INFORMATION*>(info->Buffer());
276 if (!IsSupportedRenameCall(rename_info, length, info_class))
277 return false;
279 base::string16 name;
280 name.assign(rename_info->FileName, rename_info->FileNameLength /
281 sizeof(rename_info->FileName[0]));
282 if (!PreProcessName(&name)) {
283 // The path requested might contain a reparse point.
284 ipc->return_info.nt_status = STATUS_ACCESS_DENIED;
285 return true;
288 uint32 broker = TRUE;
289 const wchar_t* filename = name.c_str();
290 CountedParameterSet<FileName> params;
291 params[FileName::NAME] = ParamPickerMake(filename);
292 params[FileName::BROKER] = ParamPickerMake(broker);
294 // To evaluate the policy we need to call back to the policy object. We
295 // are just middlemen in the operation since is the FileSystemPolicy which
296 // knows what to do.
297 EvalResult result = policy_base_->EvalPolicy(IPC_NTSETINFO_RENAME_TAG,
298 params.GetBase());
300 IO_STATUS_BLOCK* io_status =
301 reinterpret_cast<IO_STATUS_BLOCK*>(status->Buffer());
302 NTSTATUS nt_status;
303 if (!FileSystemPolicy::SetInformationFileAction(result, *ipc->client_info,
304 handle, rename_info, length,
305 info_class, io_status,
306 &nt_status)) {
307 ipc->return_info.nt_status = STATUS_ACCESS_DENIED;
308 return true;
311 // Return operation status on the IPC.
312 ipc->return_info.nt_status = nt_status;
313 return true;
316 } // namespace sandbox