次の方法で共有


ホスト名と IP アドレスの解決

Windows 7 以降では、カーネルの名前解決機能を使用すると、カーネル モード コンポーネントは、Unicode ホスト名とトランスポート アドレスの間でプロトコルに依存しない変換を実行できます。 次の Winsock カーネル (WSK) クライアント レベルの関数を使用して、この名前解決を実行できます。

これらの関数は、ユーザー モード関数 FreeAddrInfoWGetAddrInfoW、および GetNameInfoW と同様に、名前アドレス変換を実行します。

この機能を利用するには、NTDDI_VERSION マクロを NTDDI_WIN7 以上に設定して、ドライバーをコンパイルまたは再コンパイルする必要があります。

ドライバーでカーネル名解決機能を使用するには、次の呼び出しシーケンスを実行する必要があります。

  1. WskRegister を呼び出して WSK に登録します。

  2. WskCaptureProviderNPI を呼び出して、WSK プロバイダーのネットワーク プログラミング インターフェイス (NPI) をキャプチャします。

  3. WSK プロバイダー NPI の使用が完了したら、WskReleaseProviderNPI を呼び出して WSK プロバイダー NPI を解放します。

  4. WskDeregister を呼び出して、WSK アプリケーションの登録を解除します。

次のコード例では、上記の呼び出しシーケンスを使用して、WSK アプリケーションが WskGetAddressInfo 関数を呼び出してホスト名をトランスポート アドレスに変換する方法を示します。

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