Author: tkreuzer Date: Tue Oct 2 21:20:28 2012 New Revision: 57459
URL: http://svn.reactos.org/svn/reactos?rev=57459&view=rev Log: [WIN32K] 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.
Added: trunk/reactos/win32ss/gdi/ntgdi/gdikdbgext.c (with props) Modified: trunk/reactos/win32ss/CMakeLists.txt trunk/reactos/win32ss/gdi/ntgdi/gdidbg.c trunk/reactos/win32ss/gdi/ntgdi/gdidebug.h trunk/reactos/win32ss/gdi/ntgdi/gdiobj.c trunk/reactos/win32ss/gdi/ntgdi/gdiobj.h
Modified: trunk/reactos/win32ss/CMakeLists.txt URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/CMakeLists.txt?rev=... ============================================================================== --- trunk/reactos/win32ss/CMakeLists.txt [iso-8859-1] (original) +++ trunk/reactos/win32ss/CMakeLists.txt [iso-8859-1] Tue Oct 2 21:20:28 2012 @@ -206,6 +206,11 @@ 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})
Modified: trunk/reactos/win32ss/gdi/ntgdi/gdidbg.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/gdi/ntgdi/gdidbg.c?... ============================================================================== --- trunk/reactos/win32ss/gdi/ntgdi/gdidbg.c [iso-8859-1] (original) +++ trunk/reactos/win32ss/gdi/ntgdi/gdidbg.c [iso-8859-1] Tue Oct 2 21:20:28 2012 @@ -423,6 +423,7 @@ #define REL_ADDR(va) ((ULONG_PTR)va - (ULONG_PTR)&__ImageBase)
VOID +NTAPI DbgPrintEvent(PLOGENTRY pLogEntry) { PSTR pstr; @@ -465,7 +466,6 @@ pLogEntry = CONTAINING_RECORD(psle, LOGENTRY, sleLink); DbgPrintEvent(pLogEntry); } - }
VOID @@ -730,35 +730,6 @@ }
-#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 */
Modified: trunk/reactos/win32ss/gdi/ntgdi/gdidebug.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/gdi/ntgdi/gdidebug.... ============================================================================== --- trunk/reactos/win32ss/gdi/ntgdi/gdidebug.h [iso-8859-1] (original) +++ trunk/reactos/win32ss/gdi/ntgdi/gdidebug.h [iso-8859-1] Tue Oct 2 21:20:28 2012 @@ -41,6 +41,7 @@ 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)
Added: trunk/reactos/win32ss/gdi/ntgdi/gdikdbgext.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/gdi/ntgdi/gdikdbgex... ============================================================================== --- trunk/reactos/win32ss/gdi/ntgdi/gdikdbgext.c (added) +++ trunk/reactos/win32ss/gdi/ntgdi/gdikdbgext.c [iso-8859-1] Tue Oct 2 21:20:28 2012 @@ -1,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; +} + + + + +
Propchange: trunk/reactos/win32ss/gdi/ntgdi/gdikdbgext.c ------------------------------------------------------------------------------ svn:eol-style = native
Modified: trunk/reactos/win32ss/gdi/ntgdi/gdiobj.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/gdi/ntgdi/gdiobj.c?... ============================================================================== --- trunk/reactos/win32ss/gdi/ntgdi/gdiobj.c [iso-8859-1] (original) +++ trunk/reactos/win32ss/gdi/ntgdi/gdiobj.c [iso-8859-1] Tue Oct 2 21:20:28 2012 @@ -79,8 +79,8 @@
/* 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 @@ 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 */
Modified: trunk/reactos/win32ss/gdi/ntgdi/gdiobj.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/gdi/ntgdi/gdiobj.h?... ============================================================================== --- trunk/reactos/win32ss/gdi/ntgdi/gdiobj.h [iso-8859-1] (original) +++ trunk/reactos/win32ss/gdi/ntgdi/gdiobj.h [iso-8859-1] Tue Oct 2 21:20:28 2012 @@ -179,16 +179,3 @@ 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