示例#1
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 = Path.GetFullPath(junctionPath);
            targetDirectory = Path.GetFullPath(targetDirectory);

            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 = NativeMethods.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);
                }
            }
        }
示例#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));
        }