mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2024-12-18 00:12:03 +00:00
libs: add ongoing work to facilitate hactool rewrite
This commit is contained in:
parent
706b8492fd
commit
13697fa921
34 changed files with 1829 additions and 216 deletions
|
@ -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)
|
||||
|
|
|
@ -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<FsFileSystemQueryId>(query));
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
#include <stratosphere/fssrv/sf/fssrv_sf_ifile.hpp>
|
||||
#include <stratosphere/fssrv/sf/fssrv_sf_i_event_notifier.hpp>
|
||||
#include <stratosphere/fssrv/impl/fssrv_impl_program_index_map_info_manager.hpp>
|
||||
#include <stratosphere/fssrv/fssrv_access_control.hpp>
|
||||
#include <stratosphere/fssrv/impl/fssrv_access_control.hpp>
|
||||
#include <stratosphere/fssrv/fssrv_nca_crypto_configuration.hpp>
|
||||
#include <stratosphere/fssrv/fssrv_memory_resource_from_standard_allocator.hpp>
|
||||
#include <stratosphere/fssrv/fssrv_memory_resource_from_exp_heap.hpp>
|
||||
|
|
|
@ -47,6 +47,11 @@ namespace ams::fssrv::fscreator {
|
|||
virtual Result Create(std::shared_ptr<fs::IStorage> *out, std::shared_ptr<fssystem::IAsynchronousAccessSplitter> *out_splitter, fssystem::NcaFsHeaderReader *out_header_reader, std::shared_ptr<fssystem::NcaReader> nca_reader, s32 index) override;
|
||||
virtual Result CreateWithPatch(std::shared_ptr<fs::IStorage> *out, std::shared_ptr<fssystem::IAsynchronousAccessSplitter> *out_splitter, fssystem::NcaFsHeaderReader *out_header_reader, std::shared_ptr<fssystem::NcaReader> original_nca_reader, std::shared_ptr<fssystem::NcaReader> current_nca_reader, s32 index) override;
|
||||
virtual Result CreateNcaReader(std::shared_ptr<fssystem::NcaReader> *out, std::shared_ptr<fs::IStorage> storage) override;
|
||||
|
||||
#if !defined(ATMOSPHERE_BOARD_NINTENDO_NX)
|
||||
Result CreateWithContext(std::shared_ptr<fs::IStorage> *out, std::shared_ptr<fssystem::IAsynchronousAccessSplitter> *out_splitter, fssystem::NcaFsHeaderReader *out_header_reader, void *ctx, std::shared_ptr<fssystem::NcaReader> nca_reader, s32 index);
|
||||
Result CreateWithPatchWithContext(std::shared_ptr<fs::IStorage> *out, std::shared_ptr<fssystem::IAsynchronousAccessSplitter> *out_splitter, fssystem::NcaFsHeaderReader *out_header_reader, void *ctx, std::shared_ptr<fssystem::NcaReader> original_nca_reader, std::shared_ptr<fssystem::NcaReader> current_nca_reader, s32 index);
|
||||
#endif
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
#include <vapours.hpp>
|
||||
#include <stratosphere/ncm/ncm_ids.hpp>
|
||||
#include <stratosphere/fs/impl/fs_newable.hpp>
|
||||
#include <stratosphere/fssrv/impl/fssrv_access_control_bits.hpp>
|
||||
|
||||
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<u8>(read * (1 << 0) + write * (1 << 1)) };
|
||||
}
|
||||
};
|
||||
static_assert(std::is_trivial<Accessibility>::value);
|
||||
|
||||
class ContentOwnerInfo : public util::IntrusiveListBaseNode<ContentOwnerInfo>, 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<SaveDataOwnerInfo>, 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<AccessControlDataHeader>::value);
|
||||
static_assert(util::is_pod<AccessControlDescriptor>::value);
|
||||
|
||||
static constexpr u64 AllFlagBitsMask = ~static_cast<u64>(0);
|
||||
static constexpr u64 DebugFlagDisableMask = AllFlagBitsMask & ~util::ToUnderlying(AccessControlBits::Bits::Debug);
|
||||
private:
|
||||
using ContentOwnerInfoList = util::IntrusiveListBaseTraits<ContentOwnerInfo>::ListType;
|
||||
using SaveDataOwnerInfoList = util::IntrusiveListBaseTraits<SaveDataOwnerInfo>::ListType;
|
||||
private:
|
||||
util::optional<AccessControlBits> 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();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
#include <vapours.hpp>
|
||||
#include <stratosphere/ncm/ncm_ids.hpp>
|
||||
#include <stratosphere/fs/impl/fs_newable.hpp>
|
||||
#include <stratosphere/fssrv/impl/fssrv_access_control_bits.hpp>
|
||||
|
||||
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<typename... Args>
|
||||
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
|
||||
};
|
||||
|
||||
}
|
|
@ -19,6 +19,7 @@
|
|||
#include <stratosphere/fssystem/fssystem_utility.hpp>
|
||||
#include <stratosphere/fssystem/fssystem_speed_emulation_configuration.hpp>
|
||||
#include <stratosphere/fssystem/fssystem_external_code.hpp>
|
||||
#include <stratosphere/fssystem/fssystem_forwarding_file_system.hpp>
|
||||
#include <stratosphere/fssystem/fssystem_partition_file_system.hpp>
|
||||
#include <stratosphere/fssystem/fssystem_partition_file_system_meta.hpp>
|
||||
#include <stratosphere/fssystem/fssystem_thread_priority_changer.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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
#include <stratosphere/fs/fs_common.hpp>
|
||||
#include <stratosphere/fs/impl/fs_newable.hpp>
|
||||
#include <stratosphere/fs/fsa/fs_ifile.hpp>
|
||||
#include <stratosphere/fs/fsa/fs_idirectory.hpp>
|
||||
#include <stratosphere/fs/fsa/fs_ifilesystem.hpp>
|
||||
#include <stratosphere/fs/fs_query_range.hpp>
|
||||
|
||||
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<fs::fsa::IFile> m_base_file;
|
||||
public:
|
||||
ForwardingFile(std::unique_ptr<fs::fsa::IFile> 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<fs::fsa::IDirectory> m_base_dir;
|
||||
public:
|
||||
ForwardingDirectory(std::unique_ptr<fs::fsa::IDirectory> 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<fs::fsa::IFileSystem> m_base_fs;
|
||||
public:
|
||||
ForwardingFileSystem(std::shared_ptr<fs::fsa::IFileSystem> 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<fs::fsa::IFile> *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<fs::fsa::IDirectory> *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());
|
||||
}
|
||||
};
|
||||
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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<NcaBucketInfo>::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<Region>::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];
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <stratosphere.hpp>
|
||||
#include "../spl/impl/spl_ctr_drbg.hpp"
|
||||
#include <sys/random.h>
|
||||
|
||||
namespace ams::crypto {
|
||||
|
||||
namespace {
|
||||
|
||||
using Drbg = ::ams::spl::impl::CtrDrbg<crypto::AesEncryptor128, crypto::AesEncryptor128::KeySize, false>;
|
||||
|
||||
constinit util::TypedStorage<Drbg> 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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -13,11 +13,15 @@
|
|||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
#include <vapours.hpp>
|
||||
#include <stratosphere.hpp>
|
||||
#include <ntstatus.h>
|
||||
#include <bcrypt.h>
|
||||
|
||||
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<PUCHAR>(dst), dst_size, BCRYPT_USE_SYSTEM_PREFERRED_RNG);
|
||||
AMS_ABORT_UNLESS(status == STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
}
|
|
@ -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<size_t>(len) < sizeof(m_buffer));
|
||||
|
@ -112,20 +114,22 @@ namespace ams::fs::impl {
|
|||
|
||||
template<> const char *IdString::ToString<fs::ContentStorageId>(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<int>(id));
|
||||
using enum fs::ContentStorageId;
|
||||
ADD_ENUM_CASE(User);
|
||||
ADD_ENUM_CASE(System);
|
||||
ADD_ENUM_CASE(SdCard);
|
||||
default: return ToValueString(static_cast<int>(id));
|
||||
}
|
||||
}
|
||||
|
||||
template<> const char *IdString::ToString<fs::SaveDataSpaceId>(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<int>(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<int>(id));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -142,23 +146,24 @@ namespace ams::fs::impl {
|
|||
|
||||
template<> const char *IdString::ToString<fs::BisPartitionId>(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<int>(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<int>(id));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -172,10 +177,267 @@ namespace ams::fs::impl {
|
|||
|
||||
template<> const char *IdString::ToString<fs::GameCardPartition>(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<int>(id));
|
||||
using enum fs::GameCardPartition;
|
||||
ADD_ENUM_CASE(Update);
|
||||
ADD_ENUM_CASE(Normal);
|
||||
ADD_ENUM_CASE(Secure);
|
||||
default: return ToValueString(static_cast<int>(id));
|
||||
}
|
||||
}
|
||||
|
||||
template<> const char *IdString::ToString<fssystem::NcaHeader::ContentType>(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<int>(id));
|
||||
}
|
||||
}
|
||||
|
||||
template<> const char *IdString::ToString<fssystem::NcaHeader::DistributionType>(fssystem::NcaHeader::DistributionType id) {
|
||||
switch (id) {
|
||||
using enum fssystem::NcaHeader::DistributionType;
|
||||
ADD_ENUM_CASE(Download);
|
||||
ADD_ENUM_CASE(GameCard);
|
||||
default: return ToValueString(static_cast<int>(id));
|
||||
}
|
||||
}
|
||||
|
||||
template<> const char *IdString::ToString<fssystem::NcaHeader::EncryptionType>(fssystem::NcaHeader::EncryptionType id) {
|
||||
switch (id) {
|
||||
using enum fssystem::NcaHeader::EncryptionType;
|
||||
ADD_ENUM_CASE(Auto);
|
||||
ADD_ENUM_CASE(None);
|
||||
default: return ToValueString(static_cast<int>(id));
|
||||
}
|
||||
}
|
||||
|
||||
template<> const char *IdString::ToString<fssystem::NcaHeader::DecryptionKey>(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<int>(id));
|
||||
}
|
||||
}
|
||||
|
||||
template<> const char *IdString::ToString<fssystem::NcaFsHeader::FsType>(fssystem::NcaFsHeader::FsType id) {
|
||||
switch (id) {
|
||||
using enum fssystem::NcaFsHeader::FsType;
|
||||
ADD_ENUM_CASE(RomFs);
|
||||
ADD_ENUM_CASE(PartitionFs);
|
||||
default: return ToValueString(static_cast<int>(id));
|
||||
}
|
||||
}
|
||||
|
||||
template<> const char *IdString::ToString<fssystem::NcaFsHeader::EncryptionType>(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<int>(id));
|
||||
}
|
||||
}
|
||||
|
||||
template<> const char *IdString::ToString<fssystem::NcaFsHeader::HashType>(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<int>(id));
|
||||
}
|
||||
}
|
||||
|
||||
template<> const char *IdString::ToString<fssrv::impl::AccessControlBits::Bits>(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>(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<int>(id));
|
||||
}
|
||||
}
|
||||
|
||||
template<> const char *IdString::ToString<fssrv::impl::AccessControl::OperationType>(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<int>(id));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <stratosphere.hpp>
|
||||
#include <exosphere/pkg1.hpp>
|
||||
|
||||
namespace ams::fs::impl {
|
||||
|
||||
#define ADD_ENUM_CASE(v) case v: return #v
|
||||
|
||||
template<> const char *IdString::ToString<pkg1::KeyGeneration>(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";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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<char *>(g_device_buffer), DeviceBufferSize, reinterpret_cast<char *>(g_device_work_buffer), DeviceWorkBufferRequiredSize);
|
||||
|
||||
/* Setup fscreators/interfaces. */
|
||||
g_local_fs_creator.emplace(true);
|
||||
g_subdir_fs_creator.emplace();
|
||||
|
|
|
@ -60,4 +60,36 @@ namespace ams::fssrv::fscreator {
|
|||
return ResultSuccess();
|
||||
}
|
||||
|
||||
#if !defined(ATMOSPHERE_BOARD_NINTENDO_NX)
|
||||
Result StorageOnNcaCreator::CreateWithContext(std::shared_ptr<fs::IStorage> *out, std::shared_ptr<fssystem::IAsynchronousAccessSplitter> *out_splitter, fssystem::NcaFsHeaderReader *out_header_reader, void *ctx, std::shared_ptr<fssystem::NcaReader> 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<fs::IStorage> storage;
|
||||
std::shared_ptr<fssystem::IAsynchronousAccessSplitter> splitter;
|
||||
R_TRY(nca_fs_driver.OpenStorageWithContext(std::addressof(storage), std::addressof(splitter), out_header_reader, index, static_cast<fssystem::NcaFileSystemDriver::StorageContext *>(ctx)));
|
||||
|
||||
/* Set the out storage. */
|
||||
*out = std::move(storage);
|
||||
*out_splitter = std::move(splitter);
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result StorageOnNcaCreator::CreateWithPatchWithContext(std::shared_ptr<fs::IStorage> *out, std::shared_ptr<fssystem::IAsynchronousAccessSplitter> *out_splitter, fssystem::NcaFsHeaderReader *out_header_reader, void *ctx, std::shared_ptr<fssystem::NcaReader> original_nca_reader, std::shared_ptr<fssystem::NcaReader> 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<fs::IStorage> storage;
|
||||
std::shared_ptr<fssystem::IAsynchronousAccessSplitter> splitter;
|
||||
R_TRY(nca_fs_driver.OpenStorageWithContext(std::addressof(storage), std::addressof(splitter), out_header_reader, index, static_cast<fssystem::NcaFileSystemDriver::StorageContext *>(ctx)));
|
||||
|
||||
/* Set the out storage. */
|
||||
*out = std::move(storage);
|
||||
*out_splitter = std::move(splitter);
|
||||
return ResultSuccess();
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
|
|
@ -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<s64>(sizeof(AccessControlDataHeader)));
|
||||
AMS_ABORT_UNLESS(desc_size >= static_cast<s64>(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<s64>(sizeof(AccessControlDescriptor) + desc.content_owner_id_count * sizeof(u64)));
|
||||
|
||||
/* Read out the content data owner infos. */
|
||||
uintptr_t data_start = reinterpret_cast<uintptr_t>(fac_data);
|
||||
uintptr_t desc_start = reinterpret_cast<uintptr_t>(fac_desc);
|
||||
if (data.content_owner_infos_size > 0) {
|
||||
/* Get the count. */
|
||||
const u32 num_content_owner_infos = util::LoadLittleEndian<u32>(reinterpret_cast<u32 *>(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<u64>(reinterpret_cast<u64 *>(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<u64>(reinterpret_cast<u64 *>(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<s64>(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<u32>(reinterpret_cast<u32 *>(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 *>(accessibility_start + i * sizeof(Accessibility));
|
||||
const u64 id = util::LoadLittleEndian<u64>(reinterpret_cast<u64 *>(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<u64>(reinterpret_cast<u64 *>(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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -19,7 +19,9 @@
|
|||
#if defined(ATMOSPHERE_OS_LINUX)
|
||||
#include <unistd.h>
|
||||
#elif defined(ATMOSPHERE_OS_MACOS)
|
||||
#include <mach-o/dyld.h>
|
||||
#include <unistd.h>
|
||||
#include <mach-o/dyld.h>
|
||||
#include <sys/param.h>
|
||||
#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<int>(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<int>(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<int>(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<int>(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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -19,5 +19,6 @@
|
|||
namespace ams::fssrv::impl {
|
||||
|
||||
const char *GetExecutionDirectoryPath();
|
||||
const char *GetWorkingDirectoryPath();
|
||||
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ namespace ams::fssystem {
|
|||
|
||||
template<typename BasePointer>
|
||||
AesCtrStorage<BasePointer>::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);
|
||||
|
|
|
@ -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<s64>(patch_info.aes_ctr_ex_size), NcaHeader::XtsBlockSize);
|
||||
R_UNLESS(meta_offset + meta_size <= base_size, fs::ResultNcaBaseStorageOutOfRangeB());
|
||||
|
||||
/* Create the encrypted storage. */
|
||||
|
|
|
@ -45,6 +45,14 @@ namespace ams::fssystem {
|
|||
/* ... */
|
||||
}
|
||||
|
||||
void Dump(const void *s, size_t size) {
|
||||
const u8 *s8 = static_cast<const u8 *>(s);
|
||||
for (size_t i = 0; i < size; ++i) {
|
||||
printf("%02X", s8[i]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
Result NcaReader::Initialize(std::shared_ptr<fs::IStorage> 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<s32>(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();
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -57,7 +57,7 @@ namespace ams::fssystem::save {
|
|||
|
||||
/* Calculate block shift. */
|
||||
m_verification_block_shift = ILog2(static_cast<u32>(verif_block_size));
|
||||
AMS_ASSERT(static_cast<size_t>(1ull << m_verification_block_size) == m_verification_block_size);
|
||||
AMS_ASSERT(static_cast<size_t>(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)));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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<u32>(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<s64>::max(), src, src_size));
|
||||
R_TRY(m_data_storage.OperateRange(dst, dst_size, op_id, offset, size, src, src_size));
|
||||
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
|
|
@ -32,12 +32,14 @@ namespace ams::spl::impl {
|
|||
using Drbg = CtrDrbg<crypto::AesEncryptor128, AesKeySize, false>;
|
||||
|
||||
/* 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<size_t>(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<uintptr_t>(g_work_buffer);
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -17,8 +17,17 @@
|
|||
#include <vapours/includes.hpp>
|
||||
#include <vapours/defines.hpp>
|
||||
|
||||
#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__)
|
||||
|
|
|
@ -17,6 +17,9 @@
|
|||
#include <vapours/includes.hpp>
|
||||
#include <vapours/defines.hpp>
|
||||
|
||||
#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__)
|
||||
|
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#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))
|
|
@ -13,10 +13,10 @@
|
|||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <vapours/svc/svc_common.hpp>
|
||||
#include <vapours/svc/svc_types.hpp>
|
||||
#include <vapours/svc/svc_definition_macro.hpp>
|
||||
|
||||
#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<const TYPE *> NAME
|
||||
#define AMS_SVC_USER_OUTPTR_HANDLER(TYPE, NAME) ::ams::svc::UserPointer<TYPE *> 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)
|
||||
|
||||
|
|
Loading…
Reference in a new issue