aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/hle/service/fs/archive.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/hle/service/fs/archive.cpp')
-rw-r--r--src/core/hle/service/fs/archive.cpp73
1 files changed, 46 insertions, 27 deletions
diff --git a/src/core/hle/service/fs/archive.cpp b/src/core/hle/service/fs/archive.cpp
index 958dd934..ccf132f3 100644
--- a/src/core/hle/service/fs/archive.cpp
+++ b/src/core/hle/service/fs/archive.cpp
@@ -43,6 +43,11 @@ const std::string SDCARD_ID = "00000000000000000000000000000000";
namespace Service {
namespace FS {
+// TODO: Verify code
+/// Returned when a function is passed an invalid handle.
+const ResultCode ERR_INVALID_HANDLE(ErrorDescription::InvalidHandle, ErrorModule::FS,
+ ErrorSummary::InvalidArgument, ErrorLevel::Permanent);
+
// Command to access archive file
enum class FileCommand : u32 {
Dummy1 = 0x000100C6,
@@ -84,7 +89,7 @@ public:
class File : public Kernel::Session {
public:
File(std::unique_ptr<FileSys::FileBackend>&& backend, const FileSys::Path& path)
- : path(path), backend(std::move(backend)), priority(0) {
+ : path(path), priority(0), backend(std::move(backend)) {
}
std::string GetName() const override { return "Path: " + path.DebugStr(); }
@@ -158,7 +163,7 @@ public:
case FileCommand::OpenLinkFile:
{
LOG_WARNING(Service_FS, "(STUBBED) File command OpenLinkFile %s", GetName().c_str());
- cmd_buff[3] = GetHandle();
+ cmd_buff[3] = Kernel::g_handle_table.Create(this).ValueOr(INVALID_HANDLE);
break;
}
@@ -280,7 +285,7 @@ ResultVal<ArchiveHandle> OpenArchive(ArchiveIdCode id_code, FileSys::Path& archi
ResultCode CloseArchive(ArchiveHandle handle) {
if (handle_map.erase(handle) == 0)
- return InvalidHandle(ErrorModule::FS);
+ return ERR_INVALID_HANDLE;
else
return RESULT_SUCCESS;
}
@@ -298,10 +303,11 @@ ResultCode CreateArchive(std::unique_ptr<FileSys::ArchiveBackend>&& backend, Arc
return RESULT_SUCCESS;
}
-ResultVal<Handle> OpenFileFromArchive(ArchiveHandle archive_handle, const FileSys::Path& path, const FileSys::Mode mode) {
+ResultVal<Kernel::SharedPtr<Kernel::Session>> OpenFileFromArchive(ArchiveHandle archive_handle,
+ const FileSys::Path& path, const FileSys::Mode mode) {
Archive* archive = GetArchive(archive_handle);
if (archive == nullptr)
- return InvalidHandle(ErrorModule::FS);
+ return ERR_INVALID_HANDLE;
std::unique_ptr<FileSys::FileBackend> backend = archive->backend->OpenFile(path, mode);
if (backend == nullptr) {
@@ -309,16 +315,14 @@ ResultVal<Handle> OpenFileFromArchive(ArchiveHandle archive_handle, const FileSy
ErrorSummary::NotFound, ErrorLevel::Status);
}
- auto file = Common::make_unique<File>(std::move(backend), path);
- // TOOD(yuriks): Fix error reporting
- Handle handle = Kernel::g_handle_table.Create(file.release()).ValueOr(INVALID_HANDLE);
- return MakeResult<Handle>(handle);
+ auto file = Kernel::SharedPtr<File>(new File(std::move(backend), path));
+ return MakeResult<Kernel::SharedPtr<Kernel::Session>>(std::move(file));
}
ResultCode DeleteFileFromArchive(ArchiveHandle archive_handle, const FileSys::Path& path) {
Archive* archive = GetArchive(archive_handle);
if (archive == nullptr)
- return InvalidHandle(ErrorModule::FS);
+ return ERR_INVALID_HANDLE;
if (archive->backend->DeleteFile(path))
return RESULT_SUCCESS;
@@ -331,7 +335,7 @@ ResultCode RenameFileBetweenArchives(ArchiveHandle src_archive_handle, const Fil
Archive* src_archive = GetArchive(src_archive_handle);
Archive* dest_archive = GetArchive(dest_archive_handle);
if (src_archive == nullptr || dest_archive == nullptr)
- return InvalidHandle(ErrorModule::FS);
+ return ERR_INVALID_HANDLE;
if (src_archive == dest_archive) {
if (src_archive->backend->RenameFile(src_path, dest_path))
@@ -350,7 +354,7 @@ ResultCode RenameFileBetweenArchives(ArchiveHandle src_archive_handle, const Fil
ResultCode DeleteDirectoryFromArchive(ArchiveHandle archive_handle, const FileSys::Path& path) {
Archive* archive = GetArchive(archive_handle);
if (archive == nullptr)
- return InvalidHandle(ErrorModule::FS);
+ return ERR_INVALID_HANDLE;
if (archive->backend->DeleteDirectory(path))
return RESULT_SUCCESS;
@@ -361,7 +365,7 @@ ResultCode DeleteDirectoryFromArchive(ArchiveHandle archive_handle, const FileSy
ResultCode CreateFileInArchive(ArchiveHandle archive_handle, const FileSys::Path& path, u32 file_size) {
Archive* archive = GetArchive(archive_handle);
if (archive == nullptr)
- return InvalidHandle(ErrorModule::FS);
+ return ERR_INVALID_HANDLE;
return archive->backend->CreateFile(path, file_size);
}
@@ -369,7 +373,7 @@ ResultCode CreateFileInArchive(ArchiveHandle archive_handle, const FileSys::Path
ResultCode CreateDirectoryFromArchive(ArchiveHandle archive_handle, const FileSys::Path& path) {
Archive* archive = GetArchive(archive_handle);
if (archive == nullptr)
- return InvalidHandle(ErrorModule::FS);
+ return ERR_INVALID_HANDLE;
if (archive->backend->CreateDirectory(path))
return RESULT_SUCCESS;
@@ -382,7 +386,7 @@ ResultCode RenameDirectoryBetweenArchives(ArchiveHandle src_archive_handle, cons
Archive* src_archive = GetArchive(src_archive_handle);
Archive* dest_archive = GetArchive(dest_archive_handle);
if (src_archive == nullptr || dest_archive == nullptr)
- return InvalidHandle(ErrorModule::FS);
+ return ERR_INVALID_HANDLE;
if (src_archive == dest_archive) {
if (src_archive->backend->RenameDirectory(src_path, dest_path))
@@ -398,16 +402,11 @@ ResultCode RenameDirectoryBetweenArchives(ArchiveHandle src_archive_handle, cons
ErrorSummary::NothingHappened, ErrorLevel::Status);
}
-/**
- * Open a Directory from an Archive
- * @param archive_handle Handle to an open Archive object
- * @param path Path to the Directory inside of the Archive
- * @return Opened Directory object
- */
-ResultVal<Handle> OpenDirectoryFromArchive(ArchiveHandle archive_handle, const FileSys::Path& path) {
+ResultVal<Kernel::SharedPtr<Kernel::Session>> OpenDirectoryFromArchive(ArchiveHandle archive_handle,
+ const FileSys::Path& path) {
Archive* archive = GetArchive(archive_handle);
if (archive == nullptr)
- return InvalidHandle(ErrorModule::FS);
+ return ERR_INVALID_HANDLE;
std::unique_ptr<FileSys::DirectoryBackend> backend = archive->backend->OpenDirectory(path);
if (backend == nullptr) {
@@ -415,10 +414,8 @@ ResultVal<Handle> OpenDirectoryFromArchive(ArchiveHandle archive_handle, const F
ErrorSummary::NotFound, ErrorLevel::Permanent);
}
- auto directory = Common::make_unique<Directory>(std::move(backend), path);
- // TOOD(yuriks): Fix error reporting
- Handle handle = Kernel::g_handle_table.Create(directory.release()).ValueOr(INVALID_HANDLE);
- return MakeResult<Handle>(handle);
+ auto directory = Kernel::SharedPtr<Directory>(new Directory(std::move(backend), path));
+ return MakeResult<Kernel::SharedPtr<Kernel::Session>>(std::move(directory));
}
ResultCode FormatSaveData() {
@@ -432,6 +429,28 @@ ResultCode FormatSaveData() {
return archive_itr->second->backend->Format(FileSys::Path());
}
+ResultCode CreateExtSaveData(u32 high, u32 low) {
+ // Construct the binary path to the archive first
+ std::vector<u8> binary_path;
+ binary_path.reserve(12);
+ // The first word is all zero to specify a NAND archive
+ for (unsigned i = 0; i < 4; ++i)
+ binary_path.push_back(0);
+ // Next is the low word
+ for (unsigned i = 0; i < 4; ++i)
+ binary_path.push_back((low >> (8 * i)) & 0xFF);
+ // Next is the high word
+ for (unsigned i = 0; i < 4; ++i)
+ binary_path.push_back((high >> i) & 0xFF);
+ FileSys::Path path(binary_path);
+ std::string nand_directory = FileUtil::GetUserPath(D_NAND_IDX);
+ std::string base_path = FileSys::GetExtDataContainerPath(nand_directory, true);
+ std::string extsavedata_path = FileSys::GetExtSaveDataPath(base_path, path);
+ if (!FileUtil::CreateFullPath(extsavedata_path))
+ return ResultCode(-1); // TODO(Subv): Find the right error code
+ return RESULT_SUCCESS;
+}
+
/// Initialize archives
void ArchiveInit() {
next_handle = 1;