04421291ac41e6f206b9d0c0387b28283e68659f
[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 %p, 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 Status = CsrClientConnectToServer(SessionDir,
138 BASESRV_SERVERDLL_INDEX,
139 &Dummy,
140 &DummySize,
141 &BaseRunningInServerProcess);
142 if (!NT_SUCCESS(Status))
143 {
144 DPRINT1("Failed to connect to CSR (Status %lx)\n", Status);
145 NtTerminateProcess(NtCurrentProcess(), Status);
146 return FALSE;
147 }
148
149 /* Get the server data */
150 ASSERT(Peb->ReadOnlyStaticServerData);
151 BaseStaticServerData = Peb->ReadOnlyStaticServerData[BASESRV_SERVERDLL_INDEX];
152 ASSERT(BaseStaticServerData);
153
154 /* Check if we are running a CSR Server */
155 if (!BaseRunningInServerProcess)
156 {
157 /* Set the termination port for the thread */
158 DPRINT("Creating new thread for CSR\n");
159 CsrNewThread();
160 }
161
162 /* Initialize heap handle table */
163 BaseDllInitializeMemoryManager();
164
165 /* Set HMODULE for our DLL */
166 kernel32_handle = hCurrentModule = hDll;
167
168 /* Set the directories */
169 BaseWindowsDirectory = BaseStaticServerData->WindowsDirectory;
170 BaseWindowsSystemDirectory = BaseStaticServerData->WindowsSystemDirectory;
171
172 /* Construct the default path (using the static buffer) */
173 _snwprintf(BaseDefaultPathBuffer,
174 sizeof(BaseDefaultPathBuffer) / sizeof(WCHAR),
175 L".;%wZ;%wZ\\system;%wZ;",
176 &BaseWindowsSystemDirectory,
177 &BaseWindowsDirectory,
178 &BaseWindowsDirectory);
179
180 BaseDefaultPath.Buffer = BaseDefaultPathBuffer;
181 BaseDefaultPath.Length = wcslen(BaseDefaultPathBuffer) * sizeof(WCHAR);
182 BaseDefaultPath.MaximumLength = sizeof(BaseDefaultPathBuffer);
183
184 /* Use remaining part of the default path buffer for the append path */
185 BaseDefaultPathAppend.Buffer = (PWSTR)((ULONG_PTR)BaseDefaultPathBuffer + BaseDefaultPath.Length);
186 BaseDefaultPathAppend.Length = 0;
187 BaseDefaultPathAppend.MaximumLength = BaseDefaultPath.MaximumLength - BaseDefaultPath.Length;
188
189 /* Initialize command line */
190 InitCommandLines();
191
192 /* Initialize the DLL critical section */
193 RtlInitializeCriticalSection(&BaseDllDirectoryLock);
194
195 /* Initialize the National Language Support routines */
196 if (!NlsInit())
197 {
198 DPRINT1("NLS Init failed\n");
199 return FALSE;
200 }
201
202 /* Initialize Console Support */
203 if (!BasepInitConsole())
204 {
205 DPRINT1("Failed to set up console\n");
206 return FALSE;
207 }
208
209 /* Initialize application certification globals */
210 InitializeListHead(&BasepAppCertDllsList);
211 RtlInitializeCriticalSection(&gcsAppCert);
212
213 /* Insert more dll attach stuff here! */
214 DllInitialized = TRUE;
215 break;
216 }
217
218 case DLL_PROCESS_DETACH:
219 {
220 if (DllInitialized == TRUE)
221 {
222 /* Insert more dll detach stuff here! */
223 NlsUninit();
224
225 /* Uninitialize console support */
226 BasepUninitConsole();
227
228 /* Delete DLL critical section */
229 RtlDeleteCriticalSection(&BaseDllDirectoryLock);
230 }
231 break;
232 }
233
234 default:
235 break;
236 }
237
238 return TRUE;
239 }
240
241 /* EOF */