㈠ windows api 某设备插在哪个pci插槽上
PCI Express是新一代的总线接口,而采用此类接口的显卡产品,从2004年下半年开始已经全面面世。早在2001年的春季“英特尔开发者论坛”上,英特尔公司就提出了要用新一代的技术取代PCI总线和多种芯片的内部连接,并称之为第三代I/O总线技术。随后在2001年底,包括Intel、AMD、DELL、IBM在内的20多家业界主导公司开始起草新技术的规范,并在2002年完成,对其正式命名为PCI Express。
PCI Express采用了目前业内流行的点对点串行连接,比起PCI以及更早期的计算机总线的共享并行架构,每个设备都有自己的专用连接,不需要向整个总线请求带宽,而且可以把数据传输率提高到一个很高的频率,达到PCI所不能提供的高带宽。相对于传统PCI总线在单一时间周期内只能实现单向传输,PCI Express的双单工连接能提供更高的传输速率和质量,它们之间的差异跟半双工和全双工类似。
PCI Express的接口根据总线位宽不同而有所差异,包括1X、4X、8X以及16X(2X模式将用于内部接口而非插槽模式)。较短的PCI Express卡可以插入较长的PCI Express插槽中使用。PCI Express接口能够支持热拔插,这也是个不小的飞跃。PCI Express卡支持的三种电压分别为+3.3V、3.3Vaux以及+12V。用于取代AGP接口的PCI Express接口位宽为16X,能够提供上行、下行2 X 4GB/s的带宽,远远超过AGP 8X的2.1GB/s的带宽。
PCI Express推出之初,相应的图形芯片对其的支持分为原生(Native)和桥接(Bridge)两种。ATI是最先推出原生PCI Express图形芯片的公司,而NVIDIA公司首先提出了桥接的过渡方法,让针对AGP 8X开发的图形芯片也能够生产出PCI Express接口的显示卡。但是桥接的PCI Express显示卡实际上并不能真正利用PCI Express 16X的2 X 4GB/s的带宽。但也有观点认为ATI最初推出的原生PCI Express图形芯片并非真正的“原生”,但迄今这一说法并未被证实。
所谓AGP(Accelerated Graphics Port)是Intel公司配合PentiumII处理器开发的总线标准,它是建立PCI总线基础上、专门针对3D图形处理而开发的高效能总线。
首先PCI Express和PCI不同的是实现了传输方式从并行到串行的转变。PCI Express是采用点对点的串行连接方式,这个和以前的并行通道大为不同,它允许和每个设备建立独立的数据传输通道。不用再向整个系统请求带宽,这样也就轻松的到达了其他接口设备可望而不可及的高带宽。
PCI Express接口根据总线接口对位宽的要求不同而有所差异,分为PCI Express1X、2X、4X、8X、16X甚至32X。由此PCI Express的接口长短也不同。1X最小,往上侧越大。同时PCI Express不同接口还可以向下兼容其他PCI Express小接口的的产品。既PCI Express4X的设备可以插在PCI Express8X或16X上进行工作。这样,只要您拥有先进的主板,就没必要非得升级档次稍差的显卡了。它良好的向下兼容性也使不少业界人士看好。
另外Intel 的PCI Express接口将包括两条专用的通道连接某设备,比如即将要取代AGP 8X的PCI Express16X图形接口将包括它的两条通道,一条可由显卡单独到北桥,而另一条则可由北桥单独到显卡,每条单独的通道均将拥有4GB/s的数据带宽可充分避免因带宽所带来的性能瓶颈问题。
同时PCI Express还支持热插拔及热交换的特性,也就是说,你可以在不必关闭系统和电源的情况下更换PCI Express槽的版卡和各种硬件设备。由以上两点可以看出在未来PCI Express在服务器的应用上估计会更为深远。
推断:据以上文字,你可以用pci-e4x的设备插在pci-e16x上,而用pci-e 16x的显卡插在pci-e 4x上是行不通的。因为它具有向下兼容性。
4X的可以用在16的插槽上~~
㈡ 如何读取PCIE设备
玩游戏时死机花屏的原因较多,一是显卡自身的硬件问题,比如显卡的显存有轻微损坏、显卡的做工用料不好或兼容性不佳,都会导致显卡的电气性能大打折扣,如出现这种情况最好用替换法进行确认。由于使用的是AGP8×显卡,用户还可以在BIOS里把显卡工作速率调整为AGP4×试试,还有就是显卡最好不要轻易超频。另外,导致玩3D游戏时死机的原因还可能是显卡散热不佳,请认真检查一下显卡的散热器是否正常。
一、驱动问题,这也是引起花屏的重要原因,多出现于更换显卡驱动版本之后,也有可能是因为驱动文件损坏所导致。解决的办法很简单,重装通过微软WHQL认证的驱动,版本不必一味求新。花屏时首先要检查的就是显卡驱动,符合先软后硬的原则。
二、温度问题,这个问题不仅仅是因为显卡,处理器、内存甚至主板的芯片组温度过高也会引起花屏,这样的情况多发生于夏天,但是冬天时,如果散热器脱落、风扇停转,在室内也很有可能会出现硬盘温度过高的情况,同样是不可忽视的,建议打开机箱检查一下各个散热器的安装情况,试着敞开机箱运行游戏,看看会不会再次花屏,故障消失或时间后延的话基本可以确定是温度问题。
三、供电问题,包括电源和主板的AGP/PCI-E 16X供电,如果显卡得不到充足的、纯净的电流,同样有可能会出现花屏的情况。解决的办法是先断开光驱、独立声卡等非必备硬件,降低整机负载后重试。
四、显卡问题,原因非常多。有可能是显卡的BIOS有缺陷,这个可以通过刷新VGA BIOS解决;也有可能是显存损坏,这是比较常见的情况,个人没有任何的解决办法,此外,如果是核心损坏引起的花屏,显卡基本上只能报废了;有可能是金手指氧化了或灰尘过多,这是最幸运的,只要进行一下清理就可以了,氧化部分可以用橡皮去擦,再用无水酒精洗一下,故障就消失了;还有一个不可忽视的问题就是显卡上的电容,很多显卡花屏就是因为电容而花的,有的厂家甚至因此倒掉了(著名的花屏之王耕升),近年来新兴的显卡厂家也因为节约成本采用了一些对温度非常敏感的电容,一到冬天气温下降就花屏,理论上更换电容之后故障就排除了,但是建议还是和经销商联系更换或返厂维修事宜。
显示器花屏是极其常见的故障,产生的原因有多种,不同的原因所产生的故障现象也有所不同,解决方法也各异。在文本方式下的花屏表现为字符混乱,在图形方式下通常表现为图形分层,由于受到内部或外部的干扰还会产生水平条纹。以下是一些心得和经验,希望可以供大家参考。
1.显示器产生水平条纹:其原因主要有两种:
1)外部干扰,如显示器的使用现场附近有电火花或高频电磁干扰,这种干扰会使显示器的显示画面产生白色的水平条纹。处理方法:避免在此种情况下使用显示器;
2)内部干扰,这种干扰会使显示器的显示画面出现黑色的水平条纹,遇到这种情况,可以打开机壳检查一下显示器内部是否有接触不良的地方,电源的输出端或输出变压器等有无问题,因这种情况所产生的原因涉及到比较专业的技术,所以最好还是请专业人士给予修理为妙。
2.显示器分辨率设置不当引起花屏:当显示器在WIN3.X和WIN95中分辨率设置不正确时,启动Windows时就可能出现花屏故障,即画面分层、抖动、严重的甚至出现黑屏死机的现象。处理方法:进入WIN3.X的SETUP或进入WIN95的安全模式,重新设置显示器的显示模式即可。
3.显示卡与中文系统冲突:此种情况在退出中文系统时就会出现花屏,随意击键均无反应,类似死机,处理方法:此时输入"MODE C080"可得到解决。
4.显示卡的主控芯片散热效果不良:这也会产生花屏故障现象,处理方法:改善显示卡的散热性能。
5.显存速度太低:当显存速度太低以致于不能与主机的速度匹配时,也会产生花屏现象,处理方法:更换更高速的显存,或降低主机的速度。
6.显存损坏:当显存损坏后,在系统启动时就会出现花屏混乱字符的现象,处理方法:必须更换显存条。
7. 病毒原因:在某些病毒发作时也会出现花屏,处理方法:用杀毒软件杀毒即可消除。电容失效引起显示器特殊故障的处理
假如一开机显示就花屏的话则先检查下显卡的散热问题,用手摸一下显存芯片的温度,检查下显卡的风扇是否停转。再看看主板上的AGP插槽里是否有灰,检查下显卡的金手指是否被氧化了,然后根据具体情况清理下灰尘,用橡皮擦擦一下金手指,把氧化部分擦亮。假如散热有问题的话就换个风扇或在显存上加装散热片。或者进入BIOS,看看AGP的电压是否稳定在1.5V附近。
假如是玩游戏、做3D时才花屏那么在排除掉散热问题后你可以先尝试着换一个版本的显卡驱动试下,因为有可能是显卡驱动与程序本身不兼容的原因或驱动存在BUG造成的。
如果经过以上方法后显卡还是花屏的话,则你可以尝试着刷新显卡的BIOS,去显卡厂商的主页看看有没更新的BIOS下载。对于一些杂牌显卡来说,你可以试下用大厂商的BIOS刷你的显卡。要注意的是刷新BIOS是有风险的,而且以上方法都是基于你的显卡在保修期外的情况,假如你的显卡在保修期内,在排除软件问题后还是尽快送修为好.
如果是在玩游戏、处理3D时才出现花屏、停顿、死机的现象那么在排除掉散热问题之后可以先尝试着换一个版本的显卡驱动试下,同时建议使用通过WHQL认证的驱动,因为显卡驱动与程序本身不兼容的原因或驱动存在BUG可能性确实也是很常见的。针对部分显卡还可以尝试在主板BIOS里关闭AGP快写( Fastwrites)以及边带寻址(AGP Sideband)。
倘若上面方法均未奏效,那就只好重装系统,在日常维护中通过重装系统可以解决不少问题。安装系统后还要按正确的顺序来安装驱动程序:WINDOWS XP SP2补丁--主板驱动--显卡驱动--声卡以及其他PCI设备驱动--外设驱动。当驱动安装顺序不正常时,也有可能产生一些问题,驱动的安装顺序与底层设备驱动、注册表键值和Gart映射列表等都是有关系统的。
硬件方面:
首先确认一下启动过程是否正常,假如一开机显示就花屏死机的话则先检查下显卡的散热问题,用手摸一下显存芯片的温度,检查下显卡的风扇是否停转。再看看主板上的AGP/PCIE插槽里是否有灰,金手指是否被氧化了,然后根据具体情况清理下灰尘,用橡皮擦擦一下金手指,把氧化部分擦亮。假如散热有问题的话就换个风扇或在显存上加装散热片,或者进入BIOS看看电压是否稳定。
对于长时间停顿或是死机、花屏的现象,在排除超频使用的前提下,一般是电源或主板插槽供电不足引起的,建议可更换电源试一下。对于电源问题,目前DIY市场上很多品牌(包括目前比较响的几个大品牌)的电源标称300W,但实际输出功率却只有230W左右。很多显卡已经属于高频率、高温度、高功耗的产品了,对电源的要求也随之加大。建议有条件的玩家们购买时注意查看计算实际输出功率,最好不要买杂牌电源。也尽量不要图便宜购买不到200元的机箱加电源。此外对于主板设计缺陷造成的显卡插槽供电不足问题,可以尝试在主板BIOS里加大0.1V的电压。
如果经过以上方法后显卡还是花屏的话,则你可以尝试着刷新显卡的BIOS,去显卡厂商的主页看看有没更新的BIOS下载。对于一些杂牌厂商的显卡来说,你可以试下用大厂商的BIOS刷你的显卡。
㈢ 从电脑设备管理器看到的是PCI基地址吗
这是程序员了解的内容。内存范围指的是常驻内存所占用的系统总线。系统总线就是所以设备运行必备通道。输入输出范围就是PCI设备与系统交换数据的专用通道。
㈣ 怎么看我的主板支持PCIE几X
1、首复先双击桌面图标,启动制鲁大师。
㈤ 请问在设备管理器中的PCI简易设备找不到怎么解决
你声卡没驱动, 可以到网上下载.
你能不能找到的你声卡的品牌, 如果知道品牌可以版到"驱动之家"这个网站权找.
声卡驱动程序就是能让电脑发出声音的东东。
不安装电脑就没有声音
windows xp 自带许多声卡的驱动程序,一般的声卡在
xp下都不用安装了. 可能你的声卡不是大众用的, 如果你会么都不知那么只能用万能声卡驱动了.
万能声卡驱动下载地址:
http://www.wangmeng.cn/Soft/GOODSOFT/OTHERS/200505/63.html
万能声卡驱动不是很好用。
㈥ win7 64位 PCI硬件号怎么看。。开头是pci#ven的。
您下载个鲁大师或是驱动精灵就行,就能查看你的硬件具体配置了。
下载安装 gpu-z 那个是查看显卡的, 毛用没有!
还不如下载安装 cpu-z呢!
㈦ 如何获取PCI设备的配置和位置信息!
在 Windows 2000 和更高版本的 Windows 操作系统中,控制硬件总线的则是它们各自的总线驱动程序,而不是 HAL。因此,在 Windows 2000 和更高版本的 Windows 操作系统中,过去用于提供总线相关信息的所有 Hal API 都已过时。 在Windows 2000 和更高版本的 Windows 操作系统中,驱动程序无须查询设备即可查找资源。驱动程序通过即插即用 (PnP) 管理器的 IRP_MN_START_DEVICE 请求来获取这些资源。通常,正确编写的驱动程序不需要任何这类信息就能正常工作。如果由于某种原因,驱动程序需要获取这些信息,请参照下面的代码示例来获取资源。驱动程序应当是设备驱动程序堆栈的一部分,因为它需要设备的基础物理设备对象 (PDO) 才能发送 PnP 请求。 下面的代码示例演示了如何获取配置信息: NTSTATUS ReadWriteConfigSpace( IN PDEVICE_OBJECT DeviceObject, IN ULONG ReadOrWrite, // 0 for read 1 for write IN PVOID Buffer, IN ULONG Offset, IN ULONG Length ) { KEVENT event; NTSTATUS status; PIRP irp; IO_STATUS_BLOCK ioStatusBlock; PIO_STACK_LOCATION irpStack; PDEVICE_OBJECT targetObject; 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; } 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 ); return status; } 由于只能在 PASSIVE_LEVEL 级别发送 PnP I/O 请求数据包 (IRP),因此不能使用上面的函数在 DISPATCH_LEVEL 级别获取配置信息。 可以执行下列步骤以在 DISPATCH_LEVEL 级别访问配置空间: 1.在PASSIVE_LEVEL 级别发送一个 IRP_MN_QUERY_INTERFACE,以便从 PCI 总线驱动程序获取直接调用接口结构 (BUS_INTERFACE_STANDARD)。将该结构存储在非分页池内存中(通常存储在 DevcieExtension 中)。2.调用SetBusData 和 GetBusData,以便在 DISPATCH_LEVEL 级别访问配置空间。3.由于PCI 总线驱动程序将在它返回之前获取接口上的引用计数,因此当不再需要该接口时,必须取消对它的引用。4.请使用以下函数在 PASSIVE_LEVEL 级别获取 BUS_INTERFACE_STANDARD: NTSTATUS GetPCIBusInterfaceStandard( IN PDEVICE_OBJECT DeviceObject, OUT PBUS_INTERFACE_STANDARD BusInterfaceStandard ) /*++ Routine Description: This routine gets the bus interface standard information from the PDO. Arguments: DeviceObject - Device object to query for this information. BusInterface - Supplies a pointer to the retrieved information. Return Value: NT status. --*/ { KEVENT event; NTSTATUS status; PIRP irp; IO_STATUS_BLOCK ioStatusBlock; PIO_STACK_LOCATION irpStack; PDEVICE_OBJECT targetObject; Bus_KdPrint(("GetPciBusInterfaceStandard entered./n")); 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 ); irpStack->MinorFunction = IRP_MN_QUERY_INTERFACE; irpStack->Parameters.QueryInterface.InterfaceType = (LPGUID) &GUID_BUS_INTERFACE_STANDARD ; irpStack->Parameters.QueryInterface.Size = sizeof(BUS_INTERFACE_STANDARD); irpStack->Parameters.QueryInterface.Version = 1; irpStack->Parameters.QueryInterface.Interface = (PINTERFACE) BusInterfaceStandard; irpStack->Parameters.QueryInterface.InterfaceSpecificData = NULL; // // 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 ); return status; } 以下代码说明了如何使用接口直接调用函数获取总线数据。 bytes = busInterfaceStandard.GetBusData( busInterfaceStandard.Context, PCI_WHICHSPACE_CONFIG, Buffer Offset, Length); 如果不再需要该接口,请使用以下代码取消对其的引用。取消对该接口的引用之后,请勿调用任何接口例程。 (busInterfaceStandard.InterfaceDereference)( (PVOID)busInterfaceStandard.Context); 请对目标设备的 PDO 使用 IoGetDeviceProperty 函数,以获取总线号、功能号和设备号,如下所示: ULONG propertyAddress, length; USHORT FunctionNumber; DeviceNumber; // // Get the BusNumber. Please read the warning to follow. // IoGetDeviceProperty(PhysicalDeviceObject, DevicePropertyBusNumber, sizeof(ULONG), (PVOID)&BusNumber, &length); // // Get the DevicePropertyAddress // IoGetDeviceProperty(PhysicalDeviceObject, DevicePropertyAddress, sizeof(ULONG), (PVOID)&propertyAddress, &length); // // For PCI, the DevicePropertyAddress has device number // in the high word and the function number in the low word. // FunctionNumber = (USHORT)((propertyAddress) & 0x0000FFFF); DeviceNumber = (USHORT)(((propertyAddress) >> 16) & 0x0000FFFF); 重要说明:PCI 总线编号可能是动态的,会随时发生变化。因此,不建议根据总线编号或使用该信息来直接访问 PCI 端口。这可能会引发系统故障。
㈧ 如何获取 PCI 设备的配置和位置信息
PCI有三个相互独复立的物理地址空间制:设备存储器地址空间、I/O地址空间和配置空间。
配置空间是PCI所特有的一个物理空间。
由于PCI支持设备即插即用,所以PCI设备不占用固定的内存地址空间或I/O地址空间,而是由操作系统决定其映射的基址。
系统加电时,BIOS检测PCI总线,确定所有连接在PCI总线上的设备以及它们的配置要求,并进行系统配置。
所以,所有的PCI设备必须实现配置空间,从而能够实现参数的自动配置,实现真正的即插即用。
PCI总线规范定义的配置空间总长度为256个字节,配置信息按一定的顺序和大小依次存放。
前64个字节的配置空间称为配置头,对于所有的设备都一样,配置头的主要功能是用来识别设备、定义主机访问PCI卡的方式(I/O访问或者存储器访问,还有中断信息)。
其余的192个字节称为本地配置空间,主要定义卡上局部总线的特性、本地空间基地址及范围等。
㈨ windows找不到PCI设备的驱动程序文件
windows找不到PCI设备的驱动程序文件是设置错误造成的,解决方法为:
1、按下“win +R”组合键,回打答开电脑的“运行”,输入cmd后按enter键。
㈩ 如何获取PCI设备的配置和位置信息
在 Windows 2000 和更高版本的 Windows 操作系统中,控制硬件总线的则是它们各自的总线驱动程序,而不是 HAL。因此,在 Windows 2000 和更高版本的 Windows 操作系统中,过去用于提供总线相关信息的所有 Hal API 都已过时。
在Windows 2000 和更高版本的 Windows 操作系统中,驱动程序无须查询设备即可查找资源。驱动程序通过即插即用 (PnP) 管理器的 IRP_MN_START_DEVICE 请求来获取这些资源。通常,正确编写的驱动程序不需要任何这类信息就能正常工作。如果由于某种原因,驱动程序需要获取这些信息,请参照下面的代码示例来获取资源。驱动程序应当是设备驱动程序堆栈的一部分,因为它需要设备的基础物理设备对象 (PDO) 才能发送 PnP 请求。
下面的代码示例演示了如何获取配置信息: NTSTATUS ReadWriteConfigSpace( IN PDEVICE_OBJECT DeviceObject, IN ULONG ReadOrWrite, // 0 for read 1 for write IN PVOID Buffer, IN ULONG Offset, IN ULONG Length ) { KEVENT event; NTSTATUS status; PIRP irp; IO_STATUS_BLOCK ioStatusBlock; PIO_STACK_LOCATION irpStack; PDEVICE_OBJECT targetObject; 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; } 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 ); return status; } 由于只能在 PASSIVE_LEVEL 级别发送 PnP I/O 请求数据包 (IRP),因此不能使用上面的函数在 DISPATCH_LEVEL 级别获取配置信息。
可以执行下列步骤以在 DISPATCH_LEVEL 级别访问配置空间: 1.在PASSIVE_LEVEL 级别发送一个 IRP_MN_QUERY_INTERFACE,以便从 PCI 总线驱动程序获取直接调用接口结构 (BUS_INTERFACE_STANDARD)。将该结构存储在非分页池内存中(通常存储在 DevcieExtension 中)。2.调用SetBusData 和 GetBusData,以便在 DISPATCH_LEVEL 级别访问配置空间。3.由于PCI 总线驱动程序将在它返回之前获取接口上的引用计数,因此当不再需要该接口时,必须取消对它的引用。4.请使用以下函数在 PASSIVE_LEVEL 级别获取 BUS_INTERFACE_STANDARD: NTSTATUS GetPCIBusInterfaceStandard( IN PDEVICE_OBJECT DeviceObject, OUT PBUS_INTERFACE_STANDARD BusInterfaceStandard ) /*++ Routine Description: This routine gets the bus interface standard information from the PDO. Arguments: DeviceObject - Device object to query for this information. BusInterface - Supplies a pointer to the retrieved information. Return Value: NT status. --*/ { KEVENT event; NTSTATUS status; PIRP irp; IO_STATUS_BLOCK ioStatusBlock; PIO_STACK_LOCATION irpStack; PDEVICE_OBJECT targetObject; Bus_KdPrint(("GetPciBusInterfaceStandard entered./n")); 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 ); irpStack->MinorFunction = IRP_MN_QUERY_INTERFACE; irpStack->Parameters.QueryInterface.InterfaceType = (LPGUID) &GUID_BUS_INTERFACE_STANDARD ; irpStack->Parameters.QueryInterface.Size = sizeof(BUS_INTERFACE_STANDARD); irpStack->Parameters.QueryInterface.Version = 1; irpStack->Parameters.QueryInterface.Interface = (PINTERFACE) BusInterfaceStandard; irpStack->Parameters.QueryInterface.InterfaceSpecificData = NULL; // // 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 ); return status; } 以下代码说明了如何使用接口直接调用函数获取总线数据。 bytes = busInterfaceStandard.GetBusData(<BR/> busInterfaceStandard.Context, PCI_WHICHSPACE_CONFIG, Buffer Offset, Length); 如果不再需要该接口,请使用以下代码取消对其的引用。取消对该接口的引用之后,请勿调用任何接口例程。 (busInterfaceStandard.InterfaceDereference)( (PVOID)busInterfaceStandard.Context); 请对目标设备的 PDO 使用 IoGetDeviceProperty 函数,以获取总线号、功能号和设备号,如下所示: ULONG propertyAddress, length; USHORT FunctionNumber; DeviceNumber; // // Get the BusNumber. Please read the warning to follow. // IoGetDeviceProperty(PhysicalDeviceObject, DevicePropertyBusNumber, sizeof(ULONG), (PVOID)&BusNumber, &length); // // Get the DevicePropertyAddress // IoGetDeviceProperty(PhysicalDeviceObject, DevicePropertyAddress, sizeof(ULONG), (PVOID)&propertyAddress, &length); // // For PCI, the DevicePropertyAddress has device number // in the high word and the function number in the low word. // FunctionNumber = (USHORT)((propertyAddress) & 0x0000FFFF); DeviceNumber = (USHORT)(((propertyAddress) >> 16) & 0x0000FFFF); 重要说明:PCI 总线编号可能是动态的,会随时发生变化。因此,不建议根据总线编号或使用该信息来直接访问 PCI 端口。这可能会引发系统故障。