Jak získat informace o konfiguraci a umístění zařízení PCI

Překlady článku Překlady článku
ID článku: 253232 - Produkty, které se vztahují k tomuto článku.
Rozbalit všechny záložky | Minimalizovat všechny záložky

Souhrn

Tento článek popisuje, jak můžete získat konfiguraci a umístění informace (například BusNumber, DeviceNumber a funkce, číslo) v ovladači, který je součástí cílové zařízení ovladač zařízení Peripheral Component Interconnect (PCI) skládat buď jako funkce nebo ovladače filtrů.

Další informace

V systému Windows NT 4.0 ovladače tyto informace získat prohledávání sběrnice a voláním rozhraní API HalGetBusDataByOffset a HalGetBusData. V systému Windows 2000 a novější operační systémy Windows hardwarové sběrnice řízených jejich odpovídajících sběrnice ovladače a nikoliv vrstvy HAL. Všechna rozhraní API HAL, která poskytuje informace týkající se sběrnice jsou proto zastaralé v systému Windows 2000 a novější operační systémy Windows.

V systému Windows 2000 a novější operační systémy Windows ovladač nemusí zařízení najít zdroje dotazu. Ovladač získá ze Správce zařízení typu Plug and Play (PnP) ve své žádosti IRP_MN_START_DEVICE zdrojů. Obvykle well-written ovladač by nevyžadují některé z těchto informací ke správné funkci. Pokud z nějakého důvodu ovladač vyžaduje dané informace, ukázka kódu sledovat ukazuje, jak získat prostředky. Ovladač by měly být součástí zásobník ovladačů zařízení, protože vyžaduje základní objekty fyzické zařízení (CHOP) zařízení PnP žádost odeslat.

Následující příklad kódu ukazuje, jak získat informace o konfiguraci:
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;

}
				
vzhledem k tomu, že PnP vstupně-výstupní požadavek pakety (IRP) lze odeslat pouze na PASSIVE_LEVEL, výše funkci nelze použít získat informace o konfiguraci na DISPATCH_LEVEL.

Můžete provádět následující kroky a přístup k prostoru konfigurace na DISPATCH_LEVEL:
  1. Odeslat IRP_MN_QUERY_INTERFACE na PASSIVE_LEVEL získat rozhraní přímého volání strukturu (BUS_INTERFACE_STANDARD) z ovladače sběrnice PCI. Uložte tento nestránkovaného fondu paměti (obvykle v DevcieExtension).
  2. Volání přístup k prostoru konfigurace na DISPATCH_LEVEL SetBusData a GetBusData.
  3. Ovladač sběrnice PCI trvá počet odkazů na rozhraní před vrátí, tak rozhraní musí dereference, pokud již není potřeba.
  4. Použít následující funkci získat BUS_INTERFACE_STANDARD na PASSIVE_LEVEL:
    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;
    
    }
    					
Následující kód ukazuje možné použití funkce rozhraní přímého volání k získání dat sběrnice.
    bytes = busInterfaceStandard.GetBusData(<BR/>
                    busInterfaceStandard.Context,
                    PCI_WHICHSPACE_CONFIG,
                    Buffer
                    Offset,
                    Length);
				
Již potřebujete-li rozhraní, použijte následující kód k dereference rozhraní kódem a postupujte podle. Volání rutiny žádné rozhraní, po dereference rozhraní.
    (busInterfaceStandard.InterfaceDereference)(
                (PVOID)busInterfaceStandard.Context);
				
Použít funkci IoGetDeviceProperty na CHOP cílového zařízení získání čísla sběrnice, funkce a zařízení:
    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);

				
Důležité čísla sběrnice PCI mohou být dynamické a mohou měnit v každém okamžiku. Proto není vhodné závisí na číslo sběrnice nebo tyto informace použít přímý přístup ke porty PCI. To může vést k selhání systému.

Vlastnosti

ID článku: 253232 - Poslední aktualizace: 8. září 2005 - Revize: 2.1
Informace v tomto článku jsou určeny pro produkt:
  • Microsoft Win32 Device Driver Kit for Windows 2000
  • Microsoft Windows XP Driver Development Kit
  • Microsoft Windows Server 2003 Driver Development Kit (DDK)
  • Microsoft Windows 2000 Professional Edition
  • Microsoft Windows XP Home Edition
  • Microsoft Windows XP Professional
  • Microsoft Windows Server 2003 Service Pack 1
Klíčová slova: 
kbmt kbhowto kbwdm KB253232 KbMtcs
Strojově přeložený článek
Důležité: Tento článek byl přeložen pomocí software společnosti Microsoft na strojový překlad, ne profesionálním překladatelem. Společnost Microsoft nabízí jak články přeložené překladatelem, tak články přeložené pomocí software na strojový překlad, takže všechny články ve Znalostní databázi (Knowledge Base) jsou dostupné v češtině. Překlad pomocí software na strojový překlad ale není bohužel vždy dokonalý. Obsahuje chyby ve skloňování slov, skladbě vět, nebo gramatice, podobně jako když cizinci dělají chyby při mluvení v češtině. Společnost Microsoft není právně zodpovědná za nepřesnosti, chyby nebo škody vzniklé chybami v překladu, nebo při použití nepřesně přeložených instrukcí v článku zákazníkem. Společnost Microsoft aktualizuje software na strojový překlad, aby byl počet chyb omezen na minimum.
Projděte si také anglickou verzi článku:253232

Dejte nám zpětnou vazbu

 

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