internal unsafe void SeekTo(ulong physicalSectorNumber) { uint bytesPerSector = _geometry.BytesPerSector; ulong offset = physicalSectorNumber * bytesPerSector; if (!Natives.SetFilePointerEx(_rawHandle, (long)offset, out offset, Natives.FILE_BEGIN)) { throw new ApplicationException(); } }
/// <summary>Read some number of sectors.</summary> /// <param name="into">Pre-allocated buffer.</param> /// <param name="logicalSectorId">Logical identifier of the first sector to be read.</param> /// <param name="sectorsCount">Number of sectors to read.</param> /// <returns>Buffer address.</returns> internal unsafe IPartitionClusterData ReadSectors(IPartitionClusterData into, long atOffset, ulong logicalSectorId, uint sectorsCount = 1) { uint bytesPerSector = PartitionManager.Singleton.Geometry.BytesPerSector; uint expectedCount = sectorsCount * bytesPerSector; if (null == into) { throw new ArgumentNullException(); } if (0 > atOffset) { throw new ArgumentException(); } if ((into.DataSize - atOffset) < expectedCount) { throw new ArgumentException(); } if (FeaturesContext.DataPoolChecksEnabled) { if (expectedCount > into.DataSize) { throw new ApplicationException(); } } ulong offset = (logicalSectorId + StartSector) * bytesPerSector; uint totalBytesRead = 0; // Prevent concurrent reads on this partition. lock (_ioLock) { if (!Natives.SetFilePointerEx(_handle, (long)offset, out offset, Natives.FILE_BEGIN)) { int error = Marshal.GetLastWin32Error(); throw new ApplicationException(); } uint chainItemsCount = into.GetChainItemsCount(); uint chainLength = into.GetChainLength(); if (chainLength < expectedCount) { throw new ApplicationException(); } uint remainingExpectation = expectedCount; for (IPartitionClusterData currentData = into; null != currentData; currentData = currentData.NextInChain) { uint readSize = remainingExpectation; if (readSize > into.DataSize) { readSize = into.DataSize; } uint effectiveReadSize; if (!Natives.ReadFile(_handle, into.Data + atOffset, readSize, out effectiveReadSize, IntPtr.Zero)) { int error = Marshal.GetLastWin32Error(); throw new ApplicationException(); } atOffset += effectiveReadSize; totalBytesRead += effectiveReadSize; remainingExpectation -= effectiveReadSize; } } if (totalBytesRead != expectedCount) { throw new ApplicationException(); } return(into); }