Función DisableMediaSense (iphlpapi.h)

La función DisableMediaSense deshabilita la funcionalidad de detección de medios de la pila TCP/IP en un equipo local.

Sintaxis

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

Parámetros

pHandle

Puntero a una variable que se usa para almacenar un identificador. Si el parámetro pOverlapped no es NULL, esta variable se usará internamente para almacenar un identificador necesario para llamar al controlador IP y deshabilitar la funcionalidad de detección de medios.

Una aplicación no debe usar el valor al que apunta esta variable. Este identificador es para uso interno y no debe cerrarse.

pOverLapped

Puntero a una estructura OVERLAPPED. Excepto para el miembro hEvent , todos los miembros de esta estructura deben establecerse en cero. El miembro hEvent requiere un identificador para un objeto de evento válido. Use la función CreateEvent para crear este objeto de evento.

Valor devuelto

Si la función se ejecuta correctamente, el valor devuelto es NO_ERROR.

Si se produce un error en la función, el valor devuelto es uno de los siguientes códigos de error.

Código devuelto Descripción
ERROR_INVALID_PARAMETER
Se pasó un parámetro no válido a la función. Este error se devuelve si un parámetro pOverlapped es un puntero incorrecto.
ERROR_IO_PENDING
La operación está en curso. Este valor lo devuelve una llamada asincrónica correcta a DisableMediaSense.
ERROR_OPEN_FAILED
El identificador al que apunta el parámetro pHandle no era válido.
ERROR_NOT_SUPPORTED
No se admite la solicitud.
Otros
Use FormatMessage para obtener la cadena de mensaje para el error devuelto.

Comentarios

Si los parámetros pHandle o pOverlapped son NULL, la función DisableMediaSense se ejecuta de forma sincrónica.

Si los parámetros pHandle y pOverlapped no son NULL, la función DisableMediaSense se ejecuta de forma asincrónica mediante la estructura SUPERPUESTA a la que apunta el parámetro pOverlapped .

La función DisableMediaSense no se completa hasta que se llama a la función RestoreMediaSense más adelante para restaurar la funcionalidad de detección de medios. Hasta entonces, un paquete de solicitud de E/S (IRP) permanece en cola. Como alternativa, cuando se cierra el proceso llamado DisableMediaSense , se cancela el IRP y se llama a una rutina de cancelación que restauraría de nuevo la funcionalidad de detección de medios.

Para llamar a DisableMediaSense de forma sincrónica, una aplicación debe crear un subproceso independiente para esta llamada. De lo contrario, seguirá esperando la finalización de IRP y la función se bloqueará.

Para llamar a DisableMediaSense de forma asincrónica, una aplicación debe asignar una estructura SUPERPUESTA . Excepto para el miembro hEvent , todos los miembros de esta estructura deben establecerse en cero. El miembro hEvent requiere un identificador para un objeto de evento válido. Use la función CreateEvent para crear este evento. Cuando se llama de forma asincrónica, DisableMediaSense siempre devuelve ERROR_IO_PENDING. El IRP solo se completará cuando se llame a RestoreMediaSense más adelante. Use la función CloseHandle para cerrar el identificador del objeto de evento cuando ya no sea necesario. El sistema cierra el identificador automáticamente cuando finaliza el proceso. El objeto de evento se destruye cuando se ha cerrado su último identificador.

En Windows Server 2003 y Windows XP, la pila TCP/IP implementa una directiva de eliminación de todas las direcciones IP en una interfaz en respuesta a un evento de desconexión de sentido multimedia de una interfaz de red subyacente. Si un conmutador de red o un concentrador al que está conectado el equipo local está apagado o se desconecta un cable de red, la interfaz de red entregará eventos de desconexión. Se pierde la información de configuración de IP asociada a la interfaz de red. Como resultado, la pila TCP/IP implementa una directiva de ocultar interfaces desconectadas para que estas interfaces y sus direcciones IP asociadas no aparezcan en la información de configuración recuperada a través del asistente de IP. Esta directiva impide que algunas aplicaciones detecten fácilmente que una interfaz de red se desconecta simplemente, en lugar de quitarse del sistema.

Este comportamiento no suele afectar a un equipo cliente local si usa solicitudes DHCP a un servidor DHCP para obtener información de configuración de IP. Pero esto puede tener un impacto grave en los equipos servidor, especialmente en los equipos que se usan como parte de los clústeres. La función DisableMediaSense se puede usar para deshabilitar temporalmente la funcionalidad de detección de medios para estos casos. Más adelante, se llamaría a la función RestoreMediaSense para restaurar la funcionalidad de detección de medios.

La siguiente configuración del Registro está relacionada con las funciones DisableMediaSense y RestoreMediaSense :

Sistema\Currentcontrolset\Servicios\Tcpip\Parámetros\DisableDHCPMediaSense

Hay una marca interna en Windows que se establece si esta clave del Registro existe cuando la máquina arranca por primera vez. La misma marca interna también se establece y restablece llamando a DisableMediaSense y RestoreMediaSense. Sin embargo, con la configuración del Registro, debe reiniciar la máquina para que se produzcan los cambios.

La pila TCP/IP en Windows Vista y versiones posteriores se cambió para no ocultar interfaces desconectadas cuando se produce un evento de desconexión. Por lo tanto, en Windows Vista y versiones posteriores, las funciones DisableMediaSense y RestoreMediaSense no hacen nada y siempre devuelven NO_ERROR.

Ejemplos

En el ejemplo siguiente se muestra cómo llamar a las funciones DisableMediaSense y RestoreMediaSense de forma asincrónica. Este ejemplo solo es útil en Windows Server 2003 y Windows XP, donde las funciones DisableMediaSense y RestoreMediaSense hacen algo útil.

En primer lugar, el ejemplo llama a la función DisableMediaSense , se suspende durante 60 segundos para permitir que el usuario desconecte un cable de red, recupere la tabla de direcciones IP e imprima algunos miembros de las entradas de dirección IP de la tabla, llama a la función RestoreMediaSense , recupera de nuevo la tabla de direcciones IP e imprime algunos miembros de las entradas de dirección IP de la tabla. El impacto de deshabilitar la funcionalidad de detección de medios puede verse en la diferencia en las entradas de la tabla de direcciones IP.

Para ver un ejemplo que muestra cómo llamar a las funciones DisableMediaSense y RestoreMediaSense de forma sincrónica, consulte la referencia de la función 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);
}

Requisitos

   
Cliente mínimo compatible Windows XP [solo aplicaciones de escritorio]
Servidor mínimo compatible Windows Server 2003 [solo aplicaciones de escritorio]
Plataforma de destino Windows
Encabezado iphlpapi.h
Library Iphlpapi.lib
Archivo DLL Iphlpapi.dll

Consulte también

CloseHandle

CreateEvent

EnableRouter

Referencia de la función auxiliar de IP

Página de inicio del asistente de IP

OVERLAPPED

RestoreMediaSense

UnableRouter