2 * ReactOS W32 Subsystem
3 * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 ReactOS Team
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.
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.
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.
21 * Entry Point for win32k.sys
26 #include <win32k/debug1.h>
30 typedef NTSTATUS (STDCALL
*PW32_PROCESS_CALLBACK
)(
31 struct _EPROCESS
*Process
,
34 typedef NTSTATUS (STDCALL
*PW32_THREAD_CALLBACK
)(
35 struct _ETHREAD
*Thread
,
39 PsEstablishWin32Callouts(
40 PW32_PROCESS_CALLBACK W32ProcessCallback
,
41 PW32_THREAD_CALLBACK W32ThreadCallback
,
45 ULONG W32ProcessSize
);
48 BOOL INTERNAL_CALL
GDI_CleanupForProcess (struct _EPROCESS
*Process
);
50 extern SSDT Win32kSSDT
[];
51 extern SSPT Win32kSSPT
[];
52 extern ULONG Win32kNumberOfSysCalls
;
55 Win32kProcessCallback (struct _EPROCESS
*Process
,
58 PW32PROCESS Win32Process
;
60 Win32Process
= Process
->Win32Process
;
63 DPRINT("Creating W32 process PID:%d at IRQ level: %lu\n", Process
->UniqueProcessId
, KeGetCurrentIrql());
65 InitializeListHead(&Win32Process
->ClassListHead
);
66 ExInitializeFastMutex(&Win32Process
->ClassListLock
);
68 InitializeListHead(&Win32Process
->MenuListHead
);
69 ExInitializeFastMutex(&Win32Process
->MenuListLock
);
71 InitializeListHead(&Win32Process
->PrivateFontListHead
);
72 ExInitializeFastMutex(&Win32Process
->PrivateFontListLock
);
74 InitializeListHead(&Win32Process
->DriverObjListHead
);
75 ExInitializeFastMutex(&Win32Process
->DriverObjListLock
);
77 Win32Process
->KeyboardLayout
= W32kGetDefaultKeyLayout();
79 /* setup process flags */
80 Win32Process
->Flags
= 0;
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 IntEngCleanupDriverObjs(Process
, Win32Process
);
92 GDI_CleanupForProcess(Process
);
94 IntGraphicsCheck(FALSE
);
97 * Deregister logon application automatically
99 if(LogonProcess
== Win32Process
)
105 return STATUS_SUCCESS
;
110 Win32kThreadCallback (struct _ETHREAD
*Thread
,
113 struct _EPROCESS
*Process
;
114 PW32THREAD Win32Thread
;
116 Process
= Thread
->ThreadsProcess
;
117 Win32Thread
= Thread
->Tcb
.Win32Thread
;
120 HWINSTA hWinSta
= NULL
;
123 PUNICODE_STRING DesktopPath
;
124 PRTL_USER_PROCESS_PARAMETERS ProcessParams
= (Process
->Peb
? Process
->Peb
->ProcessParameters
: NULL
);
126 DPRINT("Creating W32 thread TID:%d at IRQ level: %lu\n", Thread
->Cid
.UniqueThread
, KeGetCurrentIrql());
129 * inherit the thread desktop and process window station (if not yet inherited) from the process startup
130 * info structure. See documentation of CreateProcess()
132 DesktopPath
= (ProcessParams
? ((ProcessParams
->DesktopInfo
.Length
> 0) ? &ProcessParams
->DesktopInfo
: NULL
) : NULL
);
133 Status
= IntParseDesktopPath(Process
,
137 if(NT_SUCCESS(Status
))
141 if(Process
!= CsrProcess
)
143 HWINSTA hProcessWinSta
= (HWINSTA
)InterlockedCompareExchangePointer((PVOID
)&Process
->Win32WindowStation
, (PVOID
)hWinSta
, NULL
);
144 if(hProcessWinSta
!= NULL
)
146 /* our process is already assigned to a different window station, we don't need the handle anymore */
156 Win32Thread
->hDesktop
= hDesk
;
158 Status
= ObReferenceObjectByHandle(hDesk
,
162 (PVOID
*)&Win32Thread
->Desktop
,
165 if(!NT_SUCCESS(Status
))
167 DPRINT1("Unable to reference thread desktop handle 0x%x\n", hDesk
);
168 Win32Thread
->Desktop
= NULL
;
173 Win32Thread
->IsExiting
= FALSE
;
174 IntDestroyCaret(Win32Thread
);
175 Win32Thread
->MessageQueue
= MsqCreateMessageQueue(Thread
);
176 Win32Thread
->KeyboardLayout
= W32kGetDefaultKeyLayout();
177 Win32Thread
->MessagePumpHookValue
= 0;
178 InitializeListHead(&Win32Thread
->WindowListHead
);
179 ExInitializeFastMutex(&Win32Thread
->WindowListLock
);
180 InitializeListHead(&Win32Thread
->W32CallbackListHead
);
181 ExInitializeFastMutex(&Win32Thread
->W32CallbackListLock
);
185 DPRINT("Destroying W32 thread TID:%d at IRQ level: %lu\n", Thread
->Cid
.UniqueThread
, KeGetCurrentIrql());
187 Win32Thread
->IsExiting
= TRUE
;
188 HOOK_DestroyThreadHooks(Thread
);
189 UnregisterThreadHotKeys(Thread
);
190 DestroyThreadWindows(Thread
);
191 IntBlockInput(Win32Thread
, FALSE
);
192 MsqDestroyMessageQueue(Win32Thread
->MessageQueue
);
193 IntCleanupThreadCallbacks(Win32Thread
);
194 if(Win32Thread
->Desktop
!= NULL
)
196 ObDereferenceObject(Win32Thread
->Desktop
);
200 return STATUS_SUCCESS
;
206 IN PDRIVER_OBJECT DriverObject
,
207 IN PUNICODE_STRING RegistryPath
)
213 * Register user mode call interface
214 * (system service table index = 1)
216 Result
= KeAddSystemServiceTable (Win32kSSDT
,
218 Win32kNumberOfSysCalls
,
223 DPRINT1("Adding system services failed!\n");
224 return STATUS_UNSUCCESSFUL
;
228 * Register our per-process and per-thread structures.
230 PsEstablishWin32Callouts (Win32kProcessCallback
,
231 Win32kThreadCallback
,
237 Status
= InitWindowStationImpl();
238 if (!NT_SUCCESS(Status
))
240 DPRINT1("Failed to initialize window station implementation!\n");
241 return STATUS_UNSUCCESSFUL
;
244 Status
= InitClassImpl();
245 if (!NT_SUCCESS(Status
))
247 DPRINT1("Failed to initialize window class implementation!\n");
248 return STATUS_UNSUCCESSFUL
;
251 Status
= InitDesktopImpl();
252 if (!NT_SUCCESS(Status
))
254 DPRINT1("Failed to initialize desktop implementation!\n");
255 return STATUS_UNSUCCESSFUL
;
258 Status
= InitWindowImpl();
259 if (!NT_SUCCESS(Status
))
261 DPRINT1("Failed to initialize window implementation!\n");
262 return STATUS_UNSUCCESSFUL
;
265 Status
= InitMenuImpl();
266 if (!NT_SUCCESS(Status
))
268 DPRINT1("Failed to initialize menu implementation!\n");
269 return STATUS_UNSUCCESSFUL
;
272 Status
= InitInputImpl();
273 if (!NT_SUCCESS(Status
))
275 DPRINT1("Failed to initialize input implementation.\n");
279 Status
= InitKeyboardImpl();
280 if (!NT_SUCCESS(Status
))
282 DPRINT1("Failed to initialize keyboard implementation.\n");
286 Status
= InitMonitorImpl();
287 if (!NT_SUCCESS(Status
))
289 DbgPrint("Failed to initialize monitor implementation!\n");
290 return STATUS_UNSUCCESSFUL
;
293 Status
= MsqInitializeImpl();
294 if (!NT_SUCCESS(Status
))
296 DPRINT1("Failed to initialize message queue implementation.\n");
300 Status
= InitTimerImpl();
301 if (!NT_SUCCESS(Status
))
303 DPRINT1("Failed to initialize timer implementation.\n");
307 Status
= InitAcceleratorImpl();
308 if (!NT_SUCCESS(Status
))
310 DPRINT1("Failed to initialize accelerator implementation.\n");
314 Status
= InitGuiCheckImpl();
315 if (!NT_SUCCESS(Status
))
317 DPRINT1("Failed to initialize GUI check implementation.\n");
321 InitGdiObjectHandleTable ();
323 /* Initialize FreeType library */
324 if (! InitFontSupport())
326 DPRINT1("Unable to initialize font support\n");
327 return STATUS_UNSUCCESSFUL
;
330 /* Create stock objects, ie. precreated objects commonly
331 used by win32 applications */
332 CreateStockObjects();
333 CreateSysColorObjects();
335 return STATUS_SUCCESS
;
340 Win32kInitialize (VOID
)