internal byte[] ReadCluster(int index)
{
long offset = DataOffset + index * (long)ClusterSize;
BinaryReader reader = Disc.Reader;
int read;
lock (reader) {
reader.BaseStream.Position = offset + ClusterIVOffset;
reader.Read(KeyIV, 0, KeyIV.Length);
reader.BaseStream.Position = offset + ClusterDataOffset;
read = reader.Read(ClusterData, 0, ClusterDataSize);
}
ICryptoTransform decryptor = Cypher.CreateDecryptor(Key, KeyIV);
return decryptor.TransformFinalBlock(ClusterData, 0, read);
}
/// <summary>Read data from the partition.</summary> /// <param name="buffer"></param> /// <param name="offset"></param> /// <param name="count"></param> /// <returns></returns> public override int Read(byte[] buffer, int offset, int count) { int read = 0; while (count > 0) { int positionCluster = checked ((int)(PositionField / NintendoOpticalDiscPartition.ClusterDataSize)); if (ClusterIndex != positionCluster) { ClusterData = Partition.ReadCluster(positionCluster); ClusterIndex = positionCluster; } int clusterOffset = checked ((int)(PositionField - ClusterIndex * (long)NintendoOpticalDiscPartition.ClusterDataSize)); // Offset within the cluster. int toRead = Math.Min(ClusterData.Length - clusterOffset, count); ClusterData.CopyTo(clusterOffset, toRead, buffer, offset); offset += toRead; read += toRead; PositionField += toRead; count -= toRead; } return(read); }