Como obter as informações de configuração e o local de um dispositivo PCI

O suporte para o Windows XP terminou

A Microsoft terminou o suporte para o Windows XP em 8 de abril de 2014. Esta alteração afetou as suas atualizações de software e opções de segurança. Saiba o que isto significa para você e como permanecer protegido.

O suporte para o Windows Server 2003 termina em 14 de julho de 2015.

A Microsoft terminou o suporte para o Windows Server 2003 em 14 de julho de 2015. Esta alteração afetou as suas atualizações de software e opções de segurança. Saiba o que isto significa para você e como permanecer protegido.

IMPORTANTE: Este artigo foi traduzido por um sistema de tradução automática (também designado por Machine Translation ou MT), não tendo sido portanto traduzido ou revisto por pessoas. A Microsoft possui artigos traduzidos por aplicações (MT) e artigos traduzidos por tradutores profissionais, com o objetivo de oferecer em português a totalidade dos artigos existentes na base de dados de suporte. No entanto, a tradução automática não é sempre perfeita, podendo conter erros de vocabulário, sintaxe ou gramática. A Microsoft não é responsável por incoerências, erros ou prejuízos ocorridos em decorrência da utilização dos artigos MT por parte dos nossos clientes. A Microsoft realiza atualizações freqüentes ao software de tradução automática (MT). Obrigado.

Clique aqui para ver a versão em Inglês deste artigo: 253232
Este artigo foi arquivado. É oferecido "como está" e não será mais atualizado.
Sumário
Este artigo descreve como você pode obter a configuração e informações de local (como BusNumber, DeviceNumber e número de função) de um dispositivo de interconexão de componentes periféricos (PCI) em um driver que faz parte do driver do dispositivo de destino como uma função de pilha ou driver de filtro.
Mais Informações
No Windows NT 4.0, drivers de obtém essa informação verificação o barramento e chamando as APIs HalGetBusDataByOffset e HalGetBusData. No Windows 2000 e posteriores sistemas operacionais do Windows, os barramentos de hardware são controlados por seus drivers respectivos barramento e não por HAL. Portanto, todas as APIs de HAL que usado para fornecer informações relacionadas ao barramento são obsoletas no Windows 2000 e posteriores sistemas operacionais do Windows.

No Windows 2000 e posteriores sistemas operacionais do Windows, um driver não é necessário para o dispositivo para localizar recursos de consulta. O driver obtém os recursos do Gerenciador de Plug and Play (PnP) na solicitação de IRP_MN_START_DEVICE. Normalmente, um driver bem escrito não requer qualquer um dessas informações para funcionar corretamente. Se por algum motivo o driver requer essas informações, o exemplo de código a seguir mostra como obter os recursos. O driver deve ser parte da pilha de driver do dispositivo porque ele requer os objetos de dispositivo físico subjacente (PDO) do dispositivo para enviar a solicitação PnP.

O exemplo de código a seguir demonstra como obter as informações de configuração:
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;}				
porque você só pode enviar o PnP pacotes solicitação de E/s (IRPs) em PASSIVE_LEVEL, você não pode usar a função acima para obter as informações de configuração em DISPATCH_LEVEL.

Você pode executar as seguintes etapas para acessar o espaço de configuração em DISPATCH_LEVEL:
  1. Envie um IRP_MN_QUERY_INTERFACE PASSIVE_LEVEL para aproveitar a estrutura de interface de chamada direta (BUS_INTERFACE_STANDARD) o driver de barramento PCI. Armazene isso em uma memória de pool não-paginável (normalmente em DevcieExtension).
  2. Chamar o SetBusData e GetBusData para acessar o espaço de configuração em DISPATCH_LEVEL.
  3. O driver de barramento PCI leva uma contagem de referência na interface antes de retornar, portanto, você deve eliminar referência a interface quando não for necessário.
  4. Use a função seguinte para chegar a BUS_INTERFACE_STANDARD 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;}					
O código a seguir mostra como você pode usar a função de chamada direta de interface para obter os dados de barramento.
    bytes = busInterfaceStandard.GetBusData(<BR/>                    busInterfaceStandard.Context,                    PCI_WHICHSPACE_CONFIG,                    Buffer                    Offset,                    Length);				
quando você não precisa da interface, use o código a seguir para eliminar referência a interface com o código a seguir. Não chame quaisquer rotinas de interface depois de eliminar referência da interface.
    (busInterfaceStandard.InterfaceDereference)(                (PVOID)busInterfaceStandard.Context);				
use a função IoGetDeviceProperty PDO do dispositivo de destino para obter os números de barramento, função e dispositivos da seguinte maneira:
    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);				
importante PCI Bus números podem ser dinâmicos e pode alterar a qualquer momento. Portanto, não é bom dependem o número do barramento ou usar essas informações para acessar as portas PCI diretamente. Isso pode levar à falha do sistema.

Aviso: este artigo foi traduzido automaticamente

Propriedades

ID do Artigo: 253232 - Última Revisão: 12/05/2015 18:30:47 - Revisão: 2.1

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

  • kbnosurvey kbarchive kbmt kbhowto kbwdm KB253232 KbMtpt
Comentários