Author: cgutman Date: Fri May 14 03:30:37 2010 New Revision: 47195
URL: http://svn.reactos.org/svn/reactos?rev=47195&view=rev Log: [IPHLPAPI] - Implement GetAdaptersAddresses - Fixes the last iphlpapi winetest
Modified: trunk/reactos/dll/win32/iphlpapi/iphlpapi_main.c trunk/reactos/dll/win32/iphlpapi/iphlpapi_private.h
Modified: trunk/reactos/dll/win32/iphlpapi/iphlpapi_main.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/iphlpapi/iphlpapi... ============================================================================== --- trunk/reactos/dll/win32/iphlpapi/iphlpapi_main.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/iphlpapi/iphlpapi_main.c [iso-8859-1] Fri May 14 03:30:37 2010 @@ -2301,17 +2301,196 @@ }
/* - * @unimplemented + * @implemented */ DWORD WINAPI GetAdaptersAddresses(ULONG Family,ULONG Flags,PVOID Reserved,PIP_ADAPTER_ADDRESSES pAdapterAddresses,PULONG pOutBufLen) { + InterfaceIndexTable *indexTable; + IFInfo ifInfo; + int i; + ULONG ret, requiredSize = 0; + PIP_ADAPTER_ADDRESSES currentAddress; + PUCHAR currentLocation; + HANDLE tcpFile; + if (!pOutBufLen) return ERROR_INVALID_PARAMETER; - if (!pAdapterAddresses || *pOutBufLen == 0) - return ERROR_BUFFER_OVERFLOW; if (Reserved) return ERROR_INVALID_PARAMETER;
- FIXME(":stub\n"); - return ERROR_NO_DATA; + indexTable = getNonLoopbackInterfaceIndexTable(); //I think we want non-loopback here + if (!indexTable) + return ERROR_NOT_ENOUGH_MEMORY; + + ret = openTcpFile(&tcpFile); + if (!NT_SUCCESS(ret)) + return ERROR_NO_DATA; + + for (i = indexTable->numIndexes; i >= 0; i--) + { + if (NT_SUCCESS(getIPAddrEntryForIf(tcpFile, + NULL, + indexTable->indexes[i], + &ifInfo))) + { + /* The whole struct */ + requiredSize += sizeof(IP_ADAPTER_ADDRESSES); + + /* Friendly name */ + if (!(Flags & GAA_FLAG_SKIP_FRIENDLY_NAME)) + requiredSize += strlen((char *)ifInfo.if_info.ent.if_descr) + 1; //FIXME + + /* Adapter name */ + requiredSize += strlen((char *)ifInfo.if_info.ent.if_descr) + 1; + + /* Unicast address */ + if (!(Flags & GAA_FLAG_SKIP_UNICAST)) + requiredSize += sizeof(IP_ADAPTER_UNICAST_ADDRESS); + + /* FIXME: Implement multicast, anycast, and dns server stuff */ + + /* FIXME: Implement dns suffix and description */ + requiredSize += 2 * sizeof(WCHAR); + + /* We're only going to implement what's required for XP SP0 */ + } + } + + if (*pOutBufLen < requiredSize) + { + *pOutBufLen = requiredSize; + closeTcpFile(tcpFile); + free(indexTable); + return ERROR_BUFFER_OVERFLOW; + } + + RtlZeroMemory(pAdapterAddresses, requiredSize); + + /* Let's set up the pointers */ + currentAddress = pAdapterAddresses; + for (i = indexTable->numIndexes; i >= 0; i--) + { + if (NT_SUCCESS(getIPAddrEntryForIf(tcpFile, + NULL, + indexTable->indexes[i], + &ifInfo))) + { + currentLocation = (PUCHAR)currentAddress + (ULONG_PTR)sizeof(IP_ADAPTER_ADDRESSES); + + /* FIXME: Friendly name */ + if (!(Flags & GAA_FLAG_SKIP_FRIENDLY_NAME)) + { + currentAddress->FriendlyName = (PVOID)currentLocation; + currentLocation += sizeof(WCHAR); + } + + /* Adapter name */ + currentAddress->AdapterName = (PVOID)currentLocation; + currentLocation += strlen((char *)ifInfo.if_info.ent.if_descr) + 1; + + /* Unicast address */ + if (!(Flags & GAA_FLAG_SKIP_UNICAST)) + { + currentAddress->FirstUnicastAddress = (PVOID)currentLocation; + currentLocation += sizeof(IP_ADAPTER_UNICAST_ADDRESS); + currentAddress->FirstUnicastAddress->Address.lpSockaddr = (PVOID)currentLocation; + currentLocation += sizeof(struct sockaddr); + } + + /* FIXME: Implement multicast, anycast, and dns server stuff */ + + /* FIXME: Implement dns suffix and description */ + currentAddress->DnsSuffix = (PVOID)currentLocation; + currentLocation += sizeof(WCHAR); + + currentAddress->Description = (PVOID)currentLocation; + currentLocation += sizeof(WCHAR); + + currentAddress->Next = (PVOID)currentLocation; + + /* We're only going to implement what's required for XP SP0 */ + + currentAddress = currentAddress->Next; + } + } + + /* Terminate the last address correctly */ + if (currentAddress) + currentAddress->Next = NULL; + + /* Now again, for real this time */ + + currentAddress = pAdapterAddresses; + for (i = indexTable->numIndexes; i >= 0; i--) + { + if (NT_SUCCESS(getIPAddrEntryForIf(tcpFile, + NULL, + indexTable->indexes[i], + &ifInfo))) + { + /* Make sure we're not looping more than we hoped for */ + ASSERT(currentAddress); + + /* Alignment information */ + currentAddress->Length = sizeof(IP_ADAPTER_ADDRESSES); + currentAddress->IfIndex = indexTable->indexes[i]; + + /* Adapter name */ + strcpy(currentAddress->AdapterName, (char *)ifInfo.if_info.ent.if_descr); + + if (!(Flags & GAA_FLAG_SKIP_UNICAST)) + { + currentAddress->FirstUnicastAddress->Length = sizeof(IP_ADAPTER_UNICAST_ADDRESS); + currentAddress->FirstUnicastAddress->Flags = 0; //FIXME + currentAddress->FirstUnicastAddress->Next = NULL; //FIXME: Support more than one address per adapter + currentAddress->FirstUnicastAddress->Address.lpSockaddr->sa_family = AF_INET; + memcpy(currentAddress->FirstUnicastAddress->Address.lpSockaddr->sa_data, + &ifInfo.ip_addr.iae_addr, + sizeof(ifInfo.ip_addr.iae_addr)); + currentAddress->FirstUnicastAddress->Address.iSockaddrLength = sizeof(ifInfo.ip_addr.iae_addr) + sizeof(USHORT); + currentAddress->FirstUnicastAddress->PrefixOrigin = IpPrefixOriginOther; //FIXME + currentAddress->FirstUnicastAddress->SuffixOrigin = IpPrefixOriginOther; //FIXME + currentAddress->FirstUnicastAddress->DadState = IpDadStatePreferred; //FIXME + currentAddress->FirstUnicastAddress->ValidLifetime = 0xFFFFFFFF; //FIXME + currentAddress->FirstUnicastAddress->PreferredLifetime = 0xFFFFFFFF; //FIXME + currentAddress->FirstUnicastAddress->LeaseLifetime = 0xFFFFFFFF; //FIXME + } + + /* FIXME: Implement multicast, anycast, and dns server stuff */ + currentAddress->FirstAnycastAddress = NULL; + currentAddress->FirstMulticastAddress = NULL; + currentAddress->FirstDnsServerAddress = NULL; + + /* FIXME: Implement dns suffix, description, and friendly name */ + currentAddress->DnsSuffix[0] = UNICODE_NULL; + currentAddress->Description[0] = UNICODE_NULL; + currentAddress->FriendlyName[0] = UNICODE_NULL; + + /* Physical Address */ + memcpy(currentAddress->PhysicalAddress, ifInfo.if_info.ent.if_physaddr, ifInfo.if_info.ent.if_physaddrlen); + currentAddress->PhysicalAddressLength = ifInfo.if_info.ent.if_physaddrlen; + + /* Flags */ + currentAddress->Flags = 0; //FIXME + + /* MTU */ + currentAddress->Mtu = ifInfo.if_info.ent.if_mtu; + + /* Interface type */ + currentAddress->IfType = ifInfo.if_info.ent.if_type; + + /* Operational status */ + currentAddress->OperStatus = ifInfo.if_info.ent.if_operstatus; + + /* We're only going to implement what's required for XP SP0 */ + + /* Move to the next address */ + currentAddress = currentAddress->Next; + } + } + + closeTcpFile(tcpFile); + free(indexTable); + + return NO_ERROR; }
/*
Modified: trunk/reactos/dll/win32/iphlpapi/iphlpapi_private.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/iphlpapi/iphlpapi... ============================================================================== --- trunk/reactos/dll/win32/iphlpapi/iphlpapi_private.h [iso-8859-1] (original) +++ trunk/reactos/dll/win32/iphlpapi/iphlpapi_private.h [iso-8859-1] Fri May 14 03:30:37 2010 @@ -59,6 +59,15 @@
#define TCP_REQUEST_QUERY_INFORMATION_INIT { { { 0 } } } #define TCP_REQUEST_SET_INFORMATION_INIT { { 0 } } + +/* FIXME: ROS headers suck */ +#ifndef GAA_FLAG_SKIP_UNICAST +#define GAA_FLAG_SKIP_UNICAST 0x0001 +#endif + +#ifndef GAA_FLAG_SKIP_FRIENDLY_NAME +#define GAA_FLAG_SKIP_FRIENDLY_NAME 0x0020 +#endif
// As in the mib from RFC 1213
@@ -138,6 +147,10 @@ PWCHAR NameServer, PVOID Data ); void EnumNameServers( HANDLE RegHandle, PWCHAR Interface, PVOID Data, EnumNameServersFunc cb ); +NTSTATUS getIPAddrEntryForIf(HANDLE tcpFile, + char *name, + DWORD index, + IFInfo *ifInfo);
#include <w32api.h> /* This is here until we switch to version 2.5 of the mingw headers */