private NativeMethods.ReparseDataBuffer GetReparsePointInfo() { const uint fileOpenReparsePoint = 0x00200000; const uint fileFlagBackupSemantics = 0x02000000; const FileOptions flags = (FileOptions)(fileOpenReparsePoint | fileFlagBackupSemantics); using (var handle = NativeMethods.CreateFile(LinkName, NativeMethods.FileAccessEx.None, FileShare.Read, IntPtr.Zero, FileMode.Open, flags, IntPtr.Zero)) { if (handle.IsInvalid) { throw Win32Utils.GetExceptionForLastError(); } var reparseDataBuffer = new NativeMethods.ReparseDataBuffer(); const int fsctlGetReparsePoint = 0x000900A8; var bytesReturned = 0; var success = NativeMethods.DeviceIoControl(handle, fsctlGetReparsePoint, IntPtr.Zero, 0, reparseDataBuffer, Marshal.SizeOf(typeof(NativeMethods.ReparseDataBuffer)), ref bytesReturned, IntPtr.Zero); if (!success) { const uint pathNotAReparsePointError = 0x80071126; if ((uint)Marshal.GetHRForLastWin32Error() == pathNotAReparsePointError) { return(null); } throw Win32Utils.GetExceptionForLastError(); } return(reparseDataBuffer); } }
public override bool Execute() { if (string.IsNullOrEmpty(LinkName)) { throw new InvalidOperationException("LinkName was not set"); } if (string.IsNullOrEmpty(TargetName)) { throw new InvalidOperationException("TargetName was not set"); } var linkParentDirectory = Path.GetDirectoryName(LinkName.TrimEnd('\\')); try { if (linkParentDirectory != null && !Directory.Exists(linkParentDirectory)) { Directory.CreateDirectory(linkParentDirectory); } } catch (Exception ex) { Log.LogError($"Error creating symbolic link for {LinkName} <<====>> {TargetName}. Could not create parent directory {linkParentDirectory}: {ex.Message}"); return(false); } var result = NativeMethods.CreateSymbolicLink(LinkName.TrimEnd('\\'), TargetName.TrimEnd('\\'), _targetType); if (!result) { const uint requiredPrivilegeError = 0x80070522; if ((uint)Marshal.GetHRForLastWin32Error() == requiredPrivilegeError) { Log.LogError($"Error creating symbolic link for {LinkName} <<====>> {TargetName}. Try running the build from an elevated process."); return(false); } var exception = Win32Utils.GetExceptionForLastError(); Log.LogError($"Error creating symbolic link for {LinkName} <<====>> {TargetName}: {exception.Message}"); return(false); } Log.LogMessage(MessageImportance.High, $"Symbolic link created for {LinkName} <<====>> {TargetName}"); return(true); }