[VFS] XContent: Added support for SVOD normal layout with multiple files

This commit is contained in:
Gliniak
2026-01-03 22:20:44 +01:00
committed by Radosław Gliński
parent 53c0178766
commit b8b33ecabf
2 changed files with 12 additions and 11 deletions

View File

@@ -93,7 +93,7 @@ XContentContainerDevice::Result SvodContainerDevice::Read() {
static_assert_size(root_data, 0x10); static_assert_size(root_data, 0x10);
if (fread(&root_data, sizeof(root_data), 1, svod_header) != 1) { if (fread(&root_data, sizeof(root_data), 1, svod_header) != 1) {
XELOGE("ReadSVOD failed to read root block data at 0x{X}", XELOGE("ReadSVOD failed to read root block data at 0x{:016X}",
magic_offset + 0x14); magic_offset + 0x14);
return Result::kReadError; return Result::kReadError;
} }
@@ -335,9 +335,11 @@ XContentContainerDevice::Result SvodContainerDevice::SetNormalLayout(
FILE* header, size_t& magic_offset) { FILE* header, size_t& magic_offset) {
uint8_t magic_buf[20]; uint8_t magic_buf[20];
xe::filesystem::Seek(header, 0xD000, SEEK_SET); const uint32_t magic_pos =
header_->content_metadata.data_file_count == 1 ? 0xD000 : 0x2000;
xe::filesystem::Seek(header, magic_pos, SEEK_SET);
if (fread(magic_buf, 1, countof(magic_buf), header) != countof(magic_buf)) { if (fread(magic_buf, 1, countof(magic_buf), header) != countof(magic_buf)) {
XELOGE("ReadSVOD failed to read SVOD magic at 0xD000"); XELOGE("ReadSVOD failed to read SVOD magic at 0x{:04X}", magic_pos);
return Result::kReadError; return Result::kReadError;
} }
@@ -350,18 +352,16 @@ XContentContainerDevice::Result SvodContainerDevice::SetNormalLayout(
// is a single-file system. The STFS Header is 0xB000 bytes and the // is a single-file system. The STFS Header is 0xB000 bytes and the
// remaining 0x2000 is from hash tables. In most cases, these will be // remaining 0x2000 is from hash tables. In most cases, these will be
// STFS, not SVOD. // STFS, not SVOD.
svod_base_offset_ = 0xB000;
magic_offset = 0xD000;
// Check for single file system
if (header_->content_metadata.data_file_count == 1) { if (header_->content_metadata.data_file_count == 1) {
svod_base_offset_ = 0xB000;
svod_layout_ = SvodLayoutType::kSingleFile; svod_layout_ = SvodLayoutType::kSingleFile;
XELOGI("SVOD is a single file. Magic block present at 0xD000."); XELOGI("SVOD is a single file. Magic block present at 0xD000.");
magic_offset = 0xD000;
} else { } else {
svod_layout_ = SvodLayoutType::kUnknown; svod_base_offset_ = 0x0000;
XELOGE( svod_layout_ = SvodLayoutType::kMultipleFiles;
"SVOD is not a single file, but the magic block was found at " XELOGI("SVOD is a multiple files. Magic block present at 0x2000.");
"0xD000."); magic_offset = 0x2000;
} }
return Result::kSuccess; return Result::kSuccess;
} }

View File

@@ -41,6 +41,7 @@ class SvodContainerDevice : public XContentContainerDevice {
kEnhancedGDF = 0x1, kEnhancedGDF = 0x1,
kXSF = 0x2, kXSF = 0x2,
kSingleFile = 0x4, kSingleFile = 0x4,
kMultipleFiles = 0x8,
}; };
const char* MEDIA_MAGIC = "MICROSOFT*XBOX*MEDIA"; const char* MEDIA_MAGIC = "MICROSOFT*XBOX*MEDIA";