1
0
mirror of https://github.com/veracrypt/VeraCrypt.git synced 2026-06-13 08:17:00 -05:00

Linux: allow mounting NTFS volumes with ntfs3 (#1695)

* Linux: allow mounting volumes with ntfs3

* Linux: add ntfs3 preference for NTFS mounts

* Linux: wrap ntfs3 preference help text

* Add Linux ntfs3 mount preference

* Remove Russian translation changes from ntfs3 PR

* XML Translations: Add English fallback entries for ntfs3 preference

---------

Co-authored-by: Mounir IDRASSI <mounir.idrassi@amcrypto.jp>
This commit is contained in:
Mammoth
2026-04-29 04:11:22 +03:00
committed by GitHub
parent 1b6f2690db
commit 771acf5951
55 changed files with 223 additions and 4 deletions
+2
View File
@@ -1473,6 +1473,8 @@
<entry lang="en" key="LINUX_PREF_KERNEL_CRYPT">Do not use kernel cryptographic services</entry>
<entry lang="en" key="LINUX_PREF_TAB_MOUNT_OPTIONS_FS">Filesystem</entry>
<entry lang="en" key="IDT_LINUX_PREF_TAB_MOUNT_OPTIONS">Mount options:</entry>
<entry lang="en" key="LINUX_PREF_MOUNT_NTFS_WITH_NTFS3">Mount NTFS volumes with the Linux kernel ntfs3 driver</entry>
<entry lang="en" key="LINUX_PREF_MOUNT_NTFS_WITH_NTFS3_HELP">Linux only. When enabled, VeraCrypt probes the decrypted virtual device with blkid -p and mounts detected NTFS filesystems with ntfs3 instead of the default NTFS backend. If NTFS detection fails, VeraCrypt uses the normal automatic filesystem selection. If ntfs3 is unavailable or blocked by the distribution, mounting may fail. This opt-in option can avoid suspend or hibernate hangs caused by frozen user-space FUSE filesystems.</entry>
<entry lang="en" key="LINUX_CROSS_SUPPORT">Cross-Platform Support</entry>
<entry lang="en" key="LINUX_CROSS_SUPPORT_OTHER">I will mount the volume on other platforms</entry>
<entry lang="en" key="LINUX_CROSS_SUPPORT_OTHER_HELP">Choose this option if you need to use the volume on other platforms.</entry>
+9
View File
@@ -24,6 +24,9 @@ namespace VeraCrypt
TC_CLONE (CachePassword);
TC_CLONE (FilesystemOptions);
TC_CLONE (FilesystemType);
#ifdef TC_LINUX
TC_CLONE (MountNtfsWithNtfs3);
#endif
TC_CLONE_SHARED (KeyfileList, Keyfiles);
TC_CLONE_SHARED (DirectoryPath, MountPoint);
TC_CLONE (NoFilesystem);
@@ -62,6 +65,9 @@ namespace VeraCrypt
sr.Deserialize ("CachePassword", CachePassword);
sr.Deserialize ("FilesystemOptions", FilesystemOptions);
sr.Deserialize ("FilesystemType", FilesystemType);
#ifdef TC_LINUX
sr.Deserialize ("MountNtfsWithNtfs3", MountNtfsWithNtfs3);
#endif
Keyfiles = Keyfile::DeserializeList (stream, "Keyfiles");
@@ -132,6 +138,9 @@ namespace VeraCrypt
sr.Serialize ("CachePassword", CachePassword);
sr.Serialize ("FilesystemOptions", FilesystemOptions);
sr.Serialize ("FilesystemType", FilesystemType);
#ifdef TC_LINUX
sr.Serialize ("MountNtfsWithNtfs3", MountNtfsWithNtfs3);
#endif
Keyfile::SerializeList (stream, "Keyfiles", Keyfiles);
sr.Serialize ("MountPointNull", MountPoint == nullptr);
+6
View File
@@ -26,6 +26,9 @@ namespace VeraCrypt
MountOptions ()
:
CachePassword (false),
#ifdef TC_LINUX
MountNtfsWithNtfs3 (false),
#endif
NoFilesystem (false),
NoHardwareCrypto (false),
NoKernelCrypto (false),
@@ -51,6 +54,9 @@ namespace VeraCrypt
bool CachePassword;
wstring FilesystemOptions;
wstring FilesystemType;
#ifdef TC_LINUX
bool MountNtfsWithNtfs3;
#endif
shared_ptr <KeyfileList> Keyfiles;
shared_ptr <DirectoryPath> MountPoint;
bool NoFilesystem;
+34 -1
View File
@@ -566,6 +566,29 @@ namespace VeraCrypt
return GetMountedFilesystems (DevicePath(), mountPoint).size() == 0;
}
#ifdef TC_LINUX
string CoreUnix::DetectFilesystemType (const DevicePath &devicePath) const
{
list <string> args;
args.push_back ("-p");
args.push_back ("-o");
args.push_back ("value");
args.push_back ("-s");
args.push_back ("TYPE");
args.push_back ("--");
args.push_back (devicePath);
try
{
return StringConverter::ToLower (StringConverter::Trim (Process::Execute ("blkid", args, 2000)));
}
catch (...)
{
return string();
}
}
#endif
void CoreUnix::MountFilesystem (const DevicePath &devicePath, const DirectoryPath &mountPoint, const string &filesystemType, bool readOnly, const string &systemMountOptions) const
{
if (GetMountedFilesystems (DevicePath(), mountPoint).size() > 0)
@@ -914,8 +937,18 @@ namespace VeraCrypt
if (!options.NoFilesystem && options.MountPoint && !options.MountPoint->IsEmpty())
{
wstring filesystemType = options.FilesystemType;
#ifdef TC_LINUX
if (options.MountNtfsWithNtfs3 && filesystemType.empty()
&& DetectFilesystemType (loopDev) == "ntfs")
{
filesystemType = L"ntfs3";
}
#endif
MountFilesystem (loopDev, *options.MountPoint,
StringConverter::ToSingle (options.FilesystemType),
StringConverter::ToSingle (filesystemType),
options.Protection == VolumeProtection::ReadOnly,
StringConverter::ToSingle (options.FilesystemOptions));
}
+3
View File
@@ -65,6 +65,9 @@ namespace VeraCrypt
virtual void MountFilesystem (const DevicePath &devicePath, const DirectoryPath &mountPoint, const string &filesystemType, bool readOnly, const string &systemMountOptions) const;
virtual DevicePath MountAuxVolumeImage (const DirectoryPath &auxMountPoint, const MountOptions &options) const;
virtual void MountVolumeNative (shared_ptr <Volume> volume, MountOptions &options, const DirectoryPath &auxMountPoint) const { throw NotApplicable (SRC_POS); }
#ifdef TC_LINUX
string DetectFilesystemType (const DevicePath &devicePath) const;
#endif
private:
CoreUnix (const CoreUnix &);
+9 -1
View File
@@ -455,8 +455,16 @@ namespace VeraCrypt
// Mount filesystem
if (!options.NoFilesystem && options.MountPoint && !options.MountPoint->IsEmpty())
{
wstring filesystemType = options.FilesystemType;
if (options.MountNtfsWithNtfs3 && filesystemType.empty()
&& DetectFilesystemType (nativeDevPath) == "ntfs")
{
filesystemType = L"ntfs3";
}
MountFilesystem (nativeDevPath, *options.MountPoint,
StringConverter::ToSingle (options.FilesystemType),
StringConverter::ToSingle (filesystemType),
options.Protection == VolumeProtection::ReadOnly,
StringConverter::ToSingle (options.FilesystemOptions));
+5
View File
@@ -361,6 +361,11 @@ namespace VeraCrypt
ArgFilesystem = VolumeCreationOptions::FilesystemType::Ext4;
else if (str.IsSameAs (L"NTFS", false))
ArgFilesystem = VolumeCreationOptions::FilesystemType::NTFS;
else if (str.IsSameAs (L"ntfs3", false))
{
ArgMountOptions.FilesystemType = L"ntfs3";
ArgFilesystem = VolumeCreationOptions::FilesystemType::NTFS;
}
else if (str.IsSameAs (L"exFAT", false))
ArgFilesystem = VolumeCreationOptions::FilesystemType::exFAT;
else if (str.IsSameAs (L"Btrfs", false))
-1
View File
@@ -1142,4 +1142,3 @@ namespace VeraCrypt
};
} // namespace VeraCrypt
+42
View File
@@ -55,6 +55,48 @@ namespace VeraCrypt
MountRemovableCheckBox->SetValidator (wxGenericValidator (&Preferences.DefaultMountOptions.Removable));
FilesystemOptionsTextCtrl->SetValue (Preferences.DefaultMountOptions.FilesystemOptions);
#ifdef TC_LINUX
wxBoxSizer *ntfs3PreferenceSizer = new wxBoxSizer (wxHORIZONTAL);
MountNtfsWithNtfs3CheckBox = new wxCheckBox (FilesystemSizer->GetStaticBox(), wxID_ANY, LangString["LINUX_PREF_MOUNT_NTFS_WITH_NTFS3"]);
MountNtfsWithNtfs3CheckBox->SetToolTip (LangString["LINUX_PREF_MOUNT_NTFS_WITH_NTFS3_HELP"]);
ntfs3PreferenceSizer->Add (MountNtfsWithNtfs3CheckBox, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 5);
wxWindow *ntfs3HelpIcon = new wxWindow (FilesystemSizer->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxSize (16, 16));
ntfs3HelpIcon->SetMinSize (wxSize (16, 16));
ntfs3HelpIcon->SetToolTip (LangString["LINUX_PREF_MOUNT_NTFS_WITH_NTFS3_HELP"]);
ntfs3HelpIcon->Bind (wxEVT_PAINT, [ntfs3HelpIcon] (wxPaintEvent&)
{
wxPaintDC dc (ntfs3HelpIcon);
wxSize size = ntfs3HelpIcon->GetClientSize();
wxColour backgroundColor = ntfs3HelpIcon->GetBackgroundColour();
wxColour color = ntfs3HelpIcon->GetForegroundColour();
int diameter = (size.GetWidth() < size.GetHeight() ? size.GetWidth() : size.GetHeight()) - 1;
int x = (size.GetWidth() - diameter) / 2;
int y = (size.GetHeight() - diameter) / 2;
wxCoord textWidth, textHeight;
if (ntfs3HelpIcon->GetParent())
backgroundColor = ntfs3HelpIcon->GetParent()->GetBackgroundColour();
if (!backgroundColor.IsOk())
backgroundColor = wxSystemSettings::GetColour (wxSYS_COLOUR_WINDOW);
if (!color.IsOk())
color = wxSystemSettings::GetColour (wxSYS_COLOUR_WINDOWTEXT);
dc.SetBackground (wxBrush (backgroundColor));
dc.Clear();
dc.SetPen (wxPen (color, 1));
dc.SetBrush (*wxTRANSPARENT_BRUSH);
dc.SetTextForeground (color);
dc.DrawEllipse (x, y, diameter, diameter);
dc.GetTextExtent (L"?", &textWidth, &textHeight);
dc.DrawText (L"?", (size.GetWidth() - textWidth) / 2, (size.GetHeight() - textHeight) / 2 - 1);
});
ntfs3PreferenceSizer->Add (ntfs3HelpIcon, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, 10);
FilesystemSizer->Add (ntfs3PreferenceSizer, 0, wxALL, 5);
MountNtfsWithNtfs3CheckBox->SetValidator (wxGenericValidator (&Preferences.DefaultMountOptions.MountNtfsWithNtfs3));
#endif
int index, prfInitialIndex = 0;
Pkcs5PrfChoice->Append (LangString["AUTODETECTION"]);
+3
View File
@@ -55,6 +55,9 @@ namespace VeraCrypt
};
KeyfilesPanel *DefaultKeyfilesPanel;
#ifdef TC_LINUX
wxCheckBox *MountNtfsWithNtfs3CheckBox;
#endif
int LastVirtualKeyPressed;
unique_ptr <wxTimer> mTimer;
UserPreferences Preferences;
+18
View File
@@ -1259,6 +1259,19 @@ const FileManager fileManagers[] = {
" with option -t. Default type is 'auto'. When creating a new volume, this\n"
" option specifies the filesystem to be created on the new volume.\n"
" Filesystem type 'none' disables mounting or creating a filesystem.\n"
#ifdef TC_LINUX
" On Linux, filesystem type 'ntfs3' mounts an NTFS volume using the\n"
" in-kernel ntfs3 driver. The ntfs3 kernel module must be available\n"
" and allowed by the distribution; otherwise mounting may fail.\n"
" The Linux preference \"Mount NTFS volumes with the Linux kernel ntfs3\n"
" driver\" is disabled by default. When enabled, VeraCrypt probes the\n"
" decrypted virtual device with blkid -p and applies ntfs3 only when\n"
" NTFS is detected and no explicit filesystem type was supplied. If\n"
" detection fails, VeraCrypt uses the normal automatic filesystem\n"
" selection. This can avoid suspend or hibernate hangs caused by frozen\n"
" user-space FUSE filesystems during kernel filesystem sync; use findmnt\n"
" to verify the actual mounted filesystem type.\n"
#endif
"\n"
"--force\n"
" Force mounting of a volume in use, unmounting of a volume in use, or\n"
@@ -1398,6 +1411,11 @@ const FileManager fileManagers[] = {
"Mount a volume prompting only for its password:\n"
"veracrypt -t -k \"\" --pim=0 --protect-hidden=no volume.hc /media/veracrypt1\n"
"\n"
#ifdef TC_LINUX
"Mount an NTFS volume using the Linux in-kernel ntfs3 driver:\n"
"veracrypt -t --filesystem=ntfs3 volume.hc /media/veracrypt1\n"
"\n"
#endif
"Unmount a volume:\n"
"veracrypt -u volume.hc\n"
"\n"
+6
View File
@@ -102,6 +102,9 @@ namespace VeraCrypt
if (configMap.count(L"MountVolumesReadOnly") > 0) { SetValue (configMap[L"MountVolumesReadOnly"], readOnly); configMap.erase (L"MountVolumesReadOnly"); }
DefaultMountOptions.Protection = readOnly ? VolumeProtection::ReadOnly : VolumeProtection::None;
#ifdef TC_LINUX
if (configMap.count(L"MountNtfsWithNtfs3") > 0) { SetValue (configMap[L"MountNtfsWithNtfs3"], DefaultMountOptions.MountNtfsWithNtfs3); configMap.erase (L"MountNtfsWithNtfs3"); }
#endif
if (configMap.count(L"MountVolumesRemovable") > 0) { SetValue (configMap[L"MountVolumesRemovable"], DefaultMountOptions.Removable); configMap.erase (L"MountVolumesRemovable"); }
if (configMap.count(L"NoHardwareCrypto") > 0) { SetValue (configMap[L"NoHardwareCrypto"], DefaultMountOptions.NoHardwareCrypto); configMap.erase (L"NoHardwareCrypto"); }
if (configMap.count(L"NoKernelCrypto") > 0) { SetValue (configMap[L"NoKernelCrypto"], DefaultMountOptions.NoKernelCrypto); configMap.erase (L"NoKernelCrypto"); }
@@ -221,6 +224,9 @@ namespace VeraCrypt
TC_CONFIG_ADD (MountDevicesOnLogon);
TC_CONFIG_ADD (MountFavoritesOnLogon);
formatter.AddEntry (L"MountVolumesReadOnly", DefaultMountOptions.Protection == VolumeProtection::ReadOnly);
#ifdef TC_LINUX
formatter.AddEntry (L"MountNtfsWithNtfs3", DefaultMountOptions.MountNtfsWithNtfs3);
#endif
formatter.AddEntry (L"MountVolumesRemovable", DefaultMountOptions.Removable);
formatter.AddEntry (L"NoHardwareCrypto", DefaultMountOptions.NoHardwareCrypto);
formatter.AddEntry (L"NoKernelCrypto", DefaultMountOptions.NoKernelCrypto);