mirror of
https://github.com/aaru-dps/Aaru.git
synced 2025-12-16 19:24:25 +00:00
Save metadata in CDRWin cuesheet.
This commit is contained in:
@@ -41,43 +41,31 @@ namespace DiscImageChef.DiscImages
|
|||||||
// TODO: Implement track flags
|
// TODO: Implement track flags
|
||||||
public partial class CdrWin : IWritableOpticalImage, IVerifiableImage
|
public partial class CdrWin : IWritableOpticalImage, IVerifiableImage
|
||||||
{
|
{
|
||||||
IFilter cdrwinFilter;
|
IFilter _cdrwinFilter;
|
||||||
StreamReader cueStream;
|
StreamReader _cueStream;
|
||||||
StreamWriter descriptorStream;
|
StreamWriter _descriptorStream;
|
||||||
CdrWinDisc discimage;
|
CdrWinDisc _discImage;
|
||||||
ImageInfo imageInfo;
|
ImageInfo _imageInfo;
|
||||||
Stream imageStream;
|
Stream _imageStream;
|
||||||
/// <summary>Dictionary, index is track #, value is TrackFile</summary>
|
/// <summary>Dictionary, index is track #, value is TrackFile</summary>
|
||||||
Dictionary<uint, ulong> offsetmap;
|
Dictionary<uint, ulong> _offsetMap;
|
||||||
bool separateTracksWriting;
|
bool _separateTracksWriting;
|
||||||
Dictionary<byte, byte> trackFlags;
|
Dictionary<byte, byte> _trackFlags;
|
||||||
Dictionary<byte, string> trackIsrcs;
|
Dictionary<byte, string> _trackIsrcs;
|
||||||
string writingBaseName;
|
string _writingBaseName;
|
||||||
Dictionary<uint, FileStream> writingStreams;
|
Dictionary<uint, FileStream> _writingStreams;
|
||||||
List<Track> writingTracks;
|
List<Track> _writingTracks;
|
||||||
|
|
||||||
public CdrWin()
|
public CdrWin() => _imageInfo = new ImageInfo
|
||||||
{
|
{
|
||||||
imageInfo = new ImageInfo
|
ReadableSectorTags = new List<SectorTagType>(), ReadableMediaTags = new List<MediaTagType>(),
|
||||||
{
|
HasPartitions = true, HasSessions = true, Version = null,
|
||||||
ReadableSectorTags = new List<SectorTagType>(),
|
ApplicationVersion = null,
|
||||||
ReadableMediaTags = new List<MediaTagType>(),
|
MediaTitle = null, Creator = null, MediaManufacturer = null,
|
||||||
HasPartitions = true,
|
MediaModel = null,
|
||||||
HasSessions = true,
|
MediaPartNumber = null, MediaSequence = 0, LastMediaSequence = 0,
|
||||||
Version = null,
|
DriveManufacturer = null,
|
||||||
ApplicationVersion = null,
|
DriveModel = null, DriveSerialNumber = null, DriveFirmwareRevision = null
|
||||||
MediaTitle = null,
|
};
|
||||||
Creator = null,
|
|
||||||
MediaManufacturer = null,
|
|
||||||
MediaModel = null,
|
|
||||||
MediaPartNumber = null,
|
|
||||||
MediaSequence = 0,
|
|
||||||
LastMediaSequence = 0,
|
|
||||||
DriveManufacturer = null,
|
|
||||||
DriveModel = null,
|
|
||||||
DriveSerialNumber = null,
|
|
||||||
DriveFirmwareRevision = null
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -137,6 +137,7 @@ namespace DiscImageChef.DiscImages
|
|||||||
const string REGEX_SESSION = @"\bREM\s+SESSION\s+(?<number>\d+).*$";
|
const string REGEX_SESSION = @"\bREM\s+SESSION\s+(?<number>\d+).*$";
|
||||||
const string REGEX_MEDIA_TYPE = @"\bREM\s+ORIGINAL MEDIA-TYPE:\s+(?<mediatype>.+)$";
|
const string REGEX_MEDIA_TYPE = @"\bREM\s+ORIGINAL MEDIA-TYPE:\s+(?<mediatype>.+)$";
|
||||||
const string REGEX_LEAD_OUT = @"\bREM\s+LEAD-OUT\s+(?<msf>[\d]+:[\d]+:[\d]+)$";
|
const string REGEX_LEAD_OUT = @"\bREM\s+LEAD-OUT\s+(?<msf>[\d]+:[\d]+:[\d]+)$";
|
||||||
|
|
||||||
// Not checked
|
// Not checked
|
||||||
const string REGEX_LBA = @"\bREM MSF:\s+(?<msf>[\d]+:[\d]+:[\d]+)\s+=\s+LBA:\s+(?<lba>[\d]+)$";
|
const string REGEX_LBA = @"\bREM MSF:\s+(?<msf>[\d]+:[\d]+:[\d]+)\s+=\s+LBA:\s+(?<lba>[\d]+)$";
|
||||||
const string REGEX_DISC_ID = @"\bDISC_ID\s+(?<diskid>[\da-f]{8})$";
|
const string REGEX_DISC_ID = @"\bDISC_ID\s+(?<diskid>[\da-f]{8})$";
|
||||||
@@ -157,6 +158,7 @@ namespace DiscImageChef.DiscImages
|
|||||||
const string REGEX_PREGAP = @"\bPREGAP\s+(?<msf>[\d]+:[\d]+:[\d]+)$";
|
const string REGEX_PREGAP = @"\bPREGAP\s+(?<msf>[\d]+:[\d]+:[\d]+)$";
|
||||||
const string REGEX_POSTGAP = @"\bPOSTGAP\s+(?<msf>[\d]+:[\d]+:[\d]+)$";
|
const string REGEX_POSTGAP = @"\bPOSTGAP\s+(?<msf>[\d]+:[\d]+:[\d]+)$";
|
||||||
const string REGEX_FLAGS = @"\bFLAGS\s+(((?<dcp>DCP)|(?<quad>4CH)|(?<pre>PRE)|(?<scms>SCMS))\s*)+$";
|
const string REGEX_FLAGS = @"\bFLAGS\s+(((?<dcp>DCP)|(?<quad>4CH)|(?<pre>PRE)|(?<scms>SCMS))\s*)+$";
|
||||||
|
|
||||||
// Trurip extensions
|
// Trurip extensions
|
||||||
const string REGEX_APPLICATION = @"\bREM\s+Ripping Tool:\s+(?<application>.+)$";
|
const string REGEX_APPLICATION = @"\bREM\s+Ripping Tool:\s+(?<application>.+)$";
|
||||||
const string REGEX_TRURIP_DISC_HASHES = @"\bREM\s+DISC\s+HASHES$";
|
const string REGEX_TRURIP_DISC_HASHES = @"\bREM\s+DISC\s+HASHES$";
|
||||||
@@ -169,5 +171,9 @@ namespace DiscImageChef.DiscImages
|
|||||||
const string REGEX_TRURIP_TRACK_MD5 = @"\bREM\s+(Gap|Trk)\s+(?<number>\d{2}):\s+[\da-f]{32}$";
|
const string REGEX_TRURIP_TRACK_MD5 = @"\bREM\s+(Gap|Trk)\s+(?<number>\d{2}):\s+[\da-f]{32}$";
|
||||||
const string REGEX_TRURIP_TRACK_SHA1 = @"\bREM\s+(Gap|Trk)\s+(?<number>\d{2}):\s+[\da-f]{40}$";
|
const string REGEX_TRURIP_TRACK_SHA1 = @"\bREM\s+(Gap|Trk)\s+(?<number>\d{2}):\s+[\da-f]{40}$";
|
||||||
const string REGEX_TRURIP_TRACK_UNKNOWN = @"\bREM\s+(Gap|Trk)\s+(?<number>\d{2}):\s+[\da-f]{8,}$";
|
const string REGEX_TRURIP_TRACK_UNKNOWN = @"\bREM\s+(Gap|Trk)\s+(?<number>\d{2}):\s+[\da-f]{8,}$";
|
||||||
|
const string REGEX_DIC_MEDIA_TYPE = @"\bREM\s+METADATA DIC MEDIA-TYPE:\s+(?<mediatype>.+)$";
|
||||||
|
const string REGEX_APPLICATION_VERSION = @"\bREM\s+Ripping Tool Version:\s+(?<application>.+)$";
|
||||||
|
const string REGEX_DUMP_EXTENT =
|
||||||
|
@"\bREM\s+METADATA DUMP EXTENT:\s+(?<application>.+)\s+\|\s+(?<version>.+)\s+\|\s+(?<os>.+)\s+\|\s+(?<manufacturer>.+)\s+\|\s+(?<model>.+)\s+\|\s+(?<firmware>.+)\s+\|\s+(?<serial>.+)\s+\|\s+(?<start>\d+):(?<end>\d+)$";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -38,14 +38,14 @@ namespace DiscImageChef.DiscImages
|
|||||||
{
|
{
|
||||||
public partial class CdrWin
|
public partial class CdrWin
|
||||||
{
|
{
|
||||||
static ulong CdrWinMsftoLba(string msf)
|
static ulong CdrWinMsfToLba(string msf)
|
||||||
{
|
{
|
||||||
string[] msfElements = msf.Split(':');
|
string[] msfElements = msf.Split(':');
|
||||||
ulong minute = ulong.Parse(msfElements[0]);
|
ulong minute = ulong.Parse(msfElements[0]);
|
||||||
ulong second = ulong.Parse(msfElements[1]);
|
ulong second = ulong.Parse(msfElements[1]);
|
||||||
ulong frame = ulong.Parse(msfElements[2]);
|
ulong frame = ulong.Parse(msfElements[2]);
|
||||||
|
|
||||||
ulong sectors = minute * 60 * 75 + second * 75 + frame;
|
ulong sectors = (minute * 60 * 75) + (second * 75) + frame;
|
||||||
|
|
||||||
return sectors;
|
return sectors;
|
||||||
}
|
}
|
||||||
@@ -144,8 +144,8 @@ namespace DiscImageChef.DiscImages
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static (byte minute, byte second, byte frame) LbaToMsf(ulong sector) =>
|
static(byte minute, byte second, byte frame) LbaToMsf(ulong sector) =>
|
||||||
((byte)(sector / 75 / 60), (byte)(sector / 75 % 60), (byte)(sector % 75));
|
((byte)(sector / 75 / 60), (byte)((sector / 75) % 60), (byte)(sector % 75));
|
||||||
|
|
||||||
static string GetTrackMode(Track track)
|
static string GetTrackMode(Track track)
|
||||||
{
|
{
|
||||||
@@ -235,7 +235,7 @@ namespace DiscImageChef.DiscImages
|
|||||||
case MediaType.HDDVDROM: return CDRWIN_DISK_TYPE_HDDVD;
|
case MediaType.HDDVDROM: return CDRWIN_DISK_TYPE_HDDVD;
|
||||||
case MediaType.HDDVDRW: return CDRWIN_DISK_TYPE_HDDVDRW;
|
case MediaType.HDDVDRW: return CDRWIN_DISK_TYPE_HDDVDRW;
|
||||||
case MediaType.HDDVDRWDL: return CDRWIN_DISK_TYPE_HDDVDRWDL;
|
case MediaType.HDDVDRWDL: return CDRWIN_DISK_TYPE_HDDVDRWDL;
|
||||||
default: return "";
|
default: return"";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ namespace DiscImageChef.DiscImages
|
|||||||
// Due to .cue format, this method must parse whole file, ignoring errors (those will be thrown by OpenImage()).
|
// Due to .cue format, this method must parse whole file, ignoring errors (those will be thrown by OpenImage()).
|
||||||
public bool Identify(IFilter imageFilter)
|
public bool Identify(IFilter imageFilter)
|
||||||
{
|
{
|
||||||
cdrwinFilter = imageFilter;
|
_cdrwinFilter = imageFilter;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -51,37 +51,45 @@ namespace DiscImageChef.DiscImages
|
|||||||
byte[] testArray = new byte[512];
|
byte[] testArray = new byte[512];
|
||||||
imageFilter.GetDataForkStream().Read(testArray, 0, 512);
|
imageFilter.GetDataForkStream().Read(testArray, 0, 512);
|
||||||
imageFilter.GetDataForkStream().Seek(0, SeekOrigin.Begin);
|
imageFilter.GetDataForkStream().Seek(0, SeekOrigin.Begin);
|
||||||
|
|
||||||
// Check for unexpected control characters that shouldn't be present in a text file and can crash this plugin
|
// Check for unexpected control characters that shouldn't be present in a text file and can crash this plugin
|
||||||
bool twoConsecutiveNulls = false;
|
bool twoConsecutiveNulls = false;
|
||||||
|
|
||||||
for(int i = 0; i < 512; i++)
|
for(int i = 0; i < 512; i++)
|
||||||
{
|
{
|
||||||
if(i >= imageFilter.GetDataForkStream().Length) break;
|
if(i >= imageFilter.GetDataForkStream().Length)
|
||||||
|
break;
|
||||||
|
|
||||||
if(testArray[i] == 0)
|
if(testArray[i] == 0)
|
||||||
{
|
{
|
||||||
if(twoConsecutiveNulls) return false;
|
if(twoConsecutiveNulls)
|
||||||
|
return false;
|
||||||
|
|
||||||
twoConsecutiveNulls = true;
|
twoConsecutiveNulls = true;
|
||||||
}
|
}
|
||||||
else twoConsecutiveNulls = false;
|
else
|
||||||
|
twoConsecutiveNulls = false;
|
||||||
|
|
||||||
if(testArray[i] < 0x20 && testArray[i] != 0x0A && testArray[i] != 0x0D && testArray[i] != 0x00)
|
if(testArray[i] < 0x20 &&
|
||||||
|
testArray[i] != 0x0A &&
|
||||||
|
testArray[i] != 0x0D &&
|
||||||
|
testArray[i] != 0x00)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
cueStream = new StreamReader(cdrwinFilter.GetDataForkStream());
|
_cueStream = new StreamReader(_cdrwinFilter.GetDataForkStream());
|
||||||
|
|
||||||
while(cueStream.Peek() >= 0)
|
while(_cueStream.Peek() >= 0)
|
||||||
{
|
{
|
||||||
string line = cueStream.ReadLine();
|
string line = _cueStream.ReadLine();
|
||||||
|
|
||||||
Regex sr = new Regex(REGEX_SESSION);
|
var sr = new Regex(REGEX_SESSION);
|
||||||
Regex rr = new Regex(REGEX_COMMENT);
|
var rr = new Regex(REGEX_COMMENT);
|
||||||
Regex cr = new Regex(REGEX_MCN);
|
var cr = new Regex(REGEX_MCN);
|
||||||
Regex fr = new Regex(REGEX_FILE);
|
var fr = new Regex(REGEX_FILE);
|
||||||
Regex tr = new Regex(REGEX_CDTEXT);
|
var tr = new Regex(REGEX_CDTEXT);
|
||||||
|
|
||||||
// First line must be SESSION, REM, CATALOG, FILE or CDTEXTFILE.
|
// First line must be SESSION, REM, CATALOG, FILE or CDTEXTFILE.
|
||||||
Match sm = sr.Match(line ?? throw new InvalidOperationException());
|
Match sm = sr.Match(line ?? throw new InvalidOperationException());
|
||||||
Match rm = rr.Match(line);
|
Match rm = rr.Match(line);
|
||||||
Match cm = cr.Match(line);
|
Match cm = cr.Match(line);
|
||||||
@@ -95,9 +103,10 @@ namespace DiscImageChef.DiscImages
|
|||||||
}
|
}
|
||||||
catch(Exception ex)
|
catch(Exception ex)
|
||||||
{
|
{
|
||||||
DicConsole.ErrorWriteLine("Exception trying to identify image file {0}", cdrwinFilter);
|
DicConsole.ErrorWriteLine("Exception trying to identify image file {0}", _cdrwinFilter);
|
||||||
DicConsole.ErrorWriteLine("Exception: {0}", ex.Message);
|
DicConsole.ErrorWriteLine("Exception: {0}", ex.Message);
|
||||||
DicConsole.ErrorWriteLine("Stack trace: {0}", ex.StackTrace);
|
DicConsole.ErrorWriteLine("Stack trace: {0}", ex.StackTrace);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,12 +41,13 @@ namespace DiscImageChef.DiscImages
|
|||||||
{
|
{
|
||||||
public partial class CdrWin
|
public partial class CdrWin
|
||||||
{
|
{
|
||||||
public ImageInfo Info => imageInfo;
|
public ImageInfo Info => _imageInfo;
|
||||||
public string Name => "CDRWin cuesheet";
|
public string Name => "CDRWin cuesheet";
|
||||||
public Guid Id => new Guid("664568B2-15D4-4E64-8A7A-20BDA8B8386F");
|
public Guid Id => new Guid("664568B2-15D4-4E64-8A7A-20BDA8B8386F");
|
||||||
public string Format => "CDRWin CUESheet";
|
public string Format => "CDRWin CUESheet";
|
||||||
public string Author => "Natalia Portillo";
|
public string Author => "Natalia Portillo";
|
||||||
public List<Partition> Partitions { get; private set; }
|
public List<Partition> Partitions { get; private set; }
|
||||||
|
|
||||||
public List<Track> Tracks
|
public List<Track> Tracks
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
@@ -55,36 +56,34 @@ namespace DiscImageChef.DiscImages
|
|||||||
|
|
||||||
ulong previousStartSector = 0;
|
ulong previousStartSector = 0;
|
||||||
|
|
||||||
foreach(CdrWinTrack cdrTrack in discimage.Tracks)
|
foreach(CdrWinTrack cdrTrack in _discImage.Tracks)
|
||||||
{
|
{
|
||||||
Track dicTrack = new Track
|
var dicTrack = new Track
|
||||||
{
|
{
|
||||||
Indexes = cdrTrack.Indexes,
|
Indexes = cdrTrack.Indexes, TrackDescription = cdrTrack.Title,
|
||||||
TrackDescription = cdrTrack.Title,
|
TrackStartSector = previousStartSector, TrackPregap = cdrTrack.Pregap,
|
||||||
TrackStartSector = previousStartSector,
|
TrackSession = cdrTrack.Session, TrackSequence = cdrTrack.Sequence,
|
||||||
TrackPregap = cdrTrack.Pregap,
|
TrackType = CdrWinTrackTypeToTrackType(cdrTrack.TrackType),
|
||||||
TrackSession = cdrTrack.Session,
|
TrackFile = cdrTrack.TrackFile.DataFilter.GetFilename(),
|
||||||
TrackSequence = cdrTrack.Sequence,
|
TrackFilter = cdrTrack.TrackFile.DataFilter,
|
||||||
TrackType = CdrWinTrackTypeToTrackType(cdrTrack.Tracktype),
|
TrackFileOffset = cdrTrack.TrackFile.Offset,
|
||||||
TrackFile = cdrTrack.Trackfile.Datafilter.GetFilename(),
|
TrackFileType = cdrTrack.TrackFile.FileType, TrackRawBytesPerSector = cdrTrack.Bps,
|
||||||
TrackFilter = cdrTrack.Trackfile.Datafilter,
|
TrackBytesPerSector = CdrWinTrackTypeToCookedBytesPerSector(cdrTrack.TrackType)
|
||||||
TrackFileOffset = cdrTrack.Trackfile.Offset,
|
|
||||||
TrackFileType = cdrTrack.Trackfile.Filetype,
|
|
||||||
TrackRawBytesPerSector = cdrTrack.Bps,
|
|
||||||
TrackBytesPerSector = CdrWinTrackTypeToCookedBytesPerSector(cdrTrack.Tracktype)
|
|
||||||
};
|
};
|
||||||
dicTrack.TrackEndSector = dicTrack.TrackStartSector + cdrTrack.Sectors - 1;
|
|
||||||
|
dicTrack.TrackEndSector = (dicTrack.TrackStartSector + cdrTrack.Sectors) - 1;
|
||||||
|
|
||||||
/*if(!cdrTrack.Indexes.TryGetValue(0, out dicTrack.TrackStartSector))
|
/*if(!cdrTrack.Indexes.TryGetValue(0, out dicTrack.TrackStartSector))
|
||||||
cdrTrack.Indexes.TryGetValue(1, out dicTrack.TrackStartSector);*/
|
cdrTrack.Indexes.TryGetValue(1, out dicTrack.TrackStartSector);*/
|
||||||
if(cdrTrack.Tracktype == CDRWIN_TRACK_TYPE_CDG)
|
if(cdrTrack.TrackType == CDRWIN_TRACK_TYPE_CDG)
|
||||||
{
|
{
|
||||||
dicTrack.TrackSubchannelFilter = cdrTrack.Trackfile.Datafilter;
|
dicTrack.TrackSubchannelFilter = cdrTrack.TrackFile.DataFilter;
|
||||||
dicTrack.TrackSubchannelFile = cdrTrack.Trackfile.Datafilter.GetFilename();
|
dicTrack.TrackSubchannelFile = cdrTrack.TrackFile.DataFilter.GetFilename();
|
||||||
dicTrack.TrackSubchannelOffset = cdrTrack.Trackfile.Offset;
|
dicTrack.TrackSubchannelOffset = cdrTrack.TrackFile.Offset;
|
||||||
dicTrack.TrackSubchannelType = TrackSubchannelType.RawInterleaved;
|
dicTrack.TrackSubchannelType = TrackSubchannelType.RawInterleaved;
|
||||||
}
|
}
|
||||||
else dicTrack.TrackSubchannelType = TrackSubchannelType.None;
|
else
|
||||||
|
dicTrack.TrackSubchannelType = TrackSubchannelType.None;
|
||||||
|
|
||||||
tracks.Add(dicTrack);
|
tracks.Add(dicTrack);
|
||||||
previousStartSector = dicTrack.TrackEndSector + 1;
|
previousStartSector = dicTrack.TrackEndSector + 1;
|
||||||
@@ -93,40 +92,46 @@ namespace DiscImageChef.DiscImages
|
|||||||
return tracks;
|
return tracks;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public List<Session> Sessions => discimage.Sessions;
|
|
||||||
public List<DumpHardwareType> DumpHardware => null;
|
public List<Session> Sessions => _discImage.Sessions;
|
||||||
public CICMMetadataType CicmMetadata => null;
|
public List<DumpHardwareType> DumpHardware { get; private set; }
|
||||||
public IEnumerable<MediaTagType> SupportedMediaTags => new[] {MediaTagType.CD_MCN, MediaTagType.CD_TEXT};
|
public CICMMetadataType CicmMetadata => null;
|
||||||
public IEnumerable<SectorTagType> SupportedSectorTags =>
|
public IEnumerable<MediaTagType> SupportedMediaTags => new[]
|
||||||
new[]
|
{
|
||||||
{
|
MediaTagType.CD_MCN, MediaTagType.CD_TEXT
|
||||||
SectorTagType.CdSectorEcc, SectorTagType.CdSectorEccP, SectorTagType.CdSectorEccQ,
|
};
|
||||||
SectorTagType.CdSectorEdc, SectorTagType.CdSectorHeader, SectorTagType.CdSectorSubHeader,
|
public IEnumerable<SectorTagType> SupportedSectorTags => new[]
|
||||||
SectorTagType.CdSectorSync, SectorTagType.CdTrackFlags, SectorTagType.CdTrackIsrc
|
{
|
||||||
};
|
SectorTagType.CdSectorEcc, SectorTagType.CdSectorEccP, SectorTagType.CdSectorEccQ,
|
||||||
public IEnumerable<MediaType> SupportedMediaTypes =>
|
SectorTagType.CdSectorEdc, SectorTagType.CdSectorHeader, SectorTagType.CdSectorSubHeader,
|
||||||
new[]
|
SectorTagType.CdSectorSync, SectorTagType.CdTrackFlags, SectorTagType.CdTrackIsrc
|
||||||
{
|
};
|
||||||
MediaType.BDR, MediaType.BDRE, MediaType.BDREXL, MediaType.BDROM, MediaType.BDRXL, MediaType.CBHD,
|
public IEnumerable<MediaType> SupportedMediaTypes => new[]
|
||||||
MediaType.CD, MediaType.CDDA, MediaType.CDEG, MediaType.CDG, MediaType.CDI, MediaType.CDMIDI,
|
{
|
||||||
MediaType.CDMRW, MediaType.CDPLUS, MediaType.CDR, MediaType.CDROM, MediaType.CDROMXA,
|
MediaType.BDR, MediaType.BDRE, MediaType.BDREXL, MediaType.BDROM, MediaType.BDRXL, MediaType.CBHD,
|
||||||
MediaType.CDRW, MediaType.CDV, MediaType.DDCD, MediaType.DDCDR, MediaType.DDCDRW,
|
MediaType.CD, MediaType.CDDA, MediaType.CDEG, MediaType.CDG, MediaType.CDI, MediaType.CDMIDI,
|
||||||
MediaType.DVDDownload, MediaType.DVDPR, MediaType.DVDPRDL, MediaType.DVDPRW, MediaType.DVDPRWDL,
|
MediaType.CDMRW, MediaType.CDPLUS, MediaType.CDR, MediaType.CDROM, MediaType.CDROMXA, MediaType.CDRW,
|
||||||
MediaType.DVDR, MediaType.DVDRAM, MediaType.DVDRDL, MediaType.DVDROM, MediaType.DVDRW,
|
MediaType.CDV, MediaType.DDCD, MediaType.DDCDR, MediaType.DDCDRW, MediaType.DVDDownload, MediaType.DVDPR,
|
||||||
MediaType.DVDRWDL, MediaType.EVD, MediaType.FDDVD, MediaType.DTSCD, MediaType.FVD, MediaType.HDDVDR,
|
MediaType.DVDPRDL, MediaType.DVDPRW, MediaType.DVDPRWDL, MediaType.DVDR, MediaType.DVDRAM, MediaType.DVDRDL,
|
||||||
MediaType.HDDVDRAM, MediaType.HDDVDRDL, MediaType.HDDVDROM, MediaType.HDDVDRW, MediaType.HDDVDRWDL,
|
MediaType.DVDROM, MediaType.DVDRW, MediaType.DVDRWDL, MediaType.EVD, MediaType.FDDVD, MediaType.DTSCD,
|
||||||
MediaType.HDVMD, MediaType.HVD, MediaType.JaguarCD, MediaType.MEGACD, MediaType.PS1CD,
|
MediaType.FVD, MediaType.HDDVDR, MediaType.HDDVDRAM, MediaType.HDDVDRDL, MediaType.HDDVDROM,
|
||||||
MediaType.PS2CD, MediaType.PS2DVD, MediaType.PS3BD, MediaType.PS3DVD, MediaType.PS4BD,
|
MediaType.HDDVDRW, MediaType.HDDVDRWDL, MediaType.HDVMD, MediaType.HVD, MediaType.JaguarCD,
|
||||||
MediaType.SuperCDROM2, MediaType.SVCD, MediaType.SVOD, MediaType.SATURNCD, MediaType.ThreeDO,
|
MediaType.MEGACD, MediaType.PS1CD, MediaType.PS2CD, MediaType.PS2DVD, MediaType.PS3BD, MediaType.PS3DVD,
|
||||||
MediaType.UDO, MediaType.UDO2, MediaType.UDO2_WORM, MediaType.UMD, MediaType.VCD, MediaType.VCDHD,
|
MediaType.PS4BD, MediaType.SuperCDROM2, MediaType.SVCD, MediaType.SVOD, MediaType.SATURNCD,
|
||||||
MediaType.NeoGeoCD, MediaType.PCFX, MediaType.CDTV, MediaType.CD32, MediaType.Nuon,
|
MediaType.ThreeDO, MediaType.UDO, MediaType.UDO2, MediaType.UDO2_WORM, MediaType.UMD, MediaType.VCD,
|
||||||
MediaType.Playdia, MediaType.Pippin, MediaType.FMTOWNS, MediaType.MilCD, MediaType.VideoNow,
|
MediaType.VCDHD, MediaType.NeoGeoCD, MediaType.PCFX, MediaType.CDTV, MediaType.CD32, MediaType.Nuon,
|
||||||
MediaType.VideoNowColor, MediaType.VideoNowXp
|
MediaType.Playdia, MediaType.Pippin, MediaType.FMTOWNS, MediaType.MilCD, MediaType.VideoNow,
|
||||||
};
|
MediaType.VideoNowColor, MediaType.VideoNowXp
|
||||||
public IEnumerable<(string name, Type type, string description, object @default)> SupportedOptions =>
|
};
|
||||||
new[] {("separate", typeof(bool), "Write each track to a separate file.", (object)false)};
|
public IEnumerable<(string name, Type type, string description, object @default)> SupportedOptions => new[]
|
||||||
public IEnumerable<string> KnownExtensions => new[] {".cue"};
|
{
|
||||||
public bool IsWriting { get; private set; }
|
("separate", typeof(bool), "Write each track to a separate file.", (object)false)
|
||||||
public string ErrorMessage { get; private set; }
|
};
|
||||||
|
public IEnumerable<string> KnownExtensions => new[]
|
||||||
|
{
|
||||||
|
".cue"
|
||||||
|
};
|
||||||
|
public bool IsWriting { get; private set; }
|
||||||
|
public string ErrorMessage { get; private set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -44,11 +44,11 @@ namespace DiscImageChef.DiscImages
|
|||||||
/// <summary>Track #</summary>
|
/// <summary>Track #</summary>
|
||||||
public uint Sequence;
|
public uint Sequence;
|
||||||
/// <summary>Filter of file containing track</summary>
|
/// <summary>Filter of file containing track</summary>
|
||||||
public IFilter Datafilter;
|
public IFilter DataFilter;
|
||||||
/// <summary>Offset of track start in file</summary>
|
/// <summary>Offset of track start in file</summary>
|
||||||
public ulong Offset;
|
public ulong Offset;
|
||||||
/// <summary>Type of file</summary>
|
/// <summary>Type of file</summary>
|
||||||
public string Filetype;
|
public string FileType;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct CdrWinTrack
|
struct CdrWinTrack
|
||||||
@@ -70,18 +70,18 @@ namespace DiscImageChef.DiscImages
|
|||||||
/// <summary>Track ISRC</summary>
|
/// <summary>Track ISRC</summary>
|
||||||
public string Isrc;
|
public string Isrc;
|
||||||
/// <summary>File struct for this track</summary>
|
/// <summary>File struct for this track</summary>
|
||||||
public CdrWinTrackFile Trackfile;
|
public CdrWinTrackFile TrackFile;
|
||||||
/// <summary>Indexes on this track</summary>
|
/// <summary>Indexes on this track</summary>
|
||||||
public Dictionary<int, ulong> Indexes;
|
public Dictionary<int, ulong> Indexes;
|
||||||
/// <summary>Track pre-gap in sectors</summary>
|
/// <summary>Track pre-gap in sectors</summary>
|
||||||
public ulong Pregap;
|
public ulong Pregap;
|
||||||
/// <summary>Track post-gap in sectors</summary>
|
/// <summary>Track post-gap in sectors</summary>
|
||||||
public ulong Postgap;
|
public ulong Postgap;
|
||||||
/// <summary>Digical Copy Permitted</summary>
|
/// <summary>Digital Copy Permitted</summary>
|
||||||
public bool FlagDcp;
|
public bool FlagDcp;
|
||||||
/// <summary>Track is quadraphonic</summary>
|
/// <summary>Track is quadraphonic</summary>
|
||||||
public bool Flag4ch;
|
public bool Flag4ch;
|
||||||
/// <summary>Track has preemphasis</summary>
|
/// <summary>Track has pre-emphasis</summary>
|
||||||
public bool FlagPre;
|
public bool FlagPre;
|
||||||
/// <summary>Track has SCMS</summary>
|
/// <summary>Track has SCMS</summary>
|
||||||
public bool FlagScms;
|
public bool FlagScms;
|
||||||
@@ -90,7 +90,7 @@ namespace DiscImageChef.DiscImages
|
|||||||
/// <summary>Sectors in track</summary>
|
/// <summary>Sectors in track</summary>
|
||||||
public ulong Sectors;
|
public ulong Sectors;
|
||||||
/// <summary>Track type</summary>
|
/// <summary>Track type</summary>
|
||||||
public string Tracktype;
|
public string TrackType;
|
||||||
/// <summary>Track session</summary>
|
/// <summary>Track session</summary>
|
||||||
public ushort Session;
|
public ushort Session;
|
||||||
}
|
}
|
||||||
@@ -112,11 +112,11 @@ namespace DiscImageChef.DiscImages
|
|||||||
/// <summary>Media catalog number</summary>
|
/// <summary>Media catalog number</summary>
|
||||||
public string Mcn;
|
public string Mcn;
|
||||||
/// <summary>Disk type</summary>
|
/// <summary>Disk type</summary>
|
||||||
public MediaType Disktype;
|
public MediaType MediaType;
|
||||||
/// <summary>Disk type string</summary>
|
/// <summary>Disk type string</summary>
|
||||||
public string Disktypestr;
|
public string OriginalMediaType;
|
||||||
/// <summary>Disk CDDB ID</summary>
|
/// <summary>Disk CDDB ID</summary>
|
||||||
public string DiskId;
|
public string DiscId;
|
||||||
/// <summary>Disk UPC/EAN</summary>
|
/// <summary>Disk UPC/EAN</summary>
|
||||||
public string Barcode;
|
public string Barcode;
|
||||||
/// <summary>Sessions</summary>
|
/// <summary>Sessions</summary>
|
||||||
@@ -126,11 +126,13 @@ namespace DiscImageChef.DiscImages
|
|||||||
/// <summary>Disk comment</summary>
|
/// <summary>Disk comment</summary>
|
||||||
public string Comment;
|
public string Comment;
|
||||||
/// <summary>File containing CD-Text</summary>
|
/// <summary>File containing CD-Text</summary>
|
||||||
public string Cdtextfile;
|
public string CdTextFile;
|
||||||
/// <summary>Has trurip extensions</summary>
|
/// <summary>Has trurip extensions</summary>
|
||||||
public bool IsTrurip;
|
public bool IsTrurip;
|
||||||
/// <summary>Disc image hashes</summary>
|
/// <summary>Disc image hashes</summary>
|
||||||
public Dictionary<string, string> DiscHashes;
|
public Dictionary<string, string> DiscHashes;
|
||||||
|
/// <summary>DIC media type</summary>
|
||||||
|
public string DicMediaType;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -44,27 +44,28 @@ namespace DiscImageChef.DiscImages
|
|||||||
{
|
{
|
||||||
public bool? VerifyMediaImage()
|
public bool? VerifyMediaImage()
|
||||||
{
|
{
|
||||||
if(discimage.DiscHashes.Count == 0) return null;
|
if(_discImage.DiscHashes.Count == 0)
|
||||||
|
return null;
|
||||||
|
|
||||||
// Read up to 1MiB at a time for verification
|
// Read up to 1 MiB at a time for verification
|
||||||
const int VERIFY_SIZE = 1024 * 1024;
|
const int verifySize = 1024 * 1024;
|
||||||
long readBytes;
|
long readBytes;
|
||||||
byte[] verifyBytes;
|
byte[] verifyBytes;
|
||||||
|
|
||||||
IFilter[] filters = discimage.Tracks.OrderBy(t => t.Sequence).Select(t => t.Trackfile.Datafilter).Distinct()
|
IFilter[] filters = _discImage.Tracks.OrderBy(t => t.Sequence).Select(t => t.TrackFile.DataFilter).
|
||||||
.ToArray();
|
Distinct().ToArray();
|
||||||
|
|
||||||
if(discimage.DiscHashes.TryGetValue("sha1", out string sha1))
|
if(_discImage.DiscHashes.TryGetValue("sha1", out string sha1))
|
||||||
{
|
{
|
||||||
Sha1Context ctx = new Sha1Context();
|
var ctx = new Sha1Context();
|
||||||
|
|
||||||
foreach(IFilter filter in filters)
|
foreach(IFilter filter in filters)
|
||||||
{
|
{
|
||||||
Stream stream = filter.GetDataForkStream();
|
Stream stream = filter.GetDataForkStream();
|
||||||
readBytes = 0;
|
readBytes = 0;
|
||||||
verifyBytes = new byte[VERIFY_SIZE];
|
verifyBytes = new byte[verifySize];
|
||||||
|
|
||||||
while(readBytes + VERIFY_SIZE < stream.Length)
|
while(readBytes + verifySize < stream.Length)
|
||||||
{
|
{
|
||||||
stream.Read(verifyBytes, 0, verifyBytes.Length);
|
stream.Read(verifyBytes, 0, verifyBytes.Length);
|
||||||
ctx.Update(verifyBytes);
|
ctx.Update(verifyBytes);
|
||||||
@@ -78,22 +79,22 @@ namespace DiscImageChef.DiscImages
|
|||||||
|
|
||||||
string verifySha1 = ctx.End();
|
string verifySha1 = ctx.End();
|
||||||
DicConsole.DebugWriteLine("CDRWin plugin", "Calculated SHA1: {0}", verifySha1);
|
DicConsole.DebugWriteLine("CDRWin plugin", "Calculated SHA1: {0}", verifySha1);
|
||||||
DicConsole.DebugWriteLine("CDRWin plugin", "Expected SHA1: {0}", sha1);
|
DicConsole.DebugWriteLine("CDRWin plugin", "Expected SHA1: {0}", sha1);
|
||||||
|
|
||||||
return verifySha1 == sha1;
|
return verifySha1 == sha1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(discimage.DiscHashes.TryGetValue("md5", out string md5))
|
if(_discImage.DiscHashes.TryGetValue("md5", out string md5))
|
||||||
{
|
{
|
||||||
Md5Context ctx = new Md5Context();
|
var ctx = new Md5Context();
|
||||||
|
|
||||||
foreach(IFilter filter in filters)
|
foreach(IFilter filter in filters)
|
||||||
{
|
{
|
||||||
Stream stream = filter.GetDataForkStream();
|
Stream stream = filter.GetDataForkStream();
|
||||||
readBytes = 0;
|
readBytes = 0;
|
||||||
verifyBytes = new byte[VERIFY_SIZE];
|
verifyBytes = new byte[verifySize];
|
||||||
|
|
||||||
while(readBytes + VERIFY_SIZE < stream.Length)
|
while(readBytes + verifySize < stream.Length)
|
||||||
{
|
{
|
||||||
stream.Read(verifyBytes, 0, verifyBytes.Length);
|
stream.Read(verifyBytes, 0, verifyBytes.Length);
|
||||||
ctx.Update(verifyBytes);
|
ctx.Update(verifyBytes);
|
||||||
@@ -107,22 +108,22 @@ namespace DiscImageChef.DiscImages
|
|||||||
|
|
||||||
string verifyMd5 = ctx.End();
|
string verifyMd5 = ctx.End();
|
||||||
DicConsole.DebugWriteLine("CDRWin plugin", "Calculated MD5: {0}", verifyMd5);
|
DicConsole.DebugWriteLine("CDRWin plugin", "Calculated MD5: {0}", verifyMd5);
|
||||||
DicConsole.DebugWriteLine("CDRWin plugin", "Expected MD5: {0}", md5);
|
DicConsole.DebugWriteLine("CDRWin plugin", "Expected MD5: {0}", md5);
|
||||||
|
|
||||||
return verifyMd5 == md5;
|
return verifyMd5 == md5;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(discimage.DiscHashes.TryGetValue("crc32", out string crc32))
|
if(_discImage.DiscHashes.TryGetValue("crc32", out string crc32))
|
||||||
{
|
{
|
||||||
Crc32Context ctx = new Crc32Context();
|
var ctx = new Crc32Context();
|
||||||
|
|
||||||
foreach(IFilter filter in filters)
|
foreach(IFilter filter in filters)
|
||||||
{
|
{
|
||||||
Stream stream = filter.GetDataForkStream();
|
Stream stream = filter.GetDataForkStream();
|
||||||
readBytes = 0;
|
readBytes = 0;
|
||||||
verifyBytes = new byte[VERIFY_SIZE];
|
verifyBytes = new byte[verifySize];
|
||||||
|
|
||||||
while(readBytes + VERIFY_SIZE < stream.Length)
|
while(readBytes + verifySize < stream.Length)
|
||||||
{
|
{
|
||||||
stream.Read(verifyBytes, 0, verifyBytes.Length);
|
stream.Read(verifyBytes, 0, verifyBytes.Length);
|
||||||
ctx.Update(verifyBytes);
|
ctx.Update(verifyBytes);
|
||||||
@@ -136,12 +137,12 @@ namespace DiscImageChef.DiscImages
|
|||||||
|
|
||||||
string verifyCrc = ctx.End();
|
string verifyCrc = ctx.End();
|
||||||
DicConsole.DebugWriteLine("CDRWin plugin", "Calculated CRC32: {0}", verifyCrc);
|
DicConsole.DebugWriteLine("CDRWin plugin", "Calculated CRC32: {0}", verifyCrc);
|
||||||
DicConsole.DebugWriteLine("CDRWin plugin", "Expected CRC32: {0}", crc32);
|
DicConsole.DebugWriteLine("CDRWin plugin", "Expected CRC32: {0}", crc32);
|
||||||
|
|
||||||
return verifyCrc == crc32;
|
return verifyCrc == crc32;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach(string hash in discimage.DiscHashes.Keys)
|
foreach(string hash in _discImage.DiscHashes.Keys)
|
||||||
DicConsole.DebugWriteLine("CDRWin plugin", "Found unsupported hash {0}", hash);
|
DicConsole.DebugWriteLine("CDRWin plugin", "Found unsupported hash {0}", hash);
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
@@ -150,10 +151,11 @@ namespace DiscImageChef.DiscImages
|
|||||||
public bool? VerifySector(ulong sectorAddress)
|
public bool? VerifySector(ulong sectorAddress)
|
||||||
{
|
{
|
||||||
byte[] buffer = ReadSectorLong(sectorAddress);
|
byte[] buffer = ReadSectorLong(sectorAddress);
|
||||||
|
|
||||||
return CdChecksums.CheckCdSector(buffer);
|
return CdChecksums.CheckCdSector(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool? VerifySectors(ulong sectorAddress, uint length, out List<ulong> failingLbas,
|
public bool? VerifySectors(ulong sectorAddress, uint length, out List<ulong> failingLbas,
|
||||||
out List<ulong> unknownLbas)
|
out List<ulong> unknownLbas)
|
||||||
{
|
{
|
||||||
byte[] buffer = ReadSectorsLong(sectorAddress, length);
|
byte[] buffer = ReadSectorsLong(sectorAddress, length);
|
||||||
@@ -171,19 +173,22 @@ namespace DiscImageChef.DiscImages
|
|||||||
{
|
{
|
||||||
case null:
|
case null:
|
||||||
unknownLbas.Add((ulong)i + sectorAddress);
|
unknownLbas.Add((ulong)i + sectorAddress);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case false:
|
case false:
|
||||||
failingLbas.Add((ulong)i + sectorAddress);
|
failingLbas.Add((ulong)i + sectorAddress);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(unknownLbas.Count > 0) return null;
|
if(unknownLbas.Count > 0)
|
||||||
|
return null;
|
||||||
|
|
||||||
return failingLbas.Count <= 0;
|
return failingLbas.Count <= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool? VerifySectors(ulong sectorAddress, uint length, uint track, out List<ulong> failingLbas,
|
public bool? VerifySectors(ulong sectorAddress, uint length, uint track, out List<ulong> failingLbas,
|
||||||
out List<ulong> unknownLbas)
|
out List<ulong> unknownLbas)
|
||||||
{
|
{
|
||||||
byte[] buffer = ReadSectorsLong(sectorAddress, length, track);
|
byte[] buffer = ReadSectorsLong(sectorAddress, length, track);
|
||||||
@@ -201,14 +206,17 @@ namespace DiscImageChef.DiscImages
|
|||||||
{
|
{
|
||||||
case null:
|
case null:
|
||||||
unknownLbas.Add((ulong)i + sectorAddress);
|
unknownLbas.Add((ulong)i + sectorAddress);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case false:
|
case false:
|
||||||
failingLbas.Add((ulong)i + sectorAddress);
|
failingLbas.Add((ulong)i + sectorAddress);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(unknownLbas.Count > 0) return null;
|
if(unknownLbas.Count > 0)
|
||||||
|
return null;
|
||||||
|
|
||||||
return failingLbas.Count <= 0;
|
return failingLbas.Count <= 0;
|
||||||
}
|
}
|
||||||
@@ -216,6 +224,7 @@ namespace DiscImageChef.DiscImages
|
|||||||
public bool? VerifySector(ulong sectorAddress, uint track)
|
public bool? VerifySector(ulong sectorAddress, uint track)
|
||||||
{
|
{
|
||||||
byte[] buffer = ReadSectorLong(sectorAddress, track);
|
byte[] buffer = ReadSectorLong(sectorAddress, track);
|
||||||
|
|
||||||
return CdChecksums.CheckCdSector(buffer);
|
return CdChecksums.CheckCdSector(buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,32 +51,32 @@ namespace DiscImageChef.DiscImages
|
|||||||
{
|
{
|
||||||
if(options.TryGetValue("separate", out string tmpValue))
|
if(options.TryGetValue("separate", out string tmpValue))
|
||||||
{
|
{
|
||||||
if(!bool.TryParse(tmpValue, out separateTracksWriting))
|
if(!bool.TryParse(tmpValue, out _separateTracksWriting))
|
||||||
{
|
{
|
||||||
ErrorMessage = "Invalid value for split option";
|
ErrorMessage = "Invalid value for split option";
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(separateTracksWriting)
|
if(_separateTracksWriting)
|
||||||
{
|
{
|
||||||
ErrorMessage = "Separate tracksnot yet implemented";
|
ErrorMessage = "Separate tracks not yet implemented";
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
separateTracksWriting = false;
|
_separateTracksWriting = false;
|
||||||
|
|
||||||
if(!SupportedMediaTypes.Contains(mediaType))
|
if(!SupportedMediaTypes.Contains(mediaType))
|
||||||
{
|
{
|
||||||
ErrorMessage = $"Unsupport media format {mediaType}";
|
ErrorMessage = $"Unsupported media format {mediaType}";
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
imageInfo = new ImageInfo
|
_imageInfo = new ImageInfo
|
||||||
{
|
{
|
||||||
MediaType = mediaType, SectorSize = sectorSize, Sectors = sectors
|
MediaType = mediaType, SectorSize = sectorSize, Sectors = sectors
|
||||||
};
|
};
|
||||||
@@ -84,8 +84,8 @@ namespace DiscImageChef.DiscImages
|
|||||||
// TODO: Separate tracks
|
// TODO: Separate tracks
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
writingBaseName = Path.Combine(Path.GetDirectoryName(path), Path.GetFileNameWithoutExtension(path));
|
_writingBaseName = Path.Combine(Path.GetDirectoryName(path), Path.GetFileNameWithoutExtension(path));
|
||||||
descriptorStream = new StreamWriter(path, false, Encoding.ASCII);
|
_descriptorStream = new StreamWriter(path, false, Encoding.ASCII);
|
||||||
}
|
}
|
||||||
catch(IOException e)
|
catch(IOException e)
|
||||||
{
|
{
|
||||||
@@ -94,13 +94,13 @@ namespace DiscImageChef.DiscImages
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
discimage = new CdrWinDisc
|
_discImage = new CdrWinDisc
|
||||||
{
|
{
|
||||||
Disktype = mediaType, Sessions = new List<Session>(), Tracks = new List<CdrWinTrack>()
|
MediaType = mediaType, Sessions = new List<Session>(), Tracks = new List<CdrWinTrack>()
|
||||||
};
|
};
|
||||||
|
|
||||||
trackFlags = new Dictionary<byte, byte>();
|
_trackFlags = new Dictionary<byte, byte>();
|
||||||
trackIsrcs = new Dictionary<byte, string>();
|
_trackIsrcs = new Dictionary<byte, string>();
|
||||||
|
|
||||||
IsWriting = true;
|
IsWriting = true;
|
||||||
ErrorMessage = null;
|
ErrorMessage = null;
|
||||||
@@ -120,15 +120,15 @@ namespace DiscImageChef.DiscImages
|
|||||||
switch(tag)
|
switch(tag)
|
||||||
{
|
{
|
||||||
case MediaTagType.CD_MCN:
|
case MediaTagType.CD_MCN:
|
||||||
discimage.Mcn = Encoding.ASCII.GetString(data);
|
_discImage.Mcn = Encoding.ASCII.GetString(data);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
case MediaTagType.CD_TEXT:
|
case MediaTagType.CD_TEXT:
|
||||||
var cdTextStream = new FileStream(writingBaseName + "_cdtext.bin", FileMode.Create,
|
var cdTextStream = new FileStream(_writingBaseName + "_cdtext.bin", FileMode.Create,
|
||||||
FileAccess.ReadWrite, FileShare.None);
|
FileAccess.ReadWrite, FileShare.None);
|
||||||
|
|
||||||
cdTextStream.Write(data, 0, data.Length);
|
cdTextStream.Write(data, 0, data.Length);
|
||||||
discimage.Cdtextfile = Path.GetFileName(cdTextStream.Name);
|
_discImage.CdTextFile = Path.GetFileName(cdTextStream.Name);
|
||||||
cdTextStream.Close();
|
cdTextStream.Close();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -149,8 +149,8 @@ namespace DiscImageChef.DiscImages
|
|||||||
}
|
}
|
||||||
|
|
||||||
Track track =
|
Track track =
|
||||||
writingTracks.FirstOrDefault(trk => sectorAddress >= trk.TrackStartSector &&
|
_writingTracks.FirstOrDefault(trk => sectorAddress >= trk.TrackStartSector &&
|
||||||
sectorAddress <= trk.TrackEndSector);
|
sectorAddress <= trk.TrackEndSector);
|
||||||
|
|
||||||
if(track.TrackSequence == 0)
|
if(track.TrackSequence == 0)
|
||||||
{
|
{
|
||||||
@@ -159,7 +159,7 @@ namespace DiscImageChef.DiscImages
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
FileStream trackStream = writingStreams.FirstOrDefault(kvp => kvp.Key == track.TrackSequence).Value;
|
FileStream trackStream = _writingStreams.FirstOrDefault(kvp => kvp.Key == track.TrackSequence).Value;
|
||||||
|
|
||||||
if(trackStream == null)
|
if(trackStream == null)
|
||||||
{
|
{
|
||||||
@@ -201,8 +201,8 @@ namespace DiscImageChef.DiscImages
|
|||||||
}
|
}
|
||||||
|
|
||||||
Track track =
|
Track track =
|
||||||
writingTracks.FirstOrDefault(trk => sectorAddress >= trk.TrackStartSector &&
|
_writingTracks.FirstOrDefault(trk => sectorAddress >= trk.TrackStartSector &&
|
||||||
sectorAddress <= trk.TrackEndSector);
|
sectorAddress <= trk.TrackEndSector);
|
||||||
|
|
||||||
if(track.TrackSequence == 0)
|
if(track.TrackSequence == 0)
|
||||||
{
|
{
|
||||||
@@ -211,7 +211,7 @@ namespace DiscImageChef.DiscImages
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
FileStream trackStream = writingStreams.FirstOrDefault(kvp => kvp.Key == track.TrackSequence).Value;
|
FileStream trackStream = _writingStreams.FirstOrDefault(kvp => kvp.Key == track.TrackSequence).Value;
|
||||||
|
|
||||||
if(trackStream == null)
|
if(trackStream == null)
|
||||||
{
|
{
|
||||||
@@ -260,8 +260,8 @@ namespace DiscImageChef.DiscImages
|
|||||||
}
|
}
|
||||||
|
|
||||||
Track track =
|
Track track =
|
||||||
writingTracks.FirstOrDefault(trk => sectorAddress >= trk.TrackStartSector &&
|
_writingTracks.FirstOrDefault(trk => sectorAddress >= trk.TrackStartSector &&
|
||||||
sectorAddress <= trk.TrackEndSector);
|
sectorAddress <= trk.TrackEndSector);
|
||||||
|
|
||||||
if(track.TrackSequence == 0)
|
if(track.TrackSequence == 0)
|
||||||
{
|
{
|
||||||
@@ -270,7 +270,7 @@ namespace DiscImageChef.DiscImages
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
FileStream trackStream = writingStreams.FirstOrDefault(kvp => kvp.Key == track.TrackSequence).Value;
|
FileStream trackStream = _writingStreams.FirstOrDefault(kvp => kvp.Key == track.TrackSequence).Value;
|
||||||
|
|
||||||
if(trackStream == null)
|
if(trackStream == null)
|
||||||
{
|
{
|
||||||
@@ -305,8 +305,8 @@ namespace DiscImageChef.DiscImages
|
|||||||
}
|
}
|
||||||
|
|
||||||
Track track =
|
Track track =
|
||||||
writingTracks.FirstOrDefault(trk => sectorAddress >= trk.TrackStartSector &&
|
_writingTracks.FirstOrDefault(trk => sectorAddress >= trk.TrackStartSector &&
|
||||||
sectorAddress <= trk.TrackEndSector);
|
sectorAddress <= trk.TrackEndSector);
|
||||||
|
|
||||||
if(track.TrackSequence == 0)
|
if(track.TrackSequence == 0)
|
||||||
{
|
{
|
||||||
@@ -315,7 +315,7 @@ namespace DiscImageChef.DiscImages
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
FileStream trackStream = writingStreams.FirstOrDefault(kvp => kvp.Key == track.TrackSequence).Value;
|
FileStream trackStream = _writingStreams.FirstOrDefault(kvp => kvp.Key == track.TrackSequence).Value;
|
||||||
|
|
||||||
if(trackStream == null)
|
if(trackStream == null)
|
||||||
{
|
{
|
||||||
@@ -364,42 +364,42 @@ namespace DiscImageChef.DiscImages
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(writingTracks != null &&
|
if(_writingTracks != null &&
|
||||||
writingStreams != null)
|
_writingStreams != null)
|
||||||
foreach(FileStream oldTrack in writingStreams.Select(t => t.Value).Distinct())
|
foreach(FileStream oldTrack in _writingStreams.Select(t => t.Value).Distinct())
|
||||||
oldTrack.Close();
|
oldTrack.Close();
|
||||||
|
|
||||||
ulong currentOffset = 0;
|
ulong currentOffset = 0;
|
||||||
writingTracks = new List<Track>();
|
_writingTracks = new List<Track>();
|
||||||
|
|
||||||
foreach(Track track in tracks.OrderBy(t => t.TrackSequence))
|
foreach(Track track in tracks.OrderBy(t => t.TrackSequence))
|
||||||
{
|
{
|
||||||
Track newTrack = track;
|
Track newTrack = track;
|
||||||
|
|
||||||
newTrack.TrackFile = separateTracksWriting ? writingBaseName + $"_track{track.TrackSequence:D2}.bin"
|
newTrack.TrackFile = _separateTracksWriting ? _writingBaseName + $"_track{track.TrackSequence:D2}.bin"
|
||||||
: writingBaseName + ".bin";
|
: _writingBaseName + ".bin";
|
||||||
|
|
||||||
newTrack.TrackFileOffset = separateTracksWriting ? 0 : currentOffset;
|
newTrack.TrackFileOffset = _separateTracksWriting ? 0 : currentOffset;
|
||||||
writingTracks.Add(newTrack);
|
_writingTracks.Add(newTrack);
|
||||||
|
|
||||||
currentOffset += (ulong)newTrack.TrackRawBytesPerSector *
|
currentOffset += (ulong)newTrack.TrackRawBytesPerSector *
|
||||||
((newTrack.TrackEndSector - newTrack.TrackStartSector) + 1);
|
((newTrack.TrackEndSector - newTrack.TrackStartSector) + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
writingStreams = new Dictionary<uint, FileStream>();
|
_writingStreams = new Dictionary<uint, FileStream>();
|
||||||
|
|
||||||
if(separateTracksWriting)
|
if(_separateTracksWriting)
|
||||||
foreach(Track track in writingTracks)
|
foreach(Track track in _writingTracks)
|
||||||
writingStreams.Add(track.TrackSequence,
|
_writingStreams.Add(track.TrackSequence,
|
||||||
new FileStream(track.TrackFile, FileMode.OpenOrCreate, FileAccess.ReadWrite,
|
new FileStream(track.TrackFile, FileMode.OpenOrCreate, FileAccess.ReadWrite,
|
||||||
FileShare.None));
|
FileShare.None));
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var jointstream = new FileStream(writingBaseName + ".bin", FileMode.OpenOrCreate, FileAccess.ReadWrite,
|
var jointStream = new FileStream(_writingBaseName + ".bin", FileMode.OpenOrCreate, FileAccess.ReadWrite,
|
||||||
FileShare.None);
|
FileShare.None);
|
||||||
|
|
||||||
foreach(Track track in writingTracks)
|
foreach(Track track in _writingTracks)
|
||||||
writingStreams.Add(track.TrackSequence, jointstream);
|
_writingStreams.Add(track.TrackSequence, jointStream);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -414,91 +414,118 @@ namespace DiscImageChef.DiscImages
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(separateTracksWriting)
|
if(_separateTracksWriting)
|
||||||
foreach(FileStream writingStream in writingStreams.Values)
|
foreach(FileStream writingStream in _writingStreams.Values)
|
||||||
{
|
{
|
||||||
writingStream.Flush();
|
writingStream.Flush();
|
||||||
writingStream.Close();
|
writingStream.Close();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
writingStreams.First().Value.Flush();
|
_writingStreams.First().Value.Flush();
|
||||||
writingStreams.First().Value.Close();
|
_writingStreams.First().Value.Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
int currentSession = 0;
|
int currentSession = 0;
|
||||||
|
|
||||||
if(!string.IsNullOrWhiteSpace(discimage.Comment))
|
if(!string.IsNullOrWhiteSpace(_discImage.Comment))
|
||||||
{
|
{
|
||||||
string[] commentLines = discimage.Comment.Split(new[]
|
string[] commentLines = _discImage.Comment.Split(new[]
|
||||||
{
|
{
|
||||||
'\n'
|
'\n'
|
||||||
}, StringSplitOptions.RemoveEmptyEntries);
|
}, StringSplitOptions.RemoveEmptyEntries);
|
||||||
|
|
||||||
foreach(string line in commentLines)
|
foreach(string line in commentLines)
|
||||||
descriptorStream.WriteLine("REM {0}", line);
|
_descriptorStream.WriteLine("REM {0}", line);
|
||||||
}
|
}
|
||||||
|
|
||||||
descriptorStream.WriteLine("REM ORIGINAL MEDIA-TYPE: {0}", MediaTypeToCdrwinType(imageInfo.MediaType));
|
_descriptorStream.WriteLine("REM ORIGINAL MEDIA-TYPE: {0}", MediaTypeToCdrwinType(_imageInfo.MediaType));
|
||||||
|
|
||||||
if(!string.IsNullOrEmpty(discimage.Cdtextfile))
|
_descriptorStream.WriteLine("REM METADATA DIC MEDIA-TYPE: {0}", _imageInfo.MediaType);
|
||||||
descriptorStream.WriteLine("CDTEXTFILE \"{0}\"", Path.GetFileName(discimage.Cdtextfile));
|
|
||||||
|
|
||||||
if(!string.IsNullOrEmpty(discimage.Title))
|
if(!string.IsNullOrEmpty(_imageInfo.Application))
|
||||||
descriptorStream.WriteLine("TITLE {0}", discimage.Title);
|
{
|
||||||
|
_descriptorStream.WriteLine("REM Ripping Tool: {0}", _imageInfo.Application);
|
||||||
|
|
||||||
if(!string.IsNullOrEmpty(discimage.Mcn))
|
if(!string.IsNullOrEmpty(_imageInfo.ApplicationVersion))
|
||||||
descriptorStream.WriteLine("CATALOG {0}", discimage.Mcn);
|
_descriptorStream.WriteLine("REM Ripping Tool Version: {0}", _imageInfo.ApplicationVersion);
|
||||||
|
}
|
||||||
|
|
||||||
if(!string.IsNullOrEmpty(discimage.Barcode))
|
if(DumpHardware != null)
|
||||||
descriptorStream.WriteLine("UPC_EAN {0}", discimage.Barcode);
|
{
|
||||||
|
foreach(var dumpData in from dump in DumpHardware from extent in dump.Extents.OrderBy(e => e.Start)
|
||||||
|
select new
|
||||||
|
{
|
||||||
|
dump.Manufacturer, dump.Model, dump.Firmware, dump.Serial,
|
||||||
|
Application = dump.Software.Name,
|
||||||
|
ApplicationVersion = dump.Software.Version, dump.Software.OperatingSystem,
|
||||||
|
extent.Start, extent.End
|
||||||
|
})
|
||||||
|
{
|
||||||
|
_descriptorStream.
|
||||||
|
WriteLine($"REM METADATA DUMP EXTENT: {dumpData.Application} | {dumpData.ApplicationVersion} | {dumpData.OperatingSystem} | {dumpData.Manufacturer} | {dumpData.Model} | {dumpData.Firmware} | {dumpData.Serial} | {dumpData.Start}:{dumpData.End}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(!separateTracksWriting)
|
if(!string.IsNullOrEmpty(_discImage.CdTextFile))
|
||||||
descriptorStream.WriteLine("FILE \"{0}\" BINARY", Path.GetFileName(writingStreams.First().Value.Name));
|
_descriptorStream.WriteLine("CDTEXTFILE \"{0}\"", Path.GetFileName(_discImage.CdTextFile));
|
||||||
|
|
||||||
foreach(Track track in writingTracks)
|
if(!string.IsNullOrEmpty(_discImage.Title))
|
||||||
|
_descriptorStream.WriteLine("TITLE {0}", _discImage.Title);
|
||||||
|
|
||||||
|
if(!string.IsNullOrEmpty(_discImage.Mcn))
|
||||||
|
_descriptorStream.WriteLine("CATALOG {0}", _discImage.Mcn);
|
||||||
|
|
||||||
|
if(!string.IsNullOrEmpty(_discImage.Barcode))
|
||||||
|
_descriptorStream.WriteLine("UPC_EAN {0}", _discImage.Barcode);
|
||||||
|
|
||||||
|
if(!_separateTracksWriting)
|
||||||
|
_descriptorStream.WriteLine("FILE \"{0}\" BINARY",
|
||||||
|
Path.GetFileName(_writingStreams.First().Value.Name));
|
||||||
|
|
||||||
|
foreach(Track track in _writingTracks)
|
||||||
{
|
{
|
||||||
if(track.TrackSession > currentSession)
|
if(track.TrackSession > currentSession)
|
||||||
descriptorStream.WriteLine("REM SESSION {0}", ++currentSession);
|
_descriptorStream.WriteLine("REM SESSION {0}", ++currentSession);
|
||||||
|
|
||||||
if(separateTracksWriting)
|
if(_separateTracksWriting)
|
||||||
descriptorStream.WriteLine("FILE \"{0}\" BINARY", Path.GetFileName(track.TrackFile));
|
_descriptorStream.WriteLine("FILE \"{0}\" BINARY", Path.GetFileName(track.TrackFile));
|
||||||
|
|
||||||
(byte minute, byte second, byte frame) msf = LbaToMsf(track.TrackStartSector);
|
(byte minute, byte second, byte frame) msf = LbaToMsf(track.TrackStartSector);
|
||||||
descriptorStream.WriteLine(" TRACK {0:D2} {1}", track.TrackSequence, GetTrackMode(track));
|
_descriptorStream.WriteLine(" TRACK {0:D2} {1}", track.TrackSequence, GetTrackMode(track));
|
||||||
|
|
||||||
if(trackFlags.TryGetValue((byte)track.TrackSequence, out byte flagsByte))
|
if(_trackFlags.TryGetValue((byte)track.TrackSequence, out byte flagsByte))
|
||||||
if(flagsByte != 0 &&
|
if(flagsByte != 0 &&
|
||||||
flagsByte != (byte)CdFlags.DataTrack)
|
flagsByte != (byte)CdFlags.DataTrack)
|
||||||
{
|
{
|
||||||
var flags = (CdFlags)flagsByte;
|
var flags = (CdFlags)flagsByte;
|
||||||
|
|
||||||
descriptorStream.WriteLine(" FLAGS{0}{1}{2}",
|
_descriptorStream.WriteLine(" FLAGS{0}{1}{2}",
|
||||||
flags.HasFlag(CdFlags.CopyPermitted) ? " DCP" : "",
|
flags.HasFlag(CdFlags.CopyPermitted) ? " DCP" : "",
|
||||||
flags.HasFlag(CdFlags.FourChannel) ? " 4CH" : "",
|
flags.HasFlag(CdFlags.FourChannel) ? " 4CH" : "",
|
||||||
flags.HasFlag(CdFlags.PreEmphasis) ? " PRE" : "");
|
flags.HasFlag(CdFlags.PreEmphasis) ? " PRE" : "");
|
||||||
}
|
}
|
||||||
|
|
||||||
if(trackIsrcs.TryGetValue((byte)track.TrackSequence, out string isrc))
|
if(_trackIsrcs.TryGetValue((byte)track.TrackSequence, out string isrc))
|
||||||
descriptorStream.WriteLine(" ISRC {0}", isrc);
|
_descriptorStream.WriteLine(" ISRC {0}", isrc);
|
||||||
|
|
||||||
if(track.TrackPregap > 0)
|
if(track.TrackPregap > 0)
|
||||||
{
|
{
|
||||||
descriptorStream.WriteLine(" INDEX {0:D2} {1:D2}:{2:D2}:{3:D2}", 0, msf.minute, msf.second,
|
_descriptorStream.WriteLine(" INDEX {0:D2} {1:D2}:{2:D2}:{3:D2}", 0, msf.minute, msf.second,
|
||||||
msf.frame);
|
msf.frame);
|
||||||
|
|
||||||
msf = LbaToMsf(track.TrackStartSector + track.TrackPregap);
|
msf = LbaToMsf(track.TrackStartSector + track.TrackPregap);
|
||||||
|
|
||||||
descriptorStream.WriteLine(" INDEX {0:D2} {1:D2}:{2:D2}:{3:D2}", 1, msf.minute, msf.second,
|
_descriptorStream.WriteLine(" INDEX {0:D2} {1:D2}:{2:D2}:{3:D2}", 1, msf.minute, msf.second,
|
||||||
msf.frame);
|
msf.frame);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
descriptorStream.WriteLine(" INDEX {0:D2} {1:D2}:{2:D2}:{3:D2}", 1, msf.minute, msf.second,
|
_descriptorStream.WriteLine(" INDEX {0:D2} {1:D2}:{2:D2}:{3:D2}", 1, msf.minute, msf.second,
|
||||||
msf.frame);
|
msf.frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
descriptorStream.Flush();
|
_descriptorStream.Flush();
|
||||||
descriptorStream.Close();
|
_descriptorStream.Close();
|
||||||
|
|
||||||
IsWriting = false;
|
IsWriting = false;
|
||||||
ErrorMessage = "";
|
ErrorMessage = "";
|
||||||
@@ -523,8 +550,8 @@ namespace DiscImageChef.DiscImages
|
|||||||
}
|
}
|
||||||
|
|
||||||
Track track =
|
Track track =
|
||||||
writingTracks.FirstOrDefault(trk => sectorAddress >= trk.TrackStartSector &&
|
_writingTracks.FirstOrDefault(trk => sectorAddress >= trk.TrackStartSector &&
|
||||||
sectorAddress <= trk.TrackEndSector);
|
sectorAddress <= trk.TrackEndSector);
|
||||||
|
|
||||||
if(track.TrackSequence == 0)
|
if(track.TrackSequence == 0)
|
||||||
{
|
{
|
||||||
@@ -544,14 +571,14 @@ namespace DiscImageChef.DiscImages
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
trackFlags.Add((byte)track.TrackSequence, data[0]);
|
_trackFlags.Add((byte)track.TrackSequence, data[0]);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case SectorTagType.CdTrackIsrc:
|
case SectorTagType.CdTrackIsrc:
|
||||||
{
|
{
|
||||||
if(data != null)
|
if(data != null)
|
||||||
trackIsrcs.Add((byte)track.TrackSequence, Encoding.UTF8.GetString(data));
|
_trackIsrcs.Add((byte)track.TrackSequence, Encoding.UTF8.GetString(data));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -565,15 +592,22 @@ namespace DiscImageChef.DiscImages
|
|||||||
public bool WriteSectorsTag(byte[] data, ulong sectorAddress, uint length, SectorTagType tag) =>
|
public bool WriteSectorsTag(byte[] data, ulong sectorAddress, uint length, SectorTagType tag) =>
|
||||||
WriteSectorTag(data, sectorAddress, tag);
|
WriteSectorTag(data, sectorAddress, tag);
|
||||||
|
|
||||||
public bool SetDumpHardware(List<DumpHardwareType> dumpHardware) => false;
|
public bool SetDumpHardware(List<DumpHardwareType> dumpHardware)
|
||||||
|
{
|
||||||
|
DumpHardware = dumpHardware;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
public bool SetCicmMetadata(CICMMetadataType metadata) => false;
|
public bool SetCicmMetadata(CICMMetadataType metadata) => false;
|
||||||
|
|
||||||
public bool SetMetadata(ImageInfo metadata)
|
public bool SetMetadata(ImageInfo metadata)
|
||||||
{
|
{
|
||||||
discimage.Barcode = metadata.MediaBarcode;
|
_discImage.Barcode = metadata.MediaBarcode;
|
||||||
discimage.Comment = metadata.Comments;
|
_discImage.Comment = metadata.Comments;
|
||||||
discimage.Title = metadata.MediaTitle;
|
_discImage.Title = metadata.MediaTitle;
|
||||||
|
_imageInfo.Application = metadata.Application;
|
||||||
|
_imageInfo.ApplicationVersion = metadata.ApplicationVersion;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -186,11 +186,20 @@
|
|||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=ATAPI/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=ATAPI/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=ATIP/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=ATIP/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=BANDAI/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=BANDAI/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=BDRDL/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=BDRE/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=BDREDL/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=BDROM/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=bitsetting/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=bitsetting/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Bluray/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Bluray/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=cartstatus/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=cartstatus/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=CDDA/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=CDDA/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=CDDB/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=CDMRW/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=CDRW/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=CDRWIN/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=cdtext/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=cdtext/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=CDTEXTFILE/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=CDTV/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=CDTV/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=cdrom/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=cdrom/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=certance/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=certance/@EntryIndexedValue">True</s:Boolean>
|
||||||
@@ -198,12 +207,25 @@
|
|||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=checksums/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=checksums/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=cicm/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=cicm/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Claunia/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Claunia/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=cuesheet/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=DDCD/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=DDCD/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Deinterleave/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Deinterleave/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=dicremote/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=dicremote/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Drive_0027s/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Drive_0027s/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=DVDPMRW/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=DVDPMRWDL/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=DVDPR/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=DVDPRDL/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=DVDPRW/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=DVDPRWDL/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=DVDPVR/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=dvdr/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=dvdr/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=dvdram/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=dvdram/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=DVDRDL/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=DVDROM/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=DVDRW/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=DVDRWDL/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=DVDVR/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=ecsd/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=ecsd/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=eeprom/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=eeprom/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=EVPD/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=EVPD/@EntryIndexedValue">True</s:Boolean>
|
||||||
@@ -211,9 +233,16 @@
|
|||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=getconfiguration/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=getconfiguration/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=hddvd/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=hddvd/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=hddvdr/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=hddvdr/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=HDDVDRAM/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=HDDVDRDL/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=HDDVDROM/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=HDDVDRW/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=HDDVDRWDL/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Hldtst/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Hldtst/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=iomega/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=iomega/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=isobuster/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=isrc/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=isrc/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Isrcs/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Kreon/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Kreon/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=lastrmd/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=lastrmd/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=lastsequence/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=lastsequence/@EntryIndexedValue">True</s:Boolean>
|
||||||
@@ -242,6 +271,7 @@
|
|||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Plextor/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Plextor/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=pmin/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=pmin/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Portillo/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Portillo/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Postgap/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Powe/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Powe/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=pregap/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=pregap/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=pregaps/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=pregaps/@EntryIndexedValue">True</s:Boolean>
|
||||||
@@ -257,6 +287,7 @@
|
|||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Reiser/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Reiser/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=remapanchor/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=remapanchor/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=reportdensitysupport/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=reportdensitysupport/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=SCMS/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=SDHCI/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=SDHCI/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Secu/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Secu/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=spamsum/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=spamsum/@EntryIndexedValue">True</s:Boolean>
|
||||||
@@ -264,6 +295,7 @@
|
|||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=subpages/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=subpages/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=subchannel/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=subchannel/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=subchannels/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=subchannels/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Trurip/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=umounting/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=umounting/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=undecoded/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=undecoded/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Vari/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Vari/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
|||||||
Reference in New Issue
Block a user