示例#1
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 (File.Exists(junctionPoint))
                {
                    throw new IOException("Path is not a junction point.");
                }

                return;
            }

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


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

                    int bytesReturned;
                    var 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);
                 * }*/
            }
        }
示例#2
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 = Path.GetFullPath(targetDir);

            if (!Directory.Exists(targetDir))
            {
                Directory.CreateDirectory(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 (var handle = OpenReparsePoint(junctionPoint, EFileAccess.GenericWrite))
            {
                var targetDirBytes    = Encoding.Unicode.GetBytes(NonInterpretedPathPrefix + Path.GetFullPath(targetDir));
                var reparseDataBuffer = new Object();

                //if(!isSymLink)
                if (true)
                {
                    reparseDataBuffer =
                        new REPARSE_DATA_BUFFER_MOUNT_POINT
                    {
                        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, ((REPARSE_DATA_BUFFER_MOUNT_POINT)reparseDataBuffer).PathBuffer, targetDirBytes.Length);
                }

                /*
                 * else
                 * {
                 *  reparseDataBuffer =
                 *      new REPARSE_DATA_BUFFER_SYM_LINK
                 *      {
                 *          ReparseTag = IO_REPARSE_TAG_SYMLINK,
                 *          ReparseDataLength = (ushort)(targetDirBytes.Length + 12),
                 *          SubstituteNameOffset = 0,
                 *          SubstituteNameLength = (ushort)targetDirBytes.Length,
                 *          PrintNameOffset = (ushort)(targetDirBytes.Length + 2),
                 *          PrintNameLength = 0,
                 *          Flags = 0,
                 *          PathBuffer = new byte[0x3ff0]
                 *      };
                 *  Array.Copy(targetDirBytes, ((REPARSE_DATA_BUFFER_SYM_LINK)reparseDataBuffer).PathBuffer, targetDirBytes.Length);
                 * }*/

                var inBufferSize = Marshal.SizeOf(reparseDataBuffer);
                var inBuffer     = Marshal.AllocHGlobal(inBufferSize);

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

                    int bytesReturned;
                    var 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);
                }
            }
        }