Bus drivers for buses with configuration space must handle this request for their child devices (child PDOs). Filter and function drivers do not handle this request.



Major Code


When Sent

A driver or other system component sends this IRP to read the configuration space of a device's parent bus.

A driver or other system component sends this IRP at IRQL < DISPATCH_LEVEL in an arbitrary thread context.

Input Parameters

The Parameters.ReadWriteConfig member of the IO_STACK_LOCATION structure is itself a structure containing the following information:

ULONG WhichSpace;
PVOID Buffer;
ULONG Offset;
ULONG Length

The members of the structure can be interpreted differently by different bus drivers, but the members are typically defined as follows:

Specifies which memory area to access. This parameter can take the following values:

Value Bus Meaning



PCI configuration space.



Read-only memory.




Main PCCARD memory.




PCMCIA attribute (configuration) space.



PCI configuration space.

The PCI_XXX values are defined in Wdm.h. The PCCARD_XXX values are defined in Ntddpcm.h.

Points to a buffer in which to return the requested information. The component sending the IRP allocates this structure from paged memory. The format of the buffer is bus-specific.

Specifies an offset into the configuration space.

Specifies the number of bytes to read.

Output Parameters

On success, a bus driver fills the buffer at Parameters.ReadWriteConfig.Buffer with the requested data.

I/O Status Block

A bus driver sets Irp->IoStatus.Status to STATUS_SUCCESS or to an appropriate error status such as STATUS_INVALID_PARAMETER_n, STATUS_NO_SUCH_DEVICE, or STATUS_DEVICE_NOT_READY.

On success, a bus driver sets Irp->IoStatus.Information to the number of bytes returned.

If a bus driver is unable to complete this request immediately it can mark the IRP pending, return STATUS_PENDING, and complete the IRP at a later time.


A bus driver handles this IRP for its child devices (child PDOs).

Function and filter drivers do not handle this IRP; they pass it to the next lower driver with no changes to Irp->IoStatus.Status and they do not set an IoCompletion routine.

A bus driver that handles this request should check the WhichSpace parameter to ensure that it contains a value that the driver supports.

See Plug and Play for the general rules for handling Plug and Play minor IRPs.

Sending This IRP

Typically, a function driver sends this IRP to the top driver in the device stack to which it is attached and the IRP is handled by the parent bus driver.

See Handling IRPs for information about sending IRPs. The following steps apply specifically to this IRP:

  • Allocate a buffer from a paged pool and initialize it to zeros.

  • Set the values in the next I/O stack location of the IRP: set MajorFunction to IRP_MJ_PNP, set MinorFunction to IRP_MN_READ_CONFIG, and set the appropriate values in Parameters.ReadWriteConfig.

  • Initialize IoStatus.Status to STATUS_NOT_SUPPORTED.

  • Deallocate the IRP and the buffer when they are no longer needed.

Drivers must send this IRP from IRQL < DISPATCH_LEVEL.

A driver can access a bus's configuration space at DISPATCH_LEVEL through a bus interface routine, if the parent bus driver supports such an interface. To get a bus interface, a driver sends an IRP_MN_QUERY_INTERFACE request to the device stack in which the driver is attached. The driver then calls the appropriate routine returned in the interface.

For example, to read configuration space from DISPATCH_LEVEL, a driver can call IRP_MN_QUERY_INTERFACE during driver initialization to get the BUS_INTERFACE_STANDARD interface from the parent bus driver. The driver sends the query IRP from IRQL PASSIVE_LEVEL. Later, from code at IRQL DISPATCH_LEVEL, the driver calls the appropriate routine returned in the interface, such as the Interface.GetBusData routine.



Wdm.h (include Wdm.h, Ntddk.h, or Ntifs.h)

See also