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/browser/fileapi/obfuscated_file_util.h" | 5 #include "webkit/browser/fileapi/obfuscated_file_util.h" |
6 | 6 |
7 #include <queue> | 7 #include <queue> |
8 #include <string> | 8 #include <string> |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
98 } | 98 } |
99 | 99 |
100 enum IsolatedOriginStatus { | 100 enum IsolatedOriginStatus { |
101 kIsolatedOriginMatch, | 101 kIsolatedOriginMatch, |
102 kIsolatedOriginDontMatch, | 102 kIsolatedOriginDontMatch, |
103 kIsolatedOriginStatusMax, | 103 kIsolatedOriginStatusMax, |
104 }; | 104 }; |
105 | 105 |
106 } // namespace | 106 } // namespace |
107 | 107 |
108 using base::PlatformFile; | |
109 | |
110 class ObfuscatedFileEnumerator | 108 class ObfuscatedFileEnumerator |
111 : public FileSystemFileUtil::AbstractFileEnumerator { | 109 : public FileSystemFileUtil::AbstractFileEnumerator { |
112 public: | 110 public: |
113 ObfuscatedFileEnumerator( | 111 ObfuscatedFileEnumerator( |
114 SandboxDirectoryDatabase* db, | 112 SandboxDirectoryDatabase* db, |
115 FileSystemOperationContext* context, | 113 FileSystemOperationContext* context, |
116 ObfuscatedFileUtil* obfuscated_file_util, | 114 ObfuscatedFileUtil* obfuscated_file_util, |
117 const FileSystemURL& root_url, | 115 const FileSystemURL& root_url, |
118 bool recursive) | 116 bool recursive) |
119 : db_(db), | 117 : db_(db), |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
266 file_task_runner_(file_task_runner), | 264 file_task_runner_(file_task_runner), |
267 get_type_string_for_url_(get_type_string_for_url), | 265 get_type_string_for_url_(get_type_string_for_url), |
268 known_type_strings_(known_type_strings), | 266 known_type_strings_(known_type_strings), |
269 sandbox_delegate_(sandbox_delegate) { | 267 sandbox_delegate_(sandbox_delegate) { |
270 } | 268 } |
271 | 269 |
272 ObfuscatedFileUtil::~ObfuscatedFileUtil() { | 270 ObfuscatedFileUtil::~ObfuscatedFileUtil() { |
273 DropDatabases(); | 271 DropDatabases(); |
274 } | 272 } |
275 | 273 |
276 base::File::Error ObfuscatedFileUtil::CreateOrOpen( | 274 base::File ObfuscatedFileUtil::CreateOrOpen( |
277 FileSystemOperationContext* context, | 275 FileSystemOperationContext* context, |
278 const FileSystemURL& url, int file_flags, | 276 const FileSystemURL& url, int file_flags) { |
279 PlatformFile* file_handle, bool* created) { | 277 base::File file = CreateOrOpenInternal(context, url, file_flags); |
280 base::File::Error error = CreateOrOpenInternal(context, url, file_flags, | 278 if (file.IsValid() && file_flags & base::PLATFORM_FILE_WRITE && |
281 file_handle, created); | |
282 if (*file_handle != base::kInvalidPlatformFileValue && | |
283 file_flags & base::PLATFORM_FILE_WRITE && | |
284 context->quota_limit_type() == quota::kQuotaLimitTypeUnlimited && | 279 context->quota_limit_type() == quota::kQuotaLimitTypeUnlimited && |
285 sandbox_delegate_) { | 280 sandbox_delegate_) { |
286 DCHECK_EQ(base::File::FILE_OK, error); | |
287 sandbox_delegate_->StickyInvalidateUsageCache(url.origin(), url.type()); | 281 sandbox_delegate_->StickyInvalidateUsageCache(url.origin(), url.type()); |
288 } | 282 } |
289 return error; | 283 return file.Pass(); |
290 } | |
291 | |
292 base::File::Error ObfuscatedFileUtil::Close( | |
293 FileSystemOperationContext* context, | |
294 base::PlatformFile file) { | |
295 base::File auto_closed(file); | |
296 return base::File::FILE_OK; | |
297 } | 284 } |
298 | 285 |
299 base::File::Error ObfuscatedFileUtil::EnsureFileExists( | 286 base::File::Error ObfuscatedFileUtil::EnsureFileExists( |
300 FileSystemOperationContext* context, | 287 FileSystemOperationContext* context, |
301 const FileSystemURL& url, | 288 const FileSystemURL& url, |
302 bool* created) { | 289 bool* created) { |
303 SandboxDirectoryDatabase* db = GetDirectoryDatabase(url, true); | 290 SandboxDirectoryDatabase* db = GetDirectoryDatabase(url, true); |
304 if (!db) | 291 if (!db) |
305 return base::File::FILE_ERROR_FAILED; | 292 return base::File::FILE_ERROR_FAILED; |
306 | 293 |
(...skipping 14 matching lines...) Expand all Loading... |
321 if (!db->GetFileWithPath(VirtualPath::DirName(url.path()), &parent_id)) | 308 if (!db->GetFileWithPath(VirtualPath::DirName(url.path()), &parent_id)) |
322 return base::File::FILE_ERROR_NOT_FOUND; | 309 return base::File::FILE_ERROR_NOT_FOUND; |
323 | 310 |
324 FileInfo file_info; | 311 FileInfo file_info; |
325 InitFileInfo(&file_info, parent_id, | 312 InitFileInfo(&file_info, parent_id, |
326 VirtualPath::BaseName(url.path()).value()); | 313 VirtualPath::BaseName(url.path()).value()); |
327 | 314 |
328 int64 growth = UsageForPath(file_info.name.size()); | 315 int64 growth = UsageForPath(file_info.name.size()); |
329 if (!AllocateQuota(context, growth)) | 316 if (!AllocateQuota(context, growth)) |
330 return base::File::FILE_ERROR_NO_SPACE; | 317 return base::File::FILE_ERROR_NO_SPACE; |
331 base::File::Error error = CreateFile( | 318 base::File::Error error = CreateFile(context, base::FilePath(), url, |
332 context, base::FilePath(), url, &file_info, 0, NULL); | 319 &file_info); |
333 if (created && base::File::FILE_OK == error) { | 320 if (created && base::File::FILE_OK == error) { |
334 *created = true; | 321 *created = true; |
335 UpdateUsage(context, url, growth); | 322 UpdateUsage(context, url, growth); |
336 context->change_observers()->Notify( | 323 context->change_observers()->Notify( |
337 &FileChangeObserver::OnCreateFile, MakeTuple(url)); | 324 &FileChangeObserver::OnCreateFile, MakeTuple(url)); |
338 } | 325 } |
339 return error; | 326 return error; |
340 } | 327 } |
341 | 328 |
342 base::File::Error ObfuscatedFileUtil::CreateDirectory( | 329 base::File::Error ObfuscatedFileUtil::CreateDirectory( |
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
588 error = base::File::FILE_ERROR_FAILED; | 575 error = base::File::FILE_ERROR_FAILED; |
589 if (copy) { | 576 if (copy) { |
590 if (overwrite) { | 577 if (overwrite) { |
591 error = NativeFileUtil::CopyOrMoveFile( | 578 error = NativeFileUtil::CopyOrMoveFile( |
592 src_local_path, | 579 src_local_path, |
593 dest_local_path, | 580 dest_local_path, |
594 option, | 581 option, |
595 fileapi::NativeFileUtil::CopyOrMoveModeForDestination( | 582 fileapi::NativeFileUtil::CopyOrMoveModeForDestination( |
596 dest_url, true /* copy */)); | 583 dest_url, true /* copy */)); |
597 } else { // non-overwrite | 584 } else { // non-overwrite |
598 error = CreateFile(context, src_local_path, | 585 error = CreateFile(context, src_local_path, dest_url, &dest_file_info); |
599 dest_url, &dest_file_info, 0, NULL); | |
600 } | 586 } |
601 } else { | 587 } else { |
602 if (overwrite) { | 588 if (overwrite) { |
603 if (db->OverwritingMoveFile(src_file_id, dest_file_id)) { | 589 if (db->OverwritingMoveFile(src_file_id, dest_file_id)) { |
604 if (base::File::FILE_OK != | 590 if (base::File::FILE_OK != |
605 NativeFileUtil::DeleteFile(dest_local_path)) | 591 NativeFileUtil::DeleteFile(dest_local_path)) |
606 LOG(WARNING) << "Leaked a backing file."; | 592 LOG(WARNING) << "Leaked a backing file."; |
607 error = base::File::FILE_OK; | 593 error = base::File::FILE_OK; |
608 } else { | 594 } else { |
609 error = base::File::FILE_ERROR_FAILED; | 595 error = base::File::FILE_ERROR_FAILED; |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
694 base::File::Error error; | 680 base::File::Error error; |
695 if (overwrite) { | 681 if (overwrite) { |
696 base::FilePath dest_local_path = | 682 base::FilePath dest_local_path = |
697 DataPathToLocalPath(dest_url, dest_file_info.data_path); | 683 DataPathToLocalPath(dest_url, dest_file_info.data_path); |
698 error = NativeFileUtil::CopyOrMoveFile( | 684 error = NativeFileUtil::CopyOrMoveFile( |
699 src_file_path, dest_local_path, | 685 src_file_path, dest_local_path, |
700 FileSystemOperation::OPTION_NONE, | 686 FileSystemOperation::OPTION_NONE, |
701 fileapi::NativeFileUtil::CopyOrMoveModeForDestination(dest_url, | 687 fileapi::NativeFileUtil::CopyOrMoveModeForDestination(dest_url, |
702 true /* copy */)); | 688 true /* copy */)); |
703 } else { | 689 } else { |
704 error = CreateFile(context, src_file_path, | 690 error = CreateFile(context, src_file_path, dest_url, &dest_file_info); |
705 dest_url, &dest_file_info, 0, NULL); | |
706 } | 691 } |
707 | 692 |
708 if (error != base::File::FILE_OK) | 693 if (error != base::File::FILE_OK) |
709 return error; | 694 return error; |
710 | 695 |
711 if (overwrite) { | 696 if (overwrite) { |
712 context->change_observers()->Notify( | 697 context->change_observers()->Notify( |
713 &FileChangeObserver::OnModifyFile, MakeTuple(dest_url)); | 698 &FileChangeObserver::OnModifyFile, MakeTuple(dest_url)); |
714 } else { | 699 } else { |
715 context->change_observers()->Notify( | 700 context->change_observers()->Notify( |
(...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1043 *platform_file_path = local_path; | 1028 *platform_file_path = local_path; |
1044 } else if (error == base::File::FILE_ERROR_NOT_FOUND) { | 1029 } else if (error == base::File::FILE_ERROR_NOT_FOUND) { |
1045 LOG(WARNING) << "Lost a backing file."; | 1030 LOG(WARNING) << "Lost a backing file."; |
1046 InvalidateUsageCache(context, url.origin(), url.type()); | 1031 InvalidateUsageCache(context, url.origin(), url.type()); |
1047 if (!db->RemoveFileInfo(file_id)) | 1032 if (!db->RemoveFileInfo(file_id)) |
1048 return base::File::FILE_ERROR_FAILED; | 1033 return base::File::FILE_ERROR_FAILED; |
1049 } | 1034 } |
1050 return error; | 1035 return error; |
1051 } | 1036 } |
1052 | 1037 |
| 1038 base::File ObfuscatedFileUtil::CreateAndOpenFile( |
| 1039 FileSystemOperationContext* context, |
| 1040 const FileSystemURL& dest_url, |
| 1041 FileInfo* dest_file_info, int file_flags) { |
| 1042 SandboxDirectoryDatabase* db = GetDirectoryDatabase(dest_url, true); |
| 1043 |
| 1044 base::FilePath root, dest_local_path; |
| 1045 base::File::Error error = GenerateNewLocalPath(db, context, dest_url, &root, |
| 1046 &dest_local_path); |
| 1047 if (error != base::File::FILE_OK) |
| 1048 return base::File(error); |
| 1049 |
| 1050 if (base::PathExists(dest_local_path)) { |
| 1051 if (!base::DeleteFile(dest_local_path, true /* recursive */)) |
| 1052 return base::File(base::File::FILE_ERROR_FAILED); |
| 1053 LOG(WARNING) << "A stray file detected"; |
| 1054 InvalidateUsageCache(context, dest_url.origin(), dest_url.type()); |
| 1055 } |
| 1056 |
| 1057 base::File file = NativeFileUtil::CreateOrOpen(dest_local_path, file_flags); |
| 1058 if (!file.IsValid()) |
| 1059 return file.Pass(); |
| 1060 |
| 1061 if (!file.created()) { |
| 1062 file.Close(); |
| 1063 base::DeleteFile(dest_local_path, false /* recursive */); |
| 1064 return base::File(base::File::FILE_ERROR_FAILED); |
| 1065 } |
| 1066 |
| 1067 error = CommitCreateFile(root, dest_local_path, db, dest_file_info); |
| 1068 if (error != base::File::FILE_OK) { |
| 1069 file.Close(); |
| 1070 base::DeleteFile(dest_local_path, false /* recursive */); |
| 1071 return base::File(error); |
| 1072 } |
| 1073 |
| 1074 return file.Pass(); |
| 1075 } |
| 1076 |
1053 base::File::Error ObfuscatedFileUtil::CreateFile( | 1077 base::File::Error ObfuscatedFileUtil::CreateFile( |
1054 FileSystemOperationContext* context, | 1078 FileSystemOperationContext* context, |
1055 const base::FilePath& src_file_path, | 1079 const base::FilePath& src_file_path, |
1056 const FileSystemURL& dest_url, | 1080 const FileSystemURL& dest_url, |
1057 FileInfo* dest_file_info, int file_flags, PlatformFile* handle) { | 1081 FileInfo* dest_file_info) { |
1058 if (handle) | |
1059 *handle = base::kInvalidPlatformFileValue; | |
1060 SandboxDirectoryDatabase* db = GetDirectoryDatabase(dest_url, true); | 1082 SandboxDirectoryDatabase* db = GetDirectoryDatabase(dest_url, true); |
1061 | 1083 |
1062 base::File::Error error = base::File::FILE_OK; | 1084 base::FilePath root, dest_local_path; |
1063 base::FilePath root = GetDirectoryForURL(dest_url, false, &error); | 1085 base::File::Error error = GenerateNewLocalPath(db, context, dest_url, &root, |
1064 if (error != base::File::FILE_OK) | 1086 &dest_local_path); |
1065 return error; | |
1066 | |
1067 base::FilePath dest_local_path; | |
1068 error = GenerateNewLocalPath(db, context, dest_url, &dest_local_path); | |
1069 if (error != base::File::FILE_OK) | 1087 if (error != base::File::FILE_OK) |
1070 return error; | 1088 return error; |
1071 | 1089 |
1072 bool created = false; | 1090 bool created = false; |
1073 if (!src_file_path.empty()) { | 1091 if (src_file_path.empty()) { |
1074 DCHECK(!file_flags); | |
1075 DCHECK(!handle); | |
1076 error = NativeFileUtil::CopyOrMoveFile( | |
1077 src_file_path, dest_local_path, | |
1078 FileSystemOperation::OPTION_NONE, | |
1079 fileapi::NativeFileUtil::CopyOrMoveModeForDestination(dest_url, | |
1080 true /* copy */)); | |
1081 created = true; | |
1082 } else { | |
1083 if (base::PathExists(dest_local_path)) { | 1092 if (base::PathExists(dest_local_path)) { |
1084 if (!base::DeleteFile(dest_local_path, true /* recursive */)) | 1093 if (!base::DeleteFile(dest_local_path, true /* recursive */)) |
1085 return base::File::FILE_ERROR_FAILED; | 1094 return base::File::FILE_ERROR_FAILED; |
1086 LOG(WARNING) << "A stray file detected"; | 1095 LOG(WARNING) << "A stray file detected"; |
1087 InvalidateUsageCache(context, dest_url.origin(), dest_url.type()); | 1096 InvalidateUsageCache(context, dest_url.origin(), dest_url.type()); |
1088 } | 1097 } |
1089 | 1098 |
1090 if (handle) { | 1099 error = NativeFileUtil::EnsureFileExists(dest_local_path, &created); |
1091 // TODO(rvargas): Remove PlatformFile from this code. | 1100 } else { |
1092 base::File file = | 1101 error = NativeFileUtil::CopyOrMoveFile( |
1093 NativeFileUtil::CreateOrOpen(dest_local_path, file_flags); | 1102 src_file_path, dest_local_path, |
1094 if (file.IsValid()) { | 1103 FileSystemOperation::OPTION_NONE, |
1095 created = file.created(); | 1104 fileapi::NativeFileUtil::CopyOrMoveModeForDestination(dest_url, |
1096 *handle = file.TakePlatformFile(); | 1105 true /* copy */)); |
1097 error = base::File::FILE_OK; | 1106 created = true; |
1098 } else { | |
1099 error = file.error_details(); | |
1100 } | |
1101 // If this succeeds, we must close handle on any subsequent error. | |
1102 } else { | |
1103 DCHECK(!file_flags); // file_flags is only used by CreateOrOpen. | |
1104 error = NativeFileUtil::EnsureFileExists(dest_local_path, &created); | |
1105 } | |
1106 } | 1107 } |
1107 if (error != base::File::FILE_OK) | 1108 if (error != base::File::FILE_OK) |
1108 return error; | 1109 return error; |
| 1110 if (!created) |
| 1111 return base::File::FILE_ERROR_FAILED; |
1109 | 1112 |
1110 if (!created) { | 1113 return CommitCreateFile(root, dest_local_path, db, dest_file_info); |
1111 if (handle) { | 1114 } |
1112 DCHECK_NE(base::kInvalidPlatformFileValue, *handle); | |
1113 base::ClosePlatformFile(*handle); | |
1114 base::DeleteFile(dest_local_path, false /* recursive */); | |
1115 *handle = base::kInvalidPlatformFileValue; | |
1116 } | |
1117 return base::File::FILE_ERROR_FAILED; | |
1118 } | |
1119 | 1115 |
| 1116 base::File::Error ObfuscatedFileUtil::CommitCreateFile( |
| 1117 const base::FilePath& root, |
| 1118 const base::FilePath& local_path, |
| 1119 SandboxDirectoryDatabase* db, |
| 1120 FileInfo* dest_file_info) { |
1120 // This removes the root, including the trailing slash, leaving a relative | 1121 // This removes the root, including the trailing slash, leaving a relative |
1121 // path. | 1122 // path. |
1122 dest_file_info->data_path = base::FilePath( | 1123 dest_file_info->data_path = base::FilePath( |
1123 dest_local_path.value().substr(root.value().length() + 1)); | 1124 local_path.value().substr(root.value().length() + 1)); |
1124 | 1125 |
1125 FileId file_id; | 1126 FileId file_id; |
1126 error = db->AddFileInfo(*dest_file_info, &file_id); | 1127 base::File::Error error = db->AddFileInfo(*dest_file_info, &file_id); |
1127 if (error != base::File::FILE_OK) { | 1128 if (error != base::File::FILE_OK) |
1128 if (handle) { | |
1129 DCHECK_NE(base::kInvalidPlatformFileValue, *handle); | |
1130 base::ClosePlatformFile(*handle); | |
1131 *handle = base::kInvalidPlatformFileValue; | |
1132 } | |
1133 base::DeleteFile(dest_local_path, false /* recursive */); | |
1134 return error; | 1129 return error; |
1135 } | 1130 |
1136 TouchDirectory(db, dest_file_info->parent_id); | 1131 TouchDirectory(db, dest_file_info->parent_id); |
1137 | |
1138 return base::File::FILE_OK; | 1132 return base::File::FILE_OK; |
1139 } | 1133 } |
1140 | 1134 |
1141 base::FilePath ObfuscatedFileUtil::DataPathToLocalPath( | 1135 base::FilePath ObfuscatedFileUtil::DataPathToLocalPath( |
1142 const FileSystemURL& url, const base::FilePath& data_path) { | 1136 const FileSystemURL& url, const base::FilePath& data_path) { |
1143 base::File::Error error = base::File::FILE_OK; | 1137 base::File::Error error = base::File::FILE_OK; |
1144 base::FilePath root = GetDirectoryForURL(url, false, &error); | 1138 base::FilePath root = GetDirectoryForURL(url, false, &error); |
1145 if (error != base::File::FILE_OK) | 1139 if (error != base::File::FILE_OK) |
1146 return base::FilePath(); | 1140 return base::FilePath(); |
1147 return root.Append(data_path); | 1141 return root.Append(data_path); |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1309 prioritized_origin_database->InitializePrimaryOrigin( | 1303 prioritized_origin_database->InitializePrimaryOrigin( |
1310 isolated_origin_string); | 1304 isolated_origin_string); |
1311 | 1305 |
1312 return true; | 1306 return true; |
1313 } | 1307 } |
1314 | 1308 |
1315 base::File::Error ObfuscatedFileUtil::GenerateNewLocalPath( | 1309 base::File::Error ObfuscatedFileUtil::GenerateNewLocalPath( |
1316 SandboxDirectoryDatabase* db, | 1310 SandboxDirectoryDatabase* db, |
1317 FileSystemOperationContext* context, | 1311 FileSystemOperationContext* context, |
1318 const FileSystemURL& url, | 1312 const FileSystemURL& url, |
| 1313 base::FilePath* root, |
1319 base::FilePath* local_path) { | 1314 base::FilePath* local_path) { |
1320 DCHECK(local_path); | 1315 DCHECK(local_path); |
1321 int64 number; | 1316 int64 number; |
1322 if (!db || !db->GetNextInteger(&number)) | 1317 if (!db || !db->GetNextInteger(&number)) |
1323 return base::File::FILE_ERROR_FAILED; | 1318 return base::File::FILE_ERROR_FAILED; |
1324 | 1319 |
1325 base::File::Error error = base::File::FILE_OK; | 1320 base::File::Error error = base::File::FILE_OK; |
1326 base::FilePath new_local_path = GetDirectoryForURL(url, false, &error); | 1321 *root = GetDirectoryForURL(url, false, &error); |
1327 if (error != base::File::FILE_OK) | 1322 if (error != base::File::FILE_OK) |
1328 return base::File::FILE_ERROR_FAILED; | 1323 return error; |
1329 | 1324 |
1330 // We use the third- and fourth-to-last digits as the directory. | 1325 // We use the third- and fourth-to-last digits as the directory. |
1331 int64 directory_number = number % 10000 / 100; | 1326 int64 directory_number = number % 10000 / 100; |
1332 new_local_path = new_local_path.AppendASCII( | 1327 base::FilePath new_local_path = root->AppendASCII( |
1333 base::StringPrintf("%02" PRId64, directory_number)); | 1328 base::StringPrintf("%02" PRId64, directory_number)); |
1334 | 1329 |
1335 error = NativeFileUtil::CreateDirectory( | 1330 error = NativeFileUtil::CreateDirectory( |
1336 new_local_path, false /* exclusive */, false /* recursive */); | 1331 new_local_path, false /* exclusive */, false /* recursive */); |
1337 if (error != base::File::FILE_OK) | 1332 if (error != base::File::FILE_OK) |
1338 return error; | 1333 return error; |
1339 | 1334 |
1340 *local_path = | 1335 *local_path = |
1341 new_local_path.AppendASCII(base::StringPrintf("%08" PRId64, number)); | 1336 new_local_path.AppendASCII(base::StringPrintf("%08" PRId64, number)); |
1342 return base::File::FILE_OK; | 1337 return base::File::FILE_OK; |
1343 } | 1338 } |
1344 | 1339 |
1345 base::File::Error ObfuscatedFileUtil::CreateOrOpenInternal( | 1340 base::File ObfuscatedFileUtil::CreateOrOpenInternal( |
1346 FileSystemOperationContext* context, | 1341 FileSystemOperationContext* context, |
1347 const FileSystemURL& url, int file_flags, | 1342 const FileSystemURL& url, int file_flags) { |
1348 PlatformFile* file_handle, bool* created) { | 1343 DCHECK(!(file_flags & (base::File::FLAG_DELETE_ON_CLOSE | |
1349 DCHECK(!(file_flags & (base::PLATFORM_FILE_DELETE_ON_CLOSE | | 1344 base::File::FLAG_HIDDEN | base::File::FLAG_EXCLUSIVE_READ | |
1350 base::PLATFORM_FILE_HIDDEN | base::PLATFORM_FILE_EXCLUSIVE_READ | | 1345 base::File::FLAG_EXCLUSIVE_WRITE))); |
1351 base::PLATFORM_FILE_EXCLUSIVE_WRITE))); | |
1352 SandboxDirectoryDatabase* db = GetDirectoryDatabase(url, true); | 1346 SandboxDirectoryDatabase* db = GetDirectoryDatabase(url, true); |
1353 if (!db) | 1347 if (!db) |
1354 return base::File::FILE_ERROR_FAILED; | 1348 return base::File(base::File::FILE_ERROR_FAILED); |
1355 FileId file_id; | 1349 FileId file_id; |
1356 if (!db->GetFileWithPath(url.path(), &file_id)) { | 1350 if (!db->GetFileWithPath(url.path(), &file_id)) { |
1357 // The file doesn't exist. | 1351 // The file doesn't exist. |
1358 if (!(file_flags & (base::PLATFORM_FILE_CREATE | | 1352 if (!(file_flags & (base::File::FLAG_CREATE | |
1359 base::PLATFORM_FILE_CREATE_ALWAYS | base::PLATFORM_FILE_OPEN_ALWAYS))) | 1353 base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_OPEN_ALWAYS))) { |
1360 return base::File::FILE_ERROR_NOT_FOUND; | 1354 return base::File(base::File::FILE_ERROR_NOT_FOUND); |
| 1355 } |
1361 FileId parent_id; | 1356 FileId parent_id; |
1362 if (!db->GetFileWithPath(VirtualPath::DirName(url.path()), | 1357 if (!db->GetFileWithPath(VirtualPath::DirName(url.path()), &parent_id)) |
1363 &parent_id)) | 1358 return base::File(base::File::FILE_ERROR_NOT_FOUND); |
1364 return base::File::FILE_ERROR_NOT_FOUND; | |
1365 FileInfo file_info; | 1359 FileInfo file_info; |
1366 InitFileInfo(&file_info, parent_id, | 1360 InitFileInfo(&file_info, parent_id, |
1367 VirtualPath::BaseName(url.path()).value()); | 1361 VirtualPath::BaseName(url.path()).value()); |
1368 | 1362 |
1369 int64 growth = UsageForPath(file_info.name.size()); | 1363 int64 growth = UsageForPath(file_info.name.size()); |
1370 if (!AllocateQuota(context, growth)) | 1364 if (!AllocateQuota(context, growth)) |
1371 return base::File::FILE_ERROR_NO_SPACE; | 1365 return base::File(base::File::FILE_ERROR_NO_SPACE); |
1372 base::File::Error error = CreateFile( | 1366 base::File file = CreateAndOpenFile(context, url, &file_info, file_flags); |
1373 context, base::FilePath(), | 1367 if (file.IsValid()) { |
1374 url, &file_info, file_flags, file_handle); | |
1375 if (created && base::File::FILE_OK == error) { | |
1376 *created = true; | |
1377 UpdateUsage(context, url, growth); | 1368 UpdateUsage(context, url, growth); |
1378 context->change_observers()->Notify( | 1369 context->change_observers()->Notify( |
1379 &FileChangeObserver::OnCreateFile, MakeTuple(url)); | 1370 &FileChangeObserver::OnCreateFile, MakeTuple(url)); |
1380 } | 1371 } |
1381 return error; | 1372 return file.Pass(); |
1382 } | 1373 } |
1383 | 1374 |
1384 if (file_flags & base::PLATFORM_FILE_CREATE) | 1375 if (file_flags & base::File::FLAG_CREATE) |
1385 return base::File::FILE_ERROR_EXISTS; | 1376 return base::File(base::File::FILE_ERROR_EXISTS); |
1386 | 1377 |
1387 base::File::Info platform_file_info; | 1378 base::File::Info platform_file_info; |
1388 base::FilePath local_path; | 1379 base::FilePath local_path; |
1389 FileInfo file_info; | 1380 FileInfo file_info; |
1390 base::File::Error error = GetFileInfoInternal( | 1381 base::File::Error error = GetFileInfoInternal( |
1391 db, context, url, file_id, &file_info, &platform_file_info, &local_path); | 1382 db, context, url, file_id, &file_info, &platform_file_info, &local_path); |
1392 if (error != base::File::FILE_OK) | 1383 if (error != base::File::FILE_OK) |
1393 return error; | 1384 return base::File(error); |
1394 if (file_info.is_directory()) | 1385 if (file_info.is_directory()) |
1395 return base::File::FILE_ERROR_NOT_A_FILE; | 1386 return base::File(base::File::FILE_ERROR_NOT_A_FILE); |
1396 | 1387 |
1397 int64 delta = 0; | 1388 int64 delta = 0; |
1398 if (file_flags & (base::PLATFORM_FILE_CREATE_ALWAYS | | 1389 if (file_flags & (base::File::FLAG_CREATE_ALWAYS | |
1399 base::PLATFORM_FILE_OPEN_TRUNCATED)) { | 1390 base::File::FLAG_OPEN_TRUNCATED)) { |
1400 // The file exists and we're truncating. | 1391 // The file exists and we're truncating. |
1401 delta = -platform_file_info.size; | 1392 delta = -platform_file_info.size; |
1402 AllocateQuota(context, delta); | 1393 AllocateQuota(context, delta); |
1403 } | 1394 } |
1404 | 1395 |
1405 // TODO(rvargas): make FileSystemFileUtil use base::File. | |
1406 base::File file = NativeFileUtil::CreateOrOpen(local_path, file_flags); | 1396 base::File file = NativeFileUtil::CreateOrOpen(local_path, file_flags); |
1407 if (!file.IsValid()) { | 1397 if (!file.IsValid()) { |
1408 error = file.error_details(); | 1398 error = file.error_details(); |
1409 if (error == base::File::FILE_ERROR_NOT_FOUND) { | 1399 if (error == base::File::FILE_ERROR_NOT_FOUND) { |
1410 // TODO(tzik): Also invalidate on-memory usage cache in UsageTracker. | 1400 // TODO(tzik): Also invalidate on-memory usage cache in UsageTracker. |
1411 // TODO(tzik): Delete database entry after ensuring the file lost. | 1401 // TODO(tzik): Delete database entry after ensuring the file lost. |
1412 InvalidateUsageCache(context, url.origin(), url.type()); | 1402 InvalidateUsageCache(context, url.origin(), url.type()); |
1413 LOG(WARNING) << "Lost a backing file."; | 1403 LOG(WARNING) << "Lost a backing file."; |
1414 error = base::File::FILE_ERROR_FAILED; | 1404 return base::File(base::File::FILE_ERROR_FAILED); |
1415 } | 1405 } |
1416 return error; | 1406 return file.Pass(); |
1417 } | 1407 } |
1418 | 1408 |
1419 *created = file.created(); | |
1420 *file_handle = file.TakePlatformFile(); | |
1421 | |
1422 // If truncating we need to update the usage. | 1409 // If truncating we need to update the usage. |
1423 if (delta) { | 1410 if (delta) { |
1424 UpdateUsage(context, url, delta); | 1411 UpdateUsage(context, url, delta); |
1425 context->change_observers()->Notify( | 1412 context->change_observers()->Notify( |
1426 &FileChangeObserver::OnModifyFile, MakeTuple(url)); | 1413 &FileChangeObserver::OnModifyFile, MakeTuple(url)); |
1427 } | 1414 } |
1428 return base::File::FILE_OK; | 1415 return file.Pass(); |
1429 } | 1416 } |
1430 | 1417 |
1431 bool ObfuscatedFileUtil::HasIsolatedStorage(const GURL& origin) { | 1418 bool ObfuscatedFileUtil::HasIsolatedStorage(const GURL& origin) { |
1432 return special_storage_policy_.get() && | 1419 return special_storage_policy_.get() && |
1433 special_storage_policy_->HasIsolatedStorage(origin); | 1420 special_storage_policy_->HasIsolatedStorage(origin); |
1434 } | 1421 } |
1435 | 1422 |
1436 } // namespace fileapi | 1423 } // namespace fileapi |
OLD | NEW |