// // initialization.cpp // // Copyright (c) Microsoft Corporation. All rights reserved. // // This file defines the main initialization and uninitialization routines for // the VCRuntime, shared by both the static and dynamic VCRuntime libraries. In // the dynamic VCRuntime library, these are called by DllMain. In the static // VCRuntime library, these are called by the initialization code. // #include extern "C" { #if !defined(_CRT_WINDOWS) && \ (defined(_M_ARM64) || defined(_M_ARM64EC) || defined(_M_HYBRID_X86_ARM64)) && \ !defined(_CRT_APP) && !defined(_CRT_ONECORE) && !defined(_CRT_ENCLAVE) #define INIT_STRING_FUNCTIONS 1 int __arm64_safe_unaligned_memory_access; static bool __IsWindowsVersionOrGreaterEx(WORD wMajorVersion, WORD wMinorVersion, WORD wServicePackMajor, WORD wBuildNumber) { OSVERSIONINFOEXW osvi = { sizeof(osvi) }; DWORDLONG const dwlConditionMask = VerSetConditionMask( VerSetConditionMask( VerSetConditionMask( VerSetConditionMask( 0, VER_MAJORVERSION, VER_GREATER_EQUAL), VER_MINORVERSION, VER_GREATER_EQUAL), VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL), VER_BUILDNUMBER, VER_GREATER_EQUAL); osvi.dwMajorVersion = wMajorVersion; osvi.dwMinorVersion = wMinorVersion; osvi.wServicePackMajor = wServicePackMajor; osvi.dwBuildNumber = wBuildNumber; return VerifyVersionInfoW(&osvi, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_BUILDNUMBER, dwlConditionMask) != FALSE; } static bool __IsWindows1122H2OrGreater() { const WORD WIN11_22H2_BUILD_NUM = 22621; return __IsWindowsVersionOrGreaterEx(HIBYTE(_WIN32_WINNT_WINTHRESHOLD), LOBYTE(_WIN32_WINNT_WINTHRESHOLD), 0, WIN11_22H2_BUILD_NUM); } static void __cdecl init_string_functions() { if (__IsWindows1122H2OrGreater()) { __arm64_safe_unaligned_memory_access = 1; } } #endif bool __cdecl __vcrt_initialize() { #if defined CRTDLL __isa_available_init(); #endif #ifdef INIT_STRING_FUNCTIONS init_string_functions(); #endif if (!__vcrt_initialize_locks()) { return false; } if (!__vcrt_initialize_ptd()) { __vcrt_uninitialize_locks(); return false; } return true; } bool __cdecl __vcrt_uninitialize(_In_ bool const terminating) { UNREFERENCED_PARAMETER(terminating); // If the process is terminating, there's no point in cleaning up, except // in debug builds. #ifndef _DEBUG if (!terminating) #endif { __vcrt_uninitialize_ptd(); __vcrt_uninitialize_locks(); } return true; } bool __cdecl __vcrt_uninitialize_critical() { __vcrt_uninitialize_ptd(); return true; } bool __cdecl __vcrt_thread_attach() { // Create a per-thread data structure for this thread (getptd will attempt // to create a new per-thread data structure if one does not already exist // for this thread): if (__vcrt_getptd_noexit() == nullptr) return false; return true; } bool __cdecl __vcrt_thread_detach() { // Free the per-thread data structure for this thread: __vcrt_freeptd_for_this_thread(); return true; } }