REFACTOR: Possible 'System.InvalidOperationException'.

This commit is contained in:
2017-12-21 17:10:37 +00:00
parent e06c140e45
commit 13a6473236
5 changed files with 1964 additions and 1956 deletions

View File

@@ -83,225 +83,164 @@ namespace DiscImageChef.Core.Devices.Dumping
sense = dev.AtaIdentify(out byte[] cmdBuf, out AtaErrorRegistersCHS errorChs); sense = dev.AtaIdentify(out byte[] cmdBuf, out AtaErrorRegistersCHS errorChs);
if(!sense && Identify.Decode(cmdBuf).HasValue) if(!sense && Identify.Decode(cmdBuf).HasValue)
{ {
Identify.IdentifyDevice ataId = Identify.Decode(cmdBuf).Value; Identify.IdentifyDevice? ataIdNullable = Identify.Decode(cmdBuf);
if(ataIdNullable != null) {
Identify.IdentifyDevice ataId = ataIdNullable.Value;
CICMMetadataType sidecar = CICMMetadataType sidecar =
new CICMMetadataType {BlockMedia = new[] {new BlockMediaType()}}; new CICMMetadataType {BlockMedia = new[] {new BlockMediaType()}};
if(dev.IsUsb) if(dev.IsUsb)
{
dumpLog.WriteLine("Reading USB descriptors.");
sidecar.BlockMedia[0].USB = new USBType
{ {
ProductID = dev.UsbProductId, dumpLog.WriteLine("Reading USB descriptors.");
VendorID = dev.UsbVendorId, sidecar.BlockMedia[0].USB = new USBType
Descriptors = new DumpType
{ {
Image = outputPrefix + ".usbdescriptors.bin", ProductID = dev.UsbProductId,
Size = dev.UsbDescriptors.Length, VendorID = dev.UsbVendorId,
Checksums = Checksum.GetChecksums(dev.UsbDescriptors).ToArray() Descriptors = new DumpType
} {
}; Image = outputPrefix + ".usbdescriptors.bin",
DataFile.WriteTo("ATA Dump", sidecar.BlockMedia[0].USB.Descriptors.Image, dev.UsbDescriptors); Size = dev.UsbDescriptors.Length,
} Checksums = Checksum.GetChecksums(dev.UsbDescriptors).ToArray()
if(dev.IsPcmcia)
{
dumpLog.WriteLine("Reading PCMCIA CIS.");
sidecar.BlockMedia[0].PCMCIA = new PCMCIAType
{
CIS = new DumpType
{
Image = outputPrefix + ".cis.bin",
Size = dev.Cis.Length,
Checksums = Checksum.GetChecksums(dev.Cis).ToArray()
}
};
DataFile.WriteTo("ATA Dump", sidecar.BlockMedia[0].PCMCIA.CIS.Image, dev.Cis);
dumpLog.WriteLine("Decoding PCMCIA CIS.");
Tuple[] tuples = CIS.GetTuples(dev.Cis);
if(tuples != null)
foreach(Tuple tuple in tuples)
switch(tuple.Code) {
case TupleCodes.CISTPL_MANFID:
ManufacturerIdentificationTuple manfid =
CIS.DecodeManufacturerIdentificationTuple(tuple);
if(manfid != null)
{
sidecar.BlockMedia[0].PCMCIA.ManufacturerCode = manfid.ManufacturerID;
sidecar.BlockMedia[0].PCMCIA.CardCode = manfid.CardID;
sidecar.BlockMedia[0].PCMCIA.ManufacturerCodeSpecified = true;
sidecar.BlockMedia[0].PCMCIA.CardCodeSpecified = true;
}
break;
case TupleCodes.CISTPL_VERS_1:
Level1VersionTuple vers = CIS.DecodeLevel1VersionTuple(tuple);
if(vers != null)
{
sidecar.BlockMedia[0].PCMCIA.Manufacturer = vers.Manufacturer;
sidecar.BlockMedia[0].PCMCIA.ProductName = vers.Product;
sidecar.BlockMedia[0].PCMCIA.Compliance =
string.Format("{0}.{1}", vers.MajorVersion, vers.MinorVersion);
sidecar.BlockMedia[0].PCMCIA.AdditionalInformation = vers.AdditionalInformation;
}
break;
} }
} };
DataFile.WriteTo("ATA Dump", sidecar.BlockMedia[0].USB.Descriptors.Image, dev.UsbDescriptors);
sidecar.BlockMedia[0].ATA = new ATAType
{
Identify = new DumpType
{
Image = outputPrefix + ".identify.bin",
Size = cmdBuf.Length,
Checksums = Checksum.GetChecksums(cmdBuf).ToArray()
}
};
DataFile.WriteTo("ATA Dump", sidecar.BlockMedia[0].ATA.Identify.Image, cmdBuf);
DateTime start;
DateTime end;
double totalDuration = 0;
double totalChkDuration = 0;
double currentSpeed = 0;
double maxSpeed = double.MinValue;
double minSpeed = double.MaxValue;
Checksum dataChk;
aborted = false;
System.Console.CancelKeyPress += (sender, e) => { e.Cancel = aborted = true; };
DataFile dumpFile;
// Initializate reader
dumpLog.WriteLine("Initializing reader.");
Reader ataReader = new Reader(dev, timeout, cmdBuf);
// Fill reader blocks
ulong blocks = ataReader.GetDeviceBlocks();
// Check block sizes
if(ataReader.GetBlockSize())
{
dumpLog.WriteLine("ERROR: Cannot get block size: {0}.", ataReader.ErrorMessage);
DicConsole.ErrorWriteLine(ataReader.ErrorMessage);
return;
}
uint blockSize = ataReader.LogicalBlockSize;
uint physicalsectorsize = ataReader.PhysicalBlockSize;
if(ataReader.FindReadCommand())
{
dumpLog.WriteLine("ERROR: Cannot find correct read command: {0}.", ataReader.ErrorMessage);
DicConsole.ErrorWriteLine(ataReader.ErrorMessage);
return;
}
// Check how many blocks to read, if error show and return
if(ataReader.GetBlocksToRead())
{
dumpLog.WriteLine("ERROR: Cannot get blocks to read: {0}.", ataReader.ErrorMessage);
DicConsole.ErrorWriteLine(ataReader.ErrorMessage);
return;
}
uint blocksToRead = ataReader.BlocksToRead;
ushort cylinders = ataReader.Cylinders;
byte heads = ataReader.Heads;
byte sectors = ataReader.Sectors;
dumpLog.WriteLine("Device reports {0} blocks ({1} bytes).", blocks, blocks * blockSize);
dumpLog.WriteLine("Device reports {0} cylinders {1} heads {2} sectors per track.", cylinders, heads,
sectors);
dumpLog.WriteLine("Device can read {0} blocks at a time.", blocksToRead);
dumpLog.WriteLine("Device reports {0} bytes per logical block.", blockSize);
dumpLog.WriteLine("Device reports {0} bytes per physical block.", physicalsectorsize);
bool removable = false || !dev.IsCompactFlash &&
ataId.GeneralConfiguration.HasFlag(Identify.GeneralConfigurationBit
.Removable);
DumpHardwareType currentTry = null;
ExtentsULong extents = null;
ResumeSupport.Process(ataReader.IsLba, removable, blocks, dev.Manufacturer, dev.Model, dev.Serial,
dev.PlatformId, ref resume, ref currentTry, ref extents);
if(currentTry == null || extents == null)
throw new Exception("Could not process resume file, not continuing...");
if(ataReader.IsLba)
{
DicConsole.WriteLine("Reading {0} sectors at a time.", blocksToRead);
mhddLog = new MhddLog(outputPrefix + ".mhddlog.bin", dev, blocks, blockSize, blocksToRead);
ibgLog = new IbgLog(outputPrefix + ".ibg", currentProfile);
dumpFile = new DataFile(outputPrefix + ".bin");
if(resume.NextBlock > 0) dumpLog.WriteLine("Resuming from block {0}.", resume.NextBlock);
dumpFile.Seek(resume.NextBlock, blockSize);
start = DateTime.UtcNow;
for(ulong i = resume.NextBlock; i < blocks; i += blocksToRead)
{
if(aborted)
{
currentTry.Extents = ExtentsConverter.ToMetadata(extents);
dumpLog.WriteLine("Aborted!");
break;
}
if(blocks - i < blocksToRead) blocksToRead = (byte)(blocks - i);
#pragma warning disable RECS0018 // Comparison of floating point numbers with equality operator
if(currentSpeed > maxSpeed && currentSpeed != 0) maxSpeed = currentSpeed;
if(currentSpeed < minSpeed && currentSpeed != 0) minSpeed = currentSpeed;
#pragma warning restore RECS0018 // Comparison of floating point numbers with equality operator
DicConsole.Write("\rReading sector {0} of {1} ({2:F3} MiB/sec.)", i, blocks, currentSpeed);
bool error = ataReader.ReadBlocks(out cmdBuf, i, blocksToRead, out duration);
if(!error)
{
mhddLog.Write(i, duration);
ibgLog.Write(i, currentSpeed * 1024);
dumpFile.Write(cmdBuf);
extents.Add(i, blocksToRead, true);
}
else
{
for(ulong b = i; b < i + blocksToRead; b++) resume.BadBlocks.Add(b);
if(duration < 500) mhddLog.Write(i, 65535);
else mhddLog.Write(i, duration);
ibgLog.Write(i, 0);
dumpFile.Write(new byte[blockSize * blocksToRead]);
dumpLog.WriteLine("Error reading {0} blocks from block {1}.", blocksToRead, i);
}
currentSpeed = (double)blockSize * blocksToRead / 1048576 / (duration / 1000);
GC.Collect();
resume.NextBlock = i + blocksToRead;
} }
end = DateTime.Now; if(dev.IsPcmcia)
DicConsole.WriteLine();
mhddLog.Close();
ibgLog.Close(dev, blocks, blockSize, (end - start).TotalSeconds, currentSpeed * 1024,
blockSize * (double)(blocks + 1) / 1024 / (totalDuration / 1000),
devicePath);
dumpLog.WriteLine("Dump finished in {0} seconds.", (end - start).TotalSeconds);
dumpLog.WriteLine("Average dump speed {0:F3} KiB/sec.",
(double)blockSize * (double)(blocks + 1) / 1024 / (totalDuration / 1000));
#region Error handling
if(resume.BadBlocks.Count > 0 && !aborted)
{ {
int pass = 0; dumpLog.WriteLine("Reading PCMCIA CIS.");
bool forward = true; sidecar.BlockMedia[0].PCMCIA = new PCMCIAType
bool runningPersistent = false; {
CIS = new DumpType
{
Image = outputPrefix + ".cis.bin",
Size = dev.Cis.Length,
Checksums = Checksum.GetChecksums(dev.Cis).ToArray()
}
};
DataFile.WriteTo("ATA Dump", sidecar.BlockMedia[0].PCMCIA.CIS.Image, dev.Cis);
dumpLog.WriteLine("Decoding PCMCIA CIS.");
Tuple[] tuples = CIS.GetTuples(dev.Cis);
if(tuples != null)
foreach(Tuple tuple in tuples)
switch(tuple.Code) {
case TupleCodes.CISTPL_MANFID:
ManufacturerIdentificationTuple manfid =
CIS.DecodeManufacturerIdentificationTuple(tuple);
repeatRetryLba: if(manfid != null)
ulong[] tmpArray = resume.BadBlocks.ToArray(); {
foreach(ulong badSector in tmpArray) sidecar.BlockMedia[0].PCMCIA.ManufacturerCode = manfid.ManufacturerID;
sidecar.BlockMedia[0].PCMCIA.CardCode = manfid.CardID;
sidecar.BlockMedia[0].PCMCIA.ManufacturerCodeSpecified = true;
sidecar.BlockMedia[0].PCMCIA.CardCodeSpecified = true;
}
break;
case TupleCodes.CISTPL_VERS_1:
Level1VersionTuple vers = CIS.DecodeLevel1VersionTuple(tuple);
if(vers != null)
{
sidecar.BlockMedia[0].PCMCIA.Manufacturer = vers.Manufacturer;
sidecar.BlockMedia[0].PCMCIA.ProductName = vers.Product;
sidecar.BlockMedia[0].PCMCIA.Compliance =
string.Format("{0}.{1}", vers.MajorVersion, vers.MinorVersion);
sidecar.BlockMedia[0].PCMCIA.AdditionalInformation = vers.AdditionalInformation;
}
break;
}
}
sidecar.BlockMedia[0].ATA = new ATAType
{
Identify = new DumpType
{
Image = outputPrefix + ".identify.bin",
Size = cmdBuf.Length,
Checksums = Checksum.GetChecksums(cmdBuf).ToArray()
}
};
DataFile.WriteTo("ATA Dump", sidecar.BlockMedia[0].ATA.Identify.Image, cmdBuf);
DateTime start;
DateTime end;
double totalDuration = 0;
double totalChkDuration = 0;
double currentSpeed = 0;
double maxSpeed = double.MinValue;
double minSpeed = double.MaxValue;
Checksum dataChk;
aborted = false;
System.Console.CancelKeyPress += (sender, e) => { e.Cancel = aborted = true; };
DataFile dumpFile;
// Initializate reader
dumpLog.WriteLine("Initializing reader.");
Reader ataReader = new Reader(dev, timeout, cmdBuf);
// Fill reader blocks
ulong blocks = ataReader.GetDeviceBlocks();
// Check block sizes
if(ataReader.GetBlockSize())
{
dumpLog.WriteLine("ERROR: Cannot get block size: {0}.", ataReader.ErrorMessage);
DicConsole.ErrorWriteLine(ataReader.ErrorMessage);
return;
}
uint blockSize = ataReader.LogicalBlockSize;
uint physicalsectorsize = ataReader.PhysicalBlockSize;
if(ataReader.FindReadCommand())
{
dumpLog.WriteLine("ERROR: Cannot find correct read command: {0}.", ataReader.ErrorMessage);
DicConsole.ErrorWriteLine(ataReader.ErrorMessage);
return;
}
// Check how many blocks to read, if error show and return
if(ataReader.GetBlocksToRead())
{
dumpLog.WriteLine("ERROR: Cannot get blocks to read: {0}.", ataReader.ErrorMessage);
DicConsole.ErrorWriteLine(ataReader.ErrorMessage);
return;
}
uint blocksToRead = ataReader.BlocksToRead;
ushort cylinders = ataReader.Cylinders;
byte heads = ataReader.Heads;
byte sectors = ataReader.Sectors;
dumpLog.WriteLine("Device reports {0} blocks ({1} bytes).", blocks, blocks * blockSize);
dumpLog.WriteLine("Device reports {0} cylinders {1} heads {2} sectors per track.", cylinders, heads,
sectors);
dumpLog.WriteLine("Device can read {0} blocks at a time.", blocksToRead);
dumpLog.WriteLine("Device reports {0} bytes per logical block.", blockSize);
dumpLog.WriteLine("Device reports {0} bytes per physical block.", physicalsectorsize);
bool removable = false || !dev.IsCompactFlash &&
ataId.GeneralConfiguration.HasFlag(Identify.GeneralConfigurationBit
.Removable);
DumpHardwareType currentTry = null;
ExtentsULong extents = null;
ResumeSupport.Process(ataReader.IsLba, removable, blocks, dev.Manufacturer, dev.Model, dev.Serial,
dev.PlatformId, ref resume, ref currentTry, ref extents);
if(currentTry == null || extents == null)
throw new Exception("Could not process resume file, not continuing...");
if(ataReader.IsLba)
{
DicConsole.WriteLine("Reading {0} sectors at a time.", blocksToRead);
mhddLog = new MhddLog(outputPrefix + ".mhddlog.bin", dev, blocks, blockSize, blocksToRead);
ibgLog = new IbgLog(outputPrefix + ".ibg", currentProfile);
dumpFile = new DataFile(outputPrefix + ".bin");
if(resume.NextBlock > 0) dumpLog.WriteLine("Resuming from block {0}.", resume.NextBlock);
dumpFile.Seek(resume.NextBlock, blockSize);
start = DateTime.UtcNow;
for(ulong i = resume.NextBlock; i < blocks; i += blocksToRead)
{ {
if(aborted) if(aborted)
{ {
@@ -310,53 +249,61 @@ namespace DiscImageChef.Core.Devices.Dumping
break; break;
} }
DicConsole.Write("\rRetrying sector {0}, pass {1}, {3}{2}", badSector, pass + 1, if(blocks - i < blocksToRead) blocksToRead = (byte)(blocks - i);
forward ? "forward" : "reverse",
runningPersistent ? "recovering partial data, " : "");
bool error = ataReader.ReadBlock(out cmdBuf, badSector, out duration); #pragma warning disable RECS0018 // Comparison of floating point numbers with equality operator
if(currentSpeed > maxSpeed && currentSpeed != 0) maxSpeed = currentSpeed;
if(currentSpeed < minSpeed && currentSpeed != 0) minSpeed = currentSpeed;
#pragma warning restore RECS0018 // Comparison of floating point numbers with equality operator
totalDuration += duration; DicConsole.Write("\rReading sector {0} of {1} ({2:F3} MiB/sec.)", i, blocks, currentSpeed);
bool error = ataReader.ReadBlocks(out cmdBuf, i, blocksToRead, out duration);
if(!error) if(!error)
{ {
resume.BadBlocks.Remove(badSector); mhddLog.Write(i, duration);
extents.Add(badSector); ibgLog.Write(i, currentSpeed * 1024);
dumpFile.WriteAt(cmdBuf, badSector, blockSize); dumpFile.Write(cmdBuf);
dumpLog.WriteLine("Correctly retried block {0} in pass {1}.", badSector, pass); extents.Add(i, blocksToRead, true);
} }
else if(runningPersistent) dumpFile.WriteAt(cmdBuf, badSector, blockSize); else
} {
for(ulong b = i; b < i + blocksToRead; b++) resume.BadBlocks.Add(b);
if(pass < retryPasses && !aborted && resume.BadBlocks.Count > 0)
{ if(duration < 500) mhddLog.Write(i, 65535);
pass++; else mhddLog.Write(i, duration);
forward = !forward;
resume.BadBlocks.Sort(); ibgLog.Write(i, 0);
resume.BadBlocks.Reverse(); dumpFile.Write(new byte[blockSize * blocksToRead]);
goto repeatRetryLba; dumpLog.WriteLine("Error reading {0} blocks from block {1}.", blocksToRead, i);
}
currentSpeed = (double)blockSize * blocksToRead / 1048576 / (duration / 1000);
GC.Collect();
resume.NextBlock = i + blocksToRead;
} }
end = DateTime.Now;
DicConsole.WriteLine(); DicConsole.WriteLine();
} mhddLog.Close();
#endregion Error handling LBA ibgLog.Close(dev, blocks, blockSize, (end - start).TotalSeconds, currentSpeed * 1024,
blockSize * (double)(blocks + 1) / 1024 / (totalDuration / 1000),
devicePath);
dumpLog.WriteLine("Dump finished in {0} seconds.", (end - start).TotalSeconds);
dumpLog.WriteLine("Average dump speed {0:F3} KiB/sec.",
(double)blockSize * (double)(blocks + 1) / 1024 / (totalDuration / 1000));
currentTry.Extents = ExtentsConverter.ToMetadata(extents); #region Error handling
} if(resume.BadBlocks.Count > 0 && !aborted)
else
{
mhddLog = new MhddLog(outputPrefix + ".mhddlog.bin", dev, blocks, blockSize, blocksToRead);
ibgLog = new IbgLog(outputPrefix + ".ibg", currentProfile);
dumpFile = new DataFile(outputPrefix + ".bin");
ulong currentBlock = 0;
blocks = (ulong)(cylinders * heads * sectors);
start = DateTime.UtcNow;
for(ushort cy = 0; cy < cylinders; cy++)
{
for(byte hd = 0; hd < heads; hd++)
{ {
for(byte sc = 1; sc < sectors; sc++) int pass = 0;
bool forward = true;
bool runningPersistent = false;
repeatRetryLba:
ulong[] tmpArray = resume.BadBlocks.ToArray();
foreach(ulong badSector in tmpArray)
{ {
if(aborted) if(aborted)
{ {
@@ -365,143 +312,233 @@ namespace DiscImageChef.Core.Devices.Dumping
break; break;
} }
#pragma warning disable RECS0018 // Comparison of floating point numbers with equality operator DicConsole.Write("\rRetrying sector {0}, pass {1}, {3}{2}", badSector, pass + 1,
if(currentSpeed > maxSpeed && currentSpeed != 0) maxSpeed = currentSpeed; forward ? "forward" : "reverse",
if(currentSpeed < minSpeed && currentSpeed != 0) minSpeed = currentSpeed; runningPersistent ? "recovering partial data, " : "");
#pragma warning restore RECS0018 // Comparison of floating point numbers with equality operator
DicConsole.Write("\rReading cylinder {0} head {1} sector {2} ({3:F3} MiB/sec.)", cy, hd, bool error = ataReader.ReadBlock(out cmdBuf, badSector, out duration);
sc, currentSpeed);
bool error = ataReader.ReadChs(out cmdBuf, cy, hd, sc, out duration);
totalDuration += duration; totalDuration += duration;
if(!error) if(!error)
{ {
mhddLog.Write(currentBlock, duration); resume.BadBlocks.Remove(badSector);
ibgLog.Write(currentBlock, currentSpeed * 1024); extents.Add(badSector);
dumpFile.Write(cmdBuf); dumpFile.WriteAt(cmdBuf, badSector, blockSize);
extents.Add(currentBlock); dumpLog.WriteLine("Correctly retried block {0} in pass {1}.", badSector, pass);
dumpLog.WriteLine("Error reading cylinder {0} head {1} sector {2}.", cy, hd, sc);
} }
else else if(runningPersistent) dumpFile.WriteAt(cmdBuf, badSector, blockSize);
}
if(pass < retryPasses && !aborted && resume.BadBlocks.Count > 0)
{
pass++;
forward = !forward;
resume.BadBlocks.Sort();
resume.BadBlocks.Reverse();
goto repeatRetryLba;
}
DicConsole.WriteLine();
}
#endregion Error handling LBA
currentTry.Extents = ExtentsConverter.ToMetadata(extents);
}
else
{
mhddLog = new MhddLog(outputPrefix + ".mhddlog.bin", dev, blocks, blockSize, blocksToRead);
ibgLog = new IbgLog(outputPrefix + ".ibg", currentProfile);
dumpFile = new DataFile(outputPrefix + ".bin");
ulong currentBlock = 0;
blocks = (ulong)(cylinders * heads * sectors);
start = DateTime.UtcNow;
for(ushort cy = 0; cy < cylinders; cy++)
{
for(byte hd = 0; hd < heads; hd++)
{
for(byte sc = 1; sc < sectors; sc++)
{ {
resume.BadBlocks.Add(currentBlock); if(aborted)
if(duration < 500) mhddLog.Write(currentBlock, 65535); {
else mhddLog.Write(currentBlock, duration); currentTry.Extents = ExtentsConverter.ToMetadata(extents);
dumpLog.WriteLine("Aborted!");
break;
}
ibgLog.Write(currentBlock, 0); #pragma warning disable RECS0018 // Comparison of floating point numbers with equality operator
dumpFile.Write(new byte[blockSize]); if(currentSpeed > maxSpeed && currentSpeed != 0) maxSpeed = currentSpeed;
if(currentSpeed < minSpeed && currentSpeed != 0) minSpeed = currentSpeed;
#pragma warning restore RECS0018 // Comparison of floating point numbers with equality operator
DicConsole.Write("\rReading cylinder {0} head {1} sector {2} ({3:F3} MiB/sec.)", cy, hd,
sc, currentSpeed);
bool error = ataReader.ReadChs(out cmdBuf, cy, hd, sc, out duration);
totalDuration += duration;
if(!error)
{
mhddLog.Write(currentBlock, duration);
ibgLog.Write(currentBlock, currentSpeed * 1024);
dumpFile.Write(cmdBuf);
extents.Add(currentBlock);
dumpLog.WriteLine("Error reading cylinder {0} head {1} sector {2}.", cy, hd, sc);
}
else
{
resume.BadBlocks.Add(currentBlock);
if(duration < 500) mhddLog.Write(currentBlock, 65535);
else mhddLog.Write(currentBlock, duration);
ibgLog.Write(currentBlock, 0);
dumpFile.Write(new byte[blockSize]);
}
currentSpeed = blockSize / (double)1048576 / (duration / 1000);
GC.Collect();
currentBlock++;
} }
currentSpeed = blockSize / (double)1048576 / (duration / 1000);
GC.Collect();
currentBlock++;
} }
} }
end = DateTime.Now;
DicConsole.WriteLine();
mhddLog.Close();
ibgLog.Close(dev, blocks, blockSize, (end - start).TotalSeconds, currentSpeed * 1024,
blockSize * (double)(blocks + 1) / 1024 / (totalDuration / 1000),
devicePath);
dumpLog.WriteLine("Dump finished in {0} seconds.", (end - start).TotalSeconds);
dumpLog.WriteLine("Average dump speed {0:F3} KiB/sec.",
(double)blockSize * (double)(blocks + 1) / 1024 / (totalDuration / 1000));
} }
end = DateTime.Now; dataChk = new Checksum();
DicConsole.WriteLine(); dumpFile.Seek(0, SeekOrigin.Begin);
mhddLog.Close(); blocksToRead = 500;
ibgLog.Close(dev, blocks, blockSize, (end - start).TotalSeconds, currentSpeed * 1024,
blockSize * (double)(blocks + 1) / 1024 / (totalDuration / 1000),
devicePath);
dumpLog.WriteLine("Dump finished in {0} seconds.", (end - start).TotalSeconds);
dumpLog.WriteLine("Average dump speed {0:F3} KiB/sec.",
(double)blockSize * (double)(blocks + 1) / 1024 / (totalDuration / 1000));
}
dataChk = new Checksum(); dumpLog.WriteLine("Checksum starts.");
dumpFile.Seek(0, SeekOrigin.Begin); for(ulong i = 0; i < blocks; i += blocksToRead)
blocksToRead = 500;
dumpLog.WriteLine("Checksum starts.");
for(ulong i = 0; i < blocks; i += blocksToRead)
{
if(aborted)
{ {
dumpLog.WriteLine("Aborted!"); if(aborted)
break;
}
if(blocks - i < blocksToRead) blocksToRead = (byte)(blocks - i);
DicConsole.Write("\rChecksumming sector {0} of {1} ({2:F3} MiB/sec.)", i, blocks, currentSpeed);
DateTime chkStart = DateTime.UtcNow;
byte[] dataToCheck = new byte[blockSize * blocksToRead];
dumpFile.Read(dataToCheck, 0, (int)(blockSize * blocksToRead));
dataChk.Update(dataToCheck);
DateTime chkEnd = DateTime.UtcNow;
double chkDuration = (chkEnd - chkStart).TotalMilliseconds;
totalChkDuration += chkDuration;
currentSpeed = (double)blockSize * blocksToRead / 1048576 / (chkDuration / 1000);
}
DicConsole.WriteLine();
dumpFile.Close();
end = DateTime.UtcNow;
dumpLog.WriteLine("Checksum finished in {0} seconds.", (end - start).TotalSeconds);
dumpLog.WriteLine("Average checksum speed {0:F3} KiB/sec.",
(double)blockSize * (double)(blocks + 1) / 1024 / (totalChkDuration / 1000));
PluginBase plugins = new PluginBase();
plugins.RegisterAllPlugins(encoding);
ImagePlugin imageFormat;
FiltersList filtersList = new FiltersList();
Filter inputFilter = filtersList.GetFilter(outputPrefix + ".bin");
if(inputFilter == null)
{
DicConsole.ErrorWriteLine("Cannot open file just created, this should not happen.");
return;
}
imageFormat = ImageFormat.Detect(inputFilter);
PartitionType[] xmlFileSysInfo = null;
try { if(!imageFormat.OpenImage(inputFilter)) imageFormat = null; }
catch { imageFormat = null; }
if(imageFormat != null)
{
dumpLog.WriteLine("Getting partitions.");
List<Partition> partitions = Partitions.GetAll(imageFormat);
Partitions.AddSchemesToStats(partitions);
dumpLog.WriteLine("Found {0} partitions.", partitions.Count);
if(partitions.Count > 0)
{
xmlFileSysInfo = new PartitionType[partitions.Count];
for(int i = 0; i < partitions.Count; i++)
{ {
xmlFileSysInfo[i] = new PartitionType dumpLog.WriteLine("Aborted!");
break;
}
if(blocks - i < blocksToRead) blocksToRead = (byte)(blocks - i);
DicConsole.Write("\rChecksumming sector {0} of {1} ({2:F3} MiB/sec.)", i, blocks, currentSpeed);
DateTime chkStart = DateTime.UtcNow;
byte[] dataToCheck = new byte[blockSize * blocksToRead];
dumpFile.Read(dataToCheck, 0, (int)(blockSize * blocksToRead));
dataChk.Update(dataToCheck);
DateTime chkEnd = DateTime.UtcNow;
double chkDuration = (chkEnd - chkStart).TotalMilliseconds;
totalChkDuration += chkDuration;
currentSpeed = (double)blockSize * blocksToRead / 1048576 / (chkDuration / 1000);
}
DicConsole.WriteLine();
dumpFile.Close();
end = DateTime.UtcNow;
dumpLog.WriteLine("Checksum finished in {0} seconds.", (end - start).TotalSeconds);
dumpLog.WriteLine("Average checksum speed {0:F3} KiB/sec.",
(double)blockSize * (double)(blocks + 1) / 1024 / (totalChkDuration / 1000));
PluginBase plugins = new PluginBase();
plugins.RegisterAllPlugins(encoding);
ImagePlugin imageFormat;
FiltersList filtersList = new FiltersList();
Filter inputFilter = filtersList.GetFilter(outputPrefix + ".bin");
if(inputFilter == null)
{
DicConsole.ErrorWriteLine("Cannot open file just created, this should not happen.");
return;
}
imageFormat = ImageFormat.Detect(inputFilter);
PartitionType[] xmlFileSysInfo = null;
try { if(!imageFormat.OpenImage(inputFilter)) imageFormat = null; }
catch { imageFormat = null; }
if(imageFormat != null)
{
dumpLog.WriteLine("Getting partitions.");
List<Partition> partitions = Partitions.GetAll(imageFormat);
Partitions.AddSchemesToStats(partitions);
dumpLog.WriteLine("Found {0} partitions.", partitions.Count);
if(partitions.Count > 0)
{
xmlFileSysInfo = new PartitionType[partitions.Count];
for(int i = 0; i < partitions.Count; i++)
{ {
Description = partitions[i].Description, xmlFileSysInfo[i] = new PartitionType
EndSector = (int)(partitions[i].Start + partitions[i].Length - 1), {
Name = partitions[i].Name, Description = partitions[i].Description,
Sequence = (int)partitions[i].Sequence, EndSector = (int)(partitions[i].Start + partitions[i].Length - 1),
StartSector = (int)partitions[i].Start, Name = partitions[i].Name,
Type = partitions[i].Type Sequence = (int)partitions[i].Sequence,
}; StartSector = (int)partitions[i].Start,
Type = partitions[i].Type
};
List<FileSystemType> lstFs = new List<FileSystemType>();
dumpLog
.WriteLine("Getting filesystems on partition {0}, starting at {1}, ending at {2}, with type {3}, under scheme {4}.",
i, partitions[i].Start, partitions[i].End, partitions[i].Type,
partitions[i].Scheme);
foreach(Filesystem plugin in plugins.PluginsList.Values)
try
{
if(!plugin.Identify(imageFormat, partitions[i])) continue;
plugin.GetInformation(imageFormat, partitions[i], out string foo);
lstFs.Add(plugin.XmlFSType);
Statistics.AddFilesystem(plugin.XmlFSType.Type);
dumpLog.WriteLine("Filesystem {0} found.", plugin.XmlFSType.Type);
}
#pragma warning disable RECS0022 // A catch clause that catches System.Exception and has an empty body
catch
#pragma warning restore RECS0022 // A catch clause that catches System.Exception and has an empty body
{
//DicConsole.DebugWriteLine("Dump-media command", "Plugin {0} crashed", _plugin.Name);
}
if(lstFs.Count > 0) xmlFileSysInfo[i].FileSystems = lstFs.ToArray();
}
}
else
{
dumpLog.WriteLine("Getting filesystem for whole device.");
xmlFileSysInfo = new PartitionType[1];
xmlFileSysInfo[0] = new PartitionType {EndSector = (int)(blocks - 1), StartSector = 0};
List<FileSystemType> lstFs = new List<FileSystemType>(); List<FileSystemType> lstFs = new List<FileSystemType>();
dumpLog
.WriteLine("Getting filesystems on partition {0}, starting at {1}, ending at {2}, with type {3}, under scheme {4}.", Partition wholePart = new Partition
i, partitions[i].Start, partitions[i].End, partitions[i].Type, {
partitions[i].Scheme); Name = "Whole device",
Length = blocks,
Size = blocks * blockSize
};
foreach(Filesystem plugin in plugins.PluginsList.Values) foreach(Filesystem plugin in plugins.PluginsList.Values)
try try
{ {
if(!plugin.Identify(imageFormat, partitions[i])) continue; if(!plugin.Identify(imageFormat, wholePart)) continue;
plugin.GetInformation(imageFormat, partitions[i], out string foo); plugin.GetInformation(imageFormat, wholePart, out string foo);
lstFs.Add(plugin.XmlFSType); lstFs.Add(plugin.XmlFSType);
Statistics.AddFilesystem(plugin.XmlFSType.Type); Statistics.AddFilesystem(plugin.XmlFSType.Type);
dumpLog.WriteLine("Filesystem {0} found.", plugin.XmlFSType.Type); dumpLog.WriteLine("Filesystem {0} found.", plugin.XmlFSType.Type);
@@ -510,104 +547,70 @@ namespace DiscImageChef.Core.Devices.Dumping
catch catch
#pragma warning restore RECS0022 // A catch clause that catches System.Exception and has an empty body #pragma warning restore RECS0022 // A catch clause that catches System.Exception and has an empty body
{ {
//DicConsole.DebugWriteLine("Dump-media command", "Plugin {0} crashed", _plugin.Name); //DicConsole.DebugWriteLine("Create-sidecar command", "Plugin {0} crashed", _plugin.Name);
} }
if(lstFs.Count > 0) xmlFileSysInfo[i].FileSystems = lstFs.ToArray(); if(lstFs.Count > 0) xmlFileSysInfo[0].FileSystems = lstFs.ToArray();
} }
} }
else
sidecar.BlockMedia[0].Checksums = dataChk.End().ToArray();
string xmlDskTyp, xmlDskSubTyp;
if(dev.IsCompactFlash)
MediaType.MediaTypeToString(CommonTypes.MediaType.CompactFlash, out xmlDskTyp, out xmlDskSubTyp);
else if(dev.IsPcmcia)
MediaType.MediaTypeToString(CommonTypes.MediaType.PCCardTypeI, out xmlDskTyp, out xmlDskSubTyp);
else MediaType.MediaTypeToString(CommonTypes.MediaType.GENERIC_HDD, out xmlDskTyp, out xmlDskSubTyp);
sidecar.BlockMedia[0].DiskType = xmlDskTyp;
sidecar.BlockMedia[0].DiskSubType = xmlDskSubTyp;
// TODO: Implement device firmware revision
sidecar.BlockMedia[0].Image = new ImageType
{ {
dumpLog.WriteLine("Getting filesystem for whole device."); format = "Raw disk image (sector by sector copy)",
Value = outputPrefix + ".bin"
xmlFileSysInfo = new PartitionType[1]; };
xmlFileSysInfo[0] = new PartitionType {EndSector = (int)(blocks - 1), StartSector = 0}; sidecar.BlockMedia[0].Interface = "ATA";
List<FileSystemType> lstFs = new List<FileSystemType>(); sidecar.BlockMedia[0].LogicalBlocks = (long)blocks;
sidecar.BlockMedia[0].PhysicalBlockSize = (int)physicalsectorsize;
Partition wholePart = new Partition sidecar.BlockMedia[0].LogicalBlockSize = (int)blockSize;
{ sidecar.BlockMedia[0].Manufacturer = dev.Manufacturer;
Name = "Whole device", sidecar.BlockMedia[0].Model = dev.Model;
Length = blocks, sidecar.BlockMedia[0].Serial = dev.Serial;
Size = blocks * blockSize sidecar.BlockMedia[0].Size = (long)(blocks * blockSize);
}; if(xmlFileSysInfo != null) sidecar.BlockMedia[0].FileSystemInformation = xmlFileSysInfo;
if(cylinders > 0 && heads > 0 && sectors > 0)
foreach(Filesystem plugin in plugins.PluginsList.Values) {
try sidecar.BlockMedia[0].Cylinders = cylinders;
{ sidecar.BlockMedia[0].CylindersSpecified = true;
if(!plugin.Identify(imageFormat, wholePart)) continue; sidecar.BlockMedia[0].Heads = heads;
sidecar.BlockMedia[0].HeadsSpecified = true;
plugin.GetInformation(imageFormat, wholePart, out string foo); sidecar.BlockMedia[0].SectorsPerTrack = sectors;
lstFs.Add(plugin.XmlFSType); sidecar.BlockMedia[0].SectorsPerTrackSpecified = true;
Statistics.AddFilesystem(plugin.XmlFSType.Type);
dumpLog.WriteLine("Filesystem {0} found.", plugin.XmlFSType.Type);
}
#pragma warning disable RECS0022 // A catch clause that catches System.Exception and has an empty body
catch
#pragma warning restore RECS0022 // A catch clause that catches System.Exception and has an empty body
{
//DicConsole.DebugWriteLine("Create-sidecar command", "Plugin {0} crashed", _plugin.Name);
}
if(lstFs.Count > 0) xmlFileSysInfo[0].FileSystems = lstFs.ToArray();
} }
}
sidecar.BlockMedia[0].Checksums = dataChk.End().ToArray(); DicConsole.WriteLine();
string xmlDskTyp, xmlDskSubTyp;
if(dev.IsCompactFlash)
MediaType.MediaTypeToString(CommonTypes.MediaType.CompactFlash, out xmlDskTyp, out xmlDskSubTyp);
else if(dev.IsPcmcia)
MediaType.MediaTypeToString(CommonTypes.MediaType.PCCardTypeI, out xmlDskTyp, out xmlDskSubTyp);
else MediaType.MediaTypeToString(CommonTypes.MediaType.GENERIC_HDD, out xmlDskTyp, out xmlDskSubTyp);
sidecar.BlockMedia[0].DiskType = xmlDskTyp;
sidecar.BlockMedia[0].DiskSubType = xmlDskSubTyp;
// TODO: Implement device firmware revision
sidecar.BlockMedia[0].Image = new ImageType
{
format = "Raw disk image (sector by sector copy)",
Value = outputPrefix + ".bin"
};
sidecar.BlockMedia[0].Interface = "ATA";
sidecar.BlockMedia[0].LogicalBlocks = (long)blocks;
sidecar.BlockMedia[0].PhysicalBlockSize = (int)physicalsectorsize;
sidecar.BlockMedia[0].LogicalBlockSize = (int)blockSize;
sidecar.BlockMedia[0].Manufacturer = dev.Manufacturer;
sidecar.BlockMedia[0].Model = dev.Model;
sidecar.BlockMedia[0].Serial = dev.Serial;
sidecar.BlockMedia[0].Size = (long)(blocks * blockSize);
if(xmlFileSysInfo != null) sidecar.BlockMedia[0].FileSystemInformation = xmlFileSysInfo;
if(cylinders > 0 && heads > 0 && sectors > 0)
{
sidecar.BlockMedia[0].Cylinders = cylinders;
sidecar.BlockMedia[0].CylindersSpecified = true;
sidecar.BlockMedia[0].Heads = heads;
sidecar.BlockMedia[0].HeadsSpecified = true;
sidecar.BlockMedia[0].SectorsPerTrack = sectors;
sidecar.BlockMedia[0].SectorsPerTrackSpecified = true;
}
DicConsole.WriteLine(); DicConsole.WriteLine("Took a total of {0:F3} seconds ({1:F3} processing commands, {2:F3} checksumming).",
(end - start).TotalSeconds, totalDuration / 1000, totalChkDuration / 1000);
DicConsole.WriteLine("Avegare speed: {0:F3} MiB/sec.",
(double)blockSize * (double)(blocks + 1) / 1048576 / (totalDuration / 1000));
DicConsole.WriteLine("Fastest speed burst: {0:F3} MiB/sec.", maxSpeed);
DicConsole.WriteLine("Slowest speed burst: {0:F3} MiB/sec.", minSpeed);
DicConsole.WriteLine("{0} sectors could not be read.", resume.BadBlocks.Count);
if(resume.BadBlocks.Count > 0) resume.BadBlocks.Sort();
DicConsole.WriteLine();
DicConsole.WriteLine("Took a total of {0:F3} seconds ({1:F3} processing commands, {2:F3} checksumming).", if(!aborted)
(end - start).TotalSeconds, totalDuration / 1000, totalChkDuration / 1000); {
DicConsole.WriteLine("Avegare speed: {0:F3} MiB/sec.", DicConsole.WriteLine("Writing metadata sidecar");
(double)blockSize * (double)(blocks + 1) / 1048576 / (totalDuration / 1000));
DicConsole.WriteLine("Fastest speed burst: {0:F3} MiB/sec.", maxSpeed);
DicConsole.WriteLine("Slowest speed burst: {0:F3} MiB/sec.", minSpeed);
DicConsole.WriteLine("{0} sectors could not be read.", resume.BadBlocks.Count);
if(resume.BadBlocks.Count > 0) resume.BadBlocks.Sort();
DicConsole.WriteLine();
if(!aborted) FileStream xmlFs = new FileStream(outputPrefix + ".cicm.xml", FileMode.Create);
{
DicConsole.WriteLine("Writing metadata sidecar");
FileStream xmlFs = new FileStream(outputPrefix + ".cicm.xml", FileMode.Create); XmlSerializer xmlSer =
new XmlSerializer(typeof(CICMMetadataType));
XmlSerializer xmlSer = xmlSer.Serialize(xmlFs, sidecar);
new XmlSerializer(typeof(CICMMetadataType)); xmlFs.Close();
xmlSer.Serialize(xmlFs, sidecar); }
xmlFs.Close();
} }
Statistics.AddMedia(CommonTypes.MediaType.GENERIC_HDD, true); Statistics.AddMedia(CommonTypes.MediaType.GENERIC_HDD, true);

View File

@@ -67,7 +67,8 @@ namespace DiscImageChef.Core.Devices
switch(dev.Type) switch(dev.Type)
{ {
case DeviceType.ATA: case DeviceType.ATA:
if(Identify.Decode(identification).HasValue) ataId = Identify.Decode(identification).Value; Identify.IdentifyDevice? ataIdNullable = Identify.Decode(identification);
if(ataIdNullable.HasValue) ataId = ataIdNullable.Value;
break; break;
case DeviceType.NVMe: throw new NotImplementedException("NVMe devices not yet supported."); case DeviceType.NVMe: throw new NotImplementedException("NVMe devices not yet supported.");
} }

File diff suppressed because it is too large Load Diff

View File

@@ -54,404 +54,407 @@ namespace DiscImageChef.Core.Devices.Report
if(!Identify.Decode(buffer).HasValue) return; if(!Identify.Decode(buffer).HasValue) return;
Identify.IdentifyDevice atapiId = Identify.Decode(buffer).Value; Identify.IdentifyDevice? atapiIdNullable = Identify.Decode(buffer);
if(atapiIdNullable != null) {
Identify.IdentifyDevice atapiId = atapiIdNullable.Value;
report.ATAPI = new ataType(); report.ATAPI = new ataType();
if(!string.IsNullOrWhiteSpace(atapiId.AdditionalPID)) if(!string.IsNullOrWhiteSpace(atapiId.AdditionalPID))
{ {
report.ATAPI.AdditionalPID = atapiId.AdditionalPID; report.ATAPI.AdditionalPID = atapiId.AdditionalPID;
report.ATAPI.AdditionalPIDSpecified = true; report.ATAPI.AdditionalPIDSpecified = true;
} }
if(atapiId.APIOSupported != 0) if(atapiId.APIOSupported != 0)
{ {
report.ATAPI.APIOSupported = atapiId.APIOSupported; report.ATAPI.APIOSupported = atapiId.APIOSupported;
report.ATAPI.APIOSupportedSpecified = true; report.ATAPI.APIOSupportedSpecified = true;
} }
if(atapiId.ATAPIByteCount != 0) if(atapiId.ATAPIByteCount != 0)
{ {
report.ATAPI.ATAPIByteCount = atapiId.ATAPIByteCount; report.ATAPI.ATAPIByteCount = atapiId.ATAPIByteCount;
report.ATAPI.ATAPIByteCountSpecified = true; report.ATAPI.ATAPIByteCountSpecified = true;
} }
if(atapiId.BufferType != 0) if(atapiId.BufferType != 0)
{ {
report.ATAPI.BufferType = atapiId.BufferType; report.ATAPI.BufferType = atapiId.BufferType;
report.ATAPI.BufferTypeSpecified = true; report.ATAPI.BufferTypeSpecified = true;
} }
if(atapiId.BufferSize != 0) if(atapiId.BufferSize != 0)
{ {
report.ATAPI.BufferSize = atapiId.BufferSize; report.ATAPI.BufferSize = atapiId.BufferSize;
report.ATAPI.BufferSizeSpecified = true; report.ATAPI.BufferSizeSpecified = true;
} }
if(atapiId.Capabilities != 0) if(atapiId.Capabilities != 0)
{ {
report.ATAPI.Capabilities = atapiId.Capabilities; report.ATAPI.Capabilities = atapiId.Capabilities;
report.ATAPI.CapabilitiesSpecified = true; report.ATAPI.CapabilitiesSpecified = true;
} }
if(atapiId.Capabilities2 != 0) if(atapiId.Capabilities2 != 0)
{ {
report.ATAPI.Capabilities2 = atapiId.Capabilities2; report.ATAPI.Capabilities2 = atapiId.Capabilities2;
report.ATAPI.Capabilities2Specified = true; report.ATAPI.Capabilities2Specified = true;
} }
if(atapiId.Capabilities3 != 0) if(atapiId.Capabilities3 != 0)
{ {
report.ATAPI.Capabilities3 = atapiId.Capabilities3; report.ATAPI.Capabilities3 = atapiId.Capabilities3;
report.ATAPI.Capabilities3Specified = true; report.ATAPI.Capabilities3Specified = true;
} }
if(atapiId.CFAPowerMode != 0) if(atapiId.CFAPowerMode != 0)
{ {
report.ATAPI.CFAPowerMode = atapiId.CFAPowerMode; report.ATAPI.CFAPowerMode = atapiId.CFAPowerMode;
report.ATAPI.CFAPowerModeSpecified = true; report.ATAPI.CFAPowerModeSpecified = true;
} }
if(atapiId.CommandSet != 0) if(atapiId.CommandSet != 0)
{ {
report.ATAPI.CommandSet = atapiId.CommandSet; report.ATAPI.CommandSet = atapiId.CommandSet;
report.ATAPI.CommandSetSpecified = true; report.ATAPI.CommandSetSpecified = true;
} }
if(atapiId.CommandSet2 != 0) if(atapiId.CommandSet2 != 0)
{ {
report.ATAPI.CommandSet2 = atapiId.CommandSet2; report.ATAPI.CommandSet2 = atapiId.CommandSet2;
report.ATAPI.CommandSet2Specified = true; report.ATAPI.CommandSet2Specified = true;
} }
if(atapiId.CommandSet3 != 0) if(atapiId.CommandSet3 != 0)
{ {
report.ATAPI.CommandSet3 = atapiId.CommandSet3; report.ATAPI.CommandSet3 = atapiId.CommandSet3;
report.ATAPI.CommandSet3Specified = true; report.ATAPI.CommandSet3Specified = true;
} }
if(atapiId.CommandSet4 != 0) if(atapiId.CommandSet4 != 0)
{ {
report.ATAPI.CommandSet4 = atapiId.CommandSet4; report.ATAPI.CommandSet4 = atapiId.CommandSet4;
report.ATAPI.CommandSet4Specified = true; report.ATAPI.CommandSet4Specified = true;
} }
if(atapiId.CommandSet5 != 0) if(atapiId.CommandSet5 != 0)
{ {
report.ATAPI.CommandSet5 = atapiId.CommandSet5; report.ATAPI.CommandSet5 = atapiId.CommandSet5;
report.ATAPI.CommandSet5Specified = true; report.ATAPI.CommandSet5Specified = true;
} }
if(atapiId.CurrentAAM != 0) if(atapiId.CurrentAAM != 0)
{ {
report.ATAPI.CurrentAAM = atapiId.CurrentAAM; report.ATAPI.CurrentAAM = atapiId.CurrentAAM;
report.ATAPI.CurrentAAMSpecified = true; report.ATAPI.CurrentAAMSpecified = true;
} }
if(atapiId.CurrentAPM != 0) if(atapiId.CurrentAPM != 0)
{ {
report.ATAPI.CurrentAPM = atapiId.CurrentAPM; report.ATAPI.CurrentAPM = atapiId.CurrentAPM;
report.ATAPI.CurrentAPMSpecified = true; report.ATAPI.CurrentAPMSpecified = true;
} }
if(atapiId.DataSetMgmt != 0) if(atapiId.DataSetMgmt != 0)
{ {
report.ATAPI.DataSetMgmt = atapiId.DataSetMgmt; report.ATAPI.DataSetMgmt = atapiId.DataSetMgmt;
report.ATAPI.DataSetMgmtSpecified = true; report.ATAPI.DataSetMgmtSpecified = true;
} }
if(atapiId.DataSetMgmtSize != 0) if(atapiId.DataSetMgmtSize != 0)
{ {
report.ATAPI.DataSetMgmtSize = atapiId.DataSetMgmtSize; report.ATAPI.DataSetMgmtSize = atapiId.DataSetMgmtSize;
report.ATAPI.DataSetMgmtSizeSpecified = true; report.ATAPI.DataSetMgmtSizeSpecified = true;
} }
if(atapiId.DeviceFormFactor != 0) if(atapiId.DeviceFormFactor != 0)
{ {
report.ATAPI.DeviceFormFactor = atapiId.DeviceFormFactor; report.ATAPI.DeviceFormFactor = atapiId.DeviceFormFactor;
report.ATAPI.DeviceFormFactorSpecified = true; report.ATAPI.DeviceFormFactorSpecified = true;
} }
if(atapiId.DMAActive != 0) if(atapiId.DMAActive != 0)
{ {
report.ATAPI.DMAActive = atapiId.DMAActive; report.ATAPI.DMAActive = atapiId.DMAActive;
report.ATAPI.DMAActiveSpecified = true; report.ATAPI.DMAActiveSpecified = true;
} }
if(atapiId.DMASupported != 0) if(atapiId.DMASupported != 0)
{ {
report.ATAPI.DMASupported = atapiId.DMASupported; report.ATAPI.DMASupported = atapiId.DMASupported;
report.ATAPI.DMASupportedSpecified = true; report.ATAPI.DMASupportedSpecified = true;
} }
if(atapiId.DMATransferTimingMode != 0) if(atapiId.DMATransferTimingMode != 0)
{ {
report.ATAPI.DMATransferTimingMode = atapiId.DMATransferTimingMode; report.ATAPI.DMATransferTimingMode = atapiId.DMATransferTimingMode;
report.ATAPI.DMATransferTimingModeSpecified = true; report.ATAPI.DMATransferTimingModeSpecified = true;
} }
if(atapiId.EnhancedSecurityEraseTime != 0) if(atapiId.EnhancedSecurityEraseTime != 0)
{ {
report.ATAPI.EnhancedSecurityEraseTime = atapiId.EnhancedSecurityEraseTime; report.ATAPI.EnhancedSecurityEraseTime = atapiId.EnhancedSecurityEraseTime;
report.ATAPI.EnhancedSecurityEraseTimeSpecified = true; report.ATAPI.EnhancedSecurityEraseTimeSpecified = true;
} }
if(atapiId.EnabledCommandSet != 0) if(atapiId.EnabledCommandSet != 0)
{ {
report.ATAPI.EnabledCommandSet = atapiId.EnabledCommandSet; report.ATAPI.EnabledCommandSet = atapiId.EnabledCommandSet;
report.ATAPI.EnabledCommandSetSpecified = true; report.ATAPI.EnabledCommandSetSpecified = true;
} }
if(atapiId.EnabledCommandSet2 != 0) if(atapiId.EnabledCommandSet2 != 0)
{ {
report.ATAPI.EnabledCommandSet2 = atapiId.EnabledCommandSet2; report.ATAPI.EnabledCommandSet2 = atapiId.EnabledCommandSet2;
report.ATAPI.EnabledCommandSet2Specified = true; report.ATAPI.EnabledCommandSet2Specified = true;
} }
if(atapiId.EnabledCommandSet3 != 0) if(atapiId.EnabledCommandSet3 != 0)
{ {
report.ATAPI.EnabledCommandSet3 = atapiId.EnabledCommandSet3; report.ATAPI.EnabledCommandSet3 = atapiId.EnabledCommandSet3;
report.ATAPI.EnabledCommandSet3Specified = true; report.ATAPI.EnabledCommandSet3Specified = true;
} }
if(atapiId.EnabledCommandSet4 != 0) if(atapiId.EnabledCommandSet4 != 0)
{ {
report.ATAPI.EnabledCommandSet4 = atapiId.EnabledCommandSet4; report.ATAPI.EnabledCommandSet4 = atapiId.EnabledCommandSet4;
report.ATAPI.EnabledCommandSet4Specified = true; report.ATAPI.EnabledCommandSet4Specified = true;
} }
if(atapiId.EnabledSATAFeatures != 0) if(atapiId.EnabledSATAFeatures != 0)
{ {
report.ATAPI.EnabledSATAFeatures = atapiId.EnabledSATAFeatures; report.ATAPI.EnabledSATAFeatures = atapiId.EnabledSATAFeatures;
report.ATAPI.EnabledSATAFeaturesSpecified = true; report.ATAPI.EnabledSATAFeaturesSpecified = true;
} }
if(atapiId.ExtendedUserSectors != 0) if(atapiId.ExtendedUserSectors != 0)
{ {
report.ATAPI.ExtendedUserSectors = atapiId.ExtendedUserSectors; report.ATAPI.ExtendedUserSectors = atapiId.ExtendedUserSectors;
report.ATAPI.ExtendedUserSectorsSpecified = true; report.ATAPI.ExtendedUserSectorsSpecified = true;
} }
if(atapiId.FreeFallSensitivity != 0) if(atapiId.FreeFallSensitivity != 0)
{ {
report.ATAPI.FreeFallSensitivity = atapiId.FreeFallSensitivity; report.ATAPI.FreeFallSensitivity = atapiId.FreeFallSensitivity;
report.ATAPI.FreeFallSensitivitySpecified = true; report.ATAPI.FreeFallSensitivitySpecified = true;
} }
if(!string.IsNullOrWhiteSpace(atapiId.FirmwareRevision)) if(!string.IsNullOrWhiteSpace(atapiId.FirmwareRevision))
{ {
report.ATAPI.FirmwareRevision = atapiId.FirmwareRevision; report.ATAPI.FirmwareRevision = atapiId.FirmwareRevision;
report.ATAPI.FirmwareRevisionSpecified = true; report.ATAPI.FirmwareRevisionSpecified = true;
} }
if(atapiId.GeneralConfiguration != 0) if(atapiId.GeneralConfiguration != 0)
{ {
report.ATAPI.GeneralConfiguration = atapiId.GeneralConfiguration; report.ATAPI.GeneralConfiguration = atapiId.GeneralConfiguration;
report.ATAPI.GeneralConfigurationSpecified = true; report.ATAPI.GeneralConfigurationSpecified = true;
} }
if(atapiId.HardwareResetResult != 0) if(atapiId.HardwareResetResult != 0)
{ {
report.ATAPI.HardwareResetResult = atapiId.HardwareResetResult; report.ATAPI.HardwareResetResult = atapiId.HardwareResetResult;
report.ATAPI.HardwareResetResultSpecified = true; report.ATAPI.HardwareResetResultSpecified = true;
} }
if(atapiId.InterseekDelay != 0) if(atapiId.InterseekDelay != 0)
{ {
report.ATAPI.InterseekDelay = atapiId.InterseekDelay; report.ATAPI.InterseekDelay = atapiId.InterseekDelay;
report.ATAPI.InterseekDelaySpecified = true; report.ATAPI.InterseekDelaySpecified = true;
} }
if(atapiId.MajorVersion != 0) if(atapiId.MajorVersion != 0)
{ {
report.ATAPI.MajorVersion = atapiId.MajorVersion; report.ATAPI.MajorVersion = atapiId.MajorVersion;
report.ATAPI.MajorVersionSpecified = true; report.ATAPI.MajorVersionSpecified = true;
} }
if(atapiId.MasterPasswordRevisionCode != 0) if(atapiId.MasterPasswordRevisionCode != 0)
{ {
report.ATAPI.MasterPasswordRevisionCode = atapiId.MasterPasswordRevisionCode; report.ATAPI.MasterPasswordRevisionCode = atapiId.MasterPasswordRevisionCode;
report.ATAPI.MasterPasswordRevisionCodeSpecified = true; report.ATAPI.MasterPasswordRevisionCodeSpecified = true;
} }
if(atapiId.MaxDownloadMicroMode3 != 0) if(atapiId.MaxDownloadMicroMode3 != 0)
{ {
report.ATAPI.MaxDownloadMicroMode3 = atapiId.MaxDownloadMicroMode3; report.ATAPI.MaxDownloadMicroMode3 = atapiId.MaxDownloadMicroMode3;
report.ATAPI.MaxDownloadMicroMode3Specified = true; report.ATAPI.MaxDownloadMicroMode3Specified = true;
} }
if(atapiId.MaxQueueDepth != 0) if(atapiId.MaxQueueDepth != 0)
{ {
report.ATAPI.MaxQueueDepth = atapiId.MaxQueueDepth; report.ATAPI.MaxQueueDepth = atapiId.MaxQueueDepth;
report.ATAPI.MaxQueueDepthSpecified = true; report.ATAPI.MaxQueueDepthSpecified = true;
} }
if(atapiId.MDMAActive != 0) if(atapiId.MDMAActive != 0)
{ {
report.ATAPI.MDMAActive = atapiId.MDMAActive; report.ATAPI.MDMAActive = atapiId.MDMAActive;
report.ATAPI.MDMAActiveSpecified = true; report.ATAPI.MDMAActiveSpecified = true;
} }
if(atapiId.MDMASupported != 0) if(atapiId.MDMASupported != 0)
{ {
report.ATAPI.MDMASupported = atapiId.MDMASupported; report.ATAPI.MDMASupported = atapiId.MDMASupported;
report.ATAPI.MDMASupportedSpecified = true; report.ATAPI.MDMASupportedSpecified = true;
} }
if(atapiId.MinDownloadMicroMode3 != 0) if(atapiId.MinDownloadMicroMode3 != 0)
{ {
report.ATAPI.MinDownloadMicroMode3 = atapiId.MinDownloadMicroMode3; report.ATAPI.MinDownloadMicroMode3 = atapiId.MinDownloadMicroMode3;
report.ATAPI.MinDownloadMicroMode3Specified = true; report.ATAPI.MinDownloadMicroMode3Specified = true;
} }
if(atapiId.MinMDMACycleTime != 0) if(atapiId.MinMDMACycleTime != 0)
{ {
report.ATAPI.MinMDMACycleTime = atapiId.MinMDMACycleTime; report.ATAPI.MinMDMACycleTime = atapiId.MinMDMACycleTime;
report.ATAPI.MinMDMACycleTimeSpecified = true; report.ATAPI.MinMDMACycleTimeSpecified = true;
} }
if(atapiId.MinorVersion != 0) if(atapiId.MinorVersion != 0)
{ {
report.ATAPI.MinorVersion = atapiId.MinorVersion; report.ATAPI.MinorVersion = atapiId.MinorVersion;
report.ATAPI.MinorVersionSpecified = true; report.ATAPI.MinorVersionSpecified = true;
} }
if(atapiId.MinPIOCycleTimeNoFlow != 0) if(atapiId.MinPIOCycleTimeNoFlow != 0)
{ {
report.ATAPI.MinPIOCycleTimeNoFlow = atapiId.MinPIOCycleTimeNoFlow; report.ATAPI.MinPIOCycleTimeNoFlow = atapiId.MinPIOCycleTimeNoFlow;
report.ATAPI.MinPIOCycleTimeNoFlowSpecified = true; report.ATAPI.MinPIOCycleTimeNoFlowSpecified = true;
} }
if(atapiId.MinPIOCycleTimeFlow != 0) if(atapiId.MinPIOCycleTimeFlow != 0)
{ {
report.ATAPI.MinPIOCycleTimeFlow = atapiId.MinPIOCycleTimeFlow; report.ATAPI.MinPIOCycleTimeFlow = atapiId.MinPIOCycleTimeFlow;
report.ATAPI.MinPIOCycleTimeFlowSpecified = true; report.ATAPI.MinPIOCycleTimeFlowSpecified = true;
} }
if(!string.IsNullOrWhiteSpace(atapiId.Model)) if(!string.IsNullOrWhiteSpace(atapiId.Model))
{ {
report.ATAPI.Model = atapiId.Model; report.ATAPI.Model = atapiId.Model;
report.ATAPI.ModelSpecified = true; report.ATAPI.ModelSpecified = true;
} }
if(atapiId.MultipleMaxSectors != 0) if(atapiId.MultipleMaxSectors != 0)
{ {
report.ATAPI.MultipleMaxSectors = atapiId.MultipleMaxSectors; report.ATAPI.MultipleMaxSectors = atapiId.MultipleMaxSectors;
report.ATAPI.MultipleMaxSectorsSpecified = true; report.ATAPI.MultipleMaxSectorsSpecified = true;
} }
if(atapiId.MultipleSectorNumber != 0) if(atapiId.MultipleSectorNumber != 0)
{ {
report.ATAPI.MultipleSectorNumber = atapiId.MultipleSectorNumber; report.ATAPI.MultipleSectorNumber = atapiId.MultipleSectorNumber;
report.ATAPI.MultipleSectorNumberSpecified = true; report.ATAPI.MultipleSectorNumberSpecified = true;
} }
if(atapiId.NVCacheCaps != 0) if(atapiId.NVCacheCaps != 0)
{ {
report.ATAPI.NVCacheCaps = atapiId.NVCacheCaps; report.ATAPI.NVCacheCaps = atapiId.NVCacheCaps;
report.ATAPI.NVCacheCapsSpecified = true; report.ATAPI.NVCacheCapsSpecified = true;
} }
if(atapiId.NVCacheSize != 0) if(atapiId.NVCacheSize != 0)
{ {
report.ATAPI.NVCacheSize = atapiId.NVCacheSize; report.ATAPI.NVCacheSize = atapiId.NVCacheSize;
report.ATAPI.NVCacheSizeSpecified = true; report.ATAPI.NVCacheSizeSpecified = true;
} }
if(atapiId.NVCacheWriteSpeed != 0) if(atapiId.NVCacheWriteSpeed != 0)
{ {
report.ATAPI.NVCacheWriteSpeed = atapiId.NVCacheWriteSpeed; report.ATAPI.NVCacheWriteSpeed = atapiId.NVCacheWriteSpeed;
report.ATAPI.NVCacheWriteSpeedSpecified = true; report.ATAPI.NVCacheWriteSpeedSpecified = true;
} }
if(atapiId.NVEstimatedSpinUp != 0) if(atapiId.NVEstimatedSpinUp != 0)
{ {
report.ATAPI.NVEstimatedSpinUp = atapiId.NVEstimatedSpinUp; report.ATAPI.NVEstimatedSpinUp = atapiId.NVEstimatedSpinUp;
report.ATAPI.NVEstimatedSpinUpSpecified = true; report.ATAPI.NVEstimatedSpinUpSpecified = true;
} }
if(atapiId.PacketBusRelease != 0) if(atapiId.PacketBusRelease != 0)
{ {
report.ATAPI.PacketBusRelease = atapiId.PacketBusRelease; report.ATAPI.PacketBusRelease = atapiId.PacketBusRelease;
report.ATAPI.PacketBusReleaseSpecified = true; report.ATAPI.PacketBusReleaseSpecified = true;
} }
if(atapiId.PIOTransferTimingMode != 0) if(atapiId.PIOTransferTimingMode != 0)
{ {
report.ATAPI.PIOTransferTimingMode = atapiId.PIOTransferTimingMode; report.ATAPI.PIOTransferTimingMode = atapiId.PIOTransferTimingMode;
report.ATAPI.PIOTransferTimingModeSpecified = true; report.ATAPI.PIOTransferTimingModeSpecified = true;
} }
if(atapiId.RecommendedAAM != 0) if(atapiId.RecommendedAAM != 0)
{ {
report.ATAPI.RecommendedAAM = atapiId.RecommendedAAM; report.ATAPI.RecommendedAAM = atapiId.RecommendedAAM;
report.ATAPI.RecommendedAAMSpecified = true; report.ATAPI.RecommendedAAMSpecified = true;
} }
if(atapiId.RecMDMACycleTime != 0) if(atapiId.RecMDMACycleTime != 0)
{ {
report.ATAPI.RecommendedMDMACycleTime = atapiId.RecMDMACycleTime; report.ATAPI.RecommendedMDMACycleTime = atapiId.RecMDMACycleTime;
report.ATAPI.RecommendedMDMACycleTimeSpecified = true; report.ATAPI.RecommendedMDMACycleTimeSpecified = true;
} }
if(atapiId.RemovableStatusSet != 0) if(atapiId.RemovableStatusSet != 0)
{ {
report.ATAPI.RemovableStatusSet = atapiId.RemovableStatusSet; report.ATAPI.RemovableStatusSet = atapiId.RemovableStatusSet;
report.ATAPI.RemovableStatusSetSpecified = true; report.ATAPI.RemovableStatusSetSpecified = true;
} }
if(atapiId.SATACapabilities != 0) if(atapiId.SATACapabilities != 0)
{ {
report.ATAPI.SATACapabilities = atapiId.SATACapabilities; report.ATAPI.SATACapabilities = atapiId.SATACapabilities;
report.ATAPI.SATACapabilitiesSpecified = true; report.ATAPI.SATACapabilitiesSpecified = true;
} }
if(atapiId.SATACapabilities2 != 0) if(atapiId.SATACapabilities2 != 0)
{ {
report.ATAPI.SATACapabilities2 = atapiId.SATACapabilities2; report.ATAPI.SATACapabilities2 = atapiId.SATACapabilities2;
report.ATAPI.SATACapabilities2Specified = true; report.ATAPI.SATACapabilities2Specified = true;
} }
if(atapiId.SATAFeatures != 0) if(atapiId.SATAFeatures != 0)
{ {
report.ATAPI.SATAFeatures = atapiId.SATAFeatures; report.ATAPI.SATAFeatures = atapiId.SATAFeatures;
report.ATAPI.SATAFeaturesSpecified = true; report.ATAPI.SATAFeaturesSpecified = true;
} }
if(atapiId.SCTCommandTransport != 0) if(atapiId.SCTCommandTransport != 0)
{ {
report.ATAPI.SCTCommandTransport = atapiId.SCTCommandTransport; report.ATAPI.SCTCommandTransport = atapiId.SCTCommandTransport;
report.ATAPI.SCTCommandTransportSpecified = true; report.ATAPI.SCTCommandTransportSpecified = true;
} }
if(atapiId.SectorsPerCard != 0) if(atapiId.SectorsPerCard != 0)
{ {
report.ATAPI.SectorsPerCard = atapiId.SectorsPerCard; report.ATAPI.SectorsPerCard = atapiId.SectorsPerCard;
report.ATAPI.SectorsPerCardSpecified = true; report.ATAPI.SectorsPerCardSpecified = true;
} }
if(atapiId.SecurityEraseTime != 0) if(atapiId.SecurityEraseTime != 0)
{ {
report.ATAPI.SecurityEraseTime = atapiId.SecurityEraseTime; report.ATAPI.SecurityEraseTime = atapiId.SecurityEraseTime;
report.ATAPI.SecurityEraseTimeSpecified = true; report.ATAPI.SecurityEraseTimeSpecified = true;
} }
if(atapiId.SecurityStatus != 0) if(atapiId.SecurityStatus != 0)
{ {
report.ATAPI.SecurityStatus = atapiId.SecurityStatus; report.ATAPI.SecurityStatus = atapiId.SecurityStatus;
report.ATAPI.SecurityStatusSpecified = true; report.ATAPI.SecurityStatusSpecified = true;
} }
if(atapiId.ServiceBusyClear != 0) if(atapiId.ServiceBusyClear != 0)
{ {
report.ATAPI.ServiceBusyClear = atapiId.ServiceBusyClear; report.ATAPI.ServiceBusyClear = atapiId.ServiceBusyClear;
report.ATAPI.ServiceBusyClearSpecified = true; report.ATAPI.ServiceBusyClearSpecified = true;
} }
if(atapiId.SpecificConfiguration != 0) if(atapiId.SpecificConfiguration != 0)
{ {
report.ATAPI.SpecificConfiguration = atapiId.SpecificConfiguration; report.ATAPI.SpecificConfiguration = atapiId.SpecificConfiguration;
report.ATAPI.SpecificConfigurationSpecified = true; report.ATAPI.SpecificConfigurationSpecified = true;
} }
if(atapiId.StreamAccessLatency != 0) if(atapiId.StreamAccessLatency != 0)
{ {
report.ATAPI.StreamAccessLatency = atapiId.StreamAccessLatency; report.ATAPI.StreamAccessLatency = atapiId.StreamAccessLatency;
report.ATAPI.StreamAccessLatencySpecified = true; report.ATAPI.StreamAccessLatencySpecified = true;
} }
if(atapiId.StreamMinReqSize != 0) if(atapiId.StreamMinReqSize != 0)
{ {
report.ATAPI.StreamMinReqSize = atapiId.StreamMinReqSize; report.ATAPI.StreamMinReqSize = atapiId.StreamMinReqSize;
report.ATAPI.StreamMinReqSizeSpecified = true; report.ATAPI.StreamMinReqSizeSpecified = true;
} }
if(atapiId.StreamPerformanceGranularity != 0) if(atapiId.StreamPerformanceGranularity != 0)
{ {
report.ATAPI.StreamPerformanceGranularity = atapiId.StreamPerformanceGranularity; report.ATAPI.StreamPerformanceGranularity = atapiId.StreamPerformanceGranularity;
report.ATAPI.StreamPerformanceGranularitySpecified = true; report.ATAPI.StreamPerformanceGranularitySpecified = true;
} }
if(atapiId.StreamTransferTimeDMA != 0) if(atapiId.StreamTransferTimeDMA != 0)
{ {
report.ATAPI.StreamTransferTimeDMA = atapiId.StreamTransferTimeDMA; report.ATAPI.StreamTransferTimeDMA = atapiId.StreamTransferTimeDMA;
report.ATAPI.StreamTransferTimeDMASpecified = true; report.ATAPI.StreamTransferTimeDMASpecified = true;
} }
if(atapiId.StreamTransferTimePIO != 0) if(atapiId.StreamTransferTimePIO != 0)
{ {
report.ATAPI.StreamTransferTimePIO = atapiId.StreamTransferTimePIO; report.ATAPI.StreamTransferTimePIO = atapiId.StreamTransferTimePIO;
report.ATAPI.StreamTransferTimePIOSpecified = true; report.ATAPI.StreamTransferTimePIOSpecified = true;
} }
if(atapiId.TransportMajorVersion != 0) if(atapiId.TransportMajorVersion != 0)
{ {
report.ATAPI.TransportMajorVersion = atapiId.TransportMajorVersion; report.ATAPI.TransportMajorVersion = atapiId.TransportMajorVersion;
report.ATAPI.TransportMajorVersionSpecified = true; report.ATAPI.TransportMajorVersionSpecified = true;
} }
if(atapiId.TransportMinorVersion != 0) if(atapiId.TransportMinorVersion != 0)
{ {
report.ATAPI.TransportMinorVersion = atapiId.TransportMinorVersion; report.ATAPI.TransportMinorVersion = atapiId.TransportMinorVersion;
report.ATAPI.TransportMinorVersionSpecified = true; report.ATAPI.TransportMinorVersionSpecified = true;
} }
if(atapiId.TrustedComputing != 0) if(atapiId.TrustedComputing != 0)
{ {
report.ATAPI.TrustedComputing = atapiId.TrustedComputing; report.ATAPI.TrustedComputing = atapiId.TrustedComputing;
report.ATAPI.TrustedComputingSpecified = true; report.ATAPI.TrustedComputingSpecified = true;
} }
if(atapiId.UDMAActive != 0) if(atapiId.UDMAActive != 0)
{ {
report.ATAPI.UDMAActive = atapiId.UDMAActive; report.ATAPI.UDMAActive = atapiId.UDMAActive;
report.ATAPI.UDMAActiveSpecified = true; report.ATAPI.UDMAActiveSpecified = true;
} }
if(atapiId.UDMASupported != 0) if(atapiId.UDMASupported != 0)
{ {
report.ATAPI.UDMASupported = atapiId.UDMASupported; report.ATAPI.UDMASupported = atapiId.UDMASupported;
report.ATAPI.UDMASupportedSpecified = true; report.ATAPI.UDMASupportedSpecified = true;
} }
if(atapiId.WRVMode != 0) if(atapiId.WRVMode != 0)
{ {
report.ATAPI.WRVMode = atapiId.WRVMode; report.ATAPI.WRVMode = atapiId.WRVMode;
report.ATAPI.WRVModeSpecified = true; report.ATAPI.WRVModeSpecified = true;
} }
if(atapiId.WRVSectorCountMode3 != 0) if(atapiId.WRVSectorCountMode3 != 0)
{ {
report.ATAPI.WRVSectorCountMode3 = atapiId.WRVSectorCountMode3; report.ATAPI.WRVSectorCountMode3 = atapiId.WRVSectorCountMode3;
report.ATAPI.WRVSectorCountMode3Specified = true; report.ATAPI.WRVSectorCountMode3Specified = true;
} }
if(atapiId.WRVSectorCountMode2 != 0) if(atapiId.WRVSectorCountMode2 != 0)
{ {
report.ATAPI.WRVSectorCountMode2 = atapiId.WRVSectorCountMode2; report.ATAPI.WRVSectorCountMode2 = atapiId.WRVSectorCountMode2;
report.ATAPI.WRVSectorCountMode2Specified = true; report.ATAPI.WRVSectorCountMode2Specified = true;
}
} }
if(debug) report.ATAPI.Identify = buffer; if(debug) report.ATAPI.Identify = buffer;
} }

View File

@@ -58,8 +58,6 @@ namespace DiscImageChef.Core.Devices.Scanning
sense = dev.AtaIdentify(out cmdBuf, out errorChs); sense = dev.AtaIdentify(out cmdBuf, out errorChs);
if(!sense && Identify.Decode(cmdBuf).HasValue) if(!sense && Identify.Decode(cmdBuf).HasValue)
{ {
Identify.IdentifyDevice ataId = Identify.Decode(cmdBuf).Value;
// Initializate reader // Initializate reader
Reader ataReader = new Reader(dev, timeout, cmdBuf); Reader ataReader = new Reader(dev, timeout, cmdBuf);
// Fill reader blocks // Fill reader blocks