2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Win32k subsystem
4 * PURPOSE: Driver entry and initialization of win32k
5 * FILE: subsystems/win32/win32k/main/main.c
18 PGDI_HANDLE_TABLE NTAPI
GDIOBJ_iAllocHandleTable(OUT PVOID
*SectionObject
);
19 BOOL NTAPI
GDI_CleanupForProcess (struct _EPROCESS
*Process
);
20 NTSTATUS NTAPI
UserDestroyThreadInfo(struct _ETHREAD
*Thread
);
22 HANDLE GlobalUserHeap
= NULL
;
23 PVOID GlobalUserHeapSection
= NULL
;
25 PSERVERINFO gpsi
= NULL
; // Global User Server Information.
28 PPROCESSINFO ppiScrnSaver
;
29 PPROCESSINFO gppiList
= NULL
;
31 extern ULONG_PTR Win32kSSDT
[];
32 extern UCHAR Win32kSSPT
[];
33 extern ULONG Win32kNumberOfSysCalls
;
38 DbgPreServiceHook(ULONG ulSyscallId
, PULONG_PTR pulArguments
)
40 GdiDbgPreServiceHook(ulSyscallId
, pulArguments
);
41 UserDbgPreServiceHook(ulSyscallId
, pulArguments
);
46 DbgPostServiceHook(ULONG ulSyscallId
, ULONG_PTR ulResult
)
48 ulResult
= GdiDbgPostServiceHook(ulSyscallId
, ulResult
);
49 ulResult
= UserDbgPostServiceHook(ulSyscallId
, ulResult
);
56 CreateProcessInfo(PEPROCESS Process
)
58 PPROCESSINFO ppiCurrent
;
62 PVOID UserBase
= NULL
;
63 PRTL_USER_PROCESS_PARAMETERS pParams
= Process
->Peb
->ProcessParameters
;
65 /* We might be called with an already allocated win32 process */
66 ppiCurrent
= PsGetProcessWin32Process(Process
);
67 if (ppiCurrent
!= NULL
)
69 /* There is no more to do for us (this is a success code!) */
70 return STATUS_ALREADY_WIN32
;
73 /* Allocate a new win32 process */
74 ppiCurrent
= ExAllocatePoolWithTag(NonPagedPool
,
77 if (ppiCurrent
== NULL
)
79 ERR_CH(UserProcess
, "Failed to allocate ppi for PID:0x%lx\n",
80 HandleToUlong(Process
->UniqueProcessId
));
81 return STATUS_NO_MEMORY
;
84 RtlZeroMemory(ppiCurrent
, sizeof(PROCESSINFO
));
86 PsSetProcessWin32Process(Process
, ppiCurrent
, NULL
);
89 DbgInitDebugChannels();
91 KdRosRegisterCliCallback(DbgGdiKdbgCliCallback
);
95 TRACE_CH(UserProcess
,"Allocated ppi 0x%p for PID:0x%lx\n", ppiCurrent
, HandleToUlong(Process
->UniqueProcessId
));
97 /* map the global heap into the process */
99 Status
= MmMapViewOfSection(GlobalUserHeapSection
,
100 PsGetCurrentProcess(),
108 PAGE_EXECUTE_READ
); /* would prefer PAGE_READONLY, but thanks to RTL heaps... */
109 if (!NT_SUCCESS(Status
))
111 TRACE_CH(UserProcess
,"Failed to map the global heap! 0x%x\n", Status
);
114 ppiCurrent
->HeapMappings
.Next
= NULL
;
115 ppiCurrent
->HeapMappings
.KernelMapping
= (PVOID
)GlobalUserHeap
;
116 ppiCurrent
->HeapMappings
.UserMapping
= UserBase
;
117 ppiCurrent
->HeapMappings
.Count
= 1;
119 InitializeListHead(&ppiCurrent
->GDIBrushAttrFreeList
);
120 InitializeListHead(&ppiCurrent
->GDIDcAttrFreeList
);
122 InitializeListHead(&ppiCurrent
->PrivateFontListHead
);
123 ExInitializeFastMutex(&ppiCurrent
->PrivateFontListLock
);
125 InitializeListHead(&ppiCurrent
->DriverObjListHead
);
126 ExInitializeFastMutex(&ppiCurrent
->DriverObjListLock
);
128 ppiCurrent
->KeyboardLayout
= W32kGetDefaultKeyLayout();
129 if (!EngCreateEvent((PEVENT
*)&ppiCurrent
->InputIdleEvent
))
134 KeInitializeEvent(ppiCurrent
->InputIdleEvent
, NotificationEvent
, FALSE
);
137 /* map the gdi handle table to user land */
138 Process
->Peb
->GdiSharedHandleTable
= GDI_MapHandleTable(Process
);
139 Process
->Peb
->GdiDCAttributeList
= GDI_BATCH_LIMIT
;
140 pParams
= Process
->Peb
->ProcessParameters
;
142 ppiCurrent
->peProcess
= Process
;
143 /* setup process flags */
144 ppiCurrent
->W32PF_flags
= W32PF_THREADCONNECTED
;
147 pParams
->WindowFlags
& STARTF_SCRNSAVER
)
149 ppiScrnSaver
= ppiCurrent
;
150 ppiCurrent
->W32PF_flags
|= W32PF_SCREENSAVER
;
153 // Fixme check if this process is allowed.
154 ppiCurrent
->W32PF_flags
|= W32PF_ALLOWFOREGROUNDACTIVATE
; // Starting application it will get toggled off.
156 /* Create pools for GDI object attributes */
157 ppiCurrent
->pPoolDcAttr
= GdiPoolCreate(sizeof(DC_ATTR
), 'acdG');
158 ppiCurrent
->pPoolBrushAttr
= GdiPoolCreate(sizeof(BRUSH_ATTR
), 'arbG');
159 ppiCurrent
->pPoolRgnAttr
= GdiPoolCreate(sizeof(RGN_ATTR
), 'agrG');
160 ASSERT(ppiCurrent
->pPoolDcAttr
);
161 ASSERT(ppiCurrent
->pPoolBrushAttr
);
162 ASSERT(ppiCurrent
->pPoolRgnAttr
);
164 /* Add the process to the global list */
165 ppiCurrent
->ppiNext
= gppiList
;
166 gppiList
= ppiCurrent
;
167 IntReferenceProcessInfo(ppiCurrent
);
169 return STATUS_SUCCESS
;
174 DestroyProcessInfo(PEPROCESS Process
)
176 PPROCESSINFO ppiCurrent
, *pppi
;
178 /* Get the Win32 Process */
179 ppiCurrent
= PsGetProcessWin32Process(Process
);
183 TRACE_CH(UserProcess
, "Destroying ppi 0x%p\n", ppiCurrent
);
184 ppiCurrent
->W32PF_flags
|= W32PF_TERMINATED
;
186 if (ppiScrnSaver
== ppiCurrent
)
189 /* Destroy user objects */
190 UserDestroyObjectsForOwner(gHandleTable
, ppiCurrent
);
192 TRACE_CH(UserProcess
,"Freeing ppi 0x%p\n", ppiCurrent
);
194 if (DBG_IS_CHANNEL_ENABLED(ppiCurrent
, DbgChUserObj
, WARN_LEVEL
))
196 TRACE_CH(UserObj
, "Dumping user handles at the end of the process %s (Info %p).\n",
197 ppiCurrent
->peProcess
->ImageFileName
, ppiCurrent
);
198 DbgUserDumpHandleTable();
202 /* And GDI ones too */
203 GDI_CleanupForProcess(Process
);
205 /* So we can now free the pools */
206 GdiPoolDestroy(ppiCurrent
->pPoolDcAttr
);
207 GdiPoolDestroy(ppiCurrent
->pPoolBrushAttr
);
208 GdiPoolDestroy(ppiCurrent
->pPoolRgnAttr
);
210 /* Remove it from the list of GUI apps */
211 co_IntGraphicsCheck(FALSE
);
214 * Deregister logon application automatically
216 if(LogonProcess
== ppiCurrent
)
221 /* Close the current window station */
222 UserSetProcessWindowStation(NULL
);
224 if (gppiInputProvider
== ppiCurrent
) gppiInputProvider
= NULL
;
226 /* Remove it from the list */
228 while (*pppi
!= NULL
&& *pppi
!= ppiCurrent
)
229 pppi
= &(*pppi
)->ppiNext
;
231 ASSERT(*pppi
== ppiCurrent
);
233 *pppi
= ppiCurrent
->ppiNext
;
235 if(ppiCurrent
->hdeskStartup
)
237 ZwClose(ppiCurrent
->hdeskStartup
);
238 ppiCurrent
->hdeskStartup
= NULL
;
241 #ifdef NEW_CURSORICON
242 /* Clean up the process icon cache */
243 IntCleanupCurIconCache(ppiCurrent
);
246 /* The process is dying */
247 PsSetProcessWin32Process(Process
, NULL
, ppiCurrent
);
248 ppiCurrent
->peProcess
= NULL
;
250 /* At last, dereference */
251 IntDereferenceProcessInfo(ppiCurrent
);
253 return STATUS_SUCCESS
;
257 UserDeleteW32Process(PPROCESSINFO ppiCurrent
)
259 if (ppiCurrent
->InputIdleEvent
)
261 EngDeleteEvent((PEVENT
)ppiCurrent
->InputIdleEvent
);
264 /* Close the startup desktop */
265 if(ppiCurrent
->rpdeskStartup
)
266 ObDereferenceObject(ppiCurrent
->rpdeskStartup
);
269 if (DBG_IS_CHANNEL_ENABLED(ppiCurrent
, DbgChUserObj
, WARN_LEVEL
))
271 TRACE_PPI(ppiCurrent
, UserObj
, "Dumping user handles now that process info %p is gets freed.\n", ppiCurrent
);
272 DbgUserDumpHandleTable();
276 /* Free the PROCESSINFO */
277 ExFreePoolWithTag(ppiCurrent
, USERTAG_PROCESSINFO
);
282 Win32kProcessCallback(struct _EPROCESS
*Process
,
287 ASSERT(Process
->Peb
);
289 UserEnterExclusive();
293 Status
= CreateProcessInfo(Process
);
297 Status
= DestroyProcessInfo(Process
);
305 UserCreateThreadInfo(struct _ETHREAD
*Thread
)
307 struct _EPROCESS
*Process
;
309 PTHREADINFO ptiCurrent
;
311 NTSTATUS Status
= STATUS_SUCCESS
;
313 LARGE_INTEGER LargeTickCount
;
315 Process
= Thread
->ThreadsProcess
;
317 pTeb
= NtCurrentTeb();
321 ptiCurrent
= ExAllocatePoolWithTag(NonPagedPool
,
324 if (ptiCurrent
== NULL
)
326 ERR_CH(UserThread
, "Failed to allocate pti for TID %p\n", Thread
->Cid
.UniqueThread
);
327 return STATUS_NO_MEMORY
;
330 TRACE_CH(UserThread
,"Create pti 0x%p eThread 0x%p\n", ptiCurrent
, Thread
);
332 RtlZeroMemory(ptiCurrent
, sizeof(THREADINFO
));
334 /* Initialize the THREADINFO */
336 PsSetThreadWin32Thread(Thread
, ptiCurrent
, NULL
);
337 IntReferenceThreadInfo(ptiCurrent
);
338 ptiCurrent
->pEThread
= Thread
;
339 ptiCurrent
->ppi
= PsGetProcessWin32Process(Process
);
340 IntReferenceProcessInfo(ptiCurrent
->ppi
);
341 pTeb
->Win32ThreadInfo
= ptiCurrent
;
342 ptiCurrent
->pClientInfo
= (PCLIENTINFO
)pTeb
->Win32ClientInfo
;
344 TRACE_CH(UserThread
, "Allocated pti 0x%p for TID %p\n", ptiCurrent
, Thread
->Cid
.UniqueThread
);
346 InitializeListHead(&ptiCurrent
->WindowListHead
);
347 InitializeListHead(&ptiCurrent
->W32CallbackListHead
);
348 InitializeListHead(&ptiCurrent
->PostedMessagesListHead
);
349 InitializeListHead(&ptiCurrent
->SentMessagesListHead
);
350 InitializeListHead(&ptiCurrent
->DispatchingMessagesHead
);
351 InitializeListHead(&ptiCurrent
->LocalDispatchingMessagesHead
);
352 InitializeListHead(&ptiCurrent
->PtiLink
);
353 for (i
= 0; i
< NB_HOOKS
; i
++)
355 InitializeListHead(&ptiCurrent
->aphkStart
[i
]);
357 ptiCurrent
->ptiSibling
= ptiCurrent
->ppi
->ptiList
;
358 ptiCurrent
->ppi
->ptiList
= ptiCurrent
;
359 ptiCurrent
->ppi
->cThreads
++;
361 ptiCurrent
->hEventQueueClient
= NULL
;
362 Status
= ZwCreateEvent(&ptiCurrent
->hEventQueueClient
, EVENT_ALL_ACCESS
,
363 NULL
, SynchronizationEvent
, FALSE
);
364 if (!NT_SUCCESS(Status
))
366 ERR_CH(UserThread
, "Event creation failed, Status 0x%08x.\n", Status
);
369 Status
= ObReferenceObjectByHandle(ptiCurrent
->hEventQueueClient
, 0,
370 *ExEventObjectType
, KernelMode
,
371 (PVOID
*)&ptiCurrent
->pEventQueueServer
, NULL
);
372 if (!NT_SUCCESS(Status
))
374 ERR_CH(UserThread
, "Failed referencing the event object, Status 0x%08x.\n", Status
);
375 ZwClose(ptiCurrent
->hEventQueueClient
);
376 ptiCurrent
->hEventQueueClient
= NULL
;
380 KeQueryTickCount(&LargeTickCount
);
381 ptiCurrent
->timeLast
= LargeTickCount
.u
.LowPart
;
383 ptiCurrent
->MessageQueue
= MsqCreateMessageQueue(ptiCurrent
);
384 if(ptiCurrent
->MessageQueue
== NULL
)
386 ERR_CH(UserThread
,"Failed to allocate message loop\n");
387 Status
= STATUS_NO_MEMORY
;
390 ptiCurrent
->KeyboardLayout
= W32kGetDefaultKeyLayout();
391 if (ptiCurrent
->KeyboardLayout
)
392 UserReferenceObject(ptiCurrent
->KeyboardLayout
);
393 ptiCurrent
->TIF_flags
&= ~TIF_INCLEANUP
;
394 if (Process
== gpepCSRSS
) /* If this thread is owned by CSRSS, mark it as such */
395 ptiCurrent
->TIF_flags
|= TIF_CSRSSTHREAD
;
396 ptiCurrent
->pcti
= &ptiCurrent
->cti
;
398 /* Initialize the CLIENTINFO */
399 pci
= (PCLIENTINFO
)pTeb
->Win32ClientInfo
;
400 RtlZeroMemory(pci
, sizeof(CLIENTINFO
));
401 pci
->ppi
= ptiCurrent
->ppi
;
402 pci
->fsHooks
= ptiCurrent
->fsHooks
;
403 pci
->dwTIFlags
= ptiCurrent
->TIF_flags
;
404 if (ptiCurrent
->KeyboardLayout
)
406 pci
->hKL
= ptiCurrent
->KeyboardLayout
->hkl
;
407 pci
->CodePage
= ptiCurrent
->KeyboardLayout
->CodePage
;
410 /* Assign a default window station and desktop to the process */
411 /* Do not try to open a desktop or window station before winlogon initializes */
412 if(ptiCurrent
->ppi
->hdeskStartup
== NULL
&& LogonProcess
!= NULL
)
414 HWINSTA hWinSta
= NULL
;
416 UNICODE_STRING DesktopPath
;
418 PRTL_USER_PROCESS_PARAMETERS ProcessParams
;
421 * inherit the thread desktop and process window station (if not yet inherited) from the process startup
422 * info structure. See documentation of CreateProcess()
424 ProcessParams
= pTeb
->ProcessEnvironmentBlock
->ProcessParameters
;
426 Status
= STATUS_UNSUCCESSFUL
;
427 if(ProcessParams
&& ProcessParams
->DesktopInfo
.Length
> 0)
429 Status
= IntSafeCopyUnicodeStringTerminateNULL(&DesktopPath
, &ProcessParams
->DesktopInfo
);
431 if(!NT_SUCCESS(Status
))
433 RtlInitUnicodeString(&DesktopPath
, NULL
);
436 Status
= IntParseDesktopPath(Process
,
441 if (DesktopPath
.Buffer
)
442 ExFreePoolWithTag(DesktopPath
.Buffer
, TAG_STRING
);
444 if(!NT_SUCCESS(Status
))
446 ERR_CH(UserThread
, "Failed to assign default dekstop and winsta to process\n");
450 if(!UserSetProcessWindowStation(hWinSta
))
452 Status
= STATUS_UNSUCCESSFUL
;
453 ERR_CH(UserThread
,"Failed to set initial process winsta\n");
457 /* Validate the new desktop. */
458 Status
= IntValidateDesktopHandle(hDesk
, UserMode
, 0, &pdesk
);
459 if(!NT_SUCCESS(Status
))
461 ERR_CH(UserThread
,"Failed to validate initial desktop handle\n");
465 /* Store the parsed desktop as the initial desktop */
466 ptiCurrent
->ppi
->hdeskStartup
= hDesk
;
467 ptiCurrent
->ppi
->rpdeskStartup
= pdesk
;
470 if (ptiCurrent
->ppi
->hdeskStartup
!= NULL
)
472 if (!IntSetThreadDesktop(ptiCurrent
->ppi
->hdeskStartup
, FALSE
))
474 ERR_CH(UserThread
,"Failed to set thread desktop\n");
475 Status
= STATUS_UNSUCCESSFUL
;
480 /* mark the thread as fully initialized */
481 ptiCurrent
->TIF_flags
|= TIF_GUITHREADINITIALIZED
;
483 if (!(ptiCurrent
->ppi
->W32PF_flags
& (W32PF_ALLOWFOREGROUNDACTIVATE
| W32PF_APPSTARTING
)) &&
484 (gptiForeground
&& gptiForeground
->ppi
== ptiCurrent
->ppi
))
486 ptiCurrent
->TIF_flags
|= TIF_ALLOWFOREGROUNDACTIVATE
;
488 ptiCurrent
->pClientInfo
->dwTIFlags
= ptiCurrent
->TIF_flags
;
489 TRACE_CH(UserThread
,"UserCreateW32Thread pti 0x%p\n",ptiCurrent
);
490 return STATUS_SUCCESS
;
493 ERR_CH(UserThread
,"UserCreateThreadInfo failed! Freeing pti 0x%p for TID %p\n", ptiCurrent
, Thread
->Cid
.UniqueThread
);
494 UserDestroyThreadInfo(Thread
);
499 Called from IntDereferenceThreadInfo.
502 UserDeleteW32Thread(PTHREADINFO pti
)
504 PPROCESSINFO ppi
= pti
->ppi
;
506 TRACE_CH(UserThread
,"UserDeleteW32Thread pti 0x%p\n",pti
);
508 /* Free the message queue */
509 if (pti
->MessageQueue
)
511 MsqDestroyMessageQueue(pti
);
514 MsqCleanupThreadMsgs(pti
);
516 ExFreePoolWithTag(pti
, USERTAG_THREADINFO
);
518 IntDereferenceProcessInfo(ppi
);
523 UserDestroyThreadInfo(struct _ETHREAD
*Thread
)
526 PSINGLE_LIST_ENTRY psle
;
527 PPROCESSINFO ppiCurrent
;
528 struct _EPROCESS
*Process
;
529 PTHREADINFO ptiCurrent
;
531 Process
= Thread
->ThreadsProcess
;
533 /* Get the Win32 Thread */
534 ptiCurrent
= PsGetThreadWin32Thread(Thread
);
538 TRACE_CH(UserThread
,"Destroying pti 0x%p eThread 0x%p\n", ptiCurrent
, Thread
);
540 ptiCurrent
->TIF_flags
|= TIF_INCLEANUP
;
541 ptiCurrent
->pClientInfo
->dwTIFlags
= ptiCurrent
->TIF_flags
;
543 ppiCurrent
= ptiCurrent
->ppi
;
546 IsRemoveAttachThread(ptiCurrent
);
548 ptiCurrent
->TIF_flags
|= TIF_DONTATTACHQUEUE
;
549 ptiCurrent
->pClientInfo
->dwTIFlags
= ptiCurrent
->TIF_flags
;
551 /* Decrement thread count and check if its 0 */
552 ppiCurrent
->cThreads
--;
554 if(ptiCurrent
->TIF_flags
& TIF_GUITHREADINITIALIZED
)
556 /* Do now some process cleanup that requires a valid win32 thread */
557 if(ptiCurrent
->ppi
->cThreads
== 0)
559 /* Check if we have registered the user api hook */
560 if(ptiCurrent
->ppi
== ppiUahServer
)
562 /* Unregister the api hook */
563 UserUnregisterUserApiHook();
566 /* Notify logon application to restart shell if needed */
567 if(ptiCurrent
->pDeskInfo
)
569 if(ptiCurrent
->pDeskInfo
->ppiShellProcess
== ppiCurrent
)
571 DWORD ExitCode
= PsGetProcessExitStatus(Process
);
573 TRACE_CH(UserProcess
, "Shell process is exiting (%lu)\n", ExitCode
);
575 UserPostMessage(hwndSAS
,
580 ptiCurrent
->pDeskInfo
->ppiShellProcess
= NULL
;
585 DceFreeThreadDCE(ptiCurrent
);
586 DestroyTimersForThread(ptiCurrent
);
587 KeSetEvent(ptiCurrent
->pEventQueueServer
, IO_NO_INCREMENT
, FALSE
);
588 UnregisterThreadHotKeys(ptiCurrent
);
590 if (!UserDestroyObjectsForOwner(gHandleTable
, ptiCurrent
))
592 DPRINT1("Failed to delete objects belonging to thread %p. This is VERY BAD!.\n", ptiCurrent
);
594 return STATUS_UNSUCCESSFUL
;
597 if (ppiCurrent
&& ppiCurrent
->ptiList
== ptiCurrent
&& !ptiCurrent
->ptiSibling
&&
598 ppiCurrent
->W32PF_flags
& W32PF_CLASSESREGISTERED
)
600 TRACE_CH(UserThread
,"DestroyProcessClasses\n");
601 /* no process windows should exist at this point, or the function will assert! */
602 DestroyProcessClasses(ppiCurrent
);
603 ppiCurrent
->W32PF_flags
&= ~W32PF_CLASSESREGISTERED
;
606 IntBlockInput(ptiCurrent
, FALSE
);
607 IntCleanupThreadCallbacks(ptiCurrent
);
609 /* cleanup user object references stack */
610 psle
= PopEntryList(&ptiCurrent
->ReferencesList
);
613 PUSER_REFERENCE_ENTRY ref
= CONTAINING_RECORD(psle
, USER_REFERENCE_ENTRY
, Entry
);
614 TRACE_CH(UserThread
,"thread clean: remove reference obj 0x%p\n",ref
->obj
);
615 UserDereferenceObject(ref
->obj
);
617 psle
= PopEntryList(&ptiCurrent
->ReferencesList
);
621 /* Find the THREADINFO in the PROCESSINFO's list */
622 ppti
= &ppiCurrent
->ptiList
;
623 while (*ppti
!= NULL
&& *ppti
!= ptiCurrent
)
625 ppti
= &((*ppti
)->ptiSibling
);
628 /* we must have found it */
629 ASSERT(*ppti
== ptiCurrent
);
631 /* Remove it from the list */
632 *ppti
= ptiCurrent
->ptiSibling
;
634 if (ptiCurrent
->KeyboardLayout
)
635 UserDereferenceObject(ptiCurrent
->KeyboardLayout
);
637 if (gptiForeground
== ptiCurrent
)
639 // IntNotifyWinEvent(EVENT_OBJECT_FOCUS, NULL, OBJID_CLIENT, CHILDID_SELF, 0);
640 // IntNotifyWinEvent(EVENT_SYSTEM_FOREGROUND, NULL, OBJID_WINDOW, CHILDID_SELF, 0);
642 gptiForeground
= NULL
;
645 // Fixes CORE-6384 & CORE-7030.
646 /* if (ptiLastInput == ptiCurrent)
648 if (!ppiCurrent->ptiList)
649 ptiLastInput = gptiForeground;
651 ptiLastInput = ppiCurrent->ptiList;
652 ERR_CH(UserThread,"DTI: ptiLastInput is Cleared!!\n");
655 TRACE_CH(UserThread
,"Freeing pti 0x%p\n", ptiCurrent
);
657 IntSetThreadDesktop(NULL
, TRUE
);
659 if (ptiCurrent
->hEventQueueClient
!= NULL
)
661 ZwClose(ptiCurrent
->hEventQueueClient
);
662 ObDereferenceObject(ptiCurrent
->pEventQueueServer
);
664 ptiCurrent
->hEventQueueClient
= NULL
;
666 /* The thread is dying */
667 PsSetThreadWin32Thread(ptiCurrent
->pEThread
, NULL
, ptiCurrent
);
668 ptiCurrent
->pEThread
= NULL
;
670 /* Free the THREADINFO */
671 IntDereferenceThreadInfo(ptiCurrent
);
673 return STATUS_SUCCESS
;
678 Win32kThreadCallback(struct _ETHREAD
*Thread
,
679 PSW32THREADCALLOUTTYPE Type
)
683 UserEnterExclusive();
685 ASSERT(NtCurrentTeb());
687 if (Type
== PsW32ThreadCalloutInitialize
)
689 ASSERT(PsGetThreadWin32Thread(Thread
) == NULL
);
690 Status
= UserCreateThreadInfo(Thread
);
694 ASSERT(PsGetThreadWin32Thread(Thread
) != NULL
);
695 Status
= UserDestroyThreadInfo(Thread
);
704 C_ASSERT(sizeof(SERVERINFO
) <= PAGE_SIZE
);
710 if (!NT_SUCCESS(Status)) \
712 DPRINT1("Failed '%s' (0x%lx)\n", #x, Status); \
717 * This definition doesn't work
723 IN PDRIVER_OBJECT DriverObject
,
724 IN PUNICODE_STRING RegistryPath
)
728 WIN32_CALLOUTS_FPNS CalloutData
= {0};
729 PVOID GlobalUserHeapBase
= NULL
;
732 * Register user mode call interface
733 * (system service table index = 1)
735 Result
= KeAddSystemServiceTable(Win32kSSDT
,
737 Win32kNumberOfSysCalls
,
742 DPRINT1("Adding system services failed!\n");
743 return STATUS_UNSUCCESSFUL
;
746 hModuleWin
= MmPageEntireDriver(DriverEntry
);
747 DPRINT("Win32k hInstance 0x%p!\n",hModuleWin
);
749 /* Register Object Manager Callbacks */
750 CalloutData
.ProcessCallout
= Win32kProcessCallback
;
751 CalloutData
.ThreadCallout
= Win32kThreadCallback
;
752 CalloutData
.WindowStationParseProcedure
= IntWinStaObjectParse
;
753 CalloutData
.WindowStationDeleteProcedure
= IntWinStaObjectDelete
;
754 CalloutData
.WindowStationOkToCloseProcedure
= IntWinstaOkToClose
;
755 CalloutData
.DesktopOkToCloseProcedure
= IntDesktopOkToClose
;
756 CalloutData
.DesktopDeleteProcedure
= IntDesktopObjectDelete
;
757 CalloutData
.DesktopCloseProcedure
= IntDesktopObjectClose
;
758 CalloutData
.DesktopOpenProcedure
= IntDesktopObjectOpen
;
759 CalloutData
.BatchFlushRoutine
= NtGdiFlushUserBatch
;
761 /* Register our per-process and per-thread structures. */
762 PsEstablishWin32Callouts((PWIN32_CALLOUTS_FPNS
)&CalloutData
);
764 /* Register service hook callbacks */
766 KdSystemDebugControl('CsoR', DbgPreServiceHook
, ID_Win32PreServiceHook
, 0, 0, 0, 0);
767 KdSystemDebugControl('CsoR', DbgPostServiceHook
, ID_Win32PostServiceHook
, 0, 0, 0, 0);
770 /* Create the global USER heap */
771 GlobalUserHeap
= UserCreateHeap(&GlobalUserHeapSection
,
773 1 * 1024 * 1024); /* FIXME: 1 MB for now... */
774 if (GlobalUserHeap
== NULL
)
776 DPRINT1("Failed to initialize the global heap!\n");
777 return STATUS_UNSUCCESSFUL
;
780 /* Allocate global server info structure */
781 gpsi
= UserHeapAlloc(sizeof(SERVERINFO
));
784 DPRINT1("Failed allocate server info structure!\n");
785 return STATUS_UNSUCCESSFUL
;
788 RtlZeroMemory(gpsi
, sizeof(SERVERINFO
));
789 DPRINT("Global Server Data -> %p\n", gpsi
);
791 NT_ROF(InitGdiHandleTable());
792 NT_ROF(InitPaletteImpl());
794 /* Create stock objects, ie. precreated objects commonly
795 used by win32 applications */
796 CreateStockObjects();
797 CreateSysColorObjects();
799 NT_ROF(InitBrushImpl());
800 NT_ROF(InitPDEVImpl());
801 NT_ROF(InitLDEVImpl());
802 NT_ROF(InitDeviceImpl());
803 NT_ROF(InitDcImpl());
804 NT_ROF(InitUserImpl());
805 NT_ROF(InitWindowStationImpl());
806 NT_ROF(InitDesktopImpl());
807 NT_ROF(InitInputImpl());
808 NT_ROF(InitKeyboardImpl());
809 NT_ROF(MsqInitializeImpl());
810 NT_ROF(InitTimerImpl());
811 NT_ROF(InitDCEImpl());
813 /* Initialize FreeType library */
814 if (!InitFontSupport())
816 DPRINT1("Unable to initialize font support\n");
820 gusLanguageID
= UserGetLanguageID();
822 return STATUS_SUCCESS
;