Skip to content

Commit

Permalink
Fixes #132.
Browse files Browse the repository at this point in the history
Improved upon method Path.GetHostShareFromPath().
Improved upon method Path.LocalToUncInternal().
  • Loading branch information
Yomodo committed Jan 30, 2015
1 parent 016fdba commit 2d5a25b
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 28 deletions.
40 changes: 40 additions & 0 deletions AlphaFS.UnitTest/AlphaFS_HostTest.cs
Expand Up @@ -564,6 +564,46 @@ public void EnumerateShares()

#endregion // EnumerateShares

#region GetHostShareFromPath

[TestMethod]
public void GetHostShareFromPath()
{
Console.WriteLine("Network.Host.GetHostShareFromPath\n");

string uncPath = UnitTestConstants.SysRoot32;
string[] hostAndShare = Host.GetHostShareFromPath(uncPath);
Console.WriteLine("Input local path: [{0}]", uncPath);
Assert.AreEqual(null, hostAndShare);

uncPath = Path.GetLongPath(UnitTestConstants.SysRoot32);
hostAndShare = Host.GetHostShareFromPath(uncPath);
Console.WriteLine("Input local path: [{0}]", uncPath);
Assert.AreEqual(null, hostAndShare);

Console.WriteLine();

uncPath = Path.LocalToUnc(UnitTestConstants.SysRoot32);
hostAndShare = Host.GetHostShareFromPath(uncPath);
Console.WriteLine("Input UNC path: [{0}]", uncPath);
Console.WriteLine("\tHost : [{0}]", hostAndShare[0]);
Console.WriteLine("\tShare: [{0}]", hostAndShare[1]);

Assert.AreEqual(Environment.MachineName, hostAndShare[0].ToUpperInvariant());

Console.WriteLine();

uncPath = Path.LocalToUnc(UnitTestConstants.SysRoot32, true);
hostAndShare = Host.GetHostShareFromPath(uncPath);
Console.WriteLine("Input UNC path: [{0}]", uncPath);
Console.WriteLine("\tHost : [{0}]", hostAndShare[0]);
Console.WriteLine("\tShare: [{0}]", hostAndShare[1]);

Assert.AreEqual(Environment.MachineName, hostAndShare[0].ToUpperInvariant());
}

#endregion // GetHostShareFromPath

#region GetDfsClientInfo

[TestMethod]
Expand Down
47 changes: 26 additions & 21 deletions AlphaFS/Filesystem/Path Class/Path.UncPaths.cs
Expand Up @@ -189,38 +189,43 @@ internal static string LocalToUncInternal(string localPath, bool asLongPath, boo
if (Utils.IsNullOrWhiteSpace(localPath))
return null;

var options = GetFullPathOptions.CheckInvalidPathChars |
(asLongPath ? GetFullPathOptions.AsLongPath : 0) |
(addTrailingDirectorySeparator ? GetFullPathOptions.AddTrailingDirectorySeparator : 0) |
(removeTrailingDirectorySeparator ? GetFullPathOptions.RemoveTrailingDirectorySeparator : 0);
localPath = GetRegularPathInternal(localPath, GetFullPathOptions.CheckInvalidPathChars);

localPath = (localPath[0] == CurrentDirectoryPrefixChar) || !IsPathRooted(localPath, false)
? GetFullPathInternal(null, localPath, options)
: GetRegularPathInternal(localPath, options);

if (IsUncPathInternal(localPath, false, false))
return localPath;
if (!IsUncPathInternal(localPath, true, false))
{
if (localPath[0] == CurrentDirectoryPrefixChar || !IsPathRooted(localPath, false))
localPath = GetFullPathInternal(null, localPath, GetFullPathOptions.None);

string drive = GetPathRoot(localPath, false);
string drive = GetPathRoot(localPath, false);

if (Utils.IsNullOrWhiteSpace(drive))
return localPath;
if (Utils.IsNullOrWhiteSpace(drive))
return localPath;

Network.NativeMethods.REMOTE_NAME_INFO unc = Host.GetRemoteNameInfoInternal(drive, true);

Network.NativeMethods.REMOTE_NAME_INFO unc = Host.GetRemoteNameInfoInternal(drive, true);
if (!Utils.IsNullOrWhiteSpace(unc.ConnectionName))
// Only leave trailing backslash if "localPath" also ends with backslash.
return localPath.EndsWith(DirectorySeparator, StringComparison.OrdinalIgnoreCase)
? AddTrailingDirectorySeparator(unc.ConnectionName, false)
: RemoveTrailingDirectorySeparator(unc.ConnectionName, false);

if (!Utils.IsNullOrWhiteSpace(unc.ConnectionName))
// Only leave trailing backslash if "localPath" also ends with backslash.
return localPath.EndsWith(DirectorySeparator, StringComparison.OrdinalIgnoreCase) ? AddTrailingDirectorySeparator(unc.ConnectionName, false) : RemoveTrailingDirectorySeparator(unc.ConnectionName, false);
// Split: localDrive[0] = "C", localDrive[1] = "\Windows"
string[] localDrive = localPath.Split(VolumeSeparatorChar);

// 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]);
}

// Return: "\\MachineName\C$\Windows"
string pathUnc = 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.
return localPath.EndsWith(DirectorySeparator, StringComparison.OrdinalIgnoreCase) ? AddTrailingDirectorySeparator(pathUnc, false) : RemoveTrailingDirectorySeparator(pathUnc, false);
addTrailingDirectorySeparator = addTrailingDirectorySeparator ||
(localPath.EndsWith(DirectorySeparator, StringComparison.OrdinalIgnoreCase) && !removeTrailingDirectorySeparator);

var options = (addTrailingDirectorySeparator ? GetFullPathOptions.AddTrailingDirectorySeparator : 0) |
(removeTrailingDirectorySeparator ? GetFullPathOptions.RemoveTrailingDirectorySeparator : 0);

return asLongPath ? GetLongPathInternal(localPath, options) : localPath;
}

#endregion // Internal Methods
Expand Down
23 changes: 16 additions & 7 deletions AlphaFS/Network/Host Class/ServerMessageBlock.cs
Expand Up @@ -90,21 +90,30 @@ public static IEnumerable<ShareInfo> EnumerateShares(string host, bool continueO

#region GetHostShareFromPath

/// <summary>Gets the host and Server Message Block (SMB) share name for the given <paramref name="uncPath"/>.</summary>
/// <summary>Gets the host and share path name for the given <paramref name="uncPath"/>.</summary>
/// <param name="uncPath">The share in the format: \\host\share.</param>
/// <returns>string[0] = host, string[1] = share;</returns>
/// <returns>The host and share path. For example, if <paramref name="uncPath"/> is: "\\SERVER001\C$\WINDOWS\System32",
/// its is returned as string[0] = "SERVER001" and string[1] = "\C$\WINDOWS\System32".
/// <para>If the conversion from local path to UNC path fails, <see langword="null"/> is returned.</para>
/// </returns>
[SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "0", Justification = "Utils.IsNullOrWhiteSpace validates arguments.")]
[SecurityCritical]
public static string[] GetHostShareFromPath(string uncPath)
{
if (Utils.IsNullOrWhiteSpace(uncPath))
return null;

Uri uri;
if (Uri.TryCreate(Path.GetRegularPathInternal(uncPath, GetFullPathOptions.None), UriKind.Absolute, out uri) && uri.IsUnc)
{
return new[]
{
uri.Host,
uri.AbsolutePath.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar)
};
}

// Get Host and Share.
uncPath = uncPath.Replace(Path.LongPathUncPrefix, string.Empty);
uncPath = uncPath.Replace(Path.UncPrefix, string.Empty);

return uncPath.Split(Path.DirectorySeparatorChar);
return null;
}

#endregion // GetHostShareFromPath
Expand Down

1 comment on commit 2d5a25b

@Yomodo
Copy link
Collaborator Author

@Yomodo Yomodo commented on 2d5a25b Jan 30, 2015

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wrong issue number.
Fixes #133

Please sign in to comment.