mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 13:50:03 +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.h" | ||||||
| #include "core/file_sys/archive_sdmc.h" | #include "core/file_sys/archive_sdmc.h" | ||||||
|  | #include "core/file_sys/directory.h" | ||||||
| #include "core/hle/service/service.h" | #include "core/hle/service/service.h" | ||||||
| #include "core/hle/kernel/archive.h" | #include "core/hle/kernel/archive.h" | ||||||
| 
 | 
 | ||||||
|  | @ -31,6 +32,14 @@ enum class FileCommand : u32 { | ||||||
|     Flush           = 0x08090000, |     Flush           = 0x08090000, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | // Command to access directory
 | ||||||
|  | enum class DirectoryCommand : u32 { | ||||||
|  |     Dummy1          = 0x000100C6, | ||||||
|  |     Control         = 0x040100C4, | ||||||
|  |     Read            = 0x08010042, | ||||||
|  |     Close           = 0x08020000, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
| class Archive : public Object { | class Archive : public Object { | ||||||
| public: | public: | ||||||
|     std::string GetTypeName() const { return "Archive"; } |     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
 | 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; |     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
 | /// Initialize archives
 | ||||||
| void ArchiveInit() { | void ArchiveInit() { | ||||||
|     g_archive_map.clear(); |     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); | 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
 | /// Initialize archives
 | ||||||
| void ArchiveInit(); | void ArchiveInit(); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -32,6 +32,7 @@ enum class HandleType : u32 { | ||||||
|     File            = 10, |     File            = 10, | ||||||
|     Semaphore       = 11, |     Semaphore       = 11, | ||||||
|     Archive         = 12, |     Archive         = 12, | ||||||
|  |     Directory       = 13, | ||||||
| }; | }; | ||||||
|      |      | ||||||
| enum { | enum { | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue