[WinOnCD] Implement missing methods.

This commit is contained in:
2026-03-03 16:01:43 +00:00
parent ec5d7ed76b
commit 6f5fed5299
5 changed files with 648 additions and 119 deletions

View File

@@ -96,9 +96,11 @@ public sealed partial class WinOnCD
}
// Step 3: Process track blocks and build tracks, sessions, and partitions
Tracks = [];
Sessions = [];
Partitions = [];
Tracks = [];
Sessions = [];
Partitions = [];
_trackFlags = new Dictionary<uint, byte>();
_trackIsrcs = new Dictionary<uint, string>();
var lastSession = 0;
var lastPoint = 0;
@@ -308,6 +310,14 @@ public sealed partial class WinOnCD
Type = trackType.Humanize()
};
// Store C2D flags for this track
_trackFlags[trackSequence] = (byte)entry.flags;
// Store ISRC if present
string isrc = Encoding.ASCII.GetString(entry.isrc).TrimEnd('\0');
if(!string.IsNullOrWhiteSpace(isrc)) _trackIsrcs[trackSequence] = isrc;
Tracks.Add(track);
Partitions.Add(partition);
}
@@ -333,7 +343,26 @@ public sealed partial class WinOnCD
if(!string.IsNullOrWhiteSpace(description)) _imageInfo.Comments = description;
if(header.has_upc_ean != 0) _imageInfo.MediaBarcode = Encoding.ASCII.GetString(header.upc_ean).TrimEnd('\0');
if(header.has_upc_ean != 0)
{
_mcn = Encoding.ASCII.GetString(header.upc_ean).TrimEnd('\0');
_imageInfo.MediaBarcode = _mcn;
_imageInfo.ReadableMediaTags.Add(MediaTagType.CD_MCN);
}
// Read CD-Text if present
if(header.size_cdtext > 0)
{
long cdTextOffset = header.offset_tracks + header.num_track_blocks * Marshal.SizeOf<C2dTrackBlock>();
stream.Seek(cdTextOffset, SeekOrigin.Begin);
_cdtext = new byte[header.size_cdtext];
stream.EnsureRead(_cdtext, 0, (int)header.size_cdtext);
_imageInfo.ReadableMediaTags.Add(MediaTagType.CD_TEXT);
}
if(_trackIsrcs.Count > 0 && !_imageInfo.ReadableSectorTags.Contains(SectorTagType.CdTrackIsrc))
_imageInfo.ReadableSectorTags.Add(SectorTagType.CdTrackIsrc);
// Determine media type based on tracks
var hasData = false;

542
Aaru.Images/WinOnCD/Read.cs Normal file
View File

@@ -0,0 +1,542 @@
// /***************************************************************************
// Aaru Data Preservation Suite
// ----------------------------------------------------------------------------
//
// Filename : Read.cs
// Author(s) : Natalia Portillo <claunia@claunia.com>
//
// Component : Disc image plugins.
//
// --[ Description ] ----------------------------------------------------------
//
// Reads WinOnCD disc images.
//
// --[ License ] --------------------------------------------------------------
//
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 2.1 of the
// License, or (at your option) any later version.
//
// This library 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
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, see <http://www.gnu.org/licenses/>.
//
// ----------------------------------------------------------------------------
// Copyright © 2011-2026 Natalia Portillo
// ****************************************************************************/
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using Aaru.CommonTypes.Enums;
using Aaru.CommonTypes.Structs;
using Aaru.Helpers;
using Session = Aaru.CommonTypes.Structs.Session;
namespace Aaru.Images;
public sealed partial class WinOnCD
{
/// <inheritdoc />
public ErrorNumber ReadSector(ulong sectorAddress, uint track, out byte[] buffer, out SectorStatus sectorStatus)
{
buffer = null;
sectorStatus = SectorStatus.NotDumped;
Track trk = Tracks.FirstOrDefault(t => t.Sequence == track);
if(trk is null) return ErrorNumber.SectorNotFound;
if(sectorAddress < trk.StartSector || sectorAddress > trk.EndSector) return ErrorNumber.OutOfRange;
ulong offsetInTrack = sectorAddress - trk.StartSector;
int stride = trk.RawBytesPerSector + (trk.SubchannelType != TrackSubchannelType.None ? 96 : 0);
var fileOffset = (long)(trk.FileOffset + offsetInTrack * (ulong)stride);
if(trk.RawBytesPerSector == trk.BytesPerSector)
{
buffer = new byte[trk.BytesPerSector];
_imageStream.Seek(fileOffset, SeekOrigin.Begin);
_imageStream.EnsureRead(buffer, 0, trk.BytesPerSector);
}
else
{
var rawSector = new byte[trk.RawBytesPerSector];
_imageStream.Seek(fileOffset, SeekOrigin.Begin);
_imageStream.EnsureRead(rawSector, 0, trk.RawBytesPerSector);
buffer = new byte[trk.BytesPerSector];
switch(trk.Type)
{
case TrackType.CdMode1 when trk.RawBytesPerSector == 2352:
Array.Copy(rawSector, 16, buffer, 0, trk.BytesPerSector);
break;
case TrackType.CdMode2Formless when trk.RawBytesPerSector == 2352:
Array.Copy(rawSector, 16, buffer, 0, trk.BytesPerSector);
break;
default:
Array.Copy(rawSector, 0, buffer, 0, trk.BytesPerSector);
break;
}
}
sectorStatus = SectorStatus.Dumped;
return ErrorNumber.NoError;
}
/// <inheritdoc />
public ErrorNumber ReadSectors(ulong sectorAddress, uint length, uint track, out byte[] buffer,
out SectorStatus[] sectorStatus)
{
buffer = null;
sectorStatus = null;
Track trk = Tracks.FirstOrDefault(t => t.Sequence == track);
if(trk is null) return ErrorNumber.SectorNotFound;
if(sectorAddress + length - 1 > trk.EndSector) return ErrorNumber.OutOfRange;
using var ms = new MemoryStream();
sectorStatus = new SectorStatus[length];
for(uint i = 0; i < length; i++)
{
ErrorNumber errno = ReadSector(sectorAddress + i, track, out byte[] sectorData, out SectorStatus status);
if(errno != ErrorNumber.NoError) return errno;
ms.Write(sectorData, 0, sectorData.Length);
sectorStatus[i] = status;
}
buffer = ms.ToArray();
return ErrorNumber.NoError;
}
/// <inheritdoc />
public ErrorNumber ReadSector(ulong sectorAddress, bool negative, out byte[] buffer, out SectorStatus sectorStatus)
{
buffer = null;
sectorStatus = SectorStatus.NotDumped;
if(negative) return ErrorNumber.NotSupported;
Track trk = Tracks.FirstOrDefault(t => sectorAddress >= t.StartSector && sectorAddress <= t.EndSector);
if(trk is null) return ErrorNumber.SectorNotFound;
return ReadSector(sectorAddress, trk.Sequence, out buffer, out sectorStatus);
}
/// <inheritdoc />
public ErrorNumber ReadSectors(ulong sectorAddress, bool negative, uint length, out byte[] buffer,
out SectorStatus[] sectorStatus)
{
buffer = null;
sectorStatus = null;
if(negative) return ErrorNumber.NotSupported;
Track trk = Tracks.FirstOrDefault(t => sectorAddress >= t.StartSector && sectorAddress <= t.EndSector);
if(trk is null) return ErrorNumber.SectorNotFound;
return ReadSectors(sectorAddress, length, trk.Sequence, out buffer, out sectorStatus);
}
/// <inheritdoc />
public ErrorNumber ReadSectorLong(ulong sectorAddress, uint track, out byte[] buffer, out SectorStatus sectorStatus)
{
buffer = null;
sectorStatus = SectorStatus.NotDumped;
Track trk = Tracks.FirstOrDefault(t => t.Sequence == track);
if(trk is null) return ErrorNumber.SectorNotFound;
if(sectorAddress < trk.StartSector || sectorAddress > trk.EndSector) return ErrorNumber.OutOfRange;
ulong offsetInTrack = sectorAddress - trk.StartSector;
int stride = trk.RawBytesPerSector + (trk.SubchannelType != TrackSubchannelType.None ? 96 : 0);
var fileOffset = (long)(trk.FileOffset + offsetInTrack * (ulong)stride);
switch(trk.Type)
{
case TrackType.Audio:
{
buffer = new byte[2352];
_imageStream.Seek(fileOffset, SeekOrigin.Begin);
_imageStream.EnsureRead(buffer, 0, 2352);
break;
}
case TrackType.CdMode1:
{
if(trk.RawBytesPerSector >= 2352)
{
buffer = new byte[2352];
_imageStream.Seek(fileOffset, SeekOrigin.Begin);
_imageStream.EnsureRead(buffer, 0, 2352);
}
else
{
var userData = new byte[trk.RawBytesPerSector];
_imageStream.Seek(fileOffset, SeekOrigin.Begin);
_imageStream.EnsureRead(userData, 0, trk.RawBytesPerSector);
buffer = new byte[2352];
Array.Copy(userData, 0, buffer, 16, trk.RawBytesPerSector);
_sectorBuilder.ReconstructPrefix(ref buffer, TrackType.CdMode1, (long)sectorAddress);
_sectorBuilder.ReconstructEcc(ref buffer, TrackType.CdMode1);
}
break;
}
case TrackType.CdMode2Form1:
{
var userData = new byte[trk.RawBytesPerSector];
_imageStream.Seek(fileOffset, SeekOrigin.Begin);
_imageStream.EnsureRead(userData, 0, trk.RawBytesPerSector);
buffer = new byte[2352];
Array.Copy(userData, 0, buffer, 24, trk.RawBytesPerSector);
_sectorBuilder.ReconstructPrefix(ref buffer, TrackType.CdMode2Form1, (long)sectorAddress);
_sectorBuilder.ReconstructEcc(ref buffer, TrackType.CdMode2Form1);
break;
}
case TrackType.CdMode2Form2:
{
var userData = new byte[trk.RawBytesPerSector];
_imageStream.Seek(fileOffset, SeekOrigin.Begin);
_imageStream.EnsureRead(userData, 0, trk.RawBytesPerSector);
buffer = new byte[2352];
Array.Copy(userData, 0, buffer, 24, trk.RawBytesPerSector);
_sectorBuilder.ReconstructPrefix(ref buffer, TrackType.CdMode2Form2, (long)sectorAddress);
_sectorBuilder.ReconstructEcc(ref buffer, TrackType.CdMode2Form2);
break;
}
case TrackType.CdMode2Formless:
{
if(trk.RawBytesPerSector >= 2352)
{
buffer = new byte[2352];
_imageStream.Seek(fileOffset, SeekOrigin.Begin);
_imageStream.EnsureRead(buffer, 0, 2352);
}
else
{
buffer = new byte[2352];
_sectorBuilder.ReconstructPrefix(ref buffer, TrackType.CdMode2Formless, (long)sectorAddress);
_imageStream.Seek(fileOffset, SeekOrigin.Begin);
_imageStream.EnsureRead(buffer, 16, trk.RawBytesPerSector);
}
break;
}
default:
return ErrorNumber.NotSupported;
}
sectorStatus = SectorStatus.Dumped;
return ErrorNumber.NoError;
}
/// <inheritdoc />
public ErrorNumber ReadSectorsLong(ulong sectorAddress, uint length, uint track, out byte[] buffer,
out SectorStatus[] sectorStatus)
{
buffer = null;
sectorStatus = null;
Track trk = Tracks.FirstOrDefault(t => t.Sequence == track);
if(trk is null) return ErrorNumber.SectorNotFound;
if(sectorAddress + length - 1 > trk.EndSector) return ErrorNumber.OutOfRange;
using var ms = new MemoryStream();
sectorStatus = new SectorStatus[length];
for(uint i = 0; i < length; i++)
{
ErrorNumber errno =
ReadSectorLong(sectorAddress + i, track, out byte[] sectorData, out SectorStatus status);
if(errno != ErrorNumber.NoError) return errno;
ms.Write(sectorData, 0, sectorData.Length);
sectorStatus[i] = status;
}
buffer = ms.ToArray();
return ErrorNumber.NoError;
}
/// <inheritdoc />
public ErrorNumber ReadSectorLong(ulong sectorAddress, bool negative, out byte[] buffer,
out SectorStatus sectorStatus)
{
buffer = null;
sectorStatus = SectorStatus.NotDumped;
if(negative) return ErrorNumber.NotSupported;
Track trk = Tracks.FirstOrDefault(t => sectorAddress >= t.StartSector && sectorAddress <= t.EndSector);
if(trk is null) return ErrorNumber.SectorNotFound;
return ReadSectorLong(sectorAddress, trk.Sequence, out buffer, out sectorStatus);
}
/// <inheritdoc />
public ErrorNumber ReadSectorsLong(ulong sectorAddress, bool negative, uint length, out byte[] buffer,
out SectorStatus[] sectorStatus)
{
buffer = null;
sectorStatus = null;
if(negative) return ErrorNumber.NotSupported;
Track trk = Tracks.FirstOrDefault(t => sectorAddress >= t.StartSector && sectorAddress <= t.EndSector);
if(trk is null) return ErrorNumber.SectorNotFound;
return ReadSectorsLong(sectorAddress, length, trk.Sequence, out buffer, out sectorStatus);
}
/// <inheritdoc />
public ErrorNumber ReadSectorTag(ulong sectorAddress, uint track, SectorTagType tag, out byte[] buffer)
{
buffer = null;
Track trk = Tracks.FirstOrDefault(t => t.Sequence == track);
if(trk is null) return ErrorNumber.SectorNotFound;
if(sectorAddress < trk.StartSector || sectorAddress > trk.EndSector) return ErrorNumber.OutOfRange;
switch(tag)
{
case SectorTagType.CdTrackFlags:
{
var cdFlags = (CdFlags)0;
if(_trackFlags.TryGetValue(trk.Sequence, out byte c2dFlags))
{
if((c2dFlags & (byte)C2dFlag.PreEmphasis) != 0) cdFlags |= CdFlags.PreEmphasis;
if((c2dFlags & (byte)C2dFlag.Copyright) != 0) cdFlags |= CdFlags.CopyPermitted;
if((c2dFlags & (byte)C2dFlag.Data) != 0) cdFlags |= CdFlags.DataTrack;
}
else if(trk.Type != TrackType.Audio) cdFlags = CdFlags.DataTrack;
buffer = [(byte)cdFlags];
return ErrorNumber.NoError;
}
case SectorTagType.CdSectorSync:
case SectorTagType.CdSectorHeader:
case SectorTagType.CdSectorEdc:
case SectorTagType.CdSectorEccP:
case SectorTagType.CdSectorEccQ:
case SectorTagType.CdSectorEcc:
if(trk.Type == TrackType.Audio) return ErrorNumber.NotSupported;
break;
case SectorTagType.CdSectorSubHeader:
if(trk.Type != TrackType.CdMode2Form1 &&
trk.Type != TrackType.CdMode2Form2 &&
trk.Type != TrackType.CdMode2Formless)
return ErrorNumber.NotSupported;
break;
case SectorTagType.CdTrackIsrc:
if(!_trackIsrcs.TryGetValue(trk.Sequence, out string isrc)) return ErrorNumber.NoData;
buffer = Encoding.ASCII.GetBytes(isrc);
return ErrorNumber.NoError;
case SectorTagType.CdSectorSubchannel:
if(trk.SubchannelType == TrackSubchannelType.None) return ErrorNumber.NotSupported;
{
ulong offsetInTrack = sectorAddress - trk.StartSector;
int stride = trk.RawBytesPerSector + 96;
var fileOffset = (long)(trk.FileOffset + offsetInTrack * (ulong)stride);
buffer = new byte[96];
_imageStream.Seek(fileOffset + trk.RawBytesPerSector, SeekOrigin.Begin);
_imageStream.EnsureRead(buffer, 0, 96);
}
return ErrorNumber.NoError;
default:
return ErrorNumber.NotSupported;
}
ErrorNumber errno = ReadSectorLong(sectorAddress, track, out byte[] fullSector, out SectorStatus _);
if(errno != ErrorNumber.NoError) return errno;
switch(tag)
{
case SectorTagType.CdSectorSync:
buffer = new byte[12];
Array.Copy(fullSector, 0, buffer, 0, 12);
break;
case SectorTagType.CdSectorHeader:
buffer = new byte[4];
Array.Copy(fullSector, 12, buffer, 0, 4);
break;
case SectorTagType.CdSectorSubHeader:
buffer = new byte[8];
Array.Copy(fullSector, 16, buffer, 0, 8);
break;
case SectorTagType.CdSectorEdc:
buffer = new byte[4];
if(trk.Type == TrackType.CdMode1)
Array.Copy(fullSector, 2064, buffer, 0, 4);
else if(trk.Type == TrackType.CdMode2Form1)
Array.Copy(fullSector, 2072, buffer, 0, 4);
else
return ErrorNumber.NotSupported;
break;
case SectorTagType.CdSectorEccP:
if(trk.Type == TrackType.CdMode2Formless) return ErrorNumber.NotSupported;
buffer = new byte[172];
Array.Copy(fullSector, 2076, buffer, 0, 172);
break;
case SectorTagType.CdSectorEccQ:
if(trk.Type == TrackType.CdMode2Formless) return ErrorNumber.NotSupported;
buffer = new byte[104];
Array.Copy(fullSector, 2248, buffer, 0, 104);
break;
case SectorTagType.CdSectorEcc:
if(trk.Type == TrackType.CdMode2Formless) return ErrorNumber.NotSupported;
buffer = new byte[276];
Array.Copy(fullSector, 2076, buffer, 0, 276);
break;
}
return ErrorNumber.NoError;
}
/// <inheritdoc />
public ErrorNumber ReadSectorsTag(ulong sectorAddress, uint length, uint track, SectorTagType tag,
out byte[] buffer)
{
buffer = null;
Track trk = Tracks.FirstOrDefault(t => t.Sequence == track);
if(trk is null) return ErrorNumber.SectorNotFound;
if(sectorAddress + length - 1 > trk.EndSector) return ErrorNumber.OutOfRange;
if(tag == SectorTagType.CdTrackFlags) return ReadSectorTag(sectorAddress, track, tag, out buffer);
using var ms = new MemoryStream();
for(uint i = 0; i < length; i++)
{
ErrorNumber errno = ReadSectorTag(sectorAddress + i, track, tag, out byte[] tagData);
if(errno != ErrorNumber.NoError) return errno;
ms.Write(tagData, 0, tagData.Length);
}
buffer = ms.ToArray();
return ErrorNumber.NoError;
}
/// <inheritdoc />
public ErrorNumber ReadSectorTag(ulong sectorAddress, bool negative, SectorTagType tag, out byte[] buffer)
{
buffer = null;
if(negative) return ErrorNumber.NotSupported;
Track trk = Tracks.FirstOrDefault(t => sectorAddress >= t.StartSector && sectorAddress <= t.EndSector);
if(trk is null) return ErrorNumber.SectorNotFound;
return ReadSectorTag(sectorAddress, trk.Sequence, tag, out buffer);
}
/// <inheritdoc />
public ErrorNumber ReadSectorsTag(ulong sectorAddress, bool negative, uint length, SectorTagType tag,
out byte[] buffer)
{
buffer = null;
if(negative) return ErrorNumber.NotSupported;
Track trk = Tracks.FirstOrDefault(t => sectorAddress >= t.StartSector && sectorAddress <= t.EndSector);
if(trk is null) return ErrorNumber.SectorNotFound;
return ReadSectorsTag(sectorAddress, length, trk.Sequence, tag, out buffer);
}
/// <inheritdoc />
public ErrorNumber ReadMediaTag(MediaTagType tag, out byte[] buffer)
{
buffer = null;
switch(tag)
{
case MediaTagType.CD_MCN:
if(_mcn == null) return ErrorNumber.NoData;
buffer = Encoding.ASCII.GetBytes(_mcn);
return ErrorNumber.NoError;
case MediaTagType.CD_TEXT:
if(_cdtext == null) return ErrorNumber.NoData;
buffer = _cdtext;
return ErrorNumber.NoError;
default:
return ErrorNumber.NotSupported;
}
}
/// <inheritdoc />
public List<Track> GetSessionTracks(Session session) => Tracks.Where(t => t.Session == session.Sequence).ToList();
/// <inheritdoc />
public List<Track> GetSessionTracks(ushort session) => Tracks.Where(t => t.Session == session).ToList();
}

