1 // 2 // appcrt_dllmain.cpp 3 // 4 // Copyright (c) Microsoft Corporation. All rights reserved. 5 // 6 // The entry point for the AppCRT dynamic library. 7 // 8 #include <corecrt_internal.h> 9 10 #ifndef CRTDLL 11 #error This file should only be built into the CRT DLLs 12 #endif 13 14 extern "C" { 15 16 // Flag set iff DllMain was called with DLL_PROCESS_ATTACH 17 static int __acrt_process_attached = 0; 18 19 static BOOL DllMainProcessAttach() 20 { 21 if (!__vcrt_initialize()) 22 return FALSE; 23 24 if (!__acrt_initialize()) 25 { 26 __vcrt_uninitialize(false); 27 return FALSE; 28 } 29 30 // Increment flag indicating the process attach completed successfully: 31 ++__acrt_process_attached; 32 return TRUE; 33 } 34 35 static BOOL DllMainProcessDetach(bool const terminating) 36 { 37 // If there was no prior process attach or if it failed, return immediately: 38 if (__acrt_process_attached <= 0) 39 return FALSE; 40 41 --__acrt_process_attached; 42 if (!__acrt_uninitialize(terminating)) 43 return FALSE; 44 45 // The VCRuntime is uninitialized during the AppCRT uninitialization; we do 46 // not need to uninitialize it here. 47 return TRUE; 48 } 49 50 51 // Make sure this function is not inlined so that we can use it as a place to put a breakpoint for debugging. 52 __declspec(noinline) void __acrt_end_boot() 53 { 54 // Do nothing. This function is used to mark the end of the init process. 55 } 56 57 static __declspec(noinline) BOOL DllMainDispatch(HINSTANCE, DWORD const fdwReason, LPVOID const lpReserved) 58 { 59 BOOL result = FALSE; 60 switch (fdwReason) 61 { 62 case DLL_PROCESS_ATTACH: 63 result = DllMainProcessAttach(); 64 break; 65 66 case DLL_PROCESS_DETACH: 67 result = DllMainProcessDetach(lpReserved != nullptr); 68 break; 69 70 case DLL_THREAD_ATTACH: 71 result = __acrt_thread_attach() ? TRUE : FALSE; 72 break; 73 74 case DLL_THREAD_DETACH: 75 result = __acrt_thread_detach() ? TRUE : FALSE; 76 break; 77 } 78 79 __acrt_end_boot(); 80 return result; 81 } 82 83 BOOL WINAPI __acrt_DllMain(HINSTANCE const hInstance, DWORD const fdwReason, LPVOID const lpReserved) 84 { 85 if (fdwReason == DLL_PROCESS_ATTACH) 86 { 87 // The /GS security cookie must be initialized before any exception 88 // handling targeting the current image is registered. No function 89 // using exception handling can be called in the current image until 90 // after __security_init_cookie has been called. 91 __security_init_cookie(); 92 } 93 94 // The remainder of the DllMain implementation is in a separate, noinline 95 // function to ensure that no code that might touch the security cookie 96 // runs before the __security_init_cookie function is called. (If code 97 // that uses EH or array-type local variables were to be inlined into 98 // this function, that would cause the compiler to introduce use of the 99 // cookie into this function, before the call to __security_init_cookie. 100 // The separate, noinline function ensures that this does not occur.) 101 return DllMainDispatch(hInstance, fdwReason, lpReserved); 102 } 103 104 #ifdef _UCRT_ENCLAVE_BUILD 105 106 #include <enclaveids.h> 107 108 const IMAGE_ENCLAVE_CONFIG __enclave_config = { 109 sizeof(IMAGE_ENCLAVE_CONFIG), 110 0, 111 0, 112 0, 113 0, 114 0, 115 { 0 }, 116 ENCLAVE_IMAGE_ID_UCRT, 117 }; 118 119 #endif 120 121 } // extern "C" 122