[XAM] - correct storage device ID fixes saving and storage detection in many games

most of the games this can be evidenced in are Unreal Engine titles or games that otherwise do not work in master yet but it can be shown in Saints Row 2 that does work in the master branch
this ID was found from debugging games where storage device detection wasn't working and reverse engineering of Unreal Engine 3
This commit is contained in:
Cancerous 2020-02-06 18:27:13 -05:00 committed by Rick Gibbed
parent 0fbf0eec9d
commit 596f1691c0
2 changed files with 12 additions and 23 deletions

View File

@ -45,9 +45,12 @@ struct DeviceInfo {
// they incorrectly only look at the lower 32-bits of free_bytes, // 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 // when it is a 64-bit value. Which means any size above ~4GB
// will not be recognized properly. // will not be recognized properly.
//
// NOTE(randprint): you can use 120 GB and 42 GB 'fullness'
// with the proper deviceID feel free to change at your discression
#define ONE_GB (1024ull * 1024ull * 1024ull) #define ONE_GB (1024ull * 1024ull * 1024ull)
static const DeviceInfo dummy_device_info_ = { static const DeviceInfo dummy_device_info_ = {
0xF00D0000, 1, 0x00000001, 1, // found from debugging / reversing UE3 engine titles
4ull * ONE_GB, // 4GB 4ull * ONE_GB, // 4GB
3ull * ONE_GB, // 3GB, so it looks a little used. 3ull * ONE_GB, // 3GB, so it looks a little used.
u"Dummy HDD", u"Dummy HDD",
@ -74,7 +77,7 @@ DECLARE_XAM_EXPORT2(XamContentGetLicenseMask, kContent, kStub, kHighFrequency);
dword_result_t XamContentGetDeviceName(dword_t device_id, dword_result_t XamContentGetDeviceName(dword_t device_id,
lpu16string_t name_buffer, lpu16string_t name_buffer,
dword_t name_capacity) { dword_t name_capacity) {
if ((device_id & 0xFFFF0000) != dummy_device_info_.device_id) { if ((device_id & 0x0000000F) != dummy_device_info_.device_id) {
return X_ERROR_DEVICE_NOT_CONNECTED; return X_ERROR_DEVICE_NOT_CONNECTED;
} }
@ -91,7 +94,7 @@ DECLARE_XAM_EXPORT1(XamContentGetDeviceName, kContent, kImplemented);
dword_result_t XamContentGetDeviceState(dword_t device_id, dword_result_t XamContentGetDeviceState(dword_t device_id,
lpunknown_t overlapped_ptr) { lpunknown_t overlapped_ptr) {
if ((device_id & 0xFFFF0000) != dummy_device_info_.device_id) { if ((device_id & 0x0000000F) != dummy_device_info_.device_id) {
if (overlapped_ptr) { if (overlapped_ptr) {
kernel_state()->CompleteOverlappedImmediateEx( kernel_state()->CompleteOverlappedImmediateEx(
overlapped_ptr, X_ERROR_FUNCTION_FAILED, X_ERROR_DEVICE_NOT_CONNECTED, overlapped_ptr, X_ERROR_FUNCTION_FAILED, X_ERROR_DEVICE_NOT_CONNECTED,
@ -123,7 +126,7 @@ static_assert_size(X_CONTENT_DEVICE_DATA, 0x50);
dword_result_t XamContentGetDeviceData( dword_result_t XamContentGetDeviceData(
dword_t device_id, pointer_t<X_CONTENT_DEVICE_DATA> device_data) { dword_t device_id, pointer_t<X_CONTENT_DEVICE_DATA> device_data) {
if ((device_id & 0xFFFF0000) != dummy_device_info_.device_id) { if ((device_id & 0x0000000F) != dummy_device_info_.device_id) {
// TODO(benvanik): memset 0 the data? // TODO(benvanik): memset 0 the data?
return X_ERROR_DEVICE_NOT_CONNECTED; return X_ERROR_DEVICE_NOT_CONNECTED;
} }
@ -162,7 +165,7 @@ dword_result_t XamContentCreateEnumerator(dword_t user_index, dword_t device_id,
lpdword_t buffer_size_ptr, lpdword_t buffer_size_ptr,
lpdword_t handle_out) { lpdword_t handle_out) {
assert_not_null(handle_out); assert_not_null(handle_out);
if ((device_id && (device_id & 0xFFFF0000) != dummy_device_info_.device_id) || if ((device_id && (device_id & 0x0000000F) != dummy_device_info_.device_id) ||
!handle_out) { !handle_out) {
if (buffer_size_ptr) { if (buffer_size_ptr) {
*buffer_size_ptr = 0; *buffer_size_ptr = 0;

View File

@ -316,22 +316,8 @@ dword_result_t XamShowDeviceSelectorUI(dword_t user_index, dword_t content_type,
qword_t total_requested, qword_t total_requested,
lpdword_t device_id_ptr, lpdword_t device_id_ptr,
pointer_t<XAM_OVERLAPPED> overlapped) { pointer_t<XAM_OVERLAPPED> overlapped) {
// NOTE: 0xF00D0000 magic from xam_content.cc // NOTE: 0x00000001 is our dummy device ID from xam_content.cc
switch (content_type) { *device_id_ptr = 0x00000001;
case 1: // save game
*device_id_ptr = 0xF00D0000 | 0x0001;
break;
case 2: // marketplace
*device_id_ptr = 0xF00D0000 | 0x0002;
break;
case 3: // title/publisher update?
*device_id_ptr = 0xF00D0000 | 0x0003;
break;
default:
assert_unhandled_case(content_type);
*device_id_ptr = 0xF00D0000 | 0x0001;
break;
}
// Broadcast XN_SYS_UI = true followed by XN_SYS_UI = false // Broadcast XN_SYS_UI = true followed by XN_SYS_UI = false
kernel_state()->BroadcastNotification(0x9, true); kernel_state()->BroadcastNotification(0x9, true);