xref: /reactos/dll/win32/kernel32/client/dllmain.c (revision c2c66aff)
1 /*
2  * COPYRIGHT:       See COPYING in the top level directory
3  * PROJECT:         ReactOS system libraries
4  * FILE:            dll/win32/kernel32/client/dllmain.c
5  * PURPOSE:         Initialization
6  * PROGRAMMERS:     Ariadne (ariadne@xs4all.nl)
7  *                  Aleksey Bragin (aleksey@reactos.org)
8  */
9 
10 /* INCLUDES ******************************************************************/
11 
12 #include <k32.h>
13 
14 #define NDEBUG
15 #include <debug.h>
16 
17 /* GLOBALS *******************************************************************/
18 
19 PBASE_STATIC_SERVER_DATA BaseStaticServerData;
20 BOOLEAN BaseRunningInServerProcess = FALSE;
21 
22 WCHAR BaseDefaultPathBuffer[6140];
23 
24 HANDLE BaseNamedObjectDirectory;
25 HMODULE hCurrentModule = NULL;
26 HMODULE kernel32_handle = NULL;
27 PPEB Peb;
28 ULONG SessionId;
29 static BOOL DllInitialized = FALSE;
30 
31 /* Critical section for various kernel32 data structures */
32 RTL_CRITICAL_SECTION BaseDllDirectoryLock;
33 
34 extern BOOL FASTCALL NlsInit(VOID);
35 extern VOID FASTCALL NlsUninit(VOID);
36 
37 #define WIN_OBJ_DIR L"\\Windows"
38 #define SESSION_DIR L"\\Sessions"
39 
40 /* FUNCTIONS *****************************************************************/
41 
42 NTSTATUS
43 NTAPI
44 BaseCreateThreadPoolThread(IN PTHREAD_START_ROUTINE Function,
45                            IN PVOID Parameter,
46                            OUT PHANDLE ThreadHandle)
47 {
48     NTSTATUS Status;
49 
50     /* Create a Win32 thread */
51     *ThreadHandle = CreateRemoteThread(NtCurrentProcess(),
52                                        NULL,
53                                        0,
54                                        Function,
55                                        Parameter,
56                                        CREATE_SUSPENDED,
57                                        NULL);
58     if (!(*ThreadHandle))
59     {
60         /* Get the status value if we couldn't get a handle */
61         Status = NtCurrentTeb()->LastStatusValue;
62         if (NT_SUCCESS(Status)) Status = STATUS_UNSUCCESSFUL;
63     }
64     else
65     {
66         /* Set success code */
67         Status = STATUS_SUCCESS;
68     }
69 
70     /* All done */
71     return Status;
72 }
73 
74 NTSTATUS
75 NTAPI
76 BaseExitThreadPoolThread(IN NTSTATUS ExitStatus)
77 {
78     /* Exit the thread */
79     ExitThread(ExitStatus);
80     return STATUS_SUCCESS;
81 }
82 
83 BOOL
84 WINAPI
85 DllMain(HANDLE hDll,
86         DWORD dwReason,
87         LPVOID lpReserved)
88 {
89     NTSTATUS Status;
90     BASESRV_API_CONNECTINFO ConnectInfo;
91     ULONG ConnectInfoSize = sizeof(ConnectInfo);
92     WCHAR SessionDir[256];
93 
94     DPRINT("DllMain(hInst %p, dwReason %lu)\n",
95            hDll, dwReason);
96 
97     Basep8BitStringToUnicodeString = RtlAnsiStringToUnicodeString;
98 
99     /* Cache the PEB and Session ID */
100     Peb = NtCurrentPeb();
101     SessionId = Peb->SessionId;
102 
103     switch (dwReason)
104     {
105         case DLL_PROCESS_ATTACH:
106         {
107             /* Set no filter initially */
108             GlobalTopLevelExceptionFilter = RtlEncodePointer(NULL);
109 
110             /* Enable the Rtl thread pool and timer queue to use proper Win32 thread */
111             RtlSetThreadPoolStartFunc(BaseCreateThreadPoolThread, BaseExitThreadPoolThread);
112 
113             /* Register the manifest prober routine */
114             LdrSetDllManifestProber(BasepProbeForDllManifest);
115 
116             /* Don't bother us for each thread */
117             LdrDisableThreadCalloutsForDll((PVOID)hDll);
118 
119             /* Initialize default path to NULL */
120             RtlInitUnicodeString(&BaseDefaultPath, NULL);
121 
122             /* Setup the Object Directory path */
123             if (!SessionId)
124             {
125                 /* Use the raw path */
126                 wcscpy(SessionDir, WIN_OBJ_DIR);
127             }
128             else
129             {
130                 /* Use the session path */
131                 swprintf(SessionDir,
132                          L"%ws\\%ld%ws",
133                          SESSION_DIR,
134                          SessionId,
135                          WIN_OBJ_DIR);
136             }
137 
138             /* Connect to the Base Server */
139             Status = CsrClientConnectToServer(SessionDir,
140                                               BASESRV_SERVERDLL_INDEX,
141                                               &ConnectInfo,
142                                               &ConnectInfoSize,
143                                               &BaseRunningInServerProcess);
144             if (!NT_SUCCESS(Status))
145             {
146                 DPRINT1("Failed to connect to CSR (Status %lx)\n", Status);
147                 NtTerminateProcess(NtCurrentProcess(), Status);
148                 return FALSE;
149             }
150 
151             /* Get the server data */
152             ASSERT(Peb->ReadOnlyStaticServerData);
153             BaseStaticServerData = Peb->ReadOnlyStaticServerData[BASESRV_SERVERDLL_INDEX];
154             ASSERT(BaseStaticServerData);
155 
156             /* Check if we are running a CSR Server */
157             if (!BaseRunningInServerProcess)
158             {
159                 /* Set the termination port for the thread */
160                 DPRINT("Creating new thread for CSR\n");
161                 CsrNewThread();
162             }
163 
164             /* Initialize heap handle table */
165             BaseDllInitializeMemoryManager();
166 
167             /* Set HMODULE for our DLL */
168             kernel32_handle = hCurrentModule = hDll;
169 
170             /* Set the directories */
171             BaseWindowsDirectory = BaseStaticServerData->WindowsDirectory;
172             BaseWindowsSystemDirectory = BaseStaticServerData->WindowsSystemDirectory;
173 
174             /* Construct the default path (using the static buffer) */
175             _snwprintf(BaseDefaultPathBuffer,
176                        sizeof(BaseDefaultPathBuffer) / sizeof(WCHAR),
177                        L".;%wZ;%wZ\\system;%wZ;",
178                        &BaseWindowsSystemDirectory,
179                        &BaseWindowsDirectory,
180                        &BaseWindowsDirectory);
181 
182             BaseDefaultPath.Buffer = BaseDefaultPathBuffer;
183             BaseDefaultPath.Length = wcslen(BaseDefaultPathBuffer) * sizeof(WCHAR);
184             BaseDefaultPath.MaximumLength = sizeof(BaseDefaultPathBuffer);
185 
186             /* Use remaining part of the default path buffer for the append path */
187             BaseDefaultPathAppend.Buffer = (PWSTR)((ULONG_PTR)BaseDefaultPathBuffer + BaseDefaultPath.Length);
188             BaseDefaultPathAppend.Length = 0;
189             BaseDefaultPathAppend.MaximumLength = BaseDefaultPath.MaximumLength - BaseDefaultPath.Length;
190 
191             /* Initialize command line */
192             InitCommandLines();
193 
194             /* Initialize the DLL critical section */
195             RtlInitializeCriticalSection(&BaseDllDirectoryLock);
196 
197             /* Initialize the National Language Support routines */
198             if (!NlsInit())
199             {
200                 DPRINT1("NLS Init failed\n");
201                 return FALSE;
202             }
203 
204             /* Initialize Console Support */
205             if (!ConDllInitialize(dwReason, SessionDir))
206             {
207                 DPRINT1("Failed to set up console\n");
208                 return FALSE;
209             }
210 
211             /* Initialize application certification globals */
212             InitializeListHead(&BasepAppCertDllsList);
213             RtlInitializeCriticalSection(&gcsAppCert);
214 
215             /* Insert more dll attach stuff here! */
216             DllInitialized = TRUE;
217             break;
218         }
219 
220         case DLL_PROCESS_DETACH:
221         {
222             if (DllInitialized != FALSE)
223             {
224                 /* Uninitialize console support */
225                 ConDllInitialize(dwReason, NULL);
226 
227                 /* Insert more dll detach stuff here! */
228                 NlsUninit();
229 
230                 /* Delete DLL critical section */
231                 RtlDeleteCriticalSection(&BaseDllDirectoryLock);
232             }
233             break;
234         }
235 
236         case DLL_THREAD_ATTACH:
237         {
238             /* ConDllInitialize sets the current console locale for the new thread */
239             return ConDllInitialize(dwReason, NULL);
240         }
241 
242         default:
243             break;
244     }
245 
246     return TRUE;
247 }
248 
249 /* EOF */
250