Поделиться через


Функция RestoreMediaSense (iphlpapi.h)

Функция RestoreMediaSense восстанавливает возможность зондирования мультимедиа стека TCP/IP на локальном компьютере, на котором ранее была вызвана функция DisableMediaSense .

Синтаксис

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

Параметры

pOverlapped

Указатель на структуру OVERLAPPED . За исключением элемента hEvent , все члены этой структуры должны иметь нулевое значение. Элемент hEvent должен содержать дескриптор допустимого объекта события. Используйте функцию CreateEvent для создания этого объекта события.

[optional] lpdwEnableCount

Необязательный указатель на переменную DWORD, которая получает количество оставшихся ссылок при успешном выполнении функции RestoreMediaSense . Переменная также используется функциями EnableRouter и UnenableRouter .

Возвращаемое значение

Если функция выполнена успешно, возвращаемое значение будет NO_ERROR.

Если функция завершается сбоем, возвращается один из следующих кодов ошибок.

Код возврата Описание
ERROR_INVALID_PARAMETER
В функцию передан недопустимый параметр. Эта ошибка возвращается, если параметр pOverlapped является недопустимым указателем. Эта ошибка также возвращается, если функция DisableMediaSense не была вызвана до вызова функции RestoreMediaSense .
ERROR_IO_PENDING
Операция выполняется. Это значение может быть возвращено при успешном асинхронном вызове RestoreMediaSense.
ERROR_OPEN_FAILED
Внутренний дескриптор драйвера был недопустим.
ERROR_NOT_SUPPORTED
Запрос не поддерживается.
Другое
Используйте FormatMessage , чтобы получить строку сообщения для возвращаемой ошибки.

Комментарии

Если параметр pOverlapped имеет значение NULL, функция RestoreMediaSense выполняется синхронно.

Если параметр pOverlapped не равен NULL, функция RestoreMediaSense выполняется асинхронно с использованием структуры OVERLAPPED , на которую указывает параметр pOverlapped .

Функция DisableMediaSense не будет завершена до тех пор, пока позже не будет вызвана функция RestoreMediaSense для восстановления возможности датчиков мультимедиа. До тех пор пакет запроса ввода-вывода (IRP) остается в очереди. Кроме того, когда завершается процесс с именем DisableMediaSense , IRP отменяется и вызывается подпрограмма отмены, которая снова восстановит возможность зондирования мультимедиа.

Для синхронного вызова RestoreMediaSense приложение должно передать указатель NULL в параметре pOverlapped . При синхронном вызове RestoreMediaSense функция возвращается после завершения выполнения пакета запроса ввода-вывода (IRP) для восстановления чувства мультимедиа.

Чтобы асинхронно вызвать RestoreMediaSense , приложению необходимо выделить структуру OVERLAPPED . За исключением элемента hEvent , все члены этой структуры должны иметь нулевое значение. Члену hEvent требуется дескриптор допустимого объекта события. Используйте функцию CreateEvent для создания этого события. При асинхронном вызове RestoreMediaSense может возвращать ERROR_IO_PENDING. IRP завершается после восстановления возможности зондирования носителя. Используйте функцию CloseHandle , чтобы закрыть дескриптор для объекта события, когда он больше не нужен. Система автоматически закрывает дескриптор при завершении процесса. Объект события уничтожается при закрытии последнего дескриптора.

Если метод DisableMediaSense не вызывался до вызова RestoreMediaSense, функция RestoreMediaSense возвращает ERROR_INVALID_PARAMETER.

В Windows Server 2003 и Windows XP стек TCP/IP реализует политику удаления всех IP-адресов в интерфейсе в ответ на событие отключения с точки зрения мультимедиа от базового сетевого интерфейса. Если сетевой коммутатор или концентратор, к которому подключен локальный компьютер, отключен или сетевой кабель отключен, сетевой интерфейс будет доставлять события отключения. Сведения об IP-конфигурации, связанные с сетевым интерфейсом, теряются. В результате стек TCP/IP реализует политику скрытия отключенных интерфейсов, чтобы эти интерфейсы и связанные с ними IP-адреса не отображались в сведениях о конфигурации, полученных через вспомогателя IP-адресов. Эта политика не позволяет некоторым приложениям легко обнаружить, что сетевой интерфейс просто отключен, а не удален из системы.

Обычно это не влияет на локальный клиентский компьютер, если он использует DHCP-запросы к DHCP-серверу для получения сведений об IP-конфигурации. Но это может серьезно повлиять на серверные компьютеры, особенно компьютеры, используемые в составе кластеров. Функцию DisableMediaSense можно использовать для временного отключения функции контроля мультимедиа для этих случаев. Через некоторое время будет вызвана функция RestoreMediaSense для восстановления возможности зондирования мультимедиа.

Следующий параметр реестра связан с функциями DisableMediaSense и RestoreMediaSense :

Системы\CurrentControlSet\Услуги\Tcpip\Параметры\DisableDHCPMediaSense

В Windows есть внутренний флаг, который устанавливается, если этот раздел реестра существует при первой загрузке компьютера. Тот же внутренний флаг также устанавливается и сбрасывается путем вызовов DisableMediaSense и RestoreMediaSense. Однако с параметром реестра необходимо перезагрузить компьютер, чтобы изменения произошли.

Стек TCP/IP в Windows Vista и более поздних версий был изменен, чтобы не скрывать отключенные интерфейсы при возникновении события отключения. Поэтому в Windows Vista и более поздних версиях функции DisableMediaSense и RestoreMediaSense не выполняют никаких действий и всегда возвращают NO_ERROR.

Примеры

В следующем примере показано, как синхронно вызывать функции DisableMediaSense и RestoreMediaSense . Этот пример полезен только в Windows Server 2003 и Windows XP, где функции DisableMediaSense и RestoreMediaSense выполняют некоторые полезные действия.

В примере сначала создается отдельный поток, который синхронно вызывает функцию DisableMediaSense, поток main переходит в спящий режим в течение 60 секунд, чтобы позволить пользователю отключить сетевой кабель, извлекает таблицу IP-адресов и выводит некоторые элементы записей IP-адресов в таблице, синхронно вызывает функцию RestoreMediaSense, возвращает таблицу IP-адресов снова. и выводит некоторые элементы записей IP-адресов в таблице. Влияние отключения возможности обнаружения мультимедиа можно увидеть в различиях в записях таблицы IP-адресов.

Пример асинхронного вызова функций DisableMediaSense и RestoreMediaSense см. в справочнике по функции 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);
}


Требования

   
Минимальная версия клиента Windows XP [только классические приложения]
Минимальная версия сервера Windows Server 2003 [только классические приложения]
Целевая платформа Windows
Header iphlpapi.h
Библиотека Iphlpapi.lib
DLL Iphlpapi.dll

См. также раздел

CloseHandle

CreateEvent

DisableMediaSense

EnableRouter

Справочник по вспомогательной функции IP

Начальная страница вспомогательного ip-адреса

ПЕРЕКРЫВАЮЩИХСЯ

UnenableRouter