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?r…
==============================================================================
--- 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/accele…
==============================================================================
--- 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/accele…
==============================================================================
--- 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/callpr…
==============================================================================
--- 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.…
==============================================================================
--- 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.…
==============================================================================
--- 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/cursor…
==============================================================================
--- 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/cursor…
==============================================================================
--- 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.…
==============================================================================
--- 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/simple…
==============================================================================
--- 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/userfu…
==============================================================================
--- 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.…
==============================================================================
--- 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/m…
==============================================================================
--- 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 */