//----------------------------------------------------------------//
void USAdapterInfoList::EnumerateAdapters () {

	this->Clear ();

	DWORD result;

	DWORD totalInterfaces;
	result = GetNumberOfInterfaces ( &totalInterfaces );
	if ( result != NO_ERROR ) return;
	
	DWORD dwBufLen = ( totalInterfaces + 1 ) * sizeof ( IP_ADAPTER_ADDRESSES );
	PIP_ADAPTER_ADDRESSES pAdapterAddress = ( PIP_ADAPTER_ADDRESSES )malloc ( dwBufLen );

	result = GetAdaptersAddresses ( AF_UNSPEC, 0, NULL, pAdapterAddress, &dwBufLen );
	
	if ( result == ERROR_BUFFER_OVERFLOW ) {
		free ( pAdapterAddress );
		pAdapterAddress = ( PIP_ADAPTER_ADDRESSES )malloc ( dwBufLen );
		
		result = GetAdaptersAddresses ( AF_UNSPEC, 0, NULL, pAdapterAddress, &dwBufLen );
	}
	
	if ( result == NO_ERROR ) {
		
		PIP_ADAPTER_ADDRESSES cursor;
		u32 count;
		
		count = 0;
		cursor = pAdapterAddress;
		for ( ; cursor; cursor = cursor->Next ) {
			if ( cursor->PhysicalAddressLength ) {
				++count;
			}
		}
		
		if ( count ) {
		
			this->Init ( count );
			
			count = 0;
			cursor = pAdapterAddress;
			for ( ; cursor; cursor = cursor->Next ) {
				if ( cursor->PhysicalAddressLength ) {
				
					ZLAdapterInfo& adapterInfo = ( *this )[ count ];
				
					adapterInfo.SetNameFromMACAddress (
						cursor->PhysicalAddress,
						cursor->PhysicalAddressLength
					);
					++count;
				}
			}
		}
	}
	
	free ( pAdapterAddress );
}
Exemple #2
0
long NetCollector::CollectFallback(NVDataItem *DataItems) 
{
	USES_CONVERSION;

	DWORD Status;

	DWORD NumIfEntries;

	Status = GetNumberOfInterfaces( &NumIfEntries);
	if (Status != NO_ERROR)
		return ERROR_SUCCESS;

	PMIB_IFTABLE IfTable = NULL;
	PMIB_IPADDRTABLE IPAddrTable = NULL;

	unsigned long IfLen = 0;
	unsigned long IpLen = 0;

	Status = GetIfTable(IfTable, &IfLen, TRUE);
	if (Status != ERROR_INSUFFICIENT_BUFFER)
		return ERROR_SUCCESS;

	Status = GetIpAddrTable(IPAddrTable, &IpLen, FALSE);
	if (Status != ERROR_INSUFFICIENT_BUFFER)
		return ERROR_SUCCESS;
	
	IfTable = (PMIB_IFTABLE) new char[IfLen];
	memset(IfTable, 0 , IfLen);

	IPAddrTable = (PMIB_IPADDRTABLE) new char[IpLen];
	memset(IPAddrTable, 0 , IpLen);

	Status = GetIfTable(IfTable, &IfLen, TRUE);
	if (Status != NO_ERROR) {
		delete IfTable;
		delete IPAddrTable;
		return ERROR_SUCCESS;
	}

	Status = GetIpAddrTable(IPAddrTable, &IpLen, FALSE);
	if (Status != NO_ERROR) {
		delete IfTable;
		delete IPAddrTable;
		return ERROR_SUCCESS;
	}

	DWORD CurrIf;

	char TransString[64];
	char IPString[64];

	PMIB_IFROW CurrEntry = NULL;

	for (CurrIf = 0, CurrEntry = IfTable->table;
		 CurrIf < IfTable->dwNumEntries; 
		 CurrIf ++, CurrEntry ++) {

		auto_ptr<NVDataItem> SubItem (new NVDataItem(NCI_TAG));

		TransString[0] = '\0';

		if (Status != NO_ERROR) {
			delete IfTable;
			return ERROR_SUCCESS;
		}
#if 0
		if (CurrEntry.dwPhysAddrLen < 1)
			continue;
#endif
		char * IfTypeName;
		switch (CurrEntry->dwType) {
		case MIB_IF_TYPE_ETHERNET:
			IfTypeName = "Ethernet 802.3";
			break;

		case MIB_IF_TYPE_TOKENRING:
			IfTypeName = "Token Ring 802.5";
			break;

		case MIB_IF_TYPE_FDDI:
			IfTypeName = "Fiber Distributed Data Interface (FDDI)";
			break;

		case MIB_IF_TYPE_PPP:
			IfTypeName = "PPP";
			break;

		case MIB_IF_TYPE_SLIP:
			IfTypeName = "SLIP";
			break;

		default:
			IfTypeName = "Unknown";
//			continue;
		}

		SubItem->AddNVItem("InterfaceType", IfTypeName);
		
		//if (wcslen(IfTable->Adapter[CurrIf].Name) > 0) {
		//	SubItem->AddNVItem("SysName", W2A(IfTable->Adapter[CurrIf].Name));
		//}

		if (CurrEntry->wszName != NULL && wcslen(CurrEntry->wszName) > 0) {
			SubItem->AddNVItem("Description", CurrEntry->wszName);
		}
		else if (strlen((const char *) CurrEntry->bDescr) > 0) {
			SubItem->AddNVItem("Description", (const char *) CurrEntry->bDescr);
		}

		//_ASSERT (CurrIfTableEntry.dwPhysAddrLen == 6);

		if (CurrEntry->bPhysAddr[0] == 0
		    && CurrEntry->bPhysAddr[1] == 0
		    && CurrEntry->bPhysAddr[2] == 0
		    && CurrEntry->bPhysAddr[3] == 0
		    && CurrEntry->bPhysAddr[4] == 0
			&& CurrEntry->bPhysAddr[5] == 0) {

			continue;
		}

		sprintf (TransString,"%02X:%02X:%02X:%02X:%02X:%02X",
					CurrEntry->bPhysAddr[0],
					CurrEntry->bPhysAddr[1],
					CurrEntry->bPhysAddr[2],
					CurrEntry->bPhysAddr[3],
					CurrEntry->bPhysAddr[4],
					CurrEntry->bPhysAddr[5]);

		SubItem->AddNVItem("MACAddress", TransString);


		string IPAddrList;
		
		long CurrIPIndex;
		MIB_IPADDRROW * CurrIPAddrInfo;
		long FoundIP = 0;

		for (CurrIPIndex = 0, CurrIPAddrInfo = IPAddrTable->table; 
			 CurrIPIndex < IPAddrTable->dwNumEntries; 
			 CurrIPIndex ++, CurrIPAddrInfo ++) {

			if (IPAddrTable->table[CurrIPIndex].dwIndex == CurrEntry->dwIndex) {
				FoundIP ++;
				if (FoundIP > 1)
					IPAddrList.append(",");
				else {
					GetIPAddrString (CurrIPAddrInfo->dwMask, IPString);
					SubItem->AddNVItem("IPSubNet", IPString);
				}
					

				GetIPAddrString(CurrIPAddrInfo->dwAddr, IPString);
				IPAddrList.append(IPString);
			}
		}

		SubItem->AddNVItem("IPAddress", IPAddrList.c_str());

		DataItems->AddSubItem(SubItem.release());
	}

	delete IfTable;
	delete IPAddrTable;

	// WinSetupEnumerateDevClass((GUID) GUID_DEVCLASS_NET, NCI_TAG, DataItems, NULL);

	return ERROR_SUCCESS;
}
Exemple #3
0
/*
** Reads the tables for all net interfaces
**
*/
void CMeasureNet::UpdateIFTable()
{
	bool logging = false;

	if (c_GetIfTable2)
	{
		if (c_Table)
		{
			c_FreeMibTable(c_Table);
			c_Table = NULL;
		}

		if (c_GetIfTable2((MIB_IF_TABLE2**)&c_Table) == NO_ERROR)
		{
			MIB_IF_TABLE2* ifTable = (MIB_IF_TABLE2*)c_Table;

			if (c_NumOfTables != ifTable->NumEntries)
			{
				c_NumOfTables = ifTable->NumEntries;
				logging = true;
			}

			if (Rainmeter->GetDebug() && logging)
			{
				Log(LOG_DEBUG, L"------------------------------");
				LogWithArgs(LOG_DEBUG, L"* NETWORK-INTERFACE: Count=%i", c_NumOfTables);

				for (size_t i = 0; i < c_NumOfTables; ++i)
				{
					const WCHAR* type = L"Other";
					switch (ifTable->Table[i].Type)
					{
					case IF_TYPE_ETHERNET_CSMACD:
						type = L"Ethernet";
						break;
					case IF_TYPE_PPP:
						type = L"PPP";
						break;
					case IF_TYPE_SOFTWARE_LOOPBACK:
						type = L"Loopback";
						break;
					case IF_TYPE_IEEE80211:
						type = L"IEEE802.11";
						break;
					case IF_TYPE_TUNNEL:
						type = L"Tunnel";
						break;
					case IF_TYPE_IEEE1394:
						type = L"IEEE1394";
						break;
					}

					LogWithArgs(LOG_DEBUG, L"%i: %s", (int)i + 1, ifTable->Table[i].Description);
					LogWithArgs(LOG_DEBUG, L"  Alias: %s", ifTable->Table[i].Alias);
					LogWithArgs(LOG_DEBUG, L"  Type=%s(%i), Hardware=%s, Filter=%s",
						type, ifTable->Table[i].Type,
						(ifTable->Table[i].InterfaceAndOperStatusFlags.HardwareInterface == 1) ? L"Yes" : L"No",
						(ifTable->Table[i].InterfaceAndOperStatusFlags.FilterInterface == 1) ? L"Yes" : L"No");
				}
				Log(LOG_DEBUG, L"------------------------------");
			}
		}
		else
		{
			// Something's wrong. Unable to get the table.
			c_Table = NULL;
			c_NumOfTables = 0;
		}
	}
	else
	{
		if (c_Table == NULL)
		{
			// Gotta reserve few bytes for the tables
			DWORD value = 0;
			if (GetNumberOfInterfaces(&value) == NO_ERROR)
			{
				if (c_NumOfTables != value)
				{
					c_NumOfTables = value;
					logging = true;
				}

				if (c_NumOfTables > 0)
				{
					DWORD size = sizeof(MIB_IFTABLE) + sizeof(MIB_IFROW) * c_NumOfTables;
					c_Table = new BYTE[size];
				}
			}
		}

		if (c_Table)
		{
			DWORD ret, size = 0;

			MIB_IFTABLE* ifTable = (MIB_IFTABLE*)c_Table;

			if ((ret = GetIfTable(ifTable, &size, FALSE)) == ERROR_INSUFFICIENT_BUFFER)
			{
				delete [] c_Table;
				c_Table = new BYTE[size];

				ifTable = (MIB_IFTABLE*)c_Table;

				ret = GetIfTable(ifTable, &size, FALSE);
			}

			if (ret == NO_ERROR)
			{
				if (c_NumOfTables != ifTable->dwNumEntries)
				{
					c_NumOfTables = ifTable->dwNumEntries;
					logging = true;
				}

				if (Rainmeter->GetDebug() && logging)
				{
					Log(LOG_DEBUG, L"------------------------------");
					LogWithArgs(LOG_DEBUG, L"* NETWORK-INTERFACE: Count=%i", c_NumOfTables);

					for (size_t i = 0; i < c_NumOfTables; ++i)
					{
						const WCHAR* type = L"";
						switch (ifTable->table[i].dwType)
						{
						case IF_TYPE_ETHERNET_CSMACD:
							type = L"Ethernet";
							break;
						case IF_TYPE_PPP:
							type = L"PPP";
							break;
						case IF_TYPE_SOFTWARE_LOOPBACK:
							type = L"Loopback";
							break;
						case IF_TYPE_IEEE80211:
							type = L"IEEE802.11";
							break;
						case IF_TYPE_TUNNEL:
							type = L"Tunnel";
							break;
						case IF_TYPE_IEEE1394:
							type = L"IEEE1394";
							break;
						default:
							type = L"Other";
							break;
						}

						LogWithArgs(LOG_DEBUG, L"%i: %.*S", (int)i + 1, ifTable->table[i].dwDescrLen, (char*)ifTable->table[i].bDescr);
						LogWithArgs(LOG_DEBUG, L"  Type=%s(%i)", type, ifTable->table[i].dwType);
					}
					Log(LOG_DEBUG, L"------------------------------");
				}
			}
			else
			{
				// Something's wrong. Unable to get the table.
				delete [] c_Table;
				c_Table = NULL;
				c_NumOfTables = 0;
			}
		}
	}
}
Exemple #4
0
DWORD WINAPI WsControl(DWORD protocol,
                       DWORD action,
                       LPVOID pRequestInfo,
                       LPDWORD pcbRequestInfoLen,
                       LPVOID pResponseInfo,
                       LPDWORD pcbResponseInfoLen)
{

   /* Get the command structure into a pointer we can use,
      rather than void */
   TDIObjectID *pcommand = pRequestInfo;

   /* validate input parameters.  Error codes are from winerror.h, not from
    * winsock.h.  pcbResponseInfoLen is apparently allowed to be NULL for some
    * commands, since winipcfg.exe fails if we ensure it's non-NULL in every
    * case.
    */
   if (protocol != IPPROTO_TCP) return ERROR_INVALID_PARAMETER;
   if (!pcommand) return ERROR_INVALID_PARAMETER;
   if (!pcbRequestInfoLen) return ERROR_INVALID_ACCESS;
   if (*pcbRequestInfoLen < sizeof(TDIObjectID)) return ERROR_INVALID_ACCESS;
   if (!pResponseInfo) return ERROR_INVALID_PARAMETER;
   if (pcommand->toi_type != INFO_TYPE_PROVIDER) return ERROR_INVALID_PARAMETER;

   TRACE ("   WsControl TOI_ID=>0x%lx<, {TEI_ENTITY=0x%lx, TEI_INSTANCE=0x%lx}, TOI_CLASS=0x%lx, TOI_TYPE=0x%lx\n",
      pcommand->toi_id, pcommand->toi_entity.tei_entity,
      pcommand->toi_entity.tei_instance,
      pcommand->toi_class, pcommand->toi_type );

   switch (action)
   {
   case WSCNTL_TCPIP_QUERY_INFO:
   {
      if (pcommand->toi_class != INFO_CLASS_GENERIC &&
       pcommand->toi_class != INFO_CLASS_PROTOCOL)
      {
         ERR("Unexpected class %ld for WSCNTL_TCPIP_QUERY_INFO\n",
          pcommand->toi_class);
         return ERROR_BAD_ENVIRONMENT;
      }

      switch (pcommand->toi_id)
      {
         /* ENTITY_LIST_ID gets the list of "entity IDs", where an entity
            may represent an interface, or a datagram service, or address
            translation, or other fun things.  Typically an entity ID represents
            a class of service, which is further queried for what type it is.
            Different types will then have more specific queries defined.
         */
         case ENTITY_LIST_ID:
         {
            TDIEntityID *baseptr = pResponseInfo;
            DWORD numInt, i, ifTable, spaceNeeded;
            PMIB_IFTABLE table;

            if (!pcbResponseInfoLen)
               return ERROR_BAD_ENVIRONMENT;
            if (pcommand->toi_class != INFO_CLASS_GENERIC)
            {
               FIXME ("Unexpected Option for ENTITY_LIST_ID request -> toi_class=0x%lx\n",
                    pcommand->toi_class);
               return (ERROR_BAD_ENVIRONMENT);
            }

            GetNumberOfInterfaces(&numInt);
            spaceNeeded = sizeof(TDIEntityID) * (numInt * 2 + 3);

            if (*pcbResponseInfoLen < spaceNeeded)
               return (ERROR_LOCK_VIOLATION);

            ifTable = 0;
            GetIfTable(NULL, &ifTable, FALSE);
            table = HeapAlloc( GetProcessHeap(), 0, ifTable );
            if (!table)
               return ERROR_NOT_ENOUGH_MEMORY;
            GetIfTable(table, &ifTable, FALSE);

            spaceNeeded = sizeof(TDIEntityID) * (table->dwNumEntries + 4);
            if (*pcbResponseInfoLen < spaceNeeded)
            {
               HeapFree( GetProcessHeap(), 0, table );
               return ERROR_LOCK_VIOLATION;
            }

            memset(baseptr, 0, spaceNeeded);

            for (i = 0; i < table->dwNumEntries; i++)
            {
               /* Return IF_GENERIC and CL_NL_ENTITY on every interface, and
                * AT_ENTITY, CL_TL_ENTITY, and CO_TL_ENTITY on the first
                * interface.  MS returns them only on the loopback interface,
                * but it doesn't seem to matter.
                */
               if (i == 0)
               {
                  baseptr->tei_entity = CO_TL_ENTITY;
                  baseptr->tei_instance = table->table[i].dwIndex;
                  baseptr++;
                  baseptr->tei_entity = CL_TL_ENTITY;
                  baseptr->tei_instance = table->table[i].dwIndex;
                  baseptr++;
                  baseptr->tei_entity = AT_ENTITY;
                  baseptr->tei_instance = table->table[i].dwIndex;
                  baseptr++;
               }
               baseptr->tei_entity = CL_NL_ENTITY;
               baseptr->tei_instance = table->table[i].dwIndex;
               baseptr++;
               baseptr->tei_entity = IF_GENERIC;
               baseptr->tei_instance = table->table[i].dwIndex;
               baseptr++;
            }

            *pcbResponseInfoLen = spaceNeeded;
            HeapFree( GetProcessHeap(), 0, table );
            break;
         }

         /* Returns MIB-II statistics for an interface */
         case ENTITY_TYPE_ID:
            switch (pcommand->toi_entity.tei_entity)
            {
            case IF_GENERIC:
               if (pcommand->toi_class == INFO_CLASS_GENERIC)
               {
                  if (!pcbResponseInfoLen)
                     return ERROR_BAD_ENVIRONMENT;
                  *((ULONG *)pResponseInfo) = IF_MIB;
                  *pcbResponseInfoLen = sizeof(ULONG);
               }
               else if (pcommand->toi_class == INFO_CLASS_PROTOCOL)
               {
                  MIB_IFROW row;
                  DWORD index = pcommand->toi_entity.tei_instance, ret;
                  DWORD size = sizeof(row) - sizeof(row.wszName) -
                   sizeof(row.bDescr);

                  if (!pcbResponseInfoLen)
                     return ERROR_BAD_ENVIRONMENT;
                  if (*pcbResponseInfoLen < size)
                     return (ERROR_LOCK_VIOLATION);
                  row.dwIndex = index;
                  ret = GetIfEntry(&row);
                  if (ret != NO_ERROR)
                  {
                     /* FIXME: Win98's arp.exe insists on querying index 1 for
                      * its MIB-II stats, regardless of the tei_instances
                      * returned in the ENTITY_LIST query above.  If the query
                      * fails, arp.exe fails.  So, I do this hack return value
                      * if index is 1 and the query failed just to get arp.exe
                      * to continue.
                      */
                     if (index == 1)
                        return NO_ERROR;
                     ERR ("Error retrieving data for interface index %u\n",
                      index);
                     return ret;
                  }
                  size = sizeof(row) - sizeof(row.wszName) -
                   sizeof(row.bDescr) + row.dwDescrLen;
                  if (*pcbResponseInfoLen < size)
                     return (ERROR_LOCK_VIOLATION);
                  memcpy(pResponseInfo, &row.dwIndex, size);
                  *pcbResponseInfoLen = size;
               }
               break;

            /* Returns address-translation related data.  In our case, this is
             * ARP.
             */
            case AT_ENTITY:
               if (pcommand->toi_class == INFO_CLASS_GENERIC)
               {
                  if (!pcbResponseInfoLen)
                     return ERROR_BAD_ENVIRONMENT;
                  *((ULONG *)pResponseInfo) = AT_ARP;
                  *pcbResponseInfoLen = sizeof(ULONG);
               }
               else if (pcommand->toi_class == INFO_CLASS_PROTOCOL)
               {
                  PMIB_IPNETTABLE table;
                  DWORD size;
                  PULONG output = pResponseInfo;

                  if (!pcbResponseInfoLen)
                     return ERROR_BAD_ENVIRONMENT;
                  if (*pcbResponseInfoLen < sizeof(ULONG) * 2)
                     return (ERROR_LOCK_VIOLATION);
                  GetIpNetTable(NULL, &size, FALSE);
                  table = HeapAlloc( GetProcessHeap(), 0, size );
                  if (!table)
                     return ERROR_NOT_ENOUGH_MEMORY;
                  GetIpNetTable(table, &size, FALSE);
                  /* FIXME: I don't understand the meaning of the ARP output
                   * very well, but it seems to indicate how many ARP entries
                   * exist.  I don't know whether this should reflect the
                   * number per interface, as I'm only testing with a single
                   * interface.  So, I lie and say all ARP entries exist on
                   * a single interface--the first one that appears in the
                   * ARP table.
                   */
                  *(output++) = table->dwNumEntries;
                  *output = table->table[0].dwIndex;
                  HeapFree( GetProcessHeap(), 0, table );
                  *pcbResponseInfoLen = sizeof(ULONG) * 2;
               }
               break;

            /* Returns connectionless network layer statistics--in our case,
             * this is IP.
             */
            case CL_NL_ENTITY:
               if (pcommand->toi_class == INFO_CLASS_GENERIC)
               {
                  if (!pcbResponseInfoLen)
                     return ERROR_BAD_ENVIRONMENT;
                  *((ULONG *)pResponseInfo) = CL_NL_IP;
                  *pcbResponseInfoLen = sizeof(ULONG);
               }
               else if (pcommand->toi_class == INFO_CLASS_PROTOCOL)
               {
                  if (!pcbResponseInfoLen)
                     return ERROR_BAD_ENVIRONMENT;
                  if (*pcbResponseInfoLen < sizeof(MIB_IPSTATS))
                     return ERROR_LOCK_VIOLATION;
                  GetIpStatistics(pResponseInfo);

                  *pcbResponseInfoLen = sizeof(MIB_IPSTATS);
               }
               break;

            /* Returns connectionless transport layer statistics--in our case,
             * this is UDP.
             */
            case CL_TL_ENTITY:
               if (pcommand->toi_class == INFO_CLASS_GENERIC)
               {
                  if (!pcbResponseInfoLen)
                     return ERROR_BAD_ENVIRONMENT;
                  *((ULONG *)pResponseInfo) = CL_TL_UDP;
                  *pcbResponseInfoLen = sizeof(ULONG);
               }
               else if (pcommand->toi_class == INFO_CLASS_PROTOCOL)
               {
                  if (!pcbResponseInfoLen)
                     return ERROR_BAD_ENVIRONMENT;
                  if (*pcbResponseInfoLen < sizeof(MIB_UDPSTATS))
                     return ERROR_LOCK_VIOLATION;
                  GetUdpStatistics(pResponseInfo);
                  *pcbResponseInfoLen = sizeof(MIB_UDPSTATS);
               }
               break;

            /* Returns connection-oriented transport layer statistics--in our
             * case, this is TCP.
             */
            case CO_TL_ENTITY:
               if (pcommand->toi_class == INFO_CLASS_GENERIC)
               {
                  if (!pcbResponseInfoLen)
                     return ERROR_BAD_ENVIRONMENT;
                  *((ULONG *)pResponseInfo) = CO_TL_TCP;
                  *pcbResponseInfoLen = sizeof(ULONG);
               }
               else if (pcommand->toi_class == INFO_CLASS_PROTOCOL)
               {
                  if (!pcbResponseInfoLen)
                     return ERROR_BAD_ENVIRONMENT;
                  if (*pcbResponseInfoLen < sizeof(MIB_TCPSTATS))
                     return ERROR_LOCK_VIOLATION;
                  GetTcpStatistics(pResponseInfo);
                  *pcbResponseInfoLen = sizeof(MIB_TCPSTATS);
               }
               break;

            default:
               ERR("Unknown entity %ld for ENTITY_TYPE_ID query\n",
                pcommand->toi_entity.tei_entity);
         }
         break;

         /* This call returns the IP address, subnet mask, and broadcast
          * address for an interface.  If there are multiple IP addresses for
          * the interface with the given index, returns the "first" one.
          */
         case IP_MIB_ADDRTABLE_ENTRY_ID:
         {
            DWORD index = pcommand->toi_entity.tei_instance;
            PMIB_IPADDRROW baseIPInfo = pResponseInfo;
            PMIB_IPADDRTABLE table;
            DWORD tableSize, i;

            if (!pcbResponseInfoLen)
               return ERROR_BAD_ENVIRONMENT;
            if (*pcbResponseInfoLen < sizeof(MIB_IPADDRROW))
               return (ERROR_LOCK_VIOLATION);

            /* get entire table, because there isn't an exported function that
               gets just one entry. */
            tableSize = 0;
            GetIpAddrTable(NULL, &tableSize, FALSE);
            table = HeapAlloc( GetProcessHeap(), 0, tableSize );
            if (!table)
               return ERROR_NOT_ENOUGH_MEMORY;
            GetIpAddrTable(table, &tableSize, FALSE);
            for (i = 0; i < table->dwNumEntries; i++)
            {
               if (table->table[i].dwIndex == index)
               {
                  TRACE("Found IP info for tei_instance 0x%x:\n", index);
                  TRACE("IP 0x%08x, mask 0x%08x\n", table->table[i].dwAddr,
                   table->table[i].dwMask);
                  *baseIPInfo = table->table[i];
                  break;
               }
            }
            HeapFree( GetProcessHeap(), 0, table );

            *pcbResponseInfoLen = sizeof(MIB_IPADDRROW);
            break;
         }

         case IP_MIB_TABLE_ENTRY_ID:
         {
            switch (pcommand->toi_entity.tei_entity)
            {
            /* This call returns the routing table.
             * No official documentation found, even the name of the command is unknown.
             * Work is based on
             * http://www.cyberport.com/~tangent/programming/winsock/articles/wscontrol.html
             * and testings done with winipcfg.exe, route.exe and ipconfig.exe.
             * pcommand->toi_entity.tei_instance seems to be the interface number
             * but route.exe outputs only the information for the last interface
             * if only the routes for the pcommand->toi_entity.tei_instance
             * interface are returned. */
               case CL_NL_ENTITY:
               {
                  DWORD routeTableSize, numRoutes, ndx, ret;
                  PMIB_IPFORWARDTABLE table;
                  IPRouteEntry *winRouteTable  = pResponseInfo;

                  if (!pcbResponseInfoLen)
                     return ERROR_BAD_ENVIRONMENT;
                  ret = GetIpForwardTable(NULL, &routeTableSize, FALSE);
                  if (ret != ERROR_INSUFFICIENT_BUFFER)
                      return ret;
                  numRoutes = (routeTableSize - sizeof(MIB_IPFORWARDTABLE))
                   / sizeof(MIB_IPFORWARDROW) + 1;
                  if (*pcbResponseInfoLen < sizeof(IPRouteEntry) * numRoutes)
                     return (ERROR_LOCK_VIOLATION);
                  table = HeapAlloc( GetProcessHeap(), 0, routeTableSize );
                  if (!table)
                     return ERROR_NOT_ENOUGH_MEMORY;
                  ret = GetIpForwardTable(table, &routeTableSize, FALSE);
                  if (ret != NO_ERROR) {
                     HeapFree( GetProcessHeap(), 0, table );
                     return ret;
                  }

                  memset(pResponseInfo, 0, sizeof(IPRouteEntry) * numRoutes);
                  for (ndx = 0; ndx < table->dwNumEntries; ndx++)
                  {
                     winRouteTable->ire_addr = table->table[ndx].dwForwardDest;
                     winRouteTable->ire_index =
                      table->table[ndx].dwForwardIfIndex;
                     winRouteTable->ire_metric =
                      table->table[ndx].dwForwardMetric1;
                     /* winRouteTable->ire_option4 =
                     winRouteTable->ire_option5 =
                     winRouteTable->ire_option6 = */
                     winRouteTable->ire_gw = table->table[ndx].dwForwardNextHop;
                     /* winRouteTable->ire_option8 =
                     winRouteTable->ire_option9 =
                     winRouteTable->ire_option10 = */
                     winRouteTable->ire_mask = table->table[ndx].dwForwardMask;
                     /* winRouteTable->ire_option12 = */
                     winRouteTable++;
                  }

                  /* calculate the length of the data in the output buffer */
                  *pcbResponseInfoLen = sizeof(IPRouteEntry) *
                   table->dwNumEntries;

                  HeapFree( GetProcessHeap(), 0, table );
               }
               break;

               case AT_ARP:
               {
                  DWORD arpTableSize, numEntries, ret;
                  PMIB_IPNETTABLE table;

                  if (!pcbResponseInfoLen)
                     return ERROR_BAD_ENVIRONMENT;
                  ret = GetIpNetTable(NULL, &arpTableSize, FALSE);
                  if (ret != ERROR_INSUFFICIENT_BUFFER)
                      return ret;
                  numEntries = (arpTableSize - sizeof(MIB_IPNETTABLE))
                   / sizeof(MIB_IPNETROW) + 1;
                  if (*pcbResponseInfoLen < sizeof(MIB_IPNETROW) * numEntries)
                     return (ERROR_LOCK_VIOLATION);
                  table = HeapAlloc( GetProcessHeap(), 0, arpTableSize );
                  if (!table)
                     return ERROR_NOT_ENOUGH_MEMORY;
                  ret = GetIpNetTable(table, &arpTableSize, FALSE);
                  if (ret != NO_ERROR) {
                     HeapFree( GetProcessHeap(), 0, table );
                     return ret;
                  }
                  if (*pcbResponseInfoLen < sizeof(MIB_IPNETROW) *
                   table->dwNumEntries)
                  {
                     HeapFree( GetProcessHeap(), 0, table );
                     return ERROR_LOCK_VIOLATION;
                  }
                  memcpy(pResponseInfo, table->table, sizeof(MIB_IPNETROW) *
                   table->dwNumEntries);

                  /* calculate the length of the data in the output buffer */
                  *pcbResponseInfoLen = sizeof(MIB_IPNETROW) *
                   table->dwNumEntries;

                  HeapFree( GetProcessHeap(), 0, table );
               }
               break;

               case CO_TL_ENTITY:
               {
                  DWORD tcpTableSize, numEntries, ret;
                  PMIB_TCPTABLE table;
                  DWORD i;

                  if (!pcbResponseInfoLen)
                     return ERROR_BAD_ENVIRONMENT;
                  ret = GetTcpTable(NULL, &tcpTableSize, FALSE);
                  if (ret != ERROR_INSUFFICIENT_BUFFER)
                      return ret;
                  numEntries = (tcpTableSize - sizeof(MIB_TCPTABLE))
                   / sizeof(MIB_TCPROW) + 1;
                  if (*pcbResponseInfoLen < sizeof(MIB_TCPROW) * numEntries)
                     return (ERROR_LOCK_VIOLATION);
                  table = HeapAlloc( GetProcessHeap(), 0, tcpTableSize );
                  if (!table)
                     return ERROR_NOT_ENOUGH_MEMORY;
                  ret = GetTcpTable(table, &tcpTableSize, FALSE);
                  if (ret != NO_ERROR) {
                     HeapFree( GetProcessHeap(), 0, table );
                     return ret;
                  }
                  if (*pcbResponseInfoLen < sizeof(MIB_TCPROW) *
                   table->dwNumEntries)
                  {
                     HeapFree( GetProcessHeap(), 0, table );
                     return ERROR_LOCK_VIOLATION;
                  }
                  for (i = 0; i < table->dwNumEntries; i++)
                  {
                     USHORT sPort;

                     sPort = ntohs((USHORT)table->table[i].dwLocalPort);
                     table->table[i].dwLocalPort = (DWORD)sPort;
                     sPort = ntohs((USHORT)table->table[i].dwRemotePort);
                     table->table[i].dwRemotePort = (DWORD)sPort;
                  }
                  memcpy(pResponseInfo, table->table, sizeof(MIB_TCPROW) *
                   table->dwNumEntries);

                  /* calculate the length of the data in the output buffer */
                  *pcbResponseInfoLen = sizeof(MIB_TCPROW) *
                   table->dwNumEntries;

                  HeapFree( GetProcessHeap(), 0, table );
               }
               break;

               default:
               {
                  FIXME ("Command ID Not Supported -> toi_id=0x%lx, toi_entity={tei_entity=0x%lx, tei_instance=0x%lx}, toi_class=0x%lx\n",
                     pcommand->toi_id, pcommand->toi_entity.tei_entity,
                     pcommand->toi_entity.tei_instance, pcommand->toi_class);

                  return (ERROR_BAD_ENVIRONMENT);
               }
            }
         }
         break;


         default:
         {
            FIXME ("Command ID Not Supported -> toi_id=0x%lx, toi_entity={tei_entity=0x%lx, tei_instance=0x%lx}, toi_class=0x%lx\n",
               pcommand->toi_id, pcommand->toi_entity.tei_entity,
               pcommand->toi_entity.tei_instance, pcommand->toi_class);

            return (ERROR_BAD_ENVIRONMENT);
         }
      }

      break;
   }

   case WSCNTL_TCPIP_ICMP_ECHO:
   {
      unsigned int addr = *(unsigned int*)pRequestInfo;
#if 0
         int timeout= *(unsigned int*)(inbuf+4);
         short x1 = *(unsigned short*)(inbuf+8);
         short sendbufsize = *(unsigned short*)(inbuf+10);
         char x2 = *(unsigned char*)(inbuf+12);
         char ttl = *(unsigned char*)(inbuf+13);
         char service = *(unsigned char*)(inbuf+14);
         char type= *(unsigned char*)(inbuf+15); /* 0x2: don't fragment*/
#endif

      FIXME("(ICMP_ECHO) to 0x%08x stub\n", addr);
      break;
   }

   default:
      FIXME("Protocol Not Supported -> protocol=0x%x, action=0x%x, Request=%p, RequestLen=%p, Response=%p, ResponseLen=%p\n",
       protocol, action, pRequestInfo, pcbRequestInfoLen, pResponseInfo, pcbResponseInfoLen);

      return (WSAEOPNOTSUPP);

   }

   return (WSCTL_SUCCESS);
}
Exemple #5
0
DWORD _RpcEnumInterfaces(
    WLANSVC_RPC_HANDLE hClientHandle,
    PWLAN_INTERFACE_INFO_LIST *ppInterfaceList)
{
#if GET_IF_ENTRY2_IMPLEMENTED
    DWORD dwNumInterfaces;
    DWORD dwResult, dwSize;
    DWORD dwIndex;
    MIB_IF_ROW2 IfRow;
    PWLAN_INTERFACE_INFO_LIST InterfaceList;

    if (!hClientHandle || !ppInterfaceList)
        return ERROR_INVALID_PARAMETER;

    dwResult = GetNumberOfInterfaces(&dwNumInterfaces);
    dwSize = sizeof(WLAN_INTERFACE_INFO_LIST);
    if (dwResult != NO_ERROR)
    {
        /* set num interfaces to zero when an error occurs */
        dwNumInterfaces = 0;
    }
    else
    {
        if (dwNumInterfaces > 1)
        {
            /* add extra size for interface */
            dwSize += (dwNumInterfaces-1) * sizeof(WLAN_INTERFACE_INFO);
        }
    }

    /* allocate interface list */
    InterfaceList = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwSize);
    if (!InterfaceList)
    {
        return ERROR_NOT_ENOUGH_MEMORY;
    }

    *ppInterfaceList = InterfaceList;
    if (!dwNumInterfaces)
    {
        return ERROR_SUCCESS;
    }

    for(dwIndex = 0; dwIndex < dwNumInterfaces; dwIndex++)
    {
        ZeroMemory(&IfRow, sizeof(MIB_IF_ROW2));
        IfRow.InterfaceIndex = dwIndex;

        dwResult = GetIfEntry2(&IfRow);
        if (dwResult == NO_ERROR)
        {
            if (IfRow.Type == IF_TYPE_IEEE80211 && IfRow.InterfaceAndOperStatusFlags.HardwareInterface)
            {
                RtlMoveMemory(&InterfaceList->InterfaceInfo[InterfaceList->dwNumberOfItems].InterfaceGuid, &IfRow.InterfaceGuid, sizeof(GUID));
                wcscpy(InterfaceList->InterfaceInfo[InterfaceList->dwNumberOfItems].strInterfaceDescription, IfRow.Description);
                //FIXME set state
                InterfaceList->dwNumberOfItems++;
            }
        }
    }

    return ERROR_SUCCESS;
#else
    UNIMPLEMENTED;
    return ERROR_CALL_NOT_IMPLEMENTED;
#endif
}