共用方式為


DisableMediaSense 函式 (iphlpapi.h)

DisableMediaSense函式會停用本機電腦上的 TCP/IP 堆疊媒體感知功能。

語法

IPHLPAPI_DLL_LINKAGE DWORD DisableMediaSense(
  HANDLE     *pHandle,
  OVERLAPPED *pOverLapped
);

參數

pHandle

用來儲存控制碼之變數的指標。 如果 pOverlapped 參數不是 Null,則會在內部使用此變數來儲存呼叫 IP 驅動程式並停用媒體感應器功能所需的控制碼。

應用程式不應該使用此變數所指向的值。 此控制碼適用于內部使用,不應關閉。

pOverLapped

重迭結構的指標。 除了 hEvent 成員之外,此結構的所有成員都必須設定為零。 hEvent成員需要有效事件物件的控制碼。 使用 CreateEvent 函式來建立此事件物件。

傳回值

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

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

傳回碼 描述
ERROR_INVALID_PARAMETER
不正確參數已傳遞至 函式。 如果 pOverlapped 參數是不正確的指標,就會傳回此錯誤。
ERROR_IO_PENDING
作業正在進行中。 這個值是由 DisableMediaSense的成功非同步呼叫所傳回。
ERROR_OPEN_FAILED
pHandle參數指向的控制碼無效。
ERROR_NOT_SUPPORTED
不支援此要求。
其他
使用 FormatMessage 取得傳回錯誤的訊息字串。

備註

如果 pHandlepOverlapped 參數為 Null,則會同步執行 DisableMediaSense 函式。

如果pHandlepOverlapped參數都不是Null,則會使用pOverlapped參數所指向的OVERLAPPED結構,以非同步方式執行DisableMediaSense函式。

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

若要同步呼叫 DisableMediaSense ,應用程式必須為此呼叫建立個別執行緒。 否則,它會持續等候 IRP 完成,且函式會封鎖。

若要以非同步方式呼叫 DisableMediaSense ,應用程式必須配置 OVERLAPPED 結構。 除了 hEvent 成員之外,此結構的所有成員都必須設定為零。 hEvent成員需要有效事件物件的控制碼。 使用 CreateEvent 函式來建立此事件。 以非同步方式呼叫時, DisableMediaSense 一律會傳回ERROR_IO_PENDING。 只有在稍後呼叫 RestoreMediaSense 時,才會完成 IRP。 當不再需要事件物件時,請使用 CloseHandle 函式關閉事件的控制碼。 當進程終止時,系統會自動關閉控制碼。 當最後一個控制碼已關閉時,就會終結事件物件。

在 Windows Server 2003 和 Windows XP 上,TCP/IP 堆疊會實作一個原則,以刪除介面上的所有 IP 位址,以回應來自基礎網路介面的媒體感知中斷事件。 如果本機電腦連線的網路交換器或中樞已關閉電源,或網路纜線中斷連線,網路介面將會傳遞中斷線上活動。 與網路介面相關聯的 IP 組態資訊會遺失。 因此,TCP/IP 堆疊會實作隱藏中斷連線介面的原則,讓這些介面及其相關聯的 IP 位址不會顯示在透過 IP 協助程式擷取的組態資訊中。 此原則可防止某些應用程式輕鬆地偵測網路介面只是中斷連線,而不是從系統移除。

如果本機用戶端電腦對 DHCP 伺服器使用 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 函式的範例,請參閱 RestoreMediaSense 函式參考。

#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() */

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;

    // Variables to call DisableMediaSense
    //  and RestoreMediaSense asynchronously
    HANDLE IpDriverHandle = INVALID_HANDLE_VALUE;
    OVERLAPPED Overlapped;
    HANDLE DriverHandle;
    DWORD dwEnableCount = 0;

    memset(&Overlapped, 0, sizeof (Overlapped));
    Overlapped.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);

    dwRetVal = DisableMediaSense(&DriverHandle, &Overlapped);
    if (dwRetVal != ERROR_IO_PENDING) {
        printf("DisableMediaSense failed with error %d\n", dwRetVal);
        exit(1);
    } else {
        printf(" === DisableMediaSense called ===\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 asynchronously to enable mediasense
    dwRetVal = RestoreMediaSense(&Overlapped, &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

EnableRouter

IP 協助程式函式參考

IP 協助程式起始頁

重疊

RestoreMediaSense

UnenableRouter