[WIN32K]
authorJérôme Gardou <jerome.gardou@reactos.org>
Thu, 10 Jun 2010 22:15:05 +0000 (22:15 +0000)
committerJérôme Gardou <jerome.gardou@reactos.org>
Thu, 10 Jun 2010 22:15:05 +0000 (22:15 +0000)
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

svn path=/trunk/; revision=47748

reactos/subsystems/win32/win32k/include/gdiobj.h
reactos/subsystems/win32/win32k/objects/gdiobj.c

index 6b9a7fd..9ce98f0 100644 (file)
@@ -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;
index 0f73d9b..e2771e4 100644 (file)
@@ -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);