Wie Sie die Konfigurations- und Standortinformationen Informationen eines PCI-Geräts abrufen

SPRACHE AUSWÄHLEN SPRACHE AUSWÄHLEN
Artikel-ID: 253232 - Produkte anzeigen, auf die sich dieser Artikel bezieht
Alles erweitern | Alles schließen

Zusammenfassung

Dieser Artikel beschreibt, wie erhalten Sie die Konfiguration und Standortinformationen (z. B. für die Busnummer wurde, DeviceNumber und Funktionsnummer) eines Geräts (PCI = Peripheral Component Interconnect) in ein Treiber, der das Zielgerät Treiber gehört Stapeln entweder als eine Funktion oder Treiber zu filtern.

Weitere Informationen

Unter Windows NT 4.0 Treiber werden diese Informationen durch das Scannen des Bus und Aufrufen der HalGetBusData und HalGetBusDataByOffset-APIs abrufen. Unter Windows 2000 und späteren Windows-Betriebssysteme werden die Hardware-Bussen durch ihre jeweiligen Bustreiber und nicht durch HAL gesteuert. Aus diesem Grund sind alle der Hal-APIs, die zur Bereitstellung von Bus-bezogene Informationen in Windows 2000 und späteren Windows-Betriebssystemen, veraltet.

Unter Windows 2000 und späteren Windows-Betriebssystemen muss ein Treiber nicht zum Suchen von Ressourcen des Geräts abzufragen. Der Treiber Ruft die Ressourcen aus dem Plug & Play (PnP) Manager in ihrem IRP_MN_START_DEVICE verlangen. In der Regel würde ein gut geschriebenen Treiber nicht erforderlich ist diese Informationen ordnungsgemäß funktioniert. Wenn der Treiber aus irgendeinem Grund diese Informationen benötigt, das Codebeispiel so führen die Ressourcen abrufen veranschaulicht. Der Treiber muss Teil des Treiberstapels des Geräts sein, da der zugrunde liegenden physischen Geräteobjekte (g.u.) des Geräts zum Senden der Plug & Play-Anforderung erforderlich ist.

Das folgende Codebeispiel veranschaulicht, wie die Konfigurationsinformationen zu erhalten:
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;

}
				
Da Sie nur die Plug & Play-e/a-Anforderungspakete (IRPs) an PASSIVE_LEVEL senden können, können nicht Sie durch diese Funktion verwenden, die Konfigurationsinformationen bei DISPATCH_LEVEL abgerufen.

Sie können die folgenden Schritte ausführen, um auf den Konfigurationsbereich bei DISPATCH_LEVEL zuzugreifen:
  1. Senden Sie eine IRP_MN_QUERY_INTERFACE bei PASSIVE_LEVEL die Schnittstelle Direct-Call-Struktur (BUS_INTERFACE_STANDARD) aus dem PCI-Bus-Treiber zu erhalten. Speichern Sie diese in einer nicht ausgelagerten Poolspeicher (i. d. r. in DevcieExtension).
  2. Rufen Sie die SetBusData und GetBusData, um der Konfigurationsbereich bei DISPATCH_LEVEL zugreifen.
  3. Der PCI-Bus-Treiber nimmt einen Verweiszähler auf der Schnittstelle, noch Wert zurückgegeben, damit Sie die Schnittstelle Dereferenzierung müssen, wenn es nicht mehr benötigt wird.
  4. Verwenden Sie die folgende Funktion, um die BUS_INTERFACE_STANDARD am PASSIVE_LEVEL zu erhalten:
    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;
    
    }
    					
Der folgende Code veranschaulicht die Verwendung der Schnittstelle Direct-Aufruf-Funktion zum Abrufen der Busdaten.
    bytes = busInterfaceStandard.GetBusData(<BR/>
                    busInterfaceStandard.Context,
                    PCI_WHICHSPACE_CONFIG,
                    Buffer
                    Offset,
                    Length);
				
Wenn Sie die Schnittstelle nicht mehr benötigen, verwenden Sie den folgenden Code, um die Schnittstelle mit der Beispielcode zu dereferenzieren. Rufen Sie jede Schnittstelle Routinen, nachdem die Schnittstelle zu dereferenzieren.
    (busInterfaceStandard.InterfaceDereference)(
                (PVOID)busInterfaceStandard.Context);
				
Verwenden Sie die IoGetDeviceProperty -Funktion auf die PDO des Zielgeräts, um die Bus, Funktion und Gerät Zahlen wie folgt:
    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);

				
Wichtig PCI-Bus Zahlen können dynamisch sein und können jederzeit ändern. Aus diesem Grund ist es nicht gut, hängen die Busnummer oder verwenden Sie diese Informationen auf der PCI-Ports direkt zugreifen. Dies kann zu Systemfehlern führen.

Eigenschaften

Artikel-ID: 253232 - Geändert am: Sonntag, 16. Dezember 2012 - Version: 4.0
Die Informationen in diesem Artikel beziehen sich auf:
  • 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
Keywords: 
kbhowto kbwdm kbmt KB253232 KbMtde
Maschinell übersetzter Artikel
Wichtig: Dieser Artikel wurde maschinell und nicht von einem Menschen übersetzt. Die Microsoft Knowledge Base ist sehr umfangreich und ihre Inhalte werden ständig ergänzt beziehungsweise überarbeitet. Um Ihnen dennoch alle Inhalte auf Deutsch anbieten zu können, werden viele Artikel nicht von Menschen, sondern von Übersetzungsprogrammen übersetzt, die kontinuierlich optimiert werden. Doch noch sind maschinell übersetzte Texte in der Regel nicht perfekt, insbesondere hinsichtlich Grammatik und des Einsatzes von Fremdwörtern sowie Fachbegriffen. Microsoft übernimmt keine Gewähr für die sprachliche Qualität oder die technische Richtigkeit der Übersetzungen und ist nicht für Probleme haftbar, die direkt oder indirekt durch Übersetzungsfehler oder die Verwendung der übersetzten Inhalte durch Kunden entstehen könnten.
Den englischen Originalartikel können Sie über folgenden Link abrufen: 253232
Microsoft stellt Ihnen die in der Knowledge Base angebotenen Artikel und Informationen als Service-Leistung zur Verfügung. Microsoft übernimmt keinerlei Gewährleistung dafür, dass die angebotenen Artikel und Informationen auch in Ihrer Einsatzumgebung die erwünschten Ergebnisse erzielen. Die Entscheidung darüber, ob und in welcher Form Sie die angebotenen Artikel und Informationen nutzen, liegt daher allein bei Ihnen. Mit Ausnahme der gesetzlichen Haftung für Vorsatz ist jede Haftung von Microsoft im Zusammenhang mit Ihrer Nutzung dieser Artikel oder Informationen ausgeschlossen.

Ihr Feedback an uns

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com