Skip to content

Commit

Permalink
Manually generate signatures for some PInvokes to handle SetLastError. (
Browse files Browse the repository at this point in the history
#1354)

* Manually generate signatures to handle SetLastError.

* Use new signatures on .NET 6 and newer.

* Use sbyte*

---------

Co-authored-by: Manodasan Wignarajah <mawign@microsoft.com>
  • Loading branch information
jlaanstra and manodasanW committed Sep 13, 2023
1 parent 579db0a commit 1ee556f
Showing 1 changed file with 65 additions and 5 deletions.
70 changes: 65 additions & 5 deletions src/cswinrt/strings/WinRT.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,55 @@ internal static unsafe int CoCreateInstance(ref Guid clsid, IntPtr outer, uint c
internal static extern int CoDecrementMTAUsage(IntPtr cookie);

[DllImport("api-ms-win-core-com-l1-1-0.dll")]
internal static extern unsafe int CoIncrementMTAUsage(IntPtr* cookie);
internal static extern unsafe int CoIncrementMTAUsage(IntPtr* cookie);

#if NET6_0_OR_GREATER
internal static bool FreeLibrary(IntPtr moduleHandle)
{
int lastError;
bool returnValue;
int nativeReturnValue;
{
Marshal.SetLastSystemError(0);
nativeReturnValue = PInvoke(moduleHandle);
lastError = Marshal.GetLastSystemError();
}

// Unmarshal - Convert native data to managed data.
returnValue = nativeReturnValue != 0;
Marshal.SetLastPInvokeError(lastError);
return returnValue;

// Local P/Invoke
[DllImportAttribute("kernel32.dll", EntryPoint = "FreeLibrary", ExactSpelling = true)]
static extern unsafe int PInvoke(IntPtr nativeModuleHandle);
}

internal static unsafe void* TryGetProcAddress(IntPtr moduleHandle, sbyte* functionName)
{
int lastError;
void* returnValue;
{
Marshal.SetLastSystemError(0);
returnValue = PInvoke(moduleHandle, functionName);
lastError = Marshal.GetLastSystemError();
}

Marshal.SetLastPInvokeError(lastError);
return returnValue;

// Local P/Invoke
[DllImportAttribute("kernel32.dll", EntryPoint = "GetProcAddress", ExactSpelling = true)]
static extern unsafe void* PInvoke(IntPtr nativeModuleHandle, sbyte* nativeFunctionName);
}
#else
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool FreeLibrary(IntPtr moduleHandle);

[DllImport("kernel32.dll", EntryPoint = "GetProcAddress", SetLastError = true, BestFitMapping = false)]
internal static unsafe extern void* TryGetProcAddress(IntPtr moduleHandle, sbyte* functionName);
#endif

internal static unsafe void* TryGetProcAddress(IntPtr moduleHandle, ReadOnlySpan<byte> functionName)
{
Expand Down Expand Up @@ -130,17 +171,36 @@ internal static unsafe int CoCreateInstance(ref Guid clsid, IntPtr outer, uint c
Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error(), new IntPtr(-1));
}
return functionPtr;
}

}

#if NET6_0_OR_GREATER
internal static unsafe IntPtr LoadLibraryExW(ushort* fileName, IntPtr fileHandle, uint flags)
{
int lastError;
IntPtr returnValue;
{
Marshal.SetLastSystemError(0);
returnValue = PInvoke(fileName, fileHandle, flags);
lastError = Marshal.GetLastSystemError();
}

Marshal.SetLastPInvokeError(lastError);
return returnValue;

// Local P/Invoke
[DllImportAttribute("kernel32.dll", EntryPoint = "LoadLibraryExW", ExactSpelling = true)]
static extern unsafe IntPtr PInvoke(ushort* nativeFileName, IntPtr nativeFileHandle, uint nativeFlags);
}
#else
[DllImport("kernel32.dll", SetLastError = true)]
internal static unsafe extern IntPtr LoadLibraryExW(ushort* fileName, IntPtr fileHandle, uint flags);

#endif
internal static unsafe IntPtr LoadLibraryExW(string fileName, IntPtr fileHandle, uint flags)
{
fixed (char* lpFileName = fileName)
return LoadLibraryExW((ushort*)lpFileName, fileHandle, flags);
}


[DllImport("api-ms-win-core-winrt-l1-1-0.dll")]
internal static extern unsafe int RoGetActivationFactory(IntPtr runtimeClassId, Guid* iid, IntPtr* factory);

Expand Down

0 comments on commit 1ee556f

Please sign in to comment.