mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-30 21:30:04 +00:00 
			
		
		
		
	Kernel: Add a Directory object and a getter for it from an Archive object.
This commit is contained in:
		
							parent
							
								
									c14e5713f5
								
							
						
					
					
						commit
						c197ce2180
					
				
					 3 changed files with 91 additions and 0 deletions
				
			
		|  | @ -8,6 +8,7 @@ | |||
| 
 | ||||
| #include "core/file_sys/archive.h" | ||||
| #include "core/file_sys/archive_sdmc.h" | ||||
| #include "core/file_sys/directory.h" | ||||
| #include "core/hle/service/service.h" | ||||
| #include "core/hle/kernel/archive.h" | ||||
| 
 | ||||
|  | @ -31,6 +32,14 @@ enum class FileCommand : u32 { | |||
|     Flush           = 0x08090000, | ||||
| }; | ||||
| 
 | ||||
| // Command to access directory
 | ||||
| enum class DirectoryCommand : u32 { | ||||
|     Dummy1          = 0x000100C6, | ||||
|     Control         = 0x040100C4, | ||||
|     Read            = 0x08010042, | ||||
|     Close           = 0x08020000, | ||||
| }; | ||||
| 
 | ||||
| class Archive : public Object { | ||||
| public: | ||||
|     std::string GetTypeName() const { return "Archive"; } | ||||
|  | @ -187,6 +196,62 @@ public: | |||
|     } | ||||
| }; | ||||
| 
 | ||||
| class Directory : public Object { | ||||
| public: | ||||
|     std::string GetTypeName() const { return "Directory"; } | ||||
|     std::string GetName() const { return path; } | ||||
| 
 | ||||
|     static Kernel::HandleType GetStaticHandleType() { return HandleType::Directory; } | ||||
|     Kernel::HandleType GetHandleType() const { return HandleType::Directory; } | ||||
| 
 | ||||
|     std::string path; ///< Path of the directory
 | ||||
|     std::unique_ptr<FileSys::Directory> backend; ///< File backend interface
 | ||||
| 
 | ||||
|     /**
 | ||||
|      * Synchronize kernel object | ||||
|      * @param wait Boolean wait set if current thread should wait as a result of sync operation | ||||
|      * @return Result of operation, 0 on success, otherwise error code | ||||
|      */ | ||||
|     Result SyncRequest(bool* wait) { | ||||
|         u32* cmd_buff = Service::GetCommandBuffer(); | ||||
|         DirectoryCommand cmd = static_cast<DirectoryCommand>(cmd_buff[0]); | ||||
|         switch (cmd) { | ||||
| 
 | ||||
|         // Read from directory...
 | ||||
|         case DirectoryCommand::Read: | ||||
|         { | ||||
|             u32 count = cmd_buff[1]; | ||||
|             u32 address = cmd_buff[3]; | ||||
|             FileSys::Entry* entries = reinterpret_cast<FileSys::Entry*>(Memory::GetPointer(address)); | ||||
|             DEBUG_LOG(KERNEL, "Read %s %s: count=%d", GetTypeName().c_str(), GetName().c_str(), count); | ||||
| 
 | ||||
|             // Number of entries actually read
 | ||||
|             cmd_buff[2] = backend->Read(count, entries); | ||||
|             break; | ||||
|         } | ||||
| 
 | ||||
|         // Unknown command...
 | ||||
|         default: | ||||
|             ERROR_LOG(KERNEL, "Unknown command=0x%08X!", cmd); | ||||
|             cmd_buff[1] = -1; // TODO(Link Mauve): use the correct error code for that.
 | ||||
|             return -1; | ||||
|         } | ||||
|         cmd_buff[1] = 0; // No error
 | ||||
|         return 0; | ||||
|     } | ||||
| 
 | ||||
|     /**
 | ||||
|      * Wait for kernel object to synchronize | ||||
|      * @param wait Boolean wait set if current thread should wait as a result of sync operation | ||||
|      * @return Result of operation, 0 on success, otherwise error code | ||||
|      */ | ||||
|     Result WaitSynchronization(bool* wait) { | ||||
|         // TODO(bunnei): ImplementMe
 | ||||
|         ERROR_LOG(OSHLE, "(UNIMPLEMENTED)"); | ||||
|         return 0; | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| ////////////////////////////////////////////////////////////////////////////////////////////////////
 | ||||
| 
 | ||||
| std::map<FileSys::Archive::IdCode, Handle> g_archive_map; ///< Map of file archives by IdCode
 | ||||
|  | @ -268,6 +333,23 @@ Handle OpenFileFromArchive(Handle archive_handle, const std::string& path, const | |||
|     return handle; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * Open a Directory from an Archive | ||||
|  * @param archive_handle Handle to an open Archive object | ||||
|  * @param path Path to the Directory inside of the Archive | ||||
|  * @return Opened Directory object | ||||
|  */ | ||||
| Handle OpenDirectoryFromArchive(Handle archive_handle, const std::string& path) { | ||||
|     Directory* directory = new Directory; | ||||
|     Handle handle = Kernel::g_object_pool.Create(directory); | ||||
| 
 | ||||
|     Archive* archive = Kernel::g_object_pool.GetFast<Archive>(archive_handle); | ||||
|     directory->path = path; | ||||
|     directory->backend = archive->backend->OpenDirectory(path); | ||||
| 
 | ||||
|     return handle; | ||||
| } | ||||
| 
 | ||||
| /// Initialize archives
 | ||||
| void ArchiveInit() { | ||||
|     g_archive_map.clear(); | ||||
|  |  | |||
|  | @ -38,6 +38,14 @@ Handle CreateArchive(FileSys::Archive* backend, const std::string& name); | |||
|  */ | ||||
| Handle OpenFileFromArchive(Handle handle, const std::string& name, const FileSys::Mode mode); | ||||
| 
 | ||||
| /**
 | ||||
|  * Open a Directory from an Archive | ||||
|  * @param archive_handle Handle to an open Archive object | ||||
|  * @param path Path to the Directory inside of the Archive | ||||
|  * @return Opened Directory object | ||||
|  */ | ||||
| Handle OpenDirectoryFromArchive(Handle handle, const std::string& name); | ||||
| 
 | ||||
| /// Initialize archives
 | ||||
| void ArchiveInit(); | ||||
| 
 | ||||
|  |  | |||
|  | @ -32,6 +32,7 @@ enum class HandleType : u32 { | |||
|     File            = 10, | ||||
|     Semaphore       = 11, | ||||
|     Archive         = 12, | ||||
|     Directory       = 13, | ||||
| }; | ||||
|      | ||||
| enum { | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue