--- a/eric6/Utilities/__init__.py Tue Jul 30 19:23:52 2019 +0200 +++ b/eric6/Utilities/__init__.py Tue Jul 30 19:25:23 2019 +0200 @@ -32,6 +32,8 @@ import fnmatch import glob import getpass +import ctypes +import subprocess def __showwarning(message, category, filename, lineno, file=None, line=""): @@ -1277,6 +1279,70 @@ return dirs +def findVolume(volumeName): + """ + Function to find the directory belonging to a given volume name. + + @param volumeName name of the volume to search for + @type str + @return directory path of the given volume name + @rtype str + """ + volumeDirectory = None + + if isWindowsPlatform(): + # we are on a Windows platform + def getVolumeName(diskName): + """ + Local function to determine the volume of a disk or device. + + Each disk or external device connected to windows has an + attribute called "volume name". This function returns the + volume name for the given disk/device. + + Code from http://stackoverflow.com/a/12056414 + """ + volumeNameBuffer = ctypes.create_unicode_buffer(1024) + ctypes.windll.kernel32.GetVolumeInformationW( + ctypes.c_wchar_p(diskName), volumeNameBuffer, + ctypes.sizeof(volumeNameBuffer), None, None, None, None, 0) + return volumeNameBuffer.value + + # + # In certain circumstances, volumes are allocated to USB + # storage devices which cause a Windows popup to raise if their + # volume contains no media. Wrapping the check in SetErrorMode + # with SEM_FAILCRITICALERRORS (1) prevents this popup. + # + oldMode = ctypes.windll.kernel32.SetErrorMode(1) + try: + for disk in "ABCDEFGHIJKLMNOPQRSTUVWXYZ": + dirpath = "{0}:\\".format(disk) + if (os.path.exists(dirpath) and + getVolumeName(dirpath) == volumeName): + volumeDirectory = dirpath + break + finally: + ctypes.windll.kernel32.SetErrorMode(oldMode) + else: + # we are on a Linux or macOS platform + for mountCommand in ["mount", "/sbin/mount", "/usr/sbin/mount"]: + try: + mountOutput = (subprocess.check_output(mountCommand) + .splitlines()) + mountedVolumes = [x.split()[2] for x in mountOutput] + for volume in mountedVolumes: + if volume.decode("utf-8").endswith(volumeName): + volumeDirectory = volume.decode("utf-8") + break + if volumeDirectory: + break + except FileNotFoundError: + pass + + return volumeDirectory + + def getTestFileName(fn): """ Function to build the filename of a unittest file.