Esempio n. 1
0
        /// <summary>
        ///     Prevents a default instance of the <see cref="ReparsePoint" /> class from being created. Populates the data from the buffer pointed to by the pointer.
        /// </summary>
        /// <param name="buffer"> The buffer. </param>
        /// <remarks>
        /// </remarks>
        private ReparsePoint(IntPtr buffer) {
            if (buffer == IntPtr.Zero) {
                throw new ArgumentNullException("buffer");
            }

            _reparseDataData = (ReparseData)Marshal.PtrToStructure(buffer, typeof (ReparseData));
        }
Esempio n. 2
0
        /// <summary>
        ///     Prevents a default instance of the <see cref="ReparsePoint" /> class from being created. Populates the data from the buffer pointed to by the pointer.
        /// </summary>
        /// <param name="buffer"> The buffer. </param>
        /// <remarks>
        /// </remarks>
        private ReparsePoint(IntPtr buffer)
        {
            if (buffer == IntPtr.Zero)
            {
                throw new ArgumentNullException("buffer");
            }

            _reparseDataData = (ReparseData)Marshal.PtrToStructure(buffer, typeof(ReparseData));
        }
Esempio n. 3
0
        /// <summary>
        ///     Creates the junction.
        /// </summary>
        /// <param name="junctionPath"> The junction path. </param>
        /// <param name="targetDirectory"> The target directory. </param>
        /// <returns> </returns>
        /// <remarks>
        /// </remarks>
        public static ReparsePoint CreateJunction(string junctionPath, string targetDirectory)
        {
            junctionPath    = junctionPath.GetFullPath();
            targetDirectory = targetDirectory.GetFullPath();

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

            if (Directory.Exists(junctionPath) || File.Exists(junctionPath))
            {
                throw new IOException("Junction path already exists.");
            }

            Directory.CreateDirectory(junctionPath);

            using (var handle = GetReparsePointHandle(junctionPath, NativeFileAccess.GenericWrite)) {
                var substituteName = Encoding.Unicode.GetBytes(NonInterpretedPathPrefix + targetDirectory);
                var printName      = Encoding.Unicode.GetBytes(targetDirectory);

                var reparseDataBuffer = new ReparseData {
                    ReparseTag           = IoReparseTag.MountPoint,
                    SubstituteNameOffset = 0,
                    SubstituteNameLength = (ushort)substituteName.Length,
                    PrintNameOffset      = (ushort)(substituteName.Length + 2),
                    PrintNameLength      = (ushort)printName.Length,
                    PathBuffer           = new byte[0x3ff0],
                };

                reparseDataBuffer.ReparseDataLength = (ushort)(reparseDataBuffer.PrintNameLength + reparseDataBuffer.PrintNameOffset + 10);

                Array.Copy(substituteName, reparseDataBuffer.PathBuffer, substituteName.Length);
                Array.Copy(printName, 0, reparseDataBuffer.PathBuffer, reparseDataBuffer.PrintNameOffset, printName.Length);

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

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

                    int bytesReturned;
                    var result = Kernel32.DeviceIoControl(handle, ControlCodes.SetReparsePoint, inBuffer, reparseDataBuffer.ReparseDataLength + 8, IntPtr.Zero,
                                                          0, out bytesReturned, IntPtr.Zero);

                    if (!result)
                    {
                        Directory.Delete(junctionPath);
                        throw new IOException("Unable to create junction point.", Marshal.GetExceptionForHR(Marshal.GetHRForLastWin32Error()));
                    }

                    return(Open(junctionPath));
                } finally {
                    Marshal.FreeHGlobal(inBuffer);
                }
            }
        }
