2
1
Fork 0
mirror of https://github.com/yuzu-emu/yuzu.git synced 2024-07-04 23:31:19 +01:00

filesystem: Add support for loading of system archives

This commit is contained in:
Zach Hilman 2018-08-18 21:28:17 -04:00
parent 367feaefa0
commit 27da7bc9da
7 changed files with 99 additions and 20 deletions

View file

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

View file

@ -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

View file

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

View 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,

View file

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

View file

@ -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}",

View file

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