//----------------------------------------------------------------// 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 ); }
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; }
/* ** 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; } } } }
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); }
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 }