[Win32SS]

- Fix menu crash, marking the menu object destroyed if the access count is more than one. Must remember these are not GDI objects. Expect a retooling of user objects soon. Set CORE-11892.

svn path=/trunk/; revision=72837
This commit is contained in:
James Tabor 2016-09-28 16:51:53 +00:00
parent d0e5925de2
commit eb207003e7
6 changed files with 36 additions and 23 deletions

View file

@ -13,7 +13,8 @@ typedef HANDLE HIMC;
#define FIRST_USER_HANDLE 0x0020 /* first possible value for low word of user handle */
#define LAST_USER_HANDLE 0xffef /* last possible value for low word of user handle */
#define HANDLEENTRY_INDESTROY 1
#define HANDLEENTRY_DESTROY 1
#define HANDLEENTRY_INDESTROY 2
typedef struct _USER_HANDLE_ENTRY
{

View file

@ -322,13 +322,9 @@ UserDestroyMenuObject(PVOID Object)
BOOL FASTCALL
IntDestroyMenuObject(PMENU Menu, BOOL bRecurse)
{
if(Menu)
if (Menu)
{
PWND Window;
ULONG Error;
/* Remove all menu items */
IntDestroyMenu( Menu, bRecurse);
if (PsGetCurrentProcessSessionId() == Menu->head.rpdesk->rpwinstaParent->dwSessionId)
{
@ -350,22 +346,14 @@ IntDestroyMenuObject(PMENU Menu, BOOL bRecurse)
}
}
}
if (UserObjectInDestroy(Menu->head.h))
{
WARN("Menu already dead!\n");
return FALSE;
}
if (!UserMarkObjectDestroy(Menu)) return TRUE;
/* Remove all menu items */
IntDestroyMenu( Menu, bRecurse);
ret = UserDeleteObject(Menu->head.h, TYPE_MENU);
if (!ret)
{ // Make sure it is really dead or just marked for deletion.
Error = EngGetLastError();
ret = UserObjectInDestroy(Menu->head.h);
if (ret && EngGetLastError() == ERROR_INVALID_HANDLE)
{
EngSetLastError(Error);
ret = FALSE;
}
} // See test_subpopup_locked_by_menu tests....
TRACE("IntDestroyMenuObject %d\n",ret);
return ret;
}
}

View file

@ -582,6 +582,28 @@ UserCreateObject( PUSER_HANDLE_TABLE ht,
return Object;
}
BOOL
FASTCALL
UserMarkObjectDestroy(PVOID Object)
{
PUSER_HANDLE_ENTRY entry;
PHEAD ObjHead = Object;
entry = handle_to_entry(gHandleTable, ObjHead->h);
ASSERT(entry != NULL);
entry->flags |= HANDLEENTRY_DESTROY;
if (ObjHead->cLockObj > 1)
{
entry->flags &= ~HANDLEENTRY_INDESTROY;
TRACE("Count %d\n",ObjHead->cLockObj);
return FALSE;
}
return TRUE;
}
BOOL
FASTCALL

View file

@ -19,6 +19,7 @@ BOOL FASTCALL UserObjectInDestroy(HANDLE);
void DbgUserDumpHandleTable();
PVOID FASTCALL ValidateHandle(HANDLE handle, HANDLE_TYPE type);
BOOLEAN UserDestroyObjectsForOwner(PUSER_HANDLE_TABLE Table, PVOID Owner);
BOOL FASTCALL UserMarkObjectDestroy(PVOID);
static __inline VOID
UserRefObjectCo(PVOID obj, PUSER_REFERENCE_ENTRY UserReferenceEntry)

View file

@ -641,7 +641,7 @@ LRESULT co_UserFreeWindow(PWND Window,
}
UserReferenceObject(Window);
UserDeleteObject(UserHMGetHandle(Window), TYPE_WINDOW);
UserMarkObjectDestroy(Window);
IntDestroyScrollBars(Window);
@ -670,6 +670,7 @@ LRESULT co_UserFreeWindow(PWND Window,
UserFreeWindowInfo(Window->head.pti, Window);
UserDereferenceObject(Window);
UserDeleteObject(UserHMGetHandle(Window), TYPE_WINDOW);
return 0;
}

View file

@ -283,7 +283,7 @@ ValidateHandle(HANDLE handle, UINT uType)
if ( (!pEntry) ||
(pEntry->type != uType) ||
!pEntry->ptr ||
(pEntry->flags & HANDLEENTRY_INDESTROY) )
(pEntry->flags & HANDLEENTRY_DESTROY) || (pEntry->flags & HANDLEENTRY_INDESTROY) )
{
switch ( uType )
{ // Test (with wine too) confirms these results!