- 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
#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
{
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)
{
}
}
}
- 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;
}
}
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
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)
}
UserReferenceObject(Window);
- UserDeleteObject(UserHMGetHandle(Window), TYPE_WINDOW);
+ UserMarkObjectDestroy(Window);
IntDestroyScrollBars(Window);
UserFreeWindowInfo(Window->head.pti, Window);
UserDereferenceObject(Window);
+ UserDeleteObject(UserHMGetHandle(Window), TYPE_WINDOW);
return 0;
}
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!