View File

@@ -1,112 +0,0 @@
// /***************************************************************************
// Aaru Data Preservation Suite
// ----------------------------------------------------------------------------
//
// Filename : Unimplemented.cs
// Author(s) : Natalia Portillo <claunia@claunia.com>
//
// Component : Disc image plugins.
//
// --[ Description ] ----------------------------------------------------------
//
// Manages WinOnCD disc images.
//
// --[ License ] --------------------------------------------------------------
//
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 2.1 of the
// License, or (at your option) any later version.
//
// This library 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
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, see <http://www.gnu.org/licenses/>.
//
// ----------------------------------------------------------------------------
// Copyright © 2011-2026 Natalia Portillo
// ****************************************************************************/
using System;
using System.Collections.Generic;
using Aaru.CommonTypes.Enums;
using Aaru.CommonTypes.Structs;
namespace Aaru.Images;
public sealed partial class WinOnCD
{
/// <inheritdoc />
public ErrorNumber ReadMediaTag(MediaTagType tag, out byte[] buffer) => throw new NotImplementedException();
/// <inheritdoc />
public ErrorNumber
ReadSector(ulong sectorAddress, bool negative, out byte[] buffer, out SectorStatus sectorStatus) =>
throw new NotImplementedException();
/// <inheritdoc />
public ErrorNumber ReadSectorLong(ulong sectorAddress, bool negative, out byte[] buffer,
out SectorStatus sectorStatus) => throw new NotImplementedException();
/// <inheritdoc />
public ErrorNumber ReadSectors(ulong sectorAddress, bool negative, uint length, out byte[] buffer,
out SectorStatus[] sectorStatus) => throw new NotImplementedException();
/// <inheritdoc />
public ErrorNumber ReadSectorsLong(ulong sectorAddress, bool negative, uint length, out byte[] buffer,
out SectorStatus[] sectorStatus) => throw new NotImplementedException();
/// <inheritdoc />
public ErrorNumber ReadSectorsTag(ulong sectorAddress, bool negative, uint length, SectorTagType tag,
out byte[] buffer) => throw new NotImplementedException();
/// <inheritdoc />
public ErrorNumber ReadSectorTag(ulong sectorAddress, bool negative, SectorTagType tag, out byte[] buffer) =>
throw new NotImplementedException();
/// <inheritdoc />
public bool? VerifySector(ulong sectorAddress) => throw new NotImplementedException();
/// <inheritdoc />
public bool? VerifySectors(ulong sectorAddress, uint length, out List<ulong> failingLbas,
out List<ulong> unknownLbas) => throw new NotImplementedException();
/// <inheritdoc />
public ErrorNumber ReadSector(ulong sectorAddress, uint track, out byte[] buffer, out SectorStatus sectorStatus) =>
throw new NotImplementedException();
/// <inheritdoc />
public ErrorNumber ReadSectorTag(ulong sectorAddress, uint track, SectorTagType tag, out byte[] buffer) =>
throw new NotImplementedException();
/// <inheritdoc />
public ErrorNumber ReadSectors(ulong sectorAddress, uint length, uint track, out byte[] buffer,
out SectorStatus[] sectorStatus) => throw new NotImplementedException();
/// <inheritdoc />
public ErrorNumber ReadSectorsTag(ulong sectorAddress, uint length, uint track, SectorTagType tag,
out byte[] buffer) => throw new NotImplementedException();
/// <inheritdoc />
public ErrorNumber
ReadSectorLong(ulong sectorAddress, uint track, out byte[] buffer, out SectorStatus sectorStatus) =>
throw new NotImplementedException();
/// <inheritdoc />
public ErrorNumber ReadSectorsLong(ulong sectorAddress, uint length, uint track, out byte[] buffer,
out SectorStatus[] sectorStatus) => throw new NotImplementedException();
/// <inheritdoc />
public List<Track> GetSessionTracks(Session session) => throw new NotImplementedException();
/// <inheritdoc />
public List<Track> GetSessionTracks(ushort session) => throw new NotImplementedException();
/// <inheritdoc />
public bool? VerifySectors(ulong sectorAddress, uint length, uint track, out List<ulong> failingLbas,
out List<ulong> unknownLbas) => throw new NotImplementedException();
}

