Πώς μπορείτε να λάβετε τις πληροφορίες ρύθμισης παραμέτρων και τη θέση μιας συσκευής PCI

Μεταφράσεις άρθρων Μεταφράσεις άρθρων
Αναγν. άρθρου: 253232 - Δείτε τα προϊόντα στα οποία αναφέρεται το συγκεκριμένο άρθρο.
Ανάπτυξη όλων | Σύμπτυξη όλων

Περίληψη

Αυτό το άρθρο περιγράφει πώς μπορείτε να λάβετε τη ρύθμιση παραμέτρων και πληροφορίες τοποθεσίας (όπως BusNumber, DeviceNumber και αριθμός Function) μιας συσκευής περιφερειακού στοιχείου (PCI) σε ένα πρόγραμμα οδήγησης που είναι μέρος του προγράμματος οδήγησης της συσκευής προορισμού στοιβάζονται είτε ως μια συνάρτηση ή φίλτρο προγράμματος οδήγησης.

Περισσότερες πληροφορίες

Στα Windows NT 4.0, τα προγράμματα οδήγησης λάβει την πληροφορία από σάρωση του διαύλου και καλεί το HalGetBusData και τα API HalGetBusDataByOffset. Στα Windows 2000 και νεότερες εκδόσεις λειτουργικών συστημάτων των Windows, το υλικό διαύλους ελέγχονται από τα προγράμματα οδήγησής τους αντίστοιχους διαύλου και όχι από το HAL. Επομένως, όλα τα API Hal που χρησιμοποιείται για την παροχή πληροφοριών σχετικά με το δίαυλο δεν ισχύουν πλέον στα Windows 2000 και νεότερες εκδόσεις λειτουργικών συστημάτων των Windows.

Στα Windows 2000 και νεότερες εκδόσεις λειτουργικών συστημάτων των Windows, το πρόγραμμα οδήγησης δεν χρειάζεται να υποβάλλει ερώτημα στη συσκευή για να βρείτε πόρους. Το πρόγραμμα οδήγησης λαμβάνει τους πόρους από το Τοποθέτησης και Άμεσης λειτουργίας (PnP) διαχείρισης της αίτησης IRP_MN_START_DEVICE. Συνήθως, ένα πρόγραμμα οδήγησης well-written δεν θα χρειαζόταν οποιαδήποτε από αυτές τις πληροφορίες για να λειτουργήσουν σωστά. Εάν για κάποιο λόγο το πρόγραμμα οδήγησης απαιτεί αυτές τις πληροφορίες, το δείγμα κώδικα για την ακολουθήστε δείχνει πώς μπορείτε να λάβετε τους πόρους. Το πρόγραμμα οδήγησης θα πρέπει να είναι μέρος της στοίβας του προγράμματος οδήγησης της συσκευής, επειδή απαιτεί τα υποκείμενα αντικείμενα φυσικής συσκευής (PDO) της συσκευής για να στείλετε την αίτηση Τοποθέτησης και Άμεσης λειτουργίας.

Το ακόλουθο δείγμα κώδικα δείχνει πώς μπορείτε να λάβετε τις πληροφορίες ρύθμισης παραμέτρων:
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;

}
				
Επειδή μπορείτε να στείλετε μόνο της Τοποθέτησης και Άμεσης λειτουργίας εισόδου/εξόδου σε πακέτα (IRP) στο PASSIVE_LEVEL, δεν μπορείτε να χρησιμοποιήσετε τη συνάρτηση παραπάνω για να λάβετε τις πληροφορίες ρύθμισης παραμέτρων στο DISPATCH_LEVEL.

