|
|
/*++
Copyright (c) 1992 Microsoft Corporation
Module Name:
device.c
Abstract:
WinDbg Extension Api
Author:
Wesley Witt (wesw) 15-Aug-1993
Environment:
User Mode.
Revision History:
--*/
#include "precomp.h"
#pragma hdrstop
//-----------------------------------------------------------------------------------------
//
// api declaration macros & api access macros
//
//-----------------------------------------------------------------------------------------
extern WINDBG_EXTENSION_APIS ExtensionApis;
#define KD_OBJECT_HEADER_TO_QUOTA_INFO( roh, loh ) (POBJECT_HEADER_QUOTA_INFO) \
((loh)->QuotaInfoOffset == 0 ? NULL : ((PCHAR)(roh) - (loh)->QuotaInfoOffset))
#define KD_OBJECT_HEADER_TO_HANDLE_INFO( roh, loh ) (POBJECT_HEADER_HANDLE_INFO) \
((loh)->HandleInfoOffset == 0 ? NULL : ((PCHAR)(roh) - (loh)->HandleInfoOffset))
#define KD_OBJECT_HEADER_TO_NAME_INFO( roh, loh ) (POBJECT_HEADER_NAME_INFO) \
((loh)->NameInfoOffset == 0 ? NULL : ((PCHAR)(roh) - (loh)->NameInfoOffset))
#define KD_OBJECT_HEADER_TO_CREATOR_INFO( roh, loh ) (POBJECT_HEADER_CREATOR_INFO) \
(((loh)->Flags & OB_FLAG_CREATOR_INFO) == 0 ? NULL : ((PCHAR)(roh) - sizeof(OBJECT_HEADER_CREATOR_INFO))))
VOID DumpDevice( PVOID DeviceAddress, BOOLEAN FullDetail );
VOID PrintDeviceObject(PVOID fieldPtr, ULONG fieldProxy, ULONG printDetail) { dprintf("Device Object @ %08x\n", fieldProxy); DumpDevice((PVOID)fieldProxy, TRUE); }
VOID DumpDevice( PVOID DeviceAddress, BOOLEAN FullDetail )
/*++
Routine Description:
Displays the driver name for the device object if FullDetail == FALSE. Otherwise displays more information about the device and the device queue.
Arguments:
DeviceAddress - address of device object to dump. FullDetail - TRUE means the device object name, driver name, and information about Irps queued to the device.
Return Value:
None
--*/
{ ULONG result; ULONG i; PUCHAR buffer; DEVICE_OBJECT deviceObject; UNICODE_STRING unicodeString; PLIST_ENTRY nextEntry; PVOID queueAddress; PIRP irp; KDEVICE_QUEUE_ENTRY queueEntry; POBJECT_HEADER pObjectHeader; OBJECT_HEADER objectHeader; POBJECT_HEADER_NAME_INFO pNameInfo; OBJECT_HEADER_NAME_INFO NameInfo;
if ((!ReadMemory( (DWORD)DeviceAddress, &deviceObject, sizeof(deviceObject), &result)) || (result < sizeof(deviceObject))) { dprintf("%08lx: Could not read device object\n", DeviceAddress); return; }
if (deviceObject.Type != IO_TYPE_DEVICE) { dprintf("%08lx: is not a device object\n", DeviceAddress); return; }
if (FullDetail == TRUE) {
//
// Dump the device name if present.
//
pObjectHeader = OBJECT_TO_OBJECT_HEADER(DeviceAddress); if (ReadMemory( (DWORD)pObjectHeader, &objectHeader, sizeof(objectHeader), &result) && (result == sizeof(objectHeader))) { pNameInfo = KD_OBJECT_HEADER_TO_NAME_INFO( pObjectHeader, &objectHeader ); if (ReadMemory((DWORD)pNameInfo, &NameInfo, sizeof(NameInfo), &result) && (result == sizeof(NameInfo))) { buffer = LocalAlloc(LPTR, NameInfo.Name.MaximumLength); if (buffer != NULL) { unicodeString.MaximumLength = NameInfo.Name.MaximumLength; unicodeString.Length = NameInfo.Name.Length; unicodeString.Buffer = (PWSTR)buffer; if (ReadMemory((DWORD)NameInfo.Name.Buffer, buffer, unicodeString.Length, &result) && (result == unicodeString.Length)) { dprintf(" %wZ", &unicodeString); } LocalFree(buffer); } } } }
// DumpDriver((PVOID) deviceObject.DriverObject, FALSE);
if (FullDetail == TRUE) { //
// Dump Irps related to driver.
//
dprintf(" DriverObject %08lx\n", deviceObject.DriverObject); dprintf("Current Irp %08lx RefCount %d Type %08lx ", deviceObject.CurrentIrp, deviceObject.ReferenceCount, deviceObject.DeviceType); if (deviceObject.AttachedDevice) { dprintf("AttachedDev %08lx ", deviceObject.AttachedDevice); } if (deviceObject.Vpb) { dprintf("Vpb %08lx ", deviceObject.Vpb); }
dprintf("DevExt %08lx\n", deviceObject.DeviceExtension);
if (deviceObject.DeviceQueue.Busy) {
if (IsListEmpty(&deviceObject.DeviceQueue.DeviceListHead)) { dprintf("Device queue is busy -- Queue empty\n"); } else { dprintf("DeviceQueue: "); nextEntry = deviceObject.DeviceQueue.DeviceListHead.Flink; i = 0;
while ((PCH) nextEntry != (PCH) ((PCH) DeviceAddress + ((PCH) &deviceObject.DeviceQueue.DeviceListHead.Flink - (PCH) &deviceObject))) { queueAddress = CONTAINING_RECORD(nextEntry, KDEVICE_QUEUE_ENTRY, DeviceListEntry); if ((!ReadMemory((DWORD)queueAddress, &queueEntry, sizeof(queueEntry), &result)) || (result < sizeof(queueEntry))) { dprintf("%08lx: Could not read queue entry\n", DeviceAddress); return; }
irp = CONTAINING_RECORD(&queueEntry, IRP, Tail.Overlay.DeviceQueueEntry);
dprintf("%08lx%s", irp, (i & 0x03) == 0x03 ? "\n\t " : " "); if (CheckControlC()) { break; } } dprintf("\n"); } } else { dprintf("Device queue is not busy.\n"); } } }
|