Share via


Função DisableMediaSense (iphlpapi.h)

A função DisableMediaSense desabilita o recurso de detecção de mídia da pilha TCP/IP em um computador local.

Sintaxe

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

Parâmetros

pHandle

Um ponteiro para uma variável que é usada para armazenar um identificador. Se o parâmetro pOverlapped não for NULL, essa variável será usada internamente para armazenar um identificador necessário para chamar o driver IP e desabilitar a funcionalidade de detecção de mídia.

Um aplicativo não deve usar o valor apontado por essa variável. Esse identificador é para uso interno e não deve ser fechado.

pOverLapped

Um ponteiro para uma estrutura OVERLAPPED. Exceto para o membro hEvent , todos os membros dessa estrutura devem ser definidos como zero. O membro hEvent requer um identificador para um objeto de evento válido. Use a função CreateEvent para criar esse objeto de evento.

Valor retornado

Se a função for bem-sucedida, o valor retornado será NO_ERROR.

Se a função falhar, o valor retornado será um dos códigos de erro a seguir.

Código de retorno Descrição
ERROR_INVALID_PARAMETER
Um parâmetro inválido foi passado para a função. Esse erro será retornado se um parâmetro pOverlapped for um ponteiro inválido.
ERROR_IO_PENDING
A operação está em andamento. Esse valor é retornado por uma chamada assíncrona bem-sucedida para DisableMediaSense.
ERROR_OPEN_FAILED
O identificador apontado pelo parâmetro pHandle era inválido.
ERROR_NOT_SUPPORTED
A solicitação não terá suporte.
Outros
Use FormatMessage para obter a cadeia de caracteres de mensagem para o erro retornado.

Comentários

Se os parâmetros pHandle ou pOverlapped forem NULL, a função DisableMediaSense será executada de forma síncrona.

Se os parâmetros pHandle e pOverlapped não forem NULL, a função DisableMediaSense será executada de forma assíncrona usando a estrutura OVERLAPPED apontada pelo parâmetro pOverlapped .

A função DisableMediaSense não é concluída até que a função RestoreMediaSense seja chamada posteriormente para restaurar a funcionalidade de detecção de mídia. Até lá, um IRP (pacote de solicitação de E/S) permanece na fila. Como alternativa, quando o processo chamado DisableMediaSense é encerrado, o IRP é cancelado e uma rotina de cancelamento é chamada que restauraria novamente a funcionalidade de sensoriamento de mídia.

Para chamar DisableMediaSense de forma síncrona, um aplicativo precisa criar um thread separado para essa chamada. Caso contrário, ele continuará aguardando a conclusão do IRP e a função será bloqueada.

Para chamar DisableMediaSense de forma assíncrona, um aplicativo precisa alocar uma estrutura OVERLAPPED . Exceto para o membro hEvent , todos os membros dessa estrutura devem ser definidos como zero. O membro hEvent requer um identificador para um objeto de evento válido. Use a função CreateEvent para criar esse evento. Quando chamado de forma assíncrona, DisableMediaSense sempre retorna ERROR_IO_PENDING. O IRP será concluído somente quando RestoreMediaSense for chamado posteriormente. Use a função CloseHandle para fechar o identificador do objeto de evento quando ele não for mais necessário. O sistema fecha o identificador automaticamente quando o processo é encerrado. O objeto de evento é destruído quando seu último identificador é fechado.

No Windows Server 2003 e no Windows XP, a pilha TCP/IP implementa uma política de exclusão de todos os endereços IP em uma interface em resposta a um evento de desconexão de sensor de mídia de um adaptador de rede subjacente. Se um comutador de rede ou hub ao qual o computador local está conectado estiver desligado ou se um cabo de rede estiver desconectado, o adaptador de rede fornecerá eventos de desconexão. As informações de configuração de IP associadas ao adaptador de rede são perdidas. Como resultado, a pilha TCP/IP implementa uma política de ocultação de interfaces desconectadas para que essas interfaces e seus endereços IP associados não apareçam nas informações de configuração recuperadas por meio do auxiliar de IP. Essa política impede que alguns aplicativos detectem facilmente que um adaptador de rede está meramente desconectado, em vez de removido do sistema.

Esse comportamento normalmente não afetará um computador cliente local se ele estiver usando solicitações DHCP para um servidor DHCP para obter informações de configuração de IP. Mas isso pode ter um impacto sério nos computadores servidores, especialmente nos computadores usados como parte dos clusters. A função DisableMediaSense pode ser usada para desabilitar temporariamente a funcionalidade de detecção de mídia para esses casos. Posteriormente, a função RestoreMediaSense seria chamada para restaurar a capacidade de detecção de mídia.

A seguinte configuração do Registro está relacionada às funções DisableMediaSense e RestoreMediaSense :

Sistema\Currentcontrolset\Serviços\Tcpip\Parâmetros\DisableDHCPMediaSense

Há um sinalizador interno no Windows que será definido se essa chave do Registro existir quando o computador for inicializado pela primeira vez. O mesmo sinalizador interno também é definido e redefinido chamando DisableMediaSense e RestoreMediaSense. No entanto, com a configuração do Registro, você precisa reinicializar o computador para que as alterações ocorram.

A pilha TCP/IP no Windows Vista e posterior foi alterada para não ocultar interfaces desconectadas quando ocorre um evento de desconexão. Portanto, no Windows Vista e posteriores, as funções DisableMediaSense e RestoreMediaSense não fazem nada e sempre retornam NO_ERROR.

Exemplos

O exemplo a seguir mostra como chamar as funções DisableMediaSense e RestoreMediaSense de forma assíncrona. Este exemplo só é útil no Windows Server 2003 e no Windows XP, em que as funções DisableMediaSense e RestoreMediaSense fazem algo útil.

O exemplo primeiro chama a função DisableMediaSense , dorme por 60 segundos para permitir que o usuário desconecte um cabo de rede, recupera a tabela de endereços IP e imprime alguns membros das entradas de endereço IP na tabela, chama a função RestoreMediaSense , recupera a tabela de endereços IP novamente e imprime alguns membros das entradas de endereço IP na tabela. O impacto da desabilitação da capacidade de detecção de mídia pode ser visto na diferença nas entradas da tabela de endereços IP.

Para obter um exemplo que mostra como chamar as funções DisableMediaSense e RestoreMediaSense de forma síncrona, consulte a referência de função 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 com suporte Windows XP [somente aplicativos da área de trabalho]
Servidor mínimo com suporte Windows Server 2003 [somente aplicativos da área de trabalho]
Plataforma de Destino Windows
Cabeçalho iphlpapi.h
Biblioteca Iphlpapi.lib
DLL Iphlpapi.dll

Confira também

CloseHandle

CreateEvent

EnableRouter

Referência de função auxiliar de IP

Página Inicial do Auxiliar de IP

OVERLAPPED

RestoreMediaSense

UnenableRouter