共用方式為


RestoreMediaSense 函式 (iphlpapi.h)

RestoreMediaSense 函式會在先前呼叫 DisableMediaSense 函式的本機計算機上,還原 TCP/IP 堆棧的媒體感知功能。

語法

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

參數

pOverlapped

重疊結構的指標。 除了 hEvent 成員之外,此結構的所有成員都必須設定為零。 hEvent成員應該包含有效事件物件的句柄。 使用 CreateEvent 函式來建立此事件物件。

[optional] lpdwEnableCount

DWORD 變數的選擇性指標,如果 RestoreMediaSense 函式成功,則會接收剩餘的參考數目。 EnableRouterUnenableRouter 函式也會使用變數。

傳回值

如果函式成功,傳回值會NO_ERROR。

如果函式失敗,傳回值就是下列其中一個錯誤碼。

傳回碼 Description
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 結構以異步方式執行。

DisableMediaSense 函式在稍後呼叫 RestoreMediaSense 函式才能完成,以還原媒體感知功能。 在那之前,I/O 要求封包 (IRP) 仍會排入佇列。 或者,當呼叫 DisableMediaSense 的進程結束時,會取消 IRP,並呼叫取消例程,以再次還原媒體感測器功能。

若要以同步方式呼叫 RestoreMediaSense,應用程式必須在 pOverlapped 參數中傳遞 NULL 指標。 以同步方式呼叫 RestoreMediaSense 時,當 I/O 要求封包 (IRP) 完成還原媒體感知時,函式會傳回 。

若要以異步方式呼叫 RestoreMediaSense ,應用程式必須配置 重疊 結構。 除了 hEvent 成員之外,此結構的所有成員都必須設定為零。 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協助程式擷取的組態資訊中。 此原則可防止某些應用程式輕鬆地偵測網路介面只是中斷連線,而不是從系統移除。

如果本機用戶端計算機使用 DHCP 要求來取得IP組態資訊,此行為通常不會影響本機客戶端電腦。 但這可能會對伺服器計算機造成嚴重影響,特別是用來作為叢集一部分的計算機。 DisableMediaSense 函式可用來暫時停用這些案例的媒體感知功能。 稍後會呼叫 RestoreMediaSense 函式來還原媒體檢測功能。

下列登錄設定與 DisableMediaSenseRestoreMediaSense 函式有關:

系統\CurrentControlSet\服務\Tcpip\參數\DisableDHCPMediaSense

Windows 中有一個內部旗標,如果計算機第一次開機時存在此登錄機碼,就會設定此旗標。 相同的內部旗標也會藉由呼叫 DisableMediaSenseRestoreMediaSense 來設定和重設。 不過,使用登錄設定時,您必須重新啟動計算機,才能進行變更。

Windows Vista 和更新版本的 TCP/IP 堆棧在發生中斷連線事件時,已變更為不會隱藏已中斷連線的介面。 因此,在 Windows Vista 和更新版本上, DisableMediaSenseRestoreMediaSense 函式不會執行任何動作,而且一律會傳回NO_ERROR。

範例

下列範例示範如何同步呼叫 DisableMediaSenseRestoreMediaSense 函式。 此範例僅適用於 Windows Server 2003 和 Windows XP, 其中 DisableMediaSenseRestoreMediaSense 函式會執行有用的動作。

此範例會先建立個別線程,以同步方式呼叫 DisableMediaSense 函式,主線程會睡眠 60 秒,以允許使用者中斷網路纜線連線、擷取 IP 位址數據表,並列印數據表中 IP 位址專案的一些成員、同步呼叫 RestoreMediaSense 函式、再次擷取 IP 位址表、 並列印數據表中IP位址專案的一些成員。 在IP位址表項目的差異中,可以看到停用媒體通訊功能的影響。

如需示範如何以異步方式呼叫 DisableMediaSenseRestoreMediaSense 函式的範例,請參閱 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
程式庫 Iphlpapi.lib
Dll Iphlpapi.dll

另請參閱

CloseHandle

CreateEvent

DisableMediaSense

EnableRouter

IP 協助程式函式參考

IP 協助程式起始頁

重疊

UnenableRouter