/*++ Copyright (c) 1998 Microsoft Corporation Module Name: thermal Abstract: WinDbg Extension Api Author: Environment: User Mode. Revision History: --*/ #include "precomp.h" #include "devnode.h" #pragma hdrstop DECLARE_API(locks); BOOLEAN DumpDeviceActionEntry( IN PDEBUG_CLIENT pDbgClient, IN ULONG64 Entry ) { ULONG64 deviceObject, requestType, requestArgument, module; ULONG typeId; CHAR name[MAX_PATH]; dprintf("Dumping nt!_PI_DEVICE_REQUEST @ 0x%08p\n", Entry); if (GetFieldValue(Entry, "nt!_PI_DEVICE_REQUEST", "DeviceObject", deviceObject)) { dprintf("Error reading entry->DeviceObject (%#010p)\n", Entry); return FALSE; } if (GetFieldValue(Entry, "nt!_PI_DEVICE_REQUEST", "RequestType", requestType)) { dprintf("Error reading entry->RequestType (%#010p)\n", Entry); return FALSE; } if (ExtQuery(pDbgClient) != S_OK) { dprintf("Could not query debugger information\n"); return FALSE; } if (g_ExtSymbols->GetSymbolTypeId("nt!_DEVICE_REQUEST_TYPE", &typeId, &module) != S_OK) { dprintf("Error reading name for request type\n"); return FALSE; } if (g_ExtSymbols->GetConstantName(module, typeId, requestType, name, sizeof(name), NULL) != S_OK) { dprintf("Error reading name for request type\n"); return FALSE; } dprintf("\tRequest to %s", name); if (deviceObject) { dprintf(" !devstack %08p\n", deviceObject); } else { dprintf("\n"); } if (GetFieldValue(Entry, "nt!_PI_DEVICE_REQUEST", "RequestArgument", requestArgument)) { dprintf("Error reading entry->RequestType (%#010p)\n", Entry); return FALSE; } dprintf("\tArgument - %08p\n", requestArgument); ExtRelease(); return TRUE; } DECLARE_API(pnpaction) /*++ Routine Description: Dumps device action queue. Arguments: args - Verbosity. Return Value: None --*/ { ULONG64 deviceActionListAddress, enumerationInProgressAddress; ULONG64 link, deviceActionEntry; ULONG offset, dummy; BOOLEAN enumerationInProgress; enumerationInProgressAddress = GetExpression("nt!PipEnumerationInProgress"); if (enumerationInProgressAddress == 0) { dprintf("Error retrieving address of nt!PipEnumerationInProgress\n"); return E_INVALIDARG; } enumerationInProgress = FALSE; if (!ReadMemory(enumerationInProgressAddress, &enumerationInProgress, sizeof(enumerationInProgress), &dummy)) { dprintf("Error retrieving value of nt!IopPnpEnumerationRequestList\n"); return E_INVALIDARG; } deviceActionListAddress = GetExpression("nt!IopPnpEnumerationRequestList"); if (deviceActionListAddress == 0) { dprintf("Error retrieving address of nt!IopPnpEnumerationRequestList\n"); return E_INVALIDARG; } dprintf("\n********************************************************************************\n"); dprintf("Dumping PnP DeviceAction Queue @ 0x%08p\n", deviceActionListAddress); dprintf("********************************************************************************\n\n"); if (GetFieldValue(deviceActionListAddress, "nt!_LIST_ENTRY", "Flink", link)) { dprintf("Error reading IopPnpEnumerationRequestList.Flink (%#010p)\n", deviceActionListAddress); return E_INVALIDARG; } if (GetFieldOffset("nt!_PI_DEVICE_REQUEST", "ListEntry", &offset)) { dprintf("Cannot find nt!_PI_DEVICE_REQUEST type.\n"); return E_INVALIDARG; } while (link != deviceActionListAddress && CheckControlC() == FALSE) { deviceActionEntry = link - offset; // CONTAINING_RECORD(link, PI_DEVICE_REQUEST, ListEntry); if (!DumpDeviceActionEntry(Client, deviceActionEntry)) { return E_INVALIDARG; } if (GetFieldValue(deviceActionEntry, "nt!_PI_DEVICE_REQUEST", "ListEntry.Flink", link)) { dprintf("Error reading deviceRequest->ListEntry.Flink (%#010p)\n", deviceActionEntry); return E_INVALIDARG; } } if (enumerationInProgress) { dprintf("PnP DeviceActionWorker active!\n\n"); } return S_OK; } DECLARE_API(pnptriage) /*++ Routine Description: Helps triage PnP issues (mostly stress). Arguments: args - Stress or otherwise. Return Value: None --*/ { // // Dump the PnP device action queue. // if (pnpaction(Client, "") == S_OK) { // // Dump the PnP event queue. // if (pnpevent(Client, "") == S_OK) { // // Dump devnodes with problems. // dprintf("\n********************************************************************************\n"); dprintf("Dumping devnodes with problems...\n"); dprintf("********************************************************************************\n\n"); devnode(Client, "0 21"); // // Dump our locks. // dprintf("\n********************************************************************************\n"); dprintf("Dumping PnP locks...\n"); dprintf("********************************************************************************\n\n"); locks(Client, "nt!PiEngineLock"); locks(Client, "nt!IopDeviceTreeLock"); locks(Client, "nt!PpRegistryDeviceResource"); dprintf("\n********************************************************************************\n"); dprintf("If NOT available, do !thread on the owner thread to find the thread hung in PnP\n"); dprintf("********************************************************************************\n\n"); } } return S_OK; }