/// <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> /// 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; }