From 1967bd862eaa5130260a7d7beea9657778718c31 Mon Sep 17 00:00:00 2001 From: Mounir IDRASSI Date: Wed, 19 Dec 2018 00:38:56 +0100 Subject: Windows: Add mount option that allows mounting a volume without attaching it to the specified drive letter. This is useful in situation where Windows has issue with the filesystem (e.g. ReFS on Windows 10 1809) and we need to use third party software to be able to use the filesystem under Windows through low level VeraCrypt virtual device (e.g. \Device\VeraCryptVolumeX). --- src/Common/Apidrvr.h | 1 + src/Common/Common.h | 1 + src/Common/Common.rc | 38 ++++++++++++++++++++------------------ src/Common/Dlgcode.c | 11 +++++------ src/Common/Language.xml | 2 ++ src/Common/Resource.h | 3 ++- src/Driver/Ntdriver.c | 20 +++++++++++--------- src/Mount/Mount.c | 47 ++++++++++++++++++++++++++++++++++++++++++----- 8 files changed, 84 insertions(+), 39 deletions(-) diff --git a/src/Common/Apidrvr.h b/src/Common/Apidrvr.h index 2c436bf9..5c6de908 100644 --- a/src/Common/Apidrvr.h +++ b/src/Common/Apidrvr.h @@ -210,6 +210,7 @@ typedef struct BOOL hiddenVolume; BOOL readOnly; BOOL removable; + BOOL mountDisabled; BOOL partitionInInactiveSysEncScope; uint32 volumeHeaderFlags; unsigned __int64 totalBytesRead; diff --git a/src/Common/Common.h b/src/Common/Common.h index 0620b652..02b2929a 100644 --- a/src/Common/Common.h +++ b/src/Common/Common.h @@ -92,6 +92,7 @@ typedef struct int ProtectedHidVolPkcs5Prf; int ProtectedHidVolPim; wchar_t Label[33]; /* maximum label length is 32 for NTFS and 11 for FAT32 */ + BOOL DisableMountManager; } MountOptions; #endif diff --git a/src/Common/Common.rc b/src/Common/Common.rc index 5668800a..249a1329 100644 --- a/src/Common/Common.rc +++ b/src/Common/Common.rc @@ -65,7 +65,7 @@ BEGIN PUSHBUTTON "Cancel",IDCANCEL,248,190,50,14 END -IDD_MOUNT_OPTIONS DIALOGEX 0, 0, 277, 231 +IDD_MOUNT_OPTIONS DIALOGEX 0, 0, 277, 244 STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "VeraCrypt - Mount Options" FONT 8, "MS Shell Dlg", 400, 0, 0x1 @@ -77,25 +77,27 @@ BEGIN "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,39,257,11 CONTROL "Mount partition &using system encryption without pre-boot authentication",IDC_MOUNT_SYSENC_PART_WITHOUT_PBA, "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,53,259,11 - EDITTEXT IDC_VOLUME_LABEL,112,67,150,14,ES_AUTOHSCROLL + EDITTEXT IDC_VOLUME_LABEL,112,82,150,14,ES_AUTOHSCROLL CONTROL "&Protect hidden volume against damage caused by writing to outer volume",IDC_PROTECT_HIDDEN_VOL, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,97,252,10 - EDITTEXT IDC_PASSWORD_PROT_HIDVOL,112,115,151,14,ES_PASSWORD | ES_AUTOHSCROLL - COMBOBOX IDC_PKCS5_PRF_ID,112,136,91,90,CBS_DROPDOWNLIST | WS_TABSTOP - EDITTEXT IDC_PIM,112,156,42,14,ES_RIGHT | ES_PASSWORD | ES_AUTOHSCROLL | ES_NUMBER | NOT WS_VISIBLE - CONTROL "Use P&IM",IDC_PIM_ENABLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,112,161,97,10 - LTEXT "(Empty or 0 for default iterations)",IDC_PIM_HELP,158,159,112,8,NOT WS_VISIBLE - CONTROL "&Display password",IDC_SHOW_PASSWORD_MO,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,112,174,90,10 - CONTROL "U&se keyfiles",IDC_KEYFILES_ENABLE_HIDVOL_PROT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,112,187,90,10 - PUSHBUTTON "&Keyfiles...",IDC_KEYFILES_HIDVOL_PROT,204,183,60,14 + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,115,252,10 + EDITTEXT IDC_PASSWORD_PROT_HIDVOL,112,133,151,14,ES_PASSWORD | ES_AUTOHSCROLL + COMBOBOX IDC_PKCS5_PRF_ID,112,154,91,90,CBS_DROPDOWNLIST | WS_TABSTOP + EDITTEXT IDC_PIM,112,174,42,14,ES_RIGHT | ES_PASSWORD | ES_AUTOHSCROLL | ES_NUMBER | NOT WS_VISIBLE + CONTROL "Use P&IM",IDC_PIM_ENABLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,112,179,97,10 + LTEXT "(Empty or 0 for default iterations)",IDC_PIM_HELP,158,177,112,8,NOT WS_VISIBLE + CONTROL "&Display password",IDC_SHOW_PASSWORD_MO,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,112,192,90,10 + CONTROL "U&se keyfiles",IDC_KEYFILES_ENABLE_HIDVOL_PROT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,112,205,90,10 + PUSHBUTTON "&Keyfiles...",IDC_KEYFILES_HIDVOL_PROT,204,201,60,14 DEFPUSHBUTTON "OK",IDOK,211,7,60,14 PUSHBUTTON "Cancel",IDCANCEL,211,24,60,14 - LTEXT "What is hidden volume protection?",IDC_LINK_HIDVOL_PROTECTION_INFO,16,202,247,10,SS_NOTIFY - RTEXT "P&assword to hidden volume:\n(if empty, cache is used)",IDT_HIDDEN_PROT_PASSWD,15,114,91,17,0,WS_EX_RIGHT - GROUPBOX "Hidden Volume Protection",IDT_HIDDEN_VOL_PROTECTION,6,83,265,136 - RTEXT "PKCS-5 PRF:",IDT_PKCS5_PRF,15,137,91,17 - RTEXT "Volume PIM:",IDT_PIM,15,159,91,17,NOT WS_VISIBLE - LTEXT "Volume Label in Windows:",IDT_VOLUME_LABEL,12,70,95,8 + LTEXT "What is hidden volume protection?",IDC_LINK_HIDVOL_PROTECTION_INFO,16,220,247,10,SS_NOTIFY + RTEXT "P&assword to hidden volume:\n(if empty, cache is used)",IDT_HIDDEN_PROT_PASSWD,15,132,91,17,0,WS_EX_RIGHT + GROUPBOX "Hidden Volume Protection",IDT_HIDDEN_VOL_PROTECTION,6,101,265,136 + RTEXT "PKCS-5 PRF:",IDT_PKCS5_PRF,15,155,91,17 + RTEXT "Volume PIM:",IDT_PIM,15,177,91,17,NOT WS_VISIBLE + LTEXT "Volume Label in Windows:",IDT_VOLUME_LABEL,12,85,95,8 + CONTROL "Only create virtual device without mounting on selected drive letter",IDC_DISABLE_MOUNT_MANAGER, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,67,231,10 END IDD_KEYFILES DIALOGEX 0, 0, 363, 251 @@ -374,7 +376,7 @@ BEGIN BEGIN LEFTMARGIN, 7 TOPMARGIN, 7 - BOTTOMMARGIN, 225 + BOTTOMMARGIN, 238 END IDD_KEYFILES, DIALOG diff --git a/src/Common/Dlgcode.c b/src/Common/Dlgcode.c index f9b6f327..448ee1ab 100644 --- a/src/Common/Dlgcode.c +++ b/src/Common/Dlgcode.c @@ -8049,16 +8049,15 @@ retry: mount.bMountReadOnly = mountOptions->ReadOnly; mount.bMountRemovable = mountOptions->Removable; mount.bPreserveTimestamp = mountOptions->PreserveTimestamp; - - mount.bMountManager = TRUE; + + if (mountOptions->DisableMountManager) + mount.bMountManager = FALSE; + else + mount.bMountManager = TRUE; mount.pkcs5_prf = pkcs5; mount.bTrueCryptMode = truecryptMode; mount.VolumePim = pim; - // Windows 2000 mount manager causes problems with remounted volumes - if (CurrentOSMajor == 5 && CurrentOSMinor == 0) - mount.bMountManager = FALSE; - wstring path = volumePath; if (path.find (L"\\\\?\\") == 0) { diff --git a/src/Common/Language.xml b/src/Common/Language.xml index 88b5e0fd..5fc4ce7d 100644 --- a/src/Common/Language.xml +++ b/src/Common/Language.xml @@ -1427,6 +1427,8 @@ ERROR: The size of the file container is larger than the available free space on disk. Allow Windows Disk Defragmenter to defragment non-system partition/drive WARNING: Defragmenting non-system partitions/drives may leak metadata about their content or cause issues with hidden volumes they may contain.\n\nContinue? + Virtual Device + The selected mounted volume is not associated with its drive letter in Windows and so it can not be opened in Windows Explorer. diff --git a/src/Common/Resource.h b/src/Common/Resource.h index 7106b3b8..a913bc26 100644 --- a/src/Common/Resource.h +++ b/src/Common/Resource.h @@ -223,6 +223,7 @@ #define IDC_BENCHMARK_LIST 5139 #define IDC_BENCHMARK_PREBOOT 5140 #define IDD_TEXT_EDIT_DLG 5141 +#define IDC_DISABLE_MOUNT_MANAGER 5142 // Next default values for new objects // @@ -231,7 +232,7 @@ #define _APS_NO_MFC 1 #define _APS_NEXT_RESOURCE_VALUE 578 #define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 5141 +#define _APS_NEXT_CONTROL_VALUE 5143 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif diff --git a/src/Driver/Ntdriver.c b/src/Driver/Ntdriver.c index 582df290..e4e39bc0 100644 --- a/src/Driver/Ntdriver.c +++ b/src/Driver/Ntdriver.c @@ -1090,8 +1090,8 @@ NTSTATUS ProcessVolumeDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION } } } - } - } + } + } break; @@ -1701,9 +1701,9 @@ NTSTATUS ProcessVolumeDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION Irp->IoStatus.Information = 0; break; default: - Dump ("ProcessVolumeDeviceControlIrp (unknown code 0x%.8X)\n", irpSp->Parameters.DeviceIoControl.IoControlCode); - return TCCompleteIrp (Irp, STATUS_INVALID_DEVICE_REQUEST, 0); - } + Dump ("ProcessVolumeDeviceControlIrp (unknown code 0x%.8X)\n", irpSp->Parameters.DeviceIoControl.IoControlCode); + return TCCompleteIrp (Irp, STATUS_INVALID_DEVICE_REQUEST, 0); + } #if defined(DEBUG) || defined (DEBG_TRACE) if (!NT_SUCCESS (Irp->IoStatus.Status)) @@ -2209,6 +2209,7 @@ NTSTATUS ProcessMainDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION Ex prop->volumeHeaderFlags = ListExtension->cryptoInfo->HeaderFlags; prop->readOnly = ListExtension->bReadOnly; prop->removable = ListExtension->bRemovable; + prop->mountDisabled = ListExtension->bMountManager? FALSE : TRUE; prop->partitionInInactiveSysEncScope = ListExtension->PartitionInInactiveSysEncScope; prop->hiddenVolume = ListExtension->cryptoInfo->hiddenVolume; @@ -3782,14 +3783,15 @@ NTSTATUS MountDevice (PDEVICE_OBJECT DeviceObject, MOUNT_STRUCT *mount) } if (mount->bMountManager) + { MountManagerMount (mount); + // We create symbolic link even if mount manager is notified of + // arriving volume as it apparently sometimes fails to create the link + CreateDriveLink (mount->nDosDriveNo); + } NewExtension->bMountManager = mount->bMountManager; - // We create symbolic link even if mount manager is notified of - // arriving volume as it apparently sometimes fails to create the link - CreateDriveLink (mount->nDosDriveNo); - mount->FilesystemDirty = FALSE; if (NT_SUCCESS (TCOpenFsVolume (NewExtension, &volumeHandle, &volumeFileObject))) diff --git a/src/Mount/Mount.c b/src/Mount/Mount.c index ebae35f8..5a5b877a 100644 --- a/src/Mount/Mount.c +++ b/src/Mount/Mount.c @@ -3537,6 +3537,8 @@ BOOL CALLBACK MountOptionsDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM mountOptions->Removable ? BST_CHECKED : BST_UNCHECKED, 0); SendDlgItemMessage (hwndDlg, IDC_PROTECT_HIDDEN_VOL, BM_SETCHECK, mountOptions->ProtectHiddenVolume ? BST_CHECKED : BST_UNCHECKED, 0); + SendDlgItemMessage (hwndDlg, IDC_PROTECT_HIDDEN_VOL, BM_SETCHECK, + mountOptions->DisableMountManager ? BST_CHECKED : BST_UNCHECKED, 0); SendDlgItemMessage (hwndDlg, IDC_PROTECT_HIDDEN_VOL, BM_SETCHECK, mountOptions->ProtectHiddenVolume ? BST_CHECKED : BST_UNCHECKED, 0); @@ -3554,6 +3556,10 @@ BOOL CALLBACK MountOptionsDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM SetDlgItemTextW (hwndDlg, IDC_VOLUME_LABEL, mountOptions->Label); SendDlgItemMessage (hwndDlg, IDC_VOLUME_LABEL, EM_LIMITTEXT, 32, 0); // 32 is the maximum possible length for a drive label in Windows + protect = IsButtonChecked (GetDlgItem (hwndDlg, IDC_DISABLE_MOUNT_MANAGER)); + EnableWindow (GetDlgItem (hwndDlg, IDC_VOLUME_LABEL), !protect); + EnableWindow (GetDlgItem (hwndDlg, IDT_VOLUME_LABEL), !protect); + /* Add PRF algorithm list for hidden volume password */ HWND hComboBox = GetDlgItem (hwndDlg, IDC_PKCS5_PRF_ID); SendMessage (hComboBox, CB_RESETCONTENT, 0, 0); @@ -3700,6 +3706,7 @@ BOOL CALLBACK MountOptionsDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM mountOptions->ReadOnly = IsButtonChecked (GetDlgItem (hwndDlg, IDC_MOUNT_READONLY)); mountOptions->Removable = IsButtonChecked (GetDlgItem (hwndDlg, IDC_MOUNT_REMOVABLE)); + mountOptions->DisableMountManager = IsButtonChecked (GetDlgItem (hwndDlg, IDC_DISABLE_MOUNT_MANAGER)); mountOptions->ProtectHiddenVolume = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PROTECT_HIDDEN_VOL)); mountOptions->PartitionInInactiveSysEncScope = IsButtonChecked (GetDlgItem (hwndDlg, IDC_MOUNT_SYSENC_PART_WITHOUT_PBA)); mountOptions->UseBackupHeader = IsButtonChecked (GetDlgItem (hwndDlg, IDC_USE_EMBEDDED_HEADER_BAK)); @@ -3736,7 +3743,7 @@ BOOL CALLBACK MountOptionsDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM return 1; } - if (lw == IDC_MOUNT_READONLY || lw == IDC_PROTECT_HIDDEN_VOL) + if (lw == IDC_MOUNT_READONLY || lw == IDC_PROTECT_HIDDEN_VOL || lw == IDC_DISABLE_MOUNT_MANAGER) { BOOL protect; @@ -3747,6 +3754,12 @@ BOOL CALLBACK MountOptionsDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM EnableWindow (GetDlgItem (hwndDlg, IDT_HIDDEN_VOL_PROTECTION), !IsButtonChecked (GetDlgItem (hwndDlg, IDC_MOUNT_READONLY))); } + if (lw == IDC_DISABLE_MOUNT_MANAGER) + { + EnableWindow (GetDlgItem (hwndDlg, IDC_VOLUME_LABEL), !IsButtonChecked (GetDlgItem (hwndDlg, IDC_DISABLE_MOUNT_MANAGER))); + EnableWindow (GetDlgItem (hwndDlg, IDT_VOLUME_LABEL), !IsButtonChecked (GetDlgItem (hwndDlg, IDC_DISABLE_MOUNT_MANAGER))); + } + protect = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PROTECT_HIDDEN_VOL)); EnableWindow (GetDlgItem (hwndDlg, IDC_PASSWORD_PROT_HIDVOL), protect); @@ -4000,6 +4013,14 @@ BOOL CALLBACK VolumePropertiesDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LP else ListSubItemSet (list, i++, 1, (wchar_t *) (prop.wszVolume[1] != L'?' ? prop.wszVolume : prop.wszVolume + 4)); + if (!bSysEnc && prop.mountDisabled) + { + // Virtual Device + StringCbPrintfW (szTmp, sizeof(szTmp), L"\\Device\\VeraCryptVolume%c", (wchar_t) prop.driveNo + L'A'); + ListItemAdd (list, i, GetString ("VIRTUAL_DEVICE")); + ListSubItemSet (list, i++, 1, szTmp); + } + if (!bSysEnc && IsVolumeDeviceHosted ((wchar_t *) (prop.wszVolume[1] != L'?' ? prop.wszVolume : prop.wszVolume + 4))) { // Volume ID @@ -7742,10 +7763,26 @@ BOOL CALLBACK MainDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa nSelectedDriveIndex = ((LPNMITEMACTIVATE)lParam)->iItem; if (LOWORD(state) == TC_MLIST_ITEM_NONSYS_VOL || LOWORD(state) == TC_MLIST_ITEM_SYS_PARTITION) { - // Open explorer window for mounted volume - WaitCursor (); - OpenVolumeExplorerWindow (HIWORD(state) - L'A'); - NormalCursor (); + VOLUME_PROPERTIES_STRUCT prop; + DWORD dwResult; + + memset (&prop, 0, sizeof(prop)); + prop.driveNo = HIWORD (state) - L'A'; + + if (DeviceIoControl (hDriver, TC_IOCTL_GET_VOLUME_PROPERTIES, &prop, sizeof (prop), &prop, sizeof (prop), &dwResult, NULL) + && dwResult + && prop.mountDisabled + ) + { + Warning ("MOUNTED_VOLUME_NOT_ASSOCIATED", hwndDlg); + } + else + { + // Open explorer window for mounted volume + WaitCursor (); + OpenVolumeExplorerWindow (HIWORD(state) - L'A'); + NormalCursor (); + } } else if (LOWORD (GetSelectedLong (GetDlgItem (hwndDlg, IDC_DRIVELIST))) == TC_MLIST_ITEM_FREE) { -- cgit v1.2.3