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 /* The process is dying */
242 PsSetProcessWin32Process(Process
, NULL
, ppiCurrent
);
243 ppiCurrent
->peProcess
= NULL
;
245 /* At last, dereference */
246 IntDereferenceProcessInfo(ppiCurrent
);
248 return STATUS_SUCCESS
;
252 UserDeleteW32Process(PPROCESSINFO ppiCurrent
)
254 if (ppiCurrent
->InputIdleEvent
)
256 EngDeleteEvent((PEVENT
)ppiCurrent
->InputIdleEvent
);
259 /* Close the startup desktop */
260 if(ppiCurrent
->rpdeskStartup
)
261 ObDereferenceObject(ppiCurrent
->rpdeskStartup
);
264 if (DBG_IS_CHANNEL_ENABLED(ppiCurrent
, DbgChUserObj
, WARN_LEVEL
))
266 TRACE_PPI(ppiCurrent
, UserObj
, "Dumping user handles now that process info %p is gets freed.\n", ppiCurrent
);
267 DbgUserDumpHandleTable();
271 /* Free the PROCESSINFO */
272 ExFreePoolWithTag(ppiCurrent
, USERTAG_PROCESSINFO
);
277 Win32kProcessCallback(struct _EPROCESS
*Process
,
282 ASSERT(Process
->Peb
);
284 UserEnterExclusive();
288 Status
= CreateProcessInfo(Process
);
292 Status
= DestroyProcessInfo(Process
);
300 UserCreateThreadInfo(struct _ETHREAD
*Thread
)
302 struct _EPROCESS
*Process
;
304 PTHREADINFO ptiCurrent
;
306 NTSTATUS Status
= STATUS_SUCCESS
;
308 LARGE_INTEGER LargeTickCount
;
310 Process
= Thread
->ThreadsProcess
;
312 pTeb
= NtCurrentTeb();
316 ptiCurrent
= ExAllocatePoolWithTag(NonPagedPool
,
319 if (ptiCurrent
== NULL
)
321 ERR_CH(UserThread
, "Failed to allocate pti for TID %p\n", Thread
->Cid
.UniqueThread
);
322 return STATUS_NO_MEMORY
;
325 TRACE_CH(UserThread
,"Create pti 0x%p eThread 0x%p\n", ptiCurrent
, Thread
);
327 RtlZeroMemory(ptiCurrent
, sizeof(THREADINFO
));
329 /* Initialize the THREADINFO */
331 PsSetThreadWin32Thread(Thread
, ptiCurrent
, NULL
);
332 IntReferenceThreadInfo(ptiCurrent
);
333 ptiCurrent
->pEThread
= Thread
;
334 ptiCurrent
->ppi
= PsGetProcessWin32Process(Process
);
335 IntReferenceProcessInfo(ptiCurrent
->ppi
);
336 pTeb
->Win32ThreadInfo
= ptiCurrent
;
337 ptiCurrent
->pClientInfo
= (PCLIENTINFO
)pTeb
->Win32ClientInfo
;
339 TRACE_CH(UserThread
, "Allocated pti 0x%p for TID %p\n", ptiCurrent
, Thread
->Cid
.UniqueThread
);
341 InitializeListHead(&ptiCurrent
->WindowListHead
);
342 InitializeListHead(&ptiCurrent
->W32CallbackListHead
);
343 InitializeListHead(&ptiCurrent
->PostedMessagesListHead
);
344 InitializeListHead(&ptiCurrent
->SentMessagesListHead
);
345 InitializeListHead(&ptiCurrent
->DispatchingMessagesHead
);
346 InitializeListHead(&ptiCurrent
->LocalDispatchingMessagesHead
);
347 InitializeListHead(&ptiCurrent
->PtiLink
);
348 for (i
= 0; i
< NB_HOOKS
; i
++)
350 InitializeListHead(&ptiCurrent
->aphkStart
[i
]);
352 ptiCurrent
->ptiSibling
= ptiCurrent
->ppi
->ptiList
;
353 ptiCurrent
->ppi
->ptiList
= ptiCurrent
;
354 ptiCurrent
->ppi
->cThreads
++;
356 ptiCurrent
->hEventQueueClient
= NULL
;
357 Status
= ZwCreateEvent(&ptiCurrent
->hEventQueueClient
, EVENT_ALL_ACCESS
,
358 NULL
, SynchronizationEvent
, FALSE
);
359 if (!NT_SUCCESS(Status
))
361 ERR_CH(UserThread
, "Event creation failed, Status 0x%08x.\n", Status
);
364 Status
= ObReferenceObjectByHandle(ptiCurrent
->hEventQueueClient
, 0,
365 *ExEventObjectType
, KernelMode
,
366 (PVOID
*)&ptiCurrent
->pEventQueueServer
, NULL
);
367 if (!NT_SUCCESS(Status
))
369 ERR_CH(UserThread
, "Failed referencing the event object, Status 0x%08x.\n", Status
);
370 ZwClose(ptiCurrent
->hEventQueueClient
);
371 ptiCurrent
->hEventQueueClient
= NULL
;
375 KeQueryTickCount(&LargeTickCount
);
376 ptiCurrent
->timeLast
= LargeTickCount
.u
.LowPart
;
378 ptiCurrent
->MessageQueue
= MsqCreateMessageQueue(ptiCurrent
);
379 if(ptiCurrent
->MessageQueue
== NULL
)
381 ERR_CH(UserThread
,"Failed to allocate message loop\n");
382 Status
= STATUS_NO_MEMORY
;
385 ptiCurrent
->KeyboardLayout
= W32kGetDefaultKeyLayout();
386 if (ptiCurrent
->KeyboardLayout
)
387 UserReferenceObject(ptiCurrent
->KeyboardLayout
);
388 ptiCurrent
->TIF_flags
&= ~TIF_INCLEANUP
;
389 if (Process
== gpepCSRSS
) /* If this thread is owned by CSRSS, mark it as such */
390 ptiCurrent
->TIF_flags
|= TIF_CSRSSTHREAD
;
391 ptiCurrent
->pcti
= &ptiCurrent
->cti
;
393 /* Initialize the CLIENTINFO */
394 pci
= (PCLIENTINFO
)pTeb
->Win32ClientInfo
;
395 RtlZeroMemory(pci
, sizeof(CLIENTINFO
));
396 pci
->ppi
= ptiCurrent
->ppi
;
397 pci
->fsHooks
= ptiCurrent
->fsHooks
;
398 pci
->dwTIFlags
= ptiCurrent
->TIF_flags
;
399 if (ptiCurrent
->KeyboardLayout
)
401 pci
->hKL
= ptiCurrent
->KeyboardLayout
->hkl
;
402 pci
->CodePage
= ptiCurrent
->KeyboardLayout
->CodePage
;
405 /* Assign a default window station and desktop to the process */
406 /* Do not try to open a desktop or window station before winlogon initializes */
407 if(ptiCurrent
->ppi
->hdeskStartup
== NULL
&& LogonProcess
!= NULL
)
409 HWINSTA hWinSta
= NULL
;
411 UNICODE_STRING DesktopPath
;
413 PRTL_USER_PROCESS_PARAMETERS ProcessParams
;
416 * inherit the thread desktop and process window station (if not yet inherited) from the process startup
417 * info structure. See documentation of CreateProcess()
419 ProcessParams
= pTeb
->ProcessEnvironmentBlock
->ProcessParameters
;
421 Status
= STATUS_UNSUCCESSFUL
;
422 if(ProcessParams
&& ProcessParams
->DesktopInfo
.Length
> 0)
424 Status
= IntSafeCopyUnicodeStringTerminateNULL(&DesktopPath
, &ProcessParams
->DesktopInfo
);
426 if(!NT_SUCCESS(Status
))
428 RtlInitUnicodeString(&DesktopPath
, NULL
);
431 Status
= IntParseDesktopPath(Process
,
436 if (DesktopPath
.Buffer
)
437 ExFreePoolWithTag(DesktopPath
.Buffer
, TAG_STRING
);
439 if(!NT_SUCCESS(Status
))
441 ERR_CH(UserThread
, "Failed to assign default dekstop and winsta to process\n");
445 if(!UserSetProcessWindowStation(hWinSta
))
447 Status
= STATUS_UNSUCCESSFUL
;
448 ERR_CH(UserThread
,"Failed to set initial process winsta\n");
452 /* Validate the new desktop. */
453 Status
= IntValidateDesktopHandle(hDesk
, UserMode
, 0, &pdesk
);
454 if(!NT_SUCCESS(Status
))
456 ERR_CH(UserThread
,"Failed to validate initial desktop handle\n");
460 /* Store the parsed desktop as the initial desktop */
461 ptiCurrent
->ppi
->hdeskStartup
= hDesk
;
462 ptiCurrent
->ppi
->rpdeskStartup
= pdesk
;
465 if (ptiCurrent
->ppi
->hdeskStartup
!= NULL
)
467 if (!IntSetThreadDesktop(ptiCurrent
->ppi
->hdeskStartup
, FALSE
))
469 ERR_CH(UserThread
,"Failed to set thread desktop\n");
470 Status
= STATUS_UNSUCCESSFUL
;
475 /* mark the thread as fully initialized */
476 ptiCurrent
->TIF_flags
|= TIF_GUITHREADINITIALIZED
;
478 if (!(ptiCurrent
->ppi
->W32PF_flags
& (W32PF_ALLOWFOREGROUNDACTIVATE
| W32PF_APPSTARTING
)) &&
479 (gptiForeground
&& gptiForeground
->ppi
== ptiCurrent
->ppi
))
481 ptiCurrent
->TIF_flags
|= TIF_ALLOWFOREGROUNDACTIVATE
;
483 ptiCurrent
->pClientInfo
->dwTIFlags
= ptiCurrent
->TIF_flags
;
484 TRACE_CH(UserThread
,"UserCreateW32Thread pti 0x%p\n",ptiCurrent
);
485 return STATUS_SUCCESS
;
488 ERR_CH(UserThread
,"UserCreateThreadInfo failed! Freeing pti 0x%p for TID %p\n", ptiCurrent
, Thread
->Cid
.UniqueThread
);
489 UserDestroyThreadInfo(Thread
);
494 Called from IntDereferenceThreadInfo.
497 UserDeleteW32Thread(PTHREADINFO pti
)
499 PPROCESSINFO ppi
= pti
->ppi
;
501 TRACE_CH(UserThread
,"UserDeleteW32Thread pti 0x%p\n",pti
);
503 /* Free the message queue */
504 if (pti
->MessageQueue
)
506 MsqDestroyMessageQueue(pti
);
509 MsqCleanupThreadMsgs(pti
);
511 ExFreePoolWithTag(pti
, USERTAG_THREADINFO
);
513 IntDereferenceProcessInfo(ppi
);
518 UserDestroyThreadInfo(struct _ETHREAD
*Thread
)
521 PSINGLE_LIST_ENTRY psle
;
522 PPROCESSINFO ppiCurrent
;
523 struct _EPROCESS
*Process
;
524 PTHREADINFO ptiCurrent
;
526 Process
= Thread
->ThreadsProcess
;
528 /* Get the Win32 Thread */
529 ptiCurrent
= PsGetThreadWin32Thread(Thread
);
533 TRACE_CH(UserThread
,"Destroying pti 0x%p eThread 0x%p\n", ptiCurrent
, Thread
);
535 ptiCurrent
->TIF_flags
|= TIF_INCLEANUP
;
536 ptiCurrent
->pClientInfo
->dwTIFlags
= ptiCurrent
->TIF_flags
;
538 ppiCurrent
= ptiCurrent
->ppi
;
541 IsRemoveAttachThread(ptiCurrent
);
543 ptiCurrent
->TIF_flags
|= TIF_DONTATTACHQUEUE
;
544 ptiCurrent
->pClientInfo
->dwTIFlags
= ptiCurrent
->TIF_flags
;
546 /* Decrement thread count and check if its 0 */
547 ppiCurrent
->cThreads
--;
549 if(ptiCurrent
->TIF_flags
& TIF_GUITHREADINITIALIZED
)
551 /* Do now some process cleanup that requires a valid win32 thread */
552 if(ptiCurrent
->ppi
->cThreads
== 0)
554 /* Check if we have registered the user api hook */
555 if(ptiCurrent
->ppi
== ppiUahServer
)
557 /* Unregister the api hook */
558 UserUnregisterUserApiHook();
561 /* Notify logon application to restart shell if needed */
562 if(ptiCurrent
->pDeskInfo
)
564 if(ptiCurrent
->pDeskInfo
->ppiShellProcess
== ppiCurrent
)
566 DWORD ExitCode
= PsGetProcessExitStatus(Process
);
568 TRACE_CH(UserProcess
, "Shell process is exiting (%lu)\n", ExitCode
);
570 UserPostMessage(hwndSAS
,
575 ptiCurrent
->pDeskInfo
->ppiShellProcess
= NULL
;
580 DceFreeThreadDCE(ptiCurrent
);
581 DestroyTimersForThread(ptiCurrent
);
582 KeSetEvent(ptiCurrent
->pEventQueueServer
, IO_NO_INCREMENT
, FALSE
);
583 UnregisterThreadHotKeys(ptiCurrent
);
585 if (!UserDestroyObjectsForOwner(gHandleTable
, ptiCurrent
))
587 DPRINT1("Failed to delete objects belonging to thread %p. This is VERY BAD!.\n", ptiCurrent
);
589 return STATUS_UNSUCCESSFUL
;
592 if (ppiCurrent
&& ppiCurrent
->ptiList
== ptiCurrent
&& !ptiCurrent
->ptiSibling
&&
593 ppiCurrent
->W32PF_flags
& W32PF_CLASSESREGISTERED
)
595 TRACE_CH(UserThread
,"DestroyProcessClasses\n");
596 /* no process windows should exist at this point, or the function will assert! */
597 DestroyProcessClasses(ppiCurrent
);
598 ppiCurrent
->W32PF_flags
&= ~W32PF_CLASSESREGISTERED
;
601 IntBlockInput(ptiCurrent
, FALSE
);
602 IntCleanupThreadCallbacks(ptiCurrent
);
604 /* cleanup user object references stack */
605 psle
= PopEntryList(&ptiCurrent
->ReferencesList
);
608 PUSER_REFERENCE_ENTRY ref
= CONTAINING_RECORD(psle
, USER_REFERENCE_ENTRY
, Entry
);
609 TRACE_CH(UserThread
,"thread clean: remove reference obj 0x%p\n",ref
->obj
);
610 UserDereferenceObject(ref
->obj
);
612 psle
= PopEntryList(&ptiCurrent
->ReferencesList
);
616 /* Find the THREADINFO in the PROCESSINFO's list */
617 ppti
= &ppiCurrent
->ptiList
;
618 while (*ppti
!= NULL
&& *ppti
!= ptiCurrent
)
620 ppti
= &((*ppti
)->ptiSibling
);
623 /* we must have found it */
624 ASSERT(*ppti
== ptiCurrent
);
626 /* Remove it from the list */
627 *ppti
= ptiCurrent
->ptiSibling
;
629 if (ptiCurrent
->KeyboardLayout
)
630 UserDereferenceObject(ptiCurrent
->KeyboardLayout
);
632 if (gptiForeground
== ptiCurrent
)
634 // IntNotifyWinEvent(EVENT_OBJECT_FOCUS, NULL, OBJID_CLIENT, CHILDID_SELF, 0);
635 // IntNotifyWinEvent(EVENT_SYSTEM_FOREGROUND, NULL, OBJID_WINDOW, CHILDID_SELF, 0);
637 gptiForeground
= NULL
;
640 // Fixes CORE-6384 & CORE-7030.
641 /* if (ptiLastInput == ptiCurrent)
643 if (!ppiCurrent->ptiList)
644 ptiLastInput = gptiForeground;
646 ptiLastInput = ppiCurrent->ptiList;
647 ERR_CH(UserThread,"DTI: ptiLastInput is Cleared!!\n");
650 TRACE_CH(UserThread
,"Freeing pti 0x%p\n", ptiCurrent
);
652 IntSetThreadDesktop(NULL
, TRUE
);
654 if (ptiCurrent
->hEventQueueClient
!= NULL
)
656 ZwClose(ptiCurrent
->hEventQueueClient
);
657 ObDereferenceObject(ptiCurrent
->pEventQueueServer
);
659 ptiCurrent
->hEventQueueClient
= NULL
;
661 /* The thread is dying */
662 PsSetThreadWin32Thread(ptiCurrent
->pEThread
, NULL
, ptiCurrent
);
663 ptiCurrent
->pEThread
= NULL
;
665 /* Free the THREADINFO */
666 IntDereferenceThreadInfo(ptiCurrent
);
668 return STATUS_SUCCESS
;
673 Win32kThreadCallback(struct _ETHREAD
*Thread
,
674 PSW32THREADCALLOUTTYPE Type
)
678 UserEnterExclusive();
680 ASSERT(NtCurrentTeb());
682 if (Type
== PsW32ThreadCalloutInitialize
)
684 ASSERT(PsGetThreadWin32Thread(Thread
) == NULL
);
685 Status
= UserCreateThreadInfo(Thread
);
689 ASSERT(PsGetThreadWin32Thread(Thread
) != NULL
);
690 Status
= UserDestroyThreadInfo(Thread
);
699 C_ASSERT(sizeof(SERVERINFO
) <= PAGE_SIZE
);
705 if (!NT_SUCCESS(Status)) \
707 DPRINT1("Failed '%s' (0x%lx)\n", #x, Status); \
712 * This definition doesn't work
718 IN PDRIVER_OBJECT DriverObject
,
719 IN PUNICODE_STRING RegistryPath
)
723 WIN32_CALLOUTS_FPNS CalloutData
= {0};
724 PVOID GlobalUserHeapBase
= NULL
;
727 * Register user mode call interface
728 * (system service table index = 1)
730 Result
= KeAddSystemServiceTable(Win32kSSDT
,
732 Win32kNumberOfSysCalls
,
737 DPRINT1("Adding system services failed!\n");
738 return STATUS_UNSUCCESSFUL
;
741 hModuleWin
= MmPageEntireDriver(DriverEntry
);
742 DPRINT("Win32k hInstance 0x%p!\n",hModuleWin
);
744 /* Register Object Manager Callbacks */
745 CalloutData
.ProcessCallout
= Win32kProcessCallback
;
746 CalloutData
.ThreadCallout
= Win32kThreadCallback
;
747 CalloutData
.WindowStationParseProcedure
= IntWinStaObjectParse
;
748 CalloutData
.WindowStationDeleteProcedure
= IntWinStaObjectDelete
;
749 CalloutData
.WindowStationOkToCloseProcedure
= IntWinstaOkToClose
;
750 CalloutData
.DesktopOkToCloseProcedure
= IntDesktopOkToClose
;
751 CalloutData
.DesktopDeleteProcedure
= IntDesktopObjectDelete
;
752 CalloutData
.DesktopCloseProcedure
= IntDesktopObjectClose
;
753 CalloutData
.DesktopOpenProcedure
= IntDesktopObjectOpen
;
754 CalloutData
.BatchFlushRoutine
= NtGdiFlushUserBatch
;
756 /* Register our per-process and per-thread structures. */
757 PsEstablishWin32Callouts((PWIN32_CALLOUTS_FPNS
)&CalloutData
);
759 /* Register service hook callbacks */
761 KdSystemDebugControl('CsoR', DbgPreServiceHook
, ID_Win32PreServiceHook
, 0, 0, 0, 0);
762 KdSystemDebugControl('CsoR', DbgPostServiceHook
, ID_Win32PostServiceHook
, 0, 0, 0, 0);
765 /* Create the global USER heap */
766 GlobalUserHeap
= UserCreateHeap(&GlobalUserHeapSection
,
768 1 * 1024 * 1024); /* FIXME: 1 MB for now... */
769 if (GlobalUserHeap
== NULL
)
771 DPRINT1("Failed to initialize the global heap!\n");
772 return STATUS_UNSUCCESSFUL
;
775 /* Allocate global server info structure */
776 gpsi
= UserHeapAlloc(sizeof(SERVERINFO
));
779 DPRINT1("Failed allocate server info structure!\n");
780 return STATUS_UNSUCCESSFUL
;
783 RtlZeroMemory(gpsi
, sizeof(SERVERINFO
));
784 DPRINT("Global Server Data -> %p\n", gpsi
);
786 NT_ROF(InitGdiHandleTable());
787 NT_ROF(InitPaletteImpl());
789 /* Create stock objects, ie. precreated objects commonly
790 used by win32 applications */
791 CreateStockObjects();
792 CreateSysColorObjects();
794 NT_ROF(InitBrushImpl());
795 NT_ROF(InitPDEVImpl());
796 NT_ROF(InitLDEVImpl());
797 NT_ROF(InitDeviceImpl());
798 NT_ROF(InitDcImpl());
799 NT_ROF(InitUserImpl());
800 NT_ROF(InitWindowStationImpl());
801 NT_ROF(InitDesktopImpl());
802 NT_ROF(InitInputImpl());
803 NT_ROF(InitKeyboardImpl());
804 NT_ROF(MsqInitializeImpl());
805 NT_ROF(InitTimerImpl());
806 NT_ROF(InitDCEImpl());
808 /* Initialize FreeType library */
809 if (!InitFontSupport())
811 DPRINT1("Unable to initialize font support\n");
815 gusLanguageID
= UserGetLanguageID();
817 return STATUS_SUCCESS
;