a8573ca28c6dda3b0184797af69b2706585f6fff
[reactos.git] / dll / win32 / kernel32 / client / dllmain.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS system libraries
4 * FILE: lib/kernel32/misc/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
21 BOOLEAN BaseRunningInServerProcess;
22
23 WCHAR BaseDefaultPathBuffer[6140];
24
25 HANDLE BaseNamedObjectDirectory;
26 HMODULE hCurrentModule = NULL;
27 HMODULE kernel32_handle = NULL;
28 PPEB Peb;
29 ULONG SessionId;
30 static BOOL DllInitialized = FALSE;
31
32 /* Critical section for various kernel32 data structures */
33 RTL_CRITICAL_SECTION BaseDllDirectoryLock;
34
35 extern BOOL FASTCALL NlsInit(VOID);
36 extern VOID FASTCALL NlsUninit(VOID);
37
38 #define WIN_OBJ_DIR L"\\Windows"
39 #define SESSION_DIR L"\\Sessions"
40
41 /* FUNCTIONS *****************************************************************/
42
43 NTSTATUS
44 NTAPI
45 BaseCreateThreadPoolThread(IN PTHREAD_START_ROUTINE Function,
46 IN PVOID Parameter,
47 OUT PHANDLE ThreadHandle)
48 {
49 NTSTATUS Status;
50
51 /* Create a Win32 thread */
52 *ThreadHandle = CreateRemoteThread(NtCurrentProcess(),
53 NULL,
54 0,
55 Function,
56 Parameter,
57 CREATE_SUSPENDED,
58 NULL);
59 if (!(*ThreadHandle))
60 {
61 /* Get the status value if we couldn't get a handle */
62 Status = NtCurrentTeb()->LastStatusValue;
63 if (NT_SUCCESS(Status)) Status = STATUS_UNSUCCESSFUL;
64 }
65 else
66 {
67 /* Set success code */
68 Status = STATUS_SUCCESS;
69 }
70
71 /* All done */
72 return Status;
73 }
74
75 NTSTATUS
76 NTAPI
77 BaseExitThreadPoolThread(IN NTSTATUS ExitStatus)
78 {
79 /* Exit the thread */
80 ExitThread(ExitStatus);
81 return STATUS_SUCCESS;
82 }
83
84 BOOL
85 WINAPI
86 DllMain(HANDLE hDll,
87 DWORD dwReason,
88 LPVOID lpReserved)
89 {
90 NTSTATUS Status;
91 ULONG Dummy;
92 ULONG DummySize = sizeof(Dummy);
93 WCHAR SessionDir[256];
94
95 DPRINT("DllMain(hInst %lx, dwReason %lu)\n",
96 hDll, dwReason);
97
98 Basep8BitStringToUnicodeString = RtlAnsiStringToUnicodeString;
99
100 /* Cache the PEB and Session ID */
101 Peb = NtCurrentPeb();
102 SessionId = Peb->SessionId;
103
104 switch (dwReason)
105 {
106 case DLL_PROCESS_ATTACH:
107 {
108 /* Set no filter intially */
109 GlobalTopLevelExceptionFilter = RtlEncodePointer(NULL);
110
111 /* Enable the Rtl thread pool and timer queue to use proper Win32 thread */
112 RtlSetThreadPoolStartFunc(BaseCreateThreadPoolThread, BaseExitThreadPoolThread);
113
114 /* Don't bother us for each thread */
115 LdrDisableThreadCalloutsForDll((PVOID)hDll);
116
117 /* Initialize default path to NULL */
118 RtlInitUnicodeString(&BaseDefaultPath, NULL);
119
120 /* Setup the right Object Directory path */
121 if (!SessionId)
122 {
123 /* Use the raw path */
124 wcscpy(SessionDir, WIN_OBJ_DIR);
125 }
126 else
127 {
128 /* Use the session path */
129 swprintf(SessionDir,
130 L"%ws\\%ld%ws",
131 SESSION_DIR,
132 SessionId,
133 WIN_OBJ_DIR);
134 }
135
136 /* Connect to the base server */
137 DPRINT("Connecting to CSR in DllMain...\n");
138 Status = CsrClientConnectToServer(SessionDir,
139 BASESRV_SERVERDLL_INDEX,
140 &Dummy,
141 &DummySize,
142 &BaseRunningInServerProcess);
143 if (!NT_SUCCESS(Status))
144 {
145 DPRINT1("Failed to connect to CSR (Status %lx)\n", Status);
146 NtTerminateProcess(NtCurrentProcess(), Status);
147 return FALSE;
148 }
149 DPRINT("kernel32 DllMain - OK, connection succeeded\n");
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 (!BasepInitConsole())
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 DPRINT("Initialization complete\n");
218 break;
219 }
220
221 case DLL_PROCESS_DETACH:
222 {
223 DPRINT("DLL_PROCESS_DETACH\n");
224 if (DllInitialized == TRUE)
225 {
226 /* Insert more dll detach stuff here! */
227 NlsUninit();
228
229 /* Uninitialize console support */
230 BasepUninitConsole();
231
232 /* Delete DLL critical section */
233 RtlDeleteCriticalSection(&BaseDllDirectoryLock);
234 }
235 break;
236 }
237
238 default:
239 break;
240 }
241
242 return TRUE;
243 }
244
245 /* EOF */