From 100bead52bd3964ddea8fce1f559330f63cb3e5b Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Tue, 8 Mar 2022 10:05:32 -0800 Subject: [PATCH] libs: add ongoing work to facilitate hactool rewrite --- libraries/config/templates/stratosphere.mk | 2 +- .../stratosphere/fs/fs_remote_filesystem.hpp | 14 +- .../include/stratosphere/fssrv.hpp | 2 +- .../fssrv_storage_on_nca_creator.hpp | 5 + .../fssrv/impl/fssrv_access_control.hpp | 251 ++++++++++++ .../fssrv/impl/fssrv_access_control_bits.hpp | 252 ++++++++++++ .../include/stratosphere/fssystem.hpp | 1 + .../fssystem_forwarding_file_system.hpp | 175 ++++++++ .../fssystem_i_hash_256_generator.hpp | 2 +- .../fssystem_nca_file_system_driver.hpp | 1 + .../fssystem/fssystem_nca_header.hpp | 22 +- .../include/stratosphere/ldr/ldr_types.hpp | 2 +- libraries/libstratosphere/libstratosphere.mk | 1 + .../source/crypto/crypto_csrng.os.generic.cpp | 59 +++ .../crypto/crypto_csrng.os.windows.cpp} | 12 +- .../source/fs/fs_access_log.cpp | 322 +++++++++++++-- .../fs/impl/fs_id_string_impl.os.generic.cpp | 44 ++ .../source/fs/impl/fs_library.cpp | 8 +- .../fssrv_storage_on_nca_creator.cpp | 32 ++ .../source/fssrv/fssrv_access_control.cpp | 376 ++++++++++++++++++ .../source/fssrv/impl/fssrv_utility.cpp | 106 ++++- .../source/fssrv/impl/fssrv_utility.hpp | 1 + .../fssystem/fssystem_aes_ctr_storage.cpp | 2 +- .../fssystem_nca_file_system_driver.cpp | 2 +- .../source/fssystem/fssystem_nca_reader.cpp | 21 + .../fssystem_partition_file_system.cpp | 2 +- .../fssystem_block_cache_buffered_storage.cpp | 6 +- ...ssystem_integrity_verification_storage.cpp | 14 +- .../source/spl/impl/spl_api_impl.cpp | 4 +- .../smc/spl_secure_monitor_api.os.generic.cpp | 6 +- .../vapours/impl/compiler_impl.clang.hpp | 9 + .../vapours/impl/compiler_impl.gcc.hpp | 9 + .../vapours/svc/svc_definition_macro.hpp | 147 +++++++ .../include/vapours/svc/svc_definitions.hpp | 133 +------ 34 files changed, 1829 insertions(+), 216 deletions(-) create mode 100644 libraries/libstratosphere/include/stratosphere/fssrv/impl/fssrv_access_control.hpp create mode 100644 libraries/libstratosphere/include/stratosphere/fssrv/impl/fssrv_access_control_bits.hpp create mode 100644 libraries/libstratosphere/include/stratosphere/fssystem/fssystem_forwarding_file_system.hpp create mode 100644 libraries/libstratosphere/source/crypto/crypto_csrng.os.generic.cpp rename libraries/libstratosphere/{include/stratosphere/fssrv/fssrv_access_control.hpp => source/crypto/crypto_csrng.os.windows.cpp} (64%) create mode 100644 libraries/libstratosphere/source/fs/impl/fs_id_string_impl.os.generic.cpp create mode 100644 libraries/libvapours/include/vapours/svc/svc_definition_macro.hpp diff --git a/libraries/config/templates/stratosphere.mk b/libraries/config/templates/stratosphere.mk index d51eedc08..a052c9272 100644 --- a/libraries/config/templates/stratosphere.mk +++ b/libraries/config/templates/stratosphere.mk @@ -80,7 +80,7 @@ endif ifeq ($(ATMOSPHERE_BOARD),nx-hac-001) export LIBS := -lstratosphere -lnx else ifeq ($(ATMOSPHERE_BOARD),generic_windows) -export LIBS := -lstratosphere -lwinmm -lws2_32 +export LIBS := -lstratosphere -lwinmm -lws2_32 -lbcrypt else ifeq ($(ATMOSPHERE_BOARD),generic_linux) export LIBS := -lstratosphere -pthread else ifeq ($(ATMOSPHERE_BOARD),generic_macos) diff --git a/libraries/libstratosphere/include/stratosphere/fs/fs_remote_filesystem.hpp b/libraries/libstratosphere/include/stratosphere/fs/fs_remote_filesystem.hpp index 83a4d36d4..dda728e18 100644 --- a/libraries/libstratosphere/include/stratosphere/fs/fs_remote_filesystem.hpp +++ b/libraries/libstratosphere/include/stratosphere/fs/fs_remote_filesystem.hpp @@ -63,7 +63,7 @@ namespace ams::fs { return fsFileOperateRange(std::addressof(m_base_file), static_cast<::FsOperationId>(op_id), offset, size, reinterpret_cast<::FsRangeInfo *>(dst)); } public: - virtual sf::cmif::DomainObjectId GetDomainObjectId() const override { + virtual sf::cmif::DomainObjectId GetDomainObjectId() const override final { return sf::cmif::DomainObjectId{serviceGetObjectId(const_cast<::Service *>(std::addressof(m_base_file.s)))}; } }; @@ -87,7 +87,7 @@ namespace ams::fs { return fsDirGetEntryCount(std::addressof(m_base_dir), out); } public: - virtual sf::cmif::DomainObjectId GetDomainObjectId() const override { + virtual sf::cmif::DomainObjectId GetDomainObjectId() const override final { return sf::cmif::DomainObjectId{serviceGetObjectId(const_cast<::Service *>(std::addressof(m_base_dir.s)))}; } }; @@ -202,32 +202,32 @@ namespace ams::fs { return fsFsCommit(std::addressof(m_base_fs)); } - virtual Result DoGetFreeSpaceSize(s64 *out, const fs::Path &path) { + virtual Result DoGetFreeSpaceSize(s64 *out, const fs::Path &path) override final { fssrv::sf::Path sf_path; R_TRY(GetPathForServiceObject(std::addressof(sf_path), path)); return fsFsGetFreeSpace(std::addressof(m_base_fs), sf_path.str, out); } - virtual Result DoGetTotalSpaceSize(s64 *out, const fs::Path &path) { + virtual Result DoGetTotalSpaceSize(s64 *out, const fs::Path &path) override final { fssrv::sf::Path sf_path; R_TRY(GetPathForServiceObject(std::addressof(sf_path), path)); return fsFsGetTotalSpace(std::addressof(m_base_fs), sf_path.str, out); } - virtual Result DoCleanDirectoryRecursively(const fs::Path &path) { + virtual Result DoCleanDirectoryRecursively(const fs::Path &path) override final { fssrv::sf::Path sf_path; R_TRY(GetPathForServiceObject(std::addressof(sf_path), path)); return fsFsCleanDirectoryRecursively(std::addressof(m_base_fs), sf_path.str); } - virtual Result DoGetFileTimeStampRaw(FileTimeStampRaw *out, const fs::Path &path) { + virtual Result DoGetFileTimeStampRaw(FileTimeStampRaw *out, const fs::Path &path) override final { fssrv::sf::Path sf_path; R_TRY(GetPathForServiceObject(std::addressof(sf_path), path)); static_assert(sizeof(FileTimeStampRaw) == sizeof(::FsTimeStampRaw)); return fsFsGetFileTimeStampRaw(std::addressof(m_base_fs), sf_path.str, reinterpret_cast<::FsTimeStampRaw *>(out)); } - virtual Result DoQueryEntry(char *dst, size_t dst_size, const char *src, size_t src_size, fsa::QueryId query, const fs::Path &path) { + virtual Result DoQueryEntry(char *dst, size_t dst_size, const char *src, size_t src_size, fsa::QueryId query, const fs::Path &path) override final { fssrv::sf::Path sf_path; R_TRY(GetPathForServiceObject(std::addressof(sf_path), path)); return fsFsQueryEntry(std::addressof(m_base_fs), dst, dst_size, src, src_size, sf_path.str, static_cast(query)); diff --git a/libraries/libstratosphere/include/stratosphere/fssrv.hpp b/libraries/libstratosphere/include/stratosphere/fssrv.hpp index 512e5aa48..5c8881371 100644 --- a/libraries/libstratosphere/include/stratosphere/fssrv.hpp +++ b/libraries/libstratosphere/include/stratosphere/fssrv.hpp @@ -19,7 +19,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/libraries/libstratosphere/include/stratosphere/fssrv/fscreator/fssrv_storage_on_nca_creator.hpp b/libraries/libstratosphere/include/stratosphere/fssrv/fscreator/fssrv_storage_on_nca_creator.hpp index 221d8eee1..9b3b46935 100644 --- a/libraries/libstratosphere/include/stratosphere/fssrv/fscreator/fssrv_storage_on_nca_creator.hpp +++ b/libraries/libstratosphere/include/stratosphere/fssrv/fscreator/fssrv_storage_on_nca_creator.hpp @@ -47,6 +47,11 @@ namespace ams::fssrv::fscreator { virtual Result Create(std::shared_ptr *out, std::shared_ptr *out_splitter, fssystem::NcaFsHeaderReader *out_header_reader, std::shared_ptr nca_reader, s32 index) override; virtual Result CreateWithPatch(std::shared_ptr *out, std::shared_ptr *out_splitter, fssystem::NcaFsHeaderReader *out_header_reader, std::shared_ptr original_nca_reader, std::shared_ptr current_nca_reader, s32 index) override; virtual Result CreateNcaReader(std::shared_ptr *out, std::shared_ptr storage) override; + + #if !defined(ATMOSPHERE_BOARD_NINTENDO_NX) + Result CreateWithContext(std::shared_ptr *out, std::shared_ptr *out_splitter, fssystem::NcaFsHeaderReader *out_header_reader, void *ctx, std::shared_ptr nca_reader, s32 index); + Result CreateWithPatchWithContext(std::shared_ptr *out, std::shared_ptr *out_splitter, fssystem::NcaFsHeaderReader *out_header_reader, void *ctx, std::shared_ptr original_nca_reader, std::shared_ptr current_nca_reader, s32 index); + #endif }; } diff --git a/libraries/libstratosphere/include/stratosphere/fssrv/impl/fssrv_access_control.hpp b/libraries/libstratosphere/include/stratosphere/fssrv/impl/fssrv_access_control.hpp new file mode 100644 index 000000000..e7cefaa69 --- /dev/null +++ b/libraries/libstratosphere/include/stratosphere/fssrv/impl/fssrv_access_control.hpp @@ -0,0 +1,251 @@ +/* + * 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 +#include +#include + +namespace ams::fssrv { + + bool IsDebugFlagEnabled(); + void SetDebugFlagEnabled(bool en); + +} + +namespace ams::fssrv::impl { + + struct Accessibility { + u8 value; + + constexpr bool CanRead() const { return value & (1 << 0); } + constexpr bool CanWrite() const { return value & (1 << 1); } + + static constexpr Accessibility MakeAccessibility(bool read, bool write) { + return { static_cast(read * (1 << 0) + write * (1 << 1)) }; + } + }; + static_assert(std::is_trivial::value); + + class ContentOwnerInfo : public util::IntrusiveListBaseNode, public ::ams::fs::impl::Newable { + private: + u64 m_id; + public: + ContentOwnerInfo(u64 id) : m_id(id) { /* ... */ } + + u64 GetId() const { return m_id; } + }; + + class SaveDataOwnerInfo : public util::IntrusiveListBaseNode, public ::ams::fs::impl::Newable { + private: + u64 m_id; + Accessibility m_accessibility; + public: + SaveDataOwnerInfo(u64 id, Accessibility access) : m_id(id), m_accessibility(access) { /* ... */ } + + u64 GetId() const { return m_id; } + Accessibility GetAccessibility() const { return m_accessibility; } + }; + + class AccessControl { + public: + enum class AccessibilityType : u32 { + MountLogo, + MountContentMeta, + MountContentControl, + MountContentManual, + MountContentData, + MountApplicationPackage, + MountSaveDataStorage, + MountContentStorage, + MountImageAndVideoStorage, + MountCloudBackupWorkStorage, + MountCustomStorage, + MountBisCalibrationFile, + MountBisSafeMode, + MountBisUser, + MountBisSystem, + MountBisSystemProperEncryption, + MountBisSystemProperPartition, + MountSdCard, + MountGameCard, + MountDeviceSaveData, + MountSystemSaveData, + MountOthersSaveData, + MountOthersSystemSaveData, + OpenBisPartitionBootPartition1Root, + OpenBisPartitionBootPartition2Root, + OpenBisPartitionUserDataRoot, + OpenBisPartitionBootConfigAndPackage2Part1, + OpenBisPartitionBootConfigAndPackage2Part2, + OpenBisPartitionBootConfigAndPackage2Part3, + OpenBisPartitionBootConfigAndPackage2Part4, + OpenBisPartitionBootConfigAndPackage2Part5, + OpenBisPartitionBootConfigAndPackage2Part6, + OpenBisPartitionCalibrationBinary, + OpenBisPartitionCalibrationFile, + OpenBisPartitionSafeMode, + OpenBisPartitionUser, + OpenBisPartitionSystem, + OpenBisPartitionSystemProperEncryption, + OpenBisPartitionSystemProperPartition, + OpenSdCardStorage, + OpenGameCardStorage, + MountSystemDataPrivate, + MountHost, + MountRegisteredUpdatePartition, + MountSaveDataInternalStorage, + MountTemporaryDirectory, + MountAllBaseFileSystem, + NotMount, + + Count, + }; + + enum class OperationType : u32 { + InvalidateBisCache, + EraseMmc, + GetGameCardDeviceCertificate, + GetGameCardIdSet, + FinalizeGameCardDriver, + GetGameCardAsicInfo, + CreateSaveData, + DeleteSaveData, + CreateSystemSaveData, + CreateOthersSystemSaveData, + DeleteSystemSaveData, + OpenSaveDataInfoReader, + OpenSaveDataInfoReaderForSystem, + OpenSaveDataInfoReaderForInternal, + OpenSaveDataMetaFile, + SetCurrentPosixTime, + ReadSaveDataFileSystemExtraData, + SetGlobalAccessLogMode, + SetSpeedEmulationMode, + Debug, + FillBis, + CorruptSaveData, + CorruptSystemSaveData, + VerifySaveData, + DebugSaveData, + FormatSdCard, + GetRightsId, + RegisterExternalKey, + SetEncryptionSeed, + WriteSaveDataFileSystemExtraDataTimeStamp, + WriteSaveDataFileSystemExtraDataFlags, + WriteSaveDataFileSystemExtraDataCommitId, + WriteSaveDataFileSystemExtraDataAll, + ExtendSaveData, + ExtendSystemSaveData, + ExtendOthersSystemSaveData, + RegisterUpdatePartition, + OpenSaveDataTransferManager, + OpenSaveDataTransferManagerVersion2, + OpenSaveDataTransferManagerForSaveDataRepair, + OpenSaveDataTransferManagerForSaveDataRepairTool, + OpenSaveDataTransferProhibiter, + OpenSaveDataMover, + OpenBisWiper, + ListAccessibleSaveDataOwnerId, + ControlMmcPatrol, + OverrideSaveDataTransferTokenSignVerificationKey, + OpenSdCardDetectionEventNotifier, + OpenGameCardDetectionEventNotifier, + OpenSystemDataUpdateEventNotifier, + NotifySystemDataUpdateEvent, + OpenAccessFailureDetectionEventNotifier, + GetAccessFailureDetectionEvent, + IsAccessFailureDetected, + ResolveAccessFailure, + AbandonAccessFailure, + QuerySaveDataInternalStorageTotalSize, + GetSaveDataCommitId, + SetSdCardAccessibility, + SimulateDevice, + CreateSaveDataWithHashSalt, + RegisterProgramIndexMapInfo, + ChallengeCardExistence, + CreateOwnSaveData, + DeleteOwnSaveData, + ReadOwnSaveDataFileSystemExtraData, + ExtendOwnSaveData, + OpenOwnSaveDataTransferProhibiter, + FindOwnSaveDataWithFilter, + OpenSaveDataTransferManagerForRepair, + SetDebugConfiguration, + OpenDataStorageByPath, + + Count, + }; + + AMS_PRAGMA_BEGIN_PACK(4) + struct AccessControlDataHeader { + u8 version; + u8 reserved[3]; + u64 flag_bits; + u32 content_owner_infos_offset; + u32 content_owner_infos_size; + u32 save_data_owner_infos_offset; + u32 save_data_owner_infos_size; + }; + + struct AccessControlDescriptor { + u8 version; + u8 content_owner_id_count; + u8 save_data_owner_id_count; + u8 reserved; + u64 flag_bits; + u64 content_owner_id_min; + u64 content_owner_id_max; + u64 save_data_owner_id_min; + u64 save_data_owner_id_max; + /* ... */ + }; + AMS_PRAGMA_END_PACK() + + static_assert(util::is_pod::value); + static_assert(util::is_pod::value); + + static constexpr u64 AllFlagBitsMask = ~static_cast(0); + static constexpr u64 DebugFlagDisableMask = AllFlagBitsMask & ~util::ToUnderlying(AccessControlBits::Bits::Debug); + private: + using ContentOwnerInfoList = util::IntrusiveListBaseTraits::ListType; + using SaveDataOwnerInfoList = util::IntrusiveListBaseTraits::ListType; + private: + util::optional m_flag_bits; + ContentOwnerInfoList m_content_owner_infos; + SaveDataOwnerInfoList m_save_data_owner_infos; + public: + AccessControl(const void *data, s64 data_size, const void *desc, s64 desc_size); + AccessControl(const void *data, s64 data_size, const void *desc, s64 desc_size, u64 flag_mask); + ~AccessControl(); + public: + bool HasContentOwnerId(u64 owner_id) const; + Accessibility GetAccessibilitySaveDataOwnedBy(u64 owner_id) const; + + void ListContentOwnerId(s32 *out_count, u64 *out_owner_ids, s32 offset, s32 count) const; + void ListSaveDataOwnedId(s32 *out_count, ncm::ApplicationId *out_owner_ids, s32 offset, s32 count) const; + + Accessibility GetAccessibilityFor(AccessibilityType type) const; + bool CanCall(OperationType type) const; + public: + u64 GetRawFlagBits() const { + return m_flag_bits.value().GetValue(); + } + }; + +} diff --git a/libraries/libstratosphere/include/stratosphere/fssrv/impl/fssrv_access_control_bits.hpp b/libraries/libstratosphere/include/stratosphere/fssrv/impl/fssrv_access_control_bits.hpp new file mode 100644 index 000000000..7a6785882 --- /dev/null +++ b/libraries/libstratosphere/include/stratosphere/fssrv/impl/fssrv_access_control_bits.hpp @@ -0,0 +1,252 @@ +/* + * 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 +#include +#include + +namespace ams::fssrv::impl { + + #define AMS_FSSRV_FOR_EACH_ACCESS_CONTROL_CAPABILITY(HANDLER, _NS_) \ + HANDLER(CanAbandonAccessFailure, _NS_::AccessFailureResolution) \ + HANDLER(CanChallengeCardExistence, _NS_::GameCard) \ + HANDLER(CanControlMmcPatrol, _NS_::None) \ + HANDLER(CanCorruptSaveData, _NS_::Debug, _NS_::CorruptSaveData) \ + HANDLER(CanCorruptSystemSaveData, _NS_::CorruptSaveData, _NS_::SaveDataManagement, _NS_::SaveDataBackUp) \ + HANDLER(CanCreateOthersSystemSaveData, _NS_::SaveDataBackUp) \ + HANDLER(CanCreateOwnSaveData, _NS_::CreateOwnSaveData) \ + HANDLER(CanCreateSaveData, _NS_::CreateSaveData, _NS_::SaveDataBackUp) \ + HANDLER(CanCreateSaveDataWithHashSalt, _NS_::None) \ + HANDLER(CanCreateSystemSaveData, _NS_::SaveDataBackUp, _NS_::SystemSaveData) \ + HANDLER(CanDebugSaveData, _NS_::Debug, _NS_::SaveDataForDebug) \ + HANDLER(CanDeleteOwnSaveData, _NS_::CreateOwnSaveData) \ + HANDLER(CanDeleteSaveData, _NS_::SaveDataManagement, _NS_::SaveDataBackUp) \ + HANDLER(CanDeleteSystemSaveData, _NS_::SystemSaveDataManagement, _NS_::SaveDataBackUp, _NS_::SystemSaveData) \ + HANDLER(CanEraseMmc, _NS_::BisAllRaw) \ + HANDLER(CanExtendOthersSystemSaveData, _NS_::SaveDataBackUp) \ + HANDLER(CanExtendOwnSaveData, _NS_::CreateOwnSaveData) \ + HANDLER(CanExtendSaveData, _NS_::CreateSaveData, _NS_::SaveDataBackUp) \ + HANDLER(CanExtendSystemSaveData, _NS_::SaveDataBackUp, _NS_::SystemSaveData) \ + HANDLER(CanFillBis, _NS_::Debug, _NS_::FillBis) \ + HANDLER(CanFinalizeGameCardDriver, _NS_::GameCardPrivate) \ + HANDLER(CanFindOwnSaveDataWithFilter, _NS_::CreateOwnSaveData) \ + HANDLER(CanFormatSdCard, _NS_::FormatSdCard) \ + HANDLER(CanGetAccessFailureDetectionEvent, _NS_::AccessFailureResolution) \ + HANDLER(CanGetGameCardAsicInfo, _NS_::GameCardPrivate) \ + HANDLER(CanGetGameCardDeviceCertificate, _NS_::GameCard) \ + HANDLER(CanGetGameCardIdSet, _NS_::GameCard) \ + HANDLER(CanGetRightsId, _NS_::GetRightsId) \ + HANDLER(CanGetSaveDataCommitId, _NS_::SaveDataTransferVersion2, _NS_::SaveDataBackUp) \ + HANDLER(CanInvalidateBisCache, _NS_::BisAllRaw) \ + HANDLER(CanIsAccessFailureDetected, _NS_::AccessFailureResolution) \ + HANDLER(CanListAccessibleSaveDataOwnerId, _NS_::SaveDataTransferVersion2, _NS_::SaveDataTransfer, _NS_::CreateSaveData) \ + HANDLER(CanMountAllBaseFileSystemRead, _NS_::None) \ + HANDLER(CanMountAllBaseFileSystemWrite, _NS_::None) \ + HANDLER(CanMountApplicationPackageRead, _NS_::ContentManager, _NS_::ApplicationInfo) \ + HANDLER(CanMountBisCalibrationFileRead, _NS_::BisAllRaw, _NS_::Calibration) \ + HANDLER(CanMountBisCalibrationFileWrite, _NS_::BisAllRaw, _NS_::Calibration) \ + HANDLER(CanMountBisSafeModeRead, _NS_::BisAllRaw) \ + HANDLER(CanMountBisSafeModeWrite, _NS_::BisAllRaw) \ + HANDLER(CanMountBisSystemProperEncryptionRead, _NS_::BisAllRaw) \ + HANDLER(CanMountBisSystemProperEncryptionWrite, _NS_::BisAllRaw) \ + HANDLER(CanMountBisSystemProperPartitionRead, _NS_::BisFileSystem, _NS_::BisAllRaw) \ + HANDLER(CanMountBisSystemProperPartitionWrite, _NS_::BisFileSystem, _NS_::BisAllRaw) \ + HANDLER(CanMountBisSystemRead, _NS_::BisFileSystem, _NS_::BisAllRaw) \ + HANDLER(CanMountBisSystemWrite, _NS_::BisFileSystem, _NS_::BisAllRaw) \ + HANDLER(CanMountBisUserRead, _NS_::BisFileSystem, _NS_::BisAllRaw) \ + HANDLER(CanMountBisUserWrite, _NS_::BisFileSystem, _NS_::BisAllRaw) \ + HANDLER(CanMountCloudBackupWorkStorageRead, _NS_::SaveDataTransferVersion2) \ + HANDLER(CanMountCloudBackupWorkStorageWrite, _NS_::SaveDataTransferVersion2) \ + HANDLER(CanMountContentControlRead, _NS_::ContentManager, _NS_::ApplicationInfo) \ + HANDLER(CanMountContentDataRead, _NS_::ContentManager, _NS_::ApplicationInfo) \ + HANDLER(CanMountContentManualRead, _NS_::ContentManager, _NS_::ApplicationInfo) \ + HANDLER(CanMountContentMetaRead, _NS_::ContentManager, _NS_::ApplicationInfo) \ + HANDLER(CanMountContentStorageRead, _NS_::ContentManager) \ + HANDLER(CanMountContentStorageWrite, _NS_::ContentManager) \ + HANDLER(CanMountCustomStorage0Read, _NS_::None) \ + HANDLER(CanMountCustomStorage0Write, _NS_::None) \ + HANDLER(CanMountDeviceSaveDataRead, _NS_::DeviceSaveData, _NS_::SaveDataBackUp) \ + HANDLER(CanMountDeviceSaveDataWrite, _NS_::DeviceSaveData, _NS_::SaveDataBackUp) \ + HANDLER(CanMountGameCardRead, _NS_::GameCard) \ + HANDLER(CanMountHostRead, _NS_::Debug, _NS_::Host) \ + HANDLER(CanMountHostWrite, _NS_::Debug, _NS_::Host) \ + HANDLER(CanMountImageAndVideoStorageRead, _NS_::ImageManager) \ + HANDLER(CanMountImageAndVideoStorageWrite, _NS_::ImageManager) \ + HANDLER(CanMountLogoRead, _NS_::ContentManager, _NS_::ApplicationInfo) \ + HANDLER(CanMountOthersSaveDataRead, _NS_::SaveDataBackUp) \ + HANDLER(CanMountOthersSaveDataWrite, _NS_::SaveDataBackUp) \ + HANDLER(CanMountOthersSystemSaveDataRead, _NS_::SaveDataBackUp) \ + HANDLER(CanMountOthersSystemSaveDataWrite, _NS_::SaveDataBackUp) \ + HANDLER(CanMountRegisteredUpdatePartitionRead, _NS_::SystemUpdate) \ + HANDLER(CanMountSaveDataStorageRead, _NS_::None) \ + HANDLER(CanMountSaveDataStorageWrite, _NS_::None) \ + HANDLER(CanMountSdCardRead, _NS_::Debug, _NS_::SdCard) \ + HANDLER(CanMountSdCardWrite, _NS_::Debug, _NS_::SdCard) \ + HANDLER(CanMountSystemDataPrivateRead, _NS_::SystemData, _NS_::SystemSaveData) \ + HANDLER(CanMountSystemSaveDataRead, _NS_::SaveDataBackUp, _NS_::SystemSaveData) \ + HANDLER(CanMountSystemSaveDataWrite, _NS_::SaveDataBackUp, _NS_::SystemSaveData) \ + HANDLER(CanMountTemporaryDirectoryRead, _NS_::Debug) \ + HANDLER(CanMountTemporaryDirectoryWrite, _NS_::Debug) \ + HANDLER(CanNotifySystemDataUpdateEvent, _NS_::SystemUpdate) \ + HANDLER(CanOpenAccessFailureDetectionEventNotifier, _NS_::AccessFailureResolution) \ + HANDLER(CanOpenBisPartitionBootConfigAndPackage2Part1Read, _NS_::SystemUpdate, _NS_::BisAllRaw) \ + HANDLER(CanOpenBisPartitionBootConfigAndPackage2Part1Write, _NS_::SystemUpdate, _NS_::BisAllRaw) \ + HANDLER(CanOpenBisPartitionBootConfigAndPackage2Part2Read, _NS_::SystemUpdate, _NS_::BisAllRaw) \ + HANDLER(CanOpenBisPartitionBootConfigAndPackage2Part2Write, _NS_::SystemUpdate, _NS_::BisAllRaw) \ + HANDLER(CanOpenBisPartitionBootConfigAndPackage2Part3Read, _NS_::SystemUpdate, _NS_::BisAllRaw) \ + HANDLER(CanOpenBisPartitionBootConfigAndPackage2Part3Write, _NS_::SystemUpdate, _NS_::BisAllRaw) \ + HANDLER(CanOpenBisPartitionBootConfigAndPackage2Part4Read, _NS_::SystemUpdate, _NS_::BisAllRaw) \ + HANDLER(CanOpenBisPartitionBootConfigAndPackage2Part4Write, _NS_::SystemUpdate, _NS_::BisAllRaw) \ + HANDLER(CanOpenBisPartitionBootConfigAndPackage2Part5Read, _NS_::SystemUpdate, _NS_::BisAllRaw) \ + HANDLER(CanOpenBisPartitionBootConfigAndPackage2Part5Write, _NS_::SystemUpdate, _NS_::BisAllRaw) \ + HANDLER(CanOpenBisPartitionBootConfigAndPackage2Part6Read, _NS_::SystemUpdate, _NS_::BisAllRaw) \ + HANDLER(CanOpenBisPartitionBootConfigAndPackage2Part6Write, _NS_::SystemUpdate, _NS_::BisAllRaw) \ + HANDLER(CanOpenBisPartitionBootPartition1RootRead, _NS_::SystemUpdate, _NS_::BisAllRaw, _NS_::BootModeControl) \ + HANDLER(CanOpenBisPartitionBootPartition1RootWrite, _NS_::SystemUpdate, _NS_::BisAllRaw, _NS_::BootModeControl) \ + HANDLER(CanOpenBisPartitionBootPartition2RootRead, _NS_::SystemUpdate, _NS_::BisAllRaw) \ + HANDLER(CanOpenBisPartitionBootPartition2RootWrite, _NS_::SystemUpdate, _NS_::BisAllRaw) \ + HANDLER(CanOpenBisPartitionCalibrationBinaryRead, _NS_::BisAllRaw, _NS_::Calibration) \ + HANDLER(CanOpenBisPartitionCalibrationBinaryWrite, _NS_::BisAllRaw, _NS_::Calibration) \ + HANDLER(CanOpenBisPartitionCalibrationFileRead, _NS_::BisAllRaw, _NS_::Calibration) \ + HANDLER(CanOpenBisPartitionCalibrationFileWrite, _NS_::BisAllRaw, _NS_::Calibration) \ + HANDLER(CanOpenBisPartitionSafeModeRead, _NS_::BisAllRaw) \ + HANDLER(CanOpenBisPartitionSafeModeWrite, _NS_::BisAllRaw) \ + HANDLER(CanOpenBisPartitionSystemProperEncryptionRead, _NS_::BisAllRaw) \ + HANDLER(CanOpenBisPartitionSystemProperEncryptionWrite, _NS_::BisAllRaw) \ + HANDLER(CanOpenBisPartitionSystemProperPartitionRead, _NS_::BisAllRaw) \ + HANDLER(CanOpenBisPartitionSystemProperPartitionWrite, _NS_::BisAllRaw) \ + HANDLER(CanOpenBisPartitionSystemRead, _NS_::BisAllRaw) \ + HANDLER(CanOpenBisPartitionSystemWrite, _NS_::BisAllRaw) \ + HANDLER(CanOpenBisPartitionUserDataRootRead, _NS_::BisAllRaw) \ + HANDLER(CanOpenBisPartitionUserDataRootWrite, _NS_::BisAllRaw) \ + HANDLER(CanOpenBisPartitionUserRead, _NS_::BisAllRaw) \ + HANDLER(CanOpenBisPartitionUserWrite, _NS_::BisAllRaw) \ + HANDLER(CanOpenBisWiper, _NS_::ContentManager) \ + HANDLER(CanOpenDataStorageByPath, _NS_::None) \ + HANDLER(CanOpenGameCardDetectionEventNotifier, _NS_::DeviceDetection, _NS_::GameCardRaw, _NS_::GameCard) \ + HANDLER(CanOpenGameCardStorageRead, _NS_::GameCardRaw) \ + HANDLER(CanOpenGameCardStorageWrite, _NS_::GameCardRaw) \ + HANDLER(CanOpenOwnSaveDataTransferProhibiter, _NS_::CreateOwnSaveData) \ + HANDLER(CanOpenSaveDataInfoReader, _NS_::SaveDataManagement, _NS_::SaveDataBackUp) \ + HANDLER(CanOpenSaveDataInfoReaderForInternal, _NS_::SaveDataManagement) \ + HANDLER(CanOpenSaveDataInfoReaderForSystem, _NS_::SystemSaveDataManagement, _NS_::SaveDataBackUp) \ + HANDLER(CanOpenSaveDataInternalStorageRead, _NS_::None) \ + HANDLER(CanOpenSaveDataInternalStorageWrite, _NS_::None) \ + HANDLER(CanOpenSaveDataMetaFile, _NS_::SaveDataMeta) \ + HANDLER(CanOpenSaveDataMover, _NS_::MoveCacheStorage) \ + HANDLER(CanOpenSaveDataTransferManager, _NS_::SaveDataTransfer) \ + HANDLER(CanOpenSaveDataTransferManagerForRepair, _NS_::SaveDataBackUp) \ + HANDLER(CanOpenSaveDataTransferManagerForSaveDataRepair, _NS_::SaveDataTransferVersion2) \ + HANDLER(CanOpenSaveDataTransferManagerForSaveDataRepairTool, _NS_::None) \ + HANDLER(CanOpenSaveDataTransferManagerVersion2, _NS_::SaveDataTransferVersion2) \ + HANDLER(CanOpenSaveDataTransferProhibiter, _NS_::SaveDataTransferVersion2, _NS_::CreateSaveData) \ + HANDLER(CanOpenSdCardDetectionEventNotifier, _NS_::DeviceDetection, _NS_::SdCard) \ + HANDLER(CanOpenSdCardStorageRead, _NS_::Debug, _NS_::SdCard) \ + HANDLER(CanOpenSdCardStorageWrite, _NS_::Debug, _NS_::SdCard) \ + HANDLER(CanOpenSystemDataUpdateEventNotifier, _NS_::SystemData, _NS_::SystemSaveData) \ + HANDLER(CanOverrideSaveDataTransferTokenSignVerificationKey, _NS_::None) \ + HANDLER(CanQuerySaveDataInternalStorageTotalSize, _NS_::SaveDataTransfer) \ + HANDLER(CanReadOwnSaveDataFileSystemExtraData, _NS_::CreateOwnSaveData) \ + HANDLER(CanReadSaveDataFileSystemExtraData, _NS_::SystemSaveDataManagement, _NS_::SaveDataManagement, _NS_::SaveDataBackUp) \ + HANDLER(CanRegisterExternalKey, _NS_::RegisterExternalKey) \ + HANDLER(CanRegisterProgramIndexMapInfo, _NS_::RegisterProgramIndexMapInfo) \ + HANDLER(CanRegisterUpdatePartition, _NS_::RegisterUpdatePartition) \ + HANDLER(CanResolveAccessFailure, _NS_::AccessFailureResolution) \ + HANDLER(CanSetCurrentPosixTime, _NS_::SetTime) \ + HANDLER(CanSetDebugConfiguration, _NS_::None) \ + HANDLER(CanSetEncryptionSeed, _NS_::ContentManager) \ + HANDLER(CanSetGlobalAccessLogMode, _NS_::SettingsControl) \ + HANDLER(CanSetSdCardAccessibility, _NS_::SdCard) \ + HANDLER(CanSetSpeedEmulationMode, _NS_::SettingsControl) \ + HANDLER(CanSimulateDevice, _NS_::Debug) \ + HANDLER(CanVerifySaveData, _NS_::SaveDataManagement, _NS_::SaveDataBackUp) \ + HANDLER(CanWriteSaveDataFileSystemExtraDataAll, _NS_::None) \ + HANDLER(CanWriteSaveDataFileSystemExtraDataCommitId, _NS_::SaveDataBackUp) \ + HANDLER(CanWriteSaveDataFileSystemExtraDataFlags, _NS_::SaveDataTransferVersion2, _NS_::SystemSaveDataManagement, _NS_::SaveDataBackUp) \ + HANDLER(CanWriteSaveDataFileSystemExtraDataTimeStamp, _NS_::SaveDataBackUp) + + class AccessControlBits { + public: + enum class Bits : u64 { + None = 0, + + ApplicationInfo = UINT64_C(1) << 0, + BootModeControl = UINT64_C(1) << 1, + Calibration = UINT64_C(1) << 2, + SystemSaveData = UINT64_C(1) << 3, + GameCard = UINT64_C(1) << 4, + SaveDataBackUp = UINT64_C(1) << 5, + SaveDataManagement = UINT64_C(1) << 6, + BisAllRaw = UINT64_C(1) << 7, + GameCardRaw = UINT64_C(1) << 8, + GameCardPrivate = UINT64_C(1) << 9, + SetTime = UINT64_C(1) << 10, + ContentManager = UINT64_C(1) << 11, + ImageManager = UINT64_C(1) << 12, + CreateSaveData = UINT64_C(1) << 13, + SystemSaveDataManagement = UINT64_C(1) << 14, + BisFileSystem = UINT64_C(1) << 15, + SystemUpdate = UINT64_C(1) << 16, + SaveDataMeta = UINT64_C(1) << 17, + DeviceSaveData = UINT64_C(1) << 18, + SettingsControl = UINT64_C(1) << 19, + SystemData = UINT64_C(1) << 20, + SdCard = UINT64_C(1) << 21, + Host = UINT64_C(1) << 22, + FillBis = UINT64_C(1) << 23, + CorruptSaveData = UINT64_C(1) << 24, + SaveDataForDebug = UINT64_C(1) << 25, + FormatSdCard = UINT64_C(1) << 26, + GetRightsId = UINT64_C(1) << 27, + RegisterExternalKey = UINT64_C(1) << 28, + RegisterUpdatePartition = UINT64_C(1) << 29, + SaveDataTransfer = UINT64_C(1) << 30, + DeviceDetection = UINT64_C(1) << 31, + AccessFailureResolution = UINT64_C(1) << 32, + SaveDataTransferVersion2 = UINT64_C(1) << 33, + RegisterProgramIndexMapInfo = UINT64_C(1) << 34, + CreateOwnSaveData = UINT64_C(1) << 35, + MoveCacheStorage = UINT64_C(1) << 36, + + Debug = UINT64_C(1) << 62, + FullPermission = UINT64_C(1) << 63 + }; + private: + static constexpr u64 CombineBits(Bits b) { + return util::ToUnderlying(b); + } + + template + static constexpr u64 CombineBits(Bits b, Args... args) { + return CombineBits(b) | CombineBits(args...); + } + private: + const u64 m_value; + public: + constexpr AccessControlBits(u64 v) : m_value(v) { /* ... */ } + + constexpr u64 GetValue() const { return m_value; } + + #define DEFINE_ACCESS_GETTER(name, ...) \ + constexpr bool name() const { constexpr u64 Mask = CombineBits(Bits::FullPermission, ## __VA_ARGS__); return (m_value & Mask); } + + AMS_FSSRV_FOR_EACH_ACCESS_CONTROL_CAPABILITY(DEFINE_ACCESS_GETTER, Bits) + + #undef DEFINE_ACCESS_GETTER + }; + +} diff --git a/libraries/libstratosphere/include/stratosphere/fssystem.hpp b/libraries/libstratosphere/include/stratosphere/fssystem.hpp index 658d8db30..101667352 100644 --- a/libraries/libstratosphere/include/stratosphere/fssystem.hpp +++ b/libraries/libstratosphere/include/stratosphere/fssystem.hpp @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include diff --git a/libraries/libstratosphere/include/stratosphere/fssystem/fssystem_forwarding_file_system.hpp b/libraries/libstratosphere/include/stratosphere/fssystem/fssystem_forwarding_file_system.hpp new file mode 100644 index 000000000..569d0c36c --- /dev/null +++ b/libraries/libstratosphere/include/stratosphere/fssystem/fssystem_forwarding_file_system.hpp @@ -0,0 +1,175 @@ +/* + * 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 +#include +#include +#include +#include + +namespace ams::fssystem { + + class ForwardingFile final : public ::ams::fs::fsa::IFile, public ::ams::fs::impl::Newable { + NON_COPYABLE(ForwardingFile); + NON_MOVEABLE(ForwardingFile); + private: + std::unique_ptr m_base_file; + public: + ForwardingFile(std::unique_ptr f) : m_base_file(std::move(f)) { /* ... */ } + + virtual ~ForwardingFile() { /* ... */ } + public: + virtual Result DoRead(size_t *out, s64 offset, void *buffer, size_t size, const fs::ReadOption &option) override final { + R_RETURN(m_base_file->Read(out, offset, buffer, size, option)); + } + + virtual Result DoGetSize(s64 *out) override final { + R_RETURN(m_base_file->GetSize(out)); + } + + virtual Result DoFlush() override final { + R_RETURN(m_base_file->Flush()); + } + + virtual Result DoWrite(s64 offset, const void *buffer, size_t size, const fs::WriteOption &option) override final { + R_RETURN(m_base_file->Write(offset, buffer, size, option)); + } + + virtual Result DoSetSize(s64 size) override final { + R_RETURN(m_base_file->SetSize(size)); + } + + virtual Result DoOperateRange(void *dst, size_t dst_size, fs::OperationId op_id, s64 offset, s64 size, const void *src, size_t src_size) override final { + R_RETURN(m_base_file->OperateRange(dst, dst_size, op_id, offset, size, src, src_size)); + } + public: + virtual sf::cmif::DomainObjectId GetDomainObjectId() const override final { + return m_base_file->GetDomainObjectId(); + } + }; + + class ForwardingDirectory final : public ::ams::fs::fsa::IDirectory, public ::ams::fs::impl::Newable { + NON_COPYABLE(ForwardingDirectory); + NON_MOVEABLE(ForwardingDirectory); + private: + std::unique_ptr m_base_dir; + public: + ForwardingDirectory(std::unique_ptr d) : m_base_dir(std::move(d)) { /* ... */ } + + virtual ~ForwardingDirectory() { /* ... */ } + public: + virtual Result DoRead(s64 *out_count, fs::DirectoryEntry *out_entries, s64 max_entries) override final { + R_RETURN(m_base_dir->Read(out_count, out_entries, max_entries)); + } + + virtual Result DoGetEntryCount(s64 *out) override final { + R_RETURN(m_base_dir->GetEntryCount(out)); + } + public: + virtual sf::cmif::DomainObjectId GetDomainObjectId() const override final { + return m_base_dir->GetDomainObjectId(); + } + }; + + class ForwardingFileSystem final : public ::ams::fs::fsa::IFileSystem, public ::ams::fs::impl::Newable { + NON_COPYABLE(ForwardingFileSystem); + NON_MOVEABLE(ForwardingFileSystem); + private: + std::shared_ptr m_base_fs; + public: + ForwardingFileSystem(std::shared_ptr fs) : m_base_fs(std::move(fs)) { /* ... */ } + + virtual ~ForwardingFileSystem() { /* ... */ } + public: + virtual Result DoCreateFile(const fs::Path &path, s64 size, int flags) override final { + R_RETURN(m_base_fs->CreateFile(path, size, flags)); + } + + virtual Result DoDeleteFile(const fs::Path &path) override final { + R_RETURN(m_base_fs->DeleteFile(path)); + } + + virtual Result DoCreateDirectory(const fs::Path &path) override final { + R_RETURN(m_base_fs->CreateDirectory(path)); + } + + virtual Result DoDeleteDirectory(const fs::Path &path) override final { + R_RETURN(m_base_fs->DeleteDirectory(path)); + } + + virtual Result DoDeleteDirectoryRecursively(const fs::Path &path) override final { + R_RETURN(m_base_fs->DeleteDirectoryRecursively(path)); + } + + virtual Result DoRenameFile(const fs::Path &old_path, const fs::Path &new_path) override final { + R_RETURN(m_base_fs->RenameFile(old_path, new_path)); + } + + virtual Result DoRenameDirectory(const fs::Path &old_path, const fs::Path &new_path) override final { + R_RETURN(m_base_fs->RenameDirectory(old_path, new_path)); + } + + virtual Result DoGetEntryType(fs::DirectoryEntryType *out, const fs::Path &path) override final { + R_RETURN(m_base_fs->GetEntryType(out, path)); + } + + virtual Result DoOpenFile(std::unique_ptr *out_file, const fs::Path &path, fs::OpenMode mode) override final { + R_RETURN(m_base_fs->OpenFile(out_file, path, mode)); + } + + virtual Result DoOpenDirectory(std::unique_ptr *out_dir, const fs::Path &path, fs::OpenDirectoryMode mode) override final { + R_RETURN(m_base_fs->OpenDirectory(out_dir, path, mode)); + } + + virtual Result DoCommit() override final { + R_RETURN(m_base_fs->Commit()); + } + + virtual Result DoGetFreeSpaceSize(s64 *out, const fs::Path &path) override final { + R_RETURN(m_base_fs->GetFreeSpaceSize(out, path)); + } + + virtual Result DoGetTotalSpaceSize(s64 *out, const fs::Path &path) override final { + R_RETURN(m_base_fs->GetTotalSpaceSize(out, path)); + } + + virtual Result DoCleanDirectoryRecursively(const fs::Path &path) override final { + R_RETURN(m_base_fs->CleanDirectoryRecursively(path)); + } + + virtual Result DoGetFileTimeStampRaw(fs::FileTimeStampRaw *out, const fs::Path &path) override final { + R_RETURN(m_base_fs->GetFileTimeStampRaw(out, path)); + } + + virtual Result DoQueryEntry(char *dst, size_t dst_size, const char *src, size_t src_size, fs::fsa::QueryId query, const fs::Path &path) override final { + R_RETURN(m_base_fs->QueryEntry(dst, dst_size, src, src_size, query, path)); + } + + virtual Result DoCommitProvisionally(s64 counter) override final { + R_RETURN(m_base_fs->CommitProvisionally(counter)); + } + + virtual Result DoRollback() override final { + R_RETURN(m_base_fs->Rollback()); + } + + virtual Result DoFlush() override final { + R_RETURN(m_base_fs->Flush()); + } + }; + +} diff --git a/libraries/libstratosphere/include/stratosphere/fssystem/fssystem_i_hash_256_generator.hpp b/libraries/libstratosphere/include/stratosphere/fssystem/fssystem_i_hash_256_generator.hpp index 5518c3689..eded06435 100644 --- a/libraries/libstratosphere/include/stratosphere/fssystem/fssystem_i_hash_256_generator.hpp +++ b/libraries/libstratosphere/include/stratosphere/fssystem/fssystem_i_hash_256_generator.hpp @@ -40,7 +40,7 @@ namespace ams::fssystem { /* Check pre-conditions. */ AMS_ASSERT(dst_size == HashSize); - return this->GetHash(dst, dst_size); + return this->DoGetHash(dst, dst_size); } protected: virtual void DoInitialize() = 0; diff --git a/libraries/libstratosphere/include/stratosphere/fssystem/fssystem_nca_file_system_driver.hpp b/libraries/libstratosphere/include/stratosphere/fssystem/fssystem_nca_file_system_driver.hpp index a1c87870d..41469894f 100644 --- a/libraries/libstratosphere/include/stratosphere/fssystem/fssystem_nca_file_system_driver.hpp +++ b/libraries/libstratosphere/include/stratosphere/fssystem/fssystem_nca_file_system_driver.hpp @@ -115,6 +115,7 @@ namespace ams::fssystem { u32 GetMagic() const; NcaHeader::DistributionType GetDistributionType() const; NcaHeader::ContentType GetContentType() const; + u8 GetHeaderSign1KeyGeneration() const; u8 GetKeyGeneration() const; u8 GetKeyIndex() const; u64 GetContentSize() const; diff --git a/libraries/libstratosphere/include/stratosphere/fssystem/fssystem_nca_header.hpp b/libraries/libstratosphere/include/stratosphere/fssystem/fssystem_nca_header.hpp index 85fd2ed3a..8e9ea86fe 100644 --- a/libraries/libstratosphere/include/stratosphere/fssystem/fssystem_nca_header.hpp +++ b/libraries/libstratosphere/include/stratosphere/fssystem/fssystem_nca_header.hpp @@ -128,8 +128,8 @@ namespace ams::fssystem { struct NcaBucketInfo { static constexpr size_t HeaderSize = 0x10; - s64 offset; - s64 size; + fs::Int64 offset; + fs::Int64 size; u8 header[HeaderSize]; }; static_assert(util::is_pod::value); @@ -138,11 +138,11 @@ namespace ams::fssystem { static constexpr size_t Size = 0x40; static constexpr size_t Offset = 0x100; - s64 indirect_offset; - s64 indirect_size; + fs::Int64 indirect_offset; + fs::Int64 indirect_size; u8 indirect_header[NcaBucketInfo::HeaderSize]; - s64 aes_ctr_ex_offset; - s64 aes_ctr_ex_size; + fs::Int64 aes_ctr_ex_offset; + fs::Int64 aes_ctr_ex_size; u8 aes_ctr_ex_header[NcaBucketInfo::HeaderSize]; bool HasIndirectTable() const; @@ -161,7 +161,7 @@ namespace ams::fssystem { struct NcaSparseInfo { NcaBucketInfo bucket; - s64 physical_offset; + fs::Int64 physical_offset; u16 generation; u8 reserved[6]; @@ -191,8 +191,8 @@ namespace ams::fssystem { static constexpr size_t HashDataOffset = 0x8; struct Region { - s64 offset; - s64 size; + fs::Int64 offset; + fs::Int64 size; }; static_assert(util::is_pod::value); @@ -240,8 +240,8 @@ namespace ams::fssystem { struct HierarchicalIntegrityVerificationLevelInformation { static constexpr size_t IntegrityMaxLayerCount = 7; - s64 offset; - s64 size; + fs::Int64 offset; + fs::Int64 size; s32 block_order; u8 reserved[4]; } info[HierarchicalIntegrityVerificationLevelInformation::IntegrityMaxLayerCount - 1]; diff --git a/libraries/libstratosphere/include/stratosphere/ldr/ldr_types.hpp b/libraries/libstratosphere/include/stratosphere/ldr/ldr_types.hpp index 6cc5f9d14..18302d285 100644 --- a/libraries/libstratosphere/include/stratosphere/ldr/ldr_types.hpp +++ b/libraries/libstratosphere/include/stratosphere/ldr/ldr_types.hpp @@ -23,7 +23,7 @@ namespace ams::ldr { /* General types. */ - struct ProgramInfo : sf::LargeData { + struct ProgramInfo : public sf::LargeData { u8 main_thread_priority; u8 default_cpu_id; u16 flags; diff --git a/libraries/libstratosphere/libstratosphere.mk b/libraries/libstratosphere/libstratosphere.mk index 57f47a647..83a243660 100644 --- a/libraries/libstratosphere/libstratosphere.mk +++ b/libraries/libstratosphere/libstratosphere.mk @@ -147,6 +147,7 @@ init_operator_new.o: CXXFLAGS += -fno-lto init_libnx_shim.os.horizon.o: CXXFLAGS += -fno-lto spl_secure_monitor_api.os.generic.o: CXXFLAGS += -I$(ATMOSPHERE_LIBRARIES_DIR)/libexosphere/include +fs_id_string_impl.os.generic.o: CXXFLAGS += -I$(ATMOSPHERE_LIBRARIES_DIR)/libexosphere/include ifeq ($(ATMOSPHERE_OS_NAME),windows) os_%.o: CXXFLAGS += -fno-lto diff --git a/libraries/libstratosphere/source/crypto/crypto_csrng.os.generic.cpp b/libraries/libstratosphere/source/crypto/crypto_csrng.os.generic.cpp new file mode 100644 index 000000000..ecb9e2d0a --- /dev/null +++ b/libraries/libstratosphere/source/crypto/crypto_csrng.os.generic.cpp @@ -0,0 +1,59 @@ +/* + * 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 . + */ +#include +#include "../spl/impl/spl_ctr_drbg.hpp" +#include + +namespace ams::crypto { + + namespace { + + using Drbg = ::ams::spl::impl::CtrDrbg; + + constinit util::TypedStorage g_drbg = {}; + + bool InitializeCsrng() { + u8 seed[Drbg::SeedSize]; + AMS_ABORT_UNLESS(::getentropy(seed, sizeof(seed)) == 0); + + util::ConstructAt(g_drbg); + util::GetReference(g_drbg).Initialize(seed, sizeof(seed), nullptr, 0, nullptr, 0); + + return true; + } + + } + + void GenerateCryptographicallyRandomBytes(void *dst, size_t dst_size) { + AMS_FUNCTION_LOCAL_STATIC(bool, s_initialized, InitializeCsrng()); + AMS_ABORT_UNLESS(s_initialized); + + AMS_ASSERT(dst_size <= Drbg::RequestSizeMax); + + if (!util::GetReference(g_drbg).Generate(dst, dst_size, nullptr, 0)) { + /* Reseed, if needed. */ + { + u8 seed[Drbg::SeedSize]; + AMS_ABORT_UNLESS(::getentropy(seed, sizeof(seed)) == 0); + + util::GetReference(g_drbg).Reseed(seed, sizeof(seed), nullptr, 0); + } + + util::GetReference(g_drbg).Generate(dst, dst_size, nullptr, 0); + } + } + +} diff --git a/libraries/libstratosphere/include/stratosphere/fssrv/fssrv_access_control.hpp b/libraries/libstratosphere/source/crypto/crypto_csrng.os.windows.cpp similarity index 64% rename from libraries/libstratosphere/include/stratosphere/fssrv/fssrv_access_control.hpp rename to libraries/libstratosphere/source/crypto/crypto_csrng.os.windows.cpp index 526233625..ef5707457 100644 --- a/libraries/libstratosphere/include/stratosphere/fssrv/fssrv_access_control.hpp +++ b/libraries/libstratosphere/source/crypto/crypto_csrng.os.windows.cpp @@ -13,11 +13,15 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -#pragma once -#include +#include +#include +#include -namespace ams::fssrv { +namespace ams::crypto { - void SetDebugFlagEnabled(bool en); + void GenerateCryptographicallyRandomBytes(void *dst, size_t dst_size) { + const auto status = ::BCryptGenRandom(nullptr, static_cast(dst), dst_size, BCRYPT_USE_SYSTEM_PREFERRED_RNG); + AMS_ABORT_UNLESS(status == STATUS_SUCCESS); + } } diff --git a/libraries/libstratosphere/source/fs/fs_access_log.cpp b/libraries/libstratosphere/source/fs/fs_access_log.cpp index 7f5e90745..9006a921f 100644 --- a/libraries/libstratosphere/source/fs/fs_access_log.cpp +++ b/libraries/libstratosphere/source/fs/fs_access_log.cpp @@ -84,6 +84,8 @@ namespace ams::fs { namespace ams::fs::impl { + #define ADD_ENUM_CASE(v) case v: return #v + const char *IdString::ToValueString(int id) { const int len = util::SNPrintf(m_buffer, sizeof(m_buffer), "%d", id); AMS_ASSERT(static_cast(len) < sizeof(m_buffer)); @@ -112,20 +114,22 @@ namespace ams::fs::impl { template<> const char *IdString::ToString(fs::ContentStorageId id) { switch (id) { - case fs::ContentStorageId::User: return "User"; - case fs::ContentStorageId::System: return "System"; - case fs::ContentStorageId::SdCard: return "SdCard"; - default: return ToValueString(static_cast(id)); + using enum fs::ContentStorageId; + ADD_ENUM_CASE(User); + ADD_ENUM_CASE(System); + ADD_ENUM_CASE(SdCard); + default: return ToValueString(static_cast(id)); } } template<> const char *IdString::ToString(fs::SaveDataSpaceId id) { switch (id) { - case fs::SaveDataSpaceId::System: return "System"; - case fs::SaveDataSpaceId::User: return "User"; - case fs::SaveDataSpaceId::SdSystem: return "SdSystem"; - case fs::SaveDataSpaceId::ProperSystem: return "ProperSystem"; - default: return ToValueString(static_cast(id)); + using enum fs::SaveDataSpaceId; + ADD_ENUM_CASE(System); + ADD_ENUM_CASE(User); + ADD_ENUM_CASE(SdSystem); + ADD_ENUM_CASE(ProperSystem); + default: return ToValueString(static_cast(id)); } } @@ -142,23 +146,24 @@ namespace ams::fs::impl { template<> const char *IdString::ToString(fs::BisPartitionId id) { switch (id) { - case fs::BisPartitionId::BootPartition1Root: return "BootPartition1Root"; - case fs::BisPartitionId::BootPartition2Root: return "BootPartition2Root"; - case fs::BisPartitionId::UserDataRoot: return "UserDataRoot"; - case fs::BisPartitionId::BootConfigAndPackage2Part1: return "BootConfigAndPackage2Part1"; - case fs::BisPartitionId::BootConfigAndPackage2Part2: return "BootConfigAndPackage2Part2"; - case fs::BisPartitionId::BootConfigAndPackage2Part3: return "BootConfigAndPackage2Part3"; - case fs::BisPartitionId::BootConfigAndPackage2Part4: return "BootConfigAndPackage2Part4"; - case fs::BisPartitionId::BootConfigAndPackage2Part5: return "BootConfigAndPackage2Part5"; - case fs::BisPartitionId::BootConfigAndPackage2Part6: return "BootConfigAndPackage2Part6"; - case fs::BisPartitionId::CalibrationBinary: return "CalibrationBinary"; - case fs::BisPartitionId::CalibrationFile: return "CalibrationFile"; - case fs::BisPartitionId::SafeMode: return "SafeMode"; - case fs::BisPartitionId::User: return "User"; - case fs::BisPartitionId::System: return "System"; - case fs::BisPartitionId::SystemProperEncryption: return "SystemProperEncryption"; - case fs::BisPartitionId::SystemProperPartition: return "SystemProperPartition"; - default: return ToValueString(static_cast(id)); + using enum fs::BisPartitionId; + ADD_ENUM_CASE(BootPartition1Root); + ADD_ENUM_CASE(BootPartition2Root); + ADD_ENUM_CASE(UserDataRoot); + ADD_ENUM_CASE(BootConfigAndPackage2Part1); + ADD_ENUM_CASE(BootConfigAndPackage2Part2); + ADD_ENUM_CASE(BootConfigAndPackage2Part3); + ADD_ENUM_CASE(BootConfigAndPackage2Part4); + ADD_ENUM_CASE(BootConfigAndPackage2Part5); + ADD_ENUM_CASE(BootConfigAndPackage2Part6); + ADD_ENUM_CASE(CalibrationBinary); + ADD_ENUM_CASE(CalibrationFile); + ADD_ENUM_CASE(SafeMode); + ADD_ENUM_CASE(User); + ADD_ENUM_CASE(System); + ADD_ENUM_CASE(SystemProperEncryption); + ADD_ENUM_CASE(SystemProperPartition); + default: return ToValueString(static_cast(id)); } } @@ -172,10 +177,267 @@ namespace ams::fs::impl { template<> const char *IdString::ToString(fs::GameCardPartition id) { switch (id) { - case fs::GameCardPartition::Update: return "Update"; - case fs::GameCardPartition::Normal: return "Normal"; - case fs::GameCardPartition::Secure: return "Secure"; - default: return ToValueString(static_cast(id)); + using enum fs::GameCardPartition; + ADD_ENUM_CASE(Update); + ADD_ENUM_CASE(Normal); + ADD_ENUM_CASE(Secure); + default: return ToValueString(static_cast(id)); + } + } + + template<> const char *IdString::ToString(fssystem::NcaHeader::ContentType id) { + switch (id) { + using enum fssystem::NcaHeader::ContentType; + ADD_ENUM_CASE(Program); + ADD_ENUM_CASE(Meta); + ADD_ENUM_CASE(Control); + ADD_ENUM_CASE(Manual); + ADD_ENUM_CASE(Data); + ADD_ENUM_CASE(PublicData); + default: return ToValueString(static_cast(id)); + } + } + + template<> const char *IdString::ToString(fssystem::NcaHeader::DistributionType id) { + switch (id) { + using enum fssystem::NcaHeader::DistributionType; + ADD_ENUM_CASE(Download); + ADD_ENUM_CASE(GameCard); + default: return ToValueString(static_cast(id)); + } + } + + template<> const char *IdString::ToString(fssystem::NcaHeader::EncryptionType id) { + switch (id) { + using enum fssystem::NcaHeader::EncryptionType; + ADD_ENUM_CASE(Auto); + ADD_ENUM_CASE(None); + default: return ToValueString(static_cast(id)); + } + } + + template<> const char *IdString::ToString(fssystem::NcaHeader::DecryptionKey id) { + switch (id) { + using enum fssystem::NcaHeader::DecryptionKey; + case DecryptionKey_AesXts1: return "AesXts1"; + case DecryptionKey_AesXts2: return "AesXts2"; + case DecryptionKey_AesCtr: return "AesCtr"; + case DecryptionKey_AesCtrEx: return "AesCtrEx"; + case DecryptionKey_AesCtrHw: return "AesCtrHw"; + default: return ToValueString(static_cast(id)); + } + } + + template<> const char *IdString::ToString(fssystem::NcaFsHeader::FsType id) { + switch (id) { + using enum fssystem::NcaFsHeader::FsType; + ADD_ENUM_CASE(RomFs); + ADD_ENUM_CASE(PartitionFs); + default: return ToValueString(static_cast(id)); + } + } + + template<> const char *IdString::ToString(fssystem::NcaFsHeader::EncryptionType id) { + switch (id) { + using enum fssystem::NcaFsHeader::EncryptionType; + ADD_ENUM_CASE(Auto); + ADD_ENUM_CASE(None); + ADD_ENUM_CASE(AesXts); + ADD_ENUM_CASE(AesCtr); + ADD_ENUM_CASE(AesCtrEx); + default: return ToValueString(static_cast(id)); + } + } + + template<> const char *IdString::ToString(fssystem::NcaFsHeader::HashType id) { + switch (id) { + using enum fssystem::NcaFsHeader::HashType; + ADD_ENUM_CASE(Auto); + ADD_ENUM_CASE(None); + ADD_ENUM_CASE(HierarchicalSha256Hash); + ADD_ENUM_CASE(HierarchicalIntegrityHash); + default: return ToValueString(static_cast(id)); + } + } + + template<> const char *IdString::ToString(fssrv::impl::AccessControlBits::Bits id) { + switch (id) { + using enum fssrv::impl::AccessControlBits::Bits; + ADD_ENUM_CASE(ApplicationInfo); + ADD_ENUM_CASE(BootModeControl); + ADD_ENUM_CASE(Calibration); + ADD_ENUM_CASE(SystemSaveData); + ADD_ENUM_CASE(GameCard); + ADD_ENUM_CASE(SaveDataBackUp); + ADD_ENUM_CASE(SaveDataManagement); + ADD_ENUM_CASE(BisAllRaw); + ADD_ENUM_CASE(GameCardRaw); + ADD_ENUM_CASE(GameCardPrivate); + ADD_ENUM_CASE(SetTime); + ADD_ENUM_CASE(ContentManager); + ADD_ENUM_CASE(ImageManager); + ADD_ENUM_CASE(CreateSaveData); + ADD_ENUM_CASE(SystemSaveDataManagement); + ADD_ENUM_CASE(BisFileSystem); + ADD_ENUM_CASE(SystemUpdate); + ADD_ENUM_CASE(SaveDataMeta); + ADD_ENUM_CASE(DeviceSaveData); + ADD_ENUM_CASE(SettingsControl); + ADD_ENUM_CASE(SystemData); + ADD_ENUM_CASE(SdCard); + ADD_ENUM_CASE(Host); + ADD_ENUM_CASE(FillBis); + ADD_ENUM_CASE(CorruptSaveData); + ADD_ENUM_CASE(SaveDataForDebug); + ADD_ENUM_CASE(FormatSdCard); + ADD_ENUM_CASE(GetRightsId); + ADD_ENUM_CASE(RegisterExternalKey); + ADD_ENUM_CASE(RegisterUpdatePartition); + ADD_ENUM_CASE(SaveDataTransfer); + ADD_ENUM_CASE(DeviceDetection); + ADD_ENUM_CASE(AccessFailureResolution); + ADD_ENUM_CASE(SaveDataTransferVersion2); + ADD_ENUM_CASE(RegisterProgramIndexMapInfo); + ADD_ENUM_CASE(CreateOwnSaveData); + ADD_ENUM_CASE(MoveCacheStorage); + + ADD_ENUM_CASE(Debug); + ADD_ENUM_CASE(FullPermission); + default: return ToValueString(util::CountTrailingZeros(util::ToUnderlying(id))); + } + } + + template<> const char *IdString::ToString(fssrv::impl::AccessControl::AccessibilityType id) { + switch (id) { + using enum fssrv::impl::AccessControl::AccessibilityType; + ADD_ENUM_CASE(MountLogo); + ADD_ENUM_CASE(MountContentMeta); + ADD_ENUM_CASE(MountContentControl); + ADD_ENUM_CASE(MountContentManual); + ADD_ENUM_CASE(MountContentData); + ADD_ENUM_CASE(MountApplicationPackage); + ADD_ENUM_CASE(MountSaveDataStorage); + ADD_ENUM_CASE(MountContentStorage); + ADD_ENUM_CASE(MountImageAndVideoStorage); + ADD_ENUM_CASE(MountCloudBackupWorkStorage); + ADD_ENUM_CASE(MountCustomStorage); + ADD_ENUM_CASE(MountBisCalibrationFile); + ADD_ENUM_CASE(MountBisSafeMode); + ADD_ENUM_CASE(MountBisUser); + ADD_ENUM_CASE(MountBisSystem); + ADD_ENUM_CASE(MountBisSystemProperEncryption); + ADD_ENUM_CASE(MountBisSystemProperPartition); + ADD_ENUM_CASE(MountSdCard); + ADD_ENUM_CASE(MountGameCard); + ADD_ENUM_CASE(MountDeviceSaveData); + ADD_ENUM_CASE(MountSystemSaveData); + ADD_ENUM_CASE(MountOthersSaveData); + ADD_ENUM_CASE(MountOthersSystemSaveData); + ADD_ENUM_CASE(OpenBisPartitionBootPartition1Root); + ADD_ENUM_CASE(OpenBisPartitionBootPartition2Root); + ADD_ENUM_CASE(OpenBisPartitionUserDataRoot); + ADD_ENUM_CASE(OpenBisPartitionBootConfigAndPackage2Part1); + ADD_ENUM_CASE(OpenBisPartitionBootConfigAndPackage2Part2); + ADD_ENUM_CASE(OpenBisPartitionBootConfigAndPackage2Part3); + ADD_ENUM_CASE(OpenBisPartitionBootConfigAndPackage2Part4); + ADD_ENUM_CASE(OpenBisPartitionBootConfigAndPackage2Part5); + ADD_ENUM_CASE(OpenBisPartitionBootConfigAndPackage2Part6); + ADD_ENUM_CASE(OpenBisPartitionCalibrationBinary); + ADD_ENUM_CASE(OpenBisPartitionCalibrationFile); + ADD_ENUM_CASE(OpenBisPartitionSafeMode); + ADD_ENUM_CASE(OpenBisPartitionUser); + ADD_ENUM_CASE(OpenBisPartitionSystem); + ADD_ENUM_CASE(OpenBisPartitionSystemProperEncryption); + ADD_ENUM_CASE(OpenBisPartitionSystemProperPartition); + ADD_ENUM_CASE(OpenSdCardStorage); + ADD_ENUM_CASE(OpenGameCardStorage); + ADD_ENUM_CASE(MountSystemDataPrivate); + ADD_ENUM_CASE(MountHost); + ADD_ENUM_CASE(MountRegisteredUpdatePartition); + ADD_ENUM_CASE(MountSaveDataInternalStorage); + ADD_ENUM_CASE(MountTemporaryDirectory); + ADD_ENUM_CASE(MountAllBaseFileSystem); + ADD_ENUM_CASE(NotMount); + default: return ToValueString(static_cast(id)); + } + } + + template<> const char *IdString::ToString(fssrv::impl::AccessControl::OperationType id) { + switch (id) { + using enum fssrv::impl::AccessControl::OperationType; + ADD_ENUM_CASE(InvalidateBisCache); + ADD_ENUM_CASE(EraseMmc); + ADD_ENUM_CASE(GetGameCardDeviceCertificate); + ADD_ENUM_CASE(GetGameCardIdSet); + ADD_ENUM_CASE(FinalizeGameCardDriver); + ADD_ENUM_CASE(GetGameCardAsicInfo); + ADD_ENUM_CASE(CreateSaveData); + ADD_ENUM_CASE(DeleteSaveData); + ADD_ENUM_CASE(CreateSystemSaveData); + ADD_ENUM_CASE(CreateOthersSystemSaveData); + ADD_ENUM_CASE(DeleteSystemSaveData); + ADD_ENUM_CASE(OpenSaveDataInfoReader); + ADD_ENUM_CASE(OpenSaveDataInfoReaderForSystem); + ADD_ENUM_CASE(OpenSaveDataInfoReaderForInternal); + ADD_ENUM_CASE(OpenSaveDataMetaFile); + ADD_ENUM_CASE(SetCurrentPosixTime); + ADD_ENUM_CASE(ReadSaveDataFileSystemExtraData); + ADD_ENUM_CASE(SetGlobalAccessLogMode); + ADD_ENUM_CASE(SetSpeedEmulationMode); + ADD_ENUM_CASE(Debug); + ADD_ENUM_CASE(FillBis); + ADD_ENUM_CASE(CorruptSaveData); + ADD_ENUM_CASE(CorruptSystemSaveData); + ADD_ENUM_CASE(VerifySaveData); + ADD_ENUM_CASE(DebugSaveData); + ADD_ENUM_CASE(FormatSdCard); + ADD_ENUM_CASE(GetRightsId); + ADD_ENUM_CASE(RegisterExternalKey); + ADD_ENUM_CASE(SetEncryptionSeed); + ADD_ENUM_CASE(WriteSaveDataFileSystemExtraDataTimeStamp); + ADD_ENUM_CASE(WriteSaveDataFileSystemExtraDataFlags); + ADD_ENUM_CASE(WriteSaveDataFileSystemExtraDataCommitId); + ADD_ENUM_CASE(WriteSaveDataFileSystemExtraDataAll); + ADD_ENUM_CASE(ExtendSaveData); + ADD_ENUM_CASE(ExtendSystemSaveData); + ADD_ENUM_CASE(ExtendOthersSystemSaveData); + ADD_ENUM_CASE(RegisterUpdatePartition); + ADD_ENUM_CASE(OpenSaveDataTransferManager); + ADD_ENUM_CASE(OpenSaveDataTransferManagerVersion2); + ADD_ENUM_CASE(OpenSaveDataTransferManagerForSaveDataRepair); + ADD_ENUM_CASE(OpenSaveDataTransferManagerForSaveDataRepairTool); + ADD_ENUM_CASE(OpenSaveDataTransferProhibiter); + ADD_ENUM_CASE(OpenSaveDataMover); + ADD_ENUM_CASE(OpenBisWiper); + ADD_ENUM_CASE(ListAccessibleSaveDataOwnerId); + ADD_ENUM_CASE(ControlMmcPatrol); + ADD_ENUM_CASE(OverrideSaveDataTransferTokenSignVerificationKey); + ADD_ENUM_CASE(OpenSdCardDetectionEventNotifier); + ADD_ENUM_CASE(OpenGameCardDetectionEventNotifier); + ADD_ENUM_CASE(OpenSystemDataUpdateEventNotifier); + ADD_ENUM_CASE(NotifySystemDataUpdateEvent); + ADD_ENUM_CASE(OpenAccessFailureDetectionEventNotifier); + ADD_ENUM_CASE(GetAccessFailureDetectionEvent); + ADD_ENUM_CASE(IsAccessFailureDetected); + ADD_ENUM_CASE(ResolveAccessFailure); + ADD_ENUM_CASE(AbandonAccessFailure); + ADD_ENUM_CASE(QuerySaveDataInternalStorageTotalSize); + ADD_ENUM_CASE(GetSaveDataCommitId); + ADD_ENUM_CASE(SetSdCardAccessibility); + ADD_ENUM_CASE(SimulateDevice); + ADD_ENUM_CASE(CreateSaveDataWithHashSalt); + ADD_ENUM_CASE(RegisterProgramIndexMapInfo); + ADD_ENUM_CASE(ChallengeCardExistence); + ADD_ENUM_CASE(CreateOwnSaveData); + ADD_ENUM_CASE(DeleteOwnSaveData); + ADD_ENUM_CASE(ReadOwnSaveDataFileSystemExtraData); + ADD_ENUM_CASE(ExtendOwnSaveData); + ADD_ENUM_CASE(OpenOwnSaveDataTransferProhibiter); + ADD_ENUM_CASE(FindOwnSaveDataWithFilter); + ADD_ENUM_CASE(OpenSaveDataTransferManagerForRepair); + ADD_ENUM_CASE(SetDebugConfiguration); + ADD_ENUM_CASE(OpenDataStorageByPath); + default: return ToValueString(static_cast(id)); } } diff --git a/libraries/libstratosphere/source/fs/impl/fs_id_string_impl.os.generic.cpp b/libraries/libstratosphere/source/fs/impl/fs_id_string_impl.os.generic.cpp new file mode 100644 index 000000000..3083970dc --- /dev/null +++ b/libraries/libstratosphere/source/fs/impl/fs_id_string_impl.os.generic.cpp @@ -0,0 +1,44 @@ +/* + * 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 . + */ +#include +#include + +namespace ams::fs::impl { + + #define ADD_ENUM_CASE(v) case v: return #v + + template<> const char *IdString::ToString(pkg1::KeyGeneration id) { + static_assert(pkg1::KeyGeneration_Current == pkg1::KeyGeneration_13_0_0); + switch (id) { + using enum pkg1::KeyGeneration; + case KeyGeneration_1_0_0: return "1.0.0-2.3.0"; + case KeyGeneration_3_0_0: return "3.0.0"; + case KeyGeneration_3_0_1: return "3.0.1-3.0.2"; + case KeyGeneration_4_0_0: return "4.0.0-4.1.0"; + case KeyGeneration_5_0_0: return "5.0.0-5.1.0"; + case KeyGeneration_6_0_0: return "6.0.0-6.1.0"; + case KeyGeneration_6_2_0: return "6.2.0"; + case KeyGeneration_7_0_0: return "7.0.0-8.0.1"; + case KeyGeneration_8_1_0: return "8.1.0-8.1.1"; + case KeyGeneration_9_0_0: return "9.0.0-9.0.1"; + case KeyGeneration_9_1_0: return "9.1.0-12.0.3"; + case KeyGeneration_12_1_0: return "12.1.0"; + case KeyGeneration_13_0_0: return "13.0.0-"; + default: return "Unknown"; + } + } + +} diff --git a/libraries/libstratosphere/source/fs/impl/fs_library.cpp b/libraries/libstratosphere/source/fs/impl/fs_library.cpp index 5574861de..e256d3241 100644 --- a/libraries/libstratosphere/source/fs/impl/fs_library.cpp +++ b/libraries/libstratosphere/source/fs/impl/fs_library.cpp @@ -39,12 +39,16 @@ namespace ams::fs::impl { [[maybe_unused]] constexpr size_t BufferPoolSize = 6_MB; [[maybe_unused]] constexpr size_t DeviceBufferSize = 8_MB; + [[maybe_unused]] constexpr size_t DeviceWorkBufferSize = os::MemoryPageSize; [[maybe_unused]] constexpr size_t BufferManagerHeapSize = 14_MB; + constexpr size_t DeviceWorkBufferRequiredSize = 0x140; + static_assert(util::IsAligned(BufferManagerHeapSize, os::MemoryBlockUnitSize)); //alignas(os::MemoryPageSize) u8 g_buffer_pool[BufferPoolSize]; - //alignas(os::MemoryPageSize) u8 g_device_buffer[DeviceBufferSize]; + alignas(os::MemoryPageSize) u8 g_device_buffer[DeviceBufferSize]; + alignas(os::MemoryPageSize) u8 g_device_work_buffer[DeviceWorkBufferSize]; //alignas(os::MemoryPageSize) u8 g_buffer_manager_heap[BufferManagerHeapSize]; // //alignas(os::MemoryPageSize) u8 g_buffer_manager_work_buffer[64_KB]; @@ -69,6 +73,8 @@ namespace ams::fs::impl { /* TODO: Many things. */ g_system_heap_memory_resource.emplace(std::addressof(GetSystemHeapAllocator())); + fssystem::InitializeBufferPool(reinterpret_cast(g_device_buffer), DeviceBufferSize, reinterpret_cast(g_device_work_buffer), DeviceWorkBufferRequiredSize); + /* Setup fscreators/interfaces. */ g_local_fs_creator.emplace(true); g_subdir_fs_creator.emplace(); diff --git a/libraries/libstratosphere/source/fssrv/fscreator/fssrv_storage_on_nca_creator.cpp b/libraries/libstratosphere/source/fssrv/fscreator/fssrv_storage_on_nca_creator.cpp index dd421975a..a4eddb68a 100644 --- a/libraries/libstratosphere/source/fssrv/fscreator/fssrv_storage_on_nca_creator.cpp +++ b/libraries/libstratosphere/source/fssrv/fscreator/fssrv_storage_on_nca_creator.cpp @@ -60,4 +60,36 @@ namespace ams::fssrv::fscreator { return ResultSuccess(); } + #if !defined(ATMOSPHERE_BOARD_NINTENDO_NX) + Result StorageOnNcaCreator::CreateWithContext(std::shared_ptr *out, std::shared_ptr *out_splitter, fssystem::NcaFsHeaderReader *out_header_reader, void *ctx, std::shared_ptr nca_reader, s32 index) { + /* Create a fs driver. */ + fssystem::NcaFileSystemDriver nca_fs_driver(nca_reader, m_allocator, m_buffer_manager, m_hash_generator_factory_selector); + + /* Open the storage. */ + std::shared_ptr storage; + std::shared_ptr splitter; + R_TRY(nca_fs_driver.OpenStorageWithContext(std::addressof(storage), std::addressof(splitter), out_header_reader, index, static_cast(ctx))); + + /* Set the out storage. */ + *out = std::move(storage); + *out_splitter = std::move(splitter); + return ResultSuccess(); + } + + Result StorageOnNcaCreator::CreateWithPatchWithContext(std::shared_ptr *out, std::shared_ptr *out_splitter, fssystem::NcaFsHeaderReader *out_header_reader, void *ctx, std::shared_ptr original_nca_reader, std::shared_ptr current_nca_reader, s32 index) { + /* Create a fs driver. */ + fssystem::NcaFileSystemDriver nca_fs_driver(original_nca_reader, current_nca_reader, m_allocator, m_buffer_manager, m_hash_generator_factory_selector); + + /* Open the storage. */ + std::shared_ptr storage; + std::shared_ptr splitter; + R_TRY(nca_fs_driver.OpenStorageWithContext(std::addressof(storage), std::addressof(splitter), out_header_reader, index, static_cast(ctx))); + + /* Set the out storage. */ + *out = std::move(storage); + *out_splitter = std::move(splitter); + return ResultSuccess(); + } + #endif + } diff --git a/libraries/libstratosphere/source/fssrv/fssrv_access_control.cpp b/libraries/libstratosphere/source/fssrv/fssrv_access_control.cpp index fbb64a6ed..06d53c334 100644 --- a/libraries/libstratosphere/source/fssrv/fssrv_access_control.cpp +++ b/libraries/libstratosphere/source/fssrv/fssrv_access_control.cpp @@ -23,9 +23,385 @@ namespace ams::fssrv { } + bool IsDebugFlagEnabled() { + return g_is_debug_flag_enabled; + } + void SetDebugFlagEnabled(bool en) { /* Set global debug flag. */ g_is_debug_flag_enabled = en; } + namespace impl { + + namespace { + + constexpr u8 LatestFsAccessControlInfoVersion = 1; + + } + + AccessControl::AccessControl(const void *data, s64 data_size, const void *desc, s64 desc_size) : AccessControl(data, data_size, desc, desc_size, g_is_debug_flag_enabled ? AllFlagBitsMask : DebugFlagDisableMask) { + /* ... */ + } + + AccessControl::AccessControl(const void *fac_data, s64 data_size, const void *fac_desc, s64 desc_size, u64 flag_mask) { + /* If either our data or descriptor is null, give no permissions. */ + if (fac_data == nullptr || fac_desc == nullptr) { + m_flag_bits.emplace(util::ToUnderlying(AccessControlBits::Bits::None)); + return; + } + + /* Check that data/desc are big enough. */ + AMS_ABORT_UNLESS(data_size >= static_cast(sizeof(AccessControlDataHeader))); + AMS_ABORT_UNLESS(desc_size >= static_cast(sizeof(AccessControlDescriptor))); + + /* Copy in the data/descriptor. */ + AccessControlDataHeader data = {}; + AccessControlDescriptor desc = {}; + std::memcpy(std::addressof(data), fac_data, sizeof(data)); + std::memcpy(std::addressof(desc), fac_desc, sizeof(desc)); + + /* If we don't know how to parse the descriptors, don't. */ + if (data.version != desc.version || data.version < LatestFsAccessControlInfoVersion) { + m_flag_bits.emplace(util::ToUnderlying(AccessControlBits::Bits::None)); + return; + } + + /* Restrict the descriptor's flag bits. */ + desc.flag_bits &= flag_mask; + + /* Create our flag bits. */ + m_flag_bits.emplace(data.flag_bits & desc.flag_bits); + + /* Further check sizes. */ + AMS_ABORT_UNLESS(data_size >= data.content_owner_infos_offset + data.content_owner_infos_size); + AMS_ABORT_UNLESS(desc_size >= static_cast(sizeof(AccessControlDescriptor) + desc.content_owner_id_count * sizeof(u64))); + + /* Read out the content data owner infos. */ + uintptr_t data_start = reinterpret_cast(fac_data); + uintptr_t desc_start = reinterpret_cast(fac_desc); + if (data.content_owner_infos_size > 0) { + /* Get the count. */ + const u32 num_content_owner_infos = util::LoadLittleEndian(reinterpret_cast(data_start + data.content_owner_infos_offset)); + + /* Validate the id range. */ + uintptr_t id_start = data_start + data.content_owner_infos_offset + sizeof(u32); + uintptr_t id_end = id_start + sizeof(u64) * num_content_owner_infos; + AMS_ABORT_UNLESS(id_end == data_start + data.content_owner_infos_offset + data.content_owner_infos_size); + + for (u32 i = 0; i < num_content_owner_infos; ++i) { + /* Read the id. */ + const u64 id = util::LoadLittleEndian(reinterpret_cast(id_start + i * sizeof(u64))); + + /* Check that the descriptor allows it. */ + bool allowed = false; + if (desc.content_owner_id_count != 0) { + for (u8 n = 0; n < desc.content_owner_id_count; ++n) { + if (id == util::LoadLittleEndian(reinterpret_cast(desc_start + sizeof(AccessControlDescriptor) + n * sizeof(u64)))) { + allowed = true; + break; + } + } + } else if ((desc.content_owner_id_min == 0 && desc.content_owner_id_max == 0) || (desc.content_owner_id_min <= id && id <= desc.content_owner_id_max)) { + allowed = true; + } + + /* If the id is allowed, create it. */ + if (allowed) { + if (auto *info = new ContentOwnerInfo(id); info != nullptr) { + m_content_owner_infos.push_front(*info); + } + } + } + } + + /* Read out the save data owner infos. */ + AMS_ABORT_UNLESS(data_size >= data.save_data_owner_infos_offset + data.save_data_owner_infos_size); + AMS_ABORT_UNLESS(desc_size >= static_cast(sizeof(AccessControlDescriptor) + desc.content_owner_id_count * sizeof(u64) + desc.save_data_owner_id_count * sizeof(u64))); + if (data.save_data_owner_infos_size > 0) { + /* Get the count. */ + const u32 num_save_data_owner_infos = util::LoadLittleEndian(reinterpret_cast(data_start + data.save_data_owner_infos_offset)); + + /* Get accessibility region.*/ + uintptr_t accessibility_start = data_start + data.save_data_owner_infos_offset + sizeof(u32); + + /* Validate the id range. */ + uintptr_t id_start = accessibility_start + util::AlignUp(num_save_data_owner_infos * sizeof(Accessibility), alignof(u32)); + uintptr_t id_end = id_start + sizeof(u64) * num_save_data_owner_infos; + AMS_ABORT_UNLESS(id_end == data_start + data.save_data_owner_infos_offset + data.save_data_owner_infos_size); + + for (u32 i = 0; i < num_save_data_owner_infos; ++i) { + /* Read the accessibility/id. */ + static_assert(sizeof(Accessibility) == 1); + const Accessibility accessibility = *reinterpret_cast(accessibility_start + i * sizeof(Accessibility)); + const u64 id = util::LoadLittleEndian(reinterpret_cast(id_start + i * sizeof(u64))); + + /* Check that the descriptor allows it. */ + bool allowed = false; + if (desc.save_data_owner_id_count != 0) { + for (u8 n = 0; n < desc.save_data_owner_id_count; ++n) { + if (id == util::LoadLittleEndian(reinterpret_cast(desc_start + sizeof(AccessControlDescriptor) + desc.content_owner_id_count * sizeof(u64) + n * sizeof(u64)))) { + allowed = true; + break; + } + } + } else if ((desc.save_data_owner_id_min == 0 && desc.save_data_owner_id_max == 0) || (desc.save_data_owner_id_min <= id && id <= desc.save_data_owner_id_max)) { + allowed = true; + } + + /* If the id is allowed, create it. */ + if (allowed) { + if (auto *info = new SaveDataOwnerInfo(id, accessibility); info != nullptr) { + m_save_data_owner_infos.push_front(*info); + } + } + } + } + + } + + AccessControl::~AccessControl() { + /* Delete all content owner infos. */ + while (!m_content_owner_infos.empty()) { + auto *info = std::addressof(*m_content_owner_infos.rbegin()); + m_content_owner_infos.erase(m_content_owner_infos.iterator_to(*info)); + delete info; + } + + /* Delete all save data owner infos. */ + while (!m_save_data_owner_infos.empty()) { + auto *info = std::addressof(*m_save_data_owner_infos.rbegin()); + m_save_data_owner_infos.erase(m_save_data_owner_infos.iterator_to(*info)); + delete info; + } + } + + bool AccessControl::HasContentOwnerId(u64 owner_id) const { + /* Check if we have a matching id. */ + for (const auto &info : m_content_owner_infos) { + if (info.GetId() == owner_id) { + return true; + } + } + + return false; + } + + Accessibility AccessControl::GetAccessibilitySaveDataOwnedBy(u64 owner_id) const { + /* Find a matching save data owner. */ + for (const auto &info : m_save_data_owner_infos) { + if (info.GetId() == owner_id) { + return info.GetAccessibility(); + } + } + + /* Default to no accessibility. */ + return Accessibility::MakeAccessibility(false, false); + } + + void AccessControl::ListContentOwnerId(s32 *out_count, u64 *out_owner_ids, s32 offset, s32 count) const { + /* If we have nothing to read, just give the count. */ + if (count == 0) { + *out_count = m_content_owner_infos.size(); + return; + } + + /* Read out the ids. */ + s32 read_offset = 0; + s32 read_count = 0; + if (out_owner_ids != nullptr) { + auto *cur_out = out_owner_ids; + for (const auto &info : m_content_owner_infos) { + /* Skip until we get to the desired offset. */ + if (read_offset < offset) { + ++read_offset; + continue; + } + + /* Set the output value. */ + *cur_out = info.GetId(); + ++cur_out; + ++read_count; + + /* If we've read as many as we can, finish. */ + if (read_count == count) { + break; + } + } + } + + /* Set the out value. */ + *out_count = read_count; + } + + void AccessControl::ListSaveDataOwnedId(s32 *out_count, ncm::ApplicationId *out_owner_ids, s32 offset, s32 count) const { + /* If we have nothing to read, just give the count. */ + if (count == 0) { + *out_count = m_save_data_owner_infos.size(); + return; + } + + /* Read out the ids. */ + s32 read_offset = 0; + s32 read_count = 0; + if (out_owner_ids != nullptr) { + auto *cur_out = out_owner_ids; + for (const auto &info : m_save_data_owner_infos) { + /* Skip until we get to the desired offset. */ + if (read_offset < offset) { + ++read_offset; + continue; + } + + /* Set the output value. */ + cur_out->value = info.GetId(); + ++cur_out; + ++read_count; + + /* If we've read as many as we can, finish. */ + if (read_count == count) { + break; + } + } + } + + /* Set the out value. */ + *out_count = read_count; + } + + Accessibility AccessControl::GetAccessibilityFor(AccessibilityType type) const { + switch (type) { + using enum AccessibilityType; + case MountLogo: return Accessibility::MakeAccessibility(m_flag_bits->CanMountLogoRead(), false); + case MountContentMeta: return Accessibility::MakeAccessibility(m_flag_bits->CanMountContentMetaRead(), false); + case MountContentControl: return Accessibility::MakeAccessibility(m_flag_bits->CanMountContentControlRead(), false); + case MountContentManual: return Accessibility::MakeAccessibility(m_flag_bits->CanMountContentManualRead(), false); + case MountContentData: return Accessibility::MakeAccessibility(m_flag_bits->CanMountContentDataRead(), false); + case MountApplicationPackage: return Accessibility::MakeAccessibility(m_flag_bits->CanMountApplicationPackageRead(), false); + case MountSaveDataStorage: return Accessibility::MakeAccessibility(m_flag_bits->CanMountSaveDataStorageRead(), m_flag_bits->CanMountSaveDataStorageWrite()); + case MountContentStorage: return Accessibility::MakeAccessibility(m_flag_bits->CanMountContentStorageRead(), m_flag_bits->CanMountContentStorageWrite()); + case MountImageAndVideoStorage: return Accessibility::MakeAccessibility(m_flag_bits->CanMountImageAndVideoStorageRead(), m_flag_bits->CanMountImageAndVideoStorageWrite()); + case MountCloudBackupWorkStorage: return Accessibility::MakeAccessibility(m_flag_bits->CanMountCloudBackupWorkStorageRead(), m_flag_bits->CanMountCloudBackupWorkStorageWrite()); + case MountCustomStorage: return Accessibility::MakeAccessibility(m_flag_bits->CanMountCustomStorage0Read(), m_flag_bits->CanMountCustomStorage0Write()); + case MountBisCalibrationFile: return Accessibility::MakeAccessibility(m_flag_bits->CanMountBisCalibrationFileRead(), m_flag_bits->CanMountBisCalibrationFileWrite()); + case MountBisSafeMode: return Accessibility::MakeAccessibility(m_flag_bits->CanMountBisSafeModeRead(), m_flag_bits->CanMountBisSafeModeWrite()); + case MountBisUser: return Accessibility::MakeAccessibility(m_flag_bits->CanMountBisUserRead(), m_flag_bits->CanMountBisUserWrite()); + case MountBisSystem: return Accessibility::MakeAccessibility(m_flag_bits->CanMountBisSystemRead(), m_flag_bits->CanMountBisSystemWrite()); + case MountBisSystemProperEncryption: return Accessibility::MakeAccessibility(m_flag_bits->CanMountBisSystemProperEncryptionRead(), m_flag_bits->CanMountBisSystemProperEncryptionWrite()); + case MountBisSystemProperPartition: return Accessibility::MakeAccessibility(m_flag_bits->CanMountBisSystemProperPartitionRead(), m_flag_bits->CanMountBisSystemProperPartitionWrite()); + case MountSdCard: return Accessibility::MakeAccessibility(m_flag_bits->CanMountSdCardRead(), m_flag_bits->CanMountSdCardWrite()); + case MountGameCard: return Accessibility::MakeAccessibility(m_flag_bits->CanMountGameCardRead(), false); + case MountDeviceSaveData: return Accessibility::MakeAccessibility(m_flag_bits->CanMountDeviceSaveDataRead(), m_flag_bits->CanMountDeviceSaveDataWrite()); + case MountSystemSaveData: return Accessibility::MakeAccessibility(m_flag_bits->CanMountSystemSaveDataRead(), m_flag_bits->CanMountSystemSaveDataWrite()); + case MountOthersSaveData: return Accessibility::MakeAccessibility(m_flag_bits->CanMountOthersSaveDataRead(), m_flag_bits->CanMountOthersSaveDataWrite()); + case MountOthersSystemSaveData: return Accessibility::MakeAccessibility(m_flag_bits->CanMountOthersSystemSaveDataRead(), m_flag_bits->CanMountOthersSystemSaveDataWrite()); + case OpenBisPartitionBootPartition1Root: return Accessibility::MakeAccessibility(m_flag_bits->CanOpenBisPartitionBootPartition1RootRead(), m_flag_bits->CanOpenBisPartitionBootPartition1RootWrite()); + case OpenBisPartitionBootPartition2Root: return Accessibility::MakeAccessibility(m_flag_bits->CanOpenBisPartitionBootPartition2RootRead(), m_flag_bits->CanOpenBisPartitionBootPartition2RootWrite()); + case OpenBisPartitionUserDataRoot: return Accessibility::MakeAccessibility(m_flag_bits->CanOpenBisPartitionUserDataRootRead(), m_flag_bits->CanOpenBisPartitionUserDataRootWrite()); + case OpenBisPartitionBootConfigAndPackage2Part1: return Accessibility::MakeAccessibility(m_flag_bits->CanOpenBisPartitionBootConfigAndPackage2Part1Read(), m_flag_bits->CanOpenBisPartitionBootConfigAndPackage2Part1Write()); + case OpenBisPartitionBootConfigAndPackage2Part2: return Accessibility::MakeAccessibility(m_flag_bits->CanOpenBisPartitionBootConfigAndPackage2Part2Read(), m_flag_bits->CanOpenBisPartitionBootConfigAndPackage2Part2Write()); + case OpenBisPartitionBootConfigAndPackage2Part3: return Accessibility::MakeAccessibility(m_flag_bits->CanOpenBisPartitionBootConfigAndPackage2Part3Read(), m_flag_bits->CanOpenBisPartitionBootConfigAndPackage2Part3Write()); + case OpenBisPartitionBootConfigAndPackage2Part4: return Accessibility::MakeAccessibility(m_flag_bits->CanOpenBisPartitionBootConfigAndPackage2Part4Read(), m_flag_bits->CanOpenBisPartitionBootConfigAndPackage2Part4Write()); + case OpenBisPartitionBootConfigAndPackage2Part5: return Accessibility::MakeAccessibility(m_flag_bits->CanOpenBisPartitionBootConfigAndPackage2Part5Read(), m_flag_bits->CanOpenBisPartitionBootConfigAndPackage2Part5Write()); + case OpenBisPartitionBootConfigAndPackage2Part6: return Accessibility::MakeAccessibility(m_flag_bits->CanOpenBisPartitionBootConfigAndPackage2Part6Read(), m_flag_bits->CanOpenBisPartitionBootConfigAndPackage2Part6Write()); + case OpenBisPartitionCalibrationBinary: return Accessibility::MakeAccessibility(m_flag_bits->CanOpenBisPartitionCalibrationBinaryRead(), m_flag_bits->CanOpenBisPartitionCalibrationBinaryWrite()); + case OpenBisPartitionCalibrationFile: return Accessibility::MakeAccessibility(m_flag_bits->CanOpenBisPartitionCalibrationFileRead(), m_flag_bits->CanOpenBisPartitionCalibrationFileWrite()); + case OpenBisPartitionSafeMode: return Accessibility::MakeAccessibility(m_flag_bits->CanOpenBisPartitionSafeModeRead(), m_flag_bits->CanOpenBisPartitionSafeModeWrite()); + case OpenBisPartitionUser: return Accessibility::MakeAccessibility(m_flag_bits->CanOpenBisPartitionUserRead(), m_flag_bits->CanOpenBisPartitionUserWrite()); + case OpenBisPartitionSystem: return Accessibility::MakeAccessibility(m_flag_bits->CanOpenBisPartitionSystemRead(), m_flag_bits->CanOpenBisPartitionSystemWrite()); + case OpenBisPartitionSystemProperEncryption: return Accessibility::MakeAccessibility(m_flag_bits->CanOpenBisPartitionSystemProperEncryptionRead(), m_flag_bits->CanOpenBisPartitionSystemProperEncryptionWrite()); + case OpenBisPartitionSystemProperPartition: return Accessibility::MakeAccessibility(m_flag_bits->CanOpenBisPartitionSystemProperPartitionRead(), m_flag_bits->CanOpenBisPartitionSystemProperPartitionWrite()); + case OpenSdCardStorage: return Accessibility::MakeAccessibility(m_flag_bits->CanOpenSdCardStorageRead(), m_flag_bits->CanOpenSdCardStorageWrite()); + case OpenGameCardStorage: return Accessibility::MakeAccessibility(m_flag_bits->CanOpenGameCardStorageRead(), m_flag_bits->CanOpenGameCardStorageWrite()); + case MountSystemDataPrivate: return Accessibility::MakeAccessibility(m_flag_bits->CanMountSystemDataPrivateRead(), false); + case MountHost: return Accessibility::MakeAccessibility(m_flag_bits->CanMountHostRead(), m_flag_bits->CanMountHostWrite()); + case MountRegisteredUpdatePartition: return Accessibility::MakeAccessibility(m_flag_bits->CanMountRegisteredUpdatePartitionRead() && g_is_debug_flag_enabled, false); + case MountSaveDataInternalStorage: return Accessibility::MakeAccessibility(m_flag_bits->CanOpenSaveDataInternalStorageRead(), m_flag_bits->CanOpenSaveDataInternalStorageWrite()); + case MountTemporaryDirectory: return Accessibility::MakeAccessibility(m_flag_bits->CanMountTemporaryDirectoryRead(), m_flag_bits->CanMountTemporaryDirectoryWrite()); + case MountAllBaseFileSystem: return Accessibility::MakeAccessibility(m_flag_bits->CanMountAllBaseFileSystemRead(), m_flag_bits->CanMountAllBaseFileSystemWrite()); + case NotMount: return Accessibility::MakeAccessibility(false, false); + AMS_UNREACHABLE_DEFAULT_CASE(); + } + } + + bool AccessControl::CanCall(OperationType type) const { + switch (type) { + using enum OperationType; + case InvalidateBisCache: return m_flag_bits->CanInvalidateBisCache(); + case EraseMmc: return m_flag_bits->CanEraseMmc(); + case GetGameCardDeviceCertificate: return m_flag_bits->CanGetGameCardDeviceCertificate(); + case GetGameCardIdSet: return m_flag_bits->CanGetGameCardIdSet(); + case FinalizeGameCardDriver: return m_flag_bits->CanFinalizeGameCardDriver(); + case GetGameCardAsicInfo: return m_flag_bits->CanGetGameCardAsicInfo(); + case CreateSaveData: return m_flag_bits->CanCreateSaveData(); + case DeleteSaveData: return m_flag_bits->CanDeleteSaveData(); + case CreateSystemSaveData: return m_flag_bits->CanCreateSystemSaveData(); + case CreateOthersSystemSaveData: return m_flag_bits->CanCreateOthersSystemSaveData(); + case DeleteSystemSaveData: return m_flag_bits->CanDeleteSystemSaveData(); + case OpenSaveDataInfoReader: return m_flag_bits->CanOpenSaveDataInfoReader(); + case OpenSaveDataInfoReaderForSystem: return m_flag_bits->CanOpenSaveDataInfoReaderForSystem(); + case OpenSaveDataInfoReaderForInternal: return m_flag_bits->CanOpenSaveDataInfoReaderForInternal(); + case OpenSaveDataMetaFile: return m_flag_bits->CanOpenSaveDataMetaFile(); + case SetCurrentPosixTime: return m_flag_bits->CanSetCurrentPosixTime(); + case ReadSaveDataFileSystemExtraData: return m_flag_bits->CanReadSaveDataFileSystemExtraData(); + case SetGlobalAccessLogMode: return m_flag_bits->CanSetGlobalAccessLogMode(); + case SetSpeedEmulationMode: return m_flag_bits->CanSetSpeedEmulationMode(); + case FillBis: return m_flag_bits->CanFillBis(); + case CorruptSaveData: return m_flag_bits->CanCorruptSaveData(); + case CorruptSystemSaveData: return m_flag_bits->CanCorruptSystemSaveData(); + case VerifySaveData: return m_flag_bits->CanVerifySaveData(); + case DebugSaveData: return m_flag_bits->CanDebugSaveData(); + case FormatSdCard: return m_flag_bits->CanFormatSdCard(); + case GetRightsId: return m_flag_bits->CanGetRightsId(); + case RegisterExternalKey: return m_flag_bits->CanRegisterExternalKey(); + case SetEncryptionSeed: return m_flag_bits->CanSetEncryptionSeed(); + case WriteSaveDataFileSystemExtraDataTimeStamp: return m_flag_bits->CanWriteSaveDataFileSystemExtraDataTimeStamp(); + case WriteSaveDataFileSystemExtraDataFlags: return m_flag_bits->CanWriteSaveDataFileSystemExtraDataFlags(); + case WriteSaveDataFileSystemExtraDataCommitId: return m_flag_bits->CanWriteSaveDataFileSystemExtraDataCommitId(); + case WriteSaveDataFileSystemExtraDataAll: return m_flag_bits->CanWriteSaveDataFileSystemExtraDataAll(); + case ExtendSaveData: return m_flag_bits->CanExtendSaveData(); + case ExtendSystemSaveData: return m_flag_bits->CanExtendSystemSaveData(); + case ExtendOthersSystemSaveData: return m_flag_bits->CanExtendOthersSystemSaveData(); + case RegisterUpdatePartition: return m_flag_bits->CanRegisterUpdatePartition() && g_is_debug_flag_enabled; + case OpenSaveDataTransferManager: return m_flag_bits->CanOpenSaveDataTransferManager(); + case OpenSaveDataTransferManagerVersion2: return m_flag_bits->CanOpenSaveDataTransferManagerVersion2(); + case OpenSaveDataTransferManagerForSaveDataRepair: return m_flag_bits->CanOpenSaveDataTransferManagerForSaveDataRepair(); + case OpenSaveDataTransferManagerForSaveDataRepairTool: return m_flag_bits->CanOpenSaveDataTransferManagerForSaveDataRepairTool(); + case OpenSaveDataTransferProhibiter: return m_flag_bits->CanOpenSaveDataTransferProhibiter(); + case OpenSaveDataMover: return m_flag_bits->CanOpenSaveDataMover(); + case OpenBisWiper: return m_flag_bits->CanOpenBisWiper(); + case ListAccessibleSaveDataOwnerId: return m_flag_bits->CanListAccessibleSaveDataOwnerId(); + case ControlMmcPatrol: return m_flag_bits->CanControlMmcPatrol(); + case OverrideSaveDataTransferTokenSignVerificationKey: return m_flag_bits->CanOverrideSaveDataTransferTokenSignVerificationKey(); + case OpenSdCardDetectionEventNotifier: return m_flag_bits->CanOpenSdCardDetectionEventNotifier(); + case OpenGameCardDetectionEventNotifier: return m_flag_bits->CanOpenGameCardDetectionEventNotifier(); + case OpenSystemDataUpdateEventNotifier: return m_flag_bits->CanOpenSystemDataUpdateEventNotifier(); + case NotifySystemDataUpdateEvent: return m_flag_bits->CanNotifySystemDataUpdateEvent(); + case OpenAccessFailureDetectionEventNotifier: return m_flag_bits->CanOpenAccessFailureDetectionEventNotifier(); + case GetAccessFailureDetectionEvent: return m_flag_bits->CanGetAccessFailureDetectionEvent(); + case IsAccessFailureDetected: return m_flag_bits->CanIsAccessFailureDetected(); + case ResolveAccessFailure: return m_flag_bits->CanResolveAccessFailure(); + case AbandonAccessFailure: return m_flag_bits->CanAbandonAccessFailure(); + case QuerySaveDataInternalStorageTotalSize: return m_flag_bits->CanQuerySaveDataInternalStorageTotalSize(); + case GetSaveDataCommitId: return m_flag_bits->CanGetSaveDataCommitId(); + case SetSdCardAccessibility: return m_flag_bits->CanSetSdCardAccessibility(); + case SimulateDevice: return m_flag_bits->CanSimulateDevice(); + case CreateSaveDataWithHashSalt: return m_flag_bits->CanCreateSaveDataWithHashSalt(); + case RegisterProgramIndexMapInfo: return m_flag_bits->CanRegisterProgramIndexMapInfo(); + case ChallengeCardExistence: return m_flag_bits->CanChallengeCardExistence(); + case CreateOwnSaveData: return m_flag_bits->CanCreateOwnSaveData(); + case DeleteOwnSaveData: return m_flag_bits->CanDeleteOwnSaveData(); + case ReadOwnSaveDataFileSystemExtraData: return m_flag_bits->CanReadOwnSaveDataFileSystemExtraData(); + case ExtendOwnSaveData: return m_flag_bits->CanExtendOwnSaveData(); + case OpenOwnSaveDataTransferProhibiter: return m_flag_bits->CanOpenOwnSaveDataTransferProhibiter(); + case FindOwnSaveDataWithFilter: return m_flag_bits->CanFindOwnSaveDataWithFilter(); + case OpenSaveDataTransferManagerForRepair: return m_flag_bits->CanOpenSaveDataTransferManagerForRepair(); + case SetDebugConfiguration: return m_flag_bits->CanSetDebugConfiguration(); + case OpenDataStorageByPath: return m_flag_bits->CanOpenDataStorageByPath(); + AMS_UNREACHABLE_DEFAULT_CASE(); + } + } + + } + } diff --git a/libraries/libstratosphere/source/fssrv/impl/fssrv_utility.cpp b/libraries/libstratosphere/source/fssrv/impl/fssrv_utility.cpp index 993285ac2..fe99a9288 100644 --- a/libraries/libstratosphere/source/fssrv/impl/fssrv_utility.cpp +++ b/libraries/libstratosphere/source/fssrv/impl/fssrv_utility.cpp @@ -19,7 +19,9 @@ #if defined(ATMOSPHERE_OS_LINUX) #include #elif defined(ATMOSPHERE_OS_MACOS) -#include +#include +#include +#include #endif namespace ams::fssystem { @@ -47,10 +49,10 @@ namespace ams::fssystem { ::swprintf_s(path, util::size(path), L"%s%s", drive_name, dir_name); /* Convert to utf-8. */ - const auto res = ::WideCharToMultiByte(CP_UTF8, 0, path, -1, m_path, util::size(m_path), nullptr, nullptr); - if (res == 0) { - AMS_FS_R_ABORT_UNLESS(fs::ResultUnexpectedInPathOnExecutionDirectoryB()); - } + const auto res = ::WideCharToMultiByte(CP_UTF8, 0, path, -1, m_path, util::size(m_path), nullptr, nullptr); + if (res == 0) { + AMS_FS_R_ABORT_UNLESS(fs::ResultUnexpectedInPathOnExecutionDirectoryB()); + } } #elif defined(ATMOSPHERE_OS_LINUX) { @@ -60,6 +62,10 @@ namespace ams::fssystem { } const int len = std::strlen(full_path); + if (len >= static_cast(sizeof(m_path))) { + AMS_FS_R_ABORT_UNLESS(fs::ResultUnexpectedInPathOnExecutionDirectoryB()); + } + std::memcpy(m_path, full_path, len + 1); for (int i = len - 1; i >= 0; --i) { @@ -71,11 +77,17 @@ namespace ams::fssystem { } #elif defined(ATMOSPHERE_OS_MACOS) { - char full_path[PATH_MAX + 1] = {}; + char full_path[MAXPATHLEN] = {}; uint32_t size = sizeof(full_path); - AMS_ABORT_UNLESS(_NSGetExecutablePath(full_path, std::addressof(size)) == 0); + if (_NSGetExecutablePath(full_path, std::addressof(size)) != 0) { + AMS_FS_R_ABORT_UNLESS(fs::ResultUnexpectedInPathOnExecutionDirectoryA()); + } const int len = std::strlen(full_path); + if (len >= static_cast(sizeof(m_path))) { + AMS_FS_R_ABORT_UNLESS(fs::ResultUnexpectedInPathOnExecutionDirectoryB()); + } + std::memcpy(m_path, full_path, len + 1); for (int i = len - 1; i >= 0; --i) { @@ -88,6 +100,81 @@ namespace ams::fssystem { #else AMS_ABORT("TODO: Unknown OS for PathOnExecutionDirectory"); #endif + + const auto len = std::strlen(m_path); + if (m_path[len - 1] != '/' && m_path[len - 1] != '\\') { + if (len + 1 >= sizeof(m_path)) { + AMS_FS_R_ABORT_UNLESS(fs::ResultUnexpectedInPathOnExecutionDirectoryB()); + } + m_path[len] = '/'; + m_path[len + 1] = 0; + } + } + + const char *Get() const { + return m_path; + } + }; + + class PathOnWorkingDirectory { + private: + char m_path[fs::EntryNameLengthMax + 1]; + public: + PathOnWorkingDirectory() { + #if defined(ATMOSPHERE_OS_WINDOWS) + { + /* Get the current directory. */ + wchar_t current_directory[fs::EntryNameLengthMax + 1]; + if (::GetCurrentDirectoryW(util::size(current_directory), current_directory) == 0) { + AMS_FS_R_ABORT_UNLESS(fs::ResultUnexpectedInPathOnExecutionDirectoryB()); + } + + /* Convert to utf-8. */ + const auto res = ::WideCharToMultiByte(CP_UTF8, 0, current_directory, -1, m_path, util::size(m_path), nullptr, nullptr); + if (res == 0) { + AMS_FS_R_ABORT_UNLESS(fs::ResultUnexpectedInPathOnExecutionDirectoryB()); + } + } + #elif defined(ATMOSPHERE_OS_LINUX) + { + char full_path[PATH_MAX] = {}; + if (::getcwd(full_path, sizeof(full_path)) == nullptr) { + AMS_FS_R_ABORT_UNLESS(fs::ResultUnexpectedInPathOnExecutionDirectoryB()); + } + + const int len = std::strlen(full_path); + if (len >= static_cast(sizeof(m_path))) { + AMS_FS_R_ABORT_UNLESS(fs::ResultUnexpectedInPathOnExecutionDirectoryB()); + } + + std::memcpy(m_path, full_path, len + 1); + } + #elif defined(ATMOSPHERE_OS_MACOS) + { + char full_path[MAXPATHLEN] = {}; + if (::getcwd(full_path, sizeof(full_path)) == nullptr) { + AMS_FS_R_ABORT_UNLESS(fs::ResultUnexpectedInPathOnExecutionDirectoryB()); + } + + const int len = std::strlen(full_path); + if (len >= static_cast(sizeof(m_path))) { + AMS_FS_R_ABORT_UNLESS(fs::ResultUnexpectedInPathOnExecutionDirectoryB()); + } + + std::memcpy(m_path, full_path, len + 1); + } + #else + AMS_ABORT("TODO: Unknown OS for PathOnWorkingDirectory"); + #endif + + const auto len = std::strlen(m_path); + if (m_path[len - 1] != '/' && m_path[len - 1] != '\\') { + if (len + 1 >= sizeof(m_path)) { + AMS_FS_R_ABORT_UNLESS(fs::ResultUnexpectedInPathOnExecutionDirectoryB()); + } + m_path[len] = '/'; + m_path[len + 1] = 0; + } } const char *Get() const { @@ -104,4 +191,9 @@ namespace ams::fssrv::impl { return s_path_on_execution_directory.Get(); } + const char *GetWorkingDirectoryPath() { + AMS_FUNCTION_LOCAL_STATIC(fssystem::PathOnWorkingDirectory, s_path_on_working_directory); + return s_path_on_working_directory.Get(); + } + } diff --git a/libraries/libstratosphere/source/fssrv/impl/fssrv_utility.hpp b/libraries/libstratosphere/source/fssrv/impl/fssrv_utility.hpp index fcf057aad..36fe2c33e 100644 --- a/libraries/libstratosphere/source/fssrv/impl/fssrv_utility.hpp +++ b/libraries/libstratosphere/source/fssrv/impl/fssrv_utility.hpp @@ -19,5 +19,6 @@ namespace ams::fssrv::impl { const char *GetExecutionDirectoryPath(); + const char *GetWorkingDirectoryPath(); } diff --git a/libraries/libstratosphere/source/fssystem/fssystem_aes_ctr_storage.cpp b/libraries/libstratosphere/source/fssystem/fssystem_aes_ctr_storage.cpp index a2fdddbca..9048dcaef 100644 --- a/libraries/libstratosphere/source/fssystem/fssystem_aes_ctr_storage.cpp +++ b/libraries/libstratosphere/source/fssystem/fssystem_aes_ctr_storage.cpp @@ -32,7 +32,7 @@ namespace ams::fssystem { template AesCtrStorage::AesCtrStorage(BasePointer base, const void *key, size_t key_size, const void *iv, size_t iv_size) : m_base_storage(std::move(base)) { - AMS_ASSERT(base != nullptr); + AMS_ASSERT(m_base_storage != nullptr); AMS_ASSERT(key != nullptr); AMS_ASSERT(iv != nullptr); AMS_ASSERT(key_size == KeySize); diff --git a/libraries/libstratosphere/source/fssystem/fssystem_nca_file_system_driver.cpp b/libraries/libstratosphere/source/fssystem/fssystem_nca_file_system_driver.cpp index a745c57ab..0e3584adc 100644 --- a/libraries/libstratosphere/source/fssystem/fssystem_nca_file_system_driver.cpp +++ b/libraries/libstratosphere/source/fssystem/fssystem_nca_file_system_driver.cpp @@ -777,7 +777,7 @@ namespace ams::fssystem { /* Get and validate the meta extents. */ const s64 meta_offset = patch_info.aes_ctr_ex_offset; - const s64 meta_size = util::AlignUp(patch_info.aes_ctr_ex_size, NcaHeader::XtsBlockSize); + const s64 meta_size = util::AlignUp(static_cast(patch_info.aes_ctr_ex_size), NcaHeader::XtsBlockSize); R_UNLESS(meta_offset + meta_size <= base_size, fs::ResultNcaBaseStorageOutOfRangeB()); /* Create the encrypted storage. */ diff --git a/libraries/libstratosphere/source/fssystem/fssystem_nca_reader.cpp b/libraries/libstratosphere/source/fssystem/fssystem_nca_reader.cpp index d605dae12..c67b10c80 100644 --- a/libraries/libstratosphere/source/fssystem/fssystem_nca_reader.cpp +++ b/libraries/libstratosphere/source/fssystem/fssystem_nca_reader.cpp @@ -45,6 +45,14 @@ namespace ams::fssystem { /* ... */ } + void Dump(const void *s, size_t size) { + const u8 *s8 = static_cast(s); + for (size_t i = 0; i < size; ++i) { + printf("%02X", s8[i]); + } + printf("\n"); + } + Result NcaReader::Initialize(std::shared_ptr base_storage, const NcaCryptoConfiguration &crypto_cfg, const NcaCompressionConfiguration &compression_cfg, IHash256GeneratorFactorySelector *hgf_selector) { /* Validate preconditions. */ AMS_ASSERT(base_storage != nullptr); @@ -60,6 +68,7 @@ namespace ams::fssystem { u8 header_decryption_keys[NcaCryptoConfiguration::HeaderEncryptionKeyCount][NcaCryptoConfiguration::Aes128KeySize]; for (size_t i = 0; i < NcaCryptoConfiguration::HeaderEncryptionKeyCount; i++) { crypto_cfg.generate_key(header_decryption_keys[i], AesXtsStorageForNcaHeader::KeySize, crypto_cfg.header_encrypted_encryption_keys[i], AesXtsStorageForNcaHeader::KeySize, static_cast(KeyType::NcaHeaderKey), crypto_cfg); + Dump(header_decryption_keys[i], sizeof(header_decryption_keys[i])); } /* Create the header storage. */ @@ -119,6 +128,13 @@ namespace ams::fssystem { /* If we do, then we don't have an external key, so we need to generate decryption keys. */ crypto_cfg.generate_key(m_decryption_keys[NcaHeader::DecryptionKey_AesCtr], crypto::AesDecryptor128::KeySize, m_header.encrypted_key_area + NcaHeader::DecryptionKey_AesCtr * crypto::AesDecryptor128::KeySize, crypto::AesDecryptor128::KeySize, GetKeyTypeValue(m_header.key_index, m_header.GetProperKeyGeneration()), crypto_cfg); + /* If we're building for non-nx board (i.e., a host tool), generate all keys for debug. */ + #if !defined(ATMOSPHERE_BOARD_NINTENDO_NX) + crypto_cfg.generate_key(m_decryption_keys[NcaHeader::DecryptionKey_AesXts1], crypto::AesDecryptor128::KeySize, m_header.encrypted_key_area + NcaHeader::DecryptionKey_AesXts1 * crypto::AesDecryptor128::KeySize, crypto::AesDecryptor128::KeySize, GetKeyTypeValue(m_header.key_index, m_header.GetProperKeyGeneration()), crypto_cfg); + crypto_cfg.generate_key(m_decryption_keys[NcaHeader::DecryptionKey_AesXts2], crypto::AesDecryptor128::KeySize, m_header.encrypted_key_area + NcaHeader::DecryptionKey_AesXts2 * crypto::AesDecryptor128::KeySize, crypto::AesDecryptor128::KeySize, GetKeyTypeValue(m_header.key_index, m_header.GetProperKeyGeneration()), crypto_cfg); + crypto_cfg.generate_key(m_decryption_keys[NcaHeader::DecryptionKey_AesCtrEx], crypto::AesDecryptor128::KeySize, m_header.encrypted_key_area + NcaHeader::DecryptionKey_AesCtrEx * crypto::AesDecryptor128::KeySize, crypto::AesDecryptor128::KeySize, GetKeyTypeValue(m_header.key_index, m_header.GetProperKeyGeneration()), crypto_cfg); + #endif + /* Copy the hardware speed emulation key. */ std::memcpy(m_decryption_keys[NcaHeader::DecryptionKey_AesCtrHw], m_header.encrypted_key_area + NcaHeader::DecryptionKey_AesCtrHw * crypto::AesDecryptor128::KeySize, crypto::AesDecryptor128::KeySize); } @@ -164,6 +180,11 @@ namespace ams::fssystem { return m_header.content_type; } + u8 NcaReader::GetHeaderSign1KeyGeneration() const { + AMS_ASSERT(m_body_storage != nullptr); + return m_header.header1_signature_key_generation; + } + u8 NcaReader::GetKeyGeneration() const { AMS_ASSERT(m_body_storage != nullptr); return m_header.GetProperKeyGeneration(); diff --git a/libraries/libstratosphere/source/fssystem/fssystem_partition_file_system.cpp b/libraries/libstratosphere/source/fssystem/fssystem_partition_file_system.cpp index 639173e07..34969bd3c 100644 --- a/libraries/libstratosphere/source/fssystem/fssystem_partition_file_system.cpp +++ b/libraries/libstratosphere/source/fssystem/fssystem_partition_file_system.cpp @@ -359,7 +359,7 @@ namespace ams::fssystem { R_UNLESS(p[0] == RootPath[0], fs::ResultInvalidPathFormat()); /* Check if the path is for a directory. */ - if (util::Strncmp(p, RootPath, sizeof(RootPath))) { + if (util::Strncmp(p, RootPath, sizeof(RootPath)) == 0) { *out = fs::DirectoryEntryType_Directory; R_SUCCEED(); } diff --git a/libraries/libstratosphere/source/fssystem/save/fssystem_block_cache_buffered_storage.cpp b/libraries/libstratosphere/source/fssystem/save/fssystem_block_cache_buffered_storage.cpp index b6794dd4e..5462357c9 100644 --- a/libraries/libstratosphere/source/fssystem/save/fssystem_block_cache_buffered_storage.cpp +++ b/libraries/libstratosphere/source/fssystem/save/fssystem_block_cache_buffered_storage.cpp @@ -57,7 +57,7 @@ namespace ams::fssystem::save { /* Calculate block shift. */ m_verification_block_shift = ILog2(static_cast(verif_block_size)); - AMS_ASSERT(static_cast(1ull << m_verification_block_size) == m_verification_block_size); + AMS_ASSERT(static_cast(1ull << m_verification_block_shift) == m_verification_block_size); /* Clear the entry. */ std::memset(m_entries.get(), 0, sizeof(CacheEntry) * m_max_cache_entry_count); @@ -341,10 +341,14 @@ namespace ams::fssystem::save { CacheIndex index; R_TRY(this->UpdateLastResult(this->StoreAssociateBuffer(std::addressof(index), range, entry))); + /* Set the after aligned offset. */ + aligned_offset = entry.offset + entry.size; + /* If we need to, flush the cache entry. */ if (index >= 0 && IsEnabledKeepBurstMode() && offset == aligned_offset && (block_alignment * 2 <= size)) { R_TRY(this->UpdateLastResult(this->FlushCacheEntry(index, false))); } + } } diff --git a/libraries/libstratosphere/source/fssystem/save/fssystem_integrity_verification_storage.cpp b/libraries/libstratosphere/source/fssystem/save/fssystem_integrity_verification_storage.cpp index 47d29448a..65ab21b2c 100644 --- a/libraries/libstratosphere/source/fssystem/save/fssystem_integrity_verification_storage.cpp +++ b/libraries/libstratosphere/source/fssystem/save/fssystem_integrity_verification_storage.cpp @@ -39,7 +39,7 @@ namespace ams::fssystem::save { m_buffer_manager = bm; /* Set upper layer block sizes. */ - upper_layer_verif_block_size = std::max(upper_layer_verif_block_size, HashSize); + upper_layer_verif_block_size = std::max(upper_layer_verif_block_size, HashSize); m_upper_layer_verification_block_size = upper_layer_verif_block_size; m_upper_layer_verification_block_order = ILog2(static_cast(upper_layer_verif_block_size)); AMS_ASSERT(m_upper_layer_verification_block_size == (1l << m_upper_layer_verification_block_order)); @@ -334,18 +334,10 @@ namespace ams::fssystem::save { /* Only allow cache invalidation for RomFs. */ R_UNLESS(m_storage_type != fs::StorageType_SaveData, fs::ResultUnsupportedOperationInIntegrityVerificationStorageB()); - /* Validate the range. */ - s64 data_size = 0; - R_TRY(m_data_storage.GetSize(std::addressof(data_size))); - R_UNLESS(0 <= offset && offset <= data_size, fs::ResultInvalidOffset()); - - /* Determine the extents to invalidate. */ - const auto sign_offset = (offset >> m_verification_block_order) * HashSize; - const auto sign_size = (std::min(size, data_size - offset) >> m_verification_block_order) * HashSize; /* Operate on our storages. */ - R_TRY(m_hash_storage.OperateRange(dst, dst_size, op_id, sign_offset, sign_size, src, src_size)); - R_TRY(m_data_storage.OperateRange(dst, dst_size, op_id, sign_offset, sign_size, src, src_size)); + R_TRY(m_hash_storage.OperateRange(dst, dst_size, op_id, 0, std::numeric_limits::max(), src, src_size)); + R_TRY(m_data_storage.OperateRange(dst, dst_size, op_id, offset, size, src, src_size)); return ResultSuccess(); } diff --git a/libraries/libstratosphere/source/spl/impl/spl_api_impl.cpp b/libraries/libstratosphere/source/spl/impl/spl_api_impl.cpp index e476d80f6..8352f849e 100644 --- a/libraries/libstratosphere/source/spl/impl/spl_api_impl.cpp +++ b/libraries/libstratosphere/source/spl/impl/spl_api_impl.cpp @@ -32,12 +32,14 @@ namespace ams::spl::impl { using Drbg = CtrDrbg; /* Convenient defines. */ + #if defined(ATMOSPHERE_OS_HORIZON) constexpr size_t DeviceAddressSpaceAlign = 4_MB; constexpr u32 WorkBufferBase = 0x80000000u; constexpr u32 ComputeAesInMapBase = 0x90000000u; constexpr u32 ComputeAesOutMapBase = 0xC0000000u; constexpr size_t ComputeAesSizeMax = static_cast(ComputeAesOutMapBase - ComputeAesInMapBase); + #endif constexpr size_t DeviceUniqueDataIvSize = 0x10; constexpr size_t DeviceUniqueDataPaddingSize = 0x08; @@ -248,7 +250,7 @@ namespace ams::spl::impl { R_ABORT_UNLESS(dd::MapDeviceAddressSpaceAligned(std::addressof(g_device_address_space), dd::GetCurrentProcessHandle(), work_buffer_address, dd::DeviceAddressSpaceMemoryRegionAlignment, g_work_buffer_mapped_address, dd::MemoryPermission_ReadWrite)); #else /* Just set the work buffer address directly. */ - AMS_UNUSED(WorkBufferBase, g_device_address_space); + AMS_UNUSED(g_device_address_space); g_work_buffer_mapped_address = reinterpret_cast(g_work_buffer); #endif } diff --git a/libraries/libstratosphere/source/spl/smc/spl_secure_monitor_api.os.generic.cpp b/libraries/libstratosphere/source/spl/smc/spl_secure_monitor_api.os.generic.cpp index 224c13781..95945327a 100644 --- a/libraries/libstratosphere/source/spl/smc/spl_secure_monitor_api.os.generic.cpp +++ b/libraries/libstratosphere/source/spl/smc/spl_secure_monitor_api.os.generic.cpp @@ -83,9 +83,8 @@ namespace ams::spl::smc { constinit u8 g_async_result_buffer[1_KB]; u64 GenerateRandomU64() { - /* TODO: Can/should we make this cryptographically secure? */ u64 v = -1; - os::GenerateRandomBytes(std::addressof(v), sizeof(v)); + crypto::GenerateCryptographicallyRandomBytes(std::addressof(v), sizeof(v)); return v; } @@ -223,8 +222,7 @@ namespace ams::spl::smc { //} Result GenerateRandomBytes(void *out, size_t size) { - /* TODO: Cryptographically secure? */ - os::GenerateRandomBytes(out, size); + crypto::GenerateCryptographicallyRandomBytes(out, size); return smc::Result::Success; } diff --git a/libraries/libvapours/include/vapours/impl/compiler_impl.clang.hpp b/libraries/libvapours/include/vapours/impl/compiler_impl.clang.hpp index 5b7360d21..607366c7f 100644 --- a/libraries/libvapours/include/vapours/impl/compiler_impl.clang.hpp +++ b/libraries/libvapours/include/vapours/impl/compiler_impl.clang.hpp @@ -17,8 +17,17 @@ #include #include +#define AMS_PRAGMA(X) \ + _Pragma(#X) + #define AMS_PRAGMA_BEGIN_OPTIMIZE_O3() #define AMS_PRAGMA_BEGIN_OPTIMIZE_OS() #define AMS_PRAGMA_END_OPTIMIZE() +#define AMS_PRAGMA_BEGIN_PACK(n) \ + AMS_PRAGMA(pack(push, n)) + +#define AMS_PRAGMA_END_PACK() \ + AMS_PRAGMA(pack(pop)) + #define AMS_CONCEPTS_REQUIRES_IF_SUPPORTED(__EXPR__) diff --git a/libraries/libvapours/include/vapours/impl/compiler_impl.gcc.hpp b/libraries/libvapours/include/vapours/impl/compiler_impl.gcc.hpp index df99944ad..481045801 100644 --- a/libraries/libvapours/include/vapours/impl/compiler_impl.gcc.hpp +++ b/libraries/libvapours/include/vapours/impl/compiler_impl.gcc.hpp @@ -17,6 +17,9 @@ #include #include +#define AMS_PRAGMA(X) \ + _Pragma(#X) + #define AMS_PRAGMA_BEGIN_OPTIMIZE_O3() \ _Pragma("GCC push_options") \ _Pragma("GCC optimize (\"-O3\")") @@ -28,4 +31,10 @@ #define AMS_PRAGMA_END_OPTIMIZE() \ _Pragma("GCC pop_options") +#define AMS_PRAGMA_BEGIN_PACK(n) \ + AMS_PRAGMA(pack(push, n)) + +#define AMS_PRAGMA_END_PACK() \ + AMS_PRAGMA(pack(pop)) + #define AMS_CONCEPTS_REQUIRES_IF_SUPPORTED(__EXPR__) requires (__EXPR__) diff --git a/libraries/libvapours/include/vapours/svc/svc_definition_macro.hpp b/libraries/libvapours/include/vapours/svc/svc_definition_macro.hpp new file mode 100644 index 000000000..6376148ba --- /dev/null +++ b/libraries/libvapours/include/vapours/svc/svc_definition_macro.hpp @@ -0,0 +1,147 @@ +/* + * 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 + +#define AMS_SVC_FOREACH_DEFINITION_IMPL(HANDLER, NAMESPACE, INPUT, OUTPUT, INPTR, OUTPTR) \ + HANDLER(0x01, Result, SetHeapSize, OUTPUT(::ams::svc::Address, out_address), INPUT(::ams::svc::Size, size)) \ + HANDLER(0x02, Result, SetMemoryPermission, INPUT(::ams::svc::Address, address), INPUT(::ams::svc::Size, size), INPUT(::ams::svc::MemoryPermission, perm)) \ + HANDLER(0x03, Result, SetMemoryAttribute, INPUT(::ams::svc::Address, address), INPUT(::ams::svc::Size, size), INPUT(uint32_t, mask), INPUT(uint32_t, attr)) \ + HANDLER(0x04, Result, MapMemory, INPUT(::ams::svc::Address, dst_address), INPUT(::ams::svc::Address, src_address), INPUT(::ams::svc::Size, size)) \ + HANDLER(0x05, Result, UnmapMemory, INPUT(::ams::svc::Address, dst_address), INPUT(::ams::svc::Address, src_address), INPUT(::ams::svc::Size, size)) \ + HANDLER(0x06, Result, QueryMemory, OUTPTR(::ams::svc::NAMESPACE::MemoryInfo, out_memory_info), OUTPUT(::ams::svc::PageInfo, out_page_info), INPUT(::ams::svc::Address, address)) \ + HANDLER(0x07, void, ExitProcess) \ + HANDLER(0x08, Result, CreateThread, OUTPUT(::ams::svc::Handle, out_handle), INPUT(::ams::svc::ThreadFunc, func), INPUT(::ams::svc::Address, arg), INPUT(::ams::svc::Address, stack_bottom), INPUT(int32_t, priority), INPUT(int32_t, core_id)) \ + HANDLER(0x09, Result, StartThread, INPUT(::ams::svc::Handle, thread_handle)) \ + HANDLER(0x0A, void, ExitThread) \ + HANDLER(0x0B, void, SleepThread, INPUT(int64_t, ns)) \ + HANDLER(0x0C, Result, GetThreadPriority, OUTPUT(int32_t, out_priority), INPUT(::ams::svc::Handle, thread_handle)) \ + HANDLER(0x0D, Result, SetThreadPriority, INPUT(::ams::svc::Handle, thread_handle), INPUT(int32_t, priority)) \ + HANDLER(0x0E, Result, GetThreadCoreMask, OUTPUT(int32_t, out_core_id), OUTPUT(uint64_t, out_affinity_mask), INPUT(::ams::svc::Handle, thread_handle)) \ + HANDLER(0x0F, Result, SetThreadCoreMask, INPUT(::ams::svc::Handle, thread_handle), INPUT(int32_t, core_id), INPUT(uint64_t, affinity_mask)) \ + HANDLER(0x10, int32_t, GetCurrentProcessorNumber) \ + HANDLER(0x11, Result, SignalEvent, INPUT(::ams::svc::Handle, event_handle)) \ + HANDLER(0x12, Result, ClearEvent, INPUT(::ams::svc::Handle, event_handle)) \ + HANDLER(0x13, Result, MapSharedMemory, INPUT(::ams::svc::Handle, shmem_handle), INPUT(::ams::svc::Address, address), INPUT(::ams::svc::Size, size), INPUT(::ams::svc::MemoryPermission, map_perm)) \ + HANDLER(0x14, Result, UnmapSharedMemory, INPUT(::ams::svc::Handle, shmem_handle), INPUT(::ams::svc::Address, address), INPUT(::ams::svc::Size, size)) \ + HANDLER(0x15, Result, CreateTransferMemory, OUTPUT(::ams::svc::Handle, out_handle), INPUT(::ams::svc::Address, address), INPUT(::ams::svc::Size, size), INPUT(::ams::svc::MemoryPermission, map_perm)) \ + HANDLER(0x16, Result, CloseHandle, INPUT(::ams::svc::Handle, handle)) \ + HANDLER(0x17, Result, ResetSignal, INPUT(::ams::svc::Handle, handle)) \ + HANDLER(0x18, Result, WaitSynchronization, OUTPUT(int32_t, out_index), INPTR(::ams::svc::Handle, handles), INPUT(int32_t, num_handles), INPUT(int64_t, timeout_ns)) \ + HANDLER(0x19, Result, CancelSynchronization, INPUT(::ams::svc::Handle, handle)) \ + HANDLER(0x1A, Result, ArbitrateLock, INPUT(::ams::svc::Handle, thread_handle), INPUT(::ams::svc::Address, address), INPUT(uint32_t, tag)) \ + HANDLER(0x1B, Result, ArbitrateUnlock, INPUT(::ams::svc::Address, address)) \ + HANDLER(0x1C, Result, WaitProcessWideKeyAtomic, INPUT(::ams::svc::Address, address), INPUT(::ams::svc::Address, cv_key), INPUT(uint32_t, tag), INPUT(int64_t, timeout_ns)) \ + HANDLER(0x1D, void, SignalProcessWideKey, INPUT(::ams::svc::Address, cv_key), INPUT(int32_t, count)) \ + HANDLER(0x1E, int64_t, GetSystemTick) \ + HANDLER(0x1F, Result, ConnectToNamedPort, OUTPUT(::ams::svc::Handle, out_handle), INPTR(char, name)) \ + HANDLER(0x20, Result, SendSyncRequestLight, INPUT(::ams::svc::Handle, session_handle)) \ + HANDLER(0x21, Result, SendSyncRequest, INPUT(::ams::svc::Handle, session_handle)) \ + HANDLER(0x22, Result, SendSyncRequestWithUserBuffer, INPUT(::ams::svc::Address, message_buffer), INPUT(::ams::svc::Size, message_buffer_size), INPUT(::ams::svc::Handle, session_handle)) \ + HANDLER(0x23, Result, SendAsyncRequestWithUserBuffer, OUTPUT(::ams::svc::Handle, out_event_handle), INPUT(::ams::svc::Address, message_buffer), INPUT(::ams::svc::Size, message_buffer_size), INPUT(::ams::svc::Handle, session_handle)) \ + HANDLER(0x24, Result, GetProcessId, OUTPUT(uint64_t, out_process_id), INPUT(::ams::svc::Handle, process_handle)) \ + HANDLER(0x25, Result, GetThreadId, OUTPUT(uint64_t, out_thread_id), INPUT(::ams::svc::Handle, thread_handle)) \ + HANDLER(0x26, void, Break, INPUT(::ams::svc::BreakReason, break_reason), INPUT(::ams::svc::Address, arg), INPUT(::ams::svc::Size, size)) \ + HANDLER(0x27, Result, OutputDebugString, INPTR(char, debug_str), INPUT(::ams::svc::Size, len)) \ + HANDLER(0x28, void, ReturnFromException, INPUT(::ams::Result, result)) \ + HANDLER(0x29, Result, GetInfo, OUTPUT(uint64_t, out), INPUT(::ams::svc::InfoType, info_type), INPUT(::ams::svc::Handle, handle), INPUT(uint64_t, info_subtype)) \ + HANDLER(0x2A, void, FlushEntireDataCache) \ + HANDLER(0x2B, Result, FlushDataCache, INPUT(::ams::svc::Address, address), INPUT(::ams::svc::Size, size)) \ + HANDLER(0x2C, Result, MapPhysicalMemory, INPUT(::ams::svc::Address, address), INPUT(::ams::svc::Size, size)) \ + HANDLER(0x2D, Result, UnmapPhysicalMemory, INPUT(::ams::svc::Address, address), INPUT(::ams::svc::Size, size)) \ + HANDLER(0x2E, Result, GetDebugFutureThreadInfo, OUTPUT(::ams::svc::NAMESPACE::LastThreadContext, out_context), OUTPUT(uint64_t, thread_id), INPUT(::ams::svc::Handle, debug_handle), INPUT(int64_t, ns)) \ + HANDLER(0x2F, Result, GetLastThreadInfo, OUTPUT(::ams::svc::NAMESPACE::LastThreadContext, out_context), OUTPUT(::ams::svc::Address, out_tls_address), OUTPUT(uint32_t, out_flags)) \ + HANDLER(0x30, Result, GetResourceLimitLimitValue, OUTPUT(int64_t, out_limit_value), INPUT(::ams::svc::Handle, resource_limit_handle), INPUT(::ams::svc::LimitableResource, which)) \ + HANDLER(0x31, Result, GetResourceLimitCurrentValue, OUTPUT(int64_t, out_current_value), INPUT(::ams::svc::Handle, resource_limit_handle), INPUT(::ams::svc::LimitableResource, which)) \ + HANDLER(0x32, Result, SetThreadActivity, INPUT(::ams::svc::Handle, thread_handle), INPUT(::ams::svc::ThreadActivity, thread_activity)) \ + HANDLER(0x33, Result, GetThreadContext3, OUTPTR(::ams::svc::ThreadContext, out_context), INPUT(::ams::svc::Handle, thread_handle)) \ + HANDLER(0x34, Result, WaitForAddress, INPUT(::ams::svc::Address, address), INPUT(::ams::svc::ArbitrationType, arb_type), INPUT(int32_t, value), INPUT(int64_t, timeout_ns)) \ + HANDLER(0x35, Result, SignalToAddress, INPUT(::ams::svc::Address, address), INPUT(::ams::svc::SignalType, signal_type), INPUT(int32_t, value), INPUT(int32_t, count)) \ + HANDLER(0x36, void, SynchronizePreemptionState) \ + HANDLER(0x37, Result, GetResourceLimitPeakValue, OUTPUT(int64_t, out_peak_value), INPUT(::ams::svc::Handle, resource_limit_handle), INPUT(::ams::svc::LimitableResource, which)) \ + \ + HANDLER(0x39, Result, CreateIoPool, OUTPUT(::ams::svc::Handle, out_handle), INPUT(::ams::svc::IoPoolType, which)) \ + HANDLER(0x3A, Result, CreateIoRegion, OUTPUT(::ams::svc::Handle, out_handle), INPUT(::ams::svc::Handle, io_pool), INPUT(::ams::svc::PhysicalAddress, physical_address), INPUT(::ams::svc::Size, size), INPUT(::ams::svc::MemoryMapping, mapping), INPUT(::ams::svc::MemoryPermission, perm)) \ + \ + HANDLER(0x3C, void, KernelDebug, INPUT(::ams::svc::KernelDebugType, kern_debug_type), INPUT(uint64_t, arg0), INPUT(uint64_t, arg1), INPUT(uint64_t, arg2)) \ + HANDLER(0x3D, void, ChangeKernelTraceState, INPUT(::ams::svc::KernelTraceState, kern_trace_state)) \ + \ + HANDLER(0x40, Result, CreateSession, OUTPUT(::ams::svc::Handle, out_server_session_handle), OUTPUT(::ams::svc::Handle, out_client_session_handle), INPUT(bool, is_light), INPUT(::ams::svc::Address, name)) \ + HANDLER(0x41, Result, AcceptSession, OUTPUT(::ams::svc::Handle, out_handle), INPUT(::ams::svc::Handle, port)) \ + HANDLER(0x42, Result, ReplyAndReceiveLight, INPUT(::ams::svc::Handle, handle)) \ + HANDLER(0x43, Result, ReplyAndReceive, OUTPUT(int32_t, out_index), INPTR(::ams::svc::Handle, handles), INPUT(int32_t, num_handles), INPUT(::ams::svc::Handle, reply_target), INPUT(int64_t, timeout_ns)) \ + HANDLER(0x44, Result, ReplyAndReceiveWithUserBuffer, OUTPUT(int32_t, out_index), INPUT(::ams::svc::Address, message_buffer), INPUT(::ams::svc::Size, message_buffer_size), INPTR(::ams::svc::Handle, handles), INPUT(int32_t, num_handles), INPUT(::ams::svc::Handle, reply_target), INPUT(int64_t, timeout_ns)) \ + HANDLER(0x45, Result, CreateEvent, OUTPUT(::ams::svc::Handle, out_write_handle), OUTPUT(::ams::svc::Handle, out_read_handle)) \ + HANDLER(0x46, Result, MapIoRegion, INPUT(::ams::svc::Handle, io_region), INPUT(::ams::svc::Address, address), INPUT(::ams::svc::Size, size), INPUT(::ams::svc::MemoryPermission, perm)) \ + HANDLER(0x47, Result, UnmapIoRegion, INPUT(::ams::svc::Handle, io_region), INPUT(::ams::svc::Address, address), INPUT(::ams::svc::Size, size)) \ + HANDLER(0x48, Result, MapPhysicalMemoryUnsafe, INPUT(::ams::svc::Address, address), INPUT(::ams::svc::Size, size)) \ + HANDLER(0x49, Result, UnmapPhysicalMemoryUnsafe, INPUT(::ams::svc::Address, address), INPUT(::ams::svc::Size, size)) \ + HANDLER(0x4A, Result, SetUnsafeLimit, INPUT(::ams::svc::Size, limit)) \ + HANDLER(0x4B, Result, CreateCodeMemory, OUTPUT(::ams::svc::Handle, out_handle), INPUT(::ams::svc::Address, address), INPUT(::ams::svc::Size, size)) \ + HANDLER(0x4C, Result, ControlCodeMemory, INPUT(::ams::svc::Handle, code_memory_handle), INPUT(::ams::svc::CodeMemoryOperation, operation), INPUT(uint64_t, address), INPUT(uint64_t, size), INPUT(::ams::svc::MemoryPermission, perm)) \ + HANDLER(0x4D, void, SleepSystem) \ + HANDLER(0x4E, Result, ReadWriteRegister, OUTPUT(uint32_t, out_value), INPUT(::ams::svc::PhysicalAddress, address), INPUT(uint32_t, mask), INPUT(uint32_t, value)) \ + HANDLER(0x4F, Result, SetProcessActivity, INPUT(::ams::svc::Handle, process_handle), INPUT(::ams::svc::ProcessActivity, process_activity)) \ + HANDLER(0x50, Result, CreateSharedMemory, OUTPUT(::ams::svc::Handle, out_handle), INPUT(::ams::svc::Size, size), INPUT(::ams::svc::MemoryPermission, owner_perm), INPUT(::ams::svc::MemoryPermission, remote_perm)) \ + HANDLER(0x51, Result, MapTransferMemory, INPUT(::ams::svc::Handle, trmem_handle), INPUT(::ams::svc::Address, address), INPUT(::ams::svc::Size, size), INPUT(::ams::svc::MemoryPermission, owner_perm)) \ + HANDLER(0x52, Result, UnmapTransferMemory, INPUT(::ams::svc::Handle, trmem_handle), INPUT(::ams::svc::Address, address), INPUT(::ams::svc::Size, size)) \ + HANDLER(0x53, Result, CreateInterruptEvent, OUTPUT(::ams::svc::Handle, out_read_handle), INPUT(int32_t, interrupt_id), INPUT(::ams::svc::InterruptType, interrupt_type)) \ + HANDLER(0x54, Result, QueryPhysicalAddress, OUTPUT(::ams::svc::NAMESPACE::PhysicalMemoryInfo, out_info), INPUT(::ams::svc::Address, address)) \ + HANDLER(0x55, Result, QueryIoMapping, OUTPUT(::ams::svc::Address, out_address), OUTPUT(::ams::svc::Size, out_size), INPUT(::ams::svc::PhysicalAddress, physical_address), INPUT(::ams::svc::Size, size)) \ + HANDLER(0x56, Result, CreateDeviceAddressSpace, OUTPUT(::ams::svc::Handle, out_handle), INPUT(uint64_t, das_address), INPUT(uint64_t, das_size)) \ + HANDLER(0x57, Result, AttachDeviceAddressSpace, INPUT(::ams::svc::DeviceName, device_name), INPUT(::ams::svc::Handle, das_handle)) \ + HANDLER(0x58, Result, DetachDeviceAddressSpace, INPUT(::ams::svc::DeviceName, device_name), INPUT(::ams::svc::Handle, das_handle)) \ + HANDLER(0x59, Result, MapDeviceAddressSpaceByForce, INPUT(::ams::svc::Handle, das_handle), INPUT(::ams::svc::Handle, process_handle), INPUT(uint64_t, process_address), INPUT(::ams::svc::Size, size), INPUT(uint64_t, device_address), INPUT(::ams::svc::MemoryPermission, device_perm)) \ + HANDLER(0x5A, Result, MapDeviceAddressSpaceAligned, INPUT(::ams::svc::Handle, das_handle), INPUT(::ams::svc::Handle, process_handle), INPUT(uint64_t, process_address), INPUT(::ams::svc::Size, size), INPUT(uint64_t, device_address), INPUT(::ams::svc::MemoryPermission, device_perm)) \ + HANDLER(0x5C, Result, UnmapDeviceAddressSpace, INPUT(::ams::svc::Handle, das_handle), INPUT(::ams::svc::Handle, process_handle), INPUT(uint64_t, process_address), INPUT(::ams::svc::Size, size), INPUT(uint64_t, device_address)) \ + HANDLER(0x5D, Result, InvalidateProcessDataCache, INPUT(::ams::svc::Handle, process_handle), INPUT(uint64_t, address), INPUT(uint64_t, size)) \ + HANDLER(0x5E, Result, StoreProcessDataCache, INPUT(::ams::svc::Handle, process_handle), INPUT(uint64_t, address), INPUT(uint64_t, size)) \ + HANDLER(0x5F, Result, FlushProcessDataCache, INPUT(::ams::svc::Handle, process_handle), INPUT(uint64_t, address), INPUT(uint64_t, size)) \ + HANDLER(0x60, Result, DebugActiveProcess, OUTPUT(::ams::svc::Handle, out_handle), INPUT(uint64_t, process_id)) \ + HANDLER(0x61, Result, BreakDebugProcess, INPUT(::ams::svc::Handle, debug_handle)) \ + HANDLER(0x62, Result, TerminateDebugProcess, INPUT(::ams::svc::Handle, debug_handle)) \ + HANDLER(0x63, Result, GetDebugEvent, OUTPTR(::ams::svc::NAMESPACE::DebugEventInfo, out_info), INPUT(::ams::svc::Handle, debug_handle)) \ + HANDLER(0x64, Result, ContinueDebugEvent, INPUT(::ams::svc::Handle, debug_handle), INPUT(uint32_t, flags), INPTR(uint64_t, thread_ids), INPUT(int32_t, num_thread_ids)) \ + HANDLER(0x65, Result, GetProcessList, OUTPUT(int32_t, out_num_processes), OUTPTR(uint64_t, out_process_ids), INPUT(int32_t, max_out_count)) \ + HANDLER(0x66, Result, GetThreadList, OUTPUT(int32_t, out_num_threads), OUTPTR(uint64_t, out_thread_ids), INPUT(int32_t, max_out_count), INPUT(::ams::svc::Handle, debug_handle)) \ + HANDLER(0x67, Result, GetDebugThreadContext, OUTPTR(::ams::svc::ThreadContext, out_context), INPUT(::ams::svc::Handle, debug_handle), INPUT(uint64_t, thread_id), INPUT(uint32_t, context_flags)) \ + HANDLER(0x68, Result, SetDebugThreadContext, INPUT(::ams::svc::Handle, debug_handle), INPUT(uint64_t, thread_id), INPTR(::ams::svc::ThreadContext, context), INPUT(uint32_t, context_flags)) \ + HANDLER(0x69, Result, QueryDebugProcessMemory, OUTPTR(::ams::svc::NAMESPACE::MemoryInfo, out_memory_info), OUTPUT(::ams::svc::PageInfo, out_page_info), INPUT(::ams::svc::Handle, process_handle), INPUT(::ams::svc::Address, address)) \ + HANDLER(0x6A, Result, ReadDebugProcessMemory, INPUT(::ams::svc::Address, buffer), INPUT(::ams::svc::Handle, debug_handle), INPUT(::ams::svc::Address, address), INPUT(::ams::svc::Size, size)) \ + HANDLER(0x6B, Result, WriteDebugProcessMemory, INPUT(::ams::svc::Handle, debug_handle), INPUT(::ams::svc::Address, buffer), INPUT(::ams::svc::Address, address), INPUT(::ams::svc::Size, size)) \ + HANDLER(0x6C, Result, SetHardwareBreakPoint, INPUT(::ams::svc::HardwareBreakPointRegisterName, name), INPUT(uint64_t, flags), INPUT(uint64_t, value)) \ + HANDLER(0x6D, Result, GetDebugThreadParam, OUTPUT(uint64_t, out_64), OUTPUT(uint32_t, out_32), INPUT(::ams::svc::Handle, debug_handle), INPUT(uint64_t, thread_id), INPUT(::ams::svc::DebugThreadParam, param)) \ + \ + HANDLER(0x6F, Result, GetSystemInfo, OUTPUT(uint64_t, out), INPUT(::ams::svc::SystemInfoType, info_type), INPUT(::ams::svc::Handle, handle), INPUT(uint64_t, info_subtype)) \ + HANDLER(0x70, Result, CreatePort, OUTPUT(::ams::svc::Handle, out_server_handle), OUTPUT(::ams::svc::Handle, out_client_handle), INPUT(int32_t, max_sessions), INPUT(bool, is_light), INPUT(::ams::svc::Address, name)) \ + HANDLER(0x71, Result, ManageNamedPort, OUTPUT(::ams::svc::Handle, out_server_handle), INPTR(char, name), INPUT(int32_t, max_sessions)) \ + HANDLER(0x72, Result, ConnectToPort, OUTPUT(::ams::svc::Handle, out_handle), INPUT(::ams::svc::Handle, port)) \ + HANDLER(0x73, Result, SetProcessMemoryPermission, INPUT(::ams::svc::Handle, process_handle), INPUT(uint64_t, address), INPUT(uint64_t, size), INPUT(::ams::svc::MemoryPermission, perm)) \ + HANDLER(0x74, Result, MapProcessMemory, INPUT(::ams::svc::Address, dst_address), INPUT(::ams::svc::Handle, process_handle), INPUT(uint64_t, src_address), INPUT(::ams::svc::Size, size)) \ + HANDLER(0x75, Result, UnmapProcessMemory, INPUT(::ams::svc::Address, dst_address), INPUT(::ams::svc::Handle, process_handle), INPUT(uint64_t, src_address), INPUT(::ams::svc::Size, size)) \ + HANDLER(0x76, Result, QueryProcessMemory, OUTPTR(::ams::svc::NAMESPACE::MemoryInfo, out_memory_info), OUTPUT(::ams::svc::PageInfo, out_page_info), INPUT(::ams::svc::Handle, process_handle), INPUT(uint64_t, address)) \ + HANDLER(0x77, Result, MapProcessCodeMemory, INPUT(::ams::svc::Handle, process_handle), INPUT(uint64_t, dst_address), INPUT(uint64_t, src_address), INPUT(uint64_t, size)) \ + HANDLER(0x78, Result, UnmapProcessCodeMemory, INPUT(::ams::svc::Handle, process_handle), INPUT(uint64_t, dst_address), INPUT(uint64_t, src_address), INPUT(uint64_t, size)) \ + HANDLER(0x79, Result, CreateProcess, OUTPUT(::ams::svc::Handle, out_handle), INPTR(::ams::svc::NAMESPACE::CreateProcessParameter, parameters), INPTR(uint32_t, caps), INPUT(int32_t, num_caps)) \ + HANDLER(0x7A, Result, StartProcess, INPUT(::ams::svc::Handle, process_handle), INPUT(int32_t, priority), INPUT(int32_t, core_id), INPUT(uint64_t, main_thread_stack_size)) \ + HANDLER(0x7B, Result, TerminateProcess, INPUT(::ams::svc::Handle, process_handle)) \ + HANDLER(0x7C, Result, GetProcessInfo, OUTPUT(int64_t, out_info), INPUT(::ams::svc::Handle, process_handle), INPUT(::ams::svc::ProcessInfoType, info_type)) \ + HANDLER(0x7D, Result, CreateResourceLimit, OUTPUT(::ams::svc::Handle, out_handle)) \ + HANDLER(0x7E, Result, SetResourceLimitLimitValue, INPUT(::ams::svc::Handle, resource_limit_handle), INPUT(::ams::svc::LimitableResource, which), INPUT(int64_t, limit_value)) \ + HANDLER(0x7F, void, CallSecureMonitor, OUTPUT(::ams::svc::NAMESPACE::SecureMonitorArguments, args)) \ + \ + HANDLER(0x2E, Result, LegacyGetFutureThreadInfo, OUTPUT(::ams::svc::NAMESPACE::LastThreadContext, out_context), OUTPUT(::ams::svc::Address, out_tls_address), OUTPUT(uint32_t, out_flags), INPUT(int64_t, ns)) \ + HANDLER(0x55, Result, LegacyQueryIoMapping, OUTPUT(::ams::svc::Address, out_address), INPUT(::ams::svc::PhysicalAddress, physical_address), INPUT(::ams::svc::Size, size)) \ + HANDLER(0x64, Result, LegacyContinueDebugEvent, INPUT(::ams::svc::Handle, debug_handle), INPUT(uint32_t, flags), INPUT(uint64_t, thread_id)) diff --git a/libraries/libvapours/include/vapours/svc/svc_definitions.hpp b/libraries/libvapours/include/vapours/svc/svc_definitions.hpp index 784e30f75..ab7f12501 100644 --- a/libraries/libvapours/include/vapours/svc/svc_definitions.hpp +++ b/libraries/libvapours/include/vapours/svc/svc_definitions.hpp @@ -13,10 +13,10 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - #pragma once #include #include +#include #define AMS_SVC_KERN_INPUT_HANDLER(TYPE, NAME) TYPE NAME #define AMS_SVC_KERN_OUTPUT_HANDLER(TYPE, NAME) TYPE *NAME @@ -28,137 +28,6 @@ #define AMS_SVC_USER_INPTR_HANDLER(TYPE, NAME) ::ams::svc::UserPointer NAME #define AMS_SVC_USER_OUTPTR_HANDLER(TYPE, NAME) ::ams::svc::UserPointer NAME -#define AMS_SVC_FOREACH_DEFINITION_IMPL(HANDLER, NAMESPACE, INPUT, OUTPUT, INPTR, OUTPTR) \ - HANDLER(0x01, Result, SetHeapSize, OUTPUT(::ams::svc::Address, out_address), INPUT(::ams::svc::Size, size)) \ - HANDLER(0x02, Result, SetMemoryPermission, INPUT(::ams::svc::Address, address), INPUT(::ams::svc::Size, size), INPUT(::ams::svc::MemoryPermission, perm)) \ - HANDLER(0x03, Result, SetMemoryAttribute, INPUT(::ams::svc::Address, address), INPUT(::ams::svc::Size, size), INPUT(uint32_t, mask), INPUT(uint32_t, attr)) \ - HANDLER(0x04, Result, MapMemory, INPUT(::ams::svc::Address, dst_address), INPUT(::ams::svc::Address, src_address), INPUT(::ams::svc::Size, size)) \ - HANDLER(0x05, Result, UnmapMemory, INPUT(::ams::svc::Address, dst_address), INPUT(::ams::svc::Address, src_address), INPUT(::ams::svc::Size, size)) \ - HANDLER(0x06, Result, QueryMemory, OUTPTR(::ams::svc::NAMESPACE::MemoryInfo, out_memory_info), OUTPUT(::ams::svc::PageInfo, out_page_info), INPUT(::ams::svc::Address, address)) \ - HANDLER(0x07, void, ExitProcess) \ - HANDLER(0x08, Result, CreateThread, OUTPUT(::ams::svc::Handle, out_handle), INPUT(::ams::svc::ThreadFunc, func), INPUT(::ams::svc::Address, arg), INPUT(::ams::svc::Address, stack_bottom), INPUT(int32_t, priority), INPUT(int32_t, core_id)) \ - HANDLER(0x09, Result, StartThread, INPUT(::ams::svc::Handle, thread_handle)) \ - HANDLER(0x0A, void, ExitThread) \ - HANDLER(0x0B, void, SleepThread, INPUT(int64_t, ns)) \ - HANDLER(0x0C, Result, GetThreadPriority, OUTPUT(int32_t, out_priority), INPUT(::ams::svc::Handle, thread_handle)) \ - HANDLER(0x0D, Result, SetThreadPriority, INPUT(::ams::svc::Handle, thread_handle), INPUT(int32_t, priority)) \ - HANDLER(0x0E, Result, GetThreadCoreMask, OUTPUT(int32_t, out_core_id), OUTPUT(uint64_t, out_affinity_mask), INPUT(::ams::svc::Handle, thread_handle)) \ - HANDLER(0x0F, Result, SetThreadCoreMask, INPUT(::ams::svc::Handle, thread_handle), INPUT(int32_t, core_id), INPUT(uint64_t, affinity_mask)) \ - HANDLER(0x10, int32_t, GetCurrentProcessorNumber) \ - HANDLER(0x11, Result, SignalEvent, INPUT(::ams::svc::Handle, event_handle)) \ - HANDLER(0x12, Result, ClearEvent, INPUT(::ams::svc::Handle, event_handle)) \ - HANDLER(0x13, Result, MapSharedMemory, INPUT(::ams::svc::Handle, shmem_handle), INPUT(::ams::svc::Address, address), INPUT(::ams::svc::Size, size), INPUT(::ams::svc::MemoryPermission, map_perm)) \ - HANDLER(0x14, Result, UnmapSharedMemory, INPUT(::ams::svc::Handle, shmem_handle), INPUT(::ams::svc::Address, address), INPUT(::ams::svc::Size, size)) \ - HANDLER(0x15, Result, CreateTransferMemory, OUTPUT(::ams::svc::Handle, out_handle), INPUT(::ams::svc::Address, address), INPUT(::ams::svc::Size, size), INPUT(::ams::svc::MemoryPermission, map_perm)) \ - HANDLER(0x16, Result, CloseHandle, INPUT(::ams::svc::Handle, handle)) \ - HANDLER(0x17, Result, ResetSignal, INPUT(::ams::svc::Handle, handle)) \ - HANDLER(0x18, Result, WaitSynchronization, OUTPUT(int32_t, out_index), INPTR(::ams::svc::Handle, handles), INPUT(int32_t, num_handles), INPUT(int64_t, timeout_ns)) \ - HANDLER(0x19, Result, CancelSynchronization, INPUT(::ams::svc::Handle, handle)) \ - HANDLER(0x1A, Result, ArbitrateLock, INPUT(::ams::svc::Handle, thread_handle), INPUT(::ams::svc::Address, address), INPUT(uint32_t, tag)) \ - HANDLER(0x1B, Result, ArbitrateUnlock, INPUT(::ams::svc::Address, address)) \ - HANDLER(0x1C, Result, WaitProcessWideKeyAtomic, INPUT(::ams::svc::Address, address), INPUT(::ams::svc::Address, cv_key), INPUT(uint32_t, tag), INPUT(int64_t, timeout_ns)) \ - HANDLER(0x1D, void, SignalProcessWideKey, INPUT(::ams::svc::Address, cv_key), INPUT(int32_t, count)) \ - HANDLER(0x1E, int64_t, GetSystemTick) \ - HANDLER(0x1F, Result, ConnectToNamedPort, OUTPUT(::ams::svc::Handle, out_handle), INPTR(char, name)) \ - HANDLER(0x20, Result, SendSyncRequestLight, INPUT(::ams::svc::Handle, session_handle)) \ - HANDLER(0x21, Result, SendSyncRequest, INPUT(::ams::svc::Handle, session_handle)) \ - HANDLER(0x22, Result, SendSyncRequestWithUserBuffer, INPUT(::ams::svc::Address, message_buffer), INPUT(::ams::svc::Size, message_buffer_size), INPUT(::ams::svc::Handle, session_handle)) \ - HANDLER(0x23, Result, SendAsyncRequestWithUserBuffer, OUTPUT(::ams::svc::Handle, out_event_handle), INPUT(::ams::svc::Address, message_buffer), INPUT(::ams::svc::Size, message_buffer_size), INPUT(::ams::svc::Handle, session_handle)) \ - HANDLER(0x24, Result, GetProcessId, OUTPUT(uint64_t, out_process_id), INPUT(::ams::svc::Handle, process_handle)) \ - HANDLER(0x25, Result, GetThreadId, OUTPUT(uint64_t, out_thread_id), INPUT(::ams::svc::Handle, thread_handle)) \ - HANDLER(0x26, void, Break, INPUT(::ams::svc::BreakReason, break_reason), INPUT(::ams::svc::Address, arg), INPUT(::ams::svc::Size, size)) \ - HANDLER(0x27, Result, OutputDebugString, INPTR(char, debug_str), INPUT(::ams::svc::Size, len)) \ - HANDLER(0x28, void, ReturnFromException, INPUT(::ams::Result, result)) \ - HANDLER(0x29, Result, GetInfo, OUTPUT(uint64_t, out), INPUT(::ams::svc::InfoType, info_type), INPUT(::ams::svc::Handle, handle), INPUT(uint64_t, info_subtype)) \ - HANDLER(0x2A, void, FlushEntireDataCache) \ - HANDLER(0x2B, Result, FlushDataCache, INPUT(::ams::svc::Address, address), INPUT(::ams::svc::Size, size)) \ - HANDLER(0x2C, Result, MapPhysicalMemory, INPUT(::ams::svc::Address, address), INPUT(::ams::svc::Size, size)) \ - HANDLER(0x2D, Result, UnmapPhysicalMemory, INPUT(::ams::svc::Address, address), INPUT(::ams::svc::Size, size)) \ - HANDLER(0x2E, Result, GetDebugFutureThreadInfo, OUTPUT(::ams::svc::NAMESPACE::LastThreadContext, out_context), OUTPUT(uint64_t, thread_id), INPUT(::ams::svc::Handle, debug_handle), INPUT(int64_t, ns)) \ - HANDLER(0x2F, Result, GetLastThreadInfo, OUTPUT(::ams::svc::NAMESPACE::LastThreadContext, out_context), OUTPUT(::ams::svc::Address, out_tls_address), OUTPUT(uint32_t, out_flags)) \ - HANDLER(0x30, Result, GetResourceLimitLimitValue, OUTPUT(int64_t, out_limit_value), INPUT(::ams::svc::Handle, resource_limit_handle), INPUT(::ams::svc::LimitableResource, which)) \ - HANDLER(0x31, Result, GetResourceLimitCurrentValue, OUTPUT(int64_t, out_current_value), INPUT(::ams::svc::Handle, resource_limit_handle), INPUT(::ams::svc::LimitableResource, which)) \ - HANDLER(0x32, Result, SetThreadActivity, INPUT(::ams::svc::Handle, thread_handle), INPUT(::ams::svc::ThreadActivity, thread_activity)) \ - HANDLER(0x33, Result, GetThreadContext3, OUTPTR(::ams::svc::ThreadContext, out_context), INPUT(::ams::svc::Handle, thread_handle)) \ - HANDLER(0x34, Result, WaitForAddress, INPUT(::ams::svc::Address, address), INPUT(::ams::svc::ArbitrationType, arb_type), INPUT(int32_t, value), INPUT(int64_t, timeout_ns)) \ - HANDLER(0x35, Result, SignalToAddress, INPUT(::ams::svc::Address, address), INPUT(::ams::svc::SignalType, signal_type), INPUT(int32_t, value), INPUT(int32_t, count)) \ - HANDLER(0x36, void, SynchronizePreemptionState) \ - HANDLER(0x37, Result, GetResourceLimitPeakValue, OUTPUT(int64_t, out_peak_value), INPUT(::ams::svc::Handle, resource_limit_handle), INPUT(::ams::svc::LimitableResource, which)) \ - \ - HANDLER(0x39, Result, CreateIoPool, OUTPUT(::ams::svc::Handle, out_handle), INPUT(::ams::svc::IoPoolType, which)) \ - HANDLER(0x3A, Result, CreateIoRegion, OUTPUT(::ams::svc::Handle, out_handle), INPUT(::ams::svc::Handle, io_pool), INPUT(::ams::svc::PhysicalAddress, physical_address), INPUT(::ams::svc::Size, size), INPUT(::ams::svc::MemoryMapping, mapping), INPUT(::ams::svc::MemoryPermission, perm)) \ - \ - HANDLER(0x3C, void, KernelDebug, INPUT(::ams::svc::KernelDebugType, kern_debug_type), INPUT(uint64_t, arg0), INPUT(uint64_t, arg1), INPUT(uint64_t, arg2)) \ - HANDLER(0x3D, void, ChangeKernelTraceState, INPUT(::ams::svc::KernelTraceState, kern_trace_state)) \ - \ - HANDLER(0x40, Result, CreateSession, OUTPUT(::ams::svc::Handle, out_server_session_handle), OUTPUT(::ams::svc::Handle, out_client_session_handle), INPUT(bool, is_light), INPUT(::ams::svc::Address, name)) \ - HANDLER(0x41, Result, AcceptSession, OUTPUT(::ams::svc::Handle, out_handle), INPUT(::ams::svc::Handle, port)) \ - HANDLER(0x42, Result, ReplyAndReceiveLight, INPUT(::ams::svc::Handle, handle)) \ - HANDLER(0x43, Result, ReplyAndReceive, OUTPUT(int32_t, out_index), INPTR(::ams::svc::Handle, handles), INPUT(int32_t, num_handles), INPUT(::ams::svc::Handle, reply_target), INPUT(int64_t, timeout_ns)) \ - HANDLER(0x44, Result, ReplyAndReceiveWithUserBuffer, OUTPUT(int32_t, out_index), INPUT(::ams::svc::Address, message_buffer), INPUT(::ams::svc::Size, message_buffer_size), INPTR(::ams::svc::Handle, handles), INPUT(int32_t, num_handles), INPUT(::ams::svc::Handle, reply_target), INPUT(int64_t, timeout_ns)) \ - HANDLER(0x45, Result, CreateEvent, OUTPUT(::ams::svc::Handle, out_write_handle), OUTPUT(::ams::svc::Handle, out_read_handle)) \ - HANDLER(0x46, Result, MapIoRegion, INPUT(::ams::svc::Handle, io_region), INPUT(::ams::svc::Address, address), INPUT(::ams::svc::Size, size), INPUT(::ams::svc::MemoryPermission, perm)) \ - HANDLER(0x47, Result, UnmapIoRegion, INPUT(::ams::svc::Handle, io_region), INPUT(::ams::svc::Address, address), INPUT(::ams::svc::Size, size)) \ - HANDLER(0x48, Result, MapPhysicalMemoryUnsafe, INPUT(::ams::svc::Address, address), INPUT(::ams::svc::Size, size)) \ - HANDLER(0x49, Result, UnmapPhysicalMemoryUnsafe, INPUT(::ams::svc::Address, address), INPUT(::ams::svc::Size, size)) \ - HANDLER(0x4A, Result, SetUnsafeLimit, INPUT(::ams::svc::Size, limit)) \ - HANDLER(0x4B, Result, CreateCodeMemory, OUTPUT(::ams::svc::Handle, out_handle), INPUT(::ams::svc::Address, address), INPUT(::ams::svc::Size, size)) \ - HANDLER(0x4C, Result, ControlCodeMemory, INPUT(::ams::svc::Handle, code_memory_handle), INPUT(::ams::svc::CodeMemoryOperation, operation), INPUT(uint64_t, address), INPUT(uint64_t, size), INPUT(::ams::svc::MemoryPermission, perm)) \ - HANDLER(0x4D, void, SleepSystem) \ - HANDLER(0x4E, Result, ReadWriteRegister, OUTPUT(uint32_t, out_value), INPUT(::ams::svc::PhysicalAddress, address), INPUT(uint32_t, mask), INPUT(uint32_t, value)) \ - HANDLER(0x4F, Result, SetProcessActivity, INPUT(::ams::svc::Handle, process_handle), INPUT(::ams::svc::ProcessActivity, process_activity)) \ - HANDLER(0x50, Result, CreateSharedMemory, OUTPUT(::ams::svc::Handle, out_handle), INPUT(::ams::svc::Size, size), INPUT(::ams::svc::MemoryPermission, owner_perm), INPUT(::ams::svc::MemoryPermission, remote_perm)) \ - HANDLER(0x51, Result, MapTransferMemory, INPUT(::ams::svc::Handle, trmem_handle), INPUT(::ams::svc::Address, address), INPUT(::ams::svc::Size, size), INPUT(::ams::svc::MemoryPermission, owner_perm)) \ - HANDLER(0x52, Result, UnmapTransferMemory, INPUT(::ams::svc::Handle, trmem_handle), INPUT(::ams::svc::Address, address), INPUT(::ams::svc::Size, size)) \ - HANDLER(0x53, Result, CreateInterruptEvent, OUTPUT(::ams::svc::Handle, out_read_handle), INPUT(int32_t, interrupt_id), INPUT(::ams::svc::InterruptType, interrupt_type)) \ - HANDLER(0x54, Result, QueryPhysicalAddress, OUTPUT(::ams::svc::NAMESPACE::PhysicalMemoryInfo, out_info), INPUT(::ams::svc::Address, address)) \ - HANDLER(0x55, Result, QueryIoMapping, OUTPUT(::ams::svc::Address, out_address), OUTPUT(::ams::svc::Size, out_size), INPUT(::ams::svc::PhysicalAddress, physical_address), INPUT(::ams::svc::Size, size)) \ - HANDLER(0x56, Result, CreateDeviceAddressSpace, OUTPUT(::ams::svc::Handle, out_handle), INPUT(uint64_t, das_address), INPUT(uint64_t, das_size)) \ - HANDLER(0x57, Result, AttachDeviceAddressSpace, INPUT(::ams::svc::DeviceName, device_name), INPUT(::ams::svc::Handle, das_handle)) \ - HANDLER(0x58, Result, DetachDeviceAddressSpace, INPUT(::ams::svc::DeviceName, device_name), INPUT(::ams::svc::Handle, das_handle)) \ - HANDLER(0x59, Result, MapDeviceAddressSpaceByForce, INPUT(::ams::svc::Handle, das_handle), INPUT(::ams::svc::Handle, process_handle), INPUT(uint64_t, process_address), INPUT(::ams::svc::Size, size), INPUT(uint64_t, device_address), INPUT(::ams::svc::MemoryPermission, device_perm)) \ - HANDLER(0x5A, Result, MapDeviceAddressSpaceAligned, INPUT(::ams::svc::Handle, das_handle), INPUT(::ams::svc::Handle, process_handle), INPUT(uint64_t, process_address), INPUT(::ams::svc::Size, size), INPUT(uint64_t, device_address), INPUT(::ams::svc::MemoryPermission, device_perm)) \ - HANDLER(0x5C, Result, UnmapDeviceAddressSpace, INPUT(::ams::svc::Handle, das_handle), INPUT(::ams::svc::Handle, process_handle), INPUT(uint64_t, process_address), INPUT(::ams::svc::Size, size), INPUT(uint64_t, device_address)) \ - HANDLER(0x5D, Result, InvalidateProcessDataCache, INPUT(::ams::svc::Handle, process_handle), INPUT(uint64_t, address), INPUT(uint64_t, size)) \ - HANDLER(0x5E, Result, StoreProcessDataCache, INPUT(::ams::svc::Handle, process_handle), INPUT(uint64_t, address), INPUT(uint64_t, size)) \ - HANDLER(0x5F, Result, FlushProcessDataCache, INPUT(::ams::svc::Handle, process_handle), INPUT(uint64_t, address), INPUT(uint64_t, size)) \ - HANDLER(0x60, Result, DebugActiveProcess, OUTPUT(::ams::svc::Handle, out_handle), INPUT(uint64_t, process_id)) \ - HANDLER(0x61, Result, BreakDebugProcess, INPUT(::ams::svc::Handle, debug_handle)) \ - HANDLER(0x62, Result, TerminateDebugProcess, INPUT(::ams::svc::Handle, debug_handle)) \ - HANDLER(0x63, Result, GetDebugEvent, OUTPTR(::ams::svc::NAMESPACE::DebugEventInfo, out_info), INPUT(::ams::svc::Handle, debug_handle)) \ - HANDLER(0x64, Result, ContinueDebugEvent, INPUT(::ams::svc::Handle, debug_handle), INPUT(uint32_t, flags), INPTR(uint64_t, thread_ids), INPUT(int32_t, num_thread_ids)) \ - HANDLER(0x65, Result, GetProcessList, OUTPUT(int32_t, out_num_processes), OUTPTR(uint64_t, out_process_ids), INPUT(int32_t, max_out_count)) \ - HANDLER(0x66, Result, GetThreadList, OUTPUT(int32_t, out_num_threads), OUTPTR(uint64_t, out_thread_ids), INPUT(int32_t, max_out_count), INPUT(::ams::svc::Handle, debug_handle)) \ - HANDLER(0x67, Result, GetDebugThreadContext, OUTPTR(::ams::svc::ThreadContext, out_context), INPUT(::ams::svc::Handle, debug_handle), INPUT(uint64_t, thread_id), INPUT(uint32_t, context_flags)) \ - HANDLER(0x68, Result, SetDebugThreadContext, INPUT(::ams::svc::Handle, debug_handle), INPUT(uint64_t, thread_id), INPTR(::ams::svc::ThreadContext, context), INPUT(uint32_t, context_flags)) \ - HANDLER(0x69, Result, QueryDebugProcessMemory, OUTPTR(::ams::svc::NAMESPACE::MemoryInfo, out_memory_info), OUTPUT(::ams::svc::PageInfo, out_page_info), INPUT(::ams::svc::Handle, process_handle), INPUT(::ams::svc::Address, address)) \ - HANDLER(0x6A, Result, ReadDebugProcessMemory, INPUT(::ams::svc::Address, buffer), INPUT(::ams::svc::Handle, debug_handle), INPUT(::ams::svc::Address, address), INPUT(::ams::svc::Size, size)) \ - HANDLER(0x6B, Result, WriteDebugProcessMemory, INPUT(::ams::svc::Handle, debug_handle), INPUT(::ams::svc::Address, buffer), INPUT(::ams::svc::Address, address), INPUT(::ams::svc::Size, size)) \ - HANDLER(0x6C, Result, SetHardwareBreakPoint, INPUT(::ams::svc::HardwareBreakPointRegisterName, name), INPUT(uint64_t, flags), INPUT(uint64_t, value)) \ - HANDLER(0x6D, Result, GetDebugThreadParam, OUTPUT(uint64_t, out_64), OUTPUT(uint32_t, out_32), INPUT(::ams::svc::Handle, debug_handle), INPUT(uint64_t, thread_id), INPUT(::ams::svc::DebugThreadParam, param)) \ - \ - HANDLER(0x6F, Result, GetSystemInfo, OUTPUT(uint64_t, out), INPUT(::ams::svc::SystemInfoType, info_type), INPUT(::ams::svc::Handle, handle), INPUT(uint64_t, info_subtype)) \ - HANDLER(0x70, Result, CreatePort, OUTPUT(::ams::svc::Handle, out_server_handle), OUTPUT(::ams::svc::Handle, out_client_handle), INPUT(int32_t, max_sessions), INPUT(bool, is_light), INPUT(::ams::svc::Address, name)) \ - HANDLER(0x71, Result, ManageNamedPort, OUTPUT(::ams::svc::Handle, out_server_handle), INPTR(char, name), INPUT(int32_t, max_sessions)) \ - HANDLER(0x72, Result, ConnectToPort, OUTPUT(::ams::svc::Handle, out_handle), INPUT(::ams::svc::Handle, port)) \ - HANDLER(0x73, Result, SetProcessMemoryPermission, INPUT(::ams::svc::Handle, process_handle), INPUT(uint64_t, address), INPUT(uint64_t, size), INPUT(::ams::svc::MemoryPermission, perm)) \ - HANDLER(0x74, Result, MapProcessMemory, INPUT(::ams::svc::Address, dst_address), INPUT(::ams::svc::Handle, process_handle), INPUT(uint64_t, src_address), INPUT(::ams::svc::Size, size)) \ - HANDLER(0x75, Result, UnmapProcessMemory, INPUT(::ams::svc::Address, dst_address), INPUT(::ams::svc::Handle, process_handle), INPUT(uint64_t, src_address), INPUT(::ams::svc::Size, size)) \ - HANDLER(0x76, Result, QueryProcessMemory, OUTPTR(::ams::svc::NAMESPACE::MemoryInfo, out_memory_info), OUTPUT(::ams::svc::PageInfo, out_page_info), INPUT(::ams::svc::Handle, process_handle), INPUT(uint64_t, address)) \ - HANDLER(0x77, Result, MapProcessCodeMemory, INPUT(::ams::svc::Handle, process_handle), INPUT(uint64_t, dst_address), INPUT(uint64_t, src_address), INPUT(uint64_t, size)) \ - HANDLER(0x78, Result, UnmapProcessCodeMemory, INPUT(::ams::svc::Handle, process_handle), INPUT(uint64_t, dst_address), INPUT(uint64_t, src_address), INPUT(uint64_t, size)) \ - HANDLER(0x79, Result, CreateProcess, OUTPUT(::ams::svc::Handle, out_handle), INPTR(::ams::svc::NAMESPACE::CreateProcessParameter, parameters), INPTR(uint32_t, caps), INPUT(int32_t, num_caps)) \ - HANDLER(0x7A, Result, StartProcess, INPUT(::ams::svc::Handle, process_handle), INPUT(int32_t, priority), INPUT(int32_t, core_id), INPUT(uint64_t, main_thread_stack_size)) \ - HANDLER(0x7B, Result, TerminateProcess, INPUT(::ams::svc::Handle, process_handle)) \ - HANDLER(0x7C, Result, GetProcessInfo, OUTPUT(int64_t, out_info), INPUT(::ams::svc::Handle, process_handle), INPUT(::ams::svc::ProcessInfoType, info_type)) \ - HANDLER(0x7D, Result, CreateResourceLimit, OUTPUT(::ams::svc::Handle, out_handle)) \ - HANDLER(0x7E, Result, SetResourceLimitLimitValue, INPUT(::ams::svc::Handle, resource_limit_handle), INPUT(::ams::svc::LimitableResource, which), INPUT(int64_t, limit_value)) \ - HANDLER(0x7F, void, CallSecureMonitor, OUTPUT(::ams::svc::NAMESPACE::SecureMonitorArguments, args)) \ - \ - HANDLER(0x2E, Result, LegacyGetFutureThreadInfo, OUTPUT(::ams::svc::NAMESPACE::LastThreadContext, out_context), OUTPUT(::ams::svc::Address, out_tls_address), OUTPUT(uint32_t, out_flags), INPUT(int64_t, ns)) \ - HANDLER(0x55, Result, LegacyQueryIoMapping, OUTPUT(::ams::svc::Address, out_address), INPUT(::ams::svc::PhysicalAddress, physical_address), INPUT(::ams::svc::Size, size)) \ - HANDLER(0x64, Result, LegacyContinueDebugEvent, INPUT(::ams::svc::Handle, debug_handle), INPUT(uint32_t, flags), INPUT(uint64_t, thread_id)) - #define AMS_SVC_FOREACH_USER_DEFINITION(HANDLER, NAMESPACE) AMS_SVC_FOREACH_DEFINITION_IMPL(HANDLER, NAMESPACE, AMS_SVC_USER_INPUT_HANDLER, AMS_SVC_USER_OUTPUT_HANDLER, AMS_SVC_USER_INPTR_HANDLER, AMS_SVC_USER_OUTPTR_HANDLER) #define AMS_SVC_FOREACH_KERN_DEFINITION(HANDLER, NAMESPACE) AMS_SVC_FOREACH_DEFINITION_IMPL(HANDLER, NAMESPACE, AMS_SVC_KERN_INPUT_HANDLER, AMS_SVC_KERN_OUTPUT_HANDLER, AMS_SVC_KERN_INPTR_HANDLER, AMS_SVC_KERN_OUTPTR_HANDLER)