[1/2] iphlpapi: Add GetUnicastIpAddressEntry implementation (resend)

Bruno Jesus 00cpxxx at gmail.com
Thu Feb 2 19:23:08 CST 2017


On Thu, Feb 2, 2017 at 9:08 PM, André Hentschel <nerv at dawncrow.de> wrote:
> For https://bugs.winehq.org/show_bug.cgi?id=41753
>
> Signed-off-by: André Hentschel <nerv at dawncrow.de>
> ---
>
> resending, because of bad timing together with the testbot
>
>  dlls/iphlpapi/iphlpapi.spec   |  2 +-
>  dlls/iphlpapi/iphlpapi_main.c | 77 +++++++++++++++++++++++++++++++++++++++++++
>  include/netioapi.h            | 17 ++++++++++
>  include/ws2def.h              | 13 ++++++++
>  include/ws2ipdef.h            |  7 ++++
>  5 files changed, 115 insertions(+), 1 deletion(-)
>
> diff --git a/dlls/iphlpapi/iphlpapi.spec b/dlls/iphlpapi/iphlpapi.spec
> index 500267c..1a1f8f7 100644
> --- a/dlls/iphlpapi/iphlpapi.spec
> +++ b/dlls/iphlpapi/iphlpapi.spec
> @@ -147,7 +147,7 @@
>  @ stub GetUdpStatsFromStack
>  @ stdcall GetUdpTable( ptr ptr long )
>  @ stub GetUdpTableFromStack
> -#@ stub GetUnicastIpAddressEntry
> +@ stdcall GetUnicastIpAddressEntry( ptr )
>  #@ stub GetUnicastIpAddressTable
>  @ stdcall GetUniDirectionalAdapterInfo( ptr ptr )
>  @ stdcall Icmp6CreateFile()
> diff --git a/dlls/iphlpapi/iphlpapi_main.c b/dlls/iphlpapi/iphlpapi_main.c
> index 1daf54d..ff0ad3f 100644
> --- a/dlls/iphlpapi/iphlpapi_main.c
> +++ b/dlls/iphlpapi/iphlpapi_main.c
> @@ -2467,6 +2467,83 @@ DWORD WINAPI GetExtendedUdpTable(PVOID pUdpTable, PDWORD pdwSize, BOOL bOrder,
>      return ret;
>  }
>
> +DWORD WINAPI GetUnicastIpAddressEntry(MIB_UNICASTIPADDRESS_ROW *row)
> +{
> +    char buf[MAX_ADAPTER_NAME], *name;
> +    IP_ADAPTER_ADDRESSES *aa, *ptr;
> +    ULONG size = 0;
> +    DWORD ret;
> +
> +    TRACE("%p\n", row);
> +
> +    if (!row)
> +        return ERROR_INVALID_PARAMETER;
> +
> +    if ((!(name = getInterfaceNameByIndex( row->InterfaceIndex, buf )) &&
> +         !(name = getInterfaceNameByIndex( row->InterfaceLuid.Info.NetLuidIndex, buf ))))
> +        return ERROR_FILE_NOT_FOUND;
> +
> +    GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_ALL_INTERFACES | GAA_FLAG_INCLUDE_PREFIX, NULL, NULL, &size);
> +    ptr = HeapAlloc(GetProcessHeap(), 0, size);
> +    ret = GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_ALL_INTERFACES | GAA_FLAG_INCLUDE_PREFIX, NULL, ptr, &size);

Is it possible to restrict GetAdaptersAddresses family to the one
passed in the row? Because in the loop below you check if it matches
and skip. If it is possible you could get rid of the
row->Address.si_family != uaaddr->si_family test in the loop.

> +    if (FAILED(ret))
> +    {
> +        HeapFree(GetProcessHeap(), 0, ptr);
> +        return ret;
> +    }
> +
> +    ret = ERROR_FILE_NOT_FOUND;
> +
> +    for (aa = ptr; aa; aa = aa->Next)
> +    {
> +        IP_ADAPTER_UNICAST_ADDRESS *ua;
> +
> +        if (aa->u.s.IfIndex != row->InterfaceIndex)
> +            continue;
> +
> +        ret = ERROR_NOT_FOUND;
> +
> +        if (!aa->FirstUnicastAddress)
> +            continue;

Is this really necessary? Since the while will not loop if ua = NULL too.

> +        ua = aa->FirstUnicastAddress;
> +        while (ua)
> +        {
> +            SOCKADDR_INET *uaaddr = (SOCKADDR_INET *)ua->Address.lpSockaddr;
> +            if (row->Address.si_family != uaaddr->si_family)
> +            {
> +                ua = ua->Next;
> +                continue;
> +            }
> +
> +            if ((row->Address.si_family == WS_AF_INET6 && !memcmp(&row->Address.Ipv6.sin6_addr, &uaaddr->Ipv6.sin6_addr, sizeof(row->Address.Ipv6.sin6_addr))) ||
> +                (row->Address.si_family == WS_AF_INET  && !memcmp(&row->Address.Ipv4.sin_addr,  &uaaddr->Ipv4.sin_addr,  sizeof(row->Address.Ipv4.sin_addr))))
> +            {
> +                memcpy(&row->InterfaceLuid, &aa->Luid, sizeof(aa->Luid));
> +                row->InterfaceIndex     = aa->u.s.IfIndex;
> +                row->PrefixOrigin       = ua->PrefixOrigin;
> +                row->SuffixOrigin       = ua->SuffixOrigin;
> +                row->ValidLifetime      = ua->ValidLifetime;
> +                row->PreferredLifetime  = ua->PreferredLifetime;
> +                row->OnLinkPrefixLength = ua->OnLinkPrefixLength;
> +                row->SkipAsSource       = 0;
> +                row->DadState           = ua->DadState;
> +                if (aa->IfType != IF_TYPE_SOFTWARE_LOOPBACK && row->Address.si_family == WS_AF_INET6)
> +                    row->ScopeId.Value  = aa->Ipv6IfIndex;
> +                else
> +                    row->ScopeId.Value  = 0;

As I said in the tests and just to say again, that I don't know where
this scopeid = ifindex comes from.

> +                NtQuerySystemTime(&row->CreationTimeStamp);
> +                HeapFree(GetProcessHeap(), 0, ptr);
> +                return NO_ERROR;
> +            }
> +            ua = ua->Next;
> +        }
> +    }
> +    HeapFree(GetProcessHeap(), 0, ptr);
> +
> +    return ret;
> +}
> +

Best wishes,
Bruno



More information about the wine-devel mailing list