xref: /reactos/sdk/lib/ucrt/dll/appcrt_dllmain.cpp (revision b09b5584)
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