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