Objects and I/O¶
- !alpc¶
Show an ALPC port, an ALPC message, or the ports that a process holds.
!alpc /p <port> !alpc /m <message> !alpc /lpp [process]
Also:
alpc/p decodes an _ALPC_PORT from its object body or header. It shows the kind, owner, and state flags of the port, and the connection, server, and client ports of its communication info. It also shows the queues of the port with the messages on them, and the threads on the wait queue. For a connection port, /p also lists the connections. /m decodes a _KALPC_MESSAGE and shows the IDs, type, sizes, and state of the message, its owner and queue ports, and the waiting and server threads. /lpp walks the handle table of a process to find ALPC ports. The process can be an EPROCESS address, a PID, or a name, and the default is the current process. /lpp first shows the connection ports that the process owns and, for each connection, the server and client ports and the client process. Then it shows the ports that the process is connected to. The number after a port is the count of its queued messages in the main, large-message, and pending queues.
- !devnode¶
Show a PnP device node and, optionally, its subtree.
!devnode [node|0] [-r|1]
Also:
devnodeShows the instance path, the service, the state and state history, the flags, the problem code, and the pending IRP of a device node. If you do not give a node, or give 0, the command shows the root device node. Use -r, or a trailing 1 as in WinDbg, to walk the subtree of the node, with one node on each line.
- !devobj¶
Show a DEVICE_OBJECT and its attached stack.
!devobj <device-object|device-name>
Also:
devobj
- !devstack¶
Show the device stack for a DEVICE_OBJECT or device node.
!devstack <device-object|devnode|device-name>
Also:
devstackThe argument can be any DEVICE_OBJECT in the stack, or the DEVICE_NODE of the stack. The command shows the stack from the top filter down to the PDO, with the !DevObj, !DrvObj, !DevExt, and object name of each device, and a
>marks the argument. After the stack, the command shows the device node of the PDO.
- !drvobj¶
Show a DRIVER_OBJECT with its device chain and dispatch table.
!drvobj <driver-object|driver-name> [flags]
Also:
drvobjThe flags follow WinDbg: 1 shows the device objects, 2 the dispatch routines; without flags, both.
- !fileobj¶
Decode a FILE_OBJECT and its relations to its device and name.
!fileobj <address>
- !fltkd.filters¶
List the registered minifilters and their instances.
!fltkd.filters
Walks each filter manager frame in fltmgr!FltGlobals and its registered filters. For each filter, the command shows its altitude and its attached instances, with their names and altitudes. The command uses the types from the PDB of fltmgr.
- !fltkd.instances¶
List minifilter instances with their filter and volume.
!fltkd.instances [filter]
Lists each instance of each registered filter. To list the instances of one filter, give its name (
WdFilter) or its _FLT_FILTER address. For each instance, the command shows its name, altitude, filter, and the volume that it is attached to.
- !fltkd.volumes¶
List the volumes that the filter manager is attached to, with their instances.
!fltkd.volumes
Walks the attached volumes of each filter manager frame. For each volume, the command shows the device name, the file-system type, and the attached instances with their names and altitudes.
- !handle¶
List a limited number of handles of the selected process, or show one handle.
!handle [handle-expression [flags [type]]]
Without an argument, the command scans up to 256 handle-table slots. With a handle, it shows the object, type, name, access mask, and attributes, if it can decode them. On a user-mode minidump it lists the handles the dump’s handle data records, as Windows reported them when the dump was written, with a count of each type. There, a handle of 0 selects every handle, flags choose what to show (1 type, 2 access, attributes, and counts, 4 name, 8 the object-specific information, such as an event’s state or a thread’s ID, that a dump written with it records for some types; the default shows all but 8), and a type, such as File, keeps only handles of that type.
- !htrace¶
Show the stacks that handle tracing recorded for the handles of a process.
!htrace [handle [process [max-traces]]]
Also:
htraceReads the ring of traces (open, close, bad reference) in the DebugInfo of the process handle table and shows the newest trace first. If handle is 0 or not given, the command shows the traces of all handles, and if max-traces is 0 or not given, it shows all traces. The process can be an EPROCESS address, a PID, or a name, and the default is the current process. Handle tracing must be on for the process before you use the command. The Handles check of Application Verifier or NtSetInformationProcess(ProcessHandleTracing) turns tracing on, and if it is off, !htrace shows a message. User-mode frames resolve after the modules of the process are loaded (.process /p). The command does not have the user-mode forms that change tracing (-enable, -disable, -snapshot, -diff).
- !irp¶
Show an IRP and its I/O stack locations.
!irp <address> [detail]
Also:
irpShows the IRP as WinDbg does: which stack location is current, the MDL, system buffer and thread, then each location from the lowest driver’s up, the current one marked with > and a run of locations the IRP has not reached as one unused line. A location shows its major and minor function, flags and control, device and file, its completion routine and context with when the routine runs (Success, Error, Cancel) and whether its driver returned pending, the device’s driver, and four arguments. The driver of the location below it in the list set that completion routine. With a second argument, such as 1, it first shows the IRP’s status, requestor mode, user event and user buffer.
- !irpfind¶
Scan pool for the IRPs that IoAllocateIrp allocates.
!irpfind [-v] [pool-type [restart-address [criteria data]]]
Also:
irpfindScans the pool region for 16-byte-aligned _POOL_HEADERs with the tag Irp. On Windows 10 1803 and later, the region comes from MiState.Vs.SystemVaRegions, and otherwise it is MmNonPagedPoolStart/End or MmPagedPoolStart/End. The scan walks the page tables and reads only mapped pages, and big allocations come from PoolBigPageTable. The command counts a block only if its body is a live _IRP. In a live _IRP, Type is 6 (IoFreeIrp clears it), and Size is the header plus whole stack locations and at least IoSizeOfIrp(StackCount). A lookaside IRP keeps its larger packet size. CurrentLocation is at most StackCount + 1. For each IRP, the command shows its thread (Tail.Overlay.Thread), the process of its MDL, and the major function, minor function, device, and owning driver of the current stack location. If CurrentLocation is more than StackCount, the IRP shows as complete. -v also shows the pool header, I/O status, PendingReturned, UserEvent, UserBuffer, and OriginalFileObject, and also the file object and completion routine of the current location. pool-type is 0 (nonpaged, the default) or 1 (paged). The command does not accept 2 (special) or 4 (session), because these pool types have no region of their own on these builds. restart-address continues a scan from that page. The criteria are the same as in WinDbg: arg (Argument1-4 of a stack location), device (DeviceObject of a stack location), fileobject (Tail.Overlay.OriginalFileObject), mdlprocess (MdlAddress->Process), thread (Tail.Overlay.Thread), and userevent (UserEvent). Use 0 as the restart address to scan the whole pool. The scan stops after 4,096 IRPs, or when you press Ctrl-C, and then shows the command that continues the scan, with the criteria. The scan checks the big-pool allocations last. If the scan gets to the limit in the big-pool allocations, the command shows a message. A restart cannot get to the remaining big-pool allocations. A driver can build IRPs in its own allocations (IoInitializeIrp). These IRPs have the tag of that driver, so the scan does not find them. Use irps to list the IRPs in thread IrpLists.
- !list¶
Run commands for each element of a typed LIST_ENTRY chain.
!list -t [module!]<type>.<field> -x "<commands>" <address>
Each command can get the element address as $extret, @extret, or @$extret. The walk stops at the head, at a repeated link, or after 4096 elements. The given address is the first element, as in WinDbg, so the walk includes all nodes until it returns to that address. In memory, a list head and a record link look the same, so if you start at a list head instead of at
poi(ListHead), the command uses the head as one pseudo-record and does not drop a real record. If the list is empty, its link points to itself, and the command runs nothing. The walk keeps the entries that it collected, and reports null links, cycles, unreadable links, and when it reaches the entry limit. Ctrl+C stops the commands between elements. A command that the session does not accept, for example a resume inside a breakpoint action, stops the element commands and the rest of the command line, but a command that only reports an error does not stop them.
- !locks¶
Show one ERESOURCE, or the resources of the system resource list that are held.
!locks [-v] [resource]
Without an argument, the command walks ExpSystemResourcesList, without scanning memory, and shows the resources a thread owns, as WinDbg’s does, each owner with its TID and process; -v shows every resource. If the symbol or the list metadata is not available, it cannot list the resources.
- !ndiskd.filter¶
List the NDIS filter modules, or show one.
!ndiskd.filter [filter]
Without an address, walks ndis!ndisGlobalFilterList and shows each filter module of every miniport: its _NDIS_FILTER_BLOCK, state, driver image, miniport, and name. With the address of a filter block, as this list or !ndiskd.miniport shows it, the command shows the filter driver, the miniport, the filter modules above and below it on the miniport’s stack, the module context (FilterModuleContext, which you can dt with the driver’s PDB), the link the filter last saw indicated, the reference count, the NBLs and status indications NDIS dropped because the filter was not running, and the pending OID request. The command needs the PDB for ndis.sys.
- !ndiskd.filterdriver¶
List the NDIS filter drivers, or show one and its filter modules.
!ndiskd.filterdriver [filterdriver]
Without an address, walks ndis!ndisFilterDriverList and shows each filter driver’s _NDIS_FILTER_DRIVER_BLOCK, friendly name, service, image, NDIS version, driver version, and number of filter modules. With the address of a filter driver block, the command shows the driver’s unique name (its GUID), DRIVER_OBJECT, the module its code is in, its driver context and flags, and its filter modules, one for each miniport it is attached to. The command needs the PDB for ndis.sys.
- !ndiskd.minidriver¶
List the NDIS miniport drivers, or show one and its miniports.
!ndiskd.minidriver [minidriver]
Without an address, walks ndis!ndisMiniDriverList and shows each miniport driver’s _NDIS_M_DRIVER_BLOCK, service name, image, NDIS version, driver version, and number of miniports. With the address of a driver block, as this list or !ndiskd.miniport shows it, the command shows the driver’s DRIVER_OBJECT, the module its code is in, its versions, and its miniports.
- !ndiskd.miniport¶
Show an NDIS miniport: its driver, state, filter stack, bindings, and pending OID.
!ndiskd.miniport [miniport]
Give the address that !ndiskd.miniports lists. The command shows the device name and instance ID, the miniport driver with its image and versions, the adapter context (MiniportAdapterContext, the driver’s own context, which you can dt with the driver’s PDB), the FDO and PDO (none for a virtual miniport), the miniport, PnP, and power states, the medium and link, the interface index and NetLuid, the reference count, the reset counts and the status of the last reset, the pending OID request with its OID, type, and buffer, and PendingReturnNBLCount. Then it shows the filter stack from the top down along each filter’s LowerFilter link, with each filter’s state, driver image, module context, and pending OID request, and the protocols bound to the miniport. A filter whose HigherFilter does not lead back ends the stack walk with the reason. Without an address, the command lists the miniports as !ndiskd.miniports does.
- !ndiskd.miniports¶
List the NDIS miniports (network adapters).
!ndiskd.miniports
Walks ndis!ndisMiniportList and shows one line per miniport: the address of its _NDIS_MINIPORT_BLOCK, which !ndiskd.miniport takes, the service of its miniport driver, the miniport state (Running, Pausing, Paused, Restarting, Initializing, Halted), the media connect state with the transmit link speed (and the receive speed when it differs), the device power state, the interface index, and the friendly name. Virtual miniports, such as Hyper-V’s adapters, are on the list too. The command needs the PDB for ndis.sys.
- !ndiskd.nbl¶
Show a NET_BUFFER_LIST and its NET_BUFFERs.
!ndiskd.nbl <nbl> [-chain] [-data]
Shows the NET_BUFFER_LIST at the address: its next and parent NBLs, its source handle with the miniport, filter module, or binding it names, its pool, context, Flags and NblFlags (by NDIS_NBL_FLAGS name), status, and child reference count, and each NET_BUFFER with its data length, data offset, current MDL and offset into it, and MDL chain. -chain lists every NBL on the Next chain from the address, with its NET_BUFFERs, bytes, source, and status. -data dumps each NET_BUFFER’s data, up to 64 KiB of it, read through the MDLs’ PFNs, so a buffer that is not mapped into system space reads too. The command needs the PDB for ndis.sys.
- !ndiskd.oid¶
Show the OID requests that miniports and filters have not completed.
!ndiskd.oid
Reads the PendingOidRequest of every miniport on ndis!ndisMiniportList and every filter module on ndis!ndisGlobalFilterList, and shows each request with its owner, type, OID by its ntddndis.h name, and buffer. NDIS passes a miniport or filter one OID request at a time, apart from direct OID requests, so a request that stays here holds up the ones behind it. The command needs the PDB for ndis.sys.
- !ndiskd.protocol¶
List the NDIS protocol drivers, or show one and its bindings.
!ndiskd.protocol [protocol]
Without an address, walks ndis!ndisProtocolList and shows each protocol’s _NDIS_PROTOCOL_BLOCK, name, image, NDIS version, driver version, and number of bindings. With the address of a protocol block, as this list or !ndiskd.miniport shows it, the command shows the protocol’s driver context, flags, and BindAdapterHandlerEx, and each binding (_NDIS_OPEN_BLOCK) with the miniport it opened and the protocol’s binding context. The command needs the PDB for ndis.sys.
- !object¶
Show an executive object header and body, and list the entries of a directory.
!object <path|object-expression>
Also:
objectA path that starts with
\is the name of an object in the object namespace (!object \,!object \Driver\ACPI). The command looks up the path from the root directory and ignores case. It does not follow symbolic links in the path. For a directory, the command lists the entries and their types.
- !pci¶
Read and decode PCI configuration space.
!pci [flags] [bus [device [function [min max]]]]
Also:
pciScans a bus (0 by default) in the same way as WinDbg. The command reads function 0 of each device, and functions 1-7 when function 0 is multi-function, and prints one line for each function. The line shows device:function, vendor:device.revision, the command and status registers, the class, and the subsystem IDs or, for a bridge, the primary->secondary-subordinate buses. Cmd letters: i I/O space, m memory space, b bus master, w memory write and invalidate, p parity error response, s SERR. Sts letters: c capability list, 6 66 MHz, p master data parity error, A signaled target abort, s signaled system error. All arguments are hex. Flags: 0x1 is verbose and decodes the full header, including the class code, the header type, the command and status bits by name, the BARs, the expansion ROM, the bridge bus numbers, the interrupt pin and line, and the capability lists. 0x2 scans buses 0 through bus. 0x4 shows the raw bytes of the 64-byte header, and 0x8 shows the same bytes as dwords. 0x40 shows the capability lists (the PCI capabilities, and the extended capabilities of a PCI Express function). 0x100 shows the raw bytes of the 256-byte configuration space. If you give a device and a function, min and max dump that range, which can include extended space (0-0xfff). Configuration space contains device registers and is not RAM, so the command reads it through the backend. Over kd/kdnet, the HAL reads it (DbgKdGetBusDataApi, segment 0). Over gdb, the QEMU stub reads the ECAM page of the function in its physical-memory mode, and the command finds this page from the ACPI MCFG table that the HAL keeps. The memory and dump backends cannot read configuration space, but !pcitree works on them. The target must be halted.
- !pcitree¶
Show the PCI bus hierarchy that pci.sys tracks, with the functions on each bus.
!pcitree
Also:
pcitreeReads the pci.sys segment list (pci!PciSegmentList), the root buses of each segment, and the functions and child buses of each bus. The data comes from the extensions of the driver (pci!_PCI_BUS and pci!_PCI_DEVICE), which exist on Windows 8 and later. Because the command reads only guest memory, it works on all backends. A bus line shows the bus number and the FDO extension. A function line shows the device and function number, the vendor and device ID, the PDO extension (devext), the PDO (devstack, for !devstack), and the class code and name. The secondary bus of a bridge follows the bridge and is indented. The JSON output also has the PnP instance path of each function.
- !pnptriage¶
Show the PnP device nodes that have problems, pending IRPs, or incomplete starts.
!pnptriage
Also:
pnptriage
- !poaction¶
Show the system power action and the power IRPs in flight.
!poaction
Also:
poactionShows nt!PopAction: the power action in progress, its state and flags, and the system state being entered, with the device notification pass when one runs. Then lists every power IRP the power manager has allocated, from nt!PopIrpList: its PDO, the device it was sent to, its minor function and the power state it asks for, where it is pending now (the driver of its current stack location), and how long the drivers have had it when the power IRP watchdog runs. Last come the threads that pass power IRPs to drivers, from nt!PopIrpThreadList, with the IRP and device each is working on.
- !podev¶
Show the power state of a device object.
!podev <device-object>
Also:
podevShows the device’s driver and power flags, the system and device power states its driver last set with PoSetPowerState (from the PowerFlags of its DEVOBJ_EXTENSION), the idle detection the driver registered, if any, the device state PnP records in the device node of the stack, whether the driver registered with the power framework and the device power IRP that it has outstanding, and the power IRPs on nt!PopIrpList sent to any device of the stack.
- !popolicy¶
Show the system power policy in effect.
!popolicy [address]
Also:
popolicyDecodes the SYSTEM_POWER_POLICY that nt!PopPolicy points to, or the one at the address you give: the action for the power button, the sleep button, closing the lid, idling, and overheating, with each action’s flags and notification events, the idle timeout and sensitivity, the lightest and deepest sleep states, the display and disk timeouts, the throttling settings, and the battery discharge levels.
- !rcdrkd.rcdrlogdump¶
Show a driver’s WPP recorder log records, oldest first.
!rcdrkd.rcdrlogdump <driver> [-a <log>]
Walks each of the driver’s recorder logs, both the normal and the error partition, back from the newest record, and shows the records of all of them merged in the order the driver logged them (their sequence numbers come from one counter per driver). -a shows only the log whose _WPP_AUTOLOG_HEADER you give, as !rcdrkd.rcdrloglist lists it. Each record shows its sequence number, its time when the log keeps timestamps, the log it is in, and its message formatted from the trace message format (TMF) annotations in a loaded PDB, or else the message GUID and number and the argument bytes. Microsoft’s public PDBs carry no TMF annotations; add your driver’s private PDB to the symbol path for its messages. The walk is !wdfkd.wdflogdump’s: the records share KMDF’s IFR format.
- !rcdrkd.rcdrloglist¶
List the drivers the WPP recorder keeps logs for, or one driver’s logs.
!rcdrkd.rcdrloglist [driver]
WppRecorder.sys keeps in-flight logs for each driver built with WPP’s recorder, such as the inbox USB, storage, and network drivers, and KMDF drivers’ own WPP messages. Without an argument, lists those drivers: each one’s recorder context (_WPP_AUTOLOG_CONTEXT), name, image base, and number of logs. With a driver, given by its name (with or without .sys) or its context, lists its logs: each _WPP_AUTOLOG_HEADER, its identifier, size, and the offsets of its normal and error partitions, and marks the default log and a deleted one. The recorder keeps no list of its drivers; the command finds each through the bugcheck callback the recorder registers for it, so it needs the PDB for WppRecorder.sys.
- !reg¶
Show the loaded registry hives, and keys and values read from them.
!reg hivelist !reg querykey|q <path> [-v <value>] !reg keyinfo <hive> <knode> !reg cellindex <hive> <cell>
The commands read the configuration manager’s hives in kernel memory, so they work on every backend, live or in a crash dump, without the guest’s help. hivelist lists each hive on nt!CmpHiveListHead: its _CMHIVE, the bytes of its stable and volatile storage, where it is mounted, such as \REGISTRY\MACHINE\SYSTEM, and the file it was loaded from. querykey (or q) shows a key: its last write time, its subkeys, and its values with their data decoded by type, REG_SZ, REG_EXPAND_SZ, and REG_LINK as text, REG_MULTI_SZ as its strings separated by \0, REG_DWORD, REG_DWORD_BIG_ENDIAN, and REG_QWORD as numbers, and other types as hex bytes. The path is a full one, \REGISTRY\MACHINE…, or starts with HKLM, HKU, HKCR (the machine’s classes), or HKCC; HKCU depends on the user, so give that user’s HKU<SID> instead. A path with spaces can be given unquoted. The path resolves as the kernel parses it: across the link of each hive to where it is mounted, and through symbolic links such as CurrentControlSet, which the output names. Long data is cut short in the list; -v
shows one value in full, its decoded data and every byte, and -v “” the default value. keyinfo shows the key whose _CM_KEY_NODE is at in the hive at , as querykey does, with its path found from its parents. cellindex shows where a cell of a hive is: the cell map directory and table, the map entry of its block and where it maps the block, and the cell’s address and size. The bins of a hive loaded from a file are a view of the file in the Registry process, whose pages Windows loads as they are used and can trim; a cell whose page is not in memory, or not in the dump, is reported as such, and the rest of the key still shows.
- !storagekd.storadapter¶
List the StorPort adapters, or show one adapter and its units.
!storagekd.storadapter [adapter]
Without an argument, walks storport’s driver list (storport!RaidpPortData) and each driver’s adapters, and shows one line per adapter: the miniport driver, the adapter extension (_RAID_ADAPTER_EXTENSION), the FDO, the PnP state, the port device name, the PCI location, the number of units, and the I/O state. With the address of an adapter extension or of its FDO, shows the adapter: its driver, device objects, PnP and power state, the miniport’s own device extension (the HwDeviceExtension that StorPort passes to every Hw routine, which you read with dt and the miniport’s private PDB) and its size, the flags (_FLAGS, _FLAGS2), the paging and crash-dump path counts, each I/O gateway’s outstanding and waiting requests, and each unit with its bus/target/LUN, PDO, state, inquiry product, and I/O state. The command needs storport’s PDB. It stops each list at the head, a null or repeated link, or 256 drivers or adapters, and says why it stopped early. Adapters of storport’s native NVMe path are listed but not decoded.
- !storagekd.storclass¶
List the storage class devices (disks, CD-ROMs), or show one with its requests and errors.
!storagekd.storclass [device]
Without an argument, walks classpnp!AllFdosList and shows each class device that classpnp drives for disk.sys, cdrom.sys, and the other class drivers: its FDO, class driver, device number, bus, vendor and product, and how many of its transfer packets are in flight. With the address of an FDO, its device extension, or its private data, shows the device: its identity and serial number, bus, lower device and PDO, capacity and sector size, timeout and retry limit, ErrorCount, each request in flight (a transfer packet that is not on classpnp’s free lists) with its IRP, the client’s IRP, the SRB, the command, and the retries, and the last 16 errors classpnp logged, each with its age, address, command, SRB and SCSI status, and sense key and code. The command needs the PDB for classpnp.sys.
- !storagekd.storlogirp¶
Show the entries of a StorPort adapter’s log that name an IRP.
!storagekd.storlogirp <adapter> <irp>
Shows the entries of the adapter’s internal log, as !storagekd.storloglist shows them, whose request is the IRP you give, or that log it as a parameter: when StorPort built, started, and saw the request completed.
- !storagekd.storloglist¶
Show a StorPort adapter’s internal log of requests, pauses, and resumes.
!storagekd.storloglist <adapter> [start [end]] [L<count>]
Give the address of an adapter extension or of its FDO, as !storagekd.storadapter lists them. StorPort keeps a ring of its last 256 events for each adapter (RaidLogList): requests it builds, starts, and sees completed, pauses and resumes of the adapter and its units, busy and ready notifications, timeouts, resets, and PnP and power IRPs. Each entry shows its number, its time (UTC), the event, and for a request its IRP, SRB, command, and SRB status, or else the four parameters StorPort logged, a code address by symbol. Without a range, the command shows the last 50 entries;
shows entries from that number, that range, and L how many.
- !storagekd.storlogsrb¶
Show the entries of a StorPort adapter’s log that name an SRB.
!storagekd.storlogsrb <adapter> <srb>
Shows the entries of the adapter’s internal log, as !storagekd.storloglist shows them, whose request carries the SRB you give, or that log it as a parameter.
- !storagekd.storsrb¶
Decode an SRB: its function, status, command, address, data, and sense.
!storagekd.storsrb <srb>
Decodes a STORAGE_REQUEST_BLOCK (an extended SRB, which StorPort, classpnp, and miniports use on Windows 8 and later) or a legacy SCSI_REQUEST_BLOCK with storport’s public PDB: the SRB function, the SRB status with QUEUE_FROZEN and AUTOSENSE_VALID, the SCSI status, the command its CDB holds with its LBA and block count, the port, path, target, and LUN, the data buffer and length, the IRP (OriginalRequest), the flags by SRB_FLAGS_ name, the timeout, tag, and priority, the sense data when AUTOSENSE_VALID says it is valid, the class, port, and miniport contexts, and an extended SRB’s extended data blocks. An address whose Function and Signature, or Length, are not an SRB’s is refused.
- !storagekd.storunit¶
Show a StorPort logical unit, its queue, and the requests the miniport holds.
!storagekd.storunit <unit>
Give the address of a unit extension (_RAID_UNIT_EXTENSION), as !storagekd.storadapter lists them, or of the unit’s PDO. Shows the unit’s bus/target/LUN, the inquiry vendor, product and revision, the adapter, the PnP and power state, the flags, the miniport’s per-unit extension (StorPortGetLogicalUnit), and its device queue: the depth, whether it is frozen or locked, the pause and busy counts, and the requests waiting in storport. Then it lists each request that storport handed to the miniport and has not seen completed, from the unit’s per-processor pending queues, with its _EXTENDED_REQUEST_BLOCK, IRP and SRB; use !irp on the IRP. It lists at most 256 requests and says why a list stopped early.
- !virtio¶
List the virtio devices and the state of their virtqueues.
!virtio [virtio-device [module]]
Also:
virtioLists the virtio PCI functions with their device type and driver. With a virtio-win driver’s private PDB loaded, it also shows each queue’s indexes and state: what the device holds, what it returned that the driver has not taken back, and what the driver has not published or kicked. Moved compares with the previous look in guest time, and from the second look the state names a queue that did not move. With an address, shows the virtio_device there, typed by the module you give or by the driver that owns it. See the virtio devices guide.
- !vpb¶
Decode a volume parameter block.
!vpb <vpb>
Also:
vpbShows the VPB_* flags, the volume device of the mounted file system, and the storage device below it, with their object names. It also shows the reference count, the serial number, and the volume label. The Vpb field of a device object points to the VPB. If the Type at the address is not IO_TYPE_VPB, the command shows an error.
- !vring¶
Show a virtqueue’s ring, its signalling, and its outstanding buffers.
!vring <virtqueue> [module] !vring /r <size> <desc> <avail> <used> [/t <kind>]
Also:
vringGive a virtqueue address that !virtio lists. Shows the ring’s indexes and state, when the driver wants interrupts and the device wants notifications (and for a split ring whether an interrupt was due), and up to 64 buffers the device holds or returned, with their descriptors (W device-writable, N continues, I indirect table). Under each buffer, a line decodes the request and the device’s answer from the virtio specification’s layouts, such as a block sector and status or a SCSI command and its sense. /r reads a split ring from its size and kernel addresses for a driver without a PDB, and /t names what its buffers hold: blk, scsi, scsi-control, scsi-event, net, net-control, gpu, or vsock. See the virtio devices guide.
- !wdfkd.wdfcrashdump¶
Show the KMDF data in a crash dump: one driver’s In-Flight Recorder log, or the client drivers.
!wdfkd.wdfcrashdump [log|loader]
When Windows writes a crash dump, Wdf01000 copies one client driver’s In-Flight Recorder log into the dump’s tagged data (WdfDumpGuid): the log of the driver whose code the bugcheck parameters point to, or of a driver set to keep its log in minidumps, or else of the last KMDF driver that ran on the processor that crashed. A minidump has no other copy of the log. Without an argument or with log, the command shows that log, oldest record first, as !wdfkd.wdflogdump shows a log in memory. Unlike WinDbg, it shows a log’s only record once, and it keeps the oldest record that survives in a log that has wrapped. With loader, it lists the client drivers that Wdf01000 recorded (WdfDumpGuid2), with the KMDF version each bound to and its _FX_DRIVER_GLOBALS; the first entry is the framework itself. The command needs the PDB for Wdf01000.
- !wdfkd.wdfdevice¶
Show a WDFDEVICE and its device objects, state machines, queues, and I/O targets.
!wdfkd.wdfdevice <WDFDEVICE>
Shows the kind of the device (FDO, filter, PDO, or control), its WDM device object, the device object that it is attached to, and the PDO of the stack. It also shows the current states of the PnP, power, and power policy state machines (_WDF_DEVICE_PNP_STATE, _WDF_DEVICE_POWER_STATE, _WDF_DEVICE_POWER_POLICY_STATE), and the device and system power states. For a PDO, it shows the parent device, and for an FDO, the child lists and the default and self I/O targets. For each queue of the I/O package, it shows the dispatch type, the power management, and the counts of pending and driver-owned requests, and it marks the default queue. For each I/O target of the device (m_IoTargetsList), it shows the WDFIOTARGET handle, the kind of target, its state, and the device object that it sends to, and it marks the default target. Pass a WDFQUEUE to !wdfkd.wdfqueue and a WDFIOTARGET to !wdfkd.wdfiotarget.
- !wdfkd.wdfdriverinfo¶
Show a KMDF client driver and its WDF devices.
!wdfkd.wdfdriverinfo <driver-name>
Give the driver name as !wdfkd.wdfldr lists it. The name is not case-sensitive, and
.sysis optional. The command shows the DRIVER_OBJECT, the FxDriver, the WDFDRIVER handle, the _FX_DRIVER_GLOBALS, the KMDF version, the registry path, and the image. Then it shows each device object on the DeviceObject/NextDevice chain of the driver object, with the related WDFDEVICE and its kind and PnP state. A device object links to its WDFDEVICE through its DeviceExtension, which KMDF sets to point to the first context of the device. The command checks the context header, the type and owner of the object, and the device object of the FxDevice, and if a check fails, it lists the device object with the reason.
- !wdfkd.wdfhandle¶
Decode a WDF handle and show its object.
!wdfkd.wdfhandle <handle>
A handle is the address of its object, XORed with ~7. An offset handle has bit 0 set and points to a WDFOBJECT_OFFSET value inside the object, which the command subtracts from the address that the handle points to. The command shows the FxObject, its type (FX_OBJECT_TYPES), size, reference count, state (FxObjectState), flags, owning driver, and parent, and each context with its type name, size, and address. Then it names the command that shows the object in full: !wdfkd.wdfdevice, !wdfkd.wdfqueue, !wdfkd.wdfrequest, or !wdfkd.wdfiotarget for those types, !wdfkd.wdfdriverinfo for a WDFDRIVER, and !wdfkd.wdfobject, which adds the children of the object, for any other type. It shows an error if the value does not decode to a kernel address, or if the type, state, size, context header, or owning driver of the object is not valid.
- !wdfkd.wdfiotarget¶
Show a WDFIOTARGET, the device object it sends to, and the requests sent to it.
!wdfkd.wdfiotarget <WDFIOTARGET>
Shows the kind of the target: local (in the device’s own stack, as the default target is), remote (a target that the driver opened with WdfIoTargetOpen), self, or a USB device or USB pipe, and whether it is the default I/O target of its device. It shows the state (_WDF_IO_TARGET_STATE), the open state of a remote target, the WDFDEVICE that the target belongs to, the device object that the target sends requests to and the driver of that device object, the PDO of that stack, the file object, the I/O count, and the stack size. Then it lists the requests on three lists: the requests sent to the target and not completed (m_SentIoListHead), the requests sent with WDF_REQUEST_SEND_OPTION_IGNORE_TARGET_STATE while the target was not started (m_IgnoredIoListHead), and the requests that the target holds until it starts (m_PendedQueue). For each request, it shows the WDFREQUEST handle, the FxRequest, and the IRP. A request without a handle is the framework’s own, such as the request that a synchronous send builds. A list stops at a request whose m_Target is not this target, with the reason.
- !wdfkd.wdfldr¶
List the KMDF client drivers.
!wdfkd.wdfldr
Walks the list at Wdf01000!FxLibraryGlobals.FxDriverGlobalsList. For each client driver, it shows the name, the KMDF version that the driver bound to (WdfBindInfo), the _FX_DRIVER_GLOBALS, the WDFDRIVER handle, the DRIVER_OBJECT, and whether the driver has an In-Flight Recorder log. The command needs the PDB for Wdf01000. The walk continues only while the Blink of each entry points back to the entry before it. A client has an empty DriverName if it bound to KMDF but did not create an FxDriver, and the command then lists the client by the name of its DRIVER_OBJECT, which you also use with !wdfkd.wdfdriverinfo and !wdfkd.wdflogdump. When a client name is not printable, or the FxDriver of a client fails the checks of its type, owner, or handle, the command lists the client with the problem.
- !wdfkd.wdflogdump¶
Show the In-Flight Recorder log of a KMDF driver, oldest record first.
!wdfkd.wdflogdump <driver-name>
Reads the IFR log of the driver (_FX_DRIVER_GLOBALS.WdfLogHeader). The command walks the records back from the newest record along PrevOffset, and stops at the first record written or at records that newer records overwrote. For each record, it shows the sequence number, the UTC time (only when the log keeps timestamps), the function, and the message. The command formats the message from the trace message format (TMF) annotations in the PDB for Wdf01000. For a record with a message that no loaded PDB declares, or with arguments that do not fit the message, it shows the message GUID, the message number, and the argument bytes. The command checks the header (its GUID, base, and size) and each record (signature, length, position, and sequence), and the walk stops at the first item that fails a check, with the reason.
- !wdfkd.wdfobject¶
Show a KMDF object’s header, contexts, and children.
!wdfkd.wdfobject <handle|FxObject>
Give a handle, as for !wdfkd.wdfhandle, or the address of an FxObject. The command shows what !wdfkd.wdfhandle shows: the handle, the type (FX_OBJECT_TYPES), size, reference count, state (FxObjectState), flags (FXOBJECT_FLAGS), owning driver, and parent, and each context with its type name, size, and address. Then it lists the children of the object (m_ChildListHead), each with its handle and type. The framework’s own children, such as the packages of a device, have no handle. Use the command for an object whose type has no command of its own, such as a WDFMEMORY, WDFTIMER, or WDFWORKITEM. The object must pass the same checks as for !wdfkd.wdfhandle, and the list of children stops at a child whose m_ParentObject is not this object.
- !wdfkd.wdfqueue¶
Show a WDFQUEUE and its configuration, state, callbacks, and requests.
!wdfkd.wdfqueue <WDFQUEUE>
Shows the dispatch type of the queue, the state bits (_FX_IO_QUEUE_STATE), the power state, and the power management. It also shows the execution level, the synchronization scope, the request counts, and the Evt callbacks that the driver set. Then it shows the requests on three lists: the requests that wait in the queue, the requests that the driver marked cancelable, and the requests presented to the driver. For each request, it shows the WDFREQUEST handle, which you pass to !wdfkd.wdfrequest, the FxRequest, and the IRP. If a request is not valid, the command stops that list at the request and shows the reason.
- !wdfkd.wdfrequest¶
Show a WDFREQUEST, its IRP, its queue, and the I/O target it was sent to.
!wdfkd.wdfrequest <WDFREQUEST>
Shows the FxRequest, its owning driver, parent, reference count, and object state. For the IRP of the request, it shows the current stack location: the major and minor function, the device object and its driver, and the buffer lengths of a read, a write, or a device control with its control code. It also shows the system buffer, the user buffer, and the MDL of the IRP; pass the IRP to !irp for all of its stack locations. If the IRP was freed or reused, the command shows why it is not a live IRP. The command shows whether the IRP came from the I/O manager or the framework or the driver allocated it (FxRequestAllocationSource), whether the request is completed or canceled, and whether its queue presented it to the driver. It shows the queue that the request came from or waits in (m_IoQueue) and the cancel-safe queue that holds the IRP: the requests that wait in the queue, the requests that the driver marked cancelable with its EvtRequestCancel routine, which the command shows, or the requests that an I/O target holds until it starts. A request that none of these holds cannot be canceled. For a request that the driver sent, it shows the I/O target (m_Target), the completion routine and its context, and the target flags (FxRequestTargetFlags). KMDF sets the verifier flags (FxRequestVerifierFlags) only when its verifier is on for the driver.
- callbacks¶
List the process, thread, and image notification callbacks.
callbacks [symbol-filter]
- irps¶
Find the in-flight IRPs in thread IrpLists and device CurrentIrp fields.
irps [process-filter|driver-filter]
- ssdt¶
Show the SSDT and the shadow SSDT.
ssdt