// 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; } }
/// <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(); }
internal void Clear() { for (int i = 0; i < this.Memory.Length; i++) { this.Memory[i] = 0; } this.Mode = SectorMode.Empty; }
// 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"); } }
/// <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"); } }
/// <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); }
// 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); } }
/// <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()); } } }
/// <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; } }
/// <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); }
/// <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); }
internal cSector() { Memory = new ushort[512]; Mode = SectorMode.Empty; }
/// <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)); }
/// <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)); }
/// <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)); }