| 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 |