I used below code segment to try to access the extended config space of an
PCI express card on Windows Vista, when the offset is not greater then 0xfc,
the
value can be read to the buffer. But if offset is greater then 0xfc, the
read will fail and the status is returned as 0xC0000010, I checked
the error code, it means "STATUS_INVALID_DEVICE_REQUEST". But from the
document PCI-PCIe_FAQ.doc downloaded from
http://www.microsoft.com/taiwan/whdc.../PCIe_FAQ.mspx, the
extended space should be accessable on Vista.
Windows Vista and Windows Server Longhorn. To access extended configuration
space on these operating systems, drivers should use documented interfaces
such as BUS_INTERFACE_STANDARD and IRP_MJ_PNP requests with
IRP_MN_READ_CONFIG or IRP_MN_WRITE_CONFIG. These interfaces have been
extended in Windows Vista and Windows Server Longhorn to support accessing
extended configuration space.
I used WDK 6000 to build the code.
PAGED_CODE();
KeInitializeEvent( &event, NotificationEvent, FALSE );
targetObject = IoGetAttachedDeviceReference( DeviceObject );
irp = IoBuildSynchronousFsdRequest( IRP_MJ_PNP,
targetObject,
NULL,
0,
NULL,
&event,
&ioStatusBlock );
if (irp == NULL) {
status = STATUS_INSUFFICIENT_RESOURCES;
goto End;
}
irpStack = IoGetNextIrpStackLocation( irp );
if (ReadOrWrite == 0) {
irpStack->MinorFunction = IRP_MN_READ_CONFIG;
}else {
irpStack->MinorFunction = IRP_MN_WRITE_CONFIG;
}
DbgPrint("ReadWriteConfigSpace:Offset 0x%x\n", Offset);
irpStack->Parameters.ReadWriteConfig.WhichSpace = PCI_WHICHSPACE_CONFIG;
irpStack->Parameters.ReadWriteConfig.Buffer = Buffer;
irpStack->Parameters.ReadWriteConfig.Offset = Offset;
irpStack->Parameters.ReadWriteConfig.Length = Length;
// Initialize the status to error in case the bus driver does not
// set it correctly.
irp->IoStatus.Status = STATUS_NOT_SUPPORTED ;
status = IoCallDriver( targetObject, irp );
if (status == STATUS_PENDING) {
KeWaitForSingleObject( &event, Executive, KernelMode, FALSE, NULL );
status = ioStatusBlock.Status;
}
End:
// Done with reference
ObDereferenceObject( targetObject );
DbgPrint("ReadWriteConfigSpace:Status = 0x%x\n", status);
return status;