diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/CMakeLists.txt | 4 | ||||
| -rw-r--r-- | src/core/core.vcxproj | 4 | ||||
| -rw-r--r-- | src/core/core.vcxproj.filters | 12 | ||||
| -rw-r--r-- | src/core/file_sys/archive.h | 54 | ||||
| -rw-r--r-- | src/core/file_sys/archive_romfs.cpp | 46 | ||||
| -rw-r--r-- | src/core/file_sys/archive_romfs.h | 50 | ||||
| -rw-r--r-- | src/core/file_sys/file_sys.h | 138 | ||||
| -rw-r--r-- | src/core/hle/kernel/archive.cpp | 98 | ||||
| -rw-r--r-- | src/core/hle/kernel/archive.h | 17 | ||||
| -rw-r--r-- | src/core/hle/service/fs.cpp | 33 | ||||
| -rw-r--r-- | src/core/loader/loader.cpp | 15 |
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 | |||
| 14 | namespace FileSys { | ||
| 15 | |||
| 16 | class Archive : NonCopyable { | ||
| 17 | public: | ||
| 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 | |||
| 12 | namespace FileSys { | ||
| 13 | |||
| 14 | Archive_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 | |||
| 21 | Archive_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 | */ | ||
| 31 | size_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 | */ | ||
| 41 | size_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 | |||
| 17 | namespace FileSys { | ||
| 18 | |||
| 19 | /// File system interface to the RomFS archive | ||
| 20 | class Archive_RomFS : public Archive { | ||
| 21 | public: | ||
| 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 | |||
| 46 | private: | ||
| 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 | |||
| 23 | enum FileAccess { | ||
| 24 | FILEACCESS_NONE=0, | ||
| 25 | FILEACCESS_READ=1, | ||
| 26 | FILEACCESS_WRITE=2, | ||
| 27 | FILEACCESS_APPEND=4, | ||
| 28 | FILEACCESS_CREATE=8 | ||
| 29 | }; | ||
| 30 | |||
| 31 | enum FileMove { | ||
| 32 | FILEMOVE_BEGIN=0, | ||
| 33 | FILEMOVE_CURRENT=1, | ||
| 34 | FILEMOVE_END=2 | ||
| 35 | }; | ||
| 36 | |||
| 37 | enum FileType { | ||
| 38 | FILETYPE_NORMAL=1, | ||
| 39 | FILETYPE_DIRECTORY=2 | ||
| 40 | }; | ||
| 41 | |||
| 42 | |||
| 43 | class IHandleAllocator { | ||
| 44 | public: | ||
| 45 | virtual ~IHandleAllocator() {} | ||
| 46 | virtual u32 GetNewHandle() = 0; | ||
| 47 | virtual void FreeHandle(u32 handle) = 0; | ||
| 48 | }; | ||
| 49 | |||
| 50 | class SequentialHandleAllocator : public IHandleAllocator { | ||
| 51 | public: | ||
| 52 | SequentialHandleAllocator() : handle_(1) {} | ||
| 53 | virtual u32 GetNewHandle() { return handle_++; } | ||
| 54 | virtual void FreeHandle(u32 handle) {} | ||
| 55 | private: | ||
| 56 | int handle_; | ||
| 57 | }; | ||
| 58 | |||
| 59 | struct 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 | |||
| 99 | class IFileSystem { | ||
| 100 | public: | ||
| 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 | |||
| 120 | class EmptyFileSystem : public IFileSystem { | ||
| 121 | public: | ||
| 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 | ||
| 13 | namespace Kernel { | 15 | namespace Kernel { |
| 14 | 16 | ||
| 17 | // Command to access archive file | ||
| 18 | enum 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 | |||
| 15 | class Archive : public Object { | 32 | class Archive : public Object { |
| 16 | public: | 33 | public: |
| 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 | |||
| 86 | std::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 | */ | ||
| 93 | Handle 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 | */ | ||
| 106 | Result 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 | */ |
| 43 | Archive* CreateArchive(Handle& handle, const std::string& name) { | 124 | Archive* 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 | */ |
| 55 | Handle CreateArchive(const std::string& name) { | 141 | Handle 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 @@ | |||
| 14 | namespace Kernel { | 15 | namespace 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 | */ |
| 21 | Handle CreateArchive(const std::string& name="Unknown"); | 22 | Handle 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 | */ | ||
| 30 | Handle 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 | ||
| 16 | void Initialize(Service::Interface* self) { | 17 | void 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 | |||
| 23 | void 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 | ||
| 22 | const Interface::FunctionInfo FunctionTable[] = { | 49 | const 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 | ||