OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "webkit/fileapi/isolated_context.h" | 5 #include "webkit/fileapi/isolated_context.h" |
6 | 6 |
7 #include "base/file_path.h" | 7 #include "base/file_path.h" |
8 #include "base/basictypes.h" | 8 #include "base/basictypes.h" |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/rand_util.h" | 10 #include "base/rand_util.h" |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
55 } | 55 } |
56 NOTREACHED(); | 56 NOTREACHED(); |
57 return true; | 57 return true; |
58 } | 58 } |
59 | 59 |
60 } // namespace | 60 } // namespace |
61 | 61 |
62 static base::LazyInstance<IsolatedContext>::Leaky g_isolated_context = | 62 static base::LazyInstance<IsolatedContext>::Leaky g_isolated_context = |
63 LAZY_INSTANCE_INITIALIZER; | 63 LAZY_INSTANCE_INITIALIZER; |
64 | 64 |
65 IsolatedContext::FileInfo::FileInfo() {} | |
66 IsolatedContext::FileInfo::FileInfo( | |
67 const std::string& name, const FilePath& path) | |
68 : name(name), path(path) {} | |
69 | |
70 IsolatedContext::FileInfoSet::FileInfoSet() {} | 65 IsolatedContext::FileInfoSet::FileInfoSet() {} |
71 IsolatedContext::FileInfoSet::~FileInfoSet() {} | 66 IsolatedContext::FileInfoSet::~FileInfoSet() {} |
72 | 67 |
73 bool IsolatedContext::FileInfoSet::AddPath( | 68 bool IsolatedContext::FileInfoSet::AddPath( |
74 const FilePath& path, std::string* registered_name) { | 69 const FilePath& path, std::string* registered_name) { |
75 // The given path should not contain any '..' and should be absolute. | 70 // The given path should not contain any '..' and should be absolute. |
76 if (path.ReferencesParent() || !path.IsAbsolute()) | 71 if (path.ReferencesParent() || !path.IsAbsolute()) |
77 return false; | 72 return false; |
78 FilePath::StringType name = GetRegisterNameForPath(path); | 73 FilePath::StringType name = GetRegisterNameForPath(path); |
79 std::string utf8name = FilePath(name).AsUTF8Unsafe(); | 74 std::string utf8name = FilePath(name).AsUTF8Unsafe(); |
80 FilePath normalized_path = path.NormalizePathSeparators(); | 75 FilePath normalized_path = path.NormalizePathSeparators(); |
81 bool inserted = fileset_.insert(FileInfo(utf8name, normalized_path)).second; | 76 bool inserted = |
77 fileset_.insert(MountPointInfo(utf8name, normalized_path)).second; | |
82 if (!inserted) { | 78 if (!inserted) { |
83 int suffix = 1; | 79 int suffix = 1; |
84 std::string basepart = FilePath(name).RemoveExtension().AsUTF8Unsafe(); | 80 std::string basepart = FilePath(name).RemoveExtension().AsUTF8Unsafe(); |
85 std::string ext = FilePath(FilePath(name).Extension()).AsUTF8Unsafe(); | 81 std::string ext = FilePath(FilePath(name).Extension()).AsUTF8Unsafe(); |
86 while (!inserted) { | 82 while (!inserted) { |
87 utf8name = base::StringPrintf("%s (%d)", basepart.c_str(), suffix++); | 83 utf8name = base::StringPrintf("%s (%d)", basepart.c_str(), suffix++); |
88 if (!ext.empty()) | 84 if (!ext.empty()) |
89 utf8name.append(ext); | 85 utf8name.append(ext); |
90 inserted = fileset_.insert(FileInfo(utf8name, normalized_path)).second; | 86 inserted = |
87 fileset_.insert(MountPointInfo(utf8name, normalized_path)).second; | |
91 } | 88 } |
92 } | 89 } |
93 if (registered_name) | 90 if (registered_name) |
94 *registered_name = utf8name; | 91 *registered_name = utf8name; |
95 return true; | 92 return true; |
96 } | 93 } |
97 | 94 |
98 bool IsolatedContext::FileInfoSet::AddPathWithName( | 95 bool IsolatedContext::FileInfoSet::AddPathWithName( |
99 const FilePath& path, const std::string& name) { | 96 const FilePath& path, const std::string& name) { |
100 // The given path should not contain any '..' and should be absolute. | 97 // The given path should not contain any '..' and should be absolute. |
101 if (path.ReferencesParent() || !path.IsAbsolute()) | 98 if (path.ReferencesParent() || !path.IsAbsolute()) |
102 return false; | 99 return false; |
103 return fileset_.insert(FileInfo(name, path.NormalizePathSeparators())).second; | 100 return fileset_.insert( |
101 MountPointInfo(name, path.NormalizePathSeparators())).second; | |
104 } | 102 } |
105 | 103 |
106 //-------------------------------------------------------------------------- | 104 //-------------------------------------------------------------------------- |
107 | 105 |
108 class IsolatedContext::Instance { | 106 class IsolatedContext::Instance { |
109 public: | 107 public: |
110 typedef FileSystemType MountType; | |
111 | |
112 // For a single-path isolated file system, which could be registered by | 108 // For a single-path isolated file system, which could be registered by |
113 // IsolatedContext::RegisterFileSystemForPath(). | 109 // IsolatedContext::RegisterFileSystemForPath(). |
114 // Most of isolated file system contexts should be of this type. | 110 // Most of isolated file system contexts should be of this type. |
115 Instance(FileSystemType type, const FileInfo& file_info); | 111 Instance(FileSystemType type, const MountPointInfo& file_info); |
116 | 112 |
117 // For a multi-paths isolated file system. As of writing only file system | 113 // For a multi-paths isolated file system. As of writing only file system |
118 // type which could have multi-paths is Dragged file system, and | 114 // type which could have multi-paths is Dragged file system, and |
119 // could be registered by IsolatedContext::RegisterDraggedFileSystem(). | 115 // could be registered by IsolatedContext::RegisterDraggedFileSystem(). |
120 Instance(FileSystemType type, const std::set<FileInfo>& files); | 116 Instance(FileSystemType type, const std::set<MountPointInfo>& files); |
121 | |
122 // For a single-path external file system. | |
123 Instance(FileSystemType type, const FilePath& path); | |
124 | 117 |
125 ~Instance(); | 118 ~Instance(); |
126 | 119 |
127 MountType mount_type() const { return mount_type_; } | |
128 FileSystemType type() const { return type_; } | 120 FileSystemType type() const { return type_; } |
129 const FileInfo& file_info() const { return file_info_; } | 121 const MountPointInfo& file_info() const { return file_info_; } |
130 const std::set<FileInfo>& files() const { return files_; } | 122 const std::set<MountPointInfo>& files() const { return files_; } |
131 int ref_counts() const { return ref_counts_; } | 123 int ref_counts() const { return ref_counts_; } |
132 | 124 |
133 void AddRef() { ++ref_counts_; } | 125 void AddRef() { ++ref_counts_; } |
134 void RemoveRef() { --ref_counts_; } | 126 void RemoveRef() { --ref_counts_; } |
135 | 127 |
136 bool ResolvePathForName(const std::string& name, FilePath* path) const; | 128 bool ResolvePathForName(const std::string& name, FilePath* path) const; |
137 | 129 |
138 // Returns true if the instance is a single-path instance. | 130 // Returns true if the instance is a single-path instance. |
139 bool IsSinglePathInstance() const; | 131 bool IsSinglePathInstance() const; |
140 | 132 |
141 private: | 133 private: |
142 const MountType mount_type_; | |
143 const FileSystemType type_; | 134 const FileSystemType type_; |
144 | 135 |
145 // For single-path instance. | 136 // For single-path instance. |
146 const FileInfo file_info_; | 137 const MountPointInfo file_info_; |
147 | 138 |
148 // For multiple-path instance (e.g. dragged file system). | 139 // For multiple-path instance (e.g. dragged file system). |
149 const std::set<FileInfo> files_; | 140 const std::set<MountPointInfo> files_; |
150 | 141 |
151 // Reference counts. Note that an isolated filesystem is created with ref==0 | 142 // Reference counts. Note that an isolated filesystem is created with ref==0 |
152 // and will get deleted when the ref count reaches <=0. | 143 // and will get deleted when the ref count reaches <=0. |
153 int ref_counts_; | 144 int ref_counts_; |
154 | 145 |
155 DISALLOW_COPY_AND_ASSIGN(Instance); | 146 DISALLOW_COPY_AND_ASSIGN(Instance); |
156 }; | 147 }; |
157 | 148 |
158 IsolatedContext::Instance::Instance(FileSystemType type, | 149 IsolatedContext::Instance::Instance(FileSystemType type, |
159 const FileInfo& file_info) | 150 const MountPointInfo& file_info) |
160 : mount_type_(kFileSystemTypeIsolated), | 151 : type_(type), |
161 type_(type), | |
162 file_info_(file_info), | 152 file_info_(file_info), |
163 ref_counts_(0) { | 153 ref_counts_(0) { |
164 DCHECK(IsSinglePathIsolatedFileSystem(type_)); | 154 DCHECK(IsSinglePathIsolatedFileSystem(type_)); |
165 } | 155 } |
166 | 156 |
167 IsolatedContext::Instance::Instance(FileSystemType type, | 157 IsolatedContext::Instance::Instance(FileSystemType type, |
168 const std::set<FileInfo>& files) | 158 const std::set<MountPointInfo>& files) |
169 : mount_type_(kFileSystemTypeIsolated), | 159 : type_(type), |
170 type_(type), | |
171 files_(files), | 160 files_(files), |
172 ref_counts_(0) { | 161 ref_counts_(0) { |
173 DCHECK(!IsSinglePathIsolatedFileSystem(type_)); | 162 DCHECK(!IsSinglePathIsolatedFileSystem(type_)); |
174 } | 163 } |
175 | 164 |
176 IsolatedContext::Instance::Instance(FileSystemType type, | |
177 const FilePath& path) | |
178 : mount_type_(kFileSystemTypeExternal), | |
179 type_(type), | |
180 file_info_(FileInfo("", path)), | |
181 ref_counts_(0) { | |
182 DCHECK(IsSinglePathIsolatedFileSystem(type_)); | |
183 } | |
184 | |
185 IsolatedContext::Instance::~Instance() {} | 165 IsolatedContext::Instance::~Instance() {} |
186 | 166 |
187 bool IsolatedContext::Instance::ResolvePathForName(const std::string& name, | 167 bool IsolatedContext::Instance::ResolvePathForName(const std::string& name, |
188 FilePath* path) const { | 168 FilePath* path) const { |
189 if (IsSinglePathIsolatedFileSystem(type_)) { | 169 if (IsSinglePathIsolatedFileSystem(type_)) { |
190 *path = file_info_.path; | 170 *path = file_info_.path; |
191 return file_info_.name == name; | 171 return file_info_.name == name; |
192 } | 172 } |
193 std::set<FileInfo>::const_iterator found = files_.find( | 173 std::set<MountPointInfo>::const_iterator found = files_.find( |
194 FileInfo(name, FilePath())); | 174 MountPointInfo(name, FilePath())); |
195 if (found == files_.end()) | 175 if (found == files_.end()) |
196 return false; | 176 return false; |
197 *path = found->path; | 177 *path = found->path; |
198 return true; | 178 return true; |
199 } | 179 } |
200 | 180 |
201 bool IsolatedContext::Instance::IsSinglePathInstance() const { | 181 bool IsolatedContext::Instance::IsSinglePathInstance() const { |
202 return IsSinglePathIsolatedFileSystem(type_); | 182 return IsSinglePathIsolatedFileSystem(type_); |
203 } | 183 } |
204 | 184 |
(...skipping 28 matching lines...) Expand all Loading... | |
233 if (register_name && !register_name->empty()) { | 213 if (register_name && !register_name->empty()) { |
234 name = *register_name; | 214 name = *register_name; |
235 } else { | 215 } else { |
236 name = FilePath(GetRegisterNameForPath(path)).AsUTF8Unsafe(); | 216 name = FilePath(GetRegisterNameForPath(path)).AsUTF8Unsafe(); |
237 if (register_name) | 217 if (register_name) |
238 register_name->assign(name); | 218 register_name->assign(name); |
239 } | 219 } |
240 | 220 |
241 base::AutoLock locker(lock_); | 221 base::AutoLock locker(lock_); |
242 std::string filesystem_id = GetNewFileSystemId(); | 222 std::string filesystem_id = GetNewFileSystemId(); |
243 instance_map_[filesystem_id] = new Instance(type, FileInfo(name, path)); | 223 instance_map_[filesystem_id] = new Instance(type, MountPointInfo(name, path)); |
244 path_to_id_map_[path].insert(filesystem_id); | 224 path_to_id_map_[path].insert(filesystem_id); |
245 return filesystem_id; | 225 return filesystem_id; |
246 } | 226 } |
247 | 227 |
248 bool IsolatedContext::RegisterExternalFileSystem(const std::string& mount_name, | |
249 FileSystemType type, | |
250 const FilePath& path) { | |
251 base::AutoLock locker(lock_); | |
252 IDToInstance::iterator found = instance_map_.find(mount_name); | |
253 if (found != instance_map_.end()) | |
254 return false; | |
255 instance_map_[mount_name] = new Instance(type, path); | |
256 path_to_id_map_[path].insert(mount_name); | |
257 return true; | |
258 } | |
259 | |
260 std::vector<IsolatedContext::FileInfo> | |
261 IsolatedContext::GetExternalMountPoints() const { | |
262 base::AutoLock locker(lock_); | |
263 std::vector<FileInfo> files; | |
264 for (IDToInstance::const_iterator iter = instance_map_.begin(); | |
265 iter != instance_map_.end(); | |
266 ++iter) { | |
267 if (iter->second->mount_type() == kFileSystemTypeExternal) | |
268 files.push_back(FileInfo(iter->first, iter->second->file_info().path)); | |
269 } | |
270 return files; | |
271 } | |
272 | |
273 bool IsolatedContext::RevokeFileSystem(const std::string& filesystem_id) { | |
274 base::AutoLock locker(lock_); | |
275 return UnregisterFileSystem(filesystem_id); | |
276 } | |
277 | |
278 void IsolatedContext::RevokeFileSystemByPath(const FilePath& path_in) { | 228 void IsolatedContext::RevokeFileSystemByPath(const FilePath& path_in) { |
279 base::AutoLock locker(lock_); | 229 base::AutoLock locker(lock_); |
280 FilePath path(path_in.NormalizePathSeparators()); | 230 FilePath path(path_in.NormalizePathSeparators()); |
281 PathToID::iterator ids_iter = path_to_id_map_.find(path); | 231 PathToID::iterator ids_iter = path_to_id_map_.find(path); |
282 if (ids_iter == path_to_id_map_.end()) | 232 if (ids_iter == path_to_id_map_.end()) |
283 return; | 233 return; |
284 std::set<std::string>& ids = ids_iter->second; | 234 std::set<std::string>& ids = ids_iter->second; |
285 for (std::set<std::string>::iterator iter = ids.begin(); | 235 for (std::set<std::string>::iterator iter = ids.begin(); |
286 iter != ids.end(); ++iter) { | 236 iter != ids.end(); ++iter) { |
287 IDToInstance::iterator found = instance_map_.find(*iter); | 237 IDToInstance::iterator found = instance_map_.find(*iter); |
(...skipping 14 matching lines...) Expand all Loading... | |
302 void IsolatedContext::RemoveReference(const std::string& filesystem_id) { | 252 void IsolatedContext::RemoveReference(const std::string& filesystem_id) { |
303 base::AutoLock locker(lock_); | 253 base::AutoLock locker(lock_); |
304 // This could get called for non-existent filesystem if it has been | 254 // This could get called for non-existent filesystem if it has been |
305 // already deleted by RevokeFileSystemByPath. | 255 // already deleted by RevokeFileSystemByPath. |
306 IDToInstance::iterator found = instance_map_.find(filesystem_id); | 256 IDToInstance::iterator found = instance_map_.find(filesystem_id); |
307 if (found == instance_map_.end()) | 257 if (found == instance_map_.end()) |
308 return; | 258 return; |
309 Instance* instance = found->second; | 259 Instance* instance = found->second; |
310 DCHECK_GT(instance->ref_counts(), 0); | 260 DCHECK_GT(instance->ref_counts(), 0); |
311 instance->RemoveRef(); | 261 instance->RemoveRef(); |
312 if (instance->ref_counts() == 0 && | 262 if (instance->ref_counts() == 0) { |
313 instance->mount_type() != kFileSystemTypeExternal) { | |
314 bool deleted = UnregisterFileSystem(filesystem_id); | 263 bool deleted = UnregisterFileSystem(filesystem_id); |
315 DCHECK(deleted); | 264 DCHECK(deleted); |
316 } | 265 } |
317 } | 266 } |
318 | 267 |
319 bool IsolatedContext::CrackIsolatedPath(const FilePath& virtual_path, | 268 bool IsolatedContext::CrackIsolatedPath(const FilePath& virtual_path, |
320 std::string* id_or_name, | 269 std::string* id_or_name, |
321 FileSystemType* type, | 270 FileSystemType* type, |
322 FilePath* path) const { | 271 FilePath* path) const { |
323 DCHECK(id_or_name); | 272 DCHECK(id_or_name); |
(...skipping 17 matching lines...) Expand all Loading... | |
341 FilePath cracked_path; | 290 FilePath cracked_path; |
342 { | 291 { |
343 base::AutoLock locker(lock_); | 292 base::AutoLock locker(lock_); |
344 IDToInstance::const_iterator found_instance = instance_map_.find(fsid); | 293 IDToInstance::const_iterator found_instance = instance_map_.find(fsid); |
345 if (found_instance == instance_map_.end()) | 294 if (found_instance == instance_map_.end()) |
346 return false; | 295 return false; |
347 *id_or_name = fsid; | 296 *id_or_name = fsid; |
348 const Instance* instance = found_instance->second; | 297 const Instance* instance = found_instance->second; |
349 if (type) | 298 if (type) |
350 *type = instance->type(); | 299 *type = instance->type(); |
351 switch (instance->mount_type()) { | 300 |
352 case kFileSystemTypeIsolated: { | 301 if (component_iter == components.end()) { |
353 if (component_iter == components.end()) { | 302 // The virtual root case. |
354 // The virtual root case. | 303 path->clear(); |
355 path->clear(); | 304 return true; |
356 return true; | |
357 } | |
358 // *component_iter should be a name of the registered path. | |
359 std::string name = FilePath(*component_iter++).AsUTF8Unsafe(); | |
360 if (!instance->ResolvePathForName(name, &cracked_path)) | |
361 return false; | |
362 break; | |
363 } | |
364 case kFileSystemTypeExternal: | |
365 cracked_path = instance->file_info().path; | |
366 break; | |
367 default: | |
368 NOTREACHED(); | |
369 break; | |
370 } | 305 } |
306 | |
307 // *component_iter should be a name of the registered path. | |
308 std::string name = FilePath(*component_iter++).AsUTF8Unsafe(); | |
309 if (!instance->ResolvePathForName(name, &cracked_path)) | |
310 return false; | |
371 } | 311 } |
372 | 312 |
373 for (; component_iter != components.end(); ++component_iter) | 313 for (; component_iter != components.end(); ++component_iter) |
374 cracked_path = cracked_path.Append(*component_iter); | 314 cracked_path = cracked_path.Append(*component_iter); |
375 *path = cracked_path; | 315 *path = cracked_path; |
376 return true; | 316 return true; |
377 } | 317 } |
378 | 318 |
379 bool IsolatedContext::GetDraggedFileInfo( | 319 bool IsolatedContext::GetDraggedFileInfo( |
380 const std::string& filesystem_id, std::vector<FileInfo>* files) const { | 320 const std::string& filesystem_id, |
321 std::vector<MountPointInfo>* files) const { | |
381 DCHECK(files); | 322 DCHECK(files); |
382 base::AutoLock locker(lock_); | 323 base::AutoLock locker(lock_); |
383 IDToInstance::const_iterator found = instance_map_.find(filesystem_id); | 324 IDToInstance::const_iterator found = instance_map_.find(filesystem_id); |
384 if (found == instance_map_.end() || | 325 if (found == instance_map_.end() || |
385 found->second->type() != kFileSystemTypeDragged) | 326 found->second->type() != kFileSystemTypeDragged) |
386 return false; | 327 return false; |
387 files->assign(found->second->files().begin(), | 328 files->assign(found->second->files().begin(), |
388 found->second->files().end()); | 329 found->second->files().end()); |
389 return true; | 330 return true; |
390 } | 331 } |
391 | 332 |
333 bool IsolatedContext::CanCrackMountType(FileSystemType type) const { | |
334 return type == kFileSystemTypeIsolated; | |
335 } | |
336 | |
392 bool IsolatedContext::GetRegisteredPath( | 337 bool IsolatedContext::GetRegisteredPath( |
393 const std::string& filesystem_id, FilePath* path) const { | 338 const std::string& filesystem_id, FilePath* path) const { |
394 DCHECK(path); | 339 DCHECK(path); |
395 base::AutoLock locker(lock_); | 340 base::AutoLock locker(lock_); |
396 IDToInstance::const_iterator found = instance_map_.find(filesystem_id); | 341 IDToInstance::const_iterator found = instance_map_.find(filesystem_id); |
397 if (found == instance_map_.end() || !found->second->IsSinglePathInstance()) | 342 if (found == instance_map_.end() || !found->second->IsSinglePathInstance()) |
398 return false; | 343 return false; |
399 *path = found->second->file_info().path; | 344 *path = found->second->file_info().path; |
400 return true; | 345 return true; |
401 } | 346 } |
402 | 347 |
348 bool IsolatedContext::RevokeFileSystem(const std::string& filesystem_id) { | |
349 base::AutoLock locker(lock_); | |
kinuko
2013/01/08 12:22:43
nit:indent
tbarzic
2013/01/09 01:26:34
I think indent is fine..
| |
350 return UnregisterFileSystem(filesystem_id); | |
351 } | |
352 | |
353 | |
kinuko
2013/01/08 12:22:43
nit: extra empty line
tbarzic
2013/01/09 01:26:34
Done.
| |
403 FilePath IsolatedContext::CreateVirtualRootPath( | 354 FilePath IsolatedContext::CreateVirtualRootPath( |
404 const std::string& filesystem_id) const { | 355 const std::string& filesystem_id) const { |
405 return FilePath().AppendASCII(filesystem_id); | 356 return FilePath().AppendASCII(filesystem_id); |
406 } | 357 } |
407 | 358 |
408 IsolatedContext::IsolatedContext() { | 359 IsolatedContext::IsolatedContext() { |
409 } | 360 } |
410 | 361 |
411 IsolatedContext::~IsolatedContext() { | 362 IsolatedContext::~IsolatedContext() { |
412 STLDeleteContainerPairSecondPointers(instance_map_.begin(), | 363 STLDeleteContainerPairSecondPointers(instance_map_.begin(), |
(...skipping 24 matching lines...) Expand all Loading... | |
437 lock_.AssertAcquired(); | 388 lock_.AssertAcquired(); |
438 uint32 random_data[4]; | 389 uint32 random_data[4]; |
439 std::string id; | 390 std::string id; |
440 do { | 391 do { |
441 base::RandBytes(random_data, sizeof(random_data)); | 392 base::RandBytes(random_data, sizeof(random_data)); |
442 id = base::HexEncode(random_data, sizeof(random_data)); | 393 id = base::HexEncode(random_data, sizeof(random_data)); |
443 } while (instance_map_.find(id) != instance_map_.end()); | 394 } while (instance_map_.find(id) != instance_map_.end()); |
444 return id; | 395 return id; |
445 } | 396 } |
446 | 397 |
447 ScopedExternalFileSystem::ScopedExternalFileSystem( | |
448 const std::string& mount_name, | |
449 FileSystemType type, | |
450 const FilePath& path) | |
451 : mount_name_(mount_name) { | |
452 IsolatedContext::GetInstance()->RegisterExternalFileSystem( | |
453 mount_name, type, path); | |
454 } | |
455 | |
456 FilePath ScopedExternalFileSystem::GetVirtualRootPath() const { | |
457 return IsolatedContext::GetInstance()->CreateVirtualRootPath(mount_name_); | |
458 } | |
459 | |
460 ScopedExternalFileSystem::~ScopedExternalFileSystem() { | |
461 IsolatedContext::GetInstance()->RevokeFileSystem(mount_name_); | |
462 } | |
463 | |
464 } // namespace fileapi | 398 } // namespace fileapi |
OLD | NEW |