Share via


Função RestoreMediaSense (iphlpapi.h)

A função RestoreMediaSense restaura a capacidade de detecção de mídia da pilha TCP/IP em um computador local no qual a função DisableMediaSense foi chamada anteriormente.

Sintaxe

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

Parâmetros

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 deve conter um identificador para um objeto de evento válido. Use a função CreateEvent para criar esse objeto de evento.

[optional] lpdwEnableCount

Um ponteiro opcional para uma variável DWORD que recebe o número de referências restantes se a função RestoreMediaSense for bem-sucedida. A variável também é usada pelas funções EnableRouter e UnenableRouter .

Retornar valor

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

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

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. Esse erro também será retornado se a função DisableMediaSense não tiver sido chamada antes de chamar a função RestoreMediaSense .
ERROR_IO_PENDING
A operação está em andamento. Esse valor pode ser retornado por uma chamada assíncrona bem-sucedida para RestoreMediaSense.
ERROR_OPEN_FAILED
Um identificador interno para o driver 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 o parâmetro pOverlapped for NULL, a função RestoreMediaSense será executada de forma síncrona.

Se o parâmetro pOverlapped não for NULL, a função RestoreMediaSense 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 capacidade 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 capacidade de detecção de mídia.

Para chamar RestoreMediaSense de forma síncrona, um aplicativo precisa passar um ponteiro NULL no parâmetro pOverlapped . Quando RestoreMediaSense é chamado de forma síncrona, a função retorna quando o IRP (pacote de solicitação de E/S) para restaurar o sentido de mídia é concluído.

Para chamar RestoreMediaSense 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, RestoreMediaSense pode retornar ERROR_IO_PENDING. O IRP é concluído quando a capacidade de detecção de mídia é restaurada. 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 foi fechado.

Se DisableMediaSense não tiver sido chamado antes de chamar RestoreMediaSense, RestoreMediaSense retornará ERROR_INVALID_PARAMETER.

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 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 ocultar 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á apenas 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 os computadores usados como parte dos clusters. A função DisableMediaSense pode ser usada para desabilitar temporariamente a capacidade de sensor 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. Assim, 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 sí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 cria um thread separado que chama a função DisableMediaSense de forma síncrona, o thread main 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 de forma síncrona, 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 assíncrona, consulte a referência da função 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);
}


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

DisableMediaSense

EnableRouter

Referência de função auxiliar de IP

Página Inicial do Auxiliar de IP

OVERLAPPED

UnenableRouter