diff options
| author | 2016-11-27 18:56:56 -0500 | |
|---|---|---|
| committer | 2016-11-27 18:56:56 -0500 | |
| commit | 4ba5acdaff19f5334b86e86c324763d4e9b969b0 (patch) | |
| tree | 408343a46858bcde292744d89fc6b3dadd9a54b0 /src/core/hle | |
| parent | Merge pull request #2218 from Subv/stencil_lines (diff) | |
| parent | tests: add a work-around for macOS linking error (diff) | |
| download | yuzu-4ba5acdaff19f5334b86e86c324763d4e9b969b0.tar.gz yuzu-4ba5acdaff19f5334b86e86c324763d4e9b969b0.tar.xz yuzu-4ba5acdaff19f5334b86e86c324763d4e9b969b0.zip | |
Merge pull request #2132 from wwylele/fix-fs-err
Correct FS error codes & add path boundary checks
Diffstat (limited to 'src/core/hle')
| -rw-r--r-- | src/core/hle/result.h | 9 | ||||
| -rw-r--r-- | src/core/hle/service/cfg/cfg.cpp | 9 | ||||
| -rw-r--r-- | src/core/hle/service/fs/archive.cpp | 58 | ||||
| -rw-r--r-- | src/core/hle/service/fs/archive.h | 2 | ||||
| -rw-r--r-- | src/core/hle/service/ptm/ptm.cpp | 2 |
5 files changed, 37 insertions, 43 deletions
diff --git a/src/core/hle/result.h b/src/core/hle/result.h index 7f8d8e00d..f7356f9d8 100644 --- a/src/core/hle/result.h +++ b/src/core/hle/result.h | |||
| @@ -20,15 +20,24 @@ enum class ErrorDescription : u32 { | |||
| 20 | OS_InvalidBufferDescriptor = 48, | 20 | OS_InvalidBufferDescriptor = 48, |
| 21 | WrongAddress = 53, | 21 | WrongAddress = 53, |
| 22 | FS_ArchiveNotMounted = 101, | 22 | FS_ArchiveNotMounted = 101, |
| 23 | FS_FileNotFound = 112, | ||
| 24 | FS_PathNotFound = 113, | ||
| 23 | FS_NotFound = 120, | 25 | FS_NotFound = 120, |
| 26 | FS_FileAlreadyExists = 180, | ||
| 27 | FS_DirectoryAlreadyExists = 185, | ||
| 24 | FS_AlreadyExists = 190, | 28 | FS_AlreadyExists = 190, |
| 25 | FS_InvalidOpenFlags = 230, | 29 | FS_InvalidOpenFlags = 230, |
| 30 | FS_DirectoryNotEmpty = 240, | ||
| 26 | FS_NotAFile = 250, | 31 | FS_NotAFile = 250, |
| 27 | FS_NotFormatted = 340, ///< This is used by the FS service when creating a SaveData archive | 32 | FS_NotFormatted = 340, ///< This is used by the FS service when creating a SaveData archive |
| 28 | OutofRangeOrMisalignedAddress = | 33 | OutofRangeOrMisalignedAddress = |
| 29 | 513, // TODO(purpasmart): Check if this name fits its actual usage | 34 | 513, // TODO(purpasmart): Check if this name fits its actual usage |
| 30 | GPU_FirstInitialization = 519, | 35 | GPU_FirstInitialization = 519, |
| 36 | FS_InvalidReadFlag = 700, | ||
| 31 | FS_InvalidPath = 702, | 37 | FS_InvalidPath = 702, |
| 38 | FS_WriteBeyondEnd = 705, | ||
| 39 | FS_UnsupportedOpenFlags = 760, | ||
| 40 | FS_UnexpectedFileOrDirectory = 770, | ||
| 32 | InvalidSection = 1000, | 41 | InvalidSection = 1000, |
| 33 | TooLarge = 1001, | 42 | TooLarge = 1001, |
| 34 | NotAuthorized = 1002, | 43 | NotAuthorized = 1002, |
diff --git a/src/core/hle/service/cfg/cfg.cpp b/src/core/hle/service/cfg/cfg.cpp index d3d0f3b55..d554c3f54 100644 --- a/src/core/hle/service/cfg/cfg.cpp +++ b/src/core/hle/service/cfg/cfg.cpp | |||
| @@ -360,7 +360,7 @@ ResultCode CreateConfigInfoBlk(u32 block_id, u16 size, u16 flags, const void* da | |||
| 360 | } | 360 | } |
| 361 | 361 | ||
| 362 | ResultCode DeleteConfigNANDSaveFile() { | 362 | ResultCode DeleteConfigNANDSaveFile() { |
| 363 | FileSys::Path path("config"); | 363 | FileSys::Path path("/config"); |
| 364 | return Service::FS::DeleteFileFromArchive(cfg_system_save_data_archive, path); | 364 | return Service::FS::DeleteFileFromArchive(cfg_system_save_data_archive, path); |
| 365 | } | 365 | } |
| 366 | 366 | ||
| @@ -369,7 +369,7 @@ ResultCode UpdateConfigNANDSavegame() { | |||
| 369 | mode.write_flag.Assign(1); | 369 | mode.write_flag.Assign(1); |
| 370 | mode.create_flag.Assign(1); | 370 | mode.create_flag.Assign(1); |
| 371 | 371 | ||
| 372 | FileSys::Path path("config"); | 372 | FileSys::Path path("/config"); |
| 373 | 373 | ||
| 374 | auto config_result = Service::FS::OpenFileFromArchive(cfg_system_save_data_archive, path, mode); | 374 | auto config_result = Service::FS::OpenFileFromArchive(cfg_system_save_data_archive, path, mode); |
| 375 | ASSERT_MSG(config_result.Succeeded(), "could not open file"); | 375 | ASSERT_MSG(config_result.Succeeded(), "could not open file"); |
| @@ -383,8 +383,9 @@ ResultCode UpdateConfigNANDSavegame() { | |||
| 383 | ResultCode FormatConfig() { | 383 | ResultCode FormatConfig() { |
| 384 | ResultCode res = DeleteConfigNANDSaveFile(); | 384 | ResultCode res = DeleteConfigNANDSaveFile(); |
| 385 | // The delete command fails if the file doesn't exist, so we have to check that too | 385 | // The delete command fails if the file doesn't exist, so we have to check that too |
| 386 | if (!res.IsSuccess() && res.description != ErrorDescription::FS_NotFound) | 386 | if (!res.IsSuccess() && res.description != ErrorDescription::FS_FileNotFound) { |
| 387 | return res; | 387 | return res; |
| 388 | } | ||
| 388 | // Delete the old data | 389 | // Delete the old data |
| 389 | cfg_config_file_buffer.fill(0); | 390 | cfg_config_file_buffer.fill(0); |
| 390 | // Create the header | 391 | // Create the header |
| @@ -510,7 +511,7 @@ ResultCode LoadConfigNANDSaveFile() { | |||
| 510 | 511 | ||
| 511 | cfg_system_save_data_archive = *archive_result; | 512 | cfg_system_save_data_archive = *archive_result; |
| 512 | 513 | ||
| 513 | FileSys::Path config_path("config"); | 514 | FileSys::Path config_path("/config"); |
| 514 | FileSys::Mode open_mode = {}; | 515 | FileSys::Mode open_mode = {}; |
| 515 | open_mode.read_flag.Assign(1); | 516 | open_mode.read_flag.Assign(1); |
| 516 | 517 | ||
diff --git a/src/core/hle/service/fs/archive.cpp b/src/core/hle/service/fs/archive.cpp index 7f9696bfb..4c29784e8 100644 --- a/src/core/hle/service/fs/archive.cpp +++ b/src/core/hle/service/fs/archive.cpp | |||
| @@ -15,9 +15,10 @@ | |||
| 15 | #include "common/logging/log.h" | 15 | #include "common/logging/log.h" |
| 16 | #include "core/file_sys/archive_backend.h" | 16 | #include "core/file_sys/archive_backend.h" |
| 17 | #include "core/file_sys/archive_extsavedata.h" | 17 | #include "core/file_sys/archive_extsavedata.h" |
| 18 | #include "core/file_sys/archive_ncch.h" | ||
| 18 | #include "core/file_sys/archive_savedata.h" | 19 | #include "core/file_sys/archive_savedata.h" |
| 19 | #include "core/file_sys/archive_savedatacheck.h" | ||
| 20 | #include "core/file_sys/archive_sdmc.h" | 20 | #include "core/file_sys/archive_sdmc.h" |
| 21 | #include "core/file_sys/archive_sdmcwriteonly.h" | ||
| 21 | #include "core/file_sys/archive_systemsavedata.h" | 22 | #include "core/file_sys/archive_systemsavedata.h" |
| 22 | #include "core/file_sys/directory_backend.h" | 23 | #include "core/file_sys/directory_backend.h" |
| 23 | #include "core/file_sys/file_backend.h" | 24 | #include "core/file_sys/file_backend.h" |
| @@ -338,17 +339,11 @@ ResultCode RenameFileBetweenArchives(ArchiveHandle src_archive_handle, | |||
| 338 | return ERR_INVALID_ARCHIVE_HANDLE; | 339 | return ERR_INVALID_ARCHIVE_HANDLE; |
| 339 | 340 | ||
| 340 | if (src_archive == dest_archive) { | 341 | if (src_archive == dest_archive) { |
| 341 | if (src_archive->RenameFile(src_path, dest_path)) | 342 | return src_archive->RenameFile(src_path, dest_path); |
| 342 | return RESULT_SUCCESS; | ||
| 343 | } else { | 343 | } else { |
| 344 | // TODO: Implement renaming across archives | 344 | // TODO: Implement renaming across archives |
| 345 | return UnimplementedFunction(ErrorModule::FS); | 345 | return UnimplementedFunction(ErrorModule::FS); |
| 346 | } | 346 | } |
| 347 | |||
| 348 | // TODO(yuriks): This code probably isn't right, it'll return a Status even if the file didn't | ||
| 349 | // exist or similar. Verify. | ||
| 350 | return ResultCode(ErrorDescription::NoData, ErrorModule::FS, // TODO: verify description | ||
| 351 | ErrorSummary::NothingHappened, ErrorLevel::Status); | ||
| 352 | } | 347 | } |
| 353 | 348 | ||
| 354 | ResultCode DeleteDirectoryFromArchive(ArchiveHandle archive_handle, const FileSys::Path& path) { | 349 | ResultCode DeleteDirectoryFromArchive(ArchiveHandle archive_handle, const FileSys::Path& path) { |
| @@ -356,10 +351,7 @@ ResultCode DeleteDirectoryFromArchive(ArchiveHandle archive_handle, const FileSy | |||
| 356 | if (archive == nullptr) | 351 | if (archive == nullptr) |
| 357 | return ERR_INVALID_ARCHIVE_HANDLE; | 352 | return ERR_INVALID_ARCHIVE_HANDLE; |
| 358 | 353 | ||
| 359 | if (archive->DeleteDirectory(path)) | 354 | return archive->DeleteDirectory(path); |
| 360 | return RESULT_SUCCESS; | ||
| 361 | return ResultCode(ErrorDescription::NoData, ErrorModule::FS, // TODO: verify description | ||
| 362 | ErrorSummary::Canceled, ErrorLevel::Status); | ||
| 363 | } | 355 | } |
| 364 | 356 | ||
| 365 | ResultCode DeleteDirectoryRecursivelyFromArchive(ArchiveHandle archive_handle, | 357 | ResultCode DeleteDirectoryRecursivelyFromArchive(ArchiveHandle archive_handle, |
| @@ -368,10 +360,7 @@ ResultCode DeleteDirectoryRecursivelyFromArchive(ArchiveHandle archive_handle, | |||
| 368 | if (archive == nullptr) | 360 | if (archive == nullptr) |
| 369 | return ERR_INVALID_ARCHIVE_HANDLE; | 361 | return ERR_INVALID_ARCHIVE_HANDLE; |
| 370 | 362 | ||
| 371 | if (archive->DeleteDirectoryRecursively(path)) | 363 | return archive->DeleteDirectoryRecursively(path); |
| 372 | return RESULT_SUCCESS; | ||
| 373 | return ResultCode(ErrorDescription::NoData, ErrorModule::FS, // TODO: verify description | ||
| 374 | ErrorSummary::Canceled, ErrorLevel::Status); | ||
| 375 | } | 364 | } |
| 376 | 365 | ||
| 377 | ResultCode CreateFileInArchive(ArchiveHandle archive_handle, const FileSys::Path& path, | 366 | ResultCode CreateFileInArchive(ArchiveHandle archive_handle, const FileSys::Path& path, |
| @@ -388,10 +377,7 @@ ResultCode CreateDirectoryFromArchive(ArchiveHandle archive_handle, const FileSy | |||
| 388 | if (archive == nullptr) | 377 | if (archive == nullptr) |
| 389 | return ERR_INVALID_ARCHIVE_HANDLE; | 378 | return ERR_INVALID_ARCHIVE_HANDLE; |
| 390 | 379 | ||
| 391 | if (archive->CreateDirectory(path)) | 380 | return archive->CreateDirectory(path); |
| 392 | return RESULT_SUCCESS; | ||
| 393 | return ResultCode(ErrorDescription::NoData, ErrorModule::FS, // TODO: verify description | ||
| 394 | ErrorSummary::Canceled, ErrorLevel::Status); | ||
| 395 | } | 381 | } |
| 396 | 382 | ||
| 397 | ResultCode RenameDirectoryBetweenArchives(ArchiveHandle src_archive_handle, | 383 | ResultCode RenameDirectoryBetweenArchives(ArchiveHandle src_archive_handle, |
| @@ -404,17 +390,11 @@ ResultCode RenameDirectoryBetweenArchives(ArchiveHandle src_archive_handle, | |||
| 404 | return ERR_INVALID_ARCHIVE_HANDLE; | 390 | return ERR_INVALID_ARCHIVE_HANDLE; |
| 405 | 391 | ||
| 406 | if (src_archive == dest_archive) { | 392 | if (src_archive == dest_archive) { |
| 407 | if (src_archive->RenameDirectory(src_path, dest_path)) | 393 | return src_archive->RenameDirectory(src_path, dest_path); |
| 408 | return RESULT_SUCCESS; | ||
| 409 | } else { | 394 | } else { |
| 410 | // TODO: Implement renaming across archives | 395 | // TODO: Implement renaming across archives |
| 411 | return UnimplementedFunction(ErrorModule::FS); | 396 | return UnimplementedFunction(ErrorModule::FS); |
| 412 | } | 397 | } |
| 413 | |||
| 414 | // TODO(yuriks): This code probably isn't right, it'll return a Status even if the file didn't | ||
| 415 | // exist or similar. Verify. | ||
| 416 | return ResultCode(ErrorDescription::NoData, ErrorModule::FS, // TODO: verify description | ||
| 417 | ErrorSummary::NothingHappened, ErrorLevel::Status); | ||
| 418 | } | 398 | } |
| 419 | 399 | ||
| 420 | ResultVal<Kernel::SharedPtr<Directory>> OpenDirectoryFromArchive(ArchiveHandle archive_handle, | 400 | ResultVal<Kernel::SharedPtr<Directory>> OpenDirectoryFromArchive(ArchiveHandle archive_handle, |
| @@ -423,13 +403,11 @@ ResultVal<Kernel::SharedPtr<Directory>> OpenDirectoryFromArchive(ArchiveHandle a | |||
| 423 | if (archive == nullptr) | 403 | if (archive == nullptr) |
| 424 | return ERR_INVALID_ARCHIVE_HANDLE; | 404 | return ERR_INVALID_ARCHIVE_HANDLE; |
| 425 | 405 | ||
| 426 | std::unique_ptr<FileSys::DirectoryBackend> backend = archive->OpenDirectory(path); | 406 | auto backend = archive->OpenDirectory(path); |
| 427 | if (backend == nullptr) { | 407 | if (backend.Failed()) |
| 428 | return ResultCode(ErrorDescription::FS_NotFound, ErrorModule::FS, ErrorSummary::NotFound, | 408 | return backend.Code(); |
| 429 | ErrorLevel::Permanent); | ||
| 430 | } | ||
| 431 | 409 | ||
| 432 | auto directory = Kernel::SharedPtr<Directory>(new Directory(std::move(backend), path)); | 410 | auto directory = Kernel::SharedPtr<Directory>(new Directory(backend.MoveFrom(), path)); |
| 433 | return MakeResult<Kernel::SharedPtr<Directory>>(std::move(directory)); | 411 | return MakeResult<Kernel::SharedPtr<Directory>>(std::move(directory)); |
| 434 | } | 412 | } |
| 435 | 413 | ||
| @@ -549,6 +527,13 @@ void RegisterArchiveTypes() { | |||
| 549 | LOG_ERROR(Service_FS, "Can't instantiate SDMC archive with path %s", | 527 | LOG_ERROR(Service_FS, "Can't instantiate SDMC archive with path %s", |
| 550 | sdmc_directory.c_str()); | 528 | sdmc_directory.c_str()); |
| 551 | 529 | ||
| 530 | auto sdmcwo_factory = std::make_unique<FileSys::ArchiveFactory_SDMCWriteOnly>(sdmc_directory); | ||
| 531 | if (sdmcwo_factory->Initialize()) | ||
| 532 | RegisterArchiveType(std::move(sdmcwo_factory), ArchiveIdCode::SDMCWriteOnly); | ||
| 533 | else | ||
| 534 | LOG_ERROR(Service_FS, "Can't instantiate SDMCWriteOnly archive with path %s", | ||
| 535 | sdmc_directory.c_str()); | ||
| 536 | |||
| 552 | // Create the SaveData archive | 537 | // Create the SaveData archive |
| 553 | auto savedata_factory = std::make_unique<FileSys::ArchiveFactory_SaveData>(sdmc_directory); | 538 | auto savedata_factory = std::make_unique<FileSys::ArchiveFactory_SaveData>(sdmc_directory); |
| 554 | RegisterArchiveType(std::move(savedata_factory), ArchiveIdCode::SaveData); | 539 | RegisterArchiveType(std::move(savedata_factory), ArchiveIdCode::SaveData); |
| @@ -569,10 +554,9 @@ void RegisterArchiveTypes() { | |||
| 569 | LOG_ERROR(Service_FS, "Can't instantiate SharedExtSaveData archive with path %s", | 554 | LOG_ERROR(Service_FS, "Can't instantiate SharedExtSaveData archive with path %s", |
| 570 | sharedextsavedata_factory->GetMountPoint().c_str()); | 555 | sharedextsavedata_factory->GetMountPoint().c_str()); |
| 571 | 556 | ||
| 572 | // Create the SaveDataCheck archive, basically a small variation of the RomFS archive | 557 | // Create the NCCH archive, basically a small variation of the RomFS archive |
| 573 | auto savedatacheck_factory = | 558 | auto savedatacheck_factory = std::make_unique<FileSys::ArchiveFactory_NCCH>(nand_directory); |
| 574 | std::make_unique<FileSys::ArchiveFactory_SaveDataCheck>(nand_directory); | 559 | RegisterArchiveType(std::move(savedatacheck_factory), ArchiveIdCode::NCCH); |
| 575 | RegisterArchiveType(std::move(savedatacheck_factory), ArchiveIdCode::SaveDataCheck); | ||
| 576 | 560 | ||
| 577 | auto systemsavedata_factory = | 561 | auto systemsavedata_factory = |
| 578 | std::make_unique<FileSys::ArchiveFactory_SystemSaveData>(nand_directory); | 562 | std::make_unique<FileSys::ArchiveFactory_SystemSaveData>(nand_directory); |
diff --git a/src/core/hle/service/fs/archive.h b/src/core/hle/service/fs/archive.h index 41a76285c..21ed9717b 100644 --- a/src/core/hle/service/fs/archive.h +++ b/src/core/hle/service/fs/archive.h | |||
| @@ -33,7 +33,7 @@ enum class ArchiveIdCode : u32 { | |||
| 33 | SystemSaveData = 0x00000008, | 33 | SystemSaveData = 0x00000008, |
| 34 | SDMC = 0x00000009, | 34 | SDMC = 0x00000009, |
| 35 | SDMCWriteOnly = 0x0000000A, | 35 | SDMCWriteOnly = 0x0000000A, |
| 36 | SaveDataCheck = 0x2345678A, | 36 | NCCH = 0x2345678A, |
| 37 | }; | 37 | }; |
| 38 | 38 | ||
| 39 | /// Media types for the archives | 39 | /// Media types for the archives |
diff --git a/src/core/hle/service/ptm/ptm.cpp b/src/core/hle/service/ptm/ptm.cpp index 6e6b63329..cc859c14c 100644 --- a/src/core/hle/service/ptm/ptm.cpp +++ b/src/core/hle/service/ptm/ptm.cpp | |||
| @@ -128,7 +128,7 @@ void Init() { | |||
| 128 | Service::FS::OpenArchive(Service::FS::ArchiveIdCode::SharedExtSaveData, archive_path); | 128 | Service::FS::OpenArchive(Service::FS::ArchiveIdCode::SharedExtSaveData, archive_path); |
| 129 | ASSERT_MSG(archive_result.Succeeded(), "Could not open the PTM SharedExtSaveData archive!"); | 129 | ASSERT_MSG(archive_result.Succeeded(), "Could not open the PTM SharedExtSaveData archive!"); |
| 130 | 130 | ||
| 131 | FileSys::Path gamecoin_path("gamecoin.dat"); | 131 | FileSys::Path gamecoin_path("/gamecoin.dat"); |
| 132 | FileSys::Mode open_mode = {}; | 132 | FileSys::Mode open_mode = {}; |
| 133 | open_mode.write_flag.Assign(1); | 133 | open_mode.write_flag.Assign(1); |
| 134 | open_mode.create_flag.Assign(1); | 134 | open_mode.create_flag.Assign(1); |