Skip to content

Commit

Permalink
Set ExactSpelling=true on P/Invokes in System.Private.CoreLib that al…
Browse files Browse the repository at this point in the history
…ready specify the unicode W suffix (#36257)

* Set ExactSpelling=true on P/Invokes in System.Private.CoreLib that
already specify the unicode W suffix

* PR feedback: refactor NDirectMethodDesc::FindEntryPoint
  • Loading branch information
elinor-fung authored May 13, 2020
1 parent 9740aa5 commit f2cdf3b
Show file tree
Hide file tree
Showing 30 changed files with 75 additions and 69 deletions.
65 changes: 35 additions & 30 deletions src/coreclr/src/vm/method.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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

//*******************************************************************************
Expand All @@ -5332,39 +5349,27 @@ LPVOID NDirectMethodDesc::FindEntryPoint(NATIVE_LIBRARY_HANDLE hMod) const
return reinterpret_cast<LPVOID>(GetProcAddress(hMod, (LPCSTR)(size_t)((UINT16)ordinal)));
}

// Just look for the user-provided name without charset suffixes.
// If it is unicode fcn, 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<LPVOID>(pFunc);
// Look for the user-provided entry point name only
pFunc = FindEntryPointWithMangling(hMod, funcName);
}

DWORD probedEntrypointNameLength = (DWORD)(strlen(funcName) + 1); // +1 for charset decorations

// Allocate space for a copy of the entry point name.
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'.

if(!IsNativeNoMangled())
else if (IsNativeAnsi())
{
szProbedEntrypointName[probedEntrypointNameLength - 1] = IsNativeAnsi() ? 'A' : 'W';

FARPROC pProbedFunc = FindEntryPointWithMangling(hMod, szProbedEntrypointName);

if(pProbedFunc != NULL)
{
pFunc = pProbedFunc;
}

probedEntrypointNameLength++;
// 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
{
// 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<LPVOID>(pFunc);
Expand Down
1 change: 1 addition & 0 deletions src/coreclr/src/vm/method.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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:

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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,
Expand All @@ -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,
Expand All @@ -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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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,
Expand All @@ -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,
Expand All @@ -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,
Expand All @@ -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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ internal static partial class Kernel32
/// <summary>
/// WARNING: This method does not implicitly handle long paths. Use FindFirstFile.
/// </summary>
[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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ internal static unsafe int GetEnvironmentVariable(string lpName, Span<char> 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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ internal static partial class Kernel32
/// <summary>
/// WARNING: This method does not implicitly handle long paths. Use GetFileAttributesEx.
/// </summary>
[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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
Loading

0 comments on commit f2cdf3b

Please sign in to comment.