Funzione RestoreMediaSense (iphlpapi.h)
La funzione RestoreMediaSense ripristina la funzionalità di rilevamento multimediale dello stack TCP/IP in un computer locale in cui è stata chiamata in precedenza la funzione DisableMediaSense .
Sintassi
IPHLPAPI_DLL_LINKAGE DWORD RestoreMediaSense(
OVERLAPPED *pOverlapped,
[optional] LPDWORD lpdwEnableCount
);
Parametri
pOverlapped
Puntatore a una struttura OVERLAPPED . Ad eccezione del membro hEvent , tutti i membri di questa struttura devono essere impostati su zero. Il membro hEvent deve contenere un handle per un oggetto evento valido. Utilizzare la funzione CreateEvent per creare questo oggetto evento.
[optional] lpdwEnableCount
Puntatore facoltativo a una variabile DWORD che riceve il numero di riferimenti rimanenti se la funzione RestoreMediaSense ha esito positivo. La variabile viene usata anche dalle funzioni EnableRouter e UnenableRouter .
Valore restituito
Se la funzione ha esito positivo, il valore restituito viene NO_ERROR.
Se la funzione ha esito negativo, il valore restituito è uno dei codici di errore seguenti.
Codice restituito | Descrizione |
---|---|
|
Alla funzione è stato passato un parametro non valido. Questo errore viene restituito se un parametro pOverlapped è un puntatore non valido. Questo errore viene restituito anche se la funzione DisableMediaSense non è stata chiamata prima di chiamare la funzione RestoreMediaSense . |
|
L'operazione è in corso. Questo valore può essere restituito da una chiamata asincrona riuscita a RestoreMediaSense. |
|
Handle interno per il driver non valido. |
|
La richiesta non è supportata. |
|
Usare FormatMessage per ottenere la stringa del messaggio per l'errore restituito. |
Commenti
Se il parametro pOverlapped è NULL, la funzione RestoreMediaSense viene eseguita in modo sincrono.
Se il parametro pOverlapped non è NULL, la funzione RestoreMediaSense viene eseguita in modo asincrono usando la struttura OVERLAPPED a cui punta il parametro pOverlapped .
La funzione DisableMediaSense non viene completata fino a quando non viene chiamata la funzione RestoreMediaSense in un secondo momento per ripristinare la funzionalità di rilevamento multimediale. Fino ad allora, un pacchetto di richiesta di I/O rimane in coda. In alternativa, quando il processo che ha chiamato DisableMediaSense viene chiuso, l'IRP viene annullato e viene chiamata una routine di annullamento che ripristina nuovamente la funzionalità di rilevamento multimediale.
Per chiamare RestoreMediaSense in modo sincrono, un'applicazione deve passare un puntatore NULL nel parametro pOverlapped . Quando RestoreMediaSense viene chiamato in modo sincrono, la funzione restituisce quando il pacchetto di richiesta di I/O (IRP) per ripristinare il senso multimediale è stato completato.
Per chiamare RestoreMediaSense in modo asincrono, un'applicazione deve allocare una struttura OVERLAPPED . Ad eccezione del membro hEvent , tutti i membri di questa struttura devono essere impostati su zero. Il membro hEvent richiede un handle per un oggetto evento valido. Usare la funzione CreateEvent per creare questo evento. Quando viene chiamato in modo asincrono, RestoreMediaSense può restituire ERROR_IO_PENDING. L'IRP viene completato quando è stata ripristinata la funzionalità di rilevamento multimediale. Utilizzare la funzione CloseHandle per chiudere l'handle all'oggetto evento quando non è più necessario. Il sistema chiude automaticamente l'handle al termine del processo. L'oggetto evento viene eliminato definitivamente quando l'ultimo handle è stato chiuso.
Se DisableMediaSense non è stato chiamato prima di chiamare RestoreMediaSense, RestoreMediaSense restituisce ERROR_INVALID_PARAMETER.
In Windows Server 2003e Windows XP, lo stack TCP/IP implementa un criterio di eliminazione di tutti gli indirizzi IP in un'interfaccia in risposta a un evento di disconnessione del senso multimediale da un'interfaccia di rete sottostante. Se un commutatore di rete o un hub a cui è connesso il computer locale è spento o se un cavo di rete è disconnesso, l'interfaccia di rete fornirà eventi di disconnessione. Le informazioni di configurazione IP associate all'interfaccia di rete andranno perse. Di conseguenza, lo stack TCP/IP implementa un criterio per nascondere le interfacce disconnesse in modo che queste interfacce e i relativi indirizzi IP associati non vengano visualizzati nelle informazioni di configurazione recuperate tramite l'helper IP. Questo criterio impedisce ad alcune applicazioni di rilevare facilmente che un'interfaccia di rete è semplicemente disconnessa, anziché rimossa dal sistema.
Questo comportamento in genere non influisce su un computer client locale se usa richieste DHCP a un server DHCP per le informazioni di configurazione IP. Ma questo può avere un impatto grave sui computer server, in particolare sui computer usati come parte dei cluster. La funzione DisableMediaSense può essere usata per disabilitare temporaneamente la funzionalità di rilevamento multimediale per questi casi. In un secondo momento, la funzione RestoreMediaSense verrà chiamata per ripristinare la funzionalità di rilevamento multimediale.
L'impostazione del Registro di sistema seguente è correlata alle funzioni DisableMediaSense e RestoreMediaSense :
Sistema\Currentcontrolset\Servizi\Tcpip\Parametri\DisableDHCPMediaSense
Esiste un flag interno in Windows che viene impostato se questa chiave del Registro di sistema esiste al primo avvio del computer. Lo stesso flag interno viene impostato e reimpostato chiamando DisableMediaSense e RestoreMediaSense. Tuttavia, con l'impostazione del Registro di sistema, è necessario riavviare il computer in modo che le modifiche vengano apportate.
Lo stack TCP/IP in Windows Vista e versioni successive è stato modificato in modo da non nascondere le interfacce disconnesse quando si verifica un evento di disconnessione. Quindi, in Windows Vista e versioni successive, le funzioni DisableMediaSense e RestoreMediaSense non eseguono alcuna operazione e restituiscono sempre NO_ERROR.
Esempio
L'esempio seguente illustra come chiamare in modo sincrono le funzioni DisableMediaSense e RestoreMediaSense . Questo esempio è utile solo in Windows Server 2003and Windows XP, in cui le funzioni DisableMediaSense e RestoreMediaSense svolgono un'operazione utile.
L'esempio crea innanzitutto un thread separato che chiama la funzione DisableMediaSense in modo sincrono, il thread principale rimane inattivo per 60 secondi per consentire all'utente di disconnettere un cavo di rete, recupera la tabella degli indirizzi IP e stampa alcuni membri delle voci dell'indirizzo IP nella tabella, chiama la funzione RestoreMediaSense in modo sincrono, recupera nuovamente la tabella degli indirizzi IP, e stampa alcuni membri delle voci dell'indirizzo IP nella tabella. L'impatto della disabilitazione della funzionalità di rilevamento dei supporti può essere rilevato nella differenza nelle voci della tabella degli indirizzi IP.
Per un esempio che illustra come chiamare le funzioni DisableMediaSense e RestoreMediaSense in modo asincrono, vedere il riferimento alla funzione 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);
}
Requisiti
Client minimo supportato | Windows XP [solo app desktop] |
Server minimo supportato | Windows Server 2003 [solo app desktop] |
Piattaforma di destinazione | Windows |
Intestazione | iphlpapi.h |
Libreria | Iphlpapi.lib |
DLL | Iphlpapi.dll |
Vedi anche
Informazioni di riferimento sulle funzioni helper IP