㈠ 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 埠。這可能會引發系統故障。