Partager via


DisableMediaSense, fonction (iphlpapi.h)

La fonction DisableMediaSense désactive la fonctionnalité de détection multimédia de la pile TCP/IP sur un ordinateur local.

Syntaxe

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

Paramètres

pHandle

Pointeur vers une variable utilisée pour stocker un handle. Si le paramètre pOverlapped n’est pas NULL, cette variable est utilisée en interne pour stocker un handle requis pour appeler le pilote IP et désactiver la fonctionnalité de détection du média.

Une application ne doit pas utiliser la valeur pointée par cette variable. Ce handle est destiné à un usage interne et ne doit pas être fermé.

pOverLapped

Pointeur vers une structure OVERLAPPED. À l’exception du membre hEvent , tous les membres de cette structure doivent être définis sur zéro. Le membre hEvent nécessite un handle pour un objet d’événement valide. Utilisez la fonction CreateEvent pour créer cet objet d’événement.

Valeur retournée

Si la fonction réussit, la valeur de retour est NO_ERROR.

Si la fonction échoue, la valeur de retour est l’un des codes d’erreur suivants.

Code de retour Description
ERROR_INVALID_PARAMETER
Un paramètre non valide a été transmis à la fonction. Cette erreur est retournée si un paramètre pOverlapped est un pointeur incorrect.
ERROR_IO_PENDING
L’opération est en cours. Cette valeur est retournée par un appel asynchrone réussi à DisableMediaSense.
ERROR_OPEN_FAILED
Le handle pointé par le paramètre pHandle n’était pas valide.
ERROR_NOT_SUPPORTED
La demande n'est pas prise en charge.
Autres
Utilisez FormatMessage pour obtenir la chaîne de message de l’erreur retournée.

Notes

Si les paramètres pHandle ou pOverlapped ont la valeur NULL, la fonction DisableMediaSense est exécutée de manière synchrone.

Si les paramètres pHandle et pOverlapped ne sont pas NULL, la fonction DisableMediaSense est exécutée de façon asynchrone à l’aide de la structure OVERLAPPED pointée vers le paramètre pOverlapped .

La fonction DisableMediaSense ne se termine pas tant que la fonction RestoreMediaSense n’est pas appelée ultérieurement pour restaurer la fonctionnalité de détection du média. En attendant, un paquet de demandes d’E/S (IRP) reste mis en file d’attente. Sinon, lorsque le processus qui a appelé DisableMediaSense se termine, l’IRP est annulé et une routine d’annulation est appelée pour restaurer à nouveau la capacité de détection du média.

Pour appeler DisableMediaSense de manière synchrone, une application doit créer un thread distinct pour cet appel. Sinon, elle continue d’attendre l’achèvement de l’IRP et la fonction se bloque.

Pour appeler DisableMediaSense de manière asynchrone, une application doit allouer une structure CHEVAUCHEMENT . À l’exception du membre hEvent , tous les membres de cette structure doivent être définis sur zéro. Le membre hEvent nécessite un handle pour un objet d’événement valide. Utilisez la fonction CreateEvent pour créer cet événement. Lorsqu’il est appelé de manière asynchrone, DisableMediaSense retourne toujours ERROR_IO_PENDING. L’IRP sera effectué uniquement lorsque RestoreMediaSense sera appelé ultérieurement. Utilisez la fonction CloseHandle pour fermer le handle à l’objet d’événement quand il n’est plus nécessaire. Le système ferme automatiquement le handle à l’arrêt du processus. L’objet d’événement est détruit lorsque son dernier handle a été fermé.

Sur Windows Server 2003 et Windows XP, la pile TCP/IP implémente une stratégie de suppression de toutes les adresses IP sur une interface en réponse à un événement de déconnexion media sense d’une interface réseau sous-jacente. Si un commutateur réseau ou un hub auquel l’ordinateur local est connecté est hors tension, ou si un câble réseau est déconnecté, l’interface réseau fournit des événements de déconnexion. Les informations de configuration IP associées à l’interface réseau sont perdues. Par conséquent, la pile TCP/IP implémente une stratégie de masquage des interfaces déconnectées afin que ces interfaces et leurs adresses IP associées n’apparaissent pas dans les informations de configuration récupérées via l’assistance IP. Cette stratégie empêche certaines applications de détecter facilement qu’une interface réseau est simplement déconnectée, plutôt que supprimée du système.

Ce comportement n’a normalement pas d’impact sur un ordinateur client local s’il utilise des requêtes DHCP adressées à un serveur DHCP pour obtenir des informations de configuration IP. Mais cela peut avoir un impact sérieux sur les ordinateurs serveurs, en particulier les ordinateurs utilisés dans le cadre de clusters. La fonction DisableMediaSense peut être utilisée pour désactiver temporairement la fonctionnalité de détection multimédia pour ces cas. Plus tard, la fonction RestoreMediaSense est appelée pour restaurer la capacité de détection du média.

Le paramètre de Registre suivant est lié aux fonctions DisableMediaSense et RestoreMediaSense :

Système\Currentcontrolset\Services\Tcpip\Paramètres\DisableDHCPMediaSense

Il existe un indicateur interne dans Windows qui est défini si cette clé de Registre existe lors du premier démarrage de l’ordinateur. Le même indicateur interne est également défini et réinitialisé en appelant DisableMediaSense et RestoreMediaSense. Toutefois, avec le paramètre de Registre, vous devez redémarrer l’ordinateur pour que les modifications soient effectuées.

La pile TCP/IP sur Windows Vista et versions ultérieures a été modifiée pour ne pas masquer les interfaces déconnectées lorsqu’un événement de déconnexion se produit. Ainsi, sur Windows Vista et versions ultérieures, les fonctions DisableMediaSense et RestoreMediaSense ne font rien et retournent toujours NO_ERROR.

Exemples

L’exemple suivant montre comment appeler les fonctions DisableMediaSense et RestoreMediaSense de manière asynchrone. Cet exemple n’est utile que sur Windows Server 2003 et Windows XP, où les fonctions DisableMediaSense et RestoreMediaSense font quelque chose d’utile.

L’exemple appelle d’abord la fonction DisableMediaSense , se met en veille pendant 60 secondes pour permettre à l’utilisateur de déconnecter un câble réseau, récupère la table d’adresses IP et imprime certains membres des entrées d’adresse IP dans la table, appelle la fonction RestoreMediaSense , récupère à nouveau la table d’adresses IP et imprime certains membres des entrées d’adresse IP dans la table. L’impact de la désactivation de la fonctionnalité de détection multimédia est visible dans la différence dans les entrées de la table d’adresses IP.

Pour obtenir un exemple montrant comment appeler les fonctions DisableMediaSense et RestoreMediaSense de façon synchrone, consultez la référence des fonctions 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);
}

Spécifications

   
Client minimal pris en charge Windows XP [applications de bureau uniquement]
Serveur minimal pris en charge Windows Server 2003 [applications de bureau uniquement]
Plateforme cible Windows
En-tête iphlpapi.h
Bibliothèque Iphlpapi.lib
DLL Iphlpapi.dll

Voir aussi

CloseHandle

CreateEvent

EnableRouter

Informations de référence sur les fonctions d’assistance IP

Page de démarrage de l’assistance IP

OVERLAPPED

RestoreMediaSense

UnnableRouter