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/in…
==============================================================================
--- 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/ob…
==============================================================================
--- 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);