Eric Kohl wrote:
Do you have an official definition of the _DEVICE_NODE
structure? I am
asking because I don't know whether I should keep the BusInformation
component in _DEVICE_NODE or remove it. I am pretty sure we need the
BusNumber and InterfaceType in _DEVICE_NODE but I am not sure about
BusTypeGuid?
See the attached file (at the end). It's taken from my notes and
contains a _DEVICE_NODE definition with some minor annotations.
Ooops, I forgot to mention that one of my machines
freezes while pci.sys
enumerates devices on the pci bus. This has nothing to do with the RTL8139
driver.
Reminds me we need implement support for PCI-to-PCI bridges (by stacking
another instance of pci.sys on top of the corresponding PDO) so that we
can enumerate the RTL card on Gerard's computer.
Regards,
Filip
Plug & Play Device Nodes
------------------------
One of the main structures in PnP is the device node. Each device
(or virtual device) present in the system has it's corresponding
device node which stores all information about the device it belongs
to including it's state, resource requirements, currently assigned
resources and device objects (it directly refers only to PDO, but
other device objects are accessible too).
These device nodes are grouped together in a tree which stores
all the devices in the system. On the top of the tree sits the virtual
root device node that groups together legacy device drivers, bus
drivers and drivers that don't control any physical device. The virtual
root bus is implemented in the kernel itself and enumerates it's
children based on the settings present in the registry (HKLM\System\
CurrentControlSet\Enum).
Let's look at a portion of typical device node tree:
/--------\
| TCP/IP |
\--------/ - ...
| /
/----------\ /----------\ /---------\ / /-------------\
| Root Bus |--| ACPI HAL |--| PCI Bus |----| Display Card |
\----------/ \----------/ \---------/ \ \-------------/
| \ /---------\ \ /---------------\
\ ... -| ISA Bus | -| USB Controller |-- ...
\---------/ \---------------/
In this example you can see that there is a TCP/IP service and
ACPI bus enumerated by the root bus. The ACPI HAL is a virtual bus
driver which is located in the HAL and might not be present depending
on computer and Windows configuration. Down the stack we can see the
PCI and ISA bus drivers which were itself enumerated by the ACPI HAL
and that enumerate other devices connected to them.
Plug & Play Enumeration
-----------------------
<!!!nonsense!!!>
During the system start all the drivers must be loaded. This is
accomplished by recursively iterating through the device node tree.
At first the root bus device node is created and it's called to
enumerate it's children. Then all the children drivers are loaded
and called to enumerate their children and so one. For each enumerated
device a physical device object (PDO) is created and if everything
goes right an functional device object (FDO) is attached on top of it.
The parent bus drivers supply the PDOs for their devices and the
drivers corresponding to these devices attach their FDOs.
</!!!nonsense!!!>
* IoInvalidateDeviceRelations
typedef struct _PO_DEVICE_NOTIFY
{
LIST_ENTRY Link;
PDEVICE_OBJECT TargetDevice;
UCHAR WakeNeeded;
UCHAR OrderLevel;
PDEVICE_OBJECT DeviceObject;
struct _DEVICE_NODE *Node;
WCHAR *DeviceName;
WCHAR *DriverName;
ULONG ChildCount;
ULONG ActiveChild;
} PO_DEVICE_NOTIFY, *PPO_DEVICE_NOTIFY;
typedef enum _PNP_DEVNODE_STATE
{
DeviceNodeUnspecified = 0x300
DeviceNodeUninitialized,
DeviceNodeInitialized,
DeviceNodeDriversAdded,
DeviceNodeResourcesAssigned,
DeviceNodeStartPending,
DeviceNodeStartCompletion,
DeviceNodeStartPostWork,
DeviceNodeStarted,
DeviceNodeQueryStopped,
DeviceNodeStopped,
DeviceNodeRestartCompletion,
DeviceNodeEnumeratePending,
DeviceNodeEnumerateCompletion,
DeviceNodeAwaitingQueuedDeletion,
DeviceNodeAwaitingQueuedRemoval,
DeviceNodeQueryRemoved,
DeviceNodeRemovePendingCloses,
DeviceNodeRemoved,
DeviceNodeDeletePendingCloses,
DeviceNodeDeleted
} PNP_DEVNODE_STATE, *PPNP_DEVNODE_STATE;
typedef enum {
DOCK_NOTDOCKDEVICE = 0,
DOCK_QUIESCENT,
DOCK_ARRIVING,
DOCK_DEPARTING,
DOCK_EJECTIRP_COMPLETED
} PNP_DOCK_STATUS;
typedef struct _DEVICE_NODE
{
/* A tree structure. */
struct _DEVICE_NODE *Sibling;
struct _DEVICE_NODE *Child;
struct _DEVICE_NODE *Parent;
struct _DEVICE_NODE *LastChild;
/* The level of deepness in the tree. */
UINT Level;
/* */
PPO_DEVICE_NOTIFY Notify;
/* State machine. */
PNP_DEVNODE_STATE State;
PNP_DEVNODE_STATE PreviousState;
PNP_DEVNODE_STATE StateHistory[20];
UINT StateHistoryEntry;
/* ? */
INT CompletionStatus;
/* ? */
PIRP PendingIrp;
/* See DNF_* flags below (WinDBG documentation has WRONG values) */
ULONG Flags;
/* See DNUF_* flags below */
ULONG UserFlags;
/* See CM_PROB_* values are defined in cfg.h */
ULONG Problem;
/* Pointer to the PDO corresponding to the device node. */
PDEVICE_OBJECT PhysicalDeviceObject;
/* Resource list as assigned by the PnP arbiter. See IRP_MN_START_DEVICE
and ARBITER_INTERFACE (not documented in DDK, but present in headers). */
PCM_RESOURCE_LIST ResourceList;
/* Resource list as assigned by the PnP arbiter (translated version). */
PCM_RESOURCE_LIST ResourceListTranslated;
/* Instance path relative to the Enum key in registry. */
UNICODE_STRING InstancePath;
/* Name of the driver service. */
UNICODE_STRING ServiceName;
/* ? */
PDEVICE_OBJECT DuplicatePDO;
/* See IRP_MN_QUERY_RESOURCE_REQUIREMENTS. */
PIO_RESOURCE_REQUIREMENTS_LIST ResourceRequirements;
/* Information about bus for bus drivers. */
INTERFACE_TYPE InterfaceType;
ULONG BusNumber;
/* Information about underlying bus for child devices. */
INTERFACE_TYPE ChildInterfaceType;
ULONG ChildBusNumber;
USHORT ChildBusTypeIndex;
/* ? */
UCHAR RemovalPolicy;
UCHAR HardwareRemovalPolicy;
LIST_ENTRY TargetDeviceNotify;
LIST_ENTRY DeviceArbiterList;
LIST_ENTRY DeviceTranslatorList;
USHORT NoTranslatorMask;
USHORT QueryTranslatorMask;
USHORT NoArbiterMask;
USHORT QueryArbiterMask;
ULONG OverUsed1;
ULONG OverUsed2;
/* See IRP_MN_QUERY_RESOURCES. */
PCM_RESOURCE_LIST BootResources;
/* See the bitfields in DEVICE_CAPABILITIES structure. */
ULONG CapabilityFlags;
struct {
ULONG DockStatus;
LIST_ENTRY ListEntry;
WCHAR *SerialNumber;
} DockInfo;
ULONG DisableableDepends;
LIST_ENTRY PendedSetInterfaceState;
LIST_ENTRY LegacyBusListEntry;
ULONG DriverUnloadRetryCount;
} DEVICE_NODE, *PDEVICE_NODE;
#ifdef _W2K_
#define DNF_MADEUP 1
#define DNF_HAL_NODE 4
#define DNF_PROCESSED 8
#define DNF_ENUMERATED 0x10
#define DNF_ADDED 0x40
#define DNF_HAS_BOOT_CONFIG 0x80
#define DNF_BOOT_CONFIG_RESERVED 0x100
#define DNF_NO_RESOURCE_REQUIRED 0x400
#define DNF_STARTED 0x40000
#else
#define DNF_MADEUP 1
#define DNF_HAL_NODE 4
#define DNF_ENUMERATED 0x10
#define DNF_IDS_QUERIED 0x20
#define DNF_HAS_BOOT_CONFIG 0x40
#define DNF_BOOT_CONFIG_RESERVED 0x80
#define DNF_NO_RESOURCE_REQUIRED 0x100
#define DNF_RESOURCE_REQUIREMENTS_NEED_FILTERED 0x200
#endif
#define DNUF_DONT_SHOW_IN_UI 2
#define DNUF_NOT_DISABLEABLE 8
/* CM_PROB_* values are defined in cfg.h */