From 381a5c053f76a7d85d811ebf37a5943f6a57579e Mon Sep 17 00:00:00 2001 From: Subv Date: Mon, 28 Dec 2015 09:38:10 -0500 Subject: HLE/FS: FS::CreateFile takes an u64 for the file size. --- src/core/hle/service/fs/archive.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/core/hle/service/fs/archive.cpp') diff --git a/src/core/hle/service/fs/archive.cpp b/src/core/hle/service/fs/archive.cpp index d64b3656a..57fc2f44d 100644 --- a/src/core/hle/service/fs/archive.cpp +++ b/src/core/hle/service/fs/archive.cpp @@ -347,7 +347,7 @@ ResultCode DeleteDirectoryFromArchive(ArchiveHandle archive_handle, const FileSy ErrorSummary::Canceled, ErrorLevel::Status); } -ResultCode CreateFileInArchive(ArchiveHandle archive_handle, const FileSys::Path& path, u32 file_size) { +ResultCode CreateFileInArchive(ArchiveHandle archive_handle, const FileSys::Path& path, u64 file_size) { ArchiveBackend* archive = GetArchive(archive_handle); if (archive == nullptr) return ERR_INVALID_HANDLE; -- cgit v1.2.3 From 09b0564c75c3da41eaf15dcb847831c11f4c27b9 Mon Sep 17 00:00:00 2001 From: Subv Date: Mon, 28 Dec 2015 09:59:27 -0500 Subject: HLE/FS: Corrected the error codes for DeleteFile --- src/core/hle/service/fs/archive.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'src/core/hle/service/fs/archive.cpp') diff --git a/src/core/hle/service/fs/archive.cpp b/src/core/hle/service/fs/archive.cpp index 57fc2f44d..cb98fa7aa 100644 --- a/src/core/hle/service/fs/archive.cpp +++ b/src/core/hle/service/fs/archive.cpp @@ -309,10 +309,7 @@ ResultCode DeleteFileFromArchive(ArchiveHandle archive_handle, const FileSys::Pa if (archive == nullptr) return ERR_INVALID_HANDLE; - if (archive->DeleteFile(path)) - return RESULT_SUCCESS; - return ResultCode(ErrorDescription::NoData, ErrorModule::FS, // TODO: verify description - ErrorSummary::Canceled, ErrorLevel::Status); + return archive->DeleteFile(path); } ResultCode RenameFileBetweenArchives(ArchiveHandle src_archive_handle, const FileSys::Path& src_path, -- cgit v1.2.3 From 96f0e32f836b19edb3d14ce4f87a7aed1ac6a8e1 Mon Sep 17 00:00:00 2001 From: Subv Date: Mon, 28 Dec 2015 10:03:09 -0500 Subject: HLE/FS: Return the proper error codes on file Read/Write operations. These operations are limited by the open flags specified while opening the file. --- src/core/hle/service/fs/archive.cpp | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'src/core/hle/service/fs/archive.cpp') diff --git a/src/core/hle/service/fs/archive.cpp b/src/core/hle/service/fs/archive.cpp index cb98fa7aa..8c38c3ba4 100644 --- a/src/core/hle/service/fs/archive.cpp +++ b/src/core/hle/service/fs/archive.cpp @@ -103,7 +103,14 @@ ResultVal File::SyncRequest() { u32 address = cmd_buff[5]; LOG_TRACE(Service_FS, "Read %s %s: offset=0x%llx length=%d address=0x%x", GetTypeName().c_str(), GetName().c_str(), offset, length, address); - cmd_buff[2] = static_cast(backend->Read(offset, length, Memory::GetPointer(address))); + if (offset + length > backend->GetSize()) + LOG_ERROR(Service_FS, "Reading from out of bounds offset=0x%llX length=0x%08X file_size=0x%llX", offset, length, backend->GetSize()); + ResultVal read = backend->Read(offset, length, Memory::GetPointer(address)); + if (read.Failed()) { + cmd_buff[1] = read.Code().raw; + return read.Code(); + } + cmd_buff[2] = static_cast(read.MoveFrom()); break; } @@ -116,7 +123,13 @@ ResultVal File::SyncRequest() { u32 address = cmd_buff[6]; LOG_TRACE(Service_FS, "Write %s %s: offset=0x%llx length=%d address=0x%x, flush=0x%x", GetTypeName().c_str(), GetName().c_str(), offset, length, address, flush); - cmd_buff[2] = static_cast(backend->Write(offset, length, flush != 0, Memory::GetPointer(address))); + + ResultVal written = backend->Write(offset, length, flush != 0, Memory::GetPointer(address)); + if (written.Failed()) { + cmd_buff[1] = written.Code().raw; + return written.Code(); + } + cmd_buff[2] = static_cast(written.MoveFrom()); break; } -- cgit v1.2.3 From 802ef6d09956a94e19a9426e90bbca4cb103146f Mon Sep 17 00:00:00 2001 From: Subv Date: Mon, 28 Dec 2015 10:04:05 -0500 Subject: HLE/FS: Fixed the OpenDirectory error code --- src/core/hle/service/fs/archive.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/core/hle/service/fs/archive.cpp') diff --git a/src/core/hle/service/fs/archive.cpp b/src/core/hle/service/fs/archive.cpp index 8c38c3ba4..0c56777cf 100644 --- a/src/core/hle/service/fs/archive.cpp +++ b/src/core/hle/service/fs/archive.cpp @@ -405,7 +405,7 @@ ResultVal> OpenDirectoryFromArchive(ArchiveHandle a std::unique_ptr backend = archive->OpenDirectory(path); if (backend == nullptr) { - return ResultCode(ErrorDescription::NotFound, ErrorModule::FS, + return ResultCode(ErrorDescription::FS_NotFound, ErrorModule::FS, ErrorSummary::NotFound, ErrorLevel::Permanent); } -- cgit v1.2.3 From 95b34f8081e26cfe75d63a853d1626fdd5b636e6 Mon Sep 17 00:00:00 2001 From: Subv Date: Mon, 28 Dec 2015 10:17:06 -0500 Subject: HLE/FS: Return the proper error codes when opening files. --- src/core/hle/service/fs/archive.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src/core/hle/service/fs/archive.cpp') diff --git a/src/core/hle/service/fs/archive.cpp b/src/core/hle/service/fs/archive.cpp index 0c56777cf..2ce5f0fe7 100644 --- a/src/core/hle/service/fs/archive.cpp +++ b/src/core/hle/service/fs/archive.cpp @@ -307,13 +307,14 @@ ResultVal> OpenFileFromArchive(ArchiveHandle archive_han if (archive == nullptr) return ERR_INVALID_HANDLE; - std::unique_ptr backend = archive->OpenFile(path, mode); - if (backend == nullptr) { + auto backend = archive->OpenFile(path, mode); + if (backend.Failed()) { + return backend.Code(); return ResultCode(ErrorDescription::FS_NotFound, ErrorModule::FS, ErrorSummary::NotFound, ErrorLevel::Status); } - auto file = Kernel::SharedPtr(new File(std::move(backend), path)); + auto file = Kernel::SharedPtr(new File(backend.MoveFrom(), path)); return MakeResult>(std::move(file)); } -- cgit v1.2.3 From 9b2d64345141fe9ed948fe3ce7ab2c603fdf5d9e Mon Sep 17 00:00:00 2001 From: Subv Date: Mon, 28 Dec 2015 10:17:49 -0500 Subject: HLE/FS: Don't return an error when deleting the ExtSaveData if it does not exist. --- src/core/hle/service/fs/archive.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/core/hle/service/fs/archive.cpp') diff --git a/src/core/hle/service/fs/archive.cpp b/src/core/hle/service/fs/archive.cpp index 2ce5f0fe7..b034de8f1 100644 --- a/src/core/hle/service/fs/archive.cpp +++ b/src/core/hle/service/fs/archive.cpp @@ -484,7 +484,7 @@ ResultCode DeleteExtSaveData(MediaType media_type, u32 high, u32 low) { // Delete all directories (/user, /boss) and the icon file. std::string base_path = FileSys::GetExtDataContainerPath(media_type_directory, media_type == MediaType::NAND); std::string extsavedata_path = FileSys::GetExtSaveDataPath(base_path, path); - if (!FileUtil::DeleteDirRecursively(extsavedata_path)) + if (FileUtil::Exists(extsavedata_path) && !FileUtil::DeleteDirRecursively(extsavedata_path)) return ResultCode(-1); // TODO(Subv): Find the right error code return RESULT_SUCCESS; } -- cgit v1.2.3 From d26c6b3212ed36970410814593ee5ec082b1d95a Mon Sep 17 00:00:00 2001 From: Subv Date: Mon, 28 Dec 2015 13:51:44 -0500 Subject: HLE/FS: Implemented GetFormatInfo Format information is currently only implemented for the ExtSaveData, SharedExtSaveData and SaveData archives, the information is stored in a file alongside the root folder of the archive. --- src/core/hle/service/fs/archive.cpp | 48 +++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 26 deletions(-) (limited to 'src/core/hle/service/fs/archive.cpp') diff --git a/src/core/hle/service/fs/archive.cpp b/src/core/hle/service/fs/archive.cpp index b034de8f1..63381250a 100644 --- a/src/core/hle/service/fs/archive.cpp +++ b/src/core/hle/service/fs/archive.cpp @@ -421,49 +421,45 @@ ResultVal GetFreeBytesInArchive(ArchiveHandle archive_handle) { return MakeResult(archive->GetFreeBytes()); } -ResultCode FormatArchive(ArchiveIdCode id_code, const FileSys::Path& path) { +ResultCode FormatArchive(ArchiveIdCode id_code, const FileSys::ArchiveFormatInfo& format_info, const FileSys::Path& path) { auto archive_itr = id_code_map.find(id_code); if (archive_itr == id_code_map.end()) { return UnimplementedFunction(ErrorModule::FS); // TODO(Subv): Find the right error } - return archive_itr->second->Format(path); + return archive_itr->second->Format(path, format_info); } -ResultCode CreateExtSaveData(MediaType media_type, u32 high, u32 low, VAddr icon_buffer, u32 icon_size) { +ResultVal GetArchiveFormatInfo(ArchiveIdCode id_code, FileSys::Path& archive_path) { + auto archive = id_code_map.find(id_code); + if (archive == id_code_map.end()) { + return UnimplementedFunction(ErrorModule::FS); // TODO(Subv): Find the right error + } + + return archive->second->GetFormatInfo(archive_path); +} + +ResultCode CreateExtSaveData(MediaType media_type, u32 high, u32 low, VAddr icon_buffer, u32 icon_size, const FileSys::ArchiveFormatInfo& format_info) { // Construct the binary path to the archive first FileSys::Path path = FileSys::ConstructExtDataBinaryPath(static_cast(media_type), high, low); - std::string media_type_directory; - if (media_type == MediaType::NAND) { - media_type_directory = FileUtil::GetUserPath(D_NAND_IDX); - } else if (media_type == MediaType::SDMC) { - media_type_directory = FileUtil::GetUserPath(D_SDMC_IDX); - } else { - LOG_ERROR(Service_FS, "Unsupported media type %u", media_type); - return ResultCode(-1); // TODO(Subv): Find the right error code + auto archive = id_code_map.find(media_type == MediaType::NAND ? ArchiveIdCode::SharedExtSaveData : ArchiveIdCode::ExtSaveData); + + if (archive == id_code_map.end()) { + return UnimplementedFunction(ErrorModule::FS); // TODO(Subv): Find the right error } - std::string base_path = FileSys::GetExtDataContainerPath(media_type_directory, media_type == MediaType::NAND); - std::string game_path = FileSys::GetExtSaveDataPath(base_path, path); - // These two folders are always created with the ExtSaveData - std::string user_path = game_path + "user/"; - std::string boss_path = game_path + "boss/"; - if (!FileUtil::CreateFullPath(user_path)) - return ResultCode(-1); // TODO(Subv): Find the right error code - if (!FileUtil::CreateFullPath(boss_path)) - return ResultCode(-1); // TODO(Subv): Find the right error code + auto ext_savedata = static_cast(archive->second.get()); + + ResultCode result = ext_savedata->Format(path, format_info); + if (result.IsError()) + return result; u8* smdh_icon = Memory::GetPointer(icon_buffer); if (!smdh_icon) return ResultCode(-1); // TODO(Subv): Find the right error code - // Create the icon - FileUtil::IOFile icon_file(game_path + "icon", "wb+"); - if (!icon_file.IsGood()) - return ResultCode(-1); // TODO(Subv): Find the right error code - - icon_file.WriteBytes(smdh_icon, icon_size); + ext_savedata->WriteIcon(path, smdh_icon, icon_size); return RESULT_SUCCESS; } -- cgit v1.2.3 From 3aa42627a3a35d8a4fb9acdcced24977d1f269cd Mon Sep 17 00:00:00 2001 From: Subv Date: Sat, 16 Jan 2016 17:01:01 -0500 Subject: HLE/FS: Corrected some style concerns. --- src/core/hle/service/fs/archive.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'src/core/hle/service/fs/archive.cpp') diff --git a/src/core/hle/service/fs/archive.cpp b/src/core/hle/service/fs/archive.cpp index 63381250a..676a2ee56 100644 --- a/src/core/hle/service/fs/archive.cpp +++ b/src/core/hle/service/fs/archive.cpp @@ -308,11 +308,8 @@ ResultVal> OpenFileFromArchive(ArchiveHandle archive_han return ERR_INVALID_HANDLE; auto backend = archive->OpenFile(path, mode); - if (backend.Failed()) { + if (backend.Failed()) return backend.Code(); - return ResultCode(ErrorDescription::FS_NotFound, ErrorModule::FS, - ErrorSummary::NotFound, ErrorLevel::Status); - } auto file = Kernel::SharedPtr(new File(backend.MoveFrom(), path)); return MakeResult>(std::move(file)); -- cgit v1.2.3 From f707026ac50c53716ac697ed439630d7728e9db6 Mon Sep 17 00:00:00 2001 From: Subv Date: Thu, 3 Mar 2016 13:05:50 -0500 Subject: HLE/FS: Change the error code returned when an ExtSaveData archive is not found. This allows Fire Emblem to boot again. --- src/core/hle/service/fs/archive.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'src/core/hle/service/fs/archive.cpp') diff --git a/src/core/hle/service/fs/archive.cpp b/src/core/hle/service/fs/archive.cpp index 676a2ee56..590697e76 100644 --- a/src/core/hle/service/fs/archive.cpp +++ b/src/core/hle/service/fs/archive.cpp @@ -103,14 +103,18 @@ ResultVal File::SyncRequest() { u32 address = cmd_buff[5]; LOG_TRACE(Service_FS, "Read %s %s: offset=0x%llx length=%d address=0x%x", GetTypeName().c_str(), GetName().c_str(), offset, length, address); - if (offset + length > backend->GetSize()) - LOG_ERROR(Service_FS, "Reading from out of bounds offset=0x%llX length=0x%08X file_size=0x%llX", offset, length, backend->GetSize()); + + if (offset + length > backend->GetSize()) { + LOG_ERROR(Service_FS, "Reading from out of bounds offset=0x%llX length=0x%08X file_size=0x%llX", + offset, length, backend->GetSize()); + } + ResultVal read = backend->Read(offset, length, Memory::GetPointer(address)); if (read.Failed()) { cmd_buff[1] = read.Code().raw; return read.Code(); } - cmd_buff[2] = static_cast(read.MoveFrom()); + cmd_buff[2] = static_cast(*read); break; } @@ -129,7 +133,7 @@ ResultVal File::SyncRequest() { cmd_buff[1] = written.Code().raw; return written.Code(); } - cmd_buff[2] = static_cast(written.MoveFrom()); + cmd_buff[2] = static_cast(*written); break; } -- cgit v1.2.3