[INTRIN]
[reactos.git] / reactos / win32ss / base / 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 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 intially */
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 /* Don't bother us for each thread */
114 LdrDisableThreadCalloutsForDll((PVOID)hDll);
115
116 /* Initialize default path to NULL */
117 RtlInitUnicodeString(&BaseDefaultPath, NULL);
118
119 /* Setup the Object Directory path */
120 if (!SessionId)
121 {
122 /* Use the raw path */
123 wcscpy(SessionDir, WIN_OBJ_DIR);
124 }
125 else
126 {
127 /* Use the session path */
128 swprintf(SessionDir,
129 L"%ws\\%ld%ws",
130 SESSION_DIR,
131 SessionId,
132 WIN_OBJ_DIR);
133 }
134
135 /* Connect to the Base Server */
136 Status = CsrClientConnectToServer(SessionDir,
137 BASESRV_SERVERDLL_INDEX,
138 &ConnectInfo,
139 &ConnectInfoSize,
140 &BaseRunningInServerProcess);
141 if (!NT_SUCCESS(Status))
142 {
143 DPRINT1("Failed to connect to CSR (Status %lx)\n", Status);
144 NtTerminateProcess(NtCurrentProcess(), Status);
145 return FALSE;
146 }
147
148 /* Get the server data */
149 ASSERT(Peb->ReadOnlyStaticServerData);
150 BaseStaticServerData = Peb->ReadOnlyStaticServerData[BASESRV_SERVERDLL_INDEX];
151 ASSERT(BaseStaticServerData);
152
153 /* Check if we are running a CSR Server */
154 if (!BaseRunningInServerProcess)
155 {
156 /* Set the termination port for the thread */
157 DPRINT("Creating new thread for CSR\n");
158 CsrNewThread();
159 }
160
161 /* Initialize heap handle table */
162 BaseDllInitializeMemoryManager();
163
164 /* Set HMODULE for our DLL */
165 kernel32_handle = hCurrentModule = hDll;
166
167 /* Set the directories */
168 BaseWindowsDirectory = BaseStaticServerData->WindowsDirectory;
169 BaseWindowsSystemDirectory = BaseStaticServerData->WindowsSystemDirectory;
170
171 /* Construct the default path (using the static buffer) */
172 _snwprintf(BaseDefaultPathBuffer,
173 sizeof(BaseDefaultPathBuffer) / sizeof(WCHAR),
174 L".;%wZ;%wZ\\system;%wZ;",
175 &BaseWindowsSystemDirectory,
176 &BaseWindowsDirectory,
177 &BaseWindowsDirectory);
178
179 BaseDefaultPath.Buffer = BaseDefaultPathBuffer;
180 BaseDefaultPath.Length = wcslen(BaseDefaultPathBuffer) * sizeof(WCHAR);
181 BaseDefaultPath.MaximumLength = sizeof(BaseDefaultPathBuffer);
182
183 /* Use remaining part of the default path buffer for the append path */
184 BaseDefaultPathAppend.Buffer = (PWSTR)((ULONG_PTR)BaseDefaultPathBuffer + BaseDefaultPath.Length);
185 BaseDefaultPathAppend.Length = 0;
186 BaseDefaultPathAppend.MaximumLength = BaseDefaultPath.MaximumLength - BaseDefaultPath.Length;
187
188 /* Initialize command line */
189 InitCommandLines();
190
191 /* Initialize the DLL critical section */
192 RtlInitializeCriticalSection(&BaseDllDirectoryLock);
193
194 /* Initialize the National Language Support routines */
195 if (!NlsInit())
196 {
197 DPRINT1("NLS Init failed\n");
198 return FALSE;
199 }
200
201 /* Initialize Console Support */
202 if (!ConDllInitialize(dwReason, SessionDir))
203 {
204 DPRINT1("Failed to set up console\n");
205 return FALSE;
206 }
207
208 /* Initialize application certification globals */
209 InitializeListHead(&BasepAppCertDllsList);
210 RtlInitializeCriticalSection(&gcsAppCert);
211
212 /* Insert more dll attach stuff here! */
213 DllInitialized = TRUE;
214 break;
215 }
216
217 case DLL_PROCESS_DETACH:
218 {
219 if (DllInitialized == TRUE)
220 {
221 /* Uninitialize console support */
222 ConDllInitialize(dwReason, NULL);
223
224 /* Insert more dll detach stuff here! */
225 NlsUninit();
226
227 /* Delete DLL critical section */
228 RtlDeleteCriticalSection(&BaseDllDirectoryLock);
229 }
230 break;
231 }
232
233 case DLL_THREAD_ATTACH:
234 {
235 /* ConDllInitialize sets the current console locale for the new thread */
236 return ConDllInitialize(dwReason, NULL);
237 }
238
239 default:
240 break;
241 }
242
243 return TRUE;
244 }
245
246 /* EOF */