diff --git a/reactos/subsystems/win32/win32k/include/gdidebug.h b/reactos/subsystems/win32/win32k/include/gdidebug.h index 5b53ec44218..d59d367d75f 100644 --- a/reactos/subsystems/win32/win32k/include/gdidebug.h +++ b/reactos/subsystems/win32/win32k/include/gdidebug.h @@ -55,11 +55,11 @@ NTSYSAPI ULONG APIENTRY RtlWalkFrameChain(OUT PVOID *Callers, IN ULONG Count, IN #if DBG void NTAPI -DbgPreServiceHook(ULONG ulSyscallId, PULONG_PTR pulArguments); +GdiDbgPreServiceHook(ULONG ulSyscallId, PULONG_PTR pulArguments); ULONG_PTR NTAPI -DbgPostServiceHook(ULONG ulSyscallId, ULONG_PTR ulResult); +GdiDbgPostServiceHook(ULONG ulSyscallId, ULONG_PTR ulResult); #define ID_Win32PreServiceHook 'WSH0' #define ID_Win32PostServiceHook 'WSH1' diff --git a/reactos/subsystems/win32/win32k/include/ntuser.h b/reactos/subsystems/win32/win32k/include/ntuser.h index b0f0b043ad6..1f97e9554d2 100644 --- a/reactos/subsystems/win32/win32k/include/ntuser.h +++ b/reactos/subsystems/win32/win32k/include/ntuser.h @@ -9,6 +9,7 @@ #define UserEnterCo UserEnterExclusive #define UserLeaveCo UserLeave +extern BOOL gbInitialized; extern PSERVERINFO gpsi; extern PTHREADINFO gptiCurrent; extern PPROCESSINFO ppiScrnSaver; diff --git a/reactos/subsystems/win32/win32k/include/win32.h b/reactos/subsystems/win32/win32k/include/win32.h index 2cc36a55d98..480c267a861 100644 --- a/reactos/subsystems/win32/win32k/include/win32.h +++ b/reactos/subsystems/win32/win32k/include/win32.h @@ -198,3 +198,9 @@ typedef struct _PROCESSINFO BYTE DbgChannelLevel[DbgChCount]; #endif } PROCESSINFO; + +#ifdef DBG +void NTAPI UserDbgPreServiceHook(ULONG ulSyscallId, PULONG_PTR pulArguments); +ULONG_PTR NTAPI UserDbgPostServiceHook(ULONG ulSyscallId, ULONG_PTR ulResult); +#endif + diff --git a/reactos/subsystems/win32/win32k/main/dllmain.c b/reactos/subsystems/win32/win32k/main/dllmain.c index 0c7fff08457..60dbd63b490 100644 --- a/reactos/subsystems/win32/win32k/main/dllmain.c +++ b/reactos/subsystems/win32/win32k/main/dllmain.c @@ -29,52 +29,62 @@ extern ULONG_PTR Win32kSSDT[]; 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; @@ -93,89 +103,76 @@ Win32kProcessCallback(struct _EPROCESS *Process, 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) + TRACE_CH(UserProcess, "Destroying W32 process PID:%d at IRQ level: %lu\n", Process->UniqueProcessId, KeGetCurrentIrql()); + ppiCurrent->W32PF_flags |= W32PF_TERMINATED; + + if (ppiScrnSaver == ppiCurrent) + ppiScrnSaver = NULL; + + if (ppiCurrent->InputIdleEvent) { - if(Win32Process->rpdeskStartup->pDeskInfo->ppiShellProcess == Win32Process) - { - DWORD ExitCode; - ExitCode = PsGetProcessExitStatus(Win32Process->peProcess); - - DPRINT1("Shell process is exiting (%d)\n", ExitCode); - - UserPostMessage(hwndSAS, - WM_LOGONNOTIFY, - LN_SHELL_EXITED, - ExitCode); - } + EngFreeMem(ppiCurrent->InputIdleEvent); + ppiCurrent->InputIdleEvent = NULL; } - if (Win32Process->InputIdleEvent) - { - EngFreeMem((PVOID)Win32Process->InputIdleEvent); - Win32Process->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); @@ -184,28 +181,28 @@ Win32kProcessCallback(struct _EPROCESS *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); @@ -226,23 +223,30 @@ Win32kThreadCallback(struct _ETHREAD *Thread, 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; @@ -252,20 +256,12 @@ Win32kThreadCallback(struct _ETHREAD *Thread, RtlZeroMemory(ptiCurrent, sizeof(THREADINFO)); PsSetThreadWin32Thread(Thread, ptiCurrent); - /* FIXME: Unlock the process */ - } + pTeb->Win32ThreadInfo = ptiCurrent; + ptiCurrent->pClientInfo = (PCLIENTINFO)pTeb->Win32ClientInfo; - 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); - - 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); @@ -273,25 +269,29 @@ Win32kThreadCallback(struct _ETHREAD *Thread, { 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 @@ -302,74 +302,39 @@ Win32kThreadCallback(struct _ETHREAD *Thread, 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 { @@ -377,10 +342,16 @@ Win32kThreadCallback(struct _ETHREAD *Thread, 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; @@ -407,6 +378,24 @@ Win32kThreadCallback(struct _ETHREAD *Thread, /* 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); @@ -418,7 +407,6 @@ Win32kThreadCallback(struct _ETHREAD *Thread, 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); @@ -431,7 +419,7 @@ Win32kThreadCallback(struct _ETHREAD *Thread, 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); @@ -474,8 +462,8 @@ INIT_FUNCTION NTSTATUS APIENTRY DriverEntry( - IN PDRIVER_OBJECT DriverObject, - IN PUNICODE_STRING RegistryPath) + IN PDRIVER_OBJECT DriverObject, + IN PUNICODE_STRING RegistryPath) { NTSTATUS Status; BOOLEAN Result; @@ -513,11 +501,9 @@ DriverEntry( /* 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, diff --git a/reactos/subsystems/win32/win32k/ntuser/desktop.c b/reactos/subsystems/win32/win32k/ntuser/desktop.c index 55dd8f83294..a04d2cedffe 100644 --- a/reactos/subsystems/win32/win32k/ntuser/desktop.c +++ b/reactos/subsystems/win32/win32k/ntuser/desktop.c @@ -864,6 +864,7 @@ NtUserCreateDesktop( /* Turn off hooks when calling any CreateWindowEx from inside win32k. */ NoHooks = (ptiCurrent->TIF_flags & TIF_DISABLEHOOKS); ptiCurrent->TIF_flags |= TIF_DISABLEHOOKS; + ptiCurrent->pClientInfo->dwTIFlags = ptiCurrent->TIF_flags; } DesktopName.Buffer = NULL; @@ -1069,7 +1070,11 @@ CLEANUP: { ExFreePoolWithTag(DesktopName.Buffer, TAG_STRING); } - if (!NoHooks && ptiCurrent) ptiCurrent->TIF_flags &= ~TIF_DISABLEHOOKS; + if (!NoHooks && ptiCurrent) + { + ptiCurrent->TIF_flags &= ~TIF_DISABLEHOOKS; + ptiCurrent->pClientInfo->dwTIFlags = ptiCurrent->TIF_flags; + } TRACE("Leave NtUserCreateDesktop, ret=%i\n",_ret_); UserLeave(); END_CLEANUP; @@ -1676,15 +1681,14 @@ CLEANUP: static NTSTATUS IntUnmapDesktopView(IN PDESKTOP DesktopObject) { - PTHREADINFO ti; - PPROCESSINFO CurrentWin32Process; + PPROCESSINFO ppi; PW32HEAP_USER_MAPPING HeapMapping, *PrevLink; NTSTATUS Status = STATUS_SUCCESS; TRACE("DO %p\n"); - CurrentWin32Process = PsGetCurrentProcessWin32Process(); - PrevLink = &CurrentWin32Process->HeapMappings.Next; + ppi = PsGetCurrentProcessWin32Process(); + PrevLink = &ppi->HeapMappings.Next; /* Unmap if we're the last thread using the desktop */ HeapMapping = *PrevLink; @@ -1710,13 +1714,6 @@ IntUnmapDesktopView(IN PDESKTOP DesktopObject) HeapMapping = HeapMapping->Next; } - ti = GetW32ThreadInfo(); - if (ti != NULL) - { - GetWin32ClientInfo()->pDeskInfo = NULL; - } - GetWin32ClientInfo()->ulClientDelta = 0; - return Status; } @@ -1792,17 +1789,21 @@ BOOL IntSetThreadDesktop(IN HDESK hDesktop, IN BOOL FreeOnFailure) { - PDESKTOP DesktopObject = NULL, OldDesktop; - HDESK hOldDesktop; - PTHREADINFO W32Thread; + PDESKTOP pdesk = NULL, pdeskOld; + HDESK hdeskOld; + PTHREADINFO pti; NTSTATUS Status; - BOOL MapHeap; - CLIENTTHREADINFO ctiSave; + PCLIENTTHREADINFO pctiOld, pctiNew; + PCLIENTINFO pci; + + ASSERT(NtCurrentTeb()); TRACE("IntSetThreadDesktop() , FOF=%d\n", FreeOnFailure); - MapHeap = (PsGetCurrentProcess() != PsInitialSystemProcess); - W32Thread = PsGetCurrentThreadWin32Thread(); + pti = PsGetCurrentThreadWin32Thread(); + pci = pti->pClientInfo; + + /* If the caller gave us a desktop, ensure it is valid */ if(hDesktop != NULL) { /* Validate the new desktop. */ @@ -1810,7 +1811,7 @@ IntSetThreadDesktop(IN HDESK hDesktop, hDesktop, UserMode, 0, - &DesktopObject); + &pdesk); if (!NT_SUCCESS(Status)) { @@ -1818,106 +1819,113 @@ IntSetThreadDesktop(IN HDESK hDesktop, return FALSE; } - if (W32Thread->rpdesk == DesktopObject) + if (pti->rpdesk == pdesk) { /* Nothing to do */ - ObDereferenceObject(DesktopObject); + ObDereferenceObject(pdesk); return TRUE; } - } - if (!IsListEmpty(&W32Thread->WindowListHead)) + /* Make sure that we don't own any window in the current desktop */ + if (!IsListEmpty(&pti->WindowListHead)) { + if(pdesk) + ObDereferenceObject(pdesk); ERR("Attempted to change thread desktop although the thread has windows!\n"); EngSetLastError(ERROR_BUSY); return FALSE; } - OldDesktop = W32Thread->rpdesk; - hOldDesktop = W32Thread->hdesk; - - W32Thread->rpdesk = DesktopObject; - W32Thread->hdesk = hDesktop; - - if (MapHeap && DesktopObject != NULL) + /* Before doing the switch, map the new desktop heap and allocate the new pcti */ + if(pdesk != NULL) { - Status = IntMapDesktopView(DesktopObject); + Status = IntMapDesktopView(pdesk); if (!NT_SUCCESS(Status)) { + ERR("Failed to map desktop heap!\n"); + ObDereferenceObject(pdesk); SetLastNtError(Status); return FALSE; } - W32Thread->pDeskInfo = DesktopObject->pDeskInfo; + + pctiNew = DesktopHeapAlloc( pdesk, sizeof(CLIENTTHREADINFO)); + if(pctiNew == NULL) + { + ERR("Failed to allocate new pcti\n"); + IntUnmapDesktopView(pdesk); + ObDereferenceObject(pdesk); + EngSetLastError(ERROR_NOT_ENOUGH_MEMORY); + return FALSE; + } } - RtlZeroMemory(&ctiSave, sizeof(CLIENTTHREADINFO)); - - if (W32Thread->pcti && OldDesktop && NtCurrentTeb()) + /* free all classes or move them to the shared heap */ + if(pti->rpdesk != NULL) { - RtlCopyMemory(&ctiSave, W32Thread->pcti, sizeof(CLIENTTHREADINFO)); - TRACE("Free ClientThreadInfo\n"); - DesktopHeapFree(OldDesktop, W32Thread->pcti); - W32Thread->pcti = NULL; + if(!IntCheckProcessDesktopClasses(pti->rpdesk, FreeOnFailure)) + { + ERR("Failed to move process classes to shared heap!\n"); + if(pdesk) + { + DesktopHeapFree(pdesk, pctiNew); + IntUnmapDesktopView(pdesk); + ObDereferenceObject(pdesk); + } + return FALSE; + } } - if (!W32Thread->pcti && DesktopObject && NtCurrentTeb()) - { - TRACE("Allocate ClientThreadInfo\n"); - W32Thread->pcti = DesktopHeapAlloc( DesktopObject, - sizeof(CLIENTTHREADINFO)); - RtlCopyMemory(W32Thread->pcti, &ctiSave, sizeof(CLIENTTHREADINFO)); - } + pdeskOld = pti->rpdesk; + hdeskOld = pti->hdesk; + pctiOld = pti->pcti; - if (NtCurrentTeb()) + /* do the switch */ + if(pdesk != NULL) { - PCLIENTINFO pci = GetWin32ClientInfo(); + pti->rpdesk = pdesk; + pti->hdesk = hDesktop; + pti->pDeskInfo = pti->rpdesk->pDeskInfo; + pti->pcti = pctiNew; + pci->ulClientDelta = DesktopHeapGetUserDelta(); - if (DesktopObject) + pci->pDeskInfo = (PVOID)((ULONG_PTR)pti->pDeskInfo - pci->ulClientDelta); + pci->pClientThreadInfo = (PVOID)((ULONG_PTR)pti->pcti - pci->ulClientDelta); + + /* initialize the new pcti */ + if(pctiOld != NULL) { - pci->pDeskInfo = (PVOID)((ULONG_PTR)DesktopObject->pDeskInfo - pci->ulClientDelta); - if (W32Thread->pcti) pci->pClientThreadInfo = (PVOID)((ULONG_PTR)W32Thread->pcti - pci->ulClientDelta); + RtlCopyMemory(pctiNew, pctiOld, sizeof(CLIENTTHREADINFO)); + } + else + { + RtlZeroMemory(pctiNew, sizeof(CLIENTTHREADINFO)); } } - - if (OldDesktop != NULL && - !IntCheckProcessDesktopClasses(OldDesktop, - FreeOnFailure)) + else { - ERR("Failed to move process classes to shared heap!\n"); - - /* Failed to move desktop classes to the shared heap, - unmap the view and return the error */ - if (MapHeap && DesktopObject != NULL) - IntUnmapDesktopView(DesktopObject); - - return FALSE; + pti->rpdesk = NULL; + pti->hdesk = NULL; + pti->pDeskInfo = NULL; + pti->pcti = NULL; + pci->ulClientDelta = 0; + pci->pDeskInfo = NULL; + pci->pClientThreadInfo = NULL; + } + + /* clean up the old desktop */ + if(pdeskOld != NULL) + { + RemoveEntryList(&pti->PtiLink); + DesktopHeapFree(pdeskOld, pctiOld); + IntUnmapDesktopView(pdeskOld); + ObDereferenceObject(pdeskOld); + ZwClose(hdeskOld); } - /* Remove the thread from the old desktop's list */ - RemoveEntryList(&W32Thread->PtiLink); - - if (DesktopObject != NULL) + if(pdesk) { - ObReferenceObject(DesktopObject); - /* Insert into new desktop's list */ - InsertTailList(&DesktopObject->PtiList, &W32Thread->PtiLink); - } - - /* Close the old desktop */ - if (OldDesktop != NULL) - { - if (MapHeap) - { - IntUnmapDesktopView(OldDesktop); - } - - ObDereferenceObject(OldDesktop); - } - - if (hOldDesktop != NULL) - { - ZwClose(hOldDesktop); + InsertTailList(&pdesk->PtiList, &pti->PtiLink); } return TRUE; diff --git a/reactos/subsystems/win32/win32k/ntuser/input.c b/reactos/subsystems/win32/win32k/ntuser/input.c index 8ad738cc295..7db00b66ab2 100644 --- a/reactos/subsystems/win32/win32k/ntuser/input.c +++ b/reactos/subsystems/win32/win32k/ntuser/input.c @@ -141,8 +141,10 @@ RawInputThreadMain() ByteOffset.QuadPart = (LONGLONG)0; //WaitTimeout.QuadPart = (LONGLONG)(-10000000); - ptiRawInput = PsGetCurrentThreadWin32Thread(); + ptiRawInput = GetW32ThreadInfo(); ptiRawInput->TIF_flags |= TIF_SYSTEMTHREAD; + ptiRawInput->pClientInfo->dwTIFlags = ptiRawInput->TIF_flags; + TRACE("Raw Input Thread 0x%x\n", ptiRawInput); KeSetPriorityThread(&PsGetCurrentThread()->Tcb, diff --git a/reactos/subsystems/win32/win32k/ntuser/misc.c b/reactos/subsystems/win32/win32k/ntuser/misc.c index 56449425c0c..ee96c7da2c1 100644 --- a/reactos/subsystems/win32/win32k/ntuser/misc.c +++ b/reactos/subsystems/win32/win32k/ntuser/misc.c @@ -542,6 +542,68 @@ IntSafeCopyUnicodeStringTerminateNULL(PUNICODE_STRING Dest, return STATUS_SUCCESS; } +void UserDbgAssertThreadInfo(BOOL showCaller) +{ + PTEB Teb; + PPROCESSINFO ppi; + PCLIENTINFO pci; + PTHREADINFO pti; + + ppi = PsGetCurrentProcessWin32Process(); + pti = PsGetCurrentThreadWin32Thread(); + Teb = NtCurrentTeb(); + pci = GetWin32ClientInfo(); + + ASSERT(Teb); + ASSERT(pti); + ASSERT(pti->ppi == ppi); + ASSERT(pti->pClientInfo == pci); + ASSERT(Teb->Win32ThreadInfo == pti); + ASSERT(pci->ppi == ppi); + ASSERT(pci->fsHooks == pti->fsHooks); + ASSERT(pci->ulClientDelta == DesktopHeapGetUserDelta()); + if (pti->pcti && pci->pDeskInfo) + ASSERT(pci->pClientThreadInfo == (PVOID)((ULONG_PTR)pti->pcti - pci->ulClientDelta)); + if (pti->KeyboardLayout) + ASSERT(pci->hKL == pti->KeyboardLayout->hkl); + if(pti->rpdesk != NULL) + ASSERT(pti->pDeskInfo == pti->rpdesk->pDeskInfo); + + /*too bad we still get this assertion*/ + /* ASSERT(pci->dwTIFlags == pti->TIF_flags); */ + if(pci->dwTIFlags != pti->TIF_flags) + { + ERR("pci->dwTIFlags(0x%x) doesn't match pti->TIF_flags(0x%x)\n", pci->dwTIFlags, pti->TIF_flags); + if(showCaller) + { + DbgPrint("Caller:\n"); + KeRosDumpStackFrames(NULL, 10); + } + pci->dwTIFlags = pti->TIF_flags; + } +} + +void +NTAPI +UserDbgPreServiceHook(ULONG ulSyscallId, PULONG_PTR pulArguments) +{ + UserDbgAssertThreadInfo(FALSE); +} + +ULONG_PTR +NTAPI +UserDbgPostServiceHook(ULONG ulSyscallId, ULONG_PTR ulResult) +{ + /* Make sure that the first syscall is NtUserInitialize */ + /* too bad this fails */ + //ASSERT(gbInitialized); + + UserDbgAssertThreadInfo(TRUE); + + return ulResult; +} + + PPROCESSINFO GetW32ProcessInfo(VOID) { @@ -551,66 +613,8 @@ GetW32ProcessInfo(VOID) PTHREADINFO GetW32ThreadInfo(VOID) { - PTEB Teb; - PPROCESSINFO ppi; - PCLIENTINFO pci; - PTHREADINFO pti = PsGetCurrentThreadWin32Thread(); - - if (pti == NULL) - { - /* FIXME: Temporary hack for system threads... */ - return NULL; - } - /* Initialize it */ - pti->ppi = ppi = GetW32ProcessInfo(); - - if (pti->rpdesk != NULL) - { - pti->pDeskInfo = pti->rpdesk->pDeskInfo; - } - else - { - pti->pDeskInfo = NULL; - } - /* Update the TEB */ - Teb = NtCurrentTeb(); - pci = GetWin32ClientInfo(); - pti->pClientInfo = pci; - _SEH2_TRY - { - if(Teb) - { - ProbeForWrite( Teb, - sizeof(TEB), - sizeof(ULONG)); - - Teb->Win32ThreadInfo = (PW32THREAD) pti; - } - - pci->ppi = ppi; - pci->fsHooks = pti->fsHooks; - if (pti->KeyboardLayout) pci->hKL = pti->KeyboardLayout->hkl; - pci->dwTIFlags = pti->TIF_flags; - /* CI may not have been initialized. */ - if (!pci->pDeskInfo && pti->pDeskInfo) - { - if (!pci->ulClientDelta) pci->ulClientDelta = DesktopHeapGetUserDelta(); - - pci->pDeskInfo = (PVOID)((ULONG_PTR)pti->pDeskInfo - pci->ulClientDelta); - } - if (pti->pcti && pci->pDeskInfo) - pci->pClientThreadInfo = (PVOID)((ULONG_PTR)pti->pcti - pci->ulClientDelta); - else - pci->pClientThreadInfo = NULL; - - } - _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) - { - SetLastNtError(_SEH2_GetExceptionCode()); - } - _SEH2_END; - - return pti; + UserDbgAssertThreadInfo(TRUE); + return (PTHREADINFO)PsGetCurrentThreadWin32Thread(); } /* EOF */ diff --git a/reactos/subsystems/win32/win32k/objects/gdidbg.c b/reactos/subsystems/win32/win32k/objects/gdidbg.c index 803d41e5e67..51b2a430448 100644 --- a/reactos/subsystems/win32/win32k/objects/gdidbg.c +++ b/reactos/subsystems/win32/win32k/objects/gdidbg.c @@ -483,7 +483,7 @@ DbgCleanupEventList(PSLIST_HEADER pslh) void NTAPI -DbgPreServiceHook(ULONG ulSyscallId, PULONG_PTR pulArguments) +GdiDbgPreServiceHook(ULONG ulSyscallId, PULONG_PTR pulArguments) { PTHREADINFO pti = (PTHREADINFO)PsGetCurrentThreadWin32Thread(); if (pti && pti->cExclusiveLocks != 0) @@ -498,7 +498,7 @@ DbgPreServiceHook(ULONG ulSyscallId, PULONG_PTR pulArguments) ULONG_PTR NTAPI -DbgPostServiceHook(ULONG ulSyscallId, ULONG_PTR ulResult) +GdiDbgPostServiceHook(ULONG ulSyscallId, ULONG_PTR ulResult) { PTHREADINFO pti = (PTHREADINFO)PsGetCurrentThreadWin32Thread(); if (pti && pti->cExclusiveLocks != 0)