diff --git a/CICMMetadata b/CICMMetadata
index 6e069672..ab5967fc 160000
--- a/CICMMetadata
+++ b/CICMMetadata
@@ -1 +1 @@
-Subproject commit 6e069672873883a22e45bcca15ea2a2c792d31e7
+Subproject commit ab5967fcfff5c05ce34c66a5a530ce394aac6276
diff --git a/DiscImageChef.CommonTypes/DiscImageChef.CommonTypes.csproj b/DiscImageChef.CommonTypes/DiscImageChef.CommonTypes.csproj
index 19f4a6ab..0aa63206 100644
--- a/DiscImageChef.CommonTypes/DiscImageChef.CommonTypes.csproj
+++ b/DiscImageChef.CommonTypes/DiscImageChef.CommonTypes.csproj
@@ -36,6 +36,7 @@
+
\ No newline at end of file
diff --git a/DiscImageChef.CommonTypes/MediaType.cs b/DiscImageChef.CommonTypes/MediaType.cs
index 723645a1..217d2634 100644
--- a/DiscImageChef.CommonTypes/MediaType.cs
+++ b/DiscImageChef.CommonTypes/MediaType.cs
@@ -184,9 +184,12 @@ namespace DiscImageChef.CommonTypes
#endregion MiniDisc based
#region Plasmon UDO
- /// Ultra Density Optical
+ /// 5.25", Phase-Change, 1834348 sectors, 8192 bytes/sector, Ultra Density Optical, ECMA-350, ISO 17345
UDO,
+ /// 5.25", Phase-Change, 3669724 sectors, 8192 bytes/sector, Ultra Density Optical 2, ECMA-380, ISO 11976
UDO2,
+ /// 5.25", Write-Once, 3668759 sectors, 8192 bytes/sector, Ultra Density Optical 2, ECMA-380, ISO 11976
+ UDO2_WORM,
#endregion Plasmon UDO
#region Sony game media
@@ -399,18 +402,6 @@ namespace DiscImageChef.CommonTypes
ECMA_78,
/// 5,25", DS, DD, 80 tracks, 9 spt, 512 bytes/sector, FM
ECMA_78_2,
- /// 3,5", M.O., 250000 sectors, 512 bytes/sector
- ECMA_154,
- /// 5,25", M.O., 940470 sectors, 512 bytes/sector
- ECMA_183_512,
- /// 5,25", M.O., 520902 sectors, 1024 bytes/sector
- ECMA_183_1024,
- /// 5,25", M.O., 1165600 sectors, 512 bytes/sector
- ECMA_184_512,
- /// 5,25", M.O., 639200 sectors, 1024 bytes/sector
- ECMA_184_1024,
- /// 3,5", M.O., 448500 sectors, 512 bytes/sector
- ECMA_201,
#endregion ECMA floppy standards
#region FDFORMAT, non-standard floppy formats
@@ -449,7 +440,6 @@ namespace DiscImageChef.CommonTypes
#region Iomega
Bernoulli,
Bernoulli2,
- DataPlay,
Ditto,
DittoMax,
Jaz,
@@ -501,7 +491,9 @@ namespace DiscImageChef.CommonTypes
#region Exatape
Exatape15m,
+ Exatape22m,
Exatape22mAME,
+ Exatape28m,
Exatape40m,
Exatape45m,
Exatape54m,
@@ -509,7 +501,7 @@ namespace DiscImageChef.CommonTypes
Exatape76m,
Exatape80m,
Exatape106m,
- Exatape106mXL,
+ Exatape160mXL,
Exatape112m,
Exatape125m,
Exatape150m,
@@ -540,6 +532,7 @@ namespace DiscImageChef.CommonTypes
SQ800,
SQ1500,
SQ2000,
+ SyJet,
#endregion SyQuest
#region Nintendo
@@ -679,9 +672,64 @@ namespace DiscImageChef.CommonTypes
VXA3,
#endregion VXA
+ #region Magneto-optical
+ /// 5,25", M.O., ??? sectors, 1024 bytes/sector, ECMA-153, ISO 11560
+ ECMA_153,
+ /// 5,25", M.O., ??? sectors, 512 bytes/sector, ECMA-153, ISO 11560
+ ECMA_153_512,
+ /// 3,5", M.O., 249850 sectors, 512 bytes/sector, ECMA-154, ISO 10090
+ ECMA_154,
+ /// 5,25", M.O., 904995 sectors, 512 bytes/sector, ECMA-183, ISO 13481
+ ECMA_183_512,
+ /// 5,25", M.O., 498526 sectors, 1024 bytes/sector, ECMA-183, ISO 13481
+ ECMA_183,
+ /// 5,25", M.O., 1128772 or 1163337 sectors, 512 bytes/sector, ECMA-183, ISO 13549
+ ECMA_184_512,
+ /// 5,25", M.O., 603466 or 637041 sectors, 1024 bytes/sector, ECMA-183, ISO 13549
+ ECMA_184,
+ /// 300mm, M.O., ??? sectors, 1024 bytes/sector, ECMA-189, ISO 13614
+ ECMA_189,
+ /// 300mm, M.O., ??? sectors, 1024 bytes/sector, ECMA-190, ISO 13403
+ ECMA_190,
+ /// 5,25", M.O., 936921 or 948770 sectors, 1024 bytes/sector, ECMA-195, ISO 13842
+ ECMA_195,
+ /// 5,25", M.O., 1644581 or 1647371 sectors, 512 bytes/sector, ECMA-195, ISO 13842
+ ECMA_195_512,
+ /// 3,5", M.O., 446325 sectors, 512 bytes/sector, ECMA-201, ISO 13963
+ ECMA_201,
+ /// 3,5", M.O., 429975 sectors, 512 bytes/sector, embossed, ISO 13963
+ ECMA_201_ROM,
+ /// 3,5", M.O., 371371 sectors, 1024 bytes/sector, ECMA-223
+ ECMA_223,
+ /// 3,5", M.O., 694929 sectors, 512 bytes/sector, ECMA-223
+ ECMA_223_512,
+ /// 5,25", M.O., 1244621 sectors, 1024 bytes/sector, ECMA-238, ISO 15486
+ ECMA_238,
+ /// 3,5", M.O., 318988, 320332 or 321100 sectors, 2048 bytes/sector, ECMA-239, ISO 15498
+ ECMA_239,
+ /// 356mm, M.O., 14476734 sectors, 1024 bytes/sector, ECMA-260, ISO 15898
+ ECMA_260,
+ /// 356mm, M.O., 24445990 sectors, 1024 bytes/sector, ECMA-260, ISO 15898
+ ECMA_260_Double,
+ /// 5,25", M.O., 1128134 sectors, 2048 bytes/sector, ECMA-280, ISO 18093
+ ECMA_280,
+ /// 300mm, M.O., 7355716 sectors, 2048 bytes/sector, ECMA-317, ISO 20162
+ ECMA_317,
+ /// 5,25", M.O., 1095840 sectors, 4096 bytes/sector, ECMA-322, ISO 22092
+ ECMA_322,
+ /// 5,25", M.O., 2043664 sectors, 2048 bytes/sector, ECMA-322, ISO 22092
+ ECMA_322_2k,
+ /// 3,5", M.O., 605846 sectors, 2048 bytes/sector, Cherry Book, GigaMo, ECMA-351, ISO 17346
+ GigaMo,
+ /// 3,5", M.O., 1063146 sectors, 2048 bytes/sector, Cherry Book 2, GigaMo 2, ECMA-353, ISO 22533
+ GigaMo2,
+ UnknownMO,
+ #endregion Magneto-optical
+
#region Other floppy standards
CompactFloppy,
DemiDiskette,
+ /// 3.5", 652 tracks, 2 sides, 512 bytes/sector, Floptical, ECMA-207, ISO 14169
Floptical,
HiFD,
LS120,
@@ -713,13 +761,23 @@ namespace DiscImageChef.CommonTypes
SmartMedia,
xD,
XQD,
+ DataPlay,
+ /// 120mm, Phase-Change, 1298496 sectors, 512 bytes/sector, PD650, ECMA-240, ISO 15485
+ PD650,
+ /// 120mm, Write-Once, 1281856 sectors, 512 bytes/sector, PD650, ECMA-240, ISO 15485
+ PD650_WORM,
#endregion Miscellaneous
#region Generic hard disks
Microdrive,
RDX,
- GENERIC_HDD
+ /// Imation 320Gb RDX
+ RDX320,
+ GENERIC_HDD,
+ Zone_HDD,
+ // USB flash drives
+ FlashDrive
#endregion Generic hard disks
};
}
-
+
\ No newline at end of file
diff --git a/DiscImageChef.CommonTypes/MediaTypeFromSCSI.cs b/DiscImageChef.CommonTypes/MediaTypeFromSCSI.cs
new file mode 100644
index 00000000..5687a49a
--- /dev/null
+++ b/DiscImageChef.CommonTypes/MediaTypeFromSCSI.cs
@@ -0,0 +1,1621 @@
+// /***************************************************************************
+// The Disc Image Chef
+// ----------------------------------------------------------------------------
+//
+// Filename : MediaTypeFromSCSI.cs
+// Version : 1.0
+// Author(s) : Natalia Portillo
+//
+// Component : Component
+//
+// Revision : $Revision$
+// Last change by : $Author$
+// Date : $Date$
+//
+// --[ Description ] ----------------------------------------------------------
+//
+// Description
+//
+// --[ License ] --------------------------------------------------------------
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+//
+// ----------------------------------------------------------------------------
+// Copyright (C) 2011-2015 Claunia.com
+// ****************************************************************************/
+// //$Id$
+
+namespace DiscImageChef.CommonTypes
+{
+ public static class MediaTypeFromSCSI
+ {
+ public static MediaType Get(byte scsiPeripheralType, string vendor, string model, byte mediumType, byte densityCode, ulong blocks, uint blockSize)
+ {
+ switch (scsiPeripheralType)
+ {
+ // Direct access device
+ case 0x00:
+ // Simpilified access device
+ case 0x0E:
+ {
+ if (mediumType == 0x03 || mediumType == 0x05 || mediumType == 0x07)
+ {
+ goto case 0x07;
+ }
+
+ if (vendor.ToLowerInvariant() == "syquest")
+ {
+ if (blocks == 173400 && blockSize == 256)
+ return MediaType.SQ400;
+ if (blockSize == 512)
+ {
+ if (model.ToLowerInvariant().StartsWith("syjet"))
+ return MediaType.SyJet;
+
+ switch (blocks)
+ {
+ case 262144:
+ return MediaType.EZ135;
+ case 524288:
+ return MediaType.SQ327;
+ }
+ }
+
+ return MediaType.Unknown;
+ }
+
+ if (model.ToLowerInvariant().StartsWith("zip"))
+ {
+ if (blockSize == 512)
+ {
+ if (blocks == 196608)
+ return MediaType.ZIP100;
+ if (blocks == 489532)
+ return MediaType.ZIP250;
+ return MediaType.ZIP750;
+ }
+
+ return MediaType.Unknown;
+ }
+
+ if (model.ToLowerInvariant().StartsWith("jaz"))
+ {
+ if (blockSize == 512)
+ {
+ if (blocks == 2091050)
+ return MediaType.Jaz;
+ if (blocks == 3915600)
+ return MediaType.Jaz2;
+ }
+
+ return MediaType.Unknown;
+ }
+
+ if (model.ToLowerInvariant().StartsWith("ls-"))
+ {
+ if (blockSize == 512)
+ {
+ if (blocks == 246528)
+ return MediaType.LS120;
+ if (blocks == 2880)
+ return MediaType.DOS_35_HD;
+ if (blocks == 1440)
+ return MediaType.DOS_35_DS_DD_9;
+ }
+
+ return MediaType.Unknown;
+ }
+
+ if (model.ToLowerInvariant().StartsWith("rdx"))
+ {
+ if (blockSize == 512)
+ {
+ if (blocks == 625134256)
+ return MediaType.RDX320;
+ return MediaType.RDX;
+ }
+
+ return MediaType.Unknown;
+ }
+
+ switch (mediumType)
+ {
+ case 0x01:
+ switch (blockSize)
+ {
+ case 128:
+ switch (blocks)
+ {
+ case 720:
+ return MediaType.ATARI_525_SD;
+ case 1040:
+ return MediaType.ATARI_525_DD;
+ case 1898:
+ return MediaType.IBM33FD_128;
+ case 2002:
+ return MediaType.ECMA_54;
+ }
+ break;
+ case 256:
+ switch (blocks)
+ {
+ case 322:
+ return MediaType.ECMA_66;
+ case 400:
+ return MediaType.ACORN_525_SS_SD_40;
+ case 455:
+ return MediaType.Apple32SS;
+ case 560:
+ return MediaType.Apple33SS;
+ case 640:
+ return MediaType.ACORN_525_SS_DD_40;
+ case 720:
+ return MediaType.ATARI_525_DD;
+ case 800:
+ return MediaType.ACORN_525_SS_SD_80;
+ case 1121:
+ return MediaType.IBM33FD_256;
+ case 1280:
+ return MediaType.ACORN_525_SS_DD_80;
+ case 2002:
+ return MediaType.RX02;
+ }
+ break;
+ case 319:
+ switch (blocks)
+ {
+ case 256:
+ return MediaType.IBM23FD;
+ }
+ break;
+ case 512:
+ switch (blocks)
+ {
+ case 320:
+ return MediaType.DOS_525_DS_DD_8;
+ case 360:
+ return MediaType.DOS_35_SS_DD_9;
+ case 610:
+ return MediaType.IBM33FD_512;
+ case 640:
+ return MediaType.DOS_35_SS_DD_8;
+ case 720:
+ return MediaType.DOS_35_DS_DD_9;
+ case 800:
+ return MediaType.AppleSonySS;
+ case 249850:
+ return MediaType.ECMA_154;
+ case 429975:
+ return MediaType.ECMA_201_ROM;
+ case 446325:
+ return MediaType.ECMA_201;
+ case 694929:
+ return MediaType.ECMA_223_512;
+ case 904995:
+ return MediaType.ECMA_183_512;
+ case 1128772:
+ case 1163337:
+ return MediaType.ECMA_184_512;
+ case 1281856:
+ return MediaType.PD650_WORM;
+ case 1298496:
+ return MediaType.PD650;
+ case 1644581:
+ case 1647371:
+ return MediaType.ECMA_195_512;
+ }
+ break;
+ case 1024:
+ {
+ switch (blocks)
+ {
+ case 371371:
+ return MediaType.ECMA_223;
+ case 498526:
+ return MediaType.ECMA_183;
+ case 603466:
+ case 637041:
+ return MediaType.ECMA_184;
+ case 936921:
+ case 948770:
+ return MediaType.ECMA_195;
+ case 1244621:
+ return MediaType.ECMA_238;
+ case 14476734:
+ return MediaType.ECMA_260;
+ case 24445990:
+ return MediaType.ECMA_260_Double;
+ }
+ }
+ break;
+ case 2048:
+ {
+ switch (blocks)
+ {
+ case 318988:
+ case 320332:
+ case 321100:
+ return MediaType.ECMA_239;
+ case 605846:
+ return MediaType.GigaMo;
+ case 1063146:
+ return MediaType.GigaMo2;
+ case 1128134:
+ return MediaType.ECMA_280;
+ case 2043664:
+ return MediaType.ECMA_322_2k;
+ case 7355716:
+ return MediaType.ECMA_317;
+ }
+ }
+ break;
+ case 4096:
+ {
+ switch (blocks)
+ {
+ case 1095840:
+ return MediaType.ECMA_322;
+ }
+ }
+ break;
+ case 8192:
+ {
+ switch (blocks)
+ {
+ case 1834348:
+ return MediaType.UDO;
+ case 3668759:
+ return MediaType.UDO2_WORM;
+ case 3669724:
+ return MediaType.UDO2;
+ }
+ }
+ break;
+ }
+ return MediaType.Unknown;
+ case 0x02:
+ switch (blockSize)
+ {
+ case 128:
+ switch (blocks)
+ {
+ case 3848:
+ return MediaType.IBM43FD_128;
+ case 4004:
+ return MediaType.ECMA_59;
+ }
+ break;
+ case 256:
+ switch (blocks)
+ {
+ case 910:
+ return MediaType.Apple32DS;
+ case 1120:
+ return MediaType.Apple33DS;
+ case 1280:
+ return MediaType.ECMA_70;
+ case 2560:
+ return MediaType.ECMA_78;
+ case 3848:
+ return MediaType.IBM53FD_256;
+ case 4004:
+ return MediaType.ECMA_99_26;
+ }
+ break;
+ case 512:
+ switch (blocks)
+ {
+ case 640:
+ return MediaType.DOS_525_DS_DD_8;
+ case 720:
+ return MediaType.DOS_525_DS_DD_9;
+ case 1280:
+ return MediaType.DOS_35_DS_DD_8;
+ case 1440:
+ return MediaType.ECMA_100;
+ case 1600:
+ return MediaType.ACORN_35_DS_DD;
+ case 1640:
+ return MediaType.FDFORMAT_35_DD;
+ case 1760:
+ return MediaType.CBM_AMIGA_35_DD;
+ case 2242:
+ return MediaType.IBM53FD_512;
+ case 2332:
+ return MediaType.ECMA_99_15;
+ case 2400:
+ return MediaType.DOS_525_HD;
+ case 2788:
+ return MediaType.FDFORMAT_525_HD;
+ case 2880:
+ return MediaType.ECMA_125;
+ case 3360:
+ return MediaType.DMF;
+ case 3444:
+ return MediaType.FDFORMAT_35_HD;
+ case 3520:
+ return MediaType.CBM_AMIGA_35_HD;
+ case 5760:
+ return MediaType.ECMA_147;
+ case 249850:
+ return MediaType.ECMA_154;
+ case 429975:
+ return MediaType.ECMA_201_ROM;
+ case 446325:
+ return MediaType.ECMA_201;
+ case 694929:
+ return MediaType.ECMA_223_512;
+ case 904995:
+ return MediaType.ECMA_183_512;
+ case 1128772:
+ case 1163337:
+ return MediaType.ECMA_184_512;
+ case 1281856:
+ return MediaType.PD650_WORM;
+ case 1298496:
+ return MediaType.PD650;
+ case 1644581:
+ case 1647371:
+ return MediaType.ECMA_195_512;
+ }
+ break;
+ case 1024:
+ switch (blocks)
+ {
+ case 1220:
+ return MediaType.IBM53FD_1024;
+ case 1232:
+ return MediaType.SHARP_35;
+ case 1268:
+ return MediaType.ECMA_69_8;
+ case 1280:
+ return MediaType.NEC_525_HD;
+ case 1316:
+ return MediaType.ECMA_99_8;
+ case 371371:
+ return MediaType.ECMA_223;
+ case 498526:
+ return MediaType.ECMA_183;
+ case 603466:
+ case 637041:
+ return MediaType.ECMA_184;
+ case 936921:
+ case 948770:
+ return MediaType.ECMA_195;
+ case 1244621:
+ return MediaType.ECMA_238;
+ case 14476734:
+ return MediaType.ECMA_260;
+ case 24445990:
+ return MediaType.ECMA_260_Double;
+ }
+ break;
+ case 2048:
+ {
+ switch (blocks)
+ {
+ case 318988:
+ case 320332:
+ case 321100:
+ return MediaType.ECMA_239;
+ case 605846:
+ return MediaType.GigaMo;
+ case 1063146:
+ return MediaType.GigaMo2;
+ case 1128134:
+ return MediaType.ECMA_280;
+ case 2043664:
+ return MediaType.ECMA_322_2k;
+ case 7355716:
+ return MediaType.ECMA_317;
+ }
+ }
+ break;
+ case 4096:
+ {
+ switch (blocks)
+ {
+ case 1095840:
+ return MediaType.ECMA_322;
+ }
+ }
+ break;
+ case 8192:
+ {
+ switch (blocks)
+ {
+ case 1834348:
+ return MediaType.UDO;
+ case 3668759:
+ return MediaType.UDO2_WORM;
+ case 3669724:
+ return MediaType.UDO2;
+ }
+ }
+ break;
+ }
+ return MediaType.Unknown;
+ case 0x09:
+ return MediaType.ECMA_54;
+ case 0x0A:
+ return MediaType.ECMA_59;
+ case 0x0B:
+ switch (blockSize)
+ {
+ case 256:
+ return MediaType.ECMA_69_26;
+ case 512:
+ return MediaType.ECMA_69_15;
+ case 1024:
+ return MediaType.ECMA_69_8;
+ }
+ return MediaType.Unknown;
+ case 0x0E:
+ return MediaType.ECMA_66;
+ case 0x12:
+ return MediaType.ECMA_70;
+ case 0x16:
+ switch (blockSize)
+ {
+ case 256:
+ return MediaType.ECMA_78;
+ case 512:
+ return MediaType.ECMA_78_2;
+ }
+ return MediaType.Unknown;
+ case 0x1A:
+ switch (blockSize)
+ {
+ case 256:
+ return MediaType.ECMA_99_26;
+ case 512:
+ return MediaType.ECMA_99_15;
+ case 1024:
+ return MediaType.ECMA_99_8;
+ }
+ return MediaType.Unknown;
+ case 0x1E:
+ return MediaType.ECMA_100;
+ case 0x93:
+ return MediaType.NEC_35_HD_15;
+ case 0x94:
+ return MediaType.ECMA_125;
+ }
+
+ switch (blockSize)
+ {
+ case 128:
+ {
+ switch (blocks)
+ {
+ case 720:
+ return MediaType.ATARI_525_SD;
+ case 1040:
+ return MediaType.ATARI_525_ED;
+ case 1898:
+ return MediaType.IBM33FD_128;
+ case 2002:
+ return MediaType.ECMA_54;
+ case 3848:
+ return MediaType.IBM43FD_128;
+ case 4004:
+ return MediaType.ECMA_59;
+ }
+ }
+ break;
+ case 256:
+ {
+ switch (blocks)
+ {
+ case 322:
+ return MediaType.ECMA_66;
+ case 400:
+ return MediaType.ACORN_525_SS_SD_40;
+ case 455:
+ return MediaType.Apple32SS;
+ case 560:
+ return MediaType.Apple33SS;
+ case 640:
+ return MediaType.ACORN_525_SS_DD_40;
+ case 720:
+ return MediaType.ATARI_525_DD;
+ case 800:
+ return MediaType.ACORN_525_SS_SD_80;
+ case 910:
+ return MediaType.Apple32DS;
+ case 1120:
+ return MediaType.Apple33DS;
+ case 1121:
+ return MediaType.IBM33FD_256;
+ case 1280:
+ return MediaType.ECMA_70;
+ case 2002:
+ return MediaType.RX02;
+ case 2560:
+ return MediaType.ECMA_78;
+ case 3848:
+ return MediaType.IBM53FD_256;
+ case 4004:
+ return MediaType.ECMA_99_26;
+ }
+ }
+ break;
+ case 319:
+ switch (blocks)
+ {
+ case 256:
+ return MediaType.IBM23FD;
+ }
+ break;
+ case 512:
+ {
+ switch (blocks)
+ {
+ case 320:
+ return MediaType.DOS_525_SS_DD_8;
+ case 360:
+ return MediaType.DOS_525_SS_DD_9;
+ case 610:
+ return MediaType.IBM33FD_512;
+ case 640:
+ return MediaType.DOS_525_DS_DD_8;
+ case 720:
+ return MediaType.DOS_525_DS_DD_9;
+ case 800:
+ return MediaType.AppleSonySS;
+ case 1280:
+ return MediaType.DOS_35_DS_DD_8;
+ case 1440:
+ return MediaType.ECMA_100;
+ case 1600:
+ return MediaType.ACORN_35_DS_DD;
+ case 1640:
+ return MediaType.FDFORMAT_35_DD;
+ case 1760:
+ return MediaType.CBM_AMIGA_35_DD;
+ case 2242:
+ return MediaType.IBM53FD_512;
+ case 2332:
+ return MediaType.ECMA_99_15;
+ case 2400:
+ return MediaType.DOS_525_HD;
+ case 2788:
+ return MediaType.FDFORMAT_525_HD;
+ case 2880:
+ return MediaType.ECMA_125;
+ case 3360:
+ return MediaType.DMF;
+ case 3444:
+ return MediaType.FDFORMAT_35_HD;
+ case 3520:
+ return MediaType.CBM_AMIGA_35_HD;
+ case 5760:
+ return MediaType.ECMA_147;
+ }
+ }
+ break;
+ case 1024:
+ {
+ switch (blocks)
+ {
+ case 1220:
+ return MediaType.IBM53FD_1024;
+ case 1232:
+ return MediaType.SHARP_35;
+ case 1268:
+ return MediaType.ECMA_69_8;
+ case 1280:
+ return MediaType.NEC_525_HD;
+ case 1316:
+ return MediaType.ECMA_99_8;
+ }
+ }
+ break;
+ }
+
+ return MediaType.Unknown;
+ }
+ // Sequential access device
+ case 0x01:
+ {
+ switch (mediumType)
+ {
+ case 0x00:
+ switch (densityCode)
+ {
+ case 0x04:
+ return MediaType.QIC11;
+ case 0x05:
+ return MediaType.QIC24;
+ case 0x09:
+ return MediaType.IBM3490;
+ case 0x0F:
+ return MediaType.QIC120;
+ case 0x10:
+ return MediaType.QIC150;
+ case 0x28:
+ return MediaType.IBM3490E;
+ case 0x40:
+ {
+ if (model.ToLowerInvariant().StartsWith("ult"))
+ return MediaType.LTO;
+ if (model.ToLowerInvariant().StartsWith("sdz"))
+ return MediaType.SAIT1;
+ break;
+ }
+ case 0x41:
+ {
+ if (model.ToLowerInvariant().StartsWith("ult"))
+ return MediaType.LTO2;
+ break;
+ }
+ case 0x42:
+ {
+ if (model.ToLowerInvariant().StartsWith("ult"))
+ return MediaType.LTO2;
+ if (vendor.ToLowerInvariant() == "stk")
+ return MediaType.T9840A;
+ break;
+ }
+ case 0x43:
+ {
+ if (vendor.ToLowerInvariant() == "stk")
+ return MediaType.T9940A;
+ break;
+ }
+ case 0x44:
+ {
+ if (model.ToLowerInvariant().StartsWith("ult"))
+ return MediaType.LTO3;
+ if (vendor.ToLowerInvariant() == "stk")
+ return MediaType.T9940B;
+ break;
+ }
+ case 0x45:
+ {
+ if (vendor.ToLowerInvariant() == "stk")
+ return MediaType.T9840C;
+ break;
+ }
+ case 0x46:
+ {
+ if (model.ToLowerInvariant().StartsWith("ult"))
+ return MediaType.LTO4;
+ if (vendor.ToLowerInvariant() == "stk")
+ return MediaType.T9840D;
+ break;
+ }
+ case 0x4A:
+ {
+ if (vendor.ToLowerInvariant() == "stk")
+ return MediaType.T10000A;
+ break;
+ }
+ case 0x4B:
+ {
+ if (vendor.ToLowerInvariant() == "stk")
+ return MediaType.T10000B;
+ break;
+ }
+ case 0x4C:
+ {
+ if (vendor.ToLowerInvariant() == "stk")
+ return MediaType.T10000C;
+ break;
+ }
+ case 0x4D:
+ {
+ if (vendor.ToLowerInvariant() == "stk")
+ return MediaType.T10000D;
+ break;
+ }
+ case 0x58:
+ {
+ if (model.ToLowerInvariant().StartsWith("ult"))
+ return MediaType.LTO5;
+ break;
+ }
+ }
+ break;
+ case 0x01:
+ {
+ switch (densityCode)
+ {
+ case 0x44:
+ {
+ if (model.ToLowerInvariant().StartsWith("ult"))
+ return MediaType.LTO3WORM;
+ break;
+ }
+ case 0x46:
+ {
+ if (model.ToLowerInvariant().StartsWith("ult"))
+ return MediaType.LTO4WORM;
+ break;
+ }
+ case 0x58:
+ {
+ if (model.ToLowerInvariant().StartsWith("ult"))
+ return MediaType.LTO5WORM;
+ break;
+ }
+ }
+ }
+ break;
+ case 0x18:
+ {
+ switch (densityCode)
+ {
+ case 0x00:
+ case 0x40:
+ {
+ {
+ if (model.ToLowerInvariant().StartsWith("ult"))
+ return MediaType.LTO;
+ break;
+ }
+ }
+ }
+ }
+ break;
+ case 0x28:
+ {
+ switch (densityCode)
+ {
+ case 0x00:
+ case 0x42:
+ {
+ if (model.ToLowerInvariant().StartsWith("ult"))
+ return MediaType.LTO2;
+ break;
+ }
+ }
+ }
+ break;
+ case 0x33:
+ {
+ switch (densityCode)
+ {
+ case 0x00:
+ case 0x25:
+ {
+ if (model.ToLowerInvariant().StartsWith("dat"))
+ return MediaType.DDS3;
+ break;
+ }
+ }
+ }
+ break;
+ case 0x34:
+ {
+ switch (densityCode)
+ {
+ case 0x00:
+ case 0x26:
+ {
+ if (model.ToLowerInvariant().StartsWith("dat"))
+ return MediaType.DDS4;
+ break;
+ }
+ }
+ }
+ break;
+ case 0x35:
+ {
+ switch (densityCode)
+ {
+ case 0x00:
+ case 0x47:
+ {
+ if (model.ToLowerInvariant().StartsWith("dat"))
+ return MediaType.DAT72;
+ break;
+ }
+ }
+ }
+ break;
+ case 0x38:
+ {
+ switch (densityCode)
+ {
+ case 0x00:
+ case 0x44:
+ {
+ if (model.ToLowerInvariant().StartsWith("ult"))
+ return MediaType.LTO3;
+ break;
+ }
+ }
+ }
+ break;
+ case 0x3C:
+ {
+ switch (densityCode)
+ {
+ case 0x00:
+ case 0x44:
+ {
+ if (model.ToLowerInvariant().StartsWith("ult"))
+ return MediaType.LTO3WORM;
+ break;
+ }
+ }
+ }
+ break;
+ case 0x48:
+ {
+ switch (densityCode)
+ {
+ case 0x00:
+ case 0x46:
+ {
+ if (model.ToLowerInvariant().StartsWith("ult"))
+ return MediaType.LTO4;
+ break;
+ }
+ }
+ }
+ break;
+ case 0x4C:
+ {
+ switch (densityCode)
+ {
+ case 0x00:
+ case 0x46:
+ {
+ if (model.ToLowerInvariant().StartsWith("ult"))
+ return MediaType.LTO4WORM;
+ break;
+ }
+ }
+ }
+ break;
+ case 0x58:
+ {
+ switch (densityCode)
+ {
+ case 0x00:
+ case 0x58:
+ {
+ if (model.ToLowerInvariant().StartsWith("ult"))
+ return MediaType.LTO5;
+ break;
+ }
+ }
+ }
+ break;
+ case 0x5C:
+ {
+ switch (densityCode)
+ {
+ case 0x00:
+ case 0x58:
+ {
+ if (model.ToLowerInvariant().StartsWith("ult"))
+ return MediaType.LTO5WORM;
+ break;
+ }
+ }
+ }
+ break;
+ case 0x68:
+ {
+ switch (densityCode)
+ {
+ case 0x00:
+ case 0x5A:
+ {
+ if (model.ToLowerInvariant().StartsWith("ult"))
+ return MediaType.LTO6;
+ break;
+ }
+ }
+ }
+ break;
+ case 0x6C:
+ {
+ switch (densityCode)
+ {
+ case 0x00:
+ case 0x5A:
+ {
+ if (model.ToLowerInvariant().StartsWith("ult"))
+ return MediaType.LTO6WORM;
+ break;
+ }
+ }
+ }
+ break;
+ case 0x78:
+ {
+ switch (densityCode)
+ {
+ case 0x00:
+ case 0x5C:
+ {
+ if (model.ToLowerInvariant().StartsWith("ult"))
+ return MediaType.LTO7;
+ break;
+ }
+ }
+ }
+ break;
+ case 0x7C:
+ {
+ switch (densityCode)
+ {
+ case 0x00:
+ case 0x5C:
+ {
+ if (model.ToLowerInvariant().StartsWith("ult"))
+ return MediaType.LTO7WORM;
+ break;
+ }
+ }
+ }
+ break;
+ case 0x81:
+ {
+ switch (densityCode)
+ {
+ case 0x00:
+ {
+ if (model.ToLowerInvariant().StartsWith("exb"))
+ return MediaType.Exatape15m;
+ if (vendor.ToLowerInvariant() == "ibm")
+ return MediaType.IBM3592;
+ if (model.ToLowerInvariant().StartsWith("vxa"))
+ return MediaType.VXA1;
+ break;
+ }
+ case 0x14:
+ case 0x15:
+ case 0x27:
+ case 0x8C:
+ case 0x90:
+ {
+ if (model.ToLowerInvariant().StartsWith("exb"))
+ return MediaType.Exatape15m;
+ break;
+ }
+ case 0x29:
+ case 0x2A:
+ {
+ if (vendor.ToLowerInvariant() == "ibm")
+ return MediaType.IBM3592;
+ break;
+ }
+ case 0x80:
+ {
+ if (model.ToLowerInvariant().StartsWith("vxa"))
+ return MediaType.VXA1;
+ break;
+ }
+ }
+ }
+ break;
+ case 0x82:
+ {
+ switch (densityCode)
+ {
+ case 0x00:
+ {
+ if (model.ToLowerInvariant().StartsWith("exb"))
+ return MediaType.Exatape28m;
+ if (vendor.ToLowerInvariant() == "ibm")
+ return MediaType.IBM3592;
+ break;
+ }
+ case 0x0A:
+ {
+ if (model.ToLowerInvariant().StartsWith("dlt"))
+ return MediaType.CompactTapeI;
+ break;
+ }
+ case 0x14:
+ case 0x15:
+ case 0x27:
+ case 0x8C:
+ case 0x90:
+ {
+ if (model.ToLowerInvariant().StartsWith("exb"))
+ return MediaType.Exatape28m;
+ break;
+ }
+ case 0x16:
+ {
+ if (model.ToLowerInvariant().StartsWith("dlt"))
+ return MediaType.CompactTapeII;
+ break;
+ }
+ case 0x29:
+ case 0x2A:
+ {
+ if (vendor.ToLowerInvariant() == "ibm")
+ return MediaType.IBM3592;
+ break;
+ }
+ case 0x81:
+ {
+ if (model.ToLowerInvariant().StartsWith("vxa"))
+ return MediaType.VXA2;
+ break;
+ }
+ case 0x82:
+ {
+ if (model.ToLowerInvariant().StartsWith("vxa"))
+ return MediaType.VXA3;
+ break;
+ }
+ }
+ }
+ break;
+ case 0x83:
+ {
+ switch (densityCode)
+ {
+ case 0x00:
+ {
+ if (model.ToLowerInvariant().StartsWith("exb"))
+ return MediaType.Exatape54m;
+ if (model.ToLowerInvariant().StartsWith("dlt"))
+ return MediaType.DLTtapeIII;
+ break;
+ }
+ case 0x14:
+ case 0x15:
+ case 0x27:
+ case 0x8C:
+ case 0x90:
+ {
+ if (model.ToLowerInvariant().StartsWith("exb"))
+ return MediaType.Exatape54m;
+ break;
+ }
+ case 0x17:
+ case 0x18:
+ case 0x19:
+ case 0x80:
+ case 0x81:
+ {
+ if (model.ToLowerInvariant().StartsWith("dlt"))
+ return MediaType.DLTtapeIII;
+ break;
+ }
+ }
+ }
+ break;
+ case 0x84:
+ {
+ switch (densityCode)
+ {
+ case 0x00:
+ {
+ if (model.ToLowerInvariant().StartsWith("exb"))
+ return MediaType.Exatape80m;
+ if (model.ToLowerInvariant().StartsWith("dlt"))
+ return MediaType.DLTtapeIIIxt;
+ break;
+ }
+ case 0x14:
+ case 0x15:
+ case 0x27:
+ case 0x8C:
+ case 0x90:
+ {
+ if (model.ToLowerInvariant().StartsWith("exb"))
+ return MediaType.Exatape80m;
+ break;
+ }
+ case 0x19:
+ case 0x80:
+ case 0x81:
+ {
+ if (model.ToLowerInvariant().StartsWith("dlt"))
+ return MediaType.DLTtapeIIIxt;
+ break;
+ }
+ }
+ }
+ break;
+ case 0x85:
+ {
+ switch (densityCode)
+ {
+ case 0x00:
+ {
+ if (model.ToLowerInvariant().StartsWith("exb"))
+ return MediaType.Exatape106m;
+ if (model.ToLowerInvariant().StartsWith("dlt") ||
+ model.ToLowerInvariant().StartsWith("sdlt") ||
+ model.ToLowerInvariant().StartsWith("superdlt"))
+ return MediaType.DLTtapeIV;
+ if (model.ToLowerInvariant().StartsWith("stt"))
+ return MediaType.Travan5;
+ break;
+ }
+ case 0x14:
+ case 0x15:
+ case 0x27:
+ case 0x8C:
+ case 0x90:
+ {
+ if (model.ToLowerInvariant().StartsWith("exb"))
+ return MediaType.Exatape106m;
+ break;
+ }
+ case 0x1A:
+ case 0x1B:
+ case 0x40:
+ case 0x41:
+ case 0x82:
+ case 0x83:
+ case 0x84:
+ case 0x85:
+ case 0x86:
+ case 0x87:
+ case 0x88:
+ case 0x89:
+ {
+ if (model.ToLowerInvariant().StartsWith("dlt") ||
+ model.ToLowerInvariant().StartsWith("sdlt") ||
+ model.ToLowerInvariant().StartsWith("superdlt"))
+ return MediaType.DLTtapeIV;
+ break;
+ }
+ case 0x46:
+ {
+ if (model.ToLowerInvariant().StartsWith("stt"))
+ return MediaType.Travan5;
+ break;
+ }
+ }
+ }
+ break;
+ case 0x86:
+ {
+ switch (densityCode)
+ {
+ case 0x00:
+ case 0x90:
+ {
+ if (model.ToLowerInvariant().StartsWith("exb"))
+ return MediaType.Exatape160mXL;
+ if (model.ToLowerInvariant().StartsWith("dlt") ||
+ model.ToLowerInvariant().StartsWith("sdlt") ||
+ model.ToLowerInvariant().StartsWith("superdlt"))
+ return MediaType.SDLT1;
+ break;
+ }
+ case 0x8C:
+ {
+ if (model.ToLowerInvariant().StartsWith("exb"))
+ return MediaType.Exatape160mXL;
+ break;
+ }
+ case 0x91:
+ case 0x92:
+ case 0x93:
+ {
+ if (model.ToLowerInvariant().StartsWith("dlt") ||
+ model.ToLowerInvariant().StartsWith("sdlt") ||
+ model.ToLowerInvariant().StartsWith("superdlt"))
+ return MediaType.SDLT1;
+ break;
+ }
+ }
+ }
+ break;
+ case 0x87:
+ {
+ switch (densityCode)
+ {
+ case 0x00:
+ case 0x4A:
+ {
+ if (model.ToLowerInvariant().StartsWith("dlt") ||
+ model.ToLowerInvariant().StartsWith("sdlt") ||
+ model.ToLowerInvariant().StartsWith("superdlt"))
+ return MediaType.SDLT2;
+ break;
+ }
+ }
+ }
+ break;
+ case 0x90:
+ {
+ switch (densityCode)
+ {
+ case 0x00:
+ case 0x50:
+ case 0x98:
+ case 0x99:
+ {
+ if (model.ToLowerInvariant().StartsWith("dlt") ||
+ model.ToLowerInvariant().StartsWith("sdlt") ||
+ model.ToLowerInvariant().StartsWith("superdlt"))
+ return MediaType.VStapeI;
+ break;
+ }
+ }
+ }
+ break;
+ case 0x95:
+ {
+ if (model.ToLowerInvariant().StartsWith("stt"))
+ return MediaType.Travan7;
+ }
+ break;
+ case 0xC1:
+ {
+ switch (densityCode)
+ {
+ case 0x00:
+ case 0x14:
+ case 0x15:
+ case 0x8C:
+ case 0x90:
+ {
+ if (model.ToLowerInvariant().StartsWith("exb"))
+ return MediaType.Exatape22m;
+ break;
+ }
+ }
+ }
+ break;
+ case 0xC2:
+ {
+ switch (densityCode)
+ {
+ case 0x00:
+ case 0x14:
+ case 0x15:
+ case 0x27:
+ case 0x8C:
+ case 0x90:
+ {
+ if (model.ToLowerInvariant().StartsWith("exb"))
+ return MediaType.Exatape40m;
+ break;
+ }
+ }
+ }
+ break;
+ case 0xC3:
+ {
+ switch (densityCode)
+ {
+ case 0x00:
+ case 0x14:
+ case 0x15:
+ case 0x27:
+ case 0x8C:
+ case 0x90:
+ {
+ if (model.ToLowerInvariant().StartsWith("exb"))
+ return MediaType.Exatape76m;
+ break;
+ }
+ }
+ }
+ break;
+ case 0xC4:
+ {
+ switch (densityCode)
+ {
+ case 0x00:
+ case 0x14:
+ case 0x15:
+ case 0x27:
+ case 0x8C:
+ case 0x90:
+ {
+ if (model.ToLowerInvariant().StartsWith("exb"))
+ return MediaType.Exatape112m;
+ break;
+ }
+ }
+ }
+ break;
+ case 0xD1:
+ {
+ switch (densityCode)
+ {
+ case 0x00:
+ case 0x27:
+ case 0x28:
+ {
+ if (model.ToLowerInvariant().StartsWith("exb"))
+ return MediaType.Exatape22mAME;
+ break;
+ }
+ }
+ }
+ break;
+ case 0xD2:
+ {
+ switch (densityCode)
+ {
+ case 0x00:
+ case 0x27:
+ case 0x28:
+ {
+ if (model.ToLowerInvariant().StartsWith("exb"))
+ return MediaType.Exatape170m;
+ break;
+ }
+ }
+ }
+ break;
+ case 0xD3:
+ {
+ switch (densityCode)
+ {
+ case 0x00:
+ case 0x27:
+ case 0x28:
+ {
+ if (model.ToLowerInvariant().StartsWith("exb"))
+ return MediaType.Exatape125m;
+ break;
+ }
+ }
+ }
+ break;
+ case 0xD4:
+ {
+ switch (densityCode)
+ {
+ case 0x00:
+ case 0x27:
+ case 0x28:
+ {
+ if (model.ToLowerInvariant().StartsWith("exb"))
+ return MediaType.Exatape45m;
+ break;
+ }
+ }
+ }
+ break;
+ case 0xD5:
+ {
+ switch (densityCode)
+ {
+ case 0x00:
+ case 0x27:
+ case 0x28:
+ {
+ if (model.ToLowerInvariant().StartsWith("exb"))
+ return MediaType.Exatape225m;
+ break;
+ }
+ }
+ }
+ break;
+ case 0xD6:
+ {
+ switch (densityCode)
+ {
+ case 0x00:
+ case 0x27:
+ case 0x28:
+ {
+ if (model.ToLowerInvariant().StartsWith("exb"))
+ return MediaType.Exatape150m;
+ break;
+ }
+ }
+ }
+ break;
+ case 0xD7:
+ {
+ switch (densityCode)
+ {
+ case 0x00:
+ case 0x27:
+ case 0x28:
+ {
+ if (model.ToLowerInvariant().StartsWith("exb"))
+ return MediaType.Exatape75m;
+ break;
+ }
+ }
+ }
+ break;
+ }
+
+ return MediaType.Unknown;
+ }
+ // Write-once device
+ case 0x04:
+ // Optical device
+ case 0x07:
+ {
+ if (mediumType == 0x01 || mediumType == 0x02 || mediumType == 0x03 || mediumType == 0x05 || mediumType == 0x07)
+ {
+ switch (blockSize)
+ {
+ case 512:
+ {
+ switch (blocks)
+ {
+ case 249850:
+ return MediaType.ECMA_154;
+ case 429975:
+ return MediaType.ECMA_201_ROM;
+ case 446325:
+ return MediaType.ECMA_201;
+ case 694929:
+ return MediaType.ECMA_223_512;
+ case 904995:
+ return MediaType.ECMA_183_512;
+ case 1128772:
+ case 1163337:
+ return MediaType.ECMA_184_512;
+ case 1281856:
+ return MediaType.PD650_WORM;
+ case 1298496:
+ return MediaType.PD650;
+ case 1644581:
+ case 1647371:
+ return MediaType.ECMA_195_512;
+ default:
+ return MediaType.UnknownMO;
+ }
+ }
+ case 1024:
+ {
+ switch (blocks)
+ {
+ case 371371:
+ return MediaType.ECMA_223;
+ case 498526:
+ return MediaType.ECMA_183;
+ case 603466:
+ case 637041:
+ return MediaType.ECMA_184;
+ case 936921:
+ case 948770:
+ return MediaType.ECMA_195;
+ case 1244621:
+ return MediaType.ECMA_238;
+ case 14476734:
+ return MediaType.ECMA_260;
+ case 24445990:
+ return MediaType.ECMA_260_Double;
+ default:
+ return MediaType.UnknownMO;
+ }
+ }
+ case 2048:
+ {
+ switch (blocks)
+ {
+ case 318988:
+ case 320332:
+ case 321100:
+ return MediaType.ECMA_239;
+ case 605846:
+ return MediaType.GigaMo;
+ case 1063146:
+ return MediaType.GigaMo2;
+ case 1128134:
+ return MediaType.ECMA_280;
+ case 2043664:
+ return MediaType.ECMA_322_2k;
+ case 7355716:
+ return MediaType.ECMA_317;
+ default:
+ return MediaType.UnknownMO;
+ }
+ }
+ case 4096:
+ {
+ switch (blocks)
+ {
+ case 1095840:
+ return MediaType.ECMA_322;
+ default:
+ return MediaType.UnknownMO;
+ }
+ }
+ case 8192:
+ {
+ switch (blocks)
+ {
+ case 1834348:
+ return MediaType.UDO;
+ case 3668759:
+ return MediaType.UDO2_WORM;
+ case 3669724:
+ return MediaType.UDO2;
+ default:
+ return MediaType.UnknownMO;
+ }
+ }
+ default:
+ return MediaType.UnknownMO;
+ }
+ }
+
+ return MediaType.UnknownMO;
+ }
+ // MultiMedia Device
+ case 0x05:
+ {
+ switch (mediumType)
+ {
+ case 0x00:
+ return MediaType.CD;
+ case 0x01:
+ case 0x05:
+ return MediaType.CDROM;
+ case 0x02:
+ case 0x06:
+ return MediaType.CDDA;
+ case 0x03:
+ case 0x07:
+ return MediaType.CDPLUS;
+ case 0x04:
+ return MediaType.PCD;
+ case 0x10:
+ case 0x11:
+ case 0x12:
+ case 0x13:
+ case 0x14:
+ case 0x15:
+ case 0x16:
+ case 0x17:
+ case 0x18:
+ return MediaType.CDR;
+ case 0x20:
+ case 0x21:
+ case 0x22:
+ case 0x23:
+ case 0x24:
+ case 0x25:
+ case 0x26:
+ case 0x27:
+ case 0x28:
+ return MediaType.CDRW;
+ case 0x80:
+ if (model.ToLowerInvariant().StartsWith("ult"))
+ {
+ switch (densityCode)
+ {
+ case 0x42:
+ return MediaType.LTO2;
+ case 0x44:
+ return MediaType.LTO3;
+ case 0x46:
+ return MediaType.LTO4;
+ case 0x58:
+ return MediaType.LTO5;
+ }
+ }
+ break;
+ }
+ }
+ break;
+ // Host managed zoned block device
+ case 0x14:
+ {
+ return MediaType.Zone_HDD;
+ }
+ }
+
+ return MediaType.Unknown;
+ }
+ }
+}
\ No newline at end of file
diff --git a/DiscImageChef.Decoders/SCSI/Enums.cs b/DiscImageChef.Decoders/SCSI/Enums.cs
index 0a016f93..bfc3b9e6 100644
--- a/DiscImageChef.Decoders/SCSI/Enums.cs
+++ b/DiscImageChef.Decoders/SCSI/Enums.cs
@@ -39,7 +39,7 @@ using System;
namespace DiscImageChef.Decoders.SCSI
{
- enum PeripheralQualifiers : byte
+ public enum PeripheralQualifiers : byte
{
///
/// Peripheral qualifier: Device is connected and supported
@@ -159,7 +159,7 @@ namespace DiscImageChef.Decoders.SCSI
UnknownDevice = 0x1F
}
- enum ANSIVersions : byte
+ public enum ANSIVersions : byte
{
///
/// Device does not claim conformance to any ANSI version
@@ -191,7 +191,7 @@ namespace DiscImageChef.Decoders.SCSI
ANSI2008Version = 0x06
}
- enum ECMAVersions : byte
+ public enum ECMAVersions : byte
{
///
/// Device does not claim conformance to any ECMA version
@@ -203,7 +203,7 @@ namespace DiscImageChef.Decoders.SCSI
ECMA111 = 0x01
}
- enum ISOVersions : byte
+ public enum ISOVersions : byte
{
///
/// Device does not claim conformance to any ISO/IEC version
@@ -215,7 +215,7 @@ namespace DiscImageChef.Decoders.SCSI
ISO1995Version = 0x02
}
- enum SPIClocking : byte
+ public enum SPIClocking : byte
{
///
/// Supports only ST
@@ -235,7 +235,7 @@ namespace DiscImageChef.Decoders.SCSI
STandDT = 0x03,
}
- enum TGPSValues : byte
+ public enum TGPSValues : byte
{
///
/// Assymetrical access not supported
diff --git a/DiscImageChef.Decoders/SCSI/Inquiry.cs b/DiscImageChef.Decoders/SCSI/Inquiry.cs
index 258783cf..baf0ec4a 100644
--- a/DiscImageChef.Decoders/SCSI/Inquiry.cs
+++ b/DiscImageChef.Decoders/SCSI/Inquiry.cs
@@ -204,9 +204,9 @@ namespace DiscImageChef.Decoders.SCSI
StringBuilder sb = new StringBuilder();
- sb.AppendFormat("Device vendor: {0}", VendorString.Prettify(StringHandlers.SpacePaddedToString(response.VendorIdentification))).AppendLine();
- sb.AppendFormat("Device name: {0}", StringHandlers.SpacePaddedToString(response.ProductIdentification)).AppendLine();
- sb.AppendFormat("Device release level: {0}", StringHandlers.SpacePaddedToString(response.ProductRevisionLevel)).AppendLine();
+ sb.AppendFormat("Device vendor: {0}", VendorString.Prettify(StringHandlers.CToString(response.VendorIdentification).Trim())).AppendLine();
+ sb.AppendFormat("Device name: {0}", StringHandlers.CToString(response.ProductIdentification).Trim()).AppendLine();
+ sb.AppendFormat("Device release level: {0}", StringHandlers.CToString(response.ProductRevisionLevel).Trim()).AppendLine();
switch ((PeripheralQualifiers)response.PeripheralQualifier)
{
case PeripheralQualifiers.Supported:
diff --git a/DiscImageChef.Devices/Device/Constructor.cs b/DiscImageChef.Devices/Device/Constructor.cs
index e04cb536..1318c6dd 100644
--- a/DiscImageChef.Devices/Device/Constructor.cs
+++ b/DiscImageChef.Devices/Device/Constructor.cs
@@ -91,6 +91,9 @@ namespace DiscImageChef.Devices
throw new InvalidOperationException(String.Format("Platform {0} not yet supported.", platformID));
}
+ if (error)
+ throw new SystemException(String.Format("Error {0} opening device.", lastError));
+
type = DeviceType.Unknown;
scsiType = Decoders.SCSI.PeripheralDeviceTypes.UnknownDevice;
@@ -102,6 +105,9 @@ namespace DiscImageChef.Devices
bool scsiSense = ScsiInquiry(out inqBuf, out senseBuf);
+ if (error)
+ throw new SystemException(String.Format("Error {0} trying device.", lastError));
+
#region USB
if(platformID == DiscImageChef.Interop.PlatformID.Linux)
{
@@ -251,9 +257,9 @@ namespace DiscImageChef.Devices
if (Inquiry.HasValue)
{
- revision = StringHandlers.SpacePaddedToString(Inquiry.Value.ProductRevisionLevel);
- model = StringHandlers.SpacePaddedToString(Inquiry.Value.ProductIdentification);
- manufacturer = StringHandlers.SpacePaddedToString(Inquiry.Value.VendorIdentification);
+ revision = StringHandlers.CToString(Inquiry.Value.ProductRevisionLevel).Trim();
+ model = StringHandlers.CToString(Inquiry.Value.ProductIdentification).Trim();
+ manufacturer = StringHandlers.CToString(Inquiry.Value.VendorIdentification).Trim();
removable = Inquiry.Value.RMB;
scsiType = (Decoders.SCSI.PeripheralDeviceTypes)Inquiry.Value.PeripheralDeviceType;
diff --git a/DiscImageChef.Devices/Device/ScsiCommands/MMC.cs b/DiscImageChef.Devices/Device/ScsiCommands/MMC.cs
index c65704c3..2df39d65 100644
--- a/DiscImageChef.Devices/Device/ScsiCommands/MMC.cs
+++ b/DiscImageChef.Devices/Device/ScsiCommands/MMC.cs
@@ -492,6 +492,90 @@ namespace DiscImageChef.Devices
return sense;
}
+
+ public bool PreventMediumRemoval(out byte[] senseBuffer, uint timeout, out double duration)
+ {
+ return PreventAllowMediumRemoval(out senseBuffer, false, true, timeout, out duration);
+ }
+
+ public bool AllowMediumRemoval(out byte[] senseBuffer, uint timeout, out double duration)
+ {
+ return PreventAllowMediumRemoval(out senseBuffer, false, false, timeout, out duration);
+ }
+
+ public bool PreventAllowMediumRemoval(out byte[] senseBuffer, bool persistent, bool prevent, uint timeout, out double duration)
+ {
+ senseBuffer = new byte[32];
+ byte[] cdb = new byte[6];
+ byte[] buffer = new byte[0];
+ bool sense;
+
+ cdb[0] = (byte)ScsiCommands.PreventAllowMediumRemoval;
+ if (prevent)
+ cdb[4] += 0x01;
+ if (persistent)
+ cdb[4] += 0x02;
+
+ lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.None, out duration, out sense);
+ error = lastError != 0;
+
+ DicConsole.DebugWriteLine("SCSI Device", "PREVENT ALLOW MEDIUM REMOVAL took {0} ms.", duration);
+
+ return sense;
+ }
+
+ public bool LoadTray(out byte[] senseBuffer, uint timeout, out double duration)
+ {
+ return StartStopUnit(out senseBuffer, false, 0, 0, false, true, true, timeout, out duration);
+ }
+
+ public bool EjectTray(out byte[] senseBuffer, uint timeout, out double duration)
+ {
+ return StartStopUnit(out senseBuffer, false, 0, 0, false, true, false, timeout, out duration);
+ }
+
+ public bool StartUnit(out byte[] senseBuffer, uint timeout, out double duration)
+ {
+ return StartStopUnit(out senseBuffer, false, 0, 0, false, false, true, timeout, out duration);
+ }
+
+ public bool StopUnit(out byte[] senseBuffer, uint timeout, out double duration)
+ {
+ return StartStopUnit(out senseBuffer, false, 0, 0, false, false, false, timeout, out duration);
+ }
+
+ public bool StartStopUnit(out byte[] senseBuffer, bool immediate, byte formatLayer, byte powerConditions, bool changeFormatLayer, bool loadEject, bool start, uint timeout, out double duration)
+ {
+ senseBuffer = new byte[32];
+ byte[] cdb = new byte[6];
+ byte[] buffer = new byte[0];
+ bool sense;
+
+ cdb[0] = (byte)ScsiCommands.StartStopUnit;
+ if (immediate)
+ cdb[1] += 0x01;
+ if (changeFormatLayer)
+ {
+ cdb[3] = (byte)(formatLayer & 0x03);
+ cdb[4] += 0x04;
+ }
+ else
+ {
+ if(loadEject)
+ cdb[4] += 0x02;
+ if(start)
+ cdb[4] += 0x01;
+ }
+ cdb[4] += (byte)((powerConditions & 0x0F) << 4);
+
+ lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.None, out duration, out sense);
+ error = lastError != 0;
+
+ DicConsole.DebugWriteLine("SCSI Device", "START STOP UNIT took {0} ms.", duration);
+
+ return sense;
+ }
+
}
}
diff --git a/DiscImageChef.Devices/Device/ScsiCommands/NEC.cs b/DiscImageChef.Devices/Device/ScsiCommands/NEC.cs
index ceba6463..4603221b 100644
--- a/DiscImageChef.Devices/Device/ScsiCommands/NEC.cs
+++ b/DiscImageChef.Devices/Device/ScsiCommands/NEC.cs
@@ -52,7 +52,7 @@ namespace DiscImageChef.Devices
/// Duration in milliseconds it took for the device to execute the command.
/// Start block address.
/// How many blocks to read.
- public bool ReadCdDa(out byte[] buffer, out byte[] senseBuffer, uint lba, uint transferLength, uint timeout, out double duration)
+ public bool NecReadCdDa(out byte[] buffer, out byte[] senseBuffer, uint lba, uint transferLength, uint timeout, out double duration)
{
senseBuffer = new byte[32];
byte[] cdb = new byte[10];
diff --git a/DiscImageChef.Devices/Device/ScsiCommands/Pioneer.cs b/DiscImageChef.Devices/Device/ScsiCommands/Pioneer.cs
index 18ddf506..2133ff72 100644
--- a/DiscImageChef.Devices/Device/ScsiCommands/Pioneer.cs
+++ b/DiscImageChef.Devices/Device/ScsiCommands/Pioneer.cs
@@ -107,8 +107,7 @@ namespace DiscImageChef.Devices
cdb[9] = (byte)(endMsf & 0xFF);
cdb[10] = (byte)subchannel;
- uint transferLength = (uint)((cdb[6] - cdb[3]) * 60 * 75 + (cdb[7] - cdb[4]) * 75 + (cdb[8] - cdb[5]));
-
+ uint transferLength = (uint)((cdb[7] - cdb[3]) * 60 * 75 + (cdb[8] - cdb[4]) * 75 + (cdb[9] - cdb[5]));
buffer = new byte[blockSize * transferLength];
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration, out sense);
diff --git a/DiscImageChef.Devices/Device/ScsiCommands/Plextor.cs b/DiscImageChef.Devices/Device/ScsiCommands/Plextor.cs
index 1f1d3454..acf2cd3f 100644
--- a/DiscImageChef.Devices/Device/ScsiCommands/Plextor.cs
+++ b/DiscImageChef.Devices/Device/ScsiCommands/Plextor.cs
@@ -54,7 +54,7 @@ namespace DiscImageChef.Devices
/// How many blocks to read.
/// Block size.
/// Subchannel selection.
- public bool ReadCdDa(out byte[] buffer, out byte[] senseBuffer, uint lba, uint blockSize, uint transferLength, PlextorSubchannel subchannel, uint timeout, out double duration)
+ public bool PlextorReadCdDa(out byte[] buffer, out byte[] senseBuffer, uint lba, uint blockSize, uint transferLength, PlextorSubchannel subchannel, uint timeout, out double duration)
{
senseBuffer = new byte[32];
byte[] cdb = new byte[12];
diff --git a/DiscImageChef.Devices/Device/ScsiCommands/SPC.cs b/DiscImageChef.Devices/Device/ScsiCommands/SPC.cs
index f4375c0a..ab63c636 100644
--- a/DiscImageChef.Devices/Device/ScsiCommands/SPC.cs
+++ b/DiscImageChef.Devices/Device/ScsiCommands/SPC.cs
@@ -382,9 +382,9 @@ namespace DiscImageChef.Devices
/// Sense buffer.
/// Timeout in seconds.
/// Duration in milliseconds it took for the device to execute the command.
- public bool PreventMediumRemoval(out byte[] senseBuffer, uint timeout, out double duration)
+ public bool SpcPreventMediumRemoval(out byte[] senseBuffer, uint timeout, out double duration)
{
- return PreventAllowMediumRemoval(out senseBuffer, ScsiPreventAllowMode.Prevent, timeout, out duration);
+ return SpcPreventAllowMediumRemoval(out senseBuffer, ScsiPreventAllowMode.Prevent, timeout, out duration);
}
///
@@ -394,9 +394,9 @@ namespace DiscImageChef.Devices
/// Sense buffer.
/// Timeout in seconds.
/// Duration in milliseconds it took for the device to execute the command.
- public bool AllowMediumRemoval(out byte[] senseBuffer, uint timeout, out double duration)
+ public bool SpcAllowMediumRemoval(out byte[] senseBuffer, uint timeout, out double duration)
{
- return PreventAllowMediumRemoval(out senseBuffer, ScsiPreventAllowMode.Allow, timeout, out duration);
+ return SpcPreventAllowMediumRemoval(out senseBuffer, ScsiPreventAllowMode.Allow, timeout, out duration);
}
///
@@ -407,12 +407,12 @@ namespace DiscImageChef.Devices
/// Timeout in seconds.
/// Duration in milliseconds it took for the device to execute the command.
/// true to prevent medium removal, false to allow it.
- public bool PreventAllowMediumRemoval(out byte[] senseBuffer, bool prevent, uint timeout, out double duration)
+ public bool SpcPreventAllowMediumRemoval(out byte[] senseBuffer, bool prevent, uint timeout, out double duration)
{
if (prevent)
- return PreventAllowMediumRemoval(out senseBuffer, ScsiPreventAllowMode.Prevent, timeout, out duration);
+ return SpcPreventAllowMediumRemoval(out senseBuffer, ScsiPreventAllowMode.Prevent, timeout, out duration);
else
- return PreventAllowMediumRemoval(out senseBuffer, ScsiPreventAllowMode.Allow, timeout, out duration);
+ return SpcPreventAllowMediumRemoval(out senseBuffer, ScsiPreventAllowMode.Allow, timeout, out duration);
}
///
@@ -423,7 +423,7 @@ namespace DiscImageChef.Devices
/// Timeout in seconds.
/// Duration in milliseconds it took for the device to execute the command.
/// Prevention mode.
- public bool PreventAllowMediumRemoval(out byte[] senseBuffer, ScsiPreventAllowMode preventMode, uint timeout, out double duration)
+ public bool SpcPreventAllowMediumRemoval(out byte[] senseBuffer, ScsiPreventAllowMode preventMode, uint timeout, out double duration)
{
senseBuffer = new byte[32];
byte[] cdb = new byte[6];
diff --git a/DiscImageChef.Devices/DiscImageChef.Devices.csproj b/DiscImageChef.Devices/DiscImageChef.Devices.csproj
index 3a82c25a..4e9899ba 100644
--- a/DiscImageChef.Devices/DiscImageChef.Devices.csproj
+++ b/DiscImageChef.Devices/DiscImageChef.Devices.csproj
@@ -20,6 +20,7 @@
prompt
4
false
+ x86
full
diff --git a/DiscImageChef.Devices/Linux/Command.cs b/DiscImageChef.Devices/Linux/Command.cs
index 6538a5dd..2dce631a 100644
--- a/DiscImageChef.Devices/Linux/Command.cs
+++ b/DiscImageChef.Devices/Linux/Command.cs
@@ -331,12 +331,12 @@ namespace DiscImageChef.Devices.Linux
public static string ReadLink(string path)
{
- IntPtr buf = Marshal.AllocHGlobal(int.MaxValue);
+ IntPtr buf = Marshal.AllocHGlobal(4096);
int resultSize;
if (Interop.DetectOS.Is64Bit())
{
- long result64 = Extern.readlink64(path, buf, (long)int.MaxValue);
+ long result64 = Extern.readlink64(path, buf, (long)4096);
if (result64 <= 0)
return null;
@@ -344,7 +344,7 @@ namespace DiscImageChef.Devices.Linux
}
else
{
- int result = Extern.readlink(path, buf, int.MaxValue);
+ int result = Extern.readlink(path, buf, 4096);
if (result <= 0)
return null;
diff --git a/DiscImageChef.Devices/Linux/Enums.cs b/DiscImageChef.Devices/Linux/Enums.cs
index 09372272..639bf3e9 100644
--- a/DiscImageChef.Devices/Linux/Enums.cs
+++ b/DiscImageChef.Devices/Linux/Enums.cs
@@ -145,7 +145,7 @@ namespace DiscImageChef.Devices.Linux
Unknown = -5
}
- enum LinuxIoctl : ulong
+ enum LinuxIoctl : uint
{
// SCSI IOCtls
SG_GET_VERSION_NUM = 0x2282,
diff --git a/DiscImageChef.DiscImages/ZZZRawImage.cs b/DiscImageChef.DiscImages/ZZZRawImage.cs
index f59044de..381c5620 100644
--- a/DiscImageChef.DiscImages/ZZZRawImage.cs
+++ b/DiscImageChef.DiscImages/ZZZRawImage.cs
@@ -673,11 +673,11 @@ namespace DiscImageChef.ImagePlugins
case 481520640:
return MediaType.ECMA_183_512;
case 533403648:
- return MediaType.ECMA_183_1024;
+ return MediaType.ECMA_183;
case 596787200:
return MediaType.ECMA_184_512;
case 654540800:
- return MediaType.ECMA_184_1024;
+ return MediaType.ECMA_184;
default:
return MediaType.GENERIC_HDD;
}
diff --git a/DiscImageChef.Metadata/DeviceReport.cs b/DiscImageChef.Metadata/DeviceReport.cs
new file mode 100644
index 00000000..86ae7de3
--- /dev/null
+++ b/DiscImageChef.Metadata/DeviceReport.cs
@@ -0,0 +1,958 @@
+// /***************************************************************************
+// The Disc Image Chef
+// ----------------------------------------------------------------------------
+//
+// Filename : DeviceReport.cs
+// Version : 1.0
+// Author(s) : Natalia Portillo
+//
+// Component : Component
+//
+// Revision : $Revision$
+// Last change by : $Author$
+// Date : $Date$
+//
+// --[ Description ] ----------------------------------------------------------
+//
+// Description
+//
+// --[ License ] --------------------------------------------------------------
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+//
+// ----------------------------------------------------------------------------
+// Copyright (C) 2011-2015 Claunia.com
+// ****************************************************************************/
+// //$Id$
+using System;
+using System.Xml.Serialization;
+using DiscImageChef.Decoders.ATA;
+using DiscImageChef.Decoders.SCSI;
+
+namespace DiscImageChef.Metadata
+{
+ [SerializableAttribute()]
+ [XmlRootAttribute("DicDeviceReport", Namespace="", IsNullable=false)]
+ public class DeviceReport
+ {
+ public usbType USB;
+ public firewireType FireWire;
+ public ataType ATA;
+ public ataType ATAPI;
+ public scsiType SCSI;
+ }
+
+ public class usbType
+ {
+ public ushort VendorID;
+ public ushort ProductID;
+ public string Manufacturer;
+ public string Product;
+ public bool RemovableMedia;
+ }
+
+ public class firewireType
+ {
+ public uint VendorID;
+ public uint ProductID;
+ public string Manufacturer;
+ public string Product;
+ public bool RemovableMedia;
+ }
+
+ public class ataType
+ {
+ public chsType CHS;
+ public chsType CurrentCHS;
+
+ public string AdditionalPID;
+ public Identify.TransferMode APIOSupported;
+ public ushort ATAPIByteCount;
+ public ushort BufferType;
+ public ushort BufferSize;
+ public Identify.CapabilitiesBit Capabilities;
+ public Identify.CapabilitiesBit2 Capabilities2;
+ public Identify.CapabilitiesBit3 Capabilities3;
+ public ushort CFAPowerMode;
+ public Identify.CommandSetBit CommandSet;
+ public Identify.CommandSetBit2 CommandSet2;
+ public Identify.CommandSetBit3 CommandSet3;
+ public Identify.CommandSetBit4 CommandSet4;
+ public Identify.CommandSetBit5 CommandSet5;
+ public byte CurrentAAM;
+ public ushort CurrentAPM;
+ public Identify.DataSetMgmtBit DataSetMgmt;
+ public ushort DataSetMgmtSize;
+ public Identify.DeviceFormFactorEnum DeviceFormFactor;
+ public Identify.TransferMode DMAActive;
+ public Identify.TransferMode DMASupported;
+ public byte DMATransferTimingMode;
+ public ushort EccBytes;
+ public ushort EnhancedSecurityEraseTime;
+ public Identify.CommandSetBit EnabledCommandSet;
+ public Identify.CommandSetBit2 EnabledCommandSet2;
+ public Identify.CommandSetBit3 EnabledCommandSet3;
+ public Identify.CommandSetBit4 EnabledCommandSet4;
+ public Identify.SATAFeaturesBit EnabledSATAFeatures;
+ public ulong ExtendedUserSectors;
+ public byte FreeFallSensitivity;
+ public string FirmwareRevision;
+ public Identify.GeneralConfigurationBit GeneralConfiguration;
+ public ushort HardwareResetResult;
+ public ushort InterseekDelay;
+ public uint LBASectors;
+ public uint LBASectorsCurrent;
+ public ulong LBA48Sectors;
+ public ushort LogicalAlignment;
+ public uint LogicalSectorWords;
+ public Identify.MajorVersionBit MajorVersion;
+ public ushort MasterPasswordRevisionCode;
+ public ushort MaxDownloadMicroMode3;
+ public ushort MaxQueueDepth;
+ public Identify.TransferMode MDMAActive;
+ public Identify.TransferMode MDMASupported;
+ public ushort MinDownloadMicroMode3;
+ public ushort MinMDMACycleTime;
+ public ushort MinorVersion;
+ public ushort MinPIOCycleTimeNoFlow;
+ public ushort MinPIOCycleTimeFlow;
+ public string Model;
+ public byte MultipleMaxSectors;
+ public byte MultipleSectorNumber;
+ public ushort NVCacheCaps;
+ public uint NVCacheSize;
+ public ushort NVCacheWriteSpeed;
+ public byte NVEstimatedSpinUp;
+ public ushort NominalRotationRate;
+ public ushort PacketBusRelease;
+ public ushort PhysLogSectorSize;
+ public byte PIOTransferTimingMode;
+ public byte RecommendedAAM;
+ public ushort RecommendedMDMACycleTime;
+ public ushort RemovableStatusSet;
+ public Identify.SATACapabilitiesBit SATACapabilities;
+ public Identify.SATACapabilitiesBit2 SATACapabilities2;
+ public Identify.SATAFeaturesBit SATAFeatures;
+ public Identify.SCTCommandTransportBit SCTCommandTransport;
+ public uint SectorsPerCard;
+ public ushort SecurityEraseTime;
+ public Identify.SecurityStatusBit SecurityStatus;
+ public ushort ServiceBusyClear;
+ public Identify.SpecificConfigurationEnum SpecificConfiguration;
+ public ushort StreamAccessLatency;
+ public ushort StreamMinReqSize;
+ public uint StreamPerformanceGranularity;
+ public ushort StreamTransferTimeDMA;
+ public ushort StreamTransferTimePIO;
+ public ushort TransportMajorVersion;
+ public ushort TransportMinorVersion;
+ public Identify.TrustedComputingBit TrustedComputing;
+ public Identify.TransferMode UDMAActive;
+ public Identify.TransferMode UDMASupported;
+ public ushort UnformattedBPT;
+ public ushort UnformattedBPS;
+ public byte WRVMode;
+ public uint WRVSectorCountMode3;
+ public uint WRVSectorCountMode2;
+
+ [XmlIgnoreAttribute()]
+ public bool AdditionalPIDSpecified;
+ [XmlIgnoreAttribute()]
+ public bool APIOSupportedSpecified;
+ [XmlIgnoreAttribute()]
+ public bool ATAPIByteCountSpecified;
+ [XmlIgnoreAttribute()]
+ public bool BufferTypeSpecified;
+ [XmlIgnoreAttribute()]
+ public bool BufferSizeSpecified;
+ [XmlIgnoreAttribute()]
+ public bool CapabilitiesSpecified;
+ [XmlIgnoreAttribute()]
+ public bool Capabilities2Specified;
+ [XmlIgnoreAttribute()]
+ public bool Capabilities3Specified;
+ [XmlIgnoreAttribute()]
+ public bool CFAPowerModeSpecified;
+ [XmlIgnoreAttribute()]
+ public bool CommandSetSpecified;
+ [XmlIgnoreAttribute()]
+ public bool CommandSet2Specified;
+ [XmlIgnoreAttribute()]
+ public bool CommandSet3Specified;
+ [XmlIgnoreAttribute()]
+ public bool CommandSet4Specified;
+ [XmlIgnoreAttribute()]
+ public bool CommandSet5Specified;
+ [XmlIgnoreAttribute()]
+ public bool CurrentAAMSpecified;
+ [XmlIgnoreAttribute()]
+ public bool CurrentAPMSpecified;
+ [XmlIgnoreAttribute()]
+ public bool DataSetMgmtSpecified;
+ [XmlIgnoreAttribute()]
+ public bool DataSetMgmtSizeSpecified;
+ [XmlIgnoreAttribute()]
+ public bool DeviceFormFactorSpecified;
+ [XmlIgnoreAttribute()]
+ public bool DMAActiveSpecified;
+ [XmlIgnoreAttribute()]
+ public bool DMASupportedSpecified;
+ [XmlIgnoreAttribute()]
+ public bool DMATransferTimingModeSpecified;
+ [XmlIgnoreAttribute()]
+ public bool EccBytesSpecified;
+ [XmlIgnoreAttribute()]
+ public bool EnhancedSecurityEraseTimeSpecified;
+ [XmlIgnoreAttribute()]
+ public bool EnabledCommandSetSpecified;
+ [XmlIgnoreAttribute()]
+ public bool EnabledCommandSet2Specified;
+ [XmlIgnoreAttribute()]
+ public bool EnabledCommandSet3Specified;
+ [XmlIgnoreAttribute()]
+ public bool EnabledCommandSet4Specified;
+ [XmlIgnoreAttribute()]
+ public bool EnabledSATAFeaturesSpecified;
+ [XmlIgnoreAttribute()]
+ public bool ExtendedIdentifySpecified;
+ [XmlIgnoreAttribute()]
+ public bool ExtendedUserSectorsSpecified;
+ [XmlIgnoreAttribute()]
+ public bool FreeFallSensitivitySpecified;
+ [XmlIgnoreAttribute()]
+ public bool FirmwareRevisionSpecified;
+ [XmlIgnoreAttribute()]
+ public bool GeneralConfigurationSpecified;
+ [XmlIgnoreAttribute()]
+ public bool HardwareResetResultSpecified;
+ [XmlIgnoreAttribute()]
+ public bool InterseekDelaySpecified;
+ [XmlIgnoreAttribute()]
+ public bool LBASectorsSpecified;
+ [XmlIgnoreAttribute()]
+ public bool LBASectorsCurrentSpecified;
+ [XmlIgnoreAttribute()]
+ public bool LBA48SectorsSpecified;
+ [XmlIgnoreAttribute()]
+ public bool LogicalAlignmentSpecified;
+ [XmlIgnoreAttribute()]
+ public bool LogicalSectorWordsSpecified;
+ [XmlIgnoreAttribute()]
+ public bool MajorVersionSpecified;
+ [XmlIgnoreAttribute()]
+ public bool MasterPasswordRevisionCodeSpecified;
+ [XmlIgnoreAttribute()]
+ public bool MaxDownloadMicroMode3Specified;
+ [XmlIgnoreAttribute()]
+ public bool MaxQueueDepthSpecified;
+ [XmlIgnoreAttribute()]
+ public bool MDMAActiveSpecified;
+ [XmlIgnoreAttribute()]
+ public bool MDMASupportedSpecified;
+ [XmlIgnoreAttribute()]
+ public bool MinDownloadMicroMode3Specified;
+ [XmlIgnoreAttribute()]
+ public bool MinMDMACycleTimeSpecified;
+ [XmlIgnoreAttribute()]
+ public bool MinorVersionSpecified;
+ [XmlIgnoreAttribute()]
+ public bool MinPIOCycleTimeNoFlowSpecified;
+ [XmlIgnoreAttribute()]
+ public bool MinPIOCycleTimeFlowSpecified;
+ [XmlIgnoreAttribute()]
+ public bool ModelSpecified;
+ [XmlIgnoreAttribute()]
+ public bool MultipleMaxSectorsSpecified;
+ [XmlIgnoreAttribute()]
+ public bool MultipleSectorNumberSpecified;
+ [XmlIgnoreAttribute()]
+ public bool NVCacheCapsSpecified;
+ [XmlIgnoreAttribute()]
+ public bool NVCacheSizeSpecified;
+ [XmlIgnoreAttribute()]
+ public bool NVCacheWriteSpeedSpecified;
+ [XmlIgnoreAttribute()]
+ public bool NVEstimatedSpinUpSpecified;
+ [XmlIgnoreAttribute()]
+ public bool NominalRotationRateSpecified;
+ [XmlIgnoreAttribute()]
+ public bool PacketBusReleaseSpecified;
+ [XmlIgnoreAttribute()]
+ public bool PhysLogSectorSizeSpecified;
+ [XmlIgnoreAttribute()]
+ public bool PIOTransferTimingModeSpecified;
+ [XmlIgnoreAttribute()]
+ public bool RecommendedAAMSpecified;
+ [XmlIgnoreAttribute()]
+ public bool RecommendedMDMACycleTimeSpecified;
+ [XmlIgnoreAttribute()]
+ public bool RemovableStatusSetSpecified;
+ [XmlIgnoreAttribute()]
+ public bool SATACapabilitiesSpecified;
+ [XmlIgnoreAttribute()]
+ public bool SATACapabilities2Specified;
+ [XmlIgnoreAttribute()]
+ public bool SATAFeaturesSpecified;
+ [XmlIgnoreAttribute()]
+ public bool SCTCommandTransportSpecified;
+ [XmlIgnoreAttribute()]
+ public bool SectorsPerCardSpecified;
+ [XmlIgnoreAttribute()]
+ public bool SecurityEraseTimeSpecified;
+ [XmlIgnoreAttribute()]
+ public bool SecurityStatusSpecified;
+ [XmlIgnoreAttribute()]
+ public bool ServiceBusyClearSpecified;
+ [XmlIgnoreAttribute()]
+ public bool SpecificConfigurationSpecified;
+ [XmlIgnoreAttribute()]
+ public bool StreamAccessLatencySpecified;
+ [XmlIgnoreAttribute()]
+ public bool StreamMinReqSizeSpecified;
+ [XmlIgnoreAttribute()]
+ public bool StreamPerformanceGranularitySpecified;
+ [XmlIgnoreAttribute()]
+ public bool StreamTransferTimeDMASpecified;
+ [XmlIgnoreAttribute()]
+ public bool StreamTransferTimePIOSpecified;
+ [XmlIgnoreAttribute()]
+ public bool TransportMajorVersionSpecified;
+ [XmlIgnoreAttribute()]
+ public bool TransportMinorVersionSpecified;
+ [XmlIgnoreAttribute()]
+ public bool TrustedComputingSpecified;
+ [XmlIgnoreAttribute()]
+ public bool UDMAActiveSpecified;
+ [XmlIgnoreAttribute()]
+ public bool UDMASupportedSpecified;
+ [XmlIgnoreAttribute()]
+ public bool UnformattedBPTSpecified;
+ [XmlIgnoreAttribute()]
+ public bool UnformattedBPSSpecified;
+ [XmlIgnoreAttribute()]
+ public bool WRVModeSpecified;
+ [XmlIgnoreAttribute()]
+ public bool WRVSectorCountMode3Specified;
+ [XmlIgnoreAttribute()]
+ public bool WRVSectorCountMode2Specified;
+ }
+
+ public class chsType
+ {
+ public ushort Cylinders;
+ public ushort Heads;
+ public ushort Sectors;
+ }
+
+ public class scsiType
+ {
+ public scsiInquiryType Inquiry;
+ public pageType[] EVPDPages;
+ public bool SupportsModeSense6;
+ public bool SupportsModeSense10;
+ public bool SupportsModeSubpages;
+ public modeType ModeSense;
+ public mmcType MultiMediaDevice;
+ public testedMediaType ReadCapabilities;
+ public testedMediaType[] RemovableMedias;
+ public sscType SequentialDevice;
+
+ [XmlIgnoreAttribute()]
+ public bool ReadCapabilitiesSpecified;
+ }
+
+ public class scsiInquiryType
+ {
+ public bool AccessControlCoordinator;
+ public bool ACKRequests;
+ public bool AERCSupported;
+ public bool Address16;
+ public bool Address32;
+ public byte ANSIVersion;
+ public TGPSValues AsymmetricalLUNAccess;
+ public bool BasicQueueing;
+ public byte DeviceTypeModifier;
+ public byte ECMAVersion;
+ public bool EnclosureServices;
+ public bool HierarchicalLUN;
+ public bool IUS;
+ public byte ISOVersion;
+ public bool LinkedCommands;
+ public bool MediumChanger;
+ public bool MultiPortDevice;
+ public bool NormalACA;
+ public PeripheralDeviceTypes PeripheralDeviceType;
+ public PeripheralQualifiers PeripheralQualifier;
+ public string ProductIdentification;
+ public string ProductRevisionLevel;
+ public bool Protection;
+ public bool QAS;
+ public bool RelativeAddressing;
+ public bool Removable;
+ public byte ResponseDataFormat;
+ public bool TaggedCommandQueue;
+ public bool TerminateTaskSupported;
+ public bool ThirdPartyCopy;
+ public bool TranferDisable;
+ public bool SoftReset;
+ public SPIClocking SPIClocking;
+ public bool StorageArrayController;
+ public bool SyncTransfer;
+ public string VendorIdentification;
+ public ushort[] VersionDescriptors;
+ public bool WideBus16;
+ public bool WideBus32;
+
+ [XmlIgnoreAttribute()]
+ public bool ANSIVersionSpecified;
+ [XmlIgnoreAttribute()]
+ public bool ECMAVersionSpecified;
+ [XmlIgnoreAttribute()]
+ public bool DeviceTypeModifierSpecified;
+ [XmlIgnoreAttribute()]
+ public bool ISOVersionSpecified;
+ [XmlIgnoreAttribute()]
+ public bool ProductIdentificationSpecified;
+ [XmlIgnoreAttribute()]
+ public bool ProductRevisionLevelSpecified;
+ [XmlIgnoreAttribute()]
+ public bool ResponseDataFormatSpecified;
+ [XmlIgnoreAttribute()]
+ public bool VendorIdentificationSpecified;
+ }
+
+ [SerializableAttribute()]
+ public class pageType
+ {
+ [XmlAttributeAttribute()]
+ public byte page;
+
+ [XmlTextAttribute()]
+ public byte[] value;
+ }
+
+ public class modeType
+ {
+ public byte MediumType;
+ public bool WriteProtected;
+ public blockDescriptorType[] BlockDescriptors;
+ public byte Speed;
+ public byte BufferedMode;
+ public bool BlankCheckEnabled;
+ public bool DPOandFUA;
+ public modePageType[] ModePages;
+
+ [XmlIgnoreAttribute()]
+ public bool MediumTypeSpecified;
+ [XmlIgnoreAttribute()]
+ public bool SpeedSpecified;
+ [XmlIgnoreAttribute()]
+ public bool BufferedModeSpecified;
+ }
+
+ public class blockDescriptorType
+ {
+ public byte Density;
+ public ulong Blocks;
+ public uint BlockLength;
+
+ [XmlIgnoreAttribute()]
+ public bool BlocksSpecified;
+ [XmlIgnoreAttribute()]
+ public bool BlockLengthSpecified;
+ }
+
+ [SerializableAttribute()]
+ public class modePageType
+ {
+ [XmlAttributeAttribute()]
+ public byte page;
+
+ [XmlAttributeAttribute()]
+ public byte subpage;
+
+ [XmlTextAttribute()]
+ public byte[] value;
+ }
+
+ public class mmcType
+ {
+ public mmcModeType ModeSense2A;
+ public mmcFeaturesType Features;
+ public testedMediaType[] TestedMedia;
+ }
+
+ public class mmcModeType
+ {
+ public bool AccurateCDDA;
+ public bool BCK;
+ public ushort BufferSize;
+ public bool BufferUnderRunProtection;
+ public bool CanEject;
+ public bool CanLockMedia;
+ public bool CDDACommand;
+ public bool CompositeAudioVideo;
+ public bool CSSandCPPMSupported;
+ public ushort CurrentSpeed;
+ public ushort CurrentWriteSpeed;
+ public ushort CurrentWriteSpeedSelected;
+ public bool DeterministicSlotChanger;
+ public bool DigitalPort1;
+ public bool DigitalPort2;
+ public bool LeadInPW;
+ public byte LoadingMechanismType;
+ public bool LockStatus;
+ public bool LSBF;
+ public ushort MaximumSpeed;
+ public ushort MaximumWriteSpeed;
+ public bool PlaysAudio;
+ public bool PreventJumperStatus;
+ public bool RCK;
+ public bool ReadsBarcode;
+ public bool ReadsBothSides;
+ public bool ReadsCDR;
+ public bool ReadsCDRW;
+ public bool ReadsDeinterlavedSubchannel;
+ public bool ReadsDVDR;
+ public bool ReadsDVDRAM;
+ public bool ReadsDVDROM;
+ public bool ReadsISRC;
+ public bool ReadsMode2Form2;
+ public bool ReadsMode2Form1;
+ public bool ReadsPacketCDR;
+ public bool ReadsSubchannel;
+ public bool ReadsUPC;
+ public bool ReturnsC2Pointers;
+ public byte RotationControlSelected;
+ public bool SeparateChannelMute;
+ public bool SeparateChannelVolume;
+ public bool SSS;
+ public bool SupportsMultiSession;
+ public ushort SupportedVolumeLevels;
+ public bool TestWrite;
+ public bool WritesCDR;
+ public bool WritesCDRW;
+ public bool WritesDVDR;
+ public bool WritesDVDRAM;
+ public Modes.ModePage_2A_WriteDescriptor[] WriteSpeedPerformanceDescriptors;
+
+ [XmlIgnoreAttribute()]
+ public bool MaximumSpeedSpecified;
+ [XmlIgnoreAttribute()]
+ public bool SupportedVolumeLevelsSpecified;
+ [XmlIgnoreAttribute()]
+ public bool BufferSizeSpecified;
+ [XmlIgnoreAttribute()]
+ public bool CurrentSpeedSpecified;
+ [XmlIgnoreAttribute()]
+ public bool MaximumWriteSpeedSpecified;
+ [XmlIgnoreAttribute()]
+ public bool CurrentWriteSpeedSpecified;
+ [XmlIgnoreAttribute()]
+ public bool RotationControlSelectedSpecified;
+ [XmlIgnoreAttribute()]
+ public bool CurrentWriteSpeedSelectedSpecified;
+ }
+
+ public class mmcFeaturesType
+ {
+ public byte AACSVersion;
+ public byte AGIDs;
+ public byte BindingNonceBlocks;
+ public ushort BlocksPerReadableUnit;
+ public bool BufferUnderrunFreeInDVD;
+ public bool BufferUnderrunFreeInSAO;
+ public bool BufferUnderrunFreeInTAO;
+ public bool CanAudioScan;
+ public bool CanEject;
+ public bool CanEraseSector;
+ public bool CanExpandBDRESpareArea;
+ public bool CanFormat;
+ public bool CanFormatBDREWithoutSpare;
+ public bool CanFormatCert;
+ public bool CanFormatFRF;
+ public bool CanFormatQCert;
+ public bool CanFormatRRM;
+ public bool CanGenerateBindingNonce;
+ public bool CanLoad;
+ public bool CanMuteSeparateChannels;
+ public bool CanOverwriteSAOTrack;
+ public bool CanOverwriteTAOTrack;
+ public bool CanPlayCDAudio;
+ public bool CanPseudoOverwriteBDR;
+ public bool CanReadAllDualR;
+ public bool CanReadAllDualRW;
+ public bool CanReadBD;
+ public bool CanReadBDR;
+ public bool CanReadBDRE1;
+ public bool CanReadBDRE2;
+ public bool CanReadBDROM;
+ public bool CanReadBluBCA;
+ public bool CanReadCD;
+ public bool CanReadCDMRW;
+ public bool CanReadCPRM_MKB;
+ public bool CanReadDDCD;
+ public bool CanReadDVD;
+ public bool CanReadDVDPlusMRW;
+ public bool CanReadDVDPlusR;
+ public bool CanReadDVDPlusRDL;
+ public bool CanReadDVDPlusRW;
+ public bool CanReadDVDPlusRWDL;
+ public bool CanReadDriveAACSCertificate;
+ public bool CanReadHDDVD;
+ public bool CanReadHDDVDR;
+ public bool CanReadHDDVDRAM;
+ public bool CanReadLeadInCDText;
+ public bool CanReadOldBDR;
+ public bool CanReadOldBDRE;
+ public bool CanReadOldBDROM;
+ public bool CanReadSpareAreaInformation;
+ public bool CanReportDriveSerial;
+ public bool CanReportMediaSerial;
+ public bool CanTestWriteDDCDR;
+ public bool CanTestWriteDVD;
+ public bool CanTestWriteInSAO;
+ public bool CanTestWriteInTAO;
+ public bool CanUpgradeFirmware;
+ public bool CanWriteBD;
+ public bool CanWriteBDR;
+ public bool CanWriteBDRE1;
+ public bool CanWriteBDRE2;
+ public bool CanWriteBusEncryptedBlocks;
+ public bool CanWriteCDMRW;
+ public bool CanWriteCDRW;
+ public bool CanWriteCDRWCAV;
+ public bool CanWriteCDSAO;
+ public bool CanWriteCDTAO;
+ public bool CanWriteCSSManagedDVD;
+ public bool CanWriteDDCDR;
+ public bool CanWriteDDCDRW;
+ public bool CanWriteDVDPlusMRW;
+ public bool CanWriteDVDPlusR;
+ public bool CanWriteDVDPlusRDL;
+ public bool CanWriteDVDPlusRW;
+ public bool CanWriteDVDPlusRWDL;
+ public bool CanWriteDVDR;
+ public bool CanWriteDVDRDL;
+ public bool CanWriteDVDRW;
+ public bool CanWriteHDDVDR;
+ public bool CanWriteHDDVDRAM;
+ public bool CanWriteOldBDR;
+ public bool CanWriteOldBDRE;
+ public bool CanWritePackedSubchannelInTAO;
+ public bool CanWriteRWSubchannelInSAO;
+ public bool CanWriteRWSubchannelInTAO;
+ public bool CanWriteRaw;
+ public bool CanWriteRawMultiSession;
+ public bool CanWriteRawSubchannelInTAO;
+ public bool ChangerIsSideChangeCapable;
+ public byte ChangerSlots;
+ public bool ChangerSupportsDiscPresent;
+ public byte CPRMVersion;
+ public byte CSSVersion;
+ public bool DBML;
+ public bool DVDMultiRead;
+ public bool EmbeddedChanger;
+ public bool ErrorRecoveryPage;
+ [XmlElementAttribute(DataType="date")]
+ public DateTime FirmwareDate;
+ public byte LoadingMechanismType;
+ public bool Locked;
+ public uint LogicalBlockSize;
+ public bool MultiRead;
+ public DiscImageChef.Decoders.SCSI.MMC.PhysicalInterfaces PhysicalInterfaceStandard;
+ public bool PreventJumper;
+ public bool SupportsAACS;
+ public bool SupportsBusEncryption;
+ public bool SupportsC2;
+ public bool SupportsCPRM;
+ public bool SupportsCSS;
+ public bool SupportsDAP;
+ public bool SupportsDeviceBusyEvent;
+ public bool SupportsHybridDiscs;
+ public bool SupportsModePage1Ch;
+ public bool SupportsOSSC;
+ public bool SupportsPWP;
+ public bool SupportsSWPP;
+ public bool SupportsSecurDisc;
+ public bool SupportsSeparateVolume;
+ public bool SupportsVCPS;
+ public bool SupportsWriteInhibitDCB;
+ public bool SupportsWriteProtectPAC;
+ public ushort VolumeLevels;
+
+ [XmlIgnoreAttribute()]
+ public bool PhysicalInterfaceStandardSpecified;
+ [XmlIgnoreAttribute()]
+ public bool AACSVersionSpecified;
+ [XmlIgnoreAttribute()]
+ public bool AGIDsSpecified;
+ [XmlIgnoreAttribute()]
+ public bool BindingNonceBlocksSpecified;
+ [XmlIgnoreAttribute()]
+ public bool CPRMVersionSpecified;
+ [XmlIgnoreAttribute()]
+ public bool CSSVersionSpecified;
+ [XmlIgnoreAttribute()]
+ public bool ChangerHighestSlotNumberSpecified;
+ [XmlIgnoreAttribute()]
+ public bool LoadingMechanismTypeSpecified;
+ [XmlIgnoreAttribute()]
+ public bool LogicalBlockSizeSpecified;
+ [XmlIgnoreAttribute()]
+ public bool BlocksPerReadableUnitSpecified;
+ [XmlIgnoreAttribute()]
+ public bool FirmwareDateSpecified;
+ [XmlIgnoreAttribute()]
+ public bool VolumeLevelsSpecified;
+ }
+
+ public class testedMediaType
+ {
+ public ulong Blocks;
+ public uint BlockSize;
+ public bool CanReadAACS;
+ public bool CanReadADIP;
+ public bool CanReadATIP;
+ public bool CanReadBCA;
+ public bool CanReadC2Pointers;
+ public bool CanReadCMI;
+ public bool CanReadCorrectedSubchannel;
+ public bool CanReadCorrectedSubchannelWithC2;
+ public bool CanReadDCB;
+ public bool CanReadDDS;
+ public bool CanReadDMI;
+ public bool CanReadDiscInformation;
+ public bool CanReadFullTOC;
+ public bool CanReadHDCMI;
+ public bool CanReadLayerCapacity;
+ public bool CanReadLeadIn;
+ public bool CanReadLeadOut;
+ public bool CanReadMediaID;
+ public bool CanReadMediaSerial;
+ public bool CanReadPAC;
+ public bool CanReadPFI;
+ public bool CanReadPMA;
+ public bool CanReadPQSubchannel;
+ public bool CanReadPQSubchannelWithC2;
+ public bool CanReadPRI;
+ public bool CanReadRWSubchannel;
+ public bool CanReadRWSubchannelWithC2;
+ public bool CanReadRecordablePFI;
+ public bool CanReadSpareAreaInformation;
+ public bool CanReadTOC;
+ public byte Density;
+ public uint LongBlockSize;
+ public string Manufacturer;
+ public bool MediaIsRecognized;
+ public byte MediumType;
+ public string MediumTypeName;
+ public string Model;
+ public bool SupportsHLDTSTReadRawDVD;
+ public bool SupportsNECReadCDDA;
+ public bool SupportsPioneerReadCDDA;
+ public bool SupportsPioneerReadCDDAMSF;
+ public bool SupportsPlextorReadCDDA;
+ public bool SupportsPlextorReadRawDVD;
+ public bool SupportsRead10;
+ public bool SupportsRead12;
+ public bool SupportsRead16;
+ public bool SupportsRead;
+ public bool SupportsReadCapacity16;
+ public bool SupportsReadCapacity;
+ public bool SupportsReadCd;
+ public bool SupportsReadCdMsf;
+ public bool SupportsReadCdRaw;
+ public bool SupportsReadCdMsfRaw;
+ public bool SupportsReadLong16;
+ public bool SupportsReadLong;
+
+ [XmlIgnoreAttribute()]
+ public bool BlocksSpecified;
+ [XmlIgnoreAttribute()]
+ public bool BlockSizeSpecified;
+ [XmlIgnoreAttribute()]
+ public bool CanReadAACSSpecified;
+ [XmlIgnoreAttribute()]
+ public bool CanReadADIPSpecified;
+ [XmlIgnoreAttribute()]
+ public bool CanReadATIPSpecified;
+ [XmlIgnoreAttribute()]
+ public bool CanReadBCASpecified;
+ [XmlIgnoreAttribute()]
+ public bool CanReadC2PointersSpecified;
+ [XmlIgnoreAttribute()]
+ public bool CanReadCMISpecified;
+ [XmlIgnoreAttribute()]
+ public bool CanReadCorrectedSubchannelSpecified;
+ [XmlIgnoreAttribute()]
+ public bool CanReadCorrectedSubchannelWithC2Specified;
+ [XmlIgnoreAttribute()]
+ public bool CanReadDCBSpecified;
+ [XmlIgnoreAttribute()]
+ public bool CanReadDDSSpecified;
+ [XmlIgnoreAttribute()]
+ public bool CanReadDMISpecified;
+ [XmlIgnoreAttribute()]
+ public bool CanReadDiscInformationSpecified;
+ [XmlIgnoreAttribute()]
+ public bool CanReadFullTOCSpecified;
+ [XmlIgnoreAttribute()]
+ public bool CanReadHDCMISpecified;
+ [XmlIgnoreAttribute()]
+ public bool CanReadLayerCapacitySpecified;
+ [XmlIgnoreAttribute()]
+ public bool CanReadLeadInSpecified;
+ [XmlIgnoreAttribute()]
+ public bool CanReadLeadOutSpecified;
+ [XmlIgnoreAttribute()]
+ public bool CanReadMediaIDSpecified;
+ [XmlIgnoreAttribute()]
+ public bool CanReadMediaSerialSpecified;
+ [XmlIgnoreAttribute()]
+ public bool CanReadPACSpecified;
+ [XmlIgnoreAttribute()]
+ public bool CanReadPFISpecified;
+ [XmlIgnoreAttribute()]
+ public bool CanReadPMASpecified;
+ [XmlIgnoreAttribute()]
+ public bool CanReadPQSubchannelSpecified;
+ [XmlIgnoreAttribute()]
+ public bool CanReadPQSubchannelWithC2Specified;
+ [XmlIgnoreAttribute()]
+ public bool CanReadPRISpecified;
+ [XmlIgnoreAttribute()]
+ public bool CanReadRWSubchannelSpecified;
+ [XmlIgnoreAttribute()]
+ public bool CanReadRWSubchannelWithC2Specified;
+ [XmlIgnoreAttribute()]
+ public bool CanReadRecordablePFISpecified;
+ [XmlIgnoreAttribute()]
+ public bool CanReadSpareAreaInformationSpecified;
+ [XmlIgnoreAttribute()]
+ public bool CanReadTOCSpecified;
+ [XmlIgnoreAttribute()]
+ public bool DensitySpecified;
+ [XmlIgnoreAttribute()]
+ public bool LongBlockSizeSpecified;
+ [XmlIgnoreAttribute()]
+ public bool ManufacturerSpecified;
+ [XmlIgnoreAttribute()]
+ public bool MediumTypeSpecified;
+ [XmlIgnoreAttribute()]
+ public bool ModelSpecified;
+ [XmlIgnoreAttribute()]
+ public bool SupportsHLDTSTReadRawDVDSpecified;
+ [XmlIgnoreAttribute()]
+ public bool SupportsNECReadCDDASpecified;
+ [XmlIgnoreAttribute()]
+ public bool SupportsPioneerReadCDDASpecified;
+ [XmlIgnoreAttribute()]
+ public bool SupportsPioneerReadCDDAMSFSpecified;
+ [XmlIgnoreAttribute()]
+ public bool SupportsPlextorReadCDDASpecified;
+ [XmlIgnoreAttribute()]
+ public bool SupportsPlextorReadRawDVDSpecified;
+ [XmlIgnoreAttribute()]
+ public bool SupportsRead10Specified;
+ [XmlIgnoreAttribute()]
+ public bool SupportsRead12Specified;
+ [XmlIgnoreAttribute()]
+ public bool SupportsRead16Specified;
+ [XmlIgnoreAttribute()]
+ public bool SupportsReadSpecified;
+ [XmlIgnoreAttribute()]
+ public bool SupportsReadCapacity16Specified;
+ [XmlIgnoreAttribute()]
+ public bool SupportsReadCapacitySpecified;
+ [XmlIgnoreAttribute()]
+ public bool SupportsReadCdSpecified;
+ [XmlIgnoreAttribute()]
+ public bool SupportsReadCdMsfSpecified;
+ [XmlIgnoreAttribute()]
+ public bool SupportsReadCdRawSpecified;
+ [XmlIgnoreAttribute()]
+ public bool SupportsReadCdMsfRawSpecified;
+ [XmlIgnoreAttribute()]
+ public bool SupportsReadLong16Specified;
+ [XmlIgnoreAttribute()]
+ public bool SupportsReadLongSpecified;
+ }
+
+ public class sscType
+ {
+ public byte BlockSizeGranularity;
+ public uint MaxBlockLength;
+ public uint MinBlockLength;
+
+ public SupportedDensity[] SupportedDensities;
+ public SupportedMedia[] SupportedMediaTypes;
+ public SequentialMedia[] TestedMedia;
+
+ [XmlIgnoreAttribute()]
+ public bool BlockSizeGranularitySpecified;
+ [XmlIgnoreAttribute()]
+ public bool MaxBlockLengthSpecified;
+ [XmlIgnoreAttribute()]
+ public bool MinBlockLengthSpecified;
+ }
+
+ public struct SupportedDensity
+ {
+ public byte PrimaryCode;
+ public byte SecondaryCode;
+ public bool Writable;
+ public bool Duplicate;
+ public bool DefaultDensity;
+ public uint BitsPerMm;
+ public ushort Width;
+ public ushort Tracks;
+ public uint Capacity;
+ public string Organization;
+ public string Name;
+ public string Description;
+ }
+
+ public struct SupportedMedia
+ {
+ public byte MediumType;
+ public int[] DensityCodes;
+ public ushort Width;
+ public ushort Length;
+ public string Organization;
+ public string Name;
+ public string Description;
+ }
+
+ public struct SequentialMedia
+ {
+ public bool CanReadMediaSerial;
+ public byte Density;
+ public string Manufacturer;
+ public bool MediaIsRecognized;
+ public byte MediumType;
+ public string MediumTypeName;
+ public string Model;
+ public SupportedDensity[] SupportedDensities;
+ public SupportedMedia[] SupportedMediaTypes;
+
+ [XmlIgnoreAttribute()]
+ public bool CanReadMediaSerialSpecified;
+ [XmlIgnoreAttribute()]
+ public bool DensitySpecified;
+ [XmlIgnoreAttribute()]
+ public bool MediumTypeSpecified;
+ }
+}
+
diff --git a/DiscImageChef.Metadata/Dimensions.cs b/DiscImageChef.Metadata/Dimensions.cs
index 27bb9eae..2a9aa6a7 100644
--- a/DiscImageChef.Metadata/Dimensions.cs
+++ b/DiscImageChef.Metadata/Dimensions.cs
@@ -152,11 +152,47 @@ namespace DiscImageChef.Metadata
return dmns;
#endregion 8" floppy disk
+ #region 356mm magneto optical
+ case CommonTypes.MediaType.ECMA_260:
+ case CommonTypes.MediaType.ECMA_260_Double:
+ // According to ECMA-260 et al
+ dmns.Height = 421.84;
+ dmns.HeightSpecified = true;
+ dmns.Width = 443.76;
+ dmns.WidthSpecified = true;
+ dmns.Thickness = 25.4;
+ return dmns;
+ #endregion 356mm magneto optical
+
+ #region 300mm magneto optical
+ case CommonTypes.MediaType.ECMA_189:
+ case CommonTypes.MediaType.ECMA_190:
+ case CommonTypes.MediaType.ECMA_317:
+ // According to ECMA-317 et al
+ dmns.Height = 340;
+ dmns.HeightSpecified = true;
+ dmns.Width = 320;
+ dmns.WidthSpecified = true;
+ dmns.Thickness = 17;
+ return dmns;
+ #endregion 300mm magneto optical
+
#region 5.25" magneto optical
+ case CommonTypes.MediaType.ECMA_153:
+ case CommonTypes.MediaType.ECMA_153_512:
case CommonTypes.MediaType.ECMA_183_512:
- case CommonTypes.MediaType.ECMA_183_1024:
+ case CommonTypes.MediaType.ECMA_183:
case CommonTypes.MediaType.ECMA_184_512:
- case CommonTypes.MediaType.ECMA_184_1024:
+ case CommonTypes.MediaType.ECMA_184:
+ case CommonTypes.MediaType.ECMA_195:
+ case CommonTypes.MediaType.ECMA_195_512:
+ case CommonTypes.MediaType.ECMA_238:
+ case CommonTypes.MediaType.ECMA_280:
+ case CommonTypes.MediaType.ECMA_322:
+ case CommonTypes.MediaType.ECMA_322_2k:
+ case CommonTypes.MediaType.UDO:
+ case CommonTypes.MediaType.UDO2:
+ case CommonTypes.MediaType.UDO2_WORM:
// According to ECMA-183 et al
dmns.Height = 153;
dmns.HeightSpecified = true;
@@ -169,6 +205,11 @@ namespace DiscImageChef.Metadata
#region 3.5" magneto optical
case CommonTypes.MediaType.ECMA_154:
case CommonTypes.MediaType.ECMA_201:
+ case CommonTypes.MediaType.ECMA_201_ROM:
+ case CommonTypes.MediaType.ECMA_223:
+ case CommonTypes.MediaType.ECMA_223_512:
+ case CommonTypes.MediaType.GigaMo:
+ case CommonTypes.MediaType.GigaMo2:
// According to ECMA-154 et al
dmns.Height = 94;
dmns.HeightSpecified = true;
@@ -178,6 +219,21 @@ namespace DiscImageChef.Metadata
return dmns;
#endregion 3.5" magneto optical
+ case CommonTypes.MediaType.PD650:
+ case CommonTypes.MediaType.PD650_WORM:
+ dmns.Height = 135;
+ dmns.HeightSpecified = true;
+ dmns.Width = 124;
+ dmns.WidthSpecified = true;
+ dmns.Thickness = 7.8;
+ return dmns;
+ case CommonTypes.MediaType.ECMA_239:
+ dmns.Height = 97;
+ dmns.HeightSpecified = true;
+ dmns.Width = 92;
+ dmns.WidthSpecified = true;
+ dmns.Thickness = 5;
+ return dmns;
case CommonTypes.MediaType.MMCmicro:
dmns.Height = 14;
dmns.HeightSpecified = true;
@@ -483,19 +539,14 @@ namespace DiscImageChef.Metadata
dmns.Thickness = 14;
return dmns;
case CommonTypes.MediaType.RDX:
+ case CommonTypes.MediaType.RDX320:
dmns.Height = 119;
dmns.HeightSpecified = true;
- dmns.Width = 86.5;
+ dmns.Width = 87;
dmns.WidthSpecified = true;
- dmns.Thickness = 23.2;
+ dmns.Thickness = 23;
return dmns;
case CommonTypes.MediaType.LS120:
- dmns.Height = 94;
- dmns.HeightSpecified = true;
- dmns.Width = 90;
- dmns.WidthSpecified = true;
- dmns.Thickness = 3.5;
- return dmns;
case CommonTypes.MediaType.LS240:
dmns.Height = 94;
dmns.HeightSpecified = true;
@@ -550,14 +601,16 @@ namespace DiscImageChef.Metadata
case CommonTypes.MediaType.AIT5:
case CommonTypes.MediaType.AITETurbo:
case CommonTypes.MediaType.Exatape106m:
- case CommonTypes.MediaType.Exatape106mXL:
+ case CommonTypes.MediaType.Exatape160mXL:
case CommonTypes.MediaType.Exatape112m:
case CommonTypes.MediaType.Exatape125m:
case CommonTypes.MediaType.Exatape150m:
case CommonTypes.MediaType.Exatape15m:
case CommonTypes.MediaType.Exatape170m:
case CommonTypes.MediaType.Exatape225m:
+ case CommonTypes.MediaType.Exatape22m:
case CommonTypes.MediaType.Exatape22mAME:
+ case CommonTypes.MediaType.Exatape28m:
case CommonTypes.MediaType.Exatape40m:
case CommonTypes.MediaType.Exatape45m:
case CommonTypes.MediaType.Exatape54m:
diff --git a/DiscImageChef.Metadata/DiscImageChef.Metadata.csproj b/DiscImageChef.Metadata/DiscImageChef.Metadata.csproj
index db7e2043..9bc2a1cb 100644
--- a/DiscImageChef.Metadata/DiscImageChef.Metadata.csproj
+++ b/DiscImageChef.Metadata/DiscImageChef.Metadata.csproj
@@ -40,6 +40,7 @@
+
@@ -47,5 +48,9 @@
{F2B84194-26EB-4227-B1C5-6602517E85AE}
DiscImageChef.CommonTypes
+
+ {0BEB3088-B634-4289-AE17-CDF2D25D00D5}
+ DiscImageChef.Decoders
+
\ No newline at end of file
diff --git a/DiscImageChef.Metadata/MediaType.cs b/DiscImageChef.Metadata/MediaType.cs
index 5b855359..f4d1fba6 100644
--- a/DiscImageChef.Metadata/MediaType.cs
+++ b/DiscImageChef.Metadata/MediaType.cs
@@ -613,13 +613,18 @@ namespace DiscImageChef.Metadata
DiscType = "3.5\" floppy";
DiscSubType = "FDFORMAT high-density";
break;
+ case CommonTypes.MediaType.ECMA_260:
+ case CommonTypes.MediaType.ECMA_260_Double:
+ DiscType = "356mm magneto-optical";
+ DiscSubType = "ECMA-260 / ISO 15898";
+ break;
case CommonTypes.MediaType.ECMA_183_512:
- case CommonTypes.MediaType.ECMA_183_1024:
+ case CommonTypes.MediaType.ECMA_183:
DiscType = "5.25\" magneto-optical";
DiscSubType = "ECMA-183";
break;
case CommonTypes.MediaType.ECMA_184_512:
- case CommonTypes.MediaType.ECMA_184_1024:
+ case CommonTypes.MediaType.ECMA_184:
DiscType = "5.25\" magneto-optical";
DiscSubType = "ECMA-184";
break;
@@ -631,6 +636,10 @@ namespace DiscImageChef.Metadata
DiscType = "3.5\" magneto-optical";
DiscSubType = "ECMA-201";
break;
+ case DiscImageChef.CommonTypes.MediaType.FlashDrive:
+ DiscType = "USB flash drive";
+ DiscSubType = "USB flash drive";
+ break;
default:
DiscType = "Unknown";
DiscSubType = "Unknown";
diff --git a/DiscImageChef/Commands/CreateSidecar.cs b/DiscImageChef/Commands/CreateSidecar.cs
index 0001ea65..0ae3ea66 100644
--- a/DiscImageChef/Commands/CreateSidecar.cs
+++ b/DiscImageChef/Commands/CreateSidecar.cs
@@ -96,64 +96,7 @@ namespace DiscImageChef.Commands
FileInfo fi = new FileInfo(options.InputFile);
FileStream fs = new FileStream(options.InputFile, FileMode.Open, FileAccess.Read);
- Adler32Context adler32ctx = new Adler32Context();
- CRC16Context crc16ctx = new CRC16Context();
- CRC32Context crc32ctx = new CRC32Context();
- CRC64Context crc64ctx = new CRC64Context();
- MD5Context md5ctx = new MD5Context();
- RIPEMD160Context ripemd160ctx = new RIPEMD160Context();
- SHA1Context sha1ctx = new SHA1Context();
- SHA256Context sha256ctx = new SHA256Context();
- SHA384Context sha384ctx = new SHA384Context();
- SHA512Context sha512ctx = new SHA512Context();
- SpamSumContext ssctx = new SpamSumContext();
-
- Thread adlerThread = new Thread(updateAdler);
- Thread crc16Thread = new Thread(updateCRC16);
- Thread crc32Thread = new Thread(updateCRC32);
- Thread crc64Thread = new Thread(updateCRC64);
- Thread md5Thread = new Thread(updateMD5);
- Thread ripemd160Thread = new Thread(updateRIPEMD160);
- Thread sha1Thread = new Thread(updateSHA1);
- Thread sha256Thread = new Thread(updateSHA256);
- Thread sha384Thread = new Thread(updateSHA384);
- Thread sha512Thread = new Thread(updateSHA512);
- Thread spamsumThread = new Thread(updateSpamSum);
-
- adlerPacket adlerPkt = new adlerPacket();
- crc16Packet crc16Pkt = new crc16Packet();
- crc32Packet crc32Pkt = new crc32Packet();
- crc64Packet crc64Pkt = new crc64Packet();
- md5Packet md5Pkt = new md5Packet();
- ripemd160Packet ripemd160Pkt = new ripemd160Packet();
- sha1Packet sha1Pkt = new sha1Packet();
- sha256Packet sha256Pkt = new sha256Packet();
- sha384Packet sha384Pkt = new sha384Packet();
- sha512Packet sha512Pkt = new sha512Packet();
- spamsumPacket spamsumPkt = new spamsumPacket();
-
- adler32ctx.Init();
- adlerPkt.context = adler32ctx;
- crc16ctx.Init();
- crc16Pkt.context = crc16ctx;
- crc32ctx.Init();
- crc32Pkt.context = crc32ctx;
- crc64ctx.Init();
- crc64Pkt.context = crc64ctx;
- md5ctx.Init();
- md5Pkt.context = md5ctx;
- ripemd160ctx.Init();
- ripemd160Pkt.context = ripemd160ctx;
- sha1ctx.Init();
- sha1Pkt.context = sha1ctx;
- sha256ctx.Init();
- sha256Pkt.context = sha256ctx;
- sha384ctx.Init();
- sha384Pkt.context = sha384ctx;
- sha512ctx.Init();
- sha512Pkt.context = sha512ctx;
- ssctx.Init();
- spamsumPkt.context = ssctx;
+ Core.Checksum imgChkWorker = new DiscImageChef.Core.Checksum();
byte[] data;
long position = 0;
@@ -164,49 +107,7 @@ namespace DiscImageChef.Commands
DicConsole.Write("\rHashing image file byte {0} of {1}", position, fi.Length);
- adlerPkt.data = data;
- adlerThread.Start(adlerPkt);
- crc16Pkt.data = data;
- crc16Thread.Start(crc16Pkt);
- crc32Pkt.data = data;
- crc32Thread.Start(crc32Pkt);
- crc64Pkt.data = data;
- crc64Thread.Start(crc64Pkt);
- md5Pkt.data = data;
- md5Thread.Start(md5Pkt);
- ripemd160Pkt.data = data;
- ripemd160Thread.Start(ripemd160Pkt);
- sha1Pkt.data = data;
- sha1Thread.Start(sha1Pkt);
- sha256Pkt.data = data;
- sha256Thread.Start(sha256Pkt);
- sha384Pkt.data = data;
- sha384Thread.Start(sha384Pkt);
- sha512Pkt.data = data;
- sha512Thread.Start(sha512Pkt);
- spamsumPkt.data = data;
- spamsumThread.Start(spamsumPkt);
-
- while (adlerThread.IsAlive || crc16Thread.IsAlive ||
- crc32Thread.IsAlive || crc64Thread.IsAlive ||
- md5Thread.IsAlive || ripemd160Thread.IsAlive ||
- sha1Thread.IsAlive || sha256Thread.IsAlive ||
- sha384Thread.IsAlive || sha512Thread.IsAlive ||
- spamsumThread.IsAlive)
- {
- }
-
- adlerThread = new Thread(updateAdler);
- crc16Thread = new Thread(updateCRC16);
- crc32Thread = new Thread(updateCRC32);
- crc64Thread = new Thread(updateCRC64);
- md5Thread = new Thread(updateMD5);
- ripemd160Thread = new Thread(updateRIPEMD160);
- sha1Thread = new Thread(updateSHA1);
- sha256Thread = new Thread(updateSHA256);
- sha384Thread = new Thread(updateSHA384);
- sha512Thread = new Thread(updateSHA512);
- spamsumThread = new Thread(updateSpamSum);
+ imgChkWorker.Update(data);
position += 1048576;
}
@@ -216,97 +117,12 @@ namespace DiscImageChef.Commands
DicConsole.Write("\rHashing image file byte {0} of {1}", position, fi.Length);
- adlerPkt.data = data;
- adlerThread.Start(adlerPkt);
- crc16Pkt.data = data;
- crc16Thread.Start(crc16Pkt);
- crc32Pkt.data = data;
- crc32Thread.Start(crc32Pkt);
- crc64Pkt.data = data;
- crc64Thread.Start(crc64Pkt);
- md5Pkt.data = data;
- md5Thread.Start(md5Pkt);
- ripemd160Pkt.data = data;
- ripemd160Thread.Start(ripemd160Pkt);
- sha1Pkt.data = data;
- sha1Thread.Start(sha1Pkt);
- sha256Pkt.data = data;
- sha256Thread.Start(sha256Pkt);
- sha384Pkt.data = data;
- sha384Thread.Start(sha384Pkt);
- sha512Pkt.data = data;
- sha512Thread.Start(sha512Pkt);
- spamsumPkt.data = data;
- spamsumThread.Start(spamsumPkt);
-
- while (adlerThread.IsAlive || crc16Thread.IsAlive ||
- crc32Thread.IsAlive || crc64Thread.IsAlive ||
- md5Thread.IsAlive || ripemd160Thread.IsAlive ||
- sha1Thread.IsAlive || sha256Thread.IsAlive ||
- sha384Thread.IsAlive || sha512Thread.IsAlive ||
- spamsumThread.IsAlive)
- {
- }
+ imgChkWorker.Update(data);
DicConsole.WriteLine();
fs.Close();
- List imgChecksums = new List();
-
- ChecksumType chk = new ChecksumType();
- chk.type = ChecksumTypeType.adler32;
- chk.Value = adler32ctx.End();
- imgChecksums.Add(chk);
-
- chk = new ChecksumType();
- chk.type = ChecksumTypeType.crc16;
- chk.Value = crc16ctx.End();
- imgChecksums.Add(chk);
-
- chk = new ChecksumType();
- chk.type = ChecksumTypeType.crc32;
- chk.Value = crc32ctx.End();
- imgChecksums.Add(chk);
-
- chk = new ChecksumType();
- chk.type = ChecksumTypeType.crc64;
- chk.Value = crc64ctx.End();
- imgChecksums.Add(chk);
-
- chk = new ChecksumType();
- chk.type = ChecksumTypeType.md5;
- chk.Value = md5ctx.End();
- imgChecksums.Add(chk);
-
- chk = new ChecksumType();
- chk.type = ChecksumTypeType.ripemd160;
- chk.Value = ripemd160ctx.End();
- imgChecksums.Add(chk);
-
- chk = new ChecksumType();
- chk.type = ChecksumTypeType.sha1;
- chk.Value = sha1ctx.End();
- imgChecksums.Add(chk);
-
- chk = new ChecksumType();
- chk.type = ChecksumTypeType.sha256;
- chk.Value = sha256ctx.End();
- imgChecksums.Add(chk);
-
- chk = new ChecksumType();
- chk.type = ChecksumTypeType.sha384;
- chk.Value = sha384ctx.End();
- imgChecksums.Add(chk);
-
- chk = new ChecksumType();
- chk.type = ChecksumTypeType.sha512;
- chk.Value = sha512ctx.End();
- imgChecksums.Add(chk);
-
- chk = new ChecksumType();
- chk.type = ChecksumTypeType.spamsum;
- chk.Value = ssctx.End();
- imgChecksums.Add(chk);
+ List imgChecksums = imgChkWorker.End();
switch (_imageFormat.ImageInfo.xmlMediaType)
{
@@ -342,7 +158,7 @@ namespace DiscImageChef.Commands
{
case MediaTagType.CD_ATIP:
sidecar.OpticalDisc[0].ATIP = new DumpType();
- sidecar.OpticalDisc[0].ATIP.Checksums = GetChecksums(_imageFormat.ReadDiskTag(MediaTagType.CD_ATIP)).ToArray();
+ sidecar.OpticalDisc[0].ATIP.Checksums = Core.Checksum.GetChecksums(_imageFormat.ReadDiskTag(MediaTagType.CD_ATIP)).ToArray();
sidecar.OpticalDisc[0].ATIP.Size = _imageFormat.ReadDiskTag(MediaTagType.CD_ATIP).Length;
Decoders.CD.ATIP.CDATIP? atip = Decoders.CD.ATIP.Decode(_imageFormat.ReadDiskTag(MediaTagType.CD_ATIP));
if (atip.HasValue)
@@ -355,12 +171,12 @@ namespace DiscImageChef.Commands
break;
case MediaTagType.DVD_BCA:
sidecar.OpticalDisc[0].BCA = new DumpType();
- sidecar.OpticalDisc[0].BCA.Checksums = GetChecksums(_imageFormat.ReadDiskTag(MediaTagType.DVD_BCA)).ToArray();
+ sidecar.OpticalDisc[0].BCA.Checksums = Core.Checksum.GetChecksums(_imageFormat.ReadDiskTag(MediaTagType.DVD_BCA)).ToArray();
sidecar.OpticalDisc[0].BCA.Size = _imageFormat.ReadDiskTag(MediaTagType.DVD_BCA).Length;
break;
case MediaTagType.BD_BCA:
sidecar.OpticalDisc[0].BCA = new DumpType();
- sidecar.OpticalDisc[0].BCA.Checksums = GetChecksums(_imageFormat.ReadDiskTag(MediaTagType.BD_BCA)).ToArray();
+ sidecar.OpticalDisc[0].BCA.Checksums = Core.Checksum.GetChecksums(_imageFormat.ReadDiskTag(MediaTagType.BD_BCA)).ToArray();
sidecar.OpticalDisc[0].BCA.Size = _imageFormat.ReadDiskTag(MediaTagType.BD_BCA).Length;
break;
case MediaTagType.DVD_CMI:
@@ -381,12 +197,12 @@ namespace DiscImageChef.Commands
break;
}
}
- sidecar.OpticalDisc[0].CMI.Checksums = GetChecksums(_imageFormat.ReadDiskTag(MediaTagType.DVD_CMI)).ToArray();
+ sidecar.OpticalDisc[0].CMI.Checksums = Core.Checksum.GetChecksums(_imageFormat.ReadDiskTag(MediaTagType.DVD_CMI)).ToArray();
sidecar.OpticalDisc[0].CMI.Size = _imageFormat.ReadDiskTag(MediaTagType.DVD_CMI).Length;
break;
case MediaTagType.DVD_DMI:
sidecar.OpticalDisc[0].DMI = new DumpType();
- sidecar.OpticalDisc[0].DMI.Checksums = GetChecksums(_imageFormat.ReadDiskTag(MediaTagType.DVD_DMI)).ToArray();
+ sidecar.OpticalDisc[0].DMI.Checksums = Core.Checksum.GetChecksums(_imageFormat.ReadDiskTag(MediaTagType.DVD_DMI)).ToArray();
sidecar.OpticalDisc[0].DMI.Size = _imageFormat.ReadDiskTag(MediaTagType.DVD_DMI).Length;
if (Decoders.Xbox.DMI.IsXbox(_imageFormat.ReadDiskTag(MediaTagType.DVD_DMI)))
{
@@ -403,7 +219,7 @@ namespace DiscImageChef.Commands
break;
case MediaTagType.DVD_PFI:
sidecar.OpticalDisc[0].PFI = new DumpType();
- sidecar.OpticalDisc[0].PFI.Checksums = GetChecksums(_imageFormat.ReadDiskTag(MediaTagType.DVD_PFI)).ToArray();
+ sidecar.OpticalDisc[0].PFI.Checksums = Core.Checksum.GetChecksums(_imageFormat.ReadDiskTag(MediaTagType.DVD_PFI)).ToArray();
sidecar.OpticalDisc[0].PFI.Size = _imageFormat.ReadDiskTag(MediaTagType.DVD_PFI).Length;
Decoders.DVD.PFI.PhysicalFormatInformation? pfi = Decoders.DVD.PFI.Decode(_imageFormat.ReadDiskTag(MediaTagType.DVD_PFI));
if (pfi.HasValue)
@@ -477,7 +293,7 @@ namespace DiscImageChef.Commands
break;
case MediaTagType.CD_PMA:
sidecar.OpticalDisc[0].PMA = new DumpType();
- sidecar.OpticalDisc[0].PMA.Checksums = GetChecksums(_imageFormat.ReadDiskTag(MediaTagType.CD_PMA)).ToArray();
+ sidecar.OpticalDisc[0].PMA.Checksums = Core.Checksum.GetChecksums(_imageFormat.ReadDiskTag(MediaTagType.CD_PMA)).ToArray();
sidecar.OpticalDisc[0].PMA.Size = _imageFormat.ReadDiskTag(MediaTagType.CD_PMA).Length;
break;
}
@@ -583,64 +399,7 @@ namespace DiscImageChef.Commands
uint sectorsToRead = 512;
- adler32ctx = new Adler32Context();
- crc16ctx = new CRC16Context();
- crc32ctx = new CRC32Context();
- crc64ctx = new CRC64Context();
- md5ctx = new MD5Context();
- ripemd160ctx = new RIPEMD160Context();
- sha1ctx = new SHA1Context();
- sha256ctx = new SHA256Context();
- sha384ctx = new SHA384Context();
- sha512ctx = new SHA512Context();
- ssctx = new SpamSumContext();
-
- adlerThread = new Thread(updateAdler);
- crc16Thread = new Thread(updateCRC16);
- crc32Thread = new Thread(updateCRC32);
- crc64Thread = new Thread(updateCRC64);
- md5Thread = new Thread(updateMD5);
- ripemd160Thread = new Thread(updateRIPEMD160);
- sha1Thread = new Thread(updateSHA1);
- sha256Thread = new Thread(updateSHA256);
- sha384Thread = new Thread(updateSHA384);
- sha512Thread = new Thread(updateSHA512);
- spamsumThread = new Thread(updateSpamSum);
-
- adlerPkt = new adlerPacket();
- crc16Pkt = new crc16Packet();
- crc32Pkt = new crc32Packet();
- crc64Pkt = new crc64Packet();
- md5Pkt = new md5Packet();
- ripemd160Pkt = new ripemd160Packet();
- sha1Pkt = new sha1Packet();
- sha256Pkt = new sha256Packet();
- sha384Pkt = new sha384Packet();
- sha512Pkt = new sha512Packet();
- spamsumPkt = new spamsumPacket();
-
- adler32ctx.Init();
- adlerPkt.context = adler32ctx;
- crc16ctx.Init();
- crc16Pkt.context = crc16ctx;
- crc32ctx.Init();
- crc32Pkt.context = crc32ctx;
- crc64ctx.Init();
- crc64Pkt.context = crc64ctx;
- md5ctx.Init();
- md5Pkt.context = md5ctx;
- ripemd160ctx.Init();
- ripemd160Pkt.context = ripemd160ctx;
- sha1ctx.Init();
- sha1Pkt.context = sha1ctx;
- sha256ctx.Init();
- sha256Pkt.context = sha256ctx;
- sha384ctx.Init();
- sha384Pkt.context = sha384ctx;
- sha512ctx.Init();
- sha512Pkt.context = sha512ctx;
- ssctx.Init();
- spamsumPkt.context = ssctx;
+ Core.Checksum trkChkWorker = new DiscImageChef.Core.Checksum();
ulong sectors = (ulong)(xmlTrk.EndSector - xmlTrk.StartSector + 1);
ulong doneSectors = 0;
@@ -662,107 +421,10 @@ namespace DiscImageChef.Commands
doneSectors += (sectors - doneSectors);
}
- adlerPkt.data = sector;
- adlerThread.Start(adlerPkt);
- crc16Pkt.data = sector;
- crc16Thread.Start(crc16Pkt);
- crc32Pkt.data = sector;
- crc32Thread.Start(crc32Pkt);
- crc64Pkt.data = sector;
- crc64Thread.Start(crc64Pkt);
- md5Pkt.data = sector;
- md5Thread.Start(md5Pkt);
- ripemd160Pkt.data = sector;
- ripemd160Thread.Start(ripemd160Pkt);
- sha1Pkt.data = sector;
- sha1Thread.Start(sha1Pkt);
- sha256Pkt.data = sector;
- sha256Thread.Start(sha256Pkt);
- sha384Pkt.data = sector;
- sha384Thread.Start(sha384Pkt);
- sha512Pkt.data = sector;
- sha512Thread.Start(sha512Pkt);
- spamsumPkt.data = sector;
- spamsumThread.Start(spamsumPkt);
-
- while (adlerThread.IsAlive || crc16Thread.IsAlive ||
- crc32Thread.IsAlive || crc64Thread.IsAlive ||
- md5Thread.IsAlive || ripemd160Thread.IsAlive ||
- sha1Thread.IsAlive || sha256Thread.IsAlive ||
- sha384Thread.IsAlive || sha512Thread.IsAlive ||
- spamsumThread.IsAlive)
- {
- }
-
- adlerThread = new Thread(updateAdler);
- crc16Thread = new Thread(updateCRC16);
- crc32Thread = new Thread(updateCRC32);
- crc64Thread = new Thread(updateCRC64);
- md5Thread = new Thread(updateMD5);
- ripemd160Thread = new Thread(updateRIPEMD160);
- sha1Thread = new Thread(updateSHA1);
- sha256Thread = new Thread(updateSHA256);
- sha384Thread = new Thread(updateSHA384);
- sha512Thread = new Thread(updateSHA512);
- spamsumThread = new Thread(updateSpamSum);
+ trkChkWorker.Update(sector);
}
- List trkChecksums = new List();
-
- chk = new ChecksumType();
- chk.type = ChecksumTypeType.adler32;
- chk.Value = adler32ctx.End();
- trkChecksums.Add(chk);
-
- chk = new ChecksumType();
- chk.type = ChecksumTypeType.crc16;
- chk.Value = crc16ctx.End();
- trkChecksums.Add(chk);
-
- chk = new ChecksumType();
- chk.type = ChecksumTypeType.crc32;
- chk.Value = crc32ctx.End();
- trkChecksums.Add(chk);
-
- chk = new ChecksumType();
- chk.type = ChecksumTypeType.crc64;
- chk.Value = crc64ctx.End();
- trkChecksums.Add(chk);
-
- chk = new ChecksumType();
- chk.type = ChecksumTypeType.md5;
- chk.Value = md5ctx.End();
- trkChecksums.Add(chk);
-
- chk = new ChecksumType();
- chk.type = ChecksumTypeType.ripemd160;
- chk.Value = ripemd160ctx.End();
- trkChecksums.Add(chk);
-
- chk = new ChecksumType();
- chk.type = ChecksumTypeType.sha1;
- chk.Value = sha1ctx.End();
- trkChecksums.Add(chk);
-
- chk = new ChecksumType();
- chk.type = ChecksumTypeType.sha256;
- chk.Value = sha256ctx.End();
- trkChecksums.Add(chk);
-
- chk = new ChecksumType();
- chk.type = ChecksumTypeType.sha384;
- chk.Value = sha384ctx.End();
- trkChecksums.Add(chk);
-
- chk = new ChecksumType();
- chk.type = ChecksumTypeType.sha512;
- chk.Value = sha512ctx.End();
- trkChecksums.Add(chk);
-
- chk = new ChecksumType();
- chk.type = ChecksumTypeType.spamsum;
- chk.Value = ssctx.End();
- trkChecksums.Add(chk);
+ List trkChecksums = trkChkWorker.End();
xmlTrk.Checksums = trkChecksums.ToArray();
@@ -794,64 +456,7 @@ namespace DiscImageChef.Commands
// TODO: Packed subchannel has different size?
xmlTrk.SubChannel.Size = (xmlTrk.EndSector - xmlTrk.StartSector + 1) * 96;
- adler32ctx = new Adler32Context();
- crc16ctx = new CRC16Context();
- crc32ctx = new CRC32Context();
- crc64ctx = new CRC64Context();
- md5ctx = new MD5Context();
- ripemd160ctx = new RIPEMD160Context();
- sha1ctx = new SHA1Context();
- sha256ctx = new SHA256Context();
- sha384ctx = new SHA384Context();
- sha512ctx = new SHA512Context();
- ssctx = new SpamSumContext();
-
- adlerThread = new Thread(updateAdler);
- crc16Thread = new Thread(updateCRC16);
- crc32Thread = new Thread(updateCRC32);
- crc64Thread = new Thread(updateCRC64);
- md5Thread = new Thread(updateMD5);
- ripemd160Thread = new Thread(updateRIPEMD160);
- sha1Thread = new Thread(updateSHA1);
- sha256Thread = new Thread(updateSHA256);
- sha384Thread = new Thread(updateSHA384);
- sha512Thread = new Thread(updateSHA512);
- spamsumThread = new Thread(updateSpamSum);
-
- adlerPkt = new adlerPacket();
- crc16Pkt = new crc16Packet();
- crc32Pkt = new crc32Packet();
- crc64Pkt = new crc64Packet();
- md5Pkt = new md5Packet();
- ripemd160Pkt = new ripemd160Packet();
- sha1Pkt = new sha1Packet();
- sha256Pkt = new sha256Packet();
- sha384Pkt = new sha384Packet();
- sha512Pkt = new sha512Packet();
- spamsumPkt = new spamsumPacket();
-
- adler32ctx.Init();
- adlerPkt.context = adler32ctx;
- crc16ctx.Init();
- crc16Pkt.context = crc16ctx;
- crc32ctx.Init();
- crc32Pkt.context = crc32ctx;
- crc64ctx.Init();
- crc64Pkt.context = crc64ctx;
- md5ctx.Init();
- md5Pkt.context = md5ctx;
- ripemd160ctx.Init();
- ripemd160Pkt.context = ripemd160ctx;
- sha1ctx.Init();
- sha1Pkt.context = sha1ctx;
- sha256ctx.Init();
- sha256Pkt.context = sha256ctx;
- sha384ctx.Init();
- sha384Pkt.context = sha384ctx;
- sha512ctx.Init();
- sha512Pkt.context = sha512ctx;
- ssctx.Init();
- spamsumPkt.context = ssctx;
+ Core.Checksum subChkWorker = new DiscImageChef.Core.Checksum();
sectors = (ulong)(xmlTrk.EndSector - xmlTrk.StartSector + 1);
doneSectors = 0;
@@ -873,107 +478,10 @@ namespace DiscImageChef.Commands
doneSectors += (sectors - doneSectors);
}
- adlerPkt.data = sector;
- adlerThread.Start(adlerPkt);
- crc16Pkt.data = sector;
- crc16Thread.Start(crc16Pkt);
- crc32Pkt.data = sector;
- crc32Thread.Start(crc32Pkt);
- crc64Pkt.data = sector;
- crc64Thread.Start(crc64Pkt);
- md5Pkt.data = sector;
- md5Thread.Start(md5Pkt);
- ripemd160Pkt.data = sector;
- ripemd160Thread.Start(ripemd160Pkt);
- sha1Pkt.data = sector;
- sha1Thread.Start(sha1Pkt);
- sha256Pkt.data = sector;
- sha256Thread.Start(sha256Pkt);
- sha384Pkt.data = sector;
- sha384Thread.Start(sha384Pkt);
- sha512Pkt.data = sector;
- sha512Thread.Start(sha512Pkt);
- spamsumPkt.data = sector;
- spamsumThread.Start(spamsumPkt);
-
- while (adlerThread.IsAlive || crc16Thread.IsAlive ||
- crc32Thread.IsAlive || crc64Thread.IsAlive ||
- md5Thread.IsAlive || ripemd160Thread.IsAlive ||
- sha1Thread.IsAlive || sha256Thread.IsAlive ||
- sha384Thread.IsAlive || sha512Thread.IsAlive ||
- spamsumThread.IsAlive)
- {
- }
-
- adlerThread = new Thread(updateAdler);
- crc16Thread = new Thread(updateCRC16);
- crc32Thread = new Thread(updateCRC32);
- crc64Thread = new Thread(updateCRC64);
- md5Thread = new Thread(updateMD5);
- ripemd160Thread = new Thread(updateRIPEMD160);
- sha1Thread = new Thread(updateSHA1);
- sha256Thread = new Thread(updateSHA256);
- sha384Thread = new Thread(updateSHA384);
- sha512Thread = new Thread(updateSHA512);
- spamsumThread = new Thread(updateSpamSum);
+ subChkWorker.Update(sector);
}
- List subChecksums = new List();
-
- chk = new ChecksumType();
- chk.type = ChecksumTypeType.adler32;
- chk.Value = adler32ctx.End();
- subChecksums.Add(chk);
-
- chk = new ChecksumType();
- chk.type = ChecksumTypeType.crc16;
- chk.Value = crc16ctx.End();
- subChecksums.Add(chk);
-
- chk = new ChecksumType();
- chk.type = ChecksumTypeType.crc32;
- chk.Value = crc32ctx.End();
- subChecksums.Add(chk);
-
- chk = new ChecksumType();
- chk.type = ChecksumTypeType.crc64;
- chk.Value = crc64ctx.End();
- subChecksums.Add(chk);
-
- chk = new ChecksumType();
- chk.type = ChecksumTypeType.md5;
- chk.Value = md5ctx.End();
- subChecksums.Add(chk);
-
- chk = new ChecksumType();
- chk.type = ChecksumTypeType.ripemd160;
- chk.Value = ripemd160ctx.End();
- subChecksums.Add(chk);
-
- chk = new ChecksumType();
- chk.type = ChecksumTypeType.sha1;
- chk.Value = sha1ctx.End();
- subChecksums.Add(chk);
-
- chk = new ChecksumType();
- chk.type = ChecksumTypeType.sha256;
- chk.Value = sha256ctx.End();
- subChecksums.Add(chk);
-
- chk = new ChecksumType();
- chk.type = ChecksumTypeType.sha384;
- chk.Value = sha384ctx.End();
- subChecksums.Add(chk);
-
- chk = new ChecksumType();
- chk.type = ChecksumTypeType.sha512;
- chk.Value = sha512ctx.End();
- subChecksums.Add(chk);
-
- chk = new ChecksumType();
- chk.type = ChecksumTypeType.spamsum;
- chk.Value = ssctx.End();
- subChecksums.Add(chk);
+ List subChecksums = subChkWorker.End();
xmlTrk.SubChannel.Checksums = subChecksums.ToArray();
@@ -1103,46 +611,46 @@ namespace DiscImageChef.Commands
case MediaTagType.ATAPI_IDENTIFY:
sidecar.BlockMedia[0].ATA = new ATAType();
sidecar.BlockMedia[0].ATA.Identify = new DumpType();
- sidecar.BlockMedia[0].ATA.Identify.Checksums = GetChecksums(_imageFormat.ReadDiskTag(MediaTagType.ATAPI_IDENTIFY)).ToArray();
+ sidecar.BlockMedia[0].ATA.Identify.Checksums = Core.Checksum.GetChecksums(_imageFormat.ReadDiskTag(MediaTagType.ATAPI_IDENTIFY)).ToArray();
sidecar.BlockMedia[0].ATA.Identify.Size = _imageFormat.ReadDiskTag(MediaTagType.ATAPI_IDENTIFY).Length;
break;
case MediaTagType.ATA_IDENTIFY:
sidecar.BlockMedia[0].ATA = new ATAType();
sidecar.BlockMedia[0].ATA.Identify = new DumpType();
- sidecar.BlockMedia[0].ATA.Identify.Checksums = GetChecksums(_imageFormat.ReadDiskTag(MediaTagType.ATA_IDENTIFY)).ToArray();
+ sidecar.BlockMedia[0].ATA.Identify.Checksums = Core.Checksum.GetChecksums(_imageFormat.ReadDiskTag(MediaTagType.ATA_IDENTIFY)).ToArray();
sidecar.BlockMedia[0].ATA.Identify.Size = _imageFormat.ReadDiskTag(MediaTagType.ATA_IDENTIFY).Length;
break;
case MediaTagType.PCMCIA_CIS:
sidecar.BlockMedia[0].PCMCIA = new PCMCIAType();
sidecar.BlockMedia[0].PCMCIA.CIS = new DumpType();
- sidecar.BlockMedia[0].PCMCIA.CIS.Checksums = GetChecksums(_imageFormat.ReadDiskTag(MediaTagType.PCMCIA_CIS)).ToArray();
+ sidecar.BlockMedia[0].PCMCIA.CIS.Checksums = Core.Checksum.GetChecksums(_imageFormat.ReadDiskTag(MediaTagType.PCMCIA_CIS)).ToArray();
sidecar.BlockMedia[0].PCMCIA.CIS.Size = _imageFormat.ReadDiskTag(MediaTagType.PCMCIA_CIS).Length;
break;
case MediaTagType.SCSI_INQUIRY:
sidecar.BlockMedia[0].SCSI = new SCSIType();
sidecar.BlockMedia[0].SCSI.Inquiry = new DumpType();
- sidecar.BlockMedia[0].SCSI.Inquiry.Checksums = GetChecksums(_imageFormat.ReadDiskTag(MediaTagType.SCSI_INQUIRY)).ToArray();
+ sidecar.BlockMedia[0].SCSI.Inquiry.Checksums = Core.Checksum.GetChecksums(_imageFormat.ReadDiskTag(MediaTagType.SCSI_INQUIRY)).ToArray();
sidecar.BlockMedia[0].SCSI.Inquiry.Size = _imageFormat.ReadDiskTag(MediaTagType.SCSI_INQUIRY).Length;
break;
case MediaTagType.SD_CID:
if(sidecar.BlockMedia[0].SecureDigital == null)
sidecar.BlockMedia[0].SecureDigital = new SecureDigitalType();
sidecar.BlockMedia[0].SecureDigital.CID = new DumpType();
- sidecar.BlockMedia[0].SecureDigital.CID.Checksums = GetChecksums(_imageFormat.ReadDiskTag(MediaTagType.SD_CID)).ToArray();
+ sidecar.BlockMedia[0].SecureDigital.CID.Checksums = Core.Checksum.GetChecksums(_imageFormat.ReadDiskTag(MediaTagType.SD_CID)).ToArray();
sidecar.BlockMedia[0].SecureDigital.CID.Size = _imageFormat.ReadDiskTag(MediaTagType.SD_CID).Length;
break;
case MediaTagType.SD_CSD:
if(sidecar.BlockMedia[0].SecureDigital == null)
sidecar.BlockMedia[0].SecureDigital = new SecureDigitalType();
sidecar.BlockMedia[0].SecureDigital.CSD = new DumpType();
- sidecar.BlockMedia[0].SecureDigital.CSD.Checksums = GetChecksums(_imageFormat.ReadDiskTag(MediaTagType.SD_CSD)).ToArray();
+ sidecar.BlockMedia[0].SecureDigital.CSD.Checksums = Core.Checksum.GetChecksums(_imageFormat.ReadDiskTag(MediaTagType.SD_CSD)).ToArray();
sidecar.BlockMedia[0].SecureDigital.CSD.Size = _imageFormat.ReadDiskTag(MediaTagType.SD_CSD).Length;
break;
case MediaTagType.SD_ExtendedCSD:
if(sidecar.BlockMedia[0].SecureDigital == null)
sidecar.BlockMedia[0].SecureDigital = new SecureDigitalType();
sidecar.BlockMedia[0].SecureDigital.ExtendedCSD = new DumpType();
- sidecar.BlockMedia[0].SecureDigital.ExtendedCSD.Checksums = GetChecksums(_imageFormat.ReadDiskTag(MediaTagType.SD_ExtendedCSD)).ToArray();
+ sidecar.BlockMedia[0].SecureDigital.ExtendedCSD.Checksums = Core.Checksum.GetChecksums(_imageFormat.ReadDiskTag(MediaTagType.SD_ExtendedCSD)).ToArray();
sidecar.BlockMedia[0].SecureDigital.ExtendedCSD.Size = _imageFormat.ReadDiskTag(MediaTagType.SD_ExtendedCSD).Length;
break;
}
@@ -1360,297 +868,6 @@ namespace DiscImageChef.Commands
return String.Format("{3}:{0:D2}:{1:D2}:{2:D2}", m, s, f, h);
}
-
- static List GetChecksums(byte[] data)
- {
- Adler32Context adler32ctx = new Adler32Context();
- CRC16Context crc16ctx = new CRC16Context();
- CRC32Context crc32ctx = new CRC32Context();
- CRC64Context crc64ctx = new CRC64Context();
- MD5Context md5ctx = new MD5Context();
- RIPEMD160Context ripemd160ctx = new RIPEMD160Context();
- SHA1Context sha1ctx = new SHA1Context();
- SHA256Context sha256ctx = new SHA256Context();
- SHA384Context sha384ctx = new SHA384Context();
- SHA512Context sha512ctx = new SHA512Context();
- SpamSumContext ssctx = new SpamSumContext();
-
- Thread adlerThread = new Thread(updateAdler);
- Thread crc16Thread = new Thread(updateCRC16);
- Thread crc32Thread = new Thread(updateCRC32);
- Thread crc64Thread = new Thread(updateCRC64);
- Thread md5Thread = new Thread(updateMD5);
- Thread ripemd160Thread = new Thread(updateRIPEMD160);
- Thread sha1Thread = new Thread(updateSHA1);
- Thread sha256Thread = new Thread(updateSHA256);
- Thread sha384Thread = new Thread(updateSHA384);
- Thread sha512Thread = new Thread(updateSHA512);
- Thread spamsumThread = new Thread(updateSpamSum);
-
- adlerPacket adlerPkt = new adlerPacket();
- crc16Packet crc16Pkt = new crc16Packet();
- crc32Packet crc32Pkt = new crc32Packet();
- crc64Packet crc64Pkt = new crc64Packet();
- md5Packet md5Pkt = new md5Packet();
- ripemd160Packet ripemd160Pkt = new ripemd160Packet();
- sha1Packet sha1Pkt = new sha1Packet();
- sha256Packet sha256Pkt = new sha256Packet();
- sha384Packet sha384Pkt = new sha384Packet();
- sha512Packet sha512Pkt = new sha512Packet();
- spamsumPacket spamsumPkt = new spamsumPacket();
-
- adler32ctx.Init();
- adlerPkt.context = adler32ctx;
- crc16ctx.Init();
- crc16Pkt.context = crc16ctx;
- crc32ctx.Init();
- crc32Pkt.context = crc32ctx;
- crc64ctx.Init();
- crc64Pkt.context = crc64ctx;
- md5ctx.Init();
- md5Pkt.context = md5ctx;
- ripemd160ctx.Init();
- ripemd160Pkt.context = ripemd160ctx;
- sha1ctx.Init();
- sha1Pkt.context = sha1ctx;
- sha256ctx.Init();
- sha256Pkt.context = sha256ctx;
- sha384ctx.Init();
- sha384Pkt.context = sha384ctx;
- sha512ctx.Init();
- sha512Pkt.context = sha512ctx;
- ssctx.Init();
- spamsumPkt.context = ssctx;
-
- adlerPkt.data = data;
- adlerThread.Start(adlerPkt);
- crc16Pkt.data = data;
- crc16Thread.Start(crc16Pkt);
- crc32Pkt.data = data;
- crc32Thread.Start(crc32Pkt);
- crc64Pkt.data = data;
- crc64Thread.Start(crc64Pkt);
- md5Pkt.data = data;
- md5Thread.Start(md5Pkt);
- ripemd160Pkt.data = data;
- ripemd160Thread.Start(ripemd160Pkt);
- sha1Pkt.data = data;
- sha1Thread.Start(sha1Pkt);
- sha256Pkt.data = data;
- sha256Thread.Start(sha256Pkt);
- sha384Pkt.data = data;
- sha384Thread.Start(sha384Pkt);
- sha512Pkt.data = data;
- sha512Thread.Start(sha512Pkt);
- spamsumPkt.data = data;
- spamsumThread.Start(spamsumPkt);
-
- while (adlerThread.IsAlive || crc16Thread.IsAlive ||
- crc32Thread.IsAlive || crc64Thread.IsAlive ||
- md5Thread.IsAlive || ripemd160Thread.IsAlive ||
- sha1Thread.IsAlive || sha256Thread.IsAlive ||
- sha384Thread.IsAlive || sha512Thread.IsAlive ||
- spamsumThread.IsAlive)
- {
- }
-
- List imgChecksums = new List();
- ChecksumType chk = new ChecksumType();
-
- chk.type = ChecksumTypeType.adler32;
- chk.Value = adler32ctx.End();
- imgChecksums.Add(chk);
-
- chk.type = ChecksumTypeType.crc16;
- chk.Value = crc16ctx.End();
- imgChecksums.Add(chk);
-
- chk.type = ChecksumTypeType.crc32;
- chk.Value = crc32ctx.End();
- imgChecksums.Add(chk);
-
- chk.type = ChecksumTypeType.crc64;
- chk.Value = crc64ctx.End();
- imgChecksums.Add(chk);
-
- chk.type = ChecksumTypeType.md5;
- chk.Value = md5ctx.End();
- imgChecksums.Add(chk);
-
- chk.type = ChecksumTypeType.ripemd160;
- chk.Value = ripemd160ctx.End();
- imgChecksums.Add(chk);
-
- chk.type = ChecksumTypeType.sha1;
- chk.Value = sha1ctx.End();
- imgChecksums.Add(chk);
-
- chk.type = ChecksumTypeType.sha256;
- chk.Value = sha256ctx.End();
- imgChecksums.Add(chk);
-
- chk.type = ChecksumTypeType.sha384;
- chk.Value = sha384ctx.End();
- imgChecksums.Add(chk);
-
- chk.type = ChecksumTypeType.sha512;
- chk.Value = sha512ctx.End();
- imgChecksums.Add(chk);
-
- chk.type = ChecksumTypeType.spamsum;
- chk.Value = ssctx.End();
- imgChecksums.Add(chk);
-
- return imgChecksums;
- }
-
- #region Threading helpers
-
- struct adlerPacket
- {
- public Adler32Context context;
- public byte[] data;
- }
-
- struct crc16Packet
- {
- public CRC16Context context;
- public byte[] data;
- }
-
- struct crc32Packet
- {
- public CRC32Context context;
- public byte[] data;
- }
-
- struct crc64Packet
- {
- public CRC64Context context;
- public byte[] data;
- }
-
- /*struct fletcher16Packet
- {
- public Fletcher16Context context;
- public byte[] data;
- }
-
- struct fletcher32Packet
- {
- public Fletcher32Context context;
- public byte[] data;
- }*/
-
- struct md5Packet
- {
- public MD5Context context;
- public byte[] data;
- }
-
- struct ripemd160Packet
- {
- public RIPEMD160Context context;
- public byte[] data;
- }
-
- struct sha1Packet
- {
- public SHA1Context context;
- public byte[] data;
- }
-
- struct sha256Packet
- {
- public SHA256Context context;
- public byte[] data;
- }
-
- struct sha384Packet
- {
- public SHA384Context context;
- public byte[] data;
- }
-
- struct sha512Packet
- {
- public SHA512Context context;
- public byte[] data;
- }
-
- struct spamsumPacket
- {
- public SpamSumContext context;
- public byte[] data;
- }
-
- static void updateAdler(object packet)
- {
- ((adlerPacket)packet).context.Update(((adlerPacket)packet).data);
- }
-
- static void updateCRC16(object packet)
- {
- ((crc16Packet)packet).context.Update(((crc16Packet)packet).data);
- }
-
- static void updateCRC32(object packet)
- {
- ((crc32Packet)packet).context.Update(((crc32Packet)packet).data);
- }
-
- static void updateCRC64(object packet)
- {
- ((crc64Packet)packet).context.Update(((crc64Packet)packet).data);
- }
-
- /*static void updateFletcher16(object packet)
- {
- ((fletcher16Packet)packet).context.Update(((fletcher16Packet)packet).data);
- }
-
- static void updateFletcher32(object packet)
- {
- ((fletcher32Packet)packet).context.Update(((fletcher32Packet)packet).data);
- }*/
-
- static void updateMD5(object packet)
- {
- ((md5Packet)packet).context.Update(((md5Packet)packet).data);
- }
-
- static void updateRIPEMD160(object packet)
- {
- ((ripemd160Packet)packet).context.Update(((ripemd160Packet)packet).data);
- }
-
- static void updateSHA1(object packet)
- {
- ((sha1Packet)packet).context.Update(((sha1Packet)packet).data);
- }
-
- static void updateSHA256(object packet)
- {
- ((sha256Packet)packet).context.Update(((sha256Packet)packet).data);
- }
-
- static void updateSHA384(object packet)
- {
- ((sha384Packet)packet).context.Update(((sha384Packet)packet).data);
- }
-
- static void updateSHA512(object packet)
- {
- ((sha512Packet)packet).context.Update(((sha512Packet)packet).data);
- }
-
- static void updateSpamSum(object packet)
- {
- ((spamsumPacket)packet).context.Update(((spamsumPacket)packet).data);
- }
-
- #endregion Threading helpers
-
}
}
diff --git a/DiscImageChef/Commands/DeviceInfo.cs b/DiscImageChef/Commands/DeviceInfo.cs
index 8f011c03..3c9be34b 100644
--- a/DiscImageChef/Commands/DeviceInfo.cs
+++ b/DiscImageChef/Commands/DeviceInfo.cs
@@ -164,7 +164,7 @@ namespace DiscImageChef.Commands
if (dev.Type != DeviceType.ATAPI)
DicConsole.WriteLine("SCSI device");
- doWriteFile(options.OutputPrefix, "_scsi_inquiry.bin", "SCSI IDENTIFY", inqBuf);
+ doWriteFile(options.OutputPrefix, "_scsi_inquiry.bin", "SCSI INQUIRY", inqBuf);
Decoders.SCSI.Inquiry.SCSIInquiry? inq = Decoders.SCSI.Inquiry.Decode(inqBuf);
DicConsole.WriteLine(Decoders.SCSI.Inquiry.Prettify(inq));
@@ -237,10 +237,10 @@ namespace DiscImageChef.Commands
Decoders.SCSI.Modes.DecodedMode? decMode = null;
Decoders.SCSI.PeripheralDeviceTypes devType = (DiscImageChef.Decoders.SCSI.PeripheralDeviceTypes)inq.Value.PeripheralDeviceType;
- sense = dev.ModeSense10(out modeBuf, out senseBuf, false, true, ScsiModeSensePageControl.Current, 0x3F, 0xFF, dev.Timeout, out duration);
+ sense = dev.ModeSense10(out modeBuf, out senseBuf, false, true, ScsiModeSensePageControl.Current, 0x3F, 0xFF, 5, out duration);
if (sense || dev.Error)
{
- sense = dev.ModeSense10(out modeBuf, out senseBuf, false, true, ScsiModeSensePageControl.Current, 0x3F, 0x00, dev.Timeout, out duration);
+ sense = dev.ModeSense10(out modeBuf, out senseBuf, false, true, ScsiModeSensePageControl.Current, 0x3F, 0x00, 5, out duration);
}
if (!sense && !dev.Error)
@@ -250,11 +250,11 @@ namespace DiscImageChef.Commands
if(sense || dev.Error || !decMode.HasValue)
{
- sense = dev.ModeSense6(out modeBuf, out senseBuf, false, ScsiModeSensePageControl.Current, 0x3F, 0x00, dev.Timeout, out duration);
+ sense = dev.ModeSense6(out modeBuf, out senseBuf, false, ScsiModeSensePageControl.Current, 0x3F, 0xFF, 5, out duration);
if (sense || dev.Error)
- sense = dev.ModeSense6(out modeBuf, out senseBuf, false, ScsiModeSensePageControl.Current, 0x3F, 0x00, dev.Timeout, out duration);
+ sense = dev.ModeSense6(out modeBuf, out senseBuf, false, ScsiModeSensePageControl.Current, 0x3F, 0x00, 5, out duration);
if (sense || dev.Error)
- sense = dev.ModeSense(out modeBuf, out senseBuf, 15000, out duration);
+ sense = dev.ModeSense(out modeBuf, out senseBuf, 5, out duration);
if (!sense && !dev.Error)
decMode = Decoders.SCSI.Modes.DecodeMode6(modeBuf, devType);
@@ -477,7 +477,7 @@ namespace DiscImageChef.Commands
}
case 0x3E:
{
- if (StringHandlers.SpacePaddedToString(inq.Value.VendorIdentification) == "FUJITSU")
+ if (StringHandlers.CToString(inq.Value.VendorIdentification).Trim() == "FUJITSU")
DicConsole.WriteLine(Decoders.SCSI.Modes.PrettifyFujitsuModePage_3E(page.PageResponse));
else
goto default;
diff --git a/DiscImageChef/Commands/DeviceReport.cs b/DiscImageChef/Commands/DeviceReport.cs
new file mode 100644
index 00000000..ae5062bd
--- /dev/null
+++ b/DiscImageChef/Commands/DeviceReport.cs
@@ -0,0 +1,3451 @@
+// /***************************************************************************
+// The Disc Image Chef
+// ----------------------------------------------------------------------------
+//
+// Filename : DeviceReport.cs
+// Version : 1.0
+// Author(s) : Natalia Portillo
+//
+// Component : Component
+//
+// Revision : $Revision$
+// Last change by : $Author$
+// Date : $Date$
+//
+// --[ Description ] ----------------------------------------------------------
+//
+// Description
+//
+// --[ License ] --------------------------------------------------------------
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+//
+// ----------------------------------------------------------------------------
+// Copyright (C) 2011-2015 Claunia.com
+// ****************************************************************************/
+// //$Id$
+using System;
+using DiscImageChef.Console;
+using DiscImageChef.Devices;
+using DiscImageChef.Metadata;
+using System.IO;
+using System.Collections.Generic;
+
+namespace DiscImageChef.Commands
+{
+ public static class DeviceReport
+ {
+ public static void doDeviceReport(DeviceReportSubOptions options)
+ {
+ DicConsole.DebugWriteLine("Device-Report command", "--debug={0}", options.Debug);
+ DicConsole.DebugWriteLine("Device-Report command", "--verbose={0}", options.Verbose);
+ DicConsole.DebugWriteLine("Device-Report command", "--device={0}", options.DevicePath);
+
+ if (options.DevicePath.Length == 2 && options.DevicePath[1] == ':' &&
+ options.DevicePath[0] != '/' && Char.IsLetter(options.DevicePath[0]))
+ {
+ options.DevicePath = "\\\\.\\" + Char.ToUpper(options.DevicePath[0]) + ':';
+ }
+
+ Device dev = new Device(options.DevicePath);
+
+ if (dev.Error)
+ {
+ DicConsole.ErrorWriteLine("Error {0} opening device.", dev.LastError);
+ return;
+ }
+
+ switch (dev.Type)
+ {
+ case DeviceType.ATA:
+ doATADeviceReport(options, dev);
+ break;
+ case DeviceType.MMC:
+ case DeviceType.SecureDigital:
+ doSDDeviceReport(options, dev);
+ break;
+ case DeviceType.NVMe:
+ doNVMeDeviceReport(options, dev);
+ break;
+ case DeviceType.ATAPI:
+ case DeviceType.SCSI:
+ doSCSIDeviceReport(options, dev);
+ break;
+ default:
+ throw new NotSupportedException("Unknown device type.");
+ }
+ }
+
+ static void doATADeviceReport(DeviceReportSubOptions options, Device dev)
+ {
+ DiscImageChef.Decoders.ATA.AtaErrorRegistersCHS errorRegs;
+ byte[] buffer;
+ double duration;
+ uint timeout = 5;
+ Metadata.DeviceReport report = new Metadata.DeviceReport();
+ string xmlFile;
+ if (!string.IsNullOrWhiteSpace(dev.Manufacturer) && !string.IsNullOrWhiteSpace(dev.Revision))
+ xmlFile = dev.Manufacturer + "_" + dev.Model + "_" + dev.Revision + ".xml";
+ else if (!string.IsNullOrWhiteSpace(dev.Manufacturer))
+ xmlFile = dev.Manufacturer + "_" + dev.Model + ".xml";
+ else if (!string.IsNullOrWhiteSpace(dev.Revision))
+ xmlFile = dev.Model + "_" + dev.Revision + ".xml";
+ else
+ xmlFile = dev.Model + ".xml";
+
+ ConsoleKeyInfo pressedKey;
+
+ if (dev.IsUSB)
+ {
+ pressedKey = new ConsoleKeyInfo();
+ while (pressedKey.Key != ConsoleKey.Y && pressedKey.Key != ConsoleKey.N)
+ {
+ DicConsole.Write("Is the device natively USB (in case of doubt, press Y)? (Y/N): ");
+ pressedKey = System.Console.ReadKey();
+ DicConsole.WriteLine();
+ }
+
+ if (pressedKey.Key == ConsoleKey.Y)
+ {
+ report.USB = new usbType();
+ report.USB.Manufacturer = dev.USBManufacturerString;
+ report.USB.Product = dev.USBProductString;
+ report.USB.ProductID = dev.USBProductID;
+ report.USB.VendorID = dev.USBVendorID;
+
+ pressedKey = new ConsoleKeyInfo();
+ while (pressedKey.Key != ConsoleKey.Y && pressedKey.Key != ConsoleKey.N)
+ {
+ DicConsole.Write("Is the media removable from the reading/writing elements? (Y/N): ");
+ pressedKey = System.Console.ReadKey();
+ DicConsole.WriteLine();
+ }
+
+ report.USB.RemovableMedia = pressedKey.Key == ConsoleKey.Y;
+ }
+ }
+
+ if (dev.IsFireWire)
+ {
+ pressedKey = new ConsoleKeyInfo();
+ while (pressedKey.Key != ConsoleKey.Y && pressedKey.Key != ConsoleKey.N)
+ {
+ DicConsole.Write("Is the device natively FireWire (in case of doubt, press Y)? (Y/N): ");
+ pressedKey = System.Console.ReadKey();
+ DicConsole.WriteLine();
+ }
+
+ if (pressedKey.Key == ConsoleKey.Y)
+ {
+ report.FireWire = new firewireType();
+ report.FireWire.Manufacturer = dev.FireWireVendorName;
+ report.FireWire.Product = dev.FireWireModelName;
+ report.FireWire.ProductID = dev.FireWireModel;
+ report.FireWire.VendorID = dev.FireWireVendor;
+
+ pressedKey = new ConsoleKeyInfo();
+ while (pressedKey.Key != ConsoleKey.Y && pressedKey.Key != ConsoleKey.N)
+ {
+ DicConsole.Write("Is the media removable from the reading/writing elements? (Y/N): ");
+ pressedKey = System.Console.ReadKey();
+ DicConsole.WriteLine();
+ }
+
+ report.FireWire.RemovableMedia = pressedKey.Key == ConsoleKey.Y;
+ }
+ }
+
+ DicConsole.WriteLine("Querying ATA IDENTIFY...");
+
+ dev.AtaIdentify(out buffer, out errorRegs, timeout, out duration);
+
+ if (Decoders.ATA.Identify.Decode(buffer).HasValue)
+ {
+ Decoders.ATA.Identify.IdentifyDevice ataId = Decoders.ATA.Identify.Decode(buffer).Value;
+
+ report.ATA = new ataType();
+
+ if (ataId.CurrentCylinders != 0 ||
+ ataId.CurrentHeads != 0 ||
+ ataId.CurrentSectorsPerTrack != 0)
+ {
+ report.ATA.CHS = new chsType();
+ report.ATA.CHS.Cylinders = ataId.Cylinders;
+ report.ATA.CHS.Heads = ataId.Heads;
+ report.ATA.CHS.Sectors = ataId.SectorsPerTrack;
+ }
+
+ if ((ataId.Cylinders != ataId.CurrentCylinders ||
+ ataId.Heads != ataId.CurrentHeads ||
+ ataId.SectorsPerTrack != ataId.CurrentSectorsPerTrack) &&
+ (ataId.CurrentCylinders != 0 ||
+ ataId.CurrentHeads != 0 ||
+ ataId.CurrentSectorsPerTrack != 0))
+ {
+ report.ATA.CurrentCHS = new chsType();
+ report.ATA.CurrentCHS.Cylinders = ataId.CurrentCylinders;
+ report.ATA.CurrentCHS.Heads = ataId.CurrentHeads;
+ report.ATA.CurrentCHS.Sectors = ataId.CurrentSectorsPerTrack;
+ }
+
+ if (ataId.Capabilities.HasFlag(Decoders.ATA.Identify.CapabilitiesBit.LBASupport) && ataId.LBASectors != 0)
+ {
+ report.ATA.LBASectors = ataId.LBASectors;
+ report.ATA.LBASectorsSpecified = true;
+
+ if (ataId.LBASectors != 0 && ataId.LBASectors != ataId.CurrentSectors)
+ {
+ report.ATA.LBASectorsCurrent = ataId.LBASectors;
+ report.ATA.LBASectorsCurrentSpecified = true;
+ }
+ }
+
+ if (ataId.CommandSet2.HasFlag(Decoders.ATA.Identify.CommandSetBit2.LBA48) && ataId.LBA48Sectors != 0)
+ {
+ report.ATA.LBA48Sectors = ataId.LBA48Sectors;
+ report.ATA.LBA48SectorsSpecified = true;
+ }
+
+ 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.EccBytes != 0)
+ {
+ report.ATA.EccBytes = ataId.EccBytes;
+ report.ATA.EccBytesSpecified = 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.LogicalAlignment != 0)
+ {
+ report.ATA.LogicalAlignment = ataId.LogicalAlignment;
+ report.ATA.LogicalAlignmentSpecified = true;
+ }
+ if (ataId.LogicalSectorWords != 0)
+ {
+ report.ATA.LogicalSectorWords = ataId.LogicalSectorWords;
+ report.ATA.LogicalSectorWordsSpecified = 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.NominalRotationRate != 0)
+ {
+ report.ATA.NominalRotationRate = ataId.NominalRotationRate;
+ report.ATA.NominalRotationRateSpecified = true;
+ }
+ if (ataId.PacketBusRelease != 0)
+ {
+ report.ATA.PacketBusRelease = ataId.PacketBusRelease;
+ report.ATA.PacketBusReleaseSpecified = true;
+ }
+ if (ataId.PhysLogSectorSize != 0)
+ {
+ report.ATA.PhysLogSectorSize = ataId.PhysLogSectorSize;
+ report.ATA.PhysLogSectorSizeSpecified = 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.UnformattedBPT != 0)
+ {
+ report.ATA.UnformattedBPT = ataId.UnformattedBPT;
+ report.ATA.UnformattedBPTSpecified = true;
+ }
+ if (ataId.UnformattedBPS != 0)
+ {
+ report.ATA.UnformattedBPS = ataId.UnformattedBPS;
+ report.ATA.UnformattedBPSSpecified = 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;
+ }
+ }
+
+ FileStream xmlFs = new FileStream(xmlFile, FileMode.Create);
+
+ System.Xml.Serialization.XmlSerializer xmlSer = new System.Xml.Serialization.XmlSerializer(typeof(Metadata.DeviceReport));
+ xmlSer.Serialize(xmlFs, report);
+ xmlFs.Close();
+ }
+
+ static void doNVMeDeviceReport(DeviceReportSubOptions options, Device dev)
+ {
+ throw new NotImplementedException("NVMe devices not yet supported.");
+ }
+
+ static void doSDDeviceReport(DeviceReportSubOptions options, Device dev)
+ {
+ throw new NotImplementedException("MMC/SD devices not yet supported.");
+ }
+
+ static void doSCSIDeviceReport(DeviceReportSubOptions options, Device dev)
+ {
+ byte[] senseBuffer;
+ byte[] buffer;
+ double duration;
+ bool sense;
+ uint timeout = 5;
+ Metadata.DeviceReport report = new Metadata.DeviceReport();
+ string xmlFile;
+ if (!string.IsNullOrWhiteSpace(dev.Manufacturer) && !string.IsNullOrWhiteSpace(dev.Revision))
+ xmlFile = dev.Manufacturer + "_" + dev.Model + "_" + dev.Revision + ".xml";
+ else if (!string.IsNullOrWhiteSpace(dev.Manufacturer))
+ xmlFile = dev.Manufacturer + "_" + dev.Model + ".xml";
+ else if (!string.IsNullOrWhiteSpace(dev.Revision))
+ xmlFile = dev.Model + "_" + dev.Revision + ".xml";
+ else
+ xmlFile = dev.Model + ".xml";
+ ConsoleKeyInfo pressedKey;
+ bool removable = true;
+
+ if (dev.IsUSB)
+ {
+ pressedKey = new ConsoleKeyInfo();
+ while (pressedKey.Key != ConsoleKey.Y && pressedKey.Key != ConsoleKey.N)
+ {
+ DicConsole.Write("Is the device natively USB (in case of doubt, press Y)? (Y/N): ");
+ pressedKey = System.Console.ReadKey();
+ DicConsole.WriteLine();
+ }
+
+ if (pressedKey.Key == ConsoleKey.Y)
+ {
+ report.USB = new usbType();
+ report.USB.Manufacturer = dev.USBManufacturerString;
+ report.USB.Product = dev.USBProductString;
+ report.USB.ProductID = dev.USBProductID;
+ report.USB.VendorID = dev.USBVendorID;
+
+ pressedKey = new ConsoleKeyInfo();
+ while (pressedKey.Key != ConsoleKey.Y && pressedKey.Key != ConsoleKey.N)
+ {
+ DicConsole.Write("Is the media removable from the reading/writing elements? (Y/N): ");
+ pressedKey = System.Console.ReadKey();
+ DicConsole.WriteLine();
+ }
+
+ report.USB.RemovableMedia = pressedKey.Key == ConsoleKey.Y;
+ removable = report.USB.RemovableMedia;
+ }
+ }
+
+ if (dev.IsFireWire)
+ {
+ pressedKey = new ConsoleKeyInfo();
+ while (pressedKey.Key != ConsoleKey.Y && pressedKey.Key != ConsoleKey.N)
+ {
+ DicConsole.Write("Is the device natively FireWire (in case of doubt, press Y)? (Y/N): ");
+ pressedKey = System.Console.ReadKey();
+ DicConsole.WriteLine();
+ }
+
+ if (pressedKey.Key == ConsoleKey.Y)
+ {
+ report.FireWire = new firewireType();
+ report.FireWire.Manufacturer = dev.FireWireVendorName;
+ report.FireWire.Product = dev.FireWireModelName;
+ report.FireWire.ProductID = dev.FireWireModel;
+ report.FireWire.VendorID = dev.FireWireVendor;
+
+ pressedKey = new ConsoleKeyInfo();
+ while (pressedKey.Key != ConsoleKey.Y && pressedKey.Key != ConsoleKey.N)
+ {
+ DicConsole.Write("Is the media removable from the reading/writing elements? (Y/N): ");
+ pressedKey = System.Console.ReadKey();
+ DicConsole.WriteLine();
+ }
+
+ report.FireWire.RemovableMedia = pressedKey.Key == ConsoleKey.Y;
+ removable = report.FireWire.RemovableMedia;
+ }
+ }
+
+ if (!dev.IsUSB && !dev.IsFireWire && dev.IsRemovable)
+ {
+ pressedKey = new ConsoleKeyInfo();
+ while (pressedKey.Key != ConsoleKey.Y && pressedKey.Key != ConsoleKey.N)
+ {
+ DicConsole.Write("Is the media removable from the reading/writing elements (flash memories ARE NOT removable)? (Y/N): ");
+ pressedKey = System.Console.ReadKey();
+ DicConsole.WriteLine();
+ }
+
+ removable = pressedKey.Key == ConsoleKey.Y;
+ }
+
+ if (dev.Type == DeviceType.ATAPI)
+ {
+ DicConsole.WriteLine("Querying ATAPI IDENTIFY...");
+
+ DiscImageChef.Decoders.ATA.AtaErrorRegistersCHS errorRegs;
+ dev.AtapiIdentify(out buffer, out errorRegs, timeout, out duration);
+
+ if (Decoders.ATA.Identify.Decode(buffer).HasValue)
+ {
+ Decoders.ATA.Identify.IdentifyDevice atapiId = Decoders.ATA.Identify.Decode(buffer).Value;
+
+ report.ATAPI = new ataType();
+
+ if (atapiId.CurrentCylinders != 0 ||
+ atapiId.CurrentHeads != 0 ||
+ atapiId.CurrentSectorsPerTrack != 0)
+ {
+ report.ATAPI.CHS = new chsType();
+ report.ATAPI.CHS.Cylinders = atapiId.Cylinders;
+ report.ATAPI.CHS.Heads = atapiId.Heads;
+ report.ATAPI.CHS.Sectors = atapiId.SectorsPerTrack;
+ }
+
+ if ((atapiId.Cylinders != atapiId.CurrentCylinders ||
+ atapiId.Heads != atapiId.CurrentHeads ||
+ atapiId.SectorsPerTrack != atapiId.CurrentSectorsPerTrack) &&
+ (atapiId.CurrentCylinders != 0 ||
+ atapiId.CurrentHeads != 0 ||
+ atapiId.CurrentSectorsPerTrack != 0))
+ {
+ report.ATAPI.CurrentCHS = new chsType();
+ report.ATAPI.CurrentCHS.Cylinders = atapiId.CurrentCylinders;
+ report.ATAPI.CurrentCHS.Heads = atapiId.CurrentHeads;
+ report.ATAPI.CurrentCHS.Sectors = atapiId.CurrentSectorsPerTrack;
+ }
+
+ if (atapiId.Capabilities.HasFlag(Decoders.ATA.Identify.CapabilitiesBit.LBASupport) && atapiId.LBASectors != 0)
+ {
+ report.ATAPI.LBASectors = atapiId.LBASectors;
+ report.ATAPI.LBASectorsSpecified = true;
+
+ if (atapiId.LBASectors != 0 && atapiId.LBASectors != atapiId.CurrentSectors)
+ {
+ report.ATAPI.LBASectorsCurrent = atapiId.LBASectors;
+ report.ATAPI.LBASectorsCurrentSpecified = true;
+ }
+ }
+
+ if (atapiId.CommandSet2.HasFlag(Decoders.ATA.Identify.CommandSetBit2.LBA48) && atapiId.LBA48Sectors != 0)
+ {
+ report.ATAPI.LBA48Sectors = atapiId.LBA48Sectors;
+ report.ATAPI.LBA48SectorsSpecified = 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.EccBytes != 0)
+ {
+ report.ATAPI.EccBytes = atapiId.EccBytes;
+ report.ATAPI.EccBytesSpecified = 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.LogicalAlignment != 0)
+ {
+ report.ATAPI.LogicalAlignment = atapiId.LogicalAlignment;
+ report.ATAPI.LogicalAlignmentSpecified = true;
+ }
+ if (atapiId.LogicalSectorWords != 0)
+ {
+ report.ATAPI.LogicalSectorWords = atapiId.LogicalSectorWords;
+ report.ATAPI.LogicalSectorWordsSpecified = 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.NominalRotationRate != 0)
+ {
+ report.ATAPI.NominalRotationRate = atapiId.NominalRotationRate;
+ report.ATAPI.NominalRotationRateSpecified = true;
+ }
+ if (atapiId.PacketBusRelease != 0)
+ {
+ report.ATAPI.PacketBusRelease = atapiId.PacketBusRelease;
+ report.ATAPI.PacketBusReleaseSpecified = true;
+ }
+ if (atapiId.PhysLogSectorSize != 0)
+ {
+ report.ATAPI.PhysLogSectorSize = atapiId.PhysLogSectorSize;
+ report.ATAPI.PhysLogSectorSizeSpecified = 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.UnformattedBPT != 0)
+ {
+ report.ATAPI.UnformattedBPT = atapiId.UnformattedBPT;
+ report.ATAPI.UnformattedBPTSpecified = true;
+ }
+ if (atapiId.UnformattedBPS != 0)
+ {
+ report.ATAPI.UnformattedBPS = atapiId.UnformattedBPS;
+ report.ATAPI.UnformattedBPSSpecified = 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;
+ }
+ }
+ }
+
+ DicConsole.WriteLine("Querying SCSI INQUIRY...");
+ sense = dev.ScsiInquiry(out buffer, out senseBuffer);
+
+ report.SCSI = new scsiType();
+
+ if (!sense && Decoders.SCSI.Inquiry.Decode(buffer).HasValue)
+ {
+ Decoders.SCSI.Inquiry.SCSIInquiry inq = Decoders.SCSI.Inquiry.Decode(buffer).Value;
+
+ List versionDescriptors = new List();
+ report.SCSI.Inquiry = new scsiInquiryType();
+
+ if (inq.DeviceTypeModifier != 0)
+ {
+ report.SCSI.Inquiry.DeviceTypeModifier = inq.DeviceTypeModifier;
+ report.SCSI.Inquiry.DeviceTypeModifierSpecified = true;
+ }
+ if (inq.ISOVersion != 0)
+ {
+ report.SCSI.Inquiry.ISOVersion = inq.ISOVersion;
+ report.SCSI.Inquiry.ISOVersionSpecified = true;
+ }
+ if (inq.ECMAVersion != 0)
+ {
+ report.SCSI.Inquiry.ECMAVersion = inq.ECMAVersion;
+ report.SCSI.Inquiry.ECMAVersionSpecified = true;
+ }
+ if (inq.ANSIVersion != 0)
+ {
+ report.SCSI.Inquiry.ANSIVersion = inq.ANSIVersion;
+ report.SCSI.Inquiry.ANSIVersionSpecified = true;
+ }
+ if (inq.ResponseDataFormat != 0)
+ {
+ report.SCSI.Inquiry.ResponseDataFormat = inq.ResponseDataFormat;
+ report.SCSI.Inquiry.ResponseDataFormatSpecified = true;
+ }
+ if (!string.IsNullOrWhiteSpace(StringHandlers.CToString(inq.VendorIdentification).Trim()))
+ {
+ report.SCSI.Inquiry.VendorIdentification = StringHandlers.CToString(inq.VendorIdentification).Trim();
+ report.SCSI.Inquiry.VendorIdentificationSpecified = true;
+ }
+ if (!string.IsNullOrWhiteSpace(StringHandlers.CToString(inq.ProductIdentification).Trim()))
+ {
+ report.SCSI.Inquiry.ProductIdentification = StringHandlers.CToString(inq.ProductIdentification).Trim();
+ report.SCSI.Inquiry.ProductIdentificationSpecified = true;
+ }
+ if (!string.IsNullOrWhiteSpace(StringHandlers.CToString(inq.ProductRevisionLevel).Trim()))
+ {
+ report.SCSI.Inquiry.ProductRevisionLevel = StringHandlers.CToString(inq.ProductRevisionLevel).Trim();
+ report.SCSI.Inquiry.ProductRevisionLevelSpecified = true;
+ }
+ if (inq.VersionDescriptors != null)
+ {
+ foreach (UInt16 descriptor in inq.VersionDescriptors)
+ {
+ if (descriptor != 0)
+ versionDescriptors.Add(descriptor);
+ }
+
+ if (versionDescriptors.Count > 0)
+ report.SCSI.Inquiry.VersionDescriptors = versionDescriptors.ToArray();
+ }
+
+ report.SCSI.Inquiry.PeripheralQualifier = (Decoders.SCSI.PeripheralQualifiers)inq.PeripheralQualifier;
+ report.SCSI.Inquiry.PeripheralDeviceType = (Decoders.SCSI.PeripheralDeviceTypes)inq.PeripheralDeviceType;
+ report.SCSI.Inquiry.AsymmetricalLUNAccess = (Decoders.SCSI.TGPSValues)inq.TPGS;
+ report.SCSI.Inquiry.SPIClocking = (Decoders.SCSI.SPIClocking)inq.Clocking;
+
+ report.SCSI.Inquiry.AccessControlCoordinator = inq.ACC;
+ report.SCSI.Inquiry.ACKRequests = inq.ACKREQQ;
+ report.SCSI.Inquiry.AERCSupported = inq.AERC;
+ report.SCSI.Inquiry.Address16 = inq.Addr16;
+ report.SCSI.Inquiry.Address32 = inq.Addr32;
+ report.SCSI.Inquiry.BasicQueueing = inq.BQue;
+ report.SCSI.Inquiry.EnclosureServices = inq.EncServ;
+ report.SCSI.Inquiry.HierarchicalLUN = inq.HiSup;
+ report.SCSI.Inquiry.IUS = inq.IUS;
+ report.SCSI.Inquiry.LinkedCommands = inq.Linked;
+ report.SCSI.Inquiry.MediumChanger = inq.MChngr;
+ report.SCSI.Inquiry.MultiPortDevice = inq.MultiP;
+ report.SCSI.Inquiry.NormalACA = inq.NormACA;
+ report.SCSI.Inquiry.Protection = inq.Protect;
+ report.SCSI.Inquiry.QAS = inq.QAS;
+ report.SCSI.Inquiry.RelativeAddressing = inq.RelAddr;
+ report.SCSI.Inquiry.Removable = inq.RMB;
+ report.SCSI.Inquiry.TaggedCommandQueue = inq.CmdQue;
+ report.SCSI.Inquiry.TerminateTaskSupported = inq.TrmTsk;
+ report.SCSI.Inquiry.ThirdPartyCopy = inq.ThreePC;
+ report.SCSI.Inquiry.TranferDisable = inq.TranDis;
+ report.SCSI.Inquiry.SoftReset = inq.SftRe;
+ report.SCSI.Inquiry.StorageArrayController = inq.SCCS;
+ report.SCSI.Inquiry.SyncTransfer = inq.Sync;
+ report.SCSI.Inquiry.WideBus16 = inq.WBus16;
+ report.SCSI.Inquiry.WideBus32 = inq.WBus32;
+ }
+
+ DicConsole.WriteLine("Querying list of SCSI EVPDs...");
+ sense = dev.ScsiInquiry(out buffer, out senseBuffer, 0x00);
+
+ if (!sense)
+ {
+ byte[] evpdPages = Decoders.SCSI.EVPD.DecodePage00(buffer);
+ if (evpdPages != null && evpdPages.Length > 0)
+ {
+ List evpds = new List();
+ foreach (byte page in evpdPages)
+ {
+ if (page != 0x80)
+ {
+ DicConsole.WriteLine("Querying SCSI EVPD {0:X2}h...", page);
+ sense = dev.ScsiInquiry(out buffer, out senseBuffer, page);
+ if (!sense)
+ {
+ pageType evpd = new pageType();
+ evpd.page = page;
+ evpd.value = buffer;
+ evpds.Add(evpd);
+ }
+ }
+ }
+ if (evpds.Count > 0)
+ report.SCSI.EVPDPages = evpds.ToArray();
+ }
+ }
+
+ if (removable)
+ {
+ if (dev.SCSIType == DiscImageChef.Decoders.SCSI.PeripheralDeviceTypes.MultiMediaDevice)
+ {
+ dev.AllowMediumRemoval(out senseBuffer, timeout, out duration);
+ dev.EjectTray(out senseBuffer, timeout, out duration);
+ }
+ else if (dev.SCSIType == DiscImageChef.Decoders.SCSI.PeripheralDeviceTypes.SequentialAccess)
+ {
+ dev.SpcAllowMediumRemoval(out senseBuffer, timeout, out duration);
+ DicConsole.WriteLine("Asking drive to unload tape (can take a few minutes)...");
+ dev.Unload(out senseBuffer, timeout, out duration);
+ }
+ DicConsole.WriteLine("Please remove any media from the device and press any key when it is out.");
+ System.Console.ReadKey(true);
+ }
+
+ Decoders.SCSI.Modes.DecodedMode? decMode = null;
+ Decoders.SCSI.PeripheralDeviceTypes devType = dev.SCSIType;
+
+ DicConsole.WriteLine("Querying all mode pages and subpages using SCSI MODE SENSE (10)...");
+ if (sense || dev.Error)
+ {
+ sense = dev.ModeSense6(out buffer, out senseBuffer, false, ScsiModeSensePageControl.Default, 0x3F, 0x00, timeout, out duration);
+ DicConsole.WriteLine("Querying all mode pages using SCSI MODE SENSE (6)...");
+ }
+ else
+ report.SCSI.SupportsModeSubpages = true;
+
+ if (sense || dev.Error)
+ {
+ DicConsole.WriteLine("Querying SCSI MODE SENSE (6)...");
+ sense = dev.ModeSense(out buffer, out senseBuffer, timeout, out duration);
+ }
+
+ if (!sense && !dev.Error && !decMode.HasValue)
+ decMode = Decoders.SCSI.Modes.DecodeMode6(buffer, devType);
+
+ if (!sense && !dev.Error)
+ report.SCSI.SupportsModeSense6 = true;
+
+ Decoders.SCSI.Modes.ModePage_2A? cdromMode = null;
+
+ if (decMode.HasValue)
+ {
+ report.SCSI.ModeSense = new modeType();
+ report.SCSI.ModeSense.BlankCheckEnabled = decMode.Value.Header.EBC;
+ report.SCSI.ModeSense.DPOandFUA = decMode.Value.Header.DPOFUA;
+ report.SCSI.ModeSense.WriteProtected = decMode.Value.Header.WriteProtected;
+
+ if (decMode.Value.Header.BufferedMode > 0)
+ {
+ report.SCSI.ModeSense.BufferedMode = decMode.Value.Header.BufferedMode;
+ report.SCSI.ModeSense.BufferedModeSpecified = true;
+ }
+
+ if (decMode.Value.Header.Speed > 0)
+ {
+ report.SCSI.ModeSense.Speed = decMode.Value.Header.Speed;
+ report.SCSI.ModeSense.SpeedSpecified = true;
+ }
+
+ if (decMode.Value.Pages != null)
+ {
+ List modePages = new List();
+ foreach (Decoders.SCSI.Modes.ModePage page in decMode.Value.Pages)
+ {
+ modePageType modePage = new modePageType();
+ modePage.page = page.Page;
+ modePage.subpage = page.Subpage;
+ modePage.value = page.PageResponse;
+ modePages.Add(modePage);
+
+ if (modePage.page == 0x2A && modePage.subpage == 0x00)
+ {
+ cdromMode = Decoders.SCSI.Modes.DecodeModePage_2A(page.PageResponse);
+ }
+ }
+
+ if (modePages.Count > 0)
+ report.SCSI.ModeSense.ModePages = modePages.ToArray();
+ }
+ }
+
+ List mediaTypes = new List();
+
+ #region MultiMediaDevice
+ if (dev.SCSIType == DiscImageChef.Decoders.SCSI.PeripheralDeviceTypes.MultiMediaDevice)
+ {
+ report.SCSI.MultiMediaDevice = new mmcType();
+
+ if (cdromMode.HasValue)
+ {
+ report.SCSI.MultiMediaDevice.ModeSense2A = new mmcModeType();
+ if (cdromMode.Value.BufferSize != 0)
+ {
+ report.SCSI.MultiMediaDevice.ModeSense2A.BufferSize = cdromMode.Value.BufferSize;
+ report.SCSI.MultiMediaDevice.ModeSense2A.BufferSizeSpecified = true;
+ }
+ if (cdromMode.Value.CurrentSpeed != 0)
+ {
+ report.SCSI.MultiMediaDevice.ModeSense2A.CurrentSpeed = cdromMode.Value.CurrentSpeed;
+ report.SCSI.MultiMediaDevice.ModeSense2A.CurrentSpeedSpecified = true;
+ }
+ if (cdromMode.Value.CurrentWriteSpeed != 0)
+ {
+ report.SCSI.MultiMediaDevice.ModeSense2A.CurrentWriteSpeed = cdromMode.Value.CurrentWriteSpeed;
+ report.SCSI.MultiMediaDevice.ModeSense2A.CurrentWriteSpeedSpecified = true;
+ }
+ if (cdromMode.Value.CurrentWriteSpeedSelected != 0)
+ {
+ report.SCSI.MultiMediaDevice.ModeSense2A.CurrentWriteSpeedSelected = cdromMode.Value.CurrentWriteSpeedSelected;
+ report.SCSI.MultiMediaDevice.ModeSense2A.CurrentWriteSpeedSelectedSpecified = true;
+ }
+ if (cdromMode.Value.MaximumSpeed != 0)
+ {
+ report.SCSI.MultiMediaDevice.ModeSense2A.MaximumSpeed = cdromMode.Value.MaximumSpeed;
+ report.SCSI.MultiMediaDevice.ModeSense2A.MaximumSpeedSpecified = true;
+ }
+ if (cdromMode.Value.MaxWriteSpeed != 0)
+ {
+ report.SCSI.MultiMediaDevice.ModeSense2A.MaximumWriteSpeed = cdromMode.Value.MaxWriteSpeed;
+ report.SCSI.MultiMediaDevice.ModeSense2A.MaximumWriteSpeedSpecified = true;
+ }
+ if (cdromMode.Value.RotationControlSelected != 0)
+ {
+ report.SCSI.MultiMediaDevice.ModeSense2A.RotationControlSelected = cdromMode.Value.RotationControlSelected;
+ report.SCSI.MultiMediaDevice.ModeSense2A.RotationControlSelectedSpecified = true;
+ }
+ if (cdromMode.Value.SupportedVolumeLevels != 0)
+ {
+ report.SCSI.MultiMediaDevice.ModeSense2A.SupportedVolumeLevels = cdromMode.Value.SupportedVolumeLevels;
+ report.SCSI.MultiMediaDevice.ModeSense2A.SupportedVolumeLevelsSpecified = true;
+ }
+
+ report.SCSI.MultiMediaDevice.ModeSense2A.AccurateCDDA = cdromMode.Value.AccurateCDDA;
+ report.SCSI.MultiMediaDevice.ModeSense2A.BCK = cdromMode.Value.BCK;
+ report.SCSI.MultiMediaDevice.ModeSense2A.BufferUnderRunProtection = cdromMode.Value.BUF;
+ report.SCSI.MultiMediaDevice.ModeSense2A.CanEject = cdromMode.Value.Eject;
+ report.SCSI.MultiMediaDevice.ModeSense2A.CanLockMedia = cdromMode.Value.Lock;
+ report.SCSI.MultiMediaDevice.ModeSense2A.CDDACommand = cdromMode.Value.CDDACommand;
+ report.SCSI.MultiMediaDevice.ModeSense2A.CompositeAudioVideo = cdromMode.Value.Composite;
+ report.SCSI.MultiMediaDevice.ModeSense2A.CSSandCPPMSupported = cdromMode.Value.CMRSupported == 1;
+ report.SCSI.MultiMediaDevice.ModeSense2A.DeterministicSlotChanger = cdromMode.Value.SDP;
+ report.SCSI.MultiMediaDevice.ModeSense2A.DigitalPort1 = cdromMode.Value.DigitalPort1;
+ report.SCSI.MultiMediaDevice.ModeSense2A.DigitalPort2 = cdromMode.Value.DigitalPort2;
+ report.SCSI.MultiMediaDevice.ModeSense2A.LeadInPW = cdromMode.Value.LeadInPW;
+ report.SCSI.MultiMediaDevice.ModeSense2A.LoadingMechanismType = cdromMode.Value.LoadingMechanism;
+ report.SCSI.MultiMediaDevice.ModeSense2A.LockStatus = cdromMode.Value.LockState;
+ report.SCSI.MultiMediaDevice.ModeSense2A.LSBF = cdromMode.Value.LSBF;
+ report.SCSI.MultiMediaDevice.ModeSense2A.PlaysAudio = cdromMode.Value.AudioPlay;
+ report.SCSI.MultiMediaDevice.ModeSense2A.PreventJumperStatus = cdromMode.Value.PreventJumper;
+ report.SCSI.MultiMediaDevice.ModeSense2A.RCK = cdromMode.Value.RCK;
+ report.SCSI.MultiMediaDevice.ModeSense2A.ReadsBarcode = cdromMode.Value.ReadBarcode;
+ report.SCSI.MultiMediaDevice.ModeSense2A.ReadsBothSides = cdromMode.Value.SCC;
+ report.SCSI.MultiMediaDevice.ModeSense2A.ReadsCDR = cdromMode.Value.ReadCDR;
+ report.SCSI.MultiMediaDevice.ModeSense2A.ReadsCDRW = cdromMode.Value.ReadCDRW;
+ report.SCSI.MultiMediaDevice.ModeSense2A.ReadsDeinterlavedSubchannel = cdromMode.Value.DeinterlaveSubchannel;
+ report.SCSI.MultiMediaDevice.ModeSense2A.ReadsDVDR = cdromMode.Value.ReadDVDR;
+ report.SCSI.MultiMediaDevice.ModeSense2A.ReadsDVDRAM = cdromMode.Value.ReadDVDRAM;
+ report.SCSI.MultiMediaDevice.ModeSense2A.ReadsDVDROM = cdromMode.Value.ReadDVDROM;
+ report.SCSI.MultiMediaDevice.ModeSense2A.ReadsISRC = cdromMode.Value.ISRC;
+ report.SCSI.MultiMediaDevice.ModeSense2A.ReadsMode2Form2 = cdromMode.Value.Mode2Form2;
+ report.SCSI.MultiMediaDevice.ModeSense2A.ReadsMode2Form1 = cdromMode.Value.Mode2Form1;
+ report.SCSI.MultiMediaDevice.ModeSense2A.ReadsPacketCDR = cdromMode.Value.Method2;
+ report.SCSI.MultiMediaDevice.ModeSense2A.ReadsSubchannel = cdromMode.Value.Subchannel;
+ report.SCSI.MultiMediaDevice.ModeSense2A.ReadsUPC = cdromMode.Value.UPC;
+ report.SCSI.MultiMediaDevice.ModeSense2A.ReturnsC2Pointers = cdromMode.Value.C2Pointer;
+ report.SCSI.MultiMediaDevice.ModeSense2A.SeparateChannelMute = cdromMode.Value.SeparateChannelMute;
+ report.SCSI.MultiMediaDevice.ModeSense2A.SeparateChannelVolume = cdromMode.Value.SeparateChannelVolume;
+ report.SCSI.MultiMediaDevice.ModeSense2A.SSS = cdromMode.Value.SSS;
+ report.SCSI.MultiMediaDevice.ModeSense2A.SupportsMultiSession = cdromMode.Value.MultiSession;
+ report.SCSI.MultiMediaDevice.ModeSense2A.TestWrite = cdromMode.Value.TestWrite;
+ report.SCSI.MultiMediaDevice.ModeSense2A.WritesCDR = cdromMode.Value.WriteCDR;
+ report.SCSI.MultiMediaDevice.ModeSense2A.WritesCDRW = cdromMode.Value.WriteCDRW;
+ report.SCSI.MultiMediaDevice.ModeSense2A.WritesDVDR = cdromMode.Value.WriteDVDR;
+ report.SCSI.MultiMediaDevice.ModeSense2A.WritesDVDRAM = cdromMode.Value.WriteDVDRAM;
+ report.SCSI.MultiMediaDevice.ModeSense2A.WriteSpeedPerformanceDescriptors = cdromMode.Value.WriteSpeedPerformanceDescriptors;
+
+ mediaTypes.Add("CD-ROM");
+ mediaTypes.Add("Audio CD");
+ if (cdromMode.Value.ReadCDR)
+ mediaTypes.Add("CD-R");
+ if (cdromMode.Value.ReadCDRW)
+ mediaTypes.Add("CD-RW");
+ if (cdromMode.Value.ReadDVDROM)
+ mediaTypes.Add("DVD-ROM");
+ if (cdromMode.Value.ReadDVDRAM)
+ mediaTypes.Add("DVD-RAM");
+ if (cdromMode.Value.ReadDVDR)
+ mediaTypes.Add("DVD-R");
+ }
+
+ DicConsole.WriteLine("Querying MMC GET CONFIGURATION...");
+ sense = dev.GetConfiguration(out buffer, out senseBuffer, timeout, out duration);
+
+ if (!sense)
+ {
+ Decoders.SCSI.MMC.Features.SeparatedFeatures ftr = Decoders.SCSI.MMC.Features.Separate(buffer);
+ if (ftr.Descriptors != null && ftr.Descriptors.Length > 0)
+ {
+ report.SCSI.MultiMediaDevice.Features = new mmcFeaturesType();
+ foreach (Decoders.SCSI.MMC.Features.FeatureDescriptor desc in ftr.Descriptors)
+ {
+ switch (desc.Code)
+ {
+ case 0x0001:
+ {
+ Decoders.SCSI.MMC.Feature_0001? ftr0001 = Decoders.SCSI.MMC.Features.Decode_0001(desc.Data);
+ if (ftr0001.HasValue)
+ {
+ report.SCSI.MultiMediaDevice.Features.PhysicalInterfaceStandard = ftr0001.Value.PhysicalInterfaceStandard;
+ report.SCSI.MultiMediaDevice.Features.PhysicalInterfaceStandardSpecified = true;
+ report.SCSI.MultiMediaDevice.Features.SupportsDeviceBusyEvent = ftr0001.Value.DBE;
+ }
+ }
+ break;
+ case 0x0003:
+ {
+ Decoders.SCSI.MMC.Feature_0003? ftr0003 = Decoders.SCSI.MMC.Features.Decode_0003(desc.Data);
+ if (ftr0003.HasValue)
+ {
+ report.SCSI.MultiMediaDevice.Features.LoadingMechanismType = ftr0003.Value.LoadingMechanismType;
+ report.SCSI.MultiMediaDevice.Features.LoadingMechanismTypeSpecified = true;
+ report.SCSI.MultiMediaDevice.Features.CanLoad = ftr0003.Value.Load;
+ report.SCSI.MultiMediaDevice.Features.CanEject = ftr0003.Value.Eject;
+ report.SCSI.MultiMediaDevice.Features.PreventJumper = ftr0003.Value.PreventJumper;
+ report.SCSI.MultiMediaDevice.Features.DBML = ftr0003.Value.DBML;
+ report.SCSI.MultiMediaDevice.Features.Locked = ftr0003.Value.Lock;
+ }
+ }
+ break;
+ case 0x0004:
+ {
+ Decoders.SCSI.MMC.Feature_0004? ftr0004 = Decoders.SCSI.MMC.Features.Decode_0004(desc.Data);
+ if (ftr0004.HasValue)
+ {
+ report.SCSI.MultiMediaDevice.Features.SupportsWriteProtectPAC = ftr0004.Value.DWP;
+ report.SCSI.MultiMediaDevice.Features.SupportsWriteInhibitDCB = ftr0004.Value.WDCB;
+ report.SCSI.MultiMediaDevice.Features.SupportsPWP = ftr0004.Value.SPWP;
+ report.SCSI.MultiMediaDevice.Features.SupportsSWPP = ftr0004.Value.SSWPP;
+ }
+ }
+ break;
+ case 0x0010:
+ {
+ Decoders.SCSI.MMC.Feature_0010? ftr0010 = Decoders.SCSI.MMC.Features.Decode_0010(desc.Data);
+ if (ftr0010.HasValue)
+ {
+ if (ftr0010.Value.LogicalBlockSize > 0)
+ {
+ report.SCSI.MultiMediaDevice.Features.LogicalBlockSize = ftr0010.Value.LogicalBlockSize;
+ report.SCSI.MultiMediaDevice.Features.LogicalBlockSizeSpecified = true;
+ }
+ if (ftr0010.Value.Blocking > 0)
+ {
+ report.SCSI.MultiMediaDevice.Features.BlocksPerReadableUnit = ftr0010.Value.Blocking;
+ report.SCSI.MultiMediaDevice.Features.BlocksPerReadableUnitSpecified = true;
+ }
+ report.SCSI.MultiMediaDevice.Features.ErrorRecoveryPage = ftr0010.Value.PP;
+ }
+ }
+ break;
+ case 0x001D:
+ report.SCSI.MultiMediaDevice.Features.MultiRead = true;
+ break;
+ case 0x001E:
+ {
+ report.SCSI.MultiMediaDevice.Features.CanReadCD = true;
+ Decoders.SCSI.MMC.Feature_001E? ftr001E = Decoders.SCSI.MMC.Features.Decode_001E(desc.Data);
+ if (ftr001E.HasValue)
+ {
+ report.SCSI.MultiMediaDevice.Features.SupportsDAP = ftr001E.Value.DAP;
+ report.SCSI.MultiMediaDevice.Features.SupportsC2 = ftr001E.Value.C2;
+ report.SCSI.MultiMediaDevice.Features.CanReadLeadInCDText = ftr001E.Value.CDText;
+ }
+ }
+ break;
+ case 0x001F:
+ {
+ report.SCSI.MultiMediaDevice.Features.CanReadDVD = true;
+ Decoders.SCSI.MMC.Feature_001F? ftr001F = Decoders.SCSI.MMC.Features.Decode_001F(desc.Data);
+ if (ftr001F.HasValue)
+ {
+ report.SCSI.MultiMediaDevice.Features.DVDMultiRead = ftr001F.Value.MULTI110;
+ report.SCSI.MultiMediaDevice.Features.CanReadAllDualRW = ftr001F.Value.DualRW;
+ report.SCSI.MultiMediaDevice.Features.CanReadAllDualR = ftr001F.Value.DualRW;
+ }
+ }
+ break;
+ case 0x0022:
+ report.SCSI.MultiMediaDevice.Features.CanEraseSector = true;
+ break;
+ case 0x0023:
+ {
+ report.SCSI.MultiMediaDevice.Features.CanFormat = true;
+ Decoders.SCSI.MMC.Feature_0023? ftr0023 = Decoders.SCSI.MMC.Features.Decode_0023(desc.Data);
+ if (ftr0023.HasValue)
+ {
+ report.SCSI.MultiMediaDevice.Features.CanFormatBDREWithoutSpare = ftr0023.Value.RENoSA;
+ report.SCSI.MultiMediaDevice.Features.CanExpandBDRESpareArea = ftr0023.Value.Expand;
+ report.SCSI.MultiMediaDevice.Features.CanFormatQCert = ftr0023.Value.QCert;
+ report.SCSI.MultiMediaDevice.Features.CanFormatCert = ftr0023.Value.Cert;
+ report.SCSI.MultiMediaDevice.Features.CanFormatFRF = ftr0023.Value.FRF;
+ report.SCSI.MultiMediaDevice.Features.CanFormatRRM = ftr0023.Value.RRM;
+ }
+ }
+ break;
+ case 0x0024:
+ report.SCSI.MultiMediaDevice.Features.CanReadSpareAreaInformation = true;
+ break;
+ case 0x0027:
+ report.SCSI.MultiMediaDevice.Features.CanWriteCDRWCAV = true;
+ break;
+ case 0x0028:
+ {
+ report.SCSI.MultiMediaDevice.Features.CanReadCDMRW = true;
+ Decoders.SCSI.MMC.Feature_0028? ftr0028 = Decoders.SCSI.MMC.Features.Decode_0028(desc.Data);
+ if (ftr0028.HasValue)
+ {
+ report.SCSI.MultiMediaDevice.Features.CanReadDVDPlusMRW = ftr0028.Value.DVDPRead;
+ report.SCSI.MultiMediaDevice.Features.CanWriteDVDPlusMRW = ftr0028.Value.DVDPWrite;
+ report.SCSI.MultiMediaDevice.Features.CanWriteCDMRW = ftr0028.Value.Write;
+ }
+ }
+ break;
+ case 0x002A:
+ {
+ report.SCSI.MultiMediaDevice.Features.CanReadDVDPlusRW = true;
+ Decoders.SCSI.MMC.Feature_002A? ftr002A = Decoders.SCSI.MMC.Features.Decode_002A(desc.Data);
+ if (ftr002A.HasValue)
+ {
+ report.SCSI.MultiMediaDevice.Features.CanWriteDVDPlusRW = ftr002A.Value.Write;
+ }
+ }
+ break;
+ case 0x002B:
+ {
+ report.SCSI.MultiMediaDevice.Features.CanReadDVDPlusR = true;
+ Decoders.SCSI.MMC.Feature_002B? ftr002B = Decoders.SCSI.MMC.Features.Decode_002B(desc.Data);
+ if (ftr002B.HasValue)
+ {
+ report.SCSI.MultiMediaDevice.Features.CanWriteDVDPlusR = ftr002B.Value.Write;
+ }
+ }
+ break;
+ case 0x002D:
+ {
+ report.SCSI.MultiMediaDevice.Features.CanWriteCDTAO = true;
+ Decoders.SCSI.MMC.Feature_002D? ftr002D = Decoders.SCSI.MMC.Features.Decode_002D(desc.Data);
+ if (ftr002D.HasValue)
+ {
+ report.SCSI.MultiMediaDevice.Features.BufferUnderrunFreeInTAO = ftr002D.Value.BUF;
+ report.SCSI.MultiMediaDevice.Features.CanWriteRawSubchannelInTAO = ftr002D.Value.RWRaw;
+ report.SCSI.MultiMediaDevice.Features.CanWritePackedSubchannelInTAO = ftr002D.Value.RWPack;
+ report.SCSI.MultiMediaDevice.Features.CanTestWriteInTAO = ftr002D.Value.TestWrite;
+ report.SCSI.MultiMediaDevice.Features.CanOverwriteTAOTrack = ftr002D.Value.CDRW;
+ report.SCSI.MultiMediaDevice.Features.CanWriteRWSubchannelInTAO = ftr002D.Value.RWSubchannel;
+ }
+ }
+ break;
+ case 0x002E:
+ {
+ report.SCSI.MultiMediaDevice.Features.CanWriteCDSAO = true;
+ Decoders.SCSI.MMC.Feature_002E? ftr002E = Decoders.SCSI.MMC.Features.Decode_002E(desc.Data);
+ if (ftr002E.HasValue)
+ {
+ report.SCSI.MultiMediaDevice.Features.BufferUnderrunFreeInSAO = ftr002E.Value.BUF;
+ report.SCSI.MultiMediaDevice.Features.CanWriteRawMultiSession = ftr002E.Value.RAWMS;
+ report.SCSI.MultiMediaDevice.Features.CanWriteRaw = ftr002E.Value.RAW;
+ report.SCSI.MultiMediaDevice.Features.CanTestWriteInSAO = ftr002E.Value.TestWrite;
+ report.SCSI.MultiMediaDevice.Features.CanOverwriteSAOTrack = ftr002E.Value.CDRW;
+ report.SCSI.MultiMediaDevice.Features.CanWriteRWSubchannelInSAO = ftr002E.Value.RW;
+ }
+ }
+ break;
+ case 0x002F:
+ {
+ report.SCSI.MultiMediaDevice.Features.CanWriteDVDR = true;
+ Decoders.SCSI.MMC.Feature_002F? ftr002F = Decoders.SCSI.MMC.Features.Decode_002F(desc.Data);
+ if (ftr002F.HasValue)
+ {
+ report.SCSI.MultiMediaDevice.Features.BufferUnderrunFreeInDVD = ftr002F.Value.BUF;
+ report.SCSI.MultiMediaDevice.Features.CanWriteDVDRDL = ftr002F.Value.RDL;
+ report.SCSI.MultiMediaDevice.Features.CanTestWriteDVD = ftr002F.Value.TestWrite;
+ report.SCSI.MultiMediaDevice.Features.CanWriteDVDRW = ftr002F.Value.DVDRW;
+ }
+ }
+ break;
+ case 0x0030:
+ report.SCSI.MultiMediaDevice.Features.CanReadDDCD = true;
+ break;
+ case 0x0031:
+ {
+ report.SCSI.MultiMediaDevice.Features.CanWriteDDCDR = true;
+ ;
+ Decoders.SCSI.MMC.Feature_0031? ftr0031 = Decoders.SCSI.MMC.Features.Decode_0031(desc.Data);
+ if (ftr0031.HasValue)
+ report.SCSI.MultiMediaDevice.Features.CanTestWriteDDCDR = ftr0031.Value.TestWrite;
+ }
+ break;
+ case 0x0032:
+ report.SCSI.MultiMediaDevice.Features.CanWriteDDCDRW = true;
+ break;
+ case 0x0037:
+ report.SCSI.MultiMediaDevice.Features.CanWriteCDRW = true;
+ break;
+ case 0x0038:
+ report.SCSI.MultiMediaDevice.Features.CanPseudoOverwriteBDR = true;
+ break;
+ case 0x003A:
+ {
+ report.SCSI.MultiMediaDevice.Features.CanReadDVDPlusRWDL = true;
+ Decoders.SCSI.MMC.Feature_003A? ftr003A = Decoders.SCSI.MMC.Features.Decode_003A(desc.Data);
+ if (ftr003A.HasValue)
+ report.SCSI.MultiMediaDevice.Features.CanWriteDVDPlusRWDL = ftr003A.Value.Write;
+ }
+ break;
+ case 0x003B:
+ {
+ report.SCSI.MultiMediaDevice.Features.CanReadDVDPlusRDL = true;
+ Decoders.SCSI.MMC.Feature_003B? ftr003B = Decoders.SCSI.MMC.Features.Decode_003B(desc.Data);
+ if (ftr003B.HasValue)
+ report.SCSI.MultiMediaDevice.Features.CanWriteDVDPlusRDL = ftr003B.Value.Write;
+ }
+ break;
+ case 0x0040:
+ {
+ report.SCSI.MultiMediaDevice.Features.CanReadBD = true;
+ Decoders.SCSI.MMC.Feature_0040? ftr0040 = Decoders.SCSI.MMC.Features.Decode_0040(desc.Data);
+ if (ftr0040.HasValue)
+ {
+ report.SCSI.MultiMediaDevice.Features.CanReadBluBCA = ftr0040.Value.BCA;
+ report.SCSI.MultiMediaDevice.Features.CanReadBDRE2 = ftr0040.Value.RE2;
+ report.SCSI.MultiMediaDevice.Features.CanReadBDRE1 = ftr0040.Value.RE1;
+ report.SCSI.MultiMediaDevice.Features.CanReadOldBDRE = ftr0040.Value.OldRE;
+ report.SCSI.MultiMediaDevice.Features.CanReadBDR = ftr0040.Value.R;
+ report.SCSI.MultiMediaDevice.Features.CanReadOldBDR = ftr0040.Value.OldR;
+ report.SCSI.MultiMediaDevice.Features.CanReadBDROM = ftr0040.Value.ROM;
+ report.SCSI.MultiMediaDevice.Features.CanReadOldBDROM = ftr0040.Value.OldROM;
+ }
+ }
+ break;
+ case 0x0041:
+ {
+ report.SCSI.MultiMediaDevice.Features.CanWriteBD = true;
+ Decoders.SCSI.MMC.Feature_0041? ftr0041 = Decoders.SCSI.MMC.Features.Decode_0041(desc.Data);
+ if (ftr0041.HasValue)
+ {
+ report.SCSI.MultiMediaDevice.Features.CanWriteBDRE2 = ftr0041.Value.RE2;
+ report.SCSI.MultiMediaDevice.Features.CanWriteBDRE1 = ftr0041.Value.RE1;
+ report.SCSI.MultiMediaDevice.Features.CanReadOldBDRE = ftr0041.Value.OldRE;
+ report.SCSI.MultiMediaDevice.Features.CanReadBDR = ftr0041.Value.R;
+ report.SCSI.MultiMediaDevice.Features.CanReadOldBDR = ftr0041.Value.OldR;
+ }
+ }
+ break;
+ case 0x0050:
+ {
+ report.SCSI.MultiMediaDevice.Features.CanReadHDDVD = true;
+ Decoders.SCSI.MMC.Feature_0050? ftr0050 = Decoders.SCSI.MMC.Features.Decode_0050(desc.Data);
+ if (ftr0050.HasValue)
+ {
+ report.SCSI.MultiMediaDevice.Features.CanReadHDDVDR = ftr0050.Value.HDDVDR;
+ report.SCSI.MultiMediaDevice.Features.CanReadHDDVDRAM = ftr0050.Value.HDDVDRAM;
+ }
+ }
+ break;
+ case 0x0051:
+ {
+ Decoders.SCSI.MMC.Feature_0051? ftr0051 = Decoders.SCSI.MMC.Features.Decode_0051(desc.Data);
+ if (ftr0051.HasValue)
+ {
+ report.SCSI.MultiMediaDevice.Features.CanWriteHDDVDR = ftr0051.Value.HDDVDR;
+ report.SCSI.MultiMediaDevice.Features.CanWriteHDDVDRAM = ftr0051.Value.HDDVDRAM;
+ }
+ }
+ break;
+ case 0x0080:
+ report.SCSI.MultiMediaDevice.Features.SupportsHybridDiscs = true;
+ break;
+ case 0x0101:
+ report.SCSI.MultiMediaDevice.Features.SupportsModePage1Ch = true;
+ break;
+ case 0x0102:
+ {
+ report.SCSI.MultiMediaDevice.Features.EmbeddedChanger = true;
+ Decoders.SCSI.MMC.Feature_0102? ftr0102 = Decoders.SCSI.MMC.Features.Decode_0102(desc.Data);
+ if (ftr0102.HasValue)
+ {
+ report.SCSI.MultiMediaDevice.Features.ChangerIsSideChangeCapable = ftr0102.Value.SCC;
+ report.SCSI.MultiMediaDevice.Features.ChangerSupportsDiscPresent = ftr0102.Value.SDP;
+ report.SCSI.MultiMediaDevice.Features.ChangerSlots = (byte)(ftr0102.Value.HighestSlotNumber + 1);
+ }
+ }
+ break;
+ case 0x0103:
+ {
+ report.SCSI.MultiMediaDevice.Features.CanPlayCDAudio = true;
+ Decoders.SCSI.MMC.Feature_0103? ftr0103 = Decoders.SCSI.MMC.Features.Decode_0103(desc.Data);
+ if (ftr0103.HasValue)
+ {
+ report.SCSI.MultiMediaDevice.Features.CanAudioScan = ftr0103.Value.Scan;
+ report.SCSI.MultiMediaDevice.Features.CanMuteSeparateChannels = ftr0103.Value.SCM;
+ report.SCSI.MultiMediaDevice.Features.SupportsSeparateVolume = ftr0103.Value.SV;
+ if (ftr0103.Value.VolumeLevels > 0)
+ {
+ report.SCSI.MultiMediaDevice.Features.VolumeLevelsSpecified = true;
+ report.SCSI.MultiMediaDevice.Features.VolumeLevels = ftr0103.Value.VolumeLevels;
+ }
+ }
+ }
+ break;
+ case 0x0104:
+ report.SCSI.MultiMediaDevice.Features.CanUpgradeFirmware = true;
+ break;
+ case 0x0106:
+ {
+ report.SCSI.MultiMediaDevice.Features.SupportsCSS = true;
+ Decoders.SCSI.MMC.Feature_0106? ftr0106 = Decoders.SCSI.MMC.Features.Decode_0106(desc.Data);
+ if (ftr0106.HasValue)
+ {
+ if (ftr0106.Value.CSSVersion > 0)
+ {
+ report.SCSI.MultiMediaDevice.Features.CSSVersionSpecified = true;
+ report.SCSI.MultiMediaDevice.Features.CSSVersion = ftr0106.Value.CSSVersion;
+ }
+ }
+ }
+ break;
+ case 0x0108:
+ report.SCSI.MultiMediaDevice.Features.CanReportDriveSerial = true;
+ break;
+ case 0x0109:
+ report.SCSI.MultiMediaDevice.Features.CanReportMediaSerial = true;
+ break;
+ case 0x010B:
+ {
+ report.SCSI.MultiMediaDevice.Features.SupportsCPRM = true;
+ Decoders.SCSI.MMC.Feature_010B? ftr010B = Decoders.SCSI.MMC.Features.Decode_010B(desc.Data);
+ if (ftr010B.HasValue)
+ {
+ if (ftr010B.Value.CPRMVersion > 0)
+ {
+ report.SCSI.MultiMediaDevice.Features.CPRMVersionSpecified = true;
+ report.SCSI.MultiMediaDevice.Features.CPRMVersion = ftr010B.Value.CPRMVersion;
+ }
+ }
+ }
+ break;
+ case 0x010C:
+ {
+ Decoders.SCSI.MMC.Feature_010C? ftr010C = Decoders.SCSI.MMC.Features.Decode_010C(desc.Data);
+ if (ftr010C.HasValue)
+ {
+ string syear, smonth, sday, shour, sminute, ssecond;
+ byte[] temp;
+
+ temp = new byte[4];
+ temp[0] = (byte)((ftr010C.Value.Century & 0xFF00) >> 8);
+ temp[1] = (byte)(ftr010C.Value.Century & 0xFF);
+ temp[2] = (byte)((ftr010C.Value.Year & 0xFF00) >> 8);
+ temp[3] = (byte)(ftr010C.Value.Year & 0xFF);
+ syear = System.Text.Encoding.ASCII.GetString(temp);
+ temp = new byte[2];
+ temp[0] = (byte)((ftr010C.Value.Month & 0xFF00) >> 8);
+ temp[1] = (byte)(ftr010C.Value.Month & 0xFF);
+ smonth = System.Text.Encoding.ASCII.GetString(temp);
+ temp = new byte[2];
+ temp[0] = (byte)((ftr010C.Value.Day & 0xFF00) >> 8);
+ temp[1] = (byte)(ftr010C.Value.Day & 0xFF);
+ sday = System.Text.Encoding.ASCII.GetString(temp);
+ temp = new byte[2];
+ temp[0] = (byte)((ftr010C.Value.Hour & 0xFF00) >> 8);
+ temp[1] = (byte)(ftr010C.Value.Hour & 0xFF);
+ shour = System.Text.Encoding.ASCII.GetString(temp);
+ temp = new byte[2];
+ temp[0] = (byte)((ftr010C.Value.Minute & 0xFF00) >> 8);
+ temp[1] = (byte)(ftr010C.Value.Minute & 0xFF);
+ sminute = System.Text.Encoding.ASCII.GetString(temp);
+ temp = new byte[2];
+ temp[0] = (byte)((ftr010C.Value.Second & 0xFF00) >> 8);
+ temp[1] = (byte)(ftr010C.Value.Second & 0xFF);
+ ssecond = System.Text.Encoding.ASCII.GetString(temp);
+
+ try
+ {
+ report.SCSI.MultiMediaDevice.Features.FirmwareDate = new DateTime(Int32.Parse(syear), Int32.Parse(smonth),
+ Int32.Parse(sday), Int32.Parse(shour), Int32.Parse(sminute),
+ Int32.Parse(ssecond), DateTimeKind.Utc);
+
+ report.SCSI.MultiMediaDevice.Features.FirmwareDateSpecified = true;
+ }
+ catch
+ {
+ }
+ }
+ }
+ break;
+ case 0x010D:
+ {
+ report.SCSI.MultiMediaDevice.Features.SupportsAACS = true;
+ Decoders.SCSI.MMC.Feature_010D? ftr010D = Decoders.SCSI.MMC.Features.Decode_010D(desc.Data);
+ if (ftr010D.HasValue)
+ {
+ report.SCSI.MultiMediaDevice.Features.CanReadDriveAACSCertificate = ftr010D.Value.RDC;
+ report.SCSI.MultiMediaDevice.Features.CanReadCPRM_MKB = ftr010D.Value.RMC;
+ report.SCSI.MultiMediaDevice.Features.CanWriteBusEncryptedBlocks = ftr010D.Value.WBE;
+ report.SCSI.MultiMediaDevice.Features.SupportsBusEncryption = ftr010D.Value.BEC;
+ report.SCSI.MultiMediaDevice.Features.CanGenerateBindingNonce = ftr010D.Value.BNG;
+
+ if (ftr010D.Value.BindNonceBlocks > 0)
+ {
+ report.SCSI.MultiMediaDevice.Features.BindingNonceBlocksSpecified = true;
+ report.SCSI.MultiMediaDevice.Features.BindingNonceBlocks = ftr010D.Value.BindNonceBlocks;
+ }
+
+ if (ftr010D.Value.AGIDs > 0)
+ {
+ report.SCSI.MultiMediaDevice.Features.AGIDsSpecified = true;
+ report.SCSI.MultiMediaDevice.Features.AGIDs = ftr010D.Value.AGIDs;
+ }
+
+ if (ftr010D.Value.AACSVersion > 0)
+ {
+ report.SCSI.MultiMediaDevice.Features.AACSVersionSpecified = true;
+ report.SCSI.MultiMediaDevice.Features.AACSVersion = ftr010D.Value.AACSVersion;
+ }
+ }
+ }
+ break;
+ case 0x010E:
+ report.SCSI.MultiMediaDevice.Features.CanWriteCSSManagedDVD = true;
+ break;
+ case 0x0113:
+ report.SCSI.MultiMediaDevice.Features.SupportsSecurDisc = true;
+ break;
+ case 0x0142:
+ report.SCSI.MultiMediaDevice.Features.SupportsOSSC = true;
+ break;
+ case 0x0110:
+ report.SCSI.MultiMediaDevice.Features.SupportsVCPS = true;
+ break;
+ }
+ }
+ }
+
+ if (report.SCSI.MultiMediaDevice.Features.CanReadBD ||
+ report.SCSI.MultiMediaDevice.Features.CanReadBDR ||
+ report.SCSI.MultiMediaDevice.Features.CanReadBDRE1 ||
+ report.SCSI.MultiMediaDevice.Features.CanReadBDRE2 ||
+ report.SCSI.MultiMediaDevice.Features.CanReadBDROM ||
+ report.SCSI.MultiMediaDevice.Features.CanReadOldBDR ||
+ report.SCSI.MultiMediaDevice.Features.CanReadOldBDRE ||
+ report.SCSI.MultiMediaDevice.Features.CanReadOldBDROM)
+ {
+ if (!mediaTypes.Contains("BD-ROM"))
+ mediaTypes.Add("BD-ROM");
+ if (!mediaTypes.Contains("BD-R"))
+ mediaTypes.Add("BD-R");
+ if (!mediaTypes.Contains("BD-RE"))
+ mediaTypes.Add("BD-RE");
+ if (!mediaTypes.Contains("BD-R LTH"))
+ mediaTypes.Add("BD-R LTH");
+ if (!mediaTypes.Contains("BD-R XL"))
+ mediaTypes.Add("BD-R XL");
+ }
+
+ if (report.SCSI.MultiMediaDevice.Features.CanReadCD ||
+ report.SCSI.MultiMediaDevice.Features.MultiRead)
+ {
+ if (!mediaTypes.Contains("CD-ROM"))
+ mediaTypes.Add("CD-ROM");
+ if (!mediaTypes.Contains("Audio CD"))
+ mediaTypes.Add("Audio CD");
+ if (!mediaTypes.Contains("CD-R"))
+ mediaTypes.Add("CD-R");
+ if (!mediaTypes.Contains("CD-RW"))
+ mediaTypes.Add("CD-RW");
+ }
+
+ if (report.SCSI.MultiMediaDevice.Features.CanReadCDMRW)
+ {
+ if (!mediaTypes.Contains("CD-MRW"))
+ mediaTypes.Add("CD-MRW");
+ }
+
+ if (report.SCSI.MultiMediaDevice.Features.CanReadDDCD)
+ {
+ if (!mediaTypes.Contains("DDCD-ROM"))
+ mediaTypes.Add("DDCD-ROM");
+ if (!mediaTypes.Contains("DDCD-R"))
+ mediaTypes.Add("DDCD-R");
+ if (!mediaTypes.Contains("DDCD-RW"))
+ mediaTypes.Add("DDCD-RW");
+ }
+
+ if (report.SCSI.MultiMediaDevice.Features.CanReadDVD ||
+ report.SCSI.MultiMediaDevice.Features.DVDMultiRead ||
+ report.SCSI.MultiMediaDevice.Features.CanReadDVDPlusR ||
+ report.SCSI.MultiMediaDevice.Features.CanReadDVDPlusRDL ||
+ report.SCSI.MultiMediaDevice.Features.CanReadDVDPlusRW ||
+ report.SCSI.MultiMediaDevice.Features.CanReadDVDPlusRWDL)
+ {
+ if (!mediaTypes.Contains("DVD-ROM"))
+ mediaTypes.Add("DVD-ROM");
+ if (!mediaTypes.Contains("DVD-R"))
+ mediaTypes.Add("DVD-R");
+ if (!mediaTypes.Contains("DVD-RW"))
+ mediaTypes.Add("DVD-RW");
+ if (!mediaTypes.Contains("DVD+R"))
+ mediaTypes.Add("DVD+R");
+ if (!mediaTypes.Contains("DVD+RW"))
+ mediaTypes.Add("DVD+RW");
+ if (!mediaTypes.Contains("DVD-R DL"))
+ mediaTypes.Add("DVD-R DL");
+ if (!mediaTypes.Contains("DVD+R DL"))
+ mediaTypes.Add("DVD+R DL");
+ }
+
+ if (report.SCSI.MultiMediaDevice.Features.CanReadDVDPlusMRW)
+ {
+ if (!mediaTypes.Contains("DVD+MRW"))
+ mediaTypes.Add("DVD+MRW");
+ }
+
+
+ if (report.SCSI.MultiMediaDevice.Features.CanReadHDDVD ||
+ report.SCSI.MultiMediaDevice.Features.CanReadHDDVDR)
+ {
+ if (!mediaTypes.Contains("HD DVD-ROM"))
+ mediaTypes.Add("HD DVD-ROM");
+ if (!mediaTypes.Contains("HD DVD-R"))
+ mediaTypes.Add("HD DVD-R");
+ if (!mediaTypes.Contains("HD DVD-RW"))
+ mediaTypes.Add("HD DVD-RW");
+ }
+
+ if (report.SCSI.MultiMediaDevice.Features.CanReadHDDVDRAM)
+ {
+ if (!mediaTypes.Contains("HD DVD-RAM"))
+ mediaTypes.Add("HD DVD-RAM");
+ }
+ }
+
+ bool tryPlextor = false, tryHLDTST = false, tryPioneer = false, tryNEC = false;
+
+ tryPlextor |= dev.Manufacturer.ToLowerInvariant() == "plextor";
+ tryHLDTST |= dev.Manufacturer.ToLowerInvariant() == "hl-dt-st";
+ tryPioneer |= dev.Manufacturer.ToLowerInvariant() == "pioneer";
+ tryNEC |= dev.Manufacturer.ToLowerInvariant() == "nec";
+
+ mediaTypes.Sort();
+ List mediaTests = new List();
+ foreach (string mediaType in mediaTypes)
+ {
+ pressedKey = new ConsoleKeyInfo();
+ while (pressedKey.Key != ConsoleKey.Y && pressedKey.Key != ConsoleKey.N)
+ {
+ DicConsole.Write("Do you have a {0} disc that you can insert in the drive? (Y/N): ", mediaType);
+ pressedKey = System.Console.ReadKey();
+ DicConsole.WriteLine();
+ }
+
+ if (pressedKey.Key == ConsoleKey.Y)
+ {
+ dev.AllowMediumRemoval(out senseBuffer, timeout, out duration);
+ dev.EjectTray(out senseBuffer, timeout, out duration);
+ DicConsole.WriteLine("Please insert it in the drive and press any key when it is ready.");
+ System.Console.ReadKey(true);
+
+ testedMediaType mediaTest = new testedMediaType();
+ mediaTest.MediumTypeName = mediaType;
+ mediaTest.MediaIsRecognized = true;
+
+ sense = dev.ScsiTestUnitReady(out senseBuffer, timeout, out duration);
+ if (sense)
+ {
+ Decoders.SCSI.FixedSense? decSense = Decoders.SCSI.Sense.DecodeFixed(senseBuffer);
+ if (decSense.HasValue)
+ {
+ if (decSense.Value.ASC == 0x3A)
+ {
+ int leftRetries = 20;
+ while (leftRetries > 0)
+ {
+ DicConsole.Write("\rWaiting for drive to become ready");
+ System.Threading.Thread.Sleep(2000);
+ sense = dev.ScsiTestUnitReady(out senseBuffer, timeout, out duration);
+ if (!sense)
+ break;
+
+ leftRetries--;
+ }
+
+ mediaTest.MediaIsRecognized &= !sense;
+ }
+ else if (decSense.Value.ASC == 0x04 && decSense.Value.ASCQ == 0x01)
+ {
+ int leftRetries = 20;
+ while (leftRetries > 0)
+ {
+ DicConsole.Write("\rWaiting for drive to become ready");
+ System.Threading.Thread.Sleep(2000);
+ sense = dev.ScsiTestUnitReady(out senseBuffer, timeout, out duration);
+ if (!sense)
+ break;
+
+ leftRetries--;
+ }
+
+ mediaTest.MediaIsRecognized &= !sense;
+ }
+ else
+ mediaTest.MediaIsRecognized = false;
+ }
+ else
+ mediaTest.MediaIsRecognized = false;
+ }
+
+ if (mediaTest.MediaIsRecognized)
+ {
+ mediaTest.SupportsReadCapacitySpecified = true;
+ mediaTest.SupportsReadCapacity16Specified = true;
+
+ DicConsole.WriteLine("Querying SCSI READ CAPACITY...");
+ sense = dev.ReadCapacity(out buffer, out senseBuffer, timeout, out duration);
+ if (!sense && !dev.Error)
+ {
+ mediaTest.SupportsReadCapacity = true;
+ mediaTest.Blocks = (ulong)((buffer[0] << 24) + (buffer[1] << 16) + (buffer[2] << 8) + (buffer[3])) + 1;
+ mediaTest.BlockSize = (uint)((buffer[5] << 24) + (buffer[5] << 16) + (buffer[6] << 8) + (buffer[7]));
+ mediaTest.BlocksSpecified = true;
+ mediaTest.BlockSizeSpecified = true;
+ }
+
+ DicConsole.WriteLine("Querying SCSI READ CAPACITY (16)...");
+ sense = dev.ReadCapacity16(out buffer, out buffer, timeout, out duration);
+ if (!sense && !dev.Error)
+ {
+ mediaTest.SupportsReadCapacity16 = true;
+ byte[] temp = new byte[8];
+ Array.Copy(buffer, 0, temp, 0, 8);
+ Array.Reverse(temp);
+ mediaTest.Blocks = BitConverter.ToUInt64(temp, 0) + 1;
+ mediaTest.BlockSize = (uint)((buffer[5] << 24) + (buffer[5] << 16) + (buffer[6] << 8) + (buffer[7]));
+ mediaTest.BlocksSpecified = true;
+ mediaTest.BlockSizeSpecified = true;
+ }
+
+ decMode = null;
+
+ DicConsole.WriteLine("Querying SCSI MODE SENSE (10)...");
+ sense = dev.ModeSense10(out buffer, out senseBuffer, false, true, ScsiModeSensePageControl.Current, 0x3F, 0x00, timeout, out duration);
+ if (!sense && !dev.Error)
+ {
+ report.SCSI.SupportsModeSense10 = true;
+ decMode = Decoders.SCSI.Modes.DecodeMode10(buffer, dev.SCSIType);
+ }
+ DicConsole.WriteLine("Querying SCSI MODE SENSE...");
+ sense = dev.ModeSense(out buffer, out senseBuffer, timeout, out duration);
+ if (!sense && !dev.Error)
+ {
+ report.SCSI.SupportsModeSense6 = true;
+ if (!decMode.HasValue)
+ decMode = Decoders.SCSI.Modes.DecodeMode6(buffer, dev.SCSIType);
+ }
+
+ if (decMode.HasValue)
+ {
+ mediaTest.MediumType = (byte)decMode.Value.Header.MediumType;
+ mediaTest.MediumTypeSpecified = true;
+ if (decMode.Value.Header.BlockDescriptors != null && decMode.Value.Header.BlockDescriptors.Length > 0)
+ {
+ mediaTest.Density = (byte)decMode.Value.Header.BlockDescriptors[0].Density;
+ mediaTest.DensitySpecified = true;
+ }
+ }
+
+ if (mediaType.StartsWith("CD-") || mediaType == "Audio CD")
+ {
+ mediaTest.CanReadTOCSpecified = true;
+ mediaTest.CanReadFullTOCSpecified = true;
+ DicConsole.WriteLine("Querying CD TOC...");
+ mediaTest.CanReadTOC = !dev.ReadTocPmaAtip(out buffer, out senseBuffer, false, 0, 0, timeout, out duration);
+ DicConsole.WriteLine("Querying CD Full TOC...");
+ mediaTest.CanReadFullTOC = !dev.ReadRawToc(out buffer, out senseBuffer, 1, timeout, out duration);
+ }
+
+ if (mediaType.StartsWith("CD-R"))
+ {
+ mediaTest.CanReadATIPSpecified = true;
+ mediaTest.CanReadPMASpecified = true;
+ DicConsole.WriteLine("Querying CD ATIP...");
+ mediaTest.CanReadATIP = !dev.ReadAtip(out buffer, out senseBuffer, timeout, out duration);
+ DicConsole.WriteLine("Querying CD PMA...");
+ mediaTest.CanReadPMA = !dev.ReadPma(out buffer, out senseBuffer, timeout, out duration);
+ }
+
+ if (mediaType.StartsWith("DVD-") || mediaType.StartsWith("HD DVD-"))
+ {
+ mediaTest.CanReadPFISpecified = true;
+ mediaTest.CanReadDMISpecified = true;
+ DicConsole.WriteLine("Querying DVD PFI...");
+ mediaTest.CanReadPFI = !dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.PhysicalInformation, 0, timeout, out duration);
+ DicConsole.WriteLine("Querying DVD DMI...");
+ mediaTest.CanReadDMI = !dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.DiscManufacturingInformation, 0, timeout, out duration);
+ }
+
+ if (mediaType == "DVD-ROM")
+ {
+ mediaTest.CanReadCMISpecified = true;
+ DicConsole.WriteLine("Querying DVD CMI...");
+ mediaTest.CanReadCMI = !dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.CopyrightInformation, 0, timeout, out duration);
+ }
+
+ if (mediaType == "DVD-ROM" || mediaType == "HD DVD-ROM")
+ {
+ mediaTest.CanReadBCASpecified = true;
+ DicConsole.WriteLine("Querying DVD BCA...");
+ mediaTest.CanReadBCA = !dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.BurstCuttingArea, 0, timeout, out duration);
+ mediaTest.CanReadAACSSpecified = true;
+ DicConsole.WriteLine("Querying DVD AACS...");
+ mediaTest.CanReadAACS = !dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.DVD_AACS, 0, timeout, out duration);
+ }
+
+ if (mediaType == "BD-ROM")
+ {
+ mediaTest.CanReadBCASpecified = true;
+ DicConsole.WriteLine("Querying BD BCA...");
+ mediaTest.CanReadBCA = !dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.BD, 0, 0, MmcDiscStructureFormat.BD_BurstCuttingArea, 0, timeout, out duration);
+ }
+
+ if (mediaType == "DVD-RAM" || mediaType == "HD DVD-RAM")
+ {
+ mediaTest.CanReadDDSSpecified = true;
+ mediaTest.CanReadSpareAreaInformationSpecified = true;
+ mediaTest.CanReadDDS = !dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.DVDRAM_DDS, 0, timeout, out duration);
+ mediaTest.CanReadSpareAreaInformation = !dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.DVDRAM_SpareAreaInformation, 0, timeout, out duration);
+ }
+
+ if (mediaType.StartsWith("BD-R") && mediaType != "BD-ROM")
+ {
+ mediaTest.CanReadDDSSpecified = true;
+ mediaTest.CanReadSpareAreaInformationSpecified = true;
+ DicConsole.WriteLine("Querying BD DDS...");
+ mediaTest.CanReadDDS = !dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.BD, 0, 0, MmcDiscStructureFormat.BD_DDS, 0, timeout, out duration);
+ DicConsole.WriteLine("Querying BD SAI...");
+ mediaTest.CanReadSpareAreaInformation = !dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.BD, 0, 0, MmcDiscStructureFormat.BD_SpareAreaInformation, 0, timeout, out duration);
+ }
+
+ if (mediaType == "DVD-R" || mediaType == "DVD-RW")
+ {
+ mediaTest.CanReadPRISpecified = true;
+ DicConsole.WriteLine("Querying DVD PRI...");
+ mediaTest.CanReadPRI = !dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.PreRecordedInfo, 0, timeout, out duration);
+ }
+
+ if (mediaType == "DVD-R" || mediaType == "DVD-RW" || mediaType == "HD DVD-R")
+ {
+ mediaTest.CanReadMediaIDSpecified = true;
+ mediaTest.CanReadRecordablePFISpecified = true;
+ DicConsole.WriteLine("Querying DVD Media ID...");
+ mediaTest.CanReadMediaID = !dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.DVDR_MediaIdentifier, 0, timeout, out duration);
+ DicConsole.WriteLine("Querying DVD Embossed PFI...");
+ mediaTest.CanReadRecordablePFI = !dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.DVDR_PhysicalInformation, 0, timeout, out duration);
+ }
+
+ if (mediaType.StartsWith("DVD+R"))
+ {
+ mediaTest.CanReadADIPSpecified = true;
+ mediaTest.CanReadDCBSpecified = true;
+ DicConsole.WriteLine("Querying DVD ADIP...");
+ mediaTest.CanReadADIP = !dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.ADIP, 0, timeout, out duration);
+ DicConsole.WriteLine("Querying DVD DCB...");
+ mediaTest.CanReadDCB = !dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.DCB, 0, timeout, out duration);
+ }
+
+ if (mediaType == "HD DVD-ROM")
+ {
+ mediaTest.CanReadHDCMISpecified = true;
+ DicConsole.WriteLine("Querying HD DVD CMI...");
+ mediaTest.CanReadHDCMI = !dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.HDDVD_CopyrightInformation, 0, timeout, out duration);
+ }
+
+ if (mediaType.EndsWith(" DL"))
+ {
+ mediaTest.CanReadLayerCapacitySpecified = true;
+ DicConsole.WriteLine("Querying DVD Layer Capacity...");
+ mediaTest.CanReadLayerCapacity = !dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.DVDR_LayerCapacity, 0, timeout, out duration);
+ }
+
+ if (mediaType.StartsWith("BD-R"))
+ {
+ mediaTest.CanReadDiscInformationSpecified = true;
+ mediaTest.CanReadPACSpecified = true;
+ DicConsole.WriteLine("Querying BD Disc Information...");
+ mediaTest.CanReadDiscInformation = !dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.BD, 0, 0, MmcDiscStructureFormat.DiscInformation, 0, timeout, out duration);
+ DicConsole.WriteLine("Querying BD PAC...");
+ mediaTest.CanReadPAC = !dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.BD, 0, 0, MmcDiscStructureFormat.PAC, 0, timeout, out duration);
+ }
+
+ mediaTest.SupportsReadSpecified = true;
+ mediaTest.SupportsRead10Specified = true;
+ mediaTest.SupportsRead12Specified = true;
+ mediaTest.SupportsRead16Specified = true;
+
+ DicConsole.WriteLine("Trying SCSI READ (6)...");
+ mediaTest.SupportsRead = !dev.Read6(out buffer, out senseBuffer, 0, 2048, timeout, out duration);
+ DicConsole.WriteLine("Trying SCSI READ (10)...");
+ mediaTest.SupportsRead10 = !dev.Read10(out buffer, out senseBuffer, 0, false, true, false, false, 0, 2048, 0, 1, timeout, out duration);
+ DicConsole.WriteLine("Trying SCSI READ (12)...");
+ mediaTest.SupportsRead12 = !dev.Read12(out buffer, out senseBuffer, 0, false, true, false, false, 0, 2048, 0, 1, false, timeout, out duration);
+ DicConsole.WriteLine("Trying SCSI READ (16)...");
+ mediaTest.SupportsRead16 = !dev.Read16(out buffer, out senseBuffer, 0, false, true, false, 0, 2048, 0, 1, false, timeout, out duration);
+
+ if (options.Debug)
+ {
+ if (!tryPlextor)
+ {
+ pressedKey = new ConsoleKeyInfo();
+ while (pressedKey.Key != ConsoleKey.Y && pressedKey.Key != ConsoleKey.N)
+ {
+ DicConsole.Write("Do you have want to try Plextor vendor commands? THIS IS DANGEROUS AND CAN IRREVERSIBLY DESTROY YOUR DRIVE (IF IN DOUBT PRESS 'N') (Y/N): ");
+ pressedKey = System.Console.ReadKey();
+ DicConsole.WriteLine();
+ }
+
+ tryPlextor |= pressedKey.Key == ConsoleKey.Y;
+ }
+ }
+
+ if (mediaType.StartsWith("CD-") || mediaType == "Audio CD")
+ {
+ mediaTest.CanReadC2PointersSpecified = true;
+ mediaTest.CanReadCorrectedSubchannelSpecified = true;
+ mediaTest.CanReadCorrectedSubchannelWithC2Specified = true;
+ mediaTest.CanReadLeadInSpecified = true;
+ mediaTest.CanReadLeadOutSpecified = true;
+ mediaTest.CanReadPQSubchannelSpecified = true;
+ mediaTest.CanReadPQSubchannelWithC2Specified = true;
+ mediaTest.CanReadRWSubchannelSpecified = true;
+ mediaTest.CanReadRWSubchannelWithC2Specified = true;
+ mediaTest.SupportsReadCdMsfSpecified = true;
+ mediaTest.SupportsReadCdSpecified = true;
+ mediaTest.SupportsReadCdMsfRawSpecified = true;
+ mediaTest.SupportsReadCdRawSpecified = true;
+
+ if (mediaType == "Audio CD")
+ {
+ DicConsole.WriteLine("Trying SCSI READ CD...");
+ mediaTest.SupportsReadCd = !dev.ReadCd(out buffer, out senseBuffer, 0, 2352, 1, MmcSectorTypes.CDDA, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.None, MmcSubchannel.None, timeout, out duration);
+ DicConsole.WriteLine("Trying SCSI READ CD MSF...");
+ mediaTest.SupportsReadCdMsf = !dev.ReadCdMsf(out buffer, out senseBuffer, 0x00000200, 0x00000201, 2352, MmcSectorTypes.CDDA, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.None, MmcSubchannel.None, timeout, out duration);
+ }
+ else
+ {
+ DicConsole.WriteLine("Trying SCSI READ CD...");
+ mediaTest.SupportsReadCd = !dev.ReadCd(out buffer, out senseBuffer, 0, 2048, 1, MmcSectorTypes.AllTypes, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.None, MmcSubchannel.None, timeout, out duration);
+ DicConsole.WriteLine("Trying SCSI READ CD MSF...");
+ mediaTest.SupportsReadCdMsf = !dev.ReadCdMsf(out buffer, out senseBuffer, 0x00000200, 0x00000201, 2048, MmcSectorTypes.AllTypes, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.None, MmcSubchannel.None, timeout, out duration);
+ DicConsole.WriteLine("Trying SCSI READ CD full sector...");
+ mediaTest.SupportsReadCdRaw = !dev.ReadCd(out buffer, out senseBuffer, 0, 2352, 1, MmcSectorTypes.AllTypes, false, false, true, MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.None, MmcSubchannel.None, timeout, out duration);
+ DicConsole.WriteLine("Trying SCSI READ CD MSF full sector...");
+ mediaTest.SupportsReadCdMsfRaw = !dev.ReadCdMsf(out buffer, out senseBuffer, 0x00000200, 0x00000201, 2352, MmcSectorTypes.AllTypes, false, false, MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.None, MmcSubchannel.None, timeout, out duration);
+ }
+
+ if (mediaTest.SupportsReadCdRaw)
+ {
+ DicConsole.WriteLine("Trying to read CD Lead-In...");
+ for (int i = -150; i < 0; i++)
+ {
+ if (mediaType == "Audio CD")
+ sense = dev.ReadCd(out buffer, out senseBuffer, (uint)i, 2352, 1, MmcSectorTypes.CDDA, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.None, MmcSubchannel.None, timeout, out duration);
+ else
+ sense = dev.ReadCd(out buffer, out senseBuffer, (uint)i, 2352, 1, MmcSectorTypes.AllTypes, false, false, true, MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.None, MmcSubchannel.None, timeout, out duration);
+ if (!sense)
+ {
+ mediaTest.CanReadLeadIn = true;
+ break;
+ }
+ }
+
+ DicConsole.WriteLine("Trying to read CD Lead-Out...");
+ mediaTest.CanReadLeadOut = !dev.ReadCd(out buffer, out senseBuffer, (uint)(mediaTest.Blocks + 1), 2352, 1, MmcSectorTypes.AllTypes, false, false, true, MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.None, MmcSubchannel.None, timeout, out duration);
+ }
+
+ if (mediaType == "Audio CD" && mediaTest.SupportsReadCd)
+ {
+ DicConsole.WriteLine("Trying to read C2 Pointers...");
+ mediaTest.CanReadC2Pointers = !dev.ReadCd(out buffer, out senseBuffer, 0, 2646, 1, MmcSectorTypes.CDDA, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.C2Pointers, MmcSubchannel.None, timeout, out duration);
+ if (!mediaTest.CanReadC2Pointers)
+ mediaTest.CanReadC2Pointers = !dev.ReadCd(out buffer, out senseBuffer, 0, 2648, 1, MmcSectorTypes.CDDA, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.C2PointersAndBlock, MmcSubchannel.None, timeout, out duration);
+
+ DicConsole.WriteLine("Trying to read subchannels...");
+ mediaTest.CanReadPQSubchannel = !dev.ReadCd(out buffer, out senseBuffer, 0, 2368, 1, MmcSectorTypes.CDDA, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.None, MmcSubchannel.Q16, timeout, out duration);
+ mediaTest.CanReadRWSubchannel = !dev.ReadCd(out buffer, out senseBuffer, 0, 2448, 1, MmcSectorTypes.CDDA, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.None, MmcSubchannel.Raw, timeout, out duration);
+ mediaTest.CanReadCorrectedSubchannel = !dev.ReadCd(out buffer, out senseBuffer, 0, 2448, 1, MmcSectorTypes.CDDA, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.None, MmcSubchannel.RW, timeout, out duration);
+
+ DicConsole.WriteLine("Trying to read subchannels with C2 Pointers...");
+ mediaTest.CanReadPQSubchannelWithC2 = !dev.ReadCd(out buffer, out senseBuffer, 0, 2662, 1, MmcSectorTypes.CDDA, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.C2Pointers, MmcSubchannel.Q16, timeout, out duration);
+ if (!mediaTest.CanReadPQSubchannelWithC2)
+ mediaTest.CanReadPQSubchannelWithC2 = !dev.ReadCd(out buffer, out senseBuffer, 0, 2664, 1, MmcSectorTypes.CDDA, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.C2PointersAndBlock, MmcSubchannel.Q16, timeout, out duration);
+
+ mediaTest.CanReadRWSubchannelWithC2 = !dev.ReadCd(out buffer, out senseBuffer, 0, 2712, 1, MmcSectorTypes.CDDA, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.C2Pointers, MmcSubchannel.Raw, timeout, out duration);
+ if (!mediaTest.CanReadRWSubchannelWithC2)
+ mediaTest.CanReadRWSubchannelWithC2 = !dev.ReadCd(out buffer, out senseBuffer, 0, 2714, 1, MmcSectorTypes.CDDA, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.C2PointersAndBlock, MmcSubchannel.Raw, timeout, out duration);
+
+ mediaTest.CanReadCorrectedSubchannelWithC2 = !dev.ReadCd(out buffer, out senseBuffer, 0, 2712, 1, MmcSectorTypes.CDDA, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.C2Pointers, MmcSubchannel.RW, timeout, out duration);
+ if (!mediaTest.CanReadCorrectedSubchannelWithC2)
+ mediaTest.CanReadCorrectedSubchannelWithC2 = !dev.ReadCd(out buffer, out senseBuffer, 0, 2714, 1, MmcSectorTypes.CDDA, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.C2PointersAndBlock, MmcSubchannel.RW, timeout, out duration);
+ }
+ else if (mediaTest.SupportsReadCdRaw)
+ {
+ DicConsole.WriteLine("Trying to read C2 Pointers...");
+ mediaTest.CanReadC2Pointers = !dev.ReadCd(out buffer, out senseBuffer, 0, 2646, 1, MmcSectorTypes.AllTypes, false, false, true, MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.C2Pointers, MmcSubchannel.None, timeout, out duration);
+ if (!mediaTest.CanReadC2Pointers)
+ mediaTest.CanReadC2Pointers = !dev.ReadCd(out buffer, out senseBuffer, 0, 2646, 1, MmcSectorTypes.AllTypes, false, false, true, MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.C2PointersAndBlock, MmcSubchannel.None, timeout, out duration);
+
+ DicConsole.WriteLine("Trying to read subchannels...");
+ mediaTest.CanReadPQSubchannel = !dev.ReadCd(out buffer, out senseBuffer, 0, 2368, 1, MmcSectorTypes.AllTypes, false, false, true, MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.None, MmcSubchannel.Q16, timeout, out duration);
+ mediaTest.CanReadRWSubchannel = !dev.ReadCd(out buffer, out senseBuffer, 0, 2448, 1, MmcSectorTypes.AllTypes, false, false, true, MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.None, MmcSubchannel.Raw, timeout, out duration);
+ mediaTest.CanReadCorrectedSubchannel = !dev.ReadCd(out buffer, out senseBuffer, 0, 2448, 1, MmcSectorTypes.AllTypes, false, false, true, MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.None, MmcSubchannel.RW, timeout, out duration);
+
+ DicConsole.WriteLine("Trying to read subchannels with C2 Pointers...");
+ mediaTest.CanReadPQSubchannelWithC2 = !dev.ReadCd(out buffer, out senseBuffer, 0, 2662, 1, MmcSectorTypes.AllTypes, false, false, true, MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.C2Pointers, MmcSubchannel.Q16, timeout, out duration);
+ if (!mediaTest.CanReadPQSubchannelWithC2)
+ mediaTest.CanReadPQSubchannelWithC2 = !dev.ReadCd(out buffer, out senseBuffer, 0, 2664, 1, MmcSectorTypes.AllTypes, false, false, true, MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.C2PointersAndBlock, MmcSubchannel.Q16, timeout, out duration);
+
+ mediaTest.CanReadRWSubchannelWithC2 = !dev.ReadCd(out buffer, out senseBuffer, 0, 2712, 1, MmcSectorTypes.AllTypes, false, false, true, MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.C2Pointers, MmcSubchannel.Raw, timeout, out duration);
+ if (!mediaTest.CanReadRWSubchannelWithC2)
+ mediaTest.CanReadRWSubchannelWithC2 = !dev.ReadCd(out buffer, out senseBuffer, 0, 2714, 1, MmcSectorTypes.AllTypes, false, false, true, MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.C2PointersAndBlock, MmcSubchannel.Raw, timeout, out duration);
+
+ mediaTest.CanReadCorrectedSubchannelWithC2 = !dev.ReadCd(out buffer, out senseBuffer, 0, 2712, 1, MmcSectorTypes.AllTypes, false, false, true, MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.C2Pointers, MmcSubchannel.RW, timeout, out duration);
+ if (!mediaTest.CanReadCorrectedSubchannelWithC2)
+ mediaTest.CanReadCorrectedSubchannelWithC2 = !dev.ReadCd(out buffer, out senseBuffer, 0, 2714, 1, MmcSectorTypes.AllTypes, false, false, true, MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.C2PointersAndBlock, MmcSubchannel.RW, timeout, out duration);
+ }
+ else
+ {
+ DicConsole.WriteLine("Trying to read C2 Pointers...");
+ mediaTest.CanReadC2Pointers = !dev.ReadCd(out buffer, out senseBuffer, 0, 2342, 1, MmcSectorTypes.AllTypes, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.C2Pointers, MmcSubchannel.None, timeout, out duration);
+ if (!mediaTest.CanReadC2Pointers)
+ mediaTest.CanReadC2Pointers = !dev.ReadCd(out buffer, out senseBuffer, 0, 2344, 1, MmcSectorTypes.AllTypes, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.C2PointersAndBlock, MmcSubchannel.None, timeout, out duration);
+
+ DicConsole.WriteLine("Trying to read subchannels...");
+ mediaTest.CanReadPQSubchannel = !dev.ReadCd(out buffer, out senseBuffer, 0, 2064, 1, MmcSectorTypes.AllTypes, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.None, MmcSubchannel.Q16, timeout, out duration);
+ mediaTest.CanReadRWSubchannel = !dev.ReadCd(out buffer, out senseBuffer, 0, 2144, 1, MmcSectorTypes.AllTypes, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.None, MmcSubchannel.Raw, timeout, out duration);
+ mediaTest.CanReadCorrectedSubchannel = !dev.ReadCd(out buffer, out senseBuffer, 0, 2144, 1, MmcSectorTypes.AllTypes, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.None, MmcSubchannel.RW, timeout, out duration);
+
+ DicConsole.WriteLine("Trying to read subchannels with C2 Pointers...");
+ mediaTest.CanReadPQSubchannelWithC2 = !dev.ReadCd(out buffer, out senseBuffer, 0, 2358, 1, MmcSectorTypes.AllTypes, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.C2Pointers, MmcSubchannel.Q16, timeout, out duration);
+ if (!mediaTest.CanReadPQSubchannelWithC2)
+ mediaTest.CanReadPQSubchannelWithC2 = !dev.ReadCd(out buffer, out senseBuffer, 0, 2360, 1, MmcSectorTypes.AllTypes, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.C2PointersAndBlock, MmcSubchannel.Q16, timeout, out duration);
+
+ mediaTest.CanReadRWSubchannelWithC2 = !dev.ReadCd(out buffer, out senseBuffer, 0, 2438, 1, MmcSectorTypes.AllTypes, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.C2Pointers, MmcSubchannel.Raw, timeout, out duration);
+ if (!mediaTest.CanReadRWSubchannelWithC2)
+ mediaTest.CanReadRWSubchannelWithC2 = !dev.ReadCd(out buffer, out senseBuffer, 0, 2440, 1, MmcSectorTypes.AllTypes, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.C2PointersAndBlock, MmcSubchannel.Raw, timeout, out duration);
+
+ mediaTest.CanReadCorrectedSubchannelWithC2 = !dev.ReadCd(out buffer, out senseBuffer, 0, 2438, 1, MmcSectorTypes.AllTypes, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.C2Pointers, MmcSubchannel.RW, timeout, out duration);
+ if (!mediaTest.CanReadCorrectedSubchannelWithC2)
+ mediaTest.CanReadCorrectedSubchannelWithC2 = !dev.ReadCd(out buffer, out senseBuffer, 0, 2440, 1, MmcSectorTypes.AllTypes, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.C2PointersAndBlock, MmcSubchannel.RW, timeout, out duration);
+ }
+
+ if (options.Debug)
+ {
+ if (!tryNEC)
+ {
+ pressedKey = new ConsoleKeyInfo();
+ while (pressedKey.Key != ConsoleKey.Y && pressedKey.Key != ConsoleKey.N)
+ {
+ DicConsole.Write("Do you have want to try NEC vendor commands? THIS IS DANGEROUS AND CAN IRREVERSIBLY DESTROY YOUR DRIVE (IF IN DOUBT PRESS 'N') (Y/N): ");
+ pressedKey = System.Console.ReadKey();
+ DicConsole.WriteLine();
+ }
+
+ tryNEC |= pressedKey.Key == ConsoleKey.Y;
+ }
+
+ if (!tryPioneer)
+ {
+ pressedKey = new ConsoleKeyInfo();
+ while (pressedKey.Key != ConsoleKey.Y && pressedKey.Key != ConsoleKey.N)
+ {
+ DicConsole.Write("Do you have want to try Pioneer vendor commands? THIS IS DANGEROUS AND CAN IRREVERSIBLY DESTROY YOUR DRIVE (IF IN DOUBT PRESS 'N') (Y/N): ");
+ pressedKey = System.Console.ReadKey();
+ DicConsole.WriteLine();
+ }
+
+ tryPioneer |= pressedKey.Key == ConsoleKey.Y;
+ }
+ }
+
+ if (tryPlextor)
+ {
+ mediaTest.SupportsPlextorReadCDDASpecified = true;
+ DicConsole.WriteLine("Trying Plextor READ CD-DA...");
+ mediaTest.SupportsPlextorReadCDDA = !dev.PlextorReadCdDa(out buffer, out senseBuffer, 0, 2352, 1, PlextorSubchannel.None, timeout, out duration);
+ }
+
+ if (tryPioneer)
+ {
+ mediaTest.SupportsPioneerReadCDDASpecified = true;
+ mediaTest.SupportsPioneerReadCDDAMSFSpecified = true;
+ DicConsole.WriteLine("Trying Pioneer READ CD-DA...");
+ mediaTest.SupportsPioneerReadCDDA = !dev.PioneerReadCdDa(out buffer, out senseBuffer, 0, 2352, 1, PioneerSubchannel.None, timeout, out duration);
+ DicConsole.WriteLine("Trying Pioneer READ CD-DA MSF...");
+ mediaTest.SupportsPioneerReadCDDAMSF = !dev.PioneerReadCdDaMsf(out buffer, out senseBuffer, 0x00000200, 0x00000201, 2352, PioneerSubchannel.None, timeout, out duration);
+ }
+
+ if (tryNEC)
+ {
+ mediaTest.SupportsNECReadCDDASpecified = true;
+ DicConsole.WriteLine("Trying NEC READ CD-DA...");
+ mediaTest.SupportsNECReadCDDA = !dev.NecReadCdDa(out buffer, out senseBuffer, 0, 1, timeout, out duration);
+ }
+ }
+
+ mediaTest.LongBlockSize = mediaTest.BlockSize;
+ DicConsole.WriteLine("Trying SCSI READ LONG (10)...");
+ sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, 0xFFFF, timeout, out duration);
+ if (sense && !dev.Error)
+ {
+ Decoders.SCSI.FixedSense? decSense = Decoders.SCSI.Sense.DecodeFixed(senseBuffer);
+ if (decSense.HasValue)
+ {
+ if (decSense.Value.SenseKey == DiscImageChef.Decoders.SCSI.SenseKeys.IllegalRequest &&
+ decSense.Value.ASC == 0x24 && decSense.Value.ASCQ == 0x00)
+ {
+ mediaTest.SupportsReadLong = true;
+ if (decSense.Value.InformationValid && decSense.Value.ILI)
+ {
+ mediaTest.LongBlockSize = 0xFFFF - decSense.Value.Information;
+ mediaTest.LongBlockSizeSpecified = true;
+ }
+ }
+ }
+ }
+
+ if (options.Debug)
+ {
+ if (!tryHLDTST)
+ {
+ pressedKey = new ConsoleKeyInfo();
+ while (pressedKey.Key != ConsoleKey.Y && pressedKey.Key != ConsoleKey.N)
+ {
+ DicConsole.Write("Do you have want to try HL-DT-ST (aka LG) vendor commands? THIS IS DANGEROUS AND CAN IRREVERSIBLY DESTROY YOUR DRIVE (IF IN DOUBT PRESS 'N') (Y/N): ");
+ pressedKey = System.Console.ReadKey();
+ DicConsole.WriteLine();
+ }
+
+ tryHLDTST |= pressedKey.Key == ConsoleKey.Y;
+ }
+ }
+
+ if (mediaTest.SupportsReadLong && mediaTest.LongBlockSize == mediaTest.BlockSize)
+ {
+ if (mediaTest.BlockSize == 512)
+ {
+ // Long sector sizes for 512-byte magneto-opticals
+ foreach (ushort testSize in new []{ 600, 610, 630 })
+ {
+ sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, testSize, timeout, out duration);
+ if (!sense && !dev.Error)
+ {
+ mediaTest.SupportsReadLong = true;
+ mediaTest.LongBlockSize = testSize;
+ mediaTest.LongBlockSizeSpecified = true;
+ break;
+ }
+ }
+ }
+ else if (mediaTest.BlockSize == 1024)
+ {
+ sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, 1200, timeout, out duration);
+ if (!sense && !dev.Error)
+ {
+ mediaTest.SupportsReadLong = true;
+ mediaTest.LongBlockSize = 1200;
+ mediaTest.LongBlockSizeSpecified = true;
+ }
+ }
+ else if (mediaTest.BlockSize == 2048)
+ {
+ sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, 2380, timeout, out duration);
+ if (!sense && !dev.Error)
+ {
+ mediaTest.SupportsReadLong = true;
+ mediaTest.LongBlockSize = 2380;
+ mediaTest.LongBlockSizeSpecified = true;
+ }
+ }
+ else if (mediaTest.BlockSize == 4096)
+ {
+ sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, 4760, timeout, out duration);
+ if (!sense && !dev.Error)
+ {
+ mediaTest.SupportsReadLong = true;
+ mediaTest.LongBlockSize = 4760;
+ mediaTest.LongBlockSizeSpecified = true;
+ }
+ }
+ else if (mediaTest.BlockSize == 8192)
+ {
+ sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, 9424, timeout, out duration);
+ if (!sense && !dev.Error)
+ {
+ mediaTest.SupportsReadLong = true;
+ mediaTest.LongBlockSize = 9424;
+ mediaTest.LongBlockSizeSpecified = true;
+ }
+ }
+ }
+
+ if (tryPlextor)
+ {
+ mediaTest.SupportsPlextorReadRawDVDSpecified = true;
+ DicConsole.WriteLine("Trying Plextor trick to raw read DVDs...");
+ mediaTest.SupportsPlextorReadRawDVD = !dev.PlextorReadRawDvd(out buffer, out senseBuffer, 0, 1, timeout, out duration);
+ if (mediaTest.SupportsPlextorReadRawDVD)
+ mediaTest.SupportsPlextorReadRawDVD = !ArrayHelpers.ArrayIsNullOrEmpty(buffer);
+ }
+
+ if (tryHLDTST)
+ {
+ mediaTest.SupportsHLDTSTReadRawDVDSpecified = true;
+ DicConsole.WriteLine("Trying HL-DT-ST (aka LG) trick to raw read DVDs...");
+ mediaTest.SupportsHLDTSTReadRawDVD = !dev.HlDtStReadRawDvd(out buffer, out senseBuffer, 0, 1, timeout, out duration);
+ }
+
+ if (mediaTest.SupportsReadLong && mediaTest.LongBlockSize == mediaTest.BlockSize)
+ {
+ pressedKey = new ConsoleKeyInfo();
+ while (pressedKey.Key != ConsoleKey.Y && pressedKey.Key != ConsoleKey.N)
+ {
+ DicConsole.Write("Drive supports SCSI READ LONG but I cannot find the correct size. Do you want me to try? (This can take hours) (Y/N): ");
+ pressedKey = System.Console.ReadKey();
+ DicConsole.WriteLine();
+ }
+
+ if (pressedKey.Key == ConsoleKey.Y)
+ {
+ for (ushort i = (ushort)mediaTest.BlockSize; i < 0x4000; i++)
+ {
+ DicConsole.Write("\rTrying to READ LONG with a size of {0} bytes...", i);
+ sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, i, timeout, out duration);
+ if (!sense)
+ {
+ mediaTest.LongBlockSize = i;
+ mediaTest.LongBlockSizeSpecified = true;
+ break;
+ }
+ }
+ DicConsole.WriteLine();
+ }
+ }
+ }
+ mediaTests.Add(mediaTest);
+ }
+ report.SCSI.MultiMediaDevice.TestedMedia = mediaTests.ToArray();
+ }
+ }
+ #endregion MultiMediaDevice
+ #region SequentialAccessDevice
+ else if (dev.SCSIType == DiscImageChef.Decoders.SCSI.PeripheralDeviceTypes.SequentialAccess)
+ {
+ report.SCSI.SequentialDevice = new sscType();
+ DicConsole.WriteLine("Querying SCSI READ BLOCK LIMITS...");
+ sense = dev.ReadBlockLimits(out buffer, out senseBuffer, timeout, out duration);
+ if (!sense)
+ {
+ Decoders.SCSI.SSC.BlockLimits.BlockLimitsData? decBL = Decoders.SCSI.SSC.BlockLimits.Decode(buffer);
+ if (decBL.HasValue)
+ {
+ if (decBL.Value.granularity > 0)
+ {
+ report.SCSI.SequentialDevice.BlockSizeGranularitySpecified = true;
+ report.SCSI.SequentialDevice.BlockSizeGranularity = decBL.Value.granularity;
+ }
+ if (decBL.Value.maxBlockLen > 0)
+ {
+ report.SCSI.SequentialDevice.MaxBlockLengthSpecified = true;
+ report.SCSI.SequentialDevice.MaxBlockLength = decBL.Value.maxBlockLen;
+ }
+ if (decBL.Value.minBlockLen > 0)
+ {
+ report.SCSI.SequentialDevice.MinBlockLengthSpecified = true;
+ report.SCSI.SequentialDevice.MinBlockLength = decBL.Value.minBlockLen;
+ }
+ }
+ }
+
+ DicConsole.WriteLine("Querying SCSI REPORT DENSITY SUPPORT...");
+ sense = dev.ReportDensitySupport(out buffer, out senseBuffer, false, false, timeout, out duration);
+ if (!sense)
+ {
+ Decoders.SCSI.SSC.DensitySupport.DensitySupportHeader? dsh = Decoders.SCSI.SSC.DensitySupport.DecodeDensity(buffer);
+ if (dsh.HasValue)
+ {
+ report.SCSI.SequentialDevice.SupportedDensities = new SupportedDensity[dsh.Value.descriptors.Length];
+ for (int i = 0; i < dsh.Value.descriptors.Length; i++)
+ {
+ report.SCSI.SequentialDevice.SupportedDensities[i].BitsPerMm = dsh.Value.descriptors[i].bpmm;
+ report.SCSI.SequentialDevice.SupportedDensities[i].Capacity = dsh.Value.descriptors[i].capacity;
+ report.SCSI.SequentialDevice.SupportedDensities[i].DefaultDensity = dsh.Value.descriptors[i].defaultDensity;
+ report.SCSI.SequentialDevice.SupportedDensities[i].Description = dsh.Value.descriptors[i].description;
+ report.SCSI.SequentialDevice.SupportedDensities[i].Duplicate = dsh.Value.descriptors[i].duplicate;
+ report.SCSI.SequentialDevice.SupportedDensities[i].Name = dsh.Value.descriptors[i].name;
+ report.SCSI.SequentialDevice.SupportedDensities[i].Organization = dsh.Value.descriptors[i].organization;
+ report.SCSI.SequentialDevice.SupportedDensities[i].PrimaryCode = dsh.Value.descriptors[i].primaryCode;
+ report.SCSI.SequentialDevice.SupportedDensities[i].SecondaryCode = dsh.Value.descriptors[i].secondaryCode;
+ report.SCSI.SequentialDevice.SupportedDensities[i].Tracks = dsh.Value.descriptors[i].tracks;
+ report.SCSI.SequentialDevice.SupportedDensities[i].Width = dsh.Value.descriptors[i].width;
+ report.SCSI.SequentialDevice.SupportedDensities[i].Writable = dsh.Value.descriptors[i].writable;
+ }
+ }
+ }
+
+ DicConsole.WriteLine("Querying SCSI REPORT DENSITY SUPPORT for medium types...");
+ sense = dev.ReportDensitySupport(out buffer, out senseBuffer, true, false, timeout, out duration);
+ if (!sense)
+ {
+ Decoders.SCSI.SSC.DensitySupport.MediaTypeSupportHeader? mtsh = Decoders.SCSI.SSC.DensitySupport.DecodeMediumType(buffer);
+ if (mtsh.HasValue)
+ {
+ report.SCSI.SequentialDevice.SupportedMediaTypes = new SupportedMedia[mtsh.Value.descriptors.Length];
+ for (int i = 0; i < mtsh.Value.descriptors.Length; i++)
+ {
+ report.SCSI.SequentialDevice.SupportedMediaTypes[i].Description = mtsh.Value.descriptors[i].description;
+ report.SCSI.SequentialDevice.SupportedMediaTypes[i].Length = mtsh.Value.descriptors[i].length;
+ report.SCSI.SequentialDevice.SupportedMediaTypes[i].MediumType = mtsh.Value.descriptors[i].mediumType;
+ report.SCSI.SequentialDevice.SupportedMediaTypes[i].Name = mtsh.Value.descriptors[i].name;
+ report.SCSI.SequentialDevice.SupportedMediaTypes[i].Organization = mtsh.Value.descriptors[i].organization;
+ report.SCSI.SequentialDevice.SupportedMediaTypes[i].Width = mtsh.Value.descriptors[i].width;
+ if (mtsh.Value.descriptors[i].densityCodes != null)
+ {
+ report.SCSI.SequentialDevice.SupportedMediaTypes[i].DensityCodes = new int[mtsh.Value.descriptors[i].densityCodes.Length];
+ for (int j = 0; j < mtsh.Value.descriptors.Length; j++)
+ report.SCSI.SequentialDevice.SupportedMediaTypes[i].DensityCodes[j] = (int)mtsh.Value.descriptors[i].densityCodes[j];
+ }
+ }
+ }
+ }
+
+ List seqTests = new List();
+
+ pressedKey = new ConsoleKeyInfo();
+ while (pressedKey.Key != ConsoleKey.N)
+ {
+ 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): ");
+ pressedKey = System.Console.ReadKey();
+ DicConsole.WriteLine();
+ }
+
+ if (pressedKey.Key == ConsoleKey.Y)
+ {
+ DicConsole.WriteLine("Please insert it in the drive and press any key when it is ready.");
+ System.Console.ReadKey(true);
+
+ SequentialMedia seqTest = new SequentialMedia();
+ DicConsole.Write("Please write a description of the media type and press enter: ");
+ seqTest.MediumTypeName = System.Console.ReadLine();
+ DicConsole.Write("Please write the media manufacturer and press enter: ");
+ seqTest.Manufacturer = System.Console.ReadLine();
+ DicConsole.Write("Please write the media model and press enter: ");
+ seqTest.Model = System.Console.ReadLine();
+
+ seqTest.MediaIsRecognized = true;
+
+ sense = dev.Load(out senseBuffer, timeout, out duration);
+ sense = dev.ScsiTestUnitReady(out senseBuffer, timeout, out duration);
+ if (sense)
+ {
+ Decoders.SCSI.FixedSense? decSense = Decoders.SCSI.Sense.DecodeFixed(senseBuffer);
+ if (decSense.HasValue)
+ {
+ if (decSense.Value.ASC == 0x3A)
+ {
+ int leftRetries = 20;
+ while (leftRetries > 0)
+ {
+ DicConsole.Write("\rWaiting for drive to become ready");
+ System.Threading.Thread.Sleep(2000);
+ sense = dev.ScsiTestUnitReady(out senseBuffer, timeout, out duration);
+ if (!sense)
+ break;
+
+ leftRetries--;
+ }
+
+ seqTest.MediaIsRecognized &= !sense;
+ }
+ else if (decSense.Value.ASC == 0x04 && decSense.Value.ASCQ == 0x01)
+ {
+ int leftRetries = 20;
+ while (leftRetries > 0)
+ {
+ DicConsole.Write("\rWaiting for drive to become ready");
+ System.Threading.Thread.Sleep(2000);
+ sense = dev.ScsiTestUnitReady(out senseBuffer, timeout, out duration);
+ if (!sense)
+ break;
+
+ leftRetries--;
+ }
+
+ seqTest.MediaIsRecognized &= !sense;
+ }
+ else
+ seqTest.MediaIsRecognized = false;
+ }
+ else
+ seqTest.MediaIsRecognized = false;
+ }
+
+ if (seqTest.MediaIsRecognized)
+ {
+ decMode = null;
+
+ DicConsole.WriteLine("Querying SCSI MODE SENSE (10)...");
+ sense = dev.ModeSense10(out buffer, out senseBuffer, false, true, ScsiModeSensePageControl.Current, 0x3F, 0x00, timeout, out duration);
+ if (!sense && !dev.Error)
+ {
+ report.SCSI.SupportsModeSense10 = true;
+ decMode = Decoders.SCSI.Modes.DecodeMode10(buffer, dev.SCSIType);
+ }
+
+ DicConsole.WriteLine("Querying SCSI MODE SENSE...");
+ sense = dev.ModeSense(out buffer, out senseBuffer, timeout, out duration);
+ if (!sense && !dev.Error)
+ {
+ report.SCSI.SupportsModeSense6 = true;
+ if (!decMode.HasValue)
+ decMode = Decoders.SCSI.Modes.DecodeMode6(buffer, dev.SCSIType);
+ }
+
+ if (decMode.HasValue)
+ {
+ seqTest.MediumType = (byte)decMode.Value.Header.MediumType;
+ seqTest.MediumTypeSpecified = true;
+ if (decMode.Value.Header.BlockDescriptors != null && decMode.Value.Header.BlockDescriptors.Length > 0)
+ {
+ seqTest.Density = (byte)decMode.Value.Header.BlockDescriptors[0].Density;
+ seqTest.DensitySpecified = true;
+ }
+ }
+ }
+
+ DicConsole.WriteLine("Querying SCSI REPORT DENSITY SUPPORT for current media...");
+ sense = dev.ReportDensitySupport(out buffer, out senseBuffer, false, true, timeout, out duration);
+ if (!sense)
+ {
+ Decoders.SCSI.SSC.DensitySupport.DensitySupportHeader? dsh = Decoders.SCSI.SSC.DensitySupport.DecodeDensity(buffer);
+ if (dsh.HasValue)
+ {
+ seqTest.SupportedDensities = new SupportedDensity[dsh.Value.descriptors.Length];
+ for (int i = 0; i < dsh.Value.descriptors.Length; i++)
+ {
+ seqTest.SupportedDensities[i].BitsPerMm = dsh.Value.descriptors[i].bpmm;
+ seqTest.SupportedDensities[i].Capacity = dsh.Value.descriptors[i].capacity;
+ seqTest.SupportedDensities[i].DefaultDensity = dsh.Value.descriptors[i].defaultDensity;
+ seqTest.SupportedDensities[i].Description = dsh.Value.descriptors[i].description;
+ seqTest.SupportedDensities[i].Duplicate = dsh.Value.descriptors[i].duplicate;
+ seqTest.SupportedDensities[i].Name = dsh.Value.descriptors[i].name;
+ seqTest.SupportedDensities[i].Organization = dsh.Value.descriptors[i].organization;
+ seqTest.SupportedDensities[i].PrimaryCode = dsh.Value.descriptors[i].primaryCode;
+ seqTest.SupportedDensities[i].SecondaryCode = dsh.Value.descriptors[i].secondaryCode;
+ seqTest.SupportedDensities[i].Tracks = dsh.Value.descriptors[i].tracks;
+ seqTest.SupportedDensities[i].Width = dsh.Value.descriptors[i].width;
+ seqTest.SupportedDensities[i].Writable = dsh.Value.descriptors[i].writable;
+ }
+ }
+ }
+
+ DicConsole.WriteLine("Querying SCSI REPORT DENSITY SUPPORT for medium types for current media...");
+ sense = dev.ReportDensitySupport(out buffer, out senseBuffer, true, true, timeout, out duration);
+ if (!sense)
+ {
+ Decoders.SCSI.SSC.DensitySupport.MediaTypeSupportHeader? mtsh = Decoders.SCSI.SSC.DensitySupport.DecodeMediumType(buffer);
+ if (mtsh.HasValue)
+ {
+ seqTest.SupportedMediaTypes = new SupportedMedia[mtsh.Value.descriptors.Length];
+ for (int i = 0; i < mtsh.Value.descriptors.Length; i++)
+ {
+ seqTest.SupportedMediaTypes[i].Description = mtsh.Value.descriptors[i].description;
+ seqTest.SupportedMediaTypes[i].Length = mtsh.Value.descriptors[i].length;
+ seqTest.SupportedMediaTypes[i].MediumType = mtsh.Value.descriptors[i].mediumType;
+ seqTest.SupportedMediaTypes[i].Name = mtsh.Value.descriptors[i].name;
+ seqTest.SupportedMediaTypes[i].Organization = mtsh.Value.descriptors[i].organization;
+ seqTest.SupportedMediaTypes[i].Width = mtsh.Value.descriptors[i].width;
+ if (mtsh.Value.descriptors[i].densityCodes != null)
+ {
+ seqTest.SupportedMediaTypes[i].DensityCodes = new int[mtsh.Value.descriptors[i].densityCodes.Length];
+ for (int j = 0; j < mtsh.Value.descriptors.Length; j++)
+ seqTest.SupportedMediaTypes[i].DensityCodes[j] = (int)mtsh.Value.descriptors[i].densityCodes[j];
+ }
+ }
+ }
+ }
+
+ seqTest.CanReadMediaSerialSpecified = true;
+ DicConsole.WriteLine("Trying SCSI READ MEDIA SERIAL NUMBER...");
+ seqTest.CanReadMediaSerial = !dev.ReadMediaSerialNumber(out buffer, out senseBuffer, timeout, out duration);
+ seqTests.Add(seqTest);
+ }
+ }
+ report.SCSI.SequentialDevice.TestedMedia = seqTests.ToArray();
+ }
+ #endregion SequentialAccessDevice
+ #region OtherDevices
+ else
+ {
+ if (removable)
+ {
+ List mediaTests = new List();
+
+ pressedKey = new ConsoleKeyInfo();
+ while (pressedKey.Key != ConsoleKey.N)
+ {
+ 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): ");
+ pressedKey = System.Console.ReadKey();
+ DicConsole.WriteLine();
+ }
+
+ if (pressedKey.Key == ConsoleKey.Y)
+ {
+ DicConsole.WriteLine("Please insert it in the drive and press any key when it is ready.");
+ 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 manufacturer and press enter: ");
+ mediaTest.Manufacturer = 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;
+
+ sense = dev.ScsiTestUnitReady(out senseBuffer, timeout, out duration);
+ if (sense)
+ {
+ Decoders.SCSI.FixedSense? decSense = Decoders.SCSI.Sense.DecodeFixed(senseBuffer);
+ if (decSense.HasValue)
+ {
+ if (decSense.Value.ASC == 0x3A)
+ {
+ int leftRetries = 20;
+ while (leftRetries > 0)
+ {
+ DicConsole.Write("\rWaiting for drive to become ready");
+ System.Threading.Thread.Sleep(2000);
+ sense = dev.ScsiTestUnitReady(out senseBuffer, timeout, out duration);
+ if (!sense)
+ break;
+
+ leftRetries--;
+ }
+
+ mediaTest.MediaIsRecognized &= !sense;
+ }
+ else if (decSense.Value.ASC == 0x04 && decSense.Value.ASCQ == 0x01)
+ {
+ int leftRetries = 20;
+ while (leftRetries > 0)
+ {
+ DicConsole.Write("\rWaiting for drive to become ready");
+ System.Threading.Thread.Sleep(2000);
+ sense = dev.ScsiTestUnitReady(out senseBuffer, timeout, out duration);
+ if (!sense)
+ break;
+
+ leftRetries--;
+ }
+
+ mediaTest.MediaIsRecognized &= !sense;
+ }
+ else
+ mediaTest.MediaIsRecognized = false;
+ }
+ else
+ mediaTest.MediaIsRecognized = false;
+ }
+
+ if (mediaTest.MediaIsRecognized)
+ {
+ mediaTest.SupportsReadCapacitySpecified = true;
+ mediaTest.SupportsReadCapacity16Specified = true;
+
+ DicConsole.WriteLine("Querying SCSI READ CAPACITY...");
+ sense = dev.ReadCapacity(out buffer, out senseBuffer, timeout, out duration);
+ if (!sense && !dev.Error)
+ {
+ mediaTest.SupportsReadCapacity = true;
+ mediaTest.Blocks = (ulong)((buffer[0] << 24) + (buffer[1] << 16) + (buffer[2] << 8) + (buffer[3])) + 1;
+ mediaTest.BlockSize = (uint)((buffer[5] << 24) + (buffer[5] << 16) + (buffer[6] << 8) + (buffer[7]));
+ mediaTest.BlocksSpecified = true;
+ mediaTest.BlockSizeSpecified = true;
+ }
+
+ DicConsole.WriteLine("Querying SCSI READ CAPACITY (16)...");
+ sense = dev.ReadCapacity16(out buffer, out buffer, timeout, out duration);
+ if (!sense && !dev.Error)
+ {
+ mediaTest.SupportsReadCapacity16 = true;
+ byte[] temp = new byte[8];
+ Array.Copy(buffer, 0, temp, 0, 8);
+ Array.Reverse(temp);
+ mediaTest.Blocks = BitConverter.ToUInt64(temp, 0) + 1;
+ mediaTest.BlockSize = (uint)((buffer[5] << 24) + (buffer[5] << 16) + (buffer[6] << 8) + (buffer[7]));
+ mediaTest.BlocksSpecified = true;
+ mediaTest.BlockSizeSpecified = true;
+ }
+
+ decMode = null;
+
+ DicConsole.WriteLine("Querying SCSI MODE SENSE (10)...");
+ sense = dev.ModeSense10(out buffer, out senseBuffer, false, true, ScsiModeSensePageControl.Current, 0x3F, 0x00, timeout, out duration);
+ if (!sense && !dev.Error)
+ {
+ report.SCSI.SupportsModeSense10 = true;
+ decMode = Decoders.SCSI.Modes.DecodeMode10(buffer, dev.SCSIType);
+ }
+
+ DicConsole.WriteLine("Querying SCSI MODE SENSE...");
+ sense = dev.ModeSense(out buffer, out senseBuffer, timeout, out duration);
+ if (!sense && !dev.Error)
+ {
+ report.SCSI.SupportsModeSense6 = true;
+ if (!decMode.HasValue)
+ decMode = Decoders.SCSI.Modes.DecodeMode6(buffer, dev.SCSIType);
+ }
+
+ if (decMode.HasValue)
+ {
+ mediaTest.MediumType = (byte)decMode.Value.Header.MediumType;
+ mediaTest.MediumTypeSpecified = true;
+ if (decMode.Value.Header.BlockDescriptors != null && decMode.Value.Header.BlockDescriptors.Length > 0)
+ {
+ mediaTest.Density = (byte)decMode.Value.Header.BlockDescriptors[0].Density;
+ mediaTest.DensitySpecified = true;
+ }
+ }
+
+ mediaTest.SupportsReadSpecified = true;
+ mediaTest.SupportsRead10Specified = true;
+ mediaTest.SupportsRead12Specified = true;
+ mediaTest.SupportsRead16Specified = true;
+ mediaTest.SupportsReadLongSpecified = true;
+
+ DicConsole.WriteLine("Trying SCSI READ (6)...");
+ mediaTest.SupportsRead = !dev.Read6(out buffer, out senseBuffer, 0, mediaTest.BlockSize, timeout, out duration);
+ DicConsole.WriteLine("Trying SCSI READ (10)...");
+ mediaTest.SupportsRead10 = !dev.Read10(out buffer, out senseBuffer, 0, false, true, false, false, 0, mediaTest.BlockSize, 0, 1, timeout, out duration);
+ DicConsole.WriteLine("Trying SCSI READ (12)...");
+ mediaTest.SupportsRead12 = !dev.Read12(out buffer, out senseBuffer, 0, false, true, false, false, 0, mediaTest.BlockSize, 0, 1, false, timeout, out duration);
+ DicConsole.WriteLine("Trying SCSI READ (16)...");
+ mediaTest.SupportsRead16 = !dev.Read16(out buffer, out senseBuffer, 0, false, true, false, 0, mediaTest.BlockSize, 0, 1, false, timeout, out duration);
+
+ mediaTest.LongBlockSize = mediaTest.BlockSize;
+ DicConsole.WriteLine("Trying SCSI READ LONG (10)...");
+ sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, 0xFFFF, timeout, out duration);
+ if (sense && !dev.Error)
+ {
+ Decoders.SCSI.FixedSense? decSense = Decoders.SCSI.Sense.DecodeFixed(senseBuffer);
+ if (decSense.HasValue)
+ {
+ if (decSense.Value.SenseKey == DiscImageChef.Decoders.SCSI.SenseKeys.IllegalRequest &&
+ decSense.Value.ASC == 0x24 && decSense.Value.ASCQ == 0x00)
+ {
+ mediaTest.SupportsReadLong = true;
+ if (decSense.Value.InformationValid && decSense.Value.ILI)
+ {
+ mediaTest.LongBlockSize = 0xFFFF - decSense.Value.Information;
+ mediaTest.LongBlockSizeSpecified = true;
+ }
+ }
+ }
+ }
+
+ if (mediaTest.SupportsReadLong && mediaTest.LongBlockSize == mediaTest.BlockSize)
+ {
+ if (mediaTest.BlockSize == 512)
+ {
+ // Long sector sizes for 512-byte magneto-opticals
+ foreach (ushort testSize in new []{ 600, 610, 630 })
+ {
+ sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, testSize, timeout, out duration);
+ if (!sense && !dev.Error)
+ {
+ mediaTest.SupportsReadLong = true;
+ mediaTest.LongBlockSize = testSize;
+ mediaTest.LongBlockSizeSpecified = true;
+ break;
+ }
+ }
+ }
+ else if (mediaTest.BlockSize == 1024)
+ {
+ sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, 1200, timeout, out duration);
+ if (!sense && !dev.Error)
+ {
+ mediaTest.SupportsReadLong = true;
+ mediaTest.LongBlockSize = 1200;
+ mediaTest.LongBlockSizeSpecified = true;
+ }
+ }
+ else if (mediaTest.BlockSize == 2048)
+ {
+ sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, 2380, timeout, out duration);
+ if (!sense && !dev.Error)
+ {
+ mediaTest.SupportsReadLong = true;
+ mediaTest.LongBlockSize = 2380;
+ mediaTest.LongBlockSizeSpecified = true;
+ }
+ }
+ else if (mediaTest.BlockSize == 4096)
+ {
+ sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, 4760, timeout, out duration);
+ if (!sense && !dev.Error)
+ {
+ mediaTest.SupportsReadLong = true;
+ mediaTest.LongBlockSize = 4760;
+ mediaTest.LongBlockSizeSpecified = true;
+ }
+ }
+ else if (mediaTest.BlockSize == 8192)
+ {
+ sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, 9424, timeout, out duration);
+ if (!sense && !dev.Error)
+ {
+ mediaTest.SupportsReadLong = true;
+ mediaTest.LongBlockSize = 9424;
+ mediaTest.LongBlockSizeSpecified = true;
+ }
+ }
+ }
+
+ if (mediaTest.SupportsReadLong && mediaTest.LongBlockSize == mediaTest.BlockSize)
+ {
+ pressedKey = new ConsoleKeyInfo();
+ while (pressedKey.Key != ConsoleKey.Y && pressedKey.Key != ConsoleKey.N)
+ {
+ DicConsole.Write("Drive supports SCSI READ LONG but I cannot find the correct size. Do you want me to try? (This can take hours) (Y/N): ");
+ pressedKey = System.Console.ReadKey();
+ DicConsole.WriteLine();
+ }
+
+ if (pressedKey.Key == ConsoleKey.Y)
+ {
+ for (ushort i = (ushort)mediaTest.BlockSize; i < 0x4000; i++)
+ {
+ DicConsole.Write("\rTrying to READ LONG with a size of {0} bytes...", i);
+ sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, i, timeout, out duration);
+ if (!sense)
+ {
+ mediaTest.LongBlockSize = i;
+ mediaTest.LongBlockSizeSpecified = true;
+ break;
+ }
+ }
+ DicConsole.WriteLine();
+ }
+ }
+
+ mediaTest.CanReadMediaSerialSpecified = true;
+ DicConsole.WriteLine("Trying SCSI READ MEDIA SERIAL NUMBER...");
+ mediaTest.CanReadMediaSerial = !dev.ReadMediaSerialNumber(out buffer, out senseBuffer, timeout, out duration);
+ }
+ mediaTests.Add(mediaTest);
+ }
+ }
+ report.SCSI.RemovableMedias = mediaTests.ToArray();
+ }
+ else
+ {
+ report.SCSI.ReadCapabilities = new testedMediaType();
+ report.SCSI.ReadCapabilitiesSpecified = true;
+ report.SCSI.ReadCapabilities.MediaIsRecognized = true;
+
+ report.SCSI.ReadCapabilities.SupportsReadCapacitySpecified = true;
+ report.SCSI.ReadCapabilities.SupportsReadCapacity16Specified = true;
+
+ DicConsole.WriteLine("Querying SCSI READ CAPACITY...");
+ sense = dev.ReadCapacity(out buffer, out senseBuffer, timeout, out duration);
+ if (!sense && !dev.Error)
+ {
+ report.SCSI.ReadCapabilities.SupportsReadCapacity = true;
+ report.SCSI.ReadCapabilities.Blocks = (ulong)((buffer[0] << 24) + (buffer[1] << 16) + (buffer[2] << 8) + (buffer[3])) + 1;
+ report.SCSI.ReadCapabilities.BlockSize = (uint)((buffer[5] << 24) + (buffer[5] << 16) + (buffer[6] << 8) + (buffer[7]));
+ report.SCSI.ReadCapabilities.BlocksSpecified = true;
+ report.SCSI.ReadCapabilities.BlockSizeSpecified = true;
+ }
+
+ DicConsole.WriteLine("Querying SCSI READ CAPACITY (16)...");
+ sense = dev.ReadCapacity16(out buffer, out buffer, timeout, out duration);
+ if (!sense && !dev.Error)
+ {
+ report.SCSI.ReadCapabilities.SupportsReadCapacity16 = true;
+ byte[] temp = new byte[8];
+ Array.Copy(buffer, 0, temp, 0, 8);
+ Array.Reverse(temp);
+ report.SCSI.ReadCapabilities.Blocks = BitConverter.ToUInt64(temp, 0) + 1;
+ report.SCSI.ReadCapabilities.BlockSize = (uint)((buffer[5] << 24) + (buffer[5] << 16) + (buffer[6] << 8) + (buffer[7]));
+ report.SCSI.ReadCapabilities.BlocksSpecified = true;
+ report.SCSI.ReadCapabilities.BlockSizeSpecified = true;
+ }
+
+ decMode = null;
+
+ DicConsole.WriteLine("Querying SCSI MODE SENSE (10)...");
+ sense = dev.ModeSense10(out buffer, out senseBuffer, false, true, ScsiModeSensePageControl.Current, 0x3F, 0x00, timeout, out duration);
+ if (!sense && !dev.Error)
+ {
+ report.SCSI.SupportsModeSense10 = true;
+ decMode = Decoders.SCSI.Modes.DecodeMode10(buffer, dev.SCSIType);
+ }
+
+ DicConsole.WriteLine("Querying SCSI MODE SENSE...");
+ sense = dev.ModeSense(out buffer, out senseBuffer, timeout, out duration);
+ if (!sense && !dev.Error)
+ {
+ report.SCSI.SupportsModeSense6 = true;
+ if (!decMode.HasValue)
+ decMode = Decoders.SCSI.Modes.DecodeMode6(buffer, dev.SCSIType);
+ }
+
+ if (decMode.HasValue)
+ {
+ report.SCSI.ReadCapabilities.MediumType = (byte)decMode.Value.Header.MediumType;
+ report.SCSI.ReadCapabilities.MediumTypeSpecified = true;
+ if (decMode.Value.Header.BlockDescriptors != null && decMode.Value.Header.BlockDescriptors.Length > 0)
+ {
+ report.SCSI.ReadCapabilities.Density = (byte)decMode.Value.Header.BlockDescriptors[0].Density;
+ report.SCSI.ReadCapabilities.DensitySpecified = true;
+ }
+ }
+
+ report.SCSI.ReadCapabilities.SupportsReadSpecified = true;
+ report.SCSI.ReadCapabilities.SupportsRead10Specified = true;
+ report.SCSI.ReadCapabilities.SupportsRead12Specified = true;
+ report.SCSI.ReadCapabilities.SupportsRead16Specified = true;
+ report.SCSI.ReadCapabilities.SupportsReadLongSpecified = true;
+
+ DicConsole.WriteLine("Trying SCSI READ (6)...");
+ report.SCSI.ReadCapabilities.SupportsRead = !dev.Read6(out buffer, out senseBuffer, 0, report.SCSI.ReadCapabilities.BlockSize, timeout, out duration);
+ DicConsole.WriteLine("Trying SCSI READ (10)...");
+ report.SCSI.ReadCapabilities.SupportsRead10 = !dev.Read10(out buffer, out senseBuffer, 0, false, true, false, false, 0, report.SCSI.ReadCapabilities.BlockSize, 0, 1, timeout, out duration);
+ DicConsole.WriteLine("Trying SCSI READ (12)...");
+ report.SCSI.ReadCapabilities.SupportsRead12 = !dev.Read12(out buffer, out senseBuffer, 0, false, true, false, false, 0, report.SCSI.ReadCapabilities.BlockSize, 0, 1, false, timeout, out duration);
+ DicConsole.WriteLine("Trying SCSI READ (16)...");
+ report.SCSI.ReadCapabilities.SupportsRead16 = !dev.Read16(out buffer, out senseBuffer, 0, false, true, false, 0, report.SCSI.ReadCapabilities.BlockSize, 0, 1, false, timeout, out duration);
+
+ report.SCSI.ReadCapabilities.LongBlockSize = report.SCSI.ReadCapabilities.BlockSize;
+ DicConsole.WriteLine("Trying SCSI READ LONG (10)...");
+ sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, 0xFFFF, timeout, out duration);
+ if (sense && !dev.Error)
+ {
+ Decoders.SCSI.FixedSense? decSense = Decoders.SCSI.Sense.DecodeFixed(senseBuffer);
+ if (decSense.HasValue)
+ {
+ if (decSense.Value.SenseKey == DiscImageChef.Decoders.SCSI.SenseKeys.IllegalRequest &&
+ decSense.Value.ASC == 0x24 && decSense.Value.ASCQ == 0x00)
+ {
+ report.SCSI.ReadCapabilities.SupportsReadLong = true;
+ if (decSense.Value.InformationValid && decSense.Value.ILI)
+ {
+ report.SCSI.ReadCapabilities.LongBlockSize = 0xFFFF - decSense.Value.Information;
+ report.SCSI.ReadCapabilities.LongBlockSizeSpecified = true;
+ }
+ }
+ }
+ }
+
+ if (report.SCSI.ReadCapabilities.SupportsReadLong && report.SCSI.ReadCapabilities.LongBlockSize == report.SCSI.ReadCapabilities.BlockSize)
+ {
+ if (report.SCSI.ReadCapabilities.BlockSize == 512)
+ {
+ // Long sector sizes for 512-byte magneto-opticals
+ foreach (ushort testSize in new []{ 600, 610, 630 })
+ {
+ sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, testSize, timeout, out duration);
+ if (!sense && !dev.Error)
+ {
+ report.SCSI.ReadCapabilities.SupportsReadLong = true;
+ report.SCSI.ReadCapabilities.LongBlockSize = testSize;
+ report.SCSI.ReadCapabilities.LongBlockSizeSpecified = true;
+ break;
+ }
+ }
+ }
+ else if (report.SCSI.ReadCapabilities.BlockSize == 1024)
+ {
+ sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, 1200, timeout, out duration);
+ if (!sense && !dev.Error)
+ {
+ report.SCSI.ReadCapabilities.SupportsReadLong = true;
+ report.SCSI.ReadCapabilities.LongBlockSize = 1200;
+ report.SCSI.ReadCapabilities.LongBlockSizeSpecified = true;
+ }
+ }
+ else if (report.SCSI.ReadCapabilities.BlockSize == 2048)
+ {
+ sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, 2380, timeout, out duration);
+ if (!sense && !dev.Error)
+ {
+ report.SCSI.ReadCapabilities.SupportsReadLong = true;
+ report.SCSI.ReadCapabilities.LongBlockSize = 2380;
+ report.SCSI.ReadCapabilities.LongBlockSizeSpecified = true;
+ }
+ }
+ else if (report.SCSI.ReadCapabilities.BlockSize == 4096)
+ {
+ sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, 4760, timeout, out duration);
+ if (!sense && !dev.Error)
+ {
+ report.SCSI.ReadCapabilities.SupportsReadLong = true;
+ report.SCSI.ReadCapabilities.LongBlockSize = 4760;
+ report.SCSI.ReadCapabilities.LongBlockSizeSpecified = true;
+ }
+ }
+ else if (report.SCSI.ReadCapabilities.BlockSize == 8192)
+ {
+ sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, 9424, timeout, out duration);
+ if (!sense && !dev.Error)
+ {
+ report.SCSI.ReadCapabilities.SupportsReadLong = true;
+ report.SCSI.ReadCapabilities.LongBlockSize = 9424;
+ report.SCSI.ReadCapabilities.LongBlockSizeSpecified = true;
+ }
+ }
+ }
+
+ if (report.SCSI.ReadCapabilities.SupportsReadLong && report.SCSI.ReadCapabilities.LongBlockSize == report.SCSI.ReadCapabilities.BlockSize)
+ {
+ pressedKey = new ConsoleKeyInfo();
+ while (pressedKey.Key != ConsoleKey.Y && pressedKey.Key != ConsoleKey.N)
+ {
+ DicConsole.Write("Drive supports SCSI READ LONG but I cannot find the correct size. Do you want me to try? (This can take hours) (Y/N): ");
+ pressedKey = System.Console.ReadKey();
+ DicConsole.WriteLine();
+ }
+
+ if (pressedKey.Key == ConsoleKey.Y)
+ {
+ for (ushort i = (ushort)report.SCSI.ReadCapabilities.BlockSize; i < 0x4000; i++)
+ {
+ DicConsole.Write("\rTrying to READ LONG with a size of {0} bytes...", i);
+ sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, i, timeout, out duration);
+ if (!sense)
+ {
+ report.SCSI.ReadCapabilities.LongBlockSize = i;
+ report.SCSI.ReadCapabilities.LongBlockSizeSpecified = true;
+ break;
+ }
+ }
+ DicConsole.WriteLine();
+ }
+ }
+ }
+ }
+ #endregion OtherDevices
+
+ FileStream xmlFs = new FileStream(xmlFile, FileMode.Create);
+
+ System.Xml.Serialization.XmlSerializer xmlSer = new System.Xml.Serialization.XmlSerializer(typeof(Metadata.DeviceReport));
+ xmlSer.Serialize(xmlFs, report);
+ xmlFs.Close();
+ }
+ }
+}
+
diff --git a/DiscImageChef/Commands/DumpMedia.cs b/DiscImageChef/Commands/DumpMedia.cs
new file mode 100644
index 00000000..420c5257
--- /dev/null
+++ b/DiscImageChef/Commands/DumpMedia.cs
@@ -0,0 +1,2064 @@
+// /***************************************************************************
+// The Disc Image Chef
+// ----------------------------------------------------------------------------
+//
+// Filename : DumpMedia.cs
+// Version : 1.0
+// Author(s) : Natalia Portillo
+//
+// Component : Component
+//
+// Revision : $Revision$
+// Last change by : $Author$
+// Date : $Date$
+//
+// --[ Description ] ----------------------------------------------------------
+//
+// Description
+//
+// --[ License ] --------------------------------------------------------------
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+//
+// ----------------------------------------------------------------------------
+// Copyright (C) 2011-2015 Claunia.com
+// ****************************************************************************/
+// //$Id$
+using System;
+using DiscImageChef.Console;
+using System.IO;
+using DiscImageChef.Devices;
+using System.Text;
+using System.Collections.Generic;
+using Schemas;
+using DiscImageChef.CommonTypes;
+
+namespace DiscImageChef.Commands
+{
+ public static class DumpMedia
+ {
+ static bool aborted;
+ static FileStream mhddFs;
+ static FileStream dataFs;
+ // TODO: Implement dump map
+ static FileStream mapFs;
+
+ public static void doDumpMedia(DumpMediaSubOptions options)
+ {
+ DicConsole.DebugWriteLine("Dump-Media command", "--debug={0}", options.Debug);
+ DicConsole.DebugWriteLine("Dump-Media command", "--verbose={0}", options.Verbose);
+ DicConsole.DebugWriteLine("Dump-Media command", "--device={0}", options.DevicePath);
+ DicConsole.DebugWriteLine("Dump-Media command", "--output-prefix={0}", options.OutputPrefix);
+ DicConsole.DebugWriteLine("Dump-Media command", "--raw={0}", options.Raw);
+ DicConsole.DebugWriteLine("Dump-Media command", "--stop-on-error={0}", options.StopOnError);
+ DicConsole.DebugWriteLine("Dump-Media command", "--force={0}", options.Force);
+ DicConsole.DebugWriteLine("Dump-Media command", "--reset={0}", options.Reset);
+
+ if (options.DevicePath.Length == 2 && options.DevicePath[1] == ':' &&
+ options.DevicePath[0] != '/' && Char.IsLetter(options.DevicePath[0]))
+ {
+ options.DevicePath = "\\\\.\\" + Char.ToUpper(options.DevicePath[0]) + ':';
+ }
+
+ mhddFs = null;
+
+ Device dev = new Device(options.DevicePath);
+
+ if (dev.Error)
+ {
+ DicConsole.ErrorWriteLine("Error {0} opening device.", dev.LastError);
+ return;
+ }
+
+ switch (dev.Type)
+ {
+ case DeviceType.ATA:
+ doATAMediaScan(options, dev);
+ break;
+ case DeviceType.MMC:
+ case DeviceType.SecureDigital:
+ doSDMediaScan(options, dev);
+ break;
+ case DeviceType.NVMe:
+ doNVMeMediaScan(options, dev);
+ break;
+ case DeviceType.ATAPI:
+ case DeviceType.SCSI:
+ doSCSIMediaScan(options, dev);
+ break;
+ default:
+ throw new NotSupportedException("Unknown device type.");
+ }
+ }
+
+ static void doATAMediaScan(DumpMediaSubOptions options, Device dev)
+ {
+ throw new NotImplementedException("ATA devices not yet supported.");
+ }
+
+ static void doNVMeMediaScan(DumpMediaSubOptions options, Device dev)
+ {
+ throw new NotImplementedException("NVMe devices not yet supported.");
+ }
+
+ static void doSDMediaScan(DumpMediaSubOptions options, Device dev)
+ {
+ throw new NotImplementedException("MMC/SD devices not yet supported.");
+ }
+
+ static void doSCSIMediaScan(DumpMediaSubOptions options, Device dev)
+ {
+ byte[] cmdBuf;
+ byte[] senseBuf;
+ bool sense = false;
+ double duration;
+ ulong blocks = 0;
+ uint blockSize = 0;
+ byte[] tmpBuf;
+ MediaType dskType = MediaType.Unknown;
+ bool opticalDisc = false;
+
+ if (dev.IsRemovable)
+ {
+ bool deviceReset = false;
+ retryTestReady:
+ sense = dev.ScsiTestUnitReady(out senseBuf, dev.Timeout, out duration);
+ if (sense)
+ {
+ Decoders.SCSI.FixedSense? decSense = Decoders.SCSI.Sense.DecodeFixed(senseBuf);
+ if (decSense.HasValue)
+ {
+ if (decSense.Value.ASC == 0x3A)
+ {
+ int leftRetries = 5;
+ while (leftRetries > 0)
+ {
+ DicConsole.WriteLine("\rWaiting for drive to become ready");
+ System.Threading.Thread.Sleep(2000);
+ sense = dev.ScsiTestUnitReady(out senseBuf, dev.Timeout, out duration);
+ if (!sense)
+ break;
+
+ leftRetries--;
+ }
+
+ if (sense)
+ {
+ DicConsole.ErrorWriteLine("Please insert media in drive");
+ return;
+ }
+ }
+ else if (decSense.Value.ASC == 0x04 && decSense.Value.ASCQ == 0x01)
+ {
+ int leftRetries = 10;
+ while (leftRetries > 0)
+ {
+ DicConsole.WriteLine("\rWaiting for drive to become ready");
+ System.Threading.Thread.Sleep(2000);
+ sense = dev.ScsiTestUnitReady(out senseBuf, dev.Timeout, out duration);
+ if (!sense)
+ break;
+
+ leftRetries--;
+ }
+
+ if (sense)
+ {
+ DicConsole.ErrorWriteLine("Error testing unit was ready:\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
+ return;
+ }
+ }
+ /*else if (decSense.Value.ASC == 0x29 && decSense.Value.ASCQ == 0x00)
+ {
+ if (!deviceReset)
+ {
+ deviceReset = true;
+ DicConsole.ErrorWriteLine("Device did reset, retrying...");
+ goto retryTestReady;
+ }
+
+ DicConsole.ErrorWriteLine("Error testing unit was ready:\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
+ return;
+ }*/
+ else
+ {
+ DicConsole.ErrorWriteLine("Error testing unit was ready:\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
+ return;
+ }
+ }
+ else
+ {
+ DicConsole.ErrorWriteLine("Unknown testing unit was ready.");
+ return;
+ }
+ }
+ }
+
+ if (dev.SCSIType == DiscImageChef.Decoders.SCSI.PeripheralDeviceTypes.DirectAccess ||
+ dev.SCSIType == DiscImageChef.Decoders.SCSI.PeripheralDeviceTypes.MultiMediaDevice ||
+ dev.SCSIType == DiscImageChef.Decoders.SCSI.PeripheralDeviceTypes.OCRWDevice ||
+ dev.SCSIType == DiscImageChef.Decoders.SCSI.PeripheralDeviceTypes.OpticalDevice ||
+ dev.SCSIType == DiscImageChef.Decoders.SCSI.PeripheralDeviceTypes.SimplifiedDevice ||
+ dev.SCSIType == DiscImageChef.Decoders.SCSI.PeripheralDeviceTypes.WriteOnceDevice)
+ {
+ sense = dev.ReadCapacity(out cmdBuf, out senseBuf, dev.Timeout, out duration);
+ if (!sense)
+ {
+ blocks = (ulong)((cmdBuf[0] << 24) + (cmdBuf[1] << 16) + (cmdBuf[2] << 8) + (cmdBuf[3]));
+ blockSize = (uint)((cmdBuf[5] << 24) + (cmdBuf[5] << 16) + (cmdBuf[6] << 8) + (cmdBuf[7]));
+ }
+
+ if (sense || blocks == 0xFFFFFFFF)
+ {
+ sense = dev.ReadCapacity16(out cmdBuf, out senseBuf, dev.Timeout, out duration);
+
+ if (sense && blocks == 0)
+ {
+ // Not all MMC devices support READ CAPACITY, as they have READ TOC
+ if (dev.SCSIType != DiscImageChef.Decoders.SCSI.PeripheralDeviceTypes.MultiMediaDevice)
+ {
+ DicConsole.ErrorWriteLine("Unable to get media capacity");
+ DicConsole.ErrorWriteLine("{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
+ }
+ }
+
+ if (!sense)
+ {
+ byte[] temp = new byte[8];
+
+ Array.Copy(cmdBuf, 0, temp, 0, 8);
+ Array.Reverse(temp);
+ blocks = BitConverter.ToUInt64(temp, 0);
+ blockSize = (uint)((cmdBuf[5] << 24) + (cmdBuf[5] << 16) + (cmdBuf[6] << 8) + (cmdBuf[7]));
+ }
+ }
+
+ if (blocks != 0 && blockSize != 0)
+ {
+ blocks++;
+ DicConsole.WriteLine("Media has {0} blocks of {1} bytes/each. (for a total of {2} bytes)",
+ blocks, blockSize, blocks * (ulong)blockSize);
+ }
+ }
+
+ if (dev.SCSIType == DiscImageChef.Decoders.SCSI.PeripheralDeviceTypes.SequentialAccess)
+ {
+ throw new NotImplementedException();
+ }
+
+ if (blocks == 0)
+ {
+ DicConsole.ErrorWriteLine("Unable to read medium or empty medium present...");
+ return;
+ }
+
+ bool compactDisc = true;
+ Decoders.CD.FullTOC.CDFullTOC? toc = null;
+ byte scsiMediumType = 0;
+ byte scsiDensityCode = 0;
+ bool containsFloppyPage = false;
+
+ CICMMetadataType sidecar = new CICMMetadataType();
+
+ #region MultiMediaDevice
+ if (dev.SCSIType == DiscImageChef.Decoders.SCSI.PeripheralDeviceTypes.MultiMediaDevice)
+ {
+ sidecar.OpticalDisc = new OpticalDiscType[1];
+ sidecar.OpticalDisc[0] = new OpticalDiscType();
+ opticalDisc = true;
+
+ sense = dev.GetConfiguration(out cmdBuf, out senseBuf, 0, MmcGetConfigurationRt.Current, dev.Timeout, out duration);
+ if (!sense)
+ {
+ Decoders.SCSI.MMC.Features.SeparatedFeatures ftr = Decoders.SCSI.MMC.Features.Separate(cmdBuf);
+
+ switch (ftr.CurrentProfile)
+ {
+ case 0x0001:
+ dskType = MediaType.GENERIC_HDD;
+ goto default;
+ case 0x0005:
+ dskType = MediaType.CDMO;
+ break;
+ case 0x0008:
+ dskType = MediaType.CD;
+ break;
+ case 0x0009:
+ dskType = MediaType.CDR;
+ break;
+ case 0x000A:
+ dskType = MediaType.CDRW;
+ break;
+ case 0x0010:
+ dskType = MediaType.DVDROM;
+ goto default;
+ case 0x0011:
+ dskType = MediaType.DVDR;
+ goto default;
+ case 0x0012:
+ dskType = MediaType.DVDRAM;
+ goto default;
+ case 0x0013:
+ case 0x0014:
+ dskType = MediaType.DVDRW;
+ goto default;
+ case 0x0015:
+ case 0x0016:
+ dskType = MediaType.DVDRDL;
+ goto default;
+ case 0x0017:
+ dskType = MediaType.DVDRWDL;
+ goto default;
+ case 0x0018:
+ dskType = MediaType.DVDDownload;
+ goto default;
+ case 0x001A:
+ dskType = MediaType.DVDPRW;
+ goto default;
+ case 0x001B:
+ dskType = MediaType.DVDPR;
+ goto default;
+ case 0x0020:
+ dskType = MediaType.DDCD;
+ goto default;
+ case 0x0021:
+ dskType = MediaType.DDCDR;
+ goto default;
+ case 0x0022:
+ dskType = MediaType.DDCDRW;
+ goto default;
+ case 0x002A:
+ dskType = MediaType.DVDPRWDL;
+ goto default;
+ case 0x002B:
+ dskType = MediaType.DVDPRDL;
+ goto default;
+ case 0x0040:
+ dskType = MediaType.BDROM;
+ goto default;
+ case 0x0041:
+ case 0x0042:
+ dskType = MediaType.BDR;
+ goto default;
+ case 0x0043:
+ dskType = MediaType.BDRE;
+ goto default;
+ case 0x0050:
+ dskType = MediaType.HDDVDROM;
+ goto default;
+ case 0x0051:
+ dskType = MediaType.HDDVDR;
+ goto default;
+ case 0x0052:
+ dskType = MediaType.HDDVDRAM;
+ goto default;
+ case 0x0053:
+ dskType = MediaType.HDDVDRW;
+ goto default;
+ case 0x0058:
+ dskType = MediaType.HDDVDRDL;
+ goto default;
+ case 0x005A:
+ dskType = MediaType.HDDVDRWDL;
+ goto default;
+ default:
+ compactDisc = false;
+ break;
+ }
+ }
+
+ #region CompactDisc
+ if (compactDisc)
+ {
+ // We discarded all discs that falsify a TOC before requesting a real TOC
+ // No TOC, no CD (or an empty one)
+ bool tocSense = dev.ReadRawToc(out cmdBuf, out senseBuf, 1, dev.Timeout, out duration);
+ if (!tocSense)
+ {
+ toc = Decoders.CD.FullTOC.Decode(cmdBuf);
+ if (toc.HasValue)
+ {
+ tmpBuf = new byte[cmdBuf.Length - 2];
+ Array.Copy(cmdBuf, 2, tmpBuf, 0, cmdBuf.Length - 2);
+ sidecar.OpticalDisc[0].TOC = new DumpType();
+ sidecar.OpticalDisc[0].TOC.Image = options.OutputPrefix + ".toc.bin";
+ sidecar.OpticalDisc[0].TOC.Size = tmpBuf.Length;
+ sidecar.OpticalDisc[0].TOC.Checksums = Core.Checksum.GetChecksums(tmpBuf).ToArray();
+ writeToFile(sidecar.OpticalDisc[0].TOC.Image, tmpBuf);
+
+ // ATIP exists on blank CDs
+ sense = dev.ReadAtip(out cmdBuf, out senseBuf, dev.Timeout, out duration);
+ if (!sense)
+ {
+ Decoders.CD.ATIP.CDATIP? atip = Decoders.CD.ATIP.Decode(cmdBuf);
+ if (atip.HasValue)
+ {
+ if (blocks == 0)
+ {
+ DicConsole.ErrorWriteLine("Cannot dump blank media.");
+ return;
+ }
+
+ // Only CD-R and CD-RW have ATIP
+ dskType = atip.Value.DiscType ? MediaType.CDRW : MediaType.CDR;
+
+ tmpBuf = new byte[cmdBuf.Length - 4];
+ Array.Copy(cmdBuf, 4, tmpBuf, 0, cmdBuf.Length - 4);
+ sidecar.OpticalDisc[0].ATIP = new DumpType();
+ sidecar.OpticalDisc[0].ATIP.Image = options.OutputPrefix + ".atip.bin";
+ sidecar.OpticalDisc[0].ATIP.Size = tmpBuf.Length;
+ sidecar.OpticalDisc[0].ATIP.Checksums = Core.Checksum.GetChecksums(tmpBuf).ToArray();
+ writeToFile(sidecar.OpticalDisc[0].TOC.Image, tmpBuf);
+ }
+ }
+
+ sense = dev.ReadDiscInformation(out cmdBuf, out senseBuf, MmcDiscInformationDataTypes.DiscInformation, dev.Timeout, out duration);
+ if (!sense)
+ {
+ Decoders.SCSI.MMC.DiscInformation.StandardDiscInformation? discInfo = Decoders.SCSI.MMC.DiscInformation.Decode000b(cmdBuf);
+ if (discInfo.HasValue)
+ {
+ // If it is a read-only CD, check CD type if available
+ if (dskType == MediaType.CD)
+ {
+ switch (discInfo.Value.DiscType)
+ {
+ case 0x10:
+ dskType = MediaType.CDI;
+ break;
+ case 0x20:
+ dskType = MediaType.CDROMXA;
+ break;
+ }
+ }
+ }
+ }
+
+ int sessions = 1;
+ int firstTrackLastSession = 0;
+
+ sense = dev.ReadSessionInfo(out cmdBuf, out senseBuf, dev.Timeout, out duration);
+ if (!sense)
+ {
+ Decoders.CD.Session.CDSessionInfo? session = Decoders.CD.Session.Decode(cmdBuf);
+ if (session.HasValue)
+ {
+ sessions = session.Value.LastCompleteSession;
+ firstTrackLastSession = session.Value.TrackDescriptors[0].TrackNumber;
+ }
+ }
+
+ if (dskType == MediaType.CD)
+ {
+ bool hasDataTrack = false;
+ bool hasAudioTrack = false;
+ bool allFirstSessionTracksAreAudio = true;
+ bool hasVideoTrack = false;
+
+ if (toc.HasValue)
+ {
+ foreach (Decoders.CD.FullTOC.TrackDataDescriptor track in toc.Value.TrackDescriptors)
+ {
+ if (track.TNO == 1 &&
+ ((Decoders.CD.TOC_CONTROL)(track.CONTROL & 0x0D) == Decoders.CD.TOC_CONTROL.DataTrack ||
+ (Decoders.CD.TOC_CONTROL)(track.CONTROL & 0x0D) == Decoders.CD.TOC_CONTROL.DataTrackIncremental))
+ {
+ allFirstSessionTracksAreAudio &= firstTrackLastSession != 1;
+ }
+
+ if ((Decoders.CD.TOC_CONTROL)(track.CONTROL & 0x0D) == Decoders.CD.TOC_CONTROL.DataTrack ||
+ (Decoders.CD.TOC_CONTROL)(track.CONTROL & 0x0D) == Decoders.CD.TOC_CONTROL.DataTrackIncremental)
+ {
+ hasDataTrack = true;
+ allFirstSessionTracksAreAudio &= track.TNO >= firstTrackLastSession;
+ }
+ else
+ hasAudioTrack = true;
+
+ hasVideoTrack |= track.ADR == 4;
+ }
+ }
+
+ if (hasDataTrack && hasAudioTrack && allFirstSessionTracksAreAudio && sessions == 2)
+ dskType = MediaType.CDPLUS;
+ if (!hasDataTrack && hasAudioTrack && sessions == 1)
+ dskType = MediaType.CDDA;
+ if (hasDataTrack && !hasAudioTrack && sessions == 1)
+ dskType = MediaType.CDROM;
+ if (hasVideoTrack && !hasDataTrack && sessions == 1)
+ dskType = MediaType.CDV;
+ }
+
+ sense = dev.ReadPma(out cmdBuf, out senseBuf, dev.Timeout, out duration);
+ if (!sense)
+ {
+ if (Decoders.CD.PMA.Decode(cmdBuf).HasValue)
+ {
+ tmpBuf = new byte[cmdBuf.Length - 4];
+ Array.Copy(cmdBuf, 4, tmpBuf, 0, cmdBuf.Length - 4);
+ sidecar.OpticalDisc[0].PMA = new DumpType();
+ sidecar.OpticalDisc[0].PMA.Image = options.OutputPrefix + ".pma.bin";
+ sidecar.OpticalDisc[0].PMA.Size = tmpBuf.Length;
+ sidecar.OpticalDisc[0].PMA.Checksums = Core.Checksum.GetChecksums(tmpBuf).ToArray();
+ writeToFile(sidecar.OpticalDisc[0].PMA.Image, tmpBuf);
+ }
+ }
+
+ sense = dev.ReadCdText(out cmdBuf, out senseBuf, dev.Timeout, out duration);
+ if (!sense)
+ {
+ if (Decoders.CD.CDTextOnLeadIn.Decode(cmdBuf).HasValue)
+ {
+ tmpBuf = new byte[cmdBuf.Length - 4];
+ Array.Copy(cmdBuf, 4, tmpBuf, 0, cmdBuf.Length - 4);
+ sidecar.OpticalDisc[0].LeadInCdText = new DumpType();
+ sidecar.OpticalDisc[0].LeadInCdText.Image = options.OutputPrefix + ".cdtext.bin";
+ sidecar.OpticalDisc[0].LeadInCdText.Size = tmpBuf.Length;
+ sidecar.OpticalDisc[0].LeadInCdText.Checksums = Core.Checksum.GetChecksums(tmpBuf).ToArray();
+ writeToFile(sidecar.OpticalDisc[0].LeadInCdText.Image, tmpBuf);
+ }
+ }
+ }
+ }
+ }
+ #endregion CompactDisc
+ else
+ {
+ #region Nintendo
+ if (dskType == MediaType.Unknown && blocks > 0)
+ {
+ sense = dev.ReadDiscStructure(out cmdBuf, out senseBuf, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.PhysicalInformation, 0, dev.Timeout, out duration);
+ if (!sense)
+ {
+ Decoders.DVD.PFI.PhysicalFormatInformation? nintendoPfi = Decoders.DVD.PFI.Decode(cmdBuf);
+ if (nintendoPfi != null)
+ {
+ if (nintendoPfi.Value.DiskCategory == DiscImageChef.Decoders.DVD.DiskCategory.Nintendo &&
+ nintendoPfi.Value.PartVersion == 15)
+ {
+ throw new NotImplementedException("Dumping Nintendo GameCube or Wii discs is not yet implemented.");
+ }
+ }
+ }
+ }
+ #endregion Nintendo
+
+ #region All DVD and HD DVD types
+ if (dskType == MediaType.DVDDownload || dskType == MediaType.DVDPR ||
+ dskType == MediaType.DVDPRDL || dskType == MediaType.DVDPRW ||
+ dskType == MediaType.DVDPRWDL || dskType == MediaType.DVDR ||
+ dskType == MediaType.DVDRAM || dskType == MediaType.DVDRDL ||
+ dskType == MediaType.DVDROM || dskType == MediaType.DVDRW ||
+ dskType == MediaType.DVDRWDL || dskType == MediaType.HDDVDR ||
+ dskType == MediaType.HDDVDRAM || dskType == MediaType.HDDVDRDL ||
+ dskType == MediaType.HDDVDROM || dskType == MediaType.HDDVDRW ||
+ dskType == MediaType.HDDVDRWDL)
+ {
+
+ sense = dev.ReadDiscStructure(out cmdBuf, out senseBuf, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.PhysicalInformation, 0, dev.Timeout, out duration);
+ if (!sense)
+ {
+ if (Decoders.DVD.PFI.Decode(cmdBuf).HasValue)
+ {
+ tmpBuf = new byte[cmdBuf.Length - 4];
+ Array.Copy(cmdBuf, 4, tmpBuf, 0, cmdBuf.Length - 4);
+ sidecar.OpticalDisc[0].PFI = new DumpType();
+ sidecar.OpticalDisc[0].PFI.Image = options.OutputPrefix + ".pfi.bin";
+ sidecar.OpticalDisc[0].PFI.Size = tmpBuf.Length;
+ sidecar.OpticalDisc[0].PFI.Checksums = Core.Checksum.GetChecksums(tmpBuf).ToArray();
+ writeToFile(sidecar.OpticalDisc[0].PFI.Image, tmpBuf);
+
+ Decoders.DVD.PFI.PhysicalFormatInformation decPfi = Decoders.DVD.PFI.Decode(cmdBuf).Value;
+ DicConsole.WriteLine("PFI:\n{0}", Decoders.DVD.PFI.Prettify(decPfi));
+
+ // False book types
+ if(dskType == MediaType.DVDROM)
+ {
+ switch(decPfi.DiskCategory)
+ {
+ case Decoders.DVD.DiskCategory.DVDPR:
+ dskType = MediaType.DVDPR;
+ break;
+ case Decoders.DVD.DiskCategory.DVDPRDL:
+ dskType = MediaType.DVDPRDL;
+ break;
+ case Decoders.DVD.DiskCategory.DVDPRW:
+ dskType = MediaType.DVDPRW;
+ break;
+ case Decoders.DVD.DiskCategory.DVDPRWDL:
+ dskType = MediaType.DVDPRWDL;
+ break;
+ case Decoders.DVD.DiskCategory.DVDR:
+ if(decPfi.PartVersion == 6)
+ dskType = MediaType.DVDRDL;
+ else
+ dskType = MediaType.DVDR;
+ break;
+ case Decoders.DVD.DiskCategory.DVDRAM:
+ dskType = MediaType.DVDRAM;
+ break;
+ default:
+ dskType = MediaType.DVDROM;
+ break;
+ case Decoders.DVD.DiskCategory.DVDRW:
+ if(decPfi.PartVersion == 3)
+ dskType = MediaType.DVDRWDL;
+ else
+ dskType = MediaType.DVDRW;
+ break;
+ case Decoders.DVD.DiskCategory.HDDVDR:
+ dskType = MediaType.HDDVDR;
+ break;
+ case Decoders.DVD.DiskCategory.HDDVDRAM:
+ dskType = MediaType.HDDVDRAM;
+ break;
+ case Decoders.DVD.DiskCategory.HDDVDROM:
+ dskType = MediaType.HDDVDROM;
+ break;
+ case Decoders.DVD.DiskCategory.HDDVDRW:
+ dskType = MediaType.HDDVDRW;
+ break;
+ case Decoders.DVD.DiskCategory.Nintendo:
+ if(decPfi.DiscSize == DiscImageChef.Decoders.DVD.DVDSize.Eighty)
+ dskType = MediaType.GOD;
+ else
+ dskType = MediaType.WOD;
+ break;
+ case Decoders.DVD.DiskCategory.UMD:
+ dskType = MediaType.UMD;
+ break;
+ }
+ }
+ }
+ }
+ sense = dev.ReadDiscStructure(out cmdBuf, out senseBuf, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.DiscManufacturingInformation, 0, dev.Timeout, out duration);
+ if (!sense)
+ {
+ if (Decoders.Xbox.DMI.IsXbox(cmdBuf) || Decoders.Xbox.DMI.IsXbox360(cmdBuf))
+ throw new NotImplementedException("Dumping Xbox discs is not yet implemented.");
+
+ if (cmdBuf.Length == 2052)
+ {
+ tmpBuf = new byte[cmdBuf.Length - 4];
+ Array.Copy(cmdBuf, 4, tmpBuf, 0, cmdBuf.Length - 4);
+ sidecar.OpticalDisc[0].DMI = new DumpType();
+ sidecar.OpticalDisc[0].DMI.Image = options.OutputPrefix + ".dmi.bin";
+ sidecar.OpticalDisc[0].DMI.Size = tmpBuf.Length;
+ sidecar.OpticalDisc[0].DMI.Checksums = Core.Checksum.GetChecksums(tmpBuf).ToArray();
+ writeToFile(sidecar.OpticalDisc[0].DMI.Image, tmpBuf);
+ }
+ }
+ }
+ #endregion All DVD and HD DVD types
+
+ #region DVD-ROM
+ if (dskType == MediaType.DVDDownload || dskType == MediaType.DVDROM)
+ {
+ sense = dev.ReadDiscStructure(out cmdBuf, out senseBuf, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.CopyrightInformation, 0, dev.Timeout, out duration);
+ if (!sense)
+ {
+ if (Decoders.DVD.CSS_CPRM.DecodeLeadInCopyright(cmdBuf).HasValue)
+ {
+ tmpBuf = new byte[cmdBuf.Length - 4];
+ Array.Copy(cmdBuf, 4, tmpBuf, 0, cmdBuf.Length - 4);
+ sidecar.OpticalDisc[0].CMI = new DumpType();
+ sidecar.OpticalDisc[0].CMI.Image = options.OutputPrefix + ".cmi.bin";
+ sidecar.OpticalDisc[0].CMI.Size = tmpBuf.Length;
+ sidecar.OpticalDisc[0].CMI.Checksums = Core.Checksum.GetChecksums(tmpBuf).ToArray();
+ writeToFile(sidecar.OpticalDisc[0].CMI.Image, tmpBuf);
+
+ Decoders.DVD.CSS_CPRM.LeadInCopyright cpy = Decoders.DVD.CSS_CPRM.DecodeLeadInCopyright(cmdBuf).Value;
+ if(cpy.CopyrightType != DiscImageChef.Decoders.DVD.CopyrightType.NoProtection)
+ sidecar.OpticalDisc[0].CopyProtection = cpy.CopyrightType.ToString();
+ }
+ }
+ }
+ #endregion DVD-ROM
+
+ #region DVD-ROM and HD DVD-ROM
+ if (dskType == MediaType.DVDDownload || dskType == MediaType.DVDROM ||
+ dskType == MediaType.HDDVDROM)
+ {
+ sense = dev.ReadDiscStructure(out cmdBuf, out senseBuf, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.BurstCuttingArea, 0, dev.Timeout, out duration);
+ if (!sense)
+ {
+ tmpBuf = new byte[cmdBuf.Length - 4];
+ Array.Copy(cmdBuf, 4, tmpBuf, 0, cmdBuf.Length - 4);
+ sidecar.OpticalDisc[0].BCA = new DumpType();
+ sidecar.OpticalDisc[0].BCA.Image = options.OutputPrefix + ".bca.bin";
+ sidecar.OpticalDisc[0].BCA.Size = tmpBuf.Length;
+ sidecar.OpticalDisc[0].BCA.Checksums = Core.Checksum.GetChecksums(tmpBuf).ToArray();
+ writeToFile(sidecar.OpticalDisc[0].BCA.Image, tmpBuf);
+ }
+ }
+ #endregion DVD-ROM and HD DVD-ROM
+
+ #region DVD-RAM and HD DVD-RAM
+ if (dskType == MediaType.DVDRAM || dskType == MediaType.HDDVDRAM)
+ {
+ sense = dev.ReadDiscStructure(out cmdBuf, out senseBuf, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.DVDRAM_DDS, 0, dev.Timeout, out duration);
+ if (!sense)
+ {
+ if (Decoders.DVD.DDS.Decode(cmdBuf).HasValue)
+ {
+ tmpBuf = new byte[cmdBuf.Length - 4];
+ Array.Copy(cmdBuf, 4, tmpBuf, 0, cmdBuf.Length - 4);
+ sidecar.OpticalDisc[0].DDS = new DumpType();
+ sidecar.OpticalDisc[0].DDS.Image = options.OutputPrefix + ".dds.bin";
+ sidecar.OpticalDisc[0].DDS.Size = tmpBuf.Length;
+ sidecar.OpticalDisc[0].DDS.Checksums = Core.Checksum.GetChecksums(tmpBuf).ToArray();
+ writeToFile(sidecar.OpticalDisc[0].DDS.Image, tmpBuf);
+ }
+ }
+
+ sense = dev.ReadDiscStructure(out cmdBuf, out senseBuf, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.DVDRAM_SpareAreaInformation, 0, dev.Timeout, out duration);
+ if (!sense)
+ {
+ if (Decoders.DVD.Spare.Decode(cmdBuf).HasValue)
+ {
+ tmpBuf = new byte[cmdBuf.Length - 4];
+ Array.Copy(cmdBuf, 4, tmpBuf, 0, cmdBuf.Length - 4);
+ sidecar.OpticalDisc[0].SAI = new DumpType();
+ sidecar.OpticalDisc[0].SAI.Image = options.OutputPrefix + ".sai.bin";
+ sidecar.OpticalDisc[0].SAI.Size = tmpBuf.Length;
+ sidecar.OpticalDisc[0].SAI.Checksums = Core.Checksum.GetChecksums(tmpBuf).ToArray();
+ writeToFile(sidecar.OpticalDisc[0].SAI.Image, tmpBuf);
+ }
+ }
+ }
+ #endregion DVD-RAM and HD DVD-RAM
+
+ #region DVD-R and DVD-RW
+ if (dskType == MediaType.DVDR || dskType == MediaType.DVDRW)
+ {
+ sense = dev.ReadDiscStructure(out cmdBuf, out senseBuf, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.PreRecordedInfo, 0, dev.Timeout, out duration);
+ if (!sense)
+ {
+ tmpBuf = new byte[cmdBuf.Length - 4];
+ Array.Copy(cmdBuf, 4, tmpBuf, 0, cmdBuf.Length - 4);
+ sidecar.OpticalDisc[0].PRI = new DumpType();
+ sidecar.OpticalDisc[0].PRI.Image = options.OutputPrefix + ".pri.bin";
+ sidecar.OpticalDisc[0].PRI.Size = tmpBuf.Length;
+ sidecar.OpticalDisc[0].PRI.Checksums = Core.Checksum.GetChecksums(tmpBuf).ToArray();
+ writeToFile(sidecar.OpticalDisc[0].SAI.Image, tmpBuf);
+ }
+ }
+ #endregion DVD-R and DVD-RW
+
+ #region DVD-R, DVD-RW and HD DVD-R
+ if (dskType == MediaType.DVDR || dskType == MediaType.DVDRW || dskType == MediaType.HDDVDR)
+ {
+ sense = dev.ReadDiscStructure(out cmdBuf, out senseBuf, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.DVDR_MediaIdentifier, 0, dev.Timeout, out duration);
+ if (!sense)
+ {
+ tmpBuf = new byte[cmdBuf.Length - 4];
+ Array.Copy(cmdBuf, 4, tmpBuf, 0, cmdBuf.Length - 4);
+ sidecar.OpticalDisc[0].MediaID = new DumpType();
+ sidecar.OpticalDisc[0].MediaID.Image = options.OutputPrefix + ".mid.bin";
+ sidecar.OpticalDisc[0].MediaID.Size = tmpBuf.Length;
+ sidecar.OpticalDisc[0].MediaID.Checksums = Core.Checksum.GetChecksums(tmpBuf).ToArray();
+ writeToFile(sidecar.OpticalDisc[0].MediaID.Image, tmpBuf);
+ }
+
+ sense = dev.ReadDiscStructure(out cmdBuf, out senseBuf, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.DVDR_PhysicalInformation, 0, dev.Timeout, out duration);
+ if (!sense)
+ {
+ tmpBuf = new byte[cmdBuf.Length - 4];
+ Array.Copy(cmdBuf, 4, tmpBuf, 0, cmdBuf.Length - 4);
+ sidecar.OpticalDisc[0].PFIR = new DumpType();
+ sidecar.OpticalDisc[0].PFIR.Image = options.OutputPrefix + ".pfir.bin";
+ sidecar.OpticalDisc[0].PFIR.Size = tmpBuf.Length;
+ sidecar.OpticalDisc[0].PFIR.Checksums = Core.Checksum.GetChecksums(tmpBuf).ToArray();
+ writeToFile(sidecar.OpticalDisc[0].PFIR.Image, tmpBuf);
+ }
+ }
+ #endregion DVD-R, DVD-RW and HD DVD-R
+
+ #region All DVD+
+ if (dskType == MediaType.DVDPR || dskType == MediaType.DVDPRDL ||
+ dskType == MediaType.DVDPRW || dskType == MediaType.DVDPRWDL)
+ {
+ sense = dev.ReadDiscStructure(out cmdBuf, out senseBuf, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.ADIP, 0, dev.Timeout, out duration);
+ if (!sense)
+ {
+ tmpBuf = new byte[cmdBuf.Length - 4];
+ Array.Copy(cmdBuf, 4, tmpBuf, 0, cmdBuf.Length - 4);
+ sidecar.OpticalDisc[0].ADIP = new DumpType();
+ sidecar.OpticalDisc[0].ADIP.Image = options.OutputPrefix + ".adip.bin";
+ sidecar.OpticalDisc[0].ADIP.Size = tmpBuf.Length;
+ sidecar.OpticalDisc[0].ADIP.Checksums = Core.Checksum.GetChecksums(tmpBuf).ToArray();
+ writeToFile(sidecar.OpticalDisc[0].ADIP.Image, tmpBuf);
+ }
+
+ sense = dev.ReadDiscStructure(out cmdBuf, out senseBuf, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.DCB, 0, dev.Timeout, out duration);
+ if (!sense)
+ {
+ tmpBuf = new byte[cmdBuf.Length - 4];
+ Array.Copy(cmdBuf, 4, tmpBuf, 0, cmdBuf.Length - 4);
+ sidecar.OpticalDisc[0].DCB = new DumpType();
+ sidecar.OpticalDisc[0].DCB.Image = options.OutputPrefix + ".dcb.bin";
+ sidecar.OpticalDisc[0].DCB.Size = tmpBuf.Length;
+ sidecar.OpticalDisc[0].DCB.Checksums = Core.Checksum.GetChecksums(tmpBuf).ToArray();
+ writeToFile(sidecar.OpticalDisc[0].DCB.Image, tmpBuf);
+ }
+ }
+ #endregion All DVD+
+
+ #region HD DVD-ROM
+ if (dskType == MediaType.HDDVDROM)
+ {
+ sense = dev.ReadDiscStructure(out cmdBuf, out senseBuf, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.HDDVD_CopyrightInformation, 0, dev.Timeout, out duration);
+ if (!sense)
+ {
+ tmpBuf = new byte[cmdBuf.Length - 4];
+ Array.Copy(cmdBuf, 4, tmpBuf, 0, cmdBuf.Length - 4);
+ sidecar.OpticalDisc[0].CMI = new DumpType();
+ sidecar.OpticalDisc[0].CMI.Image = options.OutputPrefix + ".cmi.bin";
+ sidecar.OpticalDisc[0].CMI.Size = tmpBuf.Length;
+ sidecar.OpticalDisc[0].CMI.Checksums = Core.Checksum.GetChecksums(tmpBuf).ToArray();
+ writeToFile(sidecar.OpticalDisc[0].CMI.Image, tmpBuf);
+ }
+ }
+ #endregion HD DVD-ROM
+
+ #region All Blu-ray
+ if (dskType == MediaType.BDR || dskType == MediaType.BDRE || dskType == MediaType.BDROM ||
+ dskType == MediaType.BDRXL || dskType == MediaType.BDREXL)
+ {
+ sense = dev.ReadDiscStructure(out cmdBuf, out senseBuf, MmcDiscStructureMediaType.BD, 0, 0, MmcDiscStructureFormat.DiscInformation, 0, dev.Timeout, out duration);
+ if (!sense)
+ {
+ if (Decoders.Bluray.DI.Decode(cmdBuf).HasValue)
+ {
+ tmpBuf = new byte[cmdBuf.Length - 4];
+ Array.Copy(cmdBuf, 4, tmpBuf, 0, cmdBuf.Length - 4);
+ sidecar.OpticalDisc[0].DI = new DumpType();
+ sidecar.OpticalDisc[0].DI.Image = options.OutputPrefix + ".di.bin";
+ sidecar.OpticalDisc[0].DI.Size = tmpBuf.Length;
+ sidecar.OpticalDisc[0].DI.Checksums = Core.Checksum.GetChecksums(tmpBuf).ToArray();
+ writeToFile(sidecar.OpticalDisc[0].DI.Image, tmpBuf);
+ }
+ }
+
+ sense = dev.ReadDiscStructure(out cmdBuf, out senseBuf, MmcDiscStructureMediaType.BD, 0, 0, MmcDiscStructureFormat.PAC, 0, dev.Timeout, out duration);
+ if (!sense)
+ {
+ tmpBuf = new byte[cmdBuf.Length - 4];
+ Array.Copy(cmdBuf, 4, tmpBuf, 0, cmdBuf.Length - 4);
+ sidecar.OpticalDisc[0].PAC = new DumpType();
+ sidecar.OpticalDisc[0].PAC.Image = options.OutputPrefix + ".pac.bin";
+ sidecar.OpticalDisc[0].PAC.Size = tmpBuf.Length;
+ sidecar.OpticalDisc[0].PAC.Checksums = Core.Checksum.GetChecksums(tmpBuf).ToArray();
+ writeToFile(sidecar.OpticalDisc[0].PAC.Image, tmpBuf);
+ }
+ }
+ #endregion All Blu-ray
+
+
+ #region BD-ROM only
+ if (dskType == MediaType.BDROM)
+ {
+ sense = dev.ReadDiscStructure(out cmdBuf, out senseBuf, MmcDiscStructureMediaType.BD, 0, 0, MmcDiscStructureFormat.BD_BurstCuttingArea, 0, dev.Timeout, out duration);
+ if (!sense)
+ {
+ tmpBuf = new byte[cmdBuf.Length - 4];
+ Array.Copy(cmdBuf, 4, tmpBuf, 0, cmdBuf.Length - 4);
+ sidecar.OpticalDisc[0].BCA = new DumpType();
+ sidecar.OpticalDisc[0].BCA.Image = options.OutputPrefix + ".bca.bin";
+ sidecar.OpticalDisc[0].BCA.Size = tmpBuf.Length;
+ sidecar.OpticalDisc[0].BCA.Checksums = Core.Checksum.GetChecksums(tmpBuf).ToArray();
+ writeToFile(sidecar.OpticalDisc[0].BCA.Image, tmpBuf);
+ }
+ }
+ #endregion BD-ROM only
+
+ #region Writable Blu-ray only
+ if (dskType == MediaType.BDR || dskType == MediaType.BDRE ||
+ dskType == MediaType.BDRXL || dskType == MediaType.BDREXL)
+ {
+ sense = dev.ReadDiscStructure(out cmdBuf, out senseBuf, MmcDiscStructureMediaType.BD, 0, 0, MmcDiscStructureFormat.BD_DDS, 0, dev.Timeout, out duration);
+ if (!sense)
+ {
+ tmpBuf = new byte[cmdBuf.Length - 4];
+ Array.Copy(cmdBuf, 4, tmpBuf, 0, cmdBuf.Length - 4);
+ sidecar.OpticalDisc[0].DDS = new DumpType();
+ sidecar.OpticalDisc[0].DDS.Image = options.OutputPrefix + ".dds.bin";
+ sidecar.OpticalDisc[0].DDS.Size = tmpBuf.Length;
+ sidecar.OpticalDisc[0].DDS.Checksums = Core.Checksum.GetChecksums(tmpBuf).ToArray();
+ writeToFile(sidecar.OpticalDisc[0].DDS.Image, tmpBuf);
+ }
+
+ sense = dev.ReadDiscStructure(out cmdBuf, out senseBuf, MmcDiscStructureMediaType.BD, 0, 0, MmcDiscStructureFormat.BD_SpareAreaInformation, 0, dev.Timeout, out duration);
+ if (!sense)
+ {
+ tmpBuf = new byte[cmdBuf.Length - 4];
+ Array.Copy(cmdBuf, 4, tmpBuf, 0, cmdBuf.Length - 4);
+ sidecar.OpticalDisc[0].SAI = new DumpType();
+ sidecar.OpticalDisc[0].SAI.Image = options.OutputPrefix + ".sai.bin";
+ sidecar.OpticalDisc[0].SAI.Size = tmpBuf.Length;
+ sidecar.OpticalDisc[0].SAI.Checksums = Core.Checksum.GetChecksums(tmpBuf).ToArray();
+ writeToFile(sidecar.OpticalDisc[0].SAI.Image, tmpBuf);
+ }
+ }
+ #endregion Writable Blu-ray only
+ }
+ }
+ #endregion MultiMediaDevice
+ else
+ {
+ compactDisc = false;
+ sidecar.BlockMedia = new BlockMediaType[1];
+ sidecar.BlockMedia[0] = new BlockMediaType();
+
+ // All USB flash drives report as removable, even if the media is not removable
+ if (!dev.IsRemovable || dev.IsUSB)
+ {
+ if (dev.IsUSB)
+ {
+ sidecar.BlockMedia[0].USB = new USBType();
+ sidecar.BlockMedia[0].USB.ProductID = dev.USBProductID;
+ sidecar.BlockMedia[0].USB.VendorID = dev.USBVendorID;
+ sidecar.BlockMedia[0].USB.Descriptors = new DumpType();
+ sidecar.BlockMedia[0].USB.Descriptors.Image = options.OutputPrefix + ".usbdescriptors.bin";
+ sidecar.BlockMedia[0].USB.Descriptors.Size = dev.USBDescriptors.Length;
+ sidecar.BlockMedia[0].USB.Descriptors.Checksums = Core.Checksum.GetChecksums(dev.USBDescriptors).ToArray();
+ writeToFile(sidecar.BlockMedia[0].USB.Descriptors.Image, dev.USBDescriptors);
+ }
+
+ if (dev.Type == DeviceType.ATAPI)
+ {
+ DiscImageChef.Decoders.ATA.AtaErrorRegistersCHS errorRegs;
+ sense = dev.AtapiIdentify(out cmdBuf, out errorRegs);
+ if (!sense)
+ {
+ sidecar.BlockMedia[0].ATA = new ATAType();
+ sidecar.BlockMedia[0].ATA.Identify = new DumpType();
+ sidecar.BlockMedia[0].ATA.Identify.Image = options.OutputPrefix + ".identify.bin";
+ sidecar.BlockMedia[0].ATA.Identify.Size = cmdBuf.Length;
+ sidecar.BlockMedia[0].ATA.Identify.Checksums = Core.Checksum.GetChecksums(cmdBuf).ToArray();
+ writeToFile(sidecar.BlockMedia[0].ATA.Identify.Image, cmdBuf);
+ }
+ }
+
+ sense = dev.ScsiInquiry(out cmdBuf, out senseBuf);
+ if (!sense)
+ {
+ sidecar.BlockMedia[0].SCSI = new SCSIType();
+ sidecar.BlockMedia[0].SCSI.Inquiry = new DumpType();
+ sidecar.BlockMedia[0].SCSI.Inquiry.Image = options.OutputPrefix + ".inquiry.bin";
+ sidecar.BlockMedia[0].SCSI.Inquiry.Size = cmdBuf.Length;
+ sidecar.BlockMedia[0].SCSI.Inquiry.Checksums = Core.Checksum.GetChecksums(cmdBuf).ToArray();
+ writeToFile(sidecar.BlockMedia[0].SCSI.Inquiry.Image, cmdBuf);
+
+ sense = dev.ScsiInquiry(out cmdBuf, out senseBuf, 0x00);
+ if (!sense)
+ {
+ byte[] pages = Decoders.SCSI.EVPD.DecodePage00(cmdBuf);
+
+ if (pages != null)
+ {
+ List evpds = new List();
+ foreach (byte page in pages)
+ {
+ sense = dev.ScsiInquiry(out cmdBuf, out senseBuf, page);
+ if (!sense)
+ {
+ EVPDType evpd = new EVPDType();
+ evpd.Image = String.Format("{0}.evpd_{1:X2}h.bin", options.OutputPrefix, page);
+ evpd.Checksums = Core.Checksum.GetChecksums(cmdBuf).ToArray();
+ evpd.Size = cmdBuf.Length;
+ evpd.Checksums = Core.Checksum.GetChecksums(cmdBuf).ToArray();
+ writeToFile(evpd.Image, cmdBuf);
+ evpds.Add(evpd);
+ }
+ }
+
+ if (evpds.Count > 0)
+ sidecar.BlockMedia[0].SCSI.EVPD = evpds.ToArray();
+ }
+ }
+
+ sense = dev.ModeSense10(out cmdBuf, out senseBuf, false, true, ScsiModeSensePageControl.Current, 0x3F, 0xFF, 5, out duration);
+ if (!sense || dev.Error)
+ {
+ sense = dev.ModeSense10(out cmdBuf, out senseBuf, false, true, ScsiModeSensePageControl.Current, 0x3F, 0x00, 5, out duration);
+ }
+
+ Decoders.SCSI.Modes.DecodedMode? decMode = null;
+
+ if (!sense && !dev.Error)
+ {
+ if (Decoders.SCSI.Modes.DecodeMode10(cmdBuf, dev.SCSIType).HasValue)
+ {
+ decMode = Decoders.SCSI.Modes.DecodeMode10(cmdBuf, dev.SCSIType);
+ sidecar.BlockMedia[0].SCSI.ModeSense10 = new DumpType();
+ sidecar.BlockMedia[0].SCSI.ModeSense10.Image = options.OutputPrefix + ".modesense10.bin";
+ sidecar.BlockMedia[0].SCSI.ModeSense10.Size = cmdBuf.Length;
+ sidecar.BlockMedia[0].SCSI.ModeSense10.Checksums = Core.Checksum.GetChecksums(cmdBuf).ToArray();
+ writeToFile(sidecar.BlockMedia[0].SCSI.ModeSense10.Image, cmdBuf);
+ }
+ }
+
+ sense = dev.ModeSense6(out cmdBuf, out senseBuf, false, ScsiModeSensePageControl.Current, 0x3F, 0x00, 5, out duration);
+ if (sense || dev.Error)
+ sense = dev.ModeSense6(out cmdBuf, out senseBuf, false, ScsiModeSensePageControl.Current, 0x3F, 0x00, 5, out duration);
+ if (sense || dev.Error)
+ sense = dev.ModeSense(out cmdBuf, out senseBuf, 5, out duration);
+
+ if (!sense && !dev.Error)
+ {
+ if (Decoders.SCSI.Modes.DecodeMode6(cmdBuf, dev.SCSIType).HasValue)
+ {
+ decMode = Decoders.SCSI.Modes.DecodeMode10(cmdBuf, dev.SCSIType);
+ sidecar.BlockMedia[0].SCSI.ModeSense = new DumpType();
+ sidecar.BlockMedia[0].SCSI.ModeSense.Image = options.OutputPrefix + ".modesense.bin";
+ sidecar.BlockMedia[0].SCSI.ModeSense.Size = cmdBuf.Length;
+ sidecar.BlockMedia[0].SCSI.ModeSense.Checksums = Core.Checksum.GetChecksums(cmdBuf).ToArray();
+ writeToFile(sidecar.BlockMedia[0].SCSI.ModeSense.Image, cmdBuf);
+ }
+ }
+
+ if(decMode.HasValue)
+ {
+ scsiMediumType = (byte)decMode.Value.Header.MediumType;
+ if(decMode.Value.Header.BlockDescriptors != null && decMode.Value.Header.BlockDescriptors.Length >= 1)
+ scsiDensityCode = (byte)decMode.Value.Header.BlockDescriptors[0].Density;
+
+ foreach(Decoders.SCSI.Modes.ModePage modePage in decMode.Value.Pages)
+ if(modePage.Page == 0x05)
+ containsFloppyPage = true;
+ }
+ }
+ }
+ }
+
+ if(dskType == MediaType.Unknown)
+ dskType = MediaTypeFromSCSI.Get((byte)dev.SCSIType, dev.Manufacturer, dev.Model, scsiMediumType, scsiDensityCode, blocks, blockSize);
+
+ if(dskType == MediaType.Unknown && dev.IsUSB && containsFloppyPage)
+ dskType = MediaType.FlashDrive;
+
+ DicConsole.WriteLine("Media identified as {0}", dskType);
+
+ byte[] readBuffer;
+ uint blocksToRead = 255;
+
+ ulong errored = 0;
+ DateTime start;
+ DateTime end;
+ double totalDuration = 0;
+ double totalChkDuration = 0;
+ double currentSpeed = 0;
+ double maxSpeed = double.MinValue;
+ double minSpeed = double.MaxValue;
+ List unreadableSectors = new List();
+ Core.Checksum dataChk;
+
+ aborted = false;
+ System.Console.CancelKeyPress += (sender, e) =>
+ {
+ e.Cancel = aborted = true;
+ };
+
+ // TODO: Raw reading
+ bool read6 = false, read10 = false, read12 = false, read16 = false, readcd;
+ bool readLong10 = false, readLong16 = false, hldtstReadRaw = false, necReadCDDA = false;
+ bool pioneerReadCDDA = false, plextorReadCDDA = false, plextorReadRaw = false, syqReadLong6 = false, syqReadLong10 = false;
+
+ if (compactDisc)
+ {
+ if (toc == null)
+ {
+ DicConsole.ErrorWriteLine("Error trying to decode TOC...");
+ return;
+ }
+
+ if (options.Raw)
+ {
+ throw new NotImplementedException("CD dumping not yet implemented");
+ }
+ else
+ {
+ // TODO: Check subchannel capabilities
+ readcd = !dev.ReadCd(out readBuffer, out senseBuf, 0, 2448, 1, MmcSectorTypes.AllTypes, false, false, true, MmcHeaderCodes.AllHeaders,
+ true, true, MmcErrorField.None, MmcSubchannel.Raw, dev.Timeout, out duration);
+
+ if (readcd)
+ DicConsole.WriteLine("Using MMC READ CD command.");
+ }
+
+ DicConsole.WriteLine("Trying to read Lead-In...");
+ bool gotLeadIn = false;
+ int leadInSectorsGood = 0, leadInSectorsTotal = 0;
+
+ initDataFile(options.OutputPrefix + ".leadin.bin");
+ dataChk = new DiscImageChef.Core.Checksum();
+
+ start = DateTime.UtcNow;
+
+ readBuffer = null;
+
+ for (int leadInBlock = -150; leadInBlock < 0; leadInBlock++)
+ {
+ if (aborted)
+ break;
+
+ double cmdDuration = 0;
+
+ if (currentSpeed > maxSpeed && currentSpeed != 0)
+ maxSpeed = currentSpeed;
+ if (currentSpeed < minSpeed && currentSpeed != 0)
+ minSpeed = currentSpeed;
+
+ DicConsole.Write("\rTrying to read lead-in sector {0} ({1:F3} MiB/sec.)", (int)leadInBlock, currentSpeed);
+
+ sense = dev.ReadCd(out readBuffer, out senseBuf, (uint)leadInBlock, 2448, 1, MmcSectorTypes.AllTypes, false, false, true, MmcHeaderCodes.AllHeaders,
+ true, true, MmcErrorField.None, MmcSubchannel.Raw, dev.Timeout, out cmdDuration);
+
+ if (!sense && !dev.Error)
+ {
+ dataChk.Update(readBuffer);
+ writeToDataFile(readBuffer);
+ gotLeadIn = true;
+ leadInSectorsGood++;
+ leadInSectorsTotal++;
+ }
+ else
+ {
+ if (gotLeadIn)
+ {
+ // Write empty data
+ dataChk.Update(new byte[2448]);
+ writeToDataFile(new byte[2448]);
+ leadInSectorsTotal++;
+ }
+ }
+
+ currentSpeed = ((double)2448 / (double)1048576) / (cmdDuration / (double)1000);
+ }
+
+ closeDataFile();
+ if (leadInSectorsGood > 0)
+ {
+ sidecar.OpticalDisc[0].LeadIn = new BorderType[1];
+ sidecar.OpticalDisc[0].LeadIn[0] = new BorderType();
+ sidecar.OpticalDisc[0].LeadIn[0].Image = options.OutputPrefix + ".leadin.bin";
+ sidecar.OpticalDisc[0].LeadIn[0].Checksums = dataChk.End().ToArray();
+ sidecar.OpticalDisc[0].LeadIn[0].Size = leadInSectorsTotal * 2448;
+ }
+ else
+ File.Delete(options.OutputPrefix + ".leadin.bin");
+
+ DicConsole.WriteLine();
+ DicConsole.WriteLine("Got {0} lead-in sectors.", leadInSectorsGood);
+
+ while (true)
+ {
+ if (readcd)
+ {
+ sense = dev.ReadCd(out readBuffer, out senseBuf, 0, 2448, blocksToRead, MmcSectorTypes.AllTypes, false, false, true, MmcHeaderCodes.AllHeaders,
+ true, true, MmcErrorField.None, MmcSubchannel.Raw, dev.Timeout, out duration);
+ if (dev.Error)
+ blocksToRead /= 2;
+ }
+
+ if (!dev.Error || blocksToRead == 1)
+ break;
+ }
+
+ if (dev.Error)
+ {
+ DicConsole.ErrorWriteLine("Device error {0} trying to guess ideal transfer length.", dev.LastError);
+ return;
+ }
+
+ DicConsole.WriteLine("Reading {0} sectors at a time.", blocksToRead);
+
+ initDataFile(options.OutputPrefix + ".bin");
+ initMHDDLogFile(options.OutputPrefix + ".mhddlog.bin", dev, blocks, blockSize, blocksToRead);
+
+ for (ulong i = 0; i < blocks; i += blocksToRead)
+ {
+ if (aborted)
+ break;
+
+ double cmdDuration = 0;
+
+ if ((blocks - i) < blocksToRead)
+ blocksToRead = (uint)(blocks - i);
+
+ if (currentSpeed > maxSpeed && currentSpeed != 0)
+ maxSpeed = currentSpeed;
+ if (currentSpeed < minSpeed && currentSpeed != 0)
+ minSpeed = currentSpeed;
+
+ DicConsole.Write("\rReading sector {0} of {1} ({2:F3} MiB/sec.)", i, blocks, currentSpeed);
+
+ if (readcd)
+ {
+ sense = dev.ReadCd(out readBuffer, out senseBuf, (uint)i, 2448, blocksToRead, MmcSectorTypes.AllTypes, false, false, true, MmcHeaderCodes.AllHeaders,
+ true, true, MmcErrorField.None, MmcSubchannel.Raw, dev.Timeout, out cmdDuration);
+ totalDuration += cmdDuration;
+ }
+
+ if (!sense && !dev.Error)
+ {
+ writeMHDDLogFile(i, cmdDuration);
+ writeToDataFile(readBuffer);
+ }
+ else
+ {
+ // TODO: Reset device after X errors
+ if (options.StopOnError)
+ return; // TODO: Return more cleanly
+
+ // Write empty data
+ writeToDataFile(new byte[2448 * blocksToRead]);
+
+ // TODO: Record error on mapfile
+
+ errored += blocksToRead;
+ unreadableSectors.Add(i);
+ DicConsole.DebugWriteLine("Dump-Media", "READ error:\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
+ if (cmdDuration < 500)
+ writeMHDDLogFile(i, 65535);
+ else
+ writeMHDDLogFile(i, cmdDuration);
+ }
+
+ currentSpeed = ((double)2448 * blocksToRead / (double)1048576) / (cmdDuration / (double)1000);
+ }
+ DicConsole.WriteLine();
+ closeMHDDLogFile();
+
+ dataChk = new Core.Checksum();
+ dataFs.Seek(0, SeekOrigin.Begin);
+ blocksToRead = 500;
+
+ for (ulong i = 0; i < blocks; i += blocksToRead)
+ {
+ if (aborted)
+ break;
+
+ if ((blocks - i) < blocksToRead)
+ blocksToRead = (uint)(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];
+ dataFs.Read(dataToCheck, 0, (int)(blockSize * blocksToRead));
+ dataChk.Update(dataToCheck);
+ DateTime chkEnd = DateTime.UtcNow;
+
+ double chkDuration = (chkEnd - chkStart).TotalMilliseconds;
+ totalChkDuration += chkDuration;
+
+ currentSpeed = ((double)blockSize * blocksToRead / (double)1048576) / (chkDuration / (double)1000);
+ }
+ DicConsole.WriteLine();
+ closeDataFile();
+ end = DateTime.UtcNow;
+
+ // TODO: Correct this
+ sidecar.OpticalDisc[0].Checksums = dataChk.End().ToArray();
+ sidecar.OpticalDisc[0].DumpHardwareArray = new DumpHardwareType[1];
+ sidecar.OpticalDisc[0].DumpHardwareArray[0] = new DumpHardwareType();
+ sidecar.OpticalDisc[0].DumpHardwareArray[0].Extents = new ExtentType[1];
+ sidecar.OpticalDisc[0].DumpHardwareArray[0].Extents[0] = new ExtentType();
+ sidecar.OpticalDisc[0].DumpHardwareArray[0].Extents[0].Start = 0;
+ sidecar.OpticalDisc[0].DumpHardwareArray[0].Extents[0].End = (int)(blocks - 1);
+ sidecar.OpticalDisc[0].DumpHardwareArray[0].Manufacturer = dev.Manufacturer;
+ sidecar.OpticalDisc[0].DumpHardwareArray[0].Model = dev.Model;
+ sidecar.OpticalDisc[0].DumpHardwareArray[0].Revision = dev.Revision;
+ sidecar.OpticalDisc[0].DumpHardwareArray[0].Software = new SoftwareType();
+ sidecar.OpticalDisc[0].DumpHardwareArray[0].Software.Name = "DiscImageChef";
+ sidecar.OpticalDisc[0].DumpHardwareArray[0].Software.OperatingSystem = dev.PlatformID.ToString();
+ sidecar.OpticalDisc[0].DumpHardwareArray[0].Software.Version = typeof(MainClass).Assembly.GetName().Version.ToString();
+ sidecar.OpticalDisc[0].Image = new ImageType();
+ sidecar.OpticalDisc[0].Image.format = "Raw disk image (sector by sector copy)";
+ sidecar.OpticalDisc[0].Image.Value = options.OutputPrefix + ".bin";
+ sidecar.OpticalDisc[0].Sessions = 1;
+ sidecar.OpticalDisc[0].Tracks = new []{1};
+ sidecar.OpticalDisc[0].Track = new TrackType[1];
+ sidecar.OpticalDisc[0].Track[0] = new TrackType();
+ sidecar.OpticalDisc[0].Track[0].BytesPerSector = (int)blockSize;
+ sidecar.OpticalDisc[0].Track[0].Checksums = sidecar.OpticalDisc[0].Checksums;
+ sidecar.OpticalDisc[0].Track[0].EndSector = (long)(blocks - 1);
+ sidecar.OpticalDisc[0].Track[0].Image = new ImageType();
+ sidecar.OpticalDisc[0].Track[0].Image.format = "BINARY";
+ sidecar.OpticalDisc[0].Track[0].Image.offset = 0;
+ sidecar.OpticalDisc[0].Track[0].Image.offsetSpecified = true;
+ sidecar.OpticalDisc[0].Track[0].Image.Value = sidecar.OpticalDisc[0].Image.Value;
+ sidecar.OpticalDisc[0].Track[0].Sequence = new TrackSequenceType();
+ sidecar.OpticalDisc[0].Track[0].Sequence.Session = 1;
+ sidecar.OpticalDisc[0].Track[0].Sequence.TrackNumber = 1;
+ sidecar.OpticalDisc[0].Track[0].Size = (long)(blocks * blockSize);
+ sidecar.OpticalDisc[0].Track[0].StartSector = 0;
+ sidecar.OpticalDisc[0].Track[0].TrackType1 = TrackTypeTrackType.mode1;
+ sidecar.OpticalDisc[0].Dimensions = Metadata.Dimensions.DimensionsFromMediaType(dskType);
+ string xmlDskTyp, xmlDskSubTyp;
+ Metadata.MediaType.MediaTypeToString(dskType, out xmlDskTyp, out xmlDskSubTyp);
+ sidecar.OpticalDisc[0].DiscType = xmlDskTyp;
+ sidecar.OpticalDisc[0].DiscSubType = xmlDskSubTyp;
+ }
+ else
+ {
+ uint longBlockSize = blockSize;
+ bool rawAble = false;
+
+ if (options.Raw)
+ {
+ bool testSense;
+ Decoders.SCSI.FixedSense? decSense;
+
+ if (dev.SCSIType != DiscImageChef.Decoders.SCSI.PeripheralDeviceTypes.MultiMediaDevice)
+ {
+ /*testSense = dev.ReadLong16(out readBuffer, out senseBuf, false, 0, 0xFFFF, dev.Timeout, out duration);
+ if (testSense && !dev.Error)
+ {
+ decSense = Decoders.SCSI.Sense.DecodeFixed(senseBuf);
+ if (decSense.HasValue)
+ {
+ if (decSense.Value.SenseKey == DiscImageChef.Decoders.SCSI.SenseKeys.IllegalRequest &&
+ decSense.Value.ASC == 0x24 && decSense.Value.ASCQ == 0x00)
+ {
+ rawAble = true;
+ if (decSense.Value.InformationValid && decSense.Value.ILI)
+ {
+ longBlockSize = 0xFFFF - decSense.Value.Information;
+ readLong16 = !dev.ReadLong16(out readBuffer, out senseBuf, false, 0, longBlockSize, dev.Timeout, out duration);
+ }
+ }
+ }
+ }*/
+
+ testSense = dev.ReadLong10(out readBuffer, out senseBuf, false, false, 0, 0xFFFF, dev.Timeout, out duration);
+ if (testSense && !dev.Error)
+ {
+ decSense = Decoders.SCSI.Sense.DecodeFixed(senseBuf);
+ if (decSense.HasValue)
+ {
+ if (decSense.Value.SenseKey == DiscImageChef.Decoders.SCSI.SenseKeys.IllegalRequest &&
+ decSense.Value.ASC == 0x24 && decSense.Value.ASCQ == 0x00)
+ {
+ rawAble = true;
+ if (decSense.Value.InformationValid && decSense.Value.ILI)
+ {
+ longBlockSize = 0xFFFF - decSense.Value.Information;
+ readLong10 = !dev.ReadLong10(out readBuffer, out senseBuf, false, false, 0, (ushort)longBlockSize, dev.Timeout, out duration);
+ }
+ }
+ }
+ }
+
+ if (rawAble && longBlockSize == blockSize)
+ {
+ if (blockSize == 512)
+ {
+ // Long sector sizes for 512-byte magneto-opticals
+ foreach (ushort testSize in new []{ 600, 610, 630 })
+ {
+ testSense = dev.ReadLong16(out readBuffer, out senseBuf, false, 0, testSize, dev.Timeout, out duration);
+ if (!testSense && !dev.Error)
+ {
+ readLong16 = true;
+ longBlockSize = testSize;
+ rawAble = true;
+ break;
+ }
+
+ testSense = dev.ReadLong10(out readBuffer, out senseBuf, false, false, 0, testSize, dev.Timeout, out duration);
+ if (!testSense && !dev.Error)
+ {
+ readLong10 = true;
+ longBlockSize = testSize;
+ rawAble = true;
+ break;
+ }
+ }
+ }
+ else if (blockSize == 1024)
+ {
+ testSense = dev.ReadLong16(out readBuffer, out senseBuf, false, 0, 1200, dev.Timeout, out duration);
+ if (!testSense && !dev.Error)
+ {
+ readLong16 = true;
+ longBlockSize = 1200;
+ rawAble = true;
+ }
+ else
+ {
+ testSense = dev.ReadLong10(out readBuffer, out senseBuf, false, false, 0, 1200, dev.Timeout, out duration);
+ if (!testSense && !dev.Error)
+ {
+ readLong10 = true;
+ longBlockSize = 1200;
+ rawAble = true;
+ }
+ }
+ }
+ else if (blockSize == 2048)
+ {
+ testSense = dev.ReadLong16(out readBuffer, out senseBuf, false, 0, 2380, dev.Timeout, out duration);
+ if (!testSense && !dev.Error)
+ {
+ readLong16 = true;
+ longBlockSize = 2380;
+ rawAble = true;
+ }
+ else
+ {
+ testSense = dev.ReadLong10(out readBuffer, out senseBuf, false, false, 0, 2380, dev.Timeout, out duration);
+ if (!testSense && !dev.Error)
+ {
+ readLong10 = true;
+ longBlockSize = 2380;
+ rawAble = true;
+ }
+ }
+ }
+ else if (blockSize == 4096)
+ {
+ testSense = dev.ReadLong16(out readBuffer, out senseBuf, false, 0, 4760, dev.Timeout, out duration);
+ if (!testSense && !dev.Error)
+ {
+ readLong16 = true;
+ longBlockSize = 4760;
+ rawAble = true;
+ }
+ else
+ {
+ testSense = dev.ReadLong10(out readBuffer, out senseBuf, false, false, 0, 4760, dev.Timeout, out duration);
+ if (!testSense && !dev.Error)
+ {
+ readLong10 = true;
+ longBlockSize = 4760;
+ rawAble = true;
+ }
+ }
+ }
+ else if (blockSize == 8192)
+ {
+ testSense = dev.ReadLong16(out readBuffer, out senseBuf, false, 0, 9424, dev.Timeout, out duration);
+ if (!testSense && !dev.Error)
+ {
+ readLong16 = true;
+ longBlockSize = 9424;
+ rawAble = true;
+ }
+ else
+ {
+ testSense = dev.ReadLong10(out readBuffer, out senseBuf, false, false, 0, 9424, dev.Timeout, out duration);
+ if (!testSense && !dev.Error)
+ {
+ readLong10 = true;
+ longBlockSize = 9424;
+ rawAble = true;
+ }
+ }
+ }
+ }
+
+ if (!rawAble && dev.Manufacturer == "SYQUEST")
+ {
+ testSense = dev.SyQuestReadLong10(out readBuffer, out senseBuf, 0, 0xFFFF, dev.Timeout, out duration);
+ if (testSense)
+ {
+ decSense = Decoders.SCSI.Sense.DecodeFixed(senseBuf);
+ if (decSense.HasValue)
+ {
+ if (decSense.Value.SenseKey == DiscImageChef.Decoders.SCSI.SenseKeys.IllegalRequest &&
+ decSense.Value.ASC == 0x24 && decSense.Value.ASCQ == 0x00)
+ {
+ rawAble = true;
+ if (decSense.Value.InformationValid && decSense.Value.ILI)
+ {
+ longBlockSize = 0xFFFF - decSense.Value.Information;
+ syqReadLong10 = !dev.SyQuestReadLong10(out readBuffer, out senseBuf, 0, longBlockSize, dev.Timeout, out duration);
+ ;
+ }
+ }
+ else
+ {
+ testSense = dev.SyQuestReadLong6(out readBuffer, out senseBuf, 0, 0xFFFF, dev.Timeout, out duration);
+ if (testSense)
+ {
+ decSense = Decoders.SCSI.Sense.DecodeFixed(senseBuf);
+ if (decSense.HasValue)
+ {
+ if (decSense.Value.SenseKey == DiscImageChef.Decoders.SCSI.SenseKeys.IllegalRequest &&
+ decSense.Value.ASC == 0x24 && decSense.Value.ASCQ == 0x00)
+ {
+ rawAble = true;
+ if (decSense.Value.InformationValid && decSense.Value.ILI)
+ {
+ longBlockSize = 0xFFFF - decSense.Value.Information;
+ syqReadLong6 = !dev.SyQuestReadLong6(out readBuffer, out senseBuf, 0, longBlockSize, dev.Timeout, out duration);
+ ;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (!rawAble && blockSize == 256)
+ {
+ testSense = dev.SyQuestReadLong6(out readBuffer, out senseBuf, 0, 262, dev.Timeout, out duration);
+ if (!testSense && !dev.Error)
+ {
+ syqReadLong6 = true;
+ longBlockSize = 262;
+ rawAble = true;
+ }
+ }
+ }
+ }
+ else
+ {
+ if (dev.Manufacturer == "HL-DT-ST")
+ hldtstReadRaw = !dev.HlDtStReadRawDvd(out readBuffer, out senseBuf, 0, 1, dev.Timeout, out duration);
+
+ if (dev.Manufacturer == "PLEXTOR")
+ hldtstReadRaw = !dev.PlextorReadRawDvd(out readBuffer, out senseBuf, 0, 1, dev.Timeout, out duration);
+
+ if (hldtstReadRaw || plextorReadRaw)
+ {
+ rawAble = true;
+ longBlockSize = 2064;
+ }
+ }
+
+ if (blockSize == longBlockSize)
+ {
+ if (!rawAble)
+ {
+ DicConsole.ErrorWriteLine("Device doesn't seem capable of reading raw data from media.");
+ }
+ else
+ {
+ DicConsole.ErrorWriteLine("Device is capable of reading raw data but I've been unable to guess correct sector size.");
+ }
+
+ if (!options.Force)
+ {
+ DicConsole.ErrorWriteLine("Not continuing. If you want to continue reading cooked data when raw is not available use the force option.");
+ // TODO: Exit more gracefully
+ return;
+ }
+
+ DicConsole.ErrorWriteLine("Continuing dumping cooked data.");
+ options.Raw = false;
+ }
+ else
+ {
+ if(readLong16)
+ DicConsole.WriteLine("Using SCSI READ LONG (16) command.");
+ else if(readLong10)
+ DicConsole.WriteLine("Using SCSI READ LONG (10) command.");
+ else if(syqReadLong10)
+ DicConsole.WriteLine("Using SyQuest READ LONG (10) command.");
+ else if(syqReadLong6)
+ DicConsole.WriteLine("Using SyQuest READ LONG (6) command.");
+ else if(hldtstReadRaw)
+ DicConsole.WriteLine("Using HL-DT-ST raw DVD reading.");
+ else if(plextorReadRaw)
+ DicConsole.WriteLine("Using Plextor raw DVD reading.");
+ else
+ throw new AccessViolationException("Should not arrive here");
+
+ DicConsole.WriteLine("Reading {0} raw bytes ({1} cooked bytes) per sector.",
+ longBlockSize, blockSize);
+ blocksToRead = 1;
+ blockSize = longBlockSize;
+ }
+ }
+
+ if (!options.Raw)
+ {
+ read6 = !dev.Read6(out readBuffer, out senseBuf, 0, blockSize, dev.Timeout, out duration);
+
+ read10 = !dev.Read10(out readBuffer, out senseBuf, 0, false, true, false, false, 0, blockSize, 0, 1, dev.Timeout, out duration);
+
+ read12 = !dev.Read12(out readBuffer, out senseBuf, 0, false, true, false, false, 0, blockSize, 0, 1, false, dev.Timeout, out duration);
+
+ read16 = !dev.Read16(out readBuffer, out senseBuf, 0, false, true, false, 0, blockSize, 0, 1, false, dev.Timeout, out duration);
+
+ if (!read6 && !read10 && !read12 && !read16)
+ {
+ DicConsole.ErrorWriteLine("Cannot read medium, aborting scan...");
+ return;
+ }
+
+ if (read6 && !read10 && !read12 && !read16 && blocks > (0x001FFFFF + 1))
+ {
+ DicConsole.ErrorWriteLine("Device only supports SCSI READ (6) but has more than {0} blocks ({1} blocks total)", 0x001FFFFF + 1, blocks);
+ return;
+ }
+
+ if (!read16 && blocks > ((long)0xFFFFFFFF + (long)1))
+ {
+ DicConsole.ErrorWriteLine("Device only supports SCSI READ (10) but has more than {0} blocks ({1} blocks total)", (long)0xFFFFFFFF + (long)1, blocks);
+ return;
+ }
+
+ if (read16)
+ DicConsole.WriteLine("Using SCSI READ (16) command.");
+ else if (read12)
+ DicConsole.WriteLine("Using SCSI READ (12) command.");
+ else if (read10)
+ DicConsole.WriteLine("Using SCSI READ (10) command.");
+ else if (read6)
+ DicConsole.WriteLine("Using SCSI READ (6) command.");
+
+ while (true)
+ {
+ if (read16)
+ {
+ sense = dev.Read16(out readBuffer, out senseBuf, 0, false, true, false, 0, blockSize, 0, blocksToRead, false, dev.Timeout, out duration);
+ if (dev.Error)
+ blocksToRead /= 2;
+ }
+ else if (read12)
+ {
+ sense = dev.Read12(out readBuffer, out senseBuf, 0, false, false, false, false, 0, blockSize, 0, blocksToRead, false, dev.Timeout, out duration);
+ if (dev.Error)
+ blocksToRead /= 2;
+ }
+ else if (read10)
+ {
+ sense = dev.Read10(out readBuffer, out senseBuf, 0, false, true, false, false, 0, blockSize, 0, (ushort)blocksToRead, dev.Timeout, out duration);
+ if (dev.Error)
+ blocksToRead /= 2;
+ }
+ else if (read6)
+ {
+ sense = dev.Read6(out readBuffer, out senseBuf, 0, blockSize, (byte)blocksToRead, dev.Timeout, out duration);
+ if (dev.Error)
+ blocksToRead /= 2;
+ }
+
+ if (!dev.Error || blocksToRead == 1)
+ break;
+ }
+
+ if (dev.Error)
+ {
+ DicConsole.ErrorWriteLine("Device error {0} trying to guess ideal transfer length.", dev.LastError);
+ return;
+ }
+ }
+
+ DicConsole.WriteLine("Reading {0} sectors at a time.", blocksToRead);
+
+ initMHDDLogFile(options.OutputPrefix + ".mhddlog.bin", dev, blocks, blockSize, blocksToRead);
+ initDataFile(options.OutputPrefix + ".bin");
+
+ start = DateTime.UtcNow;
+
+ readBuffer = null;
+
+ for (ulong i = 0; i < blocks; i += blocksToRead)
+ {
+ if (aborted)
+ break;
+
+ double cmdDuration = 0;
+
+ if ((blocks - i) < blocksToRead)
+ blocksToRead = (uint)(blocks - i);
+
+ if (currentSpeed > maxSpeed && currentSpeed != 0)
+ maxSpeed = currentSpeed;
+ if (currentSpeed < minSpeed && currentSpeed != 0)
+ minSpeed = currentSpeed;
+
+ DicConsole.Write("\rReading sector {0} of {1} ({2:F3} MiB/sec.)", i, blocks, currentSpeed);
+
+ if(readLong16)
+ {
+ sense = dev.ReadLong16(out readBuffer, out senseBuf, false, i, blockSize, dev.Timeout, out cmdDuration);
+ totalDuration += cmdDuration;
+ }
+ else if(readLong10)
+ {
+ sense = dev.ReadLong10(out readBuffer, out senseBuf, false, false, (uint)i, (ushort)blockSize, dev.Timeout, out cmdDuration);
+ totalDuration += cmdDuration;
+ }
+ else if(syqReadLong10)
+ {
+ sense = dev.SyQuestReadLong10(out readBuffer, out senseBuf, (uint)i, blockSize, dev.Timeout, out cmdDuration);
+ totalDuration += cmdDuration;
+ }
+ else if(syqReadLong6)
+ {
+ sense = dev.SyQuestReadLong6(out readBuffer, out senseBuf, (uint)i, blockSize, dev.Timeout, out cmdDuration);
+ totalDuration += cmdDuration;
+ }
+ else if(hldtstReadRaw)
+ {
+ sense = dev.HlDtStReadRawDvd(out readBuffer, out senseBuf, (uint)i, blockSize, dev.Timeout, out cmdDuration);
+ totalDuration += cmdDuration;
+ }
+ else if(plextorReadRaw)
+ {
+ sense = dev.PlextorReadRawDvd(out readBuffer, out senseBuf, (uint)i, blockSize, dev.Timeout, out cmdDuration);
+ totalDuration += cmdDuration;
+ }
+ else if (read16)
+ {
+ sense = dev.Read16(out readBuffer, out senseBuf, 0, false, true, false, i, blockSize, 0, blocksToRead, false, dev.Timeout, out cmdDuration);
+ totalDuration += cmdDuration;
+ }
+ else if (read12)
+ {
+ sense = dev.Read12(out readBuffer, out senseBuf, 0, false, false, false, false, (uint)i, blockSize, 0, blocksToRead, false, dev.Timeout, out cmdDuration);
+ totalDuration += cmdDuration;
+ }
+ else if (read10)
+ {
+ sense = dev.Read10(out readBuffer, out senseBuf, 0, false, true, false, false, (uint)i, blockSize, 0, (ushort)blocksToRead, dev.Timeout, out cmdDuration);
+ totalDuration += cmdDuration;
+ }
+ else if (read6)
+ {
+ sense = dev.Read6(out readBuffer, out senseBuf, (uint)i, blockSize, (byte)blocksToRead, dev.Timeout, out cmdDuration);
+ totalDuration += cmdDuration;
+ }
+
+ if (!sense && !dev.Error)
+ {
+ writeMHDDLogFile(i, cmdDuration);
+ writeToDataFile(readBuffer);
+ }
+ else
+ {
+ // TODO: Reset device after X errors
+ if (options.StopOnError)
+ return; // TODO: Return more cleanly
+
+ // Write empty data
+ writeToDataFile(new byte[blockSize * blocksToRead]);
+
+ // TODO: Record error on mapfile
+
+ errored += blocksToRead;
+ unreadableSectors.Add(i);
+ DicConsole.DebugWriteLine("Dump-Media", "READ error:\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
+ if (cmdDuration < 500)
+ writeMHDDLogFile(i, 65535);
+ else
+ writeMHDDLogFile(i, cmdDuration);
+ }
+
+ currentSpeed = ((double)blockSize * blocksToRead / (double)1048576) / (cmdDuration / (double)1000);
+ }
+ DicConsole.WriteLine();
+ closeMHDDLogFile();
+
+ dataChk = new Core.Checksum();
+ dataFs.Seek(0, SeekOrigin.Begin);
+ blocksToRead = 500;
+
+ for (ulong i = 0; i < blocks; i += blocksToRead)
+ {
+ if (aborted)
+ break;
+
+ if ((blocks - i) < blocksToRead)
+ blocksToRead = (uint)(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];
+ dataFs.Read(dataToCheck, 0, (int)(blockSize * blocksToRead));
+ dataChk.Update(dataToCheck);
+ DateTime chkEnd = DateTime.UtcNow;
+
+ double chkDuration = (chkEnd - chkStart).TotalMilliseconds;
+ totalChkDuration += chkDuration;
+
+ currentSpeed = ((double)blockSize * blocksToRead / (double)1048576) / (chkDuration / (double)1000);
+ }
+ DicConsole.WriteLine();
+ closeDataFile();
+ end = DateTime.UtcNow;
+
+ if (opticalDisc)
+ {
+ sidecar.OpticalDisc[0].Checksums = dataChk.End().ToArray();
+ sidecar.OpticalDisc[0].DumpHardwareArray = new DumpHardwareType[1];
+ sidecar.OpticalDisc[0].DumpHardwareArray[0] = new DumpHardwareType();
+ sidecar.OpticalDisc[0].DumpHardwareArray[0].Extents = new ExtentType[1];
+ sidecar.OpticalDisc[0].DumpHardwareArray[0].Extents[0] = new ExtentType();
+ sidecar.OpticalDisc[0].DumpHardwareArray[0].Extents[0].Start = 0;
+ sidecar.OpticalDisc[0].DumpHardwareArray[0].Extents[0].End = (int)(blocks - 1);
+ sidecar.OpticalDisc[0].DumpHardwareArray[0].Manufacturer = dev.Manufacturer;
+ sidecar.OpticalDisc[0].DumpHardwareArray[0].Model = dev.Model;
+ sidecar.OpticalDisc[0].DumpHardwareArray[0].Revision = dev.Revision;
+ sidecar.OpticalDisc[0].DumpHardwareArray[0].Software = new SoftwareType();
+ sidecar.OpticalDisc[0].DumpHardwareArray[0].Software.Name = "DiscImageChef";
+ sidecar.OpticalDisc[0].DumpHardwareArray[0].Software.OperatingSystem = dev.PlatformID.ToString();
+ sidecar.OpticalDisc[0].DumpHardwareArray[0].Software.Version = typeof(MainClass).Assembly.GetName().Version.ToString();
+ sidecar.OpticalDisc[0].Image = new ImageType();
+ sidecar.OpticalDisc[0].Image.format = "Raw disk image (sector by sector copy)";
+ sidecar.OpticalDisc[0].Image.Value = options.OutputPrefix + ".bin";
+ // TODO: Implement layers
+ //sidecar.OpticalDisc[0].Layers = new LayersType();
+ sidecar.OpticalDisc[0].Sessions = 1;
+ sidecar.OpticalDisc[0].Tracks = new []{1};
+ sidecar.OpticalDisc[0].Track = new TrackType[1];
+ sidecar.OpticalDisc[0].Track[0] = new TrackType();
+ sidecar.OpticalDisc[0].Track[0].BytesPerSector = (int)blockSize;
+ sidecar.OpticalDisc[0].Track[0].Checksums = sidecar.OpticalDisc[0].Checksums;
+ sidecar.OpticalDisc[0].Track[0].EndSector = (long)(blocks - 1);
+ sidecar.OpticalDisc[0].Track[0].Image = new ImageType();
+ sidecar.OpticalDisc[0].Track[0].Image.format = "BINARY";
+ sidecar.OpticalDisc[0].Track[0].Image.offset = 0;
+ sidecar.OpticalDisc[0].Track[0].Image.offsetSpecified = true;
+ sidecar.OpticalDisc[0].Track[0].Image.Value = sidecar.OpticalDisc[0].Image.Value;
+ sidecar.OpticalDisc[0].Track[0].Sequence = new TrackSequenceType();
+ sidecar.OpticalDisc[0].Track[0].Sequence.Session = 1;
+ sidecar.OpticalDisc[0].Track[0].Sequence.TrackNumber = 1;
+ sidecar.OpticalDisc[0].Track[0].Size = (long)(blocks * blockSize);
+ sidecar.OpticalDisc[0].Track[0].StartSector = 0;
+ switch (dskType)
+ {
+ case MediaType.DDCD:
+ case MediaType.DDCDR:
+ case MediaType.DDCDRW:
+ sidecar.OpticalDisc[0].Track[0].TrackType1 = TrackTypeTrackType.ddcd;
+ break;
+ case MediaType.DVDROM:
+ case MediaType.DVDR:
+ case MediaType.DVDRAM:
+ case MediaType.DVDRW:
+ case MediaType.DVDRDL:
+ case MediaType.DVDRWDL:
+ case MediaType.DVDDownload:
+ case MediaType.DVDPRW:
+ case MediaType.DVDPR:
+ case MediaType.DVDPRWDL:
+ case MediaType.DVDPRDL:
+ sidecar.OpticalDisc[0].Track[0].TrackType1 = TrackTypeTrackType.dvd;
+ break;
+ case MediaType.HDDVDROM:
+ case MediaType.HDDVDR:
+ case MediaType.HDDVDRAM:
+ case MediaType.HDDVDRW:
+ case MediaType.HDDVDRDL:
+ case MediaType.HDDVDRWDL:
+ sidecar.OpticalDisc[0].Track[0].TrackType1 = TrackTypeTrackType.hddvd;
+ break;
+ case MediaType.BDROM:
+ case MediaType.BDR:
+ case MediaType.BDRE:
+ case MediaType.BDREXL:
+ case MediaType.BDRXL:
+ sidecar.OpticalDisc[0].Track[0].TrackType1 = TrackTypeTrackType.bluray;
+ break;
+ }
+ sidecar.OpticalDisc[0].Dimensions = Metadata.Dimensions.DimensionsFromMediaType(dskType);
+ string xmlDskTyp, xmlDskSubTyp;
+ Metadata.MediaType.MediaTypeToString(dskType, out xmlDskTyp, out xmlDskSubTyp);
+ sidecar.OpticalDisc[0].DiscType = xmlDskTyp;
+ sidecar.OpticalDisc[0].DiscSubType = xmlDskSubTyp;
+ }
+ else
+ {
+ sidecar.BlockMedia[0].Checksums = dataChk.End().ToArray();
+ sidecar.BlockMedia[0].Dimensions = Metadata.Dimensions.DimensionsFromMediaType(dskType);
+ string xmlDskTyp, xmlDskSubTyp;
+ Metadata.MediaType.MediaTypeToString(dskType, 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();
+ sidecar.BlockMedia[0].Image.format = "Raw disk image (sector by sector copy)";
+ sidecar.BlockMedia[0].Image.Value = options.OutputPrefix + ".bin";
+ if (dev.Type == DeviceType.ATAPI)
+ sidecar.BlockMedia[0].Interface = "ATAPI";
+ else if (dev.IsUSB)
+ sidecar.BlockMedia[0].Interface = "USB";
+ else if (dev.IsFireWire)
+ sidecar.BlockMedia[0].Interface = "FireWire";
+ else
+ sidecar.BlockMedia[0].Interface = "SCSI";
+ sidecar.BlockMedia[0].LogicalBlocks = (long)blocks;
+ 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);
+ }
+ }
+
+ 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.", errored);
+ if (unreadableSectors.Count > 0)
+ {
+ foreach (ulong bad in unreadableSectors)
+ DicConsole.WriteLine("Sector {0} could not be read", bad);
+ }
+ DicConsole.WriteLine();
+
+ if (!aborted)
+ {
+ DicConsole.WriteLine("Writing metadata sidecar");
+
+ FileStream xmlFs = new FileStream(options.OutputPrefix + ".cicm.xml",
+ FileMode.Create);
+
+ System.Xml.Serialization.XmlSerializer xmlSer = new System.Xml.Serialization.XmlSerializer(typeof(CICMMetadataType));
+ xmlSer.Serialize(xmlFs, sidecar);
+ xmlFs.Close();
+ }
+ }
+
+ static void initMHDDLogFile(string outputFile, Device dev, ulong blocks, ulong blockSize, ulong blocksToRead)
+ {
+ if (dev != null && !string.IsNullOrEmpty(outputFile))
+ {
+ mhddFs = new FileStream(outputFile, FileMode.Create);
+
+ string device;
+ string mode;
+ string fw;
+ string sn;
+ string sectors;
+ string sectorsize;
+ string scanblocksize;
+ string ver;
+
+ switch (dev.Type)
+ {
+ case DeviceType.ATA:
+ case DeviceType.ATAPI:
+ mode = "MODE: IDE";
+ break;
+ case DeviceType.SCSI:
+ mode = "MODE: SCSI";
+ break;
+ case DeviceType.MMC:
+ mode = "MODE: MMC";
+ break;
+ case DeviceType.NVMe:
+ mode = "MODE: NVMe";
+ break;
+ case DeviceType.SecureDigital:
+ mode = "MODE: SD";
+ break;
+ default:
+ mode = "MODE: IDE";
+ break;
+ }
+
+ device = String.Format("DEVICE: {0} {1}", dev.Manufacturer, dev.Model);
+ fw = String.Format("F/W: {0}", dev.Revision);
+ sn = String.Format("S/N: {0}", dev.Serial);
+ sectors = String.Format(new System.Globalization.CultureInfo("en-US"), "SECTORS: {0:n0}", blocks);
+ sectorsize = String.Format(new System.Globalization.CultureInfo("en-US"), "SECTOR SIZE: {0:n0} bytes", blockSize);
+ scanblocksize = String.Format(new System.Globalization.CultureInfo("en-US"), "SCAN BLOCK SIZE: {0:n0} sectors", blocksToRead);
+ ver = "VER:2 ";
+
+ byte[] deviceBytes = Encoding.ASCII.GetBytes(device);
+ byte[] modeBytes = Encoding.ASCII.GetBytes(mode);
+ byte[] fwBytes = Encoding.ASCII.GetBytes(fw);
+ byte[] snBytes = Encoding.ASCII.GetBytes(sn);
+ byte[] sectorsBytes = Encoding.ASCII.GetBytes(sectors);
+ byte[] sectorsizeBytes = Encoding.ASCII.GetBytes(sectorsize);
+ byte[] scanblocksizeBytes = Encoding.ASCII.GetBytes(scanblocksize);
+ byte[] verBytes = Encoding.ASCII.GetBytes(ver);
+
+ uint Pointer = (uint)(deviceBytes.Length + modeBytes.Length + fwBytes.Length +
+ snBytes.Length + sectorsBytes.Length + sectorsizeBytes.Length +
+ scanblocksizeBytes.Length + verBytes.Length +
+ 2 * 9 + // New lines
+ 4); // Pointer
+
+ byte[] newLine = new byte[2];
+ newLine[0] = 0x0D;
+ newLine[1] = 0x0A;
+
+ mhddFs.Write(BitConverter.GetBytes(Pointer), 0, 4);
+ mhddFs.Write(newLine, 0, 2);
+ mhddFs.Write(verBytes, 0, verBytes.Length);
+ mhddFs.Write(newLine, 0, 2);
+ mhddFs.Write(modeBytes, 0, modeBytes.Length);
+ mhddFs.Write(newLine, 0, 2);
+ mhddFs.Write(deviceBytes, 0, deviceBytes.Length);
+ mhddFs.Write(newLine, 0, 2);
+ mhddFs.Write(fwBytes, 0, fwBytes.Length);
+ mhddFs.Write(newLine, 0, 2);
+ mhddFs.Write(snBytes, 0, snBytes.Length);
+ mhddFs.Write(newLine, 0, 2);
+ mhddFs.Write(sectorsBytes, 0, sectorsBytes.Length);
+ mhddFs.Write(newLine, 0, 2);
+ mhddFs.Write(sectorsizeBytes, 0, sectorsizeBytes.Length);
+ mhddFs.Write(newLine, 0, 2);
+ mhddFs.Write(scanblocksizeBytes, 0, scanblocksizeBytes.Length);
+ mhddFs.Write(newLine, 0, 2);
+ }
+ }
+
+ static void closeMHDDLogFile()
+ {
+ if (mhddFs != null)
+ mhddFs.Close();
+ }
+
+ static void writeMHDDLogFile(ulong sector, double duration)
+ {
+ if (mhddFs != null)
+ {
+ byte[] sectorBytes = BitConverter.GetBytes(sector);
+ byte[] durationBytes = BitConverter.GetBytes((ulong)(duration * 1000));
+
+ mhddFs.Write(sectorBytes, 0, 8);
+ mhddFs.Write(durationBytes, 0, 8);
+ }
+ }
+
+ static void writeToFile(string file, byte[] data)
+ {
+ FileStream fs = new FileStream(file, FileMode.Create, FileAccess.ReadWrite);
+ fs.Write(data, 0, data.Length);
+ fs.Close();
+ }
+
+ static void initDataFile(string outputFile)
+ {
+ dataFs = new FileStream(outputFile, FileMode.OpenOrCreate, FileAccess.ReadWrite);
+ }
+
+ static void writeToDataFile(byte[] data)
+ {
+ dataFs.Write(data, 0, data.Length);
+ }
+
+ static void closeDataFile()
+ {
+ if (dataFs != null)
+ dataFs.Close();
+ }
+ }
+}
\ No newline at end of file
diff --git a/DiscImageChef/Commands/MediaInfo.cs b/DiscImageChef/Commands/MediaInfo.cs
index 1b6436e3..668c1597 100644
--- a/DiscImageChef/Commands/MediaInfo.cs
+++ b/DiscImageChef/Commands/MediaInfo.cs
@@ -175,6 +175,51 @@ namespace DiscImageChef.Commands
}
}
+ byte[] modeBuf;
+ Decoders.SCSI.Modes.DecodedMode? decMode = null;
+ Decoders.SCSI.PeripheralDeviceTypes devType = dev.SCSIType;
+
+ sense = dev.ModeSense10(out modeBuf, out senseBuf, false, true, ScsiModeSensePageControl.Current, 0x3F, 0xFF, 5, out duration);
+ if (sense || dev.Error)
+ {
+ sense = dev.ModeSense10(out modeBuf, out senseBuf, false, true, ScsiModeSensePageControl.Current, 0x3F, 0x00, 5, out duration);
+ }
+
+ if (!sense && !dev.Error)
+ {
+ decMode = Decoders.SCSI.Modes.DecodeMode10(modeBuf, devType);
+ }
+
+ if(sense || dev.Error || !decMode.HasValue)
+ {
+ sense = dev.ModeSense6(out modeBuf, out senseBuf, false, ScsiModeSensePageControl.Current, 0x3F, 0x00, 5, out duration);
+ if (sense || dev.Error)
+ sense = dev.ModeSense6(out modeBuf, out senseBuf, false, ScsiModeSensePageControl.Current, 0x3F, 0x00, 5, out duration);
+ if (sense || dev.Error)
+ sense = dev.ModeSense(out modeBuf, out senseBuf, 5, out duration);
+
+ if (!sense && !dev.Error)
+ decMode = Decoders.SCSI.Modes.DecodeMode6(modeBuf, devType);
+ }
+
+ if (!sense)
+ doWriteFile(outputPrefix, "_scsi_modesense.bin", "SCSI MODE SENSE", modeBuf);
+
+ byte scsiMediumType = 0;
+ byte scsiDensityCode = 0;
+ bool containsFloppyPage = false;
+
+ if(decMode.HasValue)
+ {
+ scsiMediumType = (byte)decMode.Value.Header.MediumType;
+ if(decMode.Value.Header.BlockDescriptors != null && decMode.Value.Header.BlockDescriptors.Length >= 1)
+ scsiDensityCode = (byte)decMode.Value.Header.BlockDescriptors[0].Density;
+
+ foreach(Decoders.SCSI.Modes.ModePage modePage in decMode.Value.Pages)
+ if(modePage.Page == 0x05)
+ containsFloppyPage = true;
+ }
+
if (dev.SCSIType == DiscImageChef.Decoders.SCSI.PeripheralDeviceTypes.DirectAccess ||
dev.SCSIType == DiscImageChef.Decoders.SCSI.PeripheralDeviceTypes.MultiMediaDevice ||
dev.SCSIType == DiscImageChef.Decoders.SCSI.PeripheralDeviceTypes.OCRWDevice ||
@@ -280,7 +325,7 @@ namespace DiscImageChef.Commands
{
sense = dev.GetConfiguration(out cmdBuf, out senseBuf, 0, MmcGetConfigurationRt.Current, dev.Timeout, out duration);
if (sense)
- DicConsole.ErrorWriteLine("READ GET CONFIGURATION:\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
+ DicConsole.DebugWriteLine("Media-Info command", "READ GET CONFIGURATION:\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
else
{
doWriteFile(outputPrefix, "_getconfiguration_current.bin", "SCSI GET CONFIGURATION", cmdBuf);
@@ -383,12 +428,12 @@ namespace DiscImageChef.Commands
sense = dev.ReadDiscStructure(out cmdBuf, out senseBuf, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.RecognizedFormatLayers, 0, dev.Timeout, out duration);
if (sense)
- DicConsole.ErrorWriteLine("READ DISC STRUCTURE: Recognized Format Layers\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
+ DicConsole.DebugWriteLine("Media-Info command", "READ DISC STRUCTURE: Recognized Format Layers\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
else
doWriteFile(outputPrefix, "_readdiscstructure_formatlayers.bin", "SCSI READ DISC STRUCTURE", cmdBuf);
sense = dev.ReadDiscStructure(out cmdBuf, out senseBuf, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.WriteProtectionStatus, 0, dev.Timeout, out duration);
if (sense)
- DicConsole.ErrorWriteLine("READ DISC STRUCTURE: Write Protection Status\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
+ DicConsole.DebugWriteLine("Media-Info command", "READ DISC STRUCTURE: Write Protection Status\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
else
doWriteFile(outputPrefix, "_readdiscstructure_writeprotection.bin", "SCSI READ DISC STRUCTURE", cmdBuf);
@@ -396,7 +441,7 @@ namespace DiscImageChef.Commands
/*
sense = dev.ReadDiscStructure(out cmdBuf, out senseBuf, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.CapabilityList, 0, dev.Timeout, out duration);
if(sense)
- DicConsole.ErrorWriteLine("READ DISC STRUCTURE: Capability List\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
+ DicConsole.DebugWriteLine("Media-Info command", "READ DISC STRUCTURE: Capability List\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
else
doWriteFile(outputPrefix, "_readdiscstructure_capabilitylist.bin", "SCSI READ DISC STRUCTURE", cmdBuf);
*/
@@ -415,15 +460,78 @@ namespace DiscImageChef.Commands
sense = dev.ReadDiscStructure(out cmdBuf, out senseBuf, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.PhysicalInformation, 0, dev.Timeout, out duration);
if (sense)
- DicConsole.ErrorWriteLine("READ DISC STRUCTURE: PFI\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
+ DicConsole.DebugWriteLine("Media-Info command", "READ DISC STRUCTURE: PFI\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
else
{
doWriteFile(outputPrefix, "_readdiscstructure_dvd_pfi.bin", "SCSI READ DISC STRUCTURE", cmdBuf);
- DicConsole.WriteLine("PFI:\n{0}", Decoders.DVD.PFI.Prettify(cmdBuf));
+ Decoders.DVD.PFI.PhysicalFormatInformation? decPfi = Decoders.DVD.PFI.Decode(cmdBuf);
+ if(decPfi.HasValue)
+ {
+ DicConsole.WriteLine("PFI:\n{0}", Decoders.DVD.PFI.Prettify(decPfi));
+
+ // False book types
+ if(dskType == MediaType.DVDROM)
+ {
+ switch(decPfi.Value.DiskCategory)
+ {
+ case Decoders.DVD.DiskCategory.DVDPR:
+ dskType = MediaType.DVDPR;
+ break;
+ case Decoders.DVD.DiskCategory.DVDPRDL:
+ dskType = MediaType.DVDPRDL;
+ break;
+ case Decoders.DVD.DiskCategory.DVDPRW:
+ dskType = MediaType.DVDPRW;
+ break;
+ case Decoders.DVD.DiskCategory.DVDPRWDL:
+ dskType = MediaType.DVDPRWDL;
+ break;
+ case Decoders.DVD.DiskCategory.DVDR:
+ if(decPfi.Value.PartVersion == 6)
+ dskType = MediaType.DVDRDL;
+ else
+ dskType = MediaType.DVDR;
+ break;
+ case Decoders.DVD.DiskCategory.DVDRAM:
+ dskType = MediaType.DVDRAM;
+ break;
+ default:
+ dskType = MediaType.DVDROM;
+ break;
+ case Decoders.DVD.DiskCategory.DVDRW:
+ if(decPfi.Value.PartVersion == 3)
+ dskType = MediaType.DVDRWDL;
+ else
+ dskType = MediaType.DVDRW;
+ break;
+ case Decoders.DVD.DiskCategory.HDDVDR:
+ dskType = MediaType.HDDVDR;
+ break;
+ case Decoders.DVD.DiskCategory.HDDVDRAM:
+ dskType = MediaType.HDDVDRAM;
+ break;
+ case Decoders.DVD.DiskCategory.HDDVDROM:
+ dskType = MediaType.HDDVDROM;
+ break;
+ case Decoders.DVD.DiskCategory.HDDVDRW:
+ dskType = MediaType.HDDVDRW;
+ break;
+ case Decoders.DVD.DiskCategory.Nintendo:
+ if(decPfi.Value.DiscSize == DiscImageChef.Decoders.DVD.DVDSize.Eighty)
+ dskType = MediaType.GOD;
+ else
+ dskType = MediaType.WOD;
+ break;
+ case Decoders.DVD.DiskCategory.UMD:
+ dskType = MediaType.UMD;
+ break;
+ }
+ }
+ }
}
sense = dev.ReadDiscStructure(out cmdBuf, out senseBuf, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.DiscManufacturingInformation, 0, dev.Timeout, out duration);
if (sense)
- DicConsole.ErrorWriteLine("READ DISC STRUCTURE: DMI\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
+ DicConsole.DebugWriteLine("Media-Info command", "READ DISC STRUCTURE: DMI\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
else
{
doWriteFile(outputPrefix, "_readdiscstructure_dvd_dmi.bin", "SCSI READ DISC STRUCTURE", cmdBuf);
@@ -445,7 +553,7 @@ namespace DiscImageChef.Commands
{
sense = dev.ReadDiscStructure(out cmdBuf, out senseBuf, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.CopyrightInformation, 0, dev.Timeout, out duration);
if (sense)
- DicConsole.ErrorWriteLine("READ DISC STRUCTURE: CMI\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
+ DicConsole.DebugWriteLine("Media-Info command", "READ DISC STRUCTURE: CMI\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
else
{
doWriteFile(outputPrefix, "_readdiscstructure_dvd_cmi.bin", "SCSI READ DISC STRUCTURE", cmdBuf);
@@ -460,12 +568,12 @@ namespace DiscImageChef.Commands
{
sense = dev.ReadDiscStructure(out cmdBuf, out senseBuf, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.BurstCuttingArea, 0, dev.Timeout, out duration);
if (sense)
- DicConsole.ErrorWriteLine("READ DISC STRUCTURE: BCA\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
+ DicConsole.DebugWriteLine("Media-Info command", "READ DISC STRUCTURE: BCA\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
else
doWriteFile(outputPrefix, "_readdiscstructure_dvd_bca.bin", "SCSI READ DISC STRUCTURE", cmdBuf);
sense = dev.ReadDiscStructure(out cmdBuf, out senseBuf, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.DVD_AACS, 0, dev.Timeout, out duration);
if (sense)
- DicConsole.ErrorWriteLine("READ DISC STRUCTURE: DVD AACS\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
+ DicConsole.DebugWriteLine("Media-Info command", "READ DISC STRUCTURE: DVD AACS\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
else
doWriteFile(outputPrefix, "_readdiscstructure_dvd_aacs.bin", "SCSI READ DISC STRUCTURE", cmdBuf);
}
@@ -475,57 +583,57 @@ namespace DiscImageChef.Commands
/*
sense = dev.ReadDiscStructure(out cmdBuf, out senseBuf, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.DiscKey, 0, dev.Timeout, out duration);
if(sense)
- DicConsole.ErrorWriteLine("READ DISC STRUCTURE: Disc Key\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
+ DicConsole.DebugWriteLine("Media-Info command", "READ DISC STRUCTURE: Disc Key\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
else
doWriteFile(outputPrefix, "_readdiscstructure_dvd_disckey.bin", "SCSI READ DISC STRUCTURE", cmdBuf);
sense = dev.ReadDiscStructure(out cmdBuf, out senseBuf, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.SectorCopyrightInformation, 0, dev.Timeout, out duration);
if(sense)
- DicConsole.ErrorWriteLine("READ DISC STRUCTURE: Sector CMI\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
+ DicConsole.DebugWriteLine("Media-Info command", "READ DISC STRUCTURE: Sector CMI\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
else
doWriteFile(outputPrefix, "_readdiscstructure_dvd_sectorcmi.bin", "SCSI READ DISC STRUCTURE", cmdBuf);
sense = dev.ReadDiscStructure(out cmdBuf, out senseBuf, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.MediaIdentifier, 0, dev.Timeout, out duration);
if(sense)
- DicConsole.ErrorWriteLine("READ DISC STRUCTURE: Media ID\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
+ DicConsole.DebugWriteLine("Media-Info command", "READ DISC STRUCTURE: Media ID\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
else
doWriteFile(outputPrefix, "_readdiscstructure_dvd_mediaid.bin", "SCSI READ DISC STRUCTURE", cmdBuf);
sense = dev.ReadDiscStructure(out cmdBuf, out senseBuf, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.MediaKeyBlock, 0, dev.Timeout, out duration);
if(sense)
- DicConsole.ErrorWriteLine("READ DISC STRUCTURE: MKB\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
+ DicConsole.DebugWriteLine("Media-Info command", "READ DISC STRUCTURE: MKB\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
else
doWriteFile(outputPrefix, "_readdiscstructure_dvd_mkb.bin", "SCSI READ DISC STRUCTURE", cmdBuf);
sense = dev.ReadDiscStructure(out cmdBuf, out senseBuf, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.AACSVolId, 0, dev.Timeout, out duration);
if(sense)
- DicConsole.ErrorWriteLine("READ DISC STRUCTURE: AACS Volume ID\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
+ DicConsole.DebugWriteLine("Media-Info command", "READ DISC STRUCTURE: AACS Volume ID\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
else
doWriteFile(outputPrefix, "_readdiscstructure_aacsvolid.bin", "SCSI READ DISC STRUCTURE", cmdBuf);
sense = dev.ReadDiscStructure(out cmdBuf, out senseBuf, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.AACSMediaSerial, 0, dev.Timeout, out duration);
if(sense)
- DicConsole.ErrorWriteLine("READ DISC STRUCTURE: AACS Media Serial Number\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
+ DicConsole.DebugWriteLine("Media-Info command", "READ DISC STRUCTURE: AACS Media Serial Number\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
else
doWriteFile(outputPrefix, "_readdiscstructure_aacssn.bin", "SCSI READ DISC STRUCTURE", cmdBuf);
sense = dev.ReadDiscStructure(out cmdBuf, out senseBuf, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.AACSMediaId, 0, dev.Timeout, out duration);
if(sense)
- DicConsole.ErrorWriteLine("READ DISC STRUCTURE: AACS Media ID\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
+ DicConsole.DebugWriteLine("Media-Info command", "READ DISC STRUCTURE: AACS Media ID\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
else
doWriteFile(outputPrefix, "_readdiscstructure_aacsmediaid.bin", "SCSI READ DISC STRUCTURE", cmdBuf);
sense = dev.ReadDiscStructure(out cmdBuf, out senseBuf, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.AACSMKB, 0, dev.Timeout, out duration);
if(sense)
- DicConsole.ErrorWriteLine("READ DISC STRUCTURE: AACS MKB\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
+ DicConsole.DebugWriteLine("Media-Info command", "READ DISC STRUCTURE: AACS MKB\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
else
doWriteFile(outputPrefix, "_readdiscstructure_aacsmkb.bin", "SCSI READ DISC STRUCTURE", cmdBuf);
sense = dev.ReadDiscStructure(out cmdBuf, out senseBuf, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.AACSLBAExtents, 0, dev.Timeout, out duration);
if(sense)
- DicConsole.ErrorWriteLine("READ DISC STRUCTURE: AACS LBA Extents\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
+ DicConsole.DebugWriteLine("Media-Info command", "READ DISC STRUCTURE: AACS LBA Extents\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
else
doWriteFile(outputPrefix, "_readdiscstructure_aacslbaextents.bin", "SCSI READ DISC STRUCTURE", cmdBuf);
sense = dev.ReadDiscStructure(out cmdBuf, out senseBuf, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.AACSMKBCPRM, 0, dev.Timeout, out duration);
if(sense)
- DicConsole.ErrorWriteLine("READ DISC STRUCTURE: AACS CPRM MKB\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
+ DicConsole.DebugWriteLine("Media-Info command", "READ DISC STRUCTURE: AACS CPRM MKB\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
else
doWriteFile(outputPrefix, "_readdiscstructure_aacscprmmkb.bin", "SCSI READ DISC STRUCTURE", cmdBuf);
sense = dev.ReadDiscStructure(out cmdBuf, out senseBuf, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.AACSDataKeys, 0, dev.Timeout, out duration);
if(sense)
- DicConsole.ErrorWriteLine("READ DISC STRUCTURE: AACS Data Keys\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
+ DicConsole.DebugWriteLine("Media-Info command", "READ DISC STRUCTURE: AACS Data Keys\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
else
doWriteFile(outputPrefix, "_readdiscstructure_aacsdatakeys.bin", "SCSI READ DISC STRUCTURE", cmdBuf);
*/
@@ -536,7 +644,7 @@ namespace DiscImageChef.Commands
{
sense = dev.ReadDiscStructure(out cmdBuf, out senseBuf, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.DVDRAM_DDS, 0, dev.Timeout, out duration);
if (sense)
- DicConsole.ErrorWriteLine("READ DISC STRUCTURE: DDS\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
+ DicConsole.DebugWriteLine("Media-Info command", "READ DISC STRUCTURE: DDS\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
else
{
doWriteFile(outputPrefix, "_readdiscstructure_dvdram_dds.bin", "SCSI READ DISC STRUCTURE", cmdBuf);
@@ -544,7 +652,7 @@ namespace DiscImageChef.Commands
}
sense = dev.ReadDiscStructure(out cmdBuf, out senseBuf, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.DVDRAM_MediumStatus, 0, dev.Timeout, out duration);
if (sense)
- DicConsole.ErrorWriteLine("READ DISC STRUCTURE: Medium Status\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
+ DicConsole.DebugWriteLine("Media-Info command", "READ DISC STRUCTURE: Medium Status\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
else
{
doWriteFile(outputPrefix, "_readdiscstructure_dvdram_status.bin", "SCSI READ DISC STRUCTURE", cmdBuf);
@@ -552,7 +660,7 @@ namespace DiscImageChef.Commands
}
sense = dev.ReadDiscStructure(out cmdBuf, out senseBuf, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.DVDRAM_SpareAreaInformation, 0, dev.Timeout, out duration);
if (sense)
- DicConsole.ErrorWriteLine("READ DISC STRUCTURE: SAI\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
+ DicConsole.DebugWriteLine("Media-Info command", "READ DISC STRUCTURE: SAI\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
else
{
doWriteFile(outputPrefix, "_readdiscstructure_dvdram_spare.bin", "SCSI READ DISC STRUCTURE", cmdBuf);
@@ -566,7 +674,7 @@ namespace DiscImageChef.Commands
{
sense = dev.ReadDiscStructure(out cmdBuf, out senseBuf, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.LastBorderOutRMD, 0, dev.Timeout, out duration);
if (sense)
- DicConsole.ErrorWriteLine("READ DISC STRUCTURE: Last-Out Border RMD\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
+ DicConsole.DebugWriteLine("Media-Info command", "READ DISC STRUCTURE: Last-Out Border RMD\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
else
doWriteFile(outputPrefix, "_readdiscstructure_dvd_lastrmd.bin", "SCSI READ DISC STRUCTURE", cmdBuf);
}
@@ -577,7 +685,7 @@ namespace DiscImageChef.Commands
{
sense = dev.ReadDiscStructure(out cmdBuf, out senseBuf, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.PreRecordedInfo, 0, dev.Timeout, out duration);
if (sense)
- DicConsole.ErrorWriteLine("READ DISC STRUCTURE: Pre-Recorded Info\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
+ DicConsole.DebugWriteLine("Media-Info command", "READ DISC STRUCTURE: Pre-Recorded Info\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
else
doWriteFile(outputPrefix, "_readdiscstructure_dvd_pri.bin", "SCSI READ DISC STRUCTURE", cmdBuf);
}
@@ -588,12 +696,12 @@ namespace DiscImageChef.Commands
{
sense = dev.ReadDiscStructure(out cmdBuf, out senseBuf, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.DVDR_MediaIdentifier, 0, dev.Timeout, out duration);
if (sense)
- DicConsole.ErrorWriteLine("READ DISC STRUCTURE: DVD-R Media ID\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
+ DicConsole.DebugWriteLine("Media-Info command", "READ DISC STRUCTURE: DVD-R Media ID\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
else
doWriteFile(outputPrefix, "_readdiscstructure_dvdr_mediaid.bin", "SCSI READ DISC STRUCTURE", cmdBuf);
sense = dev.ReadDiscStructure(out cmdBuf, out senseBuf, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.DVDR_PhysicalInformation, 0, dev.Timeout, out duration);
if (sense)
- DicConsole.ErrorWriteLine("READ DISC STRUCTURE: DVD-R PFI\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
+ DicConsole.DebugWriteLine("Media-Info command", "READ DISC STRUCTURE: DVD-R PFI\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
else
doWriteFile(outputPrefix, "_readdiscstructure_dvdr_pfi.bin", "SCSI READ DISC STRUCTURE", cmdBuf);
}
@@ -603,18 +711,15 @@ namespace DiscImageChef.Commands
if (dskType == MediaType.DVDPR || dskType == MediaType.DVDPRDL ||
dskType == MediaType.DVDPRW || dskType == MediaType.DVDPRWDL)
{
- // TODO: None of my test discs return an ADIP. Also, it just seems to contain pre-recorded PFI, and drive is returning it on blank media using standard PFI command
- /*
sense = dev.ReadDiscStructure(out cmdBuf, out senseBuf, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.ADIP, 0, dev.Timeout, out duration);
if(sense)
- DicConsole.ErrorWriteLine("READ DISC STRUCTURE: ADIP\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
+ DicConsole.DebugWriteLine("Media-Info command", "READ DISC STRUCTURE: ADIP\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
else
doWriteFile(outputPrefix, "_readdiscstructure_dvd+_adip.bin", "SCSI READ DISC STRUCTURE", cmdBuf);
- */
sense = dev.ReadDiscStructure(out cmdBuf, out senseBuf, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.DCB, 0, dev.Timeout, out duration);
if (sense)
- DicConsole.ErrorWriteLine("READ DISC STRUCTURE: DCB\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
+ DicConsole.DebugWriteLine("Media-Info command", "READ DISC STRUCTURE: DCB\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
else
doWriteFile(outputPrefix, "_readdiscstructure_dvd+_dcb.bin", "SCSI READ DISC STRUCTURE", cmdBuf);
}
@@ -625,7 +730,7 @@ namespace DiscImageChef.Commands
{
sense = dev.ReadDiscStructure(out cmdBuf, out senseBuf, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.HDDVD_CopyrightInformation, 0, dev.Timeout, out duration);
if (sense)
- DicConsole.ErrorWriteLine("READ DISC STRUCTURE: HDDVD CMI\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
+ DicConsole.DebugWriteLine("Media-Info command", "READ DISC STRUCTURE: HDDVD CMI\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
else
doWriteFile(outputPrefix, "_readdiscstructure_hddvd_cmi.bin", "SCSI READ DISC STRUCTURE", cmdBuf);
}
@@ -636,12 +741,12 @@ namespace DiscImageChef.Commands
{
sense = dev.ReadDiscStructure(out cmdBuf, out senseBuf, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.HDDVDR_MediumStatus, 0, dev.Timeout, out duration);
if (sense)
- DicConsole.ErrorWriteLine("READ DISC STRUCTURE: HDDVD-R Medium Status\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
+ DicConsole.DebugWriteLine("Media-Info command", "READ DISC STRUCTURE: HDDVD-R Medium Status\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
else
doWriteFile(outputPrefix, "_readdiscstructure_hddvdr_status.bin", "SCSI READ DISC STRUCTURE", cmdBuf);
sense = dev.ReadDiscStructure(out cmdBuf, out senseBuf, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.HDDVDR_LastRMD, 0, dev.Timeout, out duration);
if (sense)
- DicConsole.ErrorWriteLine("READ DISC STRUCTURE: Last RMD\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
+ DicConsole.DebugWriteLine("Media-Info command", "READ DISC STRUCTURE: Last RMD\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
else
doWriteFile(outputPrefix, "_readdiscstructure_hddvdr_lastrmd.bin", "SCSI READ DISC STRUCTURE", cmdBuf);
}
@@ -653,7 +758,7 @@ namespace DiscImageChef.Commands
{
sense = dev.ReadDiscStructure(out cmdBuf, out senseBuf, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.DVDR_LayerCapacity, 0, dev.Timeout, out duration);
if (sense)
- DicConsole.ErrorWriteLine("READ DISC STRUCTURE: Layer Capacity\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
+ DicConsole.DebugWriteLine("Media-Info command", "READ DISC STRUCTURE: Layer Capacity\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
else
doWriteFile(outputPrefix, "_readdiscstructure_dvdr_layercap.bin", "SCSI READ DISC STRUCTURE", cmdBuf);
}
@@ -664,22 +769,22 @@ namespace DiscImageChef.Commands
{
sense = dev.ReadDiscStructure(out cmdBuf, out senseBuf, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.MiddleZoneStart, 0, dev.Timeout, out duration);
if (sense)
- DicConsole.ErrorWriteLine("READ DISC STRUCTURE: Middle Zone Start\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
+ DicConsole.DebugWriteLine("Media-Info command", "READ DISC STRUCTURE: Middle Zone Start\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
else
doWriteFile(outputPrefix, "_readdiscstructure_dvd_mzs.bin", "SCSI READ DISC STRUCTURE", cmdBuf);
sense = dev.ReadDiscStructure(out cmdBuf, out senseBuf, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.JumpIntervalSize, 0, dev.Timeout, out duration);
if (sense)
- DicConsole.ErrorWriteLine("READ DISC STRUCTURE: Jump Interval Size\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
+ DicConsole.DebugWriteLine("Media-Info command", "READ DISC STRUCTURE: Jump Interval Size\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
else
doWriteFile(outputPrefix, "_readdiscstructure_dvd_jis.bin", "SCSI READ DISC STRUCTURE", cmdBuf);
sense = dev.ReadDiscStructure(out cmdBuf, out senseBuf, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.ManualLayerJumpStartLBA, 0, dev.Timeout, out duration);
if (sense)
- DicConsole.ErrorWriteLine("READ DISC STRUCTURE: Manual Layer Jump Start LBA\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
+ DicConsole.DebugWriteLine("Media-Info command", "READ DISC STRUCTURE: Manual Layer Jump Start LBA\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
else
doWriteFile(outputPrefix, "_readdiscstructure_dvd_manuallj.bin", "SCSI READ DISC STRUCTURE", cmdBuf);
sense = dev.ReadDiscStructure(out cmdBuf, out senseBuf, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.RemapAnchorPoint, 0, dev.Timeout, out duration);
if (sense)
- DicConsole.ErrorWriteLine("READ DISC STRUCTURE: Remap Anchor Point\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
+ DicConsole.DebugWriteLine("Media-Info command", "READ DISC STRUCTURE: Remap Anchor Point\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
else
doWriteFile(outputPrefix, "_readdiscstructure_dvd_remapanchor.bin", "SCSI READ DISC STRUCTURE", cmdBuf);
}
@@ -691,7 +796,7 @@ namespace DiscImageChef.Commands
{
sense = dev.ReadDiscStructure(out cmdBuf, out senseBuf, MmcDiscStructureMediaType.BD, 0, 0, MmcDiscStructureFormat.DiscInformation, 0, dev.Timeout, out duration);
if (sense)
- DicConsole.ErrorWriteLine("READ DISC STRUCTURE: DI\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
+ DicConsole.DebugWriteLine("Media-Info command", "READ DISC STRUCTURE: DI\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
else
{
doWriteFile(outputPrefix, "_readdiscstructure_bd_di.bin", "SCSI READ DISC STRUCTURE", cmdBuf);
@@ -699,7 +804,7 @@ namespace DiscImageChef.Commands
}
sense = dev.ReadDiscStructure(out cmdBuf, out senseBuf, MmcDiscStructureMediaType.BD, 0, 0, MmcDiscStructureFormat.PAC, 0, dev.Timeout, out duration);
if (sense)
- DicConsole.ErrorWriteLine("READ DISC STRUCTURE: PAC\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
+ DicConsole.DebugWriteLine("Media-Info command", "READ DISC STRUCTURE: PAC\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
else
doWriteFile(outputPrefix, "_readdiscstructure_bd_pac.bin", "SCSI READ DISC STRUCTURE", cmdBuf);
}
@@ -710,7 +815,7 @@ namespace DiscImageChef.Commands
{
sense = dev.ReadDiscStructure(out cmdBuf, out senseBuf, MmcDiscStructureMediaType.BD, 0, 0, MmcDiscStructureFormat.BD_BurstCuttingArea, 0, dev.Timeout, out duration);
if (sense)
- DicConsole.ErrorWriteLine("READ DISC STRUCTURE: BCA\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
+ DicConsole.DebugWriteLine("Media-Info command", "READ DISC STRUCTURE: BCA\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
else
{
doWriteFile(outputPrefix, "_readdiscstructure_bd_bca.bin", "SCSI READ DISC STRUCTURE", cmdBuf);
@@ -725,7 +830,7 @@ namespace DiscImageChef.Commands
{
sense = dev.ReadDiscStructure(out cmdBuf, out senseBuf, MmcDiscStructureMediaType.BD, 0, 0, MmcDiscStructureFormat.BD_DDS, 0, dev.Timeout, out duration);
if (sense)
- DicConsole.ErrorWriteLine("READ DISC STRUCTURE: DDS\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
+ DicConsole.DebugWriteLine("Media-Info command", "READ DISC STRUCTURE: DDS\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
else
{
doWriteFile(outputPrefix, "_readdiscstructure_bd_dds.bin", "SCSI READ DISC STRUCTURE", cmdBuf);
@@ -733,7 +838,7 @@ namespace DiscImageChef.Commands
}
sense = dev.ReadDiscStructure(out cmdBuf, out senseBuf, MmcDiscStructureMediaType.BD, 0, 0, MmcDiscStructureFormat.CartridgeStatus, 0, dev.Timeout, out duration);
if (sense)
- DicConsole.ErrorWriteLine("READ DISC STRUCTURE: Cartridge Status\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
+ DicConsole.DebugWriteLine("Media-Info command", "READ DISC STRUCTURE: Cartridge Status\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
else
{
doWriteFile(outputPrefix, "_readdiscstructure_bd_cartstatus.bin", "SCSI READ DISC STRUCTURE", cmdBuf);
@@ -741,7 +846,7 @@ namespace DiscImageChef.Commands
}
sense = dev.ReadDiscStructure(out cmdBuf, out senseBuf, MmcDiscStructureMediaType.BD, 0, 0, MmcDiscStructureFormat.BD_SpareAreaInformation, 0, dev.Timeout, out duration);
if (sense)
- DicConsole.ErrorWriteLine("READ DISC STRUCTURE: Spare Area Information\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
+ DicConsole.DebugWriteLine("Media-Info command", "READ DISC STRUCTURE: Spare Area Information\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
else
{
doWriteFile(outputPrefix, "_readdiscstructure_bd_spare.bin", "SCSI READ DISC STRUCTURE", cmdBuf);
@@ -749,12 +854,12 @@ namespace DiscImageChef.Commands
}
sense = dev.ReadDiscStructure(out cmdBuf, out senseBuf, MmcDiscStructureMediaType.BD, 0, 0, MmcDiscStructureFormat.RawDFL, 0, dev.Timeout, out duration);
if (sense)
- DicConsole.ErrorWriteLine("READ DISC STRUCTURE: Raw DFL\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
+ DicConsole.DebugWriteLine("Media-Info command", "READ DISC STRUCTURE: Raw DFL\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
else
doWriteFile(outputPrefix, "_readdiscstructure_bd_dfl.bin", "SCSI READ DISC STRUCTURE", cmdBuf);
sense = dev.ReadDiscInformation(out cmdBuf, out senseBuf, MmcDiscInformationDataTypes.TrackResources, dev.Timeout, out duration);
if (sense)
- DicConsole.ErrorWriteLine("READ DISC INFORMATION 001b\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
+ DicConsole.DebugWriteLine("Media-Info command", "READ DISC INFORMATION 001b\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
else
{
DicConsole.WriteLine("Track Resources Information:\n{0}", Decoders.SCSI.MMC.DiscInformation.Prettify(cmdBuf));
@@ -762,7 +867,7 @@ namespace DiscImageChef.Commands
}
sense = dev.ReadDiscInformation(out cmdBuf, out senseBuf, MmcDiscInformationDataTypes.POWResources, dev.Timeout, out duration);
if (sense)
- DicConsole.ErrorWriteLine("READ DISC INFORMATION 010b\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
+ DicConsole.DebugWriteLine("Media-Info command", "READ DISC INFORMATION 010b\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
else
{
DicConsole.WriteLine("POW Resources Information:\n{0}", Decoders.SCSI.MMC.DiscInformation.Prettify(cmdBuf));
@@ -784,7 +889,7 @@ namespace DiscImageChef.Commands
// No TOC, no CD (or an empty one)
bool tocSense = dev.ReadTocPmaAtip(out cmdBuf, out senseBuf, false, 0, 0, dev.Timeout, out duration);
if (tocSense)
- DicConsole.ErrorWriteLine("READ TOC/PMA/ATIP: TOC\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
+ DicConsole.DebugWriteLine("Media-Info command", "READ TOC/PMA/ATIP: TOC\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
else
{
toc = Decoders.CD.TOC.Decode(cmdBuf);
@@ -799,7 +904,7 @@ namespace DiscImageChef.Commands
// ATIP exists on blank CDs
sense = dev.ReadAtip(out cmdBuf, out senseBuf, dev.Timeout, out duration);
if (sense)
- DicConsole.ErrorWriteLine("READ TOC/PMA/ATIP: ATIP\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
+ DicConsole.DebugWriteLine("Media-Info command", "READ TOC/PMA/ATIP: ATIP\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
else
{
doWriteFile(outputPrefix, "_atip.bin", "SCSI READ TOC/PMA/ATIP", cmdBuf);
@@ -817,7 +922,7 @@ namespace DiscImageChef.Commands
{
sense = dev.ReadDiscInformation(out cmdBuf, out senseBuf, MmcDiscInformationDataTypes.DiscInformation, dev.Timeout, out duration);
if (sense)
- DicConsole.ErrorWriteLine("READ DISC INFORMATION 000b\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
+ DicConsole.DebugWriteLine("Media-Info command", "READ DISC INFORMATION 000b\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
else
{
Decoders.SCSI.MMC.DiscInformation.StandardDiscInformation? discInfo = Decoders.SCSI.MMC.DiscInformation.Decode000b(cmdBuf);
@@ -847,7 +952,7 @@ namespace DiscImageChef.Commands
sense = dev.ReadSessionInfo(out cmdBuf, out senseBuf, dev.Timeout, out duration);
if (sense)
- DicConsole.ErrorWriteLine("READ TOC/PMA/ATIP: Session info\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
+ DicConsole.DebugWriteLine("Media-Info command", "READ TOC/PMA/ATIP: Session info\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
else
{
doWriteFile(outputPrefix, "_session.bin", "SCSI READ TOC/PMA/ATIP", cmdBuf);
@@ -904,7 +1009,7 @@ namespace DiscImageChef.Commands
sense = dev.ReadRawToc(out cmdBuf, out senseBuf, 1, dev.Timeout, out duration);
if (sense)
- DicConsole.ErrorWriteLine("READ TOC/PMA/ATIP: Raw TOC\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
+ DicConsole.DebugWriteLine("Media-Info command", "READ TOC/PMA/ATIP: Raw TOC\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
else
{
doWriteFile(outputPrefix, "_rawtoc.bin", "SCSI READ TOC/PMA/ATIP", cmdBuf);
@@ -912,7 +1017,7 @@ namespace DiscImageChef.Commands
}
sense = dev.ReadPma(out cmdBuf, out senseBuf, dev.Timeout, out duration);
if (sense)
- DicConsole.ErrorWriteLine("READ TOC/PMA/ATIP: PMA\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
+ DicConsole.DebugWriteLine("Media-Info command", "READ TOC/PMA/ATIP: PMA\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
else
{
doWriteFile(outputPrefix, "_pma.bin", "SCSI READ TOC/PMA/ATIP", cmdBuf);
@@ -921,7 +1026,7 @@ namespace DiscImageChef.Commands
sense = dev.ReadCdText(out cmdBuf, out senseBuf, dev.Timeout, out duration);
if (sense)
- DicConsole.ErrorWriteLine("READ TOC/PMA/ATIP: CD-TEXT\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
+ DicConsole.DebugWriteLine("Media-Info command", "READ TOC/PMA/ATIP: CD-TEXT\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
else
{
doWriteFile(outputPrefix, "_cdtext.bin", "SCSI READ TOC/PMA/ATIP", cmdBuf);
@@ -937,7 +1042,7 @@ namespace DiscImageChef.Commands
{
sense = dev.ReadDiscStructure(out cmdBuf, out senseBuf, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.PhysicalInformation, 0, dev.Timeout, out duration);
if (sense)
- DicConsole.ErrorWriteLine("READ DISC STRUCTURE: PFI\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
+ DicConsole.DebugWriteLine("Media-Info command", "READ DISC STRUCTURE: PFI\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
else
{
doWriteFile(outputPrefix, "_readdiscstructure_dvd_pfi.bin", "SCSI READ DISC STRUCTURE", cmdBuf);
@@ -957,18 +1062,24 @@ namespace DiscImageChef.Commands
}
sense = dev.ReadDiscStructure(out cmdBuf, out senseBuf, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.DiscManufacturingInformation, 0, dev.Timeout, out duration);
if (sense)
- DicConsole.ErrorWriteLine("READ DISC STRUCTURE: DMI\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
+ DicConsole.DebugWriteLine("Media-Info command", "READ DISC STRUCTURE: DMI\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
else
doWriteFile(outputPrefix, "_readdiscstructure_dvd_dmi.bin", "SCSI READ DISC STRUCTURE", cmdBuf);
}
#endregion Nintendo
}
+ if(dskType == MediaType.Unknown)
+ dskType = MediaTypeFromSCSI.Get((byte)dev.SCSIType, dev.Manufacturer, dev.Model, scsiMediumType, scsiDensityCode, blocks, blockSize);
+
+ if(dskType == MediaType.Unknown && dev.IsUSB && containsFloppyPage)
+ dskType = MediaType.FlashDrive;
+
DicConsole.WriteLine("Media identified as {0}", dskType);
sense = dev.ReadMediaSerialNumber(out cmdBuf, out senseBuf, dev.Timeout, out duration);
if (sense)
- DicConsole.ErrorWriteLine("READ MEDIA SERIAL NUMBER\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
+ DicConsole.DebugWriteLine("Media-Info command", "READ MEDIA SERIAL NUMBER\n{0}", Decoders.SCSI.Sense.PrettifySense(senseBuf));
else
{
doWriteFile(outputPrefix, "_mediaserialnumber.bin", "SCSI READ MEDIA SERIAL NUMBER", cmdBuf);
diff --git a/DiscImageChef/Commands/MediaScan.cs b/DiscImageChef/Commands/MediaScan.cs
index cd5379e1..bec5db13 100644
--- a/DiscImageChef/Commands/MediaScan.cs
+++ b/DiscImageChef/Commands/MediaScan.cs
@@ -41,6 +41,7 @@ using System.IO;
using DiscImageChef.Devices;
using System.Text;
using System.Collections.Generic;
+using System.Globalization;
namespace DiscImageChef.Commands
{
@@ -48,6 +49,22 @@ namespace DiscImageChef.Commands
{
static bool aborted;
static FileStream mhddFs;
+ static FileStream ibgFs;
+ static StringBuilder ibgSb;
+ static DateTime ibgDatePoint;
+ static CultureInfo ibgCulture;
+ static double ibgStartSpeed;
+ static string ibgMediaType;
+ static double ibgDivider;
+ static bool ibgStartSet;
+ static int ibgMinSampleRate;
+ static double ibgMaxSpeed;
+ static double ibgIntSpeed;
+ static int ibgSnaps;
+static ulong ibgIntSector = 0;
+static double ibgIntTime = 0;
+static int ibgSampleRate;
+
public static void doMediaScan(MediaScanSubOptions options)
{
@@ -55,6 +72,7 @@ namespace DiscImageChef.Commands
DicConsole.DebugWriteLine("Media-Scan command", "--verbose={0}", options.Verbose);
DicConsole.DebugWriteLine("Media-Scan command", "--device={0}", options.DevicePath);
DicConsole.DebugWriteLine("Media-Scan command", "--mhdd-log={0}", options.MHDDLogPath);
+ DicConsole.DebugWriteLine("Media-Scan command", "--ibg-log={0}", options.IBGLogPath);
if (options.DevicePath.Length == 2 && options.DevicePath[1] == ':' &&
options.DevicePath[0] != '/' && Char.IsLetter(options.DevicePath[0]))
@@ -63,6 +81,7 @@ namespace DiscImageChef.Commands
}
mhddFs = null;
+ ibgFs = null;
Device dev = new Device(options.DevicePath);
@@ -75,40 +94,40 @@ namespace DiscImageChef.Commands
switch (dev.Type)
{
case DeviceType.ATA:
- doATAMediaScan(options.MHDDLogPath, dev);
+ doATAMediaScan(options.MHDDLogPath, options.IBGLogPath, options.DevicePath, dev);
break;
case DeviceType.MMC:
case DeviceType.SecureDigital:
- doSDMediaScan(options.MHDDLogPath, dev);
+ doSDMediaScan(options.MHDDLogPath, options.IBGLogPath, options.DevicePath, dev);
break;
case DeviceType.NVMe:
- doNVMeMediaScan(options.MHDDLogPath, dev);
+ doNVMeMediaScan(options.MHDDLogPath, options.IBGLogPath, options.DevicePath, dev);
break;
case DeviceType.ATAPI:
case DeviceType.SCSI:
- doSCSIMediaScan(options.MHDDLogPath, dev);
+ doSCSIMediaScan(options.MHDDLogPath, options.IBGLogPath, options.DevicePath, dev);
break;
default:
throw new NotSupportedException("Unknown device type.");
}
}
- static void doATAMediaScan(string MHDDLogPath, Device dev)
+ static void doATAMediaScan(string MHDDLogPath, string IBGLogPath, string devicePath, Device dev)
{
throw new NotImplementedException("ATA devices not yet supported.");
}
- static void doNVMeMediaScan(string MHDDLogPath, Device dev)
+ static void doNVMeMediaScan(string MHDDLogPath, string IBGLogPath, string devicePath, Device dev)
{
throw new NotImplementedException("NVMe devices not yet supported.");
}
- static void doSDMediaScan(string MHDDLogPath, Device dev)
+ static void doSDMediaScan(string MHDDLogPath, string IBGLogPath, string devicePath, Device dev)
{
throw new NotImplementedException("MMC/SD devices not yet supported.");
}
- static void doSCSIMediaScan(string MHDDLogPath, Device dev)
+ static void doSCSIMediaScan(string MHDDLogPath, string IBGLogPath, string devicePath, Device dev)
{
byte[] cmdBuf;
byte[] senseBuf;
@@ -116,6 +135,7 @@ namespace DiscImageChef.Commands
double duration;
ulong blocks = 0;
uint blockSize = 0;
+ ushort currentProfile = 0x0001;
if (dev.IsRemovable)
{
@@ -249,6 +269,8 @@ namespace DiscImageChef.Commands
{
Decoders.SCSI.MMC.Features.SeparatedFeatures ftr = Decoders.SCSI.MMC.Features.Separate(cmdBuf);
+ currentProfile = ftr.CurrentProfile;
+
switch (ftr.CurrentProfile)
{
case 0x0005:
@@ -267,6 +289,7 @@ namespace DiscImageChef.Commands
if (compactDisc)
{
+ currentProfile = 0x0008;
// We discarded all discs that falsify a TOC before requesting a real TOC
// No TOC, no CD (or an empty one)
bool tocSense = dev.ReadRawToc(out cmdBuf, out senseBuf, 1, dev.Timeout, out duration);
@@ -342,6 +365,7 @@ namespace DiscImageChef.Commands
DicConsole.WriteLine("Reading {0} sectors at a time.", blocksToRead);
initMHDDLogFile(MHDDLogPath, dev, blocks, blockSize, blocksToRead);
+ initIBGLogFile(IBGLogPath, currentProfile);
for (ulong i = 0; i < blocks; i += blocksToRead)
{
@@ -395,6 +419,7 @@ namespace DiscImageChef.Commands
}
writeMHDDLogFile(i, cmdDuration);
+ writeIBGLogFile(i, currentSpeed * 1024);
}
else
{
@@ -416,6 +441,8 @@ namespace DiscImageChef.Commands
writeMHDDLogFile(i, 65535);
else
writeMHDDLogFile(i, cmdDuration);
+
+ writeIBGLogFile(i, 0);
}
}
else
@@ -426,6 +453,8 @@ namespace DiscImageChef.Commands
writeMHDDLogFile(i, 65535);
else
writeMHDDLogFile(i, cmdDuration);
+
+ writeIBGLogFile(i, 0);
}
}
@@ -435,6 +464,7 @@ namespace DiscImageChef.Commands
end = DateTime.UtcNow;
DicConsole.WriteLine();
closeMHDDLogFile();
+ closeIBGLogFile(dev, blocks, blockSize, (end - start).TotalSeconds, currentSpeed * 1024, (((double)blockSize * (double)(blocks + 1)) / 1024) / (totalDuration / 1000), devicePath);
}
else
{
@@ -460,7 +490,7 @@ namespace DiscImageChef.Commands
if (!read16 && blocks > ((long)0xFFFFFFFF + (long)1))
{
- DicConsole.ErrorWriteLine("Device only supports SCSI READ (16) but has more than {0} blocks ({1} blocks total)", (long)0xFFFFFFFF + (long)1, blocks);
+ DicConsole.ErrorWriteLine("Device only supports SCSI READ (10) but has more than {0} blocks ({1} blocks total)", (long)0xFFFFFFFF + (long)1, blocks);
return;
}
@@ -515,6 +545,7 @@ namespace DiscImageChef.Commands
DicConsole.WriteLine("Reading {0} sectors at a time.", blocksToRead);
initMHDDLogFile(MHDDLogPath, dev, blocks, blockSize, blocksToRead);
+ initIBGLogFile(IBGLogPath, currentProfile);
for (ulong i = 0; i < blocks; i += blocksToRead)
{
@@ -570,6 +601,7 @@ namespace DiscImageChef.Commands
A += blocksToRead;
writeMHDDLogFile(i, cmdDuration);
+ writeIBGLogFile(i, currentSpeed * 1024);
}
// TODO: Separate errors on kind of errors.
else
@@ -581,6 +613,7 @@ namespace DiscImageChef.Commands
writeMHDDLogFile(i, 65535);
else
writeMHDDLogFile(i, cmdDuration);
+ writeIBGLogFile(i, 0);
}
currentSpeed = ((double)blockSize * blocksToRead / (double)1048576) / (cmdDuration / (double)1000);
@@ -588,6 +621,7 @@ namespace DiscImageChef.Commands
end = DateTime.UtcNow;
DicConsole.WriteLine();
closeMHDDLogFile();
+ closeIBGLogFile(dev, blocks, blockSize, (end - start).TotalSeconds, currentSpeed * 1024, (((double)blockSize * (double)(blocks + 1)) / 1024) / (totalDuration / 1000), devicePath);
}
bool seek6, seek10;
@@ -800,6 +834,245 @@ namespace DiscImageChef.Commands
mhddFs.Write(durationBytes, 0, 8);
}
}
+
+ static void writeIBGLogFile(ulong sector, double currentSpeed)
+ {
+ if (ibgFs != null)
+ {
+ ibgIntSpeed += currentSpeed;
+ ibgSampleRate += (int)Math.Floor((DateTime.Now - ibgDatePoint).TotalMilliseconds);
+ ibgSnaps++;
+
+ if(ibgSampleRate >= 100)
+ {
+ if (ibgIntSpeed > 0 && !ibgStartSet)
+ {
+ ibgStartSpeed = ibgIntSpeed / ibgSnaps / ibgDivider;
+ ibgStartSet = true;
+ }
+
+ ibgSb.AppendFormat("{0:0.00},{1},{2:0},0", ibgIntSpeed / ibgSnaps / ibgDivider, ibgIntSector, ibgSampleRate).AppendLine();
+ if ((ibgIntSpeed / ibgSnaps / ibgDivider) > ibgMaxSpeed)
+ ibgMaxSpeed = ibgIntSpeed / ibgDivider;
+
+ ibgDatePoint = DateTime.Now;
+ ibgIntSpeed = 0;
+ ibgSampleRate = 0;
+ ibgSnaps = 0;
+ ibgIntSector = sector;
+ }
+ }
+ }
+
+ static void initIBGLogFile(string outputFile, ushort currentProfile)
+ {
+ if (!string.IsNullOrEmpty(outputFile))
+ {
+ ibgFs = new FileStream(outputFile, FileMode.Create);
+ ibgSb = new StringBuilder();
+ ibgDatePoint = DateTime.Now;
+ ibgCulture = new CultureInfo("en-US");
+ ibgStartSet = false;
+ ibgMinSampleRate = int.MaxValue;
+ ibgMaxSpeed = 0;
+ ibgIntSpeed = 0;
+ ibgSnaps = 0;
+ ibgIntSector = 0;
+ibgIntTime = 0;
+
+ switch (currentProfile)
+ {
+ case 0x0001:
+ ibgMediaType = "HDD";
+ ibgDivider = 1353;
+ break;
+ case 0x0005:
+ ibgMediaType = "CD-MO";
+ ibgDivider = 150;
+ break;
+ case 0x0008:
+ ibgMediaType = "CD-ROM";
+ ibgDivider = 150;
+ break;
+ case 0x0009:
+ ibgMediaType = "CD-R";
+ ibgDivider = 150;
+ break;
+ case 0x000A:
+ ibgMediaType = "CD-RW";
+ ibgDivider = 150;
+ break;
+ case 0x0010:
+ ibgMediaType = "DVD-ROM";
+ ibgDivider = 1353;
+ break;
+ case 0x0011:
+ ibgMediaType = "DVD-R";
+ ibgDivider = 1353;
+ break;
+ case 0x0012:
+ ibgMediaType = "DVD-RAM";
+ ibgDivider = 1353;
+ break;
+ case 0x0013:
+ case 0x0014:
+ ibgMediaType = "DVD-RW";
+ ibgDivider = 1353;
+ break;
+ case 0x0015:
+ case 0x0016:
+ ibgMediaType = "DVD-R DL";
+ ibgDivider = 1353;
+ break;
+ case 0x0017:
+ ibgMediaType = "DVD-RW DL";
+ ibgDivider = 1353;
+ break;
+ case 0x0018:
+ ibgMediaType = "DVD-Download";
+ ibgDivider = 1353;
+ break;
+ case 0x001A:
+ ibgMediaType = "DVD+RW";
+ ibgDivider = 1353;
+ break;
+ case 0x001B:
+ ibgMediaType = "DVD+R";
+ ibgDivider = 1353;
+ break;
+ case 0x0020:
+ ibgMediaType = "DDCD-ROM";
+ ibgDivider = 150;
+ break;
+ case 0x0021:
+ ibgMediaType = "DDCD-R";
+ ibgDivider = 150;
+ break;
+ case 0x0022:
+ ibgMediaType = "DDCD-RW";
+ ibgDivider = 150;
+ break;
+ case 0x002A:
+ ibgMediaType = "DVD+RW DL";
+ ibgDivider = 1353;
+ break;
+ case 0x002B:
+ ibgMediaType = "DVD+R DL";
+ ibgDivider = 1353;
+ break;
+ case 0x0040:
+ ibgMediaType = "BD-ROM";
+ ibgDivider = 4500;
+ break;
+ case 0x0041:
+ case 0x0042:
+ ibgMediaType = "BD-R";
+ ibgDivider = 4500;
+ break;
+ case 0x0043:
+ ibgMediaType = "BD-RE";
+ ibgDivider = 4500;
+ break;
+ case 0x0050:
+ ibgMediaType = "HD DVD-ROM";
+ ibgDivider = 4500;
+ break;
+ case 0x0051:
+ ibgMediaType = "HD DVD-R";
+ ibgDivider = 4500;
+ break;
+ case 0x0052:
+ ibgMediaType = "HD DVD-RAM";
+ ibgDivider = 4500;
+ break;
+ case 0x0053:
+ ibgMediaType = "HD DVD-RW";
+ ibgDivider = 4500;
+ break;
+ case 0x0058:
+ ibgMediaType = "HD DVD-R DL";
+ ibgDivider = 4500;
+ break;
+ case 0x005A:
+ ibgMediaType = "HD DVD-RW DL";
+ ibgDivider = 4500;
+ break;
+ default:
+ ibgMediaType = "Unknown";
+ ibgDivider = 1353;
+ break;
+ }
+
+ }
+ }
+
+ static void closeIBGLogFile(Device dev, ulong blocks, ulong blockSize, double totalSeconds, double currentSpeed, double averageSpeed, string devicePath)
+ {
+ if (ibgFs != null)
+ {
+ StringBuilder ibgHeader = new StringBuilder();
+ string ibgBusType;
+
+ if (dev.IsUSB)
+ ibgBusType = "USB";
+ else if (dev.IsFireWire)
+ ibgBusType = "FireWire";
+ else
+ ibgBusType = dev.Type.ToString();
+
+ ibgHeader.AppendLine("IBGD");
+ ibgHeader.AppendLine();
+ ibgHeader.AppendLine("[START_CONFIGURATION]");
+ ibgHeader.AppendLine("IBGD_VERSION=2");
+ ibgHeader.AppendLine();
+ ibgHeader.AppendFormat("DATE={0}", DateTime.Now).AppendLine();
+ ibgHeader.AppendLine();
+ ibgHeader.AppendFormat("SAMPLE_RATE={0}", 100).AppendLine();
+
+ ibgHeader.AppendLine();
+ ibgHeader.AppendFormat("DEVICE=[0:0:0] {0} {1} ({2}) ({3})",
+ dev.Manufacturer, dev.Model, devicePath, ibgBusType).AppendLine();
+ ibgHeader.AppendLine("DEVICE_ADDRESS=0:0:0");
+ ibgHeader.AppendFormat("DEVICE_MAKEMODEL={0} {1}", dev.Manufacturer, dev.Model).AppendLine();
+ ibgHeader.AppendFormat("DEVICE_FIRMWAREVERSION={0}", dev.Revision).AppendLine();
+ ibgHeader.AppendFormat("DEVICE_DRIVELETTER={0}", devicePath).AppendLine();
+ ibgHeader.AppendFormat("DEVICE_BUSTYPE={0}", ibgBusType).AppendLine();
+ ibgHeader.AppendLine();
+
+ ibgHeader.AppendFormat("MEDIA_TYPE={0}", ibgMediaType).AppendLine();
+ ibgHeader.AppendLine("MEDIA_BOOKTYPE=Unknown");
+ ibgHeader.AppendLine("MEDIA_ID=N/A");
+ ibgHeader.AppendLine("MEDIA_TRACKPATH=PTP");
+ ibgHeader.AppendLine("MEDIA_SPEEDS=N/A");
+ ibgHeader.AppendFormat("MEDIA_CAPACITY={0}", blocks).AppendLine();
+ ibgHeader.AppendLine("MEDIA_LAYER_BREAK=0");
+ ibgHeader.AppendLine();
+ ibgHeader.AppendLine("DATA_IMAGEFILE=/dev/null");
+ ibgHeader.AppendFormat("DATA_SECTORS={0}", blocks).AppendLine();
+ ibgHeader.AppendFormat("DATA_TYPE=MODE1/{0}", blockSize).AppendLine();
+ ibgHeader.AppendLine("DATA_VOLUMEIDENTIFIER=");
+ ibgHeader.AppendLine();
+ ibgHeader.AppendFormat(ibgCulture, "VERIFY_SPEED_START={0:0.00}", ibgStartSpeed).AppendLine();
+ ibgHeader.AppendFormat(ibgCulture, "VERIFY_SPEED_END={0:0.00}", currentSpeed / ibgDivider).AppendLine();
+ ibgHeader.AppendFormat(ibgCulture, "VERIFY_SPEED_AVERAGE={0:0.00}", averageSpeed / ibgDivider).AppendLine();
+ ibgHeader.AppendFormat(ibgCulture, "VERIFY_SPEED_MAX={0:0.00}", ibgMaxSpeed).AppendLine();
+ ibgHeader.AppendFormat(ibgCulture, "VERIFY_TIME_TAKEN={0:0}", Math.Floor(totalSeconds)).AppendLine();
+ ibgHeader.AppendLine("[END_CONFIGURATION]");
+ ibgHeader.AppendLine();
+ ibgHeader.AppendLine("HRPC=True");
+ ibgHeader.AppendLine();
+ ibgHeader.AppendLine("[START_VERIFY_GRAPH_VALUES]");
+ ibgHeader.Append(ibgSb.ToString());
+ ibgHeader.AppendLine("[END_VERIFY_GRAPH_VALUES]");
+ ibgHeader.AppendLine();
+ ibgHeader.Replace("\r\n", "\n").Replace("\r", "\n").Replace("\n", "\r\n");
+
+ StreamWriter sr = new StreamWriter(ibgFs);
+ sr.Write(ibgHeader.ToString());
+ sr.Close();
+ ibgFs.Close();
+ }
+ }
}
}
diff --git a/DiscImageChef/Core/Checksum.cs b/DiscImageChef/Core/Checksum.cs
new file mode 100644
index 00000000..80928614
--- /dev/null
+++ b/DiscImageChef/Core/Checksum.cs
@@ -0,0 +1,558 @@
+// /***************************************************************************
+// The Disc Image Chef
+// ----------------------------------------------------------------------------
+//
+// Filename : GetChecksum.cs
+// Version : 1.0
+// Author(s) : Natalia Portillo
+//
+// Component : Component
+//
+// Revision : $Revision$
+// Last change by : $Author$
+// Date : $Date$
+//
+// --[ Description ] ----------------------------------------------------------
+//
+// Description
+//
+// --[ License ] --------------------------------------------------------------
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+//
+// ----------------------------------------------------------------------------
+// Copyright (C) 2011-2015 Claunia.com
+// ****************************************************************************/
+// //$Id$
+using System;
+using System.Collections.Generic;
+using DiscImageChef.Checksums;
+using Schemas;
+using System.Threading;
+using System.IO;
+
+namespace DiscImageChef.Core
+{
+ class Checksum
+ {
+ Adler32Context adler32ctx;
+ CRC16Context crc16ctx;
+ CRC32Context crc32ctx;
+ CRC64Context crc64ctx;
+ MD5Context md5ctx;
+ RIPEMD160Context ripemd160ctx;
+ SHA1Context sha1ctx;
+ SHA256Context sha256ctx;
+ SHA384Context sha384ctx;
+ SHA512Context sha512ctx;
+ SpamSumContext ssctx;
+
+ Thread adlerThread;
+ Thread crc16Thread;
+ Thread crc32Thread;
+ Thread crc64Thread;
+ Thread md5Thread;
+ Thread ripemd160Thread;
+ Thread sha1Thread;
+ Thread sha256Thread;
+ Thread sha384Thread;
+ Thread sha512Thread;
+ Thread spamsumThread;
+
+ adlerPacket adlerPkt;
+ crc16Packet crc16Pkt;
+ crc32Packet crc32Pkt;
+ crc64Packet crc64Pkt;
+ md5Packet md5Pkt;
+ ripemd160Packet ripemd160Pkt;
+ sha1Packet sha1Pkt;
+ sha256Packet sha256Pkt;
+ sha384Packet sha384Pkt;
+ sha512Packet sha512Pkt;
+ spamsumPacket spamsumPkt;
+
+ internal Checksum()
+ {
+ adler32ctx = new Adler32Context();
+ crc16ctx = new CRC16Context();
+ crc32ctx = new CRC32Context();
+ crc64ctx = new CRC64Context();
+ md5ctx = new MD5Context();
+ ripemd160ctx = new RIPEMD160Context();
+ sha1ctx = new SHA1Context();
+ sha256ctx = new SHA256Context();
+ sha384ctx = new SHA384Context();
+ sha512ctx = new SHA512Context();
+ ssctx = new SpamSumContext();
+
+ adlerThread = new Thread(updateAdler);
+ crc16Thread = new Thread(updateCRC16);
+ crc32Thread = new Thread(updateCRC32);
+ crc64Thread = new Thread(updateCRC64);
+ md5Thread = new Thread(updateMD5);
+ ripemd160Thread = new Thread(updateRIPEMD160);
+ sha1Thread = new Thread(updateSHA1);
+ sha256Thread = new Thread(updateSHA256);
+ sha384Thread = new Thread(updateSHA384);
+ sha512Thread = new Thread(updateSHA512);
+ spamsumThread = new Thread(updateSpamSum);
+
+ adlerPkt = new adlerPacket();
+ crc16Pkt = new crc16Packet();
+ crc32Pkt = new crc32Packet();
+ crc64Pkt = new crc64Packet();
+ md5Pkt = new md5Packet();
+ ripemd160Pkt = new ripemd160Packet();
+ sha1Pkt = new sha1Packet();
+ sha256Pkt = new sha256Packet();
+ sha384Pkt = new sha384Packet();
+ sha512Pkt = new sha512Packet();
+ spamsumPkt = new spamsumPacket();
+
+ adler32ctx.Init();
+ adlerPkt.context = adler32ctx;
+ crc16ctx.Init();
+ crc16Pkt.context = crc16ctx;
+ crc32ctx.Init();
+ crc32Pkt.context = crc32ctx;
+ crc64ctx.Init();
+ crc64Pkt.context = crc64ctx;
+ md5ctx.Init();
+ md5Pkt.context = md5ctx;
+ ripemd160ctx.Init();
+ ripemd160Pkt.context = ripemd160ctx;
+ sha1ctx.Init();
+ sha1Pkt.context = sha1ctx;
+ sha256ctx.Init();
+ sha256Pkt.context = sha256ctx;
+ sha384ctx.Init();
+ sha384Pkt.context = sha384ctx;
+ sha512ctx.Init();
+ sha512Pkt.context = sha512ctx;
+ ssctx.Init();
+ spamsumPkt.context = ssctx;
+ }
+
+ internal void Update(byte[] data)
+ {
+ adlerPkt.data = data;
+ adlerThread.Start(adlerPkt);
+ crc16Pkt.data = data;
+ crc16Thread.Start(crc16Pkt);
+ crc32Pkt.data = data;
+ crc32Thread.Start(crc32Pkt);
+ crc64Pkt.data = data;
+ crc64Thread.Start(crc64Pkt);
+ md5Pkt.data = data;
+ md5Thread.Start(md5Pkt);
+ ripemd160Pkt.data = data;
+ ripemd160Thread.Start(ripemd160Pkt);
+ sha1Pkt.data = data;
+ sha1Thread.Start(sha1Pkt);
+ sha256Pkt.data = data;
+ sha256Thread.Start(sha256Pkt);
+ sha384Pkt.data = data;
+ sha384Thread.Start(sha384Pkt);
+ sha512Pkt.data = data;
+ sha512Thread.Start(sha512Pkt);
+ spamsumPkt.data = data;
+ spamsumThread.Start(spamsumPkt);
+
+ while (adlerThread.IsAlive || crc16Thread.IsAlive ||
+ crc32Thread.IsAlive || crc64Thread.IsAlive ||
+ md5Thread.IsAlive || ripemd160Thread.IsAlive ||
+ sha1Thread.IsAlive || sha256Thread.IsAlive ||
+ sha384Thread.IsAlive || sha512Thread.IsAlive ||
+ spamsumThread.IsAlive)
+ {
+ }
+
+ adlerThread = new Thread(updateAdler);
+ crc16Thread = new Thread(updateCRC16);
+ crc32Thread = new Thread(updateCRC32);
+ crc64Thread = new Thread(updateCRC64);
+ md5Thread = new Thread(updateMD5);
+ ripemd160Thread = new Thread(updateRIPEMD160);
+ sha1Thread = new Thread(updateSHA1);
+ sha256Thread = new Thread(updateSHA256);
+ sha384Thread = new Thread(updateSHA384);
+ sha512Thread = new Thread(updateSHA512);
+ spamsumThread = new Thread(updateSpamSum);
+ }
+
+ internal List End()
+ {
+ List Checksums = new List();
+
+ ChecksumType chk = new ChecksumType();
+ chk.type = ChecksumTypeType.adler32;
+ chk.Value = adler32ctx.End();
+ Checksums.Add(chk);
+
+ chk = new ChecksumType();
+ chk.type = ChecksumTypeType.crc16;
+ chk.Value = crc16ctx.End();
+ Checksums.Add(chk);
+
+ chk = new ChecksumType();
+ chk.type = ChecksumTypeType.crc32;
+ chk.Value = crc32ctx.End();
+ Checksums.Add(chk);
+
+ chk = new ChecksumType();
+ chk.type = ChecksumTypeType.crc64;
+ chk.Value = crc64ctx.End();
+ Checksums.Add(chk);
+
+ chk = new ChecksumType();
+ chk.type = ChecksumTypeType.md5;
+ chk.Value = md5ctx.End();
+ Checksums.Add(chk);
+
+ chk = new ChecksumType();
+ chk.type = ChecksumTypeType.ripemd160;
+ chk.Value = ripemd160ctx.End();
+ Checksums.Add(chk);
+
+ chk = new ChecksumType();
+ chk.type = ChecksumTypeType.sha1;
+ chk.Value = sha1ctx.End();
+ Checksums.Add(chk);
+
+ chk = new ChecksumType();
+ chk.type = ChecksumTypeType.sha256;
+ chk.Value = sha256ctx.End();
+ Checksums.Add(chk);
+
+ chk = new ChecksumType();
+ chk.type = ChecksumTypeType.sha384;
+ chk.Value = sha384ctx.End();
+ Checksums.Add(chk);
+
+ chk = new ChecksumType();
+ chk.type = ChecksumTypeType.sha512;
+ chk.Value = sha512ctx.End();
+ Checksums.Add(chk);
+
+ chk = new ChecksumType();
+ chk.type = ChecksumTypeType.spamsum;
+ chk.Value = ssctx.End();
+ Checksums.Add(chk);
+
+ return Checksums;
+ }
+
+ internal static List GetChecksums(byte[] data)
+ {
+ Adler32Context adler32ctxData = new Adler32Context();
+ CRC16Context crc16ctxData = new CRC16Context();
+ CRC32Context crc32ctxData = new CRC32Context();
+ CRC64Context crc64ctxData = new CRC64Context();
+ MD5Context md5ctxData = new MD5Context();
+ RIPEMD160Context ripemd160ctxData = new RIPEMD160Context();
+ SHA1Context sha1ctxData = new SHA1Context();
+ SHA256Context sha256ctxData = new SHA256Context();
+ SHA384Context sha384ctxData = new SHA384Context();
+ SHA512Context sha512ctxData = new SHA512Context();
+ SpamSumContext ssctxData = new SpamSumContext();
+
+ Thread adlerThreadData = new Thread(updateAdler);
+ Thread crc16ThreadData = new Thread(updateCRC16);
+ Thread crc32ThreadData = new Thread(updateCRC32);
+ Thread crc64ThreadData = new Thread(updateCRC64);
+ Thread md5ThreadData = new Thread(updateMD5);
+ Thread ripemd160ThreadData = new Thread(updateRIPEMD160);
+ Thread sha1ThreadData = new Thread(updateSHA1);
+ Thread sha256ThreadData = new Thread(updateSHA256);
+ Thread sha384ThreadData = new Thread(updateSHA384);
+ Thread sha512ThreadData = new Thread(updateSHA512);
+ Thread spamsumThreadData = new Thread(updateSpamSum);
+
+ adlerPacket adlerPktData = new adlerPacket();
+ crc16Packet crc16PktData = new crc16Packet();
+ crc32Packet crc32PktData = new crc32Packet();
+ crc64Packet crc64PktData = new crc64Packet();
+ md5Packet md5PktData = new md5Packet();
+ ripemd160Packet ripemd160PktData = new ripemd160Packet();
+ sha1Packet sha1PktData = new sha1Packet();
+ sha256Packet sha256PktData = new sha256Packet();
+ sha384Packet sha384PktData = new sha384Packet();
+ sha512Packet sha512PktData = new sha512Packet();
+ spamsumPacket spamsumPktData = new spamsumPacket();
+
+ adler32ctxData.Init();
+ adlerPktData.context = adler32ctxData;
+ crc16ctxData.Init();
+ crc16PktData.context = crc16ctxData;
+ crc32ctxData.Init();
+ crc32PktData.context = crc32ctxData;
+ crc64ctxData.Init();
+ crc64PktData.context = crc64ctxData;
+ md5ctxData.Init();
+ md5PktData.context = md5ctxData;
+ ripemd160ctxData.Init();
+ ripemd160PktData.context = ripemd160ctxData;
+ sha1ctxData.Init();
+ sha1PktData.context = sha1ctxData;
+ sha256ctxData.Init();
+ sha256PktData.context = sha256ctxData;
+ sha384ctxData.Init();
+ sha384PktData.context = sha384ctxData;
+ sha512ctxData.Init();
+ sha512PktData.context = sha512ctxData;
+ ssctxData.Init();
+ spamsumPktData.context = ssctxData;
+
+ adlerPktData.data = data;
+ adlerThreadData.Start(adlerPktData);
+ crc16PktData.data = data;
+ crc16ThreadData.Start(crc16PktData);
+ crc32PktData.data = data;
+ crc32ThreadData.Start(crc32PktData);
+ crc64PktData.data = data;
+ crc64ThreadData.Start(crc64PktData);
+ md5PktData.data = data;
+ md5ThreadData.Start(md5PktData);
+ ripemd160PktData.data = data;
+ ripemd160ThreadData.Start(ripemd160PktData);
+ sha1PktData.data = data;
+ sha1ThreadData.Start(sha1PktData);
+ sha256PktData.data = data;
+ sha256ThreadData.Start(sha256PktData);
+ sha384PktData.data = data;
+ sha384ThreadData.Start(sha384PktData);
+ sha512PktData.data = data;
+ sha512ThreadData.Start(sha512PktData);
+ spamsumPktData.data = data;
+ spamsumThreadData.Start(spamsumPktData);
+
+ while (adlerThreadData.IsAlive || crc16ThreadData.IsAlive ||
+ crc32ThreadData.IsAlive || crc64ThreadData.IsAlive ||
+ md5ThreadData.IsAlive || ripemd160ThreadData.IsAlive ||
+ sha1ThreadData.IsAlive || sha256ThreadData.IsAlive ||
+ sha384ThreadData.IsAlive || sha512ThreadData.IsAlive ||
+ spamsumThreadData.IsAlive)
+ {
+ }
+
+ List dataChecksums = new List();
+ ChecksumType chk;
+
+ chk = new ChecksumType();
+ chk.type = ChecksumTypeType.adler32;
+ chk.Value = adler32ctxData.End();
+ dataChecksums.Add(chk);
+
+ chk = new ChecksumType();
+ chk.type = ChecksumTypeType.crc16;
+ chk.Value = crc16ctxData.End();
+ dataChecksums.Add(chk);
+
+ chk = new ChecksumType();
+ chk.type = ChecksumTypeType.crc32;
+ chk.Value = crc32ctxData.End();
+ dataChecksums.Add(chk);
+
+ chk = new ChecksumType();
+ chk.type = ChecksumTypeType.crc64;
+ chk.Value = crc64ctxData.End();
+ dataChecksums.Add(chk);
+
+ chk = new ChecksumType();
+ chk.type = ChecksumTypeType.md5;
+ chk.Value = md5ctxData.End();
+ dataChecksums.Add(chk);
+
+ chk = new ChecksumType();
+ chk.type = ChecksumTypeType.ripemd160;
+ chk.Value = ripemd160ctxData.End();
+ dataChecksums.Add(chk);
+
+ chk = new ChecksumType();
+ chk.type = ChecksumTypeType.sha1;
+ chk.Value = sha1ctxData.End();
+ dataChecksums.Add(chk);
+
+ chk = new ChecksumType();
+ chk.type = ChecksumTypeType.sha256;
+ chk.Value = sha256ctxData.End();
+ dataChecksums.Add(chk);
+
+ chk = new ChecksumType();
+ chk.type = ChecksumTypeType.sha384;
+ chk.Value = sha384ctxData.End();
+ dataChecksums.Add(chk);
+
+ chk = new ChecksumType();
+ chk.type = ChecksumTypeType.sha512;
+ chk.Value = sha512ctxData.End();
+ dataChecksums.Add(chk);
+
+ chk = new ChecksumType();
+ chk.type = ChecksumTypeType.spamsum;
+ chk.Value = ssctxData.End();
+ dataChecksums.Add(chk);
+
+ return dataChecksums;
+ }
+
+ #region Threading helpers
+
+ struct adlerPacket
+ {
+ public Adler32Context context;
+ public byte[] data;
+ }
+
+ struct crc16Packet
+ {
+ public CRC16Context context;
+ public byte[] data;
+ }
+
+ struct crc32Packet
+ {
+ public CRC32Context context;
+ public byte[] data;
+ }
+
+ struct crc64Packet
+ {
+ public CRC64Context context;
+ public byte[] data;
+ }
+
+ /*struct fletcher16Packet
+ {
+ public Fletcher16Context context;
+ public byte[] data;
+ }
+
+ struct fletcher32Packet
+ {
+ public Fletcher32Context context;
+ public byte[] data;
+ }*/
+
+ struct md5Packet
+ {
+ public MD5Context context;
+ public byte[] data;
+ }
+
+ struct ripemd160Packet
+ {
+ public RIPEMD160Context context;
+ public byte[] data;
+ }
+
+ struct sha1Packet
+ {
+ public SHA1Context context;
+ public byte[] data;
+ }
+
+ struct sha256Packet
+ {
+ public SHA256Context context;
+ public byte[] data;
+ }
+
+ struct sha384Packet
+ {
+ public SHA384Context context;
+ public byte[] data;
+ }
+
+ struct sha512Packet
+ {
+ public SHA512Context context;
+ public byte[] data;
+ }
+
+ struct spamsumPacket
+ {
+ public SpamSumContext context;
+ public byte[] data;
+ }
+
+ static void updateAdler(object packet)
+ {
+ ((adlerPacket)packet).context.Update(((adlerPacket)packet).data);
+ }
+
+ static void updateCRC16(object packet)
+ {
+ ((crc16Packet)packet).context.Update(((crc16Packet)packet).data);
+ }
+
+ static void updateCRC32(object packet)
+ {
+ ((crc32Packet)packet).context.Update(((crc32Packet)packet).data);
+ }
+
+ static void updateCRC64(object packet)
+ {
+ ((crc64Packet)packet).context.Update(((crc64Packet)packet).data);
+ }
+
+ /*static void updateFletcher16(object packet)
+ {
+ ((fletcher16Packet)packet).context.Update(((fletcher16Packet)packet).data);
+ }
+
+ static void updateFletcher32(object packet)
+ {
+ ((fletcher32Packet)packet).context.Update(((fletcher32Packet)packet).data);
+ }*/
+
+ static void updateMD5(object packet)
+ {
+ ((md5Packet)packet).context.Update(((md5Packet)packet).data);
+ }
+
+ static void updateRIPEMD160(object packet)
+ {
+ ((ripemd160Packet)packet).context.Update(((ripemd160Packet)packet).data);
+ }
+
+ static void updateSHA1(object packet)
+ {
+ ((sha1Packet)packet).context.Update(((sha1Packet)packet).data);
+ }
+
+ static void updateSHA256(object packet)
+ {
+ ((sha256Packet)packet).context.Update(((sha256Packet)packet).data);
+ }
+
+ static void updateSHA384(object packet)
+ {
+ ((sha384Packet)packet).context.Update(((sha384Packet)packet).data);
+ }
+
+ static void updateSHA512(object packet)
+ {
+ ((sha512Packet)packet).context.Update(((sha512Packet)packet).data);
+ }
+
+ static void updateSpamSum(object packet)
+ {
+ ((spamsumPacket)packet).context.Update(((spamsumPacket)packet).data);
+ }
+
+ #endregion Threading helpers
+ }
+}
+
diff --git a/DiscImageChef/DiscImageChef.csproj b/DiscImageChef/DiscImageChef.csproj
index e30ef941..0dc119cf 100644
--- a/DiscImageChef/DiscImageChef.csproj
+++ b/DiscImageChef/DiscImageChef.csproj
@@ -58,10 +58,14 @@
+
+
+
+
diff --git a/DiscImageChef/Main.cs b/DiscImageChef/Main.cs
index 5a0d2c31..f33217f0 100644
--- a/DiscImageChef/Main.cs
+++ b/DiscImageChef/Main.cs
@@ -186,6 +186,22 @@ namespace DiscImageChef
DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
Commands.MediaScan.doMediaScan(MediaScanOptions);
break;
+ case "dump-media":
+ DumpMediaSubOptions DumpMediaOptions = (DumpMediaSubOptions)invokedVerbInstance;
+ if (DumpMediaOptions.Debug)
+ DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
+ if (DumpMediaOptions.Verbose)
+ DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
+ Commands.DumpMedia.doDumpMedia(DumpMediaOptions);
+ break;
+ case "device-report":
+ DeviceReportSubOptions DeviceReportOptions = (DeviceReportSubOptions)invokedVerbInstance;
+ if (DeviceReportOptions.Debug)
+ DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
+ if (DeviceReportOptions.Verbose)
+ DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
+ Commands.DeviceReport.doDeviceReport(DeviceReportOptions);
+ break;
default:
throw new ArgumentException("Should never arrive here!");
}
diff --git a/DiscImageChef/Options.cs b/DiscImageChef/Options.cs
index c6c06834..0afc0eb9 100644
--- a/DiscImageChef/Options.cs
+++ b/DiscImageChef/Options.cs
@@ -239,6 +239,9 @@ namespace DiscImageChef
[Option('m', "mhdd-log", Required = false, DefaultValue = "", HelpText = "Write a log of the scan in the format used by MHDD.")]
public string MHDDLogPath { get; set; }
+
+ [Option('b', "ibg-log", Required = false, DefaultValue = "", HelpText = "Write a log of the scan in the format used by ImgBurn.")]
+ public string IBGLogPath { get; set; }
}
public class FormatsSubOptions : CommonSubOptions
@@ -260,6 +263,38 @@ namespace DiscImageChef
public string InputFile { get; set; }
}
+ // TODO: Add more options
+ public class DumpMediaSubOptions : CommonSubOptions
+ {
+ [Option('i', "device", Required = true, HelpText = "Device path.")]
+ public string DevicePath { get; set; }
+
+ [Option('w', "output-prefix", Required = true, HelpText = "Prefix for media dump.")]
+ public string OutputPrefix { get; set; }
+
+ [Option('r', "raw", DefaultValue = false,
+ HelpText = "Print sectors with tags included.")]
+ public bool Raw { get; set; }
+
+ [Option('s', "stop-on-error", DefaultValue = false,
+ HelpText = "Print sectors with tags included.")]
+ public bool StopOnError { get; set; }
+
+ [Option('f', "force", DefaultValue = false,
+ HelpText = "Continue dump whatever happens.")]
+ public bool Force { get; set; }
+
+ [Option("reset", DefaultValue = (ushort)0,
+ HelpText = "Reset the device after these many errors. 0 to disable.")]
+ public ushort Reset { get; set; }
+ }
+
+ public class DeviceReportSubOptions : CommonSubOptions
+ {
+ [Option('i', "device", Required = true, HelpText = "Device path.")]
+ public string DevicePath { get; set; }
+ }
+
public class Options
{
public Options()
@@ -277,6 +312,8 @@ namespace DiscImageChef
BenchmarkVerb = new BenchmarkSubOptions();
CreateSidecarVerb = new CreateSidecarSubOptions();
MediaScanVerb = new MediaScanSubOptions();
+ DumpMediaVerb = new DumpMediaSubOptions();
+ DeviceReportVerb = new DeviceReportSubOptions();
}
[VerbOption("analyze", HelpText = "Analyzes a disc image and searches for partitions and/or filesystems.")]
@@ -318,6 +355,12 @@ namespace DiscImageChef
[VerbOption("media-scan", HelpText = "Scans the media inserted on a device.")]
public MediaScanSubOptions MediaScanVerb { get; set; }
+ [VerbOption("dump-media", HelpText = "Dumps the media inserted on a device to a media image.")]
+ public DumpMediaSubOptions DumpMediaVerb { get; set; }
+
+ [VerbOption("device-report", HelpText = "Tests the device capabilities and creates an XML report of them.")]
+ public DeviceReportSubOptions DeviceReportVerb { get; set; }
+
[HelpVerbOption]
public string DoHelpForVerb(string verbName)
{