diff --git a/DiscImageChef.Core/Devices/Dumping/ATA.cs b/DiscImageChef.Core/Devices/Dumping/ATA.cs index d22905dc2..422ad1449 100644 --- a/DiscImageChef.Core/Devices/Dumping/ATA.cs +++ b/DiscImageChef.Core/Devices/Dumping/ATA.cs @@ -83,225 +83,164 @@ namespace DiscImageChef.Core.Devices.Dumping sense = dev.AtaIdentify(out byte[] cmdBuf, out AtaErrorRegistersCHS errorChs); 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 = - new CICMMetadataType {BlockMedia = new[] {new BlockMediaType()}}; + CICMMetadataType sidecar = + new CICMMetadataType {BlockMedia = new[] {new BlockMediaType()}}; - if(dev.IsUsb) - { - dumpLog.WriteLine("Reading USB descriptors."); - sidecar.BlockMedia[0].USB = new USBType + if(dev.IsUsb) { - ProductID = dev.UsbProductId, - VendorID = dev.UsbVendorId, - Descriptors = new DumpType + dumpLog.WriteLine("Reading USB descriptors."); + sidecar.BlockMedia[0].USB = new USBType { - Image = outputPrefix + ".usbdescriptors.bin", - Size = dev.UsbDescriptors.Length, - Checksums = Checksum.GetChecksums(dev.UsbDescriptors).ToArray() - } - }; - DataFile.WriteTo("ATA Dump", sidecar.BlockMedia[0].USB.Descriptors.Image, dev.UsbDescriptors); - } - - 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; + ProductID = dev.UsbProductId, + VendorID = dev.UsbVendorId, + Descriptors = new DumpType + { + Image = outputPrefix + ".usbdescriptors.bin", + Size = dev.UsbDescriptors.Length, + Checksums = Checksum.GetChecksums(dev.UsbDescriptors).ToArray() } - } - - 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; + }; + DataFile.WriteTo("ATA Dump", sidecar.BlockMedia[0].USB.Descriptors.Image, dev.UsbDescriptors); } - 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)); - - #region Error handling - if(resume.BadBlocks.Count > 0 && !aborted) + if(dev.IsPcmcia) { - int pass = 0; - bool forward = true; - bool runningPersistent = false; + 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); - repeatRetryLba: - ulong[] tmpArray = resume.BadBlocks.ToArray(); - foreach(ulong badSector in tmpArray) + 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; + } + } + + 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) { @@ -310,53 +249,61 @@ namespace DiscImageChef.Core.Devices.Dumping break; } - DicConsole.Write("\rRetrying sector {0}, pass {1}, {3}{2}", badSector, pass + 1, - forward ? "forward" : "reverse", - runningPersistent ? "recovering partial data, " : ""); + if(blocks - i < blocksToRead) blocksToRead = (byte)(blocks - i); - 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) { - resume.BadBlocks.Remove(badSector); - extents.Add(badSector); - dumpFile.WriteAt(cmdBuf, badSector, blockSize); - dumpLog.WriteLine("Correctly retried block {0} in pass {1}.", badSector, pass); + mhddLog.Write(i, duration); + ibgLog.Write(i, currentSpeed * 1024); + dumpFile.Write(cmdBuf); + extents.Add(i, blocksToRead, true); } - 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; + 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; DicConsole.WriteLine(); - } - #endregion Error handling LBA + 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)); - 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++) + #region Error handling + if(resume.BadBlocks.Count > 0 && !aborted) { - 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) { @@ -365,143 +312,233 @@ namespace DiscImageChef.Core.Devices.Dumping break; } -#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("\rRetrying sector {0}, pass {1}, {3}{2}", badSector, pass + 1, + forward ? "forward" : "reverse", + runningPersistent ? "recovering partial data, " : ""); - 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); + bool error = ataReader.ReadBlock(out cmdBuf, badSector, 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); + resume.BadBlocks.Remove(badSector); + extents.Add(badSector); + dumpFile.WriteAt(cmdBuf, badSector, blockSize); + dumpLog.WriteLine("Correctly retried block {0} in pass {1}.", badSector, pass); } - 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(duration < 500) mhddLog.Write(currentBlock, 65535); - else mhddLog.Write(currentBlock, duration); + if(aborted) + { + currentTry.Extents = ExtentsConverter.ToMetadata(extents); + dumpLog.WriteLine("Aborted!"); + break; + } - ibgLog.Write(currentBlock, 0); - dumpFile.Write(new byte[blockSize]); +#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 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; - 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)); - } + dataChk = new Checksum(); + dumpFile.Seek(0, SeekOrigin.Begin); + blocksToRead = 500; - dataChk = new Checksum(); - dumpFile.Seek(0, SeekOrigin.Begin); - blocksToRead = 500; - - dumpLog.WriteLine("Checksum starts."); - for(ulong i = 0; i < blocks; i += blocksToRead) - { - if(aborted) + dumpLog.WriteLine("Checksum starts."); + for(ulong i = 0; i < blocks; i += blocksToRead) { - 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 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++) + if(aborted) { - 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 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, - EndSector = (int)(partitions[i].Start + partitions[i].Length - 1), - Name = partitions[i].Name, - Sequence = (int)partitions[i].Sequence, - StartSector = (int)partitions[i].Start, - Type = partitions[i].Type - }; + xmlFileSysInfo[i] = new PartitionType + { + Description = partitions[i].Description, + EndSector = (int)(partitions[i].Start + partitions[i].Length - 1), + Name = partitions[i].Name, + Sequence = (int)partitions[i].Sequence, + StartSector = (int)partitions[i].Start, + Type = partitions[i].Type + }; + List lstFs = new List(); + 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 lstFs = new List(); - 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); + + Partition wholePart = new Partition + { + Name = "Whole device", + Length = blocks, + Size = blocks * blockSize + }; foreach(Filesystem plugin in plugins.PluginsList.Values) 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); Statistics.AddFilesystem(plugin.XmlFSType.Type); dumpLog.WriteLine("Filesystem {0} found.", plugin.XmlFSType.Type); @@ -510,104 +547,70 @@ namespace DiscImageChef.Core.Devices.Dumping 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); + //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."); - - xmlFileSysInfo = new PartitionType[1]; - xmlFileSysInfo[0] = new PartitionType {EndSector = (int)(blocks - 1), StartSector = 0}; - List lstFs = new List(); - - Partition wholePart = new Partition - { - Name = "Whole device", - Length = blocks, - Size = blocks * blockSize - }; - - foreach(Filesystem plugin in plugins.PluginsList.Values) - try - { - if(!plugin.Identify(imageFormat, wholePart)) continue; - - plugin.GetInformation(imageFormat, wholePart, 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("Create-sidecar command", "Plugin {0} crashed", _plugin.Name); - } - - if(lstFs.Count > 0) xmlFileSysInfo[0].FileSystems = lstFs.ToArray(); + 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; } - } - 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 - { - 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(); + 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).", - (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(); + if(!aborted) + { + DicConsole.WriteLine("Writing metadata sidecar"); - if(!aborted) - { - DicConsole.WriteLine("Writing metadata sidecar"); + FileStream xmlFs = new FileStream(outputPrefix + ".cicm.xml", FileMode.Create); - FileStream xmlFs = new FileStream(outputPrefix + ".cicm.xml", FileMode.Create); - - XmlSerializer xmlSer = - new XmlSerializer(typeof(CICMMetadataType)); - xmlSer.Serialize(xmlFs, sidecar); - xmlFs.Close(); + XmlSerializer xmlSer = + new XmlSerializer(typeof(CICMMetadataType)); + xmlSer.Serialize(xmlFs, sidecar); + xmlFs.Close(); + } } Statistics.AddMedia(CommonTypes.MediaType.GENERIC_HDD, true); diff --git a/DiscImageChef.Core/Devices/Reader.cs b/DiscImageChef.Core/Devices/Reader.cs index 7c3c5cfe8..be1b2991d 100644 --- a/DiscImageChef.Core/Devices/Reader.cs +++ b/DiscImageChef.Core/Devices/Reader.cs @@ -67,7 +67,8 @@ namespace DiscImageChef.Core.Devices switch(dev.Type) { 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; case DeviceType.NVMe: throw new NotImplementedException("NVMe devices not yet supported."); } diff --git a/DiscImageChef.Core/Devices/Report/ATA.cs b/DiscImageChef.Core/Devices/Report/ATA.cs index 4030368f1..a6d9d97ba 100644 --- a/DiscImageChef.Core/Devices/Report/ATA.cs +++ b/DiscImageChef.Core/Devices/Report/ATA.cs @@ -63,1168 +63,1171 @@ namespace DiscImageChef.Core.Devices.Report if(!Identify.Decode(buffer).HasValue) return; - Identify.IdentifyDevice ataId = Identify.Decode(buffer).Value; + Identify.IdentifyDevice? ataIdNullable = Identify.Decode(buffer); + if(ataIdNullable != null) { + Identify.IdentifyDevice ataId = ataIdNullable.Value; - if((ushort)ataId.GeneralConfiguration == 0x848A) - { - report.CompactFlash = true; - report.CompactFlashSpecified = true; - removable = false; - } - else if(!removable && - ataId.GeneralConfiguration.HasFlag(Identify.GeneralConfigurationBit.Removable)) - { - pressedKey = new ConsoleKeyInfo(); - while(pressedKey.Key != ConsoleKey.Y && pressedKey.Key != ConsoleKey.N) + if((ushort)ataId.GeneralConfiguration == 0x848A) { - DicConsole.Write("Is the media removable from the reading/writing elements? (Y/N): "); - pressedKey = System.Console.ReadKey(); - DicConsole.WriteLine(); + report.CompactFlash = true; + report.CompactFlashSpecified = true; + removable = false; } - - removable = pressedKey.Key == ConsoleKey.Y; - } - - if(removable) - { - DicConsole.WriteLine("Please remove any media from the device and press any key when it is out."); - System.Console.ReadKey(true); - DicConsole.WriteLine("Querying ATA IDENTIFY..."); - dev.AtaIdentify(out buffer, out errorRegs, timeout, out duration); - ataId = Identify.Decode(buffer).Value; - } - - report.ATA = new ataType(); - - if(!string.IsNullOrWhiteSpace(ataId.AdditionalPID)) - { - report.ATA.AdditionalPID = ataId.AdditionalPID; - report.ATA.AdditionalPIDSpecified = true; - } - if(ataId.APIOSupported != 0) - { - report.ATA.APIOSupported = ataId.APIOSupported; - report.ATA.APIOSupportedSpecified = true; - } - if(ataId.BufferType != 0) - { - report.ATA.BufferType = ataId.BufferType; - report.ATA.BufferTypeSpecified = true; - } - if(ataId.BufferSize != 0) - { - report.ATA.BufferSize = ataId.BufferSize; - report.ATA.BufferSizeSpecified = true; - } - if(ataId.Capabilities != 0) - { - report.ATA.Capabilities = ataId.Capabilities; - report.ATA.CapabilitiesSpecified = true; - } - if(ataId.Capabilities2 != 0) - { - report.ATA.Capabilities2 = ataId.Capabilities2; - report.ATA.Capabilities2Specified = true; - } - if(ataId.Capabilities3 != 0) - { - report.ATA.Capabilities3 = ataId.Capabilities3; - report.ATA.Capabilities3Specified = true; - } - if(ataId.CFAPowerMode != 0) - { - report.ATA.CFAPowerMode = ataId.CFAPowerMode; - report.ATA.CFAPowerModeSpecified = true; - } - if(ataId.CommandSet != 0) - { - report.ATA.CommandSet = ataId.CommandSet; - report.ATA.CommandSetSpecified = true; - } - if(ataId.CommandSet2 != 0) - { - report.ATA.CommandSet2 = ataId.CommandSet2; - report.ATA.CommandSet2Specified = true; - } - if(ataId.CommandSet3 != 0) - { - report.ATA.CommandSet3 = ataId.CommandSet3; - report.ATA.CommandSet3Specified = true; - } - if(ataId.CommandSet4 != 0) - { - report.ATA.CommandSet4 = ataId.CommandSet4; - report.ATA.CommandSet4Specified = true; - } - if(ataId.CommandSet5 != 0) - { - report.ATA.CommandSet5 = ataId.CommandSet5; - report.ATA.CommandSet5Specified = true; - } - if(ataId.CurrentAAM != 0) - { - report.ATA.CurrentAAM = ataId.CurrentAAM; - report.ATA.CurrentAAMSpecified = true; - } - if(ataId.CurrentAPM != 0) - { - report.ATA.CurrentAPM = ataId.CurrentAPM; - report.ATA.CurrentAPMSpecified = true; - } - if(ataId.DataSetMgmt != 0) - { - report.ATA.DataSetMgmt = ataId.DataSetMgmt; - report.ATA.DataSetMgmtSpecified = true; - } - if(ataId.DataSetMgmtSize != 0) - { - report.ATA.DataSetMgmtSize = ataId.DataSetMgmtSize; - report.ATA.DataSetMgmtSizeSpecified = true; - } - if(ataId.DeviceFormFactor != 0) - { - report.ATA.DeviceFormFactor = ataId.DeviceFormFactor; - report.ATA.DeviceFormFactorSpecified = true; - } - if(ataId.DMAActive != 0) - { - report.ATA.DMAActive = ataId.DMAActive; - report.ATA.DMAActiveSpecified = true; - } - if(ataId.DMASupported != 0) - { - report.ATA.DMASupported = ataId.DMASupported; - report.ATA.DMASupportedSpecified = true; - } - if(ataId.DMATransferTimingMode != 0) - { - report.ATA.DMATransferTimingMode = ataId.DMATransferTimingMode; - report.ATA.DMATransferTimingModeSpecified = true; - } - if(ataId.EnhancedSecurityEraseTime != 0) - { - report.ATA.EnhancedSecurityEraseTime = ataId.EnhancedSecurityEraseTime; - report.ATA.EnhancedSecurityEraseTimeSpecified = true; - } - if(ataId.EnabledCommandSet != 0) - { - report.ATA.EnabledCommandSet = ataId.EnabledCommandSet; - report.ATA.EnabledCommandSetSpecified = true; - } - if(ataId.EnabledCommandSet2 != 0) - { - report.ATA.EnabledCommandSet2 = ataId.EnabledCommandSet2; - report.ATA.EnabledCommandSet2Specified = true; - } - if(ataId.EnabledCommandSet3 != 0) - { - report.ATA.EnabledCommandSet3 = ataId.EnabledCommandSet3; - report.ATA.EnabledCommandSet3Specified = true; - } - if(ataId.EnabledCommandSet4 != 0) - { - report.ATA.EnabledCommandSet4 = ataId.EnabledCommandSet4; - report.ATA.EnabledCommandSet4Specified = true; - } - if(ataId.EnabledSATAFeatures != 0) - { - report.ATA.EnabledSATAFeatures = ataId.EnabledSATAFeatures; - report.ATA.EnabledSATAFeaturesSpecified = true; - } - if(ataId.ExtendedUserSectors != 0) - { - report.ATA.ExtendedUserSectors = ataId.ExtendedUserSectors; - report.ATA.ExtendedUserSectorsSpecified = true; - } - if(ataId.FreeFallSensitivity != 0) - { - report.ATA.FreeFallSensitivity = ataId.FreeFallSensitivity; - report.ATA.FreeFallSensitivitySpecified = true; - } - if(!string.IsNullOrWhiteSpace(ataId.FirmwareRevision)) - { - report.ATA.FirmwareRevision = ataId.FirmwareRevision; - report.ATA.FirmwareRevisionSpecified = true; - } - if(ataId.GeneralConfiguration != 0) - { - report.ATA.GeneralConfiguration = ataId.GeneralConfiguration; - report.ATA.GeneralConfigurationSpecified = true; - } - if(ataId.HardwareResetResult != 0) - { - report.ATA.HardwareResetResult = ataId.HardwareResetResult; - report.ATA.HardwareResetResultSpecified = true; - } - if(ataId.InterseekDelay != 0) - { - report.ATA.InterseekDelay = ataId.InterseekDelay; - report.ATA.InterseekDelaySpecified = true; - } - if(ataId.MajorVersion != 0) - { - report.ATA.MajorVersion = ataId.MajorVersion; - report.ATA.MajorVersionSpecified = true; - } - if(ataId.MasterPasswordRevisionCode != 0) - { - report.ATA.MasterPasswordRevisionCode = ataId.MasterPasswordRevisionCode; - report.ATA.MasterPasswordRevisionCodeSpecified = true; - } - if(ataId.MaxDownloadMicroMode3 != 0) - { - report.ATA.MaxDownloadMicroMode3 = ataId.MaxDownloadMicroMode3; - report.ATA.MaxDownloadMicroMode3Specified = true; - } - if(ataId.MaxQueueDepth != 0) - { - report.ATA.MaxQueueDepth = ataId.MaxQueueDepth; - report.ATA.MaxQueueDepthSpecified = true; - } - if(ataId.MDMAActive != 0) - { - report.ATA.MDMAActive = ataId.MDMAActive; - report.ATA.MDMAActiveSpecified = true; - } - if(ataId.MDMASupported != 0) - { - report.ATA.MDMASupported = ataId.MDMASupported; - report.ATA.MDMASupportedSpecified = true; - } - if(ataId.MinDownloadMicroMode3 != 0) - { - report.ATA.MinDownloadMicroMode3 = ataId.MinDownloadMicroMode3; - report.ATA.MinDownloadMicroMode3Specified = true; - } - if(ataId.MinMDMACycleTime != 0) - { - report.ATA.MinMDMACycleTime = ataId.MinMDMACycleTime; - report.ATA.MinMDMACycleTimeSpecified = true; - } - if(ataId.MinorVersion != 0) - { - report.ATA.MinorVersion = ataId.MinorVersion; - report.ATA.MinorVersionSpecified = true; - } - if(ataId.MinPIOCycleTimeNoFlow != 0) - { - report.ATA.MinPIOCycleTimeNoFlow = ataId.MinPIOCycleTimeNoFlow; - report.ATA.MinPIOCycleTimeNoFlowSpecified = true; - } - if(ataId.MinPIOCycleTimeFlow != 0) - { - report.ATA.MinPIOCycleTimeFlow = ataId.MinPIOCycleTimeFlow; - report.ATA.MinPIOCycleTimeFlowSpecified = true; - } - if(!string.IsNullOrWhiteSpace(ataId.Model)) - { - report.ATA.Model = ataId.Model; - report.ATA.ModelSpecified = true; - } - if(ataId.MultipleMaxSectors != 0) - { - report.ATA.MultipleMaxSectors = ataId.MultipleMaxSectors; - report.ATA.MultipleMaxSectorsSpecified = true; - } - if(ataId.MultipleSectorNumber != 0) - { - report.ATA.MultipleSectorNumber = ataId.MultipleSectorNumber; - report.ATA.MultipleSectorNumberSpecified = true; - } - if(ataId.NVCacheCaps != 0) - { - report.ATA.NVCacheCaps = ataId.NVCacheCaps; - report.ATA.NVCacheCapsSpecified = true; - } - if(ataId.NVCacheSize != 0) - { - report.ATA.NVCacheSize = ataId.NVCacheSize; - report.ATA.NVCacheSizeSpecified = true; - } - if(ataId.NVCacheWriteSpeed != 0) - { - report.ATA.NVCacheWriteSpeed = ataId.NVCacheWriteSpeed; - report.ATA.NVCacheWriteSpeedSpecified = true; - } - if(ataId.NVEstimatedSpinUp != 0) - { - report.ATA.NVEstimatedSpinUp = ataId.NVEstimatedSpinUp; - report.ATA.NVEstimatedSpinUpSpecified = true; - } - if(ataId.PacketBusRelease != 0) - { - report.ATA.PacketBusRelease = ataId.PacketBusRelease; - report.ATA.PacketBusReleaseSpecified = true; - } - if(ataId.PIOTransferTimingMode != 0) - { - report.ATA.PIOTransferTimingMode = ataId.PIOTransferTimingMode; - report.ATA.PIOTransferTimingModeSpecified = true; - } - if(ataId.RecommendedAAM != 0) - { - report.ATA.RecommendedAAM = ataId.RecommendedAAM; - report.ATA.RecommendedAAMSpecified = true; - } - if(ataId.RecMDMACycleTime != 0) - { - report.ATA.RecommendedMDMACycleTime = ataId.RecMDMACycleTime; - report.ATA.RecommendedMDMACycleTimeSpecified = true; - } - if(ataId.RemovableStatusSet != 0) - { - report.ATA.RemovableStatusSet = ataId.RemovableStatusSet; - report.ATA.RemovableStatusSetSpecified = true; - } - if(ataId.SATACapabilities != 0) - { - report.ATA.SATACapabilities = ataId.SATACapabilities; - report.ATA.SATACapabilitiesSpecified = true; - } - if(ataId.SATACapabilities2 != 0) - { - report.ATA.SATACapabilities2 = ataId.SATACapabilities2; - report.ATA.SATACapabilities2Specified = true; - } - if(ataId.SATAFeatures != 0) - { - report.ATA.SATAFeatures = ataId.SATAFeatures; - report.ATA.SATAFeaturesSpecified = true; - } - if(ataId.SCTCommandTransport != 0) - { - report.ATA.SCTCommandTransport = ataId.SCTCommandTransport; - report.ATA.SCTCommandTransportSpecified = true; - } - if(ataId.SectorsPerCard != 0) - { - report.ATA.SectorsPerCard = ataId.SectorsPerCard; - report.ATA.SectorsPerCardSpecified = true; - } - if(ataId.SecurityEraseTime != 0) - { - report.ATA.SecurityEraseTime = ataId.SecurityEraseTime; - report.ATA.SecurityEraseTimeSpecified = true; - } - if(ataId.SecurityStatus != 0) - { - report.ATA.SecurityStatus = ataId.SecurityStatus; - report.ATA.SecurityStatusSpecified = true; - } - if(ataId.ServiceBusyClear != 0) - { - report.ATA.ServiceBusyClear = ataId.ServiceBusyClear; - report.ATA.ServiceBusyClearSpecified = true; - } - if(ataId.SpecificConfiguration != 0) - { - report.ATA.SpecificConfiguration = ataId.SpecificConfiguration; - report.ATA.SpecificConfigurationSpecified = true; - } - if(ataId.StreamAccessLatency != 0) - { - report.ATA.StreamAccessLatency = ataId.StreamAccessLatency; - report.ATA.StreamAccessLatencySpecified = true; - } - if(ataId.StreamMinReqSize != 0) - { - report.ATA.StreamMinReqSize = ataId.StreamMinReqSize; - report.ATA.StreamMinReqSizeSpecified = true; - } - if(ataId.StreamPerformanceGranularity != 0) - { - report.ATA.StreamPerformanceGranularity = ataId.StreamPerformanceGranularity; - report.ATA.StreamPerformanceGranularitySpecified = true; - } - if(ataId.StreamTransferTimeDMA != 0) - { - report.ATA.StreamTransferTimeDMA = ataId.StreamTransferTimeDMA; - report.ATA.StreamTransferTimeDMASpecified = true; - } - if(ataId.StreamTransferTimePIO != 0) - { - report.ATA.StreamTransferTimePIO = ataId.StreamTransferTimePIO; - report.ATA.StreamTransferTimePIOSpecified = true; - } - if(ataId.TransportMajorVersion != 0) - { - report.ATA.TransportMajorVersion = ataId.TransportMajorVersion; - report.ATA.TransportMajorVersionSpecified = true; - } - if(ataId.TransportMinorVersion != 0) - { - report.ATA.TransportMinorVersion = ataId.TransportMinorVersion; - report.ATA.TransportMinorVersionSpecified = true; - } - if(ataId.TrustedComputing != 0) - { - report.ATA.TrustedComputing = ataId.TrustedComputing; - report.ATA.TrustedComputingSpecified = true; - } - if(ataId.UDMAActive != 0) - { - report.ATA.UDMAActive = ataId.UDMAActive; - report.ATA.UDMAActiveSpecified = true; - } - if(ataId.UDMASupported != 0) - { - report.ATA.UDMASupported = ataId.UDMASupported; - report.ATA.UDMASupportedSpecified = true; - } - if(ataId.WRVMode != 0) - { - report.ATA.WRVMode = ataId.WRVMode; - report.ATA.WRVModeSpecified = true; - } - if(ataId.WRVSectorCountMode3 != 0) - { - report.ATA.WRVSectorCountMode3 = ataId.WRVSectorCountMode3; - report.ATA.WRVSectorCountMode3Specified = true; - } - if(ataId.WRVSectorCountMode2 != 0) - { - report.ATA.WRVSectorCountMode2 = ataId.WRVSectorCountMode2; - report.ATA.WRVSectorCountMode2Specified = true; - } - if(debug) report.ATA.Identify = buffer; - - if(removable) - { - List mediaTests = new List(); - - pressedKey = new ConsoleKeyInfo(); - while(pressedKey.Key != ConsoleKey.N) + else if(!removable && + ataId.GeneralConfiguration.HasFlag(Identify.GeneralConfigurationBit.Removable)) { pressedKey = new ConsoleKeyInfo(); while(pressedKey.Key != ConsoleKey.Y && pressedKey.Key != ConsoleKey.N) { - DicConsole.Write("Do you have media that you can insert in the drive? (Y/N): "); + DicConsole.Write("Is the media removable from the reading/writing elements? (Y/N): "); pressedKey = System.Console.ReadKey(); DicConsole.WriteLine(); } - if(pressedKey.Key != ConsoleKey.Y) continue; + removable = pressedKey.Key == ConsoleKey.Y; + } - DicConsole.WriteLine("Please insert it in the drive and press any key when it is ready."); + if(removable) + { + DicConsole.WriteLine("Please remove any media from the device and press any key when it is out."); System.Console.ReadKey(true); - - testedMediaType mediaTest = new testedMediaType(); - DicConsole.Write("Please write a description of the media type and press enter: "); - mediaTest.MediumTypeName = System.Console.ReadLine(); - DicConsole.Write("Please write the media model and press enter: "); - mediaTest.Model = System.Console.ReadLine(); - - mediaTest.ManufacturerSpecified = true; - mediaTest.ModelSpecified = true; - mediaTest.MediaIsRecognized = true; - DicConsole.WriteLine("Querying ATA IDENTIFY..."); dev.AtaIdentify(out buffer, out errorRegs, timeout, out duration); + ataId = Identify.Decode(buffer).Value; + } - if(Identify.Decode(buffer).HasValue) + report.ATA = new ataType(); + + if(!string.IsNullOrWhiteSpace(ataId.AdditionalPID)) + { + report.ATA.AdditionalPID = ataId.AdditionalPID; + report.ATA.AdditionalPIDSpecified = true; + } + if(ataId.APIOSupported != 0) + { + report.ATA.APIOSupported = ataId.APIOSupported; + report.ATA.APIOSupportedSpecified = true; + } + if(ataId.BufferType != 0) + { + report.ATA.BufferType = ataId.BufferType; + report.ATA.BufferTypeSpecified = true; + } + if(ataId.BufferSize != 0) + { + report.ATA.BufferSize = ataId.BufferSize; + report.ATA.BufferSizeSpecified = true; + } + if(ataId.Capabilities != 0) + { + report.ATA.Capabilities = ataId.Capabilities; + report.ATA.CapabilitiesSpecified = true; + } + if(ataId.Capabilities2 != 0) + { + report.ATA.Capabilities2 = ataId.Capabilities2; + report.ATA.Capabilities2Specified = true; + } + if(ataId.Capabilities3 != 0) + { + report.ATA.Capabilities3 = ataId.Capabilities3; + report.ATA.Capabilities3Specified = true; + } + if(ataId.CFAPowerMode != 0) + { + report.ATA.CFAPowerMode = ataId.CFAPowerMode; + report.ATA.CFAPowerModeSpecified = true; + } + if(ataId.CommandSet != 0) + { + report.ATA.CommandSet = ataId.CommandSet; + report.ATA.CommandSetSpecified = true; + } + if(ataId.CommandSet2 != 0) + { + report.ATA.CommandSet2 = ataId.CommandSet2; + report.ATA.CommandSet2Specified = true; + } + if(ataId.CommandSet3 != 0) + { + report.ATA.CommandSet3 = ataId.CommandSet3; + report.ATA.CommandSet3Specified = true; + } + if(ataId.CommandSet4 != 0) + { + report.ATA.CommandSet4 = ataId.CommandSet4; + report.ATA.CommandSet4Specified = true; + } + if(ataId.CommandSet5 != 0) + { + report.ATA.CommandSet5 = ataId.CommandSet5; + report.ATA.CommandSet5Specified = true; + } + if(ataId.CurrentAAM != 0) + { + report.ATA.CurrentAAM = ataId.CurrentAAM; + report.ATA.CurrentAAMSpecified = true; + } + if(ataId.CurrentAPM != 0) + { + report.ATA.CurrentAPM = ataId.CurrentAPM; + report.ATA.CurrentAPMSpecified = true; + } + if(ataId.DataSetMgmt != 0) + { + report.ATA.DataSetMgmt = ataId.DataSetMgmt; + report.ATA.DataSetMgmtSpecified = true; + } + if(ataId.DataSetMgmtSize != 0) + { + report.ATA.DataSetMgmtSize = ataId.DataSetMgmtSize; + report.ATA.DataSetMgmtSizeSpecified = true; + } + if(ataId.DeviceFormFactor != 0) + { + report.ATA.DeviceFormFactor = ataId.DeviceFormFactor; + report.ATA.DeviceFormFactorSpecified = true; + } + if(ataId.DMAActive != 0) + { + report.ATA.DMAActive = ataId.DMAActive; + report.ATA.DMAActiveSpecified = true; + } + if(ataId.DMASupported != 0) + { + report.ATA.DMASupported = ataId.DMASupported; + report.ATA.DMASupportedSpecified = true; + } + if(ataId.DMATransferTimingMode != 0) + { + report.ATA.DMATransferTimingMode = ataId.DMATransferTimingMode; + report.ATA.DMATransferTimingModeSpecified = true; + } + if(ataId.EnhancedSecurityEraseTime != 0) + { + report.ATA.EnhancedSecurityEraseTime = ataId.EnhancedSecurityEraseTime; + report.ATA.EnhancedSecurityEraseTimeSpecified = true; + } + if(ataId.EnabledCommandSet != 0) + { + report.ATA.EnabledCommandSet = ataId.EnabledCommandSet; + report.ATA.EnabledCommandSetSpecified = true; + } + if(ataId.EnabledCommandSet2 != 0) + { + report.ATA.EnabledCommandSet2 = ataId.EnabledCommandSet2; + report.ATA.EnabledCommandSet2Specified = true; + } + if(ataId.EnabledCommandSet3 != 0) + { + report.ATA.EnabledCommandSet3 = ataId.EnabledCommandSet3; + report.ATA.EnabledCommandSet3Specified = true; + } + if(ataId.EnabledCommandSet4 != 0) + { + report.ATA.EnabledCommandSet4 = ataId.EnabledCommandSet4; + report.ATA.EnabledCommandSet4Specified = true; + } + if(ataId.EnabledSATAFeatures != 0) + { + report.ATA.EnabledSATAFeatures = ataId.EnabledSATAFeatures; + report.ATA.EnabledSATAFeaturesSpecified = true; + } + if(ataId.ExtendedUserSectors != 0) + { + report.ATA.ExtendedUserSectors = ataId.ExtendedUserSectors; + report.ATA.ExtendedUserSectorsSpecified = true; + } + if(ataId.FreeFallSensitivity != 0) + { + report.ATA.FreeFallSensitivity = ataId.FreeFallSensitivity; + report.ATA.FreeFallSensitivitySpecified = true; + } + if(!string.IsNullOrWhiteSpace(ataId.FirmwareRevision)) + { + report.ATA.FirmwareRevision = ataId.FirmwareRevision; + report.ATA.FirmwareRevisionSpecified = true; + } + if(ataId.GeneralConfiguration != 0) + { + report.ATA.GeneralConfiguration = ataId.GeneralConfiguration; + report.ATA.GeneralConfigurationSpecified = true; + } + if(ataId.HardwareResetResult != 0) + { + report.ATA.HardwareResetResult = ataId.HardwareResetResult; + report.ATA.HardwareResetResultSpecified = true; + } + if(ataId.InterseekDelay != 0) + { + report.ATA.InterseekDelay = ataId.InterseekDelay; + report.ATA.InterseekDelaySpecified = true; + } + if(ataId.MajorVersion != 0) + { + report.ATA.MajorVersion = ataId.MajorVersion; + report.ATA.MajorVersionSpecified = true; + } + if(ataId.MasterPasswordRevisionCode != 0) + { + report.ATA.MasterPasswordRevisionCode = ataId.MasterPasswordRevisionCode; + report.ATA.MasterPasswordRevisionCodeSpecified = true; + } + if(ataId.MaxDownloadMicroMode3 != 0) + { + report.ATA.MaxDownloadMicroMode3 = ataId.MaxDownloadMicroMode3; + report.ATA.MaxDownloadMicroMode3Specified = true; + } + if(ataId.MaxQueueDepth != 0) + { + report.ATA.MaxQueueDepth = ataId.MaxQueueDepth; + report.ATA.MaxQueueDepthSpecified = true; + } + if(ataId.MDMAActive != 0) + { + report.ATA.MDMAActive = ataId.MDMAActive; + report.ATA.MDMAActiveSpecified = true; + } + if(ataId.MDMASupported != 0) + { + report.ATA.MDMASupported = ataId.MDMASupported; + report.ATA.MDMASupportedSpecified = true; + } + if(ataId.MinDownloadMicroMode3 != 0) + { + report.ATA.MinDownloadMicroMode3 = ataId.MinDownloadMicroMode3; + report.ATA.MinDownloadMicroMode3Specified = true; + } + if(ataId.MinMDMACycleTime != 0) + { + report.ATA.MinMDMACycleTime = ataId.MinMDMACycleTime; + report.ATA.MinMDMACycleTimeSpecified = true; + } + if(ataId.MinorVersion != 0) + { + report.ATA.MinorVersion = ataId.MinorVersion; + report.ATA.MinorVersionSpecified = true; + } + if(ataId.MinPIOCycleTimeNoFlow != 0) + { + report.ATA.MinPIOCycleTimeNoFlow = ataId.MinPIOCycleTimeNoFlow; + report.ATA.MinPIOCycleTimeNoFlowSpecified = true; + } + if(ataId.MinPIOCycleTimeFlow != 0) + { + report.ATA.MinPIOCycleTimeFlow = ataId.MinPIOCycleTimeFlow; + report.ATA.MinPIOCycleTimeFlowSpecified = true; + } + if(!string.IsNullOrWhiteSpace(ataId.Model)) + { + report.ATA.Model = ataId.Model; + report.ATA.ModelSpecified = true; + } + if(ataId.MultipleMaxSectors != 0) + { + report.ATA.MultipleMaxSectors = ataId.MultipleMaxSectors; + report.ATA.MultipleMaxSectorsSpecified = true; + } + if(ataId.MultipleSectorNumber != 0) + { + report.ATA.MultipleSectorNumber = ataId.MultipleSectorNumber; + report.ATA.MultipleSectorNumberSpecified = true; + } + if(ataId.NVCacheCaps != 0) + { + report.ATA.NVCacheCaps = ataId.NVCacheCaps; + report.ATA.NVCacheCapsSpecified = true; + } + if(ataId.NVCacheSize != 0) + { + report.ATA.NVCacheSize = ataId.NVCacheSize; + report.ATA.NVCacheSizeSpecified = true; + } + if(ataId.NVCacheWriteSpeed != 0) + { + report.ATA.NVCacheWriteSpeed = ataId.NVCacheWriteSpeed; + report.ATA.NVCacheWriteSpeedSpecified = true; + } + if(ataId.NVEstimatedSpinUp != 0) + { + report.ATA.NVEstimatedSpinUp = ataId.NVEstimatedSpinUp; + report.ATA.NVEstimatedSpinUpSpecified = true; + } + if(ataId.PacketBusRelease != 0) + { + report.ATA.PacketBusRelease = ataId.PacketBusRelease; + report.ATA.PacketBusReleaseSpecified = true; + } + if(ataId.PIOTransferTimingMode != 0) + { + report.ATA.PIOTransferTimingMode = ataId.PIOTransferTimingMode; + report.ATA.PIOTransferTimingModeSpecified = true; + } + if(ataId.RecommendedAAM != 0) + { + report.ATA.RecommendedAAM = ataId.RecommendedAAM; + report.ATA.RecommendedAAMSpecified = true; + } + if(ataId.RecMDMACycleTime != 0) + { + report.ATA.RecommendedMDMACycleTime = ataId.RecMDMACycleTime; + report.ATA.RecommendedMDMACycleTimeSpecified = true; + } + if(ataId.RemovableStatusSet != 0) + { + report.ATA.RemovableStatusSet = ataId.RemovableStatusSet; + report.ATA.RemovableStatusSetSpecified = true; + } + if(ataId.SATACapabilities != 0) + { + report.ATA.SATACapabilities = ataId.SATACapabilities; + report.ATA.SATACapabilitiesSpecified = true; + } + if(ataId.SATACapabilities2 != 0) + { + report.ATA.SATACapabilities2 = ataId.SATACapabilities2; + report.ATA.SATACapabilities2Specified = true; + } + if(ataId.SATAFeatures != 0) + { + report.ATA.SATAFeatures = ataId.SATAFeatures; + report.ATA.SATAFeaturesSpecified = true; + } + if(ataId.SCTCommandTransport != 0) + { + report.ATA.SCTCommandTransport = ataId.SCTCommandTransport; + report.ATA.SCTCommandTransportSpecified = true; + } + if(ataId.SectorsPerCard != 0) + { + report.ATA.SectorsPerCard = ataId.SectorsPerCard; + report.ATA.SectorsPerCardSpecified = true; + } + if(ataId.SecurityEraseTime != 0) + { + report.ATA.SecurityEraseTime = ataId.SecurityEraseTime; + report.ATA.SecurityEraseTimeSpecified = true; + } + if(ataId.SecurityStatus != 0) + { + report.ATA.SecurityStatus = ataId.SecurityStatus; + report.ATA.SecurityStatusSpecified = true; + } + if(ataId.ServiceBusyClear != 0) + { + report.ATA.ServiceBusyClear = ataId.ServiceBusyClear; + report.ATA.ServiceBusyClearSpecified = true; + } + if(ataId.SpecificConfiguration != 0) + { + report.ATA.SpecificConfiguration = ataId.SpecificConfiguration; + report.ATA.SpecificConfigurationSpecified = true; + } + if(ataId.StreamAccessLatency != 0) + { + report.ATA.StreamAccessLatency = ataId.StreamAccessLatency; + report.ATA.StreamAccessLatencySpecified = true; + } + if(ataId.StreamMinReqSize != 0) + { + report.ATA.StreamMinReqSize = ataId.StreamMinReqSize; + report.ATA.StreamMinReqSizeSpecified = true; + } + if(ataId.StreamPerformanceGranularity != 0) + { + report.ATA.StreamPerformanceGranularity = ataId.StreamPerformanceGranularity; + report.ATA.StreamPerformanceGranularitySpecified = true; + } + if(ataId.StreamTransferTimeDMA != 0) + { + report.ATA.StreamTransferTimeDMA = ataId.StreamTransferTimeDMA; + report.ATA.StreamTransferTimeDMASpecified = true; + } + if(ataId.StreamTransferTimePIO != 0) + { + report.ATA.StreamTransferTimePIO = ataId.StreamTransferTimePIO; + report.ATA.StreamTransferTimePIOSpecified = true; + } + if(ataId.TransportMajorVersion != 0) + { + report.ATA.TransportMajorVersion = ataId.TransportMajorVersion; + report.ATA.TransportMajorVersionSpecified = true; + } + if(ataId.TransportMinorVersion != 0) + { + report.ATA.TransportMinorVersion = ataId.TransportMinorVersion; + report.ATA.TransportMinorVersionSpecified = true; + } + if(ataId.TrustedComputing != 0) + { + report.ATA.TrustedComputing = ataId.TrustedComputing; + report.ATA.TrustedComputingSpecified = true; + } + if(ataId.UDMAActive != 0) + { + report.ATA.UDMAActive = ataId.UDMAActive; + report.ATA.UDMAActiveSpecified = true; + } + if(ataId.UDMASupported != 0) + { + report.ATA.UDMASupported = ataId.UDMASupported; + report.ATA.UDMASupportedSpecified = true; + } + if(ataId.WRVMode != 0) + { + report.ATA.WRVMode = ataId.WRVMode; + report.ATA.WRVModeSpecified = true; + } + if(ataId.WRVSectorCountMode3 != 0) + { + report.ATA.WRVSectorCountMode3 = ataId.WRVSectorCountMode3; + report.ATA.WRVSectorCountMode3Specified = true; + } + if(ataId.WRVSectorCountMode2 != 0) + { + report.ATA.WRVSectorCountMode2 = ataId.WRVSectorCountMode2; + report.ATA.WRVSectorCountMode2Specified = true; + } + if(debug) report.ATA.Identify = buffer; + + if(removable) + { + List mediaTests = new List(); + + pressedKey = new ConsoleKeyInfo(); + while(pressedKey.Key != ConsoleKey.N) { - ataId = Identify.Decode(buffer).Value; - - if(ataId.UnformattedBPT != 0) + pressedKey = new ConsoleKeyInfo(); + while(pressedKey.Key != ConsoleKey.Y && pressedKey.Key != ConsoleKey.N) { - mediaTest.UnformattedBPT = ataId.UnformattedBPT; - mediaTest.UnformattedBPTSpecified = true; - } - if(ataId.UnformattedBPS != 0) - { - mediaTest.UnformattedBPS = ataId.UnformattedBPS; - mediaTest.UnformattedBPSSpecified = true; + DicConsole.Write("Do you have media that you can insert in the drive? (Y/N): "); + pressedKey = System.Console.ReadKey(); + DicConsole.WriteLine(); } - if(ataId.Cylinders > 0 && ataId.Heads > 0 && ataId.SectorsPerTrack > 0) - { - mediaTest.CHS = new chsType(); - mediaTest.CHS.Cylinders = ataId.Cylinders; - mediaTest.CHS.Heads = ataId.Heads; - mediaTest.CHS.Sectors = ataId.SectorsPerTrack; - mediaTest.Blocks = (ulong)(ataId.Cylinders * ataId.Heads * ataId.SectorsPerTrack); - mediaTest.BlocksSpecified = true; - } + if(pressedKey.Key != ConsoleKey.Y) continue; - if(ataId.CurrentCylinders > 0 && ataId.CurrentHeads > 0 && - ataId.CurrentSectorsPerTrack > 0) - { - mediaTest.CurrentCHS = new chsType(); - mediaTest.CurrentCHS.Cylinders = ataId.CurrentCylinders; - mediaTest.CurrentCHS.Heads = ataId.CurrentHeads; - mediaTest.CurrentCHS.Sectors = ataId.CurrentSectorsPerTrack; - if(mediaTest.Blocks == 0) - mediaTest.Blocks = - (ulong)(ataId.CurrentCylinders * ataId.CurrentHeads * - ataId.CurrentSectorsPerTrack); - mediaTest.BlocksSpecified = true; - } + DicConsole.WriteLine("Please insert it in the drive and press any key when it is ready."); + System.Console.ReadKey(true); - if(ataId.Capabilities.HasFlag(Identify.CapabilitiesBit.LBASupport)) - { - mediaTest.LBASectors = ataId.LBASectors; - mediaTest.LBASectorsSpecified = true; - mediaTest.Blocks = ataId.LBASectors; - mediaTest.BlocksSpecified = true; - } + testedMediaType mediaTest = new testedMediaType(); + DicConsole.Write("Please write a description of the media type and press enter: "); + mediaTest.MediumTypeName = System.Console.ReadLine(); + DicConsole.Write("Please write the media model and press enter: "); + mediaTest.Model = System.Console.ReadLine(); - if(ataId.CommandSet2.HasFlag(Identify.CommandSetBit2.LBA48)) - { - mediaTest.LBA48Sectors = ataId.LBA48Sectors; - mediaTest.LBA48SectorsSpecified = true; - mediaTest.Blocks = ataId.LBA48Sectors; - mediaTest.BlocksSpecified = true; - } + mediaTest.ManufacturerSpecified = true; + mediaTest.ModelSpecified = true; + mediaTest.MediaIsRecognized = true; - if(ataId.NominalRotationRate != 0x0000 && ataId.NominalRotationRate != 0xFFFF) - if(ataId.NominalRotationRate == 0x0001) + DicConsole.WriteLine("Querying ATA IDENTIFY..."); + dev.AtaIdentify(out buffer, out errorRegs, timeout, out duration); + + if(Identify.Decode(buffer).HasValue) + { + ataId = Identify.Decode(buffer).Value; + + if(ataId.UnformattedBPT != 0) { - mediaTest.SolidStateDevice = true; - mediaTest.SolidStateDeviceSpecified = true; + mediaTest.UnformattedBPT = ataId.UnformattedBPT; + mediaTest.UnformattedBPTSpecified = true; + } + if(ataId.UnformattedBPS != 0) + { + mediaTest.UnformattedBPS = ataId.UnformattedBPS; + mediaTest.UnformattedBPSSpecified = true; + } + + if(ataId.Cylinders > 0 && ataId.Heads > 0 && ataId.SectorsPerTrack > 0) + { + mediaTest.CHS = new chsType(); + mediaTest.CHS.Cylinders = ataId.Cylinders; + mediaTest.CHS.Heads = ataId.Heads; + mediaTest.CHS.Sectors = ataId.SectorsPerTrack; + mediaTest.Blocks = (ulong)(ataId.Cylinders * ataId.Heads * ataId.SectorsPerTrack); + mediaTest.BlocksSpecified = true; + } + + if(ataId.CurrentCylinders > 0 && ataId.CurrentHeads > 0 && + ataId.CurrentSectorsPerTrack > 0) + { + mediaTest.CurrentCHS = new chsType(); + mediaTest.CurrentCHS.Cylinders = ataId.CurrentCylinders; + mediaTest.CurrentCHS.Heads = ataId.CurrentHeads; + mediaTest.CurrentCHS.Sectors = ataId.CurrentSectorsPerTrack; + if(mediaTest.Blocks == 0) + mediaTest.Blocks = + (ulong)(ataId.CurrentCylinders * ataId.CurrentHeads * + ataId.CurrentSectorsPerTrack); + mediaTest.BlocksSpecified = true; + } + + if(ataId.Capabilities.HasFlag(Identify.CapabilitiesBit.LBASupport)) + { + mediaTest.LBASectors = ataId.LBASectors; + mediaTest.LBASectorsSpecified = true; + mediaTest.Blocks = ataId.LBASectors; + mediaTest.BlocksSpecified = true; + } + + if(ataId.CommandSet2.HasFlag(Identify.CommandSetBit2.LBA48)) + { + mediaTest.LBA48Sectors = ataId.LBA48Sectors; + mediaTest.LBA48SectorsSpecified = true; + mediaTest.Blocks = ataId.LBA48Sectors; + mediaTest.BlocksSpecified = true; + } + + if(ataId.NominalRotationRate != 0x0000 && ataId.NominalRotationRate != 0xFFFF) + if(ataId.NominalRotationRate == 0x0001) + { + mediaTest.SolidStateDevice = true; + mediaTest.SolidStateDeviceSpecified = true; + } + else + { + mediaTest.SolidStateDevice = false; + mediaTest.SolidStateDeviceSpecified = true; + mediaTest.NominalRotationRate = ataId.NominalRotationRate; + mediaTest.NominalRotationRateSpecified = true; + } + + uint logicalsectorsize; + uint physicalsectorsize; + if((ataId.PhysLogSectorSize & 0x8000) == 0x0000 && + (ataId.PhysLogSectorSize & 0x4000) == 0x4000) + { + if((ataId.PhysLogSectorSize & 0x1000) == 0x1000) + if(ataId.LogicalSectorWords <= 255 || ataId.LogicalAlignment == 0xFFFF) + logicalsectorsize = 512; + else logicalsectorsize = ataId.LogicalSectorWords * 2; + else logicalsectorsize = 512; + + if((ataId.PhysLogSectorSize & 0x2000) == 0x2000) + { + physicalsectorsize = + (uint)(logicalsectorsize * ((1 << ataId.PhysLogSectorSize) & 0xF)); + } + else physicalsectorsize = logicalsectorsize; } else { - mediaTest.SolidStateDevice = false; - mediaTest.SolidStateDeviceSpecified = true; - mediaTest.NominalRotationRate = ataId.NominalRotationRate; - mediaTest.NominalRotationRateSpecified = true; + logicalsectorsize = 512; + physicalsectorsize = 512; } - uint logicalsectorsize; - uint physicalsectorsize; - if((ataId.PhysLogSectorSize & 0x8000) == 0x0000 && - (ataId.PhysLogSectorSize & 0x4000) == 0x4000) - { - if((ataId.PhysLogSectorSize & 0x1000) == 0x1000) - if(ataId.LogicalSectorWords <= 255 || ataId.LogicalAlignment == 0xFFFF) - logicalsectorsize = 512; - else logicalsectorsize = ataId.LogicalSectorWords * 2; - else logicalsectorsize = 512; - - if((ataId.PhysLogSectorSize & 0x2000) == 0x2000) + mediaTest.BlockSize = logicalsectorsize; + mediaTest.BlockSizeSpecified = true; + if(physicalsectorsize != logicalsectorsize) { - physicalsectorsize = - (uint)(logicalsectorsize * ((1 << ataId.PhysLogSectorSize) & 0xF)); + mediaTest.PhysicalBlockSize = physicalsectorsize; + mediaTest.PhysicalBlockSizeSpecified = true; + + if((ataId.LogicalAlignment & 0x8000) == 0x0000 && + (ataId.LogicalAlignment & 0x4000) == 0x4000) + { + mediaTest.LogicalAlignment = (ushort)(ataId.LogicalAlignment & 0x3FFF); + mediaTest.LogicalAlignmentSpecified = true; + } } - else physicalsectorsize = logicalsectorsize; - } - else - { - logicalsectorsize = 512; - physicalsectorsize = 512; - } - mediaTest.BlockSize = logicalsectorsize; - mediaTest.BlockSizeSpecified = true; - if(physicalsectorsize != logicalsectorsize) - { - mediaTest.PhysicalBlockSize = physicalsectorsize; - mediaTest.PhysicalBlockSizeSpecified = true; - - if((ataId.LogicalAlignment & 0x8000) == 0x0000 && - (ataId.LogicalAlignment & 0x4000) == 0x4000) + if(ataId.EccBytes != 0x0000 && ataId.EccBytes != 0xFFFF) { - mediaTest.LogicalAlignment = (ushort)(ataId.LogicalAlignment & 0x3FFF); - mediaTest.LogicalAlignmentSpecified = true; + mediaTest.LongBlockSize = logicalsectorsize + ataId.EccBytes; + mediaTest.LongBlockSizeSpecified = true; } - } - if(ataId.EccBytes != 0x0000 && ataId.EccBytes != 0xFFFF) - { - mediaTest.LongBlockSize = logicalsectorsize + ataId.EccBytes; - mediaTest.LongBlockSizeSpecified = true; - } - - if(ataId.UnformattedBPS > logicalsectorsize && - (!mediaTest.LongBlockSizeSpecified || mediaTest.LongBlockSize == 516)) - { - mediaTest.LongBlockSize = ataId.UnformattedBPS; - mediaTest.LongBlockSizeSpecified = true; - } - - if(ataId.CommandSet3.HasFlag(Identify.CommandSetBit3.MustBeSet) && - !ataId.CommandSet3.HasFlag(Identify.CommandSetBit3.MustBeClear) && - ataId.EnabledCommandSet3.HasFlag(Identify.CommandSetBit3.MediaSerial)) - { - mediaTest.CanReadMediaSerial = true; - mediaTest.CanReadMediaSerialSpecified = true; - if(!string.IsNullOrWhiteSpace(ataId.MediaManufacturer)) + if(ataId.UnformattedBPS > logicalsectorsize && + (!mediaTest.LongBlockSizeSpecified || mediaTest.LongBlockSize == 516)) { - mediaTest.Manufacturer = ataId.MediaManufacturer; - mediaTest.ManufacturerSpecified = true; + mediaTest.LongBlockSize = ataId.UnformattedBPS; + mediaTest.LongBlockSizeSpecified = true; } + + if(ataId.CommandSet3.HasFlag(Identify.CommandSetBit3.MustBeSet) && + !ataId.CommandSet3.HasFlag(Identify.CommandSetBit3.MustBeClear) && + ataId.EnabledCommandSet3.HasFlag(Identify.CommandSetBit3.MediaSerial)) + { + mediaTest.CanReadMediaSerial = true; + mediaTest.CanReadMediaSerialSpecified = true; + if(!string.IsNullOrWhiteSpace(ataId.MediaManufacturer)) + { + mediaTest.Manufacturer = ataId.MediaManufacturer; + mediaTest.ManufacturerSpecified = true; + } + } + + mediaTest.SupportsReadLbaSpecified = true; + mediaTest.SupportsReadRetryLbaSpecified = true; + mediaTest.SupportsReadDmaLbaSpecified = true; + mediaTest.SupportsReadDmaRetryLbaSpecified = true; + mediaTest.SupportsReadLongLbaSpecified = true; + mediaTest.SupportsReadLongRetryLbaSpecified = true; + mediaTest.SupportsSeekLbaSpecified = true; + + mediaTest.SupportsReadLba48Specified = true; + mediaTest.SupportsReadDmaLba48Specified = true; + + mediaTest.SupportsReadSpecified = true; + mediaTest.SupportsReadRetrySpecified = true; + mediaTest.SupportsReadDmaSpecified = true; + mediaTest.SupportsReadDmaRetrySpecified = true; + mediaTest.SupportsReadLongSpecified = true; + mediaTest.SupportsReadLongRetrySpecified = true; + mediaTest.SupportsSeekSpecified = true; + + AtaErrorRegistersCHS errorChs; + AtaErrorRegistersLBA28 errorLba; + AtaErrorRegistersLBA48 errorLba48; + + byte[] readBuf; + ulong checkCorrectRead = BitConverter.ToUInt64(buffer, 0); + bool sense; + + DicConsole.WriteLine("Trying READ SECTOR(S) in CHS mode..."); + sense = dev.Read(out readBuf, out errorChs, false, 0, 0, 1, 1, timeout, out duration); + mediaTest.SupportsRead = + !sense && (errorChs.status & 0x01) != 0x01 && errorChs.error == 0 && + readBuf.Length > 0; + DicConsole.DebugWriteLine("ATA Report", + "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", + sense, errorChs.status, errorChs.error, readBuf.Length); + if(debug) + DataFile.WriteTo("ATA Report", "readsectorschs", + "_debug_" + mediaTest.MediumTypeName + ".bin", "read results", + readBuf); + + DicConsole.WriteLine("Trying READ SECTOR(S) RETRY in CHS mode..."); + sense = dev.Read(out readBuf, out errorChs, true, 0, 0, 1, 1, timeout, out duration); + mediaTest.SupportsReadRetry = + !sense && (errorChs.status & 0x01) != 0x01 && errorChs.error == 0 && + readBuf.Length > 0; + DicConsole.DebugWriteLine("ATA Report", + "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", + sense, errorChs.status, errorChs.error, readBuf.Length); + if(debug) + DataFile.WriteTo("ATA Report", "readsectorsretrychs", + "_debug_" + mediaTest.MediumTypeName + ".bin", "read results", + readBuf); + + DicConsole.WriteLine("Trying READ DMA in CHS mode..."); + sense = dev.ReadDma(out readBuf, out errorChs, false, 0, 0, 1, 1, timeout, + out duration); + mediaTest.SupportsReadDma = + !sense && (errorChs.status & 0x01) != 0x01 && errorChs.error == 0 && + readBuf.Length > 0; + DicConsole.DebugWriteLine("ATA Report", + "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", + sense, errorChs.status, errorChs.error, readBuf.Length); + if(debug) + DataFile.WriteTo("ATA Report", "readdmachs", + "_debug_" + mediaTest.MediumTypeName + ".bin", "read results", + readBuf); + + DicConsole.WriteLine("Trying READ DMA RETRY in CHS mode..."); + sense = dev.ReadDma(out readBuf, out errorChs, true, 0, 0, 1, 1, timeout, out duration); + mediaTest.SupportsReadDmaRetry = + !sense && (errorChs.status & 0x01) != 0x01 && errorChs.error == 0 && + readBuf.Length > 0; + DicConsole.DebugWriteLine("ATA Report", + "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", + sense, errorChs.status, errorChs.error, readBuf.Length); + if(debug) + DataFile.WriteTo("ATA Report", "readdmaretrychs", + "_debug_" + mediaTest.MediumTypeName + ".bin", "read results", + readBuf); + + DicConsole.WriteLine("Trying SEEK in CHS mode..."); + sense = dev.Seek(out errorChs, 0, 0, 1, timeout, out duration); + mediaTest.SupportsSeek = + !sense && (errorChs.status & 0x01) != 0x01 && errorChs.error == 0; + DicConsole.DebugWriteLine("ATA Report", + "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}", sense, + errorChs.status, errorChs.error); + + DicConsole.WriteLine("Trying READ SECTOR(S) in LBA mode..."); + sense = dev.Read(out readBuf, out errorLba, false, 0, 1, timeout, out duration); + mediaTest.SupportsReadLba = + !sense && (errorLba.status & 0x01) != 0x01 && errorLba.error == 0 && + readBuf.Length > 0; + DicConsole.DebugWriteLine("ATA Report", + "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", + sense, errorChs.status, errorChs.error, readBuf.Length); + if(debug) + DataFile.WriteTo("ATA Report", "readsectors", + "_debug_" + mediaTest.MediumTypeName + ".bin", "read results", + readBuf); + + DicConsole.WriteLine("Trying READ SECTOR(S) RETRY in LBA mode..."); + sense = dev.Read(out readBuf, out errorLba, true, 0, 1, timeout, out duration); + mediaTest.SupportsReadRetryLba = + !sense && (errorLba.status & 0x01) != 0x01 && errorLba.error == 0 && + readBuf.Length > 0; + DicConsole.DebugWriteLine("ATA Report", + "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", + sense, errorChs.status, errorChs.error, readBuf.Length); + if(debug) + DataFile.WriteTo("ATA Report", "readsectorsretry", + "_debug_" + mediaTest.MediumTypeName + ".bin", "read results", + readBuf); + + DicConsole.WriteLine("Trying READ DMA in LBA mode..."); + sense = dev.ReadDma(out readBuf, out errorLba, false, 0, 1, timeout, out duration); + mediaTest.SupportsReadDmaLba = + !sense && (errorLba.status & 0x01) != 0x01 && errorLba.error == 0 && + readBuf.Length > 0; + DicConsole.DebugWriteLine("ATA Report", + "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", + sense, errorChs.status, errorChs.error, readBuf.Length); + if(debug) + DataFile.WriteTo("ATA Report", "readdma", + "_debug_" + mediaTest.MediumTypeName + ".bin", "read results", + readBuf); + + DicConsole.WriteLine("Trying READ DMA RETRY in LBA mode..."); + sense = dev.ReadDma(out readBuf, out errorLba, true, 0, 1, timeout, out duration); + mediaTest.SupportsReadDmaRetryLba = + !sense && (errorLba.status & 0x01) != 0x01 && errorLba.error == 0 && + readBuf.Length > 0; + DicConsole.DebugWriteLine("ATA Report", + "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", + sense, errorChs.status, errorChs.error, readBuf.Length); + if(debug) + DataFile.WriteTo("ATA Report", "readdmaretry", + "_debug_" + mediaTest.MediumTypeName + ".bin", "read results", + readBuf); + + DicConsole.WriteLine("Trying SEEK in LBA mode..."); + sense = dev.Seek(out errorLba, 0, timeout, out duration); + mediaTest.SupportsSeekLba = + !sense && (errorLba.status & 0x01) != 0x01 && errorLba.error == 0; + DicConsole.DebugWriteLine("ATA Report", + "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}", sense, + errorChs.status, errorChs.error); + + DicConsole.WriteLine("Trying READ SECTOR(S) in LBA48 mode..."); + sense = dev.Read(out readBuf, out errorLba48, 0, 1, timeout, out duration); + mediaTest.SupportsReadLba48 = + !sense && (errorLba48.status & 0x01) != 0x01 && errorLba48.error == 0 && + readBuf.Length > 0; + DicConsole.DebugWriteLine("ATA Report", + "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", + sense, errorChs.status, errorChs.error, readBuf.Length); + if(debug) + DataFile.WriteTo("ATA Report", "readsectors48", + "_debug_" + mediaTest.MediumTypeName + ".bin", "read results", + readBuf); + + DicConsole.WriteLine("Trying READ DMA in LBA48 mode..."); + sense = dev.ReadDma(out readBuf, out errorLba48, 0, 1, timeout, out duration); + mediaTest.SupportsReadDmaLba48 = + !sense && (errorLba48.status & 0x01) != 0x01 && errorLba48.error == 0 && + readBuf.Length > 0; + DicConsole.DebugWriteLine("ATA Report", + "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", + sense, errorChs.status, errorChs.error, readBuf.Length); + if(debug) + DataFile.WriteTo("ATA Report", "readdma48", + "_debug_" + mediaTest.MediumTypeName + ".bin", "read results", + readBuf); + + DicConsole.WriteLine("Trying READ LONG in CHS mode..."); + sense = dev.ReadLong(out readBuf, out errorChs, false, 0, 0, 1, mediaTest.LongBlockSize, + timeout, out duration); + mediaTest.SupportsReadLong = + !sense && (errorChs.status & 0x01) != 0x01 && errorChs.error == 0 && + readBuf.Length > 0 && BitConverter.ToUInt64(readBuf, 0) != checkCorrectRead; + DicConsole.DebugWriteLine("ATA Report", + "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", + sense, errorChs.status, errorChs.error, readBuf.Length); + if(debug) + DataFile.WriteTo("ATA Report", "readlongchs", + "_debug_" + mediaTest.MediumTypeName + ".bin", "read results", + readBuf); + + DicConsole.WriteLine("Trying READ LONG RETRY in CHS mode..."); + sense = dev.ReadLong(out readBuf, out errorChs, true, 0, 0, 1, mediaTest.LongBlockSize, + timeout, out duration); + mediaTest.SupportsReadLongRetry = + !sense && (errorChs.status & 0x01) != 0x01 && errorChs.error == 0 && + readBuf.Length > 0 && BitConverter.ToUInt64(readBuf, 0) != checkCorrectRead; + DicConsole.DebugWriteLine("ATA Report", + "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", + sense, errorChs.status, errorChs.error, readBuf.Length); + if(debug) + DataFile.WriteTo("ATA Report", "readlongretrychs", + "_debug_" + mediaTest.MediumTypeName + ".bin", "read results", + readBuf); + + DicConsole.WriteLine("Trying READ LONG in LBA mode..."); + sense = dev.ReadLong(out readBuf, out errorLba, false, 0, mediaTest.LongBlockSize, + timeout, out duration); + mediaTest.SupportsReadLongLba = + !sense && (errorLba.status & 0x01) != 0x01 && errorLba.error == 0 && + readBuf.Length > 0 && BitConverter.ToUInt64(readBuf, 0) != checkCorrectRead; + DicConsole.DebugWriteLine("ATA Report", + "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", + sense, errorChs.status, errorChs.error, readBuf.Length); + if(debug) + DataFile.WriteTo("ATA Report", "readlong", + "_debug_" + mediaTest.MediumTypeName + ".bin", "read results", + readBuf); + + DicConsole.WriteLine("Trying READ LONG RETRY in LBA mode..."); + sense = dev.ReadLong(out readBuf, out errorLba, true, 0, mediaTest.LongBlockSize, + timeout, out duration); + mediaTest.SupportsReadLongRetryLba = + !sense && (errorLba.status & 0x01) != 0x01 && errorLba.error == 0 && + readBuf.Length > 0 && BitConverter.ToUInt64(readBuf, 0) != checkCorrectRead; + DicConsole.DebugWriteLine("ATA Report", + "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", + sense, errorChs.status, errorChs.error, readBuf.Length); + if(debug) + DataFile.WriteTo("ATA Report", "readlongretry", + "_debug_" + mediaTest.MediumTypeName + ".bin", "read results", + readBuf); } + else mediaTest.MediaIsRecognized = false; - mediaTest.SupportsReadLbaSpecified = true; - mediaTest.SupportsReadRetryLbaSpecified = true; - mediaTest.SupportsReadDmaLbaSpecified = true; - mediaTest.SupportsReadDmaRetryLbaSpecified = true; - mediaTest.SupportsReadLongLbaSpecified = true; - mediaTest.SupportsReadLongRetryLbaSpecified = true; - mediaTest.SupportsSeekLbaSpecified = true; - - mediaTest.SupportsReadLba48Specified = true; - mediaTest.SupportsReadDmaLba48Specified = true; - - mediaTest.SupportsReadSpecified = true; - mediaTest.SupportsReadRetrySpecified = true; - mediaTest.SupportsReadDmaSpecified = true; - mediaTest.SupportsReadDmaRetrySpecified = true; - mediaTest.SupportsReadLongSpecified = true; - mediaTest.SupportsReadLongRetrySpecified = true; - mediaTest.SupportsSeekSpecified = true; - - AtaErrorRegistersCHS errorChs; - AtaErrorRegistersLBA28 errorLba; - AtaErrorRegistersLBA48 errorLba48; - - byte[] readBuf; - ulong checkCorrectRead = BitConverter.ToUInt64(buffer, 0); - bool sense; - - DicConsole.WriteLine("Trying READ SECTOR(S) in CHS mode..."); - sense = dev.Read(out readBuf, out errorChs, false, 0, 0, 1, 1, timeout, out duration); - mediaTest.SupportsRead = - !sense && (errorChs.status & 0x01) != 0x01 && errorChs.error == 0 && - readBuf.Length > 0; - DicConsole.DebugWriteLine("ATA Report", - "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", - sense, errorChs.status, errorChs.error, readBuf.Length); - if(debug) - DataFile.WriteTo("ATA Report", "readsectorschs", - "_debug_" + mediaTest.MediumTypeName + ".bin", "read results", - readBuf); - - DicConsole.WriteLine("Trying READ SECTOR(S) RETRY in CHS mode..."); - sense = dev.Read(out readBuf, out errorChs, true, 0, 0, 1, 1, timeout, out duration); - mediaTest.SupportsReadRetry = - !sense && (errorChs.status & 0x01) != 0x01 && errorChs.error == 0 && - readBuf.Length > 0; - DicConsole.DebugWriteLine("ATA Report", - "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", - sense, errorChs.status, errorChs.error, readBuf.Length); - if(debug) - DataFile.WriteTo("ATA Report", "readsectorsretrychs", - "_debug_" + mediaTest.MediumTypeName + ".bin", "read results", - readBuf); - - DicConsole.WriteLine("Trying READ DMA in CHS mode..."); - sense = dev.ReadDma(out readBuf, out errorChs, false, 0, 0, 1, 1, timeout, - out duration); - mediaTest.SupportsReadDma = - !sense && (errorChs.status & 0x01) != 0x01 && errorChs.error == 0 && - readBuf.Length > 0; - DicConsole.DebugWriteLine("ATA Report", - "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", - sense, errorChs.status, errorChs.error, readBuf.Length); - if(debug) - DataFile.WriteTo("ATA Report", "readdmachs", - "_debug_" + mediaTest.MediumTypeName + ".bin", "read results", - readBuf); - - DicConsole.WriteLine("Trying READ DMA RETRY in CHS mode..."); - sense = dev.ReadDma(out readBuf, out errorChs, true, 0, 0, 1, 1, timeout, out duration); - mediaTest.SupportsReadDmaRetry = - !sense && (errorChs.status & 0x01) != 0x01 && errorChs.error == 0 && - readBuf.Length > 0; - DicConsole.DebugWriteLine("ATA Report", - "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", - sense, errorChs.status, errorChs.error, readBuf.Length); - if(debug) - DataFile.WriteTo("ATA Report", "readdmaretrychs", - "_debug_" + mediaTest.MediumTypeName + ".bin", "read results", - readBuf); - - DicConsole.WriteLine("Trying SEEK in CHS mode..."); - sense = dev.Seek(out errorChs, 0, 0, 1, timeout, out duration); - mediaTest.SupportsSeek = - !sense && (errorChs.status & 0x01) != 0x01 && errorChs.error == 0; - DicConsole.DebugWriteLine("ATA Report", - "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}", sense, - errorChs.status, errorChs.error); - - DicConsole.WriteLine("Trying READ SECTOR(S) in LBA mode..."); - sense = dev.Read(out readBuf, out errorLba, false, 0, 1, timeout, out duration); - mediaTest.SupportsReadLba = - !sense && (errorLba.status & 0x01) != 0x01 && errorLba.error == 0 && - readBuf.Length > 0; - DicConsole.DebugWriteLine("ATA Report", - "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", - sense, errorChs.status, errorChs.error, readBuf.Length); - if(debug) - DataFile.WriteTo("ATA Report", "readsectors", - "_debug_" + mediaTest.MediumTypeName + ".bin", "read results", - readBuf); - - DicConsole.WriteLine("Trying READ SECTOR(S) RETRY in LBA mode..."); - sense = dev.Read(out readBuf, out errorLba, true, 0, 1, timeout, out duration); - mediaTest.SupportsReadRetryLba = - !sense && (errorLba.status & 0x01) != 0x01 && errorLba.error == 0 && - readBuf.Length > 0; - DicConsole.DebugWriteLine("ATA Report", - "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", - sense, errorChs.status, errorChs.error, readBuf.Length); - if(debug) - DataFile.WriteTo("ATA Report", "readsectorsretry", - "_debug_" + mediaTest.MediumTypeName + ".bin", "read results", - readBuf); - - DicConsole.WriteLine("Trying READ DMA in LBA mode..."); - sense = dev.ReadDma(out readBuf, out errorLba, false, 0, 1, timeout, out duration); - mediaTest.SupportsReadDmaLba = - !sense && (errorLba.status & 0x01) != 0x01 && errorLba.error == 0 && - readBuf.Length > 0; - DicConsole.DebugWriteLine("ATA Report", - "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", - sense, errorChs.status, errorChs.error, readBuf.Length); - if(debug) - DataFile.WriteTo("ATA Report", "readdma", - "_debug_" + mediaTest.MediumTypeName + ".bin", "read results", - readBuf); - - DicConsole.WriteLine("Trying READ DMA RETRY in LBA mode..."); - sense = dev.ReadDma(out readBuf, out errorLba, true, 0, 1, timeout, out duration); - mediaTest.SupportsReadDmaRetryLba = - !sense && (errorLba.status & 0x01) != 0x01 && errorLba.error == 0 && - readBuf.Length > 0; - DicConsole.DebugWriteLine("ATA Report", - "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", - sense, errorChs.status, errorChs.error, readBuf.Length); - if(debug) - DataFile.WriteTo("ATA Report", "readdmaretry", - "_debug_" + mediaTest.MediumTypeName + ".bin", "read results", - readBuf); - - DicConsole.WriteLine("Trying SEEK in LBA mode..."); - sense = dev.Seek(out errorLba, 0, timeout, out duration); - mediaTest.SupportsSeekLba = - !sense && (errorLba.status & 0x01) != 0x01 && errorLba.error == 0; - DicConsole.DebugWriteLine("ATA Report", - "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}", sense, - errorChs.status, errorChs.error); - - DicConsole.WriteLine("Trying READ SECTOR(S) in LBA48 mode..."); - sense = dev.Read(out readBuf, out errorLba48, 0, 1, timeout, out duration); - mediaTest.SupportsReadLba48 = - !sense && (errorLba48.status & 0x01) != 0x01 && errorLba48.error == 0 && - readBuf.Length > 0; - DicConsole.DebugWriteLine("ATA Report", - "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", - sense, errorChs.status, errorChs.error, readBuf.Length); - if(debug) - DataFile.WriteTo("ATA Report", "readsectors48", - "_debug_" + mediaTest.MediumTypeName + ".bin", "read results", - readBuf); - - DicConsole.WriteLine("Trying READ DMA in LBA48 mode..."); - sense = dev.ReadDma(out readBuf, out errorLba48, 0, 1, timeout, out duration); - mediaTest.SupportsReadDmaLba48 = - !sense && (errorLba48.status & 0x01) != 0x01 && errorLba48.error == 0 && - readBuf.Length > 0; - DicConsole.DebugWriteLine("ATA Report", - "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", - sense, errorChs.status, errorChs.error, readBuf.Length); - if(debug) - DataFile.WriteTo("ATA Report", "readdma48", - "_debug_" + mediaTest.MediumTypeName + ".bin", "read results", - readBuf); - - DicConsole.WriteLine("Trying READ LONG in CHS mode..."); - sense = dev.ReadLong(out readBuf, out errorChs, false, 0, 0, 1, mediaTest.LongBlockSize, - timeout, out duration); - mediaTest.SupportsReadLong = - !sense && (errorChs.status & 0x01) != 0x01 && errorChs.error == 0 && - readBuf.Length > 0 && BitConverter.ToUInt64(readBuf, 0) != checkCorrectRead; - DicConsole.DebugWriteLine("ATA Report", - "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", - sense, errorChs.status, errorChs.error, readBuf.Length); - if(debug) - DataFile.WriteTo("ATA Report", "readlongchs", - "_debug_" + mediaTest.MediumTypeName + ".bin", "read results", - readBuf); - - DicConsole.WriteLine("Trying READ LONG RETRY in CHS mode..."); - sense = dev.ReadLong(out readBuf, out errorChs, true, 0, 0, 1, mediaTest.LongBlockSize, - timeout, out duration); - mediaTest.SupportsReadLongRetry = - !sense && (errorChs.status & 0x01) != 0x01 && errorChs.error == 0 && - readBuf.Length > 0 && BitConverter.ToUInt64(readBuf, 0) != checkCorrectRead; - DicConsole.DebugWriteLine("ATA Report", - "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", - sense, errorChs.status, errorChs.error, readBuf.Length); - if(debug) - DataFile.WriteTo("ATA Report", "readlongretrychs", - "_debug_" + mediaTest.MediumTypeName + ".bin", "read results", - readBuf); - - DicConsole.WriteLine("Trying READ LONG in LBA mode..."); - sense = dev.ReadLong(out readBuf, out errorLba, false, 0, mediaTest.LongBlockSize, - timeout, out duration); - mediaTest.SupportsReadLongLba = - !sense && (errorLba.status & 0x01) != 0x01 && errorLba.error == 0 && - readBuf.Length > 0 && BitConverter.ToUInt64(readBuf, 0) != checkCorrectRead; - DicConsole.DebugWriteLine("ATA Report", - "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", - sense, errorChs.status, errorChs.error, readBuf.Length); - if(debug) - DataFile.WriteTo("ATA Report", "readlong", - "_debug_" + mediaTest.MediumTypeName + ".bin", "read results", - readBuf); - - DicConsole.WriteLine("Trying READ LONG RETRY in LBA mode..."); - sense = dev.ReadLong(out readBuf, out errorLba, true, 0, mediaTest.LongBlockSize, - timeout, out duration); - mediaTest.SupportsReadLongRetryLba = - !sense && (errorLba.status & 0x01) != 0x01 && errorLba.error == 0 && - readBuf.Length > 0 && BitConverter.ToUInt64(readBuf, 0) != checkCorrectRead; - DicConsole.DebugWriteLine("ATA Report", - "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", - sense, errorChs.status, errorChs.error, readBuf.Length); - if(debug) - DataFile.WriteTo("ATA Report", "readlongretry", - "_debug_" + mediaTest.MediumTypeName + ".bin", "read results", - readBuf); - } - else mediaTest.MediaIsRecognized = false; - - mediaTests.Add(mediaTest); - } - - report.ATA.RemovableMedias = mediaTests.ToArray(); - } - else - { - report.ATA.ReadCapabilities = new testedMediaType(); - - if(ataId.UnformattedBPT != 0) - { - report.ATA.ReadCapabilities.UnformattedBPT = ataId.UnformattedBPT; - report.ATA.ReadCapabilities.UnformattedBPTSpecified = true; - } - if(ataId.UnformattedBPS != 0) - { - report.ATA.ReadCapabilities.UnformattedBPS = ataId.UnformattedBPS; - report.ATA.ReadCapabilities.UnformattedBPSSpecified = true; - } - - if(ataId.Cylinders > 0 && ataId.Heads > 0 && ataId.SectorsPerTrack > 0) - { - report.ATA.ReadCapabilities.CHS = new chsType(); - report.ATA.ReadCapabilities.CHS.Cylinders = ataId.Cylinders; - report.ATA.ReadCapabilities.CHS.Heads = ataId.Heads; - report.ATA.ReadCapabilities.CHS.Sectors = ataId.SectorsPerTrack; - report.ATA.ReadCapabilities.Blocks = - (ulong)(ataId.Cylinders * ataId.Heads * ataId.SectorsPerTrack); - report.ATA.ReadCapabilities.BlocksSpecified = true; - } - - if(ataId.CurrentCylinders > 0 && ataId.CurrentHeads > 0 && ataId.CurrentSectorsPerTrack > 0) - { - report.ATA.ReadCapabilities.CurrentCHS = new chsType(); - report.ATA.ReadCapabilities.CurrentCHS.Cylinders = ataId.CurrentCylinders; - report.ATA.ReadCapabilities.CurrentCHS.Heads = ataId.CurrentHeads; - report.ATA.ReadCapabilities.CurrentCHS.Sectors = ataId.CurrentSectorsPerTrack; - report.ATA.ReadCapabilities.Blocks = - (ulong)(ataId.CurrentCylinders * ataId.CurrentHeads * ataId.CurrentSectorsPerTrack); - report.ATA.ReadCapabilities.BlocksSpecified = true; - } - - if(ataId.Capabilities.HasFlag(Identify.CapabilitiesBit.LBASupport)) - { - report.ATA.ReadCapabilities.LBASectors = ataId.LBASectors; - report.ATA.ReadCapabilities.LBASectorsSpecified = true; - report.ATA.ReadCapabilities.Blocks = ataId.LBASectors; - report.ATA.ReadCapabilities.BlocksSpecified = true; - } - - if(ataId.CommandSet2.HasFlag(Identify.CommandSetBit2.LBA48)) - { - report.ATA.ReadCapabilities.LBA48Sectors = ataId.LBA48Sectors; - report.ATA.ReadCapabilities.LBA48SectorsSpecified = true; - report.ATA.ReadCapabilities.Blocks = ataId.LBA48Sectors; - report.ATA.ReadCapabilities.BlocksSpecified = true; - } - - if(ataId.NominalRotationRate != 0x0000 && ataId.NominalRotationRate != 0xFFFF) - if(ataId.NominalRotationRate == 0x0001) - { - report.ATA.ReadCapabilities.SolidStateDevice = true; - report.ATA.ReadCapabilities.SolidStateDeviceSpecified = true; - } - else - { - report.ATA.ReadCapabilities.SolidStateDevice = false; - report.ATA.ReadCapabilities.SolidStateDeviceSpecified = true; - report.ATA.ReadCapabilities.NominalRotationRate = ataId.NominalRotationRate; - report.ATA.ReadCapabilities.NominalRotationRateSpecified = true; + mediaTests.Add(mediaTest); } - uint logicalsectorsize; - uint physicalsectorsize; - if((ataId.PhysLogSectorSize & 0x8000) == 0x0000 && (ataId.PhysLogSectorSize & 0x4000) == 0x4000) - { - if((ataId.PhysLogSectorSize & 0x1000) == 0x1000) - if(ataId.LogicalSectorWords <= 255 || ataId.LogicalAlignment == 0xFFFF) - logicalsectorsize = 512; - else logicalsectorsize = ataId.LogicalSectorWords * 2; - else logicalsectorsize = 512; - - if((ataId.PhysLogSectorSize & 0x2000) == 0x2000) - { - physicalsectorsize = logicalsectorsize * - (uint)Math.Pow(2, ataId.PhysLogSectorSize & 0xF); - } - else physicalsectorsize = logicalsectorsize; + report.ATA.RemovableMedias = mediaTests.ToArray(); } else { - logicalsectorsize = 512; - physicalsectorsize = 512; - } + report.ATA.ReadCapabilities = new testedMediaType(); - report.ATA.ReadCapabilities.BlockSize = logicalsectorsize; - report.ATA.ReadCapabilities.BlockSizeSpecified = true; - if(physicalsectorsize != logicalsectorsize) - { - report.ATA.ReadCapabilities.PhysicalBlockSize = physicalsectorsize; - report.ATA.ReadCapabilities.PhysicalBlockSizeSpecified = true; - - if((ataId.LogicalAlignment & 0x8000) == 0x0000 && (ataId.LogicalAlignment & 0x4000) == 0x4000) + if(ataId.UnformattedBPT != 0) { - report.ATA.ReadCapabilities.LogicalAlignment = (ushort)(ataId.LogicalAlignment & 0x3FFF); - report.ATA.ReadCapabilities.LogicalAlignmentSpecified = true; + report.ATA.ReadCapabilities.UnformattedBPT = ataId.UnformattedBPT; + report.ATA.ReadCapabilities.UnformattedBPTSpecified = true; } - } - - if(ataId.EccBytes != 0x0000 && ataId.EccBytes != 0xFFFF) - { - report.ATA.ReadCapabilities.LongBlockSize = logicalsectorsize + ataId.EccBytes; - report.ATA.ReadCapabilities.LongBlockSizeSpecified = true; - } - - if(ataId.UnformattedBPS > logicalsectorsize && - (!report.ATA.ReadCapabilities.LongBlockSizeSpecified || - report.ATA.ReadCapabilities.LongBlockSize == 516)) - { - report.ATA.ReadCapabilities.LongBlockSize = ataId.UnformattedBPS; - report.ATA.ReadCapabilities.LongBlockSizeSpecified = true; - } - - if(ataId.CommandSet3.HasFlag(Identify.CommandSetBit3.MustBeSet) && - !ataId.CommandSet3.HasFlag(Identify.CommandSetBit3.MustBeClear) && - ataId.EnabledCommandSet3.HasFlag(Identify.CommandSetBit3.MediaSerial)) - { - report.ATA.ReadCapabilities.CanReadMediaSerial = true; - report.ATA.ReadCapabilities.CanReadMediaSerialSpecified = true; - if(!string.IsNullOrWhiteSpace(ataId.MediaManufacturer)) + if(ataId.UnformattedBPS != 0) { - report.ATA.ReadCapabilities.Manufacturer = ataId.MediaManufacturer; - report.ATA.ReadCapabilities.ManufacturerSpecified = true; + report.ATA.ReadCapabilities.UnformattedBPS = ataId.UnformattedBPS; + report.ATA.ReadCapabilities.UnformattedBPSSpecified = true; } + + if(ataId.Cylinders > 0 && ataId.Heads > 0 && ataId.SectorsPerTrack > 0) + { + report.ATA.ReadCapabilities.CHS = new chsType(); + report.ATA.ReadCapabilities.CHS.Cylinders = ataId.Cylinders; + report.ATA.ReadCapabilities.CHS.Heads = ataId.Heads; + report.ATA.ReadCapabilities.CHS.Sectors = ataId.SectorsPerTrack; + report.ATA.ReadCapabilities.Blocks = + (ulong)(ataId.Cylinders * ataId.Heads * ataId.SectorsPerTrack); + report.ATA.ReadCapabilities.BlocksSpecified = true; + } + + if(ataId.CurrentCylinders > 0 && ataId.CurrentHeads > 0 && ataId.CurrentSectorsPerTrack > 0) + { + report.ATA.ReadCapabilities.CurrentCHS = new chsType(); + report.ATA.ReadCapabilities.CurrentCHS.Cylinders = ataId.CurrentCylinders; + report.ATA.ReadCapabilities.CurrentCHS.Heads = ataId.CurrentHeads; + report.ATA.ReadCapabilities.CurrentCHS.Sectors = ataId.CurrentSectorsPerTrack; + report.ATA.ReadCapabilities.Blocks = + (ulong)(ataId.CurrentCylinders * ataId.CurrentHeads * ataId.CurrentSectorsPerTrack); + report.ATA.ReadCapabilities.BlocksSpecified = true; + } + + if(ataId.Capabilities.HasFlag(Identify.CapabilitiesBit.LBASupport)) + { + report.ATA.ReadCapabilities.LBASectors = ataId.LBASectors; + report.ATA.ReadCapabilities.LBASectorsSpecified = true; + report.ATA.ReadCapabilities.Blocks = ataId.LBASectors; + report.ATA.ReadCapabilities.BlocksSpecified = true; + } + + if(ataId.CommandSet2.HasFlag(Identify.CommandSetBit2.LBA48)) + { + report.ATA.ReadCapabilities.LBA48Sectors = ataId.LBA48Sectors; + report.ATA.ReadCapabilities.LBA48SectorsSpecified = true; + report.ATA.ReadCapabilities.Blocks = ataId.LBA48Sectors; + report.ATA.ReadCapabilities.BlocksSpecified = true; + } + + if(ataId.NominalRotationRate != 0x0000 && ataId.NominalRotationRate != 0xFFFF) + if(ataId.NominalRotationRate == 0x0001) + { + report.ATA.ReadCapabilities.SolidStateDevice = true; + report.ATA.ReadCapabilities.SolidStateDeviceSpecified = true; + } + else + { + report.ATA.ReadCapabilities.SolidStateDevice = false; + report.ATA.ReadCapabilities.SolidStateDeviceSpecified = true; + report.ATA.ReadCapabilities.NominalRotationRate = ataId.NominalRotationRate; + report.ATA.ReadCapabilities.NominalRotationRateSpecified = true; + } + + uint logicalsectorsize; + uint physicalsectorsize; + if((ataId.PhysLogSectorSize & 0x8000) == 0x0000 && (ataId.PhysLogSectorSize & 0x4000) == 0x4000) + { + if((ataId.PhysLogSectorSize & 0x1000) == 0x1000) + if(ataId.LogicalSectorWords <= 255 || ataId.LogicalAlignment == 0xFFFF) + logicalsectorsize = 512; + else logicalsectorsize = ataId.LogicalSectorWords * 2; + else logicalsectorsize = 512; + + if((ataId.PhysLogSectorSize & 0x2000) == 0x2000) + { + physicalsectorsize = logicalsectorsize * + (uint)Math.Pow(2, ataId.PhysLogSectorSize & 0xF); + } + else physicalsectorsize = logicalsectorsize; + } + else + { + logicalsectorsize = 512; + physicalsectorsize = 512; + } + + report.ATA.ReadCapabilities.BlockSize = logicalsectorsize; + report.ATA.ReadCapabilities.BlockSizeSpecified = true; + if(physicalsectorsize != logicalsectorsize) + { + report.ATA.ReadCapabilities.PhysicalBlockSize = physicalsectorsize; + report.ATA.ReadCapabilities.PhysicalBlockSizeSpecified = true; + + if((ataId.LogicalAlignment & 0x8000) == 0x0000 && (ataId.LogicalAlignment & 0x4000) == 0x4000) + { + report.ATA.ReadCapabilities.LogicalAlignment = (ushort)(ataId.LogicalAlignment & 0x3FFF); + report.ATA.ReadCapabilities.LogicalAlignmentSpecified = true; + } + } + + if(ataId.EccBytes != 0x0000 && ataId.EccBytes != 0xFFFF) + { + report.ATA.ReadCapabilities.LongBlockSize = logicalsectorsize + ataId.EccBytes; + report.ATA.ReadCapabilities.LongBlockSizeSpecified = true; + } + + if(ataId.UnformattedBPS > logicalsectorsize && + (!report.ATA.ReadCapabilities.LongBlockSizeSpecified || + report.ATA.ReadCapabilities.LongBlockSize == 516)) + { + report.ATA.ReadCapabilities.LongBlockSize = ataId.UnformattedBPS; + report.ATA.ReadCapabilities.LongBlockSizeSpecified = true; + } + + if(ataId.CommandSet3.HasFlag(Identify.CommandSetBit3.MustBeSet) && + !ataId.CommandSet3.HasFlag(Identify.CommandSetBit3.MustBeClear) && + ataId.EnabledCommandSet3.HasFlag(Identify.CommandSetBit3.MediaSerial)) + { + report.ATA.ReadCapabilities.CanReadMediaSerial = true; + report.ATA.ReadCapabilities.CanReadMediaSerialSpecified = true; + if(!string.IsNullOrWhiteSpace(ataId.MediaManufacturer)) + { + report.ATA.ReadCapabilities.Manufacturer = ataId.MediaManufacturer; + report.ATA.ReadCapabilities.ManufacturerSpecified = true; + } + } + + report.ATA.ReadCapabilities.SupportsReadLbaSpecified = true; + report.ATA.ReadCapabilities.SupportsReadRetryLbaSpecified = true; + report.ATA.ReadCapabilities.SupportsReadDmaLbaSpecified = true; + report.ATA.ReadCapabilities.SupportsReadDmaRetryLbaSpecified = true; + report.ATA.ReadCapabilities.SupportsReadLongLbaSpecified = true; + report.ATA.ReadCapabilities.SupportsReadLongRetryLbaSpecified = true; + report.ATA.ReadCapabilities.SupportsSeekLbaSpecified = true; + + report.ATA.ReadCapabilities.SupportsReadLba48Specified = true; + report.ATA.ReadCapabilities.SupportsReadDmaLba48Specified = true; + + report.ATA.ReadCapabilities.SupportsReadSpecified = true; + report.ATA.ReadCapabilities.SupportsReadRetrySpecified = true; + report.ATA.ReadCapabilities.SupportsReadDmaSpecified = true; + report.ATA.ReadCapabilities.SupportsReadDmaRetrySpecified = true; + report.ATA.ReadCapabilities.SupportsReadLongSpecified = true; + report.ATA.ReadCapabilities.SupportsReadLongRetrySpecified = true; + report.ATA.ReadCapabilities.SupportsSeekSpecified = true; + + AtaErrorRegistersCHS errorChs; + AtaErrorRegistersLBA28 errorLba; + AtaErrorRegistersLBA48 errorLba48; + + byte[] readBuf; + ulong checkCorrectRead = BitConverter.ToUInt64(buffer, 0); + bool sense; + + DicConsole.WriteLine("Trying READ SECTOR(S) in CHS mode..."); + sense = dev.Read(out readBuf, out errorChs, false, 0, 0, 1, 1, timeout, out duration); + report.ATA.ReadCapabilities.SupportsRead = + !sense && (errorChs.status & 0x01) != 0x01 && errorChs.error == 0 && readBuf.Length > 0; + DicConsole.DebugWriteLine("ATA Report", + "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", sense, + errorChs.status, errorChs.error, readBuf.Length); + if(debug) + DataFile.WriteTo("ATA Report", "readsectorschs", "_debug_" + report.ATA.Model + ".bin", + "read results", readBuf); + + DicConsole.WriteLine("Trying READ SECTOR(S) RETRY in CHS mode..."); + sense = dev.Read(out readBuf, out errorChs, true, 0, 0, 1, 1, timeout, out duration); + report.ATA.ReadCapabilities.SupportsReadRetry = + !sense && (errorChs.status & 0x01) != 0x01 && errorChs.error == 0 && readBuf.Length > 0; + DicConsole.DebugWriteLine("ATA Report", + "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", sense, + errorChs.status, errorChs.error, readBuf.Length); + if(debug) + DataFile.WriteTo("ATA Report", "readsectorsretrychs", "_debug_" + report.ATA.Model + ".bin", + "read results", readBuf); + + DicConsole.WriteLine("Trying READ DMA in CHS mode..."); + sense = dev.ReadDma(out readBuf, out errorChs, false, 0, 0, 1, 1, timeout, out duration); + report.ATA.ReadCapabilities.SupportsReadDma = + !sense && (errorChs.status & 0x01) != 0x01 && errorChs.error == 0 && readBuf.Length > 0; + DicConsole.DebugWriteLine("ATA Report", + "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", sense, + errorChs.status, errorChs.error, readBuf.Length); + if(debug) + DataFile.WriteTo("ATA Report", "readdmachs", "_debug_" + report.ATA.Model + ".bin", + "read results", readBuf); + + DicConsole.WriteLine("Trying READ DMA RETRY in CHS mode..."); + sense = dev.ReadDma(out readBuf, out errorChs, true, 0, 0, 1, 1, timeout, out duration); + report.ATA.ReadCapabilities.SupportsReadDmaRetry = + !sense && (errorChs.status & 0x01) != 0x01 && errorChs.error == 0 && readBuf.Length > 0; + DicConsole.DebugWriteLine("ATA Report", + "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", sense, + errorChs.status, errorChs.error, readBuf.Length); + if(debug) + DataFile.WriteTo("ATA Report", "readdmaretrychs", "_debug_" + report.ATA.Model + ".bin", + "read results", readBuf); + + DicConsole.WriteLine("Trying SEEK in CHS mode..."); + sense = dev.Seek(out errorChs, 0, 0, 1, timeout, out duration); + report.ATA.ReadCapabilities.SupportsSeek = + !sense && (errorChs.status & 0x01) != 0x01 && errorChs.error == 0; + DicConsole.DebugWriteLine("ATA Report", "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}", sense, + errorChs.status, errorChs.error); + + DicConsole.WriteLine("Trying READ SECTOR(S) in LBA mode..."); + sense = dev.Read(out readBuf, out errorLba, false, 0, 1, timeout, out duration); + report.ATA.ReadCapabilities.SupportsReadLba = + !sense && (errorLba.status & 0x01) != 0x01 && errorLba.error == 0 && readBuf.Length > 0; + DicConsole.DebugWriteLine("ATA Report", + "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", sense, + errorLba.status, errorLba.error, readBuf.Length); + if(debug) + DataFile.WriteTo("ATA Report", "readsectors", "_debug_" + report.ATA.Model + ".bin", + "read results", readBuf); + + DicConsole.WriteLine("Trying READ SECTOR(S) RETRY in LBA mode..."); + sense = dev.Read(out readBuf, out errorLba, true, 0, 1, timeout, out duration); + report.ATA.ReadCapabilities.SupportsReadRetryLba = + !sense && (errorLba.status & 0x01) != 0x01 && errorLba.error == 0 && readBuf.Length > 0; + DicConsole.DebugWriteLine("ATA Report", + "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", sense, + errorLba.status, errorLba.error, readBuf.Length); + if(debug) + DataFile.WriteTo("ATA Report", "readsectorsretry", "_debug_" + report.ATA.Model + ".bin", + "read results", readBuf); + + DicConsole.WriteLine("Trying READ DMA in LBA mode..."); + sense = dev.ReadDma(out readBuf, out errorLba, false, 0, 1, timeout, out duration); + report.ATA.ReadCapabilities.SupportsReadDmaLba = + !sense && (errorLba.status & 0x01) != 0x01 && errorLba.error == 0 && readBuf.Length > 0; + DicConsole.DebugWriteLine("ATA Report", + "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", sense, + errorLba.status, errorLba.error, readBuf.Length); + if(debug) + DataFile.WriteTo("ATA Report", "readdma", "_debug_" + report.ATA.Model + ".bin", "read results", + readBuf); + + DicConsole.WriteLine("Trying READ DMA RETRY in LBA mode..."); + sense = dev.ReadDma(out readBuf, out errorLba, true, 0, 1, timeout, out duration); + report.ATA.ReadCapabilities.SupportsReadDmaRetryLba = + !sense && (errorLba.status & 0x01) != 0x01 && errorLba.error == 0 && readBuf.Length > 0; + DicConsole.DebugWriteLine("ATA Report", + "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", sense, + errorLba.status, errorLba.error, readBuf.Length); + if(debug) + DataFile.WriteTo("ATA Report", "readdmaretry", "_debug_" + report.ATA.Model + ".bin", + "read results", readBuf); + + DicConsole.WriteLine("Trying SEEK in LBA mode..."); + sense = dev.Seek(out errorLba, 0, timeout, out duration); + report.ATA.ReadCapabilities.SupportsSeekLba = + !sense && (errorLba.status & 0x01) != 0x01 && errorLba.error == 0; + DicConsole.DebugWriteLine("ATA Report", "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}", sense, + errorLba.status, errorLba.error); + + DicConsole.WriteLine("Trying READ SECTOR(S) in LBA48 mode..."); + sense = dev.Read(out readBuf, out errorLba48, 0, 1, timeout, out duration); + report.ATA.ReadCapabilities.SupportsReadLba48 = + !sense && (errorLba48.status & 0x01) != 0x01 && errorLba48.error == 0 && readBuf.Length > 0; + DicConsole.DebugWriteLine("ATA Report", + "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", sense, + errorLba48.status, errorLba48.error, readBuf.Length); + if(debug) + DataFile.WriteTo("ATA Report", "readsectors48", "_debug_" + report.ATA.Model + ".bin", + "read results", readBuf); + + DicConsole.WriteLine("Trying READ DMA in LBA48 mode..."); + sense = dev.ReadDma(out readBuf, out errorLba48, 0, 1, timeout, out duration); + report.ATA.ReadCapabilities.SupportsReadDmaLba48 = + !sense && (errorLba48.status & 0x01) != 0x01 && errorLba48.error == 0 && readBuf.Length > 0; + DicConsole.DebugWriteLine("ATA Report", + "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", sense, + errorLba48.status, errorLba48.error, readBuf.Length); + if(debug) + DataFile.WriteTo("ATA Report", "readdma48", "_debug_" + report.ATA.Model + ".bin", + "read results", readBuf); + + DicConsole.WriteLine("Trying READ LONG in CHS mode..."); + sense = dev.ReadLong(out readBuf, out errorChs, false, 0, 0, 1, + report.ATA.ReadCapabilities.LongBlockSize, timeout, out duration); + report.ATA.ReadCapabilities.SupportsReadLong = + !sense && (errorChs.status & 0x01) != 0x01 && errorChs.error == 0 && readBuf.Length > 0 && + BitConverter.ToUInt64(readBuf, 0) != checkCorrectRead; + DicConsole.DebugWriteLine("ATA Report", + "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", sense, + errorChs.status, errorChs.error, readBuf.Length); + if(debug) + DataFile.WriteTo("ATA Report", "readlongchs", "_debug_" + report.ATA.Model + ".bin", + "read results", readBuf); + + DicConsole.WriteLine("Trying READ LONG RETRY in CHS mode..."); + sense = dev.ReadLong(out readBuf, out errorChs, true, 0, 0, 1, + report.ATA.ReadCapabilities.LongBlockSize, timeout, out duration); + report.ATA.ReadCapabilities.SupportsReadLongRetry = + !sense && (errorChs.status & 0x01) != 0x01 && errorChs.error == 0 && readBuf.Length > 0 && + BitConverter.ToUInt64(readBuf, 0) != checkCorrectRead; + DicConsole.DebugWriteLine("ATA Report", + "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", sense, + errorChs.status, errorChs.error, readBuf.Length); + if(debug) + DataFile.WriteTo("ATA Report", "readlongretrychs", "_debug_" + report.ATA.Model + ".bin", + "read results", readBuf); + + DicConsole.WriteLine("Trying READ LONG in LBA mode..."); + sense = dev.ReadLong(out readBuf, out errorLba, false, 0, report.ATA.ReadCapabilities.LongBlockSize, + timeout, out duration); + report.ATA.ReadCapabilities.SupportsReadLongLba = + !sense && (errorLba.status & 0x01) != 0x01 && errorLba.error == 0 && readBuf.Length > 0 && + BitConverter.ToUInt64(readBuf, 0) != checkCorrectRead; + DicConsole.DebugWriteLine("ATA Report", + "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", sense, + errorLba.status, errorLba.error, readBuf.Length); + if(debug) + DataFile.WriteTo("ATA Report", "readlong", "_debug_" + report.ATA.Model + ".bin", + "read results", readBuf); + + DicConsole.WriteLine("Trying READ LONG RETRY in LBA mode..."); + sense = dev.ReadLong(out readBuf, out errorLba, true, 0, report.ATA.ReadCapabilities.LongBlockSize, + timeout, out duration); + report.ATA.ReadCapabilities.SupportsReadLongRetryLba = + !sense && (errorLba.status & 0x01) != 0x01 && errorLba.error == 0 && readBuf.Length > 0 && + BitConverter.ToUInt64(readBuf, 0) != checkCorrectRead; + DicConsole.DebugWriteLine("ATA Report", + "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", sense, + errorLba.status, errorLba.error, readBuf.Length); + if(debug) + DataFile.WriteTo("ATA Report", "readlongretry", "_debug_" + report.ATA.Model + ".bin", + "read results", readBuf); } - - report.ATA.ReadCapabilities.SupportsReadLbaSpecified = true; - report.ATA.ReadCapabilities.SupportsReadRetryLbaSpecified = true; - report.ATA.ReadCapabilities.SupportsReadDmaLbaSpecified = true; - report.ATA.ReadCapabilities.SupportsReadDmaRetryLbaSpecified = true; - report.ATA.ReadCapabilities.SupportsReadLongLbaSpecified = true; - report.ATA.ReadCapabilities.SupportsReadLongRetryLbaSpecified = true; - report.ATA.ReadCapabilities.SupportsSeekLbaSpecified = true; - - report.ATA.ReadCapabilities.SupportsReadLba48Specified = true; - report.ATA.ReadCapabilities.SupportsReadDmaLba48Specified = true; - - report.ATA.ReadCapabilities.SupportsReadSpecified = true; - report.ATA.ReadCapabilities.SupportsReadRetrySpecified = true; - report.ATA.ReadCapabilities.SupportsReadDmaSpecified = true; - report.ATA.ReadCapabilities.SupportsReadDmaRetrySpecified = true; - report.ATA.ReadCapabilities.SupportsReadLongSpecified = true; - report.ATA.ReadCapabilities.SupportsReadLongRetrySpecified = true; - report.ATA.ReadCapabilities.SupportsSeekSpecified = true; - - AtaErrorRegistersCHS errorChs; - AtaErrorRegistersLBA28 errorLba; - AtaErrorRegistersLBA48 errorLba48; - - byte[] readBuf; - ulong checkCorrectRead = BitConverter.ToUInt64(buffer, 0); - bool sense; - - DicConsole.WriteLine("Trying READ SECTOR(S) in CHS mode..."); - sense = dev.Read(out readBuf, out errorChs, false, 0, 0, 1, 1, timeout, out duration); - report.ATA.ReadCapabilities.SupportsRead = - !sense && (errorChs.status & 0x01) != 0x01 && errorChs.error == 0 && readBuf.Length > 0; - DicConsole.DebugWriteLine("ATA Report", - "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", sense, - errorChs.status, errorChs.error, readBuf.Length); - if(debug) - DataFile.WriteTo("ATA Report", "readsectorschs", "_debug_" + report.ATA.Model + ".bin", - "read results", readBuf); - - DicConsole.WriteLine("Trying READ SECTOR(S) RETRY in CHS mode..."); - sense = dev.Read(out readBuf, out errorChs, true, 0, 0, 1, 1, timeout, out duration); - report.ATA.ReadCapabilities.SupportsReadRetry = - !sense && (errorChs.status & 0x01) != 0x01 && errorChs.error == 0 && readBuf.Length > 0; - DicConsole.DebugWriteLine("ATA Report", - "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", sense, - errorChs.status, errorChs.error, readBuf.Length); - if(debug) - DataFile.WriteTo("ATA Report", "readsectorsretrychs", "_debug_" + report.ATA.Model + ".bin", - "read results", readBuf); - - DicConsole.WriteLine("Trying READ DMA in CHS mode..."); - sense = dev.ReadDma(out readBuf, out errorChs, false, 0, 0, 1, 1, timeout, out duration); - report.ATA.ReadCapabilities.SupportsReadDma = - !sense && (errorChs.status & 0x01) != 0x01 && errorChs.error == 0 && readBuf.Length > 0; - DicConsole.DebugWriteLine("ATA Report", - "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", sense, - errorChs.status, errorChs.error, readBuf.Length); - if(debug) - DataFile.WriteTo("ATA Report", "readdmachs", "_debug_" + report.ATA.Model + ".bin", - "read results", readBuf); - - DicConsole.WriteLine("Trying READ DMA RETRY in CHS mode..."); - sense = dev.ReadDma(out readBuf, out errorChs, true, 0, 0, 1, 1, timeout, out duration); - report.ATA.ReadCapabilities.SupportsReadDmaRetry = - !sense && (errorChs.status & 0x01) != 0x01 && errorChs.error == 0 && readBuf.Length > 0; - DicConsole.DebugWriteLine("ATA Report", - "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", sense, - errorChs.status, errorChs.error, readBuf.Length); - if(debug) - DataFile.WriteTo("ATA Report", "readdmaretrychs", "_debug_" + report.ATA.Model + ".bin", - "read results", readBuf); - - DicConsole.WriteLine("Trying SEEK in CHS mode..."); - sense = dev.Seek(out errorChs, 0, 0, 1, timeout, out duration); - report.ATA.ReadCapabilities.SupportsSeek = - !sense && (errorChs.status & 0x01) != 0x01 && errorChs.error == 0; - DicConsole.DebugWriteLine("ATA Report", "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}", sense, - errorChs.status, errorChs.error); - - DicConsole.WriteLine("Trying READ SECTOR(S) in LBA mode..."); - sense = dev.Read(out readBuf, out errorLba, false, 0, 1, timeout, out duration); - report.ATA.ReadCapabilities.SupportsReadLba = - !sense && (errorLba.status & 0x01) != 0x01 && errorLba.error == 0 && readBuf.Length > 0; - DicConsole.DebugWriteLine("ATA Report", - "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", sense, - errorLba.status, errorLba.error, readBuf.Length); - if(debug) - DataFile.WriteTo("ATA Report", "readsectors", "_debug_" + report.ATA.Model + ".bin", - "read results", readBuf); - - DicConsole.WriteLine("Trying READ SECTOR(S) RETRY in LBA mode..."); - sense = dev.Read(out readBuf, out errorLba, true, 0, 1, timeout, out duration); - report.ATA.ReadCapabilities.SupportsReadRetryLba = - !sense && (errorLba.status & 0x01) != 0x01 && errorLba.error == 0 && readBuf.Length > 0; - DicConsole.DebugWriteLine("ATA Report", - "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", sense, - errorLba.status, errorLba.error, readBuf.Length); - if(debug) - DataFile.WriteTo("ATA Report", "readsectorsretry", "_debug_" + report.ATA.Model + ".bin", - "read results", readBuf); - - DicConsole.WriteLine("Trying READ DMA in LBA mode..."); - sense = dev.ReadDma(out readBuf, out errorLba, false, 0, 1, timeout, out duration); - report.ATA.ReadCapabilities.SupportsReadDmaLba = - !sense && (errorLba.status & 0x01) != 0x01 && errorLba.error == 0 && readBuf.Length > 0; - DicConsole.DebugWriteLine("ATA Report", - "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", sense, - errorLba.status, errorLba.error, readBuf.Length); - if(debug) - DataFile.WriteTo("ATA Report", "readdma", "_debug_" + report.ATA.Model + ".bin", "read results", - readBuf); - - DicConsole.WriteLine("Trying READ DMA RETRY in LBA mode..."); - sense = dev.ReadDma(out readBuf, out errorLba, true, 0, 1, timeout, out duration); - report.ATA.ReadCapabilities.SupportsReadDmaRetryLba = - !sense && (errorLba.status & 0x01) != 0x01 && errorLba.error == 0 && readBuf.Length > 0; - DicConsole.DebugWriteLine("ATA Report", - "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", sense, - errorLba.status, errorLba.error, readBuf.Length); - if(debug) - DataFile.WriteTo("ATA Report", "readdmaretry", "_debug_" + report.ATA.Model + ".bin", - "read results", readBuf); - - DicConsole.WriteLine("Trying SEEK in LBA mode..."); - sense = dev.Seek(out errorLba, 0, timeout, out duration); - report.ATA.ReadCapabilities.SupportsSeekLba = - !sense && (errorLba.status & 0x01) != 0x01 && errorLba.error == 0; - DicConsole.DebugWriteLine("ATA Report", "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}", sense, - errorLba.status, errorLba.error); - - DicConsole.WriteLine("Trying READ SECTOR(S) in LBA48 mode..."); - sense = dev.Read(out readBuf, out errorLba48, 0, 1, timeout, out duration); - report.ATA.ReadCapabilities.SupportsReadLba48 = - !sense && (errorLba48.status & 0x01) != 0x01 && errorLba48.error == 0 && readBuf.Length > 0; - DicConsole.DebugWriteLine("ATA Report", - "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", sense, - errorLba48.status, errorLba48.error, readBuf.Length); - if(debug) - DataFile.WriteTo("ATA Report", "readsectors48", "_debug_" + report.ATA.Model + ".bin", - "read results", readBuf); - - DicConsole.WriteLine("Trying READ DMA in LBA48 mode..."); - sense = dev.ReadDma(out readBuf, out errorLba48, 0, 1, timeout, out duration); - report.ATA.ReadCapabilities.SupportsReadDmaLba48 = - !sense && (errorLba48.status & 0x01) != 0x01 && errorLba48.error == 0 && readBuf.Length > 0; - DicConsole.DebugWriteLine("ATA Report", - "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", sense, - errorLba48.status, errorLba48.error, readBuf.Length); - if(debug) - DataFile.WriteTo("ATA Report", "readdma48", "_debug_" + report.ATA.Model + ".bin", - "read results", readBuf); - - DicConsole.WriteLine("Trying READ LONG in CHS mode..."); - sense = dev.ReadLong(out readBuf, out errorChs, false, 0, 0, 1, - report.ATA.ReadCapabilities.LongBlockSize, timeout, out duration); - report.ATA.ReadCapabilities.SupportsReadLong = - !sense && (errorChs.status & 0x01) != 0x01 && errorChs.error == 0 && readBuf.Length > 0 && - BitConverter.ToUInt64(readBuf, 0) != checkCorrectRead; - DicConsole.DebugWriteLine("ATA Report", - "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", sense, - errorChs.status, errorChs.error, readBuf.Length); - if(debug) - DataFile.WriteTo("ATA Report", "readlongchs", "_debug_" + report.ATA.Model + ".bin", - "read results", readBuf); - - DicConsole.WriteLine("Trying READ LONG RETRY in CHS mode..."); - sense = dev.ReadLong(out readBuf, out errorChs, true, 0, 0, 1, - report.ATA.ReadCapabilities.LongBlockSize, timeout, out duration); - report.ATA.ReadCapabilities.SupportsReadLongRetry = - !sense && (errorChs.status & 0x01) != 0x01 && errorChs.error == 0 && readBuf.Length > 0 && - BitConverter.ToUInt64(readBuf, 0) != checkCorrectRead; - DicConsole.DebugWriteLine("ATA Report", - "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", sense, - errorChs.status, errorChs.error, readBuf.Length); - if(debug) - DataFile.WriteTo("ATA Report", "readlongretrychs", "_debug_" + report.ATA.Model + ".bin", - "read results", readBuf); - - DicConsole.WriteLine("Trying READ LONG in LBA mode..."); - sense = dev.ReadLong(out readBuf, out errorLba, false, 0, report.ATA.ReadCapabilities.LongBlockSize, - timeout, out duration); - report.ATA.ReadCapabilities.SupportsReadLongLba = - !sense && (errorLba.status & 0x01) != 0x01 && errorLba.error == 0 && readBuf.Length > 0 && - BitConverter.ToUInt64(readBuf, 0) != checkCorrectRead; - DicConsole.DebugWriteLine("ATA Report", - "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", sense, - errorLba.status, errorLba.error, readBuf.Length); - if(debug) - DataFile.WriteTo("ATA Report", "readlong", "_debug_" + report.ATA.Model + ".bin", - "read results", readBuf); - - DicConsole.WriteLine("Trying READ LONG RETRY in LBA mode..."); - sense = dev.ReadLong(out readBuf, out errorLba, true, 0, report.ATA.ReadCapabilities.LongBlockSize, - timeout, out duration); - report.ATA.ReadCapabilities.SupportsReadLongRetryLba = - !sense && (errorLba.status & 0x01) != 0x01 && errorLba.error == 0 && readBuf.Length > 0 && - BitConverter.ToUInt64(readBuf, 0) != checkCorrectRead; - DicConsole.DebugWriteLine("ATA Report", - "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", sense, - errorLba.status, errorLba.error, readBuf.Length); - if(debug) - DataFile.WriteTo("ATA Report", "readlongretry", "_debug_" + report.ATA.Model + ".bin", - "read results", readBuf); } } } diff --git a/DiscImageChef.Core/Devices/Report/ATAPI.cs b/DiscImageChef.Core/Devices/Report/ATAPI.cs index af5bf4ade..6e12c580f 100644 --- a/DiscImageChef.Core/Devices/Report/ATAPI.cs +++ b/DiscImageChef.Core/Devices/Report/ATAPI.cs @@ -54,404 +54,407 @@ namespace DiscImageChef.Core.Devices.Report 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)) - { - report.ATAPI.AdditionalPID = atapiId.AdditionalPID; - report.ATAPI.AdditionalPIDSpecified = true; - } - if(atapiId.APIOSupported != 0) - { - report.ATAPI.APIOSupported = atapiId.APIOSupported; - report.ATAPI.APIOSupportedSpecified = true; - } - if(atapiId.ATAPIByteCount != 0) - { - report.ATAPI.ATAPIByteCount = atapiId.ATAPIByteCount; - report.ATAPI.ATAPIByteCountSpecified = true; - } - if(atapiId.BufferType != 0) - { - report.ATAPI.BufferType = atapiId.BufferType; - report.ATAPI.BufferTypeSpecified = true; - } - if(atapiId.BufferSize != 0) - { - report.ATAPI.BufferSize = atapiId.BufferSize; - report.ATAPI.BufferSizeSpecified = true; - } - if(atapiId.Capabilities != 0) - { - report.ATAPI.Capabilities = atapiId.Capabilities; - report.ATAPI.CapabilitiesSpecified = true; - } - if(atapiId.Capabilities2 != 0) - { - report.ATAPI.Capabilities2 = atapiId.Capabilities2; - report.ATAPI.Capabilities2Specified = true; - } - if(atapiId.Capabilities3 != 0) - { - report.ATAPI.Capabilities3 = atapiId.Capabilities3; - report.ATAPI.Capabilities3Specified = true; - } - if(atapiId.CFAPowerMode != 0) - { - report.ATAPI.CFAPowerMode = atapiId.CFAPowerMode; - report.ATAPI.CFAPowerModeSpecified = true; - } - if(atapiId.CommandSet != 0) - { - report.ATAPI.CommandSet = atapiId.CommandSet; - report.ATAPI.CommandSetSpecified = true; - } - if(atapiId.CommandSet2 != 0) - { - report.ATAPI.CommandSet2 = atapiId.CommandSet2; - report.ATAPI.CommandSet2Specified = true; - } - if(atapiId.CommandSet3 != 0) - { - report.ATAPI.CommandSet3 = atapiId.CommandSet3; - report.ATAPI.CommandSet3Specified = true; - } - if(atapiId.CommandSet4 != 0) - { - report.ATAPI.CommandSet4 = atapiId.CommandSet4; - report.ATAPI.CommandSet4Specified = true; - } - if(atapiId.CommandSet5 != 0) - { - report.ATAPI.CommandSet5 = atapiId.CommandSet5; - report.ATAPI.CommandSet5Specified = true; - } - if(atapiId.CurrentAAM != 0) - { - report.ATAPI.CurrentAAM = atapiId.CurrentAAM; - report.ATAPI.CurrentAAMSpecified = true; - } - if(atapiId.CurrentAPM != 0) - { - report.ATAPI.CurrentAPM = atapiId.CurrentAPM; - report.ATAPI.CurrentAPMSpecified = true; - } - if(atapiId.DataSetMgmt != 0) - { - report.ATAPI.DataSetMgmt = atapiId.DataSetMgmt; - report.ATAPI.DataSetMgmtSpecified = true; - } - if(atapiId.DataSetMgmtSize != 0) - { - report.ATAPI.DataSetMgmtSize = atapiId.DataSetMgmtSize; - report.ATAPI.DataSetMgmtSizeSpecified = true; - } - if(atapiId.DeviceFormFactor != 0) - { - report.ATAPI.DeviceFormFactor = atapiId.DeviceFormFactor; - report.ATAPI.DeviceFormFactorSpecified = true; - } - if(atapiId.DMAActive != 0) - { - report.ATAPI.DMAActive = atapiId.DMAActive; - report.ATAPI.DMAActiveSpecified = true; - } - if(atapiId.DMASupported != 0) - { - report.ATAPI.DMASupported = atapiId.DMASupported; - report.ATAPI.DMASupportedSpecified = true; - } - if(atapiId.DMATransferTimingMode != 0) - { - report.ATAPI.DMATransferTimingMode = atapiId.DMATransferTimingMode; - report.ATAPI.DMATransferTimingModeSpecified = true; - } - if(atapiId.EnhancedSecurityEraseTime != 0) - { - report.ATAPI.EnhancedSecurityEraseTime = atapiId.EnhancedSecurityEraseTime; - report.ATAPI.EnhancedSecurityEraseTimeSpecified = true; - } - if(atapiId.EnabledCommandSet != 0) - { - report.ATAPI.EnabledCommandSet = atapiId.EnabledCommandSet; - report.ATAPI.EnabledCommandSetSpecified = true; - } - if(atapiId.EnabledCommandSet2 != 0) - { - report.ATAPI.EnabledCommandSet2 = atapiId.EnabledCommandSet2; - report.ATAPI.EnabledCommandSet2Specified = true; - } - if(atapiId.EnabledCommandSet3 != 0) - { - report.ATAPI.EnabledCommandSet3 = atapiId.EnabledCommandSet3; - report.ATAPI.EnabledCommandSet3Specified = true; - } - if(atapiId.EnabledCommandSet4 != 0) - { - report.ATAPI.EnabledCommandSet4 = atapiId.EnabledCommandSet4; - report.ATAPI.EnabledCommandSet4Specified = true; - } - if(atapiId.EnabledSATAFeatures != 0) - { - report.ATAPI.EnabledSATAFeatures = atapiId.EnabledSATAFeatures; - report.ATAPI.EnabledSATAFeaturesSpecified = true; - } - if(atapiId.ExtendedUserSectors != 0) - { - report.ATAPI.ExtendedUserSectors = atapiId.ExtendedUserSectors; - report.ATAPI.ExtendedUserSectorsSpecified = true; - } - if(atapiId.FreeFallSensitivity != 0) - { - report.ATAPI.FreeFallSensitivity = atapiId.FreeFallSensitivity; - report.ATAPI.FreeFallSensitivitySpecified = true; - } - if(!string.IsNullOrWhiteSpace(atapiId.FirmwareRevision)) - { - report.ATAPI.FirmwareRevision = atapiId.FirmwareRevision; - report.ATAPI.FirmwareRevisionSpecified = true; - } - if(atapiId.GeneralConfiguration != 0) - { - report.ATAPI.GeneralConfiguration = atapiId.GeneralConfiguration; - report.ATAPI.GeneralConfigurationSpecified = true; - } - if(atapiId.HardwareResetResult != 0) - { - report.ATAPI.HardwareResetResult = atapiId.HardwareResetResult; - report.ATAPI.HardwareResetResultSpecified = true; - } - if(atapiId.InterseekDelay != 0) - { - report.ATAPI.InterseekDelay = atapiId.InterseekDelay; - report.ATAPI.InterseekDelaySpecified = true; - } - if(atapiId.MajorVersion != 0) - { - report.ATAPI.MajorVersion = atapiId.MajorVersion; - report.ATAPI.MajorVersionSpecified = true; - } - if(atapiId.MasterPasswordRevisionCode != 0) - { - report.ATAPI.MasterPasswordRevisionCode = atapiId.MasterPasswordRevisionCode; - report.ATAPI.MasterPasswordRevisionCodeSpecified = true; - } - if(atapiId.MaxDownloadMicroMode3 != 0) - { - report.ATAPI.MaxDownloadMicroMode3 = atapiId.MaxDownloadMicroMode3; - report.ATAPI.MaxDownloadMicroMode3Specified = true; - } - if(atapiId.MaxQueueDepth != 0) - { - report.ATAPI.MaxQueueDepth = atapiId.MaxQueueDepth; - report.ATAPI.MaxQueueDepthSpecified = true; - } - if(atapiId.MDMAActive != 0) - { - report.ATAPI.MDMAActive = atapiId.MDMAActive; - report.ATAPI.MDMAActiveSpecified = true; - } - if(atapiId.MDMASupported != 0) - { - report.ATAPI.MDMASupported = atapiId.MDMASupported; - report.ATAPI.MDMASupportedSpecified = true; - } - if(atapiId.MinDownloadMicroMode3 != 0) - { - report.ATAPI.MinDownloadMicroMode3 = atapiId.MinDownloadMicroMode3; - report.ATAPI.MinDownloadMicroMode3Specified = true; - } - if(atapiId.MinMDMACycleTime != 0) - { - report.ATAPI.MinMDMACycleTime = atapiId.MinMDMACycleTime; - report.ATAPI.MinMDMACycleTimeSpecified = true; - } - if(atapiId.MinorVersion != 0) - { - report.ATAPI.MinorVersion = atapiId.MinorVersion; - report.ATAPI.MinorVersionSpecified = true; - } - if(atapiId.MinPIOCycleTimeNoFlow != 0) - { - report.ATAPI.MinPIOCycleTimeNoFlow = atapiId.MinPIOCycleTimeNoFlow; - report.ATAPI.MinPIOCycleTimeNoFlowSpecified = true; - } - if(atapiId.MinPIOCycleTimeFlow != 0) - { - report.ATAPI.MinPIOCycleTimeFlow = atapiId.MinPIOCycleTimeFlow; - report.ATAPI.MinPIOCycleTimeFlowSpecified = true; - } - if(!string.IsNullOrWhiteSpace(atapiId.Model)) - { - report.ATAPI.Model = atapiId.Model; - report.ATAPI.ModelSpecified = true; - } - if(atapiId.MultipleMaxSectors != 0) - { - report.ATAPI.MultipleMaxSectors = atapiId.MultipleMaxSectors; - report.ATAPI.MultipleMaxSectorsSpecified = true; - } - if(atapiId.MultipleSectorNumber != 0) - { - report.ATAPI.MultipleSectorNumber = atapiId.MultipleSectorNumber; - report.ATAPI.MultipleSectorNumberSpecified = true; - } - if(atapiId.NVCacheCaps != 0) - { - report.ATAPI.NVCacheCaps = atapiId.NVCacheCaps; - report.ATAPI.NVCacheCapsSpecified = true; - } - if(atapiId.NVCacheSize != 0) - { - report.ATAPI.NVCacheSize = atapiId.NVCacheSize; - report.ATAPI.NVCacheSizeSpecified = true; - } - if(atapiId.NVCacheWriteSpeed != 0) - { - report.ATAPI.NVCacheWriteSpeed = atapiId.NVCacheWriteSpeed; - report.ATAPI.NVCacheWriteSpeedSpecified = true; - } - if(atapiId.NVEstimatedSpinUp != 0) - { - report.ATAPI.NVEstimatedSpinUp = atapiId.NVEstimatedSpinUp; - report.ATAPI.NVEstimatedSpinUpSpecified = true; - } - if(atapiId.PacketBusRelease != 0) - { - report.ATAPI.PacketBusRelease = atapiId.PacketBusRelease; - report.ATAPI.PacketBusReleaseSpecified = true; - } - if(atapiId.PIOTransferTimingMode != 0) - { - report.ATAPI.PIOTransferTimingMode = atapiId.PIOTransferTimingMode; - report.ATAPI.PIOTransferTimingModeSpecified = true; - } - if(atapiId.RecommendedAAM != 0) - { - report.ATAPI.RecommendedAAM = atapiId.RecommendedAAM; - report.ATAPI.RecommendedAAMSpecified = true; - } - if(atapiId.RecMDMACycleTime != 0) - { - report.ATAPI.RecommendedMDMACycleTime = atapiId.RecMDMACycleTime; - report.ATAPI.RecommendedMDMACycleTimeSpecified = true; - } - if(atapiId.RemovableStatusSet != 0) - { - report.ATAPI.RemovableStatusSet = atapiId.RemovableStatusSet; - report.ATAPI.RemovableStatusSetSpecified = true; - } - if(atapiId.SATACapabilities != 0) - { - report.ATAPI.SATACapabilities = atapiId.SATACapabilities; - report.ATAPI.SATACapabilitiesSpecified = true; - } - if(atapiId.SATACapabilities2 != 0) - { - report.ATAPI.SATACapabilities2 = atapiId.SATACapabilities2; - report.ATAPI.SATACapabilities2Specified = true; - } - if(atapiId.SATAFeatures != 0) - { - report.ATAPI.SATAFeatures = atapiId.SATAFeatures; - report.ATAPI.SATAFeaturesSpecified = true; - } - if(atapiId.SCTCommandTransport != 0) - { - report.ATAPI.SCTCommandTransport = atapiId.SCTCommandTransport; - report.ATAPI.SCTCommandTransportSpecified = true; - } - if(atapiId.SectorsPerCard != 0) - { - report.ATAPI.SectorsPerCard = atapiId.SectorsPerCard; - report.ATAPI.SectorsPerCardSpecified = true; - } - if(atapiId.SecurityEraseTime != 0) - { - report.ATAPI.SecurityEraseTime = atapiId.SecurityEraseTime; - report.ATAPI.SecurityEraseTimeSpecified = true; - } - if(atapiId.SecurityStatus != 0) - { - report.ATAPI.SecurityStatus = atapiId.SecurityStatus; - report.ATAPI.SecurityStatusSpecified = true; - } - if(atapiId.ServiceBusyClear != 0) - { - report.ATAPI.ServiceBusyClear = atapiId.ServiceBusyClear; - report.ATAPI.ServiceBusyClearSpecified = true; - } - if(atapiId.SpecificConfiguration != 0) - { - report.ATAPI.SpecificConfiguration = atapiId.SpecificConfiguration; - report.ATAPI.SpecificConfigurationSpecified = true; - } - if(atapiId.StreamAccessLatency != 0) - { - report.ATAPI.StreamAccessLatency = atapiId.StreamAccessLatency; - report.ATAPI.StreamAccessLatencySpecified = true; - } - if(atapiId.StreamMinReqSize != 0) - { - report.ATAPI.StreamMinReqSize = atapiId.StreamMinReqSize; - report.ATAPI.StreamMinReqSizeSpecified = true; - } - if(atapiId.StreamPerformanceGranularity != 0) - { - report.ATAPI.StreamPerformanceGranularity = atapiId.StreamPerformanceGranularity; - report.ATAPI.StreamPerformanceGranularitySpecified = true; - } - if(atapiId.StreamTransferTimeDMA != 0) - { - report.ATAPI.StreamTransferTimeDMA = atapiId.StreamTransferTimeDMA; - report.ATAPI.StreamTransferTimeDMASpecified = true; - } - if(atapiId.StreamTransferTimePIO != 0) - { - report.ATAPI.StreamTransferTimePIO = atapiId.StreamTransferTimePIO; - report.ATAPI.StreamTransferTimePIOSpecified = true; - } - if(atapiId.TransportMajorVersion != 0) - { - report.ATAPI.TransportMajorVersion = atapiId.TransportMajorVersion; - report.ATAPI.TransportMajorVersionSpecified = true; - } - if(atapiId.TransportMinorVersion != 0) - { - report.ATAPI.TransportMinorVersion = atapiId.TransportMinorVersion; - report.ATAPI.TransportMinorVersionSpecified = true; - } - if(atapiId.TrustedComputing != 0) - { - report.ATAPI.TrustedComputing = atapiId.TrustedComputing; - report.ATAPI.TrustedComputingSpecified = true; - } - if(atapiId.UDMAActive != 0) - { - report.ATAPI.UDMAActive = atapiId.UDMAActive; - report.ATAPI.UDMAActiveSpecified = true; - } - if(atapiId.UDMASupported != 0) - { - report.ATAPI.UDMASupported = atapiId.UDMASupported; - report.ATAPI.UDMASupportedSpecified = true; - } - if(atapiId.WRVMode != 0) - { - report.ATAPI.WRVMode = atapiId.WRVMode; - report.ATAPI.WRVModeSpecified = true; - } - if(atapiId.WRVSectorCountMode3 != 0) - { - report.ATAPI.WRVSectorCountMode3 = atapiId.WRVSectorCountMode3; - report.ATAPI.WRVSectorCountMode3Specified = true; - } - if(atapiId.WRVSectorCountMode2 != 0) - { - report.ATAPI.WRVSectorCountMode2 = atapiId.WRVSectorCountMode2; - report.ATAPI.WRVSectorCountMode2Specified = true; + if(!string.IsNullOrWhiteSpace(atapiId.AdditionalPID)) + { + report.ATAPI.AdditionalPID = atapiId.AdditionalPID; + report.ATAPI.AdditionalPIDSpecified = true; + } + if(atapiId.APIOSupported != 0) + { + report.ATAPI.APIOSupported = atapiId.APIOSupported; + report.ATAPI.APIOSupportedSpecified = true; + } + if(atapiId.ATAPIByteCount != 0) + { + report.ATAPI.ATAPIByteCount = atapiId.ATAPIByteCount; + report.ATAPI.ATAPIByteCountSpecified = true; + } + if(atapiId.BufferType != 0) + { + report.ATAPI.BufferType = atapiId.BufferType; + report.ATAPI.BufferTypeSpecified = true; + } + if(atapiId.BufferSize != 0) + { + report.ATAPI.BufferSize = atapiId.BufferSize; + report.ATAPI.BufferSizeSpecified = true; + } + if(atapiId.Capabilities != 0) + { + report.ATAPI.Capabilities = atapiId.Capabilities; + report.ATAPI.CapabilitiesSpecified = true; + } + if(atapiId.Capabilities2 != 0) + { + report.ATAPI.Capabilities2 = atapiId.Capabilities2; + report.ATAPI.Capabilities2Specified = true; + } + if(atapiId.Capabilities3 != 0) + { + report.ATAPI.Capabilities3 = atapiId.Capabilities3; + report.ATAPI.Capabilities3Specified = true; + } + if(atapiId.CFAPowerMode != 0) + { + report.ATAPI.CFAPowerMode = atapiId.CFAPowerMode; + report.ATAPI.CFAPowerModeSpecified = true; + } + if(atapiId.CommandSet != 0) + { + report.ATAPI.CommandSet = atapiId.CommandSet; + report.ATAPI.CommandSetSpecified = true; + } + if(atapiId.CommandSet2 != 0) + { + report.ATAPI.CommandSet2 = atapiId.CommandSet2; + report.ATAPI.CommandSet2Specified = true; + } + if(atapiId.CommandSet3 != 0) + { + report.ATAPI.CommandSet3 = atapiId.CommandSet3; + report.ATAPI.CommandSet3Specified = true; + } + if(atapiId.CommandSet4 != 0) + { + report.ATAPI.CommandSet4 = atapiId.CommandSet4; + report.ATAPI.CommandSet4Specified = true; + } + if(atapiId.CommandSet5 != 0) + { + report.ATAPI.CommandSet5 = atapiId.CommandSet5; + report.ATAPI.CommandSet5Specified = true; + } + if(atapiId.CurrentAAM != 0) + { + report.ATAPI.CurrentAAM = atapiId.CurrentAAM; + report.ATAPI.CurrentAAMSpecified = true; + } + if(atapiId.CurrentAPM != 0) + { + report.ATAPI.CurrentAPM = atapiId.CurrentAPM; + report.ATAPI.CurrentAPMSpecified = true; + } + if(atapiId.DataSetMgmt != 0) + { + report.ATAPI.DataSetMgmt = atapiId.DataSetMgmt; + report.ATAPI.DataSetMgmtSpecified = true; + } + if(atapiId.DataSetMgmtSize != 0) + { + report.ATAPI.DataSetMgmtSize = atapiId.DataSetMgmtSize; + report.ATAPI.DataSetMgmtSizeSpecified = true; + } + if(atapiId.DeviceFormFactor != 0) + { + report.ATAPI.DeviceFormFactor = atapiId.DeviceFormFactor; + report.ATAPI.DeviceFormFactorSpecified = true; + } + if(atapiId.DMAActive != 0) + { + report.ATAPI.DMAActive = atapiId.DMAActive; + report.ATAPI.DMAActiveSpecified = true; + } + if(atapiId.DMASupported != 0) + { + report.ATAPI.DMASupported = atapiId.DMASupported; + report.ATAPI.DMASupportedSpecified = true; + } + if(atapiId.DMATransferTimingMode != 0) + { + report.ATAPI.DMATransferTimingMode = atapiId.DMATransferTimingMode; + report.ATAPI.DMATransferTimingModeSpecified = true; + } + if(atapiId.EnhancedSecurityEraseTime != 0) + { + report.ATAPI.EnhancedSecurityEraseTime = atapiId.EnhancedSecurityEraseTime; + report.ATAPI.EnhancedSecurityEraseTimeSpecified = true; + } + if(atapiId.EnabledCommandSet != 0) + { + report.ATAPI.EnabledCommandSet = atapiId.EnabledCommandSet; + report.ATAPI.EnabledCommandSetSpecified = true; + } + if(atapiId.EnabledCommandSet2 != 0) + { + report.ATAPI.EnabledCommandSet2 = atapiId.EnabledCommandSet2; + report.ATAPI.EnabledCommandSet2Specified = true; + } + if(atapiId.EnabledCommandSet3 != 0) + { + report.ATAPI.EnabledCommandSet3 = atapiId.EnabledCommandSet3; + report.ATAPI.EnabledCommandSet3Specified = true; + } + if(atapiId.EnabledCommandSet4 != 0) + { + report.ATAPI.EnabledCommandSet4 = atapiId.EnabledCommandSet4; + report.ATAPI.EnabledCommandSet4Specified = true; + } + if(atapiId.EnabledSATAFeatures != 0) + { + report.ATAPI.EnabledSATAFeatures = atapiId.EnabledSATAFeatures; + report.ATAPI.EnabledSATAFeaturesSpecified = true; + } + if(atapiId.ExtendedUserSectors != 0) + { + report.ATAPI.ExtendedUserSectors = atapiId.ExtendedUserSectors; + report.ATAPI.ExtendedUserSectorsSpecified = true; + } + if(atapiId.FreeFallSensitivity != 0) + { + report.ATAPI.FreeFallSensitivity = atapiId.FreeFallSensitivity; + report.ATAPI.FreeFallSensitivitySpecified = true; + } + if(!string.IsNullOrWhiteSpace(atapiId.FirmwareRevision)) + { + report.ATAPI.FirmwareRevision = atapiId.FirmwareRevision; + report.ATAPI.FirmwareRevisionSpecified = true; + } + if(atapiId.GeneralConfiguration != 0) + { + report.ATAPI.GeneralConfiguration = atapiId.GeneralConfiguration; + report.ATAPI.GeneralConfigurationSpecified = true; + } + if(atapiId.HardwareResetResult != 0) + { + report.ATAPI.HardwareResetResult = atapiId.HardwareResetResult; + report.ATAPI.HardwareResetResultSpecified = true; + } + if(atapiId.InterseekDelay != 0) + { + report.ATAPI.InterseekDelay = atapiId.InterseekDelay; + report.ATAPI.InterseekDelaySpecified = true; + } + if(atapiId.MajorVersion != 0) + { + report.ATAPI.MajorVersion = atapiId.MajorVersion; + report.ATAPI.MajorVersionSpecified = true; + } + if(atapiId.MasterPasswordRevisionCode != 0) + { + report.ATAPI.MasterPasswordRevisionCode = atapiId.MasterPasswordRevisionCode; + report.ATAPI.MasterPasswordRevisionCodeSpecified = true; + } + if(atapiId.MaxDownloadMicroMode3 != 0) + { + report.ATAPI.MaxDownloadMicroMode3 = atapiId.MaxDownloadMicroMode3; + report.ATAPI.MaxDownloadMicroMode3Specified = true; + } + if(atapiId.MaxQueueDepth != 0) + { + report.ATAPI.MaxQueueDepth = atapiId.MaxQueueDepth; + report.ATAPI.MaxQueueDepthSpecified = true; + } + if(atapiId.MDMAActive != 0) + { + report.ATAPI.MDMAActive = atapiId.MDMAActive; + report.ATAPI.MDMAActiveSpecified = true; + } + if(atapiId.MDMASupported != 0) + { + report.ATAPI.MDMASupported = atapiId.MDMASupported; + report.ATAPI.MDMASupportedSpecified = true; + } + if(atapiId.MinDownloadMicroMode3 != 0) + { + report.ATAPI.MinDownloadMicroMode3 = atapiId.MinDownloadMicroMode3; + report.ATAPI.MinDownloadMicroMode3Specified = true; + } + if(atapiId.MinMDMACycleTime != 0) + { + report.ATAPI.MinMDMACycleTime = atapiId.MinMDMACycleTime; + report.ATAPI.MinMDMACycleTimeSpecified = true; + } + if(atapiId.MinorVersion != 0) + { + report.ATAPI.MinorVersion = atapiId.MinorVersion; + report.ATAPI.MinorVersionSpecified = true; + } + if(atapiId.MinPIOCycleTimeNoFlow != 0) + { + report.ATAPI.MinPIOCycleTimeNoFlow = atapiId.MinPIOCycleTimeNoFlow; + report.ATAPI.MinPIOCycleTimeNoFlowSpecified = true; + } + if(atapiId.MinPIOCycleTimeFlow != 0) + { + report.ATAPI.MinPIOCycleTimeFlow = atapiId.MinPIOCycleTimeFlow; + report.ATAPI.MinPIOCycleTimeFlowSpecified = true; + } + if(!string.IsNullOrWhiteSpace(atapiId.Model)) + { + report.ATAPI.Model = atapiId.Model; + report.ATAPI.ModelSpecified = true; + } + if(atapiId.MultipleMaxSectors != 0) + { + report.ATAPI.MultipleMaxSectors = atapiId.MultipleMaxSectors; + report.ATAPI.MultipleMaxSectorsSpecified = true; + } + if(atapiId.MultipleSectorNumber != 0) + { + report.ATAPI.MultipleSectorNumber = atapiId.MultipleSectorNumber; + report.ATAPI.MultipleSectorNumberSpecified = true; + } + if(atapiId.NVCacheCaps != 0) + { + report.ATAPI.NVCacheCaps = atapiId.NVCacheCaps; + report.ATAPI.NVCacheCapsSpecified = true; + } + if(atapiId.NVCacheSize != 0) + { + report.ATAPI.NVCacheSize = atapiId.NVCacheSize; + report.ATAPI.NVCacheSizeSpecified = true; + } + if(atapiId.NVCacheWriteSpeed != 0) + { + report.ATAPI.NVCacheWriteSpeed = atapiId.NVCacheWriteSpeed; + report.ATAPI.NVCacheWriteSpeedSpecified = true; + } + if(atapiId.NVEstimatedSpinUp != 0) + { + report.ATAPI.NVEstimatedSpinUp = atapiId.NVEstimatedSpinUp; + report.ATAPI.NVEstimatedSpinUpSpecified = true; + } + if(atapiId.PacketBusRelease != 0) + { + report.ATAPI.PacketBusRelease = atapiId.PacketBusRelease; + report.ATAPI.PacketBusReleaseSpecified = true; + } + if(atapiId.PIOTransferTimingMode != 0) + { + report.ATAPI.PIOTransferTimingMode = atapiId.PIOTransferTimingMode; + report.ATAPI.PIOTransferTimingModeSpecified = true; + } + if(atapiId.RecommendedAAM != 0) + { + report.ATAPI.RecommendedAAM = atapiId.RecommendedAAM; + report.ATAPI.RecommendedAAMSpecified = true; + } + if(atapiId.RecMDMACycleTime != 0) + { + report.ATAPI.RecommendedMDMACycleTime = atapiId.RecMDMACycleTime; + report.ATAPI.RecommendedMDMACycleTimeSpecified = true; + } + if(atapiId.RemovableStatusSet != 0) + { + report.ATAPI.RemovableStatusSet = atapiId.RemovableStatusSet; + report.ATAPI.RemovableStatusSetSpecified = true; + } + if(atapiId.SATACapabilities != 0) + { + report.ATAPI.SATACapabilities = atapiId.SATACapabilities; + report.ATAPI.SATACapabilitiesSpecified = true; + } + if(atapiId.SATACapabilities2 != 0) + { + report.ATAPI.SATACapabilities2 = atapiId.SATACapabilities2; + report.ATAPI.SATACapabilities2Specified = true; + } + if(atapiId.SATAFeatures != 0) + { + report.ATAPI.SATAFeatures = atapiId.SATAFeatures; + report.ATAPI.SATAFeaturesSpecified = true; + } + if(atapiId.SCTCommandTransport != 0) + { + report.ATAPI.SCTCommandTransport = atapiId.SCTCommandTransport; + report.ATAPI.SCTCommandTransportSpecified = true; + } + if(atapiId.SectorsPerCard != 0) + { + report.ATAPI.SectorsPerCard = atapiId.SectorsPerCard; + report.ATAPI.SectorsPerCardSpecified = true; + } + if(atapiId.SecurityEraseTime != 0) + { + report.ATAPI.SecurityEraseTime = atapiId.SecurityEraseTime; + report.ATAPI.SecurityEraseTimeSpecified = true; + } + if(atapiId.SecurityStatus != 0) + { + report.ATAPI.SecurityStatus = atapiId.SecurityStatus; + report.ATAPI.SecurityStatusSpecified = true; + } + if(atapiId.ServiceBusyClear != 0) + { + report.ATAPI.ServiceBusyClear = atapiId.ServiceBusyClear; + report.ATAPI.ServiceBusyClearSpecified = true; + } + if(atapiId.SpecificConfiguration != 0) + { + report.ATAPI.SpecificConfiguration = atapiId.SpecificConfiguration; + report.ATAPI.SpecificConfigurationSpecified = true; + } + if(atapiId.StreamAccessLatency != 0) + { + report.ATAPI.StreamAccessLatency = atapiId.StreamAccessLatency; + report.ATAPI.StreamAccessLatencySpecified = true; + } + if(atapiId.StreamMinReqSize != 0) + { + report.ATAPI.StreamMinReqSize = atapiId.StreamMinReqSize; + report.ATAPI.StreamMinReqSizeSpecified = true; + } + if(atapiId.StreamPerformanceGranularity != 0) + { + report.ATAPI.StreamPerformanceGranularity = atapiId.StreamPerformanceGranularity; + report.ATAPI.StreamPerformanceGranularitySpecified = true; + } + if(atapiId.StreamTransferTimeDMA != 0) + { + report.ATAPI.StreamTransferTimeDMA = atapiId.StreamTransferTimeDMA; + report.ATAPI.StreamTransferTimeDMASpecified = true; + } + if(atapiId.StreamTransferTimePIO != 0) + { + report.ATAPI.StreamTransferTimePIO = atapiId.StreamTransferTimePIO; + report.ATAPI.StreamTransferTimePIOSpecified = true; + } + if(atapiId.TransportMajorVersion != 0) + { + report.ATAPI.TransportMajorVersion = atapiId.TransportMajorVersion; + report.ATAPI.TransportMajorVersionSpecified = true; + } + if(atapiId.TransportMinorVersion != 0) + { + report.ATAPI.TransportMinorVersion = atapiId.TransportMinorVersion; + report.ATAPI.TransportMinorVersionSpecified = true; + } + if(atapiId.TrustedComputing != 0) + { + report.ATAPI.TrustedComputing = atapiId.TrustedComputing; + report.ATAPI.TrustedComputingSpecified = true; + } + if(atapiId.UDMAActive != 0) + { + report.ATAPI.UDMAActive = atapiId.UDMAActive; + report.ATAPI.UDMAActiveSpecified = true; + } + if(atapiId.UDMASupported != 0) + { + report.ATAPI.UDMASupported = atapiId.UDMASupported; + report.ATAPI.UDMASupportedSpecified = true; + } + if(atapiId.WRVMode != 0) + { + report.ATAPI.WRVMode = atapiId.WRVMode; + report.ATAPI.WRVModeSpecified = true; + } + if(atapiId.WRVSectorCountMode3 != 0) + { + report.ATAPI.WRVSectorCountMode3 = atapiId.WRVSectorCountMode3; + report.ATAPI.WRVSectorCountMode3Specified = true; + } + if(atapiId.WRVSectorCountMode2 != 0) + { + report.ATAPI.WRVSectorCountMode2 = atapiId.WRVSectorCountMode2; + report.ATAPI.WRVSectorCountMode2Specified = true; + } } if(debug) report.ATAPI.Identify = buffer; } diff --git a/DiscImageChef.Core/Devices/Scanning/ATA.cs b/DiscImageChef.Core/Devices/Scanning/ATA.cs index f9841c6d8..726abadaa 100644 --- a/DiscImageChef.Core/Devices/Scanning/ATA.cs +++ b/DiscImageChef.Core/Devices/Scanning/ATA.cs @@ -58,8 +58,6 @@ namespace DiscImageChef.Core.Devices.Scanning sense = dev.AtaIdentify(out cmdBuf, out errorChs); if(!sense && Identify.Decode(cmdBuf).HasValue) { - Identify.IdentifyDevice ataId = Identify.Decode(cmdBuf).Value; - // Initializate reader Reader ataReader = new Reader(dev, timeout, cmdBuf); // Fill reader blocks