Làm thế nào để có được các thông tin cấu hình và vị trí của một thiết bị PCI

Hỗ trợ cho Windows XP đã kết thúc

Microsoft đã kết thúc hỗ trợ dành cho Windows XP vào ngày 8 tháng 4 năm 2014. Thay đổi này đã ảnh hưởng đến các bản cập nhật phần mềm và tùy chọn bảo mật của bạn. Tìm hiểu ý nghĩa của điều này với bạn và cách thực hiện để luôn được bảo vệ.

Hỗ trợ cho Windows Server 2003 đã kết thúc vào ngày 14 tháng 7 năm 2015

Microsoft đã kết thúc hỗ trợ cho Windows Server 2003 vào ngày 14 tháng 7 năm 2015. Thay đổi này đã ảnh hưởng đến các bản cập nhật phần mềm và tùy chọn bảo mật của bạn. Tìm hiểu ý nghĩa của điều này với bạn và cách thực hiện để luôn được bảo vệ.

QUAN TRỌNG: Bài viết này được dịch bằng phần mềm dịch máy của Microsoft chứ không phải do con người dịch. Microsoft cung cấp các bài viết do con người dịch và cả các bài viết do máy dịch để bạn có thể truy cập vào tất cả các bài viết trong Cơ sở Kiến thức của chúng tôi bằng ngôn ngữ của bạn. Tuy nhiên, bài viết do máy dịch không phải lúc nào cũng hoàn hảo. Loại bài viết này có thể chứa các sai sót về từ vựng, cú pháp hoặc ngữ pháp, giống như một người nước ngoài có thể mắc sai sót khi nói ngôn ngữ của bạn. Microsoft không chịu trách nhiệm về bất kỳ sự thiếu chính xác, sai sót hoặc thiệt hại nào do việc dịch sai nội dung hoặc do hoạt động sử dụng của khách hàng gây ra. Microsoft cũng thường xuyên cập nhật phần mềm dịch máy này.

Nhấp chuột vào đây để xem bản tiếng Anh của bài viết này:253232
Bài viết này đã được lưu trữ. Bài viết được cung cấp "nguyên trạng" và sẽ không còn được cập nhật nữa.
TÓM TẮT
Bài viết này mô tả như thế nào bạn có thể cấu hình và thông tin vị trí (như BusNumber, DeviceNumber, và chức năng số) của một thiết bị kết nối thành phần ngoại vi (PCI) trong một trình điều khiển mà là một phần của trình điều khiển thiết bị mục tiêu ngăn xếp hoặc như một chức năng hoặc lọc trình điều khiển.
THÔNG TIN THÊM
Trên Windows NT 4.0, trình điều khiển nhận được thông tin này bằng cách quét xe buýt và gọi điện thoại HalGetBusData và HalGetBusDataByOffset API. Trên Windows 2000 và hệ điều hành Windows sau này, các xe buýt phần cứng được điều khiển bởi trình điều khiển xe buýt tương ứng của họ và không phải bởi HAL. Vì vậy, tất cả các API Hal được sử dụng để cung cấp thông tin liên quan đến xe buýt là lỗi thời trong Windows 2000 và hệ điều hành Windows sau này.

Trên Windows 2000 và hệ điều hành Windows sau này, một người lái xe không cần truy vấn để tìm nguồn tài nguyên thiết bị. Trình điều khiển được các nguồn lực từ người quản lý (PnP) cắm và chạy trong yêu cầu IRP_MN_START_DEVICE của mình. Thông thường, một người lái xe tốt bằng văn bản sẽ không yêu cầu bất kỳ thông tin này để hoạt động tốt. Nếu vì một lý do chương trình điều khiển yêu cầu thông tin này, mẫu mã để làm theo cho thấy làm thế nào để có được các nguồn lực. Trình điều khiển nên là một phần của thiết bị điều khiển Stack vì nó đòi hỏi các đối tượng thiết bị vật lý nằm bên dưới (PDO) của điện thoại để gửi yêu cầu PnP.

Mẫu mã sau đây chứng tỏ làm thế nào để có được thông tin cấu hình:
NTSTATUSReadWriteConfigSpace(    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;}				
Bởi vì bạn chỉ có thể gửi các PnP I/O yêu cầu gói (IRPs) tại PASSIVE_LEVEL, bạn không thể sử dụng chức năng ở trên để có được thông tin cấu hình lúc DISPATCH_LEVEL.

Bạn có thể thực hiện các bước sau để truy cập vào không gian cấu hình lúc DISPATCH_LEVEL:
  1. Gửi một IRP_MN_QUERY_INTERFACE tại PASSIVE_LEVEL để có được cấu trúc giao diện trực tiếp cuộc gọi (BUS_INTERFACE_STANDARD) từ tài xế xe buýt PCI. Lưu trữ này trong một bộ nhớ nonpaged bơi (thường ở DevcieExtension).
  2. Gọi SetBusData và GetBusData để truy cập vào không gian cấu hình lúc DISPATCH_LEVEL.
  3. Tài xế xe buýt PCI mất một số tài liệu tham khảo trên giao diện trước khi nó trở lại, do đó, bạn phải dereference giao diện khi nó không còn là cần thiết.
  4. Sử dụng các chức năng sau đây để có được BUS_INTERFACE_STANDARD tại PASSIVE_LEVEL:
    NTSTATUSGetPCIBusInterfaceStandard(    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;}					
Mã sau đây cho thấy cách bạn có thể sử dụng chức năng cuộc gọi trực tiếp giao diện để lấy dữ liệu xe buýt.
    bytes = busInterfaceStandard.GetBusData(<BR/>                    busInterfaceStandard.Context,                    PCI_WHICHSPACE_CONFIG,                    Buffer                    Offset,                    Length);				
Khi bạn không còn cần giao diện, sử dụng mã sau đây để dereference giao diện với mã số để làm theo. Không gọi cho bất kỳ công việc giao diện sau khi bạn dereference giao diện.
    (busInterfaceStandard.InterfaceDereference)(                (PVOID)busInterfaceStandard.Context);				
Sử dụng các IoGetDeviceProperty chức năng trên PDO thiết bị mục tiêu để có được những con số xe buýt, chức năng và thiết bị như sau:
    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);				
Quan trọng PCI xe buýt số có thể năng động và có thể thay đổi tại bất kỳ thời điểm. Vì vậy, nó là không tốt phụ thuộc vào số lượng xe buýt hoặc sử dụng thông tin đó để truy cập vào cổng PCI trực tiếp. Điều này có thể dẫn đến thất bại hệ thống.

Cảnh báo: Bài viết này được dịch tự động

Thuộc tính

ID Bài viết: 253232 - Xem lại Lần cuối: 12/05/2015 18:30:50 - Bản sửa đổi: 2.0

Microsoft Windows XP Driver Development Kit, Microsoft Windows 2000 Professional Edition, Microsoft Windows XP Home Edition, Microsoft Windows XP Professional, Microsoft Windows Server 2003 Service Pack 1

  • kbnosurvey kbarchive kbhowto kbwdm kbmt KB253232 KbMtvi
Phản hồi