Esempio n. 4
0
        public static ReparsePoint CreateSymlink(string symlinkPath, string linkTarget)
        {
            symlinkPath = symlinkPath.GetFullPath();
            linkTarget  = linkTarget.GetFullPath();

            if (Directory.Exists(symlinkPath) || File.Exists(symlinkPath))
            {
                throw new IOException("Symlink path already exists.");
            }

            if (Directory.Exists(linkTarget))
            {
                Directory.CreateDirectory(symlinkPath);
            }
            else if (File.Exists(linkTarget))
            {
                File.Create(symlinkPath).Close();
            }
            else
            {
                throw new IOException("Target path does not exist or is not a directory.");
            }

            // dark magic kung-fu to get privilige to create symlink.
            var    state     = IntPtr.Zero;
            UInt32 privilege = 35;

            Ntdll.RtlAcquirePrivilege(ref privilege, 1, 0, ref state);

            using (var handle = GetReparsePointHandle(symlinkPath, NativeFileAccess.GenericWrite)) {
                var substituteName = Encoding.Unicode.GetBytes(NonInterpretedPathPrefix + linkTarget);
                var printName      = Encoding.Unicode.GetBytes(linkTarget);
                var extraOffset    = 4;

                var reparseDataBuffer = new ReparseData {
                    ReparseTag           = IoReparseTag.Symlink,
                    SubstituteNameOffset = 0,
                    SubstituteNameLength = (ushort)substituteName.Length,
                    PrintNameOffset      = (ushort)(substituteName.Length + 2),
                    PrintNameLength      = (ushort)printName.Length,
                    PathBuffer           = new byte[0x3ff0],
                };

                reparseDataBuffer.ReparseDataLength = (ushort)(reparseDataBuffer.PrintNameLength + reparseDataBuffer.PrintNameOffset + 10 + extraOffset);

                Array.Copy(substituteName, 0, reparseDataBuffer.PathBuffer, extraOffset, substituteName.Length);
                Array.Copy(printName, 0, reparseDataBuffer.PathBuffer, reparseDataBuffer.PrintNameOffset + extraOffset, printName.Length);

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

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

                    int bytesReturned;
                    var result = Kernel32.DeviceIoControl(handle, ControlCodes.SetReparsePoint, inBuffer, reparseDataBuffer.ReparseDataLength + 8, IntPtr.Zero,
                                                          0, out bytesReturned, IntPtr.Zero);

                    if (!result)
                    {
                        if (Directory.Exists(symlinkPath))
                        {
                            Directory.Delete(symlinkPath);
                        }
                        else if (File.Exists(symlinkPath))
                        {
                            File.Delete(symlinkPath);
                        }

                        throw new IOException("Unable to create symlink.", Marshal.GetExceptionForHR(Marshal.GetHRForLastWin32Error()));
                    }
                    return(Open(symlinkPath));
                } finally {
                    Marshal.FreeHGlobal(inBuffer);
                    try {
                        if (state != IntPtr.Zero)
                        {
                            Ntdll.RtlReleasePrivilege(state);
                        }
                    } catch {
                        // sometimes this doesn't work so well
                    }
                }
            }
        }
Esempio n. 5
0
        public static ReparsePoint CreateSymlink(string symlinkPath, string linkTarget) {
            symlinkPath = symlinkPath.GetFullPath();
            linkTarget = linkTarget.GetFullPath();

            if (Directory.Exists(symlinkPath) || File.Exists(symlinkPath)) {
                throw new IOException("Symlink path already exists.");
            }

            if (Directory.Exists(linkTarget)) {
                Directory.CreateDirectory(symlinkPath);
            } else if (File.Exists(linkTarget)) {
                File.Create(symlinkPath).Close();
            } else {
                throw new IOException("Target path does not exist or is not a directory.");
            }

            // dark magic kung-fu to get privilige to create symlink.
            var state = IntPtr.Zero;
            UInt32 privilege = 35;
            Ntdll.RtlAcquirePrivilege(ref privilege, 1, 0, ref state);

            using (var handle = GetReparsePointHandle(symlinkPath, NativeFileAccess.GenericWrite)) {
                var substituteName = Encoding.Unicode.GetBytes(NonInterpretedPathPrefix + linkTarget);
                var printName = Encoding.Unicode.GetBytes(linkTarget);
                var extraOffset = 4;

                var reparseDataBuffer = new ReparseData {
                    ReparseTag = IoReparseTag.Symlink,
                    SubstituteNameOffset = 0,
                    SubstituteNameLength = (ushort)substituteName.Length,
                    PrintNameOffset = (ushort)(substituteName.Length + 2),
                    PrintNameLength = (ushort)printName.Length,
                    PathBuffer = new byte[0x3ff0],
                };

                reparseDataBuffer.ReparseDataLength = (ushort)(reparseDataBuffer.PrintNameLength + reparseDataBuffer.PrintNameOffset + 10 + extraOffset);

                Array.Copy(substituteName, 0, reparseDataBuffer.PathBuffer, extraOffset, substituteName.Length);
                Array.Copy(printName, 0, reparseDataBuffer.PathBuffer, reparseDataBuffer.PrintNameOffset + extraOffset, printName.Length);

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

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

                    int bytesReturned;
                    var result = Kernel32.DeviceIoControl(handle, ControlCodes.SetReparsePoint, inBuffer, reparseDataBuffer.ReparseDataLength + 8, IntPtr.Zero,
                        0, out bytesReturned, IntPtr.Zero);

                    if (!result) {
                        if (Directory.Exists(symlinkPath)) {
                            Directory.Delete(symlinkPath);
                        } else if (File.Exists(symlinkPath)) {
                            File.Delete(symlinkPath);
                        }

                        throw new IOException("Unable to create symlink.", Marshal.GetExceptionForHR(Marshal.GetHRForLastWin32Error()));
                    }
                    return Open(symlinkPath);
                } finally {
                    Marshal.FreeHGlobal(inBuffer);
                    try {
                        if (state != IntPtr.Zero) {
                            Ntdll.RtlReleasePrivilege(state);
                        }
                    } catch {
                        // sometimes this doesn't work so well
                    }
                }
            }
        }
Esempio n. 6
0
        /// <summary>
        ///     Creates the junction.
        /// </summary>
        /// <param name="junctionPath"> The junction path. </param>
        /// <param name="targetDirectory"> The target directory. </param>
        /// <returns> </returns>
        /// <remarks>
        /// </remarks>
        public static ReparsePoint CreateJunction(string junctionPath, string targetDirectory) {
            junctionPath = junctionPath.GetFullPath();
            targetDirectory = targetDirectory.GetFullPath();

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

            if (Directory.Exists(junctionPath) || File.Exists(junctionPath)) {
                throw new IOException("Junction path already exists.");
            }

            Directory.CreateDirectory(junctionPath);

            using (var handle = GetReparsePointHandle(junctionPath, NativeFileAccess.GenericWrite)) {
                var substituteName = Encoding.Unicode.GetBytes(NonInterpretedPathPrefix + targetDirectory);
                var printName = Encoding.Unicode.GetBytes(targetDirectory);

                var reparseDataBuffer = new ReparseData {
                    ReparseTag = IoReparseTag.MountPoint,
                    SubstituteNameOffset = 0,
                    SubstituteNameLength = (ushort)substituteName.Length,
                    PrintNameOffset = (ushort)(substituteName.Length + 2),
                    PrintNameLength = (ushort)printName.Length,
                    PathBuffer = new byte[0x3ff0],
                };

                reparseDataBuffer.ReparseDataLength = (ushort)(reparseDataBuffer.PrintNameLength + reparseDataBuffer.PrintNameOffset + 10);

                Array.Copy(substituteName, reparseDataBuffer.PathBuffer, substituteName.Length);
                Array.Copy(printName, 0, reparseDataBuffer.PathBuffer, reparseDataBuffer.PrintNameOffset, printName.Length);

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

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

                    int bytesReturned;
                    var result = Kernel32.DeviceIoControl(handle, ControlCodes.SetReparsePoint, inBuffer, reparseDataBuffer.ReparseDataLength + 8, IntPtr.Zero,
                        0, out bytesReturned, IntPtr.Zero);

                    if (!result) {
                        Directory.Delete(junctionPath);
                        throw new IOException("Unable to create junction point.", Marshal.GetExceptionForHR(Marshal.GetHRForLastWin32Error()));
                    }

                    return Open(junctionPath);
                } finally {
                    Marshal.FreeHGlobal(inBuffer);
                }
            }
        }