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 <include/napi.h>
30 BOOL INTERNAL_CALL
GDI_CleanupForProcess (struct _EPROCESS
*Process
);
32 extern ULONG_PTR Win32kSSDT
[];
33 extern UCHAR Win32kSSPT
[];
34 extern ULONG Win32kNumberOfSysCalls
;
36 PSHARED_SECTION_POOL SessionSharedSectionPool
= NULL
;
40 Win32kProcessCallback(struct _EPROCESS
*Process
,
43 PW32PROCESS Win32Process
;
44 DECLARE_RETURN(NTSTATUS
);
46 DPRINT("Enter Win32kProcessCallback\n");
49 /* Get the Win32 Process */
50 Win32Process
= PsGetProcessWin32Process(Process
);
52 /* Allocate one if needed */
55 /* FIXME - lock the process */
56 Win32Process
= ExAllocatePoolWithTag(NonPagedPool
,
58 TAG('W', '3', '2', 'p'));
60 if (Win32Process
== NULL
) RETURN( STATUS_NO_MEMORY
);
62 RtlZeroMemory(Win32Process
, sizeof(W32PROCESS
));
64 PsSetProcessWin32Process(Process
, Win32Process
);
65 /* FIXME - unlock the process */
70 DPRINT("Creating W32 process PID:%d at IRQ level: %lu\n", Process
->UniqueProcessId
, KeGetCurrentIrql());
72 InitializeListHead(&Win32Process
->ClassList
);
74 InitializeListHead(&Win32Process
->MenuListHead
);
76 InitializeListHead(&Win32Process
->PrivateFontListHead
);
77 ExInitializeFastMutex(&Win32Process
->PrivateFontListLock
);
79 InitializeListHead(&Win32Process
->DriverObjListHead
);
80 ExInitializeFastMutex(&Win32Process
->DriverObjListLock
);
82 Win32Process
->KeyboardLayout
= W32kGetDefaultKeyLayout();
84 if(Process
->Peb
!= NULL
)
86 /* map the gdi handle table to user land */
87 Process
->Peb
->GdiSharedHandleTable
= GDI_MapHandleTable(Process
);
90 /* setup process flags */
91 Win32Process
->Flags
= 0;
95 DPRINT("Destroying W32 process PID:%d at IRQ level: %lu\n", Process
->UniqueProcessId
, KeGetCurrentIrql());
96 IntRemoveProcessWndProcHandles((HANDLE
)Process
->UniqueProcessId
);
97 IntCleanupMenus(Process
, Win32Process
);
98 IntCleanupCurIcons(Process
, Win32Process
);
99 IntEngCleanupDriverObjs(Process
, Win32Process
);
100 CleanupMonitorImpl();
102 /* no process windows should exist at this point, or the function will assert! */
103 DestroyProcessClasses(Win32Process
);
105 GDI_CleanupForProcess(Process
);
107 co_IntGraphicsCheck(FALSE
);
110 * Deregister logon application automatically
112 if(LogonProcess
== Win32Process
)
118 RETURN( STATUS_SUCCESS
);
122 DPRINT("Leave Win32kProcessCallback, ret=%i\n",_ret_
);
129 Win32kThreadCallback(struct _ETHREAD
*Thread
,
132 struct _EPROCESS
*Process
;
133 PW32THREAD Win32Thread
;
134 DECLARE_RETURN(NTSTATUS
);
136 DPRINT("Enter Win32kThreadCallback\n");
137 UserEnterExclusive();
139 Process
= Thread
->ThreadsProcess
;
141 /* Get the Win32 Thread */
142 Win32Thread
= PsGetThreadWin32Thread(Thread
);
144 /* Allocate one if needed */
147 /* FIXME - lock the process */
148 Win32Thread
= ExAllocatePoolWithTag(NonPagedPool
,
150 TAG('W', '3', '2', 't'));
152 if (Win32Thread
== NULL
) RETURN( STATUS_NO_MEMORY
);
154 RtlZeroMemory(Win32Thread
, sizeof(W32THREAD
));
156 PsSetThreadWin32Thread(Thread
, Win32Thread
);
157 /* FIXME - unlock the process */
161 HWINSTA hWinSta
= NULL
;
164 PUNICODE_STRING DesktopPath
;
165 PRTL_USER_PROCESS_PARAMETERS ProcessParams
= (Process
->Peb
? Process
->Peb
->ProcessParameters
: NULL
);
167 DPRINT("Creating W32 thread TID:%d at IRQ level: %lu\n", Thread
->Cid
.UniqueThread
, KeGetCurrentIrql());
170 * inherit the thread desktop and process window station (if not yet inherited) from the process startup
171 * info structure. See documentation of CreateProcess()
173 DesktopPath
= (ProcessParams
? ((ProcessParams
->DesktopInfo
.Length
> 0) ? &ProcessParams
->DesktopInfo
: NULL
) : NULL
);
174 Status
= IntParseDesktopPath(Process
,
178 if(NT_SUCCESS(Status
))
182 if(Process
!= CsrProcess
)
184 HWINSTA hProcessWinSta
= (HWINSTA
)InterlockedCompareExchangePointer((PVOID
)&Process
->Win32WindowStation
, (PVOID
)hWinSta
, NULL
);
185 if(hProcessWinSta
!= NULL
)
187 /* our process is already assigned to a different window station, we don't need the handle anymore */
199 Status
= ObReferenceObjectByHandle(hDesk
,
203 (PVOID
*)&Win32Thread
->Desktop
,
206 if(!NT_SUCCESS(Status
))
208 DPRINT1("Unable to reference thread desktop handle 0x%x\n", hDesk
);
209 Win32Thread
->Desktop
= NULL
;
213 Win32Thread
->IsExiting
= FALSE
;
214 co_IntDestroyCaret(Win32Thread
);
215 Win32Thread
->MessageQueue
= MsqCreateMessageQueue(Thread
);
216 Win32Thread
->KeyboardLayout
= W32kGetDefaultKeyLayout();
217 Win32Thread
->MessagePumpHookValue
= 0;
218 InitializeListHead(&Win32Thread
->WindowListHead
);
219 InitializeListHead(&Win32Thread
->W32CallbackListHead
);
223 PSINGLE_LIST_ENTRY e
;
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 /* what if this co_ func crash in umode? what will clean us up then? */
231 co_DestroyThreadWindows(Thread
);
232 IntBlockInput(Win32Thread
, FALSE
);
233 MsqDestroyMessageQueue(Win32Thread
->MessageQueue
);
234 IntCleanupThreadCallbacks(Win32Thread
);
235 if(Win32Thread
->Desktop
!= NULL
)
237 ObDereferenceObject(Win32Thread
->Desktop
);
240 /* cleanup user object references stack */
241 e
= PopEntryList(&Win32Thread
->ReferencesList
);
244 PUSER_REFERENCE_ENTRY ref
= CONTAINING_RECORD(e
, USER_REFERENCE_ENTRY
, Entry
);
245 DPRINT1("thread clean: remove reference obj 0x%x\n",ref
->obj
);
246 ObmDereferenceObject(ref
->obj
);
248 e
= PopEntryList(&Win32Thread
->ReferencesList
);
250 PsSetThreadWin32Thread(Thread
, NULL
);
253 RETURN( STATUS_SUCCESS
);
257 DPRINT("Leave Win32kThreadCallback, ret=%i\n",_ret_
);
261 /* Only used in ntuser/input.c KeyboardThreadMain(). If it's
262 not called there anymore, please delete */
264 Win32kInitWin32Thread(PETHREAD Thread
)
268 Process
= Thread
->ThreadsProcess
;
270 if (Process
->Win32Process
== NULL
)
272 /* FIXME - lock the process */
273 Process
->Win32Process
= ExAllocatePool(NonPagedPool
, sizeof(W32PROCESS
));
275 if (Process
->Win32Process
== NULL
)
276 return STATUS_NO_MEMORY
;
278 RtlZeroMemory(Process
->Win32Process
, sizeof(W32PROCESS
));
279 /* FIXME - unlock the process */
281 Win32kProcessCallback(Process
, TRUE
);
284 if (Thread
->Tcb
.Win32Thread
== NULL
)
286 Thread
->Tcb
.Win32Thread
= ExAllocatePool (NonPagedPool
, sizeof(W32THREAD
));
287 if (Thread
->Tcb
.Win32Thread
== NULL
)
288 return STATUS_NO_MEMORY
;
290 RtlZeroMemory(Thread
->Tcb
.Win32Thread
, sizeof(W32THREAD
));
292 Win32kThreadCallback(Thread
, TRUE
);
295 return(STATUS_SUCCESS
);
300 * This definition doesn't work
304 IN PDRIVER_OBJECT DriverObject
,
305 IN PUNICODE_STRING RegistryPath
)
309 W32_CALLOUT_DATA CalloutData
;
312 * Register user mode call interface
313 * (system service table index = 1)
315 Result
= KeAddSystemServiceTable (Win32kSSDT
,
317 Win32kNumberOfSysCalls
,
322 DPRINT1("Adding system services failed!\n");
323 return STATUS_UNSUCCESSFUL
;
327 * Register Object Manager Callbacks
329 CalloutData
.WinStaCreate
= IntWinStaObjectOpen
;
330 CalloutData
.WinStaParse
= IntWinStaObjectParse
;
331 CalloutData
.WinStaDelete
= IntWinStaObjectDelete
;
332 CalloutData
.WinStaFind
= IntWinStaObjectFind
;
333 CalloutData
.DesktopCreate
= IntDesktopObjectCreate
;
334 CalloutData
.DesktopDelete
= IntDesktopObjectDelete
;
335 CalloutData
.W32ProcessCallout
= Win32kProcessCallback
;
336 CalloutData
.W32ThreadCallout
= Win32kThreadCallback
;
339 * Register our per-process and per-thread structures.
341 PsEstablishWin32Callouts(&CalloutData
);
343 Status
= IntUserCreateSharedSectionPool(48 * 1024 * 1024, /* 48 MB by default */
344 &SessionSharedSectionPool
);
345 if (!NT_SUCCESS(Status
))
347 DPRINT1("Failed to initialize the shared section pool: Status 0x%x\n", Status
);
350 Status
= InitUserImpl();
351 if (!NT_SUCCESS(Status
))
353 DPRINT1("Failed to initialize user implementation!\n");
354 return STATUS_UNSUCCESSFUL
;
357 Status
= InitHotkeyImpl();
358 if (!NT_SUCCESS(Status
))
360 DPRINT1("Failed to initialize hotkey implementation!\n");
361 return STATUS_UNSUCCESSFUL
;
364 Status
= InitWindowStationImpl();
365 if (!NT_SUCCESS(Status
))
367 DPRINT1("Failed to initialize window station implementation!\n");
368 return STATUS_UNSUCCESSFUL
;
371 Status
= InitClassImpl();
372 if (!NT_SUCCESS(Status
))
374 DPRINT1("Failed to initialize window class implementation!\n");
375 return STATUS_UNSUCCESSFUL
;
378 Status
= InitDesktopImpl();
379 if (!NT_SUCCESS(Status
))
381 DPRINT1("Failed to initialize desktop implementation!\n");
382 return STATUS_UNSUCCESSFUL
;
385 Status
= InitWindowImpl();
386 if (!NT_SUCCESS(Status
))
388 DPRINT1("Failed to initialize window implementation!\n");
389 return STATUS_UNSUCCESSFUL
;
392 Status
= InitMenuImpl();
393 if (!NT_SUCCESS(Status
))
395 DPRINT1("Failed to initialize menu implementation!\n");
396 return STATUS_UNSUCCESSFUL
;
399 Status
= InitInputImpl();
400 if (!NT_SUCCESS(Status
))
402 DPRINT1("Failed to initialize input implementation.\n");
406 Status
= InitKeyboardImpl();
407 if (!NT_SUCCESS(Status
))
409 DPRINT1("Failed to initialize keyboard implementation.\n");
413 Status
= InitMonitorImpl();
414 if (!NT_SUCCESS(Status
))
416 DbgPrint("Failed to initialize monitor implementation!\n");
417 return STATUS_UNSUCCESSFUL
;
420 Status
= MsqInitializeImpl();
421 if (!NT_SUCCESS(Status
))
423 DPRINT1("Failed to initialize message queue implementation.\n");
427 Status
= InitTimerImpl();
428 if (!NT_SUCCESS(Status
))
430 DPRINT1("Failed to initialize timer implementation.\n");
434 Status
= InitAcceleratorImpl();
435 if (!NT_SUCCESS(Status
))
437 DPRINT1("Failed to initialize accelerator implementation.\n");
441 Status
= InitGuiCheckImpl();
442 if (!NT_SUCCESS(Status
))
444 DPRINT1("Failed to initialize GUI check implementation.\n");
448 InitGdiObjectHandleTable ();
450 /* Initialize FreeType library */
451 if (! InitFontSupport())
453 DPRINT1("Unable to initialize font support\n");
454 return STATUS_UNSUCCESSFUL
;
457 /* Create stock objects, ie. precreated objects commonly
458 used by win32 applications */
459 CreateStockObjects();
460 CreateSysColorObjects();
462 return STATUS_SUCCESS
;
467 Win32kInitialize (VOID
)