// I dont' know why I'VariousFunctions even going to bother with this function. // I don't think I'VariousFunctions going to ever use it. public override int ReadByte() { // Check if we're at the edge of a cluster... if (RealOffset == VariousFunctions.UpToNearestClusterForce(RealSectorOffset, xFile.PartitionInfo.ClusterSize)) { Underlying.Position = VariousFunctions.GetBlockOffset(xFile.BlocksOccupied[DetermineBlockIndex(VariousFunctions.UpToNearestClusterForce(RealSectorOffset, xFile.PartitionInfo.ClusterSize))], xFile); xPositionInFile++; return(Underlying.ReadByte()); } // Check if we're at the beginning of a sector... if (RealOffset == VariousFunctions.DownToNearest200(RealOffset)) { xPositionInFile++; return(Underlying.ReadByte()); } // We aren't at the beginning of a sector, and we're not at the end of a cluster // We must be somewhere in-between, so we've got to do some hax. byte[] b = new byte[1]; Read(b, 0, 1); return((int)b[0]); // I think I made it return that first byte for some reason, but idk // oh yeeeuh, I wanted it to read from the nearest 0x200 byte boundary // so if we keep calling .ReadByte() it would have that shit cached // idk why i didn't do that int index = (int)(RealOffset - RealSectorOffset); if (Position.DownToNearest200() == PreviouslyReadOffset && index < PreviouslyRead.Length) { xPositionInFile++; return((int)PreviouslyRead[index]); } else { byte[] buffer = new byte[0]; // Read the buffer if (Length - Position >= 0x200) { buffer = new byte[0x200]; } else { buffer = new byte[(Length - Position)]; } index = (int)(RealOffset - RealSectorOffset); Read(buffer, 0, buffer.Length); try { Position -= buffer.Length - 1; } catch { } // Set the previously read to thissssssssss PreviouslyRead = buffer; PreviouslyReadOffset = Position.DownToNearest200(); // Return the value at the index we should be at return((int)buffer[index]); } }
long GetRealSectorOffset(long off) { // Get the size up to the nearest cluster // Divide by cluster size // That is the block index. long SizeInCluster = VariousFunctions.DownToNearest200(off - VariousFunctions.DownToNearestCluster(off, xFile.PartitionInfo.ClusterSize));//VariousFunctions.GetBlockOffset(xFile.StartingCluster) + 0x4000; long SizeInCluster = VariousFunctions.DownToNearestCluster(off, xFile.PartitionInfo.ClusterSize) / xFile.PartitionInfo.ClusterSize) uint Cluster = (uint)(VariousFunctions.DownToNearestCluster(off, xFile.PartitionInfo.ClusterSize) / xFile.PartitionInfo.ClusterSize); //Cluster = (Cluster == 0) ? 0 : Cluster - 1; try { long Underlying = VariousFunctions.GetBlockOffset(xFile.BlocksOccupied[Cluster], xFile); return(Underlying + SizeInCluster); } catch { return(VariousFunctions.GetBlockOffset(xFile.BlocksOccupied[Cluster - 1], xFile)); } }
public override int Read(byte[] array, int offset, int count) { // If we're at the end of the stream, just return 0 since we can't read beyond it! if (this.Position == this.Length) { return(0); } // This will represent the amount of data we read, and will be our return value. int DataRead = 0; // This will act as our "resetting" at the end long InitialPosition = Position; // This int will represent the amount of data we have to remove off of the // beginning of the initial read array, due to not being in a 0-based offset int beginningDataToRemove = (int)(Position - VariousFunctions.DownToNearest200(Position)); // Pseudocount is basically there to check and see if ClustersSpanned will be greater than what it should be int Pseudocount = (int)(count + (Position - VariousFunctions.DownToNearestCluster(Position, xFile.PartitionInfo.ClusterSize))); // Used for keeping the original pseudocount in the loop int RealPseudocount = (int)(count + VariousFunctions.DownToNearestCluster(Position, xFile.PartitionInfo.ClusterSize)); bool EndingCluster = false; if (Pseudocount > Length) { Pseudocount = (int)(VariousFunctions.DownToNearestCluster(Length - Position, xFile.PartitionInfo.ClusterSize) + VariousFunctions.UpToNearestCluster((Length - Position), xFile.PartitionInfo.ClusterSize)); RealPseudocount = (int)(Length - Position); EndingCluster = true; } // This int will represent the number of clusters that our data spans int ClustersSpanned = (int)ClusterSpanned(Pseudocount); #if DEBUG System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch(); sw.Start(); #endif for (int i = 0; i < ClustersSpanned && (count - DataRead) > 0; i++) { // This int will represent the amount of data that we can read in this cluster int DataReadableCluster = (int)(xFile.PartitionInfo.ClusterSize - (Position - VariousFunctions.DownToNearestCluster(Position, xFile.PartitionInfo.ClusterSize))).UpToNearest200(); // This int will represent the amount of data we need to add to the array int AddToArray = DataReadableCluster; // If that number right above is going to be too much data than we need, let's shrink it down if (DataReadableCluster > RealPseudocount - DataRead) { DataReadableCluster = (int)VariousFunctions.UpToNearest200(beginningDataToRemove + (RealPseudocount - DataRead)); // Looks like we're on the last readthrough! AddToArray = RealPseudocount - DataRead; } else if (DataReadableCluster > count - DataRead) { DataReadableCluster = (int)VariousFunctions.UpToNearest200(beginningDataToRemove + (count - DataRead)); // Looks like we're on the last readthrough! AddToArray = count - DataRead; } else if (i == 0 && Position + DataReadableCluster + AddToArray - beginningDataToRemove > xFile.PartitionInfo.ClusterSize) { // Leave datareadablecluster alone, change the addtoarray value AddToArray -= beginningDataToRemove; } if (AddToArray == 0) { break; } // This array will represent a temp array for holding the data to copy // to the array PASSED in the arguments byte[] TempData = new byte[DataReadableCluster]; // Set our IO position Underlying.Position = GetRealSectorOffset(xPositionInFile); // If we've already read this data... if (LastRead200Offset == Underlying.Position && DataReadableCluster <= 0x200) { // Save us a disk I/O operation! TempData = LastRead200; } else { // Set the LastRead200Offset LastRead200Offset = (AddToArray <= 0x200) ? Underlying.Position : LastRead200Offset; // Read the data Underlying.Read(TempData, 0, DataReadableCluster); // Set the LastRead200 data if (AddToArray <= 0x200) { Array.Copy(TempData, LastRead200, 0x200); } } #if !DEBUG && !TRACE if (xFile.Parent.Name == "FFFE07D1") { byte[] TempDebug = new byte[AddToArray]; Array.Copy(TempData, beginningDataToRemove, TempDebug, 0, AddToArray); uint CRC = Crc32.Compute(TempDebug); byte[] RealFileBuffer = new byte[AddToArray]; FileStream fs = System.IO.File.Open(@"C:\Users\Lander\Desktop\E886364B9B6A4F3A", FileMode.Open); fs.Position = Position; fs.Read(RealFileBuffer, 0, AddToArray); fs.Close(); uint RealCRC = Crc32.Compute(RealFileBuffer); } #endif // Copy the data we read (or got somehow!) over to the output array try { Array.Copy(TempData, ((i == 0) ? beginningDataToRemove : 0), array, offset + DataRead, AddToArray); } catch (Exception e) { throw e; } #if !DEBUG && !TRACE if (xFile.Parent.Name == "FFFE07D1") { byte[] TempDebug = new byte[DataRead]; Array.Copy(array, TempDebug, DataRead); uint CRC = Crc32.Compute(TempDebug); FileStream fs = System.IO.File.Open(@"C:\Users\Lander\Desktop\E886364B9B6A4F3A", FileMode.Open); fs.Position = InitialPosition; byte[] RealFileBuffer = new byte[DataRead]; fs.Read(RealFileBuffer, 0, DataRead); fs.Close(); uint RealCRC = Crc32.Compute(RealFileBuffer); } #endif // Increase the DataRead value DataRead += AddToArray; // Increase the position in the file Position = InitialPosition + DataRead; } Position = InitialPosition + DataRead; return(DataRead); }