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