Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 15.09.2015, 00:49   #1
calypso
Форумчанин
 
Регистрация: 02.12.2012
Сообщений: 250
По умолчанию Не работает конвертация в WSAAddressToStringW

Пытаюсь получить информацию о сетевом адаптере с помощью GetAdaptersAddresses и вывести её в виде String на форму. Загвоздка с типами:
PIP_ADAPTER_UNICAST_ADDRESS FirstUnicastAddress;
PIP_ADAPTER_ANYCAST_ADDRESS FirstAnycastAddress;
PIP_ADAPTER_MULTICAST_ADDRESS FirstMulticastAddress;
PIP_ADAPTER_DNS_SERVER_ADDRESS FirstDnsServerAddress;
PIP_ADAPTER_WINS_SERVER_ADDRESS_LH FirstWinsServerAddress;
PIP_ADAPTER_GATEWAY_ADDRESS_LH FirstGatewayAddress;
SOCKET_ADDRESS Dhcpv4Server;

В конечном итоге я так понял все вышеперечисленные кроме SOCKET_ADDRESS это также структуры, то есть получается нечто вроде матрешки. А в конечном итоге значения будут в виде SOCKET_ADDRESS.

Код:
		pCurrAddresses = pAddresses;
	  while (pCurrAddresses) {
	  ShowMessage("Сетевая карта: "+ String(pCurrAddresses->Description));   // работает

	  memset(buf, 0, length);
WSAAddressToStringW(pCurrAddresses->FirstUnicastAddress->Address.lpSockaddr,	pCurrAddresses->FirstUnicastAddress->Address.iSockaddrLength,
	   NULL, buf, &length);
   ShowMessage(&buf);
Много вариантов перепробовал, либо выводит пустую строку, либо просто ругается что нельзя преобразовать например wchar_t[16] в string и т.д.
calypso вне форума Ответить с цитированием
Старый 15.09.2015, 08:40   #2
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,330
По умолчанию

Что содержит length *до* вызова?
Что возвращает WSAAddressToStringW? Какой код ошибки WSAGetLastError()?
waleri на форуме Ответить с цитированием
Старый 18.09.2015, 03:03   #3
calypso
Форумчанин
 
Регистрация: 02.12.2012
Сообщений: 250
По умолчанию

С WSAAddressToStringW разобрался, чтобы она нормально работала нужно перед вызовом сделать инициализацию:
Код:
WORD wVersionRequested;
WSADATA wsaData;
 wVersionRequested = MAKEWORD(2, 2);
 WSAStartup(wVersionRequested, &wsaData);
Теперь другая проблема - GetAdapterAddresses не выдает адрес шлюза, а IP адрес выдает в версии IPv6. То есть мне нужны элементы:
pCurrAddresses->FirstUnicastAddress
pCurrAddresses->FirstGatewayAddress

FirstGatewayAddress всегда NULL
Не пойму что за фигня, с GetAdapterInfo всё работало у меня как положено
calypso вне форума Ответить с цитированием
Старый 18.09.2015, 08:56   #4
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,330
По умолчанию

Код будете показывать?
Что передаете первым параметром GetAdaptersAdresses?
Эта функция возвращает *список* - вы его просматриваете или смотрите только первый результат?
waleri на форуме Ответить с цитированием
Старый 18.09.2015, 13:38   #5
calypso
Форумчанин
 
Регистрация: 02.12.2012
Сообщений: 250
По умолчанию

Код:
    DWORD dwSize = 0;
    DWORD dwRetVal = 0;

    // Set the flags to pass to GetAdaptersAddresses
    ULONG flags = GAA_FLAG_INCLUDE_PREFIX;

    // default to unspecified address family (both)
    ULONG family = AF_UNSPEC;

    LPVOID lpMsgBuf = NULL;

    PIP_ADAPTER_ADDRESSES pAddresses = NULL;
    ULONG outBufLen = 0;
    ULONG Iterations = 0;

    PIP_ADAPTER_ADDRESSES pCurrAddresses = NULL;
	PIP_ADAPTER_UNICAST_ADDRESS pUnicast = NULL;
    PIP_ADAPTER_ANYCAST_ADDRESS pAnycast = NULL;
	PIP_ADAPTER_MULTICAST_ADDRESS pMulticast = NULL;
	IP_ADAPTER_DNS_SERVER_ADDRESS *pDnServer = NULL;
	IP_ADAPTER_PREFIX *pPrefix = NULL;
 outBufLen = WORKING_BUFFER_SIZE;
 DWORD length = 256;
  WCHAR buf[MAX_PATH];
  String myIPadress,myGATEWAY;
WORD wVersionRequested;
WSADATA wsaData;
 wVersionRequested = MAKEWORD(2, 2);
 WSAStartup(wVersionRequested, &wsaData);
	do
	{
 pAddresses = (IP_ADAPTER_ADDRESSES *) MALLOC(outBufLen);
	  if (pAddresses == NULL) ShowMessage("Ошибка выделения памяти");

   dwRetVal =GetAdaptersAddresses(family, flags, NULL, pAddresses, &outBufLen);

 if (dwRetVal == ERROR_BUFFER_OVERFLOW)
  {
			FREE(pAddresses);
			pAddresses = NULL;
		}
		else
		{	break;
		}

		Iterations++;

	}

	 while ((dwRetVal == ERROR_BUFFER_OVERFLOW) && (Iterations < MAX_TRIES));

	if (dwRetVal == NO_ERROR) {
		// If successful, output some information from the data we received
		pCurrAddresses = pAddresses;
//перебираем все сетевые адаптеры в системе
	  while (pCurrAddresses) {
//получаем IP адрес (то же самое, что Unicast Address)
//из формата SOCKET_ADDRESS конвертируем его в текст
	  memset(buf, 0, length);
 if (pCurrAddresses->FirstUnicastAddress != NULL)
{
 pUnicast= pCurrAddresses->FirstUnicastAddress;
 WSAAddressToStringW(pUnicast->Address.lpSockaddr,
	pUnicast->Address.iSockaddrLength,  NULL, buf, &length);
	myIPadress=String(PChar(buf));
   int oshibka=WSAGetLastError();
   if (oshibka!=0) ShowMessage("Ошибка при вызове WSA "+IntToStr(oshibka));
 else
 {
 ShowMessage("IP адрес сетевой карты: "+myIPadress);
 //имя сетевой карты
	  ShowMessage("Сетевая карта: "+ String(pCurrAddresses->Description));
// ShowMessage(String(pCurrAddresses->ReceiveLinkSpeed));
//   ShowMessage(String(pCurrAddresses->TransmitLinkSpeed));

//получаем адрес шлюза и определяем, к какому из роутеров данная сетевая карта подключена
// если адреса шлюзов совпадают с IP маршрутизаторов, выводим IP сетевой карты
memset(buf, 0, length);
//WSAAddressToStringA(pCurrAddresses->FirstGatewayAddress->Address.lpSockaddr,
//	pCurrAddresses->FirstGatewayAddress->Address.iSockaddrLength,
//			   NULL, buf, &length);
//получаем адрес DHCP
 if (pCurrAddresses->Dhcpv4Server.lpSockaddr != NULL)
{
WSAAddressToStringW(pCurrAddresses->Dhcpv4Server.lpSockaddr,
	pCurrAddresses->Dhcpv4Server.iSockaddrLength,
			   NULL, buf, &length);
   int oshibka=WSAGetLastError();
   if (oshibka!=0) ShowMessage("Ошибка при вызове WSA "+IntToStr(oshibka));
	myGATEWAY=String(PChar(buf));
	ShowMessage("DHCP сервер: "+myGATEWAY);
   // тем не менее, нужно получить АДРЕС ШЛЮЗА!!!
WSAAddressToStringW(pCurrAddresses->FirstGatewayAddress->Address.lpSockaddr,
	pCurrAddresses->FirstGatewayAddress->Address.iSockaddrLength,
			   NULL, buf, &length);
   oshibka=WSAGetLastError();
   if (oshibka!=0) ShowMessage("Ошибка при вызове WSA "+IntToStr(oshibka));
	myGATEWAY=String(PChar(buf));
	ShowMessage("Адрес шлюза: "+myGATEWAY);
}
//определяем, что в сети работает DHCP сервер
	  if (pCurrAddresses->Flags== IP_ADAPTER_DHCP_ENABLED)
	  {
		 ShowMessage("DHCP Server(s):"+ String(PChar(&pCurrAddresses->Dhcpv4Server)));

//		 pIPAddr = AdapterInfo->DhcpServer.Next;
//		 while ( pIPAddr ) {
//			ShowMessage(pIPAddr ->IpAddress.String );
//			pIPAddr = pIPAddr ->Next;
//		 }
	  }
	  else
	  {
	 //	 ShowMessage("DHCP Disabled");
	  }
	  }
 }
 pCurrAddresses = pCurrAddresses->Next;
	  }
	  }
calypso вне форума Ответить с цитированием
Старый 18.09.2015, 13:41   #6
calypso
Форумчанин
 
Регистрация: 02.12.2012
Сообщений: 250
По умолчанию

Я ставил брекпоинт на вызов GetAdaptersAddresses и смотрел, что она получает. Структура заполняется, всё нормально. Но не хватает части параметров.
Адрес шлюза, DNS сервер, WINS и ещё несколько параметров NULL.
Проверял на разных операционках: Vista SP2 Ultimate, Windows 2008 Server, Windows 7 x64, Windows 8.1 и Windows 2012 R2 Datacenter. Абсолютно всё одинаково работает
calypso вне форума Ответить с цитированием
Старый 18.09.2015, 14:58   #7
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,330
По умолчанию

Нужно GAA_FLAG_INCLUDE_GATEWAYS
Насчет anycast не уверен - это явно какие-то специальные адреса, возможно не у каждого адаптера они есть.
waleri на форуме Ответить с цитированием
Старый 18.09.2015, 20:09   #8
calypso
Форумчанин
 
Регистрация: 02.12.2012
Сообщений: 250
По умолчанию

Я кстати тоже обратил внимание на эти флаги. Значит мне нужны:

GAA_FLAG_SKIP_ANYCAST
0x0002
Do not return IPv6 anycast addresses.


GAA_FLAG_INCLUDE_GATEWAYS
0x0080
Return the addresses of default gateways.

В принципе я могу и GetAdapterInfo использовать т.к. эта новая функция особо ничего толкового не дает. Скорость сети она выдает 1 гбит\сек или 100 мбит\сек вместо реальной. Остальные параметры особо не нужны никому
calypso вне форума Ответить с цитированием
Старый 20.09.2015, 02:41   #9
calypso
Форумчанин
 
Регистрация: 02.12.2012
Сообщений: 250
По умолчанию

Проблему с IP адресом в формате IPv6 решилась следующим образом:
Код:
ULONG family = AF_INET;
Теперь IP выводит в формате IPv4 как положено 192.168.1.9 и т.д.
А со шлюзом ничего не выходит. Вот здесь такой же код как у меня:
http://www.2brightsparks.com/bb/viewtopic.php?t=3803

Может конечно они и не проверяли его на работоспособность...
calypso вне форума Ответить с цитированием
Старый 20.09.2015, 09:30   #10
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,330
По умолчанию

Код:
pCurrAddresses->Flags== IP_ADAPTER_DHCP_ENABLED
Не лучший способ проверки, надо &
waleri на форуме Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Конвертация lupus_luctisonus Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM 1 23.12.2014 07:18
Конвертация Чикаашан Общие вопросы по Java, Java SE, Kotlin 0 22.11.2014 20:03
конвертация Romuald Microsoft Office Excel 8 12.07.2010 14:23
Конвертация surf135 Помощь студентам 3 31.05.2010 23:41
Конвертация фунтов freeuser Общие вопросы C/C++ 2 28.01.2010 10:33