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