Win32Process->HeapMappings.UserMapping = UserBase;
Win32Process->HeapMappings.Count = 1;
- InitializeListHead(&Win32Process->ClassList);
-
InitializeListHead(&Win32Process->MenuListHead);
InitializeListHead(&Win32Process->GDIBrushAttrFreeList);
ExInitializeFastMutex(&Win32Process->DriverObjListLock);
Win32Process->KeyboardLayout = W32kGetDefaultKeyLayout();
+ EngCreateEvent((PEVENT *)&Win32Process->InputIdleEvent);
+ KeInitializeEvent(Win32Process->InputIdleEvent, NotificationEvent, FALSE);
if(Process->Peb != NULL)
{
/* map the gdi handle table to user land */
- Process->Peb->GdiSharedHandleTable = GDI_MapHandleTable(GdiTableSection, Process);
+ Process->Peb->GdiSharedHandleTable = GDI_MapHandleTable(Process);
Process->Peb->GdiDCAttributeList = GDI_BATCH_LIMIT;
}
Win32Process->peProcess = Process;
/* setup process flags */
Win32Process->W32PF_flags = 0;
+
+ /* Create pools for GDI object attributes */
+ Win32Process->pPoolDcAttr = GdiPoolCreate(sizeof(DC_ATTR), 'acdG');
+ Win32Process->pPoolBrushAttr = GdiPoolCreate(sizeof(BRUSH_ATTR), 'arbG');
+ Win32Process->pPoolRgnAttr = GdiPoolCreate(sizeof(RGN_ATTR), 'agrG');
+ ASSERT(Win32Process->pPoolDcAttr);
+ ASSERT(Win32Process->pPoolBrushAttr);
+ ASSERT(Win32Process->pPoolRgnAttr);
}
else
{
DPRINT("Destroying W32 process PID:%d at IRQ level: %lu\n", Process->UniqueProcessId, KeGetCurrentIrql());
+ Win32Process->W32PF_flags |= W32PF_TERMINATED;
+
+ if (Win32Process->InputIdleEvent)
+ {
+ EngFreeMem((PVOID)Win32Process->InputIdleEvent);
+ Win32Process->InputIdleEvent = NULL;
+ }
+
IntCleanupMenus(Process, Win32Process);
IntCleanupCurIcons(Process, Win32Process);
CleanupMonitorImpl();
/* no process windows should exist at this point, or the function will assert! */
DestroyProcessClasses(Win32Process);
+ Win32Process->W32PF_flags &= ~W32PF_CLASSESREGISTERED;
GDI_CleanupForProcess(Process);
{
LogonProcess = NULL;
}
+
+ /* Close the startup desktop */
+ ASSERT(Win32Process->rpdeskStartup);
+ ASSERT(Win32Process->hdeskStartup);
+ ObDereferenceObject(Win32Process->rpdeskStartup);
+ ZwClose(Win32Process->hdeskStartup);
+
+ /* Close the current window station */
+ UserSetProcessWindowStation(NULL);
+
+ /* Destroy GDI pools */
+ GdiPoolDestroy(Win32Process->pPoolDcAttr);
+ GdiPoolDestroy(Win32Process->pPoolBrushAttr);
+ GdiPoolDestroy(Win32Process->pPoolRgnAttr);
}
RETURN( STATUS_SUCCESS);
HDESK hDesk = NULL;
NTSTATUS Status;
PUNICODE_STRING DesktopPath;
+ PDESKTOP pdesk;
PRTL_USER_PROCESS_PARAMETERS ProcessParams = (Process->Peb ? Process->Peb->ProcessParameters : NULL);
DPRINT("Creating W32 thread TID:%d at IRQ level: %lu\n", Thread->Cid.UniqueThread, KeGetCurrentIrql());
InitializeListHead(&Win32Thread->aphkStart[i]);
}
- /*
- * inherit the thread desktop and process window station (if not yet inherited) from the process startup
- * info structure. See documentation of CreateProcess()
- */
- DesktopPath = (ProcessParams ? ((ProcessParams->DesktopInfo.Length > 0) ? &ProcessParams->DesktopInfo : NULL) : NULL);
- Status = IntParseDesktopPath(Process,
- DesktopPath,
- &hWinSta,
- &hDesk);
- if(NT_SUCCESS(Status))
+ Win32Thread->TIF_flags &= ~TIF_INCLEANUP;
+ co_IntDestroyCaret(Win32Thread);
+ Win32Thread->ppi = PsGetCurrentProcessWin32Process();
+ Win32Thread->ptiSibling = Win32Thread->ppi->ptiList;
+ Win32Thread->ppi->ptiList = Win32Thread;
+ Win32Thread->ppi->cThreads++;
+ if (Win32Thread->rpdesk && !Win32Thread->pDeskInfo)
{
- if(hWinSta != NULL)
+ Win32Thread->pDeskInfo = Win32Thread->rpdesk->pDeskInfo;
+ }
+ Win32Thread->MessageQueue = MsqCreateMessageQueue(Thread);
+ Win32Thread->KeyboardLayout = W32kGetDefaultKeyLayout();
+
+ /* HAAAAAAAACK! This should go to Win32kProcessCallback */
+ if(Win32Thread->ppi->hdeskStartup == NULL)
+ {
+ /*
+ * inherit the thread desktop and process window station (if not yet inherited) from the process startup
+ * info structure. See documentation of CreateProcess()
+ */
+ DesktopPath = (ProcessParams ? ((ProcessParams->DesktopInfo.Length > 0) ? &ProcessParams->DesktopInfo : NULL) : NULL);
+ Status = IntParseDesktopPath(Process,
+ DesktopPath,
+ &hWinSta,
+ &hDesk);
+ if(NT_SUCCESS(Status))
{
- if(Process != CsrProcess)
+ if(hWinSta != NULL)
{
- HWINSTA hProcessWinSta = (HWINSTA)InterlockedCompareExchangePointer((PVOID)&Process->Win32WindowStation, (PVOID)hWinSta, NULL);
- if(hProcessWinSta != NULL)
+ if(!UserSetProcessWindowStation(hWinSta))
{
- /* our process is already assigned to a different window station, we don't need the handle anymore */
- NtClose(hWinSta);
+ DPRINT1("Failed to set process window station\n");
}
}
- else
- {
- NtClose(hWinSta);
- }
- }
- if (hDesk != NULL)
- {
- PDESKTOP DesktopObject;
- Win32Thread->rpdesk = NULL;
- Status = ObReferenceObjectByHandle(hDesk,
- 0,
- ExDesktopObjectType,
- KernelMode,
- (PVOID*)&DesktopObject,
- NULL);
- NtClose(hDesk);
- if(NT_SUCCESS(Status))
+ if (hDesk != NULL)
{
- if (!IntSetThreadDesktop(DesktopObject,
- FALSE))
+ /* Validate the new desktop. */
+ Status = IntValidateDesktopHandle(hDesk,
+ UserMode,
+ 0,
+ &pdesk);
+
+ if(NT_SUCCESS(Status))
{
- DPRINT1("Unable to set thread desktop\n");
+ Win32Thread->ppi->hdeskStartup = hDesk;
+ Win32Thread->ppi->rpdeskStartup = pdesk;
}
}
- else
- {
- DPRINT1("Unable to reference thread desktop handle 0x%x\n", hDesk);
- }
+ }
+ else
+ {
+ DPRINT1("No Desktop handle for this Thread!\n");
}
}
- Win32Thread->TIF_flags &= ~TIF_INCLEANUP;
- co_IntDestroyCaret(Win32Thread);
- Win32Thread->ppi = PsGetCurrentProcessWin32Process();
+
+ if (Win32Thread->ppi->hdeskStartup != NULL)
+ {
+ if (!IntSetThreadDesktop(Win32Thread->ppi->hdeskStartup, FALSE))
+ {
+ DPRINT1("Unable to set thread desktop\n");
+ }
+ }
+
pTeb = NtCurrentTeb();
if (pTeb)
+ { /* Attempt to startup client support which should have been initialized in IntSetThreadDesktop. */
+ PCLIENTINFO pci = (PCLIENTINFO)pTeb->Win32ClientInfo;
+ Win32Thread->pClientInfo = pci;
+ pci->ppi = Win32Thread->ppi;
+ pci->fsHooks = Win32Thread->fsHooks;
+ if (Win32Thread->KeyboardLayout) pci->hKL = Win32Thread->KeyboardLayout->hkl;
+ pci->dwTIFlags = Win32Thread->TIF_flags;
+ /* CI may not have been initialized. */
+ if (!pci->pDeskInfo && Win32Thread->pDeskInfo)
+ {
+ if (!pci->ulClientDelta) pci->ulClientDelta = DesktopHeapGetUserDelta();
+
+ pci->pDeskInfo = (PVOID)((ULONG_PTR)Win32Thread->pDeskInfo - pci->ulClientDelta);
+ }
+ if (Win32Thread->pcti && pci->pDeskInfo)
+ pci->pClientThreadInfo = (PVOID)((ULONG_PTR)Win32Thread->pcti - pci->ulClientDelta);
+ else
+ pci->pClientThreadInfo = NULL;
+ }
+ else
{
- Win32Thread->pClientInfo = (PCLIENTINFO)pTeb->Win32ClientInfo;
- Win32Thread->pClientInfo->pClientThreadInfo = NULL;
+ DPRINT1("No TEB for this Thread!\n");
+ // System thread running! Now SendMessage should be okay.
+ Win32Thread->pcti = &Win32Thread->cti;
}
- Win32Thread->MessageQueue = MsqCreateMessageQueue(Thread);
- Win32Thread->KeyboardLayout = W32kGetDefaultKeyLayout();
Win32Thread->pEThread = Thread;
}
else
{
+ PTHREADINFO pti;
PSINGLE_LIST_ENTRY e;
DPRINT("Destroying W32 thread TID:%d at IRQ level: %lu\n", Thread->Cid.UniqueThread, KeGetCurrentIrql());
Win32Thread->TIF_flags |= TIF_INCLEANUP;
+ pti = Win32Thread->ppi->ptiList;
+ if (pti == Win32Thread)
+ {
+ Win32Thread->ppi->ptiList = Win32Thread->ptiSibling;
+ Win32Thread->ppi->cThreads--;
+ }
+ else
+ {
+ do
+ {
+ if (pti->ptiSibling == Win32Thread)
+ {
+ pti->ptiSibling = Win32Thread->ptiSibling;
+ Win32Thread->ppi->cThreads--;
+ break;
+ }
+ pti = pti->ptiSibling;
+ }
+ while (pti);
+ }
DceFreeThreadDCE(Win32Thread);
HOOK_DestroyThreadHooks(Thread);
EVENT_DestroyThreadEvents(Thread);
e = PopEntryList(&Win32Thread->ReferencesList);
}
- IntSetThreadDesktop(NULL,
- TRUE);
+ IntSetThreadDesktop(NULL, TRUE);
PsSetThreadWin32Thread(Thread, NULL);
}
CalloutData.ProcessCallout = Win32kProcessCallback;
CalloutData.ThreadCallout = Win32kThreadCallback;
CalloutData.BatchFlushRoutine = NtGdiFlushUserBatch;
+ CalloutData.DesktopOkToCloseProcedure = IntDesktopOkToClose;
+ CalloutData.WindowStationOkToCloseProcedure = IntWinstaOkToClose;
/* Register our per-process and per-thread structures. */
PsEstablishWin32Callouts((PWIN32_CALLOUTS_FPNS)&CalloutData);
+#if DBG_ENABLE_SERVICE_HOOKS
+ /* Register service hook callbacks */
+ KdSystemDebugControl('CsoR', DbgPreServiceHook, ID_Win32PreServiceHook, 0, 0, 0, 0);
+ KdSystemDebugControl('CsoR', DbgPostServiceHook, ID_Win32PostServiceHook, 0, 0, 0, 0);
+#endif
+
/* Create the global USER heap */
GlobalUserHeap = UserCreateHeap(&GlobalUserHeapSection,
&GlobalUserHeapBase,