Author: jgardou Date: Sun Sep 21 17:44:40 2014 New Revision: 64219
URL: http://svn.reactos.org/svn/reactos?rev=64219&view=rev Log: [WIN32K] - Introduce the base of what should become a proper user object manager, with proper refcounting, handle management, cleanup callbacks and inter-object referencing. Approved by Jim and Giannis. CORE-8539 #resolve
Modified: trunk/reactos/win32ss/include/ntuser.h trunk/reactos/win32ss/user/ntuser/accelerator.c trunk/reactos/win32ss/user/ntuser/accelerator.h trunk/reactos/win32ss/user/ntuser/callproc.c trunk/reactos/win32ss/user/ntuser/class.c trunk/reactos/win32ss/user/ntuser/class.h trunk/reactos/win32ss/user/ntuser/cursoricon.c trunk/reactos/win32ss/user/ntuser/cursoricon.h trunk/reactos/win32ss/user/ntuser/event.c trunk/reactos/win32ss/user/ntuser/hook.c trunk/reactos/win32ss/user/ntuser/hook.h trunk/reactos/win32ss/user/ntuser/main.c trunk/reactos/win32ss/user/ntuser/menu.c trunk/reactos/win32ss/user/ntuser/menu.h trunk/reactos/win32ss/user/ntuser/object.c trunk/reactos/win32ss/user/ntuser/object.h trunk/reactos/win32ss/user/ntuser/simplecall.c trunk/reactos/win32ss/user/ntuser/userfuncs.h trunk/reactos/win32ss/user/ntuser/win32.h trunk/reactos/win32ss/user/ntuser/window.c trunk/reactos/win32ss/user/user32/misc/misc.c
Modified: trunk/reactos/win32ss/include/ntuser.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/include/ntuser.h?re... ============================================================================== --- trunk/reactos/win32ss/include/ntuser.h [iso-8859-1] (original) +++ trunk/reactos/win32ss/include/ntuser.h [iso-8859-1] Sun Sep 21 17:44:40 2014 @@ -172,7 +172,7 @@ typedef struct _PROCDESKHEAD { HEAD; - DWORD hTaskWow; + DWORD_PTR hTaskWow; struct _DESKTOP *rpdesk; PVOID pSelf; } PROCDESKHEAD, *PPROCDESKHEAD;
Modified: trunk/reactos/win32ss/user/ntuser/accelerator.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/acceler... ============================================================================== --- trunk/reactos/win32ss/user/ntuser/accelerator.c [iso-8859-1] (original) +++ trunk/reactos/win32ss/user/ntuser/accelerator.c [iso-8859-1] Sun Sep 21 17:44:40 2014 @@ -235,6 +235,7 @@ ULONG Index; NTSTATUS Status = STATUS_SUCCESS; DECLARE_RETURN(HACCEL); + PTHREADINFO pti;
TRACE("Enter NtUserCreateAcceleratorTable(Entries %p, EntriesCount %u)\n", Entries, EntriesCount); @@ -246,7 +247,14 @@ RETURN( (HACCEL) NULL ); }
- Accel = UserCreateObject(gHandleTable, NULL, NULL, (PHANDLE)&hAccel, TYPE_ACCELTABLE, sizeof(ACCELERATOR_TABLE)); + pti = PsGetCurrentThreadWin32Thread(); + + Accel = UserCreateObject(gHandleTable, + pti->rpdesk, + pti, + (PHANDLE)&hAccel, + TYPE_ACCELTABLE, + sizeof(ACCELERATOR_TABLE));
if (Accel == NULL) { @@ -314,6 +322,21 @@ }
BOOLEAN +UserDestroyAccelTable(PVOID Object) +{ + PACCELERATOR_TABLE Accel = Object; + + if (Accel->Table != NULL) + { + ExFreePoolWithTag(Accel->Table, USERTAG_ACCEL); + Accel->Table = NULL; + } + + UserDeleteObject(Accel->head.h, TYPE_ACCELTABLE); + return TRUE; +} + +BOOLEAN APIENTRY NtUserDestroyAcceleratorTable( HACCEL hAccel) @@ -334,13 +357,7 @@ RETURN( FALSE); }
- if (Accel->Table != NULL) - { - ExFreePoolWithTag(Accel->Table, USERTAG_ACCEL); - Accel->Table = NULL; - } - - UserDeleteObject(hAccel, TYPE_ACCELTABLE); + UserDestroyAccelTable(Accel);
RETURN( TRUE);
Modified: trunk/reactos/win32ss/user/ntuser/accelerator.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/acceler... ============================================================================== --- trunk/reactos/win32ss/user/ntuser/accelerator.h [iso-8859-1] (original) +++ trunk/reactos/win32ss/user/ntuser/accelerator.h [iso-8859-1] Sun Sep 21 17:44:40 2014 @@ -2,9 +2,11 @@
typedef struct _ACCELERATOR_TABLE { - HEAD head; + PROCMARKHEAD head; ULONG Count; LPACCEL Table; } ACCELERATOR_TABLE, *PACCELERATOR_TABLE;
PACCELERATOR_TABLE FASTCALL UserGetAccelObject(HACCEL); +BOOLEAN +UserDestroyAccelTable(PVOID Object);
Modified: trunk/reactos/win32ss/user/ntuser/callproc.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/callpro... ============================================================================== --- trunk/reactos/win32ss/user/ntuser/callproc.c [iso-8859-1] (original) +++ trunk/reactos/win32ss/user/ntuser/callproc.c [iso-8859-1] Sun Sep 21 17:44:40 2014 @@ -17,11 +17,11 @@ return (WNDPROC)((ULONG_PTR)UserHMGetHandle(CallProc) | 0xFFFF0000); }
-VOID -DestroyCallProc(IN PDESKTOPINFO Desktop, - IN OUT PCALLPROCDATA CallProc) +BOOLEAN +DestroyCallProc(_Inout_ PVOID Object) { - UserDeleteObject(UserHMGetHandle(CallProc), TYPE_CALLPROC); + UserDeleteObject(UserHMGetHandle((PCALLPROCDATA)Object), TYPE_CALLPROC); + return TRUE; }
PCALLPROCDATA @@ -33,9 +33,11 @@ PCALLPROCDATA NewCallProc; HANDLE Handle;
+ /* We can send any thread pointer to the object manager here, + * What's important is the process info */ NewCallProc = (PCALLPROCDATA)UserCreateObject(gHandleTable, Desktop, - NULL, + pi->ptiList, &Handle, TYPE_CALLPROC, sizeof(CALLPROCDATA)); @@ -129,7 +131,7 @@ // No luck, create a new one for the requested proc. if (!CallProc) { - CallProc = CreateCallProc( NULL, + CallProc = CreateCallProc( pCls->rpdeskParent, (WNDPROC)ProcIn, !!(Flags & UserGetCPDA2U), pti->ppi);
Modified: trunk/reactos/win32ss/user/ntuser/class.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/class.c... ============================================================================== --- trunk/reactos/win32ss/user/ntuser/class.c [iso-8859-1] (original) +++ trunk/reactos/win32ss/user/ntuser/class.c [iso-8859-1] Sun Sep 21 17:44:40 2014 @@ -224,8 +224,7 @@ NextCallProc = CallProc->spcpdNext;
CallProc->spcpdNext = NULL; - DestroyCallProc(NULL, - CallProc); + DestroyCallProc(CallProc);
CallProc = NextCallProc; }
Modified: trunk/reactos/win32ss/user/ntuser/class.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/class.h... ============================================================================== --- trunk/reactos/win32ss/user/ntuser/class.h [iso-8859-1] (original) +++ trunk/reactos/win32ss/user/ntuser/class.h [iso-8859-1] Sun Sep 21 17:44:40 2014 @@ -16,9 +16,8 @@ return ((ULONG_PTR)lpWndProc & 0xFFFF0000) == 0xFFFF0000; }
-VOID -DestroyCallProc(IN PDESKTOPINFO Desktop, - IN OUT PCALLPROCDATA CallProc); +BOOLEAN +DestroyCallProc(_Inout_ PVOID Object);
PCALLPROCDATA CreateCallProc(IN PDESKTOP Desktop,
Modified: trunk/reactos/win32ss/user/ntuser/cursoricon.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/cursori... ============================================================================== --- trunk/reactos/win32ss/user/ntuser/cursoricon.c [iso-8859-1] (original) +++ trunk/reactos/win32ss/user/ntuser/cursoricon.c [iso-8859-1] Sun Sep 21 17:44:40 2014 @@ -209,7 +209,13 @@ PCURICON_OBJECT CurIcon; HANDLE hCurIcon;
- CurIcon = UserCreateObject(gHandleTable, NULL, NULL, &hCurIcon, TYPE_CURSOR, sizeof(CURICON_OBJECT)); + CurIcon = UserCreateObject( + gHandleTable, + NULL, + GetW32ThreadInfo(), + &hCurIcon, + TYPE_CURSOR, + sizeof(CURICON_OBJECT));
if (!CurIcon) { @@ -315,19 +321,6 @@ Ret = UserDeleteObject(CurIcon->Self, TYPE_CURSOR);
return Ret; -} - -VOID FASTCALL -IntCleanupCurIcons(struct _EPROCESS *Process, PPROCESSINFO Win32Process) -{ - PCURICON_OBJECT CurIcon, tmp; - - /* Run through the list of icon objects */ - LIST_FOR_EACH_SAFE(CurIcon, tmp, &gCurIconList, CURICON_OBJECT, ListEntry) - { - UserReferenceObject(CurIcon); - IntDestroyCurIconObject(CurIcon, Win32Process); - } }
HCURSOR FASTCALL
Modified: trunk/reactos/win32ss/user/ntuser/cursoricon.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/cursori... ============================================================================== --- trunk/reactos/win32ss/user/ntuser/cursoricon.h [iso-8859-1] (original) +++ trunk/reactos/win32ss/user/ntuser/cursoricon.h [iso-8859-1] Sun Sep 21 17:44:40 2014 @@ -105,7 +105,6 @@
BOOL InitCursorImpl(VOID); HANDLE IntCreateCurIconHandle(BOOLEAN Anim); -VOID FASTCALL IntCleanupCurIcons(struct _EPROCESS *Process, PPROCESSINFO Win32Process);
BOOL UserDrawIconEx(HDC hDc, INT xLeft, INT yTop, PCURICON_OBJECT pIcon, INT cxWidth, INT cyHeight, UINT istepIfAniCur, HBRUSH hbrFlickerFreeDraw, UINT diFlags); @@ -115,6 +114,7 @@ PSYSTEM_CURSORINFO IntGetSysCursorInfo(VOID); HCURSOR FASTCALL IntSetCursor(HCURSOR hCursor); BOOL FASTCALL IntDestroyCursor(HANDLE hCurIcon, BOOL bForce); +BOOLEAN FASTCALL IntDestroyCurIconObject(PCURICON_OBJECT CurIcon, PPROCESSINFO ppi);
#define IntReleaseCurIconObject(CurIconObj) \ UserDereferenceObject(CurIconObj)
Modified: trunk/reactos/win32ss/user/ntuser/event.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/event.c... ============================================================================== --- trunk/reactos/win32ss/user/ntuser/event.c [iso-8859-1] (original) +++ trunk/reactos/win32ss/user/ntuser/event.c [iso-8859-1] Sun Sep 21 17:44:40 2014 @@ -129,11 +129,10 @@ return NT_SUCCESS(Status) ? uResult : 0; }
-static -BOOL -FASTCALL -IntRemoveEvent(PEVENTHOOK pEH) -{ +BOOLEAN +IntRemoveEvent(PVOID Object) +{ + PEVENTHOOK pEH = Object; if (pEH) { TRACE("IntRemoveEvent pEH %p\n", pEH); @@ -146,38 +145,6 @@ return TRUE; } return FALSE; -} - -VOID -FASTCALL -EVENT_DestroyThreadEvents(PETHREAD Thread) -{ - PTHREADINFO pti; - PEVENTHOOK pEH; - PLIST_ENTRY pLE; - - pti = Thread->Tcb.Win32Thread; - if (!pti) return; - - if (!GlobalEvents || !GlobalEvents->Counts) return; - - pLE = GlobalEvents->Events.Flink; - if (IsListEmpty(pLE)) return; - - pEH = CONTAINING_RECORD(pLE, EVENTHOOK, Chain); - do - { - if (IsListEmpty(pLE)) break; - if (!pEH) break; - pLE = pEH->Chain.Flink; - if (pEH->head.pti == pti) - { - IntRemoveEvent(pEH); - } - pEH = CONTAINING_RECORD(pLE, EVENTHOOK, Chain); - } while (pLE != &GlobalEvents->Events); - - return; }
/* FUNCTIONS *****************************************************************/ @@ -332,7 +299,7 @@ HWINEVENTHOOK Ret = NULL; NTSTATUS Status; HANDLE Handle; - PETHREAD Thread = NULL; + PTHREADINFO pti;
TRACE("NtUserSetWinEventHook hmod %p, pfn %p\n", hmodWinEventProc, lpfnWinEventProc);
@@ -370,15 +337,22 @@
if (idThread) { + PETHREAD Thread; Status = PsLookupThreadByThreadId((HANDLE)(DWORD_PTR)idThread, &Thread); if (!NT_SUCCESS(Status)) { EngSetLastError(ERROR_INVALID_THREAD_ID); goto SetEventExit; } + pti = PsGetThreadWin32Thread(Thread); + ObDereferenceObject(Thread); + } + else + { + pti = PsGetCurrentThreadWin32Thread(); } // Creator, pti is set here. - pEH = UserCreateObject(gHandleTable, NULL, NULL, &Handle, TYPE_WINEVENTHOOK, sizeof(EVENTHOOK)); + pEH = UserCreateObject(gHandleTable, NULL, pti, &Handle, TYPE_WINEVENTHOOK, sizeof(EVENTHOOK)); if (pEH) { InsertTailList(&GlobalEvents->Events, &pEH->Chain); @@ -413,7 +387,6 @@ }
SetEventExit: - if (Thread) ObDereferenceObject(Thread); UserLeave(); return Ret; }
Modified: trunk/reactos/win32ss/user/ntuser/hook.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/hook.c?... ============================================================================== --- trunk/reactos/win32ss/user/ntuser/hook.c [iso-8859-1] (original) +++ trunk/reactos/win32ss/user/ntuser/hook.c [iso-8859-1] Sun Sep 21 17:44:40 2014 @@ -1028,14 +1028,13 @@ }
/* Remove a hook, freeing it from the chain */ -static -VOID -FASTCALL -IntRemoveHook(PHOOK Hook) +BOOLEAN +IntRemoveHook(PVOID Object) { INT HookId; PTHREADINFO pti; PDESKTOP pdo; + PHOOK Hook = Object;
HookId = Hook->HookId;
@@ -1073,65 +1072,8 @@ pdo->pDeskInfo->fsHooks &= ~HOOKID_TO_FLAG(HookId); } } -} - -VOID -FASTCALL -HOOK_DestroyThreadHooks(PETHREAD Thread) -{ - PTHREADINFO pti; - PDESKTOP pdo; - int HookId; - PHOOK HookObj; - PLIST_ENTRY pElem; - - pti = Thread->Tcb.Win32Thread; - pdo = IntGetActiveDesktop(); - - if (!pti || !pdo) - { - ERR("Kill Thread Hooks pti %p pdo %p\n", pti, pdo); - return; - } - -// Local Thread cleanup. - if (pti->fsHooks) - { - for (HookId = WH_MINHOOK; HookId <= WH_MAXHOOK; HookId++) - { - PLIST_ENTRY pLastHead = &pti->aphkStart[HOOKID_TO_INDEX(HookId)]; - - pElem = pLastHead->Flink; - while (pElem != pLastHead) - { - HookObj = CONTAINING_RECORD(pElem, HOOK, Chain); - pElem = HookObj->Chain.Flink; // get next element before hook is destroyed - IntRemoveHook(HookObj); - } - } - pti->fsHooks = 0; - pti->pClientInfo->fsHooks = 0; - } -// Global search based on Thread and cleanup. - if (pdo->pDeskInfo->fsHooks) - { - for (HookId = WH_MINHOOK; HookId <= WH_MAXHOOK; HookId++) - { - PLIST_ENTRY pGLE = &pdo->pDeskInfo->aphkStart[HOOKID_TO_INDEX(HookId)]; - - pElem = pGLE->Flink; - while (pElem != pGLE) - { - HookObj = CONTAINING_RECORD(pElem, HOOK, Chain); - pElem = HookObj->Chain.Flink; // Get next element before hook is destroyed - if (HookObj->head.pti == pti) - { - IntRemoveHook(HookObj); - } - } - } - } - return; + + return TRUE; }
/* @@ -1576,7 +1518,7 @@ } ObDereferenceObject(WinStaObj);
- Hook = UserCreateObject(gHandleTable, NULL, NULL, (PHANDLE)&Handle, TYPE_HOOK, sizeof(HOOK)); + Hook = UserCreateObject(gHandleTable, NULL, ptiHook, (PHANDLE)&Handle, TYPE_HOOK, sizeof(HOOK));
if (!Hook) {
Modified: trunk/reactos/win32ss/user/ntuser/hook.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/hook.h?... ============================================================================== --- trunk/reactos/win32ss/user/ntuser/hook.h [iso-8859-1] (original) +++ trunk/reactos/win32ss/user/ntuser/hook.h [iso-8859-1] Sun Sep 21 17:44:40 2014 @@ -43,12 +43,12 @@ LRESULT FASTCALL co_CallHook(INT HookId, INT Code, WPARAM wParam, LPARAM lParam); LRESULT FASTCALL co_HOOK_CallHooks(INT HookId, INT Code, WPARAM wParam, LPARAM lParam); LRESULT FASTCALL co_EVENT_CallEvents(DWORD, HWND, UINT_PTR, LONG_PTR); -VOID FASTCALL HOOK_DestroyThreadHooks(PETHREAD Thread); -VOID FASTCALL EVENT_DestroyThreadEvents(PETHREAD Thread); PHOOK FASTCALL IntGetHookObject(HHOOK); PHOOK FASTCALL IntGetNextHook(PHOOK Hook); LRESULT FASTCALL UserCallNextHookEx( PHOOK pHook, int Code, WPARAM wParam, LPARAM lParam, BOOL Ansi); BOOL FASTCALL IntUnhookWindowsHook(int,HOOKPROC); +BOOLEAN IntRemoveHook(PVOID Object); +BOOLEAN IntRemoveEvent(PVOID Object);
BOOL FASTCALL UserLoadApiHook(VOID); BOOL IntLoadHookModule(int iHookID, HHOOK hHook, BOOL Unload);
Modified: trunk/reactos/win32ss/user/ntuser/main.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/main.c?... ============================================================================== --- trunk/reactos/win32ss/user/ntuser/main.c [iso-8859-1] (original) +++ trunk/reactos/win32ss/user/ntuser/main.c [iso-8859-1] Sun Sep 21 17:44:40 2014 @@ -51,12 +51,232 @@ } #endif
+static +NTSTATUS +CreateProcessInfo(PEPROCESS Process) +{ + PPROCESSINFO ppiCurrent; + NTSTATUS Status; + SIZE_T ViewSize = 0; + LARGE_INTEGER Offset; + PVOID UserBase = NULL; + PRTL_USER_PROCESS_PARAMETERS pParams = Process->Peb->ProcessParameters; + + /* 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!) */ + return STATUS_ALREADY_WIN32; + } + + /* 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; + } + + RtlZeroMemory(ppiCurrent, sizeof(PROCESSINFO)); + + 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)); + + /* map the global heap into the process */ + Offset.QuadPart = 0; + Status = MmMapViewOfSection(GlobalUserHeapSection, + PsGetCurrentProcess(), + &UserBase, + 0, + 0, + &Offset, + &ViewSize, + ViewUnmap, + SEC_NO_CHANGE, + PAGE_EXECUTE_READ); /* would prefer PAGE_READONLY, but thanks to RTL heaps... */ + if (!NT_SUCCESS(Status)) + { + TRACE_CH(UserProcess,"Failed to map the global heap! 0x%x\n", Status); + return Status; + } + ppiCurrent->HeapMappings.Next = NULL; + ppiCurrent->HeapMappings.KernelMapping = (PVOID)GlobalUserHeap; + ppiCurrent->HeapMappings.UserMapping = UserBase; + ppiCurrent->HeapMappings.Count = 1; + + InitializeListHead(&ppiCurrent->GDIBrushAttrFreeList); + InitializeListHead(&ppiCurrent->GDIDcAttrFreeList); + + InitializeListHead(&ppiCurrent->PrivateFontListHead); + ExInitializeFastMutex(&ppiCurrent->PrivateFontListLock); + + InitializeListHead(&ppiCurrent->DriverObjListHead); + ExInitializeFastMutex(&ppiCurrent->DriverObjListLock); + + ppiCurrent->KeyboardLayout = W32kGetDefaultKeyLayout(); + if (!EngCreateEvent((PEVENT *)&ppiCurrent->InputIdleEvent)) + { + KeBugCheck(0); + } + + 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 */ + ppiCurrent->W32PF_flags = W32PF_THREADCONNECTED; + + if ( pParams && + pParams->WindowFlags & STARTF_SCRNSAVER ) + { + ppiScrnSaver = ppiCurrent; + 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'); + ppiCurrent->pPoolRgnAttr = GdiPoolCreate(sizeof(RGN_ATTR), 'agrG'); + ASSERT(ppiCurrent->pPoolDcAttr); + ASSERT(ppiCurrent->pPoolBrushAttr); + ASSERT(ppiCurrent->pPoolRgnAttr); + + /* Add the process to the global list */ + ppiCurrent->ppiNext = gppiList; + gppiList = ppiCurrent; + IntReferenceProcessInfo(ppiCurrent); + + return STATUS_SUCCESS; +} + +static +NTSTATUS +DestroyProcessInfo(PEPROCESS Process) +{ + PPROCESSINFO ppiCurrent, *pppi; + + /* Get the Win32 Process */ + ppiCurrent = PsGetProcessWin32Process(Process); + + ASSERT(ppiCurrent); + + TRACE_CH(UserProcess, "Destroying ppi 0x%p\n", ppiCurrent); + ppiCurrent->W32PF_flags |= W32PF_TERMINATED; + + if (ppiScrnSaver == ppiCurrent) + ppiScrnSaver = NULL; + + /* Destroy user objects */ + UserDestroyObjectsForOwner(gHandleTable, ppiCurrent); + + TRACE_CH(UserProcess,"Freeing ppi 0x%p\n", ppiCurrent); +#if DBG + if (DBG_IS_CHANNEL_ENABLED(ppiCurrent, DbgChUserObj, WARN_LEVEL)) + { + TRACE_CH(UserObj, "Dumping user handles at the end of the process %s (Info %p).\n", + ppiCurrent->peProcess->ImageFileName, ppiCurrent); + DbgUserDumpHandleTable(); + } +#endif + + /* And GDI ones too */ + GDI_CleanupForProcess(Process); + + /* So we can now free the pools */ + GdiPoolDestroy(ppiCurrent->pPoolDcAttr); + GdiPoolDestroy(ppiCurrent->pPoolBrushAttr); + GdiPoolDestroy(ppiCurrent->pPoolRgnAttr); + + /* Remove it from the list of GUI apps */ + co_IntGraphicsCheck(FALSE); + + /* + * Deregister logon application automatically + */ + if(LogonProcess == ppiCurrent) + { + LogonProcess = NULL; + } + + /* Close the current window station */ + UserSetProcessWindowStation(NULL); + + if (gppiInputProvider == ppiCurrent) gppiInputProvider = NULL; + + /* Remove it from the list */ + pppi = &gppiList; + while (*pppi != NULL && *pppi != ppiCurrent) + pppi = &(*pppi)->ppiNext; + + ASSERT(*pppi == ppiCurrent); + + *pppi = ppiCurrent->ppiNext; + + if(ppiCurrent->hdeskStartup) + { + ZwClose(ppiCurrent->hdeskStartup); + ppiCurrent->hdeskStartup = NULL; + } + + /* The process is dying */ + PsSetProcessWin32Process(Process, NULL, ppiCurrent); + ppiCurrent->peProcess = NULL; + + /* At last, dereference */ + IntDereferenceProcessInfo(ppiCurrent); + + return STATUS_SUCCESS; +} + +VOID +UserDeleteW32Process(PPROCESSINFO ppiCurrent) +{ + if (ppiCurrent->InputIdleEvent) + { + EngDeleteEvent((PEVENT)ppiCurrent->InputIdleEvent); + } + + /* Close the startup desktop */ + if(ppiCurrent->rpdeskStartup) + ObDereferenceObject(ppiCurrent->rpdeskStartup); + +#if DBG + if (DBG_IS_CHANNEL_ENABLED(ppiCurrent, DbgChUserObj, WARN_LEVEL)) + { + TRACE_PPI(ppiCurrent, UserObj, "Dumping user handles now that process info %p is gets freed.\n", ppiCurrent); + DbgUserDumpHandleTable(); + } +#endif + + /* Free the PROCESSINFO */ + ExFreePoolWithTag(ppiCurrent, USERTAG_PROCESSINFO); +} + NTSTATUS APIENTRY Win32kProcessCallback(struct _EPROCESS *Process, BOOLEAN Create) { - PPROCESSINFO ppiCurrent, *pppi; NTSTATUS Status;
ASSERT(Process->Peb); @@ -65,193 +285,13 @@
if (Create) { - SIZE_T ViewSize = 0; - LARGE_INTEGER Offset; - PVOID UserBase = NULL; - PRTL_USER_PROCESS_PARAMETERS pParams = Process->Peb->ProcessParameters; - - /* 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)); - Status = STATUS_NO_MEMORY; - goto Leave; - } - - RtlZeroMemory(ppiCurrent, sizeof(PROCESSINFO)); - - 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)); - - /* map the global heap into the process */ - Offset.QuadPart = 0; - Status = MmMapViewOfSection(GlobalUserHeapSection, - PsGetCurrentProcess(), - &UserBase, - 0, - 0, - &Offset, - &ViewSize, - ViewUnmap, - SEC_NO_CHANGE, - PAGE_EXECUTE_READ); /* would prefer PAGE_READONLY, but thanks to RTL heaps... */ - if (!NT_SUCCESS(Status)) - { - TRACE_CH(UserProcess,"Failed to map the global heap! 0x%x\n", Status); - goto Leave; - } - 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(); - if (!EngCreateEvent((PEVENT *)&ppiCurrent->InputIdleEvent)) - { - KeBugCheck(0); - } - - 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 */ - ppiCurrent->W32PF_flags = W32PF_THREADCONNECTED; - - if ( pParams && - pParams->WindowFlags & STARTF_SCRNSAVER ) - { - ppiScrnSaver = ppiCurrent; - 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'); - ppiCurrent->pPoolRgnAttr = GdiPoolCreate(sizeof(RGN_ATTR), 'agrG'); - ASSERT(ppiCurrent->pPoolDcAttr); - ASSERT(ppiCurrent->pPoolBrushAttr); - ASSERT(ppiCurrent->pPoolRgnAttr); - - /* Add the process to the global list */ - ppiCurrent->ppiNext = gppiList; - gppiList = ppiCurrent; + Status = CreateProcessInfo(Process); } else { - /* Get the Win32 Process */ - ppiCurrent = PsGetProcessWin32Process(Process); - - ASSERT(ppiCurrent); - - TRACE_CH(UserProcess, "Destroying ppi 0x%p\n", ppiCurrent); - 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); - - - GDI_CleanupForProcess(Process); - - co_IntGraphicsCheck(FALSE); - - /* - * Deregister logon application automatically - */ - if(LogonProcess == ppiCurrent) - { - LogonProcess = NULL; - } - - /* Close the startup desktop */ - if(ppiCurrent->rpdeskStartup) - ObDereferenceObject(ppiCurrent->rpdeskStartup); - if(ppiCurrent->hdeskStartup) - ZwClose(ppiCurrent->hdeskStartup); - - /* Close the current window station */ - UserSetProcessWindowStation(NULL); - - /* Destroy GDI pools */ - GdiPoolDestroy(ppiCurrent->pPoolDcAttr); - GdiPoolDestroy(ppiCurrent->pPoolBrushAttr); - GdiPoolDestroy(ppiCurrent->pPoolRgnAttr); - - 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 - - /* Free the PROCESSINFO */ - PsSetProcessWin32Process(Process, NULL, ppiCurrent); - ExFreePoolWithTag(ppiCurrent, USERTAG_PROCESSINFO); - } - - Status = STATUS_SUCCESS; - -Leave: + Status = DestroyProcessInfo(Process); + } + UserLeave(); return Status; } @@ -291,7 +331,8 @@ PsSetThreadWin32Thread(Thread, ptiCurrent, NULL); IntReferenceThreadInfo(ptiCurrent); ptiCurrent->pEThread = Thread; - ptiCurrent->ppi = PsGetCurrentProcessWin32Process(); + ptiCurrent->ppi = PsGetProcessWin32Process(Process); + IntReferenceProcessInfo(ptiCurrent->ppi); pTeb->Win32ThreadInfo = ptiCurrent; ptiCurrent->pClientInfo = (PCLIENTINFO)pTeb->Win32ClientInfo;
@@ -317,6 +358,7 @@ NULL, SynchronizationEvent, FALSE); if (!NT_SUCCESS(Status)) { + ERR_CH(UserThread, "Event creation failed, Status 0x%08x.\n", Status); goto error; } Status = ObReferenceObjectByHandle(ptiCurrent->hEventQueueClient, 0, @@ -324,6 +366,7 @@ (PVOID*)&ptiCurrent->pEventQueueServer, NULL); if (!NT_SUCCESS(Status)) { + ERR_CH(UserThread, "Failed referencing the event object, Status 0x%08x.\n", Status); ZwClose(ptiCurrent->hEventQueueClient); ptiCurrent->hEventQueueClient = NULL; goto error; @@ -451,29 +494,23 @@ 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); - } + PPROCESSINFO ppi = pti->ppi; + + TRACE_CH(UserThread,"UserDeleteW32Thread pti 0x%p\n",pti); + + /* Free the message queue */ + if (pti->MessageQueue) + { + MsqDestroyMessageQueue(pti); + } + + MsqCleanupThreadMsgs(pti); + + ExFreePoolWithTag(pti, USERTAG_THREADINFO); + + IntDereferenceProcessInfo(ppi); }
NTSTATUS @@ -541,18 +578,16 @@ }
DceFreeThreadDCE(ptiCurrent); - HOOK_DestroyThreadHooks(Thread); - EVENT_DestroyThreadEvents(Thread); DestroyTimersForThread(ptiCurrent); KeSetEvent(ptiCurrent->pEventQueueServer, IO_NO_INCREMENT, FALSE); UnregisterThreadHotKeys(ptiCurrent); -/* - if (IsListEmpty(&ptiCurrent->WindowListHead)) - { - ERR_CH(UserThread,"Thread Window List is Empty!\n"); - } -*/ - co_DestroyThreadWindows(Thread); + + if (!UserDestroyObjectsForOwner(gHandleTable, ptiCurrent)) + { + DPRINT1("Failed to delete objects belonging to thread %p. This is VERY BAD!.\n", ptiCurrent); + ASSERT(FALSE); + return STATUS_UNSUCCESSFUL; + }
if (ppiCurrent && ppiCurrent->ptiList == ptiCurrent && !ptiCurrent->ptiSibling && ppiCurrent->W32PF_flags & W32PF_CLASSESREGISTERED) @@ -613,6 +648,19 @@ } */ TRACE_CH(UserThread,"Freeing pti 0x%p\n", ptiCurrent); + + IntSetThreadDesktop(NULL, TRUE); + + if (ptiCurrent->hEventQueueClient != NULL) + { + ZwClose(ptiCurrent->hEventQueueClient); + ObDereferenceObject(ptiCurrent->pEventQueueServer); + } + ptiCurrent->hEventQueueClient = NULL; + + /* The thread is dying */ + PsSetThreadWin32Thread(ptiCurrent->pEThread, NULL, ptiCurrent); + ptiCurrent->pEThread = NULL;
/* Free the THREADINFO */ IntDereferenceThreadInfo(ptiCurrent);
Modified: trunk/reactos/win32ss/user/ntuser/menu.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/menu.c?... ============================================================================== --- trunk/reactos/win32ss/user/ntuser/menu.c [iso-8859-1] (original) +++ trunk/reactos/win32ss/user/ntuser/menu.c [iso-8859-1] Sun Sep 21 17:44:40 2014 @@ -176,7 +176,7 @@ return pMenu; }
-BOOL IntDestroyMenu( PMENU pMenu, BOOL bRecurse, BOOL RemoveFromProcess) +BOOL IntDestroyMenu( PMENU pMenu, BOOL bRecurse) { PMENU SubMenu;
@@ -204,7 +204,7 @@ { /* Release submenu since it was referenced when inserted */ IntReleaseMenuObject(SubMenu); - IntDestroyMenuObject(SubMenu, bRecurse, RemoveFromProcess); + IntDestroyMenuObject(SubMenu, bRecurse); } } /* Free the Item */ @@ -215,20 +215,22 @@ return TRUE; }
+/* Callback for the object manager */ +BOOLEAN +UserDestroyMenuObject(PVOID Object) +{ + return IntDestroyMenuObject(Object, TRUE); +} + BOOL FASTCALL -IntDestroyMenuObject(PMENU Menu, BOOL bRecurse, BOOL RemoveFromProcess) +IntDestroyMenuObject(PMENU Menu, BOOL bRecurse) { if(Menu) { PWND Window;
/* Remove all menu items */ - IntDestroyMenu( Menu, bRecurse, RemoveFromProcess); - - if (RemoveFromProcess) - { - RemoveEntryList(&Menu->ListEntry); - } + IntDestroyMenu( Menu, bRecurse);
if (PsGetCurrentProcessSessionId() == Menu->head.rpdesk->rpwinstaParent->dwSessionId) { @@ -361,7 +363,7 @@ FreeMenuText(pMenu,item); if (bRecurse && item->spSubMenu) { - IntDestroyMenuObject(item->spSubMenu, bRecurse, TRUE); + IntDestroyMenuObject(item->spSubMenu, bRecurse); } ////// Use cAlloced with inc's of 8's.... if (--pMenu->cItems == 0) @@ -477,14 +479,17 @@ }
PMENU FASTCALL -IntCreateMenu(PHANDLE Handle, BOOL IsMenuBar) +IntCreateMenu( + _Out_ PHANDLE Handle, + _In_ BOOL IsMenuBar, + _In_ PDESKTOP Desktop, + _In_ PPROCESSINFO ppi) { PMENU Menu; - PPROCESSINFO CurrentWin32Process;
Menu = (PMENU)UserCreateObject( gHandleTable, - NULL, - NULL, + Desktop, + ppi->ptiList, Handle, TYPE_MENU, sizeof(MENU)); @@ -511,10 +516,6 @@
Menu->hWnd = NULL; Menu->TimeToHide = FALSE; - - /* Insert menu item into process menu handle list */ - CurrentWin32Process = PsGetCurrentProcessWin32Process(); - InsertTailList(&CurrentWin32Process->MenuListHead, &Menu->ListEntry);
return Menu; } @@ -572,19 +573,19 @@ PMENU FASTCALL IntCloneMenu(PMENU Source) { - PPROCESSINFO CurrentWin32Process; HANDLE hMenu; PMENU Menu;
if(!Source) return NULL;
+ /* A menu is valid process wide. We can pass to the object manager any thread ptr */ Menu = (PMENU)UserCreateObject( gHandleTable, - NULL, - NULL, - &hMenu, - TYPE_MENU, - sizeof(MENU)); + Source->head.rpdesk, + ((PPROCESSINFO)Source->head.hTaskWow)->ptiList, + &hMenu, + TYPE_MENU, + sizeof(MENU)); if(!Menu) return NULL;
@@ -606,10 +607,6 @@ Menu->hWnd = NULL; Menu->TimeToHide = FALSE;
- /* Insert menu item into process menu handle list */ - CurrentWin32Process = PsGetCurrentProcessWin32Process(); - InsertTailList(&CurrentWin32Process->MenuListHead, &Menu->ListEntry); - IntCloneMenuItems(Menu, Source);
return Menu; @@ -870,7 +867,10 @@ { HANDLE hMenu; ERR("Pop Up Menu Double Trouble!\n"); - SubMenuObject = IntCreateMenu(&hMenu, FALSE); // It will be marked. + SubMenuObject = IntCreateMenu(&hMenu, + FALSE, + MenuObject->head.rpdesk, + (PPROCESSINFO)MenuObject->head.hTaskWow); // It will be marked. if (!SubMenuObject) return FALSE; IntReleaseMenuObject(SubMenuObject); // This will be referenced again after insertion. circref = TRUE; @@ -878,7 +878,7 @@ if ( MENU_depth( SubMenuObject, 0) > MAXMENUDEPTH ) { ERR( "Loop detected in menu hierarchy or maximum menu depth exceeded!\n"); - if (circref) IntDestroyMenuObject(SubMenuObject, FALSE, TRUE); + if (circref) IntDestroyMenuObject(SubMenuObject, FALSE); return FALSE; } /* Make sure the submenu is marked as a popup menu */ @@ -1133,36 +1133,6 @@
co_IntExitTracking(Window, Menu, TRUE, Flags); return FALSE; -} - - -/*! - * Internal function. Called when the process is destroyed to free the remaining menu handles. -*/ -BOOL FASTCALL -IntCleanupMenus(struct _EPROCESS *Process, PPROCESSINFO Win32Process) -{ - PEPROCESS CurrentProcess; - PMENU MenuObject; - - CurrentProcess = PsGetCurrentProcess(); - if (CurrentProcess != Process) - { - KeAttachProcess(&Process->Pcb); - } - - while (!IsListEmpty(&Win32Process->MenuListHead)) - { - MenuObject = CONTAINING_RECORD(Win32Process->MenuListHead.Flink, MENU, ListEntry); - TRACE("Menus are stuck on the process list!\n"); - IntDestroyMenuObject(MenuObject, FALSE, TRUE); - } - - if (CurrentProcess != Process) - { - KeDetachProcess(); - } - return TRUE; }
BOOLEAN APIENTRY @@ -1415,7 +1385,7 @@ }
-HMENU FASTCALL UserCreateMenu(BOOL PopupMenu) +HMENU FASTCALL UserCreateMenu(PDESKTOP Desktop, BOOL PopupMenu) { PWINSTATION_OBJECT WinStaObject; HANDLE Handle; @@ -1441,7 +1411,7 @@ SetLastNtError(Status); return (HMENU)0; } - Menu = IntCreateMenu(&Handle, !PopupMenu); + Menu = IntCreateMenu(&Handle, !PopupMenu, Desktop, GetW32ProcessInfo()); if (Menu && Menu->head.rpdesk->rpwinstaParent != WinStaObject) { ERR("Desktop Window Station does not match Process one!\n"); @@ -1450,7 +1420,7 @@ } else { - Menu = IntCreateMenu(&Handle, !PopupMenu); + Menu = IntCreateMenu(&Handle, !PopupMenu, GetW32ThreadInfo()->rpdesk, GetW32ProcessInfo()); }
if (Menu) UserDereferenceObject(Menu); @@ -1678,7 +1648,7 @@ ROSMENUITEMINFO ItemInfo = {0}; UNICODE_STRING MenuName;
- hSysMenu = UserCreateMenu(FALSE); + hSysMenu = UserCreateMenu(Window->head.rpdesk, FALSE); if (NULL == hSysMenu) { return NULL; @@ -1742,7 +1712,7 @@ IntReleaseMenuObject(NewMenu); UserSetMenuDefaultItem(NewMenu, SC_CLOSE, FALSE);
- IntDestroyMenuObject(Menu, FALSE, TRUE); + IntDestroyMenuObject(Menu, FALSE); } else { @@ -1782,7 +1752,7 @@ Menu = UserGetMenuObject(Window->SystemMenu); if (Menu && !(Menu->fFlags & MNF_SYSDESKMN)) { - IntDestroyMenuObject(Menu, TRUE, TRUE); + IntDestroyMenuObject(Menu, TRUE); Window->SystemMenu = NULL; } } @@ -1826,7 +1796,7 @@ if (OldMenu) { OldMenu->fFlags &= ~MNF_SYSMENU; - IntDestroyMenuObject(OldMenu, TRUE, TRUE); + IntDestroyMenuObject(OldMenu, TRUE); } }
@@ -2091,7 +2061,7 @@ EngSetLastError(ERROR_ACCESS_DENIED); return FALSE; } - return IntDestroyMenuObject(Menu, FALSE, TRUE); + return IntDestroyMenuObject(Menu, FALSE); }
/* @@ -2116,7 +2086,7 @@ EngSetLastError(ERROR_ACCESS_DENIED); RETURN( FALSE); } - RETURN( IntDestroyMenuObject(Menu, TRUE, TRUE)); + RETURN( IntDestroyMenuObject(Menu, TRUE));
CLEANUP: TRACE("Leave NtUserDestroyMenu, ret=%i\n",_ret_);
Modified: trunk/reactos/win32ss/user/ntuser/menu.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/menu.h?... ============================================================================== --- trunk/reactos/win32ss/user/ntuser/menu.h [iso-8859-1] (original) +++ trunk/reactos/win32ss/user/ntuser/menu.h [iso-8859-1] Sun Sep 21 17:44:40 2014 @@ -23,8 +23,11 @@ #define IntReleaseMenuObject(MenuObj) \ UserDereferenceObject(MenuObj)
+BOOLEAN +UserDestroyMenuObject(PVOID Object); + BOOL FASTCALL -IntDestroyMenuObject(PMENU MenuObject, BOOL bRecurse, BOOL RemoveFromProcess); +IntDestroyMenuObject(PMENU MenuObject, BOOL bRecurse);
PMENU FASTCALL IntCloneMenu(PMENU Source);
Modified: trunk/reactos/win32ss/user/ntuser/object.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/object.... ============================================================================== --- trunk/reactos/win32ss/user/ntuser/object.c [iso-8859-1] (original) +++ trunk/reactos/win32ss/user/ntuser/object.c [iso-8859-1] Sun Sep 21 17:44:40 2014 @@ -12,6 +12,233 @@ //int usedHandles=0; PUSER_HANDLE_TABLE gHandleTable = NULL;
+/* Forward declarations */ +static PVOID AllocThreadObject( + _In_ PDESKTOP pDesk, + _In_ PTHREADINFO pti, + _In_ SIZE_T Size, + _Out_ PVOID* HandleOwner) +{ + PTHROBJHEAD ObjHead; + + UNREFERENCED_PARAMETER(pDesk); + + ASSERT(Size > sizeof(*ObjHead)); + ASSERT(pti != NULL); + + ObjHead = UserHeapAlloc(Size); + if (!ObjHead) + return NULL; + + RtlZeroMemory(ObjHead, Size); + + ObjHead->pti = pti; + IntReferenceThreadInfo(pti); + *HandleOwner = pti; + /* It's a thread object, but it still count as one for the process */ + pti->ppi->UserHandleCount++; + + return ObjHead; +} + +static void FreeThreadObject( + _In_ PVOID Object) +{ + PTHROBJHEAD ObjHead = (PTHROBJHEAD)Object; + PTHREADINFO pti = ObjHead->pti; + + UserHeapFree(ObjHead); + + pti->ppi->UserHandleCount--; + IntDereferenceThreadInfo(pti); +} + +static PVOID AllocDeskThreadObject( + _In_ PDESKTOP pDesk, + _In_ PTHREADINFO pti, + _In_ SIZE_T Size, + _Out_ PVOID* HandleOwner) +{ + PTHRDESKHEAD ObjHead; + + ASSERT(Size > sizeof(*ObjHead)); + ASSERT(pti != NULL); + + if (!pDesk) + pDesk = pti->rpdesk; + + ObjHead = DesktopHeapAlloc(pDesk, Size); + if (!ObjHead) + return NULL; + + RtlZeroMemory(ObjHead, Size); + + ObjHead->pSelf = ObjHead; + ObjHead->rpdesk = pDesk; + ObjHead->pti = pti; + IntReferenceThreadInfo(pti); + *HandleOwner = pti; + /* It's a thread object, but it still count as one for the process */ + pti->ppi->UserHandleCount++; + + return ObjHead; +} + +static void FreeDeskThreadObject( + _In_ PVOID Object) +{ + PTHRDESKHEAD ObjHead = (PTHRDESKHEAD)Object; + PDESKTOP pDesk = ObjHead->rpdesk; + PTHREADINFO pti = ObjHead->pti; + + DesktopHeapFree(pDesk, Object); + + pti->ppi->UserHandleCount--; + IntDereferenceThreadInfo(pti); +} + +static PVOID AllocDeskProcObject( + _In_ PDESKTOP pDesk, + _In_ PTHREADINFO pti, + _In_ SIZE_T Size, + _Out_ PVOID* HandleOwner) +{ + PPROCDESKHEAD ObjHead; + PPROCESSINFO ppi; + + ASSERT(Size > sizeof(*ObjHead)); + ASSERT(pDesk != NULL); + ASSERT(pti != NULL); + + ObjHead = DesktopHeapAlloc(pDesk, Size); + if (!ObjHead) + return NULL; + + RtlZeroMemory(ObjHead, Size); + + ppi = pti->ppi; + + ObjHead->pSelf = ObjHead; + ObjHead->rpdesk = pDesk; + ObjHead->hTaskWow = (DWORD_PTR)ppi; + ppi->UserHandleCount++; + IntReferenceProcessInfo(ppi); + *HandleOwner = ppi; + + return ObjHead; +} + +static void FreeDeskProcObject( + _In_ PVOID Object) +{ + PPROCDESKHEAD ObjHead = (PPROCDESKHEAD)Object; + PDESKTOP pDesk = ObjHead->rpdesk; + PPROCESSINFO ppi = (PPROCESSINFO)ObjHead->hTaskWow; + + ppi->UserHandleCount--; + IntDereferenceProcessInfo(ppi); + + DesktopHeapFree(pDesk, Object); +} + +static PVOID AllocProcMarkObject( + _In_ PDESKTOP pDesk, + _In_ PTHREADINFO pti, + _In_ SIZE_T Size, + _Out_ PVOID* HandleOwner) +{ + PPROCMARKHEAD ObjHead; + PPROCESSINFO ppi = pti->ppi; + + UNREFERENCED_PARAMETER(pDesk); + + ASSERT(Size > sizeof(*ObjHead)); + + ObjHead = UserHeapAlloc(Size); + if (!ObjHead) + return NULL; + + RtlZeroMemory(ObjHead, Size); + + ObjHead->ppi = ppi; + IntReferenceProcessInfo(ppi); + *HandleOwner = ppi; + ppi->UserHandleCount++; + + return ObjHead; +} + +static void FreeProcMarkObject( + _In_ PVOID Object) +{ + PPROCESSINFO ppi = ((PPROCMARKHEAD)Object)->ppi; + + UserHeapFree(Object); + + ppi->UserHandleCount--; + IntDereferenceProcessInfo(ppi); +} + +static PVOID AllocSysObject( + _In_ PDESKTOP pDesk, + _In_ PTHREADINFO pti, + _In_ SIZE_T Size, + _Out_ PVOID* ObjectOwner) +{ + PVOID Object; + + UNREFERENCED_PARAMETER(pDesk); + UNREFERENCED_PARAMETER(pti); + + ASSERT(Size > sizeof(HEAD)); + + Object = UserHeapAlloc(Size); + if (!Object) + return NULL; + + *ObjectOwner = NULL; + + RtlZeroMemory(Object, Size); + return Object; +} + +static void FreeSysObject( + _In_ PVOID Object) +{ + UserHeapFree(Object); +} + +static const struct +{ + PVOID (*ObjectAlloc)(PDESKTOP, PTHREADINFO, SIZE_T, PVOID*); + BOOLEAN (*ObjectDestroy)(PVOID); + void (*ObjectFree)(PVOID); +} ObjectCallbacks[TYPE_CTYPES] = +{ + { NULL, NULL, NULL }, /* TYPE_FREE */ + { AllocDeskThreadObject, co_UserDestroyWindow, FreeDeskThreadObject }, /* TYPE_WINDOW */ + { AllocDeskProcObject, UserDestroyMenuObject, FreeDeskProcObject }, /* TYPE_MENU */ + { AllocProcMarkObject, /*UserCursorCleanup*/NULL, FreeProcMarkObject }, /* TYPE_CURSOR */ + { AllocSysObject, /*UserSetWindowPosCleanup*/NULL, FreeSysObject }, /* TYPE_SETWINDOWPOS */ + { AllocDeskThreadObject, IntRemoveHook, FreeDeskThreadObject }, /* TYPE_HOOK */ + { AllocSysObject, /*UserClipDataCleanup*/NULL,FreeSysObject }, /* TYPE_CLIPDATA */ + { AllocDeskProcObject, DestroyCallProc, FreeDeskProcObject }, /* TYPE_CALLPROC */ + { AllocProcMarkObject, UserDestroyAccelTable, FreeProcMarkObject }, /* TYPE_ACCELTABLE */ + { NULL, NULL, NULL }, /* TYPE_DDEACCESS */ + { NULL, NULL, NULL }, /* TYPE_DDECONV */ + { NULL, NULL, NULL }, /* TYPE_DDEXACT */ + { AllocSysObject, /*UserMonitorCleanup*/NULL, FreeSysObject }, /* TYPE_MONITOR */ + { AllocSysObject, /*UserKbdLayoutCleanup*/NULL,FreeSysObject }, /* TYPE_KBDLAYOUT */ + { AllocSysObject, /*UserKbdFileCleanup*/NULL, FreeSysObject }, /* TYPE_KBDFILE */ + { AllocThreadObject, IntRemoveEvent, FreeThreadObject }, /* TYPE_WINEVENTHOOK */ + { AllocSysObject, /*UserTimerCleanup*/NULL, FreeSysObject }, /* TYPE_TIMER */ + { NULL, NULL, NULL }, /* TYPE_INPUTCONTEXT */ + { NULL, NULL, NULL }, /* TYPE_HIDDATA */ + { NULL, NULL, NULL }, /* TYPE_DEVICEINFO */ + { NULL, NULL, NULL }, /* TYPE_TOUCHINPUTINFO */ + { NULL, NULL, NULL }, /* TYPE_GESTUREINFOOBJ */ +}; + #if DBG
void DbgUserDumpHandleTable() @@ -27,7 +254,7 @@
memset(HandleCounts, 0, sizeof(HandleCounts));
- /* First of all count the number of handles per tpe */ + /* First of all count the number of handles per type */ ppiList = gppiList; while (ppiList) { @@ -96,7 +323,6 @@ __inline static PUSER_HANDLE_ENTRY alloc_user_entry(PUSER_HANDLE_TABLE ht) { PUSER_HANDLE_ENTRY entry; - PPROCESSINFO ppi = PsGetCurrentProcessWin32Process(); TRACE("handles used %lu\n", gpsi->cHandleEntries);
if (ht->freelist) @@ -105,7 +331,6 @@ ht->freelist = entry->ptr;
gpsi->cHandleEntries++; - ppi->UserHandleCount++; return entry; }
@@ -137,7 +362,6 @@ entry->generation = 1;
gpsi->cHandleEntries++; - ppi->UserHandleCount++;
return entry; } @@ -151,13 +375,33 @@ ht->allocated_handles = bytes / sizeof(USER_HANDLE_ENTRY); }
+ __inline static void *free_user_entry(PUSER_HANDLE_TABLE ht, PUSER_HANDLE_ENTRY entry) { - PPROCESSINFO ppi = PsGetCurrentProcessWin32Process(); void *ret;
#if DBG - ppi->DbgHandleCount[entry->type]--; + { + PPROCESSINFO ppi; + switch (entry->type) + { + case TYPE_WINDOW: + case TYPE_HOOK: + case TYPE_WINEVENTHOOK: + ppi = ((PTHREADINFO)entry->pi)->ppi; + break; + case TYPE_MENU: + case TYPE_CURSOR: + case TYPE_CALLPROC: + case TYPE_ACCELTABLE: + ppi = entry->pi; + break; + default: + ppi = NULL; + } + if (ppi) + ppi->DbgHandleCount[entry->type]--; + } #endif
ret = entry->ptr; @@ -168,46 +412,16 @@ ht->freelist = entry;
gpsi->cHandleEntries--; - ppi->UserHandleCount--;
return ret; }
-static __inline PVOID -UserHandleOwnerByType(HANDLE_TYPE type) -{ - PVOID pi; - - switch (type) - { - case TYPE_WINDOW: - case TYPE_INPUTCONTEXT: - pi = GetW32ThreadInfo(); - break; - - case TYPE_MENU: - case TYPE_CURSOR: - case TYPE_HOOK: - case TYPE_CALLPROC: - case TYPE_ACCELTABLE: - case TYPE_SETWINDOWPOS: - pi = GetW32ProcessInfo(); - break; - - case TYPE_MONITOR: - pi = NULL; /* System */ - break; - - default: - pi = NULL; - break; - } - - return pi; -} - /* allocate a user handle for a given object */ -HANDLE UserAllocHandle(PUSER_HANDLE_TABLE ht, PVOID object, HANDLE_TYPE type ) +HANDLE UserAllocHandle( + _Inout_ PUSER_HANDLE_TABLE ht, + _In_ PVOID object, + _In_ HANDLE_TYPE type, + _In_ PVOID HandleOwner) { PUSER_HANDLE_ENTRY entry = alloc_user_entry(ht); if (!entry) @@ -215,7 +429,7 @@ entry->ptr = object; entry->type = type; entry->flags = 0; - entry->pi = UserHandleOwnerByType(type); + entry->pi = HandleOwner; if (++entry->generation >= 0xffff) entry->generation = 1;
@@ -322,82 +536,41 @@ { HANDLE hi; PVOID Object; - PPROCESSINFO ppi; - BOOL dt; - PDESKTOP rpdesk = pDesktop; - - /* We could get the desktop for the new object from the pti however this is - * not always the case for example when creating a new desktop window for - * the desktop thread*/ - - if (!pti) pti = GetW32ThreadInfo(); - if (!pDesktop) rpdesk = pti->rpdesk; - ppi = pti->ppi; - - switch (type) - { - case TYPE_WINDOW: - case TYPE_MENU: - case TYPE_HOOK: - case TYPE_CALLPROC: - case TYPE_INPUTCONTEXT: - Object = DesktopHeapAlloc(rpdesk, size); - dt = TRUE; - break; - - default: - Object = UserHeapAlloc(size); - dt = FALSE; - break; - } - + PVOID ObjectOwner; + + /* Some sanity checks. Other checks will be made in the allocator */ + ASSERT(type < TYPE_CTYPES); + ASSERT(type != TYPE_FREE); + ASSERT(ht != NULL); + + /* Allocate the object */ + ASSERT(ObjectCallbacks[type].ObjectAlloc != NULL); + Object = ObjectCallbacks[type].ObjectAlloc(pDesktop, pti, size, &ObjectOwner); if (!Object) - return NULL; - - - hi = UserAllocHandle(ht, Object, type ); - if (!hi) - { - if (dt) - DesktopHeapFree(rpdesk, Object); - else - UserHeapFree(Object); - return NULL; + { + ERR("User object allocation failed. Out of memory!\n"); + return NULL; + } + + hi = UserAllocHandle(ht, Object, type, ObjectOwner); + if (hi == NULL) + { + ERR("Out of user handles!\n"); + ObjectCallbacks[type].ObjectFree(Object); + return NULL; }
#if DBG - ppi->DbgHandleCount[type]++; + if (pti) + pti->ppi->DbgHandleCount[type]++; #endif
- RtlZeroMemory(Object, size); - - switch (type) - { - case TYPE_WINDOW: - case TYPE_HOOK: - case TYPE_INPUTCONTEXT: - ((PTHRDESKHEAD)Object)->rpdesk = rpdesk; - ((PTHRDESKHEAD)Object)->pSelf = Object; - case TYPE_WINEVENTHOOK: - ((PTHROBJHEAD)Object)->pti = pti; - break; - - case TYPE_MENU: - case TYPE_CALLPROC: - ((PPROCDESKHEAD)Object)->rpdesk = rpdesk; - ((PPROCDESKHEAD)Object)->pSelf = Object; - break; - - case TYPE_CURSOR: - ((PPROCMARKHEAD)Object)->ppi = ppi; - break; - - default: - break; - } - /* Now set default headers. */ + /* Give this object its identity. */ ((PHEAD)Object)->h = hi; - ((PHEAD)Object)->cLockObj = 2; // We need this, because we create 2 refs: handle and pointer! + + /* The caller will get a locked object. + * Note: with the reference from the handle, that makes two */ + UserReferenceObject(Object);
if (h) *h = hi; @@ -407,46 +580,43 @@
BOOL FASTCALL -UserDereferenceObject(PVOID object) -{ - PUSER_HANDLE_ENTRY entry; - HANDLE_TYPE type; - - ASSERT(((PHEAD)object)->cLockObj >= 1); - - if ((INT)--((PHEAD)object)->cLockObj <= 0) - { - entry = handle_to_entry(gHandleTable, ((PHEAD)object)->h ); - - if (!entry) - { - ERR("Warning! Dereference Object without ENTRY! Obj -> %p\n", object); - return FALSE; - } - TRACE("Warning! Dereference to zero! Obj -> %p\n", object); - - ((PHEAD)object)->cLockObj = 0; - - if (!(entry->flags & HANDLEENTRY_INDESTROY)) +UserDereferenceObject(PVOID Object) +{ + PHEAD ObjHead = (PHEAD)Object; + + ASSERT(ObjHead->cLockObj >= 1); + + if (--ObjHead->cLockObj == 0) + { + PUSER_HANDLE_ENTRY entry; + HANDLE_TYPE type; + + entry = handle_to_entry(gHandleTable, ObjHead->h); + + ASSERT(entry != NULL); + /* The entry should be marked as in deletion */ + ASSERT(entry->flags & HANDLEENTRY_INDESTROY); + + type = entry->type; + ASSERT(type != TYPE_FREE); + ASSERT(type < TYPE_CTYPES); + + /* We can now get rid of everything */ + free_user_entry(gHandleTable, entry ); + +#if 0 + /* Call the object destructor */ + ASSERT(ObjectCallbacks[type].ObjectCleanup != NULL); + ObjectCallbacks[type].ObjectCleanup(Object); +#endif + + /* And free it */ + ASSERT(ObjectCallbacks[type].ObjectFree != NULL); + ObjectCallbacks[type].ObjectFree(Object); + return TRUE; - - type = entry->type; - free_user_entry(gHandleTable, entry ); - - switch (type) - { - case TYPE_WINDOW: - case TYPE_MENU: - case TYPE_HOOK: - case TYPE_CALLPROC: - case TYPE_INPUTCONTEXT: - return DesktopHeapFree(((PTHRDESKHEAD)object)->rpdesk, object); - - default: - return UserHeapFree(object); - } - } - return FALSE; + } + return FALSE; }
BOOL @@ -522,10 +692,10 @@ { PUSER_HANDLE_ENTRY entry = handle_to_entry(gHandleTable, ((PHEAD)obj)->h ); PPROCESSINFO ppi, oldppi; - + /* This must be called with a valid object */ ASSERT(entry); - + /* For now, only supported for CursorIcon object */ switch(type) { @@ -541,59 +711,55 @@ }
oldppi->UserHandleCount--; + IntDereferenceProcessInfo(oldppi); ppi->UserHandleCount++; + IntReferenceProcessInfo(ppi); #if DBG oldppi->DbgHandleCount[type]--; ppi->DbgHandleCount[type]++; #endif }
- -HANDLE FASTCALL ValidateHandleNoErr(HANDLE handle, HANDLE_TYPE type) -{ - if (handle) return (PWND)UserGetObjectNoErr(gHandleTable, handle, type); - return NULL; -} - -PVOID FASTCALL ValidateHandle(HANDLE handle, HANDLE_TYPE type) -{ - PVOID pObj; - DWORD dwError = 0; - if (handle) - { - pObj = UserGetObjectNoErr(gHandleTable, handle, type); - if (!pObj) - { - switch (type) - { - case TYPE_WINDOW: - dwError = ERROR_INVALID_WINDOW_HANDLE; - break; - case TYPE_MENU: - dwError = ERROR_INVALID_MENU_HANDLE; - break; - case TYPE_CURSOR: - dwError = ERROR_INVALID_CURSOR_HANDLE; - break; - case TYPE_SETWINDOWPOS: - dwError = ERROR_INVALID_DWP_HANDLE; - break; - case TYPE_HOOK: - dwError = ERROR_INVALID_HOOK_HANDLE; - break; - case TYPE_ACCELTABLE: - dwError = ERROR_INVALID_ACCEL_HANDLE; - break; - default: - dwError = ERROR_INVALID_HANDLE; - break; - } - EngSetLastError(dwError); - return NULL; - } - return pObj; - } - return NULL; +BOOLEAN +UserDestroyObjectsForOwner(PUSER_HANDLE_TABLE Table, PVOID Owner) +{ + int i; + PUSER_HANDLE_ENTRY Entry; + BOOLEAN Ret = TRUE; + + /* Sweep the whole handle table */ + for (i = 0; i < Table->allocated_handles; i++) + { + Entry = &Table->handles[i]; + + if (Entry->pi != Owner) + continue; + + /* Do not destroy if it's already been done */ + if (Entry->flags & HANDLEENTRY_INDESTROY) + continue; + + /* Spcial case for cursors until cursoricon_new is there */ + if (Entry->type == TYPE_CURSOR) + { + UserReferenceObject(Entry->ptr); + if (!IntDestroyCurIconObject(Entry->ptr, Owner)) + { + Ret = FALSE; + } + continue; + } + + /* Call destructor */ + if (!ObjectCallbacks[Entry->type].ObjectDestroy(Entry->ptr)) + { + ERR("Failed destructing object %p, type %u.\n", Entry->ptr, Entry->type); + /* Don't return immediately, we must continue destroying the other objects */ + Ret = FALSE; + } + } + + return Ret; }
/*
Modified: trunk/reactos/win32ss/user/ntuser/object.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/object.... ============================================================================== --- trunk/reactos/win32ss/user/ntuser/object.h [iso-8859-1] (original) +++ trunk/reactos/win32ss/user/ntuser/object.h [iso-8859-1] Sun Sep 21 17:44:40 2014 @@ -18,8 +18,8 @@ BOOL FASTCALL UserObjectInDestroy(HANDLE); void DbgUserDumpHandleTable(); VOID FASTCALL UserSetObjectOwner(PVOID obj, HANDLE_TYPE type, PVOID owner); -HANDLE FASTCALL ValidateHandleNoErr(HANDLE handle, HANDLE_TYPE type); PVOID FASTCALL ValidateHandle(HANDLE handle, HANDLE_TYPE type); +BOOLEAN UserDestroyObjectsForOwner(PUSER_HANDLE_TABLE Table, PVOID Owner);
static __inline VOID UserRefObjectCo(PVOID obj, PUSER_REFERENCE_ENTRY UserReferenceEntry)
Modified: trunk/reactos/win32ss/user/ntuser/simplecall.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/simplec... ============================================================================== --- trunk/reactos/win32ss/user/ntuser/simplecall.c [iso-8859-1] (original) +++ trunk/reactos/win32ss/user/ntuser/simplecall.c [iso-8859-1] Sun Sep 21 17:44:40 2014 @@ -73,11 +73,11 @@ switch(Routine) { case NOPARAM_ROUTINE_CREATEMENU: - Result = (DWORD_PTR)UserCreateMenu(FALSE); + Result = (DWORD_PTR)UserCreateMenu(GetW32ThreadInfo()->rpdesk, FALSE); break;
case NOPARAM_ROUTINE_CREATEMENUPOPUP: - Result = (DWORD_PTR)UserCreateMenu(TRUE); + Result = (DWORD_PTR)UserCreateMenu(GetW32ThreadInfo()->rpdesk, TRUE); break;
case NOPARAM_ROUTINE_DESTROY_CARET:
Modified: trunk/reactos/win32ss/user/ntuser/userfuncs.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/userfun... ============================================================================== --- trunk/reactos/win32ss/user/ntuser/userfuncs.h [iso-8859-1] (original) +++ trunk/reactos/win32ss/user/ntuser/userfuncs.h [iso-8859-1] Sun Sep 21 17:44:40 2014 @@ -2,7 +2,7 @@
FORCEINLINE PMENU UserGetMenuObject(HMENU hMenu) { - return ValidateHandle(hMenu, TYPE_MENU); + return UserGetObject(gHandleTable, hMenu, TYPE_MENU); }
#define ASSERT_REFS_CO(_obj_) \ @@ -106,12 +106,12 @@ VOID FASTCALL co_DestroyThreadWindows(struct _ETHREAD *Thread); HWND FASTCALL UserGetShellWindow(VOID); HDC FASTCALL UserGetDCEx(PWND Window OPTIONAL, HANDLE ClipRegion, ULONG Flags); -BOOLEAN FASTCALL co_UserDestroyWindow(PWND Wnd); +BOOLEAN co_UserDestroyWindow(PVOID Object); PWND FASTCALL UserGetAncestor(PWND Wnd, UINT Type);
/*************** MENU.C ***************/
-HMENU FASTCALL UserCreateMenu(BOOL PopupMenu); +HMENU FASTCALL UserCreateMenu(PDESKTOP Desktop, BOOL PopupMenu); BOOL FASTCALL UserSetMenuDefaultItem(PMENU Menu, UINT uItem, UINT fByPos); BOOL FASTCALL UserDestroyMenu(HMENU hMenu);
Modified: trunk/reactos/win32ss/user/ntuser/win32.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/win32.h... ============================================================================== --- trunk/reactos/win32ss/user/ntuser/win32.h [iso-8859-1] (original) +++ trunk/reactos/win32ss/user/ntuser/win32.h [iso-8859-1] Sun Sep 21 17:44:40 2014 @@ -158,14 +158,28 @@ #define IntReferenceThreadInfo(pti) \ InterlockedIncrement(&(pti)->RefCount)
-VOID FASTCALL UserDeleteW32Thread(PTHREADINFO); +VOID UserDeleteW32Thread(PTHREADINFO);
#define IntDereferenceThreadInfo(pti) \ do { \ if(InterlockedDecrement(&(pti)->RefCount) == 0) \ { \ - ASSERT(pti->TIF_flags &= (TIF_INCLEANUP|TIF_DONTATTACHQUEUE) == (TIF_INCLEANUP|TIF_DONTATTACHQUEUE)); \ + ASSERT(((pti)->TIF_flags & (TIF_INCLEANUP|TIF_DONTATTACHQUEUE)) == (TIF_INCLEANUP|TIF_DONTATTACHQUEUE)); \ UserDeleteW32Thread(pti); \ + } \ + } while(0) + +#define IntReferenceProcessInfo(ppi) \ + InterlockedIncrement((volatile LONG*)(&(ppi)->RefCount)) + +VOID UserDeleteW32Process(PPROCESSINFO); + +#define IntDereferenceProcessInfo(ppi) \ + do { \ + if(InterlockedDecrement((volatile LONG*)(&(ppi)->RefCount)) == 0) \ + { \ + ASSERT(((ppi)->W32PF_flags & W32PF_TERMINATED) != 0); \ + UserDeleteW32Process(ppi); \ } \ } while(0)
@@ -242,7 +256,6 @@ DWORD dwLayout; DWORD dwRegisteredClasses; /* ReactOS */ - LIST_ENTRY MenuListHead; FAST_MUTEX PrivateFontListLock; LIST_ENTRY PrivateFontListHead; FAST_MUTEX DriverObjListLock;
Modified: trunk/reactos/win32ss/user/ntuser/window.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/window.... ============================================================================== --- trunk/reactos/win32ss/user/ntuser/window.c [iso-8859-1] (original) +++ trunk/reactos/win32ss/user/ntuser/window.c [iso-8859-1] Sun Sep 21 17:44:40 2014 @@ -587,14 +587,14 @@ Window->IDMenu && (Menu = UserGetMenuObject((HMENU)Window->IDMenu))) { - IntDestroyMenuObject(Menu, TRUE, TRUE); + IntDestroyMenuObject(Menu, TRUE); Window->IDMenu = 0; }
if(Window->SystemMenu && (Menu = UserGetMenuObject(Window->SystemMenu))) { - IntDestroyMenuObject(Menu, TRUE, TRUE); + IntDestroyMenuObject(Menu, TRUE); Window->SystemMenu = (HMENU)0; }
@@ -860,40 +860,6 @@
/* INTERNAL ******************************************************************/
- -VOID FASTCALL -co_DestroyThreadWindows(struct _ETHREAD *Thread) -{ - PTHREADINFO WThread; - PLIST_ENTRY Current; - PWND Wnd; - USER_REFERENCE_ENTRY Ref; - WThread = (PTHREADINFO)Thread->Tcb.Win32Thread; - - while (!IsListEmpty(&WThread->WindowListHead)) - { - Current = WThread->WindowListHead.Flink; - Wnd = CONTAINING_RECORD(Current, WND, ThreadListEntry); - - TRACE("thread cleanup: while destroy wnds, wnd=%p\n", Wnd); - - /* Window removes itself from the list */ - - /* - * FIXME: It is critical that the window removes itself! If now, we will loop - * here forever... - */ - - //ASSERT(co_UserDestroyWindow(Wnd)); - - UserRefObjectCo(Wnd, &Ref); // FIXME: Temp HACK?? - if (!co_UserDestroyWindow(Wnd)) - { - ERR("Unable to destroy window %p at thread cleanup... This is _VERY_ bad!\n", Wnd); - } - UserDerefObjectCo(Wnd); // FIXME: Temp HACK?? - } -}
BOOL FASTCALL IntIsChildWindow(PWND Parent, PWND BaseWindow) @@ -1788,7 +1754,7 @@ if (Class->atomClassName == gpsi->atomSysClass[ICLS_EDIT]) { PCALLPROCDATA CallProc; - CallProc = CreateCallProc(NULL, pWnd->lpfnWndProc, pWnd->Unicode , pWnd->head.pti->ppi); + CallProc = CreateCallProc(pWnd->head.rpdesk, pWnd->lpfnWndProc, pWnd->Unicode , pWnd->head.pti->ppi);
if (!CallProc) { @@ -2431,9 +2397,10 @@ if ( (dwStyle & (WS_POPUP|WS_CHILD)) != WS_CHILD) { /* check hMenu is valid handle */ - if (hMenu && !ValidateHandle(hMenu, TYPE_MENU)) + if (hMenu && !UserGetMenuObject(hMenu)) { - /* error is set in ValidateHandle */ + ERR("NtUserCreateWindowEx: Got an invalid menu handle!\n"); + EngSetLastError(ERROR_INVALID_MENU_HANDLE); return NULL; } } @@ -2520,12 +2487,13 @@ }
-BOOLEAN FASTCALL co_UserDestroyWindow(PWND Window) +BOOLEAN co_UserDestroyWindow(PVOID Object) { HWND hWnd; PWND pwndTemp; PTHREADINFO ti; MSG msg; + PWND Window = Object;
ASSERT_REFS_CO(Window); // FIXME: Temp HACK?
Modified: trunk/reactos/win32ss/user/user32/misc/misc.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/user32/misc/mi... ============================================================================== --- trunk/reactos/win32ss/user/user32/misc/misc.c [iso-8859-1] (original) +++ trunk/reactos/win32ss/user/user32/misc/misc.c [iso-8859-1] Sun Sep 21 17:44:40 2014 @@ -315,17 +315,17 @@ TRUE, /* TYPE_CURSOR */ TRUE, /* TYPE_SETWINDOWPOS */ FALSE, /* TYPE_HOOK */ - FALSE, /* TYPE_CLIPDATA */ + TRUE, /* TYPE_CLIPDATA */ FALSE, /* TYPE_CALLPROC */ TRUE, /* TYPE_ACCELTABLE */ FALSE, /* TYPE_DDEACCESS */ FALSE, /* TYPE_DDECONV */ FALSE, /* TYPE_DDEXACT */ TRUE, /* TYPE_MONITOR */ - FALSE, /* TYPE_KBDLAYOUT */ - FALSE, /* TYPE_KBDFILE */ + TRUE, /* TYPE_KBDLAYOUT */ + TRUE, /* TYPE_KBDFILE */ TRUE, /* TYPE_WINEVENTHOOK */ - FALSE, /* TYPE_TIMER */ + TRUE, /* TYPE_TIMER */ FALSE, /* TYPE_INPUTCONTEXT */ FALSE, /* TYPE_HIDDATA */ FALSE, /* TYPE_DEVICEINFO */