• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "ppapi/proxy/flash_file_resource.h"
6 
7 #include "base/files/file_path.h"
8 #include "ipc/ipc_message.h"
9 #include "ppapi/c/pp_errors.h"
10 #include "ppapi/proxy/ppapi_messages.h"
11 #include "ppapi/shared_impl/file_type_conversion.h"
12 #include "ppapi/shared_impl/scoped_pp_var.h"
13 #include "ppapi/shared_impl/time_conversion.h"
14 #include "ppapi/shared_impl/var.h"
15 #include "ppapi/thunk/enter.h"
16 #include "ppapi/thunk/ppb_file_ref_api.h"
17 
18 namespace ppapi {
19 namespace proxy {
20 
21 namespace {
22 
23 // Returns the path that a PPB_FileRef resource references as long as it is an
24 // PP_FILESYSTEMTYPE_EXTERNAL path. Returns an empty string on error.
GetPathFromFileRef(PP_Resource file_ref)25 std::string GetPathFromFileRef(PP_Resource file_ref) {
26   thunk::EnterResourceNoLock<thunk::PPB_FileRef_API> enter(file_ref, true);
27   if (enter.failed())
28     return std::string();
29   if (enter.object()->GetFileSystemType() != PP_FILESYSTEMTYPE_EXTERNAL)
30     return std::string();
31   ScopedPPVar var(ScopedPPVar::PassRef(), enter.object()->GetAbsolutePath());
32   StringVar* string_var = StringVar::FromPPVar(var.get());
33   if (!string_var)
34     return std::string();
35   return string_var->value();
36 }
37 
38 }  // namespace
39 
FlashFileResource(Connection connection,PP_Instance instance)40 FlashFileResource::FlashFileResource(Connection connection,
41                                      PP_Instance instance)
42     : PluginResource(connection, instance) {
43   SendCreate(BROWSER, PpapiHostMsg_FlashFile_Create());
44 }
45 
~FlashFileResource()46 FlashFileResource::~FlashFileResource() {
47 }
48 
AsPPB_Flash_File_API()49 thunk::PPB_Flash_File_API* FlashFileResource::AsPPB_Flash_File_API() {
50   return this;
51 }
52 
OpenFile(PP_Instance,const char * path,int32_t mode,PP_FileHandle * file)53 int32_t FlashFileResource::OpenFile(PP_Instance /*instance*/,
54                                     const char* path,
55                                     int32_t mode,
56                                     PP_FileHandle* file) {
57   return OpenFileHelper(path, PepperFilePath::DOMAIN_MODULE_LOCAL, mode, file);
58 }
59 
RenameFile(PP_Instance,const char * path_from,const char * path_to)60 int32_t FlashFileResource::RenameFile(PP_Instance /*instance*/,
61                                       const char* path_from,
62                                       const char* path_to) {
63   PepperFilePath pepper_from(PepperFilePath::DOMAIN_MODULE_LOCAL,
64                              base::FilePath::FromUTF8Unsafe(path_from));
65   PepperFilePath pepper_to(PepperFilePath::DOMAIN_MODULE_LOCAL,
66                            base::FilePath::FromUTF8Unsafe(path_to));
67 
68   int32_t error = SyncCall<IPC::Message>(
69       BROWSER, PpapiHostMsg_FlashFile_RenameFile(pepper_from, pepper_to));
70 
71   return error;
72 }
73 
DeleteFileOrDir(PP_Instance,const char * path,PP_Bool recursive)74 int32_t FlashFileResource::DeleteFileOrDir(PP_Instance /*instance*/,
75                                            const char* path,
76                                            PP_Bool recursive) {
77   PepperFilePath pepper_path(PepperFilePath::DOMAIN_MODULE_LOCAL,
78                              base::FilePath::FromUTF8Unsafe(path));
79 
80   int32_t error = SyncCall<IPC::Message>(
81       BROWSER, PpapiHostMsg_FlashFile_DeleteFileOrDir(pepper_path,
82                                                       PP_ToBool(recursive)));
83 
84   return error;
85 }
86 
CreateDir(PP_Instance,const char * path)87 int32_t FlashFileResource::CreateDir(PP_Instance /*instance*/,
88                                      const char* path) {
89   PepperFilePath pepper_path(PepperFilePath::DOMAIN_MODULE_LOCAL,
90                              base::FilePath::FromUTF8Unsafe(path));
91 
92   int32_t error = SyncCall<IPC::Message>(BROWSER,
93       PpapiHostMsg_FlashFile_CreateDir(pepper_path));
94 
95   return error;
96 }
97 
QueryFile(PP_Instance,const char * path,PP_FileInfo * info)98 int32_t FlashFileResource::QueryFile(PP_Instance /*instance*/,
99                                      const char* path,
100                                      PP_FileInfo* info) {
101   return QueryFileHelper(path, PepperFilePath::DOMAIN_MODULE_LOCAL, info);
102 }
103 
GetDirContents(PP_Instance,const char * path,PP_DirContents_Dev ** contents)104 int32_t FlashFileResource::GetDirContents(PP_Instance /*instance*/,
105                                           const char* path,
106                                           PP_DirContents_Dev** contents) {
107   ppapi::DirContents entries;
108   PepperFilePath pepper_path(PepperFilePath::DOMAIN_MODULE_LOCAL,
109                              base::FilePath::FromUTF8Unsafe(path));
110 
111   int32_t error = SyncCall<PpapiPluginMsg_FlashFile_GetDirContentsReply>(
112       BROWSER, PpapiHostMsg_FlashFile_GetDirContents(pepper_path), &entries);
113 
114   if (error == PP_OK) {
115     // Copy the serialized dir entries to the output struct.
116     *contents = new PP_DirContents_Dev;
117     (*contents)->count = static_cast<int32_t>(entries.size());
118     (*contents)->entries = new PP_DirEntry_Dev[entries.size()];
119     for (size_t i = 0; i < entries.size(); i++) {
120       const ppapi::DirEntry& source = entries[i];
121       PP_DirEntry_Dev* dest = &(*contents)->entries[i];
122       std::string name = source.name.AsUTF8Unsafe();
123       char* name_copy = new char[name.size() + 1];
124       memcpy(name_copy, name.c_str(), name.size() + 1);
125       dest->name = name_copy;
126       dest->is_dir = PP_FromBool(source.is_dir);
127     }
128   }
129 
130   return error;
131 }
132 
FreeDirContents(PP_Instance,PP_DirContents_Dev * contents)133 void FlashFileResource::FreeDirContents(PP_Instance /*instance*/,
134                                         PP_DirContents_Dev* contents) {
135   for (int32_t i = 0; i < contents->count; ++i)
136     delete[] contents->entries[i].name;
137   delete[] contents->entries;
138   delete contents;
139 }
140 
CreateTemporaryFile(PP_Instance,PP_FileHandle * file)141 int32_t FlashFileResource::CreateTemporaryFile(PP_Instance /*instance*/,
142                                                PP_FileHandle* file) {
143   if (!file)
144     return PP_ERROR_BADARGUMENT;
145 
146   IPC::Message unused;
147   ResourceMessageReplyParams reply_params;
148   int32_t error = GenericSyncCall(BROWSER,
149       PpapiHostMsg_FlashFile_CreateTemporaryFile(), &unused, &reply_params);
150   if (error != PP_OK)
151     return error;
152 
153   IPC::PlatformFileForTransit transit_file;
154   if (!reply_params.TakeFileHandleAtIndex(0, &transit_file))
155     return PP_ERROR_FAILED;
156 
157   *file = IPC::PlatformFileForTransitToPlatformFile(transit_file);
158   return PP_OK;
159 }
160 
OpenFileRef(PP_Instance,PP_Resource file_ref,int32_t mode,PP_FileHandle * file)161 int32_t FlashFileResource::OpenFileRef(PP_Instance /*instance*/,
162                                        PP_Resource file_ref,
163                                        int32_t mode,
164                                        PP_FileHandle* file) {
165   return OpenFileHelper(GetPathFromFileRef(file_ref),
166                         PepperFilePath::DOMAIN_ABSOLUTE, mode, file);
167 }
168 
QueryFileRef(PP_Instance,PP_Resource file_ref,PP_FileInfo * info)169 int32_t FlashFileResource::QueryFileRef(PP_Instance /*instance*/,
170                                         PP_Resource file_ref,
171                                         PP_FileInfo* info) {
172   return QueryFileHelper(GetPathFromFileRef(file_ref),
173                          PepperFilePath::DOMAIN_ABSOLUTE, info);
174 }
175 
OpenFileHelper(const std::string & path,PepperFilePath::Domain domain_type,int32_t mode,PP_FileHandle * file)176 int32_t FlashFileResource::OpenFileHelper(const std::string& path,
177                                           PepperFilePath::Domain domain_type,
178                                           int32_t mode,
179                                           PP_FileHandle* file) {
180   if (path.empty() ||
181       !ppapi::PepperFileOpenFlagsToPlatformFileFlags(mode, NULL) ||
182       !file)
183     return PP_ERROR_BADARGUMENT;
184 
185   PepperFilePath pepper_path(domain_type, base::FilePath::FromUTF8Unsafe(path));
186 
187   IPC::Message unused;
188   ResourceMessageReplyParams reply_params;
189   int32_t error = GenericSyncCall(BROWSER,
190       PpapiHostMsg_FlashFile_OpenFile(pepper_path, mode), &unused,
191       &reply_params);
192   if (error != PP_OK)
193     return error;
194 
195   IPC::PlatformFileForTransit transit_file;
196   if (!reply_params.TakeFileHandleAtIndex(0, &transit_file))
197     return PP_ERROR_FAILED;
198 
199   *file = IPC::PlatformFileForTransitToPlatformFile(transit_file);
200   return PP_OK;
201 }
202 
QueryFileHelper(const std::string & path,PepperFilePath::Domain domain_type,PP_FileInfo * info)203 int32_t FlashFileResource::QueryFileHelper(const std::string& path,
204                                            PepperFilePath::Domain domain_type,
205                                            PP_FileInfo* info) {
206   if (path.empty() || !info)
207     return PP_ERROR_BADARGUMENT;
208 
209   base::File::Info file_info;
210   PepperFilePath pepper_path(domain_type, base::FilePath::FromUTF8Unsafe(path));
211 
212   int32_t error = SyncCall<PpapiPluginMsg_FlashFile_QueryFileReply>(BROWSER,
213       PpapiHostMsg_FlashFile_QueryFile(pepper_path), &file_info);
214 
215   if (error == PP_OK) {
216     info->size = file_info.size;
217     info->creation_time = TimeToPPTime(file_info.creation_time);
218     info->last_access_time = TimeToPPTime(file_info.last_accessed);
219     info->last_modified_time = TimeToPPTime(file_info.last_modified);
220     info->system_type = PP_FILESYSTEMTYPE_EXTERNAL;
221     if (file_info.is_directory)
222       info->type = PP_FILETYPE_DIRECTORY;
223     else
224       info->type = PP_FILETYPE_REGULAR;
225   }
226 
227   return error;
228 }
229 
230 }  // namespace proxy
231 }  // namespace ppapi
232