You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

111 lines
3.7 KiB

using Alphaleonis.Win32.Filesystem;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Management.Automation;
namespace NTFSSecurity
{
[Cmdlet(VerbsCommon.New, "NTFSHardLink")]
[OutputType(typeof(FileInfo), typeof(DirectoryInfo))]
public class NewHardLink : BaseCmdlet
{
string target;
private bool passThru;
System.Reflection.MethodInfo modeMethodInfo = null;
[Parameter(Position = 1, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true)]
[ValidateNotNullOrEmpty]
[Alias("FullName")]
[FileSystemPathTransformation]
public string Path
{
get { return paths[0]; }
set
{
paths.Clear();
paths.Add(value);
}
}
[Parameter(Position = 2, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true)]
[ValidateNotNullOrEmpty]
[FileSystemPathTransformation]
public string Target
{
get { return target; }
set { target = value; }
}
[Parameter]
public SwitchParameter PassThru
{
get { return passThru; }
set { passThru = value; }
}
protected override void BeginProcessing()
{
base.BeginProcessing();
modeMethodInfo = typeof(FileSystemCodeMembers).GetMethod("Mode");
}
protected override void ProcessRecord()
{
var path = paths[0];
path = GetRelativePath(path);
target = GetRelativePath(target);
var root = System.IO.Path.GetPathRoot(path);
try
{
FileSystemInfo temp = null;
if (TryGetFileSystemInfo2(path, out temp))
throw new ArgumentException(string.Format("The file '{0}' does already exist, cannot create the link", path));
if (!TryGetFileSystemInfo2(target, out temp))
throw new ArgumentException(string.Format("The target '{0}' does not exist, cannot create the link", target));
else
if (temp is DirectoryInfo)
throw new ArgumentException("The target is not a file, cannot create the link");
File.CreateHardlink(path, target);
if (passThru)
{
IEnumerable<string> links;
try
{
links = File.EnumerateHardlinks(path).ToList();
}
// Windows can't list the names of a file on a network share: (50) The request is not supported.
// The link exists; before 5.0.0-rc6, this stopped the cmdlet with a terminating error.
catch (System.IO.IOException ex)
{
WriteError(new ErrorRecord(ex, "GetHardLinkError", ErrorCategory.ReadError, path));
return;
}
foreach (var link in links)
{
var target = new PSObject(GetFileSystemInfo2(System.IO.Path.Combine(root, link.Substring(1))));
target.Properties.Add(new PSCodeProperty("Mode", modeMethodInfo));
WriteObject(target);
}
}
}
catch (System.IO.FileNotFoundException ex)
{
WriteError(new ErrorRecord(ex, "CreateHardLinkError", ErrorCategory.WriteError, path));
}
}
protected override void EndProcessing()
{
base.EndProcessing();
}
}
}