/* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ using Alphaleonis.Win32.Network; using System; using System.Globalization; using System.IO; using System.Net.NetworkInformation; using System.Security; namespace Alphaleonis.Win32.Filesystem { public static partial class Path { #region GetMappedConnectionName /// [AlphaFS] Gets the connection name of the locally mapped drive. /// The server and share as: \\servername\sharename. /// /// /// /// /// The local path with drive name. [SecurityCritical] public static string GetMappedConnectionName(string path) { return Host.GetRemoteNameInfoCore(path, true).lpConnectionName; } #endregion // GetMappedConnectionName #region GetMappedUncName /// [AlphaFS] Gets the network share name from the locally mapped path. /// The network share connection name of . /// /// /// /// /// The local path with drive name. [SecurityCritical] public static string GetMappedUncName(string path) { return Host.GetRemoteNameInfoCore(path, true).lpUniversalName; } #endregion // GetMappedUncName #region IsUncPath /// [AlphaFS] Determines if a path string is a valid Universal Naming Convention (UNC) path. /// if the specified path is a Universal Naming Convention (UNC) path, otherwise. /// The path to check. [SecurityCritical] public static bool IsUncPath(string path) { return IsUncPathCore(path, false, true); } /// [AlphaFS] Determines if a path string is a valid Universal Naming Convention (UNC) path, optionally skip invalid path character check. /// if the specified path is a Universal Naming Convention (UNC) path, otherwise. /// The path to check. /// will check for invalid path characters. [SecurityCritical] public static bool IsUncPath(string path, bool checkInvalidPathChars) { return IsUncPathCore(path, false, checkInvalidPathChars); } #endregion // IsUncPath #region LocalToUnc /// [AlphaFS] Converts a local path to a network share path. /// A Local path, e.g.: "C:\Windows" will be returned as: "\\MachineName\C$\Windows". /// If a logical drive points to a network share path, the share path will be returned instead. /// /// On successful conversion a UNC path is returned. /// If the conversion fails, is returned. /// If is an empty string or , is returned. /// /// /// /// /// A local path, e.g.: "C:\Windows". [SecurityCritical] public static string LocalToUnc(string localPath) { return LocalToUncCore(localPath, false, false, false); } /// [AlphaFS] Converts a local path to a network share path, optionally returning it in a long path format. /// A Local path, e.g.: "C:\Windows" will be returned as: "\\MachineName\C$\Windows". /// If a logical drive points to a network share path, the share path will be returned instead. /// /// On successful conversion a UNC path is returned. /// If the conversion fails, is returned. /// If is an empty string or , is returned. /// /// /// /// /// A local path, e.g.: "C:\Windows". /// returns the path in long path (Unicode) format, when returns the path as a regular path. [SecurityCritical] public static string LocalToUnc(string localPath, bool asLongPath) { return LocalToUncCore(localPath, asLongPath, false, false); } /// [AlphaFS] Converts a local path to a network share path, optionally returning it in a long path format and the ability to add or remove a trailing backslash. /// A Local path, e.g.: "C:\Windows" will be returned as: "\\MachineName\C$\Windows". /// If a logical drive points to a network share path, the share path will be returned instead. /// /// On successful conversion a UNC path is returned. /// If the conversion fails, is returned. /// If is an empty string or , is returned. /// /// /// /// /// A local path, e.g.: "C:\Windows". /// returns the path in long path (Unicode) format, when returns the path as a regular path. /// adds a trailing character to , when absent. /// removes the trailing character from , when present. [SecurityCritical] public static string LocalToUnc(string localPath, bool asLongPath, bool addTrailingDirectorySeparator, bool removeTrailingDirectorySeparator) { return LocalToUncCore(localPath, asLongPath, addTrailingDirectorySeparator, removeTrailingDirectorySeparator); } #endregion // LocalToUnc #region Internal Methods /// [AlphaFS] Determines if a path string is a valid Universal Naming Convention (UNC) path, optionally skip invalid path character check. /// if the specified path is a Universal Naming Convention (UNC) path, otherwise. /// The path to check. /// When indicates that is already in regular path format. /// will check for invalid path characters. [SecurityCritical] internal static bool IsUncPathCore(string path, bool isRegularPath, bool checkInvalidPathChars) { if (!isRegularPath) path = GetRegularPathCore(path, checkInvalidPathChars ? GetFullPathOptions.CheckInvalidPathChars : 0, false); else if (checkInvalidPathChars) CheckInvalidPathChars(path, false, false); Uri uri; return Uri.TryCreate(path, UriKind.Absolute, out uri) && uri.IsUnc; } /// Converts a local path to a network share path. /// A Local path, e.g.: "C:\Windows" will be returned as: "\\MachineName\C$\Windows". /// If a logical drive points to a network share path, the share path will be returned instead. /// /// On successful conversion a UNC path is returned. /// If the conversion fails, is returned. /// If is an empty string or , is returned. /// /// /// /// /// A local path, e.g.: "C:\Windows". /// returns the path in long path (Unicode) format, when returns the path as a regular path. /// adds a trailing character to , when absent. /// removes the trailing character from , when present. [SecurityCritical] internal static string LocalToUncCore(string localPath, bool asLongPath, bool addTrailingDirectorySeparator, bool removeTrailingDirectorySeparator) { if (Utils.IsNullOrWhiteSpace(localPath)) return null; localPath = GetRegularPathCore(localPath, GetFullPathOptions.CheckInvalidPathChars, false); if (!IsUncPathCore(localPath, true, false)) { if (localPath[0] == CurrentDirectoryPrefixChar || !IsPathRooted(localPath, false)) localPath = GetFullPathCore(null, localPath, GetFullPathOptions.None); string drive = GetPathRoot(localPath, false); if (Utils.IsNullOrWhiteSpace(drive)) return localPath; Network.NativeMethods.REMOTE_NAME_INFO unc = Host.GetRemoteNameInfoCore(drive, true); if (!Utils.IsNullOrWhiteSpace(unc.lpConnectionName)) // Only leave trailing backslash if "localPath" also ends with backslash. return localPath.EndsWith(DirectorySeparator, StringComparison.OrdinalIgnoreCase) ? AddTrailingDirectorySeparator(unc.lpConnectionName, false) : RemoveTrailingDirectorySeparator(unc.lpConnectionName, false); // Split: localDrive[0] = "C", localDrive[1] = "\Windows" string[] localDrive = localPath.Split(VolumeSeparatorChar); // Return: "\\MachineName\C$\Windows" localPath = string.Format(CultureInfo.CurrentCulture, "{0}{1}{2}${3}", Host.GetUncName(), DirectorySeparatorChar, localDrive[0], localDrive[1]); } // Only leave trailing backslash if "localPath" also ends with backslash. addTrailingDirectorySeparator = addTrailingDirectorySeparator || (localPath.EndsWith(DirectorySeparator, StringComparison.OrdinalIgnoreCase) && !removeTrailingDirectorySeparator); var options = (addTrailingDirectorySeparator ? GetFullPathOptions.AddTrailingDirectorySeparator : 0) | (removeTrailingDirectorySeparator ? GetFullPathOptions.RemoveTrailingDirectorySeparator : 0); return asLongPath ? GetLongPathCore(localPath, options) : localPath; } #endregion // Internal Methods } }