From 13efbdc2014177b84cae82e522b191e2f2f022df Mon Sep 17 00:00:00 2001
From: Subv <subv2112@gmail.com>
Date: Wed, 31 Dec 2014 19:36:50 -0500
Subject: [PATCH] SaveDataCheck: Preliminary work in this archive.

This allows Steel Diver to boot further, some files are needed.

This is still not ready and needs a big cleanup, this will possibly be delayed until the way we handle archives is fixed (with factory classes instead of ahead-of-time creation of archives)
---
 src/core/file_sys/archive_romfs.cpp | 25 +++++++++++++++++++
 src/core/file_sys/archive_romfs.h   |  7 +++---
 src/core/hle/service/fs/archive.cpp | 37 ++++++++++++++++++++++++++---
 src/core/hle/service/fs/archive.h   |  1 +
 4 files changed, 63 insertions(+), 7 deletions(-)

diff --git a/src/core/file_sys/archive_romfs.cpp b/src/core/file_sys/archive_romfs.cpp
index 2fc3831b7..df07eb657 100644
--- a/src/core/file_sys/archive_romfs.cpp
+++ b/src/core/file_sys/archive_romfs.cpp
@@ -5,6 +5,7 @@
 #include <memory>
 
 #include "common/common_types.h"
+#include "common/file_util.h"
 #include "common/make_unique.h"
 
 #include "core/file_sys/archive_romfs.h"
@@ -23,6 +24,10 @@ Archive_RomFS::Archive_RomFS(const Loader::AppLoader& app_loader) {
     }
 }
 
+Archive_RomFS::Archive_RomFS(std::string mountp) : mount_point(mountp) {
+    
+}
+
 std::unique_ptr<FileBackend> Archive_RomFS::OpenFile(const Path& path, const Mode mode) const {
     return Common::make_unique<File_RomFS>(this);
 }
@@ -67,4 +72,24 @@ ResultCode Archive_RomFS::Format(const Path& path) const {
     return UnimplementedFunction(ErrorModule::FS);
 }
 
+ResultCode Archive_RomFS::Open(const Path& path) {
+    if (mount_point.empty())
+        return RESULT_SUCCESS;
+    auto vec = path.AsBinary();
+    const u32* data = reinterpret_cast<u32*>(vec.data());
+    std::string file_path = Common::StringFromFormat("%s%08X%08X.bin", mount_point.c_str(), data[1], data[0]);
+    FileUtil::IOFile file(file_path, "rb");
+    
+    std::fill(raw_data.begin(), raw_data.end(), 0);
+
+    if (!file.IsOpen()) {
+        return ResultCode(-1); // TODO(Subv): Find the right error code
+    }
+    auto size = file.GetSize();
+    raw_data.resize(size);
+    file.ReadBytes(raw_data.data(), size);
+    file.Close();
+    return RESULT_SUCCESS;
+}
+
 } // namespace FileSys
diff --git a/src/core/file_sys/archive_romfs.h b/src/core/file_sys/archive_romfs.h
index d4b1eb7f2..b657dd38b 100644
--- a/src/core/file_sys/archive_romfs.h
+++ b/src/core/file_sys/archive_romfs.h
@@ -20,6 +20,7 @@ namespace FileSys {
 class Archive_RomFS final : public ArchiveBackend {
 public:
     Archive_RomFS(const Loader::AppLoader& app_loader);
+    Archive_RomFS(std::string mount_point);
 
     std::string GetName() const override { return "RomFS"; }
 
@@ -83,15 +84,13 @@ public:
      */
     std::unique_ptr<DirectoryBackend> OpenDirectory(const Path& path) const override;
 
-    ResultCode Open(const Path& path) override {
-        return RESULT_SUCCESS;
-    }
+    ResultCode Open(const Path& path) override;
 
     ResultCode Format(const Path& path) const override;
 
 private:
     friend class File_RomFS;
-
+    std::string mount_point;
     std::vector<u8> raw_data;
 };
 
diff --git a/src/core/hle/service/fs/archive.cpp b/src/core/hle/service/fs/archive.cpp
index 9a91bcb8b..a8383d4e5 100644
--- a/src/core/hle/service/fs/archive.cpp
+++ b/src/core/hle/service/fs/archive.cpp
@@ -10,9 +10,10 @@
 #include "common/make_unique.h"
 #include "common/math_util.h"
 
-#include "core/file_sys/archive_savedata.h"
-#include "core/file_sys/archive_extsavedata.h"
 #include "core/file_sys/archive_backend.h"
+#include "core/file_sys/archive_extsavedata.h"
+#include "core/file_sys/archive_romfs.h"
+#include "core/file_sys/archive_savedata.h"
 #include "core/file_sys/archive_sdmc.h"
 #include "core/file_sys/directory_backend.h"
 #include "core/hle/service/fs/archive.h"
@@ -50,6 +51,9 @@ enum class FileCommand : u32 {
     SetAttributes   = 0x08070040,
     Close           = 0x08080000,
     Flush           = 0x08090000,
+    SetPriority     = 0x080A0040,
+    GetPriority     = 0x080B0000,
+    OpenLinkFile    = 0x080C0000,
 };
 
 // Command to access directory
@@ -75,12 +79,13 @@ public:
 class File : public Kernel::Session {
 public:
     File(std::unique_ptr<FileSys::FileBackend>&& backend, const FileSys::Path& path)
-            : path(path), backend(std::move(backend)) {
+            : path(path), backend(std::move(backend)), priority(0) {
     }
 
     std::string GetName() const override { return "Path: " + path.DebugStr(); }
 
     FileSys::Path path; ///< Path of the file
+    u32 priority; ///< Priority of the file. TODO(Subv): Find out what this means
     std::unique_ptr<FileSys::FileBackend> backend; ///< File backend interface
 
     ResultVal<bool> SyncRequest() override {
@@ -145,6 +150,27 @@ public:
             break;
         }
 
+        case FileCommand::OpenLinkFile:
+        {
+            LOG_WARNING(Service_FS, "(STUBBED) File command OpenLinkFile %s", GetName().c_str());
+            cmd_buff[3] = GetHandle();
+            break;
+        }
+
+        case FileCommand::SetPriority:
+        {
+            priority = cmd_buff[1];
+            LOG_TRACE(Service_FS, "SetPriority %u", priority);
+            break;
+        }
+
+        case FileCommand::GetPriority:
+        {
+            cmd_buff[2] = priority;
+            LOG_TRACE(Service_FS, "GetPriority");
+            break;
+        }
+
         // Unknown command...
         default:
             LOG_ERROR(Service_FS, "Unknown command=0x%08X!", cmd);
@@ -435,6 +461,11 @@ void ArchiveInit() {
     else
         LOG_ERROR(Service_FS, "Can't instantiate SharedExtSaveData archive with path %s", 
                   sharedextsavedata_directory.c_str());
+
+    // Create the SaveDataCheck archive, basically a small variation of the RomFS archive
+    std::string savedatacheck_directory = FileUtil::GetUserPath(D_SAVEDATA_IDX) + "../savedatacheck/";
+    auto savedatacheck_archive = Common::make_unique<FileSys::Archive_RomFS>(savedatacheck_directory);
+    CreateArchive(std::move(savedatacheck_archive), ArchiveIdCode::SaveDataCheck);
 }
 
 /// Shutdown archives
diff --git a/src/core/hle/service/fs/archive.h b/src/core/hle/service/fs/archive.h
index c23b8cc46..f2e4e4a53 100644
--- a/src/core/hle/service/fs/archive.h
+++ b/src/core/hle/service/fs/archive.h
@@ -22,6 +22,7 @@ enum class ArchiveIdCode : u32 {
     SystemSaveData      = 0x00000008,
     SDMC                = 0x00000009,
     SDMCWriteOnly       = 0x0000000A,
+    SaveDataCheck       = 0x2345678A,
 };
 
 typedef u64 ArchiveHandle;