(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
{
/* 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;
NULL,
&liSize,
PAGE_READWRITE,
- SEC_COMMIT,
+ SEC_COMMIT | 0x1,
NULL,
NULL);
if (!NT_SUCCESS(status))
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;
}
{
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)
/* Push entry to the free list */
ENTRY_vPushFreeEntry(&gpentHmgr[ulIndex]);
+
+ /* Free the object */
+ GDIOBJ_vFreeObject(pobj);
}
}
else
/* 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);
+ }
}
}
{
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))
{
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)
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
/* Set new owner */
pentry->ObjectOwner.ulObj = ulOwner;
+ DBG_LOGEVENT(&pobj->slhLog, EVENT_SET_OWNER, 0);
}
/* Locks 2 or 3 objects at a time */
/* Release the pushlock and reenable APCs */
ExReleasePushLockExclusive(&pobj->pushlock);
KeLeaveCriticalRegion();
+ DBG_DECREASE_LOCK_COUNT(PsGetCurrentProcessWin32Process(), pobj->hHmgr);
}
}
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:
/* 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);
}
}
pobj = GDIOBJ_AllocateObject(objt, cjSize, fl);
+ if (!pobj)
+ {
+ return NULL;
+ }
+
if (!GDIOBJ_hInsertObject(pobj, GDI_OBJ_HMGR_POWNED))
{
GDIOBJ_vFreeObject(pobj);
DWORD dwProcessId;
PPROCESSINFO ppi;
- DPRINT("CleanupForProcess prochandle %x Pid %d\n",
+ DPRINT("CleanupForProcess prochandle %p Pid %p\n",
Process, Process->UniqueProcessId);
ASSERT(Process == PsGetCurrentProcess());
#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);
return TRUE;
}
+
/* EOF */