Start source tree (final, I hope!) restructuration. Part 1/X
[reactos.git] / reactos / win32ss / gdi / ntgdi / gdiobj.c
diff --git a/reactos/win32ss/gdi/ntgdi/gdiobj.c b/reactos/win32ss/gdi/ntgdi/gdiobj.c
deleted file mode 100644 (file)
index 4ea9f72..0000000
+++ /dev/null
@@ -1,1538 +0,0 @@
-/*
- * PROJECT:         ReactOS win32 kernel mode subsystem
- * LICENSE:         GPL - See COPYING in the top level directory
- * FILE:            subsystems/win32/win32k/objects/gdiobj.c
- * PURPOSE:         General GDI object manipulation routines
- * PROGRAMMERS:     Timo Kreuzer
- */
-
-/*
- * If you want to understand this code, you need to start thinking in portals.
- * - gpaulRefCount is a global pointer to an allocated array of ULONG values,
- * one for each handle. Bits 0 - 22 contain a reference count for the handle.
- * It gets increased for each handle lock / reference. Bit 23 contains a valid
- * bit. If this bit is 0, the handle got deleted and will be pushed to the free
- * list, once all references are gone. Bits 24 - 31 contain the reuse value of
- * the handle, which allows to check if the entry was changed before atomically
- * exchanging the reference count.
- * - Objects can exist with or without a handle
- *   - Objects with a handle can be locked either exclusively or shared.
- *     Both locks increase the handle reference count in gpaulRefCount.
- *     Exclusive locks also increase the BASEOBJECT's cExclusiveLock field
- *     and the first lock (can be acquired recursively) acquires a pushlock
- *     that is also stored in the BASEOBJECT.
- *   - Objects without a handle cannot have exclusive locks. Their reference
- *     count is tracked in the BASEOBJECT's ulShareCount field.
- * - An object that is inserted in the handle table automatically has an
- *   exclusive lock. For objects that are "shared objects" (BRUSH, PALETTE, ...)
- *   this is the only way it can ever be exclusively locked. It prevents the
- *   object from being locked by another thread. A shared lock will simply fail,
- *   while an exclusive lock will succeed after the object was unlocked.
- *
- */
-
-/* INCLUDES ******************************************************************/
-
-#include <win32k.h>
-#define NDEBUG
-#include <debug.h>
-
-
-FORCEINLINE
-void
-INCREASE_THREAD_LOCK_COUNT(
-    _In_ HANDLE hobj)
-{
-    PTHREADINFO pti = PsGetCurrentThreadWin32Thread();
-    DBG_UNREFERENCED_PARAMETER(hobj);
-    if (pti)
-    {
-#if DBG
-        pti->acExclusiveLockCount[((ULONG_PTR)hobj >> 16) & 0x1f]++;
-#endif
-        pti->cExclusiveLocks++;
-    }
-}
-
-FORCEINLINE
-void
-DECREASE_THREAD_LOCK_COUNT(
-    _In_ HANDLE hobj)
-{
-    PTHREADINFO pti = PsGetCurrentThreadWin32Thread();
-    DBG_UNREFERENCED_PARAMETER(hobj);
-    if (pti)
-    {
-#if DBG
-        pti->acExclusiveLockCount[((ULONG_PTR)hobj >> 16) & 0x1f]--;
-#endif
-        pti->cExclusiveLocks--;
-    }
-}
-
-#if DBG
-VOID
-ASSERT_LOCK_ORDER(
-    _In_ UCHAR objt)
-{
-    PTHREADINFO pti = PsGetCurrentThreadWin32Thread();
-    ULONG i;
-
-    if (pti)
-    {
-        /* Ensure correct locking order! */
-        for (i = objt + 1; i < GDIObjTypeTotal; i++)
-        {
-            NT_ASSERT(pti->acExclusiveLockCount[i] == 0);
-        }
-    }
-}
-#define ASSERT_SHARED_OBJECT_TYPE(objt) \
-    ASSERT((objt) == GDIObjType_SURF_TYPE || \
-           (objt) == GDIObjType_PAL_TYPE || \
-           (objt) == GDIObjType_LFONT_TYPE || \
-           (objt) == GDIObjType_PATH_TYPE || \
-           (objt) == GDIObjType_BRUSH_TYPE)
-#define ASSERT_EXCLUSIVE_OBJECT_TYPE(objt) \
-    ASSERT((objt) == GDIObjType_DC_TYPE || \
-           (objt) == GDIObjType_RGN_TYPE)
-#define ASSERT_TRYLOCK_OBJECT_TYPE(objt) \
-    ASSERT((objt) == GDIObjType_DRVOBJ_TYPE)
-#else
-#define ASSERT_LOCK_ORDER(hobj)
-#define ASSERT_SHARED_OBJECT_TYPE(objt)
-#define ASSERT_EXCLUSIVE_OBJECT_TYPE(objt)
-#define ASSERT_TRYLOCK_OBJECT_TYPE(objt)
-#endif
-
-#if defined(_M_IX86) || defined(_M_AMD64)
-#define InterlockedOr16 _InterlockedOr16
-#endif
-
-#define GDIOBJ_POOL_TAG(type) ('00hG' + (((type) & 0x1f) << 24))
-
-enum
-{
-    REF_MASK_REUSE = 0xff000000,
-    REF_INC_REUSE  = 0x01000000,
-    REF_MASK_VALID = 0x00800000,
-    REF_MASK_COUNT = 0x007fffff,
-    REF_MASK_INUSE = 0x00ffffff,
-};
-
-/* GLOBALS *******************************************************************/
-
-/* Per session handle table globals */
-static PVOID gpvGdiHdlTblSection = NULL;
-PENTRY gpentHmgr;
-PULONG gpaulRefCount;
-ULONG gulFirstFree;
-ULONG gulFirstUnused;
-static PPAGED_LOOKASIDE_LIST gpaLookasideList;
-
-static VOID NTAPI GDIOBJ_vCleanup(PVOID ObjectBody);
-
-static const
-GDICLEANUPPROC
-apfnCleanup[] =
-{
-    NULL,              /* 00 GDIObjType_DEF_TYPE */
-    DC_vCleanup,       /* 01 GDIObjType_DC_TYPE */
-    NULL,              /* 02 GDIObjType_UNUSED1_TYPE */
-    NULL,              /* 03 GDIObjType_UNUSED2_TYPE */
-    REGION_vCleanup,   /* 04 GDIObjType_RGN_TYPE */
-    SURFACE_vCleanup,  /* 05 GDIObjType_SURF_TYPE */
-    GDIOBJ_vCleanup,   /* 06 GDIObjType_CLIENTOBJ_TYPE */
-    GDIOBJ_vCleanup,   /* 07 GDIObjType_PATH_TYPE */
-    PALETTE_vCleanup,  /* 08 GDIObjType_PAL_TYPE */
-    GDIOBJ_vCleanup,   /* 09 GDIObjType_ICMLCS_TYPE */
-    GDIOBJ_vCleanup,   /* 0a GDIObjType_LFONT_TYPE */
-    NULL,              /* 0b GDIObjType_RFONT_TYPE, unused */
-    NULL,              /* 0c GDIObjType_PFE_TYPE, unused */
-    NULL,              /* 0d GDIObjType_PFT_TYPE, unused */
-    GDIOBJ_vCleanup,   /* 0e GDIObjType_ICMCXF_TYPE */
-    NULL,              /* 0f GDIObjType_SPRITE_TYPE, unused */
-    BRUSH_vCleanup,    /* 10 GDIObjType_BRUSH_TYPE, BRUSH, PEN, EXTPEN */
-    NULL,              /* 11 GDIObjType_UMPD_TYPE, unused */
-    NULL,              /* 12 GDIObjType_UNUSED4_TYPE */
-    NULL,              /* 13 GDIObjType_SPACE_TYPE, unused */
-    NULL,              /* 14 GDIObjType_UNUSED5_TYPE */
-    NULL,              /* 15 GDIObjType_META_TYPE, unused */
-    NULL,              /* 16 GDIObjType_EFSTATE_TYPE, unused */
-    NULL,              /* 17 GDIObjType_BMFD_TYPE, unused */
-    NULL,              /* 18 GDIObjType_VTFD_TYPE, unused */
-    NULL,              /* 19 GDIObjType_TTFD_TYPE, unused */
-    NULL,              /* 1a GDIObjType_RC_TYPE, unused */
-    NULL,              /* 1b GDIObjType_TEMP_TYPE, unused */
-    DRIVEROBJ_vCleanup,/* 1c GDIObjType_DRVOBJ_TYPE */
-    NULL,              /* 1d GDIObjType_DCIOBJ_TYPE, unused */
-    NULL,              /* 1e GDIObjType_SPOOL_TYPE, unused */
-    NULL,              /* 1f reserved entry */
-};
-
-/* INTERNAL FUNCTIONS ********************************************************/
-
-static
-VOID
-NTAPI
-GDIOBJ_vCleanup(PVOID ObjectBody)
-{
-    /* Nothing to do */
-}
-
-static
-VOID
-InitLookasideList(UCHAR objt, ULONG cjSize)
-{
-    ExInitializePagedLookasideList(&gpaLookasideList[objt],
-                                   NULL,
-                                   NULL,
-                                   0,
-                                   cjSize,
-                                   GDITAG_HMGR_LOOKASIDE_START + (objt << 24),
-                                   0);
-}
-
-INIT_FUNCTION
-NTSTATUS
-NTAPI
-InitGdiHandleTable(void)
-{
-    NTSTATUS status;
-    LARGE_INTEGER liSize;
-    PVOID pvSection;
-    SIZE_T cjViewSize = 0;
-
-    /* Create a section for the shared handle table */
-    liSize.QuadPart = sizeof(GDI_HANDLE_TABLE); // GDI_HANDLE_COUNT * sizeof(ENTRY);
-    status = MmCreateSection(&gpvGdiHdlTblSection,
-                             SECTION_ALL_ACCESS,
-                             NULL,
-                             &liSize,
-                             PAGE_READWRITE,
-                             SEC_COMMIT | 0x1,
-                             NULL,
-                             NULL);
-    if (!NT_SUCCESS(status))
-    {
-        DPRINT1("INITGDI: Could not allocate a GDI handle table.\n");
-        return status;
-    }
-
-    /* Map the section in session space */
-    status = MmMapViewInSessionSpace(gpvGdiHdlTblSection,
-                                     (PVOID*)&gpentHmgr,
-                                     &cjViewSize);
-    if (!NT_SUCCESS(status))
-    {
-        DPRINT1("INITGDI: Failed to map handle table section\n");
-        ObDereferenceObject(gpvGdiHdlTblSection);
-        return status;
-    }
-
-    /* Allocate memory for the reference counter table */
-    gpaulRefCount = EngAllocSectionMem(&pvSection,
-                                     FL_ZERO_MEMORY,
-                                     GDI_HANDLE_COUNT * sizeof(ULONG),
-                                     'frHG');
-    if (!gpaulRefCount)
-    {
-        DPRINT1("INITGDI: Failed to allocate reference table.\n");
-        ObDereferenceObject(gpvGdiHdlTblSection);
-        return STATUS_INSUFFICIENT_RESOURCES;
-    }
-
-    gulFirstFree = 0;
-    gulFirstUnused = RESERVE_ENTRIES_COUNT;
-
-    GdiHandleTable = (PVOID)gpentHmgr;
-
-    /* Initialize the lookaside lists */
-    gpaLookasideList = ExAllocatePoolWithTag(NonPagedPool,
-                           GDIObjTypeTotal * sizeof(PAGED_LOOKASIDE_LIST),
-                           TAG_GDIHNDTBLE);
-    if(!gpaLookasideList)
-        return STATUS_NO_MEMORY;
-
-    InitLookasideList(GDIObjType_DC_TYPE, sizeof(DC));
-    InitLookasideList(GDIObjType_RGN_TYPE, sizeof(REGION));
-    InitLookasideList(GDIObjType_SURF_TYPE, sizeof(SURFACE));
-    InitLookasideList(GDIObjType_CLIENTOBJ_TYPE, sizeof(CLIENTOBJ));
-    InitLookasideList(GDIObjType_PATH_TYPE, sizeof(PATH));
-    InitLookasideList(GDIObjType_PAL_TYPE, sizeof(PALETTE));
-    InitLookasideList(GDIObjType_ICMLCS_TYPE, sizeof(COLORSPACE));
-    InitLookasideList(GDIObjType_LFONT_TYPE, sizeof(TEXTOBJ));
-    InitLookasideList(GDIObjType_BRUSH_TYPE, sizeof(BRUSH));
-
-    return STATUS_SUCCESS;
-}
-
-FORCEINLINE
-VOID
-IncrementCurrentProcessGdiHandleCount(void)
-{
-    PPROCESSINFO ppi = PsGetCurrentProcessWin32Process();
-    if (ppi) InterlockedIncrement((LONG*)&ppi->GDIHandleCount);
-}
-
-FORCEINLINE
-VOID
-DecrementCurrentProcessGdiHandleCount(void)
-{
-    PPROCESSINFO ppi = PsGetCurrentProcessWin32Process();
-    if (ppi) InterlockedDecrement((LONG*)&ppi->GDIHandleCount);
-}
-
-FORCEINLINE
-VOID
-IncrementGdiHandleCount(ULONG ulProcessId)
-{
-    PEPROCESS pep;
-    PPROCESSINFO ppi;
-    NTSTATUS Status;
-
-    Status = PsLookupProcessByProcessId(ULongToHandle(ulProcessId), &pep);
-    NT_ASSERT(NT_SUCCESS(Status));
-
-    ppi = PsGetProcessWin32Process(pep);
-    if (ppi) InterlockedIncrement((LONG*)&ppi->GDIHandleCount);
-    if (NT_SUCCESS(Status)) ObDereferenceObject(pep);
-}
-
-FORCEINLINE
-VOID
-DecrementGdiHandleCount(ULONG ulProcessId)
-{
-    PEPROCESS pep;
-    PPROCESSINFO ppi;
-    NTSTATUS Status;
-
-    Status = PsLookupProcessByProcessId(ULongToHandle(ulProcessId), &pep);
-    NT_ASSERT(NT_SUCCESS(Status));
-
-    ppi = PsGetProcessWin32Process(pep);
-    if (ppi) InterlockedDecrement((LONG*)&ppi->GDIHandleCount);
-    if (NT_SUCCESS(Status)) ObDereferenceObject(pep);
-}
-
-static
-PENTRY
-ENTRY_pentPopFreeEntry(VOID)
-{
-    ULONG iFirst, iNext, iPrev;
-    PENTRY pentFree;
-
-    DPRINT("Enter InterLockedPopFreeEntry\n");
-
-    do
-    {
-        /* Get the index and sequence number of the first free entry */
-        iFirst = gulFirstFree;
-
-        /* Check if we have a free entry */
-        if (!(iFirst & GDI_HANDLE_INDEX_MASK))
-        {
-            /* Increment FirstUnused and get the new index */
-            iFirst = InterlockedIncrement((LONG*)&gulFirstUnused) - 1;
-
-            /* Check if we have unused entries left */
-            if (iFirst >= GDI_HANDLE_COUNT)
-            {
-                DPRINT1("No more GDI handles left!\n");
-#if DBG_ENABLE_GDIOBJ_BACKTRACES
-                DbgDumpGdiHandleTableWithBT();
-#endif
-                InterlockedDecrement((LONG*)&gulFirstUnused);
-                return 0;
-            }
-
-            /* Return the old entry */
-            return &gpentHmgr[iFirst];
-        }
-
-        /* Get a pointer to the first free entry */
-        pentFree = &gpentHmgr[iFirst & GDI_HANDLE_INDEX_MASK];
-
-        /* Create a new value with an increased sequence number */
-        iNext = GDI_HANDLE_GET_INDEX(pentFree->einfo.hFree);
-        iNext |= (iFirst & ~GDI_HANDLE_INDEX_MASK) + 0x10000;
-
-        /* Try to exchange the FirstFree value */
-        iPrev = InterlockedCompareExchange((LONG*)&gulFirstFree,
-                                           iNext,
-                                           iFirst);
-    }
-    while (iPrev != iFirst);
-
-    /* Sanity check: is entry really free? */
-    ASSERT(((ULONG_PTR)pentFree->einfo.pobj & ~GDI_HANDLE_INDEX_MASK) == 0);
-
-    return pentFree;
-}
-
-/* Pushes an entry of the handle table to the free list,
-   The entry must not have any references left */
-static
-VOID
-ENTRY_vPushFreeEntry(PENTRY pentFree)
-{
-    ULONG iToFree, iFirst, iPrev, idxToFree;
-
-    DPRINT("Enter ENTRY_vPushFreeEntry\n");
-
-    idxToFree = pentFree - gpentHmgr;
-    ASSERT((gpaulRefCount[idxToFree] & REF_MASK_INUSE) == 0);
-
-    /* Initialize entry */
-    pentFree->Objt = GDIObjType_DEF_TYPE;
-    pentFree->ObjectOwner.ulObj = 0;
-    pentFree->pUser = NULL;
-
-    /* Increase reuse counter in entry and reference counter */
-    InterlockedExchangeAdd((LONG*)&gpaulRefCount[idxToFree], REF_INC_REUSE);
-    pentFree->FullUnique += 0x0100;
-
-    do
-    {
-        /* Get the current first free index and sequence number */
-        iFirst = gulFirstFree;
-
-        /* Set the einfo.pobj member to the index of the first free entry */
-        pentFree->einfo.pobj = UlongToPtr(iFirst & GDI_HANDLE_INDEX_MASK);
-
-        /* Combine new index and increased sequence number in iToFree */
-        iToFree = idxToFree | ((iFirst & ~GDI_HANDLE_INDEX_MASK) + 0x10000);
-
-        /* Try to atomically update the first free entry */
-        iPrev = InterlockedCompareExchange((LONG*)&gulFirstFree,
-                                           iToFree,
-                                           iFirst);
-    }
-    while (iPrev != iFirst);
-}
-
-static
-PENTRY
-ENTRY_ReferenceEntryByHandle(HGDIOBJ hobj, FLONG fl)
-{
-    ULONG ulIndex, cNewRefs, cOldRefs;
-    PENTRY pentry;
-
-    /* Get the handle index and check if its too big */
-    ulIndex = GDI_HANDLE_GET_INDEX(hobj);
-    if (ulIndex >= GDI_HANDLE_COUNT) return NULL;
-
-    /* Get pointer to the entry */
-    pentry = &gpentHmgr[ulIndex];
-
-    /* Get the current reference count */
-    cOldRefs = gpaulRefCount[ulIndex];
-
-    do
-    {
-        /* Check if the slot is deleted */
-        if ((cOldRefs & REF_MASK_VALID) == 0)
-        {
-            DPRINT("GDIOBJ: Slot is not valid: 0x%lx, hobh=%p\n", cOldRefs, hobj);
-            return NULL;
-        }
-
-        /* Check if the unique value matches */
-        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);
-            return NULL;
-        }
-
-        /* Check if the object owner is this process or public */
-        if (!(fl & GDIOBJFLAG_IGNOREPID) &&
-            pentry->ObjectOwner.ulObj != GDI_OBJ_HMGR_PUBLIC &&
-            pentry->ObjectOwner.ulObj != PtrToUlong(PsGetCurrentProcessId()))
-        {
-            DPRINT("GDIOBJ: Cannot reference foreign handle %p, pentry=%p:%lx.\n",
-                    hobj, pentry, pentry->ObjectOwner.ulObj);
-            return NULL;
-        }
-
-        /* Try to atomically increment the reference count */
-        cNewRefs = cOldRefs + 1;
-        cOldRefs = InterlockedCompareExchange((PLONG)&gpaulRefCount[ulIndex],
-                                              cNewRefs,
-                                              cOldRefs);
-    }
-    while (cNewRefs != cOldRefs + 1);
-
-    /* Integrity checks */
-    ASSERT((pentry->FullUnique & 0x1f) == pentry->Objt);
-    ASSERT(pentry->einfo.pobj && pentry->einfo.pobj->hHmgr == hobj);
-
-    return pentry;
-}
-
-static
-HGDIOBJ
-ENTRY_hInsertObject(PENTRY pentry, POBJ pobj, UCHAR objt, ULONG ulOwner)
-{
-    ULONG ulIndex;
-
-    /* Calculate the handle index */
-    ulIndex = pentry - gpentHmgr;
-
-    /* Update the fields in the ENTRY */
-    pentry->einfo.pobj = pobj;
-    pentry->Objt = objt & 0x1f;
-    pentry->FullUnique = (pentry->FullUnique & 0xff00) | objt;
-    pentry->ObjectOwner.ulObj = ulOwner;
-
-    /* Make the handle valid with 1 reference */
-    ASSERT((gpaulRefCount[ulIndex] & REF_MASK_INUSE) == 0);
-    InterlockedOr((LONG*)&gpaulRefCount[ulIndex], REF_MASK_VALID | 1);
-
-    /* Return the handle */
-    return (HGDIOBJ)(((ULONG_PTR)pentry->FullUnique << 16) | ulIndex);
-}
-
-POBJ
-NTAPI
-GDIOBJ_AllocateObject(UCHAR objt, ULONG cjSize, FLONG fl)
-{
-    POBJ pobj;
-
-    if (fl & BASEFLAG_LOOKASIDE)
-    {
-        /* Allocate the object from a lookaside list */
-        pobj = ExAllocateFromPagedLookasideList(&gpaLookasideList[objt & 0x1f]);
-    }
-    else
-    {
-        /* Allocate the object from paged pool */
-        pobj = ExAllocatePoolWithTag(PagedPool, cjSize, GDIOBJ_POOL_TAG(objt));
-    }
-
-    if (!pobj) return NULL;
-
-    /* Initialize the object */
-    RtlZeroMemory(pobj, cjSize);
-    pobj->hHmgr = (HGDIOBJ)((ULONG_PTR)objt << 16);
-    pobj->cExclusiveLock = 0;
-    pobj->ulShareCount = 1;
-    pobj->BaseFlags = fl & 0xffff;
-    DBG_INITLOG(&pobj->slhLog);
-    DBG_LOGEVENT(&pobj->slhLog, EVENT_ALLOCATE, 0);
-#if DBG_ENABLE_GDIOBJ_BACKTRACES
-    DbgCaptureStackBackTace(pobj->apvBackTrace, 1, GDI_OBJECT_STACK_LEVELS);
-#endif /* GDI_DEBUG */
-
-    return pobj;
-}
-
-VOID
-NTAPI
-GDIOBJ_vFreeObject(POBJ pobj)
-{
-    UCHAR objt;
-
-    DBG_CLEANUP_EVENT_LIST(&pobj->slhLog);
-
-    /* Get the object type */
-    objt = ((ULONG_PTR)pobj->hHmgr >> 16) & 0x1f;
-
-    /* Call the cleanup procedure */
-    ASSERT(apfnCleanup[objt]);
-    apfnCleanup[objt](pobj);
-
-    /* Check if the object is allocated from a lookaside list */
-    if (pobj->BaseFlags & BASEFLAG_LOOKASIDE)
-    {
-        ExFreeToPagedLookasideList(&gpaLookasideList[objt], pobj);
-    }
-    else
-    {
-        ExFreePoolWithTag(pobj, GDIOBJ_POOL_TAG(objt));
-    }
-}
-
-VOID
-NTAPI
-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 (ulIndex)
-    {
-        /* Decrement reference count */
-        if ((gpaulRefCount[ulIndex] & REF_MASK_COUNT) == 0)
-        {
-            DBG_DUMP_EVENT_LIST(&pobj->slhLog);
-        }
-        ASSERT((gpaulRefCount[ulIndex] & REF_MASK_COUNT) > 0);
-        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 & 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)
-            {
-                /* Decrement the process handle count */
-                ASSERT(gpentHmgr[ulIndex].ObjectOwner.ulObj ==
-                       HandleToUlong(PsGetCurrentProcessId()));
-                DecrementCurrentProcessGdiHandleCount();
-            }
-
-            /* 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);
-
-        /* Check if we reached 0 */
-        if (cRefs == 0)
-        {
-            /* Free the object */
-            GDIOBJ_vFreeObject(pobj);
-        }
-    }
-}
-
-POBJ
-NTAPI
-GDIOBJ_ReferenceObjectByHandle(
-    HGDIOBJ hobj,
-    UCHAR objt)
-{
-    PENTRY pentry;
-    POBJ pobj;
-
-    /* Check if the handle type matches */
-    ASSERT_SHARED_OBJECT_TYPE(objt);
-    if ((((ULONG_PTR)hobj >> 16) & 0x1f) != objt)
-    {
-        DPRINT("GDIOBJ: Wrong type. handle=%p, type=%x\n", hobj, objt);
-        return NULL;
-    }
-
-    /* Reference the handle entry */
-    pentry = ENTRY_ReferenceEntryByHandle(hobj, 0);
-    if (!pentry)
-    {
-        DPRINT("GDIOBJ: Requested handle 0x%p is not valid.\n", hobj);
-        return NULL;
-    }
-
-    /* Get the pointer to the BASEOBJECT */
-    pobj = pentry->einfo.pobj;
-
-    /* Check if the object is exclusively locked */
-    if (pobj->cExclusiveLock != 0)
-    {
-        DPRINT1("GDIOBJ: Cannot reference oject %p with exclusive lock.\n", hobj);
-        GDIOBJ_vDereferenceObject(pobj);
-        DBG_DUMP_EVENT_LIST(&pobj->slhLog);
-        return NULL;
-    }
-
-    DBG_LOGEVENT(&pobj->slhLog, EVENT_REFERENCE, gpaulRefCount[pentry - gpentHmgr]);
-
-    /* All is well, return the object */
-    return pobj;
-}
-
-VOID
-NTAPI
-GDIOBJ_vReferenceObjectByPointer(POBJ pobj)
-{
-    ULONG cRefs;
-
-    /* Check if the object has a handle */
-    if (GDI_HANDLE_GET_INDEX(pobj->hHmgr))
-    {
-        /* Increase the handle's reference count */
-        ULONG ulIndex = GDI_HANDLE_GET_INDEX(pobj->hHmgr);
-        ASSERT((gpaulRefCount[ulIndex] & REF_MASK_COUNT) > 0);
-        cRefs = InterlockedIncrement((LONG*)&gpaulRefCount[ulIndex]);
-    }
-    else
-    {
-        /* Increase the object's reference count */
-        cRefs = InterlockedIncrement((LONG*)&pobj->ulShareCount);
-    }
-
-    DBG_LOGEVENT(&pobj->slhLog, EVENT_REFERENCE, cRefs);
-}
-
-PGDIOBJ
-NTAPI
-GDIOBJ_TryLockObject(
-    HGDIOBJ hobj,
-    UCHAR objt)
-{
-    PENTRY pentry;
-    POBJ pobj;
-    DWORD dwThreadId;
-
-    /* Check if the handle type matches */
-    ASSERT_TRYLOCK_OBJECT_TYPE(objt);
-    if ((((ULONG_PTR)hobj >> 16) & 0x1f) != objt)
-    {
-        DPRINT("Wrong object type: hobj=0x%p, objt=0x%x\n", hobj, objt);
-        return NULL;
-    }
-
-    /* Make sure lock order is correct */
-    ASSERT_LOCK_ORDER(objt);
-
-    /* Reference the handle entry */
-    pentry = ENTRY_ReferenceEntryByHandle(hobj, 0);
-    if (!pentry)
-    {
-        DPRINT("GDIOBJ: Requested handle 0x%p is not valid.\n", hobj);
-        return NULL;
-    }
-
-    /* Get the pointer to the BASEOBJECT */
-    pobj = pentry->einfo.pobj;
-
-    /* Check if we already own the lock */
-    dwThreadId = PtrToUlong(PsGetCurrentThreadId());
-    if (pobj->dwThreadId != dwThreadId)
-    {
-        /* Disable APCs and try acquiring the push lock */
-        KeEnterCriticalRegion();
-        if(!ExTryAcquirePushLockExclusive(&pobj->pushlock))
-        {
-            ULONG cRefs, ulIndex;
-            /* Already owned. Clean up and leave. */
-            KeLeaveCriticalRegion();
-
-            /* 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);
-
-            return NULL;
-        }
-
-        /* Set us as lock owner */
-        ASSERT(pobj->dwThreadId == 0);
-        pobj->dwThreadId = dwThreadId;
-    }
-
-    /* Increase lock count */
-    pobj->cExclusiveLock++;
-    INCREASE_THREAD_LOCK_COUNT(hobj);
-    DBG_LOGEVENT(&pobj->slhLog, EVENT_LOCK, 0);
-
-    /* Return the object */
-    return pobj;
-}
-
-PGDIOBJ
-NTAPI
-GDIOBJ_LockObject(
-    HGDIOBJ hobj,
-    UCHAR objt)
-{
-    PENTRY pentry;
-    POBJ pobj;
-    DWORD dwThreadId;
-
-    /* Check if the handle type matches */
-    ASSERT_EXCLUSIVE_OBJECT_TYPE(objt);
-    if ((((ULONG_PTR)hobj >> 16) & 0x1f) != objt)
-    {
-        DPRINT("Wrong object type: hobj=0x%p, objt=0x%x\n", hobj, objt);
-        return NULL;
-    }
-
-    /* Make sure lock order is correct */
-    ASSERT_LOCK_ORDER(objt);
-
-    /* Reference the handle entry */
-    pentry = ENTRY_ReferenceEntryByHandle(hobj, 0);
-    if (!pentry)
-    {
-        DPRINT("GDIOBJ: Requested handle 0x%p is not valid.\n", hobj);
-        return NULL;
-    }
-
-    /* Get the pointer to the BASEOBJECT */
-    pobj = pentry->einfo.pobj;
-
-    /* Check if we already own the lock */
-    dwThreadId = PtrToUlong(PsGetCurrentThreadId());
-    if (pobj->dwThreadId != dwThreadId)
-    {
-        /* Disable APCs and acquire the push lock */
-        KeEnterCriticalRegion();
-        ExAcquirePushLockExclusive(&pobj->pushlock);
-
-        /* Set us as lock owner */
-        ASSERT(pobj->dwThreadId == 0);
-        pobj->dwThreadId = dwThreadId;
-    }
-
-    /* Increase lock count */
-    pobj->cExclusiveLock++;
-    INCREASE_THREAD_LOCK_COUNT(hobj);
-    DBG_LOGEVENT(&pobj->slhLog, EVENT_LOCK, 0);
-
-    /* Return the object */
-    return pobj;
-}
-
-VOID
-NTAPI
-GDIOBJ_vUnlockObject(POBJ pobj)
-{
-    ULONG cRefs, ulIndex;
-    ASSERT(pobj->cExclusiveLock > 0);
-
-    /* Decrease lock count */
-    pobj->cExclusiveLock--;
-    DECREASE_THREAD_LOCK_COUNT(pobj->hHmgr);
-    DBG_LOGEVENT(&pobj->slhLog, EVENT_UNLOCK, 0);
-
-    /* Check if this was the last lock */
-    if (pobj->cExclusiveLock == 0)
-    {
-        /* Reset lock owner */
-        pobj->dwThreadId = 0;
-
-        /* Release the pushlock and reenable APCs */
-        ExReleasePushLockExclusive(&pobj->pushlock);
-        KeLeaveCriticalRegion();
-    }
-
-    /* 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
-NTAPI
-GDIOBJ_hInsertObject(
-    POBJ pobj,
-    ULONG ulOwner)
-{
-    PENTRY pentry;
-    UCHAR objt;
-
-    /* Must have no handle and only one reference */
-    ASSERT(GDI_HANDLE_GET_INDEX(pobj->hHmgr) == 0);
-    ASSERT(pobj->cExclusiveLock == 0);
-    ASSERT(pobj->ulShareCount == 1);
-
-    /* Get a free handle entry */
-    pentry = ENTRY_pentPopFreeEntry();
-    if (!pentry)
-    {
-        DPRINT1("GDIOBJ: Could not get a free entry.\n");
-        return NULL;
-    }
-
-    /* Make the object exclusively locked */
-    ExInitializePushLock(&pobj->pushlock);
-    KeEnterCriticalRegion();
-    ExAcquirePushLockExclusive(&pobj->pushlock);
-    pobj->cExclusiveLock = 1;
-    pobj->dwThreadId = PtrToUlong(PsGetCurrentThreadId());
-    INCREASE_THREAD_LOCK_COUNT(pobj->hHmgr);
-
-    /* Get object type from the hHmgr field */
-    objt = ((ULONG_PTR)pobj->hHmgr >> 16) & 0xff;
-    ASSERT(objt != GDIObjType_DEF_TYPE);
-
-    /* Check if current process is requested owner */
-    if (ulOwner == GDI_OBJ_HMGR_POWNED)
-    {
-        /* Increment the process handle count */
-        IncrementCurrentProcessGdiHandleCount();
-
-        /* Use Process id */
-        ulOwner = HandleToUlong(PsGetCurrentProcessId());
-    }
-
-    /* Insert the object into the handle table */
-    pobj->hHmgr = ENTRY_hInsertObject(pentry, pobj, objt, ulOwner);
-
-    /* Return the handle */
-    DPRINT("GDIOBJ: Created handle: %p\n", pobj->hHmgr);
-    DBG_LOGEVENT(&pobj->slhLog, EVENT_CREATE_HANDLE, 0);
-    return pobj->hHmgr;
-}
-
-VOID
-NTAPI
-GDIOBJ_vSetObjectOwner(
-    POBJ pobj,
-    ULONG ulNewOwner)
-{
-    PENTRY pentry;
-    ULONG ulOldOwner;
-
-    /* This is a ugly HACK, needed to fix IntGdiSetDCOwnerEx */
-    if (GDI_HANDLE_IS_STOCKOBJ(pobj->hHmgr))
-    {
-        DPRINT("Trying to set ownership of stock object %p to %lx\n", pobj->hHmgr, ulNewOwner);
-        return;
-    }
-
-    /* Get the handle entry */
-    NT_ASSERT(GDI_HANDLE_GET_INDEX(pobj->hHmgr));
-    pentry = &gpentHmgr[GDI_HANDLE_GET_INDEX(pobj->hHmgr)];
-
-    /* Check if the new owner is the same as the old one */
-    ulOldOwner = pentry->ObjectOwner.ulObj;
-    if (ulOldOwner == ulNewOwner)
-    {
-        /* Nothing to do */
-        return;
-    }
-
-    /* Is the current process requested? */
-    if (ulNewOwner == GDI_OBJ_HMGR_POWNED)
-    {
-        /* Use process id */
-        ulNewOwner = HandleToUlong(PsGetCurrentProcessId());
-    }
-
-    // HACK
-    if (ulNewOwner == GDI_OBJ_HMGR_NONE)
-        ulNewOwner = GDI_OBJ_HMGR_PUBLIC;
-
-    /* Was the object process owned? */
-    if ((ulOldOwner != GDI_OBJ_HMGR_PUBLIC) &&
-        (ulOldOwner != GDI_OBJ_HMGR_NONE))
-    {
-        /* Decrement the previous owners handle count */
-        DecrementGdiHandleCount(ulOldOwner);
-    }
-
-    /* Is the new owner a process? */
-    if ((ulNewOwner != GDI_OBJ_HMGR_PUBLIC) &&
-        (ulNewOwner != GDI_OBJ_HMGR_NONE))
-    {
-        /* Increment the new owners handle count */
-        IncrementGdiHandleCount(ulNewOwner);
-    }
-    else
-    {
-        /* Make sure we don't leak user mode memory */
-        NT_ASSERT(pentry->pUser == NULL);
-    }
-
-    /* Set new owner */
-    pentry->ObjectOwner.ulObj = ulNewOwner;
-    DBG_LOGEVENT(&pobj->slhLog, EVENT_SET_OWNER, 0);
-}
-
-/* Locks 2 or 3 objects at a time */
-BOOL
-NTAPI
-GDIOBJ_bLockMultipleObjects(
-    IN ULONG ulCount,
-    IN HGDIOBJ* ahObj,
-    OUT PGDIOBJ* apObj,
-    IN UCHAR objt)
-{
-    UINT auiIndices[3] = {0, 1, 2};
-    UINT i, j, tmp;
-
-    ASSERT(ulCount <= 3);
-
-    /* Sort the handles */
-    for (i = 0; i < ulCount - 1; i++)
-    {
-        for (j = i + 1; j < ulCount; j++)
-        {
-            if ((ULONG_PTR)ahObj[auiIndices[i]] <
-                (ULONG_PTR)ahObj[auiIndices[j]])
-            {
-                tmp = auiIndices[i];
-                auiIndices[i] = auiIndices[j];
-                auiIndices[j] = tmp;
-            }
-        }
-    }
-
-    /* Lock the objects in safe order */
-    for (i = 0; i < ulCount; i++)
-    {
-        /* Skip NULL handles */
-        if (ahObj[auiIndices[i]] == NULL)
-        {
-            apObj[auiIndices[i]] = NULL;
-            continue;
-        }
-
-        /* Lock the object */
-        apObj[auiIndices[i]] = GDIOBJ_LockObject(ahObj[auiIndices[i]], objt);
-
-        /* Check for failure */
-        if (apObj[auiIndices[i]] == NULL)
-        {
-            /* Cleanup */
-            while (i--)
-            {
-                if (apObj[auiIndices[i]])
-                    GDIOBJ_vUnlockObject(apObj[auiIndices[i]]);
-            }
-            return FALSE;
-        }
-    }
-
-    return TRUE;
-}
-
-PVOID
-NTAPI
-GDIOBJ_pvGetObjectAttr(POBJ pobj)
-{
-    ULONG ulIndex = GDI_HANDLE_GET_INDEX(pobj->hHmgr);
-    return gpentHmgr[ulIndex].pUser;
-}
-
-VOID
-NTAPI
-GDIOBJ_vSetObjectAttr(POBJ pobj, PVOID pvObjAttr)
-{
-    ULONG ulIndex;
-
-    ASSERT(pobj->hHmgr);
-
-    /* Get the handle index */
-    ulIndex = GDI_HANDLE_GET_INDEX(pobj->hHmgr);
-
-    /* Set pointer to the usermode attribute */
-    gpentHmgr[ulIndex].pUser = pvObjAttr;
-}
-
-VOID
-NTAPI
-GDIOBJ_vDeleteObject(POBJ pobj)
-{
-    ULONG ulIndex;
-
-    /* Set the object's delete flag */
-    InterlockedOr16((SHORT*)&pobj->BaseFlags, BASEFLAG_READY_TO_DIE);
-    DBG_LOGEVENT(&pobj->slhLog, EVENT_DELETE, 0);
-
-    /* Get the handle index */
-    ulIndex = GDI_HANDLE_GET_INDEX(pobj->hHmgr);
-    if (ulIndex)
-    {
-        /* Reset the handle valid bit */
-        InterlockedAnd((LONG*)&gpaulRefCount[ulIndex], ~REF_MASK_VALID);
-
-        /* Check if the object is exclusively locked */
-        if (pobj->cExclusiveLock != 0)
-        {
-            /* Reset lock owner and lock count */
-            pobj->dwThreadId = 0;
-            pobj->cExclusiveLock = 0;
-
-            /* Release the pushlock and reenable APCs */
-            ExReleasePushLockExclusive(&pobj->pushlock);
-            KeLeaveCriticalRegion();
-            DECREASE_THREAD_LOCK_COUNT(pobj->hHmgr);
-        }
-    }
-
-    /* Dereference the object (will take care of deletion) */
-    GDIOBJ_vDereferenceObject(pobj);
-}
-
-BOOL
-NTAPI
-GreIsHandleValid(HGDIOBJ hobj)
-{
-    PENTRY pentry;
-
-    pentry = ENTRY_ReferenceEntryByHandle(hobj, 0);
-    if (!pentry) return FALSE;
-    GDIOBJ_vDereferenceObject(pentry->einfo.pobj);
-    return TRUE;
-}
-
-BOOL
-NTAPI
-GreDeleteObject(HGDIOBJ hobj)
-{
-    PENTRY pentry;
-
-    /* Check for stock objects */
-    if (GDI_HANDLE_IS_STOCKOBJ(hobj))
-    {
-        DPRINT1("GreDeleteObject: Cannot delete stock object %p.\n", hobj);
-        return FALSE;
-    }
-
-    /* Reference the handle entry */
-    pentry = ENTRY_ReferenceEntryByHandle(hobj, 0);
-    if (!pentry)
-    {
-        DPRINT1("GreDeleteObject: Trying to delete invalid object %p\n", hobj);
-        return FALSE;
-    }
-
-    /* Check for public owner */
-    if (pentry->ObjectOwner.ulObj == GDI_OBJ_HMGR_PUBLIC)
-    {
-        DPRINT1("GreDeleteObject: Trying to delete global object %p\n", hobj);
-        GDIOBJ_vDereferenceObject(pentry->einfo.pobj);
-        return FALSE;
-    }
-
-    /* Delete the object */
-    GDIOBJ_vDeleteObject(pentry->einfo.pobj);
-    return TRUE;
-}
-
-ULONG
-NTAPI
-GreGetObjectOwner(HGDIOBJ hobj)
-{
-    ULONG ulIndex, ulOwner;
-
-    /* Get the handle index */
-    ulIndex = GDI_HANDLE_GET_INDEX(hobj);
-
-    /* Check if the handle is valid */
-    if (ulIndex >= GDI_HANDLE_COUNT ||
-        gpentHmgr[ulIndex].Objt == GDIObjType_DEF_TYPE ||
-        ((ULONG_PTR)hobj >> 16) != gpentHmgr[ulIndex].FullUnique)
-    {
-        DPRINT1("GreGetObjectOwner: invalid handle 0x%p.\n", hobj);
-        return GDI_OBJ_HMGR_RESTRICTED;
-    }
-
-    /* Get the object owner */
-    ulOwner = gpentHmgr[ulIndex].ObjectOwner.ulObj;
-
-    if (ulOwner == HandleToUlong(PsGetCurrentProcessId()))
-        return GDI_OBJ_HMGR_POWNED;
-
-    if (ulOwner == GDI_OBJ_HMGR_PUBLIC)
-        return GDI_OBJ_HMGR_PUBLIC;
-
-    return GDI_OBJ_HMGR_RESTRICTED;
-}
-
-BOOL
-NTAPI
-GreSetObjectOwnerEx(
-    HGDIOBJ hobj,
-    ULONG ulOwner,
-    ULONG Flags)
-{
-    PENTRY pentry;
-
-    /* Check for stock objects */
-    if (GDI_HANDLE_IS_STOCKOBJ(hobj))
-    {
-        DPRINT("GreSetObjectOwner: Got stock object %p\n", hobj);
-        return FALSE;
-    }
-
-    /* Reference the handle entry */
-    pentry = ENTRY_ReferenceEntryByHandle(hobj, Flags);
-    if (!pentry)
-    {
-        DPRINT("GreSetObjectOwner: Invalid handle 0x%p.\n", hobj);
-        return FALSE;
-    }
-
-    /* Call internal function */
-    GDIOBJ_vSetObjectOwner(pentry->einfo.pobj, ulOwner);
-
-    /* Dereference the object */
-    GDIOBJ_vDereferenceObject(pentry->einfo.pobj);
-
-    return TRUE;
-}
-
-BOOL
-NTAPI
-GreSetObjectOwner(
-    HGDIOBJ hobj,
-    ULONG ulOwner)
-{
-    return GreSetObjectOwnerEx(hobj, ulOwner, 0);
-}
-
-INT
-NTAPI
-GreGetObject(
-    IN HGDIOBJ hobj,
-    IN INT cbCount,
-    IN PVOID pvBuffer)
-{
-    PVOID pvObj;
-    UCHAR objt;
-    INT iResult = 0;
-
-    /* Verify object type */
-    objt = ((ULONG_PTR)hobj >> 16) & 0x1f;
-    if (objt != GDIObjType_BRUSH_TYPE &&
-        objt != GDIObjType_SURF_TYPE &&
-        objt != GDIObjType_LFONT_TYPE &&
-        objt != GDIObjType_PAL_TYPE)
-    {
-        DPRINT1("GreGetObject: Invalid object type\n");
-        return 0;
-    }
-
-    pvObj = GDIOBJ_ReferenceObjectByHandle(hobj, objt);
-    if (!pvObj)
-    {
-        DPRINT("GreGetObject: Could not lock object\n");
-        return 0;
-    }
-
-    switch (GDI_HANDLE_GET_TYPE(hobj))
-    {
-        case GDILoObjType_LO_PEN_TYPE:
-        case GDILoObjType_LO_EXTPEN_TYPE:
-            iResult = PEN_GetObject(pvObj, cbCount, pvBuffer);
-            break;
-
-        case GDILoObjType_LO_BRUSH_TYPE:
-            iResult = BRUSH_GetObject(pvObj, cbCount, pvBuffer);
-            break;
-
-        case GDILoObjType_LO_BITMAP_TYPE:
-            iResult = BITMAP_GetObject(pvObj, cbCount, pvBuffer);
-            break;
-
-        case GDILoObjType_LO_FONT_TYPE:
-            iResult = FontGetObject(pvObj, cbCount, pvBuffer);
-            break;
-
-        case GDILoObjType_LO_PALETTE_TYPE:
-            iResult = PALETTE_GetObject(pvObj, cbCount, pvBuffer);
-            break;
-
-        default:
-            DPRINT1("GDI object type of 0x%p not implemented\n", hobj);
-            break;
-    }
-
-    GDIOBJ_vDereferenceObject(pvObj);
-    return iResult;
-}
-
-W32KAPI
-INT
-APIENTRY
-NtGdiExtGetObjectW(
-    IN HANDLE hobj,
-    IN INT cjBufferSize,
-    OUT LPVOID lpBuffer)
-{
-    UINT iResult, cjMaxSize;
-    union
-    {
-        BITMAP bitmap;
-        DIBSECTION dibsection;
-        LOGPEN logpen;
-        LOGBRUSH logbrush;
-        LOGFONTW logfontw;
-        EXTLOGFONTW extlogfontw;
-        ENUMLOGFONTEXDVW enumlogfontexdvw;
-    } object;
-
-    /* Normalize to the largest supported object size */
-    cjMaxSize = min((UINT)cjBufferSize, sizeof(object));
-
-    /* Now do the actual call */
-    iResult = GreGetObject(hobj, cjMaxSize, lpBuffer ? &object : NULL);
-
-    /* Check if we have a buffer and data */
-    if ((lpBuffer != NULL) && (iResult != 0))
-    {
-        /* Enter SEH for buffer transfer */
-        _SEH2_TRY
-        {
-            /* Probe the buffer and copy it */
-            cjMaxSize = min(cjMaxSize, iResult);
-            ProbeForWrite(lpBuffer, cjMaxSize, sizeof(WORD));
-            RtlCopyMemory(lpBuffer, &object, cjMaxSize);
-        }
-        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
-        {
-            /* Clear the return value.
-             * Do *NOT* set last error here! */
-            iResult = 0;
-        }
-        _SEH2_END;
-    }
-
-    /* Return the count */
-    return iResult;
-}
-
-W32KAPI
-HANDLE
-APIENTRY
-NtGdiCreateClientObj(
-    IN ULONG ulType)
-{
-    POBJ pObject;
-    HANDLE handle;
-
-    /* Check if ulType is valid */
-    if ((ulType != GDILoObjType_LO_METAFILE16_TYPE) &&
-        (ulType != GDILoObjType_LO_METAFILE_TYPE) &&
-        (ulType != GDILoObjType_LO_METADC16_TYPE))
-    {
-        DPRINT1("NtGdiCreateClientObj: Invalid object type 0x%lx.\n", ulType);
-        return NULL;
-    }
-
-    /* Allocate a new object */
-    pObject = GDIOBJ_AllocateObject(GDIObjType_CLIENTOBJ_TYPE,
-                                    sizeof(CLIENTOBJ),
-                                    BASEFLAG_LOOKASIDE);
-    if (!pObject)
-    {
-        DPRINT1("NtGdiCreateClientObj: Could not allocate a clientobj.\n");
-        return NULL;
-    }
-
-    /* Set the real object type */
-    pObject->hHmgr = UlongToHandle(ulType | GDILoObjType_LO_CLIENTOBJ_TYPE);
-
-    /* Create a handle */
-    handle = GDIOBJ_hInsertObject(pObject, GDI_OBJ_HMGR_POWNED);
-    if (!handle)
-    {
-        DPRINT1("NtGdiCreateClientObj: Could not create a handle.\n");
-        GDIOBJ_vFreeObject(pObject);
-        return NULL;
-    }
-
-    /* Unlock it */
-    GDIOBJ_vUnlockObject(pObject);
-
-    return handle;
-}
-
-W32KAPI
-BOOL
-APIENTRY
-NtGdiDeleteClientObj(
-    IN HANDLE hobj)
-{
-    /* We first need to get the real type from the handle */
-    ULONG ulType = GDI_HANDLE_GET_TYPE(hobj);
-
-    /* Check if it's really a CLIENTOBJ */
-    if ((ulType & GDI_HANDLE_BASETYPE_MASK) != GDILoObjType_LO_CLIENTOBJ_TYPE)
-    {
-        /* FIXME: SetLastError? */
-        return FALSE;
-    }
-
-    return GreDeleteObject(hobj);
-}
-
-
-
-PGDI_HANDLE_TABLE GdiHandleTable = NULL;
-
-PGDIOBJ NTAPI
-GDIOBJ_ShareLockObj(HGDIOBJ hObj, DWORD ExpectedType)
-{
-    if (ExpectedType == GDI_OBJECT_TYPE_DONTCARE)
-        ExpectedType = GDI_HANDLE_GET_TYPE(hObj);
-    return GDIOBJ_ReferenceObjectByHandle(hObj, (ExpectedType >> 16) & 0x1f);
-}
-
-// This function is not safe to use with concurrent deleting attempts
-// That shouldn't be a problem, since we don't have any processes yet,
-// that could delete the handle
-BOOL
-NTAPI
-GDIOBJ_ConvertToStockObj(HGDIOBJ *phObj)
-{
-    PENTRY pentry;
-    POBJ pobj;
-
-    /* Reference the handle entry */
-    pentry = ENTRY_ReferenceEntryByHandle(*phObj, 0);
-    if (!pentry)
-    {
-        DPRINT1("GDIOBJ: Requested handle 0x%p is not valid.\n", *phObj);
-        return FALSE;
-    }
-
-    /* Update the entry */
-    pentry->FullUnique |= GDI_ENTRY_STOCK_MASK;
-    pentry->ObjectOwner.ulObj = 0;
-
-    /* Get the pointer to the BASEOBJECT */
-    pobj = pentry->einfo.pobj;
-
-    /* Calculate the new handle */
-    pobj->hHmgr = (HGDIOBJ)((ULONG_PTR)pobj->hHmgr | GDI_HANDLE_STOCK_MASK);
-
-    /* Return the new handle */
-    *phObj = pobj->hHmgr;
-
-    /* Dereference the handle */
-    GDIOBJ_vDereferenceObject(pobj);
-
-    return TRUE;
-}
-
-POBJ NTAPI
-GDIOBJ_AllocObjWithHandle(ULONG ObjectType, ULONG cjSize)
-{
-    POBJ pobj;
-    FLONG fl = 0;
-    UCHAR objt = (ObjectType >> 16) & 0xFF;
-
-    if ((objt == GDIObjType_DC_TYPE && cjSize == sizeof(DC)) ||
-        (objt == GDIObjType_PAL_TYPE && cjSize == sizeof(PALETTE)) ||
-        (objt == GDIObjType_RGN_TYPE && cjSize == sizeof(REGION)) ||
-        (objt == GDIObjType_SURF_TYPE && cjSize == sizeof(SURFACE)) ||
-        (objt == GDIObjType_PATH_TYPE && cjSize == sizeof(PATH)))
-    {
-        fl |= BASEFLAG_LOOKASIDE;
-    }
-
-    pobj = GDIOBJ_AllocateObject(objt, cjSize, fl);
-    if (!pobj)
-    {
-        return NULL;
-    }
-
-    if (!GDIOBJ_hInsertObject(pobj, GDI_OBJ_HMGR_POWNED))
-    {
-        GDIOBJ_vFreeObject(pobj);
-        return NULL;
-    }
-    return pobj;
-}
-
-PVOID NTAPI
-GDI_MapHandleTable(PEPROCESS pProcess)
-{
-    PVOID pvMappedView = NULL;
-    NTSTATUS Status;
-    LARGE_INTEGER liOffset;
-    ULONG cjViewSize = sizeof(GDI_HANDLE_TABLE);
-
-    liOffset.QuadPart = 0;
-
-    ASSERT(gpvGdiHdlTblSection != NULL);
-    ASSERT(pProcess != NULL);
-
-    Status = MmMapViewOfSection(gpvGdiHdlTblSection,
-                                pProcess,
-                                &pvMappedView,
-                                0,
-                                0,
-                                &liOffset,
-                                &cjViewSize,
-                                ViewUnmap,
-                                SEC_NO_CHANGE,
-                                PAGE_READONLY);
-
-    if (!NT_SUCCESS(Status))
-        return NULL;
-
-    return pvMappedView;
-}
-
-BOOL NTAPI
-GDI_CleanupForProcess(struct _EPROCESS *Process)
-{
-    PENTRY pentry;
-    ULONG ulIndex;
-    DWORD dwProcessId;
-    PPROCESSINFO ppi;
-
-    DPRINT("CleanupForProcess prochandle %p Pid %p\n",
-           Process, Process->UniqueProcessId);
-
-    ASSERT(Process == PsGetCurrentProcess());
-
-    /* Get the current process Id */
-    dwProcessId = PtrToUlong(PsGetCurrentProcessId());
-
-    /* Loop all handles in the handle table */
-    for (ulIndex = RESERVE_ENTRIES_COUNT; ulIndex < gulFirstUnused; ulIndex++)
-    {
-        pentry = &gpentHmgr[ulIndex];
-
-        /* Check if the object is owned by the process */
-        if (pentry->ObjectOwner.ulObj == dwProcessId)
-        {
-            ASSERT(pentry->einfo.pobj->cExclusiveLock == 0);
-
-            /* Reference the object and delete it */
-            InterlockedIncrement((LONG*)&gpaulRefCount[ulIndex]);
-            GDIOBJ_vDeleteObject(pentry->einfo.pobj);
-        }
-    }
-
-#if DBG
-    DbgGdiHTIntegrityCheck();
-#endif
-
-    ppi = PsGetCurrentProcessWin32Process();
-    DPRINT("Completed cleanup for process %p\n", Process->UniqueProcessId);
-    if (ppi->GDIHandleCount != 0)
-    {
-        DPRINT1("Leaking %d handles!\n", ppi->GDIHandleCount);
-        ASSERT(FALSE);
-    }
-
-    /* Loop all handles in the handle table */
-    for (ulIndex = RESERVE_ENTRIES_COUNT; ulIndex < gulFirstUnused; ulIndex++)
-    {
-        pentry = &gpentHmgr[ulIndex];
-
-        /* Check if the object is owned by the process */
-        if (pentry->ObjectOwner.ulObj == dwProcessId)
-        {
-            DPRINT1("Leaking object. Index=%lx, type=0x%x, refcount=%lx\n",
-                    ulIndex, pentry->Objt, gpaulRefCount[ulIndex]);
-            DBG_DUMP_EVENT_LIST(&pentry->einfo.pobj->slhLog);
-            //DBG_CLEANUP_EVENT_LIST(&pentry->einfo.pobj->slhLog);
-            ASSERT(FALSE);
-        }
-    }
-
-    return TRUE;
-}
-
-
-/* EOF */