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。
如果函式失敗,傳回值就是下列其中一個錯誤碼。
傳回碼 | 描述 |
---|---|
|
不正確參數已傳遞至 函式。 如果 pOverlapped 參數是不正確的指標,就會傳回此錯誤。 |
|
作業正在進行中。 這個值是由 DisableMediaSense的成功非同步呼叫所傳回。 |
|
pHandle參數指向的控制碼無效。 |
|
不支援此要求。 |
|
使用 FormatMessage 取得傳回錯誤的訊息字串。 |
備註
如果 pHandle 或 pOverlapped 參數為 Null,則會同步執行 DisableMediaSense 函式。
如果pHandle和pOverlapped參數都不是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 函式來還原媒體檢測功能。
下列登錄設定與 DisableMediaSense 和 RestoreMediaSense 函式相關:
系統\CurrentControlSet\服務\Tcpip\參數\DisableDHCPMediaSense
如果電腦第一次開機時存在此登錄機碼,Windows 中就會設定內部旗標。 相同的內部旗標也會藉由呼叫 DisableMediaSense 和 RestoreMediaSense來設定和重設。 不過,使用登錄設定時,您必須重新開機電腦,才能進行變更。
當發生中斷線上活動時,Windows Vista 和更新版本的 TCP/IP 堆疊已變更為不會隱藏中斷連線的介面。 因此,在 Windows Vista 和更新版本上, DisableMediaSense 和 RestoreMediaSense 函式不會執行任何動作,而且一律會傳回NO_ERROR。
範例
下列範例示範如何以非同步方式呼叫 DisableMediaSense 和 RestoreMediaSense 函式。 此範例僅適用于 Windows Server 2003 和 Windows XP, 其中 DisableMediaSense 和 RestoreMediaSense 函式會執行有用的動作。
此範例會先呼叫 DisableMediaSense 函式、睡眠 60 秒以允許使用者中斷網路纜線的連線、擷取 IP 位址資料表,並列印資料表中 IP 位址專案的一些成員、呼叫 RestoreMediaSense 函式、再次擷取 IP 位址資料表,以及列印資料表中的某些 IP 位址專案成員。 在 IP 位址資料表專案的差異中,可以看到停用媒體感應器功能的影響。
如需示範如何同步呼叫 DisableMediaSense 和 RestoreMediaSense 函式的範例,請參閱 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 |