View File

@@ -0,0 +1,65 @@
// /***************************************************************************
// Aaru Data Preservation Suite
// ----------------------------------------------------------------------------
//
// Filename : Verify.cs
// Author(s) : Natalia Portillo <claunia@claunia.com>
//
// Component : Disc image plugins.
//
// --[ Description ] ----------------------------------------------------------
//
// Verifies WinOnCD disc images.
//
// --[ License ] --------------------------------------------------------------
//
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 2.1 of the
// License, or (at your option) any later version.
//
// This library 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
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, see <http://www.gnu.org/licenses/>.
//
// ----------------------------------------------------------------------------
// Copyright © 2011-2026 Natalia Portillo
// ****************************************************************************/
using System.Collections.Generic;
namespace Aaru.Images;
public sealed partial class WinOnCD
{
/// <inheritdoc />
public bool? VerifySector(ulong sectorAddress) => null;
/// <inheritdoc />
public bool? VerifySectors(ulong sectorAddress, uint length, out List<ulong> failingLbas,
out List<ulong> unknownLbas)
{
failingLbas = [];
unknownLbas = [];
for(ulong i = 0; i < length; i++) unknownLbas.Add(sectorAddress + i);
return null;
}
/// <inheritdoc />
public bool? VerifySectors(ulong sectorAddress, uint length, uint track, out List<ulong> failingLbas,
out List<ulong> unknownLbas)
{
failingLbas = [];
unknownLbas = [];
for(ulong i = 0; i < length; i++) unknownLbas.Add(sectorAddress + i);
return null;
}
}

View File

@@ -30,6 +30,7 @@
// Copyright © 2011-2026 Natalia Portillo
// ****************************************************************************/
using System.Collections.Generic;
using System.IO;
using Aaru.CommonTypes.Interfaces;
using Aaru.CommonTypes.Structs;
@@ -40,10 +41,14 @@ namespace Aaru.Images;
public sealed partial class WinOnCD : IOpticalMediaImage
{
const string MODULE_NAME = "WinOnCD plugin";
byte[] _cdtext;
ImageInfo _imageInfo;
Stream _imageStream;
SectorBuilder _sectorBuilder;
ImageInfo _imageInfo;
Stream _imageStream;
string _mcn;
SectorBuilder _sectorBuilder;
Dictionary<uint, byte> _trackFlags;
Dictionary<uint, string> _trackIsrcs;
public WinOnCD() => _imageInfo = new ImageInfo
{