Merge 13159:13510 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 VOID STDCALL
39 PsEstablishWin32Callouts(
40 PW32_PROCESS_CALLBACK W32ProcessCallback,
41 PW32_THREAD_CALLBACK W32ThreadCallback,
42 PVOID Param3,
43 PVOID Param4,
44 ULONG W32ThreadSize,
45 ULONG W32ProcessSize);
46 #endif
47
48 BOOL INTERNAL_CALL GDI_CleanupForProcess (struct _EPROCESS *Process);
49
50 extern SSDT Win32kSSDT[];
51 extern SSPT Win32kSSPT[];
52 extern ULONG Win32kNumberOfSysCalls;
53
54 NTSTATUS STDCALL
55 Win32kProcessCallback (struct _EPROCESS *Process,
56 BOOLEAN Create)
57 {
58 PW32PROCESS Win32Process;
59
60 Win32Process = Process->Win32Process;
61 if (Create)
62 {
63 DPRINT("Creating W32 process PID:%d at IRQ level: %lu\n", Process->UniqueProcessId, KeGetCurrentIrql());
64
65 InitializeListHead(&Win32Process->ClassListHead);
66 ExInitializeFastMutex(&Win32Process->ClassListLock);
67
68 InitializeListHead(&Win32Process->MenuListHead);
69 ExInitializeFastMutex(&Win32Process->MenuListLock);
70
71 InitializeListHead(&Win32Process->PrivateFontListHead);
72 ExInitializeFastMutex(&Win32Process->PrivateFontListLock);
73
74 InitializeListHead(&Win32Process->DriverObjListHead);
75 ExInitializeFastMutex(&Win32Process->DriverObjListLock);
76
77 Win32Process->KeyboardLayout = W32kGetDefaultKeyLayout();
78
79 /* setup process flags */
80 Win32Process->Flags = 0;
81 }
82 else
83 {
84 DPRINT("Destroying W32 process PID:%d at IRQ level: %lu\n", Process->UniqueProcessId, KeGetCurrentIrql());
85 IntRemoveProcessWndProcHandles((HANDLE)Process->UniqueProcessId);
86 IntCleanupMenus(Process, Win32Process);
87 IntCleanupCurIcons(Process, Win32Process);
88 IntEngCleanupDriverObjs(Process, Win32Process);
89 CleanupMonitorImpl();
90
91
92 GDI_CleanupForProcess(Process);
93
94 IntGraphicsCheck(FALSE);
95
96 /*
97 * Deregister logon application automatically
98 */
99 if(LogonProcess == Win32Process)
100 {
101 LogonProcess = NULL;
102 }
103 }
104
105 return STATUS_SUCCESS;
106 }
107
108
109 NTSTATUS STDCALL
110 Win32kThreadCallback (struct _ETHREAD *Thread,
111 BOOLEAN Create)
112 {
113 struct _EPROCESS *Process;
114 PW32THREAD Win32Thread;
115
116 Process = Thread->ThreadsProcess;
117 Win32Thread = Thread->Tcb.Win32Thread;
118 if (Create)
119 {
120 HWINSTA hWinSta = NULL;
121 HDESK hDesk = NULL;
122 NTSTATUS Status;
123 PUNICODE_STRING DesktopPath;
124 PRTL_USER_PROCESS_PARAMETERS ProcessParams = (Process->Peb ? Process->Peb->ProcessParameters : NULL);
125
126 DPRINT("Creating W32 thread TID:%d at IRQ level: %lu\n", Thread->Cid.UniqueThread, KeGetCurrentIrql());
127
128 /*
129 * inherit the thread desktop and process window station (if not yet inherited) from the process startup
130 * info structure. See documentation of CreateProcess()
131 */
132 DesktopPath = (ProcessParams ? ((ProcessParams->DesktopInfo.Length > 0) ? &ProcessParams->DesktopInfo : NULL) : NULL);
133 Status = IntParseDesktopPath(Process,
134 DesktopPath,
135 &hWinSta,
136 &hDesk);
137 if(NT_SUCCESS(Status))
138 {
139 if(hWinSta != NULL)
140 {
141 if(Process != CsrProcess)
142 {
143 HWINSTA hProcessWinSta = (HWINSTA)InterlockedCompareExchangePointer((PVOID)&Process->Win32WindowStation, (PVOID)hWinSta, NULL);
144 if(hProcessWinSta != NULL)
145 {
146 /* our process is already assigned to a different window station, we don't need the handle anymore */
147 NtClose(hWinSta);
148 }
149 }
150 else
151 {
152 NtClose(hWinSta);
153 }
154 }
155
156 Win32Thread->hDesktop = hDesk;
157
158 Status = ObReferenceObjectByHandle(hDesk,
159 0,
160 ExDesktopObjectType,
161 KernelMode,
162 (PVOID*)&Win32Thread->Desktop,
163 NULL);
164
165 if(!NT_SUCCESS(Status))
166 {
167 DPRINT1("Unable to reference thread desktop handle 0x%x\n", hDesk);
168 Win32Thread->Desktop = NULL;
169 NtClose(hDesk);
170 }
171 }
172
173 Win32Thread->IsExiting = FALSE;
174 IntDestroyCaret(Win32Thread);
175 Win32Thread->MessageQueue = MsqCreateMessageQueue(Thread);
176 Win32Thread->KeyboardLayout = W32kGetDefaultKeyLayout();
177 Win32Thread->MessagePumpHookValue = 0;
178 InitializeListHead(&Win32Thread->WindowListHead);
179 ExInitializeFastMutex(&Win32Thread->WindowListLock);
180 InitializeListHead(&Win32Thread->W32CallbackListHead);
181 ExInitializeFastMutex(&Win32Thread->W32CallbackListLock);
182 }
183 else
184 {
185 DPRINT("Destroying W32 thread TID:%d at IRQ level: %lu\n", Thread->Cid.UniqueThread, KeGetCurrentIrql());
186
187 Win32Thread->IsExiting = TRUE;
188 HOOK_DestroyThreadHooks(Thread);
189 UnregisterThreadHotKeys(Thread);
190 DestroyThreadWindows(Thread);
191 IntBlockInput(Win32Thread, FALSE);
192 MsqDestroyMessageQueue(Win32Thread->MessageQueue);
193 IntCleanupThreadCallbacks(Win32Thread);
194 if(Win32Thread->Desktop != NULL)
195 {
196 ObDereferenceObject(Win32Thread->Desktop);
197 }
198 }
199
200 return STATUS_SUCCESS;
201 }
202
203
204 NTSTATUS STDCALL
205 DriverEntry (
206 IN PDRIVER_OBJECT DriverObject,
207 IN PUNICODE_STRING RegistryPath)
208 {
209 NTSTATUS Status;
210 BOOLEAN Result;
211
212 /*
213 * Register user mode call interface
214 * (system service table index = 1)
215 */
216 Result = KeAddSystemServiceTable (Win32kSSDT,
217 NULL,
218 Win32kNumberOfSysCalls,
219 Win32kSSPT,
220 1);
221 if (Result == FALSE)
222 {
223 DPRINT1("Adding system services failed!\n");
224 return STATUS_UNSUCCESSFUL;
225 }
226
227 /*
228 * Register our per-process and per-thread structures.
229 */
230 PsEstablishWin32Callouts (Win32kProcessCallback,
231 Win32kThreadCallback,
232 0,
233 0,
234 sizeof(W32THREAD),
235 sizeof(W32PROCESS));
236
237 Status = InitWindowStationImpl();
238 if (!NT_SUCCESS(Status))
239 {
240 DPRINT1("Failed to initialize window station implementation!\n");
241 return STATUS_UNSUCCESSFUL;
242 }
243
244 Status = InitClassImpl();
245 if (!NT_SUCCESS(Status))
246 {
247 DPRINT1("Failed to initialize window class implementation!\n");
248 return STATUS_UNSUCCESSFUL;
249 }
250
251 Status = InitDesktopImpl();
252 if (!NT_SUCCESS(Status))
253 {
254 DPRINT1("Failed to initialize desktop implementation!\n");
255 return STATUS_UNSUCCESSFUL;
256 }
257
258 Status = InitWindowImpl();
259 if (!NT_SUCCESS(Status))
260 {
261 DPRINT1("Failed to initialize window implementation!\n");
262 return STATUS_UNSUCCESSFUL;
263 }
264
265 Status = InitMenuImpl();
266 if (!NT_SUCCESS(Status))
267 {
268 DPRINT1("Failed to initialize menu implementation!\n");
269 return STATUS_UNSUCCESSFUL;
270 }
271
272 Status = InitInputImpl();
273 if (!NT_SUCCESS(Status))
274 {
275 DPRINT1("Failed to initialize input implementation.\n");
276 return(Status);
277 }
278
279 Status = InitKeyboardImpl();
280 if (!NT_SUCCESS(Status))
281 {
282 DPRINT1("Failed to initialize keyboard implementation.\n");
283 return(Status);
284 }
285
286 Status = InitMonitorImpl();
287 if (!NT_SUCCESS(Status))
288 {
289 DbgPrint("Failed to initialize monitor implementation!\n");
290 return STATUS_UNSUCCESSFUL;
291 }
292
293 Status = MsqInitializeImpl();
294 if (!NT_SUCCESS(Status))
295 {
296 DPRINT1("Failed to initialize message queue implementation.\n");
297 return(Status);
298 }
299
300 Status = InitTimerImpl();
301 if (!NT_SUCCESS(Status))
302 {
303 DPRINT1("Failed to initialize timer implementation.\n");
304 return(Status);
305 }
306
307 Status = InitAcceleratorImpl();
308 if (!NT_SUCCESS(Status))
309 {
310 DPRINT1("Failed to initialize accelerator implementation.\n");
311 return(Status);
312 }
313
314 Status = InitGuiCheckImpl();
315 if (!NT_SUCCESS(Status))
316 {
317 DPRINT1("Failed to initialize GUI check implementation.\n");
318 return(Status);
319 }
320
321 InitGdiObjectHandleTable ();
322
323 /* Initialize FreeType library */
324 if (! InitFontSupport())
325 {
326 DPRINT1("Unable to initialize font support\n");
327 return STATUS_UNSUCCESSFUL;
328 }
329
330 /* Create stock objects, ie. precreated objects commonly
331 used by win32 applications */
332 CreateStockObjects();
333 CreateSysColorObjects();
334
335 return STATUS_SUCCESS;
336 }
337
338
339 BOOLEAN STDCALL
340 Win32kInitialize (VOID)
341 {
342 return TRUE;
343 }
344
345 /* EOF */