RestoreMediaSense-Funktion (iphlpapi.h)
Die RestoreMediaSense-Funktion stellt die Mediensensorfunktion des TCP/IP-Stapels auf einem lokalen Computer wieder her, auf dem zuvor die DisableMediaSense-Funktion aufgerufen wurde.
Syntax
IPHLPAPI_DLL_LINKAGE DWORD RestoreMediaSense(
OVERLAPPED *pOverlapped,
[optional] LPDWORD lpdwEnableCount
);
Parameter
pOverlapped
Ein Zeiger auf eine Struktur OVERLAPPED. Mit Ausnahme des hEvent-Elements müssen alle Member dieser Struktur auf 0 (null) festgelegt werden. Das hEvent-Element sollte ein Handle für ein gültiges Ereignisobjekt enthalten. Verwenden Sie die CreateEvent-Funktion , um dieses Ereignisobjekt zu erstellen.
[optional] lpdwEnableCount
Ein optionaler Zeiger auf eine DWORD-Variable, die die Anzahl der verbleibenden Verweise empfängt, wenn die RestoreMediaSense-Funktion erfolgreich ist. Die Variable wird auch von den Funktionen EnableRouter und UnenableRouter verwendet.
Rückgabewert
Wenn die Funktion erfolgreich ist, wird der Rückgabewert NO_ERROR.
Wenn die Funktion fehlschlägt, ist der Rückgabewert einer der folgenden Fehlercodes.
Rückgabecode | Beschreibung |
---|---|
|
Es wurde ein ungültiger Parameter an die Funktion übergeben. Dieser Fehler wird zurückgegeben, wenn ein pOverlapped-Parameter ein ungültiger Zeiger ist. Dieser Fehler wird auch zurückgegeben, wenn die DisableMediaSense-Funktion vor dem Aufruf der RestoreMediaSense-Funktion nicht aufgerufen wurde. |
|
Der Vorgang wird ausgeführt. Dieser Wert kann durch einen erfolgreichen asynchronen Aufruf von RestoreMediaSense zurückgegeben werden. |
|
Ein internes Handle für den Treiber war ungültig. |
|
Die Anforderung wird nicht unterstützt. |
|
Verwenden Sie FormatMessage , um die Meldungszeichenfolge für den zurückgegebenen Fehler abzurufen. |
Hinweise
Wenn der pOverlapped-ParameterNULL ist, wird die RestoreMediaSense-Funktion synchron ausgeführt.
Wenn der pOverlapped-Parameter nicht NULL ist, wird die RestoreMediaSense-Funktion asynchron mit der OVERLAPPED-Struktur ausgeführt, auf die der pOverlapped-Parameter verweist.
Die DisableMediaSense-Funktion wird erst abgeschlossen, wenn die RestoreMediaSense-Funktion später aufgerufen wird, um die Mediensensorfunktion wiederherzustellen. Bis dahin bleibt ein E/A-Anforderungspaket (IRP) in der Warteschlange. Wenn der Prozess mit dem Namen DisableMediaSense beendet wird, wird der IRP abgebrochen, und es wird eine Abbruchroutine aufgerufen, die die Mediensensorfunktion erneut wiederherstellen würde.
Um RestoreMediaSense synchron aufzurufen, muss eine Anwendung einen NULL-Zeiger im pOverlapped-Parameter übergeben. Wenn RestoreMediaSense synchron aufgerufen wird, gibt die Funktion zurück, wenn das E/A-Anforderungspaket (IRP) zum Wiederherstellen des Mediensinns abgeschlossen ist.
Um RestoreMediaSense asynchron aufzurufen, muss eine Anwendung eine OVERLAPPED-Struktur zuordnen. Mit Ausnahme des hEvent-Elements müssen alle Member dieser Struktur auf 0 (null) festgelegt werden. Das hEvent-Element erfordert ein Handle für ein gültiges Ereignisobjekt. Verwenden Sie die CreateEvent-Funktion , um dieses Ereignis zu erstellen. Wenn RestoreMediaSense asynchron aufgerufen wird, kann ERROR_IO_PENDING zurückgeben. Die IRP wird abgeschlossen, wenn die Mediensensorfunktion wiederhergestellt wurde. Verwenden Sie die CloseHandle-Funktion , um das Handle für das Ereignisobjekt zu schließen, wenn es nicht mehr benötigt wird. Das System schließt das Handle automatisch, wenn der Prozess beendet wird. Das Ereignisobjekt wird zerstört, wenn sein letztes Handle geschlossen wurde.
Wenn DisableMediaSense vor dem Aufrufen von RestoreMediaSense nicht aufgerufen wurde, gibt RestoreMediaSense ERROR_INVALID_PARAMETER zurück.
Unter Windows Server 2003 und Windows XP implementiert der TCP/IP-Stapel eine Richtlinie zum Löschen aller IP-Adressen auf einer Schnittstelle als Reaktion auf ein Medienoptimierungstrennereignis von einer zugrunde liegenden Netzwerkschnittstelle. Wenn ein Netzwerkswitch oder Hub, mit dem der lokale Computer verbunden ist, ausgeschaltet ist oder ein Netzwerkkabel getrennt wird, übermittelt die Netzwerkschnittstelle Trennungsereignisse. Ip-Konfigurationsinformationen, die der Netzwerkschnittstelle zugeordnet sind, geht verloren. Daher implementiert der TCP/IP-Stapel eine Richtlinie zum Ausblenden getrennter Schnittstellen, sodass diese Schnittstellen und die zugehörigen IP-Adressen nicht in den Konfigurationsinformationen angezeigt werden, die über das IP-Hilfsprogramm abgerufen werden. Diese Richtlinie verhindert, dass einige Anwendungen leicht erkennen, dass eine Netzwerkschnittstelle nur getrennt und nicht aus dem System entfernt wird.
Dieses Verhalten wirkt sich normalerweise nicht auf einen lokalen Clientcomputer aus, wenn DHCP-Anforderungen für IP-Konfigurationsinformationen an einen DHCP-Server verwendet werden. Dies kann jedoch schwerwiegende Auswirkungen auf Servercomputer haben, insbesondere auf Computer, die als Teil von Clustern verwendet werden. Die Funktion DisableMediaSense kann verwendet werden, um die Medienoptimierungsfunktion für diese Fälle vorübergehend zu deaktivieren. Zu einem späteren Zeitpunkt wird die RestoreMediaSense-Funktion aufgerufen, um die Medienerkennungsfunktion wiederherzustellen.
Die folgende Registrierungseinstellung bezieht sich auf die Funktionen DisableMediaSense und RestoreMediaSense :
System\Currentcontrolset\Dienstleistungen\Tcpip\Parameter\DisableDHCPMediaSense
Es gibt ein internes Flag in Windows, das festgelegt wird, wenn dieser Registrierungsschlüssel vorhanden ist, wenn der Computer zum ersten Mal gestartet wird. Dasselbe interne Flag wird auch festgelegt und zurückgesetzt, indem DisableMediaSense und RestoreMediaSense aufgerufen werden. Mit der Registrierungseinstellung müssen Sie den Computer jedoch neu starten, damit die Änderungen vorgenommen werden.
Der TCP/IP-Stapel unter Windows Vista und höher wurde so geändert, dass getrennte Schnittstellen nicht ausgeblendet werden, wenn ein Trennungsereignis auftritt. Unter Windows Vista und höher führen die Funktionen DisableMediaSense und RestoreMediaSense nichts aus und geben immer NO_ERROR zurück.
Beispiele
Das folgende Beispiel zeigt, wie die Funktionen DisableMediaSense und RestoreMediaSense synchron aufgerufen werden. Dieses Beispiel ist nur unter Windows Server 2003und Windows XP nützlich, wo die Funktionen DisableMediaSense und RestoreMediaSense nützlich sind.
Im Beispiel wird zunächst ein separater Thread erstellt, der die DisableMediaSense-Funktion synchron aufruft. Der Standard Thread wird 60 Sekunden lang in den Standbymodus versetzt, damit der Benutzer ein Netzwerkkabel trennen kann, ruft die IP-Adresstabelle ab und gibt einige Elemente der IP-Adresseinträge in der Tabelle aus, ruft die RestoreMediaSense-Funktion synchron auf, ruft die IP-Adresstabelle erneut ab. und gibt einige Member der IP-Adresseinträge in der Tabelle aus. Die Auswirkungen der Deaktivierung der Medienerkennungsfunktion können am Unterschied in den IP-Adresstabelleneinträgen gesehen werden.
Ein Beispiel zum asynchronen Aufrufen der Funktionen DisableMediaSense und RestoreMediaSense finden Sie in der DisableMediaSense-Funktionsreferenz .
#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);
}
Anforderungen
Unterstützte Mindestversion (Client) | Windows XP [nur Desktop-Apps] |
Unterstützte Mindestversion (Server) | Windows Server 2003 [nur Desktop-Apps] |
Zielplattform | Windows |
Kopfzeile | iphlpapi.h |
Bibliothek | Iphlpapi.lib |
DLL | Iphlpapi.dll |