[WIN32K]
authorTimo Kreuzer <timo.kreuzer@reactos.org>
Tue, 2 Oct 2012 21:20:28 +0000 (21:20 +0000)
committerTimo Kreuzer <timo.kreuzer@reactos.org>
Tue, 2 Oct 2012 21:20:28 +0000 (21:20 +0000)
Move gdi kdbg extension into a separate file, prefix names with ! to match WinDbg extensions more closely (e.g. "!gdi.help"), imlement help, dumpht, handle, entry and eventlist commands.

svn path=/trunk/; revision=57459

reactos/win32ss/CMakeLists.txt
reactos/win32ss/gdi/ntgdi/gdidbg.c
reactos/win32ss/gdi/ntgdi/gdidebug.h
reactos/win32ss/gdi/ntgdi/gdikdbgext.c [new file with mode: 0644]
reactos/win32ss/gdi/ntgdi/gdiobj.c
reactos/win32ss/gdi/ntgdi/gdiobj.h

index 1986ce1..c889a3b 100644 (file)
@@ -206,6 +206,11 @@ list(APPEND SOURCE
     gdi/dib/dib32bppc.c)
 endif()
 
+if(KDBG)
+    list(APPEND SOURCE
+        gdi/ntgdi/gdikdbgext.c)
+endif()
+
 add_library(win32k SHARED
     ${CMAKE_CURRENT_BINARY_DIR}/win32k.def
     ${SOURCE})
index 6e683ad..2edd9f3 100644 (file)
@@ -423,6 +423,7 @@ DbgLogEvent(PSLIST_HEADER pslh, LOG_EVENT_TYPE nEventType, LPARAM lParam)
 #define REL_ADDR(va) ((ULONG_PTR)va - (ULONG_PTR)&__ImageBase)
 
 VOID
+NTAPI
 DbgPrintEvent(PLOGENTRY pLogEntry)
 {
     PSTR pstr;
@@ -465,7 +466,6 @@ DbgDumpEventList(PSLIST_HEADER pslh)
         pLogEntry = CONTAINING_RECORD(psle, LOGENTRY, sleLink);
         DbgPrintEvent(pLogEntry);
     }
-
 }
 
 VOID
@@ -730,35 +730,6 @@ BOOL DbgInitDebugChannels()
 }
 
 
-#if KDBG
-
-BOOLEAN
-NTAPI
-DbgGdiKdbgCliCallback(
-    IN PCHAR pszCommand,
-    IN ULONG argc,
-    IN PCH argv[])
-{
-
-    if (stricmp(argv[0], "gdi!dumpht") == 0)
-    {
-        DbgDumpGdiHandleTable(argc - 1, argv + 1);
-    }
-    else if (stricmp(argv[0], "gdi!handle") == 0)
-    {
-        DbgDumpHandleInfo(argv[1]);
-    }
-    else
-    {
-        /* Not handled */
-        return FALSE;
-    }
-
-    return TRUE;
-}
-
-#endif // KDBG
-
 #endif // DBG
 
 /* EOF */
index fd27537..dd868a1 100644 (file)
@@ -41,6 +41,7 @@ DbgGdiKdbgCliCallback(
 VOID NTAPI DbgDumpEventList(PSLIST_HEADER pslh);
 VOID NTAPI DbgLogEvent(PSLIST_HEADER pslh, LOG_EVENT_TYPE nEventType, LPARAM lParam);
 VOID NTAPI DbgCleanupEventList(PSLIST_HEADER pslh);
+VOID NTAPI DbgPrintEvent(PLOGENTRY pLogEntry);
 #define DBG_LOGEVENT(pslh, type, val) DbgLogEvent(pslh, type, (ULONG_PTR)val)
 #define DBG_INITLOG(pslh) InitializeSListHead(pslh)
 #define DBG_DUMP_EVENT_LIST(pslh) DbgDumpEventList(pslh)
diff --git a/reactos/win32ss/gdi/ntgdi/gdikdbgext.c b/reactos/win32ss/gdi/ntgdi/gdikdbgext.c
new file mode 100644 (file)
index 0000000..6cd3d57
--- /dev/null
@@ -0,0 +1,369 @@
+/*
+ * PROJECT:         ReactOS win32 kernel mode subsystem
+ * LICENSE:         GPL - See COPYING in the top level directory
+ * FILE:            win32ss/gdi/ntgdi/gdikdbgext.x
+ * PURPOSE:         KDBG extension for GDI
+ * PROGRAMMERS:     Timo Kreuzer
+ */
+
+/* INCLUDES ******************************************************************/
+
+#include <win32k.h>
+//#define NDEBUG
+//#include <debug.h>
+
+extern PENTRY gpentHmgr;
+extern PULONG gpaulRefCount;
+extern PEPROCESS gpepCSRSS;
+extern ULONG gulFirstUnused;
+
+
+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"
+};
+
+
+BOOLEAN
+KdbIsMemoryValid(PVOID pvBase, ULONG cjSize)
+{
+    PUCHAR pjAddress;
+
+    pjAddress = ALIGN_DOWN_POINTER_BY(pvBase, PAGE_SIZE);
+
+    while (pjAddress < (PUCHAR)pvBase + cjSize)
+    {
+        if (!MmIsAddressValid(pjAddress)) return FALSE;
+        pjAddress += PAGE_SIZE;
+    }
+
+    return TRUE;
+}
+
+static
+BOOL
+KdbGetHexNumber(char *pszNum, ULONG_PTR *pulValue)
+{
+    char *endptr;
+
+    /* Skip optional '0x' prefix */
+    if ((pszNum[0] == '0') && ((pszNum[1] == 'x') || (pszNum[1] == 'X')))
+        pszNum += 2;
+
+    /* Make a number from the string (hex) */
+    *pulValue = strtoul(pszNum, &endptr, 16);
+
+    return (*endptr == '\0');
+}
+
+static
+VOID
+KdbCommand_Gdi_help(VOID)
+{
+    DbgPrint("GDI KDBG extension.\nAvailable commands:\n"
+             "- help - Displays this screen.\n"
+             "- dumpht [<type>] - Dumps all handles of <type> or lists all types\n"
+             "- handle <handle> - Displays information about a handle\n"
+             "- entry <entry> - Displays an ENTRY, <entry> can be a pointer or index\n"
+             "- baseobject <object> - Displays a BASEOBJECT\n"
+#if DBG_ENABLE_EVENT_LOGGING
+             "- eventlist <object> - Displays the eventlist for an object\n"
+#endif
+            );
+}
+
+static
+VOID
+KdbCommand_Gdi_dumpht(ULONG argc, char *argv[])
+{
+    ULONG i;
+    UCHAR Objt, jReqestedType;
+    PENTRY pentry;
+    POBJ pobj;
+    KAPC_STATE ApcState;
+    ULONG_PTR ulArg;
+
+    /* 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 (KdbIsMemoryValid(&gpentHmgr[i], sizeof(ENTRY)))
+            {
+                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) break;
+        }
+
+        /* Check if we didn't find it yet */
+        if (i > GDIObjType_MAX_TYPE + 1)
+        {
+            /* Try if it's a number */
+            if (!KdbGetHexNumber(argv[0], &ulArg))
+            {
+                DbgPrint("Invalid parameter: %s\n", argv[0]);
+                return;
+            }
+
+            /* Check if it's inside the allowed range */
+            if (i > GDIObjType_MAX_TYPE)
+            {
+                DbgPrint("Unknown object type: %s\n", argv[0]);
+                goto leave;
+            }
+        }
+
+        jReqestedType = i;
+
+        /* Print header */
+        DbgPrint("Index Handle   Type      pObject    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;
+
+            /* Check if ALL objects are requested, or the object type matches */
+            if ((jReqestedType == GDIObjType_MAX_TYPE + 1) ||
+                (Objt == jReqestedType))
+            {
+                DbgPrint("%04lx  %p %-9s 0x%p 0x%06lx %-6ld ",
+                         i, pobj->hHmgr, gpszObjectTypes[Objt], pobj,
+                         pobj->dwThreadId, pobj->cExclusiveLock);
+                if (MmIsAddressValid(&gpaulRefCount[i]))
+                    DbgPrint("0x%08lx\n", gpaulRefCount[i]);
+                else
+                    DbgPrint("??????????\n");
+            }
+        }
+    }
+
+leave:
+    KeUnstackDetachProcess(&ApcState);
+}
+
+static
+VOID
+KdbCommand_Gdi_handle(char *argv)
+{
+    ULONG_PTR ulObject;
+    BASEOBJECT *pobj;
+    ENTRY *pentry;
+    USHORT usIndex;
+    KAPC_STATE ApcState;
+
+    /* Convert the parameter into a number */
+    if (!KdbGetHexNumber(argv, &ulObject))
+    {
+        DbgPrint("Invalid parameter: %s\n", argv);
+        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);
+}
+
+static
+VOID
+KdbCommand_Gdi_entry(char *argv)
+{
+    ULONG_PTR ulValue;
+    PENTRY pentry;
+    KAPC_STATE ApcState;
+
+    /* Convert the parameter into a number */
+    if (!KdbGetHexNumber(argv, &ulValue))
+    {
+        DbgPrint("Invalid parameter: %s\n", argv);
+        return;
+    }
+
+    /* No CSRSS, no handle table */
+    if (!gpepCSRSS) return;
+    KeStackAttachProcess(&gpepCSRSS->Pcb, &ApcState);
+
+    /* If the parameter is smaller than 0x10000, it's an index */
+    pentry = (ulValue <= 0xFFFF) ? &gpentHmgr[ulValue] : (PENTRY)ulValue;
+
+    /* Check if the address is readable */
+    if (!MmIsAddressValid(pentry))
+    {
+        DbgPrint("Cannot access entry at %p\n", pentry);
+        goto cleanup;
+    }
+
+    /* print the entry */
+    DbgPrint("Dumping ENTRY #%ld, @%p:\n", (pentry - gpentHmgr), pentry);
+    if (pentry->Objt != 0)
+        DbgPrint(" pobj = 0x%p\n", pentry->einfo.pobj);
+    else
+        DbgPrint(" hFree = 0x%p\n", pentry->einfo.hFree);
+    DbgPrint(" ObjectOwner = 0x%p\n", pentry->ObjectOwner.ulObj);
+    DbgPrint(" FullUnique = 0x%x\n", pentry->FullUnique);
+    DbgPrint(" Objt = 0x%x (%s)\n", pentry->Objt,
+             pentry->Objt <= 0x1E ? gpszObjectTypes[pentry->Objt] : "invalid");
+    DbgPrint(" Flags = 0x%x\n", pentry->Flags);
+    DbgPrint(" pUser = 0x%p\n", pentry->pUser);
+
+cleanup:
+    KeUnstackDetachProcess(&ApcState);
+}
+
+static
+VOID
+KdbCommand_Gdi_baseobject(char *argv)
+{
+}
+
+#if DBG_ENABLE_EVENT_LOGGING
+static
+VOID
+KdbCommand_Gdi_eventlist(char *argv)
+{
+    ULONG_PTR ulValue;
+    POBJ pobj;
+    PSLIST_ENTRY psle, psleFirst;
+    PLOGENTRY pLogEntry;
+
+    /* Convert the parameter into a number */
+    if (!KdbGetHexNumber(argv, &ulValue))
+    {
+        DbgPrint("Invalid parameter: %s\n", argv);
+        return;
+    }
+
+    pobj = (POBJ)ulValue;
+
+    /* Check if the address is readable */
+    if (!KdbIsMemoryValid(pobj, sizeof(BASEOBJECT)))
+    {
+        DbgPrint("Cannot access BASEOBJECT at %p\n", pobj);
+        return;
+    }
+
+    /* The kernel doesn't export RtlFirstEntrySList :( */
+    psleFirst = InterlockedFlushSList(&pobj->slhLog);
+
+    /* Loop all events, but don't remove them */
+    for (psle = psleFirst; psle != NULL; psle = psle->Next)
+    {
+        pLogEntry = CONTAINING_RECORD(psle, LOGENTRY, sleLink);
+        DbgPrintEvent(pLogEntry);
+    }
+
+    /* Put the log back in place */
+    InterlockedPushEntrySList(&pobj->slhLog, psleFirst);
+}
+#endif
+
+BOOLEAN
+NTAPI
+DbgGdiKdbgCliCallback(
+    IN PCHAR pszCommand,
+    IN ULONG argc,
+    IN PCH argv[])
+{
+
+    if (stricmp(argv[0], "!gdi.help") == 0)
+    {
+        KdbCommand_Gdi_help();
+    }
+    else if (stricmp(argv[0], "!gdi.dumpht") == 0)
+    {
+        KdbCommand_Gdi_dumpht(argc - 1, argv + 1);
+    }
+    else if (stricmp(argv[0], "!gdi.handle") == 0)
+    {
+        KdbCommand_Gdi_handle(argv[1]);
+    }
+    else if (stricmp(argv[0], "!gdi.entry") == 0)
+    {
+        KdbCommand_Gdi_entry(argv[1]);
+    }
+    else if (stricmp(argv[0], "!gdi.baseobject") == 0)
+    {
+        KdbCommand_Gdi_baseobject(argv[1]);
+    }
+#if DBG_ENABLE_EVENT_LOGGING
+    else if (stricmp(argv[0], "!gdi.eventlist") == 0)
+    {
+        KdbCommand_Gdi_eventlist(argv[1]);
+    }
+#endif
+    else
+    {
+        /* Not handled */
+        return FALSE;
+    }
+
+    return TRUE;
+}
+
+
+
+
+
index 8adec2e..2ce8783 100644 (file)
@@ -79,8 +79,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;
@@ -1341,170 +1341,5 @@ GDI_CleanupForProcess(struct _EPROCESS *Process)
     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 */
index eba7459..b459a0c 100644 (file)
@@ -179,16 +179,3 @@ BOOL    NTAPI GDIOBJ_ConvertToStockObj(HGDIOBJ *hObj);
 POBJ    NTAPI GDIOBJ_AllocObjWithHandle(ULONG ObjectType, ULONG cjSize);
 PGDIOBJ NTAPI GDIOBJ_ShareLockObj(HGDIOBJ hObj, DWORD ObjectType);
 PVOID   NTAPI GDI_MapHandleTable(PEPROCESS Process);
-
-#if DBG && KDBG
-VOID
-NTAPI
-DbgDumpGdiHandleTable(
-    ULONG argc,
-    char *argv[]);
-
-VOID
-NTAPI
-DbgDumpHandleInfo(
-    char *argv);
-#endif