From 0647f866498412f22999966cc97b122db2ef9318 Mon Sep 17 00:00:00 2001
From: wwylele <wwylele@gmail.com>
Date: Thu, 20 Oct 2016 11:45:01 +0800
Subject: [PATCH] FileSys: w->rw permission lift only happens in SDMC archive

---
 src/core/file_sys/archive_sdmc.cpp          | 11 +++++++++++
 src/core/file_sys/archive_sdmc.h            |  1 +
 src/core/file_sys/archive_sdmcwriteonly.cpp |  2 +-
 src/core/file_sys/disk_archive.cpp          |  2 +-
 4 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/src/core/file_sys/archive_sdmc.cpp b/src/core/file_sys/archive_sdmc.cpp
index c747ba82c..333dfb92e 100644
--- a/src/core/file_sys/archive_sdmc.cpp
+++ b/src/core/file_sys/archive_sdmc.cpp
@@ -19,6 +19,17 @@ namespace FileSys {
 
 ResultVal<std::unique_ptr<FileBackend>> SDMCArchive::OpenFile(const Path& path,
                                                               const Mode& mode) const {
+    Mode modified_mode;
+    modified_mode.hex = mode.hex;
+
+    // SDMC archive always opens a file with at least read permission
+    modified_mode.read_flag.Assign(1);
+
+    return OpenFileBase(path, modified_mode);
+}
+
+ResultVal<std::unique_ptr<FileBackend>> SDMCArchive::OpenFileBase(const Path& path,
+                                                                  const Mode& mode) const {
     LOG_DEBUG(Service_FS, "called path=%s mode=%01X", path.DebugStr().c_str(), mode.hex);
 
     const PathParser path_parser(path);
diff --git a/src/core/file_sys/archive_sdmc.h b/src/core/file_sys/archive_sdmc.h
index 4fa47ff35..9d99b110c 100644
--- a/src/core/file_sys/archive_sdmc.h
+++ b/src/core/file_sys/archive_sdmc.h
@@ -36,6 +36,7 @@ public:
     u64 GetFreeBytes() const override;
 
 protected:
+    ResultVal<std::unique_ptr<FileBackend>> OpenFileBase(const Path& path, const Mode& mode) const;
     std::string mount_point;
 };
 
diff --git a/src/core/file_sys/archive_sdmcwriteonly.cpp b/src/core/file_sys/archive_sdmcwriteonly.cpp
index 64ae49b86..2aafc9b1d 100644
--- a/src/core/file_sys/archive_sdmcwriteonly.cpp
+++ b/src/core/file_sys/archive_sdmcwriteonly.cpp
@@ -21,7 +21,7 @@ ResultVal<std::unique_ptr<FileBackend>> SDMCWriteOnlyArchive::OpenFile(const Pat
         LOG_ERROR(Service_FS, "Read flag is not supported");
         return ERROR_INVALID_READ_FLAG;
     }
-    return SDMCArchive::OpenFile(path, mode);
+    return SDMCArchive::OpenFileBase(path, mode);
 }
 
 ResultVal<std::unique_ptr<DirectoryBackend>> SDMCWriteOnlyArchive::OpenDirectory(
diff --git a/src/core/file_sys/disk_archive.cpp b/src/core/file_sys/disk_archive.cpp
index 43d199434..0e51fd1a6 100644
--- a/src/core/file_sys/disk_archive.cpp
+++ b/src/core/file_sys/disk_archive.cpp
@@ -163,7 +163,7 @@ u64 DiskArchive::GetFreeBytes() const {
 ////////////////////////////////////////////////////////////////////////////////////////////////////
 
 ResultVal<size_t> DiskFile::Read(const u64 offset, const size_t length, u8* buffer) const {
-    if (!mode.read_flag && !mode.write_flag)
+    if (!mode.read_flag)
         return ResultCode(ErrorDescription::FS_InvalidOpenFlags, ErrorModule::FS,
                           ErrorSummary::Canceled, ErrorLevel::Status);