Compartir a través de


Resolución de nombres de host y direcciones IP

A partir de Windows 7, una característica de resolución de nombres de kernel permite a los componentes del modo kernel realizar la traducción independiente del protocolo entre los nombres de host Unicode y las direcciones de transporte. Puede usar las siguientes funciones de nivel de cliente de Winsock Kernel (WSK) para realizar esta resolución de nombres:

Estas funciones realizan la traducción de direcciones de nombre de forma similar a las funciones en modo de usuario FreeAddrInfoW, GetAddrInfoW y GetNameInfoW, respectivamente.

Para aprovechar esta característica, debe compilar o volver a compilar el controlador con la macro NTDDI_VERSION establecida en NTDDI_WIN7 o superior.

Para que el controlador use la funcionalidad de resolución de nombres de kernel, debe realizar la siguiente secuencia de llamada:

  1. Llame a WskRegister para registrarse con WSK.

  2. Llame a WskCaptureProviderNPI para capturar la interfaz de programación de red (NPI) del proveedor WSK.

  3. Cuando haya terminado de usar el proveedor de WSK NPI, llame a WskReleaseProviderNPI para liberar el NPI del proveedor WSK.

  4. Llame a WskDeregister para anular el registro de la aplicación WSK.

En el ejemplo de código siguiente se usa la secuencia de llamada anterior para mostrar cómo una aplicación WSK puede llamar a la función WskGetAddressInfo para traducir un nombre de host a una dirección de transporte.

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;
}