diff options
Diffstat (limited to 'src/core')
| -rw-r--r-- | src/core/crypto/aes_util.cpp | 21 | ||||
| -rw-r--r-- | src/core/crypto/aes_util.h | 9 | ||||
| -rw-r--r-- | src/core/crypto/ctr_encryption_layer.cpp | 9 | ||||
| -rw-r--r-- | src/core/crypto/ctr_encryption_layer.h | 9 | ||||
| -rw-r--r-- | src/core/crypto/key_manager.cpp | 10 | ||||
| -rw-r--r-- | src/core/crypto/partition_data_manager.cpp | 211 | ||||
| -rw-r--r-- | src/core/file_sys/content_archive.cpp | 7 | ||||
| -rw-r--r-- | src/core/file_sys/nca_patch.cpp | 3 | ||||
| -rw-r--r-- | src/core/file_sys/system_archive/mii_model.cpp | 18 | ||||
| -rw-r--r-- | src/core/file_sys/system_archive/ng_word.cpp | 42 | ||||
| -rw-r--r-- | src/core/file_sys/system_archive/time_zone_binary.cpp | 9 | ||||
| -rw-r--r-- | src/core/file_sys/vfs_vector.h | 13 | ||||
| -rw-r--r-- | src/core/hle/ipc_helpers.h | 4 | ||||
| -rw-r--r-- | src/core/hle/kernel/address_arbiter.cpp | 2 | ||||
| -rw-r--r-- | src/core/hle/kernel/memory/page_table.cpp | 1 | ||||
| -rw-r--r-- | src/core/hle/kernel/scheduler.cpp | 31 | ||||
| -rw-r--r-- | src/core/hle/service/am/am.cpp | 6 | ||||
| -rw-r--r-- | src/core/hle/service/am/am.h | 7 | ||||
| -rw-r--r-- | src/core/hle/service/sm/sm.h | 2 | ||||
| -rw-r--r-- | src/core/loader/loader.cpp | 2 | ||||
| -rw-r--r-- | src/core/memory/cheat_engine.cpp | 24 | 
21 files changed, 245 insertions, 195 deletions
diff --git a/src/core/crypto/aes_util.cpp b/src/core/crypto/aes_util.cpp index 4be76bb43..330996b24 100644 --- a/src/core/crypto/aes_util.cpp +++ b/src/core/crypto/aes_util.cpp @@ -2,6 +2,7 @@  // Licensed under GPLv2 or any later version  // Refer to the license.txt file included. +#include <array>  #include <mbedtls/cipher.h>  #include "common/assert.h"  #include "common/logging/log.h" @@ -10,8 +11,10 @@  namespace Core::Crypto {  namespace { -std::vector<u8> CalculateNintendoTweak(std::size_t sector_id) { -    std::vector<u8> out(0x10); +using NintendoTweak = std::array<u8, 16>; + +NintendoTweak CalculateNintendoTweak(std::size_t sector_id) { +    NintendoTweak out{};      for (std::size_t i = 0xF; i <= 0xF; --i) {          out[i] = sector_id & 0xFF;          sector_id >>= 8; @@ -64,13 +67,6 @@ AESCipher<Key, KeySize>::~AESCipher() {  }  template <typename Key, std::size_t KeySize> -void AESCipher<Key, KeySize>::SetIV(std::vector<u8> iv) { -    ASSERT_MSG((mbedtls_cipher_set_iv(&ctx->encryption_context, iv.data(), iv.size()) || -                mbedtls_cipher_set_iv(&ctx->decryption_context, iv.data(), iv.size())) == 0, -               "Failed to set IV on mbedtls ciphers."); -} - -template <typename Key, std::size_t KeySize>  void AESCipher<Key, KeySize>::Transcode(const u8* src, std::size_t size, u8* dest, Op op) const {      auto* const context = op == Op::Encrypt ? &ctx->encryption_context : &ctx->decryption_context; @@ -124,6 +120,13 @@ void AESCipher<Key, KeySize>::XTSTranscode(const u8* src, std::size_t size, u8*      }  } +template <typename Key, std::size_t KeySize> +void AESCipher<Key, KeySize>::SetIVImpl(const u8* data, std::size_t size) { +    ASSERT_MSG((mbedtls_cipher_set_iv(&ctx->encryption_context, data, size) || +                mbedtls_cipher_set_iv(&ctx->decryption_context, data, size)) == 0, +               "Failed to set IV on mbedtls ciphers."); +} +  template class AESCipher<Key128>;  template class AESCipher<Key256>;  } // namespace Core::Crypto diff --git a/src/core/crypto/aes_util.h b/src/core/crypto/aes_util.h index edc4ab910..e2a304186 100644 --- a/src/core/crypto/aes_util.h +++ b/src/core/crypto/aes_util.h @@ -6,7 +6,6 @@  #include <memory>  #include <type_traits> -#include <vector>  #include "common/common_types.h"  #include "core/file_sys/vfs.h" @@ -32,10 +31,12 @@ class AESCipher {  public:      AESCipher(Key key, Mode mode); -      ~AESCipher(); -    void SetIV(std::vector<u8> iv); +    template <typename ContiguousContainer> +    void SetIV(const ContiguousContainer& container) { +        SetIVImpl(std::data(container), std::size(container)); +    }      template <typename Source, typename Dest>      void Transcode(const Source* src, std::size_t size, Dest* dest, Op op) const { @@ -59,6 +60,8 @@ public:                        std::size_t sector_size, Op op);  private: +    void SetIVImpl(const u8* data, std::size_t size); +      std::unique_ptr<CipherContext> ctx;  };  } // namespace Core::Crypto diff --git a/src/core/crypto/ctr_encryption_layer.cpp b/src/core/crypto/ctr_encryption_layer.cpp index 902841c77..5c84bb0a4 100644 --- a/src/core/crypto/ctr_encryption_layer.cpp +++ b/src/core/crypto/ctr_encryption_layer.cpp @@ -2,6 +2,7 @@  // Licensed under GPLv2 or any later version  // Refer to the license.txt file included. +#include <algorithm>  #include <cstring>  #include "common/assert.h"  #include "core/crypto/ctr_encryption_layer.h" @@ -10,8 +11,7 @@ namespace Core::Crypto {  CTREncryptionLayer::CTREncryptionLayer(FileSys::VirtualFile base_, Key128 key_,                                         std::size_t base_offset) -    : EncryptionLayer(std::move(base_)), base_offset(base_offset), cipher(key_, Mode::CTR), -      iv(16, 0) {} +    : EncryptionLayer(std::move(base_)), base_offset(base_offset), cipher(key_, Mode::CTR) {}  std::size_t CTREncryptionLayer::Read(u8* data, std::size_t length, std::size_t offset) const {      if (length == 0) @@ -39,9 +39,8 @@ std::size_t CTREncryptionLayer::Read(u8* data, std::size_t length, std::size_t o      return read + Read(data + read, length - read, offset + read);  } -void CTREncryptionLayer::SetIV(const std::vector<u8>& iv_) { -    const auto length = std::min(iv_.size(), iv.size()); -    iv.assign(iv_.cbegin(), iv_.cbegin() + length); +void CTREncryptionLayer::SetIV(const IVData& iv_) { +    iv = iv_;  }  void CTREncryptionLayer::UpdateIV(std::size_t offset) const { diff --git a/src/core/crypto/ctr_encryption_layer.h b/src/core/crypto/ctr_encryption_layer.h index a7bf810f4..a2429f001 100644 --- a/src/core/crypto/ctr_encryption_layer.h +++ b/src/core/crypto/ctr_encryption_layer.h @@ -4,7 +4,8 @@  #pragma once -#include <vector> +#include <array> +  #include "core/crypto/aes_util.h"  #include "core/crypto/encryption_layer.h"  #include "core/crypto/key_manager.h" @@ -14,18 +15,20 @@ namespace Core::Crypto {  // Sits on top of a VirtualFile and provides CTR-mode AES decription.  class CTREncryptionLayer : public EncryptionLayer {  public: +    using IVData = std::array<u8, 16>; +      CTREncryptionLayer(FileSys::VirtualFile base, Key128 key, std::size_t base_offset);      std::size_t Read(u8* data, std::size_t length, std::size_t offset) const override; -    void SetIV(const std::vector<u8>& iv); +    void SetIV(const IVData& iv);  private:      std::size_t base_offset;      // Must be mutable as operations modify cipher contexts.      mutable AESCipher<Key128> cipher; -    mutable std::vector<u8> iv; +    mutable IVData iv{};      void UpdateIV(std::size_t offset) const;  }; diff --git a/src/core/crypto/key_manager.cpp b/src/core/crypto/key_manager.cpp index f87fe0abc..c09f7ad41 100644 --- a/src/core/crypto/key_manager.cpp +++ b/src/core/crypto/key_manager.cpp @@ -40,12 +40,14 @@ namespace Core::Crypto {  constexpr u64 CURRENT_CRYPTO_REVISION = 0x5;  constexpr u64 FULL_TICKET_SIZE = 0x400; -using namespace Common; +using Common::AsArray; -const std::array<SHA256Hash, 2> eticket_source_hashes{ -    "B71DB271DC338DF380AA2C4335EF8873B1AFD408E80B3582D8719FC81C5E511C"_array32, // eticket_rsa_kek_source -    "E8965A187D30E57869F562D04383C996DE487BBA5761363D2D4D32391866A85C"_array32, // eticket_rsa_kekek_source +// clang-format off +constexpr std::array eticket_source_hashes{ +    AsArray("B71DB271DC338DF380AA2C4335EF8873B1AFD408E80B3582D8719FC81C5E511C"), // eticket_rsa_kek_source +    AsArray("E8965A187D30E57869F562D04383C996DE487BBA5761363D2D4D32391866A85C"), // eticket_rsa_kekek_source  }; +// clang-format on  const std::map<std::pair<S128KeyType, u64>, std::string> KEYS_VARIABLE_LENGTH{      {{S128KeyType::Master, 0}, "master_key_"}, diff --git a/src/core/crypto/partition_data_manager.cpp b/src/core/crypto/partition_data_manager.cpp index 7ed71ac3a..3e96f7516 100644 --- a/src/core/crypto/partition_data_manager.cpp +++ b/src/core/crypto/partition_data_manager.cpp @@ -27,7 +27,7 @@  #include "core/file_sys/vfs_offset.h"  #include "core/file_sys/vfs_vector.h" -using namespace Common; +using Common::AsArray;  namespace Core::Crypto { @@ -47,105 +47,123 @@ struct Package2Header {  };  static_assert(sizeof(Package2Header) == 0x200, "Package2Header has incorrect size."); -const std::array<SHA256Hash, 0x10> source_hashes{ -    "B24BD293259DBC7AC5D63F88E60C59792498E6FC5443402C7FFE87EE8B61A3F0"_array32, // keyblob_mac_key_source -    "7944862A3A5C31C6720595EFD302245ABD1B54CCDCF33000557681E65C5664A4"_array32, // master_key_source -    "21E2DF100FC9E094DB51B47B9B1D6E94ED379DB8B547955BEF8FE08D8DD35603"_array32, // package2_key_source -    "FC02B9D37B42D7A1452E71444F1F700311D1132E301A83B16062E72A78175085"_array32, // aes_kek_generation_source -    "FBD10056999EDC7ACDB96098E47E2C3606230270D23281E671F0F389FC5BC585"_array32, // aes_key_generation_source -    "C48B619827986C7F4E3081D59DB2B460C84312650E9A8E6B458E53E8CBCA4E87"_array32, // titlekek_source -    "04AD66143C726B2A139FB6B21128B46F56C553B2B3887110304298D8D0092D9E"_array32, // key_area_key_application_source -    "FD434000C8FF2B26F8E9A9D2D2C12F6BE5773CBB9DC86300E1BD99F8EA33A417"_array32, // key_area_key_ocean_source -    "1F17B1FD51AD1C2379B58F152CA4912EC2106441E51722F38700D5937A1162F7"_array32, // key_area_key_system_source -    "6B2ED877C2C52334AC51E59ABFA7EC457F4A7D01E46291E9F2EAA45F011D24B7"_array32, // sd_card_kek_source -    "D482743563D3EA5DCDC3B74E97C9AC8A342164FA041A1DC80F17F6D31E4BC01C"_array32, // sd_card_save_key_source -    "2E751CECF7D93A2B957BD5FFCB082FD038CC2853219DD3092C6DAB9838F5A7CC"_array32, // sd_card_nca_key_source -    "1888CAED5551B3EDE01499E87CE0D86827F80820EFB275921055AA4E2ABDFFC2"_array32, // header_kek_source -    "8F783E46852DF6BE0BA4E19273C4ADBAEE16380043E1B8C418C4089A8BD64AA6"_array32, // header_key_source -    "D1757E52F1AE55FA882EC690BC6F954AC46A83DC22F277F8806BD55577C6EED7"_array32, // rsa_kek_seed3 -    "FC02B9D37B42D7A1452E71444F1F700311D1132E301A83B16062E72A78175085"_array32, // rsa_kek_mask0 +// clang-format off +constexpr std::array source_hashes{ +    AsArray("B24BD293259DBC7AC5D63F88E60C59792498E6FC5443402C7FFE87EE8B61A3F0"), // keyblob_mac_key_source +    AsArray("7944862A3A5C31C6720595EFD302245ABD1B54CCDCF33000557681E65C5664A4"), // master_key_source +    AsArray("21E2DF100FC9E094DB51B47B9B1D6E94ED379DB8B547955BEF8FE08D8DD35603"), // package2_key_source +    AsArray("FC02B9D37B42D7A1452E71444F1F700311D1132E301A83B16062E72A78175085"), // aes_kek_generation_source +    AsArray("FBD10056999EDC7ACDB96098E47E2C3606230270D23281E671F0F389FC5BC585"), // aes_key_generation_source +    AsArray("C48B619827986C7F4E3081D59DB2B460C84312650E9A8E6B458E53E8CBCA4E87"), // titlekek_source +    AsArray("04AD66143C726B2A139FB6B21128B46F56C553B2B3887110304298D8D0092D9E"), // key_area_key_application_source +    AsArray("FD434000C8FF2B26F8E9A9D2D2C12F6BE5773CBB9DC86300E1BD99F8EA33A417"), // key_area_key_ocean_source +    AsArray("1F17B1FD51AD1C2379B58F152CA4912EC2106441E51722F38700D5937A1162F7"), // key_area_key_system_source +    AsArray("6B2ED877C2C52334AC51E59ABFA7EC457F4A7D01E46291E9F2EAA45F011D24B7"), // sd_card_kek_source +    AsArray("D482743563D3EA5DCDC3B74E97C9AC8A342164FA041A1DC80F17F6D31E4BC01C"), // sd_card_save_key_source +    AsArray("2E751CECF7D93A2B957BD5FFCB082FD038CC2853219DD3092C6DAB9838F5A7CC"), // sd_card_nca_key_source +    AsArray("1888CAED5551B3EDE01499E87CE0D86827F80820EFB275921055AA4E2ABDFFC2"), // header_kek_source +    AsArray("8F783E46852DF6BE0BA4E19273C4ADBAEE16380043E1B8C418C4089A8BD64AA6"), // header_key_source +    AsArray("D1757E52F1AE55FA882EC690BC6F954AC46A83DC22F277F8806BD55577C6EED7"), // rsa_kek_seed3 +    AsArray("FC02B9D37B42D7A1452E71444F1F700311D1132E301A83B16062E72A78175085"), // rsa_kek_mask0  }; - -const std::array<SHA256Hash, 0x20> keyblob_source_hashes{ -    "8A06FE274AC491436791FDB388BCDD3AB9943BD4DEF8094418CDAC150FD73786"_array32, // keyblob_key_source_00 -    "2D5CAEB2521FEF70B47E17D6D0F11F8CE2C1E442A979AD8035832C4E9FBCCC4B"_array32, // keyblob_key_source_01 -    "61C5005E713BAE780641683AF43E5F5C0E03671117F702F401282847D2FC6064"_array32, // keyblob_key_source_02 -    "8E9795928E1C4428E1B78F0BE724D7294D6934689C11B190943923B9D5B85903"_array32, // keyblob_key_source_03 -    "95FA33AF95AFF9D9B61D164655B32710ED8D615D46C7D6CC3CC70481B686B402"_array32, // keyblob_key_source_04 -    "3F5BE7B3C8B1ABD8C10B4B703D44766BA08730562C172A4FE0D6B866B3E2DB3E"_array32, // keyblob_key_source_05 -    "0000000000000000000000000000000000000000000000000000000000000000"_array32, // keyblob_key_source_06 -    "0000000000000000000000000000000000000000000000000000000000000000"_array32, // keyblob_key_source_07 - -    "0000000000000000000000000000000000000000000000000000000000000000"_array32, // keyblob_key_source_08 -    "0000000000000000000000000000000000000000000000000000000000000000"_array32, // keyblob_key_source_09 -    "0000000000000000000000000000000000000000000000000000000000000000"_array32, // keyblob_key_source_0A -    "0000000000000000000000000000000000000000000000000000000000000000"_array32, // keyblob_key_source_0B -    "0000000000000000000000000000000000000000000000000000000000000000"_array32, // keyblob_key_source_0C -    "0000000000000000000000000000000000000000000000000000000000000000"_array32, // keyblob_key_source_0D -    "0000000000000000000000000000000000000000000000000000000000000000"_array32, // keyblob_key_source_0E -    "0000000000000000000000000000000000000000000000000000000000000000"_array32, // keyblob_key_source_0F - -    "0000000000000000000000000000000000000000000000000000000000000000"_array32, // keyblob_key_source_10 -    "0000000000000000000000000000000000000000000000000000000000000000"_array32, // keyblob_key_source_11 -    "0000000000000000000000000000000000000000000000000000000000000000"_array32, // keyblob_key_source_12 -    "0000000000000000000000000000000000000000000000000000000000000000"_array32, // keyblob_key_source_13 -    "0000000000000000000000000000000000000000000000000000000000000000"_array32, // keyblob_key_source_14 -    "0000000000000000000000000000000000000000000000000000000000000000"_array32, // keyblob_key_source_15 -    "0000000000000000000000000000000000000000000000000000000000000000"_array32, // keyblob_key_source_16 -    "0000000000000000000000000000000000000000000000000000000000000000"_array32, // keyblob_key_source_17 - -    "0000000000000000000000000000000000000000000000000000000000000000"_array32, // keyblob_key_source_18 -    "0000000000000000000000000000000000000000000000000000000000000000"_array32, // keyblob_key_source_19 -    "0000000000000000000000000000000000000000000000000000000000000000"_array32, // keyblob_key_source_1A -    "0000000000000000000000000000000000000000000000000000000000000000"_array32, // keyblob_key_source_1B -    "0000000000000000000000000000000000000000000000000000000000000000"_array32, // keyblob_key_source_1C -    "0000000000000000000000000000000000000000000000000000000000000000"_array32, // keyblob_key_source_1D -    "0000000000000000000000000000000000000000000000000000000000000000"_array32, // keyblob_key_source_1E -    "0000000000000000000000000000000000000000000000000000000000000000"_array32, // keyblob_key_source_1F +// clang-format on + +// clang-format off +constexpr std::array keyblob_source_hashes{ +    AsArray("8A06FE274AC491436791FDB388BCDD3AB9943BD4DEF8094418CDAC150FD73786"), // keyblob_key_source_00 +    AsArray("2D5CAEB2521FEF70B47E17D6D0F11F8CE2C1E442A979AD8035832C4E9FBCCC4B"), // keyblob_key_source_01 +    AsArray("61C5005E713BAE780641683AF43E5F5C0E03671117F702F401282847D2FC6064"), // keyblob_key_source_02 +    AsArray("8E9795928E1C4428E1B78F0BE724D7294D6934689C11B190943923B9D5B85903"), // keyblob_key_source_03 +    AsArray("95FA33AF95AFF9D9B61D164655B32710ED8D615D46C7D6CC3CC70481B686B402"), // keyblob_key_source_04 +    AsArray("3F5BE7B3C8B1ABD8C10B4B703D44766BA08730562C172A4FE0D6B866B3E2DB3E"), // keyblob_key_source_05 +    AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // keyblob_key_source_06 +    AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // keyblob_key_source_07 + +    AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // keyblob_key_source_08 +    AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // keyblob_key_source_09 +    AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // keyblob_key_source_0A +    AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // keyblob_key_source_0B +    AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // keyblob_key_source_0C +    AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // keyblob_key_source_0D +    AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // keyblob_key_source_0E +    AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // keyblob_key_source_0F + +    AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // keyblob_key_source_10 +    AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // keyblob_key_source_11 +    AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // keyblob_key_source_12 +    AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // keyblob_key_source_13 +    AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // keyblob_key_source_14 +    AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // keyblob_key_source_15 +    AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // keyblob_key_source_16 +    AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // keyblob_key_source_17 + +    AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // keyblob_key_source_18 +    AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // keyblob_key_source_19 +    AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // keyblob_key_source_1A +    AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // keyblob_key_source_1B +    AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // keyblob_key_source_1C +    AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // keyblob_key_source_1D +    AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // keyblob_key_source_1E +    AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // keyblob_key_source_1F  }; - -const std::array<SHA256Hash, 0x20> master_key_hashes{ -    "0EE359BE3C864BB0782E1D70A718A0342C551EED28C369754F9C4F691BECF7CA"_array32, // master_key_00 -    "4FE707B7E4ABDAF727C894AAF13B1351BFE2AC90D875F73B2E20FA94B9CC661E"_array32, // master_key_01 -    "79277C0237A2252EC3DFAC1F7C359C2B3D121E9DB15BB9AB4C2B4408D2F3AE09"_array32, // master_key_02 -    "4F36C565D13325F65EE134073C6A578FFCB0008E02D69400836844EAB7432754"_array32, // master_key_03 -    "75FF1D95D26113550EE6FCC20ACB58E97EDEB3A2FF52543ED5AEC63BDCC3DA50"_array32, // master_key_04 -    "EBE2BCD6704673EC0F88A187BB2AD9F1CC82B718C389425941BDC194DC46B0DD"_array32, // master_key_05 -    "0000000000000000000000000000000000000000000000000000000000000000"_array32, // master_key_06 -    "0000000000000000000000000000000000000000000000000000000000000000"_array32, // master_key_07 - -    "0000000000000000000000000000000000000000000000000000000000000000"_array32, // master_key_08 -    "0000000000000000000000000000000000000000000000000000000000000000"_array32, // master_key_09 -    "0000000000000000000000000000000000000000000000000000000000000000"_array32, // master_key_0A -    "0000000000000000000000000000000000000000000000000000000000000000"_array32, // master_key_0B -    "0000000000000000000000000000000000000000000000000000000000000000"_array32, // master_key_0C -    "0000000000000000000000000000000000000000000000000000000000000000"_array32, // master_key_0D -    "0000000000000000000000000000000000000000000000000000000000000000"_array32, // master_key_0E -    "0000000000000000000000000000000000000000000000000000000000000000"_array32, // master_key_0F - -    "0000000000000000000000000000000000000000000000000000000000000000"_array32, // master_key_10 -    "0000000000000000000000000000000000000000000000000000000000000000"_array32, // master_key_11 -    "0000000000000000000000000000000000000000000000000000000000000000"_array32, // master_key_12 -    "0000000000000000000000000000000000000000000000000000000000000000"_array32, // master_key_13 -    "0000000000000000000000000000000000000000000000000000000000000000"_array32, // master_key_14 -    "0000000000000000000000000000000000000000000000000000000000000000"_array32, // master_key_15 -    "0000000000000000000000000000000000000000000000000000000000000000"_array32, // master_key_16 -    "0000000000000000000000000000000000000000000000000000000000000000"_array32, // master_key_17 - -    "0000000000000000000000000000000000000000000000000000000000000000"_array32, // master_key_18 -    "0000000000000000000000000000000000000000000000000000000000000000"_array32, // master_key_19 -    "0000000000000000000000000000000000000000000000000000000000000000"_array32, // master_key_1A -    "0000000000000000000000000000000000000000000000000000000000000000"_array32, // master_key_1B -    "0000000000000000000000000000000000000000000000000000000000000000"_array32, // master_key_1C -    "0000000000000000000000000000000000000000000000000000000000000000"_array32, // master_key_1D -    "0000000000000000000000000000000000000000000000000000000000000000"_array32, // master_key_1E -    "0000000000000000000000000000000000000000000000000000000000000000"_array32, // master_key_1F +// clang-format on + +// clang-format off +constexpr std::array master_key_hashes{ +    AsArray("0EE359BE3C864BB0782E1D70A718A0342C551EED28C369754F9C4F691BECF7CA"), // master_key_00 +    AsArray("4FE707B7E4ABDAF727C894AAF13B1351BFE2AC90D875F73B2E20FA94B9CC661E"), // master_key_01 +    AsArray("79277C0237A2252EC3DFAC1F7C359C2B3D121E9DB15BB9AB4C2B4408D2F3AE09"), // master_key_02 +    AsArray("4F36C565D13325F65EE134073C6A578FFCB0008E02D69400836844EAB7432754"), // master_key_03 +    AsArray("75FF1D95D26113550EE6FCC20ACB58E97EDEB3A2FF52543ED5AEC63BDCC3DA50"), // master_key_04 +    AsArray("EBE2BCD6704673EC0F88A187BB2AD9F1CC82B718C389425941BDC194DC46B0DD"), // master_key_05 +    AsArray("9497E6779F5D840F2BBA1DE4E95BA1D6F21EFC94717D5AE5CA37D7EC5BD37A19"), // master_key_06 +    AsArray("4EC96B8CB01B8DCE382149443430B2B6EBCB2983348AFA04A25E53609DABEDF6"), // master_key_07 + +    AsArray("2998E2E23609BC2675FF062A2D64AF5B1B78DFF463B24119D64A1B64F01B2D51"), // master_key_08 +    AsArray("9D486A98067C44B37CF173D3BF577891EB6081FF6B4A166347D9DBBF7025076B"), // master_key_09 +    AsArray("4EC5A237A75A083A9C5F6CF615601522A7F822D06BD4BA32612C9CEBBB29BD45"), // master_key_0A +    AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // master_key_0B +    AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // master_key_0C +    AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // master_key_0D +    AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // master_key_0E +    AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // master_key_0F + +    AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // master_key_10 +    AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // master_key_11 +    AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // master_key_12 +    AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // master_key_13 +    AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // master_key_14 +    AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // master_key_15 +    AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // master_key_16 +    AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // master_key_17 + +    AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // master_key_18 +    AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // master_key_19 +    AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // master_key_1A +    AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // master_key_1B +    AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // master_key_1C +    AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // master_key_1D +    AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // master_key_1E +    AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // master_key_1F  }; +// clang-format on + +static constexpr u8 CalculateMaxKeyblobSourceHash() { +    const auto is_zero = [](const auto& data) { +        // TODO: Replace with std::all_of whenever mingw decides to update their +        //       libraries to include the constexpr variant of it. +        for (const auto element : data) { +            if (element != 0) { +                return false; +            } +        } +        return true; +    }; -static u8 CalculateMaxKeyblobSourceHash() {      for (s8 i = 0x1F; i >= 0; --i) { -        if (keyblob_source_hashes[i] != SHA256Hash{}) +        if (!is_zero(keyblob_source_hashes[i])) {              return static_cast<u8>(i + 1); +        }      }      return 0; @@ -346,10 +364,9 @@ FileSys::VirtualFile PartitionDataManager::GetPackage2Raw(Package2Type type) con  }  static bool AttemptDecrypt(const std::array<u8, 16>& key, Package2Header& header) { -    const std::vector<u8> iv(header.header_ctr.begin(), header.header_ctr.end());      Package2Header temp = header;      AESCipher<Key128> cipher(key, Mode::CTR); -    cipher.SetIV(iv); +    cipher.SetIV(header.header_ctr);      cipher.Transcode(&temp.header_ctr, sizeof(Package2Header) - 0x100, &temp.header_ctr,                       Op::Decrypt);      if (temp.magic == Common::MakeMagic('P', 'K', '2', '1')) { @@ -388,7 +405,7 @@ void PartitionDataManager::DecryptPackage2(const std::array<Key128, 0x20>& packa      auto c = a->ReadAllBytes();      AESCipher<Key128> cipher(package2_keys[revision], Mode::CTR); -    cipher.SetIV({header.section_ctr[1].begin(), header.section_ctr[1].end()}); +    cipher.SetIV(header.section_ctr[1]);      cipher.Transcode(c.data(), c.size(), c.data(), Op::Decrypt);      const auto ini_file = std::make_shared<FileSys::VectorVfsFile>(c); diff --git a/src/core/file_sys/content_archive.cpp b/src/core/file_sys/content_archive.cpp index 473245d5a..5039341c7 100644 --- a/src/core/file_sys/content_archive.cpp +++ b/src/core/file_sys/content_archive.cpp @@ -495,9 +495,10 @@ VirtualFile NCA::Decrypt(const NCASectionHeader& s_header, VirtualFile in, u64 s              auto out = std::make_shared<Core::Crypto::CTREncryptionLayer>(std::move(in), *key,                                                                            starting_offset); -            std::vector<u8> iv(16); -            for (u8 i = 0; i < 8; ++i) -                iv[i] = s_header.raw.section_ctr[0x8 - i - 1]; +            Core::Crypto::CTREncryptionLayer::IVData iv{}; +            for (std::size_t i = 0; i < 8; ++i) { +                iv[i] = s_header.raw.section_ctr[8 - i - 1]; +            }              out->SetIV(iv);              return std::static_pointer_cast<VfsFile>(out);          } diff --git a/src/core/file_sys/nca_patch.cpp b/src/core/file_sys/nca_patch.cpp index 0090cc6c4..fe7375e84 100644 --- a/src/core/file_sys/nca_patch.cpp +++ b/src/core/file_sys/nca_patch.cpp @@ -3,6 +3,7 @@  // Refer to the license.txt file included.  #include <algorithm> +#include <array>  #include <cstddef>  #include <cstring> @@ -66,7 +67,7 @@ std::size_t BKTR::Read(u8* data, std::size_t length, std::size_t offset) const {      Core::Crypto::AESCipher<Core::Crypto::Key128> cipher(key, Core::Crypto::Mode::CTR);      // Calculate AES IV -    std::vector<u8> iv(16); +    std::array<u8, 16> iv{};      auto subsection_ctr = subsection.ctr;      auto offset_iv = section_offset + base_offset;      for (std::size_t i = 0; i < section_ctr.size(); ++i) diff --git a/src/core/file_sys/system_archive/mii_model.cpp b/src/core/file_sys/system_archive/mii_model.cpp index 61bb67945..d65c7d234 100644 --- a/src/core/file_sys/system_archive/mii_model.cpp +++ b/src/core/file_sys/system_archive/mii_model.cpp @@ -27,18 +27,12 @@ VirtualDir MiiModel() {      auto out = std::make_shared<VectorVfsDirectory>(std::vector<VirtualFile>{},                                                      std::vector<VirtualDir>{}, "data"); -    out->AddFile(std::make_shared<ArrayVfsFile<MiiModelData::TEXTURE_LOW_LINEAR.size()>>( -        MiiModelData::TEXTURE_LOW_LINEAR, "NXTextureLowLinear.dat")); -    out->AddFile(std::make_shared<ArrayVfsFile<MiiModelData::TEXTURE_LOW_SRGB.size()>>( -        MiiModelData::TEXTURE_LOW_SRGB, "NXTextureLowSRGB.dat")); -    out->AddFile(std::make_shared<ArrayVfsFile<MiiModelData::TEXTURE_MID_LINEAR.size()>>( -        MiiModelData::TEXTURE_MID_LINEAR, "NXTextureMidLinear.dat")); -    out->AddFile(std::make_shared<ArrayVfsFile<MiiModelData::TEXTURE_MID_SRGB.size()>>( -        MiiModelData::TEXTURE_MID_SRGB, "NXTextureMidSRGB.dat")); -    out->AddFile(std::make_shared<ArrayVfsFile<MiiModelData::SHAPE_HIGH.size()>>( -        MiiModelData::SHAPE_HIGH, "ShapeHigh.dat")); -    out->AddFile(std::make_shared<ArrayVfsFile<MiiModelData::SHAPE_MID.size()>>( -        MiiModelData::SHAPE_MID, "ShapeMid.dat")); +    out->AddFile(MakeArrayFile(MiiModelData::TEXTURE_LOW_LINEAR, "NXTextureLowLinear.dat")); +    out->AddFile(MakeArrayFile(MiiModelData::TEXTURE_LOW_SRGB, "NXTextureLowSRGB.dat")); +    out->AddFile(MakeArrayFile(MiiModelData::TEXTURE_MID_LINEAR, "NXTextureMidLinear.dat")); +    out->AddFile(MakeArrayFile(MiiModelData::TEXTURE_MID_SRGB, "NXTextureMidSRGB.dat")); +    out->AddFile(MakeArrayFile(MiiModelData::SHAPE_HIGH, "ShapeHigh.dat")); +    out->AddFile(MakeArrayFile(MiiModelData::SHAPE_MID, "ShapeMid.dat"));      return out;  } diff --git a/src/core/file_sys/system_archive/ng_word.cpp b/src/core/file_sys/system_archive/ng_word.cpp index f4443784d..100d3c5db 100644 --- a/src/core/file_sys/system_archive/ng_word.cpp +++ b/src/core/file_sys/system_archive/ng_word.cpp @@ -24,19 +24,18 @@ constexpr std::array<u8, 30> WORD_TXT{  } // namespace NgWord1Data  VirtualDir NgWord1() { -    std::vector<VirtualFile> files(NgWord1Data::NUMBER_WORD_TXT_FILES); +    std::vector<VirtualFile> files; +    files.reserve(NgWord1Data::NUMBER_WORD_TXT_FILES);      for (std::size_t i = 0; i < files.size(); ++i) { -        files[i] = std::make_shared<ArrayVfsFile<NgWord1Data::WORD_TXT.size()>>( -            NgWord1Data::WORD_TXT, fmt::format("{}.txt", i)); +        files.push_back(MakeArrayFile(NgWord1Data::WORD_TXT, fmt::format("{}.txt", i)));      } -    files.push_back(std::make_shared<ArrayVfsFile<NgWord1Data::WORD_TXT.size()>>( -        NgWord1Data::WORD_TXT, "common.txt")); -    files.push_back(std::make_shared<ArrayVfsFile<NgWord1Data::VERSION_DAT.size()>>( -        NgWord1Data::VERSION_DAT, "version.dat")); +    files.push_back(MakeArrayFile(NgWord1Data::WORD_TXT, "common.txt")); +    files.push_back(MakeArrayFile(NgWord1Data::VERSION_DAT, "version.dat")); -    return std::make_shared<VectorVfsDirectory>(files, std::vector<VirtualDir>{}, "data"); +    return std::make_shared<VectorVfsDirectory>(std::move(files), std::vector<VirtualDir>{}, +                                                "data");  }  namespace NgWord2Data { @@ -55,27 +54,22 @@ constexpr std::array<u8, 0x2C> AC_NX_DATA{  } // namespace NgWord2Data  VirtualDir NgWord2() { -    std::vector<VirtualFile> files(NgWord2Data::NUMBER_AC_NX_FILES * 3); +    std::vector<VirtualFile> files; +    files.reserve(NgWord2Data::NUMBER_AC_NX_FILES * 3);      for (std::size_t i = 0; i < NgWord2Data::NUMBER_AC_NX_FILES; ++i) { -        files[3 * i] = std::make_shared<ArrayVfsFile<NgWord2Data::AC_NX_DATA.size()>>( -            NgWord2Data::AC_NX_DATA, fmt::format("ac_{}_b1_nx", i)); -        files[3 * i + 1] = std::make_shared<ArrayVfsFile<NgWord2Data::AC_NX_DATA.size()>>( -            NgWord2Data::AC_NX_DATA, fmt::format("ac_{}_b2_nx", i)); -        files[3 * i + 2] = std::make_shared<ArrayVfsFile<NgWord2Data::AC_NX_DATA.size()>>( -            NgWord2Data::AC_NX_DATA, fmt::format("ac_{}_not_b_nx", i)); +        files.push_back(MakeArrayFile(NgWord2Data::AC_NX_DATA, fmt::format("ac_{}_b1_nx", i))); +        files.push_back(MakeArrayFile(NgWord2Data::AC_NX_DATA, fmt::format("ac_{}_b2_nx", i))); +        files.push_back(MakeArrayFile(NgWord2Data::AC_NX_DATA, fmt::format("ac_{}_not_b_nx", i)));      } -    files.push_back(std::make_shared<ArrayVfsFile<NgWord2Data::AC_NX_DATA.size()>>( -        NgWord2Data::AC_NX_DATA, "ac_common_b1_nx")); -    files.push_back(std::make_shared<ArrayVfsFile<NgWord2Data::AC_NX_DATA.size()>>( -        NgWord2Data::AC_NX_DATA, "ac_common_b2_nx")); -    files.push_back(std::make_shared<ArrayVfsFile<NgWord2Data::AC_NX_DATA.size()>>( -        NgWord2Data::AC_NX_DATA, "ac_common_not_b_nx")); -    files.push_back(std::make_shared<ArrayVfsFile<NgWord2Data::VERSION_DAT.size()>>( -        NgWord2Data::VERSION_DAT, "version.dat")); +    files.push_back(MakeArrayFile(NgWord2Data::AC_NX_DATA, "ac_common_b1_nx")); +    files.push_back(MakeArrayFile(NgWord2Data::AC_NX_DATA, "ac_common_b2_nx")); +    files.push_back(MakeArrayFile(NgWord2Data::AC_NX_DATA, "ac_common_not_b_nx")); +    files.push_back(MakeArrayFile(NgWord2Data::VERSION_DAT, "version.dat")); -    return std::make_shared<VectorVfsDirectory>(files, std::vector<VirtualDir>{}, "data"); +    return std::make_shared<VectorVfsDirectory>(std::move(files), std::vector<VirtualDir>{}, +                                                "data");  }  } // namespace FileSys::SystemArchive diff --git a/src/core/file_sys/system_archive/time_zone_binary.cpp b/src/core/file_sys/system_archive/time_zone_binary.cpp index d1de63f20..8fd005012 100644 --- a/src/core/file_sys/system_archive/time_zone_binary.cpp +++ b/src/core/file_sys/system_archive/time_zone_binary.cpp @@ -654,12 +654,13 @@ static VirtualFile GenerateDefaultTimeZoneFile() {  }  VirtualDir TimeZoneBinary() { -    const std::vector<VirtualDir> root_dirs{std::make_shared<VectorVfsDirectory>( +    std::vector<VirtualDir> root_dirs{std::make_shared<VectorVfsDirectory>(          std::vector<VirtualFile>{GenerateDefaultTimeZoneFile()}, std::vector<VirtualDir>{},          "zoneinfo")}; -    const std::vector<VirtualFile> root_files{ -        std::make_shared<ArrayVfsFile<LOCATION_NAMES.size()>>(LOCATION_NAMES, "binaryList.txt")}; -    return std::make_shared<VectorVfsDirectory>(root_files, root_dirs, "data"); +    std::vector<VirtualFile> root_files{MakeArrayFile(LOCATION_NAMES, "binaryList.txt")}; + +    return std::make_shared<VectorVfsDirectory>(std::move(root_files), std::move(root_dirs), +                                                "data");  }  } // namespace FileSys::SystemArchive diff --git a/src/core/file_sys/vfs_vector.h b/src/core/file_sys/vfs_vector.h index ac36cb2ee..95d3da2f2 100644 --- a/src/core/file_sys/vfs_vector.h +++ b/src/core/file_sys/vfs_vector.h @@ -4,7 +4,11 @@  #pragma once +#include <array>  #include <cstring> +#include <memory> +#include <string> +#include <vector>  #include "core/file_sys/vfs.h"  namespace FileSys { @@ -13,7 +17,8 @@ namespace FileSys {  template <std::size_t size>  class ArrayVfsFile : public VfsFile {  public: -    ArrayVfsFile(std::array<u8, size> data, std::string name = "", VirtualDir parent = nullptr) +    explicit ArrayVfsFile(const std::array<u8, size>& data, std::string name = "", +                          VirtualDir parent = nullptr)          : data(data), name(std::move(name)), parent(std::move(parent)) {}      std::string GetName() const override { @@ -61,6 +66,12 @@ private:      VirtualDir parent;  }; +template <std::size_t Size, typename... Args> +std::shared_ptr<ArrayVfsFile<Size>> MakeArrayFile(const std::array<u8, Size>& data, +                                                  Args&&... args) { +    return std::make_shared<ArrayVfsFile<Size>>(data, std::forward<Args>(args)...); +} +  // An implementation of VfsFile that is backed by a vector optionally supplied upon construction  class VectorVfsFile : public VfsFile {  public: diff --git a/src/core/hle/ipc_helpers.h b/src/core/hle/ipc_helpers.h index 0dc6a4a43..1b503331f 100644 --- a/src/core/hle/ipc_helpers.h +++ b/src/core/hle/ipc_helpers.h @@ -229,6 +229,8 @@ inline void ResponseBuilder::Push(u32 value) {  template <typename T>  void ResponseBuilder::PushRaw(const T& value) { +    static_assert(std::is_trivially_copyable_v<T>, +                  "It's undefined behavior to use memcpy with non-trivially copyable objects");      std::memcpy(cmdbuf + index, &value, sizeof(T));      index += (sizeof(T) + 3) / 4; // round up to word length  } @@ -384,6 +386,8 @@ inline s32 RequestParser::Pop() {  template <typename T>  void RequestParser::PopRaw(T& value) { +    static_assert(std::is_trivially_copyable_v<T>, +                  "It's undefined behavior to use memcpy with non-trivially copyable objects");      std::memcpy(&value, cmdbuf + index, sizeof(T));      index += (sizeof(T) + 3) / 4; // round up to word length  } diff --git a/src/core/hle/kernel/address_arbiter.cpp b/src/core/hle/kernel/address_arbiter.cpp index df0debe1b..b882eaa0f 100644 --- a/src/core/hle/kernel/address_arbiter.cpp +++ b/src/core/hle/kernel/address_arbiter.cpp @@ -81,7 +81,7 @@ ResultCode AddressArbiter::IncrementAndSignalToAddressIfEqual(VAddr address, s32      do {          current_value = monitor.ExclusiveRead32(current_core, address); -        if (current_value != value) { +        if (current_value != static_cast<u32>(value)) {              return ERR_INVALID_STATE;          }          current_value++; diff --git a/src/core/hle/kernel/memory/page_table.cpp b/src/core/hle/kernel/memory/page_table.cpp index 5d6aac00f..e22e07206 100644 --- a/src/core/hle/kernel/memory/page_table.cpp +++ b/src/core/hle/kernel/memory/page_table.cpp @@ -604,7 +604,6 @@ ResultCode PageTable::MapPages(VAddr addr, const PageLinkedList& page_linked_lis          if (const auto result{                  Operate(cur_addr, node.GetNumPages(), perm, OperationType::Map, node.GetAddress())};              result.IsError()) { -            const MemoryInfo info{block_manager->FindBlock(cur_addr).GetMemoryInfo()};              const std::size_t num_pages{(addr - cur_addr) / PageSize};              ASSERT( diff --git a/src/core/hle/kernel/scheduler.cpp b/src/core/hle/kernel/scheduler.cpp index f93e5e4b0..a4b234424 100644 --- a/src/core/hle/kernel/scheduler.cpp +++ b/src/core/hle/kernel/scheduler.cpp @@ -131,7 +131,8 @@ u32 GlobalScheduler::SelectThreads() {      u32 cores_needing_context_switch{};      for (u32 core = 0; core < Core::Hardware::NUM_CPU_CORES; core++) {          Scheduler& sched = kernel.Scheduler(core); -        ASSERT(top_threads[core] == nullptr || top_threads[core]->GetProcessorID() == core); +        ASSERT(top_threads[core] == nullptr || +               static_cast<u32>(top_threads[core]->GetProcessorID()) == core);          if (update_thread(top_threads[core], sched)) {              cores_needing_context_switch |= (1ul << core);          } @@ -663,32 +664,26 @@ void Scheduler::Reload() {  }  void Scheduler::SwitchContextStep2() { -    Thread* previous_thread = current_thread_prev.get(); -    Thread* new_thread = selected_thread.get(); -      // Load context of new thread -    Process* const previous_process = -        previous_thread != nullptr ? previous_thread->GetOwnerProcess() : nullptr; - -    if (new_thread) { -        ASSERT_MSG(new_thread->GetSchedulingStatus() == ThreadSchedStatus::Runnable, +    if (selected_thread) { +        ASSERT_MSG(selected_thread->GetSchedulingStatus() == ThreadSchedStatus::Runnable,                     "Thread must be runnable.");          // Cancel any outstanding wakeup events for this thread -        new_thread->SetIsRunning(true); -        new_thread->last_running_ticks = system.CoreTiming().GetCPUTicks(); -        new_thread->SetWasRunning(false); +        selected_thread->SetIsRunning(true); +        selected_thread->last_running_ticks = system.CoreTiming().GetCPUTicks(); +        selected_thread->SetWasRunning(false);          auto* const thread_owner_process = current_thread->GetOwnerProcess();          if (thread_owner_process != nullptr) {              system.Kernel().MakeCurrentProcess(thread_owner_process);          } -        if (!new_thread->IsHLEThread()) { -            Core::ARM_Interface& cpu_core = new_thread->ArmInterface(); -            cpu_core.LoadContext(new_thread->GetContext32()); -            cpu_core.LoadContext(new_thread->GetContext64()); -            cpu_core.SetTlsAddress(new_thread->GetTLSAddress()); -            cpu_core.SetTPIDR_EL0(new_thread->GetTPIDR_EL0()); +        if (!selected_thread->IsHLEThread()) { +            Core::ARM_Interface& cpu_core = selected_thread->ArmInterface(); +            cpu_core.LoadContext(selected_thread->GetContext32()); +            cpu_core.LoadContext(selected_thread->GetContext64()); +            cpu_core.SetTlsAddress(selected_thread->GetTLSAddress()); +            cpu_core.SetTPIDR_EL0(selected_thread->GetTPIDR_EL0());              cpu_core.ChangeProcessorID(this->core_id);              cpu_core.ClearExclusiveState();          } diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp index 55a1edf1a..7d92b25a3 100644 --- a/src/core/hle/service/am/am.cpp +++ b/src/core/hle/service/am/am.cpp @@ -378,7 +378,11 @@ void ISelfController::GetLibraryAppletLaunchableEvent(Kernel::HLERequestContext&  }  void ISelfController::SetScreenShotPermission(Kernel::HLERequestContext& ctx) { -    LOG_WARNING(Service_AM, "(STUBBED) called"); +    IPC::RequestParser rp{ctx}; +    const auto permission = rp.PopEnum<ScreenshotPermission>(); +    LOG_DEBUG(Service_AM, "called, permission={}", permission); + +    screenshot_permission = permission;      IPC::ResponseBuilder rb{ctx, 2};      rb.Push(RESULT_SUCCESS); diff --git a/src/core/hle/service/am/am.h b/src/core/hle/service/am/am.h index 6cfb11b48..6e69796ec 100644 --- a/src/core/hle/service/am/am.h +++ b/src/core/hle/service/am/am.h @@ -149,6 +149,12 @@ private:      void GetAccumulatedSuspendedTickValue(Kernel::HLERequestContext& ctx);      void GetAccumulatedSuspendedTickChangedEvent(Kernel::HLERequestContext& ctx); +    enum class ScreenshotPermission : u32 { +        Inherit = 0, +        Enable = 1, +        Disable = 2, +    }; +      Core::System& system;      std::shared_ptr<NVFlinger::NVFlinger> nvflinger;      Kernel::EventPair launchable_event; @@ -157,6 +163,7 @@ private:      u32 idle_time_detection_extension = 0;      u64 num_fatal_sections_entered = 0;      bool is_auto_sleep_disabled = false; +    ScreenshotPermission screenshot_permission = ScreenshotPermission::Inherit;  };  class ICommonStateGetter final : public ServiceFramework<ICommonStateGetter> { diff --git a/src/core/hle/service/sm/sm.h b/src/core/hle/service/sm/sm.h index b526a94fe..aabf166b7 100644 --- a/src/core/hle/service/sm/sm.h +++ b/src/core/hle/service/sm/sm.h @@ -57,7 +57,7 @@ public:      ResultVal<std::shared_ptr<Kernel::ClientPort>> GetServicePort(const std::string& name);      ResultVal<std::shared_ptr<Kernel::ClientSession>> ConnectToService(const std::string& name); -    template <Common::IsBaseOf<Kernel::SessionRequestHandler> T> +    template <Common::DerivedFrom<Kernel::SessionRequestHandler> T>      std::shared_ptr<T> GetService(const std::string& service_name) const {          auto service = registered_services.find(service_name);          if (service == registered_services.end()) { diff --git a/src/core/loader/loader.cpp b/src/core/loader/loader.cpp index b8f8f1448..7c48e55e1 100644 --- a/src/core/loader/loader.cpp +++ b/src/core/loader/loader.cpp @@ -25,7 +25,7 @@ namespace Loader {  namespace { -template <Common::IsBaseOf<AppLoader> T> +template <Common::DerivedFrom<AppLoader> T>  std::optional<FileType> IdentifyFileLoader(FileSys::VirtualFile file) {      const auto file_type = T::IdentifyType(file);      if (file_type != FileType::Error) { diff --git a/src/core/memory/cheat_engine.cpp b/src/core/memory/cheat_engine.cpp index eeebdf02e..4b5cd0624 100644 --- a/src/core/memory/cheat_engine.cpp +++ b/src/core/memory/cheat_engine.cpp @@ -199,17 +199,29 @@ void CheatEngine::Initialize() {      metadata.title_id = system.CurrentProcess()->GetTitleID();      const auto& page_table = system.CurrentProcess()->PageTable(); -    metadata.heap_extents = {page_table.GetHeapRegionStart(), page_table.GetHeapRegionSize()}; -    metadata.address_space_extents = {page_table.GetAddressSpaceStart(), -                                      page_table.GetAddressSpaceSize()}; -    metadata.alias_extents = {page_table.GetAliasCodeRegionStart(), -                              page_table.GetAliasCodeRegionSize()}; +    metadata.heap_extents = { +        .base = page_table.GetHeapRegionStart(), +        .size = page_table.GetHeapRegionSize(), +    }; + +    metadata.address_space_extents = { +        .base = page_table.GetAddressSpaceStart(), +        .size = page_table.GetAddressSpaceSize(), +    }; + +    metadata.alias_extents = { +        .base = page_table.GetAliasCodeRegionStart(), +        .size = page_table.GetAliasCodeRegionSize(), +    };      is_pending_reload.exchange(true);  }  void CheatEngine::SetMainMemoryParameters(VAddr main_region_begin, u64 main_region_size) { -    metadata.main_nso_extents = {main_region_begin, main_region_size}; +    metadata.main_nso_extents = { +        .base = main_region_begin, +        .size = main_region_size, +    };  }  void CheatEngine::Reload(std::vector<CheatEntry> cheats) {  | 
