[XAM] Added profile and create content enumerator wrappers

This commit is contained in:
Adrian
2026-02-25 21:46:01 +00:00
committed by Radosław Gliński
parent 54be3c57a0
commit a7f1a3f18a
4 changed files with 98 additions and 12 deletions

View File

@@ -157,8 +157,9 @@ dword_result_t XamContentCreateEnumerator_entry(
xuid = user->xuid();
}
auto e = make_object<XStaticEnumerator<XCONTENT_DATA>>(kernel_state(),
items_per_enumerate);
auto e = object_ref<ContentEnumerator>(
new ContentEnumerator(kernel_state(), items_per_enumerate));
auto result = e->Initialize(XUserIndexAny, 0xFE, 0x20005, 0x20007, 0);
if (XFAILED(result)) {
return result;
@@ -206,8 +207,7 @@ dword_result_t XamContentCreateEnumerator_entry(
}
for (const auto& content_data : enumerated_content) {
auto item = e->AppendItem();
*item = content_data;
e->AppendItem(content_data);
XELOGI("{}: Adding: {} (Filename: {}) to enumerator result", __func__,
xe::to_utf8(content_data.display_name()), content_data.file_name());
}

View File

@@ -165,7 +165,8 @@ dword_result_t XamProfileCreateEnumerator_entry(dword_t device_id,
return X_ERROR_INVALID_PARAMETER;
}
auto e = new XStaticEnumerator<X_PROFILEENUMRESULT>(kernel_state(), 1);
auto e =
object_ref<ProfileEnumerator>(new ProfileEnumerator(kernel_state(), 1));
auto result =
e->Initialize(XUserIndexAny, 0xFE, 0x23001, 0x23003, 0, 0x28, nullptr);
@@ -178,11 +179,7 @@ dword_result_t XamProfileCreateEnumerator_entry(dword_t device_id,
kernel_state()->xam_state()->profile_manager()->GetAccounts();
for (const auto& [xuid, account] : *accounts) {
X_PROFILEENUMRESULT* profile = e->AppendItem();
profile->xuid_offline = xuid;
profile->device_id = 1;
memcpy(&profile->account, &account, sizeof(X_XAMACCOUNTINFO));
e->AppendItem({xuid, account, 1});
}
*handle_ptr = e->handle();

View File

@@ -68,7 +68,6 @@ uint32_t XStaticUntypedEnumerator::WriteItems(uint8_t* buffer_data,
return X_ERROR_NO_MORE_FILES;
}
// 4E4D07F0 does not respect buffer_size for XContentCreateEnumerator.
assert_false(buffer_size < item_size());
const size_t available_count = buffer_size / item_size();
@@ -215,6 +214,8 @@ uint32_t XMPCreateUserPlaylistEnumerator::WriteItems(uint8_t* buffer_data,
std::copy_n(items_.begin() + current_item_, valid_count, results);
current_item_ += valid_count;
if (written_count) {
*written_count = static_cast<uint32_t>(valid_count);
}
@@ -222,5 +223,53 @@ uint32_t XMPCreateUserPlaylistEnumerator::WriteItems(uint8_t* buffer_data,
return X_ERROR_SUCCESS;
}
uint32_t ProfileEnumerator::WriteItems(uint8_t* buffer_data,
uint32_t buffer_size,
uint32_t* written_count) {
const size_t actual_count =
std::min(items_.size() - current_item_, items_per_enumerate());
if (!actual_count) {
return X_ERROR_NO_MORE_FILES;
}
// FFFE07D1 provides buffer_size of 0.
xam::X_PROFILEENUMRESULT* profiles =
reinterpret_cast<xam::X_PROFILEENUMRESULT*>(buffer_data);
std::copy_n(items_.begin() + current_item_, actual_count, profiles);
current_item_ += actual_count;
if (written_count) {
*written_count = static_cast<uint32_t>(actual_count);
}
return X_ERROR_SUCCESS;
}
uint32_t ContentEnumerator::WriteItems(uint8_t* buffer_data,
uint32_t buffer_size,
uint32_t* written_count) {
const size_t actual_count =
std::min(items_.size() - current_item_, items_per_enumerate());
if (!actual_count) {
return X_ERROR_NO_MORE_FILES;
}
// 4E4D07F0 does not respect buffer_size, possibly bug?
xam::XCONTENT_DATA* contents =
reinterpret_cast<xam::XCONTENT_DATA*>(buffer_data);
std::copy_n(items_.begin() + current_item_, actual_count, contents);
current_item_ += actual_count;
if (written_count) {
*written_count = static_cast<uint32_t>(actual_count);
}
return X_ERROR_SUCCESS;
}
} // namespace kernel
} // namespace xe

View File

@@ -13,6 +13,7 @@
#include <vector>
#include "xenia/kernel/xam/achievement_manager.h"
#include "xenia/kernel/xam/content_manager.h"
#include "xenia/kernel/xam/user_tracker.h"
#include "xenia/kernel/xam/xam.h"
#include "xenia/kernel/xobject.h"
@@ -224,7 +225,8 @@ class XMPCreateUserPlaylistEnumerator : public XEnumerator {
public:
XMPCreateUserPlaylistEnumerator(KernelState* kernel_state,
size_t items_per_enumerate)
: XEnumerator(kernel_state, items_per_enumerate, 0) {}
: XEnumerator(kernel_state, items_per_enumerate,
sizeof(xam::XMP_USER_PLAYLIST_INFO)) {}
size_t item_count() const { return items_.size(); }
@@ -240,6 +242,44 @@ class XMPCreateUserPlaylistEnumerator : public XEnumerator {
size_t current_item_ = 0;
};
class ProfileEnumerator : public XEnumerator {
public:
ProfileEnumerator(KernelState* kernel_state, size_t items_per_enumerate)
: XEnumerator(kernel_state, items_per_enumerate,
sizeof(xam::X_PROFILEENUMRESULT)) {}
size_t item_count() const { return items_.size(); }
void AppendItem(const xam::X_PROFILEENUMRESULT& item) {
items_.push_back(item);
}
uint32_t WriteItems(uint8_t* buffer_data, uint32_t buffer_size,
uint32_t* written_count) override;
private:
std::vector<xam::X_PROFILEENUMRESULT> items_;
size_t current_item_ = 0;
};
class ContentEnumerator : public XEnumerator {
public:
ContentEnumerator(KernelState* kernel_state, size_t items_per_enumerate)
: XEnumerator(kernel_state, items_per_enumerate,
sizeof(xam::XCONTENT_DATA)) {}
size_t item_count() const { return items_.size(); }
void AppendItem(const xam::XCONTENT_DATA& item) { items_.push_back(item); }
uint32_t WriteItems(uint8_t* buffer_data, uint32_t buffer_size,
uint32_t* written_count) override;
private:
std::vector<xam::XCONTENT_DATA> items_;
size_t current_item_ = 0;
};
} // namespace kernel
} // namespace xe