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 (gpidLogon
== ppiCurrent
->peProcess
->UniqueProcessId
)
219 /* Close the current window station */
220 UserSetProcessWindowStation(NULL
);
222 if (gppiInputProvider
== ppiCurrent
) gppiInputProvider
= NULL
;
224 /* Remove it from the list */
226 while (*pppi
!= NULL
&& *pppi
!= ppiCurrent
)
227 pppi
= &(*pppi
)->ppiNext
;
229 ASSERT(*pppi
== ppiCurrent
);
231 *pppi
= ppiCurrent
->ppiNext
;
233 if(ppiCurrent
->hdeskStartup
)
235 ZwClose(ppiCurrent
->hdeskStartup
);
236 ppiCurrent
->hdeskStartup
= NULL
;
239 #ifdef NEW_CURSORICON
240 /* Clean up the process icon cache */
241 IntCleanupCurIconCache(ppiCurrent
);
244 /* The process is dying */
245 PsSetProcessWin32Process(Process
, NULL
, ppiCurrent
);
246 ppiCurrent
->peProcess
= NULL
;
248 /* At last, dereference */
249 IntDereferenceProcessInfo(ppiCurrent
);
251 return STATUS_SUCCESS
;
255 UserDeleteW32Process(PPROCESSINFO ppiCurrent
)
257 if (ppiCurrent
->InputIdleEvent
)
259 EngDeleteEvent((PEVENT
)ppiCurrent
->InputIdleEvent
);
262 /* Close the startup desktop */
263 if(ppiCurrent
->rpdeskStartup
)
264 ObDereferenceObject(ppiCurrent
->rpdeskStartup
);
267 if (DBG_IS_CHANNEL_ENABLED(ppiCurrent
, DbgChUserObj
, WARN_LEVEL
))
269 TRACE_PPI(ppiCurrent
, UserObj
, "Dumping user handles now that process info %p is gets freed.\n", ppiCurrent
);
270 DbgUserDumpHandleTable();
274 /* Free the PROCESSINFO */
275 ExFreePoolWithTag(ppiCurrent
, USERTAG_PROCESSINFO
);
280 Win32kProcessCallback(struct _EPROCESS
*Process
,
285 ASSERT(Process
->Peb
);
287 UserEnterExclusive();
291 Status
= CreateProcessInfo(Process
);
295 Status
= DestroyProcessInfo(Process
);
303 UserCreateThreadInfo(struct _ETHREAD
*Thread
)
305 struct _EPROCESS
*Process
;
307 PTHREADINFO ptiCurrent
;
309 NTSTATUS Status
= STATUS_SUCCESS
;
311 LARGE_INTEGER LargeTickCount
;
313 Process
= Thread
->ThreadsProcess
;
315 pTeb
= NtCurrentTeb();
319 ptiCurrent
= ExAllocatePoolWithTag(NonPagedPool
,
322 if (ptiCurrent
== NULL
)
324 ERR_CH(UserThread
, "Failed to allocate pti for TID %p\n", Thread
->Cid
.UniqueThread
);
325 return STATUS_NO_MEMORY
;
328 TRACE_CH(UserThread
,"Create pti 0x%p eThread 0x%p\n", ptiCurrent
, Thread
);
330 RtlZeroMemory(ptiCurrent
, sizeof(THREADINFO
));
332 /* Initialize the THREADINFO */
334 PsSetThreadWin32Thread(Thread
, ptiCurrent
, NULL
);
335 IntReferenceThreadInfo(ptiCurrent
);
336 ptiCurrent
->pEThread
= Thread
;
337 ptiCurrent
->ppi
= PsGetProcessWin32Process(Process
);
338 IntReferenceProcessInfo(ptiCurrent
->ppi
);
339 pTeb
->Win32ThreadInfo
= ptiCurrent
;
340 ptiCurrent
->pClientInfo
= (PCLIENTINFO
)pTeb
->Win32ClientInfo
;
342 TRACE_CH(UserThread
, "Allocated pti 0x%p for TID %p\n", ptiCurrent
, Thread
->Cid
.UniqueThread
);
344 InitializeListHead(&ptiCurrent
->WindowListHead
);
345 InitializeListHead(&ptiCurrent
->W32CallbackListHead
);
346 InitializeListHead(&ptiCurrent
->PostedMessagesListHead
);
347 InitializeListHead(&ptiCurrent
->SentMessagesListHead
);
348 InitializeListHead(&ptiCurrent
->DispatchingMessagesHead
);
349 InitializeListHead(&ptiCurrent
->LocalDispatchingMessagesHead
);
350 InitializeListHead(&ptiCurrent
->PtiLink
);
351 for (i
= 0; i
< NB_HOOKS
; i
++)
353 InitializeListHead(&ptiCurrent
->aphkStart
[i
]);
355 ptiCurrent
->ptiSibling
= ptiCurrent
->ppi
->ptiList
;
356 ptiCurrent
->ppi
->ptiList
= ptiCurrent
;
357 ptiCurrent
->ppi
->cThreads
++;
359 ptiCurrent
->hEventQueueClient
= NULL
;
360 Status
= ZwCreateEvent(&ptiCurrent
->hEventQueueClient
, EVENT_ALL_ACCESS
,
361 NULL
, SynchronizationEvent
, FALSE
);
362 if (!NT_SUCCESS(Status
))
364 ERR_CH(UserThread
, "Event creation failed, Status 0x%08x.\n", Status
);
367 Status
= ObReferenceObjectByHandle(ptiCurrent
->hEventQueueClient
, 0,
368 *ExEventObjectType
, KernelMode
,
369 (PVOID
*)&ptiCurrent
->pEventQueueServer
, NULL
);
370 if (!NT_SUCCESS(Status
))
372 ERR_CH(UserThread
, "Failed referencing the event object, Status 0x%08x.\n", Status
);
373 ZwClose(ptiCurrent
->hEventQueueClient
);
374 ptiCurrent
->hEventQueueClient
= NULL
;
378 KeQueryTickCount(&LargeTickCount
);
379 ptiCurrent
->timeLast
= LargeTickCount
.u
.LowPart
;
381 ptiCurrent
->MessageQueue
= MsqCreateMessageQueue(ptiCurrent
);
382 if(ptiCurrent
->MessageQueue
== NULL
)
384 ERR_CH(UserThread
,"Failed to allocate message loop\n");
385 Status
= STATUS_NO_MEMORY
;
388 ptiCurrent
->KeyboardLayout
= W32kGetDefaultKeyLayout();
389 if (ptiCurrent
->KeyboardLayout
)
390 UserReferenceObject(ptiCurrent
->KeyboardLayout
);
391 ptiCurrent
->TIF_flags
&= ~TIF_INCLEANUP
;
392 if (Process
== gpepCSRSS
) /* If this thread is owned by CSRSS, mark it as such */
393 ptiCurrent
->TIF_flags
|= TIF_CSRSSTHREAD
;
394 ptiCurrent
->pcti
= &ptiCurrent
->cti
;
396 /* Initialize the CLIENTINFO */
397 pci
= (PCLIENTINFO
)pTeb
->Win32ClientInfo
;
398 RtlZeroMemory(pci
, sizeof(CLIENTINFO
));
399 pci
->ppi
= ptiCurrent
->ppi
;
400 pci
->fsHooks
= ptiCurrent
->fsHooks
;
401 pci
->dwTIFlags
= ptiCurrent
->TIF_flags
;
402 if (ptiCurrent
->KeyboardLayout
)
404 pci
->hKL
= ptiCurrent
->KeyboardLayout
->hkl
;
405 pci
->CodePage
= ptiCurrent
->KeyboardLayout
->CodePage
;
408 /* Assign a default window station and desktop to the process */
409 /* Do not try to open a desktop or window station before winlogon initializes */
410 if (ptiCurrent
->ppi
->hdeskStartup
== NULL
&& gpidLogon
!= 0)
412 HWINSTA hWinSta
= NULL
;
414 UNICODE_STRING DesktopPath
;
416 PRTL_USER_PROCESS_PARAMETERS ProcessParams
;
419 * inherit the thread desktop and process window station (if not yet inherited) from the process startup
420 * info structure. See documentation of CreateProcess()
422 ProcessParams
= pTeb
->ProcessEnvironmentBlock
->ProcessParameters
;
424 Status
= STATUS_UNSUCCESSFUL
;
425 if(ProcessParams
&& ProcessParams
->DesktopInfo
.Length
> 0)
427 Status
= IntSafeCopyUnicodeStringTerminateNULL(&DesktopPath
, &ProcessParams
->DesktopInfo
);
429 if(!NT_SUCCESS(Status
))
431 RtlInitUnicodeString(&DesktopPath
, NULL
);
434 Status
= IntParseDesktopPath(Process
,
439 if (DesktopPath
.Buffer
)
440 ExFreePoolWithTag(DesktopPath
.Buffer
, TAG_STRING
);
442 if(!NT_SUCCESS(Status
))
444 ERR_CH(UserThread
, "Failed to assign default dekstop and winsta to process\n");
448 if(!UserSetProcessWindowStation(hWinSta
))
450 Status
= STATUS_UNSUCCESSFUL
;
451 ERR_CH(UserThread
,"Failed to set initial process winsta\n");
455 /* Validate the new desktop. */
456 Status
= IntValidateDesktopHandle(hDesk
, UserMode
, 0, &pdesk
);
457 if(!NT_SUCCESS(Status
))
459 ERR_CH(UserThread
,"Failed to validate initial desktop handle\n");
463 /* Store the parsed desktop as the initial desktop */
464 ptiCurrent
->ppi
->hdeskStartup
= hDesk
;
465 ptiCurrent
->ppi
->rpdeskStartup
= pdesk
;
468 if (ptiCurrent
->ppi
->hdeskStartup
!= NULL
)
470 if (!IntSetThreadDesktop(ptiCurrent
->ppi
->hdeskStartup
, FALSE
))
472 ERR_CH(UserThread
,"Failed to set thread desktop\n");
473 Status
= STATUS_UNSUCCESSFUL
;
478 /* mark the thread as fully initialized */
479 ptiCurrent
->TIF_flags
|= TIF_GUITHREADINITIALIZED
;
481 if (!(ptiCurrent
->ppi
->W32PF_flags
& (W32PF_ALLOWFOREGROUNDACTIVATE
| W32PF_APPSTARTING
)) &&
482 (gptiForeground
&& gptiForeground
->ppi
== ptiCurrent
->ppi
))
484 ptiCurrent
->TIF_flags
|= TIF_ALLOWFOREGROUNDACTIVATE
;
486 ptiCurrent
->pClientInfo
->dwTIFlags
= ptiCurrent
->TIF_flags
;
487 TRACE_CH(UserThread
,"UserCreateW32Thread pti 0x%p\n",ptiCurrent
);
488 return STATUS_SUCCESS
;
491 ERR_CH(UserThread
,"UserCreateThreadInfo failed! Freeing pti 0x%p for TID %p\n", ptiCurrent
, Thread
->Cid
.UniqueThread
);
492 UserDestroyThreadInfo(Thread
);
497 Called from IntDereferenceThreadInfo.
500 UserDeleteW32Thread(PTHREADINFO pti
)
502 PPROCESSINFO ppi
= pti
->ppi
;
504 TRACE_CH(UserThread
,"UserDeleteW32Thread pti 0x%p\n",pti
);
506 /* Free the message queue */
507 if (pti
->MessageQueue
)
509 MsqDestroyMessageQueue(pti
);
512 MsqCleanupThreadMsgs(pti
);
514 ExFreePoolWithTag(pti
, USERTAG_THREADINFO
);
516 IntDereferenceProcessInfo(ppi
);
521 UserDestroyThreadInfo(struct _ETHREAD
*Thread
)
524 PSINGLE_LIST_ENTRY psle
;
525 PPROCESSINFO ppiCurrent
;
526 struct _EPROCESS
*Process
;
527 PTHREADINFO ptiCurrent
;
529 Process
= Thread
->ThreadsProcess
;
531 /* Get the Win32 Thread */
532 ptiCurrent
= PsGetThreadWin32Thread(Thread
);
536 TRACE_CH(UserThread
,"Destroying pti 0x%p eThread 0x%p\n", ptiCurrent
, Thread
);
538 ptiCurrent
->TIF_flags
|= TIF_INCLEANUP
;
539 ptiCurrent
->pClientInfo
->dwTIFlags
= ptiCurrent
->TIF_flags
;
541 ppiCurrent
= ptiCurrent
->ppi
;
544 IsRemoveAttachThread(ptiCurrent
);
546 ptiCurrent
->TIF_flags
|= TIF_DONTATTACHQUEUE
;
547 ptiCurrent
->pClientInfo
->dwTIFlags
= ptiCurrent
->TIF_flags
;
549 /* Decrement thread count and check if its 0 */
550 ppiCurrent
->cThreads
--;
552 if(ptiCurrent
->TIF_flags
& TIF_GUITHREADINITIALIZED
)
554 /* Do now some process cleanup that requires a valid win32 thread */
555 if(ptiCurrent
->ppi
->cThreads
== 0)
557 /* Check if we have registered the user api hook */
558 if(ptiCurrent
->ppi
== ppiUahServer
)
560 /* Unregister the api hook */
561 UserUnregisterUserApiHook();
564 /* Notify logon application to restart shell if needed */
565 if(ptiCurrent
->pDeskInfo
)
567 if(ptiCurrent
->pDeskInfo
->ppiShellProcess
== ppiCurrent
)
569 DWORD ExitCode
= PsGetProcessExitStatus(Process
);
571 TRACE_CH(UserProcess
, "Shell process is exiting (%lu)\n", ExitCode
);
573 UserPostMessage(hwndSAS
,
578 ptiCurrent
->pDeskInfo
->ppiShellProcess
= NULL
;
583 DceFreeThreadDCE(ptiCurrent
);
584 DestroyTimersForThread(ptiCurrent
);
585 KeSetEvent(ptiCurrent
->pEventQueueServer
, IO_NO_INCREMENT
, FALSE
);
586 UnregisterThreadHotKeys(ptiCurrent
);
588 if (!UserDestroyObjectsForOwner(gHandleTable
, ptiCurrent
))
590 DPRINT1("Failed to delete objects belonging to thread %p. This is VERY BAD!.\n", ptiCurrent
);
592 return STATUS_UNSUCCESSFUL
;
595 if (ppiCurrent
&& ppiCurrent
->ptiList
== ptiCurrent
&& !ptiCurrent
->ptiSibling
&&
596 ppiCurrent
->W32PF_flags
& W32PF_CLASSESREGISTERED
)
598 TRACE_CH(UserThread
,"DestroyProcessClasses\n");
599 /* no process windows should exist at this point, or the function will assert! */
600 DestroyProcessClasses(ppiCurrent
);
601 ppiCurrent
->W32PF_flags
&= ~W32PF_CLASSESREGISTERED
;
604 IntBlockInput(ptiCurrent
, FALSE
);
605 IntCleanupThreadCallbacks(ptiCurrent
);
607 /* cleanup user object references stack */
608 psle
= PopEntryList(&ptiCurrent
->ReferencesList
);
611 PUSER_REFERENCE_ENTRY ref
= CONTAINING_RECORD(psle
, USER_REFERENCE_ENTRY
, Entry
);
612 TRACE_CH(UserThread
,"thread clean: remove reference obj 0x%p\n",ref
->obj
);
613 UserDereferenceObject(ref
->obj
);
615 psle
= PopEntryList(&ptiCurrent
->ReferencesList
);
619 /* Find the THREADINFO in the PROCESSINFO's list */
620 ppti
= &ppiCurrent
->ptiList
;
621 while (*ppti
!= NULL
&& *ppti
!= ptiCurrent
)
623 ppti
= &((*ppti
)->ptiSibling
);
626 /* we must have found it */
627 ASSERT(*ppti
== ptiCurrent
);
629 /* Remove it from the list */
630 *ppti
= ptiCurrent
->ptiSibling
;
632 if (ptiCurrent
->KeyboardLayout
)
633 UserDereferenceObject(ptiCurrent
->KeyboardLayout
);
635 if (gptiForeground
== ptiCurrent
)
637 // IntNotifyWinEvent(EVENT_OBJECT_FOCUS, NULL, OBJID_CLIENT, CHILDID_SELF, 0);
638 // IntNotifyWinEvent(EVENT_SYSTEM_FOREGROUND, NULL, OBJID_WINDOW, CHILDID_SELF, 0);
640 gptiForeground
= NULL
;
643 // Fixes CORE-6384 & CORE-7030.
644 /* if (ptiLastInput == ptiCurrent)
646 if (!ppiCurrent->ptiList)
647 ptiLastInput = gptiForeground;
649 ptiLastInput = ppiCurrent->ptiList;
650 ERR_CH(UserThread,"DTI: ptiLastInput is Cleared!!\n");
653 TRACE_CH(UserThread
,"Freeing pti 0x%p\n", ptiCurrent
);
655 IntSetThreadDesktop(NULL
, TRUE
);
657 if (ptiCurrent
->hEventQueueClient
!= NULL
)
659 ZwClose(ptiCurrent
->hEventQueueClient
);
660 ObDereferenceObject(ptiCurrent
->pEventQueueServer
);
662 ptiCurrent
->hEventQueueClient
= NULL
;
664 /* The thread is dying */
665 PsSetThreadWin32Thread(ptiCurrent
->pEThread
, NULL
, ptiCurrent
);
666 ptiCurrent
->pEThread
= NULL
;
668 /* Free the THREADINFO */
669 IntDereferenceThreadInfo(ptiCurrent
);
671 return STATUS_SUCCESS
;
676 Win32kThreadCallback(struct _ETHREAD
*Thread
,
677 PSW32THREADCALLOUTTYPE Type
)
681 UserEnterExclusive();
683 ASSERT(NtCurrentTeb());
685 if (Type
== PsW32ThreadCalloutInitialize
)
687 ASSERT(PsGetThreadWin32Thread(Thread
) == NULL
);
688 Status
= UserCreateThreadInfo(Thread
);
692 ASSERT(PsGetThreadWin32Thread(Thread
) != NULL
);
693 Status
= UserDestroyThreadInfo(Thread
);
702 C_ASSERT(sizeof(SERVERINFO
) <= PAGE_SIZE
);
708 if (!NT_SUCCESS(Status)) \
710 DPRINT1("Failed '%s' (0x%lx)\n", #x, Status); \
715 * This definition doesn't work
721 IN PDRIVER_OBJECT DriverObject
,
722 IN PUNICODE_STRING RegistryPath
)
726 WIN32_CALLOUTS_FPNS CalloutData
= {0};
727 PVOID GlobalUserHeapBase
= NULL
;
730 * Register user mode call interface
731 * (system service table index = 1)
733 Result
= KeAddSystemServiceTable(Win32kSSDT
,
735 Win32kNumberOfSysCalls
,
740 DPRINT1("Adding system services failed!\n");
741 return STATUS_UNSUCCESSFUL
;
744 hModuleWin
= MmPageEntireDriver(DriverEntry
);
745 DPRINT("Win32k hInstance 0x%p!\n",hModuleWin
);
747 /* Register Object Manager Callbacks */
748 CalloutData
.ProcessCallout
= Win32kProcessCallback
;
749 CalloutData
.ThreadCallout
= Win32kThreadCallback
;
750 // CalloutData.GlobalAtomTableCallout = NULL;
751 // CalloutData.PowerEventCallout = NULL;
752 // CalloutData.PowerStateCallout = NULL;
753 // CalloutData.JobCallout = NULL;
754 CalloutData
.BatchFlushRoutine
= NtGdiFlushUserBatch
;
755 CalloutData
.DesktopOpenProcedure
= IntDesktopObjectOpen
;
756 CalloutData
.DesktopOkToCloseProcedure
= IntDesktopOkToClose
;
757 CalloutData
.DesktopCloseProcedure
= IntDesktopObjectClose
;
758 CalloutData
.DesktopDeleteProcedure
= IntDesktopObjectDelete
;
759 CalloutData
.WindowStationOkToCloseProcedure
= IntWinstaOkToClose
;
760 // CalloutData.WindowStationCloseProcedure = NULL;
761 CalloutData
.WindowStationDeleteProcedure
= IntWinStaObjectDelete
;
762 CalloutData
.WindowStationParseProcedure
= IntWinStaObjectParse
;
763 // CalloutData.WindowStationOpenProcedure = NULL;
765 /* Register our per-process and per-thread structures. */
766 PsEstablishWin32Callouts(&CalloutData
);
768 /* Register service hook callbacks */
770 KdSystemDebugControl('CsoR', DbgPreServiceHook
, ID_Win32PreServiceHook
, 0, 0, 0, 0);
771 KdSystemDebugControl('CsoR', DbgPostServiceHook
, ID_Win32PostServiceHook
, 0, 0, 0, 0);
774 /* Create the global USER heap */
775 GlobalUserHeap
= UserCreateHeap(&GlobalUserHeapSection
,
777 1 * 1024 * 1024); /* FIXME: 1 MB for now... */
778 if (GlobalUserHeap
== NULL
)
780 DPRINT1("Failed to initialize the global heap!\n");
781 return STATUS_UNSUCCESSFUL
;
784 /* Allocate global server info structure */
785 gpsi
= UserHeapAlloc(sizeof(SERVERINFO
));
788 DPRINT1("Failed allocate server info structure!\n");
789 return STATUS_UNSUCCESSFUL
;
792 RtlZeroMemory(gpsi
, sizeof(SERVERINFO
));
793 DPRINT("Global Server Data -> %p\n", gpsi
);
795 NT_ROF(InitGdiHandleTable());
796 NT_ROF(InitPaletteImpl());
798 /* Create stock objects, ie. precreated objects commonly
799 used by win32 applications */
800 CreateStockObjects();
801 CreateSysColorObjects();
803 NT_ROF(InitBrushImpl());
804 NT_ROF(InitPDEVImpl());
805 NT_ROF(InitLDEVImpl());
806 NT_ROF(InitDeviceImpl());
807 NT_ROF(InitDcImpl());
808 NT_ROF(InitUserImpl());
809 NT_ROF(InitWindowStationImpl());
810 NT_ROF(InitDesktopImpl());
811 NT_ROF(InitInputImpl());
812 NT_ROF(InitKeyboardImpl());
813 NT_ROF(MsqInitializeImpl());
814 NT_ROF(InitTimerImpl());
815 NT_ROF(InitDCEImpl());
817 /* Initialize FreeType library */
818 if (!InitFontSupport())
820 DPRINT1("Unable to initialize font support\n");
824 gusLanguageID
= UserGetLanguageID();
826 return STATUS_SUCCESS
;