Merge 14551:14980 from trunk
[reactos.git] / reactos / subsys / win32k / main / dllmain.c
1 /*
2 * ReactOS W32 Subsystem
3 * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 ReactOS Team
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19 /* $Id$
20 *
21 * Entry Point for win32k.sys
22 */
23 #include <w32k.h>
24
25 #define NDEBUG
26 #include <win32k/debug1.h>
27 #include <debug.h>
28
29 #ifdef __USE_W32API
30 typedef NTSTATUS (STDCALL *PW32_PROCESS_CALLBACK)(
31 struct _EPROCESS *Process,
32 BOOLEAN Create);
33
34 typedef NTSTATUS (STDCALL *PW32_THREAD_CALLBACK)(
35 struct _ETHREAD *Thread,
36 BOOLEAN Create);
37
38 /*
39 * Callbacks used for Win32 objects... this define won't be needed after the Object Manager
40 * rewrite -- Alex
41 */
42 typedef NTSTATUS STDCALL_FUNC
43 (*OBJECT_CREATE_ROUTINE)(PVOID ObjectBody,
44 PVOID Parent,
45 PWSTR RemainingPath,
46 struct _OBJECT_ATTRIBUTES* ObjectAttributes);
47
48 typedef NTSTATUS STDCALL_FUNC
49 (*OBJECT_PARSE_ROUTINE)(PVOID Object,
50 PVOID *NextObject,
51 PUNICODE_STRING FullPath,
52 PWSTR *Path,
53 ULONG Attributes);
54
55 typedef VOID STDCALL_FUNC
56 (*OBJECT_DELETE_ROUTINE)(PVOID DeletedObject);
57
58 typedef PVOID STDCALL_FUNC
59 (*OBJECT_FIND_ROUTINE)(PVOID WinStaObject,
60 PWSTR Name,
61 ULONG Attributes);
62
63 typedef struct _W32_OBJECT_CALLBACK {
64 OBJECT_CREATE_ROUTINE WinStaCreate;
65 OBJECT_PARSE_ROUTINE WinStaParse;
66 OBJECT_DELETE_ROUTINE WinStaDelete;
67 OBJECT_FIND_ROUTINE WinStaFind;
68 OBJECT_CREATE_ROUTINE DesktopCreate;
69 OBJECT_DELETE_ROUTINE DesktopDelete;
70 } W32_OBJECT_CALLBACK, *PW32_OBJECT_CALLBACK;
71
72 VOID STDCALL
73 PsEstablishWin32Callouts(
74 PW32_PROCESS_CALLBACK W32ProcessCallback,
75 PW32_THREAD_CALLBACK W32ThreadCallback,
76 PW32_OBJECT_CALLBACK W32ObjectCallback,
77 PVOID Param4,
78 ULONG W32ThreadSize,
79 ULONG W32ProcessSize);
80 #endif
81
82 BOOL INTERNAL_CALL GDI_CleanupForProcess (struct _EPROCESS *Process);
83
84 extern SSDT Win32kSSDT[];
85 extern SSPT Win32kSSPT[];
86 extern ULONG Win32kNumberOfSysCalls;
87
88 PSHARED_SECTION_POOL SessionSharedSectionPool = NULL;
89
90 NTSTATUS STDCALL
91 Win32kProcessCallback (struct _EPROCESS *Process,
92 BOOLEAN Create)
93 {
94 PW32PROCESS Win32Process;
95
96 Win32Process = Process->Win32Process;
97 if (Create)
98 {
99 DPRINT("Creating W32 process PID:%d at IRQ level: %lu\n", Process->UniqueProcessId, KeGetCurrentIrql());
100
101 InitializeListHead(&Win32Process->ClassListHead);
102 ExInitializeFastMutex(&Win32Process->ClassListLock);
103
104 InitializeListHead(&Win32Process->MenuListHead);
105 ExInitializeFastMutex(&Win32Process->MenuListLock);
106
107 InitializeListHead(&Win32Process->PrivateFontListHead);
108 ExInitializeFastMutex(&Win32Process->PrivateFontListLock);
109
110 InitializeListHead(&Win32Process->DriverObjListHead);
111 ExInitializeFastMutex(&Win32Process->DriverObjListLock);
112
113 Win32Process->KeyboardLayout = W32kGetDefaultKeyLayout();
114
115 if(Process->Peb != NULL)
116 {
117 /* map the gdi handle table to user land */
118 Process->Peb->GdiSharedHandleTable = GDI_MapHandleTable(Process);
119 }
120
121 /* setup process flags */
122 Win32Process->Flags = 0;
123 }
124 else
125 {
126 DPRINT("Destroying W32 process PID:%d at IRQ level: %lu\n", Process->UniqueProcessId, KeGetCurrentIrql());
127 IntRemoveProcessWndProcHandles((HANDLE)Process->UniqueProcessId);
128 IntCleanupMenus(Process, Win32Process);
129 IntCleanupCurIcons(Process, Win32Process);
130 IntEngCleanupDriverObjs(Process, Win32Process);
131 CleanupMonitorImpl();
132
133
134 GDI_CleanupForProcess(Process);
135
136 IntGraphicsCheck(FALSE);
137
138 /*
139 * Deregister logon application automatically
140 */
141 if(LogonProcess == Win32Process)
142 {
143 LogonProcess = NULL;
144 }
145 }
146
147 return STATUS_SUCCESS;
148 }
149
150
151 NTSTATUS STDCALL
152 Win32kThreadCallback (struct _ETHREAD *Thread,
153 BOOLEAN Create)
154 {
155 struct _EPROCESS *Process;
156 PW32THREAD Win32Thread;
157
158 Process = Thread->ThreadsProcess;
159 Win32Thread = Thread->Tcb.Win32Thread;
160 if (Create)
161 {
162 HWINSTA hWinSta = NULL;
163 HDESK hDesk = NULL;
164 NTSTATUS Status;
165 PUNICODE_STRING DesktopPath;
166 PRTL_USER_PROCESS_PARAMETERS ProcessParams = (Process->Peb ? Process->Peb->ProcessParameters : NULL);
167
168 DPRINT("Creating W32 thread TID:%d at IRQ level: %lu\n", Thread->Cid.UniqueThread, KeGetCurrentIrql());
169
170 /*
171 * inherit the thread desktop and process window station (if not yet inherited) from the process startup
172 * info structure. See documentation of CreateProcess()
173 */
174 DesktopPath = (ProcessParams ? ((ProcessParams->DesktopInfo.Length > 0) ? &ProcessParams->DesktopInfo : NULL) : NULL);
175 Status = IntParseDesktopPath(Process,
176 DesktopPath,
177 &hWinSta,
178 &hDesk);
179 if(NT_SUCCESS(Status))
180 {
181 if(hWinSta != NULL)
182 {
183 if(Process != CsrProcess)
184 {
185 HWINSTA hProcessWinSta = (HWINSTA)InterlockedCompareExchangePointer((PVOID)&Process->Win32WindowStation, (PVOID)hWinSta, NULL);
186 if(hProcessWinSta != NULL)
187 {
188 /* our process is already assigned to a different window station, we don't need the handle anymore */
189 NtClose(hWinSta);
190 }
191 }
192 else
193 {
194 NtClose(hWinSta);
195 }
196 }
197
198 if (hDesk != NULL)
199 {
200 Status = ObReferenceObjectByHandle(hDesk,
201 0,
202 ExDesktopObjectType,
203 KernelMode,
204 (PVOID*)&Win32Thread->Desktop,
205 NULL);
206 NtClose(hDesk);
207 if(!NT_SUCCESS(Status))
208 {
209 DPRINT1("Unable to reference thread desktop handle 0x%x\n", hDesk);
210 Win32Thread->Desktop = NULL;
211 }
212 }
213 }
214 Win32Thread->IsExiting = FALSE;
215 IntDestroyCaret(Win32Thread);
216 Win32Thread->MessageQueue = MsqCreateMessageQueue(Thread);
217 Win32Thread->KeyboardLayout = W32kGetDefaultKeyLayout();
218 Win32Thread->MessagePumpHookValue = 0;
219 InitializeListHead(&Win32Thread->WindowListHead);
220 ExInitializeFastMutex(&Win32Thread->WindowListLock);
221 InitializeListHead(&Win32Thread->W32CallbackListHead);
222 }
223 else
224 {
225 DPRINT("Destroying W32 thread TID:%d at IRQ level: %lu\n", Thread->Cid.UniqueThread, KeGetCurrentIrql());
226
227 Win32Thread->IsExiting = TRUE;
228 HOOK_DestroyThreadHooks(Thread);
229 UnregisterThreadHotKeys(Thread);
230 DestroyThreadWindows(Thread);
231 IntBlockInput(Win32Thread, FALSE);
232 MsqDestroyMessageQueue(Win32Thread->MessageQueue);
233 IntCleanupThreadCallbacks(Win32Thread);
234 if(Win32Thread->Desktop != NULL)
235 {
236 ObDereferenceObject(Win32Thread->Desktop);
237 }
238 }
239
240 return STATUS_SUCCESS;
241 }
242
243
244 NTSTATUS STDCALL
245 DriverEntry (
246 IN PDRIVER_OBJECT DriverObject,
247 IN PUNICODE_STRING RegistryPath)
248 {
249 NTSTATUS Status;
250 BOOLEAN Result;
251 W32_OBJECT_CALLBACK Win32kObjectCallbacks;
252
253 /*
254 * Register user mode call interface
255 * (system service table index = 1)
256 */
257 Result = KeAddSystemServiceTable (Win32kSSDT,
258 NULL,
259 Win32kNumberOfSysCalls,
260 Win32kSSPT,
261 1);
262 if (Result == FALSE)
263 {
264 DPRINT1("Adding system services failed!\n");
265 return STATUS_UNSUCCESSFUL;
266 }
267
268 /*
269 * Register Object Manager Callbacks
270 */
271 Win32kObjectCallbacks.WinStaCreate = IntWinStaObjectCreate;
272 Win32kObjectCallbacks.WinStaParse = IntWinStaObjectParse;
273 Win32kObjectCallbacks.WinStaDelete = IntWinStaObjectDelete;
274 Win32kObjectCallbacks.WinStaFind = IntWinStaObjectFind;
275 Win32kObjectCallbacks.DesktopCreate = IntDesktopObjectCreate;
276 Win32kObjectCallbacks.DesktopDelete = IntDesktopObjectDelete;
277 /*
278 * Register our per-process and per-thread structures.
279 */
280 PsEstablishWin32Callouts (Win32kProcessCallback,
281 Win32kThreadCallback,
282 &Win32kObjectCallbacks,
283 0,
284 sizeof(W32THREAD),
285 sizeof(W32PROCESS));
286
287 Status = IntUserCreateSharedSectionPool(48 * 1024 * 1024, /* 48 MB by default */
288 &SessionSharedSectionPool);
289 if (!NT_SUCCESS(Status))
290 {
291 DPRINT1("Failed to initialize the shared section pool: Status 0x%x\n", Status);
292 }
293
294 Status = InitWindowStationImpl();
295 if (!NT_SUCCESS(Status))
296 {
297 DPRINT1("Failed to initialize window station implementation!\n");
298 return STATUS_UNSUCCESSFUL;
299 }
300
301 Status = InitClassImpl();
302 if (!NT_SUCCESS(Status))
303 {
304 DPRINT1("Failed to initialize window class implementation!\n");
305 return STATUS_UNSUCCESSFUL;
306 }
307
308 Status = InitDesktopImpl();
309 if (!NT_SUCCESS(Status))
310 {
311 DPRINT1("Failed to initialize desktop implementation!\n");
312 return STATUS_UNSUCCESSFUL;
313 }
314
315 Status = InitWindowImpl();
316 if (!NT_SUCCESS(Status))
317 {
318 DPRINT1("Failed to initialize window implementation!\n");
319 return STATUS_UNSUCCESSFUL;
320 }
321
322 Status = InitMenuImpl();
323 if (!NT_SUCCESS(Status))
324 {
325 DPRINT1("Failed to initialize menu implementation!\n");
326 return STATUS_UNSUCCESSFUL;
327 }
328
329 Status = InitInputImpl();
330 if (!NT_SUCCESS(Status))
331 {
332 DPRINT1("Failed to initialize input implementation.\n");
333 return(Status);
334 }
335
336 Status = InitKeyboardImpl();
337 if (!NT_SUCCESS(Status))
338 {
339 DPRINT1("Failed to initialize keyboard implementation.\n");
340 return(Status);
341 }
342
343 Status = InitMonitorImpl();
344 if (!NT_SUCCESS(Status))
345 {
346 DbgPrint("Failed to initialize monitor implementation!\n");
347 return STATUS_UNSUCCESSFUL;
348 }
349
350 Status = MsqInitializeImpl();
351 if (!NT_SUCCESS(Status))
352 {
353 DPRINT1("Failed to initialize message queue implementation.\n");
354 return(Status);
355 }
356
357 Status = InitTimerImpl();
358 if (!NT_SUCCESS(Status))
359 {
360 DPRINT1("Failed to initialize timer implementation.\n");
361 return(Status);
362 }
363
364 Status = InitAcceleratorImpl();
365 if (!NT_SUCCESS(Status))
366 {
367 DPRINT1("Failed to initialize accelerator implementation.\n");
368 return(Status);
369 }
370
371 Status = InitGuiCheckImpl();
372 if (!NT_SUCCESS(Status))
373 {
374 DPRINT1("Failed to initialize GUI check implementation.\n");
375 return(Status);
376 }
377
378 InitGdiObjectHandleTable ();
379
380 /* Initialize FreeType library */
381 if (! InitFontSupport())
382 {
383 DPRINT1("Unable to initialize font support\n");
384 return STATUS_UNSUCCESSFUL;
385 }
386
387 /* Create stock objects, ie. precreated objects commonly
388 used by win32 applications */
389 CreateStockObjects();
390 CreateSysColorObjects();
391
392 return STATUS_SUCCESS;
393 }
394
395
396 BOOLEAN STDCALL
397 Win32kInitialize (VOID)
398 {
399 return TRUE;
400 }
401
402 /* EOF */