public Win32RawDisk(string path, bool writeable = false) { this.writeable = writeable; safeFileHandle = DeviceApi.CreateFile(path, writeable ? DeviceApi.GENERIC_READ | DeviceApi.GENERIC_WRITE : DeviceApi.GENERIC_READ, writeable ? DeviceApi.FILE_SHARE_READ | DeviceApi.FILE_SHARE_WRITE : DeviceApi.FILE_SHARE_READ, IntPtr.Zero, DeviceApi.OPEN_EXISTING, 0, IntPtr.Zero); if (safeFileHandle.IsInvalid) { throw new IOException($"Path '{path}' is invalid"); } if (writeable && !LockDevice()) { CloseDevice(); throw new IOException($"Failed to lock device '{path}'"); } if (writeable && !DismountDevice()) { UnlockDevice(); CloseDevice(); throw new IOException("Failed to dismount device '{path}'"); } }
public static void Read(uint volume, Int64 address, uint length, byte[] data) { // try to open the current physical drive SafeFileHandle hndl = DeviceApi.CreateFile(string.Format("\\\\.\\PhysicalDrive{0}", volume), DeviceApi.GENERIC_READ, DeviceApi.FILE_SHARE_READ | DeviceApi.FILE_SHARE_WRITE, IntPtr.Zero, DeviceApi.OPEN_EXISTING, DeviceApi.FILE_ATTRIBUTE_READONLY, IntPtr.Zero); if (!hndl.IsInvalid) { // set the file pointer to the requested address if (DeviceApi.SetFilePointerEx(hndl, address, out _, DeviceApi.EMoveMethod.Begin)) { // read the requested data from the physical drive uint dummy; if (!DeviceApi.ReadFile(hndl, data, length, out dummy, IntPtr.Zero)) { throw new System.IO.IOException("\"ReadFile\" API call failed"); } } else { throw new System.IO.IOException("\"SetFilePointerEx\" API call failed"); } hndl.Close(); } }
public bool UnlockDevice() { uint intOut = 0; return(DeviceApi.DeviceIoControl(safeFileHandle, DeviceApi.FSCTL_UNLOCK_VOLUME, IntPtr.Zero, 0, IntPtr.Zero, 0, ref intOut, IntPtr.Zero)); }
public bool DismountDevice() { uint intOut = 0; return(DeviceApi.DeviceIoControl(safeFileHandle, DeviceApi.FSCTL_DISMOUNT_VOLUME, IntPtr.Zero, 0, IntPtr.Zero, 0, ref intOut, IntPtr.Zero)); }
public long Position() { if (DeviceApi.SetFilePointerEx(safeFileHandle, 0, out var offset, DeviceApi.EMoveMethod.Current)) { return(offset); } var error = Marshal.GetLastWin32Error(); throw new IOException($"Failed to get position, SetFilePointerEx returned Win32 error {error}"); }
public uint Write(byte[] buffer) { if (DeviceApi.WriteFile(safeFileHandle, buffer, Convert.ToUInt32(buffer.Length), out var bytesWritten, IntPtr.Zero)) { return(bytesWritten); } var error = Marshal.GetLastWin32Error(); throw new IOException($"Failed to WriteFile returned Win32 error {error}"); }
public long Seek(long offset, SeekOrigin origin) { if (!Enum.TryParse <DeviceApi.EMoveMethod>(origin.ToString(), out var moveMethod)) { throw new ArgumentOutOfRangeException(nameof(origin)); } if (DeviceApi.SetFilePointerEx(safeFileHandle, offset, out var newOffset, moveMethod)) { return(newOffset); } var error = Marshal.GetLastWin32Error(); throw new IOException($"Failed to seek position offset {offset} and origin {origin}, SetFilePointerEx returned Win32 error {error}"); }
public void CloseDevice() { DeviceApi.CloseHandle(safeFileHandle); }