[XAM] Allow content to read license from header
This commit is contained in:
parent
1cda06d5bf
commit
9e4b2e343f
|
@ -53,6 +53,26 @@ ContentPackage::~ContentPackage() {
|
|||
fs->UnregisterDevice(device_path_);
|
||||
}
|
||||
|
||||
void ContentPackage::LoadPackageLicenseMask(
|
||||
const std::filesystem::path header_path) {
|
||||
license_ = 0;
|
||||
|
||||
if (!std::filesystem::exists(header_path)) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto file = xe::filesystem::OpenFile(header_path, "rb");
|
||||
auto file_size = std::filesystem::file_size(header_path);
|
||||
if (file_size < sizeof(XCONTENT_AGGREGATE_DATA) + sizeof(license_)) {
|
||||
fclose(file);
|
||||
return;
|
||||
}
|
||||
|
||||
fseek(file, sizeof(XCONTENT_AGGREGATE_DATA), SEEK_SET);
|
||||
size_t result = fread(&license_, 1, sizeof(license_), file);
|
||||
fclose(file);
|
||||
}
|
||||
|
||||
ContentManager::ContentManager(KernelState* kernel_state,
|
||||
const std::filesystem::path& root_path)
|
||||
: kernel_state_(kernel_state), root_path_(root_path) {}
|
||||
|
@ -267,16 +287,17 @@ X_RESULT ContentManager::ReadContentHeaderFile(
|
|||
std::array<uint8_t, header_size> buffer;
|
||||
|
||||
auto file_size = std::filesystem::file_size(header_file_path);
|
||||
if (file_size != header_size && file_size != sizeof(XCONTENT_DATA)) {
|
||||
if (file_size < header_size) {
|
||||
fclose(file);
|
||||
return X_STATUS_END_OF_FILE;
|
||||
}
|
||||
|
||||
size_t result = fread(buffer.data(), 1, file_size, file);
|
||||
if (result != file_size) {
|
||||
size_t result = fread(buffer.data(), 1, header_size, file);
|
||||
if (result != header_size) {
|
||||
fclose(file);
|
||||
return X_STATUS_END_OF_FILE;
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
std::memcpy(&data, buffer.data(), buffer.size());
|
||||
// It only reads basic info, however importing savefiles
|
||||
|
@ -321,6 +342,7 @@ X_RESULT ContentManager::CreateContent(const std::string_view root_name,
|
|||
X_RESULT ContentManager::OpenContent(const std::string_view root_name,
|
||||
const uint64_t xuid,
|
||||
const XCONTENT_AGGREGATE_DATA& data,
|
||||
uint32_t& content_license,
|
||||
const uint32_t disc_number) {
|
||||
auto global_lock = global_critical_region_.Acquire();
|
||||
|
||||
|
@ -339,6 +361,11 @@ X_RESULT ContentManager::OpenContent(const std::string_view root_name,
|
|||
auto package = ResolvePackage(root_name, xuid, data, disc_number);
|
||||
assert_not_null(package);
|
||||
|
||||
package->LoadPackageLicenseMask(ResolvePackageHeaderPath(
|
||||
data.file_name(), xuid, kernel_state_->title_id(), data.content_type));
|
||||
|
||||
content_license = package->GetPackageLicense();
|
||||
|
||||
open_packages_.insert({string_key::create(root_name), package.release()});
|
||||
|
||||
return X_ERROR_SUCCESS;
|
||||
|
|
|
@ -125,15 +125,21 @@ class ContentPackage {
|
|||
const std::filesystem::path& package_path);
|
||||
~ContentPackage();
|
||||
|
||||
void LoadPackageLicenseMask(const std::filesystem::path header_path);
|
||||
|
||||
const XCONTENT_AGGREGATE_DATA& GetPackageContentData() const {
|
||||
return content_data_;
|
||||
}
|
||||
|
||||
const uint32_t GetPackageLicense() const { return license_; }
|
||||
|
||||
private:
|
||||
KernelState* kernel_state_;
|
||||
std::string root_name_;
|
||||
std::string device_path_;
|
||||
XCONTENT_AGGREGATE_DATA content_data_;
|
||||
uint32_t license_;
|
||||
;
|
||||
};
|
||||
|
||||
class ContentManager {
|
||||
|
@ -161,6 +167,7 @@ class ContentManager {
|
|||
const XCONTENT_AGGREGATE_DATA& data);
|
||||
X_RESULT OpenContent(const std::string_view root_name, const uint64_t xuid,
|
||||
const XCONTENT_AGGREGATE_DATA& data,
|
||||
uint32_t& content_license,
|
||||
const uint32_t disc_number = -1);
|
||||
X_RESULT CloseContent(const std::string_view root_name);
|
||||
X_RESULT GetContentThumbnail(const uint64_t xuid,
|
||||
|
|
|
@ -251,23 +251,19 @@ dword_result_t xeXamContentCreate(dword_t user_index, lpstring_t root_name,
|
|||
break;
|
||||
}
|
||||
|
||||
uint32_t content_license = 0;
|
||||
if (disposition == kDispositionState::Create) {
|
||||
result = content_manager->CreateContent(root_name, xuid, content_data);
|
||||
if (XSUCCEEDED(result)) {
|
||||
content_manager->WriteContentHeaderFile(xuid, &content_data);
|
||||
}
|
||||
} else if (disposition == kDispositionState::Open) {
|
||||
result = content_manager->OpenContent(root_name, xuid, content_data);
|
||||
result = content_manager->OpenContent(root_name, xuid, content_data,
|
||||
content_license);
|
||||
}
|
||||
|
||||
if (license_mask_ptr && XSUCCEEDED(result)) {
|
||||
*license_mask_ptr = 0; // Stub!
|
||||
|
||||
// Set license only for DLCs and XBLA titles
|
||||
if (content_data.content_type == xe::XContentType::kMarketplaceContent ||
|
||||
content_data.content_type == xe::XContentType::kArcadeTitle) {
|
||||
*license_mask_ptr = static_cast<uint32_t>(cvars::license_mask);
|
||||
}
|
||||
*license_mask_ptr = content_license;
|
||||
}
|
||||
|
||||
extended_error = X_HRESULT_FROM_WIN32(result);
|
||||
|
|
|
@ -64,6 +64,9 @@ class XContentContainerDevice : public Device {
|
|||
}
|
||||
|
||||
kernel::xam::XCONTENT_AGGREGATE_DATA content_header() const;
|
||||
uint32_t license_mask() const {
|
||||
return header_->content_header.licenses[0].license_bits;
|
||||
}
|
||||
|
||||
protected:
|
||||
XContentContainerDevice(const std::string_view mount_path,
|
||||
|
|
|
@ -437,8 +437,11 @@ void VirtualFileSystem::ExtractContentHeader(Device* device,
|
|||
auto file = xe::filesystem::OpenFile(header_path, "wb");
|
||||
kernel::xam::XCONTENT_AGGREGATE_DATA data =
|
||||
xcontent_device->content_header();
|
||||
uint32_t license_mask = xcontent_device->license_mask();
|
||||
|
||||
data.set_file_name(base_path.filename().string());
|
||||
fwrite(&data, 1, sizeof(kernel::xam::XCONTENT_AGGREGATE_DATA), file);
|
||||
fwrite(&license_mask, 1, sizeof(license_mask), file);
|
||||
fclose(file);
|
||||
}
|
||||
return;
|
||||
|
|
Loading…
Reference in New Issue