Removed incorrect Create/DuplicationNotify callbacks and replaced by a more correct...
[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
43 /* TEMPORARY HACK */
44 typedef NTSTATUS STDCALL_FUNC
45 (*OBJECT_CREATE_ROUTINE)(PVOID ObjectBody,
46 PVOID Parent,
47 PWSTR RemainingPath,
48 struct _OBJECT_ATTRIBUTES* ObjectAttributes);
49
50 typedef NTSTATUS STDCALL_FUNC
51 (*OBJECT_OPEN_ROUTINE)(ULONG Reason,
52 PVOID ObjectBody,
53 PEPROCESS Process,
54 ULONG HandleCount,
55 ACCESS_MASK GrantedAccess);
56
57 typedef NTSTATUS STDCALL_FUNC
58 (*OBJECT_PARSE_ROUTINE)(PVOID Object,
59 PVOID *NextObject,
60 PUNICODE_STRING FullPath,
61 PWSTR *Path,
62 ULONG Attributes);
63
64 typedef VOID STDCALL_FUNC
65 (*OBJECT_DELETE_ROUTINE)(PVOID DeletedObject);
66
67 typedef PVOID STDCALL_FUNC
68 (*OBJECT_FIND_ROUTINE)(PVOID WinStaObject,
69 PWSTR Name,
70 ULONG Attributes);
71
72 typedef struct _W32_OBJECT_CALLBACK {
73 OBJECT_OPEN_ROUTINE WinStaCreate;
74 OBJECT_PARSE_ROUTINE WinStaParse;
75 OBJECT_DELETE_ROUTINE WinStaDelete;
76 OBJECT_FIND_ROUTINE WinStaFind;
77 OBJECT_CREATE_ROUTINE DesktopCreate;
78 OBJECT_DELETE_ROUTINE DesktopDelete;
79 } W32_OBJECT_CALLBACK, *PW32_OBJECT_CALLBACK;
80
81 VOID STDCALL
82 PsEstablishWin32Callouts(
83 PW32_PROCESS_CALLBACK W32ProcessCallback,
84 PW32_THREAD_CALLBACK W32ThreadCallback,
85 PW32_OBJECT_CALLBACK W32ObjectCallback,
86 PVOID Param4,
87 ULONG W32ThreadSize,
88 ULONG W32ProcessSize);
89 #endif
90
91 BOOL INTERNAL_CALL GDI_CleanupForProcess (struct _EPROCESS *Process);
92
93 extern SSDT Win32kSSDT[];
94 extern SSPT Win32kSSPT[];
95 extern ULONG Win32kNumberOfSysCalls;
96
97 PSHARED_SECTION_POOL SessionSharedSectionPool = NULL;
98
99 NTSTATUS STDCALL
100 Win32kProcessCallback (struct _EPROCESS *Process,
101 BOOLEAN Create)
102 {
103 PW32PROCESS Win32Process;
104
105 Win32Process = (PW32PROCESS)Process->Win32Process;
106 if (Create)
107 {
108 DPRINT("Creating W32 process PID:%d at IRQ level: %lu\n", Process->UniqueProcessId, KeGetCurrentIrql());
109
110 InitializeListHead(&Win32Process->ClassListHead);
111 ExInitializeFastMutex(&Win32Process->ClassListLock);
112
113 InitializeListHead(&Win32Process->MenuListHead);
114 ExInitializeFastMutex(&Win32Process->MenuListLock);
115
116 InitializeListHead(&Win32Process->PrivateFontListHead);
117 ExInitializeFastMutex(&Win32Process->PrivateFontListLock);
118
119 InitializeListHead(&Win32Process->DriverObjListHead);
120 ExInitializeFastMutex(&Win32Process->DriverObjListLock);
121
122 Win32Process->KeyboardLayout = W32kGetDefaultKeyLayout();
123
124 if(Process->Peb != NULL)
125 {
126 /* map the gdi handle table to user land */
127 Process->Peb->GdiSharedHandleTable = GDI_MapHandleTable(Process);
128 }
129
130 /* setup process flags */
131 Win32Process->Flags = 0;
132 }
133 else
134 {
135 DPRINT("Destroying W32 process PID:%d at IRQ level: %lu\n", Process->UniqueProcessId, KeGetCurrentIrql());
136 IntRemoveProcessWndProcHandles((HANDLE)Process->UniqueProcessId);
137 IntCleanupMenus(Process, Win32Process);
138 IntCleanupCurIcons(Process, Win32Process);
139 IntEngCleanupDriverObjs(Process, Win32Process);
140 CleanupMonitorImpl();
141
142
143 GDI_CleanupForProcess(Process);
144
145 IntGraphicsCheck(FALSE);
146
147 /*
148 * Deregister logon application automatically
149 */
150 if(LogonProcess == Win32Process)
151 {
152 LogonProcess = NULL;
153 }
154 }
155
156 return STATUS_SUCCESS;
157 }
158
159
160 NTSTATUS STDCALL
161 Win32kThreadCallback (struct _ETHREAD *Thread,
162 BOOLEAN Create)
163 {
164 struct _EPROCESS *Process;
165 PW32THREAD Win32Thread;
166
167 Process = Thread->ThreadsProcess;
168 Win32Thread = Thread->Tcb.Win32Thread;
169 if (Create)
170 {
171 HWINSTA hWinSta = NULL;
172 HDESK hDesk = NULL;
173 NTSTATUS Status;
174 PUNICODE_STRING DesktopPath;
175 PRTL_USER_PROCESS_PARAMETERS ProcessParams = (Process->Peb ? Process->Peb->ProcessParameters : NULL);
176
177 DPRINT("Creating W32 thread TID:%d at IRQ level: %lu\n", Thread->Cid.UniqueThread, KeGetCurrentIrql());
178
179 /*
180 * inherit the thread desktop and process window station (if not yet inherited) from the process startup
181 * info structure. See documentation of CreateProcess()
182 */
183 DesktopPath = (ProcessParams ? ((ProcessParams->DesktopInfo.Length > 0) ? &ProcessParams->DesktopInfo : NULL) : NULL);
184 Status = IntParseDesktopPath(Process,
185 DesktopPath,
186 &hWinSta,
187 &hDesk);
188 if(NT_SUCCESS(Status))
189 {
190 if(hWinSta != NULL)
191 {
192 if(Process != CsrProcess)
193 {
194 HWINSTA hProcessWinSta = (HWINSTA)InterlockedCompareExchangePointer((PVOID)&Process->Win32WindowStation, (PVOID)hWinSta, NULL);
195 if(hProcessWinSta != NULL)
196 {
197 /* our process is already assigned to a different window station, we don't need the handle anymore */
198 NtClose(hWinSta);
199 }
200 }
201 else
202 {
203 NtClose(hWinSta);
204 }
205 }
206
207 if (hDesk != NULL)
208 {
209 Status = ObReferenceObjectByHandle(hDesk,
210 0,
211 ExDesktopObjectType,
212 KernelMode,
213 (PVOID*)&Win32Thread->Desktop,
214 NULL);
215 NtClose(hDesk);
216 if(!NT_SUCCESS(Status))
217 {
218 DPRINT1("Unable to reference thread desktop handle 0x%x\n", hDesk);
219 Win32Thread->Desktop = NULL;
220 }
221 }
222 }
223 Win32Thread->IsExiting = FALSE;
224 IntDestroyCaret(Win32Thread);
225 Win32Thread->MessageQueue = MsqCreateMessageQueue(Thread);
226 Win32Thread->KeyboardLayout = W32kGetDefaultKeyLayout();
227 Win32Thread->MessagePumpHookValue = 0;
228 InitializeListHead(&Win32Thread->WindowListHead);
229 ExInitializeFastMutex(&Win32Thread->WindowListLock);
230 InitializeListHead(&Win32Thread->W32CallbackListHead);
231 }
232 else
233 {
234 DPRINT("Destroying W32 thread TID:%d at IRQ level: %lu\n", Thread->Cid.UniqueThread, KeGetCurrentIrql());
235
236 Win32Thread->IsExiting = TRUE;
237 HOOK_DestroyThreadHooks(Thread);
238 UnregisterThreadHotKeys(Thread);
239 DestroyThreadWindows(Thread);
240 IntBlockInput(Win32Thread, FALSE);
241 MsqDestroyMessageQueue(Win32Thread->MessageQueue);
242 IntCleanupThreadCallbacks(Win32Thread);
243 if(Win32Thread->Desktop != NULL)
244 {
245 ObDereferenceObject(Win32Thread->Desktop);
246 }
247 }
248
249 return STATUS_SUCCESS;
250 }
251
252 /* Only used in ntuser/input.c KeyboardThreadMain(). If it's
253 not called there anymore, please delete */
254 NTSTATUS
255 Win32kInitWin32Thread(PETHREAD Thread)
256 {
257 PEPROCESS Process;
258
259 Process = Thread->ThreadsProcess;
260
261 if (Process->Win32Process == NULL)
262 {
263 /* FIXME - lock the process */
264 Process->Win32Process = ExAllocatePool(NonPagedPool, sizeof(W32PROCESS));
265
266 if (Process->Win32Process == NULL)
267 return STATUS_NO_MEMORY;
268
269 RtlZeroMemory(Process->Win32Process, sizeof(W32PROCESS));
270 /* FIXME - unlock the process */
271
272 Win32kProcessCallback(Process, TRUE);
273 }
274
275 if (Thread->Tcb.Win32Thread == NULL)
276 {
277 Thread->Tcb.Win32Thread = ExAllocatePool (NonPagedPool, sizeof(W32THREAD));
278 if (Thread->Tcb.Win32Thread == NULL)
279 return STATUS_NO_MEMORY;
280
281 RtlZeroMemory(Thread->Tcb.Win32Thread, sizeof(W32THREAD));
282
283 Win32kThreadCallback(Thread, TRUE);
284 }
285
286 return(STATUS_SUCCESS);
287 }
288
289
290 /*
291 * This definition doesn't work
292 */
293 // BOOL STDCALL DllMain(VOID)
294 NTSTATUS STDCALL
295 DllMain (
296 IN PDRIVER_OBJECT DriverObject,
297 IN PUNICODE_STRING RegistryPath)
298 {
299 NTSTATUS Status;
300 BOOLEAN Result;
301 W32_OBJECT_CALLBACK Win32kObjectCallbacks;
302
303 /*
304 * Register user mode call interface
305 * (system service table index = 1)
306 */
307 Result = KeAddSystemServiceTable (Win32kSSDT,
308 NULL,
309 Win32kNumberOfSysCalls,
310 Win32kSSPT,
311 1);
312 if (Result == FALSE)
313 {
314 DPRINT1("Adding system services failed!\n");
315 return STATUS_UNSUCCESSFUL;
316 }
317
318 /*
319 * Register Object Manager Callbacks
320 */
321 Win32kObjectCallbacks.WinStaCreate = IntWinStaObjectOpen;
322 Win32kObjectCallbacks.WinStaParse = IntWinStaObjectParse;
323 Win32kObjectCallbacks.WinStaDelete = IntWinStaObjectDelete;
324 Win32kObjectCallbacks.WinStaFind = IntWinStaObjectFind;
325 Win32kObjectCallbacks.DesktopCreate = IntDesktopObjectCreate;
326 Win32kObjectCallbacks.DesktopDelete = IntDesktopObjectDelete;
327 /*
328 * Register our per-process and per-thread structures.
329 */
330 PsEstablishWin32Callouts (Win32kProcessCallback,
331 Win32kThreadCallback,
332 &Win32kObjectCallbacks,
333 0,
334 sizeof(W32THREAD),
335 sizeof(W32PROCESS));
336
337 Status = IntUserCreateSharedSectionPool(48 * 1024 * 1024, /* 48 MB by default */
338 &SessionSharedSectionPool);
339 if (!NT_SUCCESS(Status))
340 {
341 DPRINT1("Failed to initialize the shared section pool: Status 0x%x\n", Status);
342 }
343
344 Status = InitWindowStationImpl();
345 if (!NT_SUCCESS(Status))
346 {
347 DPRINT1("Failed to initialize window station implementation!\n");
348 return STATUS_UNSUCCESSFUL;
349 }
350
351 Status = InitClassImpl();
352 if (!NT_SUCCESS(Status))
353 {
354 DPRINT1("Failed to initialize window class implementation!\n");
355 return STATUS_UNSUCCESSFUL;
356 }
357
358 Status = InitDesktopImpl();
359 if (!NT_SUCCESS(Status))
360 {
361 DPRINT1("Failed to initialize desktop implementation!\n");
362 return STATUS_UNSUCCESSFUL;
363 }
364
365 Status = InitWindowImpl();
366 if (!NT_SUCCESS(Status))
367 {
368 DPRINT1("Failed to initialize window implementation!\n");
369 return STATUS_UNSUCCESSFUL;
370 }
371
372 Status = InitMenuImpl();
373 if (!NT_SUCCESS(Status))
374 {
375 DPRINT1("Failed to initialize menu implementation!\n");
376 return STATUS_UNSUCCESSFUL;
377 }
378
379 Status = InitInputImpl();
380 if (!NT_SUCCESS(Status))
381 {
382 DPRINT1("Failed to initialize input implementation.\n");
383 return(Status);
384 }
385
386 Status = InitKeyboardImpl();
387 if (!NT_SUCCESS(Status))
388 {
389 DPRINT1("Failed to initialize keyboard implementation.\n");
390 return(Status);
391 }
392
393 Status = InitMonitorImpl();
394 if (!NT_SUCCESS(Status))
395 {
396 DbgPrint("Failed to initialize monitor implementation!\n");
397 return STATUS_UNSUCCESSFUL;
398 }
399
400 Status = MsqInitializeImpl();
401 if (!NT_SUCCESS(Status))
402 {
403 DPRINT1("Failed to initialize message queue implementation.\n");
404 return(Status);
405 }
406
407 Status = InitTimerImpl();
408 if (!NT_SUCCESS(Status))
409 {
410 DPRINT1("Failed to initialize timer implementation.\n");
411 return(Status);
412 }
413
414 Status = InitAcceleratorImpl();
415 if (!NT_SUCCESS(Status))
416 {
417 DPRINT1("Failed to initialize accelerator implementation.\n");
418 return(Status);
419 }
420
421 Status = InitGuiCheckImpl();
422 if (!NT_SUCCESS(Status))
423 {
424 DPRINT1("Failed to initialize GUI check implementation.\n");
425 return(Status);
426 }
427
428 InitGdiObjectHandleTable ();
429
430 /* Initialize FreeType library */
431 if (! InitFontSupport())
432 {
433 DPRINT1("Unable to initialize font support\n");
434 return STATUS_UNSUCCESSFUL;
435 }
436
437 /* Create stock objects, ie. precreated objects commonly
438 used by win32 applications */
439 CreateStockObjects();
440 CreateSysColorObjects();
441
442 PREPARE_TESTS
443
444 return STATUS_SUCCESS;
445 }
446
447
448 BOOLEAN STDCALL
449 Win32kInitialize (VOID)
450 {
451 return TRUE;
452 }
453
454 /* EOF */