From 6b055f1f74fceb85d82c80b28a704d5178046e63 Mon Sep 17 00:00:00 2001 From: Adrian <78108584+AdrianCassar@users.noreply.github.com> Date: Mon, 5 May 2025 17:57:45 +0100 Subject: [PATCH] [XAM] Assert struct sizes and misc struct adjustments --- src/xenia/emulator.cc | 6 +++--- src/xenia/kernel/kernel_state.h | 2 +- src/xenia/kernel/xam/apps/xam_app.cc | 11 ++++++----- src/xenia/kernel/xam/apps/xgi_app.cc | 13 ++++++++++--- src/xenia/kernel/xam/user_profile.h | 4 ++-- src/xenia/kernel/xam/user_property.h | 2 ++ src/xenia/kernel/xam/xam_content.cc | 2 +- src/xenia/kernel/xam/xam_net.cc | 17 +++++++++++------ src/xenia/kernel/xam/xam_nui.cc | 11 +++++------ src/xenia/kernel/xam/xam_user.cc | 6 +++--- src/xenia/kernel/xsocket.h | 2 ++ src/xenia/xbox.h | 10 ++++++---- 12 files changed, 52 insertions(+), 34 deletions(-) diff --git a/src/xenia/emulator.cc b/src/xenia/emulator.cc index 56f8fc75b..fa346e616 100644 --- a/src/xenia/emulator.cc +++ b/src/xenia/emulator.cc @@ -574,7 +574,7 @@ X_STATUS Emulator::LaunchXexFile(const std::filesystem::path& path) { X_STATUS result = CompleteLaunch(path, fs_path); if (XSUCCEEDED(result)) { - kernel_state_->deployment_type_ = XDeploymentType::kHardDrive; + kernel_state_->deployment_type_ = XDeploymentType::kInstalledToHDD; auto title_id = kernel_state_->title_id(); if (!kernel::IsSystemTitle(title_id)) { // Assumption that any loaded game is loaded as a disc. @@ -613,7 +613,7 @@ X_STATUS Emulator::LaunchStfsContainer(const std::filesystem::path& path) { if (result == X_STATUS_NOT_FOUND && !cvars::launch_module.empty()) { return LaunchDefaultModule(path); } - kernel_state_->deployment_type_ = XDeploymentType::kGoD; + kernel_state_->deployment_type_ = XDeploymentType::kDownload; return result; } @@ -623,7 +623,7 @@ X_STATUS Emulator::LaunchDefaultModule(const std::filesystem::path& path) { X_STATUS result = CompleteLaunch(path, module_path); if (XSUCCEEDED(result)) { - kernel_state_->deployment_type_ = XDeploymentType::kHardDrive; + kernel_state_->deployment_type_ = XDeploymentType::kInstalledToHDD; auto title_id = kernel_state_->title_id(); if (!kernel::IsSystemTitle(title_id)) { // Assumption that any loaded game is loaded as a disc. diff --git a/src/xenia/kernel/kernel_state.h b/src/xenia/kernel/kernel_state.h index 975dbf6f3..9475bfc64 100644 --- a/src/xenia/kernel/kernel_state.h +++ b/src/xenia/kernel/kernel_state.h @@ -309,7 +309,7 @@ class KernelState { bool Restore(ByteStream* stream); uint32_t notification_position_ = 2; - XDeploymentType deployment_type_ = XDeploymentType::kUnknown; + XDeploymentType deployment_type_ = XDeploymentType::kOther; uint32_t GetKeTimestampBundle(); diff --git a/src/xenia/kernel/xam/apps/xam_app.cc b/src/xenia/kernel/xam/apps/xam_app.cc index 79582f0fc..354ded5d0 100644 --- a/src/xenia/kernel/xam/apps/xam_app.cc +++ b/src/xenia/kernel/xam/apps/xam_app.cc @@ -97,8 +97,8 @@ X_HRESULT XamApp::DispatchMessageSync(uint32_t message, uint32_t buffer_ptr, static_cast(data->device_type_ptr.get())); switch (kernel_state_->deployment_type_) { - case XDeploymentType::kGoD: - case XDeploymentType::kHardDrive: { + case XDeploymentType::kDownload: + case XDeploymentType::kInstalledToHDD: { *device_type_ptr = DeviceType::HDD; } break; case XDeploymentType::kOpticalDisc: { @@ -123,11 +123,12 @@ X_HRESULT XamApp::DispatchMessageSync(uint32_t message, uint32_t buffer_ptr, return X_E_SUCCESS; } case 0x00022005: { - struct message_data { + struct XTITLE_GET_DEPLOYMENT_TYPE { xe::be deployment_type_ptr; xe::be overlapped_ptr; - }* data = reinterpret_cast(buffer); - assert_true(buffer_length == sizeof(message_data)); + }* data = reinterpret_cast(buffer); + assert_true(!buffer_length || + buffer_length == sizeof(XTITLE_GET_DEPLOYMENT_TYPE)); auto deployment_type = memory_->TranslateVirtual(data->deployment_type_ptr); *deployment_type = static_cast(kernel_state_->deployment_type_); diff --git a/src/xenia/kernel/xam/apps/xgi_app.cc b/src/xenia/kernel/xam/apps/xgi_app.cc index b3f1f7c55..36c97befa 100644 --- a/src/xenia/kernel/xam/apps/xgi_app.cc +++ b/src/xenia/kernel/xam/apps/xgi_app.cc @@ -25,9 +25,10 @@ namespace apps { */ struct XGI_XUSER_ACHIEVEMENT { - xe::be user_idx; + xe::be user_index; xe::be achievement_id; }; +static_assert_size(XGI_XUSER_ACHIEVEMENT, 0x8); struct XGI_XUSER_GET_PROPERTY { xe::be user_index; @@ -39,6 +40,7 @@ struct XGI_XUSER_GET_PROPERTY { xe::be context_address; xe::be property_address; }; +static_assert_size(XGI_XUSER_GET_PROPERTY, 0x20); struct XGI_XUSER_SET_CONTEXT { xe::be user_index; @@ -46,6 +48,7 @@ struct XGI_XUSER_SET_CONTEXT { xe::be xuid; XUSER_CONTEXT context; }; +static_assert_size(XGI_XUSER_SET_CONTEXT, 0x18); struct XGI_XUSER_SET_PROPERTY { xe::be user_index; @@ -55,6 +58,7 @@ struct XGI_XUSER_SET_PROPERTY { xe::be data_size; xe::be data_address; }; +static_assert_size(XGI_XUSER_SET_PROPERTY, 0x20); struct XUSER_STATS_VIEW { xe::be ViewId; @@ -116,6 +120,8 @@ X_HRESULT XgiApp::DispatchMessageSync(uint32_t message, uint32_t buffer_ptr, return X_E_SUCCESS; } case 0x000B0007: { + assert_true(!buffer_length || + buffer_length == sizeof(XGI_XUSER_SET_PROPERTY)); const XGI_XUSER_SET_PROPERTY* xgi_property = reinterpret_cast(buffer); @@ -144,7 +150,8 @@ X_HRESULT XgiApp::DispatchMessageSync(uint32_t message, uint32_t buffer_ptr, return X_E_SUCCESS; } case 0x000B0008: { - assert_true(!buffer_length || buffer_length == 8); + assert_true(!buffer_length || + buffer_length == sizeof(XGI_XUSER_ACHIEVEMENT)); uint32_t achievement_count = xe::load_and_swap(buffer + 0); uint32_t achievements_ptr = xe::load_and_swap(buffer + 4); XELOGD("XGIUserWriteAchievements({:08X}, {:08X})", achievement_count, @@ -154,7 +161,7 @@ X_HRESULT XgiApp::DispatchMessageSync(uint32_t message, uint32_t buffer_ptr, memory_->TranslateVirtual(achievements_ptr); for (uint32_t i = 0; i < achievement_count; i++, achievement++) { kernel_state_->achievement_manager()->EarnAchievement( - achievement->user_idx, kernel_state_->title_id(), + achievement->user_index, kernel_state_->title_id(), achievement->achievement_id); } return X_E_SUCCESS; diff --git a/src/xenia/kernel/xam/user_profile.h b/src/xenia/kernel/xam/user_profile.h index cfa7c6953..dd4c387b9 100644 --- a/src/xenia/kernel/xam/user_profile.h +++ b/src/xenia/kernel/xam/user_profile.h @@ -26,10 +26,10 @@ namespace kernel { namespace xam { enum class X_USER_PROFILE_SETTING_SOURCE : uint32_t { - NOT_SET = 0, + NO_VALUE = 0, DEFAULT = 1, // Default value taken from default OS values. TITLE = 2, // Value written by title or OS. - UNKNOWN = 3, + PERMISSION_DENIED = 3, }; struct X_USER_PROFILE_SETTING { diff --git a/src/xenia/kernel/xam/user_property.h b/src/xenia/kernel/xam/user_property.h index 81a005e1a..59b39d98f 100644 --- a/src/xenia/kernel/xam/user_property.h +++ b/src/xenia/kernel/xam/user_property.h @@ -25,11 +25,13 @@ struct XUSER_CONTEXT { xe::be context_id; xe::be value; }; +static_assert_size(XUSER_CONTEXT, 0x8); struct XUSER_PROPERTY { xe::be property_id; X_USER_DATA data; }; +static_assert_size(XUSER_PROPERTY, 0x18); class Property : public UserData { public: diff --git a/src/xenia/kernel/xam/xam_content.cc b/src/xenia/kernel/xam/xam_content.cc index 2f7117d78..6dcd8e838 100644 --- a/src/xenia/kernel/xam/xam_content.cc +++ b/src/xenia/kernel/xam/xam_content.cc @@ -50,7 +50,7 @@ dword_result_t XamContentGetLicenseMask_entry(lpdword_t mask_ptr, // Remark: This cannot be reflected as on console. Xenia can boot games // directly and XBLA games can be repacked to ZAR. For these titles we must // provide some license. Normally it should fail for OpticalDisc type. - if (kernel_state()->deployment_type_ != XDeploymentType::kUnknown) { + if (kernel_state()->deployment_type_ != XDeploymentType::kOther) { // Each bit in the mask represents a granted license. Available licenses // seems to vary from game to game, but most appear to use bit 0 to // indicate if the game is purchased or not. diff --git a/src/xenia/kernel/xam/xam_net.cc b/src/xenia/kernel/xam/xam_net.cc index 9c0e8ce7c..86888a922 100644 --- a/src/xenia/kernel/xam/xam_net.cc +++ b/src/xenia/kernel/xam/xam_net.cc @@ -57,13 +57,14 @@ typedef struct { uint8_t abOnline[20]; // Online identification } XNADDR; -typedef struct { +struct XNDNS { xe::be status; xe::be cina; in_addr aina[8]; -} XNDNS; +}; +static_assert_size(XNDNS, 0x28); -typedef struct { +struct XNQOSINFO { uint8_t flags; uint8_t reserved; xe::be probes_xmit; @@ -74,18 +75,20 @@ typedef struct { xe::be rtt_med_in_msecs; xe::be up_bits_per_sec; xe::be down_bits_per_sec; -} XNQOSINFO; +}; +static_assert_size(XNQOSINFO, 0x18); -typedef struct { +struct XNQOS { xe::be count; xe::be count_pending; XNQOSINFO info[1]; -} XNQOS; +}; struct Xsockaddr_t { xe::be sa_family; char sa_data[14]; }; +static_assert_size(XNQOS, 0x20); struct X_WSADATA { xe::be version; @@ -96,6 +99,7 @@ struct X_WSADATA { xe::be max_udpdg; xe::be vendor_info_ptr; }; +static_assert_size(X_WSADATA, 0x190); struct XWSABUF { xe::be len; @@ -166,6 +170,7 @@ struct XNetStartupParams { uint8_t cfgQosSrvMaxSimultaneousResponses; uint8_t cfgQosPairWaitTimeInSeconds; }; +static_assert_size(XNetStartupParams, 0xD); XNetStartupParams xnet_startup_params = {0}; diff --git a/src/xenia/kernel/xam/xam_nui.cc b/src/xenia/kernel/xam/xam_nui.cc index 8d3b79563..431961020 100644 --- a/src/xenia/kernel/xam/xam_nui.cc +++ b/src/xenia/kernel/xam/xam_nui.cc @@ -327,11 +327,10 @@ void XamNuiHudGetVersions_entry(lpqword_t unk1, lpqword_t unk2) { DECLARE_XAM_EXPORT1(XamNuiHudGetVersions, kNone, kImplemented); // UI -dword_result_t XamShowNuiTroubleshooterUI_entry(unknown_t unk1, unknown_t unk2, - dword_t flag) { +dword_result_t XamShowNuiTroubleshooterUI_entry(dword_t user_index, + dword_t tracking_id, + dword_t flags) { /* Notes: - - unk1 is 0xFF - possibly user index? - - unk2 appear to always be zero. - calls XamPackageManagerGetExperienceMode(&var) with var = 1 - If returns less than zero or (var & 1) == 0 then get error message: - if XamPackageManagerGetExperienceMode = 0 then call XamShowMessageBoxUI @@ -339,8 +338,8 @@ dword_result_t XamShowNuiTroubleshooterUI_entry(unknown_t unk1, unknown_t unk2, returns 0 - else XamShowNuiTroubleshooterUI returns 0x65b and call another func - else: - - call XamNuiHudSetEngagedTrackingID(unk2) and doesn't care aboot return - and set var2 = 2 + - call XamNuiHudSetEngagedTrackingID(tracking_id) and doesn't care aboot + return and set var2 = 2 - checks if (flag & 0x800000) == 0 - if true call XamNuiGetDeviceStatus. - if XamNuiGetDeviceStatus != 0 set var2 = 3 diff --git a/src/xenia/kernel/xam/xam_user.cc b/src/xenia/kernel/xam/xam_user.cc index 5b5eb16ec..971560bd3 100644 --- a/src/xenia/kernel/xam/xam_user.cc +++ b/src/xenia/kernel/xam/xam_user.cc @@ -107,10 +107,10 @@ DECLARE_XAM_EXPORT2(XamUserGetSigninState, kUserProfiles, kImplemented, typedef struct { xe::be xuid; - xe::be unk08; // maybe zero? + xe::be flags; xe::be signin_state; - xe::be unk10; // ? - xe::be unk14; // ? + xe::be guest_num; + xe::be sponsor_user_index; char name[16]; } X_USER_SIGNIN_INFO; static_assert_size(X_USER_SIGNIN_INFO, 40); diff --git a/src/xenia/kernel/xsocket.h b/src/xenia/kernel/xsocket.h index 537d353d3..607341a9d 100644 --- a/src/xenia/kernel/xsocket.h +++ b/src/xenia/kernel/xsocket.h @@ -31,6 +31,7 @@ struct XSOCKADDR { xe::be address_family; char sa_data[14]; }; +static_assert_size(XSOCKADDR, 0x10); struct N_XSOCKADDR { N_XSOCKADDR() {} @@ -54,6 +55,7 @@ struct XSOCKADDR_IN { // sin_zero is defined as __pad on Android, so prefixed here. char x_sin_zero[8]; }; +static_assert_size(XSOCKADDR_IN, 0x10); // Xenia native sockaddr_in struct N_XSOCKADDR_IN { diff --git a/src/xenia/xbox.h b/src/xenia/xbox.h index e7e4faf0f..debe3a83b 100644 --- a/src/xenia/xbox.h +++ b/src/xenia/xbox.h @@ -198,6 +198,7 @@ struct XAM_OVERLAPPED { 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); @@ -411,7 +412,7 @@ struct X_IO_STATUS_BLOCK { struct X_EX_TITLE_TERMINATE_REGISTRATION { xe::be notification_routine; // 0x0 xe::be priority; // 0x4 - X_LIST_ENTRY list_entry; // 0x8 ?? + X_LIST_ENTRY list_entry; // 0x8 }; static_assert_size(X_EX_TITLE_TERMINATE_REGISTRATION, 16); @@ -636,9 +637,9 @@ enum X_MARKETPLACE_ENTRYPOINT : uint32_t { enum class XDeploymentType : uint32_t { kOpticalDisc = 0, - kHardDrive = 1, // Like extracted? - kGoD = 2, - kUnknown = 0xFF, + kInstalledToHDD = 1, // Like extracted? + kDownload = 2, + kOther = 3, }; inline bool IsOfflineXUID(uint64_t xuid) { return ((xuid >> 60) & 0xF) == 0xE; } @@ -750,6 +751,7 @@ struct MESSAGEBOX_RESULT { xe::be Passcode[4]; }; }; +static_assert_size(MESSAGEBOX_RESULT, 0x8); // clang-format off