[WIN32K]
[reactos.git] / reactos / win32ss / gdi / ntgdi / gdiobj.c
index 79f87ac..6b82c34 100644 (file)
@@ -476,19 +476,23 @@ GDIOBJ_vDereferenceObject(POBJ pobj)
 {
     ULONG cRefs, ulIndex;
 
+    /* Calculate the index */
+    ulIndex = GDI_HANDLE_GET_INDEX(pobj->hHmgr);
+
     /* Check if the object has a handle */
-    if (GDI_HANDLE_GET_INDEX(pobj->hHmgr))
+    if (ulIndex)
     {
-        /* Calculate the index */
-        ulIndex = GDI_HANDLE_GET_INDEX(pobj->hHmgr);
-
         /* Decrement reference count */
         ASSERT((gpaulRefCount[ulIndex] & REF_MASK_COUNT) > 0);
-        cRefs = InterlockedDecrement((LONG*)&gpaulRefCount[ulIndex]) & REF_MASK_INUSE;
+        cRefs = InterlockedDecrement((LONG*)&gpaulRefCount[ulIndex]);
+        DBG_LOGEVENT(&pobj->slhLog, EVENT_DEREFERENCE, cRefs);
 
         /* Check if we reached 0 and handle bit is not set */
-        if (cRefs == 0)
+        if ((cRefs & REF_MASK_INUSE) == 0)
         {
+            /* Make sure it's ok to delete the object */
+            ASSERT(pobj->BaseFlags & BASEFLAG_READY_TO_DIE);
+
             /* Check if the handle was process owned */
             if (gpentHmgr[ulIndex].ObjectOwner.ulObj != GDI_OBJ_HMGR_PUBLIC &&
                 gpentHmgr[ulIndex].ObjectOwner.ulObj != GDI_OBJ_HMGR_NONE)
@@ -501,6 +505,9 @@ GDIOBJ_vDereferenceObject(POBJ pobj)
 
             /* Push entry to the free list */
             ENTRY_vPushFreeEntry(&gpentHmgr[ulIndex]);
+
+            /* Free the object */
+            GDIOBJ_vFreeObject(pobj);
         }
     }
     else
@@ -508,18 +515,14 @@ GDIOBJ_vDereferenceObject(POBJ pobj)
         /* Decrement the objects reference count */
         ASSERT(pobj->ulShareCount > 0);
         cRefs = InterlockedDecrement((LONG*)&pobj->ulShareCount);
-    }
-
-    DBG_LOGEVENT(&pobj->slhLog, EVENT_DEREFERENCE, cRefs);
-
-    /* Check if we reached 0 */
-    if (cRefs == 0)
-    {
-        /* Make sure it's ok to delete the object */
-        ASSERT(pobj->BaseFlags & BASEFLAG_READY_TO_DIE);
+        DBG_LOGEVENT(&pobj->slhLog, EVENT_DEREFERENCE, cRefs);
 
-        /* Free the object */
-        GDIOBJ_vFreeObject(pobj);
+        /* Check if we reached 0 */
+        if (cRefs == 0)
+        {
+            /* Free the object */
+            GDIOBJ_vFreeObject(pobj);
+        }
     }
 }
 
@@ -572,9 +575,6 @@ GDIOBJ_vReferenceObjectByPointer(POBJ pobj)
 {
     ULONG cRefs;
 
-    /* Must not be exclusively locked */
-    ASSERT(pobj->cExclusiveLock == 0);
-
     /* Check if the object has a handle */
     if (GDI_HANDLE_GET_INDEX(pobj->hHmgr))
     {
@@ -647,11 +647,13 @@ VOID
 NTAPI
 GDIOBJ_vUnlockObject(POBJ pobj)
 {
+    ULONG cRefs, ulIndex;
     ASSERT(pobj->cExclusiveLock > 0);
 
     /* Decrease lock count */
     pobj->cExclusiveLock--;
     DBG_DECREASE_LOCK_COUNT(PsGetCurrentProcessWin32Process(), pobj->hHmgr);
+    DBG_LOGEVENT(&pobj->slhLog, EVENT_UNLOCK, 0);
 
     /* Check if this was the last lock */
     if (pobj->cExclusiveLock == 0)
@@ -664,9 +666,13 @@ GDIOBJ_vUnlockObject(POBJ pobj)
         KeLeaveCriticalRegion();
     }
 
-    /* Dereference the object */
-    DBG_LOGEVENT(&pobj->slhLog, EVENT_UNLOCK, 0);
-    GDIOBJ_vDereferenceObject(pobj);
+    /* Calculate the index */
+    ulIndex = GDI_HANDLE_GET_INDEX(pobj->hHmgr);
+
+    /* Decrement reference count */
+    ASSERT((gpaulRefCount[ulIndex] & REF_MASK_COUNT) > 0);
+    cRefs = InterlockedDecrement((LONG*)&gpaulRefCount[ulIndex]);
+    ASSERT(cRefs & REF_MASK_VALID);
 }
 
 HGDIOBJ
@@ -770,6 +776,7 @@ GDIOBJ_vSetObjectOwner(
 
     /* Set new owner */
     pentry->ObjectOwner.ulObj = ulOwner;
+    DBG_LOGEVENT(&pobj->slhLog, EVENT_SET_OWNER, 0);
 }
 
 /* Locks 2 or 3 objects at a time */
@@ -880,6 +887,7 @@ GDIOBJ_vDeleteObject(POBJ pobj)
             /* Release the pushlock and reenable APCs */
             ExReleasePushLockExclusive(&pobj->pushlock);
             KeLeaveCriticalRegion();
+            DBG_DECREASE_LOCK_COUNT(PsGetCurrentProcessWin32Process(), pobj->hHmgr);
         }
     }
 
@@ -1021,7 +1029,6 @@ GreGetObject(
     if (!pvObj)
     {
         DPRINT("GreGetObject: Could not lock object\n");
-        EngSetLastError(ERROR_INVALID_HANDLE);
         return 0;
     }
 
@@ -1039,15 +1046,9 @@ GreGetObject(
         case GDILoObjType_LO_BITMAP_TYPE:
             iResult = BITMAP_GetObject(pvObj, cbCount, pvBuffer);
             break;
+
         case GDILoObjType_LO_FONT_TYPE:
             iResult = FontGetObject(pvObj, cbCount, pvBuffer);
-#if 0
-            // Fix the LOGFONT structure for the stock fonts
-            if (FIRST_STOCK_HANDLE <= hobj && hobj <= LAST_STOCK_HANDLE)
-            {
-                FixStockFontSizeW(hobj, cbCount, pvBuffer);
-            }
-#endif
             break;
 
         case GDILoObjType_LO_PALETTE_TYPE:
@@ -1097,7 +1098,7 @@ NtGdiExtGetObjectW(
         /* Enter SEH for buffer transfer */
         _SEH2_TRY
         {
-            // Probe the buffer and copy it
+            /* Probe the buffer and copy it */
             ProbeForWrite(lpBuffer, cbCopyCount, sizeof(WORD));
             RtlCopyMemory(lpBuffer, &object, cbCopyCount);
         }