public byte[] ReadSectorsTag(ulong sectorAddress, uint length, SectorTagType tag) =>
 throw new FeatureUnsupportedImageException("Feature not supported by image format");
Beispiel #2
0
 public bool WriteSectorsTag(byte[] data, ulong sectorAddress, uint length, SectorTagType tag)
 {
     ErrorMessage = "Unsupported feature";
     return(false);
 }
Beispiel #3
0
        public bool WriteSectorsTag(byte[] data, ulong sectorAddress, uint length, SectorTagType tag)
        {
            if (!IsWriting)
            {
                ErrorMessage = "Tried to write on a non-writable image";
                return(false);
            }

            Track track =
                Tracks.FirstOrDefault(trk => sectorAddress >= trk.TrackStartSector &&
                                      sectorAddress <= trk.TrackEndSector);

            if (track.TrackSequence == 0)
            {
                ErrorMessage = $"Can't found track containing {sectorAddress}";
                return(false);
            }

            switch (tag)
            {
            case SectorTagType.CdTrackFlags:
            case SectorTagType.CdTrackIsrc: return(WriteSectorTag(data, sectorAddress, tag));

            case SectorTagType.CdSectorSubchannel:
            {
                if (track.TrackSubchannelType == 0)
                {
                    ErrorMessage =
                        $"Trying to write subchannel to track {track.TrackSequence}, that does not have subchannel";
                    return(false);
                }

                if (data.Length % 96 != 0)
                {
                    ErrorMessage = "Incorrect data size for subchannel";
                    return(false);
                }

                if (subStream == null)
                {
                    try
                    {
                        subStream = new FileStream(writingBaseName + ".sub", FileMode.OpenOrCreate,
                                                   FileAccess.ReadWrite, FileShare.None);
                    }
                    catch (IOException e)
                    {
                        ErrorMessage = $"Could not create subchannel file, exception {e.Message}";
                        return(false);
                    }
                }

                subStream.Seek((long)(track.TrackSubchannelOffset + (sectorAddress - track.TrackStartSector) * 96),
                               SeekOrigin.Begin);
                subStream.Write(data, 0, data.Length);

                return(true);
            }

            default:
                ErrorMessage = $"Unsupported tag type {tag}";
                return(false);
            }
        }
Beispiel #4
0
        public bool WriteSectorTag(byte[] data, ulong sectorAddress, SectorTagType tag)
        {
            if (!IsWriting)
            {
                ErrorMessage = "Tried to write on a non-writable image";
                return(false);
            }

            Track track =
                writingTracks.FirstOrDefault(trk => sectorAddress >= trk.TrackStartSector &&
                                             sectorAddress <= trk.TrackEndSector);

            if (track.TrackSequence == 0)
            {
                ErrorMessage = $"Can't found track containing {sectorAddress}";
                return(false);
            }

            switch (tag)
            {
            case SectorTagType.CdTrackFlags:
            {
                if (data.Length != 1)
                {
                    ErrorMessage = "Incorrect data size for track flags";
                    return(false);
                }

                trackFlags.Add((byte)track.TrackSequence, data[0]);

                return(true);
            }

            case SectorTagType.CdSectorSubchannel:
            {
                if (track.TrackSubchannelType == 0)
                {
                    ErrorMessage =
                        $"Trying to write subchannel to track {track.TrackSequence}, that does not have subchannel";
                    return(false);
                }

                if (data.Length != 96)
                {
                    ErrorMessage = "Incorrect data size for subchannel";
                    return(false);
                }

                imageStream
                .Seek((long)(track.TrackFileOffset + (sectorAddress - track.TrackStartSector) * (ulong)(track.TrackRawBytesPerSector + 96)) + track.TrackRawBytesPerSector,
                      SeekOrigin.Begin);
                imageStream.Write(data, 0, data.Length);

                return(true);
            }

            default:
                ErrorMessage = $"Unsupported tag type {tag}";
                return(false);
            }
        }
Beispiel #5
0
 public byte[] ReadSectorsTag(ulong sectorAddress, uint length, SectorTagType tag) =>
 throw new NotImplementedException("Flux decoding is not yet implemented.");
Beispiel #6
0
 public byte[] ReadSectorTag(ulong sectorAddress, SectorTagType tag)
 {
     return(ReadSectorsTag(sectorAddress, 1, tag));
 }
Beispiel #7
0
        public bool WriteSectorsTag(byte[] data, ulong sectorAddress, uint length, SectorTagType tag)
        {
            if (!IsWriting)
            {
                ErrorMessage = "Tried to write on a non-writable image";

                return(false);
            }

            Track track =
                writingTracks.FirstOrDefault(trk => sectorAddress >= trk.TrackStartSector &&
                                             sectorAddress <= trk.TrackEndSector);

            if (track.TrackSequence == 0)
            {
                ErrorMessage = $"Can't found track containing {sectorAddress}";

                return(false);
            }

            switch (tag)
            {
            case SectorTagType.CdTrackFlags:
            case SectorTagType.CdTrackIsrc: return(WriteSectorTag(data, sectorAddress, tag));

            case SectorTagType.CdSectorSubchannel:
            {
                if (track.TrackSubchannelType == 0)
                {
                    ErrorMessage =
                        $"Trying to write subchannel to track {track.TrackSequence}, that does not have subchannel";

                    return(false);
                }

                if (data.Length % 96 != 0)
                {
                    ErrorMessage = "Incorrect data size for subchannel";

                    return(false);
                }

                FileStream trackStream = writingStreams.FirstOrDefault(kvp => kvp.Key == track.TrackSequence).Value;

                if (trackStream == null)
                {
                    ErrorMessage = $"Can't found file containing {sectorAddress}";

                    return(false);
                }

                for (uint i = 0; i < length; i++)
                {
                    trackStream.
                    Seek((long)(track.TrackFileOffset + (((i + sectorAddress) - track.TrackStartSector) * (ulong)(track.TrackRawBytesPerSector + 96))) + track.TrackRawBytesPerSector,
                         SeekOrigin.Begin);

                    trackStream.Write(data, (int)(i * 96), 96);
                }

                return(true);
            }

            default:
                ErrorMessage = $"Unsupported tag type {tag}";

                return(false);
            }
        }
Beispiel #8
0
 public byte[] ReadSectorTag(ulong sectorAddress, SectorTagType tag) => ReadSectorsTag(sectorAddress, 1, tag);
Beispiel #9
0
 public bool WriteSectorsTag(byte[] data, ulong sectorAddress, uint length, SectorTagType tag) =>
 WriteSectorTag(data, sectorAddress, tag);
Beispiel #10
0
        public byte[] ReadSectorsTag(ulong sectorAddress, uint length, uint track, SectorTagType tag)
        {
            if (track == 0)
            {
                if (sectorAddress + length > densitySeparationSectors)
                {
                    throw new ArgumentOutOfRangeException(nameof(length),
                                                          "Requested more sectors than present in track, won't cross tracks");
                }

                if (tag == SectorTagType.CdTrackFlags)
                {
                    return new byte[] { 0x00 }
                }
                ;

                throw new ArgumentException("Unsupported tag requested for this track", nameof(tag));
            }

            GdiTrack dicTrack = new GdiTrack {
                Sequence = 0
            };

            foreach (GdiTrack gdiTrack in discimage.Tracks.Where(gdiTrack => gdiTrack.Sequence == track))
            {
                dicTrack = gdiTrack;
                break;
            }

            if (dicTrack.Sequence == 0)
            {
                throw new ArgumentOutOfRangeException(nameof(track), "Track does not exist in disc image");
            }

            if (length > dicTrack.Sectors)
            {
                throw new ArgumentOutOfRangeException(nameof(length),
                                                      "Requested more sectors than present in track, won't cross tracks");
            }

            uint sectorOffset;
            uint sectorSize;
            uint sectorSkip;

            switch (tag)
            {
            case SectorTagType.CdSectorEcc:
            case SectorTagType.CdSectorEccP:
            case SectorTagType.CdSectorEccQ:
            case SectorTagType.CdSectorEdc:
            case SectorTagType.CdSectorHeader:
            case SectorTagType.CdSectorSync: break;

            case SectorTagType.CdTrackFlags:
            {
                byte[] flags = new byte[1];

                flags[0] += dicTrack.Flags;

                return(flags);
            }

            default: throw new ArgumentException("Unsupported tag requested", nameof(tag));
            }

            switch (dicTrack.Tracktype)
            {
            case TrackType.Audio: throw new ArgumentException("There are no tags on audio tracks", nameof(tag));

            case TrackType.CdMode1:
            {
                if (dicTrack.Bps != 2352)
                {
                    throw new FeatureNotPresentImageException("Image does not include tags for mode 1 sectors");
                }

                switch (tag)
                {
                case SectorTagType.CdSectorSync:
                {
                    sectorOffset = 0;
                    sectorSize   = 12;
                    sectorSkip   = 2340;
                    break;
                }

                case SectorTagType.CdSectorHeader:
                {
                    sectorOffset = 12;
                    sectorSize   = 4;
                    sectorSkip   = 2336;
                    break;
                }

                case SectorTagType.CdSectorSubchannel:
                case SectorTagType.CdSectorSubHeader:
                    throw new ArgumentException("Unsupported tag requested for this track", nameof(tag));

                case SectorTagType.CdSectorEcc:
                {
                    sectorOffset = 2076;
                    sectorSize   = 276;
                    sectorSkip   = 0;
                    break;
                }

                case SectorTagType.CdSectorEccP:
                {
                    sectorOffset = 2076;
                    sectorSize   = 172;
                    sectorSkip   = 104;
                    break;
                }

                case SectorTagType.CdSectorEccQ:
                {
                    sectorOffset = 2248;
                    sectorSize   = 104;
                    sectorSkip   = 0;
                    break;
                }

                case SectorTagType.CdSectorEdc:
                {
                    sectorOffset = 2064;
                    sectorSize   = 4;
                    sectorSkip   = 284;
                    break;
                }

                default: throw new ArgumentException("Unsupported tag requested", nameof(tag));
                }

                break;
            }

            default: throw new FeatureSupportedButNotImplementedImageException("Unsupported track type");
            }

            byte[] buffer = new byte[sectorSize * length];

            ulong remainingSectors = length;

            if (dicTrack.Pregap > 0 && sectorAddress < dicTrack.Pregap)
            {
                ulong  remainingPregap = dicTrack.Pregap - sectorAddress;
                byte[] zero;
                if (length > remainingPregap)
                {
                    zero              = new byte[remainingPregap * sectorSize];
                    remainingSectors -= remainingPregap;
                }
                else
                {
                    zero              = new byte[length * sectorSize];
                    remainingSectors -= length;
                }

                Array.Copy(zero, 0, buffer, 0, zero.Length);
            }

            if (remainingSectors == 0)
            {
                return(buffer);
            }

            imageStream = dicTrack.Trackfilter.GetDataForkStream();
            BinaryReader br = new BinaryReader(imageStream);

            br.BaseStream
            .Seek(dicTrack.Offset + (long)(sectorAddress * (sectorOffset + sectorSize + sectorSkip) + dicTrack.Pregap * dicTrack.Bps),
                  SeekOrigin.Begin);
            if (sectorOffset == 0 && sectorSkip == 0)
            {
                buffer = br.ReadBytes((int)(sectorSize * remainingSectors));
            }
            else
            {
                for (ulong i = 0; i < remainingSectors; i++)
                {
                    br.BaseStream.Seek(sectorOffset, SeekOrigin.Current);
                    byte[] sector = br.ReadBytes((int)sectorSize);
                    br.BaseStream.Seek(sectorSkip, SeekOrigin.Current);
                    Array.Copy(sector, 0, buffer, (int)(i * sectorSize), sectorSize);
                }
            }

            return(buffer);
        }
Beispiel #11
0
        public bool WriteSectorsTag(byte[] data, ulong sectorAddress, uint length, SectorTagType tag)
        {
            ErrorMessage = "Writing sectors with tags is not supported.";

            return(false);
        }
Beispiel #12
0
        public bool WriteSectorTag(byte[] data, ulong sectorAddress, SectorTagType tag)
        {
            if (!IsWriting)
            {
                ErrorMessage = "Tried to write on a non-writable image";

                return(false);
            }

            Track track =
                _writingTracks.FirstOrDefault(trk => sectorAddress >= trk.TrackStartSector &&
                                              sectorAddress <= trk.TrackEndSector);

            if (track is null)
            {
                ErrorMessage = $"Can't found track containing {sectorAddress}";

                return(false);
            }

            switch (tag)
            {
            case SectorTagType.CdTrackFlags:
            {
                if (data.Length != 1)
                {
                    ErrorMessage = "Incorrect data size for track flags";

                    return(false);
                }

                _trackFlags[(byte)sectorAddress] = data[0];

                return(true);
            }

            case SectorTagType.CdTrackIsrc:
            {
                if (data != null)
                {
                    _trackIsrcs[(byte)sectorAddress] = Encoding.UTF8.GetString(data);
                }

                return(true);
            }

            case SectorTagType.CdSectorSubchannel:
            {
                if (track.TrackSubchannelType == 0)
                {
                    ErrorMessage =
                        $"Trying to write subchannel to track {track.TrackSequence}, that does not have subchannel";

                    return(false);
                }

                if (data.Length != 96)
                {
                    ErrorMessage = "Incorrect data size for subchannel";

                    return(false);
                }

                FileStream trackStream =
                    _writingStreams.FirstOrDefault(kvp => kvp.Key == track.TrackSequence).Value;

                if (trackStream == null)
                {
                    ErrorMessage = $"Can't found file containing {sectorAddress}";

                    return(false);
                }

                trackStream.
                Seek((long)(track.TrackFileOffset + ((sectorAddress - track.TrackStartSector) * (ulong)(track.TrackRawBytesPerSector + 96))) + track.TrackRawBytesPerSector,
                     SeekOrigin.Begin);

                trackStream.Write(data, 0, data.Length);

                return(true);
            }

            default:
                ErrorMessage = $"Unsupported tag type {tag}";

                return(false);
            }
        }