Beispiel #1
0
        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);
        }
Beispiel #2
0
        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();
            }
        }
Beispiel #3
0
        /// <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);
        }
Beispiel #4
0
        /// <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);
                }
            }
        }