Skip to content

Commit

Permalink
Add xvdutil finds
Browse files Browse the repository at this point in the history
  • Loading branch information
emoose committed Mar 20, 2019
1 parent f95e041 commit 101f682
Show file tree
Hide file tree
Showing 3 changed files with 202 additions and 83 deletions.
47 changes: 37 additions & 10 deletions LibXboxOne/XVD/XVDEnums.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,17 +31,17 @@ public enum XvdContentType : uint
EraTools = 0x12,
SystemTools = 0x13,
SystemAux = 0x14,
SomethingSomething = 0x15,
Codec = 0x16,
Qaslt = 0x17,
AcousticModel = 0x15,
SystemCodecsVolume = 0x16,
QasltPackage = 0x17,
AppDlc = 0x18,
TitleDlc = 0x19,
UniversalDlc = 0x1A,
SystemData = 0x1B,
Test = 0x1C,
Unknown1D = 0x1D,
Kiosk = 0x1E,
Unknown20 = 0x20,
SystemDataVolume = 0x1B,
TestVolume = 0x1C,
HardwareTestVolume = 0x1D,
KioskContent = 0x1E,
HostProfiler = 0x20,
Uwa = 0x21,
Unknown22 = 0x22,
Unknown23 = 0x23,
Expand All @@ -53,9 +53,12 @@ public enum XvdContentType : uint
public enum XvcRegionFlags : uint
{
Resident = 1,
InitialPlay = 2, // might be 4, or maybe InitialPlay stuff in XvcInfo struct should be swapped with Preview
InitialPlay = 2,
Preview = 4,
FileSystemMetadata = 8
FileSystemMetadata = 8,
Present = 0x10,
OnDemand = 0x20,
Available = 0x40,
}

[Flags]
Expand All @@ -70,4 +73,28 @@ public enum XvdVolumeFlags : uint
RegionIdInXts = 0x40,
EraSpecific = 0x80
}

[Flags]
public enum XvcRegionPresenceInfo : byte
{
IsPresent = 1, // not set = "not present"
IsAvailable = 2, // not set = "unavailable"

//value >> 4 = discnum
Disc1 = 0x10,
Disc2 = 0x20,
Disc3 = 0x30,
Disc4 = 0x40,
Disc5 = 0x50,
Disc6 = 0x60,
Disc7 = 0x70,
Disc8 = 0x80,
Disc9 = 0x90,
Disc10 = 0xA0,
Disc11 = 0xB0,
Disc12 = 0xC0,
Disc13 = 0xD0,
Disc14 = 0xE0,
Disc15 = 0xF0
}
}
62 changes: 55 additions & 7 deletions LibXboxOne/XVD/XVDFile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,9 @@ public class XvdFile : IDisposable
public XvcInfo XvcInfo;

public List<XvcRegionHeader> RegionHeaders;
public List<XvcUpdateSegmentInfo> UpdateSegments;
public List<XvcUpdateSegment> UpdateSegments;
public List<XvcRegionSpecifier> RegionSpecifiers;
public List<XvcRegionPresenceInfo> RegionPresenceInfo;

public bool HashTreeValid = false;
public bool DataHashTreeValid = false;
Expand Down Expand Up @@ -640,6 +642,8 @@ public bool Save()

XvcInfo.RegionCount = (uint)RegionHeaders.Count;
XvcInfo.UpdateSegmentCount = (uint)UpdateSegments.Count;
if (RegionSpecifiers != null)
XvcInfo.RegionSpecifierCount = (uint)RegionSpecifiers.Count;

_io.Writer.WriteStruct(XvcInfo);

Expand All @@ -648,6 +652,10 @@ public bool Save()

for (int i = 0; i < XvcInfo.UpdateSegmentCount; i++)
_io.Writer.WriteStruct(UpdateSegments[i]);

if (RegionSpecifiers != null)
for (int i = 0; i < XvcInfo.RegionSpecifierCount; i++)
_io.Writer.WriteStruct(RegionSpecifiers[i]);
}

if (IsDataIntegrityEnabled)
Expand Down Expand Up @@ -686,9 +694,24 @@ public bool Load()
for (int i = 0; i < XvcInfo.RegionCount; i++)
RegionHeaders.Add(_io.Reader.ReadStruct<XvcRegionHeader>());

UpdateSegments = new List<XvcUpdateSegmentInfo>();
UpdateSegments = new List<XvcUpdateSegment>();
for (int i = 0; i < XvcInfo.UpdateSegmentCount; i++)
UpdateSegments.Add(_io.Reader.ReadStruct<XvcUpdateSegmentInfo>());
UpdateSegments.Add(_io.Reader.ReadStruct<XvcUpdateSegment>());

if(XvcInfo.Version >= 2) // RegionSpecifiers / RegionPresenseInfo only seems to be used on XvcInfo v2
{
RegionSpecifiers = new List<XvcRegionSpecifier>();
for (int i = 0; i < XvcInfo.RegionSpecifierCount; i++)
RegionSpecifiers.Add(_io.Reader.ReadStruct<XvcRegionSpecifier>());

if(Header.NumMDUPages > 0)
{
RegionPresenceInfo = new List<XvcRegionPresenceInfo>();
_io.Stream.Position = (long)MduOffset;
for (int i = 0; i < XvcInfo.RegionCount; i++)
RegionPresenceInfo.Add((XvcRegionPresenceInfo)_io.Reader.ReadByte());
}
}
}
}

Expand Down Expand Up @@ -725,6 +748,10 @@ public bool VerifyXvcHash(bool rehash = false)
for (int i = 0; i < XvcInfo.UpdateSegmentCount; i++)
msIo.Writer.WriteStruct(UpdateSegments[i]);

if (RegionSpecifiers != null)
for (int i = 0; i < XvcInfo.RegionSpecifierCount; i++)
msIo.Writer.WriteStruct(RegionSpecifiers[i]);

msIo.Stream.SetLength(Header.XvcDataLength);

// fix region headers to match pre-hashtable
Expand Down Expand Up @@ -810,7 +837,7 @@ public bool AddHashTree()
else if (header.Offset > HashTreeOffset)
header.Offset += (ulong) hashTreeSize;

header.RegionPDUID = 0;
header.Hash = 0;
}
}

Expand Down Expand Up @@ -857,7 +884,7 @@ public bool RemoveHashTree()
else if (newHdr.Offset > HashTreeOffset)
newHdr.Offset -= (ulong)hashTreeSize;

newHdr.RegionPDUID = 0;
newHdr.Hash = 0;

RegionHeaders[i] = newHdr;
}
Expand Down Expand Up @@ -1288,20 +1315,41 @@ public string ToString(bool formatted)
for (int i = 0; i < RegionHeaders.Count; i++)
{
b.AppendLine();
b.AppendLine("Region " + i);
string presenceInfo = "";
if (RegionPresenceInfo != null)
{
var presenceFlags = RegionPresenceInfo[i];
presenceInfo = " (";
presenceInfo += (presenceFlags.HasFlag(XvcRegionPresenceInfo.IsPresent) ? "present" : "not present") + ", ";
presenceInfo += presenceFlags.HasFlag(XvcRegionPresenceInfo.IsAvailable) ? "available" : "unavailable";
if (((int)presenceFlags & 0xF0) != 0)
{
presenceInfo += $", on disc {(int)presenceFlags >> 4}";
}
presenceInfo += ")";
}
b.AppendLine($"Region {i}{presenceInfo}");
b.Append(RegionHeaders[i].ToString(formatted));
}

if (UpdateSegments != null)
for (int i = 0; i < UpdateSegments.Count; i++)
{
if (UpdateSegments[i].Unknown1 == 0)
if (UpdateSegments[i].Hash == 0)
break;
b.AppendLine();
b.AppendLine("Update Segment " + i);
b.Append(UpdateSegments[i].ToString(formatted));
}

if (RegionSpecifiers != null)
for (int i = 0; i < RegionSpecifiers.Count; i++)
{
b.AppendLine();
b.AppendLine("RegionSpecifier " + i);
b.Append(RegionSpecifiers[i].ToString(formatted));
}

return b.ToString();
}
#endregion
Expand Down
Loading

0 comments on commit 101f682

Please sign in to comment.