diff options
| author | 2014-09-12 00:45:40 +0200 | |
|---|---|---|
| committer | 2014-09-17 14:35:46 +0000 | |
| commit | 19d04f3abe4427b38a04a60080f52fdf5b9ee7fe (patch) | |
| tree | e1d61a73e4de9d5e202c2744ee19902ab39fc761 /src/core/hle/kernel/archive.cpp | |
| parent | Core: Add a passthrough backend for the filesystem, exposed as SDMC. (diff) | |
| download | yuzu-19d04f3abe4427b38a04a60080f52fdf5b9ee7fe.tar.gz yuzu-19d04f3abe4427b38a04a60080f52fdf5b9ee7fe.tar.xz yuzu-19d04f3abe4427b38a04a60080f52fdf5b9ee7fe.zip | |
Kernel: Add a File object and a getter for it from an Archive object.
Diffstat (limited to 'src/core/hle/kernel/archive.cpp')
| -rw-r--r-- | src/core/hle/kernel/archive.cpp | 109 |
1 files changed, 109 insertions, 0 deletions
diff --git a/src/core/hle/kernel/archive.cpp b/src/core/hle/kernel/archive.cpp index 20536f40f..24b2262bc 100644 --- a/src/core/hle/kernel/archive.cpp +++ b/src/core/hle/kernel/archive.cpp | |||
| @@ -3,9 +3,11 @@ | |||
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include "common/common_types.h" | 5 | #include "common/common_types.h" |
| 6 | #include "common/file_util.h" | ||
| 6 | #include "common/math_util.h" | 7 | #include "common/math_util.h" |
| 7 | 8 | ||
| 8 | #include "core/file_sys/archive.h" | 9 | #include "core/file_sys/archive.h" |
| 10 | #include "core/file_sys/archive_sdmc.h" | ||
| 9 | #include "core/hle/service/service.h" | 11 | #include "core/hle/service/service.h" |
| 10 | #include "core/hle/kernel/archive.h" | 12 | #include "core/hle/kernel/archive.h" |
| 11 | 13 | ||
| @@ -108,6 +110,83 @@ public: | |||
| 108 | } | 110 | } |
| 109 | }; | 111 | }; |
| 110 | 112 | ||
| 113 | class File : public Object { | ||
| 114 | public: | ||
| 115 | std::string GetTypeName() const { return "File"; } | ||
| 116 | std::string GetName() const { return path; } | ||
| 117 | |||
| 118 | static Kernel::HandleType GetStaticHandleType() { return HandleType::File; } | ||
| 119 | Kernel::HandleType GetHandleType() const { return HandleType::File; } | ||
| 120 | |||
| 121 | std::string path; ///< Path of the file | ||
| 122 | std::unique_ptr<FileSys::File> backend; ///< File backend interface | ||
| 123 | |||
| 124 | /** | ||
| 125 | * Synchronize kernel object | ||
| 126 | * @param wait Boolean wait set if current thread should wait as a result of sync operation | ||
| 127 | * @return Result of operation, 0 on success, otherwise error code | ||
| 128 | */ | ||
| 129 | Result SyncRequest(bool* wait) { | ||
| 130 | u32* cmd_buff = Service::GetCommandBuffer(); | ||
| 131 | FileCommand cmd = static_cast<FileCommand>(cmd_buff[0]); | ||
| 132 | switch (cmd) { | ||
| 133 | |||
| 134 | // Read from file... | ||
| 135 | case FileCommand::Read: | ||
| 136 | { | ||
| 137 | u64 offset = cmd_buff[1] | ((u64) cmd_buff[2]) << 32; | ||
| 138 | u32 length = cmd_buff[3]; | ||
| 139 | u32 address = cmd_buff[5]; | ||
| 140 | DEBUG_LOG(KERNEL, "Read %s %s: offset=0x%x length=%d address=0x%x", | ||
| 141 | GetTypeName().c_str(), GetName().c_str(), offset, length, address); | ||
| 142 | cmd_buff[2] = backend->Read(offset, length, Memory::GetPointer(address)); | ||
| 143 | break; | ||
| 144 | } | ||
| 145 | |||
| 146 | // Write to file... | ||
| 147 | case FileCommand::Write: | ||
| 148 | { | ||
| 149 | u64 offset = cmd_buff[1] | ((u64) cmd_buff[2]) << 32; | ||
| 150 | u32 length = cmd_buff[3]; | ||
| 151 | u32 flush = cmd_buff[4]; | ||
| 152 | u32 address = cmd_buff[6]; | ||
| 153 | DEBUG_LOG(KERNEL, "Write %s %s: offset=0x%x length=%d address=0x%x, flush=0x%x", | ||
| 154 | GetTypeName().c_str(), GetName().c_str(), offset, length, address, flush); | ||
| 155 | cmd_buff[2] = backend->Write(offset, length, flush, Memory::GetPointer(address)); | ||
| 156 | break; | ||
| 157 | } | ||
| 158 | |||
| 159 | case FileCommand::GetSize: | ||
| 160 | { | ||
| 161 | DEBUG_LOG(KERNEL, "GetSize %s %s", GetTypeName().c_str(), GetName().c_str()); | ||
| 162 | u64 size = backend->GetSize(); | ||
| 163 | cmd_buff[2] = (u32)size; | ||
| 164 | cmd_buff[3] = size >> 32; | ||
| 165 | break; | ||
| 166 | } | ||
| 167 | |||
| 168 | // Unknown command... | ||
| 169 | default: | ||
| 170 | ERROR_LOG(KERNEL, "Unknown command=0x%08X!", cmd); | ||
| 171 | cmd_buff[1] = -1; // TODO(Link Mauve): use the correct error code for that. | ||
| 172 | return -1; | ||
| 173 | } | ||
| 174 | cmd_buff[1] = 0; // No error | ||
| 175 | return 0; | ||
| 176 | } | ||
| 177 | |||
| 178 | /** | ||
| 179 | * Wait for kernel object to synchronize | ||
| 180 | * @param wait Boolean wait set if current thread should wait as a result of sync operation | ||
| 181 | * @return Result of operation, 0 on success, otherwise error code | ||
| 182 | */ | ||
| 183 | Result WaitSynchronization(bool* wait) { | ||
| 184 | // TODO(bunnei): ImplementMe | ||
| 185 | ERROR_LOG(OSHLE, "(UNIMPLEMENTED)"); | ||
| 186 | return 0; | ||
| 187 | } | ||
| 188 | }; | ||
| 189 | |||
| 111 | //////////////////////////////////////////////////////////////////////////////////////////////////// | 190 | //////////////////////////////////////////////////////////////////////////////////////////////////// |
| 112 | 191 | ||
| 113 | std::map<FileSys::Archive::IdCode, Handle> g_archive_map; ///< Map of file archives by IdCode | 192 | std::map<FileSys::Archive::IdCode, Handle> g_archive_map; ///< Map of file archives by IdCode |
| @@ -171,9 +250,39 @@ Handle CreateArchive(FileSys::Archive* backend, const std::string& name) { | |||
| 171 | return handle; | 250 | return handle; |
| 172 | } | 251 | } |
| 173 | 252 | ||
| 253 | /** | ||
| 254 | * Open a File from an Archive | ||
| 255 | * @param archive_handle Handle to an open Archive object | ||
| 256 | * @param path Path to the File inside of the Archive | ||
| 257 | * @param mode Mode under which to open the File | ||
| 258 | * @return Opened File object | ||
| 259 | */ | ||
| 260 | Handle OpenFileFromArchive(Handle archive_handle, const std::string& path, const FileSys::Mode mode) { | ||
| 261 | File* file = new File; | ||
| 262 | Handle handle = Kernel::g_object_pool.Create(file); | ||
| 263 | |||
| 264 | Archive* archive = Kernel::g_object_pool.GetFast<Archive>(archive_handle); | ||
| 265 | file->path = path; | ||
| 266 | file->backend = archive->backend->OpenFile(path, mode); | ||
| 267 | |||
| 268 | return handle; | ||
| 269 | } | ||
| 270 | |||
| 174 | /// Initialize archives | 271 | /// Initialize archives |
| 175 | void ArchiveInit() { | 272 | void ArchiveInit() { |
| 176 | g_archive_map.clear(); | 273 | g_archive_map.clear(); |
| 274 | |||
| 275 | // TODO(Link Mauve): Add the other archive types (see here for the known types: | ||
| 276 | // http://3dbrew.org/wiki/FS:OpenArchive#Archive_idcodes). Currently the only half-finished | ||
| 277 | // archive type is SDMC, so it is the only one getting exposed. | ||
| 278 | |||
| 279 | // TODO(Link Mauve): don't assume the path separator is '/'. | ||
| 280 | std::string sdmc_directory = FileUtil::GetCurrentDir() + "/userdata/sdmc"; | ||
| 281 | auto archive = new FileSys::Archive_SDMC(sdmc_directory); | ||
| 282 | if (archive->Initialize()) | ||
| 283 | CreateArchive(archive, "SDMC"); | ||
| 284 | else | ||
| 285 | ERROR_LOG(KERNEL, "Can't instantiate SDMC archive with path %s", sdmc_directory.c_str()); | ||
| 177 | } | 286 | } |
| 178 | 287 | ||
| 179 | /// Shutdown archives | 288 | /// Shutdown archives |