diff --git a/reactos/subsystems/win32/win32k/include/gdiobj.h b/reactos/subsystems/win32/win32k/include/gdiobj.h index 6b9a7fd8aa8..9ce98f0d830 100644 --- a/reactos/subsystems/win32/win32k/include/gdiobj.h +++ b/reactos/subsystems/win32/win32k/include/gdiobj.h @@ -87,7 +87,7 @@ BOOL FASTCALL IntGdiSetDCOwnerEx( HDC, DWORD, BOOL); 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 @@ GDIOBJ_ShareUnlockObjByPtr(POBJ Object) ASSERT(cLocks >= 0); if ((flags & BASEFLAG_READY_TO_DIE) && (cLocks == 0)) { + GDIOBJ_SetOwnership(hobj, PsGetCurrentProcess()); GDIOBJ_FreeObjByHandle(hobj, GDI_OBJECT_TYPE_DONTCARE); } return cLocks; diff --git a/reactos/subsystems/win32/win32k/objects/gdiobj.c b/reactos/subsystems/win32/win32k/objects/gdiobj.c index 0f73d9b57cf..e2771e43ee3 100644 --- a/reactos/subsystems/win32/win32k/objects/gdiobj.c +++ b/reactos/subsystems/win32/win32k/objects/gdiobj.c @@ -631,10 +631,24 @@ LockHandle: } 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 @@ GDIOBJ_LockObj(HGDIOBJ hObj, DWORD ExpectedType) 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); @@ -1091,6 +1109,10 @@ GDIOBJ_ShareLockObj(HGDIOBJ hObj, DWORD ExpectedType) 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); HandleUpper = GDI_HANDLE_GET_UPPER(hObj);