From 23c2fbfc7a900ae3c9f8791a87c5ad672f5778fe Mon Sep 17 00:00:00 2001
From: Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
Date: Sat, 27 Sep 2014 19:16:51 +0000
Subject: [PATCH] FileSys/Kernel: Implement SetSize service call for File
 objects.

---
 src/core/file_sys/file.h         |  7 +++++++
 src/core/file_sys/file_romfs.cpp |  9 +++++++++
 src/core/file_sys/file_romfs.h   |  7 +++++++
 src/core/file_sys/file_sdmc.cpp  | 11 +++++++++++
 src/core/file_sys/file_sdmc.h    |  7 +++++++
 src/core/hle/kernel/archive.cpp  |  8 ++++++++
 6 files changed, 49 insertions(+)

diff --git a/src/core/file_sys/file.h b/src/core/file_sys/file.h
index 3749e4fcf7..443e65319e 100644
--- a/src/core/file_sys/file.h
+++ b/src/core/file_sys/file.h
@@ -43,6 +43,13 @@ public:
      */
     virtual size_t GetSize() const = 0;
 
+    /**
+     * Set the size of the file in bytes
+     * @param size New size of the file
+     * @return true if successful
+     */
+    virtual bool SetSize(const u64 size) const = 0;
+
     /**
      * Close the file
      * @return true if the file closed correctly
diff --git a/src/core/file_sys/file_romfs.cpp b/src/core/file_sys/file_romfs.cpp
index 0709e98f0d..3ef616e083 100644
--- a/src/core/file_sys/file_romfs.cpp
+++ b/src/core/file_sys/file_romfs.cpp
@@ -48,6 +48,15 @@ size_t File_RomFS::GetSize() const {
     return -1;
 }
 
+/**
+ * Set the size of the file in bytes
+ * @param size New size of the file
+ * @return true if successful
+ */
+bool File_RomFS::SetSize(const u64 size) const {
+    return false;
+}
+
 /**
  * Close the file
  * @return true if the file closed correctly
diff --git a/src/core/file_sys/file_romfs.h b/src/core/file_sys/file_romfs.h
index 28b4f1158d..06973eb938 100644
--- a/src/core/file_sys/file_romfs.h
+++ b/src/core/file_sys/file_romfs.h
@@ -44,6 +44,13 @@ public:
      */
     size_t GetSize() const override;
 
+    /**
+     * Set the size of the file in bytes
+     * @param size New size of the file
+     * @return true if successful
+     */
+    bool SetSize(const u64 size) const override;
+
     /**
      * Close the file
      * @return true if the file closed correctly
diff --git a/src/core/file_sys/file_sdmc.cpp b/src/core/file_sys/file_sdmc.cpp
index 76e7f5d3dd..3ef2b0c0e7 100644
--- a/src/core/file_sys/file_sdmc.cpp
+++ b/src/core/file_sys/file_sdmc.cpp
@@ -75,6 +75,17 @@ size_t File_SDMC::GetSize() const {
     return static_cast<size_t>(file->GetSize());
 }
 
+/**
+ * Set the size of the file in bytes
+ * @param size New size of the file
+ * @return true if successful
+ */
+bool File_SDMC::SetSize(const u64 size) const {
+    file->Resize(size);
+    file->Flush();
+    return true;
+}
+
 /**
  * Close the file
  * @return true if the file closed correctly
diff --git a/src/core/file_sys/file_sdmc.h b/src/core/file_sys/file_sdmc.h
index d23020494e..6b3a1f3a59 100644
--- a/src/core/file_sys/file_sdmc.h
+++ b/src/core/file_sys/file_sdmc.h
@@ -47,6 +47,13 @@ public:
      */
     size_t GetSize() const override;
 
+    /**
+     * Set the size of the file in bytes
+     * @param size New size of the file
+     * @return true if successful
+     */
+    bool SetSize(const u64 size) const override;
+
     /**
      * Close the file
      * @return true if the file closed correctly
diff --git a/src/core/hle/kernel/archive.cpp b/src/core/hle/kernel/archive.cpp
index fa49729945..0a66ab29bb 100644
--- a/src/core/hle/kernel/archive.cpp
+++ b/src/core/hle/kernel/archive.cpp
@@ -181,6 +181,14 @@ public:
             break;
         }
 
+        case FileCommand::SetSize:
+        {
+            u64 size = cmd_buff[1] | ((u64)cmd_buff[2] << 32);
+            DEBUG_LOG(KERNEL, "SetSize %s %s size=%d", GetTypeName().c_str(), GetName().c_str(), size);
+            backend->SetSize(size);
+            break;
+        }
+
         case FileCommand::Close:
         {
             DEBUG_LOG(KERNEL, "Close %s %s", GetTypeName().c_str(), GetName().c_str());