VeraCrypt
aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Build/CMakeLists.txt15
-rw-r--r--src/Common/Common.rc4
-rw-r--r--src/Common/Dlgcode.c50
-rw-r--r--src/Main/UserInterface.cpp98
4 files changed, 112 insertions, 55 deletions
diff --git a/src/Build/CMakeLists.txt b/src/Build/CMakeLists.txt
index ce3d372b..458040e8 100644
--- a/src/Build/CMakeLists.txt
+++ b/src/Build/CMakeLists.txt
@@ -84,114 +84,125 @@ if ( UNIX )
file(READ "/etc/lsb-release" UBUNTU_RELEASE)
string(REGEX MATCH "DISTRIB_RELEASE=([0-9 /\\.]+)" _ ${UBUNTU_RELEASE})
set(PLATFORM_VERSION ${CMAKE_MATCH_1})
else()
file(READ "/etc/debian_version" DEBIAN_RELEASE)
string(REGEX MATCH "([0-9]+\\.[0-9]+)" _ ${DEBIAN_RELEASE})
set(PLATFORM_VERSION ${CMAKE_MATCH_1})
endif()
# Get debian release version
elseif(EXISTS "/etc/debian_version")
file(READ "/etc/debian_version" DEBIAN_RELEASE)
string(REGEX MATCH "([0-9]+\\.[0-9]+)" _ ${DEBIAN_RELEASE})
set(PLATFORM_VERSION ${CMAKE_MATCH_1})
endif()
# Get centos release version
elseif(EXISTS "/etc/centos-release")
set ( PLATFORM "CentOS" )
file(READ "/etc/centos-release" CENTOS_RELEASE)
string(REGEX MATCH "release ([0-9 /\\.]+)" _ ${CENTOS_RELEASE})
set(PLATFORM_VERSION ${CMAKE_MATCH_1})
+
+ # Get fedora release version
+ elseif(EXISTS "/etc/fedora-release")
+
+ set ( PLATFORM "Fedora" )
+
+ file(READ "/etc/fedora-release" FEDORA_RELEASE)
+ string(REGEX MATCH "release ([0-9 /\\.]+)" _ ${FEDORA_RELEASE})
+ set(PLATFORM_VERSION ${CMAKE_MATCH_1})
# Only if distribution uses systemd and if all previous files didn't exist
# i.e OpenSUSE
elseif(EXISTS "/etc/os-release")
file(READ "/etc/os-release" OS_RELEASE_NAME)
string(REGEX MATCH "NAME=\"([a-zA-Z0-9 /\\.]+)\"" _ ${OS_RELEASE_NAME})
set(FULL_PLATFORM ${CMAKE_MATCH_1})
if (FULL_PLATFORM MATCHES "^.*openSUSE.*$")
set ( PLATFORM "openSUSE" )
elseif ( FULL_PLATFORM MATCHES "^.*Ubuntu.*$")
set ( PLATFORM "Ubuntu" )
elseif ( FULL_PLATFORM MATCHES "^.*Debian.*$")
set ( PLATFORM "Debian" )
elseif ( FULL_PLATFORM MATCHES "^.*CentOS.*$" )
set ( PLATFORM "CentOS" )
+ elseif ( FULL_PLATFORM MATCHES "^.*Fedora.*$" )
+ set ( PLATFORM "Fedora" )
endif ( )
# Get ditribution release version
file(READ "/etc/os-release" OS_RELEASE)
string(REGEX MATCH "VERSION=\"([a-zA-Z0-9 /\\.]+)\"" _ ${OS_RELEASE})
set(PLATFORM_VERSION ${CMAKE_MATCH_1})
endif()
endif ( )
string(REGEX REPLACE " $" "" PLATFORM_VERSION "${PLATFORM_VERSION}") # Trim the last trailing whitespace
set ( DISTRO_NAME ${PLATFORM}-${PLATFORM_VERSION} )
MESSAGE ( STATUS "Platform = ${PLATFORM}" )
MESSAGE ( STATUS "Platform Version = ${PLATFORM_VERSION}" )
MESSAGE ( STATUS "Distribution name = ${DISTRO_NAME}" )
# - Detect the architecture under OSX, Debian, CentOS and OpenSUSE platforms
# The following variable will be set
# $ARCHITECTURE
if ( PLATFORM STREQUAL "Debian" OR PLATFORM STREQUAL "Ubuntu" )
# There is no such thing as i686 architecture on debian, i386 is to be used instead
# dpkg --print-architecture
find_program(DPKG_CMD dpkg)
if(NOT DPKG_CMD)
# Cannot find dpkg in path
# Try best guess following SUFFIX value calculated from CMAKE_SIZEOF_VOID_P
if (SUFFIX STREQUAL "32")
SET(ARCHITECTURE i386)
elseif (SUFFIX STREQUAL "64")
SET(ARCHITECTURE amd64)
endif()
else( )
execute_process(COMMAND dpkg --print-architecture OUTPUT_VARIABLE ARCHITECTURE OUTPUT_STRIP_TRAILING_WHITESPACE)
endif( )
-elseif ( ( PLATFORM STREQUAL "CentOS" ) OR ( PLATFORM STREQUAL "openSUSE" ) )
+elseif ( ( PLATFORM STREQUAL "CentOS" ) OR ( PLATFORM STREQUAL "openSUSE" ) OR ( PLATFORM STREQUAL "Fedora" ))
execute_process(COMMAND arch OUTPUT_VARIABLE ARCHITECTURE OUTPUT_STRIP_TRAILING_WHITESPACE)
else ()
MESSAGE(FATAL_ERROR "Unrecognized / unsupported distribution")
endif ( )
MESSAGE ( STATUS "Architecture = ${ARCHITECTURE}" )
# - Create installation folder directory at install time
# This won't lead to the files being actually installed (in CMAKE_INSTALL_PREFIX)
# unless "cmake --build . --target install" is executed, which is not the case here.
#
# Doing things like the following
# - install(DIRECTORY ${VERACRYPT_BUILD_DIR}/usr DESTINATION /)
# - install(DIRECTORY ${VERACRYPT_BUILD_DIR}/usr/bin DESTINATION /usr)
# lead to conflicts despite the usage of CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION
# because install() forces CpackRPM to create the DESTINATION folders.
#
# We fix this by installing ALL directories inside '/usr' in '.', and setting
# CPACK_PACKAGING_INSTALL_PREFIX to '/usr'.
# This way, during the packaging, 'bin' and 'share' folders will be installed
# inside '${CPACK_PACKAGE_DIRECTORY}/_CPack_Packages/<system_name>/DEB,RPM/${CPACK_PACKAGE_NAME}/${CPACK_PACKAGING_INSTALL_PREFIX}'.
#
# Also, we use USE_SOURCE_PERMISSIONS to save the permissions
install(DIRECTORY ${VERACRYPT_BUILD_DIR}/usr/bin
DESTINATION .
USE_SOURCE_PERMISSIONS)
install(DIRECTORY ${VERACRYPT_BUILD_DIR}/usr/sbin
@@ -268,61 +279,61 @@ if ( ( PLATFORM STREQUAL "Debian" ) OR ( PLATFORM STREQUAL "Ubuntu" ) )
OR ( ( PLATFORM STREQUAL "Ubuntu" ) AND ( PLATFORM_VERSION VERSION_GREATER_EQUAL "23.04" ) ) )
set( CPACK_DEBIAN_PACKAGE_DEPENDS "libwxgtk3.2-1, libayatana-appindicator3-1, libfuse2, dmsetup, sudo, libpcsclite1, pcscd" )
elseif ( ( ( PLATFORM STREQUAL "Debian" ) AND ( PLATFORM_VERSION VERSION_GREATER_EQUAL "10" ) )
OR ( ( PLATFORM STREQUAL "Ubuntu" ) AND ( PLATFORM_VERSION VERSION_GREATER_EQUAL "18.04" ) ) )
set( CPACK_DEBIAN_PACKAGE_DEPENDS "libwxgtk3.0-gtk3-0v5, libayatana-appindicator3-1, libfuse2, dmsetup, sudo, libpcsclite1, pcscd" )
else ()
# Link against statically built wxWidgets on Ubuntu 14.04 and older, and Debian 8 and older
if ( ( ( PLATFORM STREQUAL "Debian" ) AND ( PLATFORM_VERSION VERSION_LESS_EQUAL "8" ) )
OR ( ( PLATFORM STREQUAL "Ubuntu" ) AND ( PLATFORM_VERSION VERSION_LESS_EQUAL "14.04" ) ) )
set( CPACK_DEBIAN_PACKAGE_DEPENDS "libgtk2.0-0, libfuse2, dmsetup, sudo, libpcsclite1, pcscd" )
else ()
set( CPACK_DEBIAN_PACKAGE_DEPENDS "libwxgtk3.0-0v5, libfuse2, dmsetup, sudo, libpcsclite1, pcscd" )
endif ()
endif()
endif()
set( CPACK_DEBIAN_PACKAGE_MAINTAINER ${CONTACT} ) # mandatory
set( CPACK_DEBIAN_PACKAGE_DESCRIPTION ${CPACK_PACKAGE_DESCRIPTION_SUMMARY} ) # mandatory
set( CPACK_DEBIAN_ARCHIVE_TYPE "gnutar") # mandatory
set( CPACK_DEBIAN_COMPRESSION_TYPE "gzip") # mandatory
set( CPACK_DEBIAN_PACKAGE_PRIORITY "optional" ) # mandatory
set( CPACK_DEBIAN_PACKAGE_SECTION "libs" ) # recommended, Section relative to Debian sections (https://www.debian.org/doc/debian-policy/ch-archive.html#s-subsections)
set(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA ${DEBIAN_PREINST};${DEBIAN_POSTINST};${DEBIAN_PRERM};${DEBIAN_POSTRM})
set(CPACK_DEBIAN_PACKAGE_CONFLICTS "${CONFLICT_PACKAGE}")
-elseif ( ( PLATFORM STREQUAL "CentOS" ) OR ( PLATFORM STREQUAL "openSUSE" ) )
+elseif ( ( PLATFORM STREQUAL "CentOS" ) OR ( PLATFORM STREQUAL "openSUSE" ) OR ( PLATFORM STREQUAL "Fedora" ))
# RPM control script(s)
file( MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/Packaging/rpm-control)
configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/Packaging/rpm-control/prerm.sh ${CMAKE_CURRENT_BINARY_DIR}/Packaging/rpm-control/prerm.sh)
set( RPM_PRERM ${CMAKE_CURRENT_BINARY_DIR}/Packaging/rpm-control/prerm.sh)
set( CPACK_GENERATOR "RPM" ) # mandatory
set( CPACK_RPM_PACKAGE_SUMMARY ${CPACK_PACKAGE_SUMMARY} ) # mandatory
set( CPACK_RPM_PACKAGE_DESCRIPTION ${CPACK_PACKAGE_DESCRIPTION} ) # mandatory
set( CPACK_RPM_PACKAGE_NAME ${CPACK_PACKAGE_NAME} ) # mandatory
set( CPACK_RPM_FILE_NAME ${CPACK_PACKAGE_FILE_NAME}.rpm ) # mandatory
set( CPACK_RPM_PACKAGE_VERSION ${CPACK_PACKAGE_VERSION} ) # mandatory
set( CPACK_RPM_PACKAGE_ARCHITECTURE ${ARCHITECTURE} ) # mandatory
set( CPACK_RPM_PACKAGE_RELEASE ${CPACK_PACKAGE_RELEASE} ) # mandatory
set( CPACK_RPM_PACKAGE_LICENSE ${CPACK_PACKAGE_LICENSE} ) # mandatory
set( CPACK_RPM_PACKAGE_GROUP "Applications/System" ) # mandatory, https://fedoraproject.org/wiki/RPMGroups
set( CPACK_RPM_PACKAGE_VENDOR ${CPACK_PACKAGE_VENDOR} ) # mandatory
set( CPACK_RPM_PACKAGE_AUTOREQ "no" ) # disable automatic shared libraries dependency detection (most of the time buggy)
if (NOGUI)
set( CPACK_RPM_PACKAGE_REQUIRES "fuse, device-mapper, sudo" )
else ()
find_package(PkgConfig REQUIRED)
pkg_check_modules(GTK3 gtk+-3.0)
if(GTK3_FOUND)
set( CPACK_RPM_PACKAGE_REQUIRES "fuse, device-mapper, gtk3, sudo, pcsc-lite" )
else()
set( CPACK_RPM_PACKAGE_REQUIRES "fuse, device-mapper, gtk2, sudo, pcsc-lite" )
endif()
diff --git a/src/Common/Common.rc b/src/Common/Common.rc
index cbd401d8..41778dfc 100644
--- a/src/Common/Common.rc
+++ b/src/Common/Common.rc
@@ -317,63 +317,63 @@ BEGIN
RTEXT "Mixing PRF:",IDT_PRF,6,51,67,10,SS_CENTERIMAGE
GROUPBOX "Current Pool Content",IDT_POOL_CONTENTS,6,70,296,170
CONTROL "",IDC_POOL_CONTENTS,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,16,83,282,148,WS_EX_TRANSPARENT
CONTROL "Display pool content",IDC_DISPLAY_POOL_CONTENTS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,191,51,111,10
CONTROL "",IDC_ENTROPY_BAR,"msctls_progress32",PBS_SMOOTH | WS_BORDER,16,255,275,12
GROUPBOX "Randomness Collected From Mouse Movements",IDT_ENTROPY_BAR,7,244,294,29
END
IDD_STATIC_MODELESS_WAIT_DLG DIALOGEX 0, 0, 292, 42
STYLE DS_SYSMODAL | DS_SETFONT | DS_MODALFRAME | DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION
EXSTYLE WS_EX_TOPMOST | WS_EX_TOOLWINDOW
CAPTION "VeraCrypt"
FONT 8, "MS Shell Dlg", 0, 0, 0x0
BEGIN
LTEXT "Please wait. This process may take a long time...",IDT_STATIC_MODELESS_WAIT_DLG_INFO,9,8,274,27
END
IDD_STATIC_MODAL_WAIT_DLG DIALOGEX 0, 0, 292, 74
STYLE DS_SETFONT | DS_MODALFRAME | DS_SETFOREGROUND | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION
CAPTION "VeraCrypt"
FONT 8, "MS Shell Dlg", 0, 0, 0x0
BEGIN
CTEXT "Please wait...\nThis process may take a long time and VeraCrypt may seem unresponsive.",IDT_STATIC_MODAL_WAIT_DLG_INFO,9,11,274,33
CONTROL "",IDC_WAIT_PROGRESS_BAR,"msctls_progress32",WS_BORDER,7,49,278,14
END
IDD_TEXT_EDIT_DLG DIALOGEX 0, 0, 372, 220
STYLE DS_SETFONT | DS_MODALFRAME | DS_3DLOOK | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
FONT 8, "MS Shell Dlg", 0, 0, 0x0
BEGIN
- PUSHBUTTON "OK",IDOK,306,201,58,14
+ PUSHBUTTON "OK",IDOK,244,201,58,14
CONTROL "",IDC_INFO_BOX_TEXT,"RichEdit20W",ES_MULTILINE | ES_WANTRETURN | ES_NUMBER | WS_BORDER | WS_VSCROLL | WS_HSCROLL | WS_TABSTOP,5,6,361,188
- DEFPUSHBUTTON "Cancel",IDCANCEL,240,201,58,14
+ DEFPUSHBUTTON "Cancel",IDCANCEL,308,201,58,14
END
/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO
BEGIN
IDD_ABOUT_DLG, DIALOG
BEGIN
END
IDD_COMMANDHELP_DLG, DIALOG
BEGIN
BOTTOMMARGIN, 281
END
IDD_RAWDEVICES_DLG, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 298
TOPMARGIN, 7
BOTTOMMARGIN, 205
END
IDD_MOUNT_OPTIONS, DIALOG
BEGIN
diff --git a/src/Common/Dlgcode.c b/src/Common/Dlgcode.c
index 269817d8..b91167d4 100644
--- a/src/Common/Dlgcode.c
+++ b/src/Common/Dlgcode.c
@@ -4138,103 +4138,143 @@ struct _TEXT_EDIT_DIALOG_PARAM {
_TEXT_EDIT_DIALOG_PARAM (const _TEXT_EDIT_DIALOG_PARAM& other) : ReadOnly (other.ReadOnly), Text (other.Text), Title (other.Title) {}
_TEXT_EDIT_DIALOG_PARAM(BOOL _readOnly, const WCHAR* title, std::string& _text) : ReadOnly(_readOnly), Text(_text), Title(title) {}
_TEXT_EDIT_DIALOG_PARAM& operator=( const _TEXT_EDIT_DIALOG_PARAM& other) {
if (this != &other)
{
ReadOnly = other.ReadOnly;
Text = other.Text;
Title = other.Title;
}
return *this;
}
};
typedef struct _TEXT_EDIT_DIALOG_PARAM TEXT_INFO_DIALOG_PARAM,*TEXT_INFO_DIALOG_PARAM_PTR;
INT_PTR TextEditDialogBox (BOOL readOnly, HWND parent, const WCHAR* Title, std::string& text)
{
TEXT_INFO_DIALOG_PARAM pm(readOnly, Title, text);
return DialogBoxParamW (hInst, MAKEINTRESOURCEW (IDD_TEXT_EDIT_DLG), parent, (DLGPROC) TextEditDlgProc, (LPARAM) &pm);
}
BOOL CALLBACK TextEditDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
WORD lw = LOWORD (wParam);
static int nID = 0;
static TEXT_INFO_DIALOG_PARAM_PTR prm;
switch (msg)
{
case WM_INITDIALOG:
{
prm = (TEXT_INFO_DIALOG_PARAM_PTR)lParam;
+ LocalizeDialog (hwndDlg, NULL);
// increase size limit of rich edit control
SendMessage(GetDlgItem (hwndDlg, IDC_INFO_BOX_TEXT), EM_EXLIMITTEXT, 0, -1);
SetWindowTextW (hwndDlg, prm->Title);
// Left margin for rich edit text field
SendMessage (GetDlgItem (hwndDlg, IDC_INFO_BOX_TEXT), EM_SETMARGINS, (WPARAM) EC_LEFTMARGIN, (LPARAM) CompensateXDPI (4));
if (prm->ReadOnly)
{
// switch rich edit control to ReadOnly
- SendMessage(GetDlgItem (hwndDlg, IDC_INFO_BOX_TEXT), ES_READONLY, TRUE, 0);
+ SendMessage(GetDlgItem (hwndDlg, IDC_INFO_BOX_TEXT), EM_SETREADONLY , TRUE, 0);
// hide cancel button
- ShowWindow(GetDlgItem(hwndDlg, IDCANCEL), SW_HIDE);
+ HWND hwndCancel = GetDlgItem(hwndDlg, IDCANCEL);
+ ShowWindow(hwndCancel, SW_HIDE);
+
+ // Reposition OK button to Cancel button's position
+ HWND hwndOK = GetDlgItem(hwndDlg, IDOK);
+ if (hwndOK && hwndCancel)
+ {
+ // Get Cancel button's position in screen coordinates
+ RECT rectCancel;
+ if (GetWindowRect(hwndCancel, &rectCancel))
+ {
+ // Convert Cancel button's position to dialog's client coordinates
+ POINT ptCancel = { rectCancel.left, rectCancel.top };
+ ScreenToClient(hwndDlg, &ptCancel);
+
+ // Get OK button's current size
+ RECT rectOK;
+ if (GetWindowRect(hwndOK, &rectOK))
+ {
+ int width = rectOK.right - rectOK.left;
+ int height = rectOK.bottom - rectOK.top;
+
+ // Move OK button to Cancel button's position
+ SetWindowPos(
+ hwndOK,
+ NULL,
+ ptCancel.x,
+ ptCancel.y,
+ width,
+ height,
+ SWP_NOZORDER | SWP_NOACTIVATE
+ );
+ }
+ }
+ }
}
SendMessage (hwndDlg, TC_APPMSG_LOAD_TEXT_BOX_CONTENT, 0, 0);
}
return 0;
case WM_COMMAND:
if (lw == IDOK )
{
if (!prm->ReadOnly)
{
- prm->Text.resize(GetWindowTextLengthA (GetDlgItem (hwndDlg, IDC_INFO_BOX_TEXT)) + 1);
- GetWindowTextA (GetDlgItem (hwndDlg, IDC_INFO_BOX_TEXT), &(prm->Text)[0], (int) prm->Text.size());
+ // read content of the text box as UTF16 and then convert it to UTF8
+ HWND hEdit = GetDlgItem(hwndDlg, IDC_INFO_BOX_TEXT);
+ int size = GetWindowTextLengthW(hEdit);
+ std::vector<WCHAR> buffer(size + 1);
+ GetWindowTextW(hEdit, buffer.data(), size + 1);
+ prm->Text = WideToUtf8String(buffer.data());
}
NormalCursor ();
EndDialog (hwndDlg, IDOK);
return 1;
}
if (lw == IDCANCEL )
{
NormalCursor ();
EndDialog (hwndDlg, IDCANCEL);
return 1;
}
return 0;
case TC_APPMSG_LOAD_TEXT_BOX_CONTENT:
{
- SetWindowTextA (GetDlgItem (hwndDlg, IDC_INFO_BOX_TEXT), prm->Text.c_str());
+ // convert prm->Text to UTF16 using Utf8StringToWide
+ SetWindowTextW(GetDlgItem(hwndDlg, IDC_INFO_BOX_TEXT), Utf8StringToWide(prm->Text).c_str());
}
return 0;
case WM_CLOSE:
NormalCursor ();
EndDialog (hwndDlg, 0);
return 1;
}
return 0;
}
INT_PTR TextInfoDialogBox (int nID)
{
return DialogBoxParamW (hInst, MAKEINTRESOURCEW (IDD_TEXT_INFO_DIALOG_BOX_DLG), MainDlg, (DLGPROC) TextInfoDialogBoxDlgProc, (LPARAM) nID);
}
BOOL CALLBACK TextInfoDialogBoxDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
WORD lw = LOWORD (wParam);
static int nID = 0;
switch (msg)
{
case WM_INITDIALOG:
{
nID = (int) lParam;
// increase size limit of rich edit control
SendMessage(GetDlgItem (hwndDlg, IDC_INFO_BOX_TEXT), EM_EXLIMITTEXT, 0, -1);
diff --git a/src/Main/UserInterface.cpp b/src/Main/UserInterface.cpp
index ad2f22b8..b216101a 100644
--- a/src/Main/UserInterface.cpp
+++ b/src/Main/UserInterface.cpp
@@ -846,138 +846,144 @@ namespace VeraCrypt
catch (UserAbort&)
{
}
catch (exception &e)
{
ShowError (e);
}
catch (...)
{
ShowError (LangString["LINUX_UNKNOWN_EXC_OCCURRED"]);
}
Yield();
Application::SetExitCode (1);
}
void UserInterface::OnVolumeMounted (EventArgs &args)
{
shared_ptr <VolumeInfo> mountedVolume = (dynamic_cast <VolumeEventArgs &> (args)).mVolume;
if (Preferences.OpenExplorerWindowAfterMount && !mountedVolume->MountPoint.IsEmpty())
OpenExplorerWindow (mountedVolume->MountPoint);
}
void UserInterface::OnWarning (EventArgs &args)
{
ExceptionEventArgs &e = dynamic_cast <ExceptionEventArgs &> (args);
ShowWarning (e.mException);
}
+#if !defined(TC_WINDOWS) && !defined(TC_MACOSX)
+// Function to check if a given executable exists and is executable
+static bool IsExecutable(const string& exe) {
+ return wxFileName::IsFileExecutable("/usr/bin/" + exe) ||
+ wxFileName::IsFileExecutable("/usr/local/bin/" + exe);
+}
+#endif
+
void UserInterface::OpenExplorerWindow (const DirectoryPath &path)
{
if (path.IsEmpty())
return;
list <string> args;
#ifdef TC_WINDOWS
wstring p (Directory::AppendSeparator (path));
SHFILEINFO fInfo;
SHGetFileInfo (p.c_str(), 0, &fInfo, sizeof (fInfo), 0); // Force explorer to discover the drive
ShellExecute (GetTopWindow() ? static_cast <HWND> (GetTopWindow()->GetHandle()) : nullptr, L"open", p.c_str(), nullptr, nullptr, SW_SHOWNORMAL);
#elif defined (TC_MACOSX)
args.push_back (string (path));
try
{
Process::Execute ("open", args);
}
catch (exception &e) { ShowError (e); }
#else
- // MIME handler for directory seems to be unavailable through wxWidgets
- wxString desktop = GetTraits()->GetDesktopEnvironment();
- bool xdgOpenPresent = wxFileName::IsFileExecutable (wxT("/usr/bin/xdg-open")) || wxFileName::IsFileExecutable (wxT("/usr/local/bin/xdg-open"));
- bool nautilusPresent = wxFileName::IsFileExecutable (wxT("/usr/bin/nautilus")) || wxFileName::IsFileExecutable (wxT("/usr/local/bin/nautilus"));
-
- if (desktop == L"GNOME" || (desktop.empty() && !xdgOpenPresent && nautilusPresent))
- {
- // args.push_back ("--no-default-window"); // This option causes nautilus not to launch under FreeBSD 11
- args.push_back ("--no-desktop");
- args.push_back (string (path));
- try
- {
- Process::Execute ("nautilus", args, 2000);
+ string directoryPath = string(path);
+ // Primary attempt: Use xdg-open
+ if (IsExecutable("xdg-open")) {
+ try {
+ args.push_back(directoryPath);
+ Process::Execute("xdg-open", args, 2000);
+ return;
}
catch (TimeOut&) { }
- catch (exception &e) { ShowError (e); }
+ catch (exception&) {}
}
- else if (desktop == L"KDE")
- {
- try
- {
- args.push_back (string (path));
- Process::Execute ("dolphin", args, 2000);
- }
- catch (TimeOut&) { }
- catch (exception&)
- {
+
+ // Fallback attempts: Try known file managers
+ const char* fallbackFileManagers[] = { "gio", "kioclient5", "kfmclient", "exo-open", "nautilus", "dolphin", "caja", "thunar", "pcmanfm" };
+ const size_t numFileManagers = sizeof(fallbackFileManagers) / sizeof(fallbackFileManagers[0]);
+
+ for (size_t i = 0; i < numFileManagers; ++i) {
+ const char* fm = fallbackFileManagers[i];
+ if (IsExecutable(fm)) {
args.clear();
- args.push_back ("openURL");
- args.push_back (string (path));
- try
- {
- Process::Execute ("kfmclient", args, 2000);
+ if (strcmp(fm, "gio") == 0) {
+ args.push_back("open");
+ args.push_back(directoryPath);
+ }
+ else if (strcmp(fm, "kioclient5") == 0) {
+ args.push_back("exec");
+ args.push_back(directoryPath);
+ }
+ else if (strcmp(fm, "kfmclient") == 0) {
+ args.push_back("openURL");
+ args.push_back(directoryPath);
+ }
+ else if (strcmp(fm, "exo-open") == 0) {
+ args.push_back("--launch");
+ args.push_back("FileManager");
+ args.push_back(directoryPath);
+ }
+ else {
+ args.push_back(directoryPath);
+ }
+
+ try {
+ Process::Execute(fm, args, 2000);
+ return; // Success
}
catch (TimeOut&) { }
- catch (exception &e) { ShowError (e); }
- }
- }
- else if (xdgOpenPresent)
- {
- // Fallback on the standard xdg-open command
- // which is not always available by default
- args.push_back (string (path));
- try
- {
- Process::Execute ("xdg-open", args, 2000);
+ catch (exception &) {}
}
- catch (TimeOut&) { }
- catch (exception &e) { ShowError (e); }
- }
- else
- {
- ShowWarning (wxT("Unable to find a file manager to open the mounted volume"));
}
+
+ ShowWarning(wxT("Unable to find a file manager to open the mounted volume.\n"
+ "Please install xdg-utils or set a default file manager."));
#endif
}
bool UserInterface::ProcessCommandLine ()
{
CommandLineInterface &cmdLine = *CmdLine;
if (cmdLine.ArgCommand == CommandId::None)
return false;
if (Preferences.UseStandardInput)
{
wstring pwdInput;
getline(wcin, pwdInput);
size_t maxUtf8Len = cmdLine.ArgUseLegacyPassword? VolumePassword::MaxLegacySize : VolumePassword::MaxSize;
cmdLine.ArgPassword = ToUTF8Password ( pwdInput.c_str (), pwdInput.size (), maxUtf8Len);
}
switch (cmdLine.ArgCommand)
{
case CommandId::AutoMountDevices:
case CommandId::AutoMountFavorites:
case CommandId::AutoMountDevicesFavorites:
case CommandId::MountVolume:
{
cmdLine.ArgMountOptions.Path = cmdLine.ArgVolumePath;
cmdLine.ArgMountOptions.MountPoint = cmdLine.ArgMountPoint;
cmdLine.ArgMountOptions.Password = cmdLine.ArgPassword;
cmdLine.ArgMountOptions.Pim = cmdLine.ArgPim;