Μπορείτε να εκτελέσετε τα ακόλουθα βήματα για να αποκτήσετε πρόσβαση στο χώρο ρύθμισης παραμέτρων στο DISPATCH_LEVEL:
  1. Στείλτε ένα IRP_MN_QUERY_INTERFACE στο PASSIVE_LEVEL για τη λήψη της δομής απευθείας κλήση διασύνδεσης (BUS_INTERFACE_STANDARD) από το πρόγραμμα οδήγησης διαύλου PCI. Αποθηκεύστε αυτό σε μια μη σελιδοποιημένη μνήμη (συνήθως σε DevcieExtension).
  2. Καλέστε το SetBusData και GetBusData πρόσβασης στο χώρο ρύθμισης παραμέτρων στο DISPATCH_LEVEL.
  3. Το πρόγραμμα οδήγησης διαύλου PCI λαμβάνει ένα πλήθος αναφορών στη διασύνδεση πριν από την επιστροφή, έτσι πρέπει να dereference διασύνδεση, όταν δεν είναι πλέον απαραίτητη.
  4. Χρησιμοποιήστε την παρακάτω συνάρτηση για να πάρετε το BUS_INTERFACE_STANDARD στο 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;
    
    }
    					
Ο ακόλουθος κώδικας δείχνει πώς μπορείτε να χρησιμοποιήσετε τη συνάρτηση απευθείας κλήση διασύνδεσης για τη λήψη των δεδομένων διαύλου.
    bytes = busInterfaceStandard.GetBusData(<BR/>
                    busInterfaceStandard.Context,
                    PCI_WHICHSPACE_CONFIG,
                    Buffer
                    Offset,
                    Length);
				
Όταν δεν χρειάζεστε πλέον τη διασύνδεση, χρησιμοποιήστε τον ακόλουθο κώδικα για να dereference διασύνδεση με τον κώδικα που θα ακολουθήσετε. Μην καλείτε τις ρουτίνες διασύνδεσης αφού dereference το περιβάλλον.
    (busInterfaceStandard.InterfaceDereference)(
                (PVOID)busInterfaceStandard.Context);
				
Χρήση τουIoGetDevicePropertyσυνάρτηση από το PDO της συσκευής προορισμού για να λάβετε τους αριθμούς διαύλου, λειτουργιών και συσκευών ως εξής:
    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. Αυτό μπορεί να οδηγήσει σε αποτυχία του συστήματος.

Ιδιότητες

Αναγν. άρθρου: 253232 - Τελευταία αναθεώρηση: Κυριακή, 19 Δεκεμβρίου 2010 - Αναθεώρηση: 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
Λέξεις-κλειδιά: 
kbhowto kbwdm kbmt KB253232 KbMtel
Μηχανικά μεταφρασμένο
ΣΗΜΑΝΤΙΚΟ: Αυτό το άρθρο είναι προϊόν λογισμικού μηχανικής μετάφρασης της Microsoft και όχι ανθρώπινης μετάφρασης. Η Microsoft σάς προσφέρει άρθρα που είναι προϊόντα ανθρώπινης αλλά και μηχανικής μετάφρασης έτσι ώστε να έχετε πρόσβαση σε όλα τα άρθρα της Γνωσιακής Βάσης μας στη δική σας γλώσσα. Ωστόσο, ένα άρθρο που έχει προκύψει από μηχανική μετάφραση δεν είναι πάντα άριστης ποιότητας. Ενδέχεται να περιέχει λεξιλογικά, συντακτικά ή γραμματικά λάθη, όπως ακριβώς τα λάθη που θα έκανε ένας μη φυσικός ομιλητής επιχειρώντας να μιλήσει τη γλώσσα σας. Η Microsoft δεν φέρει καμία ευθύνη για τυχόν ανακρίβειες, σφάλματα ή ζημίες που προκύψουν λόγω τυχόν παρερμηνειών στη μετάφραση του περιεχομένου ή χρήσης του από τους πελάτες της. Επίσης, η Microsoft πραγματοποιεί συχνά ενημερώσεις στο λογισμικό μηχανικής μετάφρασης.
Η αγγλική έκδοση αυτού του άρθρου είναι η ακόλουθη:253232

Αποστολή σχολίων

 

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