`winapisupp.cpp`: Dramatically shrink the function pointer table (#2841)

This commit is contained in:
Stephan T. Lavavej 2022-07-11 17:08:58 -07:00 коммит произвёл GitHub
Родитель a4dc8a7110
Коммит 658a04ba1f
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
2 изменённых файлов: 43 добавлений и 144 удалений

Просмотреть файл

@ -12,10 +12,6 @@
_CRT_BEGIN_C_HEADER
#if !defined(_CRT_WINDOWS) && !defined(UNDOCKED_WINDOWS_UCRT)
_CRTIMP2 BOOL __cdecl __crtIsPackagedApp();
#endif // !defined(_CRT_WINDOWS) && !defined(UNDOCKED_WINDOWS_UCRT)
#if _STL_WIN32_WINNT >= _WIN32_WINNT_WIN8
#define __crtGetSystemTimePreciseAsFileTime(lpSystemTimeAsFileTime) \
@ -27,79 +23,6 @@ _CRTIMP2 void __cdecl __crtGetSystemTimePreciseAsFileTime(_Out_ LPFILETIME lpSys
#endif // _STL_WIN32_WINNT >= _WIN32_WINNT_WIN8
// This enum should not change, even though some functions are no longer imported dynamically
enum wrapKERNEL32Functions {
eFlsAlloc,
eFlsFree,
eFlsGetValue,
eFlsSetValue,
eInitializeCriticalSectionEx,
eInitOnceExecuteOnce,
eCreateEventExW,
eCreateSemaphoreW,
eCreateSemaphoreExW,
eCreateThreadpoolTimer,
eSetThreadpoolTimer,
eWaitForThreadpoolTimerCallbacks,
eCloseThreadpoolTimer,
eCreateThreadpoolWait,
eSetThreadpoolWait,
eCloseThreadpoolWait,
eFlushProcessWriteBuffers,
eFreeLibraryWhenCallbackReturns,
eGetCurrentProcessorNumber,
eCreateSymbolicLinkW,
#if defined(_CRT_WINDOWS) || defined(UNDOCKED_WINDOWS_UCRT)
eSetDefaultDllDirectories,
eCompareStringEx,
eEnumSystemLocalesEx,
eGetLocaleInfoEx,
eGetUserDefaultLocaleName,
eIsValidLocaleName,
eLCMapStringEx,
#else // defined(_CRT_WINDOWS) || defined(UNDOCKED_WINDOWS_UCRT)
eGetCurrentPackageId,
#endif // defined(_CRT_WINDOWS) || defined(UNDOCKED_WINDOWS_UCRT)
eGetTickCount64,
eGetFileInformationByHandleEx,
eSetFileInformationByHandle,
eGetSystemTimePreciseAsFileTime,
eInitializeConditionVariable,
eWakeConditionVariable,
eWakeAllConditionVariable,
eSleepConditionVariableCS,
eInitializeSRWLock,
eAcquireSRWLockExclusive,
eTryAcquireSRWLockExclusive,
eReleaseSRWLockExclusive,
eSleepConditionVariableSRW,
eCreateThreadpoolWork,
eSubmitThreadpoolWork,
eCloseThreadpoolWork,
#if !defined(_CRT_WINDOWS) && !defined(UNDOCKED_WINDOWS_UCRT)
eCompareStringEx,
eGetLocaleInfoEx,
eLCMapStringEx,
#endif // !defined(_CRT_WINDOWS) && !defined(UNDOCKED_WINDOWS_UCRT)
eMaxKernel32Function
};
extern PVOID __KERNEL32Functions[eMaxKernel32Function];
using PFNGETSYSTEMTIMEPRECISEASFILETIME = VOID(WINAPI*)(LPFILETIME);
// Use this macro for caching a function pointer from a DLL
#define STOREFUNCTIONPOINTER(instance, function_name) \
__KERNEL32Functions[e##function_name] = reinterpret_cast<PVOID>(GetProcAddress(instance, #function_name));
// Use this macro as a cached function pointer from a DLL
#define DYNAMICGETCACHEDFUNCTION(function_pointer_type, function_name, variable_name) \
const auto variable_name = reinterpret_cast<function_pointer_type>(__KERNEL32Functions[e##function_name])
#define IFDYNAMICGETCACHEDFUNCTION(function_pointer_type, function_name, variable_name) \
DYNAMICGETCACHEDFUNCTION(function_pointer_type, function_name, variable_name); \
if (variable_name != nullptr)
_CRTIMP2 int __cdecl __crtCompareStringA(_In_z_ LPCWSTR _LocaleName, _In_ DWORD _DwCmpFlags,
_In_reads_(_CchCount1) LPCSTR _LpString1, _In_ int _CchCount1, _In_reads_(_CchCount2) LPCSTR _LpString2,
_In_ int _CchCount2, _In_ int _CodePage);

Просмотреть файл

@ -14,11 +14,36 @@
#pragma warning(disable : 4265) // non-virtual destructor in base class
#include <wrl/wrappers/corewrappers.h>
#pragma warning(pop)
#include <cstdint>
#if !defined(_ONECORE)
namespace {
enum wrapKERNEL32Functions {
#if !defined(_CRT_WINDOWS) && !defined(UNDOCKED_WINDOWS_UCRT)
eGetCurrentPackageId,
#endif // !defined(_CRT_WINDOWS) && !defined(UNDOCKED_WINDOWS_UCRT)
#if _STL_WIN32_WINNT < _WIN32_WINNT_WIN8
eGetSystemTimePreciseAsFileTime,
#endif // _STL_WIN32_WINNT < _WIN32_WINNT_WIN8
eMaxKernel32Function
};
PVOID __KERNEL32Functions[eMaxKernel32Function > 0 ? eMaxKernel32Function : 1]{};
// Use this macro for caching a function pointer from a DLL
#define STOREFUNCTIONPOINTER(instance, function_name) \
__KERNEL32Functions[e##function_name] = reinterpret_cast<PVOID>(GetProcAddress(instance, #function_name))
// Use this macro for retrieving a cached function pointer from a DLL
#define IFDYNAMICGETCACHEDFUNCTION(name) \
if (const auto pf##name = reinterpret_cast<decltype(&name)>(__KERNEL32Functions[e##name]); pf##name)
} // unnamed namespace
#endif // ^^^ !defined(_ONECORE) ^^^
#if !defined(_CRT_WINDOWS) && !defined(UNDOCKED_WINDOWS_UCRT)
// GetCurrentPackageId retrieves the current package id, if the app is deployed via a package.
using PFNGETCURRENTPACKAGEID = BOOL(WINAPI*)(UINT32*, BYTE*);
#if !defined _CRT_APP
#if defined _ONECORE
@ -46,16 +71,14 @@ extern "C" int __crt_IsPackagedAppHelper() {
L"appmodel.dll" // LNM implementation DLL
};
wchar_t const* const* const first_possible_apiset = possible_apisets;
wchar_t const* const* const last_possible_apiset = possible_apisets + _countof(possible_apisets);
for (wchar_t const* const* it = first_possible_apiset; it != last_possible_apiset; ++it) {
HMODULEHandle const apiset(LoadLibraryExW(*it, nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32));
for (auto& dll : possible_apisets) {
HMODULEHandle const apiset(LoadLibraryExW(dll, nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32));
if (!apiset.IsValid()) {
continue;
}
PFNGETCURRENTPACKAGEID const get_current_package_id =
reinterpret_cast<PFNGETCURRENTPACKAGEID>(GetProcAddress(apiset.Get(), "GetCurrentPackageId"));
auto const get_current_package_id =
reinterpret_cast<decltype(&GetCurrentPackageId)>(GetProcAddress(apiset.Get(), "GetCurrentPackageId"));
if (!get_current_package_id) {
continue;
@ -79,8 +102,8 @@ extern "C" int __crt_IsPackagedAppHelper() {
LONG retValue = APPMODEL_ERROR_NO_PACKAGE;
UINT32 bufferLength = 0;
IFDYNAMICGETCACHEDFUNCTION(PFNGETCURRENTPACKAGEID, GetCurrentPackageId, pfn) {
retValue = pfn(&bufferLength, nullptr);
IFDYNAMICGETCACHEDFUNCTION(GetCurrentPackageId) {
retValue = pfGetCurrentPackageId(&bufferLength, nullptr);
}
if (retValue == ERROR_INSUFFICIENT_BUFFER) {
@ -110,7 +133,8 @@ extern "C" int __crt_IsPackagedAppHelper() {
//
// Exit:
// TRUE if Packaged app, FALSE if not.
extern "C" BOOL __cdecl __crtIsPackagedApp() {
// TRANSITION, ABI: preserved for binary compatibility
extern "C" _CRTIMP2 BOOL __cdecl __crtIsPackagedApp() {
#ifdef _CRT_APP
return TRUE;
#else
@ -349,8 +373,7 @@ extern "C" BOOLEAN __cdecl __crtTryAcquireSRWLockExclusive(_Inout_ PSRWLOCK cons
extern "C" void __cdecl __crtGetSystemTimePreciseAsFileTime(_Out_ LPFILETIME lpSystemTimeAsFileTime) {
// use GetSystemTimePreciseAsFileTime if it is available (only on Windows 8+)...
IFDYNAMICGETCACHEDFUNCTION(
PFNGETSYSTEMTIMEPRECISEASFILETIME, GetSystemTimePreciseAsFileTime, pfGetSystemTimePreciseAsFileTime) {
IFDYNAMICGETCACHEDFUNCTION(GetSystemTimePreciseAsFileTime) {
pfGetSystemTimePreciseAsFileTime(lpSystemTimeAsFileTime);
return;
}
@ -370,64 +393,17 @@ extern "C" void __cdecl __crtGetSystemTimePreciseAsFileTime(_Out_ LPFILETIME lpS
#else // defined _ONECORE
extern "C" PVOID __KERNEL32Functions[eMaxKernel32Function] = {nullptr};
static int __cdecl initialize_pointers() {
HINSTANCE hKernel32 = GetModuleHandleW(L"kernel32.dll");
_Analysis_assume_(hKernel32);
STOREFUNCTIONPOINTER(hKernel32, FlsAlloc);
STOREFUNCTIONPOINTER(hKernel32, FlsFree);
STOREFUNCTIONPOINTER(hKernel32, FlsGetValue);
STOREFUNCTIONPOINTER(hKernel32, FlsSetValue);
STOREFUNCTIONPOINTER(hKernel32, InitializeCriticalSectionEx);
STOREFUNCTIONPOINTER(hKernel32, InitOnceExecuteOnce);
STOREFUNCTIONPOINTER(hKernel32, CreateEventExW);
STOREFUNCTIONPOINTER(hKernel32, CreateSemaphoreW);
STOREFUNCTIONPOINTER(hKernel32, CreateSemaphoreExW);
STOREFUNCTIONPOINTER(hKernel32, CreateThreadpoolTimer);
STOREFUNCTIONPOINTER(hKernel32, SetThreadpoolTimer);
STOREFUNCTIONPOINTER(hKernel32, WaitForThreadpoolTimerCallbacks);
STOREFUNCTIONPOINTER(hKernel32, CloseThreadpoolTimer);
STOREFUNCTIONPOINTER(hKernel32, CreateThreadpoolWait);
STOREFUNCTIONPOINTER(hKernel32, SetThreadpoolWait);
STOREFUNCTIONPOINTER(hKernel32, CloseThreadpoolWait);
STOREFUNCTIONPOINTER(hKernel32, FlushProcessWriteBuffers);
STOREFUNCTIONPOINTER(hKernel32, FreeLibraryWhenCallbackReturns);
STOREFUNCTIONPOINTER(hKernel32, GetCurrentProcessorNumber);
STOREFUNCTIONPOINTER(hKernel32, CreateSymbolicLinkW);
#if defined(_CRT_WINDOWS) || defined(UNDOCKED_WINDOWS_UCRT)
STOREFUNCTIONPOINTER(hKernel32, SetDefaultDllDirectories);
STOREFUNCTIONPOINTER(hKernel32, EnumSystemLocalesEx);
STOREFUNCTIONPOINTER(hKernel32, CompareStringEx);
STOREFUNCTIONPOINTER(hKernel32, GetLocaleInfoEx);
STOREFUNCTIONPOINTER(hKernel32, GetUserDefaultLocaleName);
STOREFUNCTIONPOINTER(hKernel32, IsValidLocaleName);
STOREFUNCTIONPOINTER(hKernel32, LCMapStringEx);
#else
STOREFUNCTIONPOINTER(hKernel32, GetCurrentPackageId);
#endif
STOREFUNCTIONPOINTER(hKernel32, GetTickCount64);
STOREFUNCTIONPOINTER(hKernel32, GetFileInformationByHandleEx);
STOREFUNCTIONPOINTER(hKernel32, SetFileInformationByHandle);
STOREFUNCTIONPOINTER(hKernel32, GetSystemTimePreciseAsFileTime);
STOREFUNCTIONPOINTER(hKernel32, InitializeConditionVariable);
STOREFUNCTIONPOINTER(hKernel32, WakeConditionVariable);
STOREFUNCTIONPOINTER(hKernel32, WakeAllConditionVariable);
STOREFUNCTIONPOINTER(hKernel32, SleepConditionVariableCS);
STOREFUNCTIONPOINTER(hKernel32, InitializeSRWLock);
STOREFUNCTIONPOINTER(hKernel32, AcquireSRWLockExclusive);
STOREFUNCTIONPOINTER(hKernel32, TryAcquireSRWLockExclusive);
STOREFUNCTIONPOINTER(hKernel32, ReleaseSRWLockExclusive);
STOREFUNCTIONPOINTER(hKernel32, SleepConditionVariableSRW);
STOREFUNCTIONPOINTER(hKernel32, CreateThreadpoolWork);
STOREFUNCTIONPOINTER(hKernel32, SubmitThreadpoolWork);
STOREFUNCTIONPOINTER(hKernel32, CloseThreadpoolWork);
#if !defined(_CRT_WINDOWS) && !defined(UNDOCKED_WINDOWS_UCRT)
STOREFUNCTIONPOINTER(hKernel32, CompareStringEx);
STOREFUNCTIONPOINTER(hKernel32, GetLocaleInfoEx);
STOREFUNCTIONPOINTER(hKernel32, LCMapStringEx);
#endif
STOREFUNCTIONPOINTER(hKernel32, GetCurrentPackageId);
#endif // !defined(_CRT_WINDOWS) && !defined(UNDOCKED_WINDOWS_UCRT)
#if _STL_WIN32_WINNT < _WIN32_WINNT_WIN8
STOREFUNCTIONPOINTER(hKernel32, GetSystemTimePreciseAsFileTime);
#endif // _STL_WIN32_WINNT < _WIN32_WINNT_WIN8
return 0;
}