Skip to content

Commit

Permalink
Convert all possible DllImports to LibraryImport for .NET 7+ (#41573
Browse files Browse the repository at this point in the history
)

* Convert all possible DllImports to LibraryImport for .NET 7+

* Explicitly declare entry point on Windows P/Invokes with W suffix.

* Mark as "ref struct".

* Consume latest source generator.

* Permit unsafe blocks.
  • Loading branch information
AaronRobinsonMSFT authored May 31, 2022
1 parent 53855d2 commit 332a6f9
Show file tree
Hide file tree
Showing 26 changed files with 683 additions and 432 deletions.
3 changes: 3 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,9 @@ charset = utf-8-bom

[*.{cs,vb}]

# SYSLIB1054: Use 'LibraryImportAttribute' instead of 'DllImportAttribute' to generate P/Invoke marshalling code at compile time
dotnet_diagnostic.SYSLIB1054.severity = warning

# CA1018: Mark attributes with AttributeUsageAttribute
dotnet_diagnostic.CA1018.severity = warning

Expand Down
1 change: 1 addition & 0 deletions eng/tools/HelixTestRunner/HelixTestRunner.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
<OutputType>Exe</OutputType>
<NoWarn>$(NoWarn);CA2007;NU5104</NoWarn>
<IsPackable>false</IsPackable>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>

<!-- We don't need this unless building for tests. -->
<ExcludeFromBuild Condition=" '$(DotNetBuildFromSource)' == 'true' OR '$(SkipTestBuild)' == 'true' ">true</ExcludeFromBuild>
Expand Down
6 changes: 3 additions & 3 deletions eng/tools/HelixTestRunner/ProcessUtil.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@

namespace HelixTestRunner;

public static class ProcessUtil
public static partial class ProcessUtil
{
[DllImport("libc", SetLastError = true, EntryPoint = "kill")]
private static extern int sys_kill(int pid, int sig);
[LibraryImport("libc", SetLastError = true, EntryPoint = "kill")]
private static partial int sys_kill(int pid, int sig);

public static Task CaptureDumpAsync()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ namespace Microsoft.AspNetCore.Cryptography.SafeHandles;
/// <summary>
/// Represents a handle to a Windows module (DLL).
/// </summary>
internal sealed unsafe class SafeLibraryHandle : SafeHandleZeroOrMinusOneIsInvalid
internal sealed unsafe partial class SafeLibraryHandle : SafeHandleZeroOrMinusOneIsInvalid
{
// Called by P/Invoke when returning SafeHandles
private SafeLibraryHandle()
Expand Down Expand Up @@ -125,48 +125,74 @@ protected override bool ReleaseHandle()
}

[SuppressUnmanagedCodeSecurity]
private static class UnsafeNativeMethods
private static partial class UnsafeNativeMethods
{
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms679351(v=vs.85).aspx
[DllImport("kernel32.dll", EntryPoint = "FormatMessageW", CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Unicode, SetLastError = true)]
#if NET7_0_OR_GREATER
[LibraryImport("kernel32.dll", EntryPoint = "FormatMessageW", SetLastError = true)]
public static partial int FormatMessage(
#else
[DllImport("kernel32.dll", EntryPoint = "FormatMessageW", SetLastError = true)]
public static extern int FormatMessage(
[In] uint dwFlags,
[In] SafeLibraryHandle lpSource,
[In] uint dwMessageId,
[In] uint dwLanguageId,
[Out] out LocalAllocHandle lpBuffer,
[In] uint nSize,
[In] IntPtr Arguments
#endif
uint dwFlags,
SafeLibraryHandle lpSource,
uint dwMessageId,
uint dwLanguageId,
out LocalAllocHandle lpBuffer,
uint nSize,
IntPtr Arguments
);

// http://msdn.microsoft.com/en-us/library/ms683152(v=vs.85).aspx
[return: MarshalAs(UnmanagedType.Bool)]
#if NETSTANDARD2_0
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
#endif
[DllImport("kernel32.dll", CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Unicode)]
internal static extern bool FreeLibrary(IntPtr hModule);
#if NET7_0_OR_GREATER
[LibraryImport("kernel32.dll")]
internal static partial bool FreeLibrary(
#else
[DllImport("kernel32.dll")]
internal static extern bool FreeLibrary(
#endif
IntPtr hModule);

// http://msdn.microsoft.com/en-us/library/ms683200(v=vs.85).aspx
[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("kernel32.dll", EntryPoint = "GetModuleHandleExW", CallingConvention = CallingConvention.Winapi, SetLastError = true)]
#if NET7_0_OR_GREATER
[LibraryImport("kernel32.dll", EntryPoint = "GetModuleHandleExW", SetLastError = true)]
internal static partial bool GetModuleHandleEx(
#else
[DllImport("kernel32.dll", EntryPoint = "GetModuleHandleExW", SetLastError = true)]
internal static extern bool GetModuleHandleEx(
[In] uint dwFlags,
[In] SafeLibraryHandle lpModuleName, // can point to a location within the module if GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS is set
[Out] out IntPtr phModule);
#endif
uint dwFlags,
SafeLibraryHandle lpModuleName, // can point to a location within the module if GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS is set
out IntPtr phModule);

// http://msdn.microsoft.com/en-us/library/ms683212(v=vs.85).aspx
[DllImport("kernel32.dll", CallingConvention = CallingConvention.Winapi, SetLastError = true)]
#if NET7_0_OR_GREATER
[LibraryImport("kernel32.dll", SetLastError = true)]
internal static partial IntPtr GetProcAddress(
#else
[DllImport("kernel32.dll", SetLastError = true)]
internal static extern IntPtr GetProcAddress(
[In] SafeLibraryHandle hModule,
[In, MarshalAs(UnmanagedType.LPStr)] string lpProcName);
#endif
SafeLibraryHandle hModule,
[MarshalAs(UnmanagedType.LPStr)] string lpProcName);

// http://msdn.microsoft.com/en-us/library/windows/desktop/ms684179(v=vs.85).aspx
[DllImport("kernel32.dll", EntryPoint = "LoadLibraryExW", CallingConvention = CallingConvention.Winapi, SetLastError = true)]
#if NET7_0_OR_GREATER
[LibraryImport("kernel32.dll", EntryPoint = "LoadLibraryExW", SetLastError = true)]
internal static partial SafeLibraryHandle LoadLibraryEx(
#else
[DllImport("kernel32.dll", EntryPoint = "LoadLibraryExW", SetLastError = true)]
internal static extern SafeLibraryHandle LoadLibraryEx(
[In, MarshalAs(UnmanagedType.LPWStr)] string lpFileName,
[In] IntPtr hFile,
[In] uint dwFlags);
#endif
[MarshalAs(UnmanagedType.LPWStr)] string lpFileName,
IntPtr hFile,
uint dwFlags);

#pragma warning disable CS8763 // A method marked [DoesNotReturn] should not return.
[DoesNotReturn]
Expand Down
Loading

0 comments on commit 332a6f9

Please sign in to comment.