From 60974a5f4ee28680ce0a76b8d6dd7ea27c60e603 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 25 Oct 2023 12:41:18 -0700 Subject: [PATCH] erpt: GetMmcErrorInfo, GetSdCard*Info --- .../include/stratosphere/fat.hpp | 17 ++ .../stratosphere/fat/fat_file_system.hpp | 55 ++++++ .../include/stratosphere/fs.hpp | 1 + .../include/stratosphere/fs/fs_error_info.hpp | 58 ++++++ .../include/stratosphere/fs/fs_sd_card.hpp | 26 +++ .../fssrv/sf/fssrv_sf_i_device_operator.hpp | 21 ++- .../erpt/srv/erpt_srv_fs_info.os.horizon.cpp | 172 +++++++++++++++++- .../libstratosphere/source/fs/fs_mmc.cpp | 20 ++ .../libstratosphere/source/fs/fs_sd_card.cpp | 86 +++++++++ .../fs/impl/fs_remote_device_operator.hpp | 26 +++ 10 files changed, 472 insertions(+), 10 deletions(-) create mode 100644 libraries/libstratosphere/include/stratosphere/fat.hpp create mode 100644 libraries/libstratosphere/include/stratosphere/fat/fat_file_system.hpp create mode 100644 libraries/libstratosphere/include/stratosphere/fs/fs_error_info.hpp diff --git a/libraries/libstratosphere/include/stratosphere/fat.hpp b/libraries/libstratosphere/include/stratosphere/fat.hpp new file mode 100644 index 000000000..995267a2a --- /dev/null +++ b/libraries/libstratosphere/include/stratosphere/fat.hpp @@ -0,0 +1,17 @@ +/* + * Copyright (c) Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once +#include \ No newline at end of file diff --git a/libraries/libstratosphere/include/stratosphere/fat/fat_file_system.hpp b/libraries/libstratosphere/include/stratosphere/fat/fat_file_system.hpp new file mode 100644 index 000000000..2be687b83 --- /dev/null +++ b/libraries/libstratosphere/include/stratosphere/fat/fat_file_system.hpp @@ -0,0 +1,55 @@ +/* + * Copyright (c) Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once +#include + +namespace ams::fat { + + constexpr inline size_t FatErrorNameMaxLength = 0x10; + + struct FatError { + int error; + int extra_error; + int device_id; + char name[FatErrorNameMaxLength]; + u8 reserved[4]; + }; + static_assert(sizeof(FatError) == 0x20); + static_assert(util::is_pod::value); + + struct FatReportInfo1 { + u16 file_peak_open_count; + u16 directory_peak_open_count; + }; + static_assert(sizeof(FatReportInfo1) == 4); + static_assert(util::is_pod::value); + + struct FatReportInfo2 { + u16 unique_file_entry_peak_open_count; + u16 unique_directory_entry_peak_open_count; + }; + static_assert(sizeof(FatReportInfo2) == 4); + static_assert(util::is_pod::value); + + struct FatSafeInfo { + u32 result; + u32 error_number; + u32 safe_error_number; + }; + static_assert(sizeof(FatSafeInfo) == 12); + static_assert(util::is_pod::value); + +} diff --git a/libraries/libstratosphere/include/stratosphere/fs.hpp b/libraries/libstratosphere/include/stratosphere/fs.hpp index 5e3da8c2c..9c3414051 100644 --- a/libraries/libstratosphere/include/stratosphere/fs.hpp +++ b/libraries/libstratosphere/include/stratosphere/fs.hpp @@ -51,6 +51,7 @@ #include #include #include +#include #include #include #include diff --git a/libraries/libstratosphere/include/stratosphere/fs/fs_error_info.hpp b/libraries/libstratosphere/include/stratosphere/fs/fs_error_info.hpp new file mode 100644 index 000000000..71ed0d8d2 --- /dev/null +++ b/libraries/libstratosphere/include/stratosphere/fs/fs_error_info.hpp @@ -0,0 +1,58 @@ +/* + * Copyright (c) Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once +#include +#include + +namespace ams::fs { + + struct StorageErrorInfo { + u32 num_activation_failures; + u32 num_activation_error_corrections; + u32 num_read_write_failures; + u32 num_read_write_error_corrections; + }; + static_assert(sizeof(StorageErrorInfo) == 0x10); + static_assert(util::is_pod::value); + + struct FileSystemProxyErrorInfo { + u32 rom_fs_remont_for_data_corruption_count; + u32 rom_fs_unrecoverable_data_corruption_by_remount_count; + fat::FatError fat_fs_error; + u32 rom_fs_recovered_by_invalidate_cache_count; + u32 save_data_index_count; + fat::FatReportInfo1 bis_system_report1; + fat::FatReportInfo1 bis_user_report1; + fat::FatReportInfo1 sd_card_report1; + fat::FatReportInfo2 bis_system_report2; + fat::FatReportInfo2 bis_user_report2; + fat::FatReportInfo2 sd_card_report2; + u32 rom_fs_deep_retry_start_count; + u32 rom_fs_unrecoverable_by_game_card_access_failed_count; + fat::FatSafeInfo bis_system_fat_safe_info; + fat::FatSafeInfo bis_user_fat_safe_info; + + u8 reserved[0x18]; + }; + static_assert(sizeof(FileSystemProxyErrorInfo) == 0x80); + static_assert(util::is_pod::value); + + Result GetAndClearMmcErrorInfo(StorageErrorInfo *out_sei, size_t *out_log_size, char *out_log_buffer, size_t log_buffer_size); + Result GetAndClearSdCardErrorInfo(StorageErrorInfo *out_sei, size_t *out_log_size, char *out_log_buffer, size_t log_buffer_size); + + Result GetAndClearFileSystemProxyErrorInfo(FileSystemProxyErrorInfo *out); + +} diff --git a/libraries/libstratosphere/include/stratosphere/fs/fs_sd_card.hpp b/libraries/libstratosphere/include/stratosphere/fs/fs_sd_card.hpp index 6ceda83db..b72d90709 100644 --- a/libraries/libstratosphere/include/stratosphere/fs/fs_sd_card.hpp +++ b/libraries/libstratosphere/include/stratosphere/fs/fs_sd_card.hpp @@ -21,12 +21,38 @@ namespace ams::fs { /* ACCURATE_TO_VERSION: Unknown */ class IEventNotifier; + constexpr inline size_t SdCardCidSize = 0x10; + + enum SdCardSpeedMode { + SdCardSpeedMode_Identification = 0, + SdCardSpeedMode_DefaultSpeed = 1, + SdCardSpeedMode_HighSpeed = 2, + SdCardSpeedMode_Sdr12 = 3, + SdCardSpeedMode_Sdr25 = 4, + SdCardSpeedMode_Sdr50 = 5, + SdCardSpeedMode_Sdr104 = 6, + SdCardSpeedMode_Ddr50 = 7, + SdCardSpeedMode_Unknown = 8, + }; + struct EncryptionSeed { char value[0x10]; }; static_assert(util::is_pod::value); static_assert(sizeof(EncryptionSeed) == 0x10); + Result GetSdCardCid(void *dst, size_t size); + + inline void ClearSdCardCidSerialNumber(u8 *cid) { + /* Clear the serial number from the cid. */ + std::memset(cid + 2, 0, 4); + } + + Result GetSdCardUserAreaSize(s64 *out); + Result GetSdCardProtectedAreaSize(s64 *out); + + Result GetSdCardSpeedMode(SdCardSpeedMode *out); + Result MountSdCard(const char *name); Result MountSdCardErrorReportDirectoryForAtmosphere(const char *name); diff --git a/libraries/libstratosphere/include/stratosphere/fssrv/sf/fssrv_sf_i_device_operator.hpp b/libraries/libstratosphere/include/stratosphere/fssrv/sf/fssrv_sf_i_device_operator.hpp index e81b31cfb..4d6fa71ef 100644 --- a/libraries/libstratosphere/include/stratosphere/fssrv/sf/fssrv_sf_i_device_operator.hpp +++ b/libraries/libstratosphere/include/stratosphere/fssrv/sf/fssrv_sf_i_device_operator.hpp @@ -16,16 +16,23 @@ #pragma once #include #include +#include /* TODO */ /* ACCURATE_TO_VERSION: 13.4.0.0 */ #define AMS_FSSRV_I_DEVICE_OPERATOR_INTERFACE_INFO(C, H) \ - AMS_SF_METHOD_INFO(C, H, 0, Result, IsSdCardInserted, (ams::sf::Out out), (out)) \ - AMS_SF_METHOD_INFO(C, H, 100, Result, GetMmcCid, (ams::sf::OutBuffer out, s64 size), (out, size)) \ - AMS_SF_METHOD_INFO(C, H, 101, Result, GetMmcSpeedMode, (ams::sf::Out out), (out)) \ - AMS_SF_METHOD_INFO(C, H, 112, Result, GetMmcPatrolCount, (ams::sf::Out out), (out)) \ - AMS_SF_METHOD_INFO(C, H, 114, Result, GetMmcExtendedCsd, (ams::sf::OutBuffer out, s64 size), (out, size)) \ - AMS_SF_METHOD_INFO(C, H, 200, Result, IsGameCardInserted, (ams::sf::Out out), (out)) \ - AMS_SF_METHOD_INFO(C, H, 202, Result, GetGameCardHandle, (ams::sf::Out out), (out)) + AMS_SF_METHOD_INFO(C, H, 0, Result, IsSdCardInserted, (ams::sf::Out out), (out)) \ + AMS_SF_METHOD_INFO(C, H, 1, Result, GetSdCardSpeedMode, (ams::sf::Out out), (out)) \ + AMS_SF_METHOD_INFO(C, H, 2, Result, GetSdCardCid, (ams::sf::OutBuffer out, s64 size), (out, size)) \ + AMS_SF_METHOD_INFO(C, H, 3, Result, GetSdCardUserAreaSize, (ams::sf::Out out), (out)) \ + AMS_SF_METHOD_INFO(C, H, 4, Result, GetSdCardProtectedAreaSize, (ams::sf::Out out), (out)) \ + AMS_SF_METHOD_INFO(C, H, 5, Result, GetAndClearSdCardErrorInfo, (ams::sf::Out out_sei, ams::sf::Out out_size, ams::sf::OutBuffer out_buf, s64 size), (out_sei, out_size, out_buf, size)) \ + AMS_SF_METHOD_INFO(C, H, 100, Result, GetMmcCid, (ams::sf::OutBuffer out, s64 size), (out, size)) \ + AMS_SF_METHOD_INFO(C, H, 101, Result, GetMmcSpeedMode, (ams::sf::Out out), (out)) \ + AMS_SF_METHOD_INFO(C, H, 112, Result, GetMmcPatrolCount, (ams::sf::Out out), (out)) \ + AMS_SF_METHOD_INFO(C, H, 113, Result, GetAndClearMmcErrorInfo, (ams::sf::Out out_sei, ams::sf::Out out_size, ams::sf::OutBuffer out_buf, s64 size), (out_sei, out_size, out_buf, size)) \ + AMS_SF_METHOD_INFO(C, H, 114, Result, GetMmcExtendedCsd, (ams::sf::OutBuffer out, s64 size), (out, size)) \ + AMS_SF_METHOD_INFO(C, H, 200, Result, IsGameCardInserted, (ams::sf::Out out), (out)) \ + AMS_SF_METHOD_INFO(C, H, 202, Result, GetGameCardHandle, (ams::sf::Out out), (out)) AMS_SF_DEFINE_INTERFACE(ams::fssrv::sf, IDeviceOperator, AMS_FSSRV_I_DEVICE_OPERATOR_INTERFACE_INFO, 0x1484E21C) diff --git a/libraries/libstratosphere/source/erpt/srv/erpt_srv_fs_info.os.horizon.cpp b/libraries/libstratosphere/source/erpt/srv/erpt_srv_fs_info.os.horizon.cpp index 3c8957104..0290b2fd3 100644 --- a/libraries/libstratosphere/source/erpt/srv/erpt_srv_fs_info.os.horizon.cpp +++ b/libraries/libstratosphere/source/erpt/srv/erpt_srv_fs_info.os.horizon.cpp @@ -127,17 +127,183 @@ namespace ams::erpt::srv { } Result SubmitMmcErrorInfo() { - /* TODO */ + /* Get the mmc error info. */ + fs::StorageErrorInfo sei = {}; + char log_buffer[erpt::ArrayBufferSizeDefault] = {}; + size_t log_size = 0; + if (R_SUCCEEDED(fs::GetAndClearMmcErrorInfo(std::addressof(sei), std::addressof(log_size), log_buffer, sizeof(log_buffer)))) { + /* Submit the error info. */ + { + /* Create a record. */ + auto record = std::make_unique(CategoryId_NANDErrorInfo, 0); + R_UNLESS(record != nullptr, erpt::ResultOutOfMemory()); + + /* Add fields. */ + R_ABORT_UNLESS(record->Add(FieldId_NANDNumActivationFailures, sei.num_activation_failures)); + R_ABORT_UNLESS(record->Add(FieldId_NANDNumActivationErrorCorrections, sei.num_activation_error_corrections)); + R_ABORT_UNLESS(record->Add(FieldId_NANDNumReadWriteFailures, sei.num_read_write_failures)); + R_ABORT_UNLESS(record->Add(FieldId_NANDNumReadWriteErrorCorrections, sei.num_read_write_error_corrections)); + + /* Submit the record. */ + R_ABORT_UNLESS(Context::SubmitContextRecord(std::move(record))); + } + + /* If we have a log, submit it. */ + if (log_size > 0) { + /* Create a record. */ + auto record = std::make_unique(CategoryId_NANDDriverLog, log_size); + R_UNLESS(record != nullptr, erpt::ResultOutOfMemory()); + + /* Add fields. */ + R_ABORT_UNLESS(record->Add(FieldId_NANDErrorLog, log_buffer, log_size)); + + /* Submit the record. */ + R_ABORT_UNLESS(Context::SubmitContextRecord(std::move(record))); + } + } + R_SUCCEED(); } Result SubmitSdCardDetailInfo() { - /* TODO */ + /* Submit the sd card cid. */ + { + u8 sd_cid[fs::SdCardCidSize] = {}; + if (R_SUCCEEDED(fs::GetSdCardCid(sd_cid, sizeof(sd_cid)))) { + /* Clear the serial number from the cid. */ + fs::ClearSdCardCidSerialNumber(sd_cid); + + /* Create a record. */ + auto record = std::make_unique(CategoryId_MicroSDTypeInfo, sizeof(sd_cid)); + R_UNLESS(record != nullptr, erpt::ResultOutOfMemory()); + + /* Add the cid. */ + R_ABORT_UNLESS(record->Add(FieldId_MicroSDType, sd_cid, sizeof(sd_cid))); + + /* Submit the record. */ + R_ABORT_UNLESS(Context::SubmitContextRecord(std::move(record))); + } + } + + /* Submit the sd card speed mode. */ + { + /* Create a record. */ + auto record = std::make_unique(CategoryId_MicroSDSpeedModeInfo, 0x20); + R_UNLESS(record != nullptr, erpt::ResultOutOfMemory()); + + /* Get the speed mode. */ + fs::SdCardSpeedMode speed_mode{}; + const auto res = fs::GetSdCardSpeedMode(std::addressof(speed_mode)); + if (R_SUCCEEDED(res)) { + const char *speed_mode_name = "None"; + switch (speed_mode) { + case fs::SdCardSpeedMode_Identification: + speed_mode_name = "Identification"; + break; + case fs::SdCardSpeedMode_DefaultSpeed: + speed_mode_name = "DefaultSpeed"; + break; + case fs::SdCardSpeedMode_HighSpeed: + speed_mode_name = "HighSpeed"; + break; + case fs::SdCardSpeedMode_Sdr12: + speed_mode_name = "Sdr12"; + break; + case fs::SdCardSpeedMode_Sdr25: + speed_mode_name = "Sdr25"; + break; + case fs::SdCardSpeedMode_Sdr50: + speed_mode_name = "Sdr50"; + break; + case fs::SdCardSpeedMode_Sdr104: + speed_mode_name = "Sdr104"; + break; + case fs::SdCardSpeedMode_Ddr50: + speed_mode_name = "Ddr50"; + break; + case fs::SdCardSpeedMode_Unknown: + speed_mode_name = "Unknown"; + break; + default: + speed_mode_name = "UnDefined"; + break; + } + + R_ABORT_UNLESS(record->Add(FieldId_MicroSDSpeedMode, speed_mode_name, std::strlen(speed_mode_name))); + } else { + /* Getting speed mode failed, so add the result. */ + char res_str[0x20]; + util::SNPrintf(res_str, sizeof(res_str), "0x%08X", res.GetValue()); + R_ABORT_UNLESS(record->Add(FieldId_MicroSDSpeedMode, res_str, std::strlen(res_str))); + } + + /* Submit the record. */ + R_ABORT_UNLESS(Context::SubmitContextRecord(std::move(record))); + } + + /* Submit the area sizes. */ + { + s64 user_area_size = 0; + s64 prot_area_size = 0; + const Result res_user = fs::GetSdCardUserAreaSize(std::addressof(user_area_size)); + const Result res_prot = fs::GetSdCardProtectedAreaSize(std::addressof(prot_area_size)); + if (R_SUCCEEDED(res_user) || R_SUCCEEDED(res_prot)) { + /* Create a record. */ + auto record = std::make_unique(CategoryId_SdCardSizeSpec, 0); + R_UNLESS(record != nullptr, erpt::ResultOutOfMemory()); + + /* Add sizes. */ + if (R_SUCCEEDED(res_user)) { + R_ABORT_UNLESS(record->Add(FieldId_SdCardUserAreaSize, user_area_size)); + } + if (R_SUCCEEDED(res_prot)) { + R_ABORT_UNLESS(record->Add(FieldId_SdCardProtectedAreaSize, prot_area_size)); + } + + /* Submit the record. */ + R_ABORT_UNLESS(Context::SubmitContextRecord(std::move(record))); + } + } + R_SUCCEED(); } Result SubmitSdCardErrorInfo() { - /* TODO */ + /* Get the sd card error info. */ + fs::StorageErrorInfo sei = {}; + char log_buffer[erpt::ArrayBufferSizeDefault] = {}; + size_t log_size = 0; + if (R_SUCCEEDED(fs::GetAndClearSdCardErrorInfo(std::addressof(sei), std::addressof(log_size), log_buffer, sizeof(log_buffer)))) { + /* Submit the error info. */ + { + /* Create a record. */ + auto record = std::make_unique(CategoryId_SdCardErrorInfo, 0); + R_UNLESS(record != nullptr, erpt::ResultOutOfMemory()); + + /* Add fields. */ + R_ABORT_UNLESS(record->Add(FieldId_SdCardNumActivationFailures, sei.num_activation_failures)); + R_ABORT_UNLESS(record->Add(FieldId_SdCardNumActivationErrorCorrections, sei.num_activation_error_corrections)); + R_ABORT_UNLESS(record->Add(FieldId_SdCardNumReadWriteFailures, sei.num_read_write_failures)); + R_ABORT_UNLESS(record->Add(FieldId_SdCardNumReadWriteErrorCorrections, sei.num_read_write_error_corrections)); + + /* Submit the record. */ + R_ABORT_UNLESS(Context::SubmitContextRecord(std::move(record))); + } + + /* If we have a log, submit it. */ + if (log_size > 0) { + /* Create a record. */ + auto record = std::make_unique(CategoryId_SdCardDriverLog, log_size); + R_UNLESS(record != nullptr, erpt::ResultOutOfMemory()); + + /* Add fields. */ + R_ABORT_UNLESS(record->Add(FieldId_SdCardErrorLog, log_buffer, log_size)); + + /* Submit the record. */ + R_ABORT_UNLESS(Context::SubmitContextRecord(std::move(record))); + } + } + R_SUCCEED(); } diff --git a/libraries/libstratosphere/source/fs/fs_mmc.cpp b/libraries/libstratosphere/source/fs/fs_mmc.cpp index f0f8d6587..f14364b92 100644 --- a/libraries/libstratosphere/source/fs/fs_mmc.cpp +++ b/libraries/libstratosphere/source/fs/fs_mmc.cpp @@ -70,6 +70,26 @@ namespace ams::fs { R_SUCCEED(); } + Result GetAndClearMmcErrorInfo(StorageErrorInfo *out_sei, size_t *out_log_size, char *out_log_buffer, size_t log_buffer_size) { + /* Check pre-conditions. */ + AMS_FS_R_UNLESS(out_sei != nullptr, fs::ResultNullptrArgument()); + AMS_FS_R_UNLESS(out_log_size != nullptr, fs::ResultNullptrArgument()); + AMS_FS_R_UNLESS(out_log_buffer != nullptr, fs::ResultNullptrArgument()); + + auto fsp = impl::GetFileSystemProxyServiceObject(); + + /* Open a device operator. */ + sf::SharedPointer device_operator; + AMS_FS_R_TRY(fsp->OpenDeviceOperator(std::addressof(device_operator))); + + /* Get the error info. */ + s64 log_size = 0; + AMS_FS_R_TRY(device_operator->GetAndClearMmcErrorInfo(out_sei, std::addressof(log_size), sf::OutBuffer(out_log_buffer, log_buffer_size), static_cast(log_buffer_size))); + + *out_log_size = static_cast(log_size); + R_SUCCEED(); + } + Result GetMmcExtendedCsd(void *dst, size_t size) { /* Check pre-conditions. */ AMS_FS_R_UNLESS(dst != nullptr, fs::ResultNullptrArgument()); diff --git a/libraries/libstratosphere/source/fs/fs_sd_card.cpp b/libraries/libstratosphere/source/fs/fs_sd_card.cpp index a1e5964ef..cf923c3fd 100644 --- a/libraries/libstratosphere/source/fs/fs_sd_card.cpp +++ b/libraries/libstratosphere/source/fs/fs_sd_card.cpp @@ -124,4 +124,90 @@ namespace ams::fs { return inserted; } + Result GetSdCardSpeedMode(SdCardSpeedMode *out) { + /* Check pre-conditions. */ + AMS_FS_R_UNLESS(out != nullptr, fs::ResultNullptrArgument()); + + auto fsp = impl::GetFileSystemProxyServiceObject(); + + /* Open a device operator. */ + sf::SharedPointer device_operator; + AMS_FS_R_TRY(fsp->OpenDeviceOperator(std::addressof(device_operator))); + + /* Get the speed mode. */ + s64 speed_mode = 0; + AMS_FS_R_TRY(device_operator->GetSdCardSpeedMode(std::addressof(speed_mode))); + + *out = static_cast(speed_mode); + R_SUCCEED(); + } + + Result GetSdCardCid(void *dst, size_t size) { + /* Check pre-conditions. */ + AMS_FS_R_UNLESS(dst != nullptr, fs::ResultNullptrArgument()); + + auto fsp = impl::GetFileSystemProxyServiceObject(); + + /* Open a device operator. */ + sf::SharedPointer device_operator; + AMS_FS_R_TRY(fsp->OpenDeviceOperator(std::addressof(device_operator))); + + /* Get the cid. */ + AMS_FS_R_TRY(device_operator->GetSdCardCid(sf::OutBuffer(dst, size), static_cast(size))); + + R_SUCCEED(); + } + + Result GetSdCardUserAreaSize(s64 *out) { + /* Check pre-conditions. */ + AMS_FS_R_UNLESS(out != nullptr, fs::ResultNullptrArgument()); + + auto fsp = impl::GetFileSystemProxyServiceObject(); + + /* Open a device operator. */ + sf::SharedPointer device_operator; + AMS_FS_R_TRY(fsp->OpenDeviceOperator(std::addressof(device_operator))); + + /* Get the size. */ + AMS_FS_R_TRY(device_operator->GetSdCardUserAreaSize(out)); + + R_SUCCEED(); + } + + Result GetSdCardProtectedAreaSize(s64 *out) { + /* Check pre-conditions. */ + AMS_FS_R_UNLESS(out != nullptr, fs::ResultNullptrArgument()); + + auto fsp = impl::GetFileSystemProxyServiceObject(); + + /* Open a device operator. */ + sf::SharedPointer device_operator; + AMS_FS_R_TRY(fsp->OpenDeviceOperator(std::addressof(device_operator))); + + /* Get the size. */ + AMS_FS_R_TRY(device_operator->GetSdCardProtectedAreaSize(out)); + + R_SUCCEED(); + } + + Result GetAndClearSdCardErrorInfo(StorageErrorInfo *out_sei, size_t *out_log_size, char *out_log_buffer, size_t log_buffer_size) { + /* Check pre-conditions. */ + AMS_FS_R_UNLESS(out_sei != nullptr, fs::ResultNullptrArgument()); + AMS_FS_R_UNLESS(out_log_size != nullptr, fs::ResultNullptrArgument()); + AMS_FS_R_UNLESS(out_log_buffer != nullptr, fs::ResultNullptrArgument()); + + auto fsp = impl::GetFileSystemProxyServiceObject(); + + /* Open a device operator. */ + sf::SharedPointer device_operator; + AMS_FS_R_TRY(fsp->OpenDeviceOperator(std::addressof(device_operator))); + + /* Get the error info. */ + s64 log_size = 0; + AMS_FS_R_TRY(device_operator->GetAndClearSdCardErrorInfo(out_sei, std::addressof(log_size), sf::OutBuffer(out_log_buffer, log_buffer_size), static_cast(log_buffer_size))); + + *out_log_size = static_cast(log_size); + R_SUCCEED(); + } + } diff --git a/libraries/libstratosphere/source/fs/impl/fs_remote_device_operator.hpp b/libraries/libstratosphere/source/fs/impl/fs_remote_device_operator.hpp index 6b5c109ab..98860fe1f 100644 --- a/libraries/libstratosphere/source/fs/impl/fs_remote_device_operator.hpp +++ b/libraries/libstratosphere/source/fs/impl/fs_remote_device_operator.hpp @@ -33,6 +33,27 @@ namespace ams::fs::impl { R_RETURN(fsDeviceOperatorIsSdCardInserted(std::addressof(m_operator), out.GetPointer())); } + Result GetSdCardSpeedMode(ams::sf::Out out) { + R_RETURN(fsDeviceOperatorGetSdCardSpeedMode(std::addressof(m_operator), out.GetPointer())); + } + + Result GetSdCardCid(ams::sf::OutBuffer out, s64 size) { + R_RETURN(fsDeviceOperatorGetSdCardCid(std::addressof(m_operator), out.GetPointer(), out.GetSize(), size)); + } + + Result GetSdCardUserAreaSize(ams::sf::Out out) { + R_RETURN(fsDeviceOperatorGetSdCardUserAreaSize(std::addressof(m_operator), out.GetPointer())); + } + + Result GetSdCardProtectedAreaSize(ams::sf::Out out) { + R_RETURN(fsDeviceOperatorGetSdCardProtectedAreaSize(std::addressof(m_operator), out.GetPointer())); + } + + Result GetAndClearSdCardErrorInfo(ams::sf::Out out_sei, ams::sf::Out out_size, ams::sf::OutBuffer out_buf, s64 size) { + static_assert(sizeof(::FsStorageErrorInfo) == sizeof(fs::StorageErrorInfo)); + R_RETURN(fsDeviceOperatorGetAndClearSdCardErrorInfo(std::addressof(m_operator), reinterpret_cast<::FsStorageErrorInfo *>(out_sei.GetPointer()), out_size.GetPointer(), out_buf.GetPointer(), out_buf.GetSize(), size)); + } + Result GetMmcCid(ams::sf::OutBuffer out, s64 size) { R_RETURN(fsDeviceOperatorGetMmcCid(std::addressof(m_operator), out.GetPointer(), out.GetSize(), size)); } @@ -45,6 +66,11 @@ namespace ams::fs::impl { R_RETURN(fsDeviceOperatorGetMmcPatrolCount(std::addressof(m_operator), out.GetPointer())); } + Result GetAndClearMmcErrorInfo(ams::sf::Out out_sei, ams::sf::Out out_size, ams::sf::OutBuffer out_buf, s64 size) { + static_assert(sizeof(::FsStorageErrorInfo) == sizeof(fs::StorageErrorInfo)); + R_RETURN(fsDeviceOperatorGetAndClearMmcErrorInfo(std::addressof(m_operator), reinterpret_cast<::FsStorageErrorInfo *>(out_sei.GetPointer()), out_size.GetPointer(), out_buf.GetPointer(), out_buf.GetSize(), size)); + } + Result GetMmcExtendedCsd(ams::sf::OutBuffer out, s64 size) { R_RETURN(fsDeviceOperatorGetMmcExtendedCsd(std::addressof(m_operator), out.GetPointer(), out.GetSize(), size)); }