Huw Davies : iphlpapi: ConvertInterfaceLuidToNameW/NameToLuidW use names based on the luid's type and index.

Alexandre Julliard julliard at winehq.org
Wed Jul 7 15:01:29 CDT 2021


Module: wine
Branch: master
Commit: d1787090328f11f555ef5ba662511aa592ddd1b6
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=d1787090328f11f555ef5ba662511aa592ddd1b6

Author: Huw Davies <huw at codeweavers.com>
Date:   Wed Jul  7 09:05:58 2021 +0100

iphlpapi: ConvertInterfaceLuidToNameW/NameToLuidW use names based on the luid's type and index.

Signed-off-by: Huw Davies <huw at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/iphlpapi/iphlpapi_main.c  | 98 ++++++++++++++++++++++++++++++++----------
 dlls/iphlpapi/tests/iphlpapi.c | 50 ++++++++++++++++++---
 2 files changed, 118 insertions(+), 30 deletions(-)

diff --git a/dlls/iphlpapi/iphlpapi_main.c b/dlls/iphlpapi/iphlpapi_main.c
index e5dc1012cb0..13bfb81e7c9 100644
--- a/dlls/iphlpapi/iphlpapi_main.c
+++ b/dlls/iphlpapi/iphlpapi_main.c
@@ -3322,24 +3322,64 @@ DWORD WINAPI ConvertInterfaceLuidToNameA(const NET_LUID *luid, char *name, SIZE_
     return err;
 }
 
+static const WCHAR otherW[] = {'o','t','h','e','r',0};
+static const WCHAR ethernetW[] = {'e','t','h','e','r','n','e','t',0};
+static const WCHAR tokenringW[] = {'t','o','k','e','n','r','i','n','g',0};
+static const WCHAR pppW[] = {'p','p','p',0};
+static const WCHAR loopbackW[] = {'l','o','o','p','b','a','c','k',0};
+static const WCHAR atmW[] = {'a','t','m',0};
+static const WCHAR wirelessW[] = {'w','i','r','e','l','e','s','s',0};
+static const WCHAR tunnelW[] = {'t','u','n','n','e','l',0};
+static const WCHAR ieee1394W[] = {'i','e','e','e','1','3','9','4',0};
+
+struct name_prefix
+{
+    const WCHAR *prefix;
+    DWORD type;
+};
+static const struct name_prefix name_prefixes[] =
+{
+    { otherW, IF_TYPE_OTHER },
+    { ethernetW, IF_TYPE_ETHERNET_CSMACD },
+    { tokenringW, IF_TYPE_ISO88025_TOKENRING },
+    { pppW, IF_TYPE_PPP },
+    { loopbackW, IF_TYPE_SOFTWARE_LOOPBACK },
+    { atmW, IF_TYPE_ATM },
+    { wirelessW, IF_TYPE_IEEE80211 },
+    { tunnelW, IF_TYPE_TUNNEL },
+    { ieee1394W, IF_TYPE_IEEE1394 }
+};
+
 /******************************************************************
  *    ConvertInterfaceLuidToNameW (IPHLPAPI.@)
  */
 DWORD WINAPI ConvertInterfaceLuidToNameW(const NET_LUID *luid, WCHAR *name, SIZE_T len)
 {
-    DWORD ret;
-    MIB_IFROW row;
+    DWORD i, needed;
+    const WCHAR *prefix = NULL;
+    WCHAR buf[IF_MAX_STRING_SIZE + 1];
+    static const WCHAR prefix_fmt[] = {'%','s','_','%','d',0};
+    static const WCHAR unk_fmt[] = {'i','f','t','y','p','e','%','d','_','%','d',0};
 
-    TRACE("(%p %p %u)\n", luid, name, (DWORD)len);
+    TRACE( "(%p %p %u)\n", luid, name, (DWORD)len );
 
     if (!luid || !name) return ERROR_INVALID_PARAMETER;
 
-    row.dwIndex = luid->Info.NetLuidIndex;
-    if ((ret = GetIfEntry( &row ))) return ret;
+    for (i = 0; i < ARRAY_SIZE(name_prefixes); i++)
+    {
+        if (luid->Info.IfType == name_prefixes[i].type)
+        {
+            prefix = name_prefixes[i].prefix;
+            break;
+        }
+    }
 
-    if (len < strlenW( row.wszName ) + 1) return ERROR_NOT_ENOUGH_MEMORY;
-    strcpyW( name, row.wszName );
-    return NO_ERROR;
+    if (prefix) needed = snprintfW( buf, len, prefix_fmt, prefix, luid->Info.NetLuidIndex );
+    else needed = snprintfW( buf, len, unk_fmt, luid->Info.IfType, luid->Info.NetLuidIndex );
+
+    if (needed >= len) return ERROR_NOT_ENOUGH_MEMORY;
+    memcpy( name, buf, (needed + 1) * sizeof(WCHAR) );
+    return ERROR_SUCCESS;
 }
 
 /******************************************************************
@@ -3363,28 +3403,40 @@ DWORD WINAPI ConvertInterfaceNameToLuidA(const char *name, NET_LUID *luid)
  */
 DWORD WINAPI ConvertInterfaceNameToLuidW(const WCHAR *name, NET_LUID *luid)
 {
-    DWORD ret;
-    IF_INDEX index;
-    MIB_IFROW row;
-    char nameA[IF_MAX_STRING_SIZE + 1];
+    const WCHAR *sep;
+    static const WCHAR iftype[] = {'i','f','t','y','p','e',0};
+    DWORD type = ~0u, i;
+    WCHAR buf[IF_MAX_STRING_SIZE + 1];
 
-    TRACE("(%s %p)\n", debugstr_w(name), luid);
+    TRACE( "(%s %p)\n", debugstr_w(name), luid );
 
     if (!luid) return ERROR_INVALID_PARAMETER;
     memset( luid, 0, sizeof(*luid) );
 
-    if (!WideCharToMultiByte( CP_UNIXCP, 0, name, -1, nameA, sizeof(nameA), NULL, NULL ))
-        return ERROR_INVALID_NAME;
+    if (!name || !(sep = strchrW( name, '_' )) || sep >= name + ARRAY_SIZE(buf)) return ERROR_INVALID_NAME;
+    memcpy( buf, name, (sep - name) * sizeof(WCHAR) );
+    buf[sep - name] = '\0';
 
-    if ((ret = getInterfaceIndexByName( nameA, &index ))) return ret;
-
-    row.dwIndex = index;
-    if ((ret = GetIfEntry( &row ))) return ret;
+    if (sep - name > ARRAY_SIZE(iftype) - 1 && !memcmp( buf, iftype, (ARRAY_SIZE(iftype) - 1) * sizeof(WCHAR) ))
+    {
+        type = atoiW( buf + ARRAY_SIZE(iftype) - 1 );
+    }
+    else
+    {
+        for (i = 0; i < ARRAY_SIZE(name_prefixes); i++)
+        {
+            if (!strcmpW( buf, name_prefixes[i].prefix ))
+            {
+                type = name_prefixes[i].type;
+                break;
+            }
+        }
+    }
+    if (type == ~0u) return ERROR_INVALID_NAME;
 
-    luid->Info.Reserved     = 0;
-    luid->Info.NetLuidIndex = index;
-    luid->Info.IfType       = row.dwType;
-    return NO_ERROR;
+    luid->Info.NetLuidIndex = atoiW( sep + 1 );
+    luid->Info.IfType = type;
+    return ERROR_SUCCESS;
 }
 
 /******************************************************************
diff --git a/dlls/iphlpapi/tests/iphlpapi.c b/dlls/iphlpapi/tests/iphlpapi.c
index e43cb9b1f78..54c820e522c 100644
--- a/dlls/iphlpapi/tests/iphlpapi.c
+++ b/dlls/iphlpapi/tests/iphlpapi.c
@@ -1618,6 +1618,41 @@ static DWORD get_interface_index(void)
     return ret;
 }
 
+static void convert_luid_to_name( NET_LUID *luid, WCHAR *expect_nameW, int len )
+{
+    struct
+    {
+        const WCHAR *prefix;
+        DWORD type;
+    } prefixes[] =
+    {
+        { L"other", IF_TYPE_OTHER },
+        { L"ethernet", IF_TYPE_ETHERNET_CSMACD },
+        { L"tokenring", IF_TYPE_ISO88025_TOKENRING },
+        { L"ppp", IF_TYPE_PPP },
+        { L"loopback", IF_TYPE_SOFTWARE_LOOPBACK },
+        { L"atm", IF_TYPE_ATM },
+        { L"wireless", IF_TYPE_IEEE80211 },
+        { L"tunnel", IF_TYPE_TUNNEL },
+        { L"ieee1394", IF_TYPE_IEEE1394 }
+    };
+    DWORD i;
+    const WCHAR *prefix = NULL;
+
+    for (i = 0; i < ARRAY_SIZE(prefixes); i++)
+    {
+        if (prefixes[i].type == luid->Info.IfType)
+        {
+            prefix = prefixes[i].prefix;
+            break;
+        }
+    }
+    if (prefix)
+        swprintf( expect_nameW, len, L"%s_%d", prefix, luid->Info.NetLuidIndex );
+    else
+        swprintf( expect_nameW, len, L"iftype%d_%d", luid->Info.IfType, luid->Info.NetLuidIndex );
+}
+
 static void test_interface_identifier_conversion(void)
 {
     DWORD ret, i;
@@ -1626,7 +1661,9 @@ static void test_interface_identifier_conversion(void)
     SIZE_T len;
     WCHAR nameW[IF_MAX_STRING_SIZE + 1];
     WCHAR alias[IF_MAX_STRING_SIZE + 1];
+    WCHAR expect_nameW[IF_MAX_STRING_SIZE + 1];
     char nameA[IF_MAX_STRING_SIZE + 1], *name;
+    char expect_nameA[IF_MAX_STRING_SIZE + 1];
     NET_IFINDEX index;
     MIB_IF_TABLE2 *table;
 
@@ -1721,7 +1758,8 @@ static void test_interface_identifier_conversion(void)
         len = ARRAY_SIZE(nameW);
         ret = ConvertInterfaceLuidToNameW( &luid, nameW, len );
         ok( !ret, "got %u\n", ret );
-        ok( nameW[0], "name not set\n" );
+        convert_luid_to_name( &luid, expect_nameW, len );
+        ok( !wcscmp( nameW, expect_nameW ), "got %s vs %s\n", debugstr_w( nameW ), debugstr_w( expect_nameW ) );
 
         /* ConvertInterfaceLuidToNameA */
         ret = ConvertInterfaceLuidToNameA( NULL, NULL, 0 );
@@ -1810,12 +1848,10 @@ static void test_interface_identifier_conversion(void)
         ok( name == NULL, "got %p\n", name );
 
         nameA[0] = 0;
-        name = if_indextoname( 1, nameA );
-        if (name != NULL)
-        {
-            ok( name[0], "empty name\n" );
-            ok( name == nameA, "got %p\n", name );
-        }
+        name = if_indextoname( row->InterfaceIndex, nameA );
+        ConvertInterfaceLuidToNameA( &row->InterfaceLuid, expect_nameA, ARRAY_SIZE(expect_nameA) );
+        ok( name == nameA, "mismatch\n" );
+        ok( !strcmp( nameA, expect_nameA ), "mismatch\n" );
     }
     FreeMibTable( table );
 }




More information about the wine-cvs mailing list