Funzione DisableMediaSense (iphlpapi.h)
La funzione DisableMediaSense disabilita la funzionalità di rilevamento multimediale dello stack TCP/IP in un computer locale.
Sintassi
IPHLPAPI_DLL_LINKAGE DWORD DisableMediaSense(
HANDLE *pHandle,
OVERLAPPED *pOverLapped
);
Parametri
pHandle
Puntatore a una variabile usata per archiviare un handle. Se il parametro pOverlapped non è NULL, questa variabile verrà usata internamente per archiviare un handle necessario per chiamare il driver IP e disabilitare la funzionalità di rilevamento multimediale.
Un'applicazione non deve usare il valore a cui punta questa variabile. Questo handle è per l'uso interno e non deve essere chiuso.
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 richiede un handle per un oggetto evento valido. Usare la funzione CreateEvent per creare questo oggetto evento.
Valore restituito
Se la funzione ha esito positivo, il valore restituito è NO_ERROR.
Se la funzione ha esito negativo, il valore restituito è uno dei codici di errore seguenti.
Codice restituito | Descrizione |
---|---|
|
Un parametro non valido è stato passato alla funzione. Questo errore viene restituito se un parametro pOverlapped è un puntatore non valido. |
|
L'operazione è in corso. Questo valore viene restituito da una chiamata asincrona riuscita a DisableMediaSense. |
|
L'handle a cui fa riferimento il parametro pHandle non è valido. |
|
La richiesta non è supportata. |
|
Usare FormatMessage per ottenere la stringa di messaggio per l'errore restituito. |
Commenti
Se i parametri pHandle o pOverlapped sono NULL, la funzione DisableMediaSense viene eseguita in modo sincrono.
Se i parametri pHandle e pOverlapped non sono NULL, la funzione DisableMediaSense viene eseguita in modo asincrono usando la struttura OVERLAPPED a cui fa riferimento il parametro pOverlapped .
La funzione DisableMediaSense non viene completata fino a quando la funzione RestoreMediaSense viene chiamata in un secondo momento per ripristinare la funzionalità di rilevamento multimediale. Fino a allora, un pacchetto di richiesta I/O (IRP) rimane in coda. In alternativa, quando il processo denominato DisableMediaSense viene chiuso, l'IRP viene annullato e viene chiamata una routine di annullamento che ripristina nuovamente la funzionalità di rilevamento multimediale.
Per chiamare DisableMediaSense in modo sincrono, un'applicazione deve creare un thread separato per questa chiamata. In caso contrario, sarebbe in attesa del completamento di IRP e la funzione verrà bloccata.
Per chiamare DisableMediaSense 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, DisableMediaSense restituisce sempre ERROR_IO_PENDING. L'IRP verrà completato solo quando RestoreMediaSense viene chiamato in un secondo momento. Usare 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 quando l'ultimo handle è stato chiuso.
In Windows Server 2003and 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 è disattivato o viene disconnesso un cavo di rete, l'interfaccia di rete recapita eventi di disconnessione. Le informazioni di configurazione IP associate all'interfaccia di rete sono perse. Di conseguenza, lo stack TCP/IP implementa un criterio di nascondere interfacce disconnesse in modo che queste interfacce e i relativi indirizzi IP associati non vengano visualizzati nelle informazioni di configurazione recuperate tramite helper IP. Questo criterio impedisce a alcune applicazioni di rilevare facilmente che un'interfaccia di rete è semplicemente disconnessa, anziché rimossa dal sistema.
Questo comportamento non influisce normalmente su un computer client locale se usa richieste DHCP a un server DHCP per informazioni sulla configurazione IP. Ma questo può avere un impatto grave sui computer server, in particolare i computer usati come parte dei cluster. La funzione DisableMediaSense può essere temporaneamente 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 impostato se questa chiave del Registro di sistema esiste quando il computer viene avviato per la prima volta. Lo stesso flag interno viene impostato e reimpostato chiamando DisableMediaSense e RestoreMediaSense. Tuttavia, con l'impostazione del Registro di sistema, è necessario riavviare il computer per le modifiche da eseguire.
Lo stack TCP/IP in Windows Vista e successivamente è 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 fanno nulla e restituisce sempre NO_ERROR.
Esempio
Nell'esempio seguente viene illustrato come chiamare le funzioni DisableMediaSense e RestoreMediaSense in modo asincrono. Questo esempio è utile solo in Windows Server 2003and Windows XP in cui le funzioni DisableMediaSense e RestoreMediaSense fanno qualcosa di utile.
L'esempio chiama prima la funzione DisableMediaSense , dorme 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 , 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 multimediale può essere visto nella differenza nelle voci della tabella degli indirizzi IP.
Per un esempio che illustra come chiamare le funzioni DisableMediaSense e RestoreMediaSense in modo sincrono, vedere il riferimento alla funzione 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);
}
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 sulla funzione helper IP