diff --git a/src/xenia/kernel/xam/xam_content.cc b/src/xenia/kernel/xam/xam_content.cc index 570e29947..61e4ecdd2 100644 --- a/src/xenia/kernel/xam/xam_content.cc +++ b/src/xenia/kernel/xam/xam_content.cc @@ -25,13 +25,24 @@ struct DeviceInfo { uint64_t free_bytes; wchar_t name[28]; }; + +// TODO(gibbed): real information. +// +// Until we expose real information about a HDD device, we +// claim there is 3GB free on a 4GB dummy HDD. +// +// There is a possibility that certain games are bugged in that +// they incorrectly only look at the lower 32-bits of free_bytes, +// when it is a 64-bit value. Which means any size above ~4GB +// will not be recognized properly. +#define ONE_GB (1024ull * 1024ull * 1024ull) static const DeviceInfo dummy_device_info_ = { - 0xF00D0000, - 1, - 120ull * 1024ull * 1024ull * 1024ull, // 120GB - 100ull * 1024ull * 1024ull * 1024ull, // 100GB, so it looks a little used. + 0xF00D0000, 1, + 4ull * ONE_GB, // 4GB + 3ull * ONE_GB, // 3GB, so it looks a little used. L"Dummy HDD", }; +#undef ONE_GB dword_result_t XamContentGetLicenseMask(lpdword_t mask_ptr, lpunknown_t overlapped_ptr) { @@ -57,11 +68,13 @@ dword_result_t XamContentGetDeviceName(dword_t device_id, return X_ERROR_DEVICE_NOT_CONNECTED; } - if (name_capacity < wcslen(dummy_device_info_.name) + 1) { + auto name = std::wstring(dummy_device_info_.name); + if (name_capacity < name.size() + 1) { return X_ERROR_INSUFFICIENT_BUFFER; } - xe::store_and_swap(name_buffer, dummy_device_info_.name); + xe::store_and_swap(name_buffer, name); + ((wchar_t*)name_buffer)[name.size()] = 0; return X_ERROR_SUCCESS; } DECLARE_XAM_EXPORT1(XamContentGetDeviceName, kContent, kImplemented); @@ -96,6 +109,7 @@ typedef struct { xe::be free_bytes; xe::be name[28]; } X_CONTENT_DEVICE_DATA; +static_assert_size(X_CONTENT_DEVICE_DATA, 0x50); dword_result_t XamContentGetDeviceData( dword_t device_id, pointer_t device_data) { @@ -104,6 +118,7 @@ dword_result_t XamContentGetDeviceData( return X_ERROR_DEVICE_NOT_CONNECTED; } + device_data.Zero(); const auto& device_info = dummy_device_info_; device_data->device_id = device_info.device_id; device_data->unknown = device_id & 0xFFFF; // Fake it. diff --git a/src/xenia/kernel/xboxkrnl/xboxkrnl_threading.cc b/src/xenia/kernel/xboxkrnl/xboxkrnl_threading.cc index 40307c6f6..fc220404e 100644 --- a/src/xenia/kernel/xboxkrnl/xboxkrnl_threading.cc +++ b/src/xenia/kernel/xboxkrnl/xboxkrnl_threading.cc @@ -136,6 +136,7 @@ dword_result_t ExCreateThread(lpdword_t handle_ptr, dword_t stack_size, if (creation_flags & 0x80) { *handle_ptr = thread->guest_object(); } else { + thread->RetainHandle(); *handle_ptr = thread->handle(); } } @@ -789,8 +790,6 @@ dword_result_t KeWaitForMultipleObjects(dword_t count, lpdword_t objects_ptr, lpvoid_t wait_block_array_ptr) { assert_true(wait_type <= 1); - X_STATUS result = X_STATUS_SUCCESS; - std::vector> objects; for (uint32_t n = 0; n < count; n++) { auto object_ptr = kernel_memory()->TranslateVirtual(objects_ptr[n]); @@ -804,12 +803,10 @@ dword_result_t KeWaitForMultipleObjects(dword_t count, lpdword_t objects_ptr, } uint64_t timeout = timeout_ptr ? static_cast(*timeout_ptr) : 0u; - result = XObject::WaitMultiple(uint32_t(objects.size()), - reinterpret_cast(objects.data()), - wait_type, wait_reason, processor_mode, - alertable, timeout_ptr ? &timeout : nullptr); - - return result; + return XObject::WaitMultiple(uint32_t(objects.size()), + reinterpret_cast(objects.data()), + wait_type, wait_reason, processor_mode, + alertable, timeout_ptr ? &timeout : nullptr); } DECLARE_XBOXKRNL_EXPORT3(KeWaitForMultipleObjects, kThreading, kImplemented, kBlocking, kHighFrequency);