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 * Callbacks used for Win32 objects... this define won't be needed after the Object Manager
42 typedef NTSTATUS STDCALL_FUNC
43 (*OBJECT_CREATE_ROUTINE
)(PVOID ObjectBody
,
46 struct _OBJECT_ATTRIBUTES
* ObjectAttributes
);
48 typedef NTSTATUS STDCALL_FUNC
49 (*OBJECT_PARSE_ROUTINE
)(PVOID Object
,
51 PUNICODE_STRING FullPath
,
55 typedef VOID STDCALL_FUNC
56 (*OBJECT_DELETE_ROUTINE
)(PVOID DeletedObject
);
58 typedef PVOID STDCALL_FUNC
59 (*OBJECT_FIND_ROUTINE
)(PVOID WinStaObject
,
63 typedef struct _W32_OBJECT_CALLBACK
{
64 OBJECT_CREATE_ROUTINE WinStaCreate
;
65 OBJECT_PARSE_ROUTINE WinStaParse
;
66 OBJECT_DELETE_ROUTINE WinStaDelete
;
67 OBJECT_FIND_ROUTINE WinStaFind
;
68 OBJECT_CREATE_ROUTINE DesktopCreate
;
69 OBJECT_DELETE_ROUTINE DesktopDelete
;
70 } W32_OBJECT_CALLBACK
, *PW32_OBJECT_CALLBACK
;
73 PsEstablishWin32Callouts(
74 PW32_PROCESS_CALLBACK W32ProcessCallback
,
75 PW32_THREAD_CALLBACK W32ThreadCallback
,
76 PW32_OBJECT_CALLBACK W32ObjectCallback
,
79 ULONG W32ProcessSize
);
82 BOOL INTERNAL_CALL
GDI_CleanupForProcess (struct _EPROCESS
*Process
);
84 extern SSDT Win32kSSDT
[];
85 extern SSPT Win32kSSPT
[];
86 extern ULONG Win32kNumberOfSysCalls
;
88 PSHARED_SECTION_POOL SessionSharedSectionPool
= NULL
;
91 Win32kProcessCallback (struct _EPROCESS
*Process
,
94 PW32PROCESS Win32Process
;
96 Win32Process
= Process
->Win32Process
;
99 DPRINT("Creating W32 process PID:%d at IRQ level: %lu\n", Process
->UniqueProcessId
, KeGetCurrentIrql());
101 InitializeListHead(&Win32Process
->ClassListHead
);
102 ExInitializeFastMutex(&Win32Process
->ClassListLock
);
104 InitializeListHead(&Win32Process
->MenuListHead
);
105 ExInitializeFastMutex(&Win32Process
->MenuListLock
);
107 InitializeListHead(&Win32Process
->PrivateFontListHead
);
108 ExInitializeFastMutex(&Win32Process
->PrivateFontListLock
);
110 InitializeListHead(&Win32Process
->DriverObjListHead
);
111 ExInitializeFastMutex(&Win32Process
->DriverObjListLock
);
113 Win32Process
->KeyboardLayout
= W32kGetDefaultKeyLayout();
115 if(Process
->Peb
!= NULL
)
117 /* map the gdi handle table to user land */
118 Process
->Peb
->GdiSharedHandleTable
= GDI_MapHandleTable(Process
);
121 /* setup process flags */
122 Win32Process
->Flags
= 0;
126 DPRINT("Destroying W32 process PID:%d at IRQ level: %lu\n", Process
->UniqueProcessId
, KeGetCurrentIrql());
127 IntRemoveProcessWndProcHandles((HANDLE
)Process
->UniqueProcessId
);
128 IntCleanupMenus(Process
, Win32Process
);
129 IntCleanupCurIcons(Process
, Win32Process
);
130 IntEngCleanupDriverObjs(Process
, Win32Process
);
131 CleanupMonitorImpl();
134 GDI_CleanupForProcess(Process
);
136 IntGraphicsCheck(FALSE
);
139 * Deregister logon application automatically
141 if(LogonProcess
== Win32Process
)
147 return STATUS_SUCCESS
;
152 Win32kThreadCallback (struct _ETHREAD
*Thread
,
155 struct _EPROCESS
*Process
;
156 PW32THREAD Win32Thread
;
158 Process
= Thread
->ThreadsProcess
;
159 Win32Thread
= Thread
->Tcb
.Win32Thread
;
162 HWINSTA hWinSta
= NULL
;
165 PUNICODE_STRING DesktopPath
;
166 PRTL_USER_PROCESS_PARAMETERS ProcessParams
= (Process
->Peb
? Process
->Peb
->ProcessParameters
: NULL
);
168 DPRINT("Creating W32 thread TID:%d at IRQ level: %lu\n", Thread
->Cid
.UniqueThread
, KeGetCurrentIrql());
171 * inherit the thread desktop and process window station (if not yet inherited) from the process startup
172 * info structure. See documentation of CreateProcess()
174 DesktopPath
= (ProcessParams
? ((ProcessParams
->DesktopInfo
.Length
> 0) ? &ProcessParams
->DesktopInfo
: NULL
) : NULL
);
175 Status
= IntParseDesktopPath(Process
,
179 if(NT_SUCCESS(Status
))
183 if(Process
!= CsrProcess
)
185 HWINSTA hProcessWinSta
= (HWINSTA
)InterlockedCompareExchangePointer((PVOID
)&Process
->Win32WindowStation
, (PVOID
)hWinSta
, NULL
);
186 if(hProcessWinSta
!= NULL
)
188 /* our process is already assigned to a different window station, we don't need the handle anymore */
200 Status
= ObReferenceObjectByHandle(hDesk
,
204 (PVOID
*)&Win32Thread
->Desktop
,
207 if(!NT_SUCCESS(Status
))
209 DPRINT1("Unable to reference thread desktop handle 0x%x\n", hDesk
);
210 Win32Thread
->Desktop
= NULL
;
214 Win32Thread
->IsExiting
= FALSE
;
215 IntDestroyCaret(Win32Thread
);
216 Win32Thread
->MessageQueue
= MsqCreateMessageQueue(Thread
);
217 Win32Thread
->KeyboardLayout
= W32kGetDefaultKeyLayout();
218 Win32Thread
->MessagePumpHookValue
= 0;
219 InitializeListHead(&Win32Thread
->WindowListHead
);
220 ExInitializeFastMutex(&Win32Thread
->WindowListLock
);
221 InitializeListHead(&Win32Thread
->W32CallbackListHead
);
225 DPRINT("Destroying W32 thread TID:%d at IRQ level: %lu\n", Thread
->Cid
.UniqueThread
, KeGetCurrentIrql());
227 Win32Thread
->IsExiting
= TRUE
;
228 HOOK_DestroyThreadHooks(Thread
);
229 UnregisterThreadHotKeys(Thread
);
230 DestroyThreadWindows(Thread
);
231 IntBlockInput(Win32Thread
, FALSE
);
232 MsqDestroyMessageQueue(Win32Thread
->MessageQueue
);
233 IntCleanupThreadCallbacks(Win32Thread
);
234 if(Win32Thread
->Desktop
!= NULL
)
236 ObDereferenceObject(Win32Thread
->Desktop
);
240 return STATUS_SUCCESS
;
246 IN PDRIVER_OBJECT DriverObject
,
247 IN PUNICODE_STRING RegistryPath
)
251 W32_OBJECT_CALLBACK Win32kObjectCallbacks
;
254 * Register user mode call interface
255 * (system service table index = 1)
257 Result
= KeAddSystemServiceTable (Win32kSSDT
,
259 Win32kNumberOfSysCalls
,
264 DPRINT1("Adding system services failed!\n");
265 return STATUS_UNSUCCESSFUL
;
269 * Register Object Manager Callbacks
271 Win32kObjectCallbacks
.WinStaCreate
= IntWinStaObjectCreate
;
272 Win32kObjectCallbacks
.WinStaParse
= IntWinStaObjectParse
;
273 Win32kObjectCallbacks
.WinStaDelete
= IntWinStaObjectDelete
;
274 Win32kObjectCallbacks
.WinStaFind
= IntWinStaObjectFind
;
275 Win32kObjectCallbacks
.DesktopCreate
= IntDesktopObjectCreate
;
276 Win32kObjectCallbacks
.DesktopDelete
= IntDesktopObjectDelete
;
278 * Register our per-process and per-thread structures.
280 PsEstablishWin32Callouts (Win32kProcessCallback
,
281 Win32kThreadCallback
,
282 &Win32kObjectCallbacks
,
287 Status
= IntUserCreateSharedSectionPool(48 * 1024 * 1024, /* 48 MB by default */
288 &SessionSharedSectionPool
);
289 if (!NT_SUCCESS(Status
))
291 DPRINT1("Failed to initialize the shared section pool: Status 0x%x\n", Status
);
294 Status
= InitWindowStationImpl();
295 if (!NT_SUCCESS(Status
))
297 DPRINT1("Failed to initialize window station implementation!\n");
298 return STATUS_UNSUCCESSFUL
;
301 Status
= InitClassImpl();
302 if (!NT_SUCCESS(Status
))
304 DPRINT1("Failed to initialize window class implementation!\n");
305 return STATUS_UNSUCCESSFUL
;
308 Status
= InitDesktopImpl();
309 if (!NT_SUCCESS(Status
))
311 DPRINT1("Failed to initialize desktop implementation!\n");
312 return STATUS_UNSUCCESSFUL
;
315 Status
= InitWindowImpl();
316 if (!NT_SUCCESS(Status
))
318 DPRINT1("Failed to initialize window implementation!\n");
319 return STATUS_UNSUCCESSFUL
;
322 Status
= InitMenuImpl();
323 if (!NT_SUCCESS(Status
))
325 DPRINT1("Failed to initialize menu implementation!\n");
326 return STATUS_UNSUCCESSFUL
;
329 Status
= InitInputImpl();
330 if (!NT_SUCCESS(Status
))
332 DPRINT1("Failed to initialize input implementation.\n");
336 Status
= InitKeyboardImpl();
337 if (!NT_SUCCESS(Status
))
339 DPRINT1("Failed to initialize keyboard implementation.\n");
343 Status
= InitMonitorImpl();
344 if (!NT_SUCCESS(Status
))
346 DbgPrint("Failed to initialize monitor implementation!\n");
347 return STATUS_UNSUCCESSFUL
;
350 Status
= MsqInitializeImpl();
351 if (!NT_SUCCESS(Status
))
353 DPRINT1("Failed to initialize message queue implementation.\n");
357 Status
= InitTimerImpl();
358 if (!NT_SUCCESS(Status
))
360 DPRINT1("Failed to initialize timer implementation.\n");
364 Status
= InitAcceleratorImpl();
365 if (!NT_SUCCESS(Status
))
367 DPRINT1("Failed to initialize accelerator implementation.\n");
371 Status
= InitGuiCheckImpl();
372 if (!NT_SUCCESS(Status
))
374 DPRINT1("Failed to initialize GUI check implementation.\n");
378 InitGdiObjectHandleTable ();
380 /* Initialize FreeType library */
381 if (! InitFontSupport())
383 DPRINT1("Unable to initialize font support\n");
384 return STATUS_UNSUCCESSFUL
;
387 /* Create stock objects, ie. precreated objects commonly
388 used by win32 applications */
389 CreateStockObjects();
390 CreateSysColorObjects();
392 return STATUS_SUCCESS
;
397 Win32kInitialize (VOID
)