Partager via


Fonction RestoreMediaSense (iphlpapi.h)

La fonction RestoreMediaSense restaure la fonctionnalité de détection multimédia de la pile TCP/IP sur un ordinateur local sur lequel la fonction DisableMediaSense a été appelée précédemment.

Syntaxe

IPHLPAPI_DLL_LINKAGE DWORD RestoreMediaSense(
             OVERLAPPED *pOverlapped,
  [optional] LPDWORD    lpdwEnableCount
);

Paramètres

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 doit contenir un handle pour un objet d’événement valide. Utilisez la fonction CreateEvent pour créer cet objet d’événement.

[optional] lpdwEnableCount

Pointeur facultatif vers une variable DWORD qui reçoit le nombre de références restantes si la fonction RestoreMediaSense réussit. La variable est également utilisée par les fonctions EnableRouter et UnenableRouter .

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. Cette erreur est également retournée si la fonction DisableMediaSense n’a pas été appelée avant l’appel de la fonction RestoreMediaSense .
ERROR_IO_PENDING
L’opération est en cours. Cette valeur peut être retournée par un appel asynchrone réussi à RestoreMediaSense.
ERROR_OPEN_FAILED
Un handle interne du pilote 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 pour l’erreur retournée.

Remarques

Si le paramètre pOverlapped a la valeur NULL, la fonction RestoreMediaSense est exécutée de manière synchrone.

Si le paramètre pOverlapped n’a pas la valeur NULL, la fonction RestoreMediaSense est exécutée de manière 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 multimédia. D’ici là, un paquet de demandes d’E/S (IRP) reste mis en file d’attente. Par ailleurs, lorsque le processus appelé DisableMediaSense se termine, l’IRP est annulé et une routine d’annulation est appelée pour restaurer à nouveau la fonctionnalité de détection multimédia.

Pour appeler RestoreMediaSense de manière synchrone, une application doit passer un pointeur NULL dans le paramètre pOverlapped . Lorsque RestoreMediaSense est appelé de manière synchrone, la fonction retourne lorsque le paquet de demande d’E/S (IRP) pour restaurer le sens multimédia est terminé.

Pour appeler RestoreMediaSense 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 a besoin d’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, RestoreMediaSense peut retourner ERROR_IO_PENDING. L’IRP se termine lorsque la fonctionnalité de détection multimédia a été restaurée. Utilisez la fonction CloseHandle pour fermer le handle à l’objet d’événement lorsqu’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é.

Si DisableMediaSense n’a pas été appelé avant l’appel de RestoreMediaSense, RestoreMediaSense retourne ERROR_INVALID_PARAMETER.

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 ne s’affichent 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é media sense dans ces cas. Ultérieurement, la fonction RestoreMediaSense sera appelée pour restaurer la fonctionnalité de détection multimé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 lorsque la machine démarre pour la première fois. 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 se produisent.

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 synchrone. 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 crée d’abord un thread distinct qui appelle la fonction DisableMediaSense de manière synchrone, le thread main 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 de manière synchrone, 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 peut être vu dans la différence dans les entrées de table d’adresses IP.

Pour obtenir un exemple qui montre comment appeler les fonctions DisableMediaSense et RestoreMediaSense de manière asynchrone, consultez la référence des fonctions 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);
}


Configuration requise

   
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

DisableMediaSense

EnableRouter

Informations de référence sur la fonction d’assistance IP

Page d’accueil de l’assistance IP

OVERLAPPED

UnnableRouter