From 19149bbba6bccfeb931fb0f578cfa58cbc656fae Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sat, 2 Aug 2014 21:37:11 -0700 Subject: [PATCH] Stubbed out enumeration. --- src/xenia/kernel/objects/sources.gypi | 2 ++ src/xenia/kernel/objects/xenumerator.cc | 25 ++++++++++++++ src/xenia/kernel/objects/xenumerator.h | 37 +++++++++++++++++++++ src/xenia/kernel/xam_info.cc | 39 ++++++++++++++++++++++ src/xenia/kernel/xam_msg.cc | 43 ++++++++++++++++++++++++- src/xenia/kernel/xam_user.cc | 26 +++++++++++++++ src/xenia/kernel/xobject.h | 1 + src/xenia/xbox.h | 30 +++++++++++++++++ 8 files changed, 202 insertions(+), 1 deletion(-) create mode 100644 src/xenia/kernel/objects/xenumerator.cc create mode 100644 src/xenia/kernel/objects/xenumerator.h diff --git a/src/xenia/kernel/objects/sources.gypi b/src/xenia/kernel/objects/sources.gypi index 7e849919a..49c07754a 100644 --- a/src/xenia/kernel/objects/sources.gypi +++ b/src/xenia/kernel/objects/sources.gypi @@ -1,6 +1,8 @@ # Copyright 2013 Ben Vanik. All Rights Reserved. { 'sources': [ + 'xenumerator.cc', + 'xenumerator.h', 'xevent.cc', 'xevent.h', 'xfile.cc', diff --git a/src/xenia/kernel/objects/xenumerator.cc b/src/xenia/kernel/objects/xenumerator.cc new file mode 100644 index 000000000..b4516d813 --- /dev/null +++ b/src/xenia/kernel/objects/xenumerator.cc @@ -0,0 +1,25 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#include + + +using namespace xe; +using namespace xe::kernel; + + +XEnumerator::XEnumerator(KernelState* kernel_state) : + XObject(kernel_state, kTypeEnumerator) { +} + +XEnumerator::~XEnumerator() { +} + +void XEnumerator::Initialize() { +} diff --git a/src/xenia/kernel/objects/xenumerator.h b/src/xenia/kernel/objects/xenumerator.h new file mode 100644 index 000000000..fa3a0dbde --- /dev/null +++ b/src/xenia/kernel/objects/xenumerator.h @@ -0,0 +1,37 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#ifndef XENIA_KERNEL_XBOXKRNL_XENUMERATOR_H_ +#define XENIA_KERNEL_XBOXKRNL_XENUMERATOR_H_ + +#include + +#include + + +namespace xe { +namespace kernel { + + +class XEnumerator : public XObject { +public: + XEnumerator(KernelState* kernel_state); + virtual ~XEnumerator(); + + void Initialize(); + +private: +}; + + +} // namespace kernel +} // namespace xe + + +#endif // XENIA_KERNEL_XBOXKRNL_XENUMERATOR_H_ diff --git a/src/xenia/kernel/xam_info.cc b/src/xenia/kernel/xam_info.cc index a8c1b1b22..3a05acab9 100644 --- a/src/xenia/kernel/xam_info.cc +++ b/src/xenia/kernel/xam_info.cc @@ -11,6 +11,7 @@ #include #include +#include #include #include @@ -102,6 +103,42 @@ SHIM_CALL XamLoaderGetLaunchData_shim( } +SHIM_CALL XamEnumerate_shim( + PPCContext* ppc_state, KernelState* state) { + uint32_t handle = SHIM_GET_ARG_32(0); + uint32_t zero = SHIM_GET_ARG_32(1); + uint32_t buffer_ptr = SHIM_GET_ARG_32(2); + uint32_t buffer_length = SHIM_GET_ARG_32(3); + uint32_t item_count_ptr = SHIM_GET_ARG_32(4); + uint32_t overlapped_ptr = SHIM_GET_ARG_32(5); + + XELOGD( + "XamEnumerate(%.8X, %d, %d, %.8X, %d, %.8X, %.8X)", + handle, zero, buffer_ptr, buffer_length, item_count_ptr, + overlapped_ptr); + + XEnumerator* e = nullptr; + if (XFAILED(state->object_table()->GetObject( + handle, (XObject**)&e))) { + SHIM_SET_RETURN_64(X_ERROR_INVALID_HANDLE); + return; + } + + if (item_count_ptr) { + SHIM_SET_MEM_32(item_count_ptr, 0); + } else if (overlapped_ptr) { + // TODO(benvanik): overlapped IO. + assert_zero(overlapped_ptr); + } else { + assert_always(); + } + + e->Release(); + + SHIM_SET_RETURN_64(0); +} + + } // namespace kernel } // namespace xe @@ -115,4 +152,6 @@ void xe::kernel::xam::RegisterInfoExports( SHIM_SET_MAPPING("xam.xex", XamLoaderGetLaunchDataSize, state); SHIM_SET_MAPPING("xam.xex", XamLoaderGetLaunchData, state); + + SHIM_SET_MAPPING("xam.xex", XamEnumerate, state); } diff --git a/src/xenia/kernel/xam_msg.cc b/src/xenia/kernel/xam_msg.cc index ded24cee1..72f2b2eca 100644 --- a/src/xenia/kernel/xam_msg.cc +++ b/src/xenia/kernel/xam_msg.cc @@ -74,8 +74,48 @@ SHIM_CALL XMsgInProcessCall_shim( } +SHIM_CALL XMsgStartIORequest_shim( + PPCContext* ppc_state, KernelState* state) { + uint32_t app = SHIM_GET_ARG_32(0); + uint32_t message = SHIM_GET_ARG_32(1); + uint32_t overlapped_ptr = SHIM_GET_ARG_32(2); + uint32_t buffer = SHIM_GET_ARG_32(3); + uint32_t buffer_length = SHIM_GET_ARG_32(4); + + XELOGD( + "XMsgStartIORequest(%.8X, %.8X, %.8X, %.8X, %d)", + app, message, overlapped_ptr, buffer, buffer_length); + + bool handled = false; + + assert_zero(overlapped_ptr); + + // TODO(benvanik): build XMsg pump? async/sync/etc + if (app == 0xFA) { + // XMP = music + // http://freestyledash.googlecode.com/svn-history/r1/trunk/Freestyle/Scenes/Media/Music/ScnMusic.cpp + if (message == 0x00070009) { + assert(buffer_length == 8); + uint32_t a = SHIM_MEM_32(buffer + 0); // 0x00000002 + uint32_t b = SHIM_MEM_32(buffer + 4); // out ptr to 4b - expect 0 + XELOGD("XMPGetStatusEx(%.8X, %.8X)", a, b); + assert_true(a == 2); + SHIM_SET_MEM_32(b, 0); + Sleep(1); + handled = true; + } + } + + if (!handled) { + XELOGE("Unimplemented XMsgStartIORequest message!"); + } + + SHIM_SET_RETURN_32(handled ? X_ERROR_SUCCESS : X_ERROR_NOT_FOUND); +} + + SHIM_CALL XMsgCancelIORequest_shim( - PPCContext* ppc_state, KernelState* state) { + PPCContext* ppc_state, KernelState* state) { uint32_t overlapped_ptr = SHIM_GET_ARG_32(0); uint32_t wait = SHIM_GET_ARG_32(1); @@ -97,5 +137,6 @@ SHIM_CALL XMsgCancelIORequest_shim( void xe::kernel::xam::RegisterMsgExports( ExportResolver* export_resolver, KernelState* state) { SHIM_SET_MAPPING("xam.xex", XMsgInProcessCall, state); + SHIM_SET_MAPPING("xam.xex", XMsgStartIORequest, state); SHIM_SET_MAPPING("xam.xex", XMsgCancelIORequest, state); } diff --git a/src/xenia/kernel/xam_user.cc b/src/xenia/kernel/xam_user.cc index 85ebc4835..560c41623 100644 --- a/src/xenia/kernel/xam_user.cc +++ b/src/xenia/kernel/xam_user.cc @@ -11,6 +11,7 @@ #include #include +#include #include @@ -191,6 +192,30 @@ SHIM_CALL XamShowSigninUI_shim( } +SHIM_CALL XamUserCreateAchievementEnumerator_shim( + PPCContext* ppc_state, KernelState* state) { + uint32_t title_id = SHIM_GET_ARG_32(0); + uint32_t user_index = SHIM_GET_ARG_32(1); + uint32_t xuid = SHIM_GET_ARG_32(2); + uint32_t flags = SHIM_GET_ARG_32(3); + uint32_t offset = SHIM_GET_ARG_32(4); + uint32_t count = SHIM_GET_ARG_32(5); + uint32_t buffer = SHIM_GET_ARG_32(6); + uint32_t handle_ptr = SHIM_GET_ARG_32(7); + + XELOGD( + "XamUserCreateAchievementEnumerator(%.8X, %d, %.8X, %.8X, %d, %d, %.8X, %.8X)", + title_id, user_index, xuid, flags, offset, count, buffer, handle_ptr); + + XEnumerator* e = new XEnumerator(state); + e->Initialize(); + + SHIM_SET_MEM_32(handle_ptr, e->handle()); + + SHIM_SET_RETURN_32(X_ERROR_SUCCESS); +} + + } // namespace kernel } // namespace xe @@ -203,4 +228,5 @@ void xe::kernel::xam::RegisterUserExports( SHIM_SET_MAPPING("xam.xex", XamUserGetName, state); SHIM_SET_MAPPING("xam.xex", XamUserReadProfileSettings, state); SHIM_SET_MAPPING("xam.xex", XamShowSigninUI, state); + SHIM_SET_MAPPING("xam.xex", XamUserCreateAchievementEnumerator, state); } diff --git a/src/xenia/kernel/xobject.h b/src/xenia/kernel/xobject.h index 7733db4ab..9be1a632e 100644 --- a/src/xenia/kernel/xobject.h +++ b/src/xenia/kernel/xobject.h @@ -41,6 +41,7 @@ public: kTypeNotifyListener, kTypeMutant, kTypeTimer, + kTypeEnumerator, }; XObject(KernelState* kernel_state, Type type); diff --git a/src/xenia/xbox.h b/src/xenia/xbox.h index 8e24fa3a4..9c47ced22 100644 --- a/src/xenia/xbox.h +++ b/src/xenia/xbox.h @@ -63,6 +63,7 @@ typedef uint32_t X_RESULT; #define X_HRESULT_FROM_WIN32(x) ((X_RESULT)(x) <= 0 ? ((X_RESULT)(x)) : ((X_RESULT) (((x) & 0x0000FFFF) | (X_FACILITY_WIN32 << 16) | 0x80000000))) #define X_ERROR_SUCCESS X_HRESULT_FROM_WIN32(0x00000000L) #define X_ERROR_ACCESS_DENIED X_HRESULT_FROM_WIN32(0x00000005L) +#define X_ERROR_INVALID_HANDLE X_HRESULT_FROM_WIN32(0x00000006L) #define X_ERROR_NO_MORE_FILES X_HRESULT_FROM_WIN32(0x00000018L) #define X_ERROR_INSUFFICIENT_BUFFER X_HRESULT_FROM_WIN32(0x0000007AL) #define X_ERROR_BAD_ARGUMENTS X_HRESULT_FROM_WIN32(0x000000A0L) @@ -191,6 +192,35 @@ typedef enum _X_FILE_INFORMATION_CLASS { } X_FILE_INFORMATION_CLASS; +inline void XOverlappedSetResult(void* ptr, uint32_t value) { + auto p = reinterpret_cast(ptr); + p[0] = value; +} +inline void XOverlappedSetLength(void* ptr, uint32_t value) { + auto p = reinterpret_cast(ptr); + p[1] = value; +} +inline void XOverlappedSetContext(void* ptr, uint32_t value) { + auto p = reinterpret_cast(ptr); + p[2] = value; +} +inline void XOverlappedSetExtendedError(void* ptr, uint32_t value) { + auto p = reinterpret_cast(ptr); + p[7] = value; +} +inline X_HANDLE XOverlappedGetEvent(void* ptr) { + auto p = reinterpret_cast(ptr); + return p[4]; +} +inline uint32_t XOverlappedGetCompletionRoutine(void* ptr) { + auto p = reinterpret_cast(ptr); + return p[5]; +} +inline uint32_t XOverlappedGetCompletionContext(void* ptr) { + auto p = reinterpret_cast(ptr); + return p[6]; +} + class X_ANSI_STRING { private: uint16_t length;