diff --git a/src/xenia/kernel/xam/apps/messenger_app.cc b/src/xenia/kernel/xam/apps/messenger_app.cc index cd4872940..0db3073a5 100644 --- a/src/xenia/kernel/xam/apps/messenger_app.cc +++ b/src/xenia/kernel/xam/apps/messenger_app.cc @@ -26,15 +26,31 @@ X_RESULT MessengerApp::DispatchMessageSync(uint32_t message, auto buffer = memory_->TranslateVirtual(buffer_ptr); switch (message) { case 0x00200002: { - // Used on start in blades dashboard v5759 (marketplace update) and 6717 - XELOGD("MessengerUnk200002({:08X}, {:08X}), unimplemented", buffer_ptr, - buffer_length); + // Used on blades dashboard v5759 - 6717 when requesting to sign out + assert_true(!buffer_length || buffer_length == 12); + struct { + xe::be user_index; + xe::be unk1; + xe::be unk2; + }* args = memory_->TranslateVirtual(buffer_ptr); + static_assert_size(decltype(*args), 12); + + XELOGD("MessengerUnk200002({:08X}, {:08X}, {:08X}), unimplemented", + args->user_index.get(), args->unk1.get(), args->unk2.get()); return X_E_FAIL; } case 0x00200018: { - // Used on logging out in blades 6717 - XELOGD("MessengerUnk200018({:08X}, {:08X}), unimplemented", buffer_ptr, - buffer_length); + // Used after signing out in blades 6717 + assert_true(!buffer_length || buffer_length == 12); + struct { + xe::be user_index; + xe::be unk1; + xe::be unk2; + }* args = memory_->TranslateVirtual(buffer_ptr); + static_assert_size(decltype(*args), 12); + + XELOGD("MessengerUnk200018({:08X}, {:08X}, {:08X}), unimplemented", + args->user_index.get(), args->unk1.get(), args->unk2.get()); return X_E_FAIL; } } diff --git a/src/xenia/kernel/xam/apps/xam_app.cc b/src/xenia/kernel/xam/apps/xam_app.cc index f069ad3c3..817353c32 100644 --- a/src/xenia/kernel/xam/apps/xam_app.cc +++ b/src/xenia/kernel/xam/apps/xam_app.cc @@ -138,8 +138,15 @@ X_HRESULT XamApp::DispatchMessageSync(uint32_t message, uint32_t buffer_ptr, case 0x0002B003: { // Games used in: // 4D5309C9 - XELOGD("XamUnk2B003({:08X}, {:08X}), unimplemented", buffer_ptr, - buffer_length); + // It only receives buffer + struct { + xe::be unk1; + xe::be unk2; + xe::be unk3; + }* args = memory_->TranslateVirtual(buffer_ptr); + + XELOGD("XamUnk2B003({:016X}, {:016X}, {:016X}), unimplemented", + args->unk1.get(), args->unk2.get(), args->unk3.get()); return X_E_SUCCESS; } } diff --git a/src/xenia/kernel/xam/apps/xgi_app.cc b/src/xenia/kernel/xam/apps/xgi_app.cc index 7ea975789..3a642e535 100644 --- a/src/xenia/kernel/xam/apps/xgi_app.cc +++ b/src/xenia/kernel/xam/apps/xgi_app.cc @@ -250,8 +250,8 @@ X_HRESULT XgiApp::DispatchMessageSync(uint32_t message, uint32_t buffer_ptr, // Called after opening xbox live arcade and clicking on xbox live v5759 // to 5787 and called after clicking xbox live in the game library from // v6683 to v6717 - XELOGD("XGIUnkB0036({:08X}, {:08X}), unimplemented", buffer_ptr, - buffer_length); + // Does not get sent a buffer + XELOGD("XInvalidateGamerTileCache, unimplemented"); return X_E_FAIL; } case 0x000B003D: { @@ -320,8 +320,8 @@ X_HRESULT XgiApp::DispatchMessageSync(uint32_t message, uint32_t buffer_ptr, property); } case 0x000B0071: { - XELOGD("XGIUnkB0071({:08X}, {:08X}), unimplemented", buffer_ptr, - buffer_length); + XELOGD("ContentEnumerate::ResetEnumerator({:08X}, {:08X}), unimplemented", + buffer_ptr, buffer_length); return X_E_SUCCESS; } } diff --git a/src/xenia/kernel/xam/apps/xmp_app.cc b/src/xenia/kernel/xam/apps/xmp_app.cc index a86d0d3ae..ba9c03637 100644 --- a/src/xenia/kernel/xam/apps/xmp_app.cc +++ b/src/xenia/kernel/xam/apps/xmp_app.cc @@ -397,6 +397,8 @@ X_HRESULT XmpApp::DispatchMessageSync(uint32_t message, uint32_t buffer_ptr, // XMPCreateUserPlaylistEnumerator // For whatever reason buffer_length is 0 in this case. // Return buffer size is set to be items * 0x338 bytes. + // Games used in: + // 54540809, 494707D4 return X_E_SUCCESS; } case 0x00070029: { @@ -439,10 +441,26 @@ X_HRESULT XmpApp::DispatchMessageSync(uint32_t message, uint32_t buffer_ptr, return X_E_SUCCESS; } case 0x0007002B: { + // XMPGetMediaSources // Called on the NXE and Kinect dashboard after clicking on the picture, // video, and music library - XELOGD("XMPUnk7002B({:08X}, {:08X}), unimplemented", buffer_ptr, - buffer_length); + assert_true(!buffer_length || buffer_length == 20); + struct { + xe::be xmp_client; + xe::be unk1; + xe::be unk2; + xe::be unk3; + xe::be unk4; + }* args = memory_->TranslateVirtual(buffer_ptr); + static_assert_size(decltype(*args), 20); + + assert_true(args->xmp_client == 0x00000002 || + args->xmp_client == 0x00000000); + XELOGD( + "XMPGetMediaSources({:08X}, {:08X}, {:08X}, {:08X}, {:08X}), " + "unimplemented", + args->xmp_client.get(), args->unk1.get(), args->unk2.get(), + args->unk3.get(), args->unk4.get()); return X_E_INVALIDARG; } case 0x0007002E: { @@ -464,9 +482,26 @@ X_HRESULT XmpApp::DispatchMessageSync(uint32_t message, uint32_t buffer_ptr, return X_E_SUCCESS; } case 0x0007002F: { + // XMPDashInIt // Called on the start up of all dashboard versions before kinect - XELOGD("XMPUnk7002F({:08X}, {:08X}), unimplemented", buffer_ptr, - buffer_length); + assert_true(!buffer_length || buffer_length == 24); + struct { + xe::be xmp_client; + xe::be unk1; + xe::be unk2; + xe::be unk3; + xe::be unk4; + xe::be storage_ptr; + }* args = memory_->TranslateVirtual(buffer_ptr); + static_assert_size(decltype(*args), 24); + + assert_true(args->xmp_client == 0x00000002 || + args->xmp_client == 0x00000000); + XELOGD( + "XMPDashInIt({:08X}, {:08X}, {:08X}, {:08X}, {:08X}, {:08X}), " + "unimplemented", + args->xmp_client.get(), args->unk1.get(), args->unk2.get(), + args->unk3.get(), args->unk4.get(), args->storage_ptr.get()); return X_E_INVALIDARG; } case 0x0007003D: { @@ -488,19 +523,41 @@ X_HRESULT XmpApp::DispatchMessageSync(uint32_t message, uint32_t buffer_ptr, return X_E_SUCCESS; } case 0x00070044: { + // XMPSetMediaSourceWorkspace // Called on the start up of all dashboard versions before kinect // When it returns X_E_INVALIDARG you can access the music player up to // version 5787 - XELOGD("XMPUnk70044({:08X}, {:08X}), unimplemented", buffer_ptr, - buffer_length); + assert_true(!buffer_length || buffer_length == 16); + struct { + xe::be xmp_client; + xe::be unk1; + xe::be storage_ptr; + xe::be unk2; + }* args = memory_->TranslateVirtual(buffer_ptr); + static_assert_size(decltype(*args), 16); + + assert_true(args->xmp_client == 0x00000002 || + args->xmp_client == 0x00000000); + XELOGD( + "XMPSetMediaSourceWorkspace({:08X}, {:08X}, {:08X}, {:08X}), " + "unimplemented", + args->xmp_client.get(), args->unk1.get(), args->storage_ptr.get(), + args->unk2.get()); return X_E_INVALIDARG; } case 0x00070053: { - // Called on the blades dashboard after clicking on the picture, - // video, and music library in rapid succession then freezes - // it only recieves buffer - XELOGD("XMPUnk70053({:08X}, {:08X}), unimplemented", buffer_ptr, - buffer_length); + // Called on the blades dashboard Version 4532-5787 after clicking on the + // picture or video library. It only receives buffer + struct { + xe::be xmp_client; + xe::be unk1; + }* args = memory_->TranslateVirtual(buffer_ptr); + static_assert_size(decltype(*args), 8); + + assert_true(args->xmp_client == 0x00000002 || + args->xmp_client == 0x00000000); + XELOGD("XMPUnk70053({:08X}, {:08X}), unimplemented", + args->xmp_client.get(), args->unk1.get()); return X_E_SUCCESS; } } diff --git a/src/xenia/kernel/xam/xam_info.cc b/src/xenia/kernel/xam/xam_info.cc index 391f820c8..1b9041fb8 100644 --- a/src/xenia/kernel/xam/xam_info.cc +++ b/src/xenia/kernel/xam/xam_info.cc @@ -58,7 +58,7 @@ namespace xam { // https://github.com/tpn/winsdk-10/blob/master/Include/10.0.14393.0/km/wdm.h#L15539 typedef enum _MODE { KernelMode, UserMode, MaximumMode } MODE; -dword_result_t XamFeatureEnabled_entry(dword_t unk) { return 0; } +dword_result_t XamFeatureEnabled_entry(dword_t app_id) { return 0; } DECLARE_XAM_EXPORT1(XamFeatureEnabled, kNone, kStub); dword_result_t XamGetStagingMode_entry() { return cvars::staging_mode; } @@ -107,7 +107,7 @@ void XamFormatDateString_entry(dword_t locale_format, qword_t filetime, } DECLARE_XAM_EXPORT1(XamFormatDateString, kNone, kImplemented); -void XamFormatTimeString_entry(dword_t unk, qword_t filetime, +void XamFormatTimeString_entry(dword_t user_index, qword_t filetime, lpvoid_t output_buffer, dword_t output_count) { output_buffer.Zero(output_count * sizeof(char16_t)); @@ -530,22 +530,20 @@ dword_result_t GetModuleHandleA_entry(lpstring_t module_name) { } DECLARE_XAM_EXPORT1(GetModuleHandleA, kNone, kImplemented); -dword_result_t XapipCreateThread_entry(lpdword_t lpThreadAttributes, - dword_t dwStackSize, - lpvoid_t lpStartAddress, - lpvoid_t lpParameter, - dword_t dwCreationFlags, dword_t unkn, - lpdword_t lpThreadId) { - uint32_t flags = (dwCreationFlags >> 2) & 1; +dword_result_t XapipCreateThread_entry( + lpdword_t thread_attributes, dword_t stack_size, lpvoid_t start_address, + lpvoid_t parameter, dword_t creation_flags, dword_t thread_processor, + lpdword_t thread_id) { + uint32_t flags = (creation_flags >> 2) & 1; - if (unkn != -1) { - flags |= 1 << unkn << 24; + if (thread_processor != -1) { + flags |= 1 << thread_processor << 24; } xe::be result = 0; const X_STATUS error_code = xe::kernel::xboxkrnl::ExCreateThread( - &result, dwStackSize, lpThreadId, lpStartAddress, lpParameter, 0, flags); + &result, stack_size, thread_id, start_address, parameter, 0, flags); if (XFAILED(error_code)) { RtlSetLastNTError_entry(error_code); diff --git a/src/xenia/kernel/xam/xam_input.cc b/src/xenia/kernel/xam/xam_input.cc index 3f49f852f..9d642c2c7 100644 --- a/src/xenia/kernel/xam/xam_input.cc +++ b/src/xenia/kernel/xam/xam_input.cc @@ -40,8 +40,9 @@ void XamResetInactivity_entry() { } DECLARE_XAM_EXPORT1(XamResetInactivity, kInput, kStub); -dword_result_t XamEnableInactivityProcessing_entry(dword_t unk, +dword_result_t XamEnableInactivityProcessing_entry(dword_t inactivity_index, dword_t enable) { + // Enables/disables screen saver and auto shutoff return X_ERROR_SUCCESS; } DECLARE_XAM_EXPORT1(XamEnableInactivityProcessing, kInput, kStub); diff --git a/src/xenia/kernel/xam/xam_msg.cc b/src/xenia/kernel/xam/xam_msg.cc index e7ba8b921..68facfb1f 100644 --- a/src/xenia/kernel/xam/xam_msg.cc +++ b/src/xenia/kernel/xam/xam_msg.cc @@ -114,7 +114,7 @@ DECLARE_XAM_EXPORT2(XMsgCompleteIORequest, kNone, kImplemented, kSketchy); dword_result_t XamGetOverlappedResult_entry( pointer_t overlapped_ptr, lpdword_t length_ptr, - dword_t unknown) { + dword_t wait) { uint32_t result; if (overlapped_ptr->result != X_ERROR_IO_PENDING) { result = overlapped_ptr->result; diff --git a/src/xenia/kernel/xam/xam_profile.cc b/src/xenia/kernel/xam/xam_profile.cc index 3cc511140..07501b0ac 100644 --- a/src/xenia/kernel/xam/xam_profile.cc +++ b/src/xenia/kernel/xam/xam_profile.cc @@ -57,11 +57,12 @@ dword_result_t XamProfileOpen_entry(qword_t xuid, lpstring_t mount_path, } DECLARE_XAM_EXPORT1(XamProfileOpen, kNone, kImplemented); -dword_result_t XamProfileCreate_entry(dword_t flags, lpdword_t device_id, - qword_t xuid, - pointer_t account, - dword_t unk1, dword_t unk2, dword_t unk3, - dword_t unk4) { +dword_result_t XamProfileCreate_entry( + dword_t flags, lpdword_t device_id, qword_t xuid, + pointer_t account, + pointer_t payment_info, + pointer_t user_token, + pointer_t owner_token, lpvoid_t unk1) { if (device_id) { *device_id = 0x1; } @@ -92,7 +93,8 @@ dword_result_t XamProfileClose_entry(lpstring_t mount_name) { } DECLARE_XAM_EXPORT1(XamProfileClose, kNone, kStub); -dword_result_t XamProfileGetCreationStatus_entry(lpdword_t r3, lpdword_t r4) { +dword_result_t XamProfileGetCreationStatus_entry(lpvoid_t unk1, + lpqword_t offline_xuid) { return X_ERROR_SUCCESS; } DECLARE_XAM_EXPORT1(XamProfileGetCreationStatus, kNone, kStub); diff --git a/src/xenia/kernel/xam/xam_ui.cc b/src/xenia/kernel/xam/xam_ui.cc index a3fc549a2..2c7c91a74 100644 --- a/src/xenia/kernel/xam/xam_ui.cc +++ b/src/xenia/kernel/xam/xam_ui.cc @@ -591,7 +591,7 @@ void XamShowDirtyDiscErrorUI_entry(dword_t user_index) { } DECLARE_XAM_EXPORT1(XamShowDirtyDiscErrorUI, kUI, kImplemented); -dword_result_t XamShowPartyUI_entry(unknown_t r3, unknown_t r4) { +dword_result_t XamShowPartyUI_entry(dword_t user_index) { return X_ERROR_FUNCTION_FAILED; } DECLARE_XAM_EXPORT1(XamShowPartyUI, kNone, kStub); diff --git a/src/xenia/kernel/xam/xam_user.cc b/src/xenia/kernel/xam/xam_user.cc index 2dd35663c..8ed030780 100644 --- a/src/xenia/kernel/xam/xam_user.cc +++ b/src/xenia/kernel/xam/xam_user.cc @@ -65,7 +65,7 @@ X_HRESULT_result_t XamUserGetXUID_entry(dword_t user_index, dword_t type_mask, DECLARE_XAM_EXPORT1(XamUserGetXUID, kUserProfiles, kImplemented); dword_result_t XamUserGetIndexFromXUID_entry(qword_t xuid, dword_t flags, - pointer_t index) { + lpdword_t index) { if (!index) { return X_E_INVALIDARG; } diff --git a/src/xenia/kernel/xam/xam_voice.cc b/src/xenia/kernel/xam/xam_voice.cc index f745088ce..4e084818c 100644 --- a/src/xenia/kernel/xam/xam_voice.cc +++ b/src/xenia/kernel/xam/xam_voice.cc @@ -21,8 +21,8 @@ dword_result_t XamVoiceIsActiveProcess_entry() { } DECLARE_XAM_EXPORT1(XamVoiceIsActiveProcess, kNone, kStub); -dword_result_t XamVoiceCreate_entry(unknown_t unk1, // 0 - unknown_t unk2, // 0xF +dword_result_t XamVoiceCreate_entry(dword_t user_index, + dword_t max_attached_packets, // 0xF lpdword_t out_voice_ptr) { // Null out the ptr. out_voice_ptr.Zero(); diff --git a/src/xenia/kernel/xboxkrnl/xboxkrnl_usbcam.cc b/src/xenia/kernel/xboxkrnl/xboxkrnl_usbcam.cc index 81c3473e3..31289098c 100644 --- a/src/xenia/kernel/xboxkrnl/xboxkrnl_usbcam.cc +++ b/src/xenia/kernel/xboxkrnl/xboxkrnl_usbcam.cc @@ -17,7 +17,7 @@ namespace xboxkrnl { dword_result_t XUsbcamCreate_entry(dword_t buffer, dword_t buffer_size, // 0x4B000 640x480? - lpunknown_t unk3_ptr) { + lpdword_t handle_out) { // This function should return success. // It looks like it only allocates space for usbcam support. // returning error code might cause games to initialize incorrectly. @@ -31,6 +31,8 @@ DECLARE_XBOXKRNL_EXPORT1(XUsbcamCreate, kNone, kStub); dword_result_t XUsbcamGetState_entry() { // 0 = not connected. + // 1 = initialized + // 2 = connected return 0; } DECLARE_XBOXKRNL_EXPORT1(XUsbcamGetState, kNone, kStub); diff --git a/src/xenia/xbox.h b/src/xenia/xbox.h index 427d0c368..f4d62da0b 100644 --- a/src/xenia/xbox.h +++ b/src/xenia/xbox.h @@ -274,14 +274,16 @@ constexpr uint8_t XUserIndexAny = 0xFF; // https://github.com/ThirteenAG/Ultimate-ASI-Loader/blob/master/source/xlive/xliveless.h typedef uint32_t XNotificationID; -enum : XNotificationID { - /* XNotification Notes: - - Notification Ids are split into three Sections: Area, Version, and - Message Id. - - Each Area has the potential to hold 65535 unique notifications as it - always starts at 1. - */ +struct X_NOTIFICATION_ID { + uint32_t reserved : 1; // Always one + uint32_t area : 6; + uint32_t version : 9; + uint32_t message_id : 16; +}; +static_assert_size(X_NOTIFICATION_ID, 4); + +enum : XNotificationID { // Notification Areas kXNotifySystem = 0x00000001, kXNotifyLive = 0x00000002, @@ -878,6 +880,59 @@ struct X_XAMACCOUNTINFO { } }; 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 { @@ -931,6 +986,11 @@ struct X_DASH_APP_INFO { 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