From 3abe43b1065d3bbc8ec2770eff966726b94ca760 Mon Sep 17 00:00:00 2001 From: Elinor Fung Date: Mon, 11 May 2020 11:27:24 -0700 Subject: [PATCH 1/2] Set ExactSpelling=true on P/Invokes in System.Private.CoreLib that already specify the unicode W suffix --- src/coreclr/src/vm/method.cpp | 24 +++++++------------ .../Advapi32/Interop.RegCreateKeyEx.cs | 2 +- .../Advapi32/Interop.RegDeleteKeyEx.cs | 2 +- .../Advapi32/Interop.RegDeleteValue.cs | 2 +- .../Windows/Advapi32/Interop.RegEnumKeyEx.cs | 2 +- .../Windows/Advapi32/Interop.RegEnumValue.cs | 2 +- .../Windows/Advapi32/Interop.RegOpenKeyEx.cs | 4 ++-- .../Advapi32/Interop.RegQueryValueEx.cs | 8 +++---- .../Windows/Advapi32/Interop.RegSetValueEx.cs | 10 ++++---- .../Kernel32/Interop.EventWaitHandle.cs | 4 ++-- .../Interop.ExpandEnvironmentStrings.cs | 2 +- .../Kernel32/Interop.FindFirstFileEx.cs | 2 +- .../Windows/Kernel32/Interop.FormatMessage.cs | 2 +- .../Interop.FreeEnvironmentStrings.cs | 2 +- .../Kernel32/Interop.GetComputerName.cs | 2 +- .../Kernel32/Interop.GetCurrentDirectory.cs | 2 +- .../Kernel32/Interop.GetEnvironmentStrings.cs | 2 +- .../Interop.GetEnvironmentVariable.cs | 2 +- .../Kernel32/Interop.GetFileAttributesEx.cs | 2 +- .../Kernel32/Interop.GetSystemDirectoryW.cs | 2 +- .../Kernel32/Interop.GetTempFileNameW.cs | 2 +- .../Windows/Kernel32/Interop.GetTempPathW.cs | 2 +- .../Kernel32/Interop.LoadLibraryEx_IntPtr.cs | 2 +- .../Interop/Windows/Kernel32/Interop.Mutex.cs | 4 ++-- .../Windows/Kernel32/Interop.Semaphore.cs | 4 ++-- .../Kernel32/Interop.SetCurrentDirectory.cs | 2 +- .../Interop.SetEnvironmentVariable.cs | 2 +- .../Windows/Secur32/Interop.GetUserNameExW.cs | 2 +- .../Windows/User32/Interop.LoadString.cs | 2 +- 29 files changed, 47 insertions(+), 55 deletions(-) diff --git a/src/coreclr/src/vm/method.cpp b/src/coreclr/src/vm/method.cpp index 314b777052cd8..b19f0ae858877 100644 --- a/src/coreclr/src/vm/method.cpp +++ b/src/coreclr/src/vm/method.cpp @@ -5333,7 +5333,7 @@ LPVOID NDirectMethodDesc::FindEntryPoint(NATIVE_LIBRARY_HANDLE hMod) const } // Just look for the user-provided name without charset suffixes. - // If it is unicode fcn, we are going + // If it is a unicode function, we are going // to need to check for the 'W' API because it takes precedence over the // unmangled one (on NT some APIs have unmangled ANSI exports). FARPROC pFunc = FindEntryPointWithMangling(hMod, funcName); @@ -5342,29 +5342,21 @@ LPVOID NDirectMethodDesc::FindEntryPoint(NATIVE_LIBRARY_HANDLE hMod) const return reinterpret_cast(pFunc); } - DWORD probedEntrypointNameLength = (DWORD)(strlen(funcName) + 1); // +1 for charset decorations - // Allocate space for a copy of the entry point name. + DWORD probedEntrypointNameLength = (DWORD)(strlen(funcName) + 1); // +1 for charset decorations int dstbufsize = (int)(sizeof(char) * (probedEntrypointNameLength + 1)); // +1 for the null terminator - LPSTR szProbedEntrypointName = ((LPSTR)_alloca(dstbufsize)); // Copy the name so we can mangle it. strcpy_s(szProbedEntrypointName, dstbufsize, funcName); - szProbedEntrypointName[probedEntrypointNameLength] = '\0'; // Add an extra '\0'. + szProbedEntrypointName[probedEntrypointNameLength] = '\0'; // Null terminator + szProbedEntrypointName[probedEntrypointNameLength - 1] = IsNativeAnsi() ? 'A' : 'W'; // Charset suffix - if(!IsNativeNoMangled()) + // Look for entry point with the suffix based on charset + FARPROC pProbedFunc = FindEntryPointWithMangling(hMod, szProbedEntrypointName); + if (pProbedFunc != NULL) { - szProbedEntrypointName[probedEntrypointNameLength - 1] = IsNativeAnsi() ? 'A' : 'W'; - - FARPROC pProbedFunc = FindEntryPointWithMangling(hMod, szProbedEntrypointName); - - if(pProbedFunc != NULL) - { - pFunc = pProbedFunc; - } - - probedEntrypointNameLength++; + pFunc = pProbedFunc; } return reinterpret_cast(pFunc); diff --git a/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.RegCreateKeyEx.cs b/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.RegCreateKeyEx.cs index bb9da06c11d48..3caac3041f920 100644 --- a/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.RegCreateKeyEx.cs +++ b/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.RegCreateKeyEx.cs @@ -16,7 +16,7 @@ internal static partial class Advapi32 { // Note: RegCreateKeyEx won't set the last error on failure - it returns // an error code if it fails. - [DllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegCreateKeyExW")] + [DllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegCreateKeyExW", ExactSpelling = true)] internal static extern int RegCreateKeyEx( SafeRegistryHandle hKey, string lpSubKey, diff --git a/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.RegDeleteKeyEx.cs b/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.RegDeleteKeyEx.cs index 487caf8b6d79d..2fff3b1ed5164 100644 --- a/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.RegDeleteKeyEx.cs +++ b/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.RegDeleteKeyEx.cs @@ -13,7 +13,7 @@ internal static partial class Interop { internal static partial class Advapi32 { - [DllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegDeleteKeyExW")] + [DllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegDeleteKeyExW", ExactSpelling = true)] internal static extern int RegDeleteKeyEx(SafeRegistryHandle hKey, string lpSubKey, int samDesired, int Reserved); } } diff --git a/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.RegDeleteValue.cs b/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.RegDeleteValue.cs index 43cf683c2bddf..7bb376930fa75 100644 --- a/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.RegDeleteValue.cs +++ b/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.RegDeleteValue.cs @@ -14,7 +14,7 @@ internal static partial class Interop { internal static partial class Advapi32 { - [DllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegDeleteValueW")] + [DllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegDeleteValueW", ExactSpelling = true)] internal static extern int RegDeleteValue(SafeRegistryHandle hKey, string? lpValueName); } } diff --git a/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.RegEnumKeyEx.cs b/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.RegEnumKeyEx.cs index 11165cc91a966..d618b50cd1cd8 100644 --- a/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.RegEnumKeyEx.cs +++ b/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.RegEnumKeyEx.cs @@ -14,7 +14,7 @@ internal static partial class Interop { internal static partial class Advapi32 { - [DllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegEnumKeyExW")] + [DllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegEnumKeyExW", ExactSpelling = true)] internal static extern unsafe int RegEnumKeyEx( SafeRegistryHandle hKey, int dwIndex, diff --git a/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.RegEnumValue.cs b/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.RegEnumValue.cs index e2ab45dea1933..02a7ad9692844 100644 --- a/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.RegEnumValue.cs +++ b/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.RegEnumValue.cs @@ -15,7 +15,7 @@ internal static partial class Interop { internal static partial class Advapi32 { - [DllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegEnumValueW")] + [DllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegEnumValueW", ExactSpelling = true)] internal static extern unsafe int RegEnumValue( SafeRegistryHandle hKey, int dwIndex, diff --git a/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.RegOpenKeyEx.cs b/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.RegOpenKeyEx.cs index 5f5b6b6e372ed..0bc2cdce3c836 100644 --- a/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.RegOpenKeyEx.cs +++ b/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.RegOpenKeyEx.cs @@ -15,7 +15,7 @@ internal static partial class Interop { internal static partial class Advapi32 { - [DllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegOpenKeyExW")] + [DllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegOpenKeyExW", ExactSpelling = true)] internal static extern int RegOpenKeyEx( SafeRegistryHandle hKey, string? lpSubKey, @@ -24,7 +24,7 @@ internal static extern int RegOpenKeyEx( out SafeRegistryHandle hkResult); - [DllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegOpenKeyExW")] + [DllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegOpenKeyExW", ExactSpelling = true)] internal static extern int RegOpenKeyEx( IntPtr hKey, string? lpSubKey, diff --git a/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.RegQueryValueEx.cs b/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.RegQueryValueEx.cs index 72b8aa8f7bcf1..bde703ad18632 100644 --- a/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.RegQueryValueEx.cs +++ b/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.RegQueryValueEx.cs @@ -14,7 +14,7 @@ internal static partial class Interop { internal static partial class Advapi32 { - [DllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegQueryValueExW")] + [DllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegQueryValueExW", ExactSpelling = true)] internal static extern int RegQueryValueEx( SafeRegistryHandle hKey, string? lpValueName, @@ -23,7 +23,7 @@ internal static extern int RegQueryValueEx( [Out] byte[]? lpData, ref int lpcbData); - [DllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegQueryValueExW")] + [DllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegQueryValueExW", ExactSpelling = true)] internal static extern int RegQueryValueEx( SafeRegistryHandle hKey, string? lpValueName, @@ -32,7 +32,7 @@ internal static extern int RegQueryValueEx( ref int lpData, ref int lpcbData); - [DllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegQueryValueExW")] + [DllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegQueryValueExW", ExactSpelling = true)] internal static extern int RegQueryValueEx( SafeRegistryHandle hKey, string? lpValueName, @@ -41,7 +41,7 @@ internal static extern int RegQueryValueEx( ref long lpData, ref int lpcbData); - [DllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegQueryValueExW")] + [DllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegQueryValueExW", ExactSpelling = true)] internal static extern int RegQueryValueEx( SafeRegistryHandle hKey, string? lpValueName, diff --git a/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.RegSetValueEx.cs b/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.RegSetValueEx.cs index 847d28fa1c577..72cee21e1a17b 100644 --- a/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.RegSetValueEx.cs +++ b/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.RegSetValueEx.cs @@ -14,7 +14,7 @@ internal static partial class Interop { internal static partial class Advapi32 { - [DllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegSetValueExW")] + [DllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegSetValueExW", ExactSpelling = true)] internal static extern int RegSetValueEx( SafeRegistryHandle hKey, string? lpValueName, @@ -23,7 +23,7 @@ internal static extern int RegSetValueEx( byte[]? lpData, int cbData); - [DllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegSetValueExW")] + [DllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegSetValueExW", ExactSpelling = true)] internal static extern int RegSetValueEx( SafeRegistryHandle hKey, string? lpValueName, @@ -32,7 +32,7 @@ internal static extern int RegSetValueEx( char[]? lpData, int cbData); - [DllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegSetValueExW")] + [DllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegSetValueExW", ExactSpelling = true)] internal static extern int RegSetValueEx( SafeRegistryHandle hKey, string? lpValueName, @@ -41,7 +41,7 @@ internal static extern int RegSetValueEx( ref int lpData, int cbData); - [DllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegSetValueExW")] + [DllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegSetValueExW", ExactSpelling = true)] internal static extern int RegSetValueEx( SafeRegistryHandle hKey, string? lpValueName, @@ -50,7 +50,7 @@ internal static extern int RegSetValueEx( ref long lpData, int cbData); - [DllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegSetValueExW")] + [DllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegSetValueExW", ExactSpelling = true)] internal static extern int RegSetValueEx( SafeRegistryHandle hKey, string? lpValueName, diff --git a/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.EventWaitHandle.cs b/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.EventWaitHandle.cs index c3adfadb53d54..e4b0904b76ba1 100644 --- a/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.EventWaitHandle.cs +++ b/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.EventWaitHandle.cs @@ -20,10 +20,10 @@ internal static partial class Kernel32 [DllImport(Libraries.Kernel32, SetLastError = true)] internal static extern bool ResetEvent(SafeWaitHandle handle); - [DllImport(Libraries.Kernel32, EntryPoint = "CreateEventExW", SetLastError = true, CharSet = CharSet.Unicode)] + [DllImport(Libraries.Kernel32, EntryPoint = "CreateEventExW", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = true)] internal static extern SafeWaitHandle CreateEventEx(IntPtr lpSecurityAttributes, string? name, uint flags, uint desiredAccess); - [DllImport(Libraries.Kernel32, EntryPoint = "OpenEventW", SetLastError = true, CharSet = CharSet.Unicode)] + [DllImport(Libraries.Kernel32, EntryPoint = "OpenEventW", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = true)] internal static extern SafeWaitHandle OpenEvent(uint desiredAccess, bool inheritHandle, string name); } } diff --git a/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.ExpandEnvironmentStrings.cs b/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.ExpandEnvironmentStrings.cs index fbd5da84b8e0a..94a3714644e12 100644 --- a/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.ExpandEnvironmentStrings.cs +++ b/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.ExpandEnvironmentStrings.cs @@ -8,7 +8,7 @@ internal static partial class Interop { internal static partial class Kernel32 { - [DllImport(Libraries.Kernel32, EntryPoint = "ExpandEnvironmentStringsW", CharSet = CharSet.Unicode, SetLastError = true)] + [DllImport(Libraries.Kernel32, EntryPoint = "ExpandEnvironmentStringsW", CharSet = CharSet.Unicode, SetLastError = true, ExactSpelling = true)] internal static extern uint ExpandEnvironmentStrings(string lpSrc, ref char lpDst, uint nSize); } } diff --git a/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.FindFirstFileEx.cs b/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.FindFirstFileEx.cs index 6ab52b4d0e9e2..a7cd35262d50d 100644 --- a/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.FindFirstFileEx.cs +++ b/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.FindFirstFileEx.cs @@ -15,7 +15,7 @@ internal static partial class Kernel32 /// /// WARNING: This method does not implicitly handle long paths. Use FindFirstFile. /// - [DllImport(Libraries.Kernel32, EntryPoint = "FindFirstFileExW", SetLastError = true, CharSet = CharSet.Unicode)] + [DllImport(Libraries.Kernel32, EntryPoint = "FindFirstFileExW", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = true)] private static extern SafeFindHandle FindFirstFileExPrivate(string lpFileName, FINDEX_INFO_LEVELS fInfoLevelId, ref WIN32_FIND_DATA lpFindFileData, FINDEX_SEARCH_OPS fSearchOp, IntPtr lpSearchFilter, int dwAdditionalFlags); internal static SafeFindHandle FindFirstFile(string fileName, ref WIN32_FIND_DATA data) diff --git a/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.FormatMessage.cs b/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.FormatMessage.cs index 2eda58f250426..14ba39b044b9f 100644 --- a/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.FormatMessage.cs +++ b/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.FormatMessage.cs @@ -16,7 +16,7 @@ internal static partial class Kernel32 private const int FORMAT_MESSAGE_ALLOCATE_BUFFER = 0x00000100; private const int ERROR_INSUFFICIENT_BUFFER = 0x7A; - [DllImport(Libraries.Kernel32, CharSet = CharSet.Unicode, EntryPoint = "FormatMessageW", SetLastError = true, BestFitMapping = true)] + [DllImport(Libraries.Kernel32, CharSet = CharSet.Unicode, EntryPoint = "FormatMessageW", SetLastError = true, BestFitMapping = true, ExactSpelling = true)] private static extern unsafe int FormatMessage( int dwFlags, IntPtr lpSource, diff --git a/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.FreeEnvironmentStrings.cs b/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.FreeEnvironmentStrings.cs index c222db8ef91b5..f325c281df8cf 100644 --- a/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.FreeEnvironmentStrings.cs +++ b/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.FreeEnvironmentStrings.cs @@ -8,7 +8,7 @@ internal static partial class Interop { internal static partial class Kernel32 { - [DllImport(Libraries.Kernel32, EntryPoint = "FreeEnvironmentStringsW", SetLastError = true, CharSet = CharSet.Unicode, BestFitMapping = false)] + [DllImport(Libraries.Kernel32, EntryPoint = "FreeEnvironmentStringsW", SetLastError = true, CharSet = CharSet.Unicode, BestFitMapping = false, ExactSpelling = true)] internal static extern unsafe bool FreeEnvironmentStrings(char* lpszEnvironmentBlock); } } diff --git a/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.GetComputerName.cs b/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.GetComputerName.cs index 011430da5c7e8..92cfb955a4cba 100644 --- a/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.GetComputerName.cs +++ b/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.GetComputerName.cs @@ -10,7 +10,7 @@ internal static partial class Interop { internal static partial class Kernel32 { - [DllImport(Libraries.Kernel32, CharSet = CharSet.Unicode, EntryPoint = "GetComputerNameW")] + [DllImport(Libraries.Kernel32, CharSet = CharSet.Unicode, EntryPoint = "GetComputerNameW", ExactSpelling = true)] private static extern unsafe int GetComputerName(ref char lpBuffer, ref uint nSize); // maximum length of the NETBIOS name (not including NULL) diff --git a/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.GetCurrentDirectory.cs b/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.GetCurrentDirectory.cs index 4e30a8be4328a..bf283df9c4046 100644 --- a/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.GetCurrentDirectory.cs +++ b/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.GetCurrentDirectory.cs @@ -8,7 +8,7 @@ internal static partial class Interop { internal static partial class Kernel32 { - [DllImport(Libraries.Kernel32, EntryPoint = "GetCurrentDirectoryW", SetLastError = true, CharSet = CharSet.Unicode, BestFitMapping = false)] + [DllImport(Libraries.Kernel32, EntryPoint = "GetCurrentDirectoryW", SetLastError = true, CharSet = CharSet.Unicode, BestFitMapping = false, ExactSpelling = true)] internal static extern uint GetCurrentDirectory(uint nBufferLength, ref char lpBuffer); } } diff --git a/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.GetEnvironmentStrings.cs b/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.GetEnvironmentStrings.cs index 5594fe7a4cb8e..cdbd01ca50208 100644 --- a/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.GetEnvironmentStrings.cs +++ b/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.GetEnvironmentStrings.cs @@ -8,7 +8,7 @@ internal static partial class Interop { internal static partial class Kernel32 { - [DllImport(Libraries.Kernel32, EntryPoint = "GetEnvironmentStringsW", SetLastError = true, CharSet = CharSet.Unicode, BestFitMapping = false)] + [DllImport(Libraries.Kernel32, EntryPoint = "GetEnvironmentStringsW", SetLastError = true, CharSet = CharSet.Unicode, BestFitMapping = false, ExactSpelling = true)] internal static extern unsafe char* GetEnvironmentStrings(); } } diff --git a/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.GetEnvironmentVariable.cs b/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.GetEnvironmentVariable.cs index 43463e52304cb..0c14b3dd40398 100644 --- a/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.GetEnvironmentVariable.cs +++ b/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.GetEnvironmentVariable.cs @@ -17,7 +17,7 @@ internal static unsafe int GetEnvironmentVariable(string lpName, Span buff } } - [DllImport(Libraries.Kernel32, EntryPoint = "GetEnvironmentVariableW", SetLastError = true, CharSet = CharSet.Unicode)] + [DllImport(Libraries.Kernel32, EntryPoint = "GetEnvironmentVariableW", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = true)] private static extern unsafe int GetEnvironmentVariable(string lpName, char* lpBuffer, int nSize); } } diff --git a/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.GetFileAttributesEx.cs b/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.GetFileAttributesEx.cs index aed8919cd03e9..84cd7326b39fe 100644 --- a/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.GetFileAttributesEx.cs +++ b/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.GetFileAttributesEx.cs @@ -13,7 +13,7 @@ internal static partial class Kernel32 /// /// WARNING: This method does not implicitly handle long paths. Use GetFileAttributesEx. /// - [DllImport(Libraries.Kernel32, EntryPoint = "GetFileAttributesExW", SetLastError = true, CharSet = CharSet.Unicode)] + [DllImport(Libraries.Kernel32, EntryPoint = "GetFileAttributesExW", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = true)] private static extern bool GetFileAttributesExPrivate(string? name, GET_FILEEX_INFO_LEVELS fileInfoLevel, ref WIN32_FILE_ATTRIBUTE_DATA lpFileInformation); internal static bool GetFileAttributesEx(string? name, GET_FILEEX_INFO_LEVELS fileInfoLevel, ref WIN32_FILE_ATTRIBUTE_DATA lpFileInformation) diff --git a/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.GetSystemDirectoryW.cs b/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.GetSystemDirectoryW.cs index 197f6f5eadcdb..b247a509c40d8 100644 --- a/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.GetSystemDirectoryW.cs +++ b/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.GetSystemDirectoryW.cs @@ -8,7 +8,7 @@ internal static partial class Interop { internal static partial class Kernel32 { - [DllImport(Libraries.Kernel32, CharSet = CharSet.Unicode, SetLastError = true)] + [DllImport(Libraries.Kernel32, CharSet = CharSet.Unicode, SetLastError = true, ExactSpelling = true)] internal static extern uint GetSystemDirectoryW(ref char lpBuffer, uint uSize); } } diff --git a/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.GetTempFileNameW.cs b/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.GetTempFileNameW.cs index d7f9b828c0c03..5c3140b82ea66 100644 --- a/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.GetTempFileNameW.cs +++ b/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.GetTempFileNameW.cs @@ -8,7 +8,7 @@ internal static partial class Interop { internal static partial class Kernel32 { - [DllImport(Libraries.Kernel32, CharSet = CharSet.Unicode, SetLastError = true, BestFitMapping = false)] + [DllImport(Libraries.Kernel32, CharSet = CharSet.Unicode, SetLastError = true, BestFitMapping = false, ExactSpelling = true)] internal static extern uint GetTempFileNameW(ref char lpPathName, string lpPrefixString, uint uUnique, ref char lpTempFileName); } } diff --git a/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.GetTempPathW.cs b/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.GetTempPathW.cs index 8d2b0b199edd0..654a3b57011cd 100644 --- a/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.GetTempPathW.cs +++ b/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.GetTempPathW.cs @@ -8,7 +8,7 @@ internal static partial class Interop { internal static partial class Kernel32 { - [DllImport(Libraries.Kernel32, CharSet = CharSet.Unicode, BestFitMapping = false)] + [DllImport(Libraries.Kernel32, CharSet = CharSet.Unicode, BestFitMapping = false, ExactSpelling = true)] internal static extern uint GetTempPathW(int bufferLen, ref char buffer); } } diff --git a/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.LoadLibraryEx_IntPtr.cs b/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.LoadLibraryEx_IntPtr.cs index a77cf49179382..3e3d1d34a81a7 100644 --- a/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.LoadLibraryEx_IntPtr.cs +++ b/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.LoadLibraryEx_IntPtr.cs @@ -12,7 +12,7 @@ internal static partial class Kernel32 internal const int LOAD_LIBRARY_AS_DATAFILE = 0x00000002; internal const int LOAD_LIBRARY_SEARCH_SYSTEM32 = 0x00000800; - [DllImport(Libraries.Kernel32, CharSet = CharSet.Unicode, EntryPoint = "LoadLibraryExW", SetLastError = true)] + [DllImport(Libraries.Kernel32, CharSet = CharSet.Unicode, EntryPoint = "LoadLibraryExW", SetLastError = true, ExactSpelling = true)] internal static extern IntPtr LoadLibraryEx(string libFilename, IntPtr reserved, int flags); } } diff --git a/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.Mutex.cs b/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.Mutex.cs index 6adaf98737040..ad1d649fe9da8 100644 --- a/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.Mutex.cs +++ b/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.Mutex.cs @@ -13,10 +13,10 @@ internal static partial class Kernel32 { internal const uint CREATE_MUTEX_INITIAL_OWNER = 0x1; - [DllImport(Libraries.Kernel32, EntryPoint = "OpenMutexW", SetLastError = true, CharSet = CharSet.Unicode)] + [DllImport(Libraries.Kernel32, EntryPoint = "OpenMutexW", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = true)] internal static extern SafeWaitHandle OpenMutex(uint desiredAccess, bool inheritHandle, string name); - [DllImport(Libraries.Kernel32, EntryPoint = "CreateMutexExW", SetLastError = true, CharSet = CharSet.Unicode)] + [DllImport(Libraries.Kernel32, EntryPoint = "CreateMutexExW", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = true)] internal static extern SafeWaitHandle CreateMutexEx(IntPtr lpMutexAttributes, string? name, uint flags, uint desiredAccess); [DllImport(Libraries.Kernel32, SetLastError = true)] diff --git a/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.Semaphore.cs b/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.Semaphore.cs index 4f6d8de8768a3..c83db1f934c00 100644 --- a/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.Semaphore.cs +++ b/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.Semaphore.cs @@ -11,10 +11,10 @@ internal static partial class Interop { internal static partial class Kernel32 { - [DllImport(Libraries.Kernel32, EntryPoint = "OpenSemaphoreW", SetLastError = true, CharSet = CharSet.Unicode)] + [DllImport(Libraries.Kernel32, EntryPoint = "OpenSemaphoreW", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = true)] internal static extern SafeWaitHandle OpenSemaphore(uint desiredAccess, bool inheritHandle, string name); - [DllImport(Libraries.Kernel32, EntryPoint = "CreateSemaphoreExW", SetLastError = true, CharSet = CharSet.Unicode)] + [DllImport(Libraries.Kernel32, EntryPoint = "CreateSemaphoreExW", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = true)] internal static extern SafeWaitHandle CreateSemaphoreEx(IntPtr lpSecurityAttributes, int initialCount, int maximumCount, string? name, uint flags, uint desiredAccess); [DllImport(Libraries.Kernel32, SetLastError = true)] diff --git a/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.SetCurrentDirectory.cs b/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.SetCurrentDirectory.cs index d268d4daa6f77..17360399a7c0d 100644 --- a/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.SetCurrentDirectory.cs +++ b/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.SetCurrentDirectory.cs @@ -8,7 +8,7 @@ internal static partial class Interop { internal static partial class Kernel32 { - [DllImport(Libraries.Kernel32, EntryPoint = "SetCurrentDirectoryW", SetLastError = true, CharSet = CharSet.Unicode, BestFitMapping = false)] + [DllImport(Libraries.Kernel32, EntryPoint = "SetCurrentDirectoryW", SetLastError = true, CharSet = CharSet.Unicode, BestFitMapping = false, ExactSpelling = true)] internal static extern bool SetCurrentDirectory(string path); } } diff --git a/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.SetEnvironmentVariable.cs b/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.SetEnvironmentVariable.cs index 243bd6562e034..ab3a6d34cd42b 100644 --- a/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.SetEnvironmentVariable.cs +++ b/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.SetEnvironmentVariable.cs @@ -8,7 +8,7 @@ internal static partial class Interop { internal static partial class Kernel32 { - [DllImport(Libraries.Kernel32, EntryPoint = "SetEnvironmentVariableW", SetLastError = true, CharSet = CharSet.Unicode, BestFitMapping = false)] + [DllImport(Libraries.Kernel32, EntryPoint = "SetEnvironmentVariableW", SetLastError = true, CharSet = CharSet.Unicode, BestFitMapping = false, ExactSpelling = true)] internal static extern bool SetEnvironmentVariable(string lpName, string? lpValue); } } diff --git a/src/libraries/Common/src/Interop/Windows/Secur32/Interop.GetUserNameExW.cs b/src/libraries/Common/src/Interop/Windows/Secur32/Interop.GetUserNameExW.cs index e88864cd9e747..7001cd6df09ea 100644 --- a/src/libraries/Common/src/Interop/Windows/Secur32/Interop.GetUserNameExW.cs +++ b/src/libraries/Common/src/Interop/Windows/Secur32/Interop.GetUserNameExW.cs @@ -8,7 +8,7 @@ internal static partial class Interop { internal static partial class Secur32 { - [DllImport(Libraries.Secur32, CharSet = CharSet.Unicode, SetLastError = true)] + [DllImport(Libraries.Secur32, CharSet = CharSet.Unicode, SetLastError = true, ExactSpelling = true)] internal static extern BOOLEAN GetUserNameExW(int NameFormat, ref char lpNameBuffer, ref uint lpnSize); internal const int NameSamCompatible = 2; diff --git a/src/libraries/Common/src/Interop/Windows/User32/Interop.LoadString.cs b/src/libraries/Common/src/Interop/Windows/User32/Interop.LoadString.cs index 6ff50442eb428..8824f7c3dfa02 100644 --- a/src/libraries/Common/src/Interop/Windows/User32/Interop.LoadString.cs +++ b/src/libraries/Common/src/Interop/Windows/User32/Interop.LoadString.cs @@ -9,7 +9,7 @@ internal static partial class Interop { internal static partial class User32 { - [DllImport(Libraries.User32, SetLastError = true, EntryPoint = "LoadStringW", CharSet = CharSet.Unicode)] + [DllImport(Libraries.User32, SetLastError = true, EntryPoint = "LoadStringW", CharSet = CharSet.Unicode, ExactSpelling = true)] internal static extern unsafe int LoadString(IntPtr hInstance, uint uID, char* lpBuffer, int cchBufferMax); } } From a4a5bcddcd127b18bae13346bb65420b91300290 Mon Sep 17 00:00:00 2001 From: Elinor Fung Date: Tue, 12 May 2020 11:15:47 -0700 Subject: [PATCH 2/2] PR feedback: refactor NDirectMethodDesc::FindEntryPoint --- src/coreclr/src/vm/method.cpp | 57 +++++++++++++++++++++-------------- src/coreclr/src/vm/method.hpp | 1 + 2 files changed, 36 insertions(+), 22 deletions(-) diff --git a/src/coreclr/src/vm/method.cpp b/src/coreclr/src/vm/method.cpp index b19f0ae858877..690051b905bf8 100644 --- a/src/coreclr/src/vm/method.cpp +++ b/src/coreclr/src/vm/method.cpp @@ -5307,6 +5307,23 @@ FARPROC NDirectMethodDesc::FindEntryPointWithMangling(NATIVE_LIBRARY_HANDLE hMod return pFunc; } + +FARPROC NDirectMethodDesc::FindEntryPointWithSuffix(NATIVE_LIBRARY_HANDLE hMod, PTR_CUTF8 entryPointName, char suffix) const +{ + // Allocate space for a copy of the entry point name. + DWORD entryPointWithSuffixLen = (DWORD)(strlen(entryPointName) + 1); // +1 for charset decorations + int dstbufsize = (int)(sizeof(char) * (entryPointWithSuffixLen + 1)); // +1 for the null terminator + LPSTR entryPointWithSuffix = ((LPSTR)_alloca(dstbufsize)); + + // Copy the name so we can mangle it. + strcpy_s(entryPointWithSuffix, dstbufsize, entryPointName); + entryPointWithSuffix[entryPointWithSuffixLen] = '\0'; // Null terminator + entryPointWithSuffix[entryPointWithSuffixLen - 1] = suffix; // Charset suffix + + // Look for entry point with the suffix based on charset + return FindEntryPointWithMangling(hMod, entryPointWithSuffix); +} + #endif //******************************************************************************* @@ -5332,31 +5349,27 @@ LPVOID NDirectMethodDesc::FindEntryPoint(NATIVE_LIBRARY_HANDLE hMod) const return reinterpret_cast(GetProcAddress(hMod, (LPCSTR)(size_t)((UINT16)ordinal))); } - // Just look for the user-provided name without charset suffixes. - // If it is a unicode function, we are going - // to need to check for the 'W' API because it takes precedence over the - // unmangled one (on NT some APIs have unmangled ANSI exports). - FARPROC pFunc = FindEntryPointWithMangling(hMod, funcName); - if ((pFunc != NULL && IsNativeAnsi()) || IsNativeNoMangled()) + FARPROC pFunc = NULL; + if (IsNativeNoMangled()) { - return reinterpret_cast(pFunc); + // Look for the user-provided entry point name only + pFunc = FindEntryPointWithMangling(hMod, funcName); } - - // Allocate space for a copy of the entry point name. - DWORD probedEntrypointNameLength = (DWORD)(strlen(funcName) + 1); // +1 for charset decorations - int dstbufsize = (int)(sizeof(char) * (probedEntrypointNameLength + 1)); // +1 for the null terminator - LPSTR szProbedEntrypointName = ((LPSTR)_alloca(dstbufsize)); - - // Copy the name so we can mangle it. - strcpy_s(szProbedEntrypointName, dstbufsize, funcName); - szProbedEntrypointName[probedEntrypointNameLength] = '\0'; // Null terminator - szProbedEntrypointName[probedEntrypointNameLength - 1] = IsNativeAnsi() ? 'A' : 'W'; // Charset suffix - - // Look for entry point with the suffix based on charset - FARPROC pProbedFunc = FindEntryPointWithMangling(hMod, szProbedEntrypointName); - if (pProbedFunc != NULL) + else if (IsNativeAnsi()) + { + // For ANSI, look for the user-provided entry point name first. + // If that does not exist, try the charset suffix. + pFunc = FindEntryPointWithMangling(hMod, funcName); + if (pFunc == NULL) + pFunc = FindEntryPointWithSuffix(hMod, funcName, 'A'); + } + else { - pFunc = pProbedFunc; + // For Unicode, look for the entry point name with the charset suffix first. + // The 'W' API takes precedence over the undecorated one. + pFunc = FindEntryPointWithSuffix(hMod, funcName, 'W'); + if (pFunc == NULL) + pFunc = FindEntryPointWithMangling(hMod, funcName); } return reinterpret_cast(pFunc); diff --git a/src/coreclr/src/vm/method.hpp b/src/coreclr/src/vm/method.hpp index 8870e7a5f5a23..ba5f6ae096778 100644 --- a/src/coreclr/src/vm/method.hpp +++ b/src/coreclr/src/vm/method.hpp @@ -3150,6 +3150,7 @@ class NDirectMethodDesc : public MethodDesc #ifdef TARGET_WINDOWS private: FARPROC FindEntryPointWithMangling(NATIVE_LIBRARY_HANDLE mod, PTR_CUTF8 entryPointName) const; + FARPROC FindEntryPointWithSuffix(NATIVE_LIBRARY_HANDLE mod, PTR_CUTF8 entryPointName, char suffix) const; #endif public: