diff --git a/src/xenia/kernel/info/file.h b/src/xenia/kernel/info/file.h index 3e5c22785..813e4bd2d 100644 --- a/src/xenia/kernel/info/file.h +++ b/src/xenia/kernel/info/file.h @@ -10,7 +10,8 @@ #ifndef XENIA_KERNEL_INFO_FILE_H_ #define XENIA_KERNEL_INFO_FILE_H_ -#include "xenia/xbox.h" +#include "xenia/base/byte_order.h" +#include "xenia/kernel/kernel.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/kernel.h b/src/xenia/kernel/kernel.h new file mode 100644 index 000000000..0f296bb74 --- /dev/null +++ b/src/xenia/kernel/kernel.h @@ -0,0 +1,276 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2025 Xenia Canary. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#ifndef XENIA_KERNEL_KERNEL_H_ +#define XENIA_KERNEL_KERNEL_H_ + +#include "xenia/base/byte_order.h" +#include "xenia/base/memory.h" +#include "xenia/xbox.h" + +namespace xe { +namespace kernel { + +// IOCTL_, used by NtDeviceIoControlFile +constexpr uint32_t X_IOCTL_DISK_GET_DRIVE_GEOMETRY = 0x70000; +constexpr uint32_t X_IOCTL_DISK_GET_PARTITION_INFO = 0x74004; + +// MEM_*, used by NtAllocateVirtualMemory +enum X_MEM : uint32_t { + X_MEM_COMMIT = 0x00001000, + X_MEM_RESERVE = 0x00002000, + X_MEM_DECOMMIT = 0x00004000, + X_MEM_RELEASE = 0x00008000, + X_MEM_FREE = 0x00010000, + X_MEM_PRIVATE = 0x00020000, + X_MEM_RESET = 0x00080000, + X_MEM_TOP_DOWN = 0x00100000, + X_MEM_NOZERO = 0x00800000, + X_MEM_LARGE_PAGES = 0x20000000, + X_MEM_HEAP = 0x40000000, + X_MEM_16MB_PAGES = 0x80000000 // from Valve SDK +}; + +// PAGE_*, used by NtAllocateVirtualMemory +enum X_PAGE : uint32_t { + X_PAGE_NOACCESS = 0x00000001, + X_PAGE_READONLY = 0x00000002, + X_PAGE_READWRITE = 0x00000004, + X_PAGE_WRITECOPY = 0x00000008, + X_PAGE_EXECUTE = 0x00000010, + X_PAGE_EXECUTE_READ = 0x00000020, + X_PAGE_EXECUTE_READWRITE = 0x00000040, + X_PAGE_EXECUTE_WRITECOPY = 0x00000080, + X_PAGE_GUARD = 0x00000100, + X_PAGE_NOCACHE = 0x00000200, + X_PAGE_WRITECOMBINE = 0x00000400 +}; + +// Known as XOVERLAPPED to 360 code. +struct XAM_OVERLAPPED { + xe::be result; // 0x0 + xe::be length; // 0x4 + xe::be context; // 0x8 + xe::be event; // 0xC + xe::be completion_routine; // 0x10 + xe::be completion_context; // 0x14 + xe::be extended_error; // 0x18 +}; +static_assert_size(XAM_OVERLAPPED, 0x1C); + +inline uint32_t XOverlappedGetResult(void* ptr) { + auto p = reinterpret_cast(ptr); + return xe::load_and_swap(&p[0]); +} +inline void XOverlappedSetResult(void* ptr, uint32_t value) { + auto p = reinterpret_cast(ptr); + xe::store_and_swap(&p[0], value); +} +inline uint32_t XOverlappedGetLength(void* ptr) { + auto p = reinterpret_cast(ptr); + return xe::load_and_swap(&p[1]); +} +inline void XOverlappedSetLength(void* ptr, uint32_t value) { + auto p = reinterpret_cast(ptr); + xe::store_and_swap(&p[1], value); +} +inline uint32_t XOverlappedGetContext(void* ptr) { + auto p = reinterpret_cast(ptr); + return xe::load_and_swap(&p[2]); +} +inline void XOverlappedSetContext(void* ptr, uint32_t value) { + auto p = reinterpret_cast(ptr); + xe::store_and_swap(&p[2], value); +} +inline X_HANDLE XOverlappedGetEvent(void* ptr) { + auto p = reinterpret_cast(ptr); + return xe::load_and_swap(&p[3]); +} +inline uint32_t XOverlappedGetCompletionRoutine(void* ptr) { + auto p = reinterpret_cast(ptr); + return xe::load_and_swap(&p[4]); +} +inline uint32_t XOverlappedGetCompletionContext(void* ptr) { + auto p = reinterpret_cast(ptr); + return xe::load_and_swap(&p[5]); +} +inline void XOverlappedSetExtendedError(void* ptr, uint32_t value) { + auto p = reinterpret_cast(ptr); + xe::store_and_swap(&p[6], value); +} + +struct X_ANSI_STRING { + xe::be length; + xe::be maximum_length; + xe::be pointer; + + void reset() { + length = 0; + maximum_length = 0; + pointer = 0; + } +}; +static_assert_size(X_ANSI_STRING, 8); + +struct X_UNICODE_STRING { + xe::be length; // 0x0 + xe::be maximum_length; // 0x2 + xe::be pointer; // 0x4 + + void reset() { + length = 0; + maximum_length = 0; + pointer = 0; + } +}; +static_assert_size(X_UNICODE_STRING, 8); + +// https://github.com/CodeAsm/ffplay360/blob/master/Common/XTLOnPC.h +struct X_VIDEO_MODE { + be display_width; + be display_height; + be is_interlaced; + be is_widescreen; + be is_hi_def; + be refresh_rate; + be video_standard; + be pixel_rate; + be widescreen_flag; + be reserved[3]; +}; +static_assert_size(X_VIDEO_MODE, 48); + +// https://docs.microsoft.com/en-us/windows/win32/api/ntdef/ns-ntdef-list_entry +struct X_LIST_ENTRY { + be flink_ptr; // next entry / head + be blink_ptr; // previous entry / head +}; +static_assert_size(X_LIST_ENTRY, 8); + +struct X_SINGLE_LIST_ENTRY { + be next; // 0x0 pointer to next entry +}; +static_assert_size(X_SINGLE_LIST_ENTRY, 4); + +// https://www.nirsoft.net/kernel_struct/vista/SLIST_HEADER.html +struct X_SLIST_HEADER { + X_SINGLE_LIST_ENTRY next; // 0x0 + be depth; // 0x4 + be sequence; // 0x6 +}; +static_assert_size(X_SLIST_HEADER, 8); + +struct X_EX_TITLE_TERMINATE_REGISTRATION { + xe::be notification_routine; // 0x0 + xe::be priority; // 0x4 + X_LIST_ENTRY list_entry; // 0x8 +}; +static_assert_size(X_EX_TITLE_TERMINATE_REGISTRATION, 16); + +enum X_OBJECT_HEADER_FLAGS : uint16_t { + OBJECT_HEADER_FLAG_NAMED_OBJECT = + 1, // if set, has X_OBJECT_HEADER_NAME_INFO prior to X_OBJECT_HEADER + OBJECT_HEADER_FLAG_IS_PERMANENT = 2, + OBJECT_HEADER_FLAG_CONTAINED_IN_DIRECTORY = + 4, // this object resides in an X_OBJECT_DIRECTORY + OBJECT_HEADER_IS_TITLE_OBJECT = 0x10, // used in obcreateobject + +}; + +struct X_OBJECT_DIRECTORY { + // each is a pointer to X_OBJECT_HEADER_NAME_INFO + // i believe offset 0 = pointer to next in bucket + xe::be name_buckets[13]; +}; +static_assert_size(X_OBJECT_DIRECTORY, 0x34); + +// https://www.geoffchappell.com/studies/windows/km/ntoskrnl/inc/ntos/ob/object_header_name_info.htm +// quite different, though +struct X_OBJECT_HEADER_NAME_INFO { + // i think that this is the next link in an X_OBJECT_DIRECTORY's buckets + xe::be next_in_directory; + xe::be object_directory; // pointer to X_OBJECT_DIRECTORY + X_ANSI_STRING name; +}; + +struct X_OBJECT_ATTRIBUTES { + xe::be root_directory; // 0x0 + xe::be name_ptr; // 0x4 PANSI_STRING + xe::be attributes; // 0xC +}; + +struct X_OBJECT_TYPE { + xe::be allocate_proc; // 0x0 + xe::be free_proc; // 0x4 + xe::be close_proc; // 0x8 + xe::be delete_proc; // 0xC + xe::be unknown_proc; // 0x10 + xe::be + unknown_size_or_object_; // this seems to be a union, it can be a pointer + // or it can be the size of the object + xe::be pool_tag; // 0x18 +}; +static_assert_size(X_OBJECT_TYPE, 0x1C); + +struct X_KSYMLINK { + xe::be refed_object_maybe; + X_ANSI_STRING refed_object_name_maybe; +}; +static_assert_size(X_KSYMLINK, 0xC); +// https://msdn.microsoft.com/en-us/library/windows/desktop/aa363082.aspx +typedef struct { + // Renamed due to a collision with exception_code from Windows excpt.h. + xe::be code; + xe::be exception_flags; + xe::be exception_record; + xe::be exception_address; + xe::be number_parameters; + xe::be exception_information[15]; +} X_EXCEPTION_RECORD; +static_assert_size(X_EXCEPTION_RECORD, 0x50); + +struct X_KSPINLOCK { + xe::be prcb_of_owner; +}; +static_assert_size(X_KSPINLOCK, 4); + +struct MESSAGEBOX_RESULT { + union { + xe::be ButtonPressed; + xe::be Passcode[4]; + }; +}; +static_assert_size(MESSAGEBOX_RESULT, 0x8); + +inline bool IsOfflineXUID(uint64_t xuid) { return ((xuid >> 60) & 0xF) == 0xE; } + +inline bool IsOnlineXUID(uint64_t xuid) { + return ((xuid >> 48) & 0xFFFF) == 0x9; +} + +inline bool IsGuestXUID(uint64_t xuid) { + const uint32_t HighPart = xuid >> 48; + return ((HighPart & 0x000F) == 0x9) && ((HighPart & 0x00C0) > 0); +} + +inline bool IsTeamXUID(uint64_t xuid) { + return (xuid & 0xFF00000000000140) == 0xFE00000000000100; +} + +inline bool IsValidXUID(uint64_t xuid) { + const bool valid = IsOfflineXUID(xuid) || IsOnlineXUID(xuid) || + IsTeamXUID(xuid) || IsGuestXUID(xuid); + + return valid; +} + +} // namespace kernel +} // namespace xe + +#endif // XENIA_KERNEL_KERNEL_H_ diff --git a/src/xenia/kernel/kernel_state.cc b/src/xenia/kernel/kernel_state.cc index b5e79d111..04311fffa 100644 --- a/src/xenia/kernel/kernel_state.cc +++ b/src/xenia/kernel/kernel_state.cc @@ -139,27 +139,6 @@ const std::unique_ptr KernelState::module_xdbf( return nullptr; } -bool KernelState::UpdateSpaData(vfs::Entry* spa_file_update) { - vfs::File* file; - if (spa_file_update->Open(vfs::FileAccess::kFileReadData, &file) != - X_STATUS_SUCCESS) { - return false; - } - - std::vector data(spa_file_update->size()); - - size_t read_bytes = 0; - if (file->ReadSync(std::span(data.data(), spa_file_update->size()), - 0, &read_bytes) != X_STATUS_SUCCESS) { - return false; - } - - xam::SpaInfo new_spa_data(std::span(data.data(), data.size())); - xam_state_->LoadSpaInfo(&new_spa_data); - emulator_->game_info_database()->Update(&new_spa_data); - return true; -} - uint32_t KernelState::AllocateTLS() { return uint32_t(tls_bitmap_.Acquire()); } void KernelState::FreeTLS(uint32_t slot) { diff --git a/src/xenia/kernel/kernel_state.h b/src/xenia/kernel/kernel_state.h index 9cb57dcc5..3986b92e8 100644 --- a/src/xenia/kernel/kernel_state.h +++ b/src/xenia/kernel/kernel_state.h @@ -19,6 +19,7 @@ #include "xenia/base/bit_map.h" #include "xenia/cpu/backend/backend.h" #include "xenia/cpu/export_resolver.h" +#include "xenia/kernel/kernel.h" #include "xenia/kernel/smc.h" #include "xenia/kernel/util/kernel_fwd.h" #include "xenia/kernel/util/native_list.h" @@ -31,7 +32,6 @@ #include "xenia/kernel/xam/xdbf/spa_info.h" #include "xenia/kernel/xevent.h" #include "xenia/vfs/virtual_file_system.h" -#include "xenia/xbox.h" namespace xe { class ByteStream; @@ -182,7 +182,6 @@ class KernelState { const std::unique_ptr title_xdbf() const; const std::unique_ptr module_xdbf( object_ref exec_module) const; - bool UpdateSpaData(vfs::Entry* spa_file_update); xam::XamState* xam_state() const { return xam_state_.get(); } @@ -382,7 +381,6 @@ class KernelState { public: uint32_t dash_context_ = 0; - X_DASH_APP_INFO dash_app_info_ = {}; std::unordered_map host_object_type_enum_to_guest_object_type_ptr_; uint32_t GetKernelGuestGlobals() const { return kernel_guest_globals_; } diff --git a/src/xenia/kernel/util/guest_object_table.h b/src/xenia/kernel/util/guest_object_table.h index d6de005c4..4b6cc08f2 100644 --- a/src/xenia/kernel/util/guest_object_table.h +++ b/src/xenia/kernel/util/guest_object_table.h @@ -10,7 +10,7 @@ #ifndef XENIA_KERNEL_UTIL_GUEST_OBJECT_TABLE_H_ #define XENIA_KERNEL_UTIL_GUEST_OBJECT_TABLE_H_ -#include "xenia/xbox.h" +#include "xenia/kernel/kernel.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/util/native_list.h b/src/xenia/kernel/util/native_list.h index af581f8b1..985c72a47 100644 --- a/src/xenia/kernel/util/native_list.h +++ b/src/xenia/kernel/util/native_list.h @@ -10,8 +10,8 @@ #ifndef XENIA_KERNEL_UTIL_NATIVE_LIST_H_ #define XENIA_KERNEL_UTIL_NATIVE_LIST_H_ +#include "xenia/kernel/kernel.h" #include "xenia/memory.h" -#include "xenia/xbox.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/util/presence_string_builder.cc b/src/xenia/kernel/util/presence_string_builder.cc index 708720728..91b0cf982 100644 --- a/src/xenia/kernel/util/presence_string_builder.cc +++ b/src/xenia/kernel/util/presence_string_builder.cc @@ -10,6 +10,8 @@ #include "xenia/kernel/util/presence_string_builder.h" #include "third_party/fmt/include/fmt/format.h" +#include "xenia/base/string.h" + namespace xe { namespace kernel { namespace util { diff --git a/src/xenia/kernel/util/xlast.h b/src/xenia/kernel/util/xlast.h index 6a7ad9fc2..bc2e34b7f 100644 --- a/src/xenia/kernel/util/xlast.h +++ b/src/xenia/kernel/util/xlast.h @@ -11,6 +11,7 @@ #define XENIA_KERNEL_UTIL_XLAST_H_ #include +#include #include #include #include diff --git a/src/xenia/kernel/xam/content_manager.cc b/src/xenia/kernel/xam/content_manager.cc index 882ee110a..a7dfed38f 100644 --- a/src/xenia/kernel/xam/content_manager.cc +++ b/src/xenia/kernel/xam/content_manager.cc @@ -421,7 +421,7 @@ X_RESULT ContentManager::OpenContent(const std::string_view root_name, std::string spa_path = fmt::format("{}:\\{}", root_name, kSpaFilename); auto spa_update = kernel_state_->file_system()->ResolvePath(spa_path); if (spa_update) { - kernel_state_->UpdateSpaData(spa_update); + UpdateSpaData(spa_update); } } @@ -559,6 +559,27 @@ uint64_t ContentManager::GetContentFreeSpace() const { return drive_stats.free; } +bool ContentManager::UpdateSpaData(vfs::Entry* spa_file_update) { + vfs::File* file; + if (spa_file_update->Open(vfs::FileAccess::kFileReadData, &file) != + X_STATUS_SUCCESS) { + return false; + } + + std::vector data(spa_file_update->size()); + + size_t read_bytes = 0; + if (file->ReadSync(std::span(data.data(), spa_file_update->size()), + 0, &read_bytes) != X_STATUS_SUCCESS) { + return false; + } + + xam::SpaInfo new_spa_data(std::span(data.data(), data.size())); + kernel_state_->xam_state()->LoadSpaInfo(&new_spa_data); + kernel_state_->emulator()->game_info_database()->Update(&new_spa_data); + return true; +} + } // namespace xam } // namespace kernel } // namespace xe diff --git a/src/xenia/kernel/xam/content_manager.h b/src/xenia/kernel/xam/content_manager.h index cdef45297..7e9d71ea3 100644 --- a/src/xenia/kernel/xam/content_manager.h +++ b/src/xenia/kernel/xam/content_manager.h @@ -20,6 +20,7 @@ #include "xenia/base/mutex.h" #include "xenia/base/string_key.h" #include "xenia/base/string_util.h" +#include "xenia/vfs/entry.h" #include "xenia/xbox.h" namespace xe { @@ -203,6 +204,8 @@ class ContentManager { const uint64_t xuid, uint32_t base_title_id = kCurrentlyRunningTitleId) const; + bool UpdateSpaData(vfs::Entry* spa_file_update); + KernelState* kernel_state_; std::filesystem::path root_path_; diff --git a/src/xenia/kernel/xam/user_profile.h b/src/xenia/kernel/xam/user_profile.h index a288dacd9..1cf7a4d4c 100644 --- a/src/xenia/kernel/xam/user_profile.h +++ b/src/xenia/kernel/xam/user_profile.h @@ -17,9 +17,9 @@ #include #include "xenia/kernel/xam/user_property.h" +#include "xenia/kernel/xam/xam.h" #include "xenia/kernel/xam/xdbf/gpd_info_profile.h" #include "xenia/kernel/xam/xdbf/gpd_info_title.h" -#include "xenia/xbox.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/xam/xam.h b/src/xenia/kernel/xam/xam.h new file mode 100644 index 000000000..12cfc7512 --- /dev/null +++ b/src/xenia/kernel/xam/xam.h @@ -0,0 +1,241 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2025 Xenia Canary. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#ifndef XENIA_KERNEL_XAM_XAM_H_ +#define XENIA_KERNEL_XAM_XAM_H_ + +#include + +#include "xenia/base/byte_order.h" +#include "xenia/base/string.h" +#include "xenia/xbox.h" + +namespace xe { +namespace kernel { +namespace xam { + +#pragma pack(push, 4) +struct X_XAMACCOUNTINFO { + enum AccountReservedFlags { + kPasswordProtected = 0x10000000, + kLiveEnabled = 0x20000000, + kRecovering = 0x40000000, + kVersionMask = 0x000000FF + }; + + enum AccountUserFlags { + kPaymentInstrumentCreditCard = 1, + + kCountryMask = 0xFF00, + kSubscriptionTierMask = 0xF00000, + kLanguageMask = 0x3E000000, + + kParentalControlEnabled = 0x1000000, + }; + + enum AccountSubscriptionTier { + kSubscriptionTierNone = 0, + kSubscriptionTierSilver = 3, + kSubscriptionTierGold = 6, + kSubscriptionTierFamilyGold = 9 + }; + + enum AccountLiveFlags { kAcctRequiresManagement = 1 }; + + be reserved_flags; + be live_flags; + char16_t gamertag[0x10]; + be xuid_online; // 09.... + be cached_user_flags; + be network_id; + char passcode[4]; + char online_domain[0x14]; + char online_kerberos_realm[0x18]; + char online_key[0x10]; + char passport_membername[0x72]; + char passport_password[0x20]; + char owner_passport_membername[0x72]; + + bool IsPasscodeEnabled() const { + return static_cast(reserved_flags & + AccountReservedFlags::kPasswordProtected); + } + + bool IsLiveEnabled() const { + return static_cast(reserved_flags & + AccountReservedFlags::kLiveEnabled); + } + + uint64_t GetOnlineXUID() const { return xuid_online; } + + std::string_view GetOnlineDomain() const { + return std::string_view(online_domain); + } + + uint32_t GetReservedFlags() const { return reserved_flags; }; + uint32_t GetCachedFlags() const { return cached_user_flags; }; + + XOnlineCountry GetCountry() const { + return static_cast((cached_user_flags & kCountryMask) >> 8); + } + + AccountSubscriptionTier GetSubscriptionTier() const { + return static_cast( + (cached_user_flags & kSubscriptionTierMask) >> 20); + } + + bool IsParentalControlled() const { + return static_cast((cached_user_flags & kLanguageMask) >> 24); + } + + XLanguage GetLanguage() const { + return static_cast((cached_user_flags & kLanguageMask) >> 25); + } + + std::string GetGamertagString() const { + return xe::to_utf8(std::u16string(gamertag)); + } + + void ToggleLiveFlag(bool is_live) { + reserved_flags = reserved_flags & ~AccountReservedFlags::kLiveEnabled; + + if (is_live) { + reserved_flags = reserved_flags | AccountReservedFlags::kLiveEnabled; + } + } + + void SetCountry(XOnlineCountry country) { + cached_user_flags = cached_user_flags & ~kCountryMask; + cached_user_flags = cached_user_flags | + (static_cast(country) << 8) & kCountryMask; + } + + void SetLanguage(XLanguage language) { + cached_user_flags = cached_user_flags & ~kLanguageMask; + + cached_user_flags = cached_user_flags | + (static_cast(language) << 25) & kLanguageMask; + } + + void SetSubscriptionTier(AccountSubscriptionTier sub_tier) { + cached_user_flags = cached_user_flags & ~kSubscriptionTierMask; + + cached_user_flags = + cached_user_flags | + (static_cast(sub_tier) << 20) & kSubscriptionTierMask; + } +}; +static_assert_size(X_XAMACCOUNTINFO, 0x17C); + +#define MAX_FIRSTNAME_SIZE 64 +#define MAX_LASTNAME_SIZE 64 +#define MAX_EMAIL_SIZE 129 +#define MAX_STREET_SIZE 128 +#define MAX_CITY_SIZE 64 +#define MAX_DISTRICT_SIZE 64 +#define MAX_STATE_SIZE 64 +#define MAX_POSTALCODE_SIZE 16 +#define MAX_PHONE_PREFIX_SIZE 12 +#define MAX_PHONE_NUMBER_SIZE 12 +#define MAX_PHONE_EXTENSION_SIZE 12 +#define MAX_CC_NAME_SIZE 64 +#define MAX_CC_NUMBER_SIZE 24 +#define MAX_DD_BANK_CODE_SIZE 64 +#define MAX_DD_BRANCH_CODE_SIZE 64 +#define MAX_DD_CHECK_DIGITS_SIZE 64 +#define MAX_VOUCHER_SIZE 26 + +struct X_USER_PAYMENT_INFO { + char16_t FirstName[MAX_FIRSTNAME_SIZE]; + char16_t LastName[MAX_LASTNAME_SIZE]; + char16_t Street1[MAX_STREET_SIZE]; + char16_t Street2[MAX_STREET_SIZE]; + char16_t District[MAX_STREET_SIZE]; + char16_t City[MAX_CITY_SIZE]; + char16_t State[MAX_STATE_SIZE]; + uint8_t CountryId; + uint16_t LanguageId; + char16_t PostalCode[MAX_POSTALCODE_SIZE]; + char16_t PhonePrefix[MAX_PHONE_PREFIX_SIZE]; + char16_t PhoneNumber[MAX_PHONE_NUMBER_SIZE]; + char16_t PhoneExtension[MAX_PHONE_EXTENSION_SIZE]; + + uint8_t PaymentTypeId; + char16_t CardHolder[MAX_CC_NAME_SIZE]; + uint8_t CardTypeId; + char16_t CardNumber[MAX_CC_NUMBER_SIZE]; + be ftCardExpiration; + + char16_t Email[MAX_EMAIL_SIZE]; + char16_t BankCode[MAX_DD_BANK_CODE_SIZE]; + char16_t BranchCode[MAX_DD_BRANCH_CODE_SIZE]; + char16_t CheckDigits[MAX_DD_CHECK_DIGITS_SIZE]; + + char16_t Voucher[MAX_VOUCHER_SIZE]; + + uint8_t MsftOptIn; + uint8_t PartnerOptIn; + uint64_t OfferId; + be ftBirthdate; +}; +static_assert_size(X_USER_PAYMENT_INFO, 0x8F0); + +struct X_PROFILEENUMRESULT { + xe::be xuid_offline; // E0..... + X_XAMACCOUNTINFO account; + xe::be device_id; +}; +static_assert_size(X_PROFILEENUMRESULT, 0x188); + +struct X_DASH_APP_INFO { + uint64_t unk1; + uint32_t unk2; +}; +static_assert_size(X_DASH_APP_INFO, 0xC); + +struct X_PASSPORT_SESSION_TOKEN { + uint8_t SessionToken[28]; +}; +static_assert_size(X_PASSPORT_SESSION_TOKEN, 0x1C); + +#pragma pack(pop) + +// clang-format off +#define XMBox_NOICON 0x00000000 +#define XMBox_ERRORICON 0x00000001 +#define XMBox_WARNINGICON 0x00000002 +#define XMBox_ALERTICON 0x00000003 + +#define XMBox_PASSCODEMODE 0x00010000 +#define XMBox_VERIFYPASSCODEMODE 0x00020000 + +#define XMBox_WAITANIMATION 0x00001000 +#define XMBox_LIVEPASSCODEMODE 0x00030000 +#define XMBox_MODEMASK 0x00030000 + +#define XMBox_OK 1 +#define XMBox_CANCEL 2 + +#define X_BUTTON_PASSCODE 0x00005802 +#define Y_BUTTON_PASSCODE 0x00005803 +#define RIGHT_BUMPER_PASSCODE 0x00005804 +#define LEFT_BUMPER_PASSCODE 0x00005805 +#define LEFT_TRIGGER_PASSCODE 0x00005806 +#define RIGHT_TRIGGER_PASSCODE 0x00005807 +#define DPAD_UP_PASSCODE 0x00005810 +#define DPAD_DOWN_PASSCODE 0x00005811 +#define DPAD_LEFT_PASSCODE 0x00005812 +#define DPAD_RIGHT_PASSCODE 0x00005813 +// clang-format on + +} // namespace xam +} // namespace kernel +} // namespace xe + +#endif // XENIA_KERNEL_XAM_XAM_H_ diff --git a/src/xenia/kernel/xam/xam_content_device.h b/src/xenia/kernel/xam/xam_content_device.h index 088bcf983..2c15273f3 100644 --- a/src/xenia/kernel/xam/xam_content_device.h +++ b/src/xenia/kernel/xam/xam_content_device.h @@ -10,7 +10,9 @@ #ifndef XENIA_KERNEL_XAM_XAM_CONTENT_DEVICE_H_ #define XENIA_KERNEL_XAM_XAM_CONTENT_DEVICE_H_ -#include "xenia/xbox.h" +#include +#include +#include namespace xe { namespace kernel { diff --git a/src/xenia/kernel/xam/xam_info.cc b/src/xenia/kernel/xam/xam_info.cc index 293343d55..5af9a8cdb 100644 --- a/src/xenia/kernel/xam/xam_info.cc +++ b/src/xenia/kernel/xam/xam_info.cc @@ -771,10 +771,10 @@ DECLARE_XAM_EXPORT1(XamIsChildAccountSignedIn, kNone, kImplemented); void XamSetActiveDashAppInfo_entry(pointer_t dash_app) { if (!dash_app) { - kernel_state()->dash_app_info_ = {}; + kernel_state()->xam_state()->dash_app_info_ = {}; return; } - std::memcpy(&kernel_state()->dash_app_info_, dash_app, + std::memcpy(&kernel_state()->xam_state()->dash_app_info_, dash_app, sizeof(X_DASH_APP_INFO)); } DECLARE_XAM_EXPORT1(XamSetActiveDashAppInfo, kNone, kImplemented); @@ -783,7 +783,7 @@ void XamGetActiveDashAppInfo_entry(pointer_t dash_app) { if (!dash_app) { return; } - std::memcpy(dash_app, &kernel_state()->dash_app_info_, + std::memcpy(dash_app, &kernel_state()->xam_state()->dash_app_info_, sizeof(X_DASH_APP_INFO)); } DECLARE_XAM_EXPORT1(XamGetActiveDashAppInfo, kNone, kImplemented); diff --git a/src/xenia/kernel/xam/xam_state.h b/src/xenia/kernel/xam/xam_state.h index 2c0d74451..2c9364748 100644 --- a/src/xenia/kernel/xam/xam_state.h +++ b/src/xenia/kernel/xam/xam_state.h @@ -11,11 +11,13 @@ #define XENIA_KERNEL_XAM_XAM_STATE_H_ #include + #include "xenia/kernel/xam/achievement_manager.h" #include "xenia/kernel/xam/app_manager.h" #include "xenia/kernel/xam/content_manager.h" #include "xenia/kernel/xam/profile_manager.h" #include "xenia/kernel/xam/user_tracker.h" +#include "xenia/kernel/xam/xam.h" namespace xe { class Emulator; @@ -55,6 +57,8 @@ class XamState { // void LoadSpaInfo(const SpaInfo* info); + X_DASH_APP_INFO dash_app_info_ = {}; + private: KernelState* kernel_state_; diff --git a/src/xenia/kernel/xboxkrnl/xboxkrnl_ob.h b/src/xenia/kernel/xboxkrnl/xboxkrnl_ob.h index 96295b0cb..216ca80c3 100644 --- a/src/xenia/kernel/xboxkrnl/xboxkrnl_ob.h +++ b/src/xenia/kernel/xboxkrnl/xboxkrnl_ob.h @@ -11,7 +11,7 @@ #define XENIA_KERNEL_XBOXKRNL_XBOXKRNL_OB_H_ #include "xenia/cpu/ppc/ppc_context.h" -#include "xenia/xbox.h" +#include "xenia/kernel/kernel.h" using PPCContext = xe::cpu::ppc::PPCContext; diff --git a/src/xenia/kernel/xboxkrnl/xboxkrnl_video.h b/src/xenia/kernel/xboxkrnl/xboxkrnl_video.h index 8cee8e3f2..3074a12f8 100644 --- a/src/xenia/kernel/xboxkrnl/xboxkrnl_video.h +++ b/src/xenia/kernel/xboxkrnl/xboxkrnl_video.h @@ -10,7 +10,7 @@ #ifndef XENIA_KERNEL_XBOXKRNL_XBOXKRNL_VIDEO_H_ #define XENIA_KERNEL_XBOXKRNL_XBOXKRNL_VIDEO_H_ -#include "xenia/xbox.h" +#include "xenia/kernel/kernel.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/xmodule.h b/src/xenia/kernel/xmodule.h index 28e860da3..47a36f388 100644 --- a/src/xenia/kernel/xmodule.h +++ b/src/xenia/kernel/xmodule.h @@ -12,9 +12,10 @@ #include +#include "xenia/base/byte_order.h" #include "xenia/cpu/module.h" +#include "xenia/kernel/kernel.h" #include "xenia/kernel/xobject.h" -#include "xenia/xbox.h" namespace xe { namespace kernel { diff --git a/src/xenia/vfs/file.h b/src/xenia/vfs/file.h index 9add3c70f..f61651f3e 100644 --- a/src/xenia/vfs/file.h +++ b/src/xenia/vfs/file.h @@ -11,6 +11,7 @@ #define XENIA_VFS_FILE_H_ #include +#include #include #include "xenia/xbox.h" diff --git a/src/xenia/xbox.h b/src/xenia/xbox.h index f4d62da0b..8fb5dc643 100644 --- a/src/xenia/xbox.h +++ b/src/xenia/xbox.h @@ -13,16 +13,10 @@ #include #include -#include "xenia/base/memory.h" -#include "xenia/base/string.h" - -// TODO(benvanik): split this header, cleanup, etc. +#include "xenia/base/assert.h" // clang-format off - namespace xe { -#pragma pack(push, 4) - typedef uint32_t X_HANDLE; #define X_INVALID_HANDLE_VALUE ((X_HANDLE)-1) @@ -132,47 +126,11 @@ typedef uint32_t X_HRESULT; #define X_E_NOTFOUND X_HRESULT_FROM_WIN32(X_ERROR_NOT_FOUND) #define X_E_NO_SUCH_USER X_HRESULT_FROM_WIN32(X_ERROR_NO_SUCH_USER) -//IOCTL_, used by NtDeviceIoControlFile -constexpr uint32_t X_IOCTL_DISK_GET_DRIVE_GEOMETRY = 0x70000; -constexpr uint32_t X_IOCTL_DISK_GET_PARTITION_INFO = 0x74004; - -// MEM_*, used by NtAllocateVirtualMemory -enum X_MEM : uint32_t { - X_MEM_COMMIT = 0x00001000, - X_MEM_RESERVE = 0x00002000, - X_MEM_DECOMMIT = 0x00004000, - X_MEM_RELEASE = 0x00008000, - X_MEM_FREE = 0x00010000, - X_MEM_PRIVATE = 0x00020000, - X_MEM_RESET = 0x00080000, - X_MEM_TOP_DOWN = 0x00100000, - X_MEM_NOZERO = 0x00800000, - X_MEM_LARGE_PAGES = 0x20000000, - X_MEM_HEAP = 0x40000000, - X_MEM_16MB_PAGES = 0x80000000 // from Valve SDK -}; - -// PAGE_*, used by NtAllocateVirtualMemory -enum X_PAGE : uint32_t { - X_PAGE_NOACCESS = 0x00000001, - X_PAGE_READONLY = 0x00000002, - X_PAGE_READWRITE = 0x00000004, - X_PAGE_WRITECOPY = 0x00000008, - X_PAGE_EXECUTE = 0x00000010, - X_PAGE_EXECUTE_READ = 0x00000020, - X_PAGE_EXECUTE_READWRITE = 0x00000040, - X_PAGE_EXECUTE_WRITECOPY = 0x00000080, - X_PAGE_GUARD = 0x00000100, - X_PAGE_NOCACHE = 0x00000200, - X_PAGE_WRITECOMBINE = 0x00000400 -}; - // Sockets/networking. #define X_INVALID_SOCKET (uint32_t)(~0) #define X_SOCKET_ERROR (uint32_t)(-1) // clang-format on - enum X_FILE_ATTRIBUTES : uint32_t { X_FILE_ATTRIBUTE_NONE = 0x0000, X_FILE_ATTRIBUTE_READONLY = 0x0001, @@ -187,85 +145,6 @@ enum X_FILE_ATTRIBUTES : uint32_t { X_FILE_ATTRIBUTE_ENCRYPTED = 0x4000, }; -// Known as XOVERLAPPED to 360 code. -struct XAM_OVERLAPPED { - xe::be result; // 0x0 - xe::be length; // 0x4 - xe::be context; // 0x8 - xe::be event; // 0xC - xe::be completion_routine; // 0x10 - xe::be completion_context; // 0x14 - xe::be extended_error; // 0x18 -}; -static_assert_size(XAM_OVERLAPPED, 0x1C); - -inline uint32_t XOverlappedGetResult(void* ptr) { - auto p = reinterpret_cast(ptr); - return xe::load_and_swap(&p[0]); -} -inline void XOverlappedSetResult(void* ptr, uint32_t value) { - auto p = reinterpret_cast(ptr); - xe::store_and_swap(&p[0], value); -} -inline uint32_t XOverlappedGetLength(void* ptr) { - auto p = reinterpret_cast(ptr); - return xe::load_and_swap(&p[1]); -} -inline void XOverlappedSetLength(void* ptr, uint32_t value) { - auto p = reinterpret_cast(ptr); - xe::store_and_swap(&p[1], value); -} -inline uint32_t XOverlappedGetContext(void* ptr) { - auto p = reinterpret_cast(ptr); - return xe::load_and_swap(&p[2]); -} -inline void XOverlappedSetContext(void* ptr, uint32_t value) { - auto p = reinterpret_cast(ptr); - xe::store_and_swap(&p[2], value); -} -inline X_HANDLE XOverlappedGetEvent(void* ptr) { - auto p = reinterpret_cast(ptr); - return xe::load_and_swap(&p[3]); -} -inline uint32_t XOverlappedGetCompletionRoutine(void* ptr) { - auto p = reinterpret_cast(ptr); - return xe::load_and_swap(&p[4]); -} -inline uint32_t XOverlappedGetCompletionContext(void* ptr) { - auto p = reinterpret_cast(ptr); - return xe::load_and_swap(&p[5]); -} -inline void XOverlappedSetExtendedError(void* ptr, uint32_t value) { - auto p = reinterpret_cast(ptr); - xe::store_and_swap(&p[6], value); -} - -struct X_ANSI_STRING { - xe::be length; - xe::be maximum_length; - xe::be pointer; - - void reset() { - length = 0; - maximum_length = 0; - pointer = 0; - } -}; -static_assert_size(X_ANSI_STRING, 8); - -struct X_UNICODE_STRING { - xe::be length; // 0x0 - xe::be maximum_length; // 0x2 - xe::be pointer; // 0x4 - - void reset() { - length = 0; - maximum_length = 0; - pointer = 0; - } -}; -static_assert_size(X_UNICODE_STRING, 8); - constexpr uint8_t XUserMaxUserCount = 4; constexpr uint8_t XUserIndexLatest = 0xFD; @@ -384,125 +263,6 @@ enum FIRMWARE_REENTRY { HalPowerCycleQuiesceRoutine = 0x8, }; -// https://github.com/CodeAsm/ffplay360/blob/master/Common/XTLOnPC.h -struct X_VIDEO_MODE { - be display_width; - be display_height; - be is_interlaced; - be is_widescreen; - be is_hi_def; - be refresh_rate; - be video_standard; - be pixel_rate; - be widescreen_flag; - be reserved[3]; -}; -static_assert_size(X_VIDEO_MODE, 48); - -// https://docs.microsoft.com/en-us/windows/win32/api/ntdef/ns-ntdef-list_entry -struct X_LIST_ENTRY { - be flink_ptr; // next entry / head - be blink_ptr; // previous entry / head -}; -static_assert_size(X_LIST_ENTRY, 8); - -struct X_SINGLE_LIST_ENTRY { - be next; // 0x0 pointer to next entry -}; -static_assert_size(X_SINGLE_LIST_ENTRY, 4); - -// https://www.nirsoft.net/kernel_struct/vista/SLIST_HEADER.html -struct X_SLIST_HEADER { - X_SINGLE_LIST_ENTRY next; // 0x0 - be depth; // 0x4 - be sequence; // 0x6 -}; -static_assert_size(X_SLIST_HEADER, 8); - -// https://msdn.microsoft.com/en-us/library/windows/hardware/ff550671(v=vs.85).aspx -struct X_IO_STATUS_BLOCK { - union { - xe::be status; - xe::be pointer; - }; - xe::be information; -}; - -struct X_EX_TITLE_TERMINATE_REGISTRATION { - xe::be notification_routine; // 0x0 - xe::be priority; // 0x4 - X_LIST_ENTRY list_entry; // 0x8 -}; -static_assert_size(X_EX_TITLE_TERMINATE_REGISTRATION, 16); - -enum X_OBJECT_HEADER_FLAGS : uint16_t { - OBJECT_HEADER_FLAG_NAMED_OBJECT = - 1, // if set, has X_OBJECT_HEADER_NAME_INFO prior to X_OBJECT_HEADER - OBJECT_HEADER_FLAG_IS_PERMANENT = 2, - OBJECT_HEADER_FLAG_CONTAINED_IN_DIRECTORY = - 4, // this object resides in an X_OBJECT_DIRECTORY - OBJECT_HEADER_IS_TITLE_OBJECT = 0x10, // used in obcreateobject - -}; - -struct X_OBJECT_DIRECTORY { - // each is a pointer to X_OBJECT_HEADER_NAME_INFO - // i believe offset 0 = pointer to next in bucket - xe::be name_buckets[13]; -}; -static_assert_size(X_OBJECT_DIRECTORY, 0x34); - -// https://www.geoffchappell.com/studies/windows/km/ntoskrnl/inc/ntos/ob/object_header_name_info.htm -// quite different, though -struct X_OBJECT_HEADER_NAME_INFO { - // i think that this is the next link in an X_OBJECT_DIRECTORY's buckets - xe::be next_in_directory; - xe::be object_directory; // pointer to X_OBJECT_DIRECTORY - X_ANSI_STRING name; -}; - -struct X_OBJECT_ATTRIBUTES { - xe::be root_directory; // 0x0 - xe::be name_ptr; // 0x4 PANSI_STRING - xe::be attributes; // 0xC -}; - -struct X_OBJECT_TYPE { - xe::be allocate_proc; // 0x0 - xe::be free_proc; // 0x4 - xe::be close_proc; // 0x8 - xe::be delete_proc; // 0xC - xe::be unknown_proc; // 0x10 - xe::be - unknown_size_or_object_; // this seems to be a union, it can be a pointer - // or it can be the size of the object - xe::be pool_tag; // 0x18 -}; -static_assert_size(X_OBJECT_TYPE, 0x1C); - -struct X_KSYMLINK { - xe::be refed_object_maybe; - X_ANSI_STRING refed_object_name_maybe; -}; -static_assert_size(X_KSYMLINK, 0xC); -// https://msdn.microsoft.com/en-us/library/windows/desktop/aa363082.aspx -typedef struct { - // Renamed due to a collision with exception_code from Windows excpt.h. - xe::be code; - xe::be exception_flags; - xe::be exception_record; - xe::be exception_address; - xe::be number_parameters; - xe::be exception_information[15]; -} X_EXCEPTION_RECORD; -static_assert_size(X_EXCEPTION_RECORD, 0x50); - -struct X_KSPINLOCK { - xe::be prcb_of_owner; -}; -static_assert_size(X_KSPINLOCK, 4); -#pragma pack(pop) - // Found by dumping the kSectionStringTable sections of various games: // and the language list at // https://free60project.github.io/wiki/Profile_Account/ @@ -746,253 +506,6 @@ enum class XDeploymentType : uint32_t { kOther = 3, }; -inline bool IsOfflineXUID(uint64_t xuid) { return ((xuid >> 60) & 0xF) == 0xE; } - -inline bool IsOnlineXUID(uint64_t xuid) { - return ((xuid >> 48) & 0xFFFF) == 0x9; -} - -inline bool IsGuestXUID(uint64_t xuid) { - const uint32_t HighPart = xuid >> 48; - return ((HighPart & 0x000F) == 0x9) && ((HighPart & 0x00C0) > 0); -} - -inline bool IsTeamXUID(uint64_t xuid) { - return (xuid & 0xFF00000000000140) == 0xFE00000000000100; -} - -inline bool IsValidXUID(uint64_t xuid) { - const bool valid = IsOfflineXUID(xuid) || IsOnlineXUID(xuid) || - IsTeamXUID(xuid) || IsGuestXUID(xuid); - - return valid; -} - -#pragma pack(push, 4) -struct X_XAMACCOUNTINFO { - enum AccountReservedFlags { - kPasswordProtected = 0x10000000, - kLiveEnabled = 0x20000000, - kRecovering = 0x40000000, - kVersionMask = 0x000000FF - }; - - enum AccountUserFlags { - kPaymentInstrumentCreditCard = 1, - - kCountryMask = 0xFF00, - kSubscriptionTierMask = 0xF00000, - kLanguageMask = 0x3E000000, - - kParentalControlEnabled = 0x1000000, - }; - - enum AccountSubscriptionTier { - kSubscriptionTierNone = 0, - kSubscriptionTierSilver = 3, - kSubscriptionTierGold = 6, - kSubscriptionTierFamilyGold = 9 - }; - - enum AccountLiveFlags { kAcctRequiresManagement = 1 }; - - xe::be reserved_flags; - xe::be live_flags; - char16_t gamertag[0x10]; - xe::be xuid_online; // 09.... - xe::be cached_user_flags; - xe::be network_id; - char passcode[4]; - char online_domain[0x14]; - char online_kerberos_realm[0x18]; - char online_key[0x10]; - char passport_membername[0x72]; - char passport_password[0x20]; - char owner_passport_membername[0x72]; - - bool IsPasscodeEnabled() const { - return static_cast(reserved_flags & - AccountReservedFlags::kPasswordProtected); - } - - bool IsLiveEnabled() const { - return static_cast(reserved_flags & - AccountReservedFlags::kLiveEnabled); - } - - uint64_t GetOnlineXUID() const { return xuid_online; } - - std::string_view GetOnlineDomain() const { - return std::string_view(online_domain); - } - - uint32_t GetReservedFlags() const { return reserved_flags; }; - uint32_t GetCachedFlags() const { return cached_user_flags; }; - - XOnlineCountry GetCountry() const { - return static_cast((cached_user_flags & kCountryMask) >> 8); - } - - AccountSubscriptionTier GetSubscriptionTier() const { - return static_cast( - (cached_user_flags & kSubscriptionTierMask) >> 20); - } - - bool IsParentalControlled() const { - return static_cast((cached_user_flags & kLanguageMask) >> 24); - } - - XLanguage GetLanguage() const { - return static_cast((cached_user_flags & kLanguageMask) >> 25); - } - - std::string GetGamertagString() const { - return xe::to_utf8(std::u16string(gamertag)); - } - - void ToggleLiveFlag(bool is_live) { - reserved_flags = reserved_flags & ~AccountReservedFlags::kLiveEnabled; - - if (is_live) { - reserved_flags = reserved_flags | AccountReservedFlags::kLiveEnabled; - } - } - - void SetCountry(XOnlineCountry country) { - cached_user_flags = cached_user_flags & ~kCountryMask; - cached_user_flags = cached_user_flags | - (static_cast(country) << 8) & kCountryMask; - } - - void SetLanguage(XLanguage language) { - cached_user_flags = cached_user_flags & ~kLanguageMask; - - cached_user_flags = cached_user_flags | - (static_cast(language) << 25) & kLanguageMask; - } - - void SetSubscriptionTier(AccountSubscriptionTier sub_tier) { - cached_user_flags = cached_user_flags & ~kSubscriptionTierMask; - - cached_user_flags = - cached_user_flags | - (static_cast(sub_tier) << 20) & kSubscriptionTierMask; - } -}; -static_assert_size(X_XAMACCOUNTINFO, 0x17C); - -#define MAX_FIRSTNAME_SIZE 64 -#define MAX_LASTNAME_SIZE 64 -#define MAX_EMAIL_SIZE 129 -#define MAX_STREET_SIZE 128 -#define MAX_CITY_SIZE 64 -#define MAX_DISTRICT_SIZE 64 -#define MAX_STATE_SIZE 64 -#define MAX_POSTALCODE_SIZE 16 -#define MAX_PHONE_PREFIX_SIZE 12 -#define MAX_PHONE_NUMBER_SIZE 12 -#define MAX_PHONE_EXTENSION_SIZE 12 -#define MAX_CC_NAME_SIZE 64 -#define MAX_CC_NUMBER_SIZE 24 -#define MAX_DD_BANK_CODE_SIZE 64 -#define MAX_DD_BRANCH_CODE_SIZE 64 -#define MAX_DD_CHECK_DIGITS_SIZE 64 -#define MAX_VOUCHER_SIZE 26 - -struct X_USER_PAYMENT_INFO { - char16_t FirstName[MAX_FIRSTNAME_SIZE]; - char16_t LastName[MAX_LASTNAME_SIZE]; - char16_t Street1[MAX_STREET_SIZE]; - char16_t Street2[MAX_STREET_SIZE]; - char16_t District[MAX_STREET_SIZE]; - char16_t City[MAX_CITY_SIZE]; - char16_t State[MAX_STATE_SIZE]; - uint8_t CountryId; - uint16_t LanguageId; - char16_t PostalCode[MAX_POSTALCODE_SIZE]; - char16_t PhonePrefix[MAX_PHONE_PREFIX_SIZE]; - char16_t PhoneNumber[MAX_PHONE_NUMBER_SIZE]; - char16_t PhoneExtension[MAX_PHONE_EXTENSION_SIZE]; - - uint8_t PaymentTypeId; - char16_t CardHolder[MAX_CC_NAME_SIZE]; - uint8_t CardTypeId; - char16_t CardNumber[MAX_CC_NUMBER_SIZE]; - be ftCardExpiration; - - char16_t Email[MAX_EMAIL_SIZE]; - char16_t BankCode[MAX_DD_BANK_CODE_SIZE]; - char16_t BranchCode[MAX_DD_BRANCH_CODE_SIZE]; - char16_t CheckDigits[MAX_DD_CHECK_DIGITS_SIZE]; - - char16_t Voucher[MAX_VOUCHER_SIZE]; - - uint8_t MsftOptIn; - uint8_t PartnerOptIn; - uint64_t OfferId; - be ftBirthdate; -}; -static_assert_size(X_USER_PAYMENT_INFO, 0x8F0); -#pragma pack(pop) - -struct X_PROFILEENUMRESULT { - xe::be xuid_offline; // E0..... - X_XAMACCOUNTINFO account; - xe::be device_id; -}; -static_assert_size(X_PROFILEENUMRESULT, 0x188); - -struct MESSAGEBOX_RESULT { - union { - xe::be ButtonPressed; - xe::be Passcode[4]; - }; -}; -static_assert_size(MESSAGEBOX_RESULT, 0x8); - -// clang-format off - -#define XMBox_NOICON 0x00000000 -#define XMBox_ERRORICON 0x00000001 -#define XMBox_WARNINGICON 0x00000002 -#define XMBox_ALERTICON 0x00000003 - -#define XMBox_PASSCODEMODE 0x00010000 -#define XMBox_VERIFYPASSCODEMODE 0x00020000 - -#define XMBox_WAITANIMATION 0x00001000 -#define XMBox_LIVEPASSCODEMODE 0x00030000 -#define XMBox_MODEMASK 0x00030000 - -#define XMBox_OK 1 -#define XMBox_CANCEL 2 - -#define X_BUTTON_PASSCODE 0x00005802 -#define Y_BUTTON_PASSCODE 0x00005803 -#define RIGHT_BUMPER_PASSCODE 0x00005804 -#define LEFT_BUMPER_PASSCODE 0x00005805 -#define LEFT_TRIGGER_PASSCODE 0x00005806 -#define RIGHT_TRIGGER_PASSCODE 0x00005807 -#define DPAD_UP_PASSCODE 0x00005810 -#define DPAD_DOWN_PASSCODE 0x00005811 -#define DPAD_LEFT_PASSCODE 0x00005812 -#define DPAD_RIGHT_PASSCODE 0x00005813 - -#pragma pack(push, 4) -struct X_DASH_APP_INFO { - uint64_t unk1; - uint32_t unk2; -}; -static_assert_size(X_DASH_APP_INFO, 0xC); -#pragma pack(pop) - -struct X_PASSPORT_SESSION_TOKEN { - uint8_t SessionToken[28]; -}; -static_assert_size(X_PASSPORT_SESSION_TOKEN, 0x1C); - -// clang-format on - } // namespace xe #endif // XENIA_XBOX_H_