Freigeben über


Auflösen von Hostnamen und IP-Adressen

Ab Windows 7 ermöglicht eine Kernel-Namensauflösungsfunktion Komponenten im Kernelmodus die protokollunabhängige Übersetzung zwischen Unicode-Hostnamen und Transportadressen. Sie können die folgenden Winsock Kernel -Funktionen (WSK) auf Clientebene verwenden, um diese Namensauflösung auszuführen:

Diese Funktionen führen die Namens-Adressübersetzung ähnlich wie die Benutzermodusfunktionen FreeAddrInfoW, GetAddrInfoW und GetNameInfoW aus.

Um dieses Feature nutzen zu können, müssen Sie Ihren Treiber kompilieren oder neu kompilieren, wobei das makro NTDDI_VERSION auf NTDDI_WIN7 oder höher festgelegt ist.

Damit Ihr Treiber die Kernelnamenauflösungsfunktionalität verwenden kann, muss er die folgende Aufrufsequenz ausführen:

  1. Rufen Sie WskRegister auf, um sich bei WSK zu registrieren.

  2. Rufen Sie WskCaptureProviderNPI auf, um die Netzwerkprogrammierschnittstelle (Network Programming Interface, NPI) des WSK-Anbieters zu erfassen.

  3. Wenn Sie mit der Verwendung des WSK-Anbieters NPI fertig sind, rufen Sie WskReleaseProviderNPI auf, um die NPI des WSK-Anbieters freizugeben.

  4. Rufen Sie WskDeregister auf, um die Registrierung der WSK-Anwendung aufzuheben.

Im folgenden Codebeispiel wird anhand der obigen Aufrufsequenz veranschaulicht, wie eine WSK-Anwendung die WskGetAddressInfo-Funktion aufrufen kann, um einen Hostnamen in eine Transportadresse zu übersetzen.

NTSTATUS
SyncIrpCompletionRoutine(
    __in PDEVICE_OBJECT Reserved,
    __in PIRP Irp,
    __in PVOID Context
    )
{    
    PKEVENT compEvent = (PKEVENT)Context;
    UNREFERENCED_PARAMETER(Reserved);
    UNREFERENCED_PARAMETER(Irp);
    KeSetEvent(compEvent, 2, FALSE);    
    return STATUS_MORE_PROCESSING_REQUIRED;
}

NTSTATUS
KernelNameResolutionSample(
    __in PCWSTR NodeName,
    __in_opt PCWSTR ServiceName,
    __in_opt PADDRINFOEXW Hints,
    __in PWSK_PROVIDER_NPI WskProviderNpi
    )
{
    NTSTATUS status;
    PIRP irp;
    KEVENT completionEvent;
    UNICODE_STRING uniNodeName, uniServiceName, *uniServiceNamePtr;
    PADDRINFOEXW results;

    PAGED_CODE();
    //
    // Initialize UNICODE_STRING structures for NodeName and ServiceName 
    //
 
    RtlInitUnicodeString(&uniNodeName, NodeName);

    if(ServiceName == NULL) {
        uniServiceNamePtr = NULL;
    }
    else {
        RtlInitUnicodeString(&uniServiceName, ServiceName);
        uniServiceNamePtr = &uniServiceName;
    }

    //
    // Use an event object to synchronously wait for the 
    // WskGetAddressInfo request to be completed. 
    //
 
    KeInitializeEvent(&completionEvent, SynchronizationEvent, FALSE);

    //
    // Allocate an IRP for the WskGetAddressInfo request, and set the 
    // IRP completion routine, which will signal the completionEvent
    // when the request is completed.
    //
 
    irp = IoAllocateIrp(1, FALSE);
    if(irp == NULL) {
        return STATUS_INSUFFICIENT_RESOURCES;
    }        

    IoSetCompletionRoutine(irp, SyncIrpCompletionRoutine, 
  &completionEvent, TRUE, TRUE, TRUE);

    //
    // Make the WskGetAddressInfo request.
    //
 
    WskProviderNpi->Dispatch->WskGetAddressInfo (
        WskProviderNpi->Client,
        &uniNodeName,
        uniServiceNamePtr,
        NS_ALL,
        NULL, // Provider
        Hints,
        &results, 
        NULL, // OwningProcess
        NULL, // OwningThread
        irp);

    //
    // Wait for completion. Note that processing of name resolution results
    // can also be handled directly within the IRP completion routine, but
    // for simplicity, this example shows how to wait synchronously for 
    // completion.
    //
 
    KeWaitForSingleObject(&completionEvent, Executive, 
                        KernelMode, FALSE, NULL);

    status = irp->IoStatus.Status;

    IoFreeIrp(irp);

    if(!NT_SUCCESS(status)) {
        return status;
    }

    //
    // Process the name resolution results by iterating through the addresses
    // within the returned ADDRINFOEXW structure.
    //
 
   results; // your code here

    //
    // Release the returned ADDRINFOEXW structure when no longer needed.
    //
 
    WskProviderNpi->Dispatch->WskFreeAddressInfo(
        WskProviderNpi->Client,
        results);

    return status;
}