#define NDEBUG
#include <debug.h>
+#include <kdros.h>
HANDLE hModuleWin;
-PGDI_HANDLE_TABLE NTAPI GDIOBJ_iAllocHandleTable(OUT PSECTION_OBJECT *SectionObject);
+PGDI_HANDLE_TABLE NTAPI GDIOBJ_iAllocHandleTable(OUT PVOID *SectionObject);
BOOL NTAPI GDI_CleanupForProcess (struct _EPROCESS *Process);
NTSTATUS NTAPI UserDestroyThreadInfo(struct _ETHREAD *Thread);
HANDLE GlobalUserHeap = NULL;
-PSECTION_OBJECT GlobalUserHeapSection = NULL;
+PVOID GlobalUserHeapSection = NULL;
PSERVERINFO gpsi = NULL; // Global User Server Information.
SHORT gusLanguageID;
PPROCESSINFO ppiScrnSaver;
+PPROCESSINFO gppiList = NULL;
extern ULONG_PTR Win32kSSDT[];
extern UCHAR Win32kSSPT[];
Win32kProcessCallback(struct _EPROCESS *Process,
BOOLEAN Create)
{
- PPROCESSINFO ppiCurrent;
- DECLARE_RETURN(NTSTATUS);
+ PPROCESSINFO ppiCurrent, *pppi;
+ NTSTATUS Status;
ASSERT(Process->Peb);
LARGE_INTEGER Offset;
PVOID UserBase = NULL;
PRTL_USER_PROCESS_PARAMETERS pParams = Process->Peb->ProcessParameters;
- NTSTATUS Status;
- ASSERT(PsGetProcessWin32Process(Process) == NULL);
+ /* We might be called with an already allocated win32 process */
+ ppiCurrent = PsGetProcessWin32Process(Process);
+ if (ppiCurrent != NULL)
+ {
+ /* There is no more to do for us (this is a success code!) */
+ Status = STATUS_ALREADY_WIN32;
+ goto Leave;
+ }
+ /* Allocate a new win32 process */
ppiCurrent = ExAllocatePoolWithTag(NonPagedPool,
sizeof(PROCESSINFO),
USERTAG_PROCESSINFO);
-
if (ppiCurrent == NULL)
{
- ERR_CH(UserProcess, "Failed to allocate ppi for PID:0x%lx\n", HandleToUlong(Process->UniqueProcessId));
- RETURN( STATUS_NO_MEMORY);
+ ERR_CH(UserProcess, "Failed to allocate ppi for PID:0x%lx\n",
+ HandleToUlong(Process->UniqueProcessId));
+ Status = STATUS_NO_MEMORY;
+ goto Leave;
}
RtlZeroMemory(ppiCurrent, sizeof(PROCESSINFO));
- PsSetProcessWin32Process(Process, ppiCurrent);
+ PsSetProcessWin32Process(Process, ppiCurrent, NULL);
#if DBG
DbgInitDebugChannels();
+#if KDBG
+ KdRosRegisterCliCallback(DbgGdiKdbgCliCallback);
+#endif
#endif
TRACE_CH(UserProcess,"Allocated ppi 0x%p for PID:0x%lx\n", ppiCurrent, HandleToUlong(Process->UniqueProcessId));
if (!NT_SUCCESS(Status))
{
TRACE_CH(UserProcess,"Failed to map the global heap! 0x%x\n", Status);
- RETURN(Status);
+ goto Leave;
}
ppiCurrent->HeapMappings.Next = NULL;
ppiCurrent->HeapMappings.KernelMapping = (PVOID)GlobalUserHeap;
ppiCurrent->W32PF_flags |= W32PF_SCREENSAVER;
}
+ // Fixme check if this process is allowed.
+ ppiCurrent->W32PF_flags |= W32PF_ALLOWFOREGROUNDACTIVATE; // Starting application it will get toggled off.
+
/* Create pools for GDI object attributes */
ppiCurrent->pPoolDcAttr = GdiPoolCreate(sizeof(DC_ATTR), 'acdG');
ppiCurrent->pPoolBrushAttr = GdiPoolCreate(sizeof(BRUSH_ATTR), 'arbG');
ASSERT(ppiCurrent->pPoolDcAttr);
ASSERT(ppiCurrent->pPoolBrushAttr);
ASSERT(ppiCurrent->pPoolRgnAttr);
+
+ /* Add the process to the global list */
+ ppiCurrent->ppiNext = gppiList;
+ gppiList = ppiCurrent;
}
else
{
if (gppiInputProvider == ppiCurrent) gppiInputProvider = NULL;
+ pppi = &gppiList;
+ while (*pppi != NULL && *pppi != ppiCurrent)
+ pppi = &(*pppi)->ppiNext;
+
+ ASSERT(*pppi == ppiCurrent);
+
+ *pppi = ppiCurrent->ppiNext;
+
TRACE_CH(UserProcess,"Freeing ppi 0x%p\n", ppiCurrent);
+#if DBG
+ if (DBG_IS_CHANNEL_ENABLED(ppiCurrent, DbgChUserObj, WARN_LEVEL))
+ {
+ DbgUserDumpHandleTable();
+ }
+#endif
- /* Ftee the PROCESSINFO */
- PsSetProcessWin32Process(Process, NULL);
+ /* Free the PROCESSINFO */
+ PsSetProcessWin32Process(Process, NULL, ppiCurrent);
ExFreePoolWithTag(ppiCurrent, USERTAG_PROCESSINFO);
}
- RETURN( STATUS_SUCCESS);
+ Status = STATUS_SUCCESS;
-CLEANUP:
+Leave:
UserLeave();
- END_CLEANUP;
+ return Status;
}
NTSTATUS NTAPI
int i;
NTSTATUS Status = STATUS_SUCCESS;
PTEB pTeb;
+ LARGE_INTEGER LargeTickCount;
+ OBJECT_ATTRIBUTES EventQueueObjAttr;
Process = Thread->ThreadsProcess;
RtlZeroMemory(ptiCurrent, sizeof(THREADINFO));
- PsSetThreadWin32Thread(Thread, ptiCurrent);
+ /* Initialize the THREADINFO */
+
+ PsSetThreadWin32Thread(Thread, ptiCurrent, NULL);
+ IntReferenceThreadInfo(ptiCurrent);
+ ptiCurrent->pEThread = Thread;
+ ptiCurrent->ppi = PsGetCurrentProcessWin32Process();
pTeb->Win32ThreadInfo = ptiCurrent;
ptiCurrent->pClientInfo = (PCLIENTINFO)pTeb->Win32ClientInfo;
TRACE_CH(UserThread, "Allocated pti 0x%p for TID %p\n", ptiCurrent, Thread->Cid.UniqueThread);
- /* Initialize the THREADINFO */
InitializeListHead(&ptiCurrent->WindowListHead);
InitializeListHead(&ptiCurrent->W32CallbackListHead);
+ InitializeListHead(&ptiCurrent->PostedMessagesListHead);
+ InitializeListHead(&ptiCurrent->SentMessagesListHead);
+ InitializeListHead(&ptiCurrent->DispatchingMessagesHead);
+ InitializeListHead(&ptiCurrent->LocalDispatchingMessagesHead);
InitializeListHead(&ptiCurrent->PtiLink);
for (i = 0; i < NB_HOOKS; i++)
{
InitializeListHead(&ptiCurrent->aphkStart[i]);
}
- ptiCurrent->pEThread = Thread;
- ptiCurrent->ppi = PsGetCurrentProcessWin32Process();
ptiCurrent->ptiSibling = ptiCurrent->ppi->ptiList;
ptiCurrent->ppi->ptiList = ptiCurrent;
ptiCurrent->ppi->cThreads++;
- ptiCurrent->MessageQueue = MsqCreateMessageQueue(Thread);
+
+ ptiCurrent->hEventQueueClient = NULL;
+ InitializeObjectAttributes(&EventQueueObjAttr, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);
+ Status = ZwCreateEvent(&ptiCurrent->hEventQueueClient, EVENT_ALL_ACCESS,
+ NULL, SynchronizationEvent, FALSE);
+ if (!NT_SUCCESS(Status))
+ {
+ goto error;
+ }
+ Status = ObReferenceObjectByHandle(ptiCurrent->hEventQueueClient, 0,
+ *ExEventObjectType, KernelMode,
+ (PVOID*)&ptiCurrent->pEventQueueServer, NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ ZwClose(ptiCurrent->hEventQueueClient);
+ ptiCurrent->hEventQueueClient = NULL;
+ goto error;
+ }
+
+ KeQueryTickCount(&LargeTickCount);
+ ptiCurrent->timeLast = LargeTickCount.u.LowPart;
+
+ ptiCurrent->MessageQueue = MsqCreateMessageQueue(ptiCurrent);
if(ptiCurrent->MessageQueue == NULL)
{
ERR_CH(UserThread,"Failed to allocate message loop\n");
if (ptiCurrent->KeyboardLayout)
UserReferenceObject(ptiCurrent->KeyboardLayout);
ptiCurrent->TIF_flags &= ~TIF_INCLEANUP;
+ if (Process == gpepCSRSS) /* If this thread is owned by CSRSS, mark it as such */
+ ptiCurrent->TIF_flags |= TIF_CSRSSTHREAD;
+ ptiCurrent->pcti = &ptiCurrent->cti;
/* Initialize the CLIENTINFO */
pci = (PCLIENTINFO)pTeb->Win32ClientInfo;
/* mark the thread as fully initialized */
ptiCurrent->TIF_flags |= TIF_GUITHREADINITIALIZED;
- ptiCurrent->pClientInfo->dwTIFlags = ptiCurrent->TIF_flags;
+ if (!(ptiCurrent->ppi->W32PF_flags & (W32PF_ALLOWFOREGROUNDACTIVATE | W32PF_APPSTARTING)) &&
+ (gptiForeground && gptiForeground->ppi == ptiCurrent->ppi ))
+ {
+ ptiCurrent->TIF_flags |= TIF_ALLOWFOREGROUNDACTIVATE;
+ }
+ ptiCurrent->pClientInfo->dwTIFlags = ptiCurrent->TIF_flags;
+ TRACE_CH(UserThread,"UserCreateW32Thread pti 0x%p\n",ptiCurrent);
return STATUS_SUCCESS;
error:
return Status;
}
+/*
+ Called from IntDereferenceThreadInfo.
+ */
+VOID
+FASTCALL
+UserDeleteW32Thread(PTHREADINFO pti)
+{
+ if (!pti->RefCount)
+ {
+ TRACE_CH(UserThread,"UserDeleteW32Thread pti 0x%p\n",pti);
+ if (pti->hEventQueueClient != NULL)
+ ZwClose(pti->hEventQueueClient);
+ pti->hEventQueueClient = NULL;
+
+ /* Free the message queue */
+ if (pti->MessageQueue)
+ {
+ MsqDestroyMessageQueue(pti);
+ }
+
+ MsqCleanupThreadMsgs(pti);
+
+ IntSetThreadDesktop(NULL, TRUE);
+
+ PsSetThreadWin32Thread(pti->pEThread, NULL, pti);
+ ExFreePoolWithTag(pti, USERTAG_THREADINFO);
+ }
+}
+
NTSTATUS
NTAPI
UserDestroyThreadInfo(struct _ETHREAD *Thread)
ppiCurrent = ptiCurrent->ppi;
ASSERT(ppiCurrent);
+ IsRemoveAttachThread(ptiCurrent);
+
+ ptiCurrent->TIF_flags |= TIF_DONTATTACHQUEUE;
+ ptiCurrent->pClientInfo->dwTIFlags = ptiCurrent->TIF_flags;
+
/* Decrement thread count and check if its 0 */
ppiCurrent->cThreads--;
HOOK_DestroyThreadHooks(Thread);
EVENT_DestroyThreadEvents(Thread);
DestroyTimersForThread(ptiCurrent);
- KeSetEvent(ptiCurrent->MessageQueue->NewMessages, IO_NO_INCREMENT, FALSE);
- UnregisterThreadHotKeys(Thread);
+ KeSetEvent(ptiCurrent->pEventQueueServer, IO_NO_INCREMENT, FALSE);
+ UnregisterThreadHotKeys(ptiCurrent);
/*
if (IsListEmpty(&ptiCurrent->WindowListHead))
{
*/
co_DestroyThreadWindows(Thread);
- if (ppiCurrent && ppiCurrent->ptiList == ptiCurrent && !ptiCurrent->ptiSibling)
+ if (ppiCurrent && ppiCurrent->ptiList == ptiCurrent && !ptiCurrent->ptiSibling &&
+ ppiCurrent->W32PF_flags & W32PF_CLASSESREGISTERED)
{
- //ERR_CH(UserThread,"DestroyProcessClasses\n");
+ TRACE_CH(UserThread,"DestroyProcessClasses\n");
/* no process windows should exist at this point, or the function will assert! */
DestroyProcessClasses(ppiCurrent);
ppiCurrent->W32PF_flags &= ~W32PF_CLASSESREGISTERED;
}
}
- // ptiTo
- if (IsThreadAttach(ptiCurrent))
- {
- PTHREADINFO ptiFrom = IsThreadAttach(ptiCurrent);
- TRACE_CH(UserThread,"Attached Thread ptiTo is getting switched!\n");
- UserAttachThreadInput(ptiFrom, ptiCurrent, FALSE);
- }
-
- // ptiFrom
- if (ptiCurrent->pqAttach && ptiCurrent->MessageQueue)
- {
- PTHREADINFO ptiTo;
- ptiTo = PsGetThreadWin32Thread(ptiCurrent->MessageQueue->Thread);
- TRACE_CH(UserThread,"Attached Thread ptiFrom is getting switched!\n");
- UserAttachThreadInput( ptiCurrent, ptiTo, FALSE);
- }
-
- /* Free the message queue */
- if(ptiCurrent->MessageQueue)
- {
- MsqDestroyMessageQueue(ptiCurrent->MessageQueue);
- }
-
/* Find the THREADINFO in the PROCESSINFO's list */
ppti = &ppiCurrent->ptiList;
while (*ppti != NULL && *ppti != ptiCurrent)
if (ptiCurrent->KeyboardLayout)
UserDereferenceObject(ptiCurrent->KeyboardLayout);
- IntSetThreadDesktop(NULL, TRUE);
+ if (gptiForeground == ptiCurrent)
+ {
+// IntNotifyWinEvent(EVENT_OBJECT_FOCUS, NULL, OBJID_CLIENT, CHILDID_SELF, 0);
+// IntNotifyWinEvent(EVENT_SYSTEM_FOREGROUND, NULL, OBJID_WINDOW, CHILDID_SELF, 0);
+ gptiForeground = NULL;
+ }
+
+ // Fixes CORE-6384 & CORE-7030.
+/* if (ptiLastInput == ptiCurrent)
+ {
+ if (!ppiCurrent->ptiList)
+ ptiLastInput = gptiForeground;
+ else
+ ptiLastInput = ppiCurrent->ptiList;
+ ERR_CH(UserThread,"DTI: ptiLastInput is Cleared!!\n");
+ }
+*/
TRACE_CH(UserThread,"Freeing pti 0x%p\n", ptiCurrent);
/* Free the THREADINFO */
- PsSetThreadWin32Thread(Thread, NULL);
- ExFreePoolWithTag(ptiCurrent, USERTAG_THREADINFO);
+ IntDereferenceThreadInfo(ptiCurrent);
return STATUS_SUCCESS;
}
DPRINT("Win32k hInstance 0x%p!\n",hModuleWin);
/* Register Object Manager Callbacks */
+ CalloutData.ProcessCallout = Win32kProcessCallback;
+ CalloutData.ThreadCallout = Win32kThreadCallback;
CalloutData.WindowStationParseProcedure = IntWinStaObjectParse;
CalloutData.WindowStationDeleteProcedure = IntWinStaObjectDelete;
+ CalloutData.WindowStationOkToCloseProcedure = IntWinstaOkToClose;
+ CalloutData.DesktopOkToCloseProcedure = IntDesktopOkToClose;
CalloutData.DesktopDeleteProcedure = IntDesktopObjectDelete;
- CalloutData.ProcessCallout = Win32kProcessCallback;
- CalloutData.ThreadCallout = Win32kThreadCallback;
+ CalloutData.DesktopCloseProcedure = IntDesktopObjectClose;
+ CalloutData.DesktopOpenProcedure = IntDesktopObjectOpen;
CalloutData.BatchFlushRoutine = NtGdiFlushUserBatch;
- CalloutData.DesktopOkToCloseProcedure = IntDesktopOkToClose;
- CalloutData.WindowStationOkToCloseProcedure = IntWinstaOkToClose;
/* Register our per-process and per-thread structures. */
PsEstablishWin32Callouts((PWIN32_CALLOUTS_FPNS)&CalloutData);