Beispiel #1
0
        /// <summary>
        /// Creates a junction point from the specified directory to the specified target directory.
        /// </summary>
        /// <remarks>
        /// Only works on NTFS.
        /// </remarks>
        /// <param name="junctionPoint">The junction point path</param>
        /// <param name="targetDir">The target directory</param>
        /// <param name="overwrite">If true overwrites an existing reparse point or empty directory</param>
        /// <exception cref="IOException">Thrown when the junction point could not be created or when
        /// an existing directory was found and <paramref name="overwrite" /> if false</exception>
        public static void Create(string junctionPoint, string targetDir, bool overwrite)
        {
            targetDir = System.IO.Path.GetFullPath(targetDir);

            if (!Directory.Exists(targetDir))
            {
                throw new IOException("Target path does not exist or is not a directory.");
            }

            if (Directory.Exists(junctionPoint))
            {
                if (!overwrite)
                {
                    throw new IOException("Directory already exists and overwrite parameter is false.");
                }
            }
            else
            {
                Directory.CreateDirectory(junctionPoint);
            }

            using (SafeFileHandle handle = ReparsePoint.OpenReparsePoint(junctionPoint, ReparsePoint.EFileAccess.GenericWrite))
            {
                byte[] targetDirBytes = Encoding.Unicode.GetBytes(NonInterpretedPathPrefix + System.IO.Path.GetFullPath(targetDir));

                var reparseDataBuffer = new ReparseData
                {
                    ReparseTag           = IO_REPARSE_TAG_MOUNT_POINT,
                    ReparseDataLength    = (ushort)(targetDirBytes.Length + 12),
                    SubstituteNameOffset = 0,
                    SubstituteNameLength = (ushort)targetDirBytes.Length,
                    PrintNameOffset      = (ushort)(targetDirBytes.Length + 2),
                    PrintNameLength      = 0,
                    PathBuffer           = new byte[0x3ff0]
                };

                Array.Copy(targetDirBytes, reparseDataBuffer.PathBuffer, targetDirBytes.Length);

                int    inBufferSize = Marshal.SizeOf(reparseDataBuffer);
                IntPtr inBuffer     = Marshal.AllocHGlobal(inBufferSize);

                try
                {
                    Marshal.StructureToPtr(reparseDataBuffer, inBuffer, false);

                    int  bytesReturned;
                    bool result = DeviceIoControl(handle.DangerousGetHandle(), FSCTL_SET_REPARSE_POINT,
                                                  inBuffer, targetDirBytes.Length + 20, IntPtr.Zero, 0, out bytesReturned, IntPtr.Zero);

                    if (!result)
                    {
                        ThrowLastWin32Error("Unable to create junction point.");
                    }
                }
                finally
                {
                    Marshal.FreeHGlobal(inBuffer);
                }
            }
        }
Beispiel #2
0
        /// <summary>
        /// Determines whether the specified path exists and refers to a junction point.
        /// </summary>
        /// <param name="path">The junction point path</param>
        /// <returns>True if the specified path represents a junction point</returns>
        /// <exception cref="IOException">Thrown if the specified path is invalid
        /// or some other error occurs</exception>
        public static bool Exists(string path)
        {
            if (!Directory.Exists(path))
            {
                return(false);
            }

            var target = ReparsePoint.GetTarget(path);

            return(target != null);
        }
Beispiel #3
0
        public static bool IsSymbolicLink(string path)
        {
            using (SafeFileHandle handle = ReparsePoint.OpenReparsePoint(path, ReparsePoint.EFileAccess.GenericRead))
            {
                var data = ReparsePoint.GetReparseData(handle);
                if (data == null)
                {
                    return(false);
                }

                return(data.Value.ReparseTag == ReparsePoint.IO_SYMOBOLIC_LINK_TAG);
            }
        }
Beispiel #4
0
        /// <summary>
        /// Deletes a junction point at the specified source directory along with the directory itself.
        /// Does nothing if the junction point does not exist.
        /// </summary>
        /// <remarks>
        /// Only works on NTFS.
        /// </remarks>
        /// <param name="junctionPoint">The junction point path</param>
        public static void Delete(string junctionPoint)
        {
            if (!Directory.Exists(junctionPoint))
            {
                if (IOFile.Exists(junctionPoint))
                {
                    throw new IOException("Path is not a junction point.");
                }

                return;
            }

            using (SafeFileHandle handle = ReparsePoint.OpenReparsePoint(junctionPoint, ReparsePoint.EFileAccess.GenericWrite))
            {
                var reparseDataBuffer = new ReparseData
                {
                    ReparseTag        = IO_REPARSE_TAG_MOUNT_POINT,
                    ReparseDataLength = 0,
                    PathBuffer        = new byte[0x3ff0]
                };

                int    inBufferSize = Marshal.SizeOf(reparseDataBuffer);
                IntPtr inBuffer     = Marshal.AllocHGlobal(inBufferSize);
                try
                {
                    Marshal.StructureToPtr(reparseDataBuffer, inBuffer, false);

                    int  bytesReturned;
                    bool result = DeviceIoControl(handle.DangerousGetHandle(), FSCTL_DELETE_REPARSE_POINT,
                                                  inBuffer, 8, IntPtr.Zero, 0, out bytesReturned, IntPtr.Zero);

                    if (!result)
                    {
                        ThrowLastWin32Error("Unable to delete junction point.");
                    }
                }
                finally
                {
                    Marshal.FreeHGlobal(inBuffer);
                }

                try
                {
                    Directory.Delete(junctionPoint);
                }
                catch (IOException ex)
                {
                    throw new IOException("Unable to delete junction point.", ex);
                }
            }
        }
Beispiel #5
0
 /// <summary>
 /// Gets the target of the specified junction point.
 /// </summary>
 /// <remarks>
 /// Only works on NTFS.
 /// </remarks>
 /// <param name="junctionPoint">The junction point path</param>
 /// <returns>The target of the junction point</returns>
 /// <exception cref="IOException">Thrown when the specified path does not
 /// exist, is invalid, is not a junction point, or some other error occurs</exception>
 public static string GetTarget(string junctionPoint)
 {
     return(ReparsePoint.GetTarget(junctionPoint));
 }
Beispiel #6
0
 public static string GetTargetPath(string path)
 {
     return(ReparsePoint.GetTarget(path));
 }