summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar bunnei2014-06-27 16:18:56 -0400
committerGravatar bunnei2014-07-04 20:37:45 -0400
commit17a6148f9df406a6ca4bdca98777e0aaf21f582a (patch)
tree3763cf9417649428c81c7e9e0cb6abac251faa49
parentAPT: Added stubbed ReceiveParameter and various cleanups. (diff)
downloadyuzu-17a6148f9df406a6ca4bdca98777e0aaf21f582a.tar.gz
yuzu-17a6148f9df406a6ca4bdca98777e0aaf21f582a.tar.xz
yuzu-17a6148f9df406a6ca4bdca98777e0aaf21f582a.zip
FileSys: Added preliminary support for applications reading the RomFS archive.
Archive: Fixed brace ugliness for neobrain :) FS: Commented out unused local variables to prevent warnings. ...But keeping them here for future use. archive_romfs: Removed unused #include.
-rw-r--r--src/core/CMakeLists.txt4
-rw-r--r--src/core/core.vcxproj4
-rw-r--r--src/core/core.vcxproj.filters12
-rw-r--r--src/core/file_sys/archive.h54
-rw-r--r--src/core/file_sys/archive_romfs.cpp46
-rw-r--r--src/core/file_sys/archive_romfs.h50
-rw-r--r--src/core/file_sys/file_sys.h138
-rw-r--r--src/core/hle/kernel/archive.cpp98
-rw-r--r--src/core/hle/kernel/archive.h17
-rw-r--r--src/core/hle/service/fs.cpp33
-rw-r--r--src/core/loader/loader.cpp15
11 files changed, 311 insertions, 160 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 978e956dc..9ee803fda 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -8,6 +8,7 @@ set(SRCS core.cpp
8 system.cpp 8 system.cpp
9 arm/disassembler/arm_disasm.cpp 9 arm/disassembler/arm_disasm.cpp
10 arm/disassembler/load_symbol_map.cpp 10 arm/disassembler/load_symbol_map.cpp
11 file_sys/archive_romfs.cpp
11 arm/interpreter/arm_interpreter.cpp 12 arm/interpreter/arm_interpreter.cpp
12 arm/interpreter/armcopro.cpp 13 arm/interpreter/armcopro.cpp
13 arm/interpreter/armemu.cpp 14 arm/interpreter/armemu.cpp
@@ -75,7 +76,8 @@ set(HEADERS core.h
75 arm/interpreter/vfp/asm_vfp.h 76 arm/interpreter/vfp/asm_vfp.h
76 arm/interpreter/vfp/vfp.h 77 arm/interpreter/vfp/vfp.h
77 arm/interpreter/vfp/vfp_helper.h 78 arm/interpreter/vfp/vfp_helper.h
78 file_sys/file_sys.h 79 file_sys/archive.h
80 file_sys/archive_romfs.h
79 hle/config_mem.h 81 hle/config_mem.h
80 hle/coprocessor.h 82 hle/coprocessor.h
81 hle/hle.h 83 hle/hle.h
diff --git a/src/core/core.vcxproj b/src/core/core.vcxproj
index 63efe7c4d..4e521903c 100644
--- a/src/core/core.vcxproj
+++ b/src/core/core.vcxproj
@@ -162,6 +162,7 @@
162 <ClCompile Include="arm\interpreter\vfp\vfpsingle.cpp" /> 162 <ClCompile Include="arm\interpreter\vfp\vfpsingle.cpp" />
163 <ClCompile Include="core.cpp" /> 163 <ClCompile Include="core.cpp" />
164 <ClCompile Include="core_timing.cpp" /> 164 <ClCompile Include="core_timing.cpp" />
165 <ClCompile Include="file_sys\archive_romfs.cpp" />
165 <ClCompile Include="hle\config_mem.cpp" /> 166 <ClCompile Include="hle\config_mem.cpp" />
166 <ClCompile Include="hle\coprocessor.cpp" /> 167 <ClCompile Include="hle\coprocessor.cpp" />
167 <ClCompile Include="hle\hle.cpp" /> 168 <ClCompile Include="hle\hle.cpp" />
@@ -211,7 +212,8 @@
211 <ClInclude Include="arm\interpreter\vfp\vfp_helper.h" /> 212 <ClInclude Include="arm\interpreter\vfp\vfp_helper.h" />
212 <ClInclude Include="core.h" /> 213 <ClInclude Include="core.h" />
213 <ClInclude Include="core_timing.h" /> 214 <ClInclude Include="core_timing.h" />
214 <ClInclude Include="file_sys\file_sys.h" /> 215 <ClInclude Include="file_sys\archive.h" />
216 <ClInclude Include="file_sys\archive_romfs.h" />
215 <ClInclude Include="hle\config_mem.h" /> 217 <ClInclude Include="hle\config_mem.h" />
216 <ClInclude Include="hle\coprocessor.h" /> 218 <ClInclude Include="hle\coprocessor.h" />
217 <ClInclude Include="hle\function_wrappers.h" /> 219 <ClInclude Include="hle\function_wrappers.h" />
diff --git a/src/core/core.vcxproj.filters b/src/core/core.vcxproj.filters
index 39a3cdc4b..17829b8b1 100644
--- a/src/core/core.vcxproj.filters
+++ b/src/core/core.vcxproj.filters
@@ -176,6 +176,9 @@
176 <ClCompile Include="hle\service\fs.cpp"> 176 <ClCompile Include="hle\service\fs.cpp">
177 <Filter>hle\service</Filter> 177 <Filter>hle\service</Filter>
178 </ClCompile> 178 </ClCompile>
179 <ClCompile Include="file_sys\archive_romfs.cpp">
180 <Filter>file_sys</Filter>
181 </ClCompile>
179 </ItemGroup> 182 </ItemGroup>
180 <ItemGroup> 183 <ItemGroup>
181 <ClInclude Include="arm\disassembler\arm_disasm.h"> 184 <ClInclude Include="arm\disassembler\arm_disasm.h">
@@ -205,9 +208,6 @@
205 <ClInclude Include="arm\interpreter\skyeye_defs.h"> 208 <ClInclude Include="arm\interpreter\skyeye_defs.h">
206 <Filter>arm\interpreter</Filter> 209 <Filter>arm\interpreter</Filter>
207 </ClInclude> 210 </ClInclude>
208 <ClInclude Include="file_sys\file_sys.h">
209 <Filter>file_sys</Filter>
210 </ClInclude>
211 <ClInclude Include="hw\hw.h"> 211 <ClInclude Include="hw\hw.h">
212 <Filter>hw</Filter> 212 <Filter>hw</Filter>
213 </ClInclude> 213 </ClInclude>
@@ -314,6 +314,12 @@
314 <ClInclude Include="hle\service\fs.h"> 314 <ClInclude Include="hle\service\fs.h">
315 <Filter>hle\service</Filter> 315 <Filter>hle\service</Filter>
316 </ClInclude> 316 </ClInclude>
317 <ClInclude Include="file_sys\archive.h">
318 <Filter>file_sys</Filter>
319 </ClInclude>
320 <ClInclude Include="file_sys\archive_romfs.h">
321 <Filter>file_sys</Filter>
322 </ClInclude>
317 </ItemGroup> 323 </ItemGroup>
318 <ItemGroup> 324 <ItemGroup>
319 <Text Include="CMakeLists.txt" /> 325 <Text Include="CMakeLists.txt" />
diff --git a/src/core/file_sys/archive.h b/src/core/file_sys/archive.h
new file mode 100644
index 000000000..ed2d83640
--- /dev/null
+++ b/src/core/file_sys/archive.h
@@ -0,0 +1,54 @@
1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include "common/common_types.h"
8
9#include "core/hle/kernel/kernel.h"
10
11////////////////////////////////////////////////////////////////////////////////////////////////////
12// FileSys namespace
13
14namespace FileSys {
15
16class Archive : NonCopyable {
17public:
18 /// Supported archive types
19 enum class IdCode : u32 {
20 RomFS = 0x00000003,
21 SaveData = 0x00000004,
22 ExtSaveData = 0x00000006,
23 SharedExtSaveData = 0x00000007,
24 SystemSaveData = 0x00000008,
25 SDMC = 0x00000009,
26 SDMCWriteOnly = 0x0000000A,
27 };
28
29 Archive() { }
30 virtual ~Archive() { }
31
32 /**
33 * Get the IdCode of the archive (e.g. RomFS, SaveData, etc.)
34 * @return IdCode of the archive
35 */
36 virtual IdCode GetIdCode() const = 0;
37
38 /**
39 * Read data from the archive
40 * @param offset Offset in bytes to start reading archive from
41 * @param length Length in bytes to read data from archive
42 * @param buffer Buffer to read data into
43 * @return Number of bytes read
44 */
45 virtual size_t Read(const u64 offset, const u32 length, u8* buffer) const = 0;
46
47 /**
48 * Get the size of the archive in bytes
49 * @return Size of the archive in bytes
50 */
51 virtual size_t GetSize() const = 0;
52};
53
54} // namespace FileSys
diff --git a/src/core/file_sys/archive_romfs.cpp b/src/core/file_sys/archive_romfs.cpp
new file mode 100644
index 000000000..6fdb768d6
--- /dev/null
+++ b/src/core/file_sys/archive_romfs.cpp
@@ -0,0 +1,46 @@
1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2
3// Refer to the license.txt file included.
4
5#include "common/common_types.h"
6
7#include "core/file_sys/archive_romfs.h"
8
9////////////////////////////////////////////////////////////////////////////////////////////////////
10// FileSys namespace
11
12namespace FileSys {
13
14Archive_RomFS::Archive_RomFS(Loader::AppLoader& app_loader) {
15 // Load the RomFS from the app
16 if (Loader::ResultStatus::Success != app_loader.ReadRomFS(raw_data)) {
17 WARN_LOG(FILESYS, "Unable to read RomFS!");
18 }
19}
20
21Archive_RomFS::~Archive_RomFS() {
22}
23
24/**
25 * Read data from the archive
26 * @param offset Offset in bytes to start reading archive from
27 * @param length Length in bytes to read data from archive
28 * @param buffer Buffer to read data into
29 * @return Number of bytes read
30 */
31size_t Archive_RomFS::Read(const u64 offset, const u32 length, u8* buffer) const {
32 DEBUG_LOG(FILESYS, "called offset=%d, length=%d", offset, length);
33 memcpy(buffer, &raw_data[(u32)offset], length);
34 return length;
35}
36
37/**
38 * Get the size of the archive in bytes
39 * @return Size of the archive in bytes
40 */
41size_t Archive_RomFS::GetSize() const {
42 ERROR_LOG(FILESYS, "(UNIMPLEMENTED)");
43 return 0;
44}
45
46} // namespace FileSys
diff --git a/src/core/file_sys/archive_romfs.h b/src/core/file_sys/archive_romfs.h
new file mode 100644
index 000000000..60af8ff0d
--- /dev/null
+++ b/src/core/file_sys/archive_romfs.h
@@ -0,0 +1,50 @@
1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <vector>
8
9#include "common/common_types.h"
10
11#include "core/file_sys/archive.h"
12#include "core/loader/loader.h"
13
14////////////////////////////////////////////////////////////////////////////////////////////////////
15// FileSys namespace
16
17namespace FileSys {
18
19/// File system interface to the RomFS archive
20class Archive_RomFS : public Archive {
21public:
22 Archive_RomFS(Loader::AppLoader& app_loader);
23 ~Archive_RomFS();
24
25 /**
26 * Get the IdCode of the archive (e.g. RomFS, SaveData, etc.)
27 * @return IdCode of the archive
28 */
29 IdCode GetIdCode() const { return IdCode::RomFS; };
30
31 /**
32 * Read data from the archive
33 * @param offset Offset in bytes to start reading archive from
34 * @param length Length in bytes to read data from archive
35 * @param buffer Buffer to read data into
36 * @return Number of bytes read
37 */
38 size_t Read(const u64 offset, const u32 length, u8* buffer) const;
39
40 /**
41 * Get the size of the archive in bytes
42 * @return Size of the archive in bytes
43 */
44 size_t GetSize() const;
45
46private:
47 std::vector<u8> raw_data;
48};
49
50} // namespace FileSys
diff --git a/src/core/file_sys/file_sys.h b/src/core/file_sys/file_sys.h
deleted file mode 100644
index bb8503e62..000000000
--- a/src/core/file_sys/file_sys.h
+++ /dev/null
@@ -1,138 +0,0 @@
1// Copyright (c) 2012- PPSSPP Project.
2
3// This program is free software: you can redistribute it and/or modify
4// it under the terms of the GNU General Public License as published by
5// the Free Software Foundation, version 2.0 or later versions.
6
7// This program is distributed in the hope that it will be useful,
8// but WITHOUT ANY WARRANTY; without even the implied warranty of
9// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10// GNU General Public License 2.0 for more details.
11
12// A copy of the GPL 2.0 should have been included with the program.
13// If not, see http://www.gnu.org/licenses/
14
15// Official git repository and contact information can be found at
16// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
17
18#pragma once
19
20#include "common/common.h"
21#include "common/chunk_file.h"
22
23enum FileAccess {
24 FILEACCESS_NONE=0,
25 FILEACCESS_READ=1,
26 FILEACCESS_WRITE=2,
27 FILEACCESS_APPEND=4,
28 FILEACCESS_CREATE=8
29};
30
31enum FileMove {
32 FILEMOVE_BEGIN=0,
33 FILEMOVE_CURRENT=1,
34 FILEMOVE_END=2
35};
36
37enum FileType {
38 FILETYPE_NORMAL=1,
39 FILETYPE_DIRECTORY=2
40};
41
42
43class IHandleAllocator {
44public:
45 virtual ~IHandleAllocator() {}
46 virtual u32 GetNewHandle() = 0;
47 virtual void FreeHandle(u32 handle) = 0;
48};
49
50class SequentialHandleAllocator : public IHandleAllocator {
51public:
52 SequentialHandleAllocator() : handle_(1) {}
53 virtual u32 GetNewHandle() { return handle_++; }
54 virtual void FreeHandle(u32 handle) {}
55private:
56 int handle_;
57};
58
59struct FileInfo {
60 FileInfo()
61 : size(0), access(0), exists(false), type(FILETYPE_NORMAL), isOnSectorSystem(false), startSector(0), numSectors(0) {}
62
63 void DoState(PointerWrap &p) {
64 auto s = p.Section("FileInfo", 1);
65 if (!s)
66 return;
67
68 p.Do(name);
69 p.Do(size);
70 p.Do(access);
71 p.Do(exists);
72 p.Do(type);
73 p.Do(atime);
74 p.Do(ctime);
75 p.Do(mtime);
76 p.Do(isOnSectorSystem);
77 p.Do(startSector);
78 p.Do(numSectors);
79 p.Do(sectorSize);
80 }
81
82 std::string name;
83 s64 size;
84 u32 access; //unix 777
85 bool exists;
86 FileType type;
87
88 tm atime;
89 tm ctime;
90 tm mtime;
91
92 bool isOnSectorSystem;
93 u32 startSector;
94 u32 numSectors;
95 u32 sectorSize;
96};
97
98
99class IFileSystem {
100public:
101 virtual ~IFileSystem() {}
102
103 virtual void DoState(PointerWrap &p) = 0;
104 virtual std::vector<FileInfo> GetDirListing(std::string path) = 0;
105 virtual u32 OpenFile(std::string filename, FileAccess access, const char *devicename=NULL) = 0;
106 virtual void CloseFile(u32 handle) = 0;
107 virtual size_t ReadFile(u32 handle, u8 *pointer, s64 size) = 0;
108 virtual size_t WriteFile(u32 handle, const u8 *pointer, s64 size) = 0;
109 virtual size_t SeekFile(u32 handle, s32 position, FileMove type) = 0;
110 virtual FileInfo GetFileInfo(std::string filename) = 0;
111 virtual bool OwnsHandle(u32 handle) = 0;
112 virtual bool MkDir(const std::string &dirname) = 0;
113 virtual bool RmDir(const std::string &dirname) = 0;
114 virtual int RenameFile(const std::string &from, const std::string &to) = 0;
115 virtual bool RemoveFile(const std::string &filename) = 0;
116 virtual bool GetHostPath(const std::string &inpath, std::string &outpath) = 0;
117};
118
119
120class EmptyFileSystem : public IFileSystem {
121public:
122 virtual void DoState(PointerWrap &p) {}
123 std::vector<FileInfo> GetDirListing(std::string path) {std::vector<FileInfo> vec; return vec;}
124 u32 OpenFile(std::string filename, FileAccess access, const char *devicename=NULL) {return 0;}
125 void CloseFile(u32 handle) {}
126 size_t ReadFile(u32 handle, u8 *pointer, s64 size) {return 0;}
127 size_t WriteFile(u32 handle, const u8 *pointer, s64 size) {return 0;}
128 size_t SeekFile(u32 handle, s32 position, FileMove type) {return 0;}
129 FileInfo GetFileInfo(std::string filename) {FileInfo f; return f;}
130 bool OwnsHandle(u32 handle) {return false;}
131 virtual bool MkDir(const std::string &dirname) {return false;}
132 virtual bool RmDir(const std::string &dirname) {return false;}
133 virtual int RenameFile(const std::string &from, const std::string &to) {return -1;}
134 virtual bool RemoveFile(const std::string &filename) {return false;}
135 virtual bool GetHostPath(const std::string &inpath, std::string &outpath) {return false;}
136};
137
138
diff --git a/src/core/hle/kernel/archive.cpp b/src/core/hle/kernel/archive.cpp
index d7351e702..f31c02ea9 100644
--- a/src/core/hle/kernel/archive.cpp
+++ b/src/core/hle/kernel/archive.cpp
@@ -4,6 +4,8 @@
4 4
5#include "common/common_types.h" 5#include "common/common_types.h"
6 6
7#include "core/file_sys/archive.h"
8#include "core/hle/service/service.h"
7#include "core/hle/kernel/kernel.h" 9#include "core/hle/kernel/kernel.h"
8#include "core/hle/kernel/archive.h" 10#include "core/hle/kernel/archive.h"
9 11
@@ -12,6 +14,21 @@
12 14
13namespace Kernel { 15namespace Kernel {
14 16
17// Command to access archive file
18enum class FileCommand : u32 {
19 Dummy1 = 0x000100C6,
20 Control = 0x040100C4,
21 OpenSubFile = 0x08010100,
22 Read = 0x080200C2,
23 Write = 0x08030102,
24 GetSize = 0x08040000,
25 SetSize = 0x08050080,
26 GetAttributes = 0x08060000,
27 SetAttributes = 0x08070040,
28 Close = 0x08080000,
29 Flush = 0x08090000,
30};
31
15class Archive : public Object { 32class Archive : public Object {
16public: 33public:
17 const char* GetTypeName() const { return "Archive"; } 34 const char* GetTypeName() const { return "Archive"; }
@@ -20,7 +37,37 @@ public:
20 static Kernel::HandleType GetStaticHandleType() { return HandleType::Archive; } 37 static Kernel::HandleType GetStaticHandleType() { return HandleType::Archive; }
21 Kernel::HandleType GetHandleType() const { return HandleType::Archive; } 38 Kernel::HandleType GetHandleType() const { return HandleType::Archive; }
22 39
23 std::string name; ///< Name of archive (optional) 40 std::string name; ///< Name of archive (optional)
41 FileSys::Archive* backend; ///< Archive backend interface
42
43 /**
44 * Synchronize kernel object
45 * @param wait Boolean wait set if current thread should wait as a result of sync operation
46 * @return Result of operation, 0 on success, otherwise error code
47 */
48 Result SyncRequest(bool* wait) {
49 u32* cmd_buff = Service::GetCommandBuffer();
50 FileCommand cmd = static_cast<FileCommand>(cmd_buff[0]);
51 switch (cmd) {
52
53 // Read from archive...
54 case FileCommand::Read:
55 {
56 u64 offset = cmd_buff[1] | ((u64) cmd_buff[2]) << 32;
57 u32 length = cmd_buff[3];
58 u32 address = cmd_buff[5];
59 cmd_buff[2] = backend->Read(offset, length, Memory::GetPointer(address));
60 break;
61 }
62
63 // Unknown command...
64 default:
65 ERROR_LOG(KERNEL, "Unknown command=0x%08X!", cmd);
66 return -1;
67 }
68 cmd_buff[1] = 0; // No error
69 return 0;
70 }
24 71
25 /** 72 /**
26 * Wait for kernel object to synchronize 73 * Wait for kernel object to synchronize
@@ -29,32 +76,71 @@ public:
29 */ 76 */
30 Result WaitSynchronization(bool* wait) { 77 Result WaitSynchronization(bool* wait) {
31 // TODO(bunnei): ImplementMe 78 // TODO(bunnei): ImplementMe
32 ERROR_LOG(OSHLE, "unimplemented function"); 79 ERROR_LOG(OSHLE, "(UNIMPLEMENTED)");
33 return 0; 80 return 0;
34 } 81 }
35}; 82};
36 83
84////////////////////////////////////////////////////////////////////////////////////////////////////
85
86std::map<FileSys::Archive::IdCode, Handle> g_archive_map; ///< Map of file archives by IdCode
87
88/**
89 * Opens an archive
90 * @param id_code IdCode of the archive to open
91 * @return Handle to archive if it exists, otherwise a null handle (0)
92 */
93Handle OpenArchive(FileSys::Archive::IdCode id_code) {
94 auto itr = g_archive_map.find(id_code);
95 if (itr == g_archive_map.end()) {
96 return 0;
97 }
98 return itr->second;
99}
100
101/**
102 * Mounts an archive
103 * @param archive Pointer to the archive to mount
104 * @return Result of operation, 0 on success, otherwise error code
105 */
106Result MountArchive(Archive* archive) {
107 FileSys::Archive::IdCode id_code = archive->backend->GetIdCode();
108 if (0 != OpenArchive(id_code)) {
109 ERROR_LOG(KERNEL, "Cannot mount two archives with the same ID code! (%d)", (int) id_code);
110 return -1;
111 }
112 g_archive_map[id_code] = archive->GetHandle();
113 INFO_LOG(KERNEL, "Mounted archive %s", archive->GetName());
114 return 0;
115}
116
37/** 117/**
38 * Creates an Archive 118 * Creates an Archive
39 * @param name Optional name of Archive
40 * @param handle Handle to newly created archive object 119 * @param handle Handle to newly created archive object
120 * @param backend File system backend interface to the archive
121 * @param name Optional name of Archive
41 * @return Newly created Archive object 122 * @return Newly created Archive object
42 */ 123 */
43Archive* CreateArchive(Handle& handle, const std::string& name) { 124Archive* CreateArchive(Handle& handle, FileSys::Archive* backend, const std::string& name) {
44 Archive* archive = new Archive; 125 Archive* archive = new Archive;
45 handle = Kernel::g_object_pool.Create(archive); 126 handle = Kernel::g_object_pool.Create(archive);
46 archive->name = name; 127 archive->name = name;
128 archive->backend = backend;
129
130 MountArchive(archive);
131
47 return archive; 132 return archive;
48} 133}
49 134
50/** 135/**
51 * Creates an Archive 136 * Creates an Archive
137 * @param backend File system backend interface to the archive
52 * @param name Optional name of Archive 138 * @param name Optional name of Archive
53 * @return Handle to newly created Archive object 139 * @return Handle to newly created Archive object
54 */ 140 */
55Handle CreateArchive(const std::string& name) { 141Handle CreateArchive(FileSys::Archive* backend, const std::string& name) {
56 Handle handle; 142 Handle handle;
57 Archive* archive = CreateArchive(handle, name); 143 Archive* archive = CreateArchive(handle, backend, name);
58 return handle; 144 return handle;
59} 145}
60 146
diff --git a/src/core/hle/kernel/archive.h b/src/core/hle/kernel/archive.h
index 98670f06c..07fb37ae7 100644
--- a/src/core/hle/kernel/archive.h
+++ b/src/core/hle/kernel/archive.h
@@ -7,6 +7,7 @@
7#include "common/common_types.h" 7#include "common/common_types.h"
8 8
9#include "core/hle/kernel/kernel.h" 9#include "core/hle/kernel/kernel.h"
10#include "core/file_sys/archive.h"
10 11
11//////////////////////////////////////////////////////////////////////////////////////////////////// 12////////////////////////////////////////////////////////////////////////////////////////////////////
12// Kernel namespace 13// Kernel namespace
@@ -14,10 +15,18 @@
14namespace Kernel { 15namespace Kernel {
15 16
16/** 17/**
17 * Creates an archive 18 * Opens an archive
18 * @param name Optional name of archive 19 * @param id_code IdCode of the archive to open
19 * @return Handle to newly created archive object 20 * @return Handle to archive if it exists, otherwise a null handle (0)
20 */ 21 */
21Handle CreateArchive(const std::string& name="Unknown"); 22Handle OpenArchive(FileSys::Archive::IdCode id_code);
23
24/**
25 * Creates an Archive
26 * @param backend File system backend interface to the archive
27 * @param name Optional name of Archive
28 * @return Handle to newly created Archive object
29 */
30Handle CreateArchive(FileSys::Archive* backend, const std::string& name);
22 31
23} // namespace FileSys 32} // namespace FileSys
diff --git a/src/core/hle/service/fs.cpp b/src/core/hle/service/fs.cpp
index 3a5afaa3c..5eabf36ad 100644
--- a/src/core/hle/service/fs.cpp
+++ b/src/core/hle/service/fs.cpp
@@ -2,11 +2,12 @@
2// Licensed under GPLv2 2// Licensed under GPLv2
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5
6#include "common/common.h" 5#include "common/common.h"
7 6
7#include "core/loader/loader.h"
8#include "core/hle/hle.h" 8#include "core/hle/hle.h"
9#include "core/hle/service/fs.h" 9#include "core/hle/service/fs.h"
10#include "core/hle/kernel/archive.h"
10 11
11//////////////////////////////////////////////////////////////////////////////////////////////////// 12////////////////////////////////////////////////////////////////////////////////////////////////////
12// Namespace FS_User 13// Namespace FS_User
@@ -15,8 +16,34 @@ namespace FS_User {
15 16
16void Initialize(Service::Interface* self) { 17void Initialize(Service::Interface* self) {
17 u32* cmd_buff = Service::GetCommandBuffer(); 18 u32* cmd_buff = Service::GetCommandBuffer();
18 DEBUG_LOG(KERNEL, "called");
19 cmd_buff[1] = 0; // No error 19 cmd_buff[1] = 0; // No error
20 DEBUG_LOG(KERNEL, "called");
21}
22
23void OpenFileDirectly(Service::Interface* self) {
24 u32* cmd_buff = Service::GetCommandBuffer();
25
26 FileSys::Archive::IdCode arch_id = static_cast<FileSys::Archive::IdCode>(cmd_buff[2]);
27
28 // TODO(bunnei): Properly implement use of these...
29 //u32 transaction = cmd_buff[1];
30 //u32 arch_lowpath_type = cmd_buff[3];
31 //u32 arch_lowpath_sz = cmd_buff[4];
32 //u32 file_lowpath_type = cmd_buff[5];
33 //u32 file_lowpath_sz = cmd_buff[6];
34 //u32 flags = cmd_buff[7];
35 //u32 attr = cmd_buff[8];
36 //u32 arch_lowpath_desc = cmd_buff[9];
37 //u32 arch_lowpath_ptr = cmd_buff[10];
38 //u32 file_lowpath_desc = cmd_buff[11];
39 //u32 file_lowpath_ptr = cmd_buff[12];
40
41 Handle handle = Kernel::OpenArchive(arch_id);
42 if (0 != handle) {
43 cmd_buff[1] = 0; // No error
44 cmd_buff[3] = handle;
45 }
46 DEBUG_LOG(KERNEL, "called");
20} 47}
21 48
22const Interface::FunctionInfo FunctionTable[] = { 49const Interface::FunctionInfo FunctionTable[] = {
@@ -24,7 +51,7 @@ const Interface::FunctionInfo FunctionTable[] = {
24 {0x040100C4, nullptr, "Control"}, 51 {0x040100C4, nullptr, "Control"},
25 {0x08010002, Initialize, "Initialize"}, 52 {0x08010002, Initialize, "Initialize"},
26 {0x080201C2, nullptr, "OpenFile"}, 53 {0x080201C2, nullptr, "OpenFile"},
27 {0x08030204, nullptr, "OpenFileDirectly"}, 54 {0x08030204, OpenFileDirectly, "OpenFileDirectly"},
28 {0x08040142, nullptr, "DeleteFile"}, 55 {0x08040142, nullptr, "DeleteFile"},
29 {0x08050244, nullptr, "RenameFile"}, 56 {0x08050244, nullptr, "RenameFile"},
30 {0x08060142, nullptr, "DeleteDirectory"}, 57 {0x08060142, nullptr, "DeleteDirectory"},
diff --git a/src/core/loader/loader.cpp b/src/core/loader/loader.cpp
index 96cb81de0..2b42e3c64 100644
--- a/src/core/loader/loader.cpp
+++ b/src/core/loader/loader.cpp
@@ -4,9 +4,11 @@
4 4
5#include <memory> 5#include <memory>
6 6
7#include "core/file_sys/archive_romfs.h"
7#include "core/loader/loader.h" 8#include "core/loader/loader.h"
8#include "core/loader/elf.h" 9#include "core/loader/elf.h"
9#include "core/loader/ncch.h" 10#include "core/loader/ncch.h"
11#include "core/hle/kernel/archive.h"
10 12
11//////////////////////////////////////////////////////////////////////////////////////////////////// 13////////////////////////////////////////////////////////////////////////////////////////////////////
12 14
@@ -51,14 +53,20 @@ ResultStatus LoadFile(const std::string& filename) {
51 switch (IdentifyFile(filename)) { 53 switch (IdentifyFile(filename)) {
52 54
53 // Standard ELF file format... 55 // Standard ELF file format...
54 case FileType::ELF: { 56 case FileType::ELF:
55 return AppLoader_ELF(filename).Load(); 57 return AppLoader_ELF(filename).Load();
56 }
57 58
58 // NCCH/NCSD container formats... 59 // NCCH/NCSD container formats...
59 case FileType::CXI: 60 case FileType::CXI:
60 case FileType::CCI: { 61 case FileType::CCI: {
61 return AppLoader_NCCH(filename).Load(); 62 AppLoader_NCCH app_loader(filename);
63
64 // Load application and RomFS
65 if (ResultStatus::Success == app_loader.Load()) {
66 Kernel::CreateArchive(new FileSys::Archive_RomFS(app_loader), "RomFS");
67 return ResultStatus::Success;
68 }
69 break;
62 } 70 }
63 71
64 // Error occurred durring IdentifyFile... 72 // Error occurred durring IdentifyFile...
@@ -70,7 +78,6 @@ ResultStatus LoadFile(const std::string& filename) {
70 default: 78 default:
71 return ResultStatus::ErrorInvalidFormat; 79 return ResultStatus::ErrorInvalidFormat;
72 } 80 }
73
74 return ResultStatus::Error; 81 return ResultStatus::Error;
75} 82}
76 83