From 783e7af5b283f307b036665122d3de335c5e5b60 Mon Sep 17 00:00:00 2001 From: Subv Date: Wed, 15 Apr 2020 16:38:37 -0500 Subject: [PATCH] Services/FS: Stubbed GetSdmcArchiveResource and GetNandArchiveResource. Also rewritten how GetArchiveResource works so that they all use the same interface. We should decide what to do with these at some point. Related to #3131 and #3110 --- src/core/hle/service/fs/archive.cpp | 10 ++++++ src/core/hle/service/fs/archive.h | 15 ++++++++ src/core/hle/service/fs/fs_user.cpp | 55 ++++++++++++++++++++++++----- src/core/hle/service/fs/fs_user.h | 26 ++++++++++++++ 4 files changed, 98 insertions(+), 8 deletions(-) diff --git a/src/core/hle/service/fs/archive.cpp b/src/core/hle/service/fs/archive.cpp index 6e179978b..971ae5c0e 100644 --- a/src/core/hle/service/fs/archive.cpp +++ b/src/core/hle/service/fs/archive.cpp @@ -288,6 +288,16 @@ ResultCode ArchiveManager::CreateSystemSaveData(u32 high, u32 low) { return RESULT_SUCCESS; } +ResultVal ArchiveManager::GetArchiveResource(MediaType media_type) const { + // TODO(Subv): Implement querying the actual size information for these storages. + ArchiveResource resource{}; + resource.sector_size_in_bytes = 512; + resource.cluster_size_in_bytes = 16384; + resource.partition_capacity_in_clusters = 0x80000; // 8GiB capacity + resource.free_space_in_clusters = 0x80000; // 8GiB free + return MakeResult(resource); +} + void ArchiveManager::RegisterArchiveTypes() { // TODO(Subv): Add the other archive types (see here for the known types: // http://3dbrew.org/wiki/FS:OpenArchive#Archive_idcodes). diff --git a/src/core/hle/service/fs/archive.h b/src/core/hle/service/fs/archive.h index 862e74980..3c6d20b71 100644 --- a/src/core/hle/service/fs/archive.h +++ b/src/core/hle/service/fs/archive.h @@ -49,6 +49,14 @@ enum class MediaType : u32 { NAND = 0, SDMC = 1, GameCard = 2 }; typedef u64 ArchiveHandle; +struct ArchiveResource { + u32 sector_size_in_bytes; + u32 cluster_size_in_bytes; + u32 partition_capacity_in_clusters; + u32 free_space_in_clusters; +}; +static_assert(sizeof(ArchiveResource) == 0x10, "ArchiveResource has incorrect size"); + using FileSys::ArchiveBackend; using FileSys::ArchiveFactory; @@ -230,6 +238,13 @@ public: */ ResultCode CreateSystemSaveData(u32 high, u32 low); + /** + * Returns capacity and free space information about the given media type. + * @param media_type The media type to obtain the information about. + * @return The capacity information of the media type, or an error code if failed. + */ + ResultVal GetArchiveResource(MediaType media_type) const; + /// Registers a new NCCH file with the SelfNCCH archive factory void RegisterSelfNCCH(Loader::AppLoader& app_loader); diff --git a/src/core/hle/service/fs/fs_user.cpp b/src/core/hle/service/fs/fs_user.cpp index bca8e77e5..0d3e37e0c 100644 --- a/src/core/hle/service/fs/fs_user.cpp +++ b/src/core/hle/service/fs/fs_user.cpp @@ -449,6 +449,41 @@ void FS_USER::GetFreeBytes(Kernel::HLERequestContext& ctx) { } } +void FS_USER::GetSdmcArchiveResource(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp(ctx, 0x814, 0, 0); + + LOG_WARNING(Service_FS, "(STUBBED) called"); + + auto resource = archives.GetArchiveResource(MediaType::SDMC); + + if (resource.Failed()) { + IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); + rb.Push(resource.Code()); + return; + } + + IPC::RequestBuilder rb = rp.MakeBuilder(5, 0); + rb.Push(RESULT_SUCCESS); + rb.PushRaw(*resource); +} + +void FS_USER::GetNandArchiveResource(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp(ctx, 0x815, 0, 0); + + LOG_WARNING(Service_FS, "(STUBBED) called"); + + auto resource = archives.GetArchiveResource(MediaType::NAND); + if (resource.Failed()) { + IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); + rb.Push(resource.Code()); + return; + } + + IPC::RequestBuilder rb = rp.MakeBuilder(5, 0); + rb.Push(RESULT_SUCCESS); + rb.PushRaw(*resource); +} + void FS_USER::CreateExtSaveData(Kernel::HLERequestContext& ctx) { // TODO(Subv): Figure out the other parameters. IPC::RequestParser rp(ctx, 0x0851, 9, 2); @@ -601,16 +636,20 @@ void FS_USER::GetPriority(Kernel::HLERequestContext& ctx) { void FS_USER::GetArchiveResource(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp(ctx, 0x849, 1, 0); - u32 system_media_type = rp.Pop(); + auto media_type = rp.PopEnum(); - LOG_WARNING(Service_FS, "(STUBBED) called Media type=0x{:08X}", system_media_type); + LOG_WARNING(Service_FS, "(STUBBED) called Media type=0x{:08X}", static_cast(media_type)); + + auto resource = archives.GetArchiveResource(media_type); + if (resource.Failed()) { + IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); + rb.Push(resource.Code()); + return; + } IPC::RequestBuilder rb = rp.MakeBuilder(5, 0); rb.Push(RESULT_SUCCESS); - rb.Push(512); - rb.Push(16384); - rb.Push(0x80000); // 8GiB capacity - rb.Push(0x80000); // 8GiB free + rb.PushRaw(*resource); } void FS_USER::GetFormatInfo(Kernel::HLERequestContext& ctx) { @@ -798,8 +837,8 @@ FS_USER::FS_USER(Core::System& system) {0x08110040, nullptr, "DeleteSystemSaveData"}, {0x08120080, &FS_USER::GetFreeBytes, "GetFreeBytes"}, {0x08130000, nullptr, "GetCardType"}, - {0x08140000, nullptr, "GetSdmcArchiveResource"}, - {0x08150000, nullptr, "GetNandArchiveResource"}, + {0x08140000, &FS_USER::GetSdmcArchiveResource, "GetSdmcArchiveResource"}, + {0x08150000, &FS_USER::GetNandArchiveResource, "GetNandArchiveResource"}, {0x08160000, nullptr, "GetSdmcFatfsError"}, {0x08170000, &FS_USER::IsSdmcDetected, "IsSdmcDetected"}, {0x08180000, &FS_USER::IsSdmcWriteable, "IsSdmcWritable"}, diff --git a/src/core/hle/service/fs/fs_user.h b/src/core/hle/service/fs/fs_user.h index 97b45714b..36a1866fb 100644 --- a/src/core/hle/service/fs/fs_user.h +++ b/src/core/hle/service/fs/fs_user.h @@ -291,6 +291,32 @@ private: */ void GetFreeBytes(Kernel::HLERequestContext& ctx); + /** + * FS_User::GetSdmcArchiveResource service function. + * Inputs: + * 0 : 0x08140000 + * Outputs: + * 1 : Result of function, 0 on success, otherwise error code + * 2 : Sector byte-size + * 3 : Cluster byte-size + * 4 : Partition capacity in clusters + * 5 : Available free space in clusters + */ + void GetSdmcArchiveResource(Kernel::HLERequestContext& ctx); + + /** + * FS_User::GetNandArchiveResource service function. + * Inputs: + * 0 : 0x08150000 + * Outputs: + * 1 : Result of function, 0 on success, otherwise error code + * 2 : Sector byte-size + * 3 : Cluster byte-size + * 4 : Partition capacity in clusters + * 5 : Available free space in clusters + */ + void GetNandArchiveResource(Kernel::HLERequestContext& ctx); + /** * FS_User::CreateExtSaveData service function * Inputs: