[WIN32K]
[reactos.git] / reactos / win32ss / gdi / ntgdi / gdiobj.c
index d5b1d20..f3365cb 100644 (file)
@@ -51,8 +51,7 @@
            (objt) == GDIObjType_BRUSH_TYPE)
 #define ASSERT_EXCLUSIVE_OBJECT_TYPE(objt) \
     ASSERT((objt) == GDIObjType_DC_TYPE || \
-           (objt) == GDIObjType_RGN_TYPE || \
-           (objt) == GDIObjType_LFONT_TYPE)
+           (objt) == GDIObjType_RGN_TYPE)
 #else
 #define DBG_INCREASE_LOCK_COUNT(ppi, hobj)
 #define DBG_DECREASE_LOCK_COUNT(x, y)
 #define ASSERT_EXCLUSIVE_OBJECT_TYPE(objt)
 #endif
 
-#define MmMapViewInSessionSpace MmMapViewInSystemSpace
-
 #if defined(_M_IX86) || defined(_M_AMD64)
 #define InterlockedOr16 _InterlockedOr16
 #endif
 
-#define GDIOBJ_POOL_TAG(type) ('00hG' + ((objt & 0x1f) << 24))
+#define GDIOBJ_POOL_TAG(type) ('00hG' + (((type) & 0x1f) << 24))
 
 enum
 {
@@ -81,8 +78,8 @@ enum
 
 /* Per session handle table globals */
 static PVOID gpvGdiHdlTblSection = NULL;
-static PENTRY gpentHmgr;
-static PULONG gpaulRefCount;
+PENTRY gpentHmgr;
+PULONG gpaulRefCount;
 ULONG gulFirstFree;
 ULONG gulFirstUnused;
 static PPAGED_LOOKASIDE_LIST gpaLookasideList;
@@ -166,7 +163,7 @@ InitGdiHandleTable(void)
                              NULL,
                              &liSize,
                              PAGE_READWRITE,
-                             SEC_COMMIT,
+                             SEC_COMMIT | 0x1,
                              NULL,
                              NULL);
     if (!NT_SUCCESS(status))
@@ -361,7 +358,7 @@ ENTRY_ReferenceEntryByHandle(HGDIOBJ hobj, FLONG fl)
         if (pentry->FullUnique != (USHORT)((ULONG_PTR)hobj >> 16))
         {
             DPRINT("GDIOBJ: Wrong unique value. Handle: 0x%4x, entry: 0x%4x\n",
-                   (USHORT)((ULONG_PTR)hobj >> 16, pentry->FullUnique));
+                   (USHORT)((ULONG_PTR)hobj >> 16), pentry->FullUnique);
             return NULL;
         }
 
@@ -476,19 +473,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 +502,9 @@ GDIOBJ_vDereferenceObject(POBJ pobj)
 
             /* Push entry to the free list */
             ENTRY_vPushFreeEntry(&gpentHmgr[ulIndex]);
+
+            /* Free the object */
+            GDIOBJ_vFreeObject(pobj);
         }
     }
     else
@@ -508,18 +512,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);
+        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);
-
-        /* Free the object */
-        GDIOBJ_vFreeObject(pobj);
+        /* Check if we reached 0 */
+        if (cRefs == 0)
+        {
+            /* Free the object */
+            GDIOBJ_vFreeObject(pobj);
+        }
     }
 }
 
@@ -572,9 +572,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 +644,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 +663,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 +773,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 +884,7 @@ GDIOBJ_vDeleteObject(POBJ pobj)
             /* Release the pushlock and reenable APCs */
             ExReleasePushLockExclusive(&pobj->pushlock);
             KeLeaveCriticalRegion();
+            DBG_DECREASE_LOCK_COUNT(PsGetCurrentProcessWin32Process(), pobj->hHmgr);
         }
     }
 
@@ -1038,15 +1043,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:
@@ -1096,7 +1095,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);
         }
@@ -1238,6 +1237,11 @@ GDIOBJ_AllocObjWithHandle(ULONG ObjectType, ULONG cjSize)
     }
 
     pobj = GDIOBJ_AllocateObject(objt, cjSize, fl);
+    if (!pobj)
+    {
+        return NULL;
+    }
+
     if (!GDIOBJ_hInsertObject(pobj, GDI_OBJ_HMGR_POWNED))
     {
         GDIOBJ_vFreeObject(pobj);
@@ -1284,7 +1288,7 @@ GDI_CleanupForProcess(struct _EPROCESS *Process)
     DWORD dwProcessId;
     PPROCESSINFO ppi;
 
-    DPRINT("CleanupForProcess prochandle %x Pid %d\n",
+    DPRINT("CleanupForProcess prochandle %p Pid %p\n",
            Process, Process->UniqueProcessId);
 
     ASSERT(Process == PsGetCurrentProcess());
@@ -1315,7 +1319,7 @@ GDI_CleanupForProcess(struct _EPROCESS *Process)
 #endif
 
     ppi = PsGetCurrentProcessWin32Process();
-    DPRINT("Completed cleanup for process %d\n", Process->UniqueProcessId);
+    DPRINT("Completed cleanup for process %p\n", Process->UniqueProcessId);
     if (ppi->GDIHandleCount != 0)
     {
         DPRINT1("Leaking %d handles!\n", ppi->GDIHandleCount);
@@ -1341,4 +1345,5 @@ GDI_CleanupForProcess(struct _EPROCESS *Process)
     return TRUE;
 }
 
+
 /* EOF */