extern UCHAR Win32kSSPT[];
extern ULONG Win32kNumberOfSysCalls;
+void
+NTAPI
+DbgPreServiceHook(ULONG ulSyscallId, PULONG_PTR pulArguments)
+{
+ GdiDbgPreServiceHook(ulSyscallId, pulArguments);
+ UserDbgPreServiceHook(ulSyscallId, pulArguments);
+}
+
+ULONG_PTR
+NTAPI
+DbgPostServiceHook(ULONG ulSyscallId, ULONG_PTR ulResult)
+{
+ ulResult = GdiDbgPostServiceHook(ulSyscallId, ulResult);
+ ulResult = UserDbgPostServiceHook(ulSyscallId, ulResult);
+ return ulResult;
+}
+
NTSTATUS
APIENTRY
Win32kProcessCallback(struct _EPROCESS *Process,
BOOLEAN Create)
{
- PPROCESSINFO Win32Process;
+ PPROCESSINFO ppiCurrent;
DECLARE_RETURN(NTSTATUS);
+ ASSERT(Process->Peb);
+
DPRINT("Enter Win32kProcessCallback\n");
UserEnterExclusive();
- /* Get the Win32 Process */
- Win32Process = PsGetProcessWin32Process(Process);
-
- /* Allocate one if needed */
- if (!Win32Process)
- {
- /* FIXME: Lock the process */
- Win32Process = ExAllocatePoolWithTag(NonPagedPool,
- sizeof(PROCESSINFO),
- USERTAG_PROCESSINFO);
-
- if (Win32Process == NULL) RETURN( STATUS_NO_MEMORY);
-
- RtlZeroMemory(Win32Process, sizeof(PROCESSINFO));
-
- PsSetProcessWin32Process(Process, Win32Process);
- /* FIXME: Unlock the process */
- }
-
if (Create)
{
SIZE_T ViewSize = 0;
LARGE_INTEGER Offset;
PVOID UserBase = NULL;
- PRTL_USER_PROCESS_PARAMETERS pParams = NULL;
+ PRTL_USER_PROCESS_PARAMETERS pParams = Process->Peb->ProcessParameters;
NTSTATUS Status;
- extern PSECTION_OBJECT GlobalUserHeapSection;
+
+ ASSERT(PsGetProcessWin32Process(Process) == NULL);
+
+ ppiCurrent = ExAllocatePoolWithTag(NonPagedPool,
+ sizeof(PROCESSINFO),
+ USERTAG_PROCESSINFO);
+
+ if (ppiCurrent == NULL)
+ RETURN( STATUS_NO_MEMORY);
+
+ RtlZeroMemory(ppiCurrent, sizeof(PROCESSINFO));
+
+ PsSetProcessWin32Process(Process, ppiCurrent);
#ifdef DBG
DbgInitDebugChannels();
#endif
- TRACE_PPI(Win32Process, UserProcess,"Allocated ppi for PID:%d\n", Process->UniqueProcessId);
-
- DPRINT("Creating W32 process PID:%d at IRQ level: %lu\n", Process->UniqueProcessId, KeGetCurrentIrql());
+ TRACE_PPI(ppiCurrent, UserProcess,"Allocated ppi for PID:%d\n", Process->UniqueProcessId);
/* map the global heap into the process */
Offset.QuadPart = 0;
DPRINT1("Failed to map the global heap! 0x%x\n", Status);
RETURN(Status);
}
- Win32Process->HeapMappings.Next = NULL;
- Win32Process->HeapMappings.KernelMapping = (PVOID)GlobalUserHeap;
- Win32Process->HeapMappings.UserMapping = UserBase;
- Win32Process->HeapMappings.Count = 1;
+ ppiCurrent->HeapMappings.Next = NULL;
+ ppiCurrent->HeapMappings.KernelMapping = (PVOID)GlobalUserHeap;
+ ppiCurrent->HeapMappings.UserMapping = UserBase;
+ ppiCurrent->HeapMappings.Count = 1;
- InitializeListHead(&Win32Process->MenuListHead);
+ InitializeListHead(&ppiCurrent->MenuListHead);
- InitializeListHead(&Win32Process->GDIBrushAttrFreeList);
- InitializeListHead(&Win32Process->GDIDcAttrFreeList);
+ InitializeListHead(&ppiCurrent->GDIBrushAttrFreeList);
+ InitializeListHead(&ppiCurrent->GDIDcAttrFreeList);
- InitializeListHead(&Win32Process->PrivateFontListHead);
- ExInitializeFastMutex(&Win32Process->PrivateFontListLock);
+ InitializeListHead(&ppiCurrent->PrivateFontListHead);
+ ExInitializeFastMutex(&ppiCurrent->PrivateFontListLock);
- InitializeListHead(&Win32Process->DriverObjListHead);
- ExInitializeFastMutex(&Win32Process->DriverObjListLock);
+ InitializeListHead(&ppiCurrent->DriverObjListHead);
+ ExInitializeFastMutex(&ppiCurrent->DriverObjListLock);
- Win32Process->KeyboardLayout = W32kGetDefaultKeyLayout();
- EngCreateEvent((PEVENT *)&Win32Process->InputIdleEvent);
- KeInitializeEvent(Win32Process->InputIdleEvent, NotificationEvent, FALSE);
+ ppiCurrent->KeyboardLayout = W32kGetDefaultKeyLayout();
+ EngCreateEvent((PEVENT *)&ppiCurrent->InputIdleEvent);
+ KeInitializeEvent(ppiCurrent->InputIdleEvent, NotificationEvent, FALSE);
+
- if(Process->Peb != NULL)
- {
- /* map the gdi handle table to user land */
- Process->Peb->GdiSharedHandleTable = GDI_MapHandleTable(Process);
- Process->Peb->GdiDCAttributeList = GDI_BATCH_LIMIT;
- pParams = Process->Peb->ProcessParameters;
- }
+ /* map the gdi handle table to user land */
+ Process->Peb->GdiSharedHandleTable = GDI_MapHandleTable(Process);
+ Process->Peb->GdiDCAttributeList = GDI_BATCH_LIMIT;
+ pParams = Process->Peb->ProcessParameters;
- Win32Process->peProcess = Process;
+ ppiCurrent->peProcess = Process;
/* setup process flags */
- Win32Process->W32PF_flags = W32PF_THREADCONNECTED;
+ ppiCurrent->W32PF_flags = W32PF_THREADCONNECTED;
if ( pParams &&
pParams->WindowFlags & STARTF_SCRNSAVER )
{
- ppiScrnSaver = Win32Process;
- Win32Process->W32PF_flags |= W32PF_SCREENSAVER;
+ ppiScrnSaver = ppiCurrent;
+ ppiCurrent->W32PF_flags |= W32PF_SCREENSAVER;
}
/* 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);
+ ppiCurrent->pPoolDcAttr = GdiPoolCreate(sizeof(DC_ATTR), 'acdG');
+ ppiCurrent->pPoolBrushAttr = GdiPoolCreate(sizeof(BRUSH_ATTR), 'arbG');
+ ppiCurrent->pPoolRgnAttr = GdiPoolCreate(sizeof(RGN_ATTR), 'agrG');
+ ASSERT(ppiCurrent->pPoolDcAttr);
+ ASSERT(ppiCurrent->pPoolBrushAttr);
+ ASSERT(ppiCurrent->pPoolRgnAttr);
}
else
{
- DPRINT("Destroying W32 process PID:%d at IRQ level: %lu\n", Process->UniqueProcessId, KeGetCurrentIrql());
- Win32Process->W32PF_flags |= W32PF_TERMINATED;
+ /* Get the Win32 Process */
+ ppiCurrent = PsGetProcessWin32Process(Process);
- if (ppiScrnSaver == Win32Process) ppiScrnSaver = NULL;
+ ASSERT(ppiCurrent);
- /* Notify logon application to restart shell if needed */
- if(Win32Process->rpdeskStartup->pDeskInfo)
- {
- if(Win32Process->rpdeskStartup->pDeskInfo->ppiShellProcess == Win32Process)
- {
- DWORD ExitCode;
- ExitCode = PsGetProcessExitStatus(Win32Process->peProcess);
+ TRACE_CH(UserProcess, "Destroying W32 process PID:%d at IRQ level: %lu\n", Process->UniqueProcessId, KeGetCurrentIrql());
+ ppiCurrent->W32PF_flags |= W32PF_TERMINATED;
- DPRINT1("Shell process is exiting (%d)\n", ExitCode);
+ if (ppiScrnSaver == ppiCurrent)
+ ppiScrnSaver = NULL;
- UserPostMessage(hwndSAS,
- WM_LOGONNOTIFY,
- LN_SHELL_EXITED,
- ExitCode);
- }
- }
-
- if (Win32Process->InputIdleEvent)
+ if (ppiCurrent->InputIdleEvent)
{
- EngFreeMem((PVOID)Win32Process->InputIdleEvent);
- Win32Process->InputIdleEvent = NULL;
+ EngFreeMem(ppiCurrent->InputIdleEvent);
+ ppiCurrent->InputIdleEvent = NULL;
}
- IntCleanupMenus(Process, Win32Process);
- IntCleanupCurIcons(Process, Win32Process);
+ IntCleanupMenus(Process, ppiCurrent);
+ IntCleanupCurIcons(Process, ppiCurrent);
/* no process windows should exist at this point, or the function will assert! */
- DestroyProcessClasses(Win32Process);
- Win32Process->W32PF_flags &= ~W32PF_CLASSESREGISTERED;
+ DestroyProcessClasses(ppiCurrent);
+ ppiCurrent->W32PF_flags &= ~W32PF_CLASSESREGISTERED;
GDI_CleanupForProcess(Process);
/*
* Deregister logon application automatically
*/
- if(LogonProcess == Win32Process)
+ if(LogonProcess == ppiCurrent)
{
LogonProcess = NULL;
}
/* Close the startup desktop */
- ASSERT(Win32Process->rpdeskStartup);
- ASSERT(Win32Process->hdeskStartup);
- ObDereferenceObject(Win32Process->rpdeskStartup);
- ZwClose(Win32Process->hdeskStartup);
+ ASSERT(ppiCurrent->rpdeskStartup);
+ ASSERT(ppiCurrent->hdeskStartup);
+ ObDereferenceObject(ppiCurrent->rpdeskStartup);
+ ZwClose(ppiCurrent->hdeskStartup);
/* Close the current window station */
UserSetProcessWindowStation(NULL);
/* Destroy GDI pools */
- GdiPoolDestroy(Win32Process->pPoolDcAttr);
- GdiPoolDestroy(Win32Process->pPoolBrushAttr);
- GdiPoolDestroy(Win32Process->pPoolRgnAttr);
+ GdiPoolDestroy(ppiCurrent->pPoolDcAttr);
+ GdiPoolDestroy(ppiCurrent->pPoolBrushAttr);
+ GdiPoolDestroy(ppiCurrent->pPoolRgnAttr);
/* Ftee the PROCESSINFO */
PsSetProcessWin32Process(Process, NULL);
- ExFreePoolWithTag(Win32Process, USERTAG_PROCESSINFO);
+ ExFreePoolWithTag(ppiCurrent, USERTAG_PROCESSINFO);
}
RETURN( STATUS_SUCCESS);
PTHREADINFO ptiCurrent;
int i;
NTSTATUS Status;
+ PTEB pTeb;
DPRINT("Enter Win32kThreadCallback\n");
UserEnterExclusive();
Process = Thread->ThreadsProcess;
+ pTeb = NtCurrentTeb();
- /* Get the Win32 Thread */
- ptiCurrent = PsGetThreadWin32Thread(Thread);
+ ASSERT(pTeb);
- /* Allocate one if needed */
- if (!ptiCurrent)
+ if (Type == PsW32ThreadCalloutInitialize)
{
- /* FIXME: Lock the process */
+ HWINSTA hWinSta = NULL;
+ PCLIENTINFO pci;
+ HDESK hDesk = NULL;
+ PUNICODE_STRING DesktopPath;
+ PDESKTOP pdesk;
+ PRTL_USER_PROCESS_PARAMETERS ProcessParams = Process->Peb->ProcessParameters;
+
+ ASSERT(PsGetThreadWin32Thread(Thread)==NULL);
+
ptiCurrent = ExAllocatePoolWithTag(NonPagedPool,
sizeof(THREADINFO),
USERTAG_THREADINFO);
-
if (ptiCurrent == NULL)
{
Status = STATUS_NO_MEMORY;
RtlZeroMemory(ptiCurrent, sizeof(THREADINFO));
PsSetThreadWin32Thread(Thread, ptiCurrent);
- /* FIXME: Unlock the process */
- }
-
- if (Type == PsW32ThreadCalloutInitialize)
- {
- HWINSTA hWinSta = NULL;
- PTEB pTeb;
- HDESK hDesk = NULL;
- PUNICODE_STRING DesktopPath;
- PDESKTOP pdesk;
- PRTL_USER_PROCESS_PARAMETERS ProcessParams = (Process->Peb ? Process->Peb->ProcessParameters : NULL);
+ pTeb->Win32ThreadInfo = ptiCurrent;
+ ptiCurrent->pClientInfo = (PCLIENTINFO)pTeb->Win32ClientInfo;
- DPRINT("Creating W32 thread TID:%d at IRQ level: %lu\n", Thread->Cid.UniqueThread, KeGetCurrentIrql());
+ TRACE_CH(UserThread, "Creating W32 thread TID:%d at IRQ level: %lu\n", Thread->Cid.UniqueThread, KeGetCurrentIrql());
+ /* Initialize the THREADINFO */
InitializeListHead(&ptiCurrent->WindowListHead);
InitializeListHead(&ptiCurrent->W32CallbackListHead);
InitializeListHead(&ptiCurrent->PtiLink);
{
InitializeListHead(&ptiCurrent->aphkStart[i]);
}
-
- ptiCurrent->TIF_flags &= ~TIF_INCLEANUP;
- co_IntDestroyCaret(ptiCurrent);
+ ptiCurrent->pEThread = Thread;
ptiCurrent->ppi = PsGetCurrentProcessWin32Process();
ptiCurrent->ptiSibling = ptiCurrent->ppi->ptiList;
ptiCurrent->ppi->ptiList = ptiCurrent;
ptiCurrent->ppi->cThreads++;
- if (ptiCurrent->rpdesk && !ptiCurrent->pDeskInfo)
- {
- ptiCurrent->pDeskInfo = ptiCurrent->rpdesk->pDeskInfo;
- }
ptiCurrent->MessageQueue = MsqCreateMessageQueue(Thread);
ptiCurrent->KeyboardLayout = W32kGetDefaultKeyLayout();
if (ptiCurrent->KeyboardLayout)
UserReferenceObject(ptiCurrent->KeyboardLayout);
- ptiCurrent->pEThread = Thread;
+ ptiCurrent->TIF_flags &= ~TIF_INCLEANUP;
- /* HAAAAAAAACK! This should go to Win32kProcessCallback */
- if(ptiCurrent->ppi->hdeskStartup == NULL)
+ /* Initialize the CLIENTINFO */
+ pci = (PCLIENTINFO)pTeb->Win32ClientInfo;
+ RtlZeroMemory(pci, sizeof(CLIENTINFO));
+ pci->ppi = ptiCurrent->ppi;
+ pci->fsHooks = ptiCurrent->fsHooks;
+ pci->dwTIFlags = ptiCurrent->TIF_flags;
+ if (ptiCurrent->KeyboardLayout)
+ pci->hKL = ptiCurrent->KeyboardLayout->hkl;
+
+ /* Assign a default window station and desktop to the process */
+ /* Do not try to open a desktop or window station before winlogon initializes */
+ if(ptiCurrent->ppi->hdeskStartup == NULL && LogonProcess != NULL)
{
/*
* inherit the thread desktop and process window station (if not yet inherited) from the process startup
DesktopPath,
&hWinSta,
&hDesk);
- if(NT_SUCCESS(Status))
+ if(!NT_SUCCESS(Status))
{
- if(hWinSta != NULL)
- {
- if(!UserSetProcessWindowStation(hWinSta))
- {
- DPRINT1("Failed to set process window station\n");
- }
- }
-
- if (hDesk != NULL)
- {
- /* Validate the new desktop. */
- Status = IntValidateDesktopHandle(hDesk,
- UserMode,
- 0,
- &pdesk);
-
- if(NT_SUCCESS(Status))
- {
- ptiCurrent->ppi->hdeskStartup = hDesk;
- ptiCurrent->ppi->rpdeskStartup = pdesk;
- }
- }
+ ERR_CH(UserThread, "Failed to assign default dekstop and winsta to process\n");
+ goto leave;
}
- else
+
+ if(!UserSetProcessWindowStation(hWinSta))
{
- DPRINT1("No Desktop handle for this Thread!\n");
+ Status = STATUS_UNSUCCESSFUL;
+ goto leave;
}
+
+ /* Validate the new desktop. */
+ Status = IntValidateDesktopHandle(hDesk, UserMode, 0, &pdesk);
+ if(!NT_SUCCESS(Status))
+ {
+ goto leave;
+ }
+
+ /* Store the parsed desktop as the initial desktop */
+ ptiCurrent->ppi->hdeskStartup = hDesk;
+ ptiCurrent->ppi->rpdeskStartup = pdesk;
}
if (ptiCurrent->ppi->hdeskStartup != NULL)
{
if (!IntSetThreadDesktop(ptiCurrent->ppi->hdeskStartup, FALSE))
{
- DPRINT1("Unable to set thread desktop\n");
+ ERR_CH(UserThread,"Unable to set thread desktop\n");
+ Status = STATUS_UNSUCCESSFUL;
+ goto leave;
}
}
-
- pTeb = NtCurrentTeb();
- if (pTeb)
- { /* Attempt to startup client support which should have been initialized in IntSetThreadDesktop. */
- PCLIENTINFO pci = (PCLIENTINFO)pTeb->Win32ClientInfo;
- ptiCurrent->pClientInfo = pci;
- pci->ppi = ptiCurrent->ppi;
- pci->fsHooks = ptiCurrent->fsHooks;
- if (ptiCurrent->KeyboardLayout) pci->hKL = ptiCurrent->KeyboardLayout->hkl;
- pci->dwTIFlags = ptiCurrent->TIF_flags;
-
- /* CI may not have been initialized. */
- if (!pci->pDeskInfo && ptiCurrent->pDeskInfo)
- {
- if (!pci->ulClientDelta) pci->ulClientDelta = DesktopHeapGetUserDelta();
-
- pci->pDeskInfo = (PVOID)((ULONG_PTR)ptiCurrent->pDeskInfo - pci->ulClientDelta);
- }
- if (ptiCurrent->pcti && pci->pDeskInfo)
- pci->pClientThreadInfo = (PVOID)((ULONG_PTR)ptiCurrent->pcti - pci->ulClientDelta);
- else
- pci->pClientThreadInfo = NULL;
- }
- else
- {
- DPRINT1("No TEB for this Thread!\n");
- // System thread running! Now SendMessage should be okay.
- ptiCurrent->pcti = &ptiCurrent->cti;
- }
- GetW32ThreadInfo();
}
else
{
PSINGLE_LIST_ENTRY psle;
PPROCESSINFO ppiCurrent;
- DPRINT("Destroying W32 thread TID:%d at IRQ level: %lu\n", Thread->Cid.UniqueThread, KeGetCurrentIrql());
+ /* Get the Win32 Thread */
+ ptiCurrent = PsGetThreadWin32Thread(Thread);
+
+ ASSERT(ptiCurrent);
+
+ TRACE_CH(UserThread,"Destroying W32 thread TID:%d at IRQ level: %lu\n", Thread->Cid.UniqueThread, KeGetCurrentIrql());
ppiCurrent = ptiCurrent->ppi;
ptiCurrent->TIF_flags |= TIF_INCLEANUP;
+ ptiCurrent->pClientInfo->dwTIFlags = ptiCurrent->TIF_flags;
/* Find the THREADINFO in the PROCESSINFO's list */
ppti = &ppiCurrent->ptiList;
/* Unregister the api hook without blocking */
UserUnregisterUserApiHook();
}
+
+ /* Notify logon application to restart shell if needed */
+ if(ptiCurrent->pDeskInfo)
+ {
+ if(ptiCurrent->pDeskInfo->ppiShellProcess == ppiCurrent)
+ {
+ DWORD ExitCode = PsGetProcessExitStatus(Process);
+
+ TRACE_PPI(ppiCurrent, UserProcess, "Shell process is exiting (%d)\n", ExitCode);
+
+ UserPostMessage(hwndSAS,
+ WM_LOGONNOTIFY,
+ LN_SHELL_EXITED,
+ ExitCode);
+
+ ptiCurrent->pDeskInfo->ppiShellProcess = NULL;
+ }
+ }
}
DceFreeThreadDCE(ptiCurrent);
KeSetEvent(ptiCurrent->MessageQueue->NewMessages, IO_NO_INCREMENT, FALSE);
UnregisterThreadHotKeys(Thread);
- /* what if this co_ func crash in umode? what will clean us up then? */
co_DestroyThreadWindows(Thread);
IntBlockInput(ptiCurrent, FALSE);
MsqDestroyMessageQueue(ptiCurrent->MessageQueue);
while (psle)
{
PUSER_REFERENCE_ENTRY ref = CONTAINING_RECORD(psle, USER_REFERENCE_ENTRY, Entry);
- DPRINT("thread clean: remove reference obj 0x%x\n",ref->obj);
+ TRACE_CH(UserThread,"thread clean: remove reference obj 0x%x\n",ref->obj);
UserDereferenceObject(ref->obj);
psle = PopEntryList(&ptiCurrent->ReferencesList);
NTSTATUS
APIENTRY
DriverEntry(
- IN PDRIVER_OBJECT DriverObject,
- IN PUNICODE_STRING RegistryPath)
+ IN PDRIVER_OBJECT DriverObject,
+ IN PUNICODE_STRING RegistryPath)
{
NTSTATUS Status;
BOOLEAN Result;
/* 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,