次の方法で共有


RestoreMediaSense 関数 (iphlpapi.h)

RestoreMediaSense 関数は、DisableMediaSense 関数が以前に呼び出されたローカル コンピューター上の TCP/IP スタックのメディア 検出機能を復元します。

構文

IPHLPAPI_DLL_LINKAGE DWORD RestoreMediaSense(
             OVERLAPPED *pOverlapped,
  [optional] LPDWORD    lpdwEnableCount
);

パラメーター

pOverlapped

OVERLAPPED 構造体へのポインター。 hEvent メンバーを除き、この構造体のすべてのメンバーを 0 に設定する必要があります。 hEvent メンバーには、有効なイベント オブジェクトへのハンドルが含まれている必要があります。 CreateEvent 関数を使用して、このイベント オブジェクトを作成します。

[optional] lpdwEnableCount

RestoreMediaSense 関数が成功した場合に残りの参照の数を受け取る DWORD 変数への省略可能なポインター。 変数は、 EnableRouter 関数と UnenableRouter 関数でも使用されます。

戻り値

関数が成功した場合、戻り値はNO_ERROR。

関数が失敗した場合、戻り値は次のいずれかのエラー コードになります。

リターン コード 説明
ERROR_INVALID_PARAMETER
無効なパラメーターが関数に渡されました。 このエラーは、 pOverlapped パラメーターが不適切なポインターである場合に返されます。 このエラーは、 RestoreMediaSense 関数を呼び出す前に DisableMediaSense 関数が呼び出されなかった場合にも返されます。
ERROR_IO_PENDING
操作が進行中です。 この値は、 RestoreMediaSense の非同期呼び出しが成功すると返される場合があります。
ERROR_OPEN_FAILED
ドライバーの内部ハンドルが無効でした。
ERROR_NOT_SUPPORTED
要求はサポートされていません。
その他
FormatMessage を使用して、返されたエラーのメッセージ文字列を取得します。

注釈

pOverlapped パラメーターが NULL の場合、RestoreMediaSense 関数は同期的に実行されます。

pOverlapped パラメーターが NULL でない場合、RestoreMediaSense 関数は pOverlapped パラメーターが指す OVERLAPPED 構造体を使用して非同期的に実行されます。

メディア 検出機能を復元するために RestoreMediaSense 関数が後で呼び出されるまで、DisableMediaSense 関数は完了しません。 それまでは、I/O 要求パケット (IRP) はキューに登録されたままです。 または、 DisableMediaSense を呼び出したプロセスが終了すると、IRP が取り消され、メディア 検出機能を再度復元するキャンセル ルーチンが呼び出されます。

RestoreMediaSense を同期的に呼び出すには、アプリケーションで pOverlapped パラメーターに NULL ポインターを渡す必要があります。 RestoreMediaSense が同期的に呼び出されると、メディア センスを復元するための I/O 要求パケット (IRP) が完了すると、関数は を返します。

RestoreMediaSense を非同期的に呼び出すには、アプリケーションで OVERLAPPED 構造体を割り当てる必要があります。 hEvent メンバーを除き、この構造体のすべてのメンバーを 0 に設定する必要があります。 hEvent メンバーには、有効なイベント オブジェクトへのハンドルが必要です。 CreateEvent 関数を使用して、このイベントを作成します。 非同期で呼び出されると、 RestoreMediaSense はERROR_IO_PENDINGを返すことができます。 メディア 検出機能が復元されると、IRP は完了します。 CloseHandle 関数を使用して、不要になったイベント オブジェクトへのハンドルを閉じます。 プロセスが終了すると、ハンドルが自動的に閉じられます。 イベント オブジェクトは、最後のハンドルが閉じられたときに破棄されます。

RestoreMediaSense を呼び出す前に DisableMediaSense が呼び出されなかった場合、RestoreMediaSense はERROR_INVALID_PARAMETERを返します。

Windows Server 2003 および Windows XP では、TCP/IP スタックは、基になるネットワーク インターフェイスからメディア センス切断イベントに応答して、インターフェイス上のすべての IP アドレスを削除するポリシーを実装します。 ローカル コンピューターが接続されているネットワーク スイッチまたはハブの電源がオフになっている場合、またはネットワーク ケーブルが切断されている場合、ネットワーク インターフェイスは切断イベントを配信します。 ネットワーク インターフェイスに関連付けられている IP 構成情報が失われます。 その結果、TCP/IP スタックは、切断されたインターフェイスを非表示にするポリシーを実装するため、これらのインターフェイスとそれに関連付けられている IP アドレスは、IP ヘルパーを介して取得された構成情報に表示されません。 このポリシーにより、一部のアプリケーションでは、システムから削除されるのではなく、ネットワーク インターフェイスが単に切断されていることを簡単に検出できなくなります。

この動作は、通常、IP 構成情報に DHCP サーバーへの DHCP 要求を使用している場合、ローカル クライアント コンピューターには影響しません。 ただし、これはサーバー コンピューター、特にクラスターの一部として使用されるコンピューターに深刻な影響を与える可能性があります。 DisableMediaSense 関数を使用すると、このような場合にメディア センス機能を一時的に無効にすることができます。 しばらくすると、メディア 検出機能を復元するために RestoreMediaSense 関数が呼び出されます。

次のレジストリ設定は、 DisableMediaSense 関数と RestoreMediaSense 関数に関連しています。

システム\CurrentControlSet\サービス\Tcpip\パラメーター\DisableDHCPMediaSense

Windows には、マシンが最初に起動したときにこのレジストリ キーが存在する場合に設定される内部フラグがあります。 また、 DisableMediaSenseRestoreMediaSense を呼び出すことで、同じ内部フラグが設定およびリセットされます。 ただし、レジストリ設定では、変更を行うためにマシンを再起動する必要があります。

Windows Vista 以降の TCP/IP スタックは、切断イベントが発生したときに切断されたインターフェイスを非表示にしないように変更されました。 そのため、Windows Vista 以降では、 DisableMediaSense 関数と RestoreMediaSense 関数は何もせず、常にNO_ERRORを返します。

次の例は、 DisableMediaSense 関数と RestoreMediaSense 関数を同期的に呼び出す方法を示しています。 このサンプルは、 DisableMediaSense 関数と RestoreMediaSense 関数が役立つ機能を実行する Windows Server 2003 および Windows XP でのみ役立ちます。

このサンプルでは、最初に DisableMediaSense 関数を同期的に呼び出す別のスレッドを作成します。メイン スレッドは、ユーザーがネットワーク ケーブルを切断できるように 60 秒間スリープ状態になり、IP アドレス テーブルを取得して、テーブル内の IP アドレス エントリの一部のメンバーを出力し、RestoreMediaSense 関数を同期的に呼び出し、IP アドレス テーブルをもう一度取得します。 IP アドレス エントリの一部のメンバーをテーブルに出力します。 メディア 検出機能を無効にした場合の影響は、IP アドレス テーブル エントリの違いにあります。

DisableMediaSense 関数と RestoreMediaSense 関数を非同期で呼び出す方法を示す例については、DisableMediaSense 関数リファレンスを参照してください。

#include <winsock2.h>
#include <ws2tcpip.h>
#include <iphlpapi.h>
#include <stdio.h>

#pragma comment(lib, "iphlpapi.lib")
#pragma comment(lib, "ws2_32.lib")

#define MALLOC(x) HeapAlloc(GetProcessHeap(), 0, (x))
#define FREE(x) HeapFree(GetProcessHeap(), 0, (x))

/* Note: could also use malloc() and free() */

// The thread proc to call DisableMediaSense
DWORD WINAPI ThreadProc(LPVOID lpParam)
{
    if (*((DWORD *) lpParam)) {
        DWORD dwRetVal;
        dwRetVal = DisableMediaSense(NULL, NULL);
        if (dwRetVal && dwRetVal != ERROR_IO_PENDING) {
            printf("DisableMediaSense failed with error %d\n", dwRetVal);
            return 0;
        } else {
            Sleep(1000);
            printf(" === DisableMediaSense Returned now. ===\n\n");
        }
    }
    return 0;
}

int __cdecl main()
{

    int i;

    /* Variables used by GetIpAddrTable */
    PMIB_IPADDRTABLE pIPAddrTable;
    DWORD dwSize = 0;
    DWORD dwRetVal = 0;
    IN_ADDR IPAddr;

    /* Variables used to return error message */
    LPVOID lpMsgBuf;

    /* Variable to use with RestoreMediaSense */
    DWORD dwEnableCount = 0;

    // Variables used to create a separate thread to call
    // the DisableMediaSense function
    DWORD ThreadID;
    DWORD IsDisable = TRUE;
    HANDLE Disable_THandle;

    // Create the thread to call Disable MediaSense synchronously
    Disable_THandle =
        CreateThread(NULL, 0, ThreadProc, (LPVOID) & IsDisable, 0, &ThreadID);
    if (!Disable_THandle) {
        printf("CreateTread Failed:%d", GetLastError());
        exit(1);
    }

    printf(" === DisableMediaSense called on separate thread ===\n\n");
// Sleep for 60 seconds so we can disconnect a cable
    Sleep(60000);

    // Before calling AddIPAddress we use GetIpAddrTable to get
    // an adapter to which we can add the IP.
    pIPAddrTable = (MIB_IPADDRTABLE *) MALLOC(sizeof (MIB_IPADDRTABLE));

    if (pIPAddrTable) {
        // Make an initial call to GetIpAddrTable to get the
        // necessary size into the dwSize variable
        if (GetIpAddrTable(pIPAddrTable, &dwSize, 0) ==
            ERROR_INSUFFICIENT_BUFFER) {
            FREE(pIPAddrTable);
            pIPAddrTable = (MIB_IPADDRTABLE *) MALLOC(dwSize);

        }
        if (pIPAddrTable == NULL) {
            printf("Memory allocation failed for GetIpAddrTable\n");
            exit(1);
        }
    }
    // Make a second call to GetIpAddrTable to get the
    // actual data we want
    if ((dwRetVal = GetIpAddrTable(pIPAddrTable, &dwSize, 0)) != NO_ERROR) {
        printf("GetIpAddrTable failed with error %d\n", dwRetVal);
        if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
                    FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, 
                    NULL, 
                    dwRetVal, 
                    MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
                    (LPTSTR) & lpMsgBuf, 0, NULL)) {
            printf("\tError: %s", lpMsgBuf);
            LocalFree(lpMsgBuf);
        }
        exit(1);
    }

    printf("\tNum Entries: %ld\n", pIPAddrTable->dwNumEntries);
    for (i = 0; i < (int) pIPAddrTable->dwNumEntries; i++) {
        printf("\n\tInterface Index[%d]:\t%ld\n", i,
               pIPAddrTable->table[i].dwIndex);
        IPAddr.S_un.S_addr = (u_long) pIPAddrTable->table[i].dwAddr;
        printf("\tIP Address[%d]:     \t%s\n", i, inet_ntoa(IPAddr));
        IPAddr.S_un.S_addr = (u_long) pIPAddrTable->table[i].dwMask;
        printf("\tSubnet Mask[%d]:    \t%s\n", i, inet_ntoa(IPAddr));
        IPAddr.S_un.S_addr = (u_long) pIPAddrTable->table[i].dwBCastAddr;
        printf("\tBroadCast[%d]:      \t%s (%ld%)\n", i, inet_ntoa(IPAddr),
               pIPAddrTable->table[i].dwBCastAddr);
        printf("\tReassembly size[%d]:\t%ld\n", i,
               pIPAddrTable->table[i].dwReasmSize);
        printf("\tType and State[%d]:", i);
        if (pIPAddrTable->table[i].wType & MIB_IPADDR_PRIMARY)
            printf("\tPrimary IP Address");
        if (pIPAddrTable->table[i].wType & MIB_IPADDR_DYNAMIC)
            printf("\tDynamic IP Address");
        if (pIPAddrTable->table[i].wType & MIB_IPADDR_DISCONNECTED)
            printf("\tAddress is on disconnected interface");
        if (pIPAddrTable->table[i].wType & MIB_IPADDR_DELETED)
            printf("\tAddress is being deleted");
        if (pIPAddrTable->table[i].wType & MIB_IPADDR_TRANSIENT)
            printf("\tTransient address");
        printf("\n");
    }

    // Call RestoreMediaSense synchronously to enable mediasense
    dwRetVal = RestoreMediaSense(NULL, &dwEnableCount);
    if (dwRetVal && dwRetVal != ERROR_IO_PENDING) {
        printf("RestoreMediaSense failed with error %d\n", dwRetVal);
        exit(1);
    } else {
        printf(" === RestoreMediaSense called ===\n");
        printf("  EnableCount returned was %ld\n\n", dwEnableCount);
    }

    if (pIPAddrTable) {
        // Make an initial call to GetIpAddrTable to get the
        // necessary size into the dwSize variable
        if (GetIpAddrTable(pIPAddrTable, &dwSize, 0) ==
            ERROR_INSUFFICIENT_BUFFER) {
            FREE(pIPAddrTable);
            pIPAddrTable = (MIB_IPADDRTABLE *) MALLOC(dwSize);

        }
        if (pIPAddrTable == NULL) {
            printf("Memory allocation failed for GetIpAddrTable\n");
            exit(1);
        }
    }
    // Make a second call to GetIpAddrTable to get the
    // actual data we want
    if ((dwRetVal = GetIpAddrTable(pIPAddrTable, &dwSize, 0)) != NO_ERROR) {
        printf("GetIpAddrTable failed with error %d\n", dwRetVal);
        if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
                    FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, 
                    NULL, 
                    dwRetVal, 
                    MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
                    (LPTSTR) & lpMsgBuf, 0, NULL)) {
            printf("\tError: %s", lpMsgBuf);
            LocalFree(lpMsgBuf);
        }
        exit(1);
    }

    printf("\tNum Entries: %ld\n", pIPAddrTable->dwNumEntries);
    for (i = 0; i < (int) pIPAddrTable->dwNumEntries; i++) {
        printf("\n\tInterface Index[%d]:\t%ld\n", i,
               pIPAddrTable->table[i].dwIndex);
        IPAddr.S_un.S_addr = (u_long) pIPAddrTable->table[i].dwAddr;
        printf("\tIP Address[%d]:     \t%s\n", i, inet_ntoa(IPAddr));
        IPAddr.S_un.S_addr = (u_long) pIPAddrTable->table[i].dwMask;
        printf("\tSubnet Mask[%d]:    \t%s\n", i, inet_ntoa(IPAddr));
        IPAddr.S_un.S_addr = (u_long) pIPAddrTable->table[i].dwBCastAddr;
        printf("\tBroadCast[%d]:      \t%s (%ld%)\n", i, inet_ntoa(IPAddr),
               pIPAddrTable->table[i].dwBCastAddr);
        printf("\tReassembly size[%d]:\t%ld\n", i,
               pIPAddrTable->table[i].dwReasmSize);
        printf("\tType and State[%d]:", i);
        if (pIPAddrTable->table[i].wType & MIB_IPADDR_PRIMARY)
            printf("\tPrimary IP Address");
        if (pIPAddrTable->table[i].wType & MIB_IPADDR_DYNAMIC)
            printf("\tDynamic IP Address");
        if (pIPAddrTable->table[i].wType & MIB_IPADDR_DISCONNECTED)
            printf("\tAddress is on disconnected interface");
        if (pIPAddrTable->table[i].wType & MIB_IPADDR_DELETED)
            printf("\tAddress is being deleted");
        if (pIPAddrTable->table[i].wType & MIB_IPADDR_TRANSIENT)
            printf("\tTransient address");
        printf("\n");
    }

    if (pIPAddrTable) {
        FREE(pIPAddrTable);
        pIPAddrTable = NULL;
    }

    exit(0);
}


要件

   
サポートされている最小のクライアント Windows XP (デスクトップ アプリのみ)
サポートされている最小のサーバー Windows Server 2003 (デスクトップ アプリのみ)
対象プラットフォーム Windows
ヘッダー iphlpapi.h
Library Iphlpapi.lib
[DLL] Iphlpapi.dll

こちらもご覧ください

CloseHandle

CreateEvent

DisableMediaSense

EnableRouter

IP ヘルパー関数リファレンス

IP ヘルパーの開始ページ

OVERLAPPED

UnenableRouter