Why is a raw disk read in C # read from a slightly offset bias?

I am trying to read a raw disk. I successfully opened the disk and received a valid descriptor ( CreateFile ), set the offset for this descriptor to zero ( SetFilePointerEx ) and read the data into the Byte[] buffer ( ReadFile ). So far, so good. But for some unknown reason, when I compare the buffer (for a while I understood it), as shown by third-party utilities (Disc Investigator). It does not contain boot information (jump command), but corrects the data on the disk, but starts at offset 85 = 0x55 . So, somewhere in the middle of the boot information of the volume.

Why? Is there something I'm missing (obviously me)?

System: Windows 8 (on VmWare workstation)

code:

 // moves the pointer to a given offset Int64 offset = 0; Int64 newOffset; Int32 bufferSize = (Int32) clusterSizeInBytes; SetFilePointerEx(driveHandle.Handle, offset, out newOffset, WinMoveMethod.Begin); Int32 error = Marshal.GetLastWin32Error(); // reads the raw buffer Int32 numberOfBytesRead; rawData = new Byte[bufferSize]; Boolean result = ReadFile(driveHandle.Handle, rawData, bufferSize, out numberOfBytesRead, IntPtr.Zero); 

CreateFile (elsewhere)

 driveHandle = CreateFile("\\.\PhysicalDrive1", WinFileAccessMode.GenericRead, WinFileSharedAccess.All, IntPtr.Zero, WinFileMode.OpenExisting, WinFileAttribute.None, IntPtr.Zero); 

PInvoke Methods:

 [DllImport("kernel32.dll", SetLastError = true)] public static extern Boolean SetFilePointerEx( [In] SafeFileHandle fileHandle, [In] Int64 distanceToMove, [Out] out Int64 newOffset, [In] WinMoveMethod moveMethod); [DllImport("kernel32", SetLastError = true)] public extern static Boolean ReadFile( [In] SafeFileHandle handle, [Out] Byte[] buffer, [In] Int32 numBytesToRead, [Out] out Int32 numBytesRead, [In] IntPtr overlapped); 

Lists:

 public enum WinMoveMethod : uint { Begin = 0, Current = 1, End = 2 } 
+4
source share
1 answer

Unable to find library using DiskLib namespace. I can’t check it or download it completely now, even I don’t know anymore who wrote this piece of code, but the lines that may seem interesting

 public class DiskStream : Stream { public const int DEFAULT_SECTOR_SIZE = 512; private const int BUFFER_SIZE = 4096; private string diskID; private DiskInfo diskInfo; private FileAccess desiredAccess; private SafeFileHandle fileHandle; public DiskInfo DiskInfo { get { return this.diskInfo; } } public uint SectorSize { get { return this.diskInfo.BytesPerSector; } } public DiskStream(string diskID, FileAccess desiredAccess) { this.diskID = diskID; this.diskInfo = new DiskInfo(diskID); this.desiredAccess = desiredAccess; // if desiredAccess is Write or Read/Write // find volumes on this disk // lock the volumes using FSCTL_LOCK_VOLUME // unlock the volumes on Close() or in destructor this.fileHandle = this.openFile(diskID, desiredAccess); } private SafeFileHandle openFile(string id, FileAccess desiredAccess) { uint access; switch (desiredAccess) { case FileAccess.Read: access = DeviceIO.GENERIC_READ; break; case FileAccess.Write: access = DeviceIO.GENERIC_WRITE; break; case FileAccess.ReadWrite: access = DeviceIO.GENERIC_READ | DeviceIO.GENERIC_WRITE; break; default: access = DeviceIO.GENERIC_READ; break; } SafeFileHandle ptr = DeviceIO.CreateFile( id, access, DeviceIO.FILE_SHARE_READ, IntPtr.Zero, DeviceIO.OPEN_EXISTING, DeviceIO.FILE_FLAG_NO_BUFFERING | DeviceIO.FILE_FLAG_WRITE_THROUGH, IntPtr.Zero); if (ptr.IsInvalid) { Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error()); } return ptr; } public override bool CanRead { get { return (this.desiredAccess == FileAccess.Read || this.desiredAccess == FileAccess.ReadWrite) ? true : false; } } public override bool CanWrite { get { return (this.desiredAccess == FileAccess.Write || this.desiredAccess == FileAccess.ReadWrite) ? true : false; } } public override bool CanSeek { get { return true; } } public override long Length { get { return (long)this.Length; } } public ulong LengthU { get { return this.diskInfo.Size; } } public override long Position { get { return (long)PositionU; } set { PositionU = (ulong)value; } } public ulong PositionU { get { ulong n = 0; if (!DeviceIO.SetFilePointerEx(this.fileHandle, 0, out n, (uint)SeekOrigin.Current)) Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error()); return n; } set { if (value > (this.LengthU - 1)) throw new EndOfStreamException("Cannot set position beyond the end of the disk."); ulong n = 0; if (!DeviceIO.SetFilePointerEx(this.fileHandle, value, out n, (uint)SeekOrigin.Begin)) Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error()); } } public override void Flush() { // not required, since FILE_FLAG_WRITE_THROUGH and FILE_FLAG_NO_BUFFERING are used //if (!Unmanaged.FlushFileBuffers(this.fileHandle)) // Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error()); } public override void Close() { if (this.fileHandle != null) { DeviceIO.CloseHandle(this.fileHandle); this.fileHandle.SetHandleAsInvalid(); this.fileHandle = null; } base.Close(); } public override void SetLength(long value) { throw new NotSupportedException("Setting the length is not supported with DiskStream objects."); } public override int Read(byte[] buffer, int offset, int count) { return (int)Read(buffer, (uint)offset, (uint)count); } public unsafe uint Read(byte[] buffer, uint offset, uint count) { uint n = 0; fixed (byte* p = buffer) { if (!DeviceIO.ReadFile(this.fileHandle, p + offset, count, &n, IntPtr.Zero)) Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error()); } return n; } public override void Write(byte[] buffer, int offset, int count) { Write(buffer, (uint)offset, (uint)count); } public unsafe void Write(byte[] buffer, uint offset, uint count) { uint n = 0; fixed (byte* p = buffer) { if (!DeviceIO.WriteFile(this.fileHandle, p + offset, count, &n, IntPtr.Zero)) Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error()); } } public override long Seek(long offset, SeekOrigin origin) { return (long)SeekU((ulong)offset, origin); } public ulong SeekU(ulong offset, SeekOrigin origin) { ulong n = 0; if (!DeviceIO.SetFilePointerEx(this.fileHandle, offset, out n, (uint)origin)) Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error()); return n; } public uint ReadSector(DiskSector sector) { return this.Read(sector.Data, 0, sector.SectorSize); } public void WriteSector(DiskSector sector) { this.Write(sector.Data, 0, sector.SectorSize); } public void SeekSector(DiskSector sector) { this.Seek(sector.Offset, SeekOrigin.Begin); } } 

The DeviceIO class is a p / invoke template for the Win32 API.

The DiskInfo class is a wrapper for the Win32_DiskDrive and Win32_DiskPartition WMI classes.

I used this library once to clone a disk (on Win7). Hope this helps find a solution.

For completeness and because of details, the DeviceIO class is used universally using unsigned integers:

 /// <summary> /// P/Invoke wrappers around Win32 functions and constants. /// </summary> internal partial class DeviceIO { #region Constants used in unmanaged functions public const uint FILE_SHARE_READ = 0x00000001; public const uint FILE_SHARE_WRITE = 0x00000002; public const uint FILE_SHARE_DELETE = 0x00000004; public const uint OPEN_EXISTING = 3; public const uint GENERIC_READ = (0x80000000); public const uint GENERIC_WRITE = (0x40000000); public const uint FILE_FLAG_NO_BUFFERING = 0x20000000; public const uint FILE_FLAG_WRITE_THROUGH = 0x80000000; public const uint FILE_READ_ATTRIBUTES = (0x0080); public const uint FILE_WRITE_ATTRIBUTES = 0x0100; public const uint ERROR_INSUFFICIENT_BUFFER = 122; #endregion #region Unamanged function declarations [DllImport("kernel32.dll", SetLastError = true)] public static unsafe extern SafeFileHandle CreateFile( string FileName, uint DesiredAccess, uint ShareMode, IntPtr SecurityAttributes, uint CreationDisposition, uint FlagsAndAttributes, IntPtr hTemplateFile); [DllImport("kernel32.dll", SetLastError = true)] public static extern bool CloseHandle(SafeFileHandle hHandle); [DllImport("kernel32.dll", SetLastError = true)] public static extern bool DeviceIoControl( SafeFileHandle hDevice, uint dwIoControlCode, IntPtr lpInBuffer, uint nInBufferSize, [Out] IntPtr lpOutBuffer, uint nOutBufferSize, ref uint lpBytesReturned, IntPtr lpOverlapped); [DllImport("kernel32.dll", SetLastError = true)] public static extern unsafe bool WriteFile( SafeFileHandle hFile, byte* pBuffer, uint NumberOfBytesToWrite, uint* pNumberOfBytesWritten, IntPtr Overlapped); [DllImport("kernel32.dll", SetLastError = true)] public static extern unsafe bool ReadFile( SafeFileHandle hFile, byte* pBuffer, uint NumberOfBytesToRead, uint* pNumberOfBytesRead, IntPtr Overlapped); [DllImport("kernel32.dll", SetLastError = true)] public static extern bool SetFilePointerEx( SafeFileHandle hFile, ulong liDistanceToMove, out ulong lpNewFilePointer, uint dwMoveMethod); [DllImport("kernel32.dll")] public static extern bool FlushFileBuffers( SafeFileHandle hFile); #endregion } 
+1
source

All Articles