public static SafeFileHandle OpenDriver() { SafeFileHandle hDriver = DeviceApi.CreateFile(WIN32_ROOT_PREFIX, 0, DeviceApi.FILE_SHARE_READ | DeviceApi.FILE_SHARE_WRITE, IntPtr.Zero, DeviceApi.OPEN_EXISTING, 0, IntPtr.Zero); if (hDriver.IsInvalid) { LoadDriver(); hDriver = DeviceApi.CreateFile(WIN32_ROOT_PREFIX, 0, DeviceApi.FILE_SHARE_READ | DeviceApi.FILE_SHARE_WRITE, IntPtr.Zero, DeviceApi.OPEN_EXISTING, 0, IntPtr.Zero); if (hDriver.IsInvalid) { Win32Exception ex = new Win32Exception(); throw new TrueCryptException(TrueCryptException.ExceptionCause.DriverOpenFailed, ex.ErrorCode, ex.Message); } } return(hDriver); }
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, IntPtr.Zero, 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(); } }
/// <summary> /// Mounts a volume using the TestCrypt driver. /// </summary> /// <param name="password">The password of the TrueCrypt volume.</param> /// <param name="useBackupHeader">True if the embedded backup header should be used to mount the volume, otherwise false.</param> /// <param name="deviceNo">The device which contains the TrueCrypt volume.</param> /// <param name="diskOffset">The start offset in bytes of the TrueCrypt volume on the devie.</param> /// <param name="diskLength">The length of the TrueCrypt volume in bytes.</param> /// <returns>The drive letter (as number starting from 0 for "A:") which has been used to mount the volume.</returns> public static int Mount(Password password, bool useBackupHeader, uint deviceNo, long diskOffset, long diskLength) { IntPtr mountPtr = IntPtr.Zero; int dosDriveNo; try { // try to get a available drive letter for the volume dosDriveNo = GetFirstAvailableDrive(); if (-1 != dosDriveNo) { // open/load the TestCrypt driver first SafeFileHandle hDriver = OpenDriver(); MOUNT_STRUCT mount = new MOUNT_STRUCT(); mount.VolumePassword = password; mount.ProtectedHidVolPassword.Length = 0; mount.wszVolume = string.Format("\\Device\\Harddisk{0}\\Partition0", deviceNo); mount.DiskOffset = diskOffset; mount.DiskLength = diskLength; mount.nDosDriveNo = dosDriveNo; mount.UseBackupHeader = useBackupHeader; // without enabling the mount manager, the mounted volume won't be visible mount.bMountManager = true; // due to security reasons, volumes will be mounted read-only mount.bMountReadOnly = true; uint result = 0; mountPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(MOUNT_STRUCT))); Marshal.StructureToPtr(mount, mountPtr, true); if (DeviceApi.DeviceIoControl(hDriver, TC_IOCTL_MOUNT_VOLUME, mountPtr, (uint)Marshal.SizeOf(typeof(MOUNT_STRUCT)), mountPtr, (uint)Marshal.SizeOf(typeof(MOUNT_STRUCT)), ref result, IntPtr.Zero)) { mount = (MOUNT_STRUCT)Marshal.PtrToStructure(mountPtr, typeof(MOUNT_STRUCT)); if (mount.nReturnCode != 0) { throw new TrueCryptException(TrueCryptException.ExceptionCause.DriverIoControlFailed, mount.nReturnCode, "TC_IOCTL_MOUNT_VOLUME", null); } else { // inform the operating system about new device arrival BroadcastDeviceChange(DBT_DEVICEARRIVAL, dosDriveNo, 0); } } else { Win32Exception ex = new Win32Exception(); throw new TrueCryptException(TrueCryptException.ExceptionCause.DriverIoControlFailed, ex.ErrorCode, "TC_IOCTL_MOUNT_VOLUME", ex.Message); } hDriver.Close(); } else { throw new TrueCryptException(TrueCryptException.ExceptionCause.NoDriveLetterAvailable); } } finally { if (mountPtr != IntPtr.Zero) { Marshal.FreeHGlobal(mountPtr); } } return(dosDriveNo); }
/// <summary> /// Dismounts all volumes mounted by the TestCrypt driver. /// </summary> public static void DismountAll() { IntPtr mountListPtr = IntPtr.Zero; IntPtr umountPtr = IntPtr.Zero; try { // open/load the TestCrypt driver first SafeFileHandle hDriver = OpenDriver(); // retrieve a list of all volumes currently mounted by the TestCrypt driver uint result = 0; mountListPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(MOUNT_LIST_STRUCT))); if (DeviceApi.DeviceIoControl(hDriver, TC_IOCTL_GET_MOUNTED_VOLUMES, mountListPtr, (uint)Marshal.SizeOf(typeof(MOUNT_LIST_STRUCT)), mountListPtr, (uint)Marshal.SizeOf(typeof(MOUNT_LIST_STRUCT)), ref result, IntPtr.Zero)) { MOUNT_LIST_STRUCT mountList = (MOUNT_LIST_STRUCT)Marshal.PtrToStructure(mountListPtr, typeof(MOUNT_LIST_STRUCT)); if (mountList.ulMountedDrives != 0) { // inform the operating system about pending device removal BroadcastDeviceChange(DBT_DEVICEREMOVEPENDING, 0, mountList.ulMountedDrives); UMOUNT_STRUCT umount = new UMOUNT_STRUCT(); umount.ignoreOpenFiles = true; umountPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(UMOUNT_STRUCT))); Marshal.StructureToPtr(umount, umountPtr, true); if (DeviceApi.DeviceIoControl(hDriver, TC_IOCTL_DISMOUNT_ALL_VOLUMES, umountPtr, (uint)Marshal.SizeOf(typeof(UMOUNT_STRUCT)), umountPtr, (uint)Marshal.SizeOf(typeof(UMOUNT_STRUCT)), ref result, IntPtr.Zero)) { umount = (UMOUNT_STRUCT)Marshal.PtrToStructure(umountPtr, typeof(UMOUNT_STRUCT)); if (umount.nReturnCode != 0) { throw new TrueCryptException(TrueCryptException.ExceptionCause.DriverIoControlFailed, umount.nReturnCode, "TC_IOCTL_DISMOUNT_ALL_VOLUMES", null); } else { // inform the operating system about completed device removal BroadcastDeviceChange(DBT_DEVICEREMOVECOMPLETE, 0, mountList.ulMountedDrives); } } else { Win32Exception ex = new Win32Exception(); throw new TrueCryptException(TrueCryptException.ExceptionCause.DriverIoControlFailed, ex.ErrorCode, "TC_IOCTL_DISMOUNT_ALL_VOLUMES", ex.Message); } } else { // there is currently no volume mounted by the TestCrypt driver } } else { Win32Exception ex = new Win32Exception(); throw new TrueCryptException(TrueCryptException.ExceptionCause.DriverIoControlFailed, ex.ErrorCode, "TC_IOCTL_GET_MOUNTED_VOLUMES", ex.Message); } hDriver.Close(); } finally { if (mountListPtr != IntPtr.Zero) { Marshal.FreeHGlobal(mountListPtr); } if (umountPtr != IntPtr.Zero) { Marshal.FreeHGlobal(umountPtr); } } }