Kernel: Add a Directory object and a getter for it from an Archive object.

This commit is contained in:
Emmanuel Gil Peyrot 2014-09-12 00:48:04 +02:00
parent c14e5713f5
commit c197ce2180
3 changed files with 91 additions and 0 deletions

View file

@ -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();

View file

@ -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();

View file

@ -32,6 +32,7 @@ enum class HandleType : u32 {
File = 10, File = 10,
Semaphore = 11, Semaphore = 11,
Archive = 12, Archive = 12,
Directory = 13,
}; };
enum { enum {