mirror of
https://git.suyu.dev/suyu/suyu.git
synced 2024-11-30 10:42:47 +01:00
filesystem: Add support for loading of system archives
This commit is contained in:
parent
367feaefa0
commit
27da7bc9da
7 changed files with 99 additions and 20 deletions
|
@ -77,12 +77,13 @@ static ContentRecordType GetCRTypeFromNCAType(NCAContentType type) {
|
||||||
case NCAContentType::Control:
|
case NCAContentType::Control:
|
||||||
return ContentRecordType::Control;
|
return ContentRecordType::Control;
|
||||||
case NCAContentType::Data:
|
case NCAContentType::Data:
|
||||||
|
case static_cast<NCAContentType>(0x05): ///< Seems to be used on some system archives
|
||||||
return ContentRecordType::Data;
|
return ContentRecordType::Data;
|
||||||
case NCAContentType::Manual:
|
case NCAContentType::Manual:
|
||||||
// TODO(DarkLordZach): Peek at NCA contents to differentiate Manual and Legal.
|
// TODO(DarkLordZach): Peek at NCA contents to differentiate Manual and Legal.
|
||||||
return ContentRecordType::Manual;
|
return ContentRecordType::Manual;
|
||||||
default:
|
default:
|
||||||
UNREACHABLE();
|
UNREACHABLE_MSG("Invalid NCAContentType={:02X}", static_cast<u8>(type));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,9 @@
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
|
#include "core/core.h"
|
||||||
#include "core/file_sys/romfs_factory.h"
|
#include "core/file_sys/romfs_factory.h"
|
||||||
|
#include "core/hle/kernel/process.h"
|
||||||
|
|
||||||
namespace FileSys {
|
namespace FileSys {
|
||||||
|
|
||||||
|
@ -17,9 +19,41 @@ RomFSFactory::RomFSFactory(Loader::AppLoader& app_loader) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultVal<VirtualFile> RomFSFactory::Open(u64 title_id) {
|
ResultVal<VirtualFile> RomFSFactory::OpenCurrentProcess() {
|
||||||
// TODO(DarkLordZach): Use title id.
|
|
||||||
return MakeResult<VirtualFile>(file);
|
return MakeResult<VirtualFile>(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ResultVal<VirtualFile> RomFSFactory::Open(u64 title_id, StorageId storage, ContentRecordType type) {
|
||||||
|
switch (storage) {
|
||||||
|
case StorageId::NandSystem: {
|
||||||
|
const auto res = Service::FileSystem::GetSystemNANDContents()->GetEntry(title_id, type);
|
||||||
|
if (res == nullptr) {
|
||||||
|
// TODO(DarkLordZach): Find the right error code to use here
|
||||||
|
return ResultCode(-1);
|
||||||
|
}
|
||||||
|
const auto romfs = res->GetRomFS();
|
||||||
|
if (romfs == nullptr) {
|
||||||
|
// TODO(DarkLordZach): Find the right error code to use here
|
||||||
|
return ResultCode(-1);
|
||||||
|
}
|
||||||
|
return MakeResult<VirtualFile>(romfs);
|
||||||
|
}
|
||||||
|
case StorageId::NandUser: {
|
||||||
|
const auto res = Service::FileSystem::GetUserNANDContents()->GetEntry(title_id, type);
|
||||||
|
if (res == nullptr) {
|
||||||
|
// TODO(DarkLordZach): Find the right error code to use here
|
||||||
|
return ResultCode(-1);
|
||||||
|
}
|
||||||
|
const auto romfs = res->GetRomFS();
|
||||||
|
if (romfs == nullptr) {
|
||||||
|
// TODO(DarkLordZach): Find the right error code to use here
|
||||||
|
return ResultCode(-1);
|
||||||
|
}
|
||||||
|
return MakeResult<VirtualFile>(romfs);
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
UNIMPLEMENTED_MSG("Unimplmented storage_id={:02X}", static_cast<u8>(storage));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace FileSys
|
} // namespace FileSys
|
||||||
|
|
|
@ -11,12 +11,22 @@
|
||||||
|
|
||||||
namespace FileSys {
|
namespace FileSys {
|
||||||
|
|
||||||
|
enum class StorageId : u8 {
|
||||||
|
None = 0,
|
||||||
|
Host = 1,
|
||||||
|
GameCard = 2,
|
||||||
|
NandSystem = 3,
|
||||||
|
NandUser = 4,
|
||||||
|
SdCard = 5,
|
||||||
|
};
|
||||||
|
|
||||||
/// File system interface to the RomFS archive
|
/// File system interface to the RomFS archive
|
||||||
class RomFSFactory {
|
class RomFSFactory {
|
||||||
public:
|
public:
|
||||||
explicit RomFSFactory(Loader::AppLoader& app_loader);
|
explicit RomFSFactory(Loader::AppLoader& app_loader);
|
||||||
|
|
||||||
ResultVal<VirtualFile> Open(u64 title_id);
|
ResultVal<VirtualFile> OpenCurrentProcess();
|
||||||
|
ResultVal<VirtualFile> Open(u64 title_id, StorageId storage, ContentRecordType type);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
VirtualFile file;
|
VirtualFile file;
|
||||||
|
|
|
@ -256,15 +256,28 @@ ResultCode RegisterBIS(std::unique_ptr<FileSys::BISFactory>&& factory) {
|
||||||
return RESULT_SUCCESS;
|
return RESULT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultVal<FileSys::VirtualFile> OpenRomFS(u64 title_id) {
|
ResultVal<FileSys::VirtualFile> OpenRomFSCurrentProcess() {
|
||||||
LOG_TRACE(Service_FS, "Opening RomFS for title_id={:016X}", title_id);
|
LOG_TRACE(Service_FS, "Opening RomFS for current process");
|
||||||
|
|
||||||
if (romfs_factory == nullptr) {
|
if (romfs_factory == nullptr) {
|
||||||
// TODO(bunnei): Find a better error code for this
|
// TODO(bunnei): Find a better error code for this
|
||||||
return ResultCode(-1);
|
return ResultCode(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return romfs_factory->Open(title_id);
|
return romfs_factory->OpenCurrentProcess();
|
||||||
|
}
|
||||||
|
|
||||||
|
ResultVal<FileSys::VirtualFile> OpenRomFS(u64 title_id, FileSys::StorageId storage_id,
|
||||||
|
FileSys::ContentRecordType type) {
|
||||||
|
LOG_TRACE(Service_FS, "Opening RomFS for title_id={:016X}, storage_id={:02X}, type={:02X}",
|
||||||
|
title_id, static_cast<u8>(storage_id), static_cast<u8>(type));
|
||||||
|
|
||||||
|
if (romfs_factory == nullptr) {
|
||||||
|
// TODO(bunnei): Find a better error code for this
|
||||||
|
return ResultCode(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return romfs_factory->Open(title_id, storage_id, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultVal<FileSys::VirtualDir> OpenSaveData(FileSys::SaveDataSpaceId space,
|
ResultVal<FileSys::VirtualDir> OpenSaveData(FileSys::SaveDataSpaceId space,
|
||||||
|
|
|
@ -27,7 +27,9 @@ ResultCode RegisterSaveData(std::unique_ptr<FileSys::SaveDataFactory>&& factory)
|
||||||
ResultCode RegisterSDMC(std::unique_ptr<FileSys::SDMCFactory>&& factory);
|
ResultCode RegisterSDMC(std::unique_ptr<FileSys::SDMCFactory>&& factory);
|
||||||
ResultCode RegisterBIS(std::unique_ptr<FileSys::BISFactory>&& factory);
|
ResultCode RegisterBIS(std::unique_ptr<FileSys::BISFactory>&& factory);
|
||||||
|
|
||||||
ResultVal<FileSys::VirtualFile> OpenRomFS(u64 title_id);
|
ResultVal<FileSys::VirtualFile> OpenRomFSCurrentProcess();
|
||||||
|
ResultVal<FileSys::VirtualFile> OpenRomFS(u64 title_id, FileSys::StorageId storage_id,
|
||||||
|
FileSys::ContentRecordType type);
|
||||||
ResultVal<FileSys::VirtualDir> OpenSaveData(FileSys::SaveDataSpaceId space,
|
ResultVal<FileSys::VirtualDir> OpenSaveData(FileSys::SaveDataSpaceId space,
|
||||||
FileSys::SaveDataDescriptor save_struct);
|
FileSys::SaveDataDescriptor save_struct);
|
||||||
ResultVal<FileSys::VirtualDir> OpenSDMC();
|
ResultVal<FileSys::VirtualDir> OpenSDMC();
|
||||||
|
|
|
@ -23,15 +23,6 @@
|
||||||
|
|
||||||
namespace Service::FileSystem {
|
namespace Service::FileSystem {
|
||||||
|
|
||||||
enum class StorageId : u8 {
|
|
||||||
None = 0,
|
|
||||||
Host = 1,
|
|
||||||
GameCard = 2,
|
|
||||||
NandSystem = 3,
|
|
||||||
NandUser = 4,
|
|
||||||
SdCard = 5,
|
|
||||||
};
|
|
||||||
|
|
||||||
class IStorage final : public ServiceFramework<IStorage> {
|
class IStorage final : public ServiceFramework<IStorage> {
|
||||||
public:
|
public:
|
||||||
explicit IStorage(FileSys::VirtualFile backend_)
|
explicit IStorage(FileSys::VirtualFile backend_)
|
||||||
|
@ -467,7 +458,7 @@ FSP_SRV::FSP_SRV() : ServiceFramework("fsp-srv") {
|
||||||
{110, nullptr, "OpenContentStorageFileSystem"},
|
{110, nullptr, "OpenContentStorageFileSystem"},
|
||||||
{200, &FSP_SRV::OpenDataStorageByCurrentProcess, "OpenDataStorageByCurrentProcess"},
|
{200, &FSP_SRV::OpenDataStorageByCurrentProcess, "OpenDataStorageByCurrentProcess"},
|
||||||
{201, nullptr, "OpenDataStorageByProgramId"},
|
{201, nullptr, "OpenDataStorageByProgramId"},
|
||||||
{202, nullptr, "OpenDataStorageByDataId"},
|
{202, &FSP_SRV::OpenDataStorageByDataId, "OpenDataStorageByDataId"},
|
||||||
{203, &FSP_SRV::OpenRomStorage, "OpenRomStorage"},
|
{203, &FSP_SRV::OpenRomStorage, "OpenRomStorage"},
|
||||||
{400, nullptr, "OpenDeviceOperator"},
|
{400, nullptr, "OpenDeviceOperator"},
|
||||||
{500, nullptr, "OpenSdCardDetectionEventNotifier"},
|
{500, nullptr, "OpenSdCardDetectionEventNotifier"},
|
||||||
|
@ -580,7 +571,7 @@ void FSP_SRV::GetGlobalAccessLogMode(Kernel::HLERequestContext& ctx) {
|
||||||
void FSP_SRV::OpenDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx) {
|
void FSP_SRV::OpenDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx) {
|
||||||
LOG_DEBUG(Service_FS, "called");
|
LOG_DEBUG(Service_FS, "called");
|
||||||
|
|
||||||
auto romfs = OpenRomFS(Core::System::GetInstance().CurrentProcess()->program_id);
|
auto romfs = OpenRomFSCurrentProcess();
|
||||||
if (romfs.Failed()) {
|
if (romfs.Failed()) {
|
||||||
// TODO (bunnei): Find the right error code to use here
|
// TODO (bunnei): Find the right error code to use here
|
||||||
LOG_CRITICAL(Service_FS, "no file system interface available!");
|
LOG_CRITICAL(Service_FS, "no file system interface available!");
|
||||||
|
@ -596,10 +587,37 @@ void FSP_SRV::OpenDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx) {
|
||||||
rb.PushIpcInterface<IStorage>(std::move(storage));
|
rb.PushIpcInterface<IStorage>(std::move(storage));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FSP_SRV::OpenDataStorageByDataId(Kernel::HLERequestContext& ctx) {
|
||||||
|
IPC::RequestParser rp{ctx};
|
||||||
|
const auto storage_id = rp.PopRaw<FileSys::StorageId>();
|
||||||
|
const auto unknown = rp.PopRaw<u32>();
|
||||||
|
const auto title_id = rp.PopRaw<u64>();
|
||||||
|
|
||||||
|
LOG_DEBUG(Service_FS, "called with storage_id={:02X}, unknown={:08X}, title_id={:016X}",
|
||||||
|
static_cast<u8>(storage_id), unknown, title_id);
|
||||||
|
|
||||||
|
auto data = OpenRomFS(title_id, storage_id, FileSys::ContentRecordType::Data);
|
||||||
|
if (data.Failed()) {
|
||||||
|
// TODO(DarkLordZach): Find the right error code to use here
|
||||||
|
LOG_ERROR(Service_FS,
|
||||||
|
"could not open data storage with title_id={:016X}, storage_id={:02X}", title_id,
|
||||||
|
static_cast<u8>(storage_id));
|
||||||
|
IPC::ResponseBuilder rb{ctx, 2};
|
||||||
|
rb.Push(ResultCode(-1));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
IStorage storage(std::move(data.Unwrap()));
|
||||||
|
|
||||||
|
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||||
|
rb.Push(RESULT_SUCCESS);
|
||||||
|
rb.PushIpcInterface<IStorage>(std::move(storage));
|
||||||
|
}
|
||||||
|
|
||||||
void FSP_SRV::OpenRomStorage(Kernel::HLERequestContext& ctx) {
|
void FSP_SRV::OpenRomStorage(Kernel::HLERequestContext& ctx) {
|
||||||
IPC::RequestParser rp{ctx};
|
IPC::RequestParser rp{ctx};
|
||||||
|
|
||||||
auto storage_id = rp.PopRaw<StorageId>();
|
auto storage_id = rp.PopRaw<FileSys::StorageId>();
|
||||||
auto title_id = rp.PopRaw<u64>();
|
auto title_id = rp.PopRaw<u64>();
|
||||||
|
|
||||||
LOG_DEBUG(Service_FS, "called with storage_id={:02X}, title_id={:016X}",
|
LOG_DEBUG(Service_FS, "called with storage_id={:02X}, title_id={:016X}",
|
||||||
|
|
|
@ -25,6 +25,7 @@ private:
|
||||||
void MountSaveData(Kernel::HLERequestContext& ctx);
|
void MountSaveData(Kernel::HLERequestContext& ctx);
|
||||||
void GetGlobalAccessLogMode(Kernel::HLERequestContext& ctx);
|
void GetGlobalAccessLogMode(Kernel::HLERequestContext& ctx);
|
||||||
void OpenDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx);
|
void OpenDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx);
|
||||||
|
void OpenDataStorageByDataId(Kernel::HLERequestContext& ctx);
|
||||||
void OpenRomStorage(Kernel::HLERequestContext& ctx);
|
void OpenRomStorage(Kernel::HLERequestContext& ctx);
|
||||||
|
|
||||||
FileSys::VirtualFile romfs;
|
FileSys::VirtualFile romfs;
|
||||||
|
|
Loading…
Reference in a new issue