diff --git a/src/AlphaFS/Device/Device.cs b/src/AlphaFS/Device/Device.cs index 48fc880f6..74eceaeb2 100644 --- a/src/AlphaFS/Device/Device.cs +++ b/src/AlphaFS/Device/Device.cs @@ -352,7 +352,12 @@ internal static void ToggleCompressionCore(KernelTransaction transaction, bool i /// [AlphaFS] Creates an NTFS directory junction (similar to CMD command: "MKLINK /J"). internal static void CreateDirectoryJunction(SafeFileHandle safeHandle, string directoryPath) { - var targetDirBytes = Encoding.Unicode.GetBytes(Path.NonInterpretedPathPrefix + Path.GetRegularPathCore(directoryPath, GetFullPathOptions.AddTrailingDirectorySeparator, false)); + var targetDir = Path.GetRegularPathCore(directoryPath, GetFullPathOptions.AddTrailingDirectorySeparator, false); + // junctions to volume-prefixed paths need the long path prefix removed. Correct: \??\Volume{000...}\foo, wrong: \??\\\?\Volume{000...}\foo + if (targetDir.StartsWith(Path.VolumePrefix)) + targetDir = targetDir.Substring(Path.LongPathPrefix.Length); + targetDir = Path.NonInterpretedPathPrefix + targetDir; + var targetDirBytes = Encoding.Unicode.GetBytes(targetDir); var header = new NativeMethods.ReparseDataBufferHeader { diff --git a/tests/AlphaFS.UnitTest/AlphaFS Junctions, Links/AlphaFS_DirectoryInfo.CreateJunction_And_ExistsJunction_And_DeleteJunction.cs b/tests/AlphaFS.UnitTest/AlphaFS Junctions, Links/AlphaFS_DirectoryInfo.CreateJunction_And_ExistsJunction_And_DeleteJunction.cs index 33596d543..fb24fdb6d 100644 --- a/tests/AlphaFS.UnitTest/AlphaFS Junctions, Links/AlphaFS_DirectoryInfo.CreateJunction_And_ExistsJunction_And_DeleteJunction.cs +++ b/tests/AlphaFS.UnitTest/AlphaFS Junctions, Links/AlphaFS_DirectoryInfo.CreateJunction_And_ExistsJunction_And_DeleteJunction.cs @@ -31,12 +31,33 @@ public partial class AlphaFS_JunctionsLinksTest [TestMethod] public void AlphaFS_DirectoryInfo_CreateJunction_And_ExistsJunction_And_DeleteJunction_Local_Success() + { + AlphaFS_DirectoryInfo_CreateJunction_And_ExistsJunction_And_DeleteJunction_Local_Success_core(false); + } + + [TestMethod] + public void AlphaFS_DirectoryInfo_CreateJunction_And_ExistsJunction_And_DeleteJunction_Local_VolumePath_Success() + { + AlphaFS_DirectoryInfo_CreateJunction_And_ExistsJunction_And_DeleteJunction_Local_Success_core(true); + } + + private void AlphaFS_DirectoryInfo_CreateJunction_And_ExistsJunction_And_DeleteJunction_Local_Success_core(bool volumeTarget) { using (var tempRoot = new TemporaryDirectory()) { var toDelete = tempRoot.Directory.CreateSubdirectory("ToDelete"); var junction = System.IO.Path.Combine(toDelete.FullName, "MyJunctionPoint"); - var target = tempRoot.Directory.CreateSubdirectory("JunctionTarget"); + var target = tempRoot.Directory.CreateSubdirectory("JunctionTarget").FullName; + + if (volumeTarget) + { + var volumeGuidPath = Alphaleonis.Win32.Filesystem.Volume.GetUniqueVolumeNameForPath(target); + var volumePath = Alphaleonis.Win32.Filesystem.Volume.GetVolumePathName(target); + var targetNew = target.Replace(volumePath, volumeGuidPath); + if (targetNew == target || !targetNew.StartsWith(Alphaleonis.Win32.Filesystem.Path.VolumePrefix)) + Assert.Inconclusive(@"Failed to construct a \\?\Volume style path for this test"); + target = targetNew; + } Console.WriteLine("Input Directory JunctionPoint Path: [{0}]", junction); Console.WriteLine("Input Directory JunctionTarget Path: [{0}]", target); @@ -44,7 +65,7 @@ public void AlphaFS_DirectoryInfo_CreateJunction_And_ExistsJunction_And_DeleteJu #region CreateJunction - var dirInfo = new Alphaleonis.Win32.Filesystem.DirectoryInfo(target.FullName); + var dirInfo = new Alphaleonis.Win32.Filesystem.DirectoryInfo(target); // On success, dirInfo.FullName now points to the directory junction. @@ -87,7 +108,7 @@ public void AlphaFS_DirectoryInfo_CreateJunction_And_ExistsJunction_And_DeleteJu const string subFolder = "Test folder"; dirInfo.CreateSubdirectory(subFolder); - Assert.IsTrue(System.IO.Directory.Exists(System.IO.Path.Combine(target.FullName, subFolder))); + Assert.IsTrue(System.IO.Directory.Exists(System.IO.Path.Combine(target, subFolder))); #endregion // CreateJunction