示例#1
0
        /// <summary>[AlphaFS] Creates an NTFS directory junction (similar to CMD command: "MKLINK /J").</summary>
        internal static void CreateDirectoryJunction(SafeFileHandle safeHandle, string directoryPath)
        {
            var targetDirBytes = Encoding.Unicode.GetBytes(Path.NonInterpretedPathPrefix + Path.GetRegularPathCore(directoryPath, GetFullPathOptions.AddTrailingDirectorySeparator, false));

            var header = new NativeMethods.ReparseDataBufferHeader
            {
                ReparseTag        = ReparsePointTag.MountPoint,
                ReparseDataLength = (ushort)(targetDirBytes.Length + 12)
            };

            var mountPoint = new NativeMethods.MountPointReparseBuffer
            {
                SubstituteNameOffset = 0,
                SubstituteNameLength = (ushort)targetDirBytes.Length,
                PrintNameOffset      = (ushort)(targetDirBytes.Length + UnicodeEncoding.CharSize),
                PrintNameLength      = 0
            };

            var reparseDataBuffer = new NativeMethods.REPARSE_DATA_BUFFER
            {
                ReparseTag        = header.ReparseTag,
                ReparseDataLength = header.ReparseDataLength,

                SubstituteNameOffset = mountPoint.SubstituteNameOffset,
                SubstituteNameLength = mountPoint.SubstituteNameLength,
                PrintNameOffset      = mountPoint.PrintNameOffset,
                PrintNameLength      = mountPoint.PrintNameLength,

                PathBuffer = new byte[NativeMethods.MAXIMUM_REPARSE_DATA_BUFFER_SIZE - 16] // 16368
            };

            targetDirBytes.CopyTo(reparseDataBuffer.PathBuffer, 0);


            using (var safeBuffer = new SafeGlobalMemoryBufferHandle(Marshal.SizeOf(reparseDataBuffer)))
            {
                safeBuffer.StructureToPtr(reparseDataBuffer, false);

                uint bytesReturned;
                var  succes = NativeMethods.DeviceIoControl2(safeHandle, NativeMethods.FSCTL_SET_REPARSE_POINT, safeBuffer, (uint)(targetDirBytes.Length + 20), IntPtr.Zero, 0, out bytesReturned, IntPtr.Zero);

                var lastError = Marshal.GetLastWin32Error();
                if (!succes)
                {
                    NativeError.ThrowException(lastError, directoryPath);
                }
            }
        }
示例#2
0
        /// <summary>[AlphaFS] Deletes an NTFS directory junction.</summary>
        internal static void DeleteDirectoryJunction(SafeFileHandle safeHandle)
        {
            var reparseDataBuffer = new NativeMethods.REPARSE_DATA_BUFFER
            {
                ReparseTag        = ReparsePointTag.MountPoint,
                ReparseDataLength = 0,
                PathBuffer        = new byte[NativeMethods.MAXIMUM_REPARSE_DATA_BUFFER_SIZE - 16] // 16368
            };


            using (var safeBuffer = new SafeGlobalMemoryBufferHandle(Marshal.SizeOf(reparseDataBuffer)))
            {
                safeBuffer.StructureToPtr(reparseDataBuffer, false);

                uint bytesReturned;
                var  success = NativeMethods.DeviceIoControl2(safeHandle, NativeMethods.FSCTL_DELETE_REPARSE_POINT, safeBuffer, NativeMethods.REPARSE_DATA_BUFFER_HEADER_SIZE, IntPtr.Zero, 0, out bytesReturned, IntPtr.Zero);

                var lastError = Marshal.GetLastWin32Error();
                if (!success)
                {
                    NativeError.ThrowException(lastError);
                }
            }
        }