From 805c1bcd008fdbfba2eca2c37a6076df1e7c09b2 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Fri, 1 Jul 2022 17:17:25 -0700 Subject: [PATCH 01/15] Dramatically shrink the `__KERNEL32Functions` table. The only direct uses of `__KERNEL32Functions` are in `STOREFUNCTIONPOINTER` and `DYNAMICGETCACHEDFUNCTION`. The only use of `DYNAMICGETCACHEDFUNCTION` is in `IFDYNAMICGETCACHEDFUNCTION`. There are only two uses of `IFDYNAMICGETCACHEDFUNCTION`, loading `GetCurrentPackageId` and `GetSystemTimePreciseAsFileTime`. Therefore, all other table entries are unused. The comment `// This enum should not change` was introduced by GH 1194, but we were being overly cautious. The enum and table aren't mentioned outside of `stl/src`. Also, while the table was `extern "C"`, it wasn't exported. Therefore, they're purely internal to the separately compiled STL. --- stl/src/awint.hpp | 48 ------------------------------------------ stl/src/winapisupp.cpp | 47 ----------------------------------------- 2 files changed, 95 deletions(-) diff --git a/stl/src/awint.hpp b/stl/src/awint.hpp index 2dbabd271c6..debf78f2668 100644 --- a/stl/src/awint.hpp +++ b/stl/src/awint.hpp @@ -27,60 +27,12 @@ _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 }; diff --git a/stl/src/winapisupp.cpp b/stl/src/winapisupp.cpp index d2a02cff3f5..21049f7279b 100644 --- a/stl/src/winapisupp.cpp +++ b/stl/src/winapisupp.cpp @@ -376,58 +376,11 @@ 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 return 0; } From c3a7fee5fd2c4ba6132bc2c76e7f1509e3d6f84e Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Fri, 1 Jul 2022 17:22:16 -0700 Subject: [PATCH 02/15] De Morgan. --- stl/src/awint.hpp | 5 ++--- stl/src/winapisupp.cpp | 5 ++--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/stl/src/awint.hpp b/stl/src/awint.hpp index debf78f2668..b23c009e9b0 100644 --- a/stl/src/awint.hpp +++ b/stl/src/awint.hpp @@ -28,10 +28,9 @@ _CRTIMP2 void __cdecl __crtGetSystemTimePreciseAsFileTime(_Out_ LPFILETIME lpSys #endif // _STL_WIN32_WINNT >= _WIN32_WINNT_WIN8 enum wrapKERNEL32Functions { -#if defined(_CRT_WINDOWS) || defined(UNDOCKED_WINDOWS_UCRT) -#else // defined(_CRT_WINDOWS) || defined(UNDOCKED_WINDOWS_UCRT) +#if !defined(_CRT_WINDOWS) && !defined(UNDOCKED_WINDOWS_UCRT) eGetCurrentPackageId, -#endif // defined(_CRT_WINDOWS) || defined(UNDOCKED_WINDOWS_UCRT) +#endif // !defined(_CRT_WINDOWS) && !defined(UNDOCKED_WINDOWS_UCRT) eGetSystemTimePreciseAsFileTime, eMaxKernel32Function }; diff --git a/stl/src/winapisupp.cpp b/stl/src/winapisupp.cpp index 21049f7279b..a990000c97d 100644 --- a/stl/src/winapisupp.cpp +++ b/stl/src/winapisupp.cpp @@ -376,10 +376,9 @@ static int __cdecl initialize_pointers() { HINSTANCE hKernel32 = GetModuleHandleW(L"kernel32.dll"); _Analysis_assume_(hKernel32); -#if defined(_CRT_WINDOWS) || defined(UNDOCKED_WINDOWS_UCRT) -#else +#if !defined(_CRT_WINDOWS) && !defined(UNDOCKED_WINDOWS_UCRT) STOREFUNCTIONPOINTER(hKernel32, GetCurrentPackageId); -#endif +#endif // !defined(_CRT_WINDOWS) && !defined(UNDOCKED_WINDOWS_UCRT) STOREFUNCTIONPOINTER(hKernel32, GetSystemTimePreciseAsFileTime); return 0; From 5765cd970f9e25d7f7895e91cde4ac962f2b7430 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Fri, 1 Jul 2022 18:02:31 -0700 Subject: [PATCH 03/15] Move `__KERNEL32Functions` machinery to `winapisupp.cpp`. It was within `_CRT_BEGIN_C_HEADER` / `_CRT_END_C_HEADER`. --- stl/src/awint.hpp | 24 ------------------------ stl/src/winapisupp.cpp | 28 ++++++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 24 deletions(-) diff --git a/stl/src/awint.hpp b/stl/src/awint.hpp index b23c009e9b0..f874fcc6bed 100644 --- a/stl/src/awint.hpp +++ b/stl/src/awint.hpp @@ -27,30 +27,6 @@ _CRTIMP2 void __cdecl __crtGetSystemTimePreciseAsFileTime(_Out_ LPFILETIME lpSys #endif // _STL_WIN32_WINNT >= _WIN32_WINNT_WIN8 -enum wrapKERNEL32Functions { -#if !defined(_CRT_WINDOWS) && !defined(UNDOCKED_WINDOWS_UCRT) - eGetCurrentPackageId, -#endif // !defined(_CRT_WINDOWS) && !defined(UNDOCKED_WINDOWS_UCRT) - eGetSystemTimePreciseAsFileTime, - 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(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(__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); diff --git a/stl/src/winapisupp.cpp b/stl/src/winapisupp.cpp index a990000c97d..56ad74ca421 100644 --- a/stl/src/winapisupp.cpp +++ b/stl/src/winapisupp.cpp @@ -16,6 +16,34 @@ #pragma warning(pop) #include +_CRT_BEGIN_C_HEADER + +enum wrapKERNEL32Functions { +#if !defined(_CRT_WINDOWS) && !defined(UNDOCKED_WINDOWS_UCRT) + eGetCurrentPackageId, +#endif // !defined(_CRT_WINDOWS) && !defined(UNDOCKED_WINDOWS_UCRT) + eGetSystemTimePreciseAsFileTime, + 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(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(__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) + +_CRT_END_C_HEADER + #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*); From 916551098ca1400d49914a8b69138c54a756582f Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Fri, 1 Jul 2022 18:18:11 -0700 Subject: [PATCH 04/15] Guard `__KERNEL32Functions` machinery with `#if !defined(_ONECORE)`. Fuse declaration and definition. The definition and initialization of `__KERNEL32Functions` were effectively guarded by `#if !defined(_ONECORE)`, so we should extend that guard to all of the machinery. When fusing the declaration and definition, we're within `_CRT_BEGIN_C_HEADER` so we don't need `extern "C"`. We also don't need `extern` (the definition already has external linkage, and other TUs don't need this anyways). For style, initialize with `{}` instead of ` = {nullptr}`. They have the same effect here, but `{}` emphasizes that we want to value-initialize the entire table. --- stl/src/winapisupp.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/stl/src/winapisupp.cpp b/stl/src/winapisupp.cpp index 56ad74ca421..30ced6e3a6d 100644 --- a/stl/src/winapisupp.cpp +++ b/stl/src/winapisupp.cpp @@ -16,6 +16,7 @@ #pragma warning(pop) #include +#if !defined(_ONECORE) _CRT_BEGIN_C_HEADER enum wrapKERNEL32Functions { @@ -26,7 +27,7 @@ enum wrapKERNEL32Functions { eMaxKernel32Function }; -extern PVOID __KERNEL32Functions[eMaxKernel32Function]; +PVOID __KERNEL32Functions[eMaxKernel32Function]{}; using PFNGETSYSTEMTIMEPRECISEASFILETIME = VOID(WINAPI*)(LPFILETIME); @@ -43,6 +44,7 @@ using PFNGETSYSTEMTIMEPRECISEASFILETIME = VOID(WINAPI*)(LPFILETIME); if (variable_name != nullptr) _CRT_END_C_HEADER +#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. @@ -398,8 +400,6 @@ 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); From 407a0e70477bf7d2c3a4f465b17def4a8cd1c9f1 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Fri, 1 Jul 2022 18:32:01 -0700 Subject: [PATCH 05/15] Use an unnamed namespace instead of `extern "C"` for the `__KERNEL32Functions` machinery. We don't need this in other TUs. The unnamed namespace emphasizes that it's purely internal. --- stl/src/winapisupp.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/stl/src/winapisupp.cpp b/stl/src/winapisupp.cpp index 30ced6e3a6d..a5eec0f6f86 100644 --- a/stl/src/winapisupp.cpp +++ b/stl/src/winapisupp.cpp @@ -17,19 +17,19 @@ #include #if !defined(_ONECORE) -_CRT_BEGIN_C_HEADER +namespace { -enum wrapKERNEL32Functions { + enum wrapKERNEL32Functions { #if !defined(_CRT_WINDOWS) && !defined(UNDOCKED_WINDOWS_UCRT) - eGetCurrentPackageId, + eGetCurrentPackageId, #endif // !defined(_CRT_WINDOWS) && !defined(UNDOCKED_WINDOWS_UCRT) - eGetSystemTimePreciseAsFileTime, - eMaxKernel32Function -}; + eGetSystemTimePreciseAsFileTime, + eMaxKernel32Function + }; -PVOID __KERNEL32Functions[eMaxKernel32Function]{}; + PVOID __KERNEL32Functions[eMaxKernel32Function]{}; -using PFNGETSYSTEMTIMEPRECISEASFILETIME = VOID(WINAPI*)(LPFILETIME); + using PFNGETSYSTEMTIMEPRECISEASFILETIME = VOID(WINAPI*)(LPFILETIME); // Use this macro for caching a function pointer from a DLL #define STOREFUNCTIONPOINTER(instance, function_name) \ @@ -43,7 +43,7 @@ using PFNGETSYSTEMTIMEPRECISEASFILETIME = VOID(WINAPI*)(LPFILETIME); DYNAMICGETCACHEDFUNCTION(function_pointer_type, function_name, variable_name); \ if (variable_name != nullptr) -_CRT_END_C_HEADER +} // unnamed namespace #endif // ^^^ !defined(_ONECORE) ^^^ #if !defined(_CRT_WINDOWS) && !defined(UNDOCKED_WINDOWS_UCRT) From 975c4cfb46293d60399c59d68e696619ac385d68 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Fri, 1 Jul 2022 18:43:17 -0700 Subject: [PATCH 06/15] Cache `GetSystemTimePreciseAsFileTime` only when we need it. Now we need to guard against `eMaxKernel32Function` being `0`. --- stl/src/winapisupp.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/stl/src/winapisupp.cpp b/stl/src/winapisupp.cpp index a5eec0f6f86..0832139c5fd 100644 --- a/stl/src/winapisupp.cpp +++ b/stl/src/winapisupp.cpp @@ -23,11 +23,15 @@ namespace { #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]{}; + PVOID __KERNEL32Functions[eMaxKernel32Function > 0 ? eMaxKernel32Function : 1]{}; using PFNGETSYSTEMTIMEPRECISEASFILETIME = VOID(WINAPI*)(LPFILETIME); @@ -407,7 +411,10 @@ static int __cdecl initialize_pointers() { #if !defined(_CRT_WINDOWS) && !defined(UNDOCKED_WINDOWS_UCRT) 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; } From 2e13066bbc02cb65040509de973251f072e27f03 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Fri, 1 Jul 2022 19:12:35 -0700 Subject: [PATCH 07/15] Fix return type in `PFNGETCURRENTPACKAGEID` typedef. See: https://docs.microsoft.com/en-us/windows/win32/api/appmodel/nf-appmodel-getcurrentpackageid Verified that this is now identical to `decltype(&GetCurrentPackageId)`. --- stl/src/winapisupp.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stl/src/winapisupp.cpp b/stl/src/winapisupp.cpp index 0832139c5fd..7974e7f4796 100644 --- a/stl/src/winapisupp.cpp +++ b/stl/src/winapisupp.cpp @@ -52,7 +52,7 @@ namespace { #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*); +using PFNGETCURRENTPACKAGEID = LONG(WINAPI*)(UINT32*, BYTE*); #if !defined _CRT_APP #if defined _ONECORE From da8d4d940e0927f3912ddefac5a4c4ceb65cc215 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Fri, 1 Jul 2022 19:25:36 -0700 Subject: [PATCH 08/15] Fuse `DYNAMICGETCACHEDFUNCTION` into `IFDYNAMICGETCACHEDFUNCTION`. Update comment. Style: Directly test the function pointer. --- stl/src/winapisupp.cpp | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/stl/src/winapisupp.cpp b/stl/src/winapisupp.cpp index 7974e7f4796..437d14ed010 100644 --- a/stl/src/winapisupp.cpp +++ b/stl/src/winapisupp.cpp @@ -39,13 +39,10 @@ namespace { #define STOREFUNCTIONPOINTER(instance, function_name) \ __KERNEL32Functions[e##function_name] = reinterpret_cast(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(__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) +// Use this macro for retrieving a cached function pointer from a DLL +#define IFDYNAMICGETCACHEDFUNCTION(function_pointer_type, function_name, variable_name) \ + const auto variable_name = reinterpret_cast(__KERNEL32Functions[e##function_name]); \ + if (variable_name) } // unnamed namespace #endif // ^^^ !defined(_ONECORE) ^^^ From 037445b2048ead8ff105b6f114ce8bfe7af4f41c Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Fri, 1 Jul 2022 20:26:48 -0700 Subject: [PATCH 09/15] Always use `decltype` in `IFDYNAMICGETCACHEDFUNCTION`. We no longer need `PFNGETSYSTEMTIMEPRECISEASFILETIME`. Also, always emit `pf##function_name`. --- stl/src/winapisupp.cpp | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/stl/src/winapisupp.cpp b/stl/src/winapisupp.cpp index 437d14ed010..9786c302a72 100644 --- a/stl/src/winapisupp.cpp +++ b/stl/src/winapisupp.cpp @@ -33,16 +33,14 @@ namespace { PVOID __KERNEL32Functions[eMaxKernel32Function > 0 ? eMaxKernel32Function : 1]{}; - 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(GetProcAddress(instance, #function_name)); // Use this macro for retrieving a cached function pointer from a DLL -#define IFDYNAMICGETCACHEDFUNCTION(function_pointer_type, function_name, variable_name) \ - const auto variable_name = reinterpret_cast(__KERNEL32Functions[e##function_name]); \ - if (variable_name) +#define IFDYNAMICGETCACHEDFUNCTION(function_name) \ + const auto pf##function_name = reinterpret_cast(__KERNEL32Functions[e##function_name]); \ + if (pf##function_name) } // unnamed namespace #endif // ^^^ !defined(_ONECORE) ^^^ @@ -110,8 +108,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) { @@ -380,8 +378,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; } From 86eb5579e2787a5a5b88431fbf2a0db9c747cffd Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Fri, 1 Jul 2022 20:31:56 -0700 Subject: [PATCH 10/15] Use C++17 if-statement with initializer to improve scoping. --- stl/src/winapisupp.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/stl/src/winapisupp.cpp b/stl/src/winapisupp.cpp index 9786c302a72..2f34fef3bfb 100644 --- a/stl/src/winapisupp.cpp +++ b/stl/src/winapisupp.cpp @@ -38,9 +38,8 @@ namespace { __KERNEL32Functions[e##function_name] = reinterpret_cast(GetProcAddress(instance, #function_name)); // Use this macro for retrieving a cached function pointer from a DLL -#define IFDYNAMICGETCACHEDFUNCTION(function_name) \ - const auto pf##function_name = reinterpret_cast(__KERNEL32Functions[e##function_name]); \ - if (pf##function_name) +#define IFDYNAMICGETCACHEDFUNCTION(name) \ + if (const auto pf##name = reinterpret_cast(__KERNEL32Functions[e##name]); pf##name) } // unnamed namespace #endif // ^^^ !defined(_ONECORE) ^^^ From c80d0398dd1342168e4cde34b9f5de1b70c2ab03 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Fri, 1 Jul 2022 20:36:15 -0700 Subject: [PATCH 11/15] Avoid emitting empty statements after `STOREFUNCTIONPOINTER`. --- stl/src/winapisupp.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stl/src/winapisupp.cpp b/stl/src/winapisupp.cpp index 2f34fef3bfb..aeff5b7875d 100644 --- a/stl/src/winapisupp.cpp +++ b/stl/src/winapisupp.cpp @@ -35,7 +35,7 @@ namespace { // Use this macro for caching a function pointer from a DLL #define STOREFUNCTIONPOINTER(instance, function_name) \ - __KERNEL32Functions[e##function_name] = reinterpret_cast(GetProcAddress(instance, #function_name)); + __KERNEL32Functions[e##function_name] = reinterpret_cast(GetProcAddress(instance, #function_name)) // Use this macro for retrieving a cached function pointer from a DLL #define IFDYNAMICGETCACHEDFUNCTION(name) \ From 1472f80818e50e1041be1ef26da4a06ca2a52aba Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Fri, 1 Jul 2022 20:41:05 -0700 Subject: [PATCH 12/15] `winapisupp.cpp` isn't using `` at all. --- stl/src/winapisupp.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/stl/src/winapisupp.cpp b/stl/src/winapisupp.cpp index aeff5b7875d..d900cf52838 100644 --- a/stl/src/winapisupp.cpp +++ b/stl/src/winapisupp.cpp @@ -14,7 +14,6 @@ #pragma warning(disable : 4265) // non-virtual destructor in base class #include #pragma warning(pop) -#include #if !defined(_ONECORE) namespace { From 2f2877bf4b950e8f4c9a80e3b3f7129eb7d2ac1f Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Sat, 28 May 2022 01:28:16 -0700 Subject: [PATCH 13/15] Simplify `__crt_IsPackagedAppHelper()` with range-for and auto. --- stl/src/winapisupp.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/stl/src/winapisupp.cpp b/stl/src/winapisupp.cpp index d900cf52838..8a563a6610c 100644 --- a/stl/src/winapisupp.cpp +++ b/stl/src/winapisupp.cpp @@ -73,15 +73,13 @@ 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 = + auto const get_current_package_id = reinterpret_cast(GetProcAddress(apiset.Get(), "GetCurrentPackageId")); if (!get_current_package_id) { From 75e974d157c4b6fe26fb3653055eebd4b33b7746 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Fri, 1 Jul 2022 21:02:00 -0700 Subject: [PATCH 14/15] `awint.hpp` doesn't need to declare `__crtIsPackagedApp()`. We still need to export it for bincompat. --- stl/src/awint.hpp | 4 ---- stl/src/winapisupp.cpp | 3 ++- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/stl/src/awint.hpp b/stl/src/awint.hpp index f874fcc6bed..7d9e4f80a09 100644 --- a/stl/src/awint.hpp +++ b/stl/src/awint.hpp @@ -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) \ diff --git a/stl/src/winapisupp.cpp b/stl/src/winapisupp.cpp index 8a563a6610c..be68c437d04 100644 --- a/stl/src/winapisupp.cpp +++ b/stl/src/winapisupp.cpp @@ -135,7 +135,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 From 68e342e9778352cfdd2b79af9494c96724fee9d7 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Fri, 1 Jul 2022 21:12:18 -0700 Subject: [PATCH 15/15] We can always use `decltype` for `GetCurrentPackageId`. Verified with an internal build. --- stl/src/winapisupp.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/stl/src/winapisupp.cpp b/stl/src/winapisupp.cpp index be68c437d04..0ae4d3d4c39 100644 --- a/stl/src/winapisupp.cpp +++ b/stl/src/winapisupp.cpp @@ -44,8 +44,6 @@ 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 = LONG(WINAPI*)(UINT32*, BYTE*); #if !defined _CRT_APP #if defined _ONECORE @@ -80,7 +78,7 @@ extern "C" int __crt_IsPackagedAppHelper() { } auto const get_current_package_id = - reinterpret_cast(GetProcAddress(apiset.Get(), "GetCurrentPackageId")); + reinterpret_cast(GetProcAddress(apiset.Get(), "GetCurrentPackageId")); if (!get_current_package_id) { continue;