mirror of
https://github.com/reactos/reactos.git
synced 2025-02-22 08:25:03 +00:00
[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:
parent
d0e5925de2
commit
eb207003e7
6 changed files with 36 additions and 23 deletions
|
@ -13,7 +13,8 @@ typedef HANDLE HIMC;
|
||||||
#define FIRST_USER_HANDLE 0x0020 /* first possible value for low word of user handle */
|
#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 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
|
typedef struct _USER_HANDLE_ENTRY
|
||||||
{
|
{
|
||||||
|
|
|
@ -322,13 +322,9 @@ UserDestroyMenuObject(PVOID Object)
|
||||||
BOOL FASTCALL
|
BOOL FASTCALL
|
||||||
IntDestroyMenuObject(PMENU Menu, BOOL bRecurse)
|
IntDestroyMenuObject(PMENU Menu, BOOL bRecurse)
|
||||||
{
|
{
|
||||||
if(Menu)
|
if (Menu)
|
||||||
{
|
{
|
||||||
PWND Window;
|
PWND Window;
|
||||||
ULONG Error;
|
|
||||||
|
|
||||||
/* Remove all menu items */
|
|
||||||
IntDestroyMenu( Menu, bRecurse);
|
|
||||||
|
|
||||||
if (PsGetCurrentProcessSessionId() == Menu->head.rpdesk->rpwinstaParent->dwSessionId)
|
if (PsGetCurrentProcessSessionId() == Menu->head.rpdesk->rpwinstaParent->dwSessionId)
|
||||||
{
|
{
|
||||||
|
@ -350,22 +346,14 @@ IntDestroyMenuObject(PMENU Menu, BOOL bRecurse)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (UserObjectInDestroy(Menu->head.h))
|
|
||||||
{
|
if (!UserMarkObjectDestroy(Menu)) return TRUE;
|
||||||
WARN("Menu already dead!\n");
|
|
||||||
return FALSE;
|
/* Remove all menu items */
|
||||||
}
|
IntDestroyMenu( Menu, bRecurse);
|
||||||
|
|
||||||
ret = UserDeleteObject(Menu->head.h, TYPE_MENU);
|
ret = UserDeleteObject(Menu->head.h, TYPE_MENU);
|
||||||
if (!ret)
|
TRACE("IntDestroyMenuObject %d\n",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....
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -582,6 +582,28 @@ UserCreateObject( PUSER_HANDLE_TABLE ht,
|
||||||
return Object;
|
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
|
BOOL
|
||||||
FASTCALL
|
FASTCALL
|
||||||
|
|
|
@ -19,6 +19,7 @@ BOOL FASTCALL UserObjectInDestroy(HANDLE);
|
||||||
void DbgUserDumpHandleTable();
|
void DbgUserDumpHandleTable();
|
||||||
PVOID FASTCALL ValidateHandle(HANDLE handle, HANDLE_TYPE type);
|
PVOID FASTCALL ValidateHandle(HANDLE handle, HANDLE_TYPE type);
|
||||||
BOOLEAN UserDestroyObjectsForOwner(PUSER_HANDLE_TABLE Table, PVOID Owner);
|
BOOLEAN UserDestroyObjectsForOwner(PUSER_HANDLE_TABLE Table, PVOID Owner);
|
||||||
|
BOOL FASTCALL UserMarkObjectDestroy(PVOID);
|
||||||
|
|
||||||
static __inline VOID
|
static __inline VOID
|
||||||
UserRefObjectCo(PVOID obj, PUSER_REFERENCE_ENTRY UserReferenceEntry)
|
UserRefObjectCo(PVOID obj, PUSER_REFERENCE_ENTRY UserReferenceEntry)
|
||||||
|
|
|
@ -641,7 +641,7 @@ LRESULT co_UserFreeWindow(PWND Window,
|
||||||
}
|
}
|
||||||
|
|
||||||
UserReferenceObject(Window);
|
UserReferenceObject(Window);
|
||||||
UserDeleteObject(UserHMGetHandle(Window), TYPE_WINDOW);
|
UserMarkObjectDestroy(Window);
|
||||||
|
|
||||||
IntDestroyScrollBars(Window);
|
IntDestroyScrollBars(Window);
|
||||||
|
|
||||||
|
@ -670,6 +670,7 @@ LRESULT co_UserFreeWindow(PWND Window,
|
||||||
UserFreeWindowInfo(Window->head.pti, Window);
|
UserFreeWindowInfo(Window->head.pti, Window);
|
||||||
|
|
||||||
UserDereferenceObject(Window);
|
UserDereferenceObject(Window);
|
||||||
|
UserDeleteObject(UserHMGetHandle(Window), TYPE_WINDOW);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -283,7 +283,7 @@ ValidateHandle(HANDLE handle, UINT uType)
|
||||||
if ( (!pEntry) ||
|
if ( (!pEntry) ||
|
||||||
(pEntry->type != uType) ||
|
(pEntry->type != uType) ||
|
||||||
!pEntry->ptr ||
|
!pEntry->ptr ||
|
||||||
(pEntry->flags & HANDLEENTRY_INDESTROY) )
|
(pEntry->flags & HANDLEENTRY_DESTROY) || (pEntry->flags & HANDLEENTRY_INDESTROY) )
|
||||||
{
|
{
|
||||||
switch ( uType )
|
switch ( uType )
|
||||||
{ // Test (with wine too) confirms these results!
|
{ // Test (with wine too) confirms these results!
|
||||||
|
|
Loading…
Reference in a new issue