#define NDEBUG
#include <debug.h>
-// Move to gdidbg.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
-#define DBG_INCREASE_LOCK_COUNT(pti, hobj) \
- if (pti) ((PTHREADINFO)pti)->acExclusiveLockCount[((ULONG_PTR)hobj >> 16) & 0x1f]++;
-#define DBG_DECREASE_LOCK_COUNT(pti, hobj) \
- if (pti) ((PTHREADINFO)pti)->acExclusiveLockCount[((ULONG_PTR)hobj >> 16) & 0x1f]--;
#define ASSERT_SHARED_OBJECT_TYPE(objt) \
ASSERT((objt) == GDIObjType_SURF_TYPE || \
(objt) == GDIObjType_PAL_TYPE || \
(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)
+#define ASSERT_TRYLOCK_OBJECT_TYPE(objt) \
+ ASSERT((objt) == GDIObjType_DRVOBJ_TYPE)
#else
-#define DBG_INCREASE_LOCK_COUNT(ppi, hobj)
-#define DBG_DECREASE_LOCK_COUNT(x, y)
#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)
/* 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;
-static BOOL NTAPI GDIOBJ_Cleanup(PVOID ObjectBody);
+static VOID NTAPI GDIOBJ_vCleanup(PVOID ObjectBody);
static const
GDICLEANUPPROC
apfnCleanup[] =
{
- NULL, /* 00 GDIObjType_DEF_TYPE */
- DC_Cleanup, /* 01 GDIObjType_DC_TYPE */
- NULL, /* 02 GDIObjType_UNUSED1_TYPE */
- NULL, /* 03 GDIObjType_UNUSED2_TYPE */
- REGION_Cleanup, /* 04 GDIObjType_RGN_TYPE */
- SURFACE_Cleanup, /* 05 GDIObjType_SURF_TYPE */
- GDIOBJ_Cleanup, /* 06 GDIObjType_CLIENTOBJ_TYPE */
- GDIOBJ_Cleanup, /* 07 GDIObjType_PATH_TYPE */
- PALETTE_Cleanup, /* 08 GDIObjType_PAL_TYPE */
- GDIOBJ_Cleanup, /* 09 GDIObjType_ICMLCS_TYPE */
- GDIOBJ_Cleanup, /* 0a GDIObjType_LFONT_TYPE */
- NULL, /* 0b GDIObjType_RFONT_TYPE, unused */
- NULL, /* 0c GDIObjType_PFE_TYPE, unused */
- NULL, /* 0d GDIObjType_PFT_TYPE, unused */
- GDIOBJ_Cleanup, /* 0e GDIObjType_ICMCXF_TYPE */
- NULL, /* 0f GDIObjType_SPRITE_TYPE, unused */
- BRUSH_Cleanup, /* 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_Cleanup,/* 1c GDIObjType_DRVOBJ_TYPE */
- NULL, /* 1d GDIObjType_DCIOBJ_TYPE, unused */
- NULL, /* 1e GDIObjType_SPOOL_TYPE, unused */
- NULL, /* 1f reserved entry */
+ 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
-BOOL NTAPI
-GDIOBJ_Cleanup(PVOID ObjectBody)
+VOID
+NTAPI
+GDIOBJ_vCleanup(PVOID ObjectBody)
{
- return TRUE;
+ /* Nothing to do */
}
static
FORCEINLINE
VOID
-IncrementGdiHandleCount(void)
+IncrementCurrentProcessGdiHandleCount(void)
{
PPROCESSINFO ppi = PsGetCurrentProcessWin32Process();
if (ppi) InterlockedIncrement((LONG*)&ppi->GDIHandleCount);
FORCEINLINE
VOID
-DecrementGdiHandleCount(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)
/* Decrement the process handle count */
ASSERT(gpentHmgr[ulIndex].ObjectOwner.ulObj ==
HandleToUlong(PsGetCurrentProcessId()));
- DecrementGdiHandleCount();
+ DecrementCurrentProcessGdiHandleCount();
}
/* Push entry to the free list */
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;
+ }
+
+ /* 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(
/* Increase lock count */
pobj->cExclusiveLock++;
- DBG_INCREASE_LOCK_COUNT(PsGetCurrentProcessWin32Process(), hobj);
+ INCREASE_THREAD_LOCK_COUNT(hobj);
DBG_LOGEVENT(&pobj->slhLog, EVENT_LOCK, 0);
/* Return the object */
/* Decrease lock count */
pobj->cExclusiveLock--;
- DBG_DECREASE_LOCK_COUNT(PsGetCurrentProcessWin32Process(), pobj->hHmgr);
+ DECREASE_THREAD_LOCK_COUNT(pobj->hHmgr);
DBG_LOGEVENT(&pobj->slhLog, EVENT_UNLOCK, 0);
/* Check if this was the last lock */
ExAcquirePushLockExclusive(&pobj->pushlock);
pobj->cExclusiveLock = 1;
pobj->dwThreadId = PtrToUlong(PsGetCurrentThreadId());
- DBG_INCREASE_LOCK_COUNT(PsGetCurrentProcessWin32Process(), pobj->hHmgr);
+ INCREASE_THREAD_LOCK_COUNT(pobj->hHmgr);
/* Get object type from the hHmgr field */
objt = ((ULONG_PTR)pobj->hHmgr >> 16) & 0xff;
if (ulOwner == GDI_OBJ_HMGR_POWNED)
{
/* Increment the process handle count */
- IncrementGdiHandleCount();
+ IncrementCurrentProcessGdiHandleCount();
/* Use Process id */
ulOwner = HandleToUlong(PsGetCurrentProcessId());
NTAPI
GDIOBJ_vSetObjectOwner(
POBJ pobj,
- ULONG ulOwner)
+ 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, ulOwner);
+ DPRINT("Trying to set ownership of stock object %p to %lx\n", pobj->hHmgr, ulNewOwner);
return;
}
/* Get the handle entry */
- ASSERT(GDI_HANDLE_GET_INDEX(pobj->hHmgr));
+ 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 (ulOwner == GDI_OBJ_HMGR_POWNED)
+ if (ulNewOwner == GDI_OBJ_HMGR_POWNED)
{
/* Use process id */
- ulOwner = HandleToUlong(PsGetCurrentProcessId());
- if (pentry->ObjectOwner.ulObj != ulOwner)
- {
- IncrementGdiHandleCount();
- }
+ ulNewOwner = HandleToUlong(PsGetCurrentProcessId());
}
// HACK
- if (ulOwner == GDI_OBJ_HMGR_NONE)
- ulOwner = GDI_OBJ_HMGR_PUBLIC;
+ 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);
+ }
- if (ulOwner == GDI_OBJ_HMGR_PUBLIC ||
- ulOwner == GDI_OBJ_HMGR_NONE)
+ /* 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 */
- ASSERT(pentry->pUser == NULL);
- if (pentry->ObjectOwner.ulObj != GDI_OBJ_HMGR_PUBLIC &&
- pentry->ObjectOwner.ulObj != GDI_OBJ_HMGR_NONE)
- {
- DecrementGdiHandleCount();
- }
+ NT_ASSERT(pentry->pUser == NULL);
}
/* Set new owner */
- pentry->ObjectOwner.ulObj = ulOwner;
+ pentry->ObjectOwner.ulObj = ulNewOwner;
DBG_LOGEVENT(&pobj->slhLog, EVENT_SET_OWNER, 0);
}
/* Release the pushlock and reenable APCs */
ExReleasePushLockExclusive(&pobj->pushlock);
KeLeaveCriticalRegion();
- DBG_DECREASE_LOCK_COUNT(PsGetCurrentProcessWin32Process(), pobj->hHmgr);
+ DECREASE_THREAD_LOCK_COUNT(pobj->hHmgr);
}
}
BOOL
NTAPI
-GreSetObjectOwner(
+GreSetObjectOwnerEx(
HGDIOBJ hobj,
- ULONG ulOwner)
+ ULONG ulOwner,
+ ULONG Flags)
{
PENTRY pentry;
}
/* Reference the handle entry */
- pentry = ENTRY_ReferenceEntryByHandle(hobj, 0);
+ pentry = ENTRY_ReferenceEntryByHandle(hobj, Flags);
if (!pentry)
{
DPRINT("GreSetObjectOwner: Invalid handle 0x%p.\n", hobj);
return TRUE;
}
+BOOL
+NTAPI
+GreSetObjectOwner(
+ HGDIOBJ hobj,
+ ULONG ulOwner)
+{
+ return GreSetObjectOwnerEx(hobj, ulOwner, 0);
+}
+
INT
NTAPI
GreGetObject(
APIENTRY
NtGdiExtGetObjectW(
IN HANDLE hobj,
- IN INT cbCount,
+ IN INT cjBufferSize,
OUT LPVOID lpBuffer)
{
- INT iRetCount = 0;
- INT cbCopyCount;
+ UINT iResult, cjMaxSize;
union
{
BITMAP bitmap;
} object;
/* Normalize to the largest supported object size */
- cbCount = min((UINT)cbCount, sizeof(object));
+ cjMaxSize = min((UINT)cjBufferSize, sizeof(object));
/* Now do the actual call */
- iRetCount = GreGetObject(hobj, cbCount, lpBuffer ? &object : NULL);
- cbCopyCount = min((UINT)cbCount, (UINT)iRetCount);
+ iResult = GreGetObject(hobj, cjMaxSize, lpBuffer ? &object : NULL);
- /* Make sure we have a buffer and a copy size */
- if ((cbCopyCount) && (lpBuffer))
+ /* 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 */
- ProbeForWrite(lpBuffer, cbCopyCount, sizeof(WORD));
- RtlCopyMemory(lpBuffer, &object, cbCopyCount);
+ 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! */
- iRetCount = 0;
+ iResult = 0;
}
_SEH2_END;
}
/* Return the count */
- return iRetCount;
+ return iResult;
}
W32KAPI
}
pobj = GDIOBJ_AllocateObject(objt, cjSize, fl);
+ if (!pobj)
+ {
+ return NULL;
+ }
+
if (!GDIOBJ_hInsertObject(pobj, GDI_OBJ_HMGR_POWNED))
{
GDIOBJ_vFreeObject(pobj);
return TRUE;
}
-#if DBG && KDBG
-static const char * gpszObjectTypes[] =
-{
- "FREE", "DC", "UNUSED1", "UNUSED2", "RGN", "SURF", "CLIENTOBJ", "PATH",
- "PAL", "ICMLCS", "LFONT", "RFONT", "PFE", "PFT", "ICMCXF", "SPRITE",
- "BRUSH", "UMPD", "UNUSED4", "SPACE", "UNUSED5", "META", "EFSTATE",
- "BMFD", "VTFD", "TTFD", "RC", "TEMP", "DRVOBJ", "DCIOBJ", "SPOOL",
- "RESERVED", "ALL"
-};
-
-extern PEPROCESS gpepCSRSS;;
-
-VOID
-NTAPI
-DbgDumpGdiHandleTable(ULONG argc, char *argv[])
-{
- ULONG i;
- UCHAR Objt, jReqestedType;
- PENTRY pentry;
- POBJ pobj;
- KAPC_STATE ApcState;
-
- /* No CSRSS, no handle table */
- if (!gpepCSRSS) return;
- KeStackAttachProcess(&gpepCSRSS->Pcb, &ApcState);
-
- if (argc == 0)
- {
- USHORT Counts[GDIObjType_MAX_TYPE + 2] = {0};
-
- /* Loop all possibly used entries in the handle table */
- for (i = RESERVE_ENTRIES_COUNT; i < gulFirstUnused; i++)
- {
- if (MmIsAddressValid(&gpentHmgr[i]))
- {
- Objt = gpentHmgr[i].Objt & 0x1F;
- Counts[Objt]++;
- }
- }
-
- DbgPrint("Type Count\n");
- DbgPrint("-------------------\n");
- for (i = 0; i <= GDIObjType_MAX_TYPE; i++)
- {
- DbgPrint("%02x %-9s %d\n",
- i, gpszObjectTypes[i], Counts[i]);
- }
- DbgPrint("\n");
- }
- else
- {
- /* Loop all object types */
- for (i = 0; i <= GDIObjType_MAX_TYPE + 1; i++)
- {
- /* Check if this object type was requested */
- if (stricmp(argv[0], gpszObjectTypes[i]) == 0)
- {
- jReqestedType = i;
- break;
- }
- }
-
- /* Check if we didn't find it yet */
- if (i > GDIObjType_MAX_TYPE)
- {
- /* Try if it's a number */
- i = atoi(argv[0]);
-
- /* Check for "0" */
- if ((i > GDIObjType_MAX_TYPE) ||
- ((i == 0) && (stricmp(argv[0], "0") == 0)))
- {
- DbgPrint("Unknown object type: %s\n", argv[0]);
- goto leave;
- }
-
- jReqestedType = i;
- }
-
- /* Print header */
- DbgPrint("Index Handle Type ThreadId cLocks ulRefCount\n");
- DbgPrint("----------------------------------------------------\n");
-
- /* Loop all possibly used entries in the handle table */
- for (i = RESERVE_ENTRIES_COUNT; i < gulFirstUnused; i++)
- {
- /* Get the entry and the object */
- pentry = &gpentHmgr[i];
-
- if (!MmIsAddressValid(pentry)) continue;
-
- pobj = pentry->einfo.pobj;
- Objt = pentry->Objt & 0x1F;
-
- if ((jReqestedType == GDIObjType_MAX_TYPE + 1) ||
- (Objt == jReqestedType))
- {
- DbgPrint("%04lx %p %-9s 0x%06lx %-7ld ",
- i, pobj->hHmgr, gpszObjectTypes[Objt],
- pobj->dwThreadId, pobj->cExclusiveLock);
- if (MmIsAddressValid(&gpaulRefCount[i]))
- DbgPrint("0x%06lx\n", gpaulRefCount[i]);
- else
- DbgPrint("????????\n");
- }
- }
- }
-
-leave:
- KeUnstackDetachProcess(&ApcState);
-}
-
-VOID
-NTAPI
-DbgDumpHandleInfo(char *argv)
-{
- ULONG_PTR ulObject;
- BASEOBJECT *pobj;
- ENTRY *pentry;
- USHORT usIndex;
- char *endptr;
- KAPC_STATE ApcState;
-
- /* Skip optional '0x' prefix */
- if ((argv[0] == '0') && ((argv[1] == 'x') || (argv[1] == 'X')))
- argv += 2;
-
- /* Make a number from the string (hex) */
- ulObject = strtol(argv, &endptr, 16);
- if (*endptr != '\0')
- return;
-
- /* No CSRSS, no handle table */
- if (!gpepCSRSS) return;
- KeStackAttachProcess(&gpepCSRSS->Pcb, &ApcState);
-
- usIndex = ulObject & 0xFFFF;
- pentry = &gpentHmgr[usIndex];
-
- if (MmIsAddressValid(pentry))
- {
- pobj = pentry->einfo.pobj;
-
- DbgPrint("GDI handle=%p, type=%s, index=0x%lx, pentry=%p.\n",
- ulObject, gpszObjectTypes[(ulObject >> 16) & 0x1f],
- usIndex, pentry);
- DbgPrint(" ENTRY = {.pobj = %p, ObjectOwner = 0x%lx, FullUnique = 0x%04x,\n"
- " Objt=0x%02x, Flags = 0x%02x, pUser = 0x%p}\n",
- pentry->einfo.pobj, pentry->ObjectOwner.ulObj, pentry->FullUnique,
- pentry->Objt, pentry->Flags, pentry->pUser);
- DbgPrint(" BASEOBJECT = {hHmgr = %p, dwThreadId = 0x%lx,\n"
- " cExclusiveLock = %ld, BaseFlags = 0x%lx}\n",
- pobj->hHmgr, pobj->dwThreadId,
- pobj->cExclusiveLock, pobj->BaseFlags);
- if (MmIsAddressValid(&gpaulRefCount[usIndex]))
- DbgPrint(" gpaulRefCount[idx] = %ld\n", gpaulRefCount[usIndex]);
- }
- else
- {
- DbgPrint("Coudn't access ENTRY. Probably paged out.\n");
- }
-
- KeUnstackDetachProcess(&ApcState);
-}
-#endif // DBG && KDBG
/* EOF */