1. added basic reference counting for message queues
[reactos.git] / reactos / subsys / win32k / main / dllmain.c
1 /*
2 * ReactOS W32 Subsystem
3 * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 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: dllmain.c,v 1.75 2004/05/22 16:48:50 weiden Exp $
20 *
21 * Entry Point for win32k.sys
22 */
23 #include <w32k.h>
24 #include <roscfg.h>
25
26 #ifdef __USE_W32API
27 typedef NTSTATUS (STDCALL *PW32_PROCESS_CALLBACK)(
28 struct _EPROCESS *Process,
29 BOOLEAN Create);
30
31 typedef NTSTATUS (STDCALL *PW32_THREAD_CALLBACK)(
32 struct _ETHREAD *Thread,
33 BOOLEAN Create);
34
35 VOID STDCALL
36 PsEstablishWin32Callouts(
37 PW32_PROCESS_CALLBACK W32ProcessCallback,
38 PW32_THREAD_CALLBACK W32ThreadCallback,
39 PVOID Param3,
40 PVOID Param4,
41 ULONG W32ThreadSize,
42 ULONG W32ProcessSize);
43 #endif
44
45 extern SSDT Win32kSSDT[];
46 extern SSPT Win32kSSPT[];
47 extern ULONG Win32kNumberOfSysCalls;
48
49 NTSTATUS STDCALL
50 Win32kProcessCallback (struct _EPROCESS *Process,
51 BOOLEAN Create)
52 {
53 PW32PROCESS Win32Process;
54 NTSTATUS Status;
55
56 #if 0
57 DbgPrint ("Win32kProcessCallback() called\n");
58 #endif
59
60 Win32Process = Process->Win32Process;
61 if (Create)
62 {
63 #if 0
64 DbgPrint (" Create process\n");
65 #endif
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->CursorIconListHead);
77 ExInitializeFastMutex(&Win32Process->CursorIconListLock);
78
79 Win32Process->KeyboardLayout = W32kGetDefaultKeyLayout();
80 Win32Process->WindowStation = NULL;
81 if (Process->Win32WindowStation != NULL)
82 {
83 Status =
84 IntValidateWindowStationHandle(Process->Win32WindowStation,
85 UserMode,
86 GENERIC_ALL,
87 &Win32Process->WindowStation);
88 if (!NT_SUCCESS(Status))
89 {
90 DbgPrint("Win32K: Failed to reference a window station for "
91 "process.\n");
92 }
93 }
94
95 /* setup process flags */
96 Win32Process->Flags = 0;
97 }
98 else
99 {
100 #if 0
101 DbgPrint (" Destroy process\n");
102 DbgPrint (" IRQ level: %lu\n", KeGetCurrentIrql ());
103 #endif
104 IntRemoveProcessWndProcHandles((HANDLE)Process->UniqueProcessId);
105 IntCleanupMenus(Process, Win32Process);
106 IntCleanupCurIcons(Process, Win32Process);
107
108 CleanupForProcess(Process, Process->UniqueProcessId);
109
110 IntGraphicsCheck(FALSE);
111
112 /*
113 * Deregister logon application automatically
114 */
115 if(LogonProcess == Win32Process)
116 {
117 LogonProcess = NULL;
118 }
119 }
120
121 return STATUS_SUCCESS;
122 }
123
124
125 NTSTATUS STDCALL
126 Win32kThreadCallback (struct _ETHREAD *Thread,
127 BOOLEAN Create)
128 {
129 struct _EPROCESS *Process;
130 PW32THREAD Win32Thread;
131 NTSTATUS Status;
132
133 #if 0
134 DbgPrint ("Win32kThreadCallback() called\n");
135 #endif
136
137 Process = Thread->ThreadsProcess;
138 Win32Thread = Thread->Win32Thread;
139 if (Create)
140 {
141 #if 0
142 DbgPrint (" Create thread\n");
143 #endif
144
145 Win32Thread->IsExiting = FALSE;
146 IntDestroyCaret(Win32Thread);
147 Win32Thread->MessageQueue = MsqCreateMessageQueue(Thread);
148 Win32Thread->KeyboardLayout = W32kGetDefaultKeyLayout();
149 Win32Thread->MessagePumpHookValue = 0;
150 InitializeListHead(&Win32Thread->WindowListHead);
151 ExInitializeFastMutex(&Win32Thread->WindowListLock);
152
153 /* By default threads get assigned their process's desktop. */
154 Win32Thread->Desktop = NULL;
155 Win32Thread->hDesktop = NULL;
156 if (Process->Win32Desktop != NULL)
157 {
158 Status = ObReferenceObjectByHandle(Process->Win32Desktop,
159 GENERIC_ALL,
160 ExDesktopObjectType,
161 UserMode,
162 (PVOID*)&Win32Thread->Desktop,
163 NULL);
164 if (!NT_SUCCESS(Status))
165 {
166 DbgPrint("Win32K: Failed to reference a desktop for thread.\n");
167 }
168
169 Win32Thread->hDesktop = Process->Win32Desktop;
170 }
171 }
172 else
173 {
174 #if 0
175 DbgPrint (" Destroy thread\n");
176 #endif
177
178 Win32Thread->IsExiting = TRUE;
179 HOOK_DestroyThreadHooks(Thread);
180 RemoveTimersThread(Thread->Cid.UniqueThread);
181 UnregisterThreadHotKeys(Thread);
182 DestroyThreadWindows(Thread);
183 IntBlockInput(Win32Thread, FALSE);
184 MsqDestroyMessageQueue(Win32Thread->MessageQueue);
185 }
186
187 return STATUS_SUCCESS;
188 }
189
190
191 /*
192 * This definition doesn't work
193 */
194 // BOOL STDCALL DllMain(VOID)
195 NTSTATUS STDCALL
196 DllMain (
197 IN PDRIVER_OBJECT DriverObject,
198 IN PUNICODE_STRING RegistryPath)
199 {
200 NTSTATUS Status;
201 BOOLEAN Result;
202
203 /*
204 * Register user mode call interface
205 * (system service table index = 1)
206 */
207 Result = KeAddSystemServiceTable (Win32kSSDT,
208 NULL,
209 Win32kNumberOfSysCalls,
210 Win32kSSPT,
211 1);
212 if (Result == FALSE)
213 {
214 DbgPrint("Adding system services failed!\n");
215 return STATUS_UNSUCCESSFUL;
216 }
217
218 /*
219 * Register our per-process and per-thread structures.
220 */
221 PsEstablishWin32Callouts (Win32kProcessCallback,
222 Win32kThreadCallback,
223 0,
224 0,
225 sizeof(W32THREAD),
226 sizeof(W32PROCESS));
227
228 Status = InitWindowStationImpl();
229 if (!NT_SUCCESS(Status))
230 {
231 DbgPrint("Failed to initialize window station implementation!\n");
232 return STATUS_UNSUCCESSFUL;
233 }
234
235 Status = InitClassImpl();
236 if (!NT_SUCCESS(Status))
237 {
238 DbgPrint("Failed to initialize window class implementation!\n");
239 return STATUS_UNSUCCESSFUL;
240 }
241
242 Status = InitDesktopImpl();
243 if (!NT_SUCCESS(Status))
244 {
245 DbgPrint("Failed to initialize window station implementation!\n");
246 return STATUS_UNSUCCESSFUL;
247 }
248
249 Status = InitWindowImpl();
250 if (!NT_SUCCESS(Status))
251 {
252 DbgPrint("Failed to initialize window implementation!\n");
253 return STATUS_UNSUCCESSFUL;
254 }
255
256 Status = InitMenuImpl();
257 if (!NT_SUCCESS(Status))
258 {
259 DbgPrint("Failed to initialize menu implementation!\n");
260 return STATUS_UNSUCCESSFUL;
261 }
262
263 Status = InitInputImpl();
264 if (!NT_SUCCESS(Status))
265 {
266 DbgPrint("Failed to initialize input implementation.\n");
267 return(Status);
268 }
269
270 Status = InitKeyboardImpl();
271 if (!NT_SUCCESS(Status))
272 {
273 DbgPrint("Failed to initialize keyboard implementation.\n");
274 return(Status);
275 }
276
277 Status = MsqInitializeImpl();
278 if (!NT_SUCCESS(Status))
279 {
280 DbgPrint("Failed to initialize message queue implementation.\n");
281 return(Status);
282 }
283
284 Status = InitTimerImpl();
285 if (!NT_SUCCESS(Status))
286 {
287 DbgPrint("Failed to initialize timer implementation.\n");
288 return(Status);
289 }
290
291 Status = InitAcceleratorImpl();
292 if (!NT_SUCCESS(Status))
293 {
294 DbgPrint("Failed to initialize accelerator implementation.\n");
295 return(Status);
296 }
297
298 InitGdiObjectHandleTable ();
299
300 /* Initialize FreeType library */
301 if (! InitFontSupport())
302 {
303 DPRINT1("Unable to initialize font support\n");
304 return STATUS_UNSUCCESSFUL;
305 }
306
307 /* Create stock objects, ie. precreated objects commonly
308 used by win32 applications */
309 CreateStockObjects();
310
311 PREPARE_TESTS
312
313 return STATUS_SUCCESS;
314 }
315
316
317 BOOLEAN STDCALL
318 Win32kInitialize (VOID)
319 {
320 return TRUE;
321 }
322
323 /* EOF */