|
|
/*++
Copyright (c) 1998 Microsoft Corporation
Module Name:
devstack.c
Abstract:
WinDbg Extension Api
Author:
Adrian Oney (adriao) 29-Sep-1998
Environment:
User Mode.
Revision History:
--*/
#include "precomp.h"
#pragma hdrstop
/*
#define FLAG_NAME(flag) {flag, #flag}
FLAG_NAME DeviceObjectExtensionFlags[] = { FLAG_NAME(DOE_UNLOAD_PENDING), // 00000001
FLAG_NAME(DOE_DELETE_PENDING), // 00000002
FLAG_NAME(DOE_REMOVE_PENDING), // 00000004
FLAG_NAME(DOE_REMOVE_PROCESSED), // 00000008
FLAG_NAME(DOE_RAW_FDO), // 20000000
FLAG_NAME(DOE_BOTTOM_OF_FDO_STACK), // 40000000
FLAG_NAME(DOE_DESIGNATED_FDO), // 80000000
{ 0, 0 } }; */
VOID DumpDeviceStack( ULONG64 DeviceAddress );
DECLARE_API( devstack )
/*++
Routine Description:
Dump a device object.
Arguments:
args - the location of the device object to dump.
Return Value:
None
--*/
{ ULONG64 deviceToDump ; char deviceExprBuf[256] ; char *deviceExpr ;
//
// !devstack DeviceAddress DumpLevel
// where DeviceAddress can be an expression or device name
// and DumpLevel is a hex mask
//
strcpy(deviceExprBuf, "\\Device\\") ; deviceExpr = deviceExprBuf+strlen(deviceExprBuf) ; deviceToDump = 0 ;
if (StringCchCopy(deviceExpr, sizeof(deviceExprBuf) - strlen(deviceExprBuf), args) != S_OK) { deviceExpr[0] = 0; } //
// sscanf(args, "%255s %lx", deviceExpr, &Flags);
//
//
// The debugger will treat C0000000 as a symbol first, then a number if
// no match comes up. We sanely reverse this ordering.
//
if (IsHexNumber(deviceExpr)) {
deviceToDump = GetExpression (deviceExpr) ;
} else if (deviceExpr[0] == '\\') {
deviceToDump = FindObjectByName( deviceExpr, 0);
} else if (isalpha(deviceExpr[0])) {
//
// Perhaps it's an object. Try with \\Device\\ prepended...
//
deviceToDump = FindObjectByName((PUCHAR) deviceExprBuf, 0); }
if (deviceToDump == 0) {
//
// Last try, is it an expression to evaluate?
//
deviceToDump = GetExpression( deviceExpr ) ; }
if(deviceToDump == 0) { dprintf("Device object %s not found\n", args); return E_INVALIDARG; }
DumpDeviceStack(deviceToDump); return S_OK; }
VOID DumpDeviceStack( ULONG64 DeviceAddress )
/*++
Routine Description:
Displays the driver name for the device object . Otherwise displays more information about the device and the device queue.
Arguments:
DeviceAddress - address of device object to dump.
Return Value:
None
--*/
{ ULONG result; ULONG i; ULONG64 nextEntry; BOOLEAN devObjExtRead; ULONG64 currentDeviceObject ; ULONG64 DeviceNode=0 ; ULONG64 AttachedDevice; ULONG64 DeviceObjectExtension; ULONG Type;
if (!IsPtr64()) { DeviceAddress = (ULONG64) (LONG64) (LONG) DeviceAddress; } //
// Find top of stack...
//
currentDeviceObject = DeviceAddress; dprintf(" !DevObj !DrvObj !DevExt ObjectName\n") ; while(1) {
if (GetFieldValue(currentDeviceObject,"nt!_DEVICE_OBJECT","Type",Type)) { dprintf("%08p: Could not read device object\n", currentDeviceObject); return; }
if (Type != IO_TYPE_DEVICE) { dprintf("%08p: is not a device object\n", currentDeviceObject); return; }
GetFieldValue(currentDeviceObject,"nt!_DEVICE_OBJECT", "AttachedDevice", AttachedDevice);
if ((!AttachedDevice)||CheckControlC()) { break; }
currentDeviceObject = AttachedDevice ; }
//
// Crawl back down...
//
while(1) { ULONG64 DeviceExtension, AttachedTo;
InitTypeRead(currentDeviceObject, nt!_DEVICE_OBJECT); dprintf("%c %08p ", (currentDeviceObject == DeviceAddress) ? '>' : ' ', currentDeviceObject ) ;
DumpDevice(currentDeviceObject, 20, FALSE) ;
InitTypeRead(currentDeviceObject, nt!_DEVICE_OBJECT); dprintf("%08p ", (DeviceExtension = ReadField(DeviceExtension)));
//
// Dump the device name if present.
//
DumpObjectName(currentDeviceObject) ;
InitTypeRead(currentDeviceObject, nt!_DEVICE_OBJECT); devObjExtRead = FALSE ; if (DeviceObjectExtension = ReadField(DeviceObjectExtension)) {
//
// grab a copy of the device object extension as well
//
if(!GetFieldValue(DeviceObjectExtension,"nt!_DEVOBJ_EXTENSION", "AttachedTo",AttachedTo)) {
devObjExtRead = TRUE ; } GetFieldValue(DeviceObjectExtension,"nt!_DEVOBJ_EXTENSION", "DeviceNode", DeviceNode); }
if (!devObjExtRead) {
dprintf("\n%#08p: Could not read device object extension\n", currentDeviceObject);
return ; }
dprintf("\n"); /*
DumpFlags(0, "ExtensionFlags", deviceObjectExtension.ExtensionFlags, DeviceObjectExtensionFlags); } */ currentDeviceObject = AttachedTo ;
if ((!currentDeviceObject)||CheckControlC()) { break; }
if (GetFieldValue(currentDeviceObject,"nt!_DEVICE_OBJECT","Type",Type)) { dprintf("%08p: Could not read device object\n", currentDeviceObject); return; } }
if(DeviceNode) { UNICODE_STRING64 InstancePath, ServiceName;
dprintf("!DevNode %08p :\n", DeviceNode);
if (GetFieldValue(DeviceNode, "nt!_DEVICE_NODE", "InstancePath.Length", InstancePath.Length)) {
dprintf( "%08p: Could not read device node\n", DeviceNode );
return; } InitTypeRead(DeviceNode, nt!_DEVICE_NODE); InstancePath.MaximumLength = (USHORT) ReadField(InstancePath.MaximumLength); InstancePath.Buffer = ReadField(InstancePath.Buffer); ServiceName.Length = (USHORT) ReadField(ServiceName.Length); ServiceName.MaximumLength = (USHORT) ReadField(ServiceName.MaximumLength); ServiceName.Buffer = ReadField(ServiceName.Buffer); if (InstancePath.Buffer != 0) {
dprintf(" DeviceInst is \""); DumpUnicode64(InstancePath); dprintf("\"\n"); }
if (ServiceName.Buffer != 0) {
dprintf(" ServiceName is \""); DumpUnicode64(ServiceName); dprintf("\"\n"); } } }
|