Author: jgardou Date: Thu Jun 10 22:15:05 2010 New Revision: 47748
URL: http://svn.reactos.org/svn/reactos?rev=47748&view=rev Log: [WIN32K] Merge GDIOBJ related changes from yarotows - GDIOBJ_(Share)LockObj : return NULL on NULL input, avoiding debug spew - Set NULL process owner when setting READY_TO_DIE flag of a gdiobj - So now GDIOBJ_ShareUnlockObj can claim ownership before trying to delete the object
Modified: trunk/reactos/subsystems/win32/win32k/include/gdiobj.h trunk/reactos/subsystems/win32/win32k/objects/gdiobj.c
Modified: trunk/reactos/subsystems/win32/win32k/include/gdiobj.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/inc... ============================================================================== --- trunk/reactos/subsystems/win32/win32k/include/gdiobj.h [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/win32k/include/gdiobj.h [iso-8859-1] Thu Jun 10 22:15:05 2010 @@ -87,7 +87,7 @@ BOOL FASTCALL IntGdiSetRegionOwner(HRGN,DWORD);
/*! - * Release GDI object. Every object locked by GDIOBJ_LockObj() must be unlocked. + * Release GDI object. Every object locked by GDIOBJ_LockObj() must be unlocked. * You should unlock the object * as soon as you don't need to have access to it's data.
@@ -112,6 +112,7 @@ ASSERT(cLocks >= 0); if ((flags & BASEFLAG_READY_TO_DIE) && (cLocks == 0)) { + GDIOBJ_SetOwnership(hobj, PsGetCurrentProcess()); GDIOBJ_FreeObjByHandle(hobj, GDI_OBJECT_TYPE_DONTCARE); } return cLocks;
Modified: trunk/reactos/subsystems/win32/win32k/objects/gdiobj.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/obj... ============================================================================== --- trunk/reactos/subsystems/win32/win32k/objects/gdiobj.c [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/win32k/objects/gdiobj.c [iso-8859-1] Thu Jun 10 22:15:05 2010 @@ -631,10 +631,24 @@ } else if (Object->ulShareCount != 0) { + NTSTATUS Status; + PEPROCESS OldProcess; Object->BaseFlags |= BASEFLAG_READY_TO_DIE; DPRINT("Object %p, ulShareCount = %d\n", Object->hHmgr, Object->ulShareCount); //GDIDBG_TRACECALLER(); //GDIDBG_TRACESHARELOCKER(GDI_HANDLE_GET_INDEX(hObj)); + /* Set NULL owner. This will permit an other process to kill the object + * Do the work here to avoid race conditions */ + Status = PsLookupProcessByProcessId((HANDLE)((ULONG_PTR)PrevProcId & ~0x1), &OldProcess); + if (NT_SUCCESS(Status)) + { + PPROCESSINFO W32Process = (PPROCESSINFO)OldProcess->Win32Process; + if (W32Process != NULL) + { + InterlockedDecrement(&W32Process->GDIHandleCount); + } + ObDereferenceObject(OldProcess); + } (void)InterlockedExchangePointer((PVOID*)&Entry->ProcessId, PrevProcId); /* Don't wait on shared locks */ return FALSE; @@ -952,6 +966,10 @@ POBJ Object = NULL; ULONG HandleType, HandleUpper;
+ /* Check for dummy call */ + if(hObj == NULL) + return NULL ; + HandleIndex = GDI_HANDLE_GET_INDEX(hObj); HandleType = GDI_HANDLE_GET_TYPE(hObj); HandleUpper = GDI_HANDLE_GET_UPPER(hObj); @@ -1090,6 +1108,10 @@ HANDLE ProcessId, HandleProcessId, LockedProcessId, PrevProcId; POBJ Object = NULL; ULONG_PTR HandleType, HandleUpper; + + /* Check for dummy call */ + if(hObj == NULL) + return NULL ;
HandleIndex = GDI_HANDLE_GET_INDEX(hObj); HandleType = GDI_HANDLE_GET_TYPE(hObj);