Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/Framework/NativeMethods.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1136,7 +1136,7 @@ internal static bool TryGetFinalLinkTarget(FileInfo fileInfo, out string finalTa
return true;
}

internal static bool MakeSymbolicLink(string newFileName, string exitingFileName, ref string errorMessage)
internal static bool MakeSymbolicLink(string newFileName, string exitingFileName, ref string errorMessage, string errorMessagePrefix = "")
{
bool symbolicLinkCreated;
if (IsWindows)
Expand All @@ -1154,7 +1154,7 @@ internal static bool MakeSymbolicLink(string newFileName, string exitingFileName
else
{
symbolicLinkCreated = symlink(exitingFileName, newFileName) == 0;
errorMessage = symbolicLinkCreated ? null : "The link() library call failed with the following error code: " + Marshal.GetLastWin32Error();
errorMessage = symbolicLinkCreated ? null : errorMessagePrefix + Marshal.GetLastWin32Error();
}

return symbolicLinkCreated;
Expand Down
19 changes: 10 additions & 9 deletions src/Tasks.UnitTests/Copy_Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2313,15 +2313,6 @@ public void CopyToDestinationFolderWithHardLinkFallbackTooManyLinks()

Directory.CreateDirectory(destFolder);

// Exhaust the number (1024) of directory entries that can be created for a file
// This is 1 + (1 x hard links)
// We need to test the fallback code path when we're out of directory entries for a file..
for (int n = 0; n < 1025 /* make sure */; n++)
{
string destLink = Path.Combine(destFolder, Path.GetFileNameWithoutExtension(sourceFile) + "." + n);
string linkError = String.Empty;
Tasks.NativeMethods.MakeHardLink(destLink, sourceFile, ref linkError);
}

ITaskItem[] sourceFiles = { new TaskItem(sourceFile) };

Expand All @@ -2336,6 +2327,16 @@ public void CopyToDestinationFolderWithHardLinkFallbackTooManyLinks()
SkipUnchangedFiles = true
};

// Exhaust the number (1024) of directory entries that can be created for a file
// This is 1 + (1 x hard links)
// We need to test the fallback code path when we're out of directory entries for a file..
for (int n = 0; n < 1025 /* make sure */; n++)
{
string destLink = Path.Combine(destFolder, Path.GetFileNameWithoutExtension(sourceFile) + "." + n);
string linkError = String.Empty;
Tasks.NativeMethods.MakeHardLink(destLink, sourceFile, ref linkError, t.Log);
}

bool success = t.Execute();

Assert.True(success); // "success"
Expand Down
10 changes: 5 additions & 5 deletions src/Tasks/Copy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -283,10 +283,10 @@ FileState destinationFileState // The destination file
// Create hard links if UseHardlinksIfPossible is true
if (UseHardlinksIfPossible)
{
TryCopyViaLink(HardLinkComment, MessageImportance.Normal, sourceFileState, destinationFileState, ref destinationFileExists, out hardLinkCreated, ref errorMessage, (source, destination, errMessage) => NativeMethods.MakeHardLink(destination, source, ref errorMessage));
if(!hardLinkCreated)
TryCopyViaLink(HardLinkComment, MessageImportance.Normal, sourceFileState, destinationFileState, ref destinationFileExists, out hardLinkCreated, ref errorMessage, (source, destination, errMessage) => NativeMethods.MakeHardLink(destination, source, ref errorMessage, Log));
if (!hardLinkCreated)
{
if(UseSymboliclinksIfPossible)
if (UseSymboliclinksIfPossible)
{
// This is a message for fallback to SymbolicLinks if HardLinks fail when UseHardlinksIfPossible and UseSymboliclinksIfPossible are true
Log.LogMessage(MessageImportance.Normal, RetryingAsSymbolicLink, sourceFileState.Name, destinationFileState.Name, errorMessage);
Expand All @@ -301,8 +301,8 @@ FileState destinationFileState // The destination file
// Create symbolic link if UseSymboliclinksIfPossible is true and hard link is not created
if (!hardLinkCreated && UseSymboliclinksIfPossible)
{
TryCopyViaLink(SymbolicLinkComment, MessageImportance.Normal, sourceFileState, destinationFileState, ref destinationFileExists, out symbolicLinkCreated, ref errorMessage, (source, destination, errMessage) => NativeMethodsShared.MakeSymbolicLink(destination, source, ref errorMessage));
if(!symbolicLinkCreated)
TryCopyViaLink(SymbolicLinkComment, MessageImportance.Normal, sourceFileState, destinationFileState, ref destinationFileExists, out symbolicLinkCreated, ref errorMessage, (source, destination, errMessage) => NativeMethodsShared.MakeSymbolicLink(destination, source, ref errorMessage, Log.FormatResourceString("Copy.LinklibraryFailedPrefix", "symlink()")));
if (!symbolicLinkCreated)
{
Log.LogMessage(MessageImportance.Normal, RetryingAsFileCopy, sourceFileState.Name, destinationFileState.Name, errorMessage);
}
Expand Down
48 changes: 24 additions & 24 deletions src/Tasks/NativeMethods.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,20 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System;
using System.IO;
using System.Runtime.InteropServices;
using Microsoft.Build.Shared.FileSystem;

using System.Text;
using System.Reflection;
using Microsoft.Build.Shared;
using System.Collections.Generic;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.ExceptionServices;
using System.Text.RegularExpressions;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Text;
using System.Text.RegularExpressions;
using Microsoft.Build.Shared;
using Microsoft.Build.Shared.FileSystem;
using Microsoft.Build.Utilities;

#nullable disable

Expand Down Expand Up @@ -94,7 +94,7 @@ internal interface IMetaDataDispenser
object DefineScope([In] ref Guid rclsid, [In] UInt32 dwCreateFlags, [In] ref Guid riid);

[return: MarshalAs(UnmanagedType.Interface)]
object OpenScope([In][MarshalAs(UnmanagedType.LPWStr)] string szScope, [In] UInt32 dwOpenFlags, [In] ref Guid riid);
object OpenScope([In][MarshalAs(UnmanagedType.LPWStr)] string szScope, [In] UInt32 dwOpenFlags, [In] ref Guid riid);

[return: MarshalAs(UnmanagedType.Interface)]
object OpenScopeOnMemory([In] IntPtr pData, [In] UInt32 cbData, [In] UInt32 dwOpenFlags, [In] ref Guid riid);
Expand Down Expand Up @@ -519,7 +519,7 @@ internal struct PROCESS_INFORMATION
/// </summary>
internal static class NativeMethods
{
#region Constants
#region Constants

internal static readonly IntPtr NullPtr = IntPtr.Zero;
internal static readonly IntPtr InvalidIntPtr = new IntPtr(-1);
Expand Down Expand Up @@ -624,9 +624,9 @@ internal enum MoveFileFlags
MOVEFILE_FAIL_IF_NOT_TRACKABLE = 0x00000020
}

#endregion
#endregion

#region NT header stuff
#region NT header stuff

internal const uint IMAGE_NT_OPTIONAL_HDR32_MAGIC = 0x10b;
internal const uint IMAGE_NT_OPTIONAL_HDR64_MAGIC = 0x20b;
Expand Down Expand Up @@ -777,9 +777,9 @@ internal struct CRYPTOAPI_BLOB
internal IntPtr pbData;
}

#endregion
#endregion

#region PInvoke
#region PInvoke
private const string Crypt32DLL = "crypt32.dll";
private const string Advapi32DLL = "advapi32.dll";
#if !RUNTIME_TYPE_NETCORE
Expand All @@ -795,7 +795,7 @@ internal struct CRYPTOAPI_BLOB
[DllImport("libc", SetLastError = true)]
internal static extern int link(string oldpath, string newpath);

internal static bool MakeHardLink(string newFileName, string exitingFileName, ref string errorMessage)
internal static bool MakeHardLink(string newFileName, string exitingFileName, ref string errorMessage, TaskLoggingHelper log)
{
bool hardLinkCreated;
if (NativeMethodsShared.IsWindows)
Expand All @@ -806,7 +806,7 @@ internal static bool MakeHardLink(string newFileName, string exitingFileName, re
else
{
hardLinkCreated = link(exitingFileName, newFileName) == 0;
errorMessage = hardLinkCreated ? null : "The link() library call failed with the following error code: " + Marshal.GetLastWin32Error();
errorMessage = hardLinkCreated ? null : log.FormatResourceString("Copy.LinklibraryFailedPrefix", "link()") + Marshal.GetLastWin32Error();
}

return hardLinkCreated;
Expand Down Expand Up @@ -1046,13 +1046,13 @@ internal static extern int CreateAssemblyNameObject(
//------------------------------------------------------------------------------
[DllImport(Crypt32DLL, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool CertCloseStore([In] IntPtr CertStore, CertStoreClose Flags);
internal static extern bool CertCloseStore([In] IntPtr CertStore, CertStoreClose Flags);

//------------------------------------------------------------------------------
// CertEnumCertificatesInStore
//------------------------------------------------------------------------------
[DllImport(Crypt32DLL, SetLastError = true)]
internal static extern IntPtr CertEnumCertificatesInStore([In] IntPtr CertStore, [In] IntPtr PrevCertContext);
internal static extern IntPtr CertEnumCertificatesInStore([In] IntPtr CertStore, [In] IntPtr PrevCertContext);

//------------------------------------------------------------------------------
// CryptAcquireCertificatePrivateKey
Expand Down Expand Up @@ -1108,9 +1108,9 @@ internal static extern int CreateAssemblyNameObject(
[DllImport(MscoreeDLL, SetLastError = true, CharSet = CharSet.Unicode)]
internal static extern unsafe uint GetFileVersion([MarshalAs(UnmanagedType.LPWStr)] string szFileName, [Out] char* szBuffer, int cchBuffer, out int dwLength);
#endif
#endregion
#endregion

#region Methods
#region Methods
#if FEATURE_HANDLEPROCESSCORRUPTEDSTATEEXCEPTIONS
/// <summary>
/// Given a pointer to a metadata blob, read the string parameter from it. Returns true if
Expand Down Expand Up @@ -1231,8 +1231,8 @@ internal static unsafe int CorSigUncompressData(IntPtr data, out int uncompresse

return count;
}
#endregion
#region InternalClass
#endregion
#region InternalClass
/// <summary>
/// This class is a wrapper over the native GAC enumeration API.
/// </summary>
Expand Down Expand Up @@ -1470,6 +1470,6 @@ public static string AssemblyPathFromStrongName(string strongName)
return null;
}
}
#endregion
#endregion
}
}
3 changes: 3 additions & 0 deletions src/Tasks/Resources/Strings.resx
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,9 @@
If this bucket overflows, pls. contact 'vsppbdev'.
-->
<data name="Copy.LinklibraryFailedPrefix">
<value>The {0} library call failed with the following error code: </value>
</data>
<data name="Copy.CreatesDirectory">
<value>Creating directory "{0}".</value>
</data>
Expand Down
5 changes: 5 additions & 0 deletions src/Tasks/Resources/xlf/Strings.cs.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/Tasks/Resources/xlf/Strings.de.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/Tasks/Resources/xlf/Strings.es.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/Tasks/Resources/xlf/Strings.fr.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/Tasks/Resources/xlf/Strings.it.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/Tasks/Resources/xlf/Strings.ja.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/Tasks/Resources/xlf/Strings.ko.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/Tasks/Resources/xlf/Strings.pl.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/Tasks/Resources/xlf/Strings.pt-BR.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/Tasks/Resources/xlf/Strings.ru.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading