From 5e91fc0d1aa806a9635e06e047d5367988f21093 Mon Sep 17 00:00:00 2001
From: Yuri Kunde Schlesner <yuriks@yuriks.net>
Date: Fri, 30 Jan 2015 12:32:46 -0200
Subject: [PATCH] Filesys: Move creation of Handles for File/Directory to
 service handlers

---
 src/core/hle/service/fs/archive.cpp | 24 ++++++++----------------
 src/core/hle/service/fs/archive.h   | 14 ++++++++++----
 src/core/hle/service/fs/fs_user.cpp | 27 +++++++++++++++------------
 3 files changed, 33 insertions(+), 32 deletions(-)

diff --git a/src/core/hle/service/fs/archive.cpp b/src/core/hle/service/fs/archive.cpp
index 43eef034ed..0ce9ad4d65 100644
--- a/src/core/hle/service/fs/archive.cpp
+++ b/src/core/hle/service/fs/archive.cpp
@@ -303,7 +303,8 @@ 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 ERR_INVALID_HANDLE;
@@ -314,10 +315,8 @@ 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) {
@@ -403,13 +402,8 @@ 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 ERR_INVALID_HANDLE;
@@ -420,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() {
diff --git a/src/core/hle/service/fs/archive.h b/src/core/hle/service/fs/archive.h
index ba674d7f6e..ab5ea4da8e 100644
--- a/src/core/hle/service/fs/archive.h
+++ b/src/core/hle/service/fs/archive.h
@@ -15,6 +15,10 @@ extern const std::string SYSTEM_ID;
 /// The scrambled SD card CID, also known as ID1
 extern const std::string SDCARD_ID;
 
+namespace Kernel {
+    class Session;
+}
+
 namespace Service {
 namespace FS {
 
@@ -58,9 +62,10 @@ ResultCode CreateArchive(std::unique_ptr<FileSys::ArchiveBackend>&& backend, Arc
  * @param archive_handle Handle to an open Archive object
  * @param path Path to the File inside of the Archive
  * @param mode Mode under which to open the File
- * @return Handle to the opened File object
+ * @return The opened File object as a Session
  */
-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);
 
 /**
  * Delete a File from an Archive
@@ -121,9 +126,10 @@ ResultCode RenameDirectoryBetweenArchives(ArchiveHandle src_archive_handle, cons
  * 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 Handle to the opened File object
+ * @return The opened Directory object as a Session
  */
-ResultVal<Handle> OpenDirectoryFromArchive(ArchiveHandle archive_handle, const FileSys::Path& path);
+ResultVal<Kernel::SharedPtr<Kernel::Session>> OpenDirectoryFromArchive(ArchiveHandle archive_handle,
+        const FileSys::Path& path);
 
 /**
  * Creates a blank SaveData archive.
diff --git a/src/core/hle/service/fs/fs_user.cpp b/src/core/hle/service/fs/fs_user.cpp
index c495b6f3ce..9cb7d809ab 100644
--- a/src/core/hle/service/fs/fs_user.cpp
+++ b/src/core/hle/service/fs/fs_user.cpp
@@ -14,6 +14,9 @@
 ////////////////////////////////////////////////////////////////////////////////////////////////////
 // Namespace FS_User
 
+using Kernel::SharedPtr;
+using Kernel::Session;
+
 namespace Service {
 namespace FS {
 
@@ -58,10 +61,10 @@ static void OpenFile(Service::Interface* self) {
 
     LOG_DEBUG(Service_FS, "path=%s, mode=%d attrs=%u", file_path.DebugStr().c_str(), mode.hex, attributes);
 
-    ResultVal<Handle> handle = OpenFileFromArchive(archive_handle, file_path, mode);
-    cmd_buff[1] = handle.Code().raw;
-    if (handle.Succeeded()) {
-        cmd_buff[3] = *handle;
+    ResultVal<SharedPtr<Session>> file_res = OpenFileFromArchive(archive_handle, file_path, mode);
+    cmd_buff[1] = file_res.Code().raw;
+    if (file_res.Succeeded()) {
+        cmd_buff[3] = Kernel::g_handle_table.Create(*file_res).MoveFrom();
     } else {
         cmd_buff[3] = 0;
         LOG_ERROR(Service_FS, "failed to get a handle for file %s", file_path.DebugStr().c_str());
@@ -114,10 +117,10 @@ static void OpenFileDirectly(Service::Interface* self) {
     }
     SCOPE_EXIT({ CloseArchive(*archive_handle); });
 
-    ResultVal<Handle> handle = OpenFileFromArchive(*archive_handle, file_path, mode);
-    cmd_buff[1] = handle.Code().raw;
-    if (handle.Succeeded()) {
-        cmd_buff[3] = *handle;
+    ResultVal<SharedPtr<Session>> file_res = OpenFileFromArchive(*archive_handle, file_path, mode);
+    cmd_buff[1] = file_res.Code().raw;
+    if (file_res.Succeeded()) {
+        cmd_buff[3] = Kernel::g_handle_table.Create(*file_res).MoveFrom();
     } else {
         cmd_buff[3] = 0;
         LOG_ERROR(Service_FS, "failed to get a handle for file %s", file_path.DebugStr().c_str());
@@ -334,10 +337,10 @@ static void OpenDirectory(Service::Interface* self) {
 
     LOG_DEBUG(Service_FS, "type=%d size=%d data=%s", dirname_type, dirname_size, dir_path.DebugStr().c_str());
 
-    ResultVal<Handle> handle = OpenDirectoryFromArchive(archive_handle, dir_path);
-    cmd_buff[1] = handle.Code().raw;
-    if (handle.Succeeded()) {
-        cmd_buff[3] = *handle;
+    ResultVal<SharedPtr<Session>> dir_res = OpenDirectoryFromArchive(archive_handle, dir_path);
+    cmd_buff[1] = dir_res.Code().raw;
+    if (dir_res.Succeeded()) {
+        cmd_buff[3] = Kernel::g_handle_table.Create(*dir_res).MoveFrom();
     } else {
         LOG_ERROR(Service_FS, "failed to get a handle for directory");
     }