From c4ca802b9dc7f0d3f3aed5aa937240bf85370c15 Mon Sep 17 00:00:00 2001
From: Subv <subv2112@gmail.com>
Date: Mon, 19 Mar 2018 21:17:15 -0500
Subject: [PATCH] FS: Added an SDMC archive factory and registered it to the
 SDMC archive on startup.

---
 src/core/CMakeLists.txt                       |  2 +
 src/core/file_sys/sdmc_factory.cpp            | 40 +++++++++++++++++++
 src/core/file_sys/sdmc_factory.h              | 31 ++++++++++++++
 .../hle/service/filesystem/filesystem.cpp     |  5 +++
 src/core/hle/service/filesystem/filesystem.h  |  1 +
 5 files changed, 79 insertions(+)
 create mode 100644 src/core/file_sys/sdmc_factory.cpp
 create mode 100644 src/core/file_sys/sdmc_factory.h

diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index faaa50e4d..d2275d9a9 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -22,6 +22,8 @@ add_library(core STATIC
     file_sys/romfs_filesystem.h
     file_sys/savedata_factory.cpp
     file_sys/savedata_factory.h
+    file_sys/sdmc_factory.cpp
+    file_sys/sdmc_factory.h
     file_sys/storage.h
     frontend/emu_window.cpp
     frontend/emu_window.h
diff --git a/src/core/file_sys/sdmc_factory.cpp b/src/core/file_sys/sdmc_factory.cpp
new file mode 100644
index 000000000..00e80d2a7
--- /dev/null
+++ b/src/core/file_sys/sdmc_factory.cpp
@@ -0,0 +1,40 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include <cinttypes>
+#include <memory>
+#include "common/common_types.h"
+#include "common/logging/log.h"
+#include "common/string_util.h"
+#include "core/core.h"
+#include "core/file_sys/disk_filesystem.h"
+#include "core/file_sys/sdmc_factory.h"
+
+namespace FileSys {
+
+SDMC_Factory::SDMC_Factory(std::string sd_directory) : sd_directory(std::move(sd_directory)) {}
+
+ResultVal<std::unique_ptr<FileSystemBackend>> SDMC_Factory::Open(const Path& path) {
+    // Create the SD Card directory if it doesn't already exist.
+    if (!FileUtil::IsDirectory(sd_directory)) {
+        FileUtil::CreateFullPath(sd_directory);
+    }
+
+    auto archive = std::make_unique<Disk_FileSystem>(sd_directory);
+    return MakeResult<std::unique_ptr<FileSystemBackend>>(std::move(archive));
+}
+
+ResultCode SDMC_Factory::Format(const Path& path) {
+    LOG_ERROR(Service_FS, "Unimplemented Format archive %s", GetName().c_str());
+    // TODO(Subv): Find the right error code for this
+    return ResultCode(-1);
+}
+
+ResultVal<ArchiveFormatInfo> SDMC_Factory::GetFormatInfo(const Path& path) const {
+    LOG_ERROR(Service_FS, "Unimplemented GetFormatInfo archive %s", GetName().c_str());
+    // TODO(bunnei): Find the right error code for this
+    return ResultCode(-1);
+}
+
+} // namespace FileSys
diff --git a/src/core/file_sys/sdmc_factory.h b/src/core/file_sys/sdmc_factory.h
new file mode 100644
index 000000000..93becda25
--- /dev/null
+++ b/src/core/file_sys/sdmc_factory.h
@@ -0,0 +1,31 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include <memory>
+#include <string>
+#include "common/common_types.h"
+#include "core/file_sys/filesystem.h"
+#include "core/hle/result.h"
+
+namespace FileSys {
+
+/// File system interface to the SDCard archive
+class SDMC_Factory final : public FileSystemFactory {
+public:
+    explicit SDMC_Factory(std::string sd_directory);
+
+    std::string GetName() const override {
+        return "SDMC_Factory";
+    }
+    ResultVal<std::unique_ptr<FileSystemBackend>> Open(const Path& path) override;
+    ResultCode Format(const Path& path) override;
+    ResultVal<ArchiveFormatInfo> GetFormatInfo(const Path& path) const override;
+
+private:
+    std::string sd_directory;
+};
+
+} // namespace FileSys
diff --git a/src/core/hle/service/filesystem/filesystem.cpp b/src/core/hle/service/filesystem/filesystem.cpp
index ef05955b9..945832e98 100644
--- a/src/core/hle/service/filesystem/filesystem.cpp
+++ b/src/core/hle/service/filesystem/filesystem.cpp
@@ -6,6 +6,7 @@
 #include "common/file_util.h"
 #include "core/file_sys/filesystem.h"
 #include "core/file_sys/savedata_factory.h"
+#include "core/file_sys/sdmc_factory.h"
 #include "core/hle/service/filesystem/filesystem.h"
 #include "core/hle/service/filesystem/fsp_srv.h"
 
@@ -60,9 +61,13 @@ void RegisterFileSystems() {
     filesystem_map.clear();
 
     std::string nand_directory = FileUtil::GetUserPath(D_NAND_IDX);
+    std::string sd_directory = FileUtil::GetUserPath(D_SDMC_IDX);
 
     auto savedata = std::make_unique<FileSys::SaveData_Factory>(std::move(nand_directory));
     RegisterFileSystem(std::move(savedata), Type::SaveData);
+
+    auto sdcard = std::make_unique<FileSys::SDMC_Factory>(std::move(sd_directory));
+    RegisterFileSystem(std::move(sdcard), Type::SDMC);
 }
 
 void InstallInterfaces(SM::ServiceManager& service_manager) {
diff --git a/src/core/hle/service/filesystem/filesystem.h b/src/core/hle/service/filesystem/filesystem.h
index 8d30e94a1..56d26146e 100644
--- a/src/core/hle/service/filesystem/filesystem.h
+++ b/src/core/hle/service/filesystem/filesystem.h
@@ -26,6 +26,7 @@ namespace FileSystem {
 enum class Type {
     RomFS = 1,
     SaveData = 2,
+    SDMC = 3,
 };
 
 /**