Chromium Code Reviews| 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::Error ObfuscatedFileUtil::GetDbRootAndLocalPath( | |
| 1039 FileSystemOperationContext* context, | |
| 1040 const FileSystemURL& dest_url, | |
| 1041 SandboxDirectoryDatabase** db, | |
| 1042 base::FilePath* root, | |
| 1043 base::FilePath* local_path) { | |
| 1044 *db = GetDirectoryDatabase(dest_url, true); | |
|
kinuko
2014/05/12 05:39:57
I'd probably remove this part from this method but
rvargas (doing something else)
2014/05/12 23:39:59
Done.
| |
| 1045 | |
| 1046 base::File::Error error = base::File::FILE_OK; | |
| 1047 *root = GetDirectoryForURL(dest_url, false, &error); | |
| 1048 if (error != base::File::FILE_OK) | |
| 1049 return error; | |
| 1050 | |
| 1051 return GenerateNewLocalPath(*db, context, dest_url, local_path); | |
| 1052 } | |
| 1053 | |
| 1054 base::File::Error ObfuscatedFileUtil::PostCreateFile( | |
|
kinuko
2014/05/12 05:39:57
The term 'Post' is a bit confusing (we often use i
rvargas (doing something else)
2014/05/12 23:39:59
Done. (db is now the first in_out argument)
| |
| 1055 const base::FilePath& root, | |
| 1056 const base::FilePath& local_path, | |
| 1057 FileInfo* dest_file_info, | |
| 1058 SandboxDirectoryDatabase* db) { | |
| 1059 // This removes the root, including the trailing slash, leaving a relative | |
| 1060 // path. | |
| 1061 dest_file_info->data_path = base::FilePath( | |
| 1062 local_path.value().substr(root.value().length() + 1)); | |
| 1063 | |
| 1064 FileId file_id; | |
| 1065 base::File::Error error = db->AddFileInfo(*dest_file_info, &file_id); | |
| 1066 if (error != base::File::FILE_OK) | |
| 1067 return error; | |
| 1068 | |
| 1069 TouchDirectory(db, dest_file_info->parent_id); | |
| 1070 return base::File::FILE_OK; | |
| 1071 } | |
| 1072 | |
| 1073 base::File ObfuscatedFileUtil::CreateAndOpenFile( | |
| 1074 FileSystemOperationContext* context, | |
| 1075 const FileSystemURL& dest_url, | |
| 1076 FileInfo* dest_file_info, int file_flags) { | |
| 1077 SandboxDirectoryDatabase* db; | |
| 1078 base::FilePath root, dest_local_path; | |
| 1079 base::File::Error error = GetDbRootAndLocalPath(context, dest_url, &db, &root, | |
| 1080 &dest_local_path); | |
| 1081 if (error != base::File::FILE_OK) | |
| 1082 return base::File(error); | |
| 1083 | |
| 1084 if (base::PathExists(dest_local_path)) { | |
| 1085 if (!base::DeleteFile(dest_local_path, true /* recursive */)) | |
| 1086 return base::File(base::File::FILE_ERROR_FAILED); | |
| 1087 LOG(WARNING) << "A stray file detected"; | |
| 1088 InvalidateUsageCache(context, dest_url.origin(), dest_url.type()); | |
| 1089 } | |
| 1090 | |
| 1091 base::File file = NativeFileUtil::CreateOrOpen(dest_local_path, file_flags); | |
| 1092 if (!file.IsValid()) | |
| 1093 return file.Pass(); | |
| 1094 | |
| 1095 if (!file.created()) { | |
| 1096 file.Close(); | |
| 1097 base::DeleteFile(dest_local_path, false /* recursive */); | |
| 1098 return base::File(base::File::FILE_ERROR_FAILED); | |
| 1099 } | |
| 1100 | |
| 1101 error = PostCreateFile(root, dest_local_path, dest_file_info, db); | |
| 1102 if (error != base::File::FILE_OK) { | |
| 1103 file.Close(); | |
| 1104 base::DeleteFile(dest_local_path, false /* recursive */); | |
| 1105 return base::File(error); | |
| 1106 } | |
| 1107 | |
| 1108 return file.Pass(); | |
| 1109 } | |
| 1110 | |
| 1053 base::File::Error ObfuscatedFileUtil::CreateFile( | 1111 base::File::Error ObfuscatedFileUtil::CreateFile( |
| 1054 FileSystemOperationContext* context, | 1112 FileSystemOperationContext* context, |
| 1055 const base::FilePath& src_file_path, | 1113 const base::FilePath& src_file_path, |
| 1056 const FileSystemURL& dest_url, | 1114 const FileSystemURL& dest_url, |
| 1057 FileInfo* dest_file_info, int file_flags, PlatformFile* handle) { | 1115 FileInfo* dest_file_info) { |
| 1058 if (handle) | 1116 SandboxDirectoryDatabase* db; |
| 1059 *handle = base::kInvalidPlatformFileValue; | 1117 base::FilePath root, dest_local_path; |
| 1060 SandboxDirectoryDatabase* db = GetDirectoryDatabase(dest_url, true); | 1118 base::File::Error error = GetDbRootAndLocalPath(context, dest_url, &db, &root, |
| 1061 | 1119 &dest_local_path); |
| 1062 base::File::Error error = base::File::FILE_OK; | |
| 1063 base::FilePath root = GetDirectoryForURL(dest_url, false, &error); | |
| 1064 if (error != base::File::FILE_OK) | |
| 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) | 1120 if (error != base::File::FILE_OK) |
| 1070 return error; | 1121 return error; |
| 1071 | 1122 |
| 1072 bool created = false; | 1123 bool created = false; |
| 1073 if (!src_file_path.empty()) { | 1124 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)) { | 1125 if (base::PathExists(dest_local_path)) { |
| 1084 if (!base::DeleteFile(dest_local_path, true /* recursive */)) | 1126 if (!base::DeleteFile(dest_local_path, true /* recursive */)) |
| 1085 return base::File::FILE_ERROR_FAILED; | 1127 return base::File::FILE_ERROR_FAILED; |
| 1086 LOG(WARNING) << "A stray file detected"; | 1128 LOG(WARNING) << "A stray file detected"; |
| 1087 InvalidateUsageCache(context, dest_url.origin(), dest_url.type()); | 1129 InvalidateUsageCache(context, dest_url.origin(), dest_url.type()); |
| 1088 } | 1130 } |
| 1089 | 1131 |
| 1090 if (handle) { | 1132 error = NativeFileUtil::EnsureFileExists(dest_local_path, &created); |
| 1091 // TODO(rvargas): Remove PlatformFile from this code. | 1133 } else { |
| 1092 base::File file = | 1134 error = NativeFileUtil::CopyOrMoveFile( |
| 1093 NativeFileUtil::CreateOrOpen(dest_local_path, file_flags); | 1135 src_file_path, dest_local_path, |
| 1094 if (file.IsValid()) { | 1136 FileSystemOperation::OPTION_NONE, |
| 1095 created = file.created(); | 1137 fileapi::NativeFileUtil::CopyOrMoveModeForDestination(dest_url, |
| 1096 *handle = file.TakePlatformFile(); | 1138 true /* copy */)); |
| 1097 error = base::File::FILE_OK; | 1139 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 } | 1140 } |
| 1107 if (error != base::File::FILE_OK) | 1141 if (error != base::File::FILE_OK) |
| 1108 return error; | 1142 return error; |
| 1143 if (!created) | |
| 1144 return base::File::FILE_ERROR_FAILED; | |
| 1109 | 1145 |
| 1110 if (!created) { | 1146 return PostCreateFile(root, dest_local_path, dest_file_info, db); |
| 1111 if (handle) { | |
| 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 | 1147 |
| 1120 // This removes the root, including the trailing slash, leaving a relative | |
| 1121 // path. | |
| 1122 dest_file_info->data_path = base::FilePath( | |
| 1123 dest_local_path.value().substr(root.value().length() + 1)); | |
| 1124 | |
| 1125 FileId file_id; | |
| 1126 error = db->AddFileInfo(*dest_file_info, &file_id); | |
| 1127 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; | |
| 1135 } | |
| 1136 TouchDirectory(db, dest_file_info->parent_id); | |
| 1137 | |
| 1138 return base::File::FILE_OK; | |
| 1139 } | 1148 } |
| 1140 | 1149 |
| 1141 base::FilePath ObfuscatedFileUtil::DataPathToLocalPath( | 1150 base::FilePath ObfuscatedFileUtil::DataPathToLocalPath( |
| 1142 const FileSystemURL& url, const base::FilePath& data_path) { | 1151 const FileSystemURL& url, const base::FilePath& data_path) { |
| 1143 base::File::Error error = base::File::FILE_OK; | 1152 base::File::Error error = base::File::FILE_OK; |
| 1144 base::FilePath root = GetDirectoryForURL(url, false, &error); | 1153 base::FilePath root = GetDirectoryForURL(url, false, &error); |
| 1145 if (error != base::File::FILE_OK) | 1154 if (error != base::File::FILE_OK) |
| 1146 return base::FilePath(); | 1155 return base::FilePath(); |
| 1147 return root.Append(data_path); | 1156 return root.Append(data_path); |
| 1148 } | 1157 } |
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1335 error = NativeFileUtil::CreateDirectory( | 1344 error = NativeFileUtil::CreateDirectory( |
| 1336 new_local_path, false /* exclusive */, false /* recursive */); | 1345 new_local_path, false /* exclusive */, false /* recursive */); |
| 1337 if (error != base::File::FILE_OK) | 1346 if (error != base::File::FILE_OK) |
| 1338 return error; | 1347 return error; |
| 1339 | 1348 |
| 1340 *local_path = | 1349 *local_path = |
| 1341 new_local_path.AppendASCII(base::StringPrintf("%08" PRId64, number)); | 1350 new_local_path.AppendASCII(base::StringPrintf("%08" PRId64, number)); |
| 1342 return base::File::FILE_OK; | 1351 return base::File::FILE_OK; |
| 1343 } | 1352 } |
| 1344 | 1353 |
| 1345 base::File::Error ObfuscatedFileUtil::CreateOrOpenInternal( | 1354 base::File ObfuscatedFileUtil::CreateOrOpenInternal( |
| 1346 FileSystemOperationContext* context, | 1355 FileSystemOperationContext* context, |
| 1347 const FileSystemURL& url, int file_flags, | 1356 const FileSystemURL& url, int file_flags) { |
| 1348 PlatformFile* file_handle, bool* created) { | 1357 DCHECK(!(file_flags & (base::File::FLAG_DELETE_ON_CLOSE | |
| 1349 DCHECK(!(file_flags & (base::PLATFORM_FILE_DELETE_ON_CLOSE | | 1358 base::File::FLAG_HIDDEN | base::File::FLAG_EXCLUSIVE_READ | |
| 1350 base::PLATFORM_FILE_HIDDEN | base::PLATFORM_FILE_EXCLUSIVE_READ | | 1359 base::File::FLAG_EXCLUSIVE_WRITE))); |
| 1351 base::PLATFORM_FILE_EXCLUSIVE_WRITE))); | |
| 1352 SandboxDirectoryDatabase* db = GetDirectoryDatabase(url, true); | 1360 SandboxDirectoryDatabase* db = GetDirectoryDatabase(url, true); |
| 1353 if (!db) | 1361 if (!db) |
| 1354 return base::File::FILE_ERROR_FAILED; | 1362 return base::File(base::File::FILE_ERROR_FAILED); |
| 1355 FileId file_id; | 1363 FileId file_id; |
| 1356 if (!db->GetFileWithPath(url.path(), &file_id)) { | 1364 if (!db->GetFileWithPath(url.path(), &file_id)) { |
| 1357 // The file doesn't exist. | 1365 // The file doesn't exist. |
| 1358 if (!(file_flags & (base::PLATFORM_FILE_CREATE | | 1366 if (!(file_flags & (base::File::FLAG_CREATE | |
| 1359 base::PLATFORM_FILE_CREATE_ALWAYS | base::PLATFORM_FILE_OPEN_ALWAYS))) | 1367 base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_OPEN_ALWAYS))) { |
| 1360 return base::File::FILE_ERROR_NOT_FOUND; | 1368 return base::File(base::File::FILE_ERROR_NOT_FOUND); |
| 1369 } | |
| 1361 FileId parent_id; | 1370 FileId parent_id; |
| 1362 if (!db->GetFileWithPath(VirtualPath::DirName(url.path()), | 1371 if (!db->GetFileWithPath(VirtualPath::DirName(url.path()), &parent_id)) |
| 1363 &parent_id)) | 1372 return base::File(base::File::FILE_ERROR_NOT_FOUND); |
| 1364 return base::File::FILE_ERROR_NOT_FOUND; | |
| 1365 FileInfo file_info; | 1373 FileInfo file_info; |
| 1366 InitFileInfo(&file_info, parent_id, | 1374 InitFileInfo(&file_info, parent_id, |
| 1367 VirtualPath::BaseName(url.path()).value()); | 1375 VirtualPath::BaseName(url.path()).value()); |
| 1368 | 1376 |
| 1369 int64 growth = UsageForPath(file_info.name.size()); | 1377 int64 growth = UsageForPath(file_info.name.size()); |
| 1370 if (!AllocateQuota(context, growth)) | 1378 if (!AllocateQuota(context, growth)) |
| 1371 return base::File::FILE_ERROR_NO_SPACE; | 1379 return base::File(base::File::FILE_ERROR_NO_SPACE); |
| 1372 base::File::Error error = CreateFile( | 1380 base::File file = CreateAndOpenFile(context, url, &file_info, file_flags); |
| 1373 context, base::FilePath(), | 1381 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); | 1382 UpdateUsage(context, url, growth); |
| 1378 context->change_observers()->Notify( | 1383 context->change_observers()->Notify( |
| 1379 &FileChangeObserver::OnCreateFile, MakeTuple(url)); | 1384 &FileChangeObserver::OnCreateFile, MakeTuple(url)); |
| 1380 } | 1385 } |
| 1381 return error; | 1386 return file.Pass(); |
| 1382 } | 1387 } |
| 1383 | 1388 |
| 1384 if (file_flags & base::PLATFORM_FILE_CREATE) | 1389 if (file_flags & base::File::FLAG_CREATE) |
| 1385 return base::File::FILE_ERROR_EXISTS; | 1390 return base::File(base::File::FILE_ERROR_EXISTS); |
| 1386 | 1391 |
| 1387 base::File::Info platform_file_info; | 1392 base::File::Info platform_file_info; |
| 1388 base::FilePath local_path; | 1393 base::FilePath local_path; |
| 1389 FileInfo file_info; | 1394 FileInfo file_info; |
| 1390 base::File::Error error = GetFileInfoInternal( | 1395 base::File::Error error = GetFileInfoInternal( |
| 1391 db, context, url, file_id, &file_info, &platform_file_info, &local_path); | 1396 db, context, url, file_id, &file_info, &platform_file_info, &local_path); |
| 1392 if (error != base::File::FILE_OK) | 1397 if (error != base::File::FILE_OK) |
| 1393 return error; | 1398 return base::File(error); |
| 1394 if (file_info.is_directory()) | 1399 if (file_info.is_directory()) |
| 1395 return base::File::FILE_ERROR_NOT_A_FILE; | 1400 return base::File(base::File::FILE_ERROR_NOT_A_FILE); |
| 1396 | 1401 |
| 1397 int64 delta = 0; | 1402 int64 delta = 0; |
| 1398 if (file_flags & (base::PLATFORM_FILE_CREATE_ALWAYS | | 1403 if (file_flags & (base::File::FLAG_CREATE_ALWAYS | |
| 1399 base::PLATFORM_FILE_OPEN_TRUNCATED)) { | 1404 base::File::FLAG_OPEN_TRUNCATED)) { |
| 1400 // The file exists and we're truncating. | 1405 // The file exists and we're truncating. |
| 1401 delta = -platform_file_info.size; | 1406 delta = -platform_file_info.size; |
| 1402 AllocateQuota(context, delta); | 1407 AllocateQuota(context, delta); |
| 1403 } | 1408 } |
| 1404 | 1409 |
| 1405 // TODO(rvargas): make FileSystemFileUtil use base::File. | |
| 1406 base::File file = NativeFileUtil::CreateOrOpen(local_path, file_flags); | 1410 base::File file = NativeFileUtil::CreateOrOpen(local_path, file_flags); |
| 1407 if (!file.IsValid()) { | 1411 if (!file.IsValid()) { |
| 1408 error = file.error_details(); | 1412 error = file.error_details(); |
| 1409 if (error == base::File::FILE_ERROR_NOT_FOUND) { | 1413 if (error == base::File::FILE_ERROR_NOT_FOUND) { |
| 1410 // TODO(tzik): Also invalidate on-memory usage cache in UsageTracker. | 1414 // TODO(tzik): Also invalidate on-memory usage cache in UsageTracker. |
| 1411 // TODO(tzik): Delete database entry after ensuring the file lost. | 1415 // TODO(tzik): Delete database entry after ensuring the file lost. |
| 1412 InvalidateUsageCache(context, url.origin(), url.type()); | 1416 InvalidateUsageCache(context, url.origin(), url.type()); |
| 1413 LOG(WARNING) << "Lost a backing file."; | 1417 LOG(WARNING) << "Lost a backing file."; |
| 1414 error = base::File::FILE_ERROR_FAILED; | 1418 return base::File(base::File::FILE_ERROR_FAILED); |
| 1415 } | 1419 } |
| 1416 return error; | 1420 return file.Pass(); |
| 1417 } | 1421 } |
| 1418 | 1422 |
| 1419 *created = file.created(); | |
| 1420 *file_handle = file.TakePlatformFile(); | |
| 1421 | |
| 1422 // If truncating we need to update the usage. | 1423 // If truncating we need to update the usage. |
| 1423 if (delta) { | 1424 if (delta) { |
| 1424 UpdateUsage(context, url, delta); | 1425 UpdateUsage(context, url, delta); |
| 1425 context->change_observers()->Notify( | 1426 context->change_observers()->Notify( |
| 1426 &FileChangeObserver::OnModifyFile, MakeTuple(url)); | 1427 &FileChangeObserver::OnModifyFile, MakeTuple(url)); |
| 1427 } | 1428 } |
| 1428 return base::File::FILE_OK; | 1429 return file.Pass(); |
| 1429 } | 1430 } |
| 1430 | 1431 |
| 1431 bool ObfuscatedFileUtil::HasIsolatedStorage(const GURL& origin) { | 1432 bool ObfuscatedFileUtil::HasIsolatedStorage(const GURL& origin) { |
| 1432 return special_storage_policy_.get() && | 1433 return special_storage_policy_.get() && |
| 1433 special_storage_policy_->HasIsolatedStorage(origin); | 1434 special_storage_policy_->HasIsolatedStorage(origin); |
| 1434 } | 1435 } |
| 1435 | 1436 |
| 1436 } // namespace fileapi | 1437 } // namespace fileapi |
| OLD | NEW |