diff --git a/.idea/.idea.DiscImageChef/.idea/contentModel.xml b/.idea/.idea.DiscImageChef/.idea/contentModel.xml index 8ddeb5dbc..796e95896 100644 --- a/.idea/.idea.DiscImageChef/.idea/contentModel.xml +++ b/.idea/.idea.DiscImageChef/.idea/contentModel.xml @@ -254,6 +254,9 @@ + + + diff --git a/DiscImageChef.Core/DiscImageChef.Core.csproj b/DiscImageChef.Core/DiscImageChef.Core.csproj index 4269ad10b..5c9698e9e 100644 --- a/DiscImageChef.Core/DiscImageChef.Core.csproj +++ b/DiscImageChef.Core/DiscImageChef.Core.csproj @@ -51,6 +51,7 @@ + diff --git a/DiscImageChef.Core/Media/Detection/MMC.cs b/DiscImageChef.Core/Media/Detection/MMC.cs new file mode 100644 index 000000000..9ae1387bd --- /dev/null +++ b/DiscImageChef.Core/Media/Detection/MMC.cs @@ -0,0 +1,65 @@ +// /*************************************************************************** +// The Disc Image Chef +// ---------------------------------------------------------------------------- +// +// Filename : MMC.cs +// Author(s) : Natalia Portillo +// +// Component : Core. +// +// --[ Description ] ---------------------------------------------------------- +// +// Detects media types in MultiMediaCommand devices +// +// --[ 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 © 2011-2018 Natalia Portillo +// ****************************************************************************/ + +using System; +using System.Linq; + +namespace DiscImageChef.Core.Media.Detection +{ + public static class MMC + { + /// + /// Checks if the media corresponds to CD-i. + /// + /// Contents of LBA 0, with all headers. + /// Contents of LBA 0, with all headers. + /// true if it corresponds to a CD-i, falseotherwise. + public static bool IsCdi(byte[] sector0, byte[] sector16) + { + if(sector0?.Length != 2352 || sector16?.Length != 2352) return false; + + byte[] syncMark = {0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00}; + byte[] cdiMark = {0x01, 0x43, 0x44, 0x2D}; + byte[] testMark = new byte[12]; + Array.Copy(sector0, 0, testMark, 0, 12); + + bool hiddenData = syncMark.SequenceEqual(testMark) && + (sector0[0xF] == 0 || sector0[0xF] == 1 || sector0[0xF] == 2); + + if(!hiddenData || sector0[0xF] != 2) return false; + + testMark = new byte[4]; + Array.Copy(sector16, 24, testMark, 0, 4); + return cdiMark.SequenceEqual(testMark); + } + } +} \ No newline at end of file diff --git a/DiscImageChef.Core/Media/Info/ScsiInfo.cs b/DiscImageChef.Core/Media/Info/ScsiInfo.cs index 1cf25ac37..bce2c261d 100644 --- a/DiscImageChef.Core/Media/Info/ScsiInfo.cs +++ b/DiscImageChef.Core/Media/Info/ScsiInfo.cs @@ -38,6 +38,7 @@ using System.Threading; using DiscImageChef.Checksums; using DiscImageChef.CommonTypes; using DiscImageChef.Console; +using DiscImageChef.Core.Media.Detection; using DiscImageChef.Decoders.CD; using DiscImageChef.Decoders.DVD; using DiscImageChef.Decoders.SCSI; @@ -1270,6 +1271,30 @@ namespace DiscImageChef.Core.Media.Info } } + // Check for hidden data before start of track 1 + if(DecodedToc.HasValue && + DecodedToc.Value.TrackDescriptors.FirstOrDefault(t => t.TrackNumber == 1).TrackStartAddress > 0) + { + sense = dev.ReadCd(out cmdBuf, out senseBuf, 0, 2352, 1, MmcSectorTypes.AllTypes, false, false, true, + MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.None, MmcSubchannel.None, + dev.Timeout, out _); + + if(!dev.Error && !sense) + { + sector0 = cmdBuf; + + sense = dev.ReadCd(out cmdBuf, out senseBuf, 16, 2352, 1, MmcSectorTypes.AllTypes, false, false, + true, MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.None, + MmcSubchannel.None, dev.Timeout, out _); + + if(!dev.Error && !sense) + if(MMC.IsCdi(sector0, cmdBuf)) + MediaType = MediaType.CDIREADY; + } + } + + sector0 = null; + switch(MediaType) { case MediaType.CD: