[XAM/User] Add extra checks to XamReadTile, remove GetTitleSpa
GetTitleGpd should work fine for what we're using it for here... it could be a good idea to keep an instance of the current SpaFile of the running title and have a GetTitleSpa that returns that though, since I think some stuff like XamReadString might eventually need access to SPA data, not really sure yet though.
This commit is contained in:
parent
598cff4b50
commit
6caf986153
|
@ -570,23 +570,6 @@ bool UserProfile::AddSettingIfNotExist(xdbf::Setting& setting) {
|
||||||
|
|
||||||
xdbf::GpdFile* UserProfile::GetDashboardGpd() { return &dash_gpd_; }
|
xdbf::GpdFile* UserProfile::GetDashboardGpd() { return &dash_gpd_; }
|
||||||
|
|
||||||
xdbf::SpaFile* UserProfile::GetTitleSpa(uint32_t title_id) {
|
|
||||||
std::wstring file_location = xe::to_wstring(cvars::profile_directory) +
|
|
||||||
format_string(L"%X", title_id) + L".gpd";
|
|
||||||
|
|
||||||
auto mmap_ = MappedMemory::Open(file_location, MappedMemory::Mode::kRead);
|
|
||||||
|
|
||||||
if (!mmap_) {
|
|
||||||
return (nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
xdbf::SpaFile* game_entry = new xdbf::SpaFile();
|
|
||||||
game_entry->Read(mmap_->data(), mmap_->size());
|
|
||||||
mmap_->Close();
|
|
||||||
|
|
||||||
return (game_entry);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace xam
|
} // namespace xam
|
||||||
} // namespace kernel
|
} // namespace kernel
|
||||||
} // namespace xe
|
} // namespace xe
|
||||||
|
|
|
@ -147,7 +147,6 @@ class UserProfile {
|
||||||
xdbf::GpdFile* SetTitleSpaData(const xdbf::SpaFile& spa_data);
|
xdbf::GpdFile* SetTitleSpaData(const xdbf::SpaFile& spa_data);
|
||||||
xdbf::GpdFile* GetTitleGpd(uint32_t title_id = -1);
|
xdbf::GpdFile* GetTitleGpd(uint32_t title_id = -1);
|
||||||
xdbf::GpdFile* GetDashboardGpd();
|
xdbf::GpdFile* GetDashboardGpd();
|
||||||
xdbf::SpaFile* GetTitleSpa(uint32_t title_id);
|
|
||||||
|
|
||||||
void GetTitles(std::vector<xdbf::GpdFile*>& titles);
|
void GetTitles(std::vector<xdbf::GpdFile*>& titles);
|
||||||
|
|
||||||
|
|
|
@ -754,44 +754,80 @@ dword_result_t XamUserCreateTitlesPlayedEnumerator(
|
||||||
DECLARE_XAM_EXPORT1(XamUserCreateTitlesPlayedEnumerator, kUserProfiles,
|
DECLARE_XAM_EXPORT1(XamUserCreateTitlesPlayedEnumerator, kUserProfiles,
|
||||||
kImplemented);
|
kImplemented);
|
||||||
|
|
||||||
dword_result_t XamReadTile(dword_t section_id, dword_t game_id, qword_t item_id,
|
// https://github.com/jogolden/testdev/blob/master/xkelib/xam/_xamext.h#L68
|
||||||
|
enum class XTileType {
|
||||||
|
kAchievement,
|
||||||
|
kGameIcon,
|
||||||
|
kGamerTile,
|
||||||
|
kGamerTileSmall,
|
||||||
|
kLocalGamerTile,
|
||||||
|
kLocalGamerTileSmall,
|
||||||
|
kBkgnd,
|
||||||
|
kAwardedGamerTile,
|
||||||
|
kAwardedGamerTileSmall,
|
||||||
|
kGamerTileByImageId,
|
||||||
|
kPersonalGamerTile,
|
||||||
|
kPersonalGamerTileSmall,
|
||||||
|
kGamerTileByKey,
|
||||||
|
kAvatarGamerTile,
|
||||||
|
kAvatarGamerTileSmall,
|
||||||
|
kAvatarFullBody
|
||||||
|
};
|
||||||
|
|
||||||
|
dword_result_t XamReadTile(dword_t tile_type, dword_t game_id, qword_t item_id,
|
||||||
dword_t offset, lpdword_t output_ptr,
|
dword_t offset, lpdword_t output_ptr,
|
||||||
lpdword_t buffer_size_ptr, dword_t overlapped) {
|
lpdword_t buffer_size_ptr, dword_t overlapped_ptr) {
|
||||||
uint32_t buffer_size = buffer_size_ptr ? *buffer_size_ptr : 0;
|
if (!output_ptr || !buffer_size_ptr) {
|
||||||
|
|
||||||
if (!output_ptr) {
|
|
||||||
return X_ERROR_FILE_NOT_FOUND;
|
return X_ERROR_FILE_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
SpaFile* game_spa =
|
uint64_t image_id = item_id;
|
||||||
kernel_state()->user_profile()->GetTitleSpa(game_id.value());
|
|
||||||
|
|
||||||
if (!game_spa) {
|
auto type = (XTileType)tile_type.value();
|
||||||
|
if (type == XTileType::kPersonalGamerTile) {
|
||||||
|
// TODO: read pic from profile dir, it's stored as a .png file
|
||||||
|
// image_id = XUID of profile to retrieve from
|
||||||
|
image_id = (uint64_t)SpaID::Title; // return dash image for now
|
||||||
|
}
|
||||||
|
|
||||||
|
auto gpd = kernel_state()->user_profile()->GetTitleGpd(game_id.value());
|
||||||
|
|
||||||
|
if (!gpd) {
|
||||||
return X_ERROR_FILE_NOT_FOUND;
|
return X_ERROR_FILE_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Section 2 == images
|
auto entry =
|
||||||
Entry* entry =
|
gpd->GetEntry(static_cast<uint16_t>(xdbf::GpdSection::kImage), image_id);
|
||||||
game_spa->GetEntry((uint16_t)SpaSection::kImage, item_id.value());
|
|
||||||
|
|
||||||
if (!buffer_size) {
|
if (!entry) {
|
||||||
buffer_size = entry->info.size;
|
return X_ERROR_FILE_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy_s(output_ptr, entry->info.size, entry->data.data(), entry->info.size);
|
auto passed_size = *buffer_size_ptr;
|
||||||
|
*buffer_size_ptr = (uint32_t)entry->data.size();
|
||||||
|
|
||||||
if (overlapped) {
|
uint32_t ret_val = X_ERROR_INVALID_PARAMETER;
|
||||||
kernel_state()->CompleteOverlappedImmediate(overlapped, X_ERROR_SUCCESS);
|
|
||||||
|
if (passed_size >= *buffer_size_ptr) {
|
||||||
|
memcpy_s(output_ptr, *buffer_size_ptr, entry->data.data(),
|
||||||
|
entry->data.size());
|
||||||
|
ret_val = X_ERROR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (overlapped_ptr) {
|
||||||
|
kernel_state()->CompleteOverlappedImmediate(overlapped_ptr, ret_val);
|
||||||
return X_ERROR_IO_PENDING;
|
return X_ERROR_IO_PENDING;
|
||||||
}
|
}
|
||||||
return X_ERROR_SUCCESS;
|
return ret_val;
|
||||||
}
|
}
|
||||||
DECLARE_XAM_EXPORT1(XamReadTile, kUserProfiles, kSketchy);
|
DECLARE_XAM_EXPORT1(XamReadTile, kUserProfiles, kSketchy);
|
||||||
|
|
||||||
dword_result_t XamReadTileEx(dword_t section_id, dword_t game_id,
|
dword_result_t XamReadTileEx(dword_t section_id, dword_t game_id,
|
||||||
qword_t item_id, dword_t offset, dword_t unk1,
|
qword_t item_id, dword_t offset, dword_t unk1,
|
||||||
dword_t unk2, lpdword_t output_ptr) {
|
dword_t unk2, lpdword_t output_ptr,
|
||||||
return XamReadTile(section_id, game_id, item_id, offset, output_ptr, 0, 0);
|
lpdword_t buffer_size_ptr) {
|
||||||
|
return XamReadTile(section_id, game_id, item_id, offset, output_ptr,
|
||||||
|
buffer_size_ptr, 0);
|
||||||
}
|
}
|
||||||
DECLARE_XAM_EXPORT1(XamReadTileEx, kUserProfiles, kSketchy);
|
DECLARE_XAM_EXPORT1(XamReadTileEx, kUserProfiles, kSketchy);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue