Author: gadamopoulos Date: Mon Feb 6 12:30:59 2012 New Revision: 55458 URL: http://svn.reactos.org/svn/reactos?rev=55458&view=rev Log: [win32k] - Cleanup Win32kProcessCallback and Win32kThreadCallback - Even though it works, trying to post a message in Win32kProcessCallback after the THREADINFO is destroyed can only cause trouble, so move it in Win32kThreadCallback - There is no need to try opening a desktop and windowstation before winlogon initializes - Handle errors properly when we fail to get a default window station and desktop for the new process - Enable win32k syscall hook callbacks - Rewrite SetThreadDesktop to update THREADINFO properly and handle errors properly - Do not initialize the THREADINFO in GetW32ThreadInfo as it is now done properly (actually leave a small hack that updates pci->dwTIFlags) - Add UserDbgAssertThreadInfo that asserts the integrity of THREADINFO, CLIENTINFO and CLIENTTHREADINFO. This is called by GetW32ThreadInfo and the syscall hook callbacks
Modified: trunk/reactos/subsystems/win32/win32k/include/gdidebug.h trunk/reactos/subsystems/win32/win32k/include/ntuser.h trunk/reactos/subsystems/win32/win32k/include/win32.h trunk/reactos/subsystems/win32/win32k/main/dllmain.c trunk/reactos/subsystems/win32/win32k/ntuser/desktop.c trunk/reactos/subsystems/win32/win32k/ntuser/input.c trunk/reactos/subsystems/win32/win32k/ntuser/misc.c trunk/reactos/subsystems/win32/win32k/objects/gdidbg.c Modified: trunk/reactos/subsystems/win32/win32k/include/gdidebug.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/include/gdidebug.h?rev=55458&r1=55457&r2=55458&view=diff ============================================================================== --- trunk/reactos/subsystems/win32/win32k/include/gdidebug.h [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/win32k/include/gdidebug.h [iso-8859-1] Mon Feb 6 12:30:59 2012 @@ -55,11 +55,11 @@ #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' Modified: trunk/reactos/subsystems/win32/win32k/include/ntuser.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/include/ntuser.h?rev=55458&r1=55457&r2=55458&view=diff ============================================================================== --- trunk/reactos/subsystems/win32/win32k/include/ntuser.h [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/win32k/include/ntuser.h [iso-8859-1] Mon Feb 6 12:30:59 2012 @@ -9,6 +9,7 @@ #define UserEnterCo UserEnterExclusive #define UserLeaveCo UserLeave +extern BOOL gbInitialized; extern PSERVERINFO gpsi; extern PTHREADINFO gptiCurrent; extern PPROCESSINFO ppiScrnSaver; Modified: trunk/reactos/subsystems/win32/win32k/include/win32.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/include/win32.h?rev=55458&r1=55457&r2=55458&view=diff ============================================================================== --- trunk/reactos/subsystems/win32/win32k/include/win32.h [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/win32k/include/win32.h [iso-8859-1] Mon Feb 6 12:30:59 2012 @@ -198,3 +198,9 @@ 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 + Modified: trunk/reactos/subsystems/win32/win32k/main/dllmain.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/main/dllmain.c?rev=55458&r1=55457&r2=55458&view=diff ============================================================================== --- trunk/reactos/subsystems/win32/win32k/main/dllmain.c [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/win32k/main/dllmain.c [iso-8859-1] Mon Feb 6 12:30:59 2012 @@ -29,52 +29,62 @@ 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 @@ 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; - - InitializeListHead(&Win32Process->MenuListHead); - - InitializeListHead(&Win32Process->GDIBrushAttrFreeList); - InitializeListHead(&Win32Process->GDIDcAttrFreeList); - - InitializeListHead(&Win32Process->PrivateFontListHead); - ExInitializeFastMutex(&Win32Process->PrivateFontListLock); - - InitializeListHead(&Win32Process->DriverObjListHead); - 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(Process); - Process->Peb->GdiDCAttributeList = GDI_BATCH_LIMIT; - pParams = Process->Peb->ProcessParameters; - } - - Win32Process->peProcess = Process; + ppiCurrent->HeapMappings.Next = NULL; + ppiCurrent->HeapMappings.KernelMapping = (PVOID)GlobalUserHeap; + ppiCurrent->HeapMappings.UserMapping = UserBase; + ppiCurrent->HeapMappings.Count = 1; + + InitializeListHead(&ppiCurrent->MenuListHead); + + InitializeListHead(&ppiCurrent->GDIBrushAttrFreeList); + InitializeListHead(&ppiCurrent->GDIDcAttrFreeList); + + InitializeListHead(&ppiCurrent->PrivateFontListHead); + ExInitializeFastMutex(&ppiCurrent->PrivateFontListLock); + + InitializeListHead(&ppiCurrent->DriverObjListHead); + ExInitializeFastMutex(&ppiCurrent->DriverObjListLock); + + ppiCurrent->KeyboardLayout = W32kGetDefaultKeyLayout(); + EngCreateEvent((PEVENT *)&ppiCurrent->InputIdleEvent); + KeInitializeEvent(ppiCurrent->InputIdleEvent, NotificationEvent, FALSE); + + + /* map the gdi handle table to user land */ + Process->Peb->GdiSharedHandleTable = GDI_MapHandleTable(Process); + Process->Peb->GdiDCAttributeList = GDI_BATCH_LIMIT; + pParams = Process->Peb->ProcessParameters; + + 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; - - if (ppiScrnSaver == Win32Process) ppiScrnSaver = NULL; - - /* Notify logon application to restart shell if needed */ - if(Win32Process->rpdeskStartup->pDeskInfo) - { - 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); - } - } - - if (Win32Process->InputIdleEvent) - { - EngFreeMem((PVOID)Win32Process->InputIdleEvent); - Win32Process->InputIdleEvent = NULL; - } - - IntCleanupMenus(Process, Win32Process); - IntCleanupCurIcons(Process, Win32Process); + /* Get the Win32 Process */ + ppiCurrent = PsGetProcessWin32Process(Process); + + ASSERT(ppiCurrent); + + 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) + { + EngFreeMem(ppiCurrent->InputIdleEvent); + ppiCurrent->InputIdleEvent = NULL; + } + + 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 @@ /* * 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 @@ PTHREADINFO ptiCurrent; int i; NTSTATUS Status; + PTEB pTeb; DPRINT("Enter Win32kThreadCallback\n"); UserEnterExclusive(); Process = Thread->ThreadsProcess; - - /* Get the Win32 Thread */ - ptiCurrent = PsGetThreadWin32Thread(Thread); - - /* Allocate one if needed */ - if (!ptiCurrent) - { - /* FIXME: Lock the process */ + pTeb = NtCurrentTeb(); + + ASSERT(pTeb); + + if (Type == PsW32ThreadCalloutInitialize) + { + 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 @@ 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); - - DPRINT("Creating W32 thread TID:%d at IRQ level: %lu\n", Thread->Cid.UniqueThread, KeGetCurrentIrql()); - + pTeb->Win32ThreadInfo = ptiCurrent; + ptiCurrent->pClientInfo = (PCLIENTINFO)pTeb->Win32ClientInfo; + + 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 @@ { 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; - - /* HAAAAAAAACK! This should go to Win32kProcessCallback */ - if(ptiCurrent->ppi->hdeskStartup == NULL) + ptiCurrent->TIF_flags &= ~TIF_INCLEANUP; + + /* 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 @@ 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 @@ 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 @@ /* 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 @@ 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 @@ 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 @@ 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 @@ /* 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, Modified: trunk/reactos/subsystems/win32/win32k/ntuser/desktop.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ntuser/desktop.c?rev=55458&r1=55457&r2=55458&view=diff ============================================================================== --- trunk/reactos/subsystems/win32/win32k/ntuser/desktop.c [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/win32k/ntuser/desktop.c [iso-8859-1] Mon Feb 6 12:30:59 2012 @@ -864,6 +864,7 @@ /* 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 @@ { 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 @@ 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; @@ -1709,13 +1713,6 @@ PrevLink = &HeapMapping->Next; HeapMapping = HeapMapping->Next; } - - ti = GetW32ThreadInfo(); - if (ti != NULL) - { - GetWin32ClientInfo()->pDeskInfo = NULL; - } - GetWin32ClientInfo()->ulClientDelta = 0; return Status; } @@ -1792,17 +1789,21 @@ 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 @@ hDesktop, UserMode, 0, - &DesktopObject); + &pdesk); if (!NT_SUCCESS(Status)) { @@ -1818,106 +1819,113 @@ 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) - { - Status = IntMapDesktopView(DesktopObject); + /* Before doing the switch, map the new desktop heap and allocate the new pcti */ + if(pdesk != NULL) + { + Status = IntMapDesktopView(pdesk); if (!NT_SUCCESS(Status)) { + ERR("Failed to map desktop heap!\n"); + ObDereferenceObject(pdesk); SetLastNtError(Status); return FALSE; } - W32Thread->pDeskInfo = DesktopObject->pDeskInfo; - } - - RtlZeroMemory(&ctiSave, sizeof(CLIENTTHREADINFO)); - - if (W32Thread->pcti && OldDesktop && NtCurrentTeb()) - { - RtlCopyMemory(&ctiSave, W32Thread->pcti, sizeof(CLIENTTHREADINFO)); - TRACE("Free ClientThreadInfo\n"); - DesktopHeapFree(OldDesktop, W32Thread->pcti); - W32Thread->pcti = NULL; - } - - if (!W32Thread->pcti && DesktopObject && NtCurrentTeb()) - { - TRACE("Allocate ClientThreadInfo\n"); - W32Thread->pcti = DesktopHeapAlloc( DesktopObject, - sizeof(CLIENTTHREADINFO)); - RtlCopyMemory(W32Thread->pcti, &ctiSave, sizeof(CLIENTTHREADINFO)); - } - - if (NtCurrentTeb()) - { - PCLIENTINFO pci = GetWin32ClientInfo(); + + 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; + } + } + + /* free all classes or move them to the shared heap */ + if(pti->rpdesk != 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; + } + } + + pdeskOld = pti->rpdesk; + hdeskOld = pti->hdesk; + pctiOld = pti->pcti; + + /* do the switch */ + if(pdesk != NULL) + { + 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)); } - } - - if (OldDesktop != NULL && - !IntCheckProcessDesktopClasses(OldDesktop, - FreeOnFailure)) - { - 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; - } - - /* Remove the thread from the old desktop's list */ - RemoveEntryList(&W32Thread->PtiLink); - - if (DesktopObject != NULL) - { - ObReferenceObject(DesktopObject); - /* Insert into new desktop's list */ - InsertTailList(&DesktopObject->PtiList, &W32Thread->PtiLink); - } - - /* Close the old desktop */ - if (OldDesktop != NULL) - { - if (MapHeap) + else { - IntUnmapDesktopView(OldDesktop); + RtlZeroMemory(pctiNew, sizeof(CLIENTTHREADINFO)); } - - ObDereferenceObject(OldDesktop); - } - - if (hOldDesktop != NULL) - { - ZwClose(hOldDesktop); + } + else + { + 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); + } + + if(pdesk) + { + InsertTailList(&pdesk->PtiList, &pti->PtiLink); } return TRUE; Modified: trunk/reactos/subsystems/win32/win32k/ntuser/input.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ntuser/input.c?rev=55458&r1=55457&r2=55458&view=diff ============================================================================== --- trunk/reactos/subsystems/win32/win32k/ntuser/input.c [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/win32k/ntuser/input.c [iso-8859-1] Mon Feb 6 12:30:59 2012 @@ -141,8 +141,10 @@ 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, Modified: trunk/reactos/subsystems/win32/win32k/ntuser/misc.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ntuser/misc.c?rev=55458&r1=55457&r2=55458&view=diff ============================================================================== --- trunk/reactos/subsystems/win32/win32k/ntuser/misc.c [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/win32k/ntuser/misc.c [iso-8859-1] Mon Feb 6 12:30:59 2012 @@ -542,75 +542,79 @@ return STATUS_SUCCESS; } -PPROCESSINFO -GetW32ProcessInfo(VOID) -{ - return (PPROCESSINFO)PsGetCurrentProcessWin32Process(); -} - -PTHREADINFO -GetW32ThreadInfo(VOID) +void UserDbgAssertThreadInfo(BOOL showCaller) { 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 */ + PTHREADINFO pti; + + ppi = PsGetCurrentProcessWin32Process(); + pti = PsGetCurrentThreadWin32Thread(); Teb = NtCurrentTeb(); pci = GetWin32ClientInfo(); - pti->pClientInfo = pci; - _SEH2_TRY + + 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) { - if(Teb) - { - ProbeForWrite( Teb, - sizeof(TEB), - sizeof(ULONG)); - - Teb->Win32ThreadInfo = (PW32THREAD) pti; + 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->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; +} + +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) +{ + return (PPROCESSINFO)PsGetCurrentProcessWin32Process(); +} + +PTHREADINFO +GetW32ThreadInfo(VOID) +{ + UserDbgAssertThreadInfo(TRUE); + return (PTHREADINFO)PsGetCurrentThreadWin32Thread(); } /* EOF */ Modified: trunk/reactos/subsystems/win32/win32k/objects/gdidbg.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/objects/gdidbg.c?rev=55458&r1=55457&r2=55458&view=diff ============================================================================== --- trunk/reactos/subsystems/win32/win32k/objects/gdidbg.c [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/win32k/objects/gdidbg.c [iso-8859-1] Mon Feb 6 12:30:59 2012 @@ -483,7 +483,7 @@ 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 @@ ULONG_PTR NTAPI -DbgPostServiceHook(ULONG ulSyscallId, ULONG_PTR ulResult) +GdiDbgPostServiceHook(ULONG ulSyscallId, ULONG_PTR ulResult) { PTHREADINFO pti = (PTHREADINFO)PsGetCurrentThreadWin32Thread(); if (pti && pti->cExclusiveLocks != 0)