From 04c90c395d27e6bc205fb2d933ced50e70c1841a Mon Sep 17 00:00:00 2001 From: archshift <admin@archshift.com> Date: Tue, 28 Oct 2014 22:52:56 -0700 Subject: [PATCH] Added CreateDirectory function to service/fs.cpp, and in Archive. --- src/core/file_sys/archive.h | 7 +++++ src/core/file_sys/archive_romfs.cpp | 10 ++++++++ src/core/file_sys/archive_romfs.h | 7 +++++ src/core/file_sys/archive_sdmc.cpp | 9 +++++++ src/core/file_sys/archive_sdmc.h | 7 +++++ src/core/hle/kernel/archive.cpp | 15 +++++++++++ src/core/hle/kernel/archive.h | 12 +++++++-- src/core/hle/service/fs_user.cpp | 40 +++++++++++++++++++++++++++-- 8 files changed, 103 insertions(+), 4 deletions(-) diff --git a/src/core/file_sys/archive.h b/src/core/file_sys/archive.h index 560db6dea..aeabf09ac 100644 --- a/src/core/file_sys/archive.h +++ b/src/core/file_sys/archive.h @@ -56,6 +56,13 @@ public: */ virtual std::unique_ptr<File> OpenFile(const std::string& path, const Mode mode) const = 0; + /** + * Create a directory specified by its path + * @param path Path relative to the archive + * @return Whether the directory could be created + */ + virtual bool CreateDirectory(const std::string& path) const = 0; + /** * Open a directory specified by its path * @param path Path relative to the archive diff --git a/src/core/file_sys/archive_romfs.cpp b/src/core/file_sys/archive_romfs.cpp index f101fc729..cc759faa8 100644 --- a/src/core/file_sys/archive_romfs.cpp +++ b/src/core/file_sys/archive_romfs.cpp @@ -33,6 +33,16 @@ std::unique_ptr<File> Archive_RomFS::OpenFile(const std::string& path, const Mod return std::unique_ptr<File>(new File_RomFS); } +/** + * Create a directory specified by its path + * @param path Path relative to the archive + * @return Whether the directory could be created + */ +bool Archive_RomFS::CreateDirectory(const std::string& path) const { + ERROR_LOG(FILESYS, "Attempted to create a directory in ROMFS."); + return false; +}; + /** * Open a directory specified by its path * @param path Path relative to the archive diff --git a/src/core/file_sys/archive_romfs.h b/src/core/file_sys/archive_romfs.h index fcdefa95f..ae2344e82 100644 --- a/src/core/file_sys/archive_romfs.h +++ b/src/core/file_sys/archive_romfs.h @@ -36,6 +36,13 @@ public: */ std::unique_ptr<File> OpenFile(const std::string& path, const Mode mode) const override; + /** + * Create a directory specified by its path + * @param path Path relative to the archive + * @return Whether the directory could be created + */ + bool CreateDirectory(const std::string& path) const override; + /** * Open a directory specified by its path * @param path Path relative to the archive diff --git a/src/core/file_sys/archive_sdmc.cpp b/src/core/file_sys/archive_sdmc.cpp index 0b647f7d0..66931e93e 100644 --- a/src/core/file_sys/archive_sdmc.cpp +++ b/src/core/file_sys/archive_sdmc.cpp @@ -57,6 +57,15 @@ std::unique_ptr<File> Archive_SDMC::OpenFile(const std::string& path, const Mode return std::unique_ptr<File>(file); } +/** + * Create a directory specified by its path + * @param path Path relative to the archive + * @return Whether the directory could be created + */ +bool Archive_SDMC::CreateDirectory(const std::string& path) const { + return FileUtil::CreateDir(GetMountPoint() + path); +} + /** * Open a directory specified by its path * @param path Path relative to the archive diff --git a/src/core/file_sys/archive_sdmc.h b/src/core/file_sys/archive_sdmc.h index f68648e6f..0e059b635 100644 --- a/src/core/file_sys/archive_sdmc.h +++ b/src/core/file_sys/archive_sdmc.h @@ -40,6 +40,13 @@ public: */ std::unique_ptr<File> OpenFile(const std::string& path, const Mode mode) const override; + /** + * Create a directory specified by its path + * @param path Path relative to the archive + * @return Whether the directory could be created + */ + bool CreateDirectory(const std::string& path) const override; + /** * Open a directory specified by its path * @param path Path relative to the archive diff --git a/src/core/hle/kernel/archive.cpp b/src/core/hle/kernel/archive.cpp index 4a6140c71..764082d71 100644 --- a/src/core/hle/kernel/archive.cpp +++ b/src/core/hle/kernel/archive.cpp @@ -380,6 +380,21 @@ Handle OpenFileFromArchive(Handle archive_handle, const std::string& path, const return handle; } +/** + * Create 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 + */ +Result CreateDirectoryFromArchive(Handle archive_handle, const std::string& path) { + Archive* archive = Kernel::g_object_pool.GetFast<Archive>(archive_handle); + if (archive == nullptr) + return -1; + if (archive->backend->CreateDirectory(path)) + return 0; + return -1; +} + /** * Open a Directory from an Archive * @param archive_handle Handle to an open Archive object diff --git a/src/core/hle/kernel/archive.h b/src/core/hle/kernel/archive.h index 593861f8e..0230996b6 100644 --- a/src/core/hle/kernel/archive.h +++ b/src/core/hle/kernel/archive.h @@ -43,7 +43,15 @@ Handle CreateArchive(FileSys::Archive* backend, const std::string& name); * @param mode Mode under which to open the File * @return Opened File object */ -Handle OpenFileFromArchive(Handle handle, const std::string& name, const FileSys::Mode mode); +Handle OpenFileFromArchive(Handle archive_handle, const std::string& name, const FileSys::Mode mode); + +/** + * Create 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 Whether creation of directory succeeded + */ +Result CreateDirectoryFromArchive(Handle archive_handle, const std::string& name); /** * Open a Directory from an Archive @@ -51,7 +59,7 @@ Handle OpenFileFromArchive(Handle handle, const std::string& name, const FileSys * @param path Path to the Directory inside of the Archive * @return Opened Directory object */ -Handle OpenDirectoryFromArchive(Handle handle, const std::string& name); +Handle OpenDirectoryFromArchive(Handle archive_handle, const std::string& name); /// Initialize archives void ArchiveInit(); diff --git a/src/core/hle/service/fs_user.cpp b/src/core/hle/service/fs_user.cpp index 845c94103..48d806e2f 100644 --- a/src/core/hle/service/fs_user.cpp +++ b/src/core/hle/service/fs_user.cpp @@ -100,7 +100,7 @@ void OpenFileDirectly(Service::Interface* self) { std::string archive_name = GetStringFromCmdBuff(archive_pointer, archive_size); std::string file_name = GetStringFromCmdBuff(pointer, size); - DEBUG_LOG(KERNEL, "archive_type=%d archive_size=%d archive_data=%s" + DEBUG_LOG(KERNEL, "archive_type=%d archive_size=%d archive_data=%s " "file_type=%d file_size=%d file_mode=%d file_attrs=%d file_data=%s", archive_type, archive_size, archive_name.c_str(), file_type, size, mode, attributes, file_name.c_str()); @@ -136,6 +136,42 @@ void OpenFileDirectly(Service::Interface* self) { DEBUG_LOG(KERNEL, "called"); } +/* + * FS_User::CreateDirectory service function + * Inputs: + * 2 : Archive handle lower word + * 3 : Archive handle upper word + * 4 : Directory path string type + * 5 : Directory path string size + * 8 : Directory path string data + * Outputs: + * 1 : Result of function, 0 on success, otherwise error code + */ +void CreateDirectory(Service::Interface* self) { + u32* cmd_buff = Service::GetCommandBuffer(); + + // TODO: cmd_buff[2], aka archive handle lower word, isn't used according to + // 3dmoo's or ctrulib's implementations. Triple check if it's really the case. + Handle archive_handle = static_cast<Handle>(cmd_buff[3]); + LowPathType type = static_cast<LowPathType>(cmd_buff[4]); + u32 name_size = cmd_buff[5]; + u32 name_offset = cmd_buff[8]; + + if (type != LowPathType::Char) { + ERROR_LOG(KERNEL, "directory LowPath type other than char is currently unsupported"); + cmd_buff[1] = -1; + return; + } + + std::string dir_name = GetStringFromCmdBuff(name_offset, name_size); + + DEBUG_LOG(KERNEL, "type=%d size=%d data=%s", type, name_size, dir_name.c_str()); + + cmd_buff[1] = Kernel::CreateDirectoryFromArchive(archive_handle, dir_name); + + DEBUG_LOG(KERNEL, "called"); +} + void OpenDirectory(Service::Interface* self) { u32* cmd_buff = Service::GetCommandBuffer(); @@ -227,7 +263,7 @@ const Interface::FunctionInfo FunctionTable[] = { {0x08060142, nullptr, "DeleteDirectory"}, {0x08070142, nullptr, "DeleteDirectoryRecursively"}, {0x08080202, nullptr, "CreateFile"}, - {0x08090182, nullptr, "CreateDirectory"}, + {0x08090182, CreateDirectory, "CreateDirectory"}, {0x080A0244, nullptr, "RenameDirectory"}, {0x080B0102, OpenDirectory, "OpenDirectory"}, {0x080C00C2, OpenArchive, "OpenArchive"},