UpdateDeviceMappings() private static method

Updates the internal maps between the volume names (D:\) and device names (\Device\HarddiskVolume2\).
private static UpdateDeviceMappings ( ) : void
return void
Esempio n. 1
0
        /// <summary>
        /// Changes the DOS device name for the <paramref name="path"/> given to the according drive letter.
        /// </summary>
        /// <param name="path">Path to replace DOS device name for.</param>
        /// <returns>New path string.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="path"/> is <see langword="null"/> or empty.</exception>
        /// <exception cref="ArgumentException"><paramref name="path"/> does not start with a DOS device name.</exception>
        /// <exception cref="InvalidOperationException">Drive letter could not be found for the <paramref name="path"/> given.</exception>
        /// <remarks>
        /// This method also supports UNC paths.
        /// </remarks>
        public static string ChangeDeviceNameToDriveLetter(string path)
        {
            if (string.IsNullOrEmpty(path))
            {
                throw new ArgumentNullException(nameof(path));
            }

            path = LongPathCommon.RemoveLongPathPrefix(path);

            // Path is already converted.
            if (Regex.IsMatch(path, @"^(?:\\\\|[a-z]:)", RegexOptions.IgnoreCase))
            {
                return(path);
            }

            if (!path.StartsWith(@"\Device\", StringComparison.OrdinalIgnoreCase))
            {
                throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, "Path given does not start with a device name: {0}", path), nameof(path));
            }

            // Convert Network Redirector path to UNC.
            if (path.StartsWith(@"\Device\Mup\", StringComparison.OrdinalIgnoreCase))
            {
                return(@"\\" + path.Substring(12));
            }

            string driveLetter;
            string deviceName = null;

            // Find the proper device name.
            lock (PathHelper.DriveLetterToDeviceName)
            {
                Func <string> findDeviceName = () => deviceName = PathHelper.DriveLetterToDeviceName.Values.FirstOrDefault(dn => path.StartsWith(dn, StringComparison.OrdinalIgnoreCase));
                if (findDeviceName() == null)
                {
                    PathHelper.UpdateDeviceMappings();

                    if (findDeviceName() == null)
                    {
                        throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "Unable to find root path for {0}", path));
                    }
                }

                // Find the root path for the device name given.
                driveLetter = PathHelper.DriveLetterToDeviceName.Keys.First(rp => string.Equals(PathHelper.DriveLetterToDeviceName[rp], deviceName));
            }

            // Change parent.
            return(driveLetter + path.Substring(deviceName.Length));
        }
Esempio n. 2
0
        /// <summary>
        /// Changes the drive letter for the <paramref name="path"/> given to the according DOS device name.
        /// </summary>
        /// <param name="path">Path to replace the drive letter for.</param>
        /// <returns>New path string.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="path"/> is <see langword="null"/> or empty.</exception>
        /// <exception cref="ArgumentException"><paramref name="path"/> is too short.</exception>
        /// <exception cref="InvalidOperationException">The according DOS device name could not be found.</exception>
        /// <remarks>
        /// This method also supports UNC paths.
        /// </remarks>
        public static string ChangeDriveLetterToDeviceName(string path)
        {
            if (string.IsNullOrEmpty(path))
            {
                throw new ArgumentNullException(nameof(path));
            }

            if (path.Length < 2)
            {
                throw new ArgumentException("Path is too short.", nameof(path));
            }

            // If the path is already converted, skip.
            if (path.StartsWith(@"\Device\", StringComparison.OrdinalIgnoreCase))
            {
                return(path);
            }

            path = LongPathCommon.RemoveLongPathPrefix(path);

            // Convert UNC path to a Network Redirector path.
            if (path.StartsWith(@"\\", StringComparison.OrdinalIgnoreCase) || path.StartsWith(@"//", StringComparison.OrdinalIgnoreCase))
            {
                return(@"\Device\Mup\" + path.Substring(2));
            }

            // C:\, for example. Or will contain invalid string and will fail later.
            string driveLetter = path.Substring(0, 2) + "\\";
            string deviceName;

            lock (PathHelper.DriveLetterToDeviceName)
            {
                // Update the device-root caches, if the root path is not there.
                if (!PathHelper.DriveLetterToDeviceName.ContainsKey(driveLetter))
                {
                    PathHelper.UpdateDeviceMappings();

                    if (!PathHelper.DriveLetterToDeviceName.ContainsKey(driveLetter))
                    {
                        throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "Unable to find DOS device name for path: {0}", path));
                    }
                }

                deviceName = PathHelper.DriveLetterToDeviceName[driveLetter];
            }

            // Change parent.
            return(deviceName + path.Substring(driveLetter.Length));
        }