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
BaseCreateThreadPoolThread(IN PTHREAD_START_ROUTINE Function,IN PVOID Parameter,OUT PHANDLE ThreadHandle)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
BaseExitThreadPoolThread(IN NTSTATUS ExitStatus)76 BaseExitThreadPoolThread(IN NTSTATUS ExitStatus)
77 {
78 /* Exit the thread */
79 ExitThread(ExitStatus);
80 return STATUS_SUCCESS;
81 }
82
83 BOOL
84 WINAPI
DllMain(HANDLE hDll,DWORD dwReason,LPVOID lpReserved)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 Status = RtlStringCbPrintfW(BaseDefaultPathBuffer,
176 sizeof(BaseDefaultPathBuffer),
177 L"%wZ;%wZ\\system;%wZ;",
178 &BaseWindowsSystemDirectory,
179 &BaseWindowsDirectory,
180 &BaseWindowsDirectory);
181 if (!NT_SUCCESS(Status))
182 {
183 DPRINT1("NLS Init failed\n");
184 return FALSE;
185 }
186
187 BaseDefaultPath.Buffer = BaseDefaultPathBuffer;
188 BaseDefaultPath.Length = (USHORT)wcslen(BaseDefaultPathBuffer) * sizeof(WCHAR);
189 BaseDefaultPath.MaximumLength = sizeof(BaseDefaultPathBuffer);
190
191 /* Use remaining part of the default path buffer for the append path */
192 BaseDefaultPathAppend.Buffer = (PWSTR)((ULONG_PTR)BaseDefaultPathBuffer + BaseDefaultPath.Length);
193 BaseDefaultPathAppend.Length = 0;
194 BaseDefaultPathAppend.MaximumLength = BaseDefaultPath.MaximumLength - BaseDefaultPath.Length;
195
196 /* Initialize command line */
197 InitCommandLines();
198
199 /* Initialize the DLL critical section */
200 RtlInitializeCriticalSection(&BaseDllDirectoryLock);
201
202 /* Initialize the National Language Support routines */
203 if (!NlsInit())
204 {
205 DPRINT1("NLS Init failed\n");
206 return FALSE;
207 }
208
209 /* Initialize Console Support */
210 if (!ConDllInitialize(dwReason, SessionDir))
211 {
212 DPRINT1("Failed to set up console\n");
213 return FALSE;
214 }
215
216 /* Initialize application certification globals */
217 InitializeListHead(&BasepAppCertDllsList);
218 RtlInitializeCriticalSection(&gcsAppCert);
219
220 /* Insert more dll attach stuff here! */
221 DllInitialized = TRUE;
222 break;
223 }
224
225 case DLL_PROCESS_DETACH:
226 {
227 if (DllInitialized != FALSE)
228 {
229 /* Uninitialize console support */
230 ConDllInitialize(dwReason, NULL);
231
232 /* Insert more dll detach stuff here! */
233 NlsUninit();
234
235 /* Delete DLL critical section */
236 RtlDeleteCriticalSection(&BaseDllDirectoryLock);
237 }
238 break;
239 }
240
241 case DLL_THREAD_ATTACH:
242 {
243 /* ConDllInitialize sets the current console locale for the new thread */
244 return ConDllInitialize(dwReason, NULL);
245 }
246
247 default:
248 break;
249 }
250
251 return TRUE;
252 }
253
254 /* EOF */
255