diff --git a/DiscImageChef.Core/Devices/Dumping/XGD.cs b/DiscImageChef.Core/Devices/Dumping/XGD.cs
index dd4569da1..f181ff86a 100644
--- a/DiscImageChef.Core/Devices/Dumping/XGD.cs
+++ b/DiscImageChef.Core/Devices/Dumping/XGD.cs
@@ -53,14 +53,10 @@ using TrackType = DiscImageChef.CommonTypes.Enums.TrackType;
namespace DiscImageChef.Core.Devices.Dumping
{
- ///
- /// Implements dumping an Xbox Game Disc using a Kreon drive
- ///
+ /// Implements dumping an Xbox Game Disc using a Kreon drive
partial class Dump
{
- ///
- /// Dumps an Xbox Game Disc using a Kreon drive
- ///
+ /// Dumps an Xbox Game Disc using a Kreon drive
/// Media tags as retrieved in MMC layer
/// Disc type as detected in MMC layer
internal void Xgd(Dictionary mediaTags, ref MediaType dskType)
@@ -75,26 +71,33 @@ namespace DiscImageChef.Core.Devices.Dumping
double maxSpeed = double.MinValue;
double minSpeed = double.MaxValue;
- if(mediaTags.ContainsKey(MediaTagType.DVD_PFI)) mediaTags.Remove(MediaTagType.DVD_PFI);
- if(mediaTags.ContainsKey(MediaTagType.DVD_DMI)) mediaTags.Remove(MediaTagType.DVD_DMI);
+ if(mediaTags.ContainsKey(MediaTagType.DVD_PFI))
+ mediaTags.Remove(MediaTagType.DVD_PFI);
+
+ if(mediaTags.ContainsKey(MediaTagType.DVD_DMI))
+ mediaTags.Remove(MediaTagType.DVD_DMI);
UpdateStatus?.Invoke("Reading Xbox Security Sector.");
dumpLog.WriteLine("Reading Xbox Security Sector.");
sense = dev.KreonExtractSs(out byte[] ssBuf, out byte[] senseBuf, dev.Timeout, out _);
+
if(sense)
{
dumpLog.WriteLine("Cannot get Xbox Security Sector, not continuing.");
StoppingErrorMessage?.Invoke("Cannot get Xbox Security Sector, not continuing.");
+
return;
}
dumpLog.WriteLine("Decoding Xbox Security Sector.");
UpdateStatus?.Invoke("Decoding Xbox Security Sector.");
SS.SecuritySector? xboxSs = SS.Decode(ssBuf);
+
if(!xboxSs.HasValue)
{
dumpLog.WriteLine("Cannot decode Xbox Security Sector, not continuing.");
StoppingErrorMessage?.Invoke("Cannot decode Xbox Security Sector, not continuing.");
+
return;
}
@@ -107,33 +110,41 @@ namespace DiscImageChef.Core.Devices.Dumping
UpdateStatus?.Invoke("Locking drive.");
dumpLog.WriteLine("Locking drive.");
sense = dev.KreonLock(out senseBuf, dev.Timeout, out _);
+
if(sense)
{
dumpLog.WriteLine("Cannot lock drive, not continuing.");
StoppingErrorMessage?.Invoke("Cannot lock drive, not continuing.");
+
return;
}
UpdateStatus?.Invoke("Getting video partition size.");
dumpLog.WriteLine("Getting video partition size.");
sense = dev.ReadCapacity(out byte[] readBuffer, out senseBuf, dev.Timeout, out _);
+
if(sense)
{
dumpLog.WriteLine("Cannot get disc capacity.");
StoppingErrorMessage?.Invoke("Cannot get disc capacity.");
+
return;
}
ulong totalSize =
(ulong)((readBuffer[0] << 24) + (readBuffer[1] << 16) + (readBuffer[2] << 8) + readBuffer[3]);
+
UpdateStatus?.Invoke("Reading Physical Format Information.");
dumpLog.WriteLine("Reading Physical Format Information.");
+
sense = dev.ReadDiscStructure(out readBuffer, out senseBuf, MmcDiscStructureMediaType.Dvd, 0, 0,
MmcDiscStructureFormat.PhysicalInformation, 0, 0, out _);
+
if(sense)
{
dumpLog.WriteLine("Cannot get PFI.");
StoppingErrorMessage?.Invoke("Cannot get PFI.");
+
return;
}
@@ -141,17 +152,22 @@ namespace DiscImageChef.Core.Devices.Dumping
Array.Copy(readBuffer, 4, tmpBuf, 0, readBuffer.Length - 4);
mediaTags.Add(MediaTagType.DVD_PFI, tmpBuf);
DicConsole.DebugWriteLine("Dump-media command", "Video partition total size: {0} sectors", totalSize);
+
ulong l0Video = PFI.Decode(readBuffer).Value.Layer0EndPSN - PFI.Decode(readBuffer).Value.DataAreaStartPSN +
1;
+
ulong l1Video = totalSize - l0Video + 1;
UpdateStatus?.Invoke("Reading Disc Manufacturing Information.");
dumpLog.WriteLine("Reading Disc Manufacturing Information.");
+
sense = dev.ReadDiscStructure(out readBuffer, out senseBuf, MmcDiscStructureMediaType.Dvd, 0, 0,
MmcDiscStructureFormat.DiscManufacturingInformation, 0, 0, out _);
+
if(sense)
{
dumpLog.WriteLine("Cannot get DMI.");
StoppingErrorMessage?.Invoke("Cannot get DMI.");
+
return;
}
@@ -164,25 +180,30 @@ namespace DiscImageChef.Core.Devices.Dumping
UpdateStatus?.Invoke("Unlocking drive (Xtreme).");
dumpLog.WriteLine("Unlocking drive (Xtreme).");
sense = dev.KreonUnlockXtreme(out senseBuf, dev.Timeout, out _);
+
if(sense)
{
dumpLog.WriteLine("Cannot unlock drive, not continuing.");
StoppingErrorMessage?.Invoke("Cannot unlock drive, not continuing.");
+
return;
}
UpdateStatus?.Invoke("Getting game partition size.");
dumpLog.WriteLine("Getting game partition size.");
sense = dev.ReadCapacity(out readBuffer, out senseBuf, dev.Timeout, out _);
+
if(sense)
{
dumpLog.WriteLine("Cannot get disc capacity.");
StoppingErrorMessage?.Invoke("Cannot get disc capacity.");
+
return;
}
ulong gameSize =
(ulong)((readBuffer[0] << 24) + (readBuffer[1] << 16) + (readBuffer[2] << 8) + readBuffer[3]) + 1;
+
DicConsole.DebugWriteLine("Dump-media command", "Game partition total size: {0} sectors", gameSize);
// Get middle zone size
@@ -190,41 +211,52 @@ namespace DiscImageChef.Core.Devices.Dumping
UpdateStatus?.Invoke("Unlocking drive (Wxripper).");
dumpLog.WriteLine("Unlocking drive (Wxripper).");
sense = dev.KreonUnlockWxripper(out senseBuf, dev.Timeout, out _);
+
if(sense)
{
dumpLog.WriteLine("Cannot unlock drive, not continuing.");
StoppingErrorMessage?.Invoke("Cannot unlock drive, not continuing.");
+
return;
}
UpdateStatus?.Invoke("Getting disc size.");
dumpLog.WriteLine("Getting disc size.");
sense = dev.ReadCapacity(out readBuffer, out senseBuf, dev.Timeout, out _);
+
if(sense)
{
dumpLog.WriteLine("Cannot get disc capacity.");
StoppingErrorMessage?.Invoke("Cannot get disc capacity.");
+
return;
}
totalSize = (ulong)((readBuffer[0] << 24) + (readBuffer[1] << 16) + (readBuffer[2] << 8) + readBuffer[3]);
UpdateStatus?.Invoke("Reading Physical Format Information.");
dumpLog.WriteLine("Reading Physical Format Information.");
+
sense = dev.ReadDiscStructure(out readBuffer, out senseBuf, MmcDiscStructureMediaType.Dvd, 0, 0,
MmcDiscStructureFormat.PhysicalInformation, 0, 0, out _);
+
if(sense)
{
dumpLog.WriteLine("Cannot get PFI.");
StoppingErrorMessage?.Invoke("Cannot get PFI.");
+
return;
}
DicConsole.DebugWriteLine("Dump-media command", "Unlocked total size: {0} sectors", totalSize);
- ulong blocks = totalSize + 1;
- ulong middleZone =
- totalSize - (PFI.Decode(readBuffer).Value.Layer0EndPSN -
- PFI.Decode(readBuffer).Value.DataAreaStartPSN +
- 1) - gameSize + 1;
+ ulong blocks = totalSize + 1;
+ PFI.PhysicalFormatInformation wxRipperPfi = PFI.Decode(readBuffer).Value;
+
+ UpdateStatus?.Invoke($"WxRipper PFI's Data Area Start PSN: {wxRipperPfi.DataAreaStartPSN} sectors");
+ UpdateStatus?.Invoke($"WxRipper PFI's Layer 0 End PSN: {wxRipperPfi.Layer0EndPSN} sectors");
+ dumpLog.WriteLine($"WxRipper PFI's Data Area Start PSN: {wxRipperPfi.DataAreaStartPSN} sectors");
+ dumpLog.WriteLine($"WxRipper PFI's Layer 0 End PSN: {wxRipperPfi.Layer0EndPSN} sectors");
+
+ ulong middleZone = totalSize - (wxRipperPfi.Layer0EndPSN - wxRipperPfi.DataAreaStartPSN + 1) - gameSize + 1;
tmpBuf = new byte[readBuffer.Length - 4];
Array.Copy(readBuffer, 4, tmpBuf, 0, readBuffer.Length - 4);
@@ -232,12 +264,15 @@ namespace DiscImageChef.Core.Devices.Dumping
UpdateStatus?.Invoke("Reading Disc Manufacturing Information.");
dumpLog.WriteLine("Reading Disc Manufacturing Information.");
+
sense = dev.ReadDiscStructure(out readBuffer, out senseBuf, MmcDiscStructureMediaType.Dvd, 0, 0,
MmcDiscStructureFormat.DiscManufacturingInformation, 0, 0, out _);
+
if(sense)
{
dumpLog.WriteLine("Cannot get DMI.");
StoppingErrorMessage?.Invoke("Cannot get DMI.");
+
return;
}
@@ -259,16 +294,18 @@ namespace DiscImageChef.Core.Devices.Dumping
dumpLog.WriteLine("Video layer 0 size: {0} sectors", l0Video);
dumpLog.WriteLine("Video layer 1 size: {0} sectors", l1Video);
dumpLog.WriteLine("Middle zone 0 size: {0} sectors", middleZone);
- dumpLog.WriteLine("Game data 0 size: {0} sectors", gameSize);
- dumpLog.WriteLine("Total 0 size: {0} sectors", totalSize);
- dumpLog.WriteLine("Real layer break: {0}", layerBreak);
+ dumpLog.WriteLine("Game data 0 size: {0} sectors", gameSize);
+ dumpLog.WriteLine("Total 0 size: {0} sectors", totalSize);
+ dumpLog.WriteLine("Real layer break: {0}", layerBreak);
bool read12 = !dev.Read12(out readBuffer, out senseBuf, 0, false, true, false, false, 0, BLOCK_SIZE, 0, 1,
false, dev.Timeout, out _);
+
if(!read12)
{
dumpLog.WriteLine("Cannot read medium, aborting scan...");
StoppingErrorMessage?.Invoke("Cannot read medium, aborting scan...");
+
return;
}
@@ -281,26 +318,33 @@ namespace DiscImageChef.Core.Devices.Dumping
{
sense = dev.Read12(out readBuffer, out senseBuf, 0, false, false, false, false, 0, BLOCK_SIZE, 0,
blocksToRead, false, dev.Timeout, out _);
- if(sense || dev.Error) blocksToRead /= 2;
+
+ if(sense || dev.Error)
+ blocksToRead /= 2;
}
- if(!dev.Error || blocksToRead == 1) break;
+ if(!dev.Error ||
+ blocksToRead == 1)
+ break;
}
if(dev.Error)
{
dumpLog.WriteLine("Device error {0} trying to guess ideal transfer length.", dev.LastError);
StoppingErrorMessage?.Invoke($"Device error {dev.LastError} trying to guess ideal transfer length.");
+
return;
}
- if(skip < blocksToRead) skip = blocksToRead;
+ if(skip < blocksToRead)
+ skip = blocksToRead;
bool ret = true;
foreach(MediaTagType tag in mediaTags.Keys)
{
- if(outputPlugin.SupportedMediaTags.Contains(tag)) continue;
+ if(outputPlugin.SupportedMediaTags.Contains(tag))
+ continue;
ret = false;
dumpLog.WriteLine($"Output format does not support {tag}.");
@@ -318,6 +362,7 @@ namespace DiscImageChef.Core.Devices.Dumping
{
dumpLog.WriteLine("Several media tags not supported, not continuing...");
StoppingErrorMessage?.Invoke("Several media tags not supported, not continuing...");
+
return;
}
}
@@ -325,8 +370,8 @@ namespace DiscImageChef.Core.Devices.Dumping
dumpLog.WriteLine("Reading {0} sectors at a time.", blocksToRead);
UpdateStatus?.Invoke($"Reading {blocksToRead} sectors at a time.");
- MhddLog mhddLog = new MhddLog(outputPrefix + ".mhddlog.bin", dev, blocks, BLOCK_SIZE, blocksToRead);
- IbgLog ibgLog = new IbgLog(outputPrefix + ".ibg", 0x0010);
+ var mhddLog = new MhddLog(outputPrefix + ".mhddlog.bin", dev, blocks, BLOCK_SIZE, blocksToRead);
+ var ibgLog = new IbgLog(outputPrefix + ".ibg", 0x0010);
ret = outputPlugin.Create(outputPath, dskType, formatOptions, blocks, BLOCK_SIZE);
// Cannot create image
@@ -334,8 +379,10 @@ namespace DiscImageChef.Core.Devices.Dumping
{
dumpLog.WriteLine("Error creating output image, not continuing.");
dumpLog.WriteLine(outputPlugin.ErrorMessage);
+
StoppingErrorMessage?.Invoke("Error creating output image, not continuing." + Environment.NewLine +
outputPlugin.ErrorMessage);
+
return;
}
@@ -346,27 +393,26 @@ namespace DiscImageChef.Core.Devices.Dumping
uint saveBlocksToRead = blocksToRead;
DumpHardwareType currentTry = null;
ExtentsULong extents = null;
+
ResumeSupport.Process(true, true, totalSize, dev.Manufacturer, dev.Model, dev.Serial, dev.PlatformId,
ref resume, ref currentTry, ref extents);
- if(currentTry == null || extents == null)
+
+ if(currentTry == null ||
+ extents == null)
StoppingErrorMessage?.Invoke("Could not process resume file, not continuing...");
(outputPlugin as IWritableOpticalImage).SetTracks(new List