예제 #1
0
        // Constructors

        /// <summary>
        /// DataTrack (abstract)
        /// </summary>
        /// <param name="fileStream">The iso file stream</param>
        /// <param name="trackNumber">The track number</param>
        /// <param name="system">File system used for this data track</param>
        /// <param name="mode">The sector mode of the track</param>
        internal DataTrack(FileStream fileStream, int trackNumber, DiskFileSystem system, DataTrackMode mode)
            : base(fileStream, trackNumber, TrackType.DATA)
        {
            _system     = system;
            _mode       = mode;
            _sectorSize = mode == DataTrackMode.RAW ? 2048 : 2352;
            _isXa       = false;
            _pregapSize = 150;

            switch (_mode)
            {
            case DataTrackMode.MODE1:
                _defaultSectorMode = SectorMode.MODE1;
                break;

            case DataTrackMode.MODE2:
                _defaultSectorMode = SectorMode.MODE2;
                break;

            case DataTrackMode.MODE2_XA:
                _defaultSectorMode = SectorMode.XA_FORM1;
                _isXa = true;
                break;

            case DataTrackMode.RAW:
            default:
                _defaultSectorMode = SectorMode.RAW;
                break;
            }
        }
예제 #2
0
        /// <summary>
        /// Read a file
        /// </summary>
        /// <param name="lba">Sector's lba</param>
        /// <param name="size">The size of the file</param>
        /// <param name="mode">Sector's mode</param>
        /// <param name="stream">The stream to write the data</param>
        public void ReadFile(long lba, long size, SectorMode mode, Stream stream)
        {
            int  sectorDataSize = GetSectorDataSize(mode);
            long bytesRead      = 0;

            SeekSector(lba);

            long remaining;

            while (bytesRead < size)
            {
                remaining = size - bytesRead;
                if (remaining >= sectorDataSize)
                {
                    stream.Write(ReadSector(mode), 0, sectorDataSize);
                }
                else
                {
                    stream.Write(ReadSector(mode), 0, (int)remaining);
                }

                bytesRead += sectorDataSize;
            }

            stream.Flush();
        }
예제 #3
0
 internal void Clear()
 {
     for (int i = 0; i < this.Memory.Length; i++)
     {
         this.Memory[i] = 0;
     }
     this.Mode = SectorMode.Empty;
 }
예제 #4
0
        // Methods

        /// <summary>
        /// Read a sector's data
        /// </summary>
        /// <param name="mode">Sector's mode</param>
        public byte[] ReadSector(SectorMode mode)
        {
            try
            {
                byte[] buffer;

                int dataSize = GetSectorDataSize(mode);
                buffer = new byte[dataSize];

                if (mode != SectorMode.RAW)
                {
                    _stream.Position += (SYNC_SIZE + HEADER_SIZE);
                }

                if (mode == SectorMode.XA_FORM1 || mode == SectorMode.XA_FORM2)
                {
                    _stream.Position += SUBHEADER_SIZE;
                }

                _stream.Read(buffer, 0, dataSize);

                if (mode == SectorMode.MODE1 || mode == SectorMode.XA_FORM1)
                {
                    _stream.Position += EDC_SIZE;
                }

                if (mode == SectorMode.MODE1)
                {
                    _stream.Position += INTERMEDIATE_SIZE;
                }

                if (mode == SectorMode.MODE1 || mode == SectorMode.XA_FORM1)
                {
                    _stream.Position += ECC_SIZE;
                }

                if (mode == SectorMode.XA_FORM2)
                {
                    _stream.Position += EDC_SIZE;
                }

                return(buffer);
            }
            catch (FrameworkException ex)
            {
                throw ex;
            }
            catch (EndOfStreamException)
            {
                throw new FrameworkException("Errow while reading sector : end of file occured");
            }
            catch (Exception)
            {
                throw new FrameworkException("Errow while reading sector : unable to read sector");
            }
        }
예제 #5
0
        /// <summary>
        /// Write a sector
        /// </summary>
        /// <param name="data">The sector's data to write</param>
        /// <param name="mode">Sector's mode</param>
        /// <param name="subHeader">Subheader (if mode XA_FORM1 or XA_FORM2)</param>
        public void WriteSector(byte[] data, SectorMode mode, XaSubHeader subHeader = null)
        {
            try
            {
                byte[] buffer = new byte[_sectorSize];
                using (var bufferStream = new CBinaryWriter(buffer))
                {
                    if (mode != SectorMode.RAW)
                    {
                        bufferStream.Write(SYNC);
                        long   position = SectorPosition + 150;
                        byte[] header   = new byte[4];
                        header[3] = (byte)(mode == SectorMode.MODE0 ? 0 : mode == SectorMode.MODE1 ? 1 : 2);
                        header[2] = Converter.DecToBcd((byte)(position % 75)); position /= 75;
                        header[1] = Converter.DecToBcd((byte)(position % 60)); position /= 60;
                        header[0] = Converter.DecToBcd((byte)(position % 60));
                        bufferStream.Write(header);
                    }

                    if (mode == SectorMode.XA_FORM1 || mode == SectorMode.XA_FORM2)
                    {
                        if (subHeader == null)
                        {
                            subHeader = new XaSubHeader();
                        }
                        subHeader.IsForm2 = (mode == SectorMode.XA_FORM2);

                        bufferStream.Write(subHeader.File);
                        bufferStream.Write(subHeader.Channel);
                        bufferStream.Write(subHeader.SubMode);
                        bufferStream.Write(subHeader.DataType);

                        // Subheader is written twice
                        bufferStream.Write(subHeader.File);
                        bufferStream.Write(subHeader.Channel);
                        bufferStream.Write(subHeader.SubMode);
                        bufferStream.Write(subHeader.DataType);
                    }

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

                    if (mode == SectorMode.MODE1 || mode == SectorMode.XA_FORM1 || mode == SectorMode.XA_FORM2)
                    {
                        EccEdc.EccEdcCompute(buffer, mode);
                    }

                    _stream.Write(buffer);
                }
            }
            catch (Exception)
            {
                throw new FrameworkException("Errow while writing sector : unable to write sector");
            }
        }
예제 #6
0
        /// <summary>
        /// Read several consecutives sectors's data
        /// </summary>
        /// <param name="count">Number of sectors to read</param>
        /// <param name="mode">Sector's mode</param>
        public byte[] ReadSectors(int count, SectorMode mode)
        {
            int dataSize = GetSectorDataSize(mode);

            byte[] data = new byte[count * dataSize];

            for (int i = 0, offset = 0; i < count; i++, offset += dataSize)
            {
                CBuffer.Copy(ReadSector(mode), data, 0, offset);
            }

            return(data);
        }
예제 #7
0
        // Méthods

        /// <summary>
        /// Get the sector data size
        /// </summary>
        /// <param name="size"></param>
        /// <param name="mode"></param>
        /// <returns></returns>
        internal static int GetSectorDataSize(SectorMode mode)
        {
            switch (mode)
            {
            case SectorMode.MODE2:
                return(2336);

            case SectorMode.XA_FORM2:
                return(2324);

            default:
                return(2048);
            }
        }
예제 #8
0
 /// <summary>
 /// Copy sectors from another disk
 /// </summary>
 /// <param name="diskIn">The disk to copy sectors from</param>
 /// <param name="mode">Sector's mode</param>
 /// <param name="count">Number of sectors to copy</param>
 public void CopySectors(DataTrackReader diskIn, SectorMode mode, int count)
 {
     if (diskIn.IsXa)
     {
         XaSubHeader subHeader;
         for (int i = 0; i < count; i++)
         {
             WriteSector(diskIn.ReadSector(mode, out subHeader), mode, subHeader);
         }
     }
     else
     {
         for (int i = 0; i < count; i++)
         {
             WriteSector(diskIn.ReadSector());
         }
     }
 }
예제 #9
0
        /// <summary>
        /// Compute Ecc/edc for the given sector
        /// </summary>
        /// <param name="sector">The sector</param>
        internal static void EccEdcCompute(byte[] sector, SectorMode mode)
        {
            switch (mode)
            {
            case SectorMode.MODE1:
                EdcBlockCompute(sector, 0, DataTrack.GetSectorDataSize(mode) + 16);
                EccCompute(sector);
                break;

            case SectorMode.XA_FORM1:
                EdcBlockCompute(sector, 16, DataTrack.SUBHEADER_SIZE + DataTrack.GetSectorDataSize(mode));
                _headerBackup[0] = sector[12]; _headerBackup[1] = sector[13]; _headerBackup[2] = sector[14]; _headerBackup[3] = sector[15];
                sector[12]       = sector[13] = sector[14] = sector[15] = 0;
                EccCompute(sector);
                sector[12] = _headerBackup[0]; sector[13] = _headerBackup[1]; sector[14] = _headerBackup[2]; sector[15] = _headerBackup[3];
                break;

            case SectorMode.XA_FORM2:
                EdcBlockCompute(sector, 16, DataTrack.SUBHEADER_SIZE + DataTrack.GetSectorDataSize(mode));
                break;
            }
        }
예제 #10
0
 /// <summary>
 /// Copy sectors from another disk
 /// </summary>
 /// <param name="reader">The disk to copy sectors from</param>
 /// <param name="mode">Sector's mode</param>
 /// <param name="readerLba">Starting LBA for reading</param>
 /// <param name="writerLba">Starting LBA for writing</param>
 /// <param name="count">Number of sectors to copy</param>
 public void CopySectors(DataTrackReader reader, SectorMode mode, long readerLba, long writerLba, int count)
 {
     SeekSector(writerLba);
     reader.SeekSector(readerLba);
     CopySectors(reader, mode, count);
 }
예제 #11
0
 /// <summary>
 /// Write a sector at the specified lba
 /// </summary>
 /// <param name="lba">Sector's LBA</param>
 /// <param name="data">The sector to write</param>
 /// <param name="mode">Sector's mode</param>
 /// <param name="subHeader">Subheader (if mode XA_FORM1 or XA_FORM2)</param>
 public void WriteSector(long lba, byte[] data, SectorMode mode, XaSubHeader subHeader = null)
 {
     SeekSector(lba);
     WriteSector(data, mode, subHeader);
 }
예제 #12
0
 internal cSector()
 {
     Memory = new ushort[512];
     Mode   = SectorMode.Empty;
 }
예제 #13
0
 /// <summary>
 /// Read several consecutives sectors data (only data : does not include modes specifics fields)
 /// </summary>
 /// <param name="lba">Starting sector's LBA</param>
 /// <param name="count">Number of sectors to read</param>
 /// <param name="mode">Sector's mode</param>
 public byte[] ReadSectors(long lba, int count, SectorMode mode)
 {
     SeekSector(lba);
     return(ReadSectors(count, mode));
 }
예제 #14
0
 /// <summary>
 /// Read a sector's data, including sub header
 /// </summary>
 /// <param name="lba">Sector's LBA to read</param>
 /// <param name="mode">Sector's mode</param>
 /// <param name="subHeader">Sub header container to write sub header to</param>
 public byte[] ReadSector(long lba, SectorMode mode, out XaSubHeader subHeader)
 {
     SeekSector(lba);
     return(ReadSector(mode, out subHeader));
 }
예제 #15
0
 /// <summary>
 /// Read a sector's data
 /// </summary>
 /// <param name="lba">Sector's LBA to read</param>
 /// <param name="mode">Sector's mode</param>
 public byte[] ReadSector(long lba, SectorMode mode)
 {
     SeekSector(lba);
     return(ReadSector(mode));
 }