为什么C#中的原始磁盘读取从略微偏移的偏移读取?
发布时间:2020-12-15 21:48:30 所属栏目:百科 来源:网络整理
导读:我正在尝试读取原始磁盘.我已成功打开驱动器并获得有效句柄(CreateFile),将该句柄的偏移量设置为零(SetFilePointerEx)并将数据读取到缓冲区Byte [](ReadFile).到现在为止还挺好.但是由于某些未知的原因,当我将缓冲区(实际上花了我一段时间才弄清楚)与第三方
我正在尝试读取原始磁盘.我已成功打开驱动器并获得有效句柄(CreateFile),将该句柄的偏移量设置为零(SetFilePointerEx)并将数据读取到缓冲区Byte [](ReadFile).到现在为止还挺好.但是由于某些未知的原因,当我将缓冲区(实际上花了我一段时间才弄清楚)与第三方实用程序(Disk Investigator)显示的内容进行比较时.它不包含引导信息(跳转指令),但是包含正确的磁盘数据,但是从偏移量85 = 0x55开始.所以在卷启动信息的中间某处.
这是为什么?有什么东西,我很想念(显然我是)? 系统:Windows 8(在VmWare工作站中) 码: // 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(其他地方) driveHandle = CreateFile(".PhysicalDrive1",WinFileAccessMode.GenericRead,WinFileSharedAccess.All,IntPtr.Zero,WinFileMode.OpenExisting,WinFileAttribute.None,IntPtr.Zero); PInvoke方法: [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); 枚举: public enum WinMoveMethod : uint { Begin = 0,Current = 1,End = 2 } 解决方法
使用命名空间“DiskLib”找不到库.我现在无法测试或完全上传,即使我不知道谁写了那段代码,但你可能会发现有趣的线条是
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,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,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,(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 count) { Write(buffer,(uint)count); } public unsafe void Write(byte[] buffer,uint count) { uint n = 0; fixed (byte* p = buffer) { if (!DeviceIO.WriteFile(this.fileHandle,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,(uint)origin)) Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error()); return n; } public uint ReadSector(DiskSector sector) { return this.Read(sector.Data,sector.SectorSize); } public void WriteSector(DiskSector sector) { this.Write(sector.Data,sector.SectorSize); } public void SeekSector(DiskSector sector) { this.Seek(sector.Offset,SeekOrigin.Begin); } } DeviceIO类是Win32 API的p / invoke样板. DiskInfo类是WMI Win32_DiskDrive和Win32_DiskPartition类的包装. 我使用该库一次克隆磁盘(在Win7上).希望有助于找到解决方案. 为了完整性和详细信息,DeviceIO类始终使用无符号整数: /// <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,uint NumberOfBytesToRead,uint* pNumberOfBytesRead,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 } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |