Definition: A PDO is a Physical Device Object.
This entry is not going into how to enumerate a PDO or the rules involved in PDO enumeration and management.
There are two types of PDOs. A raw PDO and a PDO which is not raw (e.g. cooked). Assume that the term “PDO” always refers to a cooked PDO and that a raw PDO will always be referred to as a “raw PDO.”
A PDO will typically not expose an I/O interface for general usage, rather it’s I/O interface will be for the FDO that will load on top of it. A PDO will handle a very specific set of PIRPs and may provide callbacks to the stack’s FDO.
Why would a bus driver create a raw PDO vs a PDO? A raw PDO is the combination of functionality of a PDO and FDO into one device object. Typically the bus driver does not know how the PDO will function. As an example, pci.sys will enumerate a PDO for your NIC when it detects the device. The PDO represents the device’s presence and it’s hardware resource requirements. The PDO without the FDO is useless, it is not a NIC. PCI.sys does not know how to expose a NIC I/O interface on the PDO. PCI.sys just know how to identify the device via properties like hardware IDs or compatible IDs. The FDO that loads on the PDO is the device object that exposes the NIC I/O interface.
On the other hand, if the bus knows how the PDO works, it can expose the PDO as raw. When a PDO is marked as raw, no FDO is required to be loaded on the PDO. The device stack will typically be just the PDO, no other device attached to it. Note that this is not always the case, you can still load a device stack on a raw PDO. When marked as raw, the PDO will start immediately, without waiting for the PnP manager to try to make an INF match. As an in box example, hidclass.sys enumerates all of its PDOs as raw. They are raw since HIDCLASS uses PDOs to distinguish between separate top level collections and it knows how each PDO can function, so there is no need for an FDO on top of its PDOs.