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
25 #include <win32k/ntddraw.h>
26 #include <include/napi.h>
31 BOOL INTERNAL_CALL
GDI_CleanupForProcess (struct _EPROCESS
*Process
);
33 extern ULONG_PTR Win32kSSDT
[];
34 extern UCHAR Win32kSSPT
[];
35 extern ULONG Win32kNumberOfSysCalls
;
37 PSHARED_SECTION_POOL SessionSharedSectionPool
= NULL
;
41 Win32kProcessCallback(struct _EPROCESS
*Process
,
44 PW32PROCESS Win32Process
;
45 DECLARE_RETURN(NTSTATUS
);
47 DPRINT("Enter Win32kProcessCallback\n");
50 /* Get the Win32 Process */
51 Win32Process
= PsGetProcessWin32Process(Process
);
53 /* Allocate one if needed */
56 /* FIXME - lock the process */
57 Win32Process
= ExAllocatePoolWithTag(NonPagedPool
,
59 TAG('W', '3', '2', 'p'));
61 if (Win32Process
== NULL
) RETURN( STATUS_NO_MEMORY
);
63 RtlZeroMemory(Win32Process
, sizeof(W32PROCESS
));
65 PsSetProcessWin32Process(Process
, Win32Process
);
66 /* FIXME - unlock the process */
71 DPRINT("Creating W32 process PID:%d at IRQ level: %lu\n", Process
->UniqueProcessId
, KeGetCurrentIrql());
73 InitializeListHead(&Win32Process
->ClassListHead
);
75 InitializeListHead(&Win32Process
->MenuListHead
);
77 InitializeListHead(&Win32Process
->PrivateFontListHead
);
78 ExInitializeFastMutex(&Win32Process
->PrivateFontListLock
);
80 InitializeListHead(&Win32Process
->DriverObjListHead
);
81 ExInitializeFastMutex(&Win32Process
->DriverObjListLock
);
83 Win32Process
->KeyboardLayout
= W32kGetDefaultKeyLayout();
85 if(Process
->Peb
!= NULL
)
87 /* map the gdi handle table to user land */
88 Process
->Peb
->GdiSharedHandleTable
= GDI_MapHandleTable(Process
);
91 /* setup process flags */
92 Win32Process
->Flags
= 0;
96 DPRINT("Destroying W32 process PID:%d at IRQ level: %lu\n", Process
->UniqueProcessId
, KeGetCurrentIrql());
97 IntRemoveProcessWndProcHandles((HANDLE
)Process
->UniqueProcessId
);
98 IntCleanupMenus(Process
, Win32Process
);
99 IntCleanupCurIcons(Process
, Win32Process
);
100 IntEngCleanupDriverObjs(Process
, Win32Process
);
101 CleanupMonitorImpl();
104 GDI_CleanupForProcess(Process
);
106 co_IntGraphicsCheck(FALSE
);
109 * Deregister logon application automatically
111 if(LogonProcess
== Win32Process
)
117 RETURN( STATUS_SUCCESS
);
121 DPRINT("Leave Win32kProcessCallback, ret=%i\n",_ret_
);
128 Win32kThreadCallback(struct _ETHREAD
*Thread
,
131 struct _EPROCESS
*Process
;
132 PW32THREAD Win32Thread
;
133 DECLARE_RETURN(NTSTATUS
);
135 DPRINT("Enter Win32kThreadCallback\n");
136 UserEnterExclusive();
138 Process
= Thread
->ThreadsProcess
;
140 /* Get the Win32 Thread */
141 Win32Thread
= PsGetThreadWin32Thread(Thread
);
143 /* Allocate one if needed */
146 /* FIXME - lock the process */
147 Win32Thread
= ExAllocatePoolWithTag(NonPagedPool
,
149 TAG('W', '3', '2', 't'));
151 if (Win32Thread
== NULL
) RETURN( STATUS_NO_MEMORY
);
153 RtlZeroMemory(Win32Thread
, sizeof(W32THREAD
));
155 PsSetThreadWin32Thread(Thread
, Win32Thread
);
156 /* FIXME - unlock the process */
160 HWINSTA hWinSta
= NULL
;
163 PUNICODE_STRING DesktopPath
;
164 PRTL_USER_PROCESS_PARAMETERS ProcessParams
= (Process
->Peb
? Process
->Peb
->ProcessParameters
: NULL
);
166 DPRINT("Creating W32 thread TID:%d at IRQ level: %lu\n", Thread
->Cid
.UniqueThread
, KeGetCurrentIrql());
169 * inherit the thread desktop and process window station (if not yet inherited) from the process startup
170 * info structure. See documentation of CreateProcess()
172 DesktopPath
= (ProcessParams
? ((ProcessParams
->DesktopInfo
.Length
> 0) ? &ProcessParams
->DesktopInfo
: NULL
) : NULL
);
173 Status
= IntParseDesktopPath(Process
,
177 if(NT_SUCCESS(Status
))
181 if(Process
!= CsrProcess
)
183 HWINSTA hProcessWinSta
= (HWINSTA
)InterlockedCompareExchangePointer((PVOID
)&Process
->Win32WindowStation
, (PVOID
)hWinSta
, NULL
);
184 if(hProcessWinSta
!= NULL
)
186 /* our process is already assigned to a different window station, we don't need the handle anymore */
198 Status
= ObReferenceObjectByHandle(hDesk
,
202 (PVOID
*)&Win32Thread
->Desktop
,
205 if(!NT_SUCCESS(Status
))
207 DPRINT1("Unable to reference thread desktop handle 0x%x\n", hDesk
);
208 Win32Thread
->Desktop
= NULL
;
212 Win32Thread
->IsExiting
= FALSE
;
213 co_IntDestroyCaret(Win32Thread
);
214 Win32Thread
->MessageQueue
= MsqCreateMessageQueue(Thread
);
215 Win32Thread
->KeyboardLayout
= W32kGetDefaultKeyLayout();
216 Win32Thread
->MessagePumpHookValue
= 0;
217 InitializeListHead(&Win32Thread
->WindowListHead
);
218 InitializeListHead(&Win32Thread
->W32CallbackListHead
);
222 DPRINT("Destroying W32 thread TID:%d at IRQ level: %lu\n", Thread
->Cid
.UniqueThread
, KeGetCurrentIrql());
224 Win32Thread
->IsExiting
= TRUE
;
225 HOOK_DestroyThreadHooks(Thread
);
226 UnregisterThreadHotKeys(Thread
);
227 co_DestroyThreadWindows(Thread
);
228 IntBlockInput(Win32Thread
, FALSE
);
229 MsqDestroyMessageQueue(Win32Thread
->MessageQueue
);
230 IntCleanupThreadCallbacks(Win32Thread
);
231 if(Win32Thread
->Desktop
!= NULL
)
233 ObDereferenceObject(Win32Thread
->Desktop
);
237 RETURN( STATUS_SUCCESS
);
241 DPRINT("Leave Win32kThreadCallback, ret=%i\n",_ret_
);
245 /* Only used in ntuser/input.c KeyboardThreadMain(). If it's
246 not called there anymore, please delete */
248 Win32kInitWin32Thread(PETHREAD Thread
)
252 Process
= Thread
->ThreadsProcess
;
254 if (Process
->Win32Process
== NULL
)
256 /* FIXME - lock the process */
257 Process
->Win32Process
= ExAllocatePool(NonPagedPool
, sizeof(W32PROCESS
));
259 if (Process
->Win32Process
== NULL
)
260 return STATUS_NO_MEMORY
;
262 RtlZeroMemory(Process
->Win32Process
, sizeof(W32PROCESS
));
263 /* FIXME - unlock the process */
265 Win32kProcessCallback(Process
, TRUE
);
268 if (Thread
->Tcb
.Win32Thread
== NULL
)
270 Thread
->Tcb
.Win32Thread
= ExAllocatePool (NonPagedPool
, sizeof(W32THREAD
));
271 if (Thread
->Tcb
.Win32Thread
== NULL
)
272 return STATUS_NO_MEMORY
;
274 RtlZeroMemory(Thread
->Tcb
.Win32Thread
, sizeof(W32THREAD
));
276 Win32kThreadCallback(Thread
, TRUE
);
279 return(STATUS_SUCCESS
);
284 * This definition doesn't work
288 IN PDRIVER_OBJECT DriverObject
,
289 IN PUNICODE_STRING RegistryPath
)
293 W32_CALLOUT_DATA CalloutData
;
296 * Register user mode call interface
297 * (system service table index = 1)
299 Result
= KeAddSystemServiceTable (Win32kSSDT
,
301 Win32kNumberOfSysCalls
,
306 DPRINT1("Adding system services failed!\n");
307 return STATUS_UNSUCCESSFUL
;
311 * Register Object Manager Callbacks
313 CalloutData
.WinStaCreate
= IntWinStaObjectOpen
;
314 CalloutData
.WinStaParse
= IntWinStaObjectParse
;
315 CalloutData
.WinStaDelete
= IntWinStaObjectDelete
;
316 CalloutData
.WinStaFind
= IntWinStaObjectFind
;
317 CalloutData
.DesktopCreate
= IntDesktopObjectCreate
;
318 CalloutData
.DesktopDelete
= IntDesktopObjectDelete
;
319 CalloutData
.W32ProcessCallout
= Win32kProcessCallback
;
320 CalloutData
.W32ThreadCallout
= Win32kThreadCallback
;
323 * Register our per-process and per-thread structures.
325 PsEstablishWin32Callouts(&CalloutData
);
327 Status
= IntUserCreateSharedSectionPool(48 * 1024 * 1024, /* 48 MB by default */
328 &SessionSharedSectionPool
);
329 if (!NT_SUCCESS(Status
))
331 DPRINT1("Failed to initialize the shared section pool: Status 0x%x\n", Status
);
334 Status
= InitUserImpl();
335 if (!NT_SUCCESS(Status
))
337 DPRINT1("Failed to initialize user implementation!\n");
338 return STATUS_UNSUCCESSFUL
;
341 Status
= InitWindowStationImpl();
342 if (!NT_SUCCESS(Status
))
344 DPRINT1("Failed to initialize window station implementation!\n");
345 return STATUS_UNSUCCESSFUL
;
348 Status
= InitClassImpl();
349 if (!NT_SUCCESS(Status
))
351 DPRINT1("Failed to initialize window class implementation!\n");
352 return STATUS_UNSUCCESSFUL
;
355 Status
= InitDesktopImpl();
356 if (!NT_SUCCESS(Status
))
358 DPRINT1("Failed to initialize desktop implementation!\n");
359 return STATUS_UNSUCCESSFUL
;
362 Status
= InitWindowImpl();
363 if (!NT_SUCCESS(Status
))
365 DPRINT1("Failed to initialize window implementation!\n");
366 return STATUS_UNSUCCESSFUL
;
369 Status
= InitMenuImpl();
370 if (!NT_SUCCESS(Status
))
372 DPRINT1("Failed to initialize menu implementation!\n");
373 return STATUS_UNSUCCESSFUL
;
376 Status
= InitInputImpl();
377 if (!NT_SUCCESS(Status
))
379 DPRINT1("Failed to initialize input implementation.\n");
383 Status
= InitKeyboardImpl();
384 if (!NT_SUCCESS(Status
))
386 DPRINT1("Failed to initialize keyboard implementation.\n");
390 Status
= InitMonitorImpl();
391 if (!NT_SUCCESS(Status
))
393 DbgPrint("Failed to initialize monitor implementation!\n");
394 return STATUS_UNSUCCESSFUL
;
397 Status
= MsqInitializeImpl();
398 if (!NT_SUCCESS(Status
))
400 DPRINT1("Failed to initialize message queue implementation.\n");
404 Status
= InitTimerImpl();
405 if (!NT_SUCCESS(Status
))
407 DPRINT1("Failed to initialize timer implementation.\n");
411 Status
= InitAcceleratorImpl();
412 if (!NT_SUCCESS(Status
))
414 DPRINT1("Failed to initialize accelerator implementation.\n");
418 Status
= InitGuiCheckImpl();
419 if (!NT_SUCCESS(Status
))
421 DPRINT1("Failed to initialize GUI check implementation.\n");
425 InitGdiObjectHandleTable ();
427 /* Initialize FreeType library */
428 if (! InitFontSupport())
430 DPRINT1("Unable to initialize font support\n");
431 return STATUS_UNSUCCESSFUL
;
434 /* Create stock objects, ie. precreated objects commonly
435 used by win32 applications */
436 CreateStockObjects();
437 CreateSysColorObjects();
439 return STATUS_SUCCESS
;
444 Win32kInitialize (VOID
)