iphlpapi: Implement a couple of interface identifier conversion functions.

This commit is contained in:
Hans Leidekker 2015-07-22 14:26:59 +02:00 committed by Alexandre Julliard
parent 939fb10a6e
commit 6cf1de4492
5 changed files with 404 additions and 9 deletions

View File

@ -12,15 +12,15 @@
#@ stub ConvertGuidToStringA
#@ stub ConvertGuidToStringW
#@ stub ConvertInterfaceAliasToLuid
#@ stub ConvertInterfaceGuidToLuid
#@ stub ConvertInterfaceIndexToLuid
@ stdcall ConvertInterfaceGuidToLuid( ptr ptr )
@ stdcall ConvertInterfaceIndexToLuid( long ptr )
#@ stub ConvertInterfaceLuidToAlias
@ stdcall ConvertInterfaceLuidToGuid( ptr ptr )
#@ stub ConvertInterfaceLuidToIndex
#@ stub ConvertInterfaceLuidToNameA
#@ stub ConvertInterfaceLuidToNameW
#@ stub ConvertInterfaceNameToLuidA
#@ stub ConvertInterfaceNameToLuidW
@ stdcall ConvertInterfaceLuidToIndex( ptr ptr )
@ stdcall ConvertInterfaceLuidToNameA( ptr ptr long )
@ stdcall ConvertInterfaceLuidToNameW( ptr ptr long )
@ stdcall ConvertInterfaceNameToLuidA( str ptr )
@ stdcall ConvertInterfaceNameToLuidW( wstr ptr )
#@ stub ConvertInterfacePhysicalAddressToLuid
#@ stub ConvertIpv4MaskToLength
#@ stub ConvertLengthToIpv4Mask

View File

@ -51,8 +51,10 @@
#include "ipstats.h"
#include "ipifcons.h"
#include "fltdefs.h"
#include "netioapi.h"
#include "wine/debug.h"
#include "wine/unicode.h"
WINE_DEFAULT_DEBUG_CHANNEL(iphlpapi);
@ -2744,11 +2746,176 @@ ULONG WINAPI GetTcp6Table2(PMIB_TCP6TABLE2 table, PULONG size, BOOL order)
return ERROR_NOT_SUPPORTED;
}
/******************************************************************
* ConvertInterfaceGuidToLuid (IPHLPAPI.@)
*/
DWORD WINAPI ConvertInterfaceGuidToLuid(const GUID *guid, NET_LUID *luid)
{
DWORD ret;
MIB_IFROW row;
TRACE("(%s %p)\n", debugstr_guid(guid), luid);
if (!guid || !luid) return ERROR_INVALID_PARAMETER;
row.dwIndex = guid->Data1;
if ((ret = GetIfEntry( &row ))) return ret;
luid->Info.Reserved = 0;
luid->Info.NetLuidIndex = guid->Data1;
luid->Info.IfType = row.dwType;
return NO_ERROR;
}
/******************************************************************
* ConvertInterfaceIndexToLuid (IPHLPAPI.@)
*/
DWORD WINAPI ConvertInterfaceIndexToLuid(NET_IFINDEX index, NET_LUID *luid)
{
MIB_IFROW row;
TRACE("(%u %p)\n", index, luid);
if (!luid) return ERROR_INVALID_PARAMETER;
memset( luid, 0, sizeof(*luid) );
row.dwIndex = index;
if (GetIfEntry( &row )) return ERROR_FILE_NOT_FOUND;
luid->Info.Reserved = 0;
luid->Info.NetLuidIndex = index;
luid->Info.IfType = row.dwType;
return NO_ERROR;
}
/******************************************************************
* ConvertInterfaceLuidToGuid (IPHLPAPI.@)
*/
DWORD WINAPI ConvertInterfaceLuidToGuid(const NET_LUID *luid, GUID *guid)
{
FIXME("(%p %p) stub\n", luid, guid);
return ERROR_CALL_NOT_IMPLEMENTED;
DWORD ret;
MIB_IFROW row;
TRACE("(%p %p)\n", luid, guid);
if (!luid || !guid) return ERROR_INVALID_PARAMETER;
row.dwIndex = luid->Info.NetLuidIndex;
if ((ret = GetIfEntry( &row ))) return ret;
guid->Data1 = luid->Info.NetLuidIndex;
return NO_ERROR;
}
/******************************************************************
* ConvertInterfaceLuidToIndex (IPHLPAPI.@)
*/
DWORD WINAPI ConvertInterfaceLuidToIndex(const NET_LUID *luid, NET_IFINDEX *index)
{
DWORD ret;
MIB_IFROW row;
TRACE("(%p %p)\n", luid, index);
if (!luid || !index) return ERROR_INVALID_PARAMETER;
row.dwIndex = luid->Info.NetLuidIndex;
if ((ret = GetIfEntry( &row ))) return ret;
*index = luid->Info.NetLuidIndex;
return NO_ERROR;
}
/******************************************************************
* ConvertInterfaceLuidToNameA (IPHLPAPI.@)
*/
DWORD WINAPI ConvertInterfaceLuidToNameA(const NET_LUID *luid, char *name, SIZE_T len)
{
DWORD ret;
MIB_IFROW row;
TRACE("(%p %p %u)\n", luid, name, (DWORD)len);
if (!luid) return ERROR_INVALID_PARAMETER;
row.dwIndex = luid->Info.NetLuidIndex;
if ((ret = GetIfEntry( &row ))) return ret;
if (!name || len < WideCharToMultiByte( CP_UNIXCP, 0, row.wszName, -1, NULL, 0, NULL, NULL ))
return ERROR_NOT_ENOUGH_MEMORY;
WideCharToMultiByte( CP_UNIXCP, 0, row.wszName, -1, name, len, NULL, NULL );
return NO_ERROR;
}
/******************************************************************
* ConvertInterfaceLuidToNameW (IPHLPAPI.@)
*/
DWORD WINAPI ConvertInterfaceLuidToNameW(const NET_LUID *luid, WCHAR *name, SIZE_T len)
{
DWORD ret;
MIB_IFROW row;
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;
if (len < strlenW( row.wszName ) + 1) return ERROR_NOT_ENOUGH_MEMORY;
strcpyW( name, row.wszName );
return NO_ERROR;
}
/******************************************************************
* ConvertInterfaceNameToLuidA (IPHLPAPI.@)
*/
DWORD WINAPI ConvertInterfaceNameToLuidA(const char *name, NET_LUID *luid)
{
DWORD ret;
IF_INDEX index;
MIB_IFROW row;
TRACE("(%s %p)\n", debugstr_a(name), luid);
if ((ret = getInterfaceIndexByName( name, &index ))) return ERROR_INVALID_NAME;
if (!luid) return ERROR_INVALID_PARAMETER;
row.dwIndex = index;
if ((ret = GetIfEntry( &row ))) return ret;
luid->Info.Reserved = 0;
luid->Info.NetLuidIndex = index;
luid->Info.IfType = row.dwType;
return NO_ERROR;
}
/******************************************************************
* ConvertInterfaceNameToLuidW (IPHLPAPI.@)
*/
DWORD WINAPI ConvertInterfaceNameToLuidW(const WCHAR *name, NET_LUID *luid)
{
DWORD ret;
IF_INDEX index;
MIB_IFROW row;
char nameA[IF_MAX_STRING_SIZE + 1];
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 ((ret = getInterfaceIndexByName( nameA, &index ))) return ret;
row.dwIndex = index;
if ((ret = GetIfEntry( &row ))) return ret;
luid->Info.Reserved = 0;
luid->Info.NetLuidIndex = index;
luid->Info.IfType = row.dwType;
return NO_ERROR;
}

View File

@ -81,6 +81,14 @@ static DWORD (WINAPI *pIcmpSendEcho)(HANDLE,IPAddr,LPVOID,WORD,PIP_OPTION_INFORM
static DWORD (WINAPI *pCreateSortedAddressPairs)(const PSOCKADDR_IN6,ULONG,const PSOCKADDR_IN6,ULONG,ULONG,
PSOCKADDR_IN6_PAIR*,ULONG*);
static void (WINAPI *pFreeMibTable)(void*);
static DWORD (WINAPI *pConvertInterfaceGuidToLuid)(const GUID*,NET_LUID*);
static DWORD (WINAPI *pConvertInterfaceIndexToLuid)(NET_IFINDEX,NET_LUID*);
static DWORD (WINAPI *pConvertInterfaceLuidToGuid)(const NET_LUID*,GUID*);
static DWORD (WINAPI *pConvertInterfaceLuidToIndex)(const NET_LUID*,NET_IFINDEX*);
static DWORD (WINAPI *pConvertInterfaceLuidToNameW)(const NET_LUID*,WCHAR*,SIZE_T);
static DWORD (WINAPI *pConvertInterfaceLuidToNameA)(const NET_LUID*,char*,SIZE_T);
static DWORD (WINAPI *pConvertInterfaceNameToLuidA)(const char*,NET_LUID*);
static DWORD (WINAPI *pConvertInterfaceNameToLuidW)(const WCHAR*,NET_LUID*);
static void loadIPHlpApi(void)
{
@ -117,6 +125,14 @@ static void loadIPHlpApi(void)
pIcmpSendEcho = (void *)GetProcAddress(hLibrary, "IcmpSendEcho");
pCreateSortedAddressPairs = (void *)GetProcAddress(hLibrary, "CreateSortedAddressPairs");
pFreeMibTable = (void *)GetProcAddress(hLibrary, "FreeMibTable");
pConvertInterfaceGuidToLuid = (void *)GetProcAddress(hLibrary, "ConvertInterfaceGuidToLuid");
pConvertInterfaceIndexToLuid = (void *)GetProcAddress(hLibrary, "ConvertInterfaceIndexToLuid");
pConvertInterfaceLuidToGuid = (void *)GetProcAddress(hLibrary, "ConvertInterfaceLuidToGuid");
pConvertInterfaceLuidToIndex = (void *)GetProcAddress(hLibrary, "ConvertInterfaceLuidToIndex");
pConvertInterfaceLuidToNameA = (void *)GetProcAddress(hLibrary, "ConvertInterfaceLuidToNameA");
pConvertInterfaceLuidToNameW = (void *)GetProcAddress(hLibrary, "ConvertInterfaceLuidToNameW");
pConvertInterfaceNameToLuidA = (void *)GetProcAddress(hLibrary, "ConvertInterfaceNameToLuidA");
pConvertInterfaceNameToLuidW = (void *)GetProcAddress(hLibrary, "ConvertInterfaceNameToLuidW");
}
}
@ -1627,6 +1643,184 @@ static void test_CreateSortedAddressPairs(void)
pFreeMibTable( pair );
}
static void test_interface_identifier_conversion(void)
{
DWORD ret, size;
NET_LUID luid;
GUID guid;
IP_ADAPTER_ADDRESSES *buf, *aa;
SIZE_T len;
WCHAR nameW[IF_MAX_STRING_SIZE + 1];
char nameA[IF_MAX_STRING_SIZE + 1];
NET_IFINDEX index;
if (!pConvertInterfaceIndexToLuid)
{
win_skip( "ConvertInterfaceIndexToLuid not available\n" );
return;
}
size = 0;
ret = pGetAdaptersAddresses( AF_UNSPEC, 0, NULL, NULL, &size );
if (ret != ERROR_BUFFER_OVERFLOW) return;
buf = HeapAlloc( GetProcessHeap(), 0, size );
pGetAdaptersAddresses( AF_UNSPEC, 0, NULL, buf, &size );
for (aa = buf; aa; aa = aa->Next) { if (aa->IfType == IF_TYPE_ETHERNET_CSMACD) break; }
if (aa->IfType != IF_TYPE_ETHERNET_CSMACD)
{
skip( "no suitable interface found\n" );
return;
}
/* ConvertInterfaceIndexToLuid */
ret = pConvertInterfaceIndexToLuid( 0, NULL );
ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
memset( &luid, 0xff, sizeof(luid) );
ret = pConvertInterfaceIndexToLuid( 0, &luid );
ok( ret == ERROR_FILE_NOT_FOUND, "got %u\n", ret );
ok( !luid.Info.Reserved, "got %x\n", luid.Info.Reserved );
ok( !luid.Info.NetLuidIndex, "got %u\n", luid.Info.NetLuidIndex );
ok( !luid.Info.IfType, "got %u\n", luid.Info.IfType );
memset( &luid, 0, sizeof(luid) );
ret = pConvertInterfaceIndexToLuid( aa->IfIndex, &luid );
ok( !ret, "got %u\n", ret );
ok( !luid.Info.Reserved, "got %x\n", luid.Info.Reserved );
ok( luid.Info.NetLuidIndex, "got %u\n", luid.Info.NetLuidIndex );
ok( luid.Info.IfType == IF_TYPE_ETHERNET_CSMACD, "got %u\n", luid.Info.IfType );
/* ConvertInterfaceLuidToIndex */
ret = pConvertInterfaceLuidToIndex( NULL, NULL );
ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
ret = pConvertInterfaceLuidToIndex( NULL, &index );
ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
ret = pConvertInterfaceLuidToIndex( &luid, NULL );
ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
ret = pConvertInterfaceLuidToIndex( &luid, &index );
ok( !ret, "got %u\n", ret );
/* ConvertInterfaceLuidToGuid */
ret = pConvertInterfaceLuidToGuid( NULL, NULL );
ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
memset( &guid, 0xff, sizeof(guid) );
ret = pConvertInterfaceLuidToGuid( NULL, &guid );
ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
ok( guid.Data1 == 0xffffffff, "got %x\n", guid.Data1 );
ret = pConvertInterfaceLuidToGuid( &luid, NULL );
ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
memset( &guid, 0, sizeof(guid) );
ret = pConvertInterfaceLuidToGuid( &luid, &guid );
ok( !ret, "got %u\n", ret );
ok( guid.Data1, "got %x\n", guid.Data1 );
/* ConvertInterfaceGuidToLuid */
ret = pConvertInterfaceGuidToLuid( NULL, NULL );
ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
luid.Info.NetLuidIndex = 1;
ret = pConvertInterfaceGuidToLuid( NULL, &luid );
ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
ok( luid.Info.NetLuidIndex == 1, "got %u\n", luid.Info.NetLuidIndex );
ret = pConvertInterfaceGuidToLuid( &guid, NULL );
ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
memset( &luid, 0, sizeof(luid) );
ret = pConvertInterfaceGuidToLuid( &guid, &luid );
ok( !ret, "got %u\n", ret );
ok( luid.Info.NetLuidIndex, "got %u\n", luid.Info.NetLuidIndex );
/* ConvertInterfaceLuidToNameW */
ret = pConvertInterfaceLuidToNameW( NULL, NULL, 0 );
ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
ret = pConvertInterfaceLuidToNameW( &luid, NULL, 0 );
ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
ret = pConvertInterfaceLuidToNameW( NULL, nameW, 0 );
ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
ret = pConvertInterfaceLuidToNameW( &luid, nameW, 0 );
ok( ret == ERROR_NOT_ENOUGH_MEMORY, "got %u\n", ret );
nameW[0] = 0;
len = sizeof(nameW)/sizeof(nameW[0]);
ret = pConvertInterfaceLuidToNameW( &luid, nameW, len );
ok( !ret, "got %u\n", ret );
ok( nameW[0], "name not set\n" );
/* ConvertInterfaceLuidToNameA */
ret = pConvertInterfaceLuidToNameA( NULL, NULL, 0 );
ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
ret = pConvertInterfaceLuidToNameA( &luid, NULL, 0 );
ok( ret == ERROR_NOT_ENOUGH_MEMORY, "got %u\n", ret );
ret = pConvertInterfaceLuidToNameA( NULL, nameA, 0 );
ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
ret = pConvertInterfaceLuidToNameA( &luid, nameA, 0 );
ok( ret == ERROR_NOT_ENOUGH_MEMORY, "got %u\n", ret );
nameA[0] = 0;
len = sizeof(nameA)/sizeof(nameA[0]);
ret = pConvertInterfaceLuidToNameA( &luid, nameA, len );
ok( !ret, "got %u\n", ret );
ok( nameA[0], "name not set\n" );
/* ConvertInterfaceNameToLuidW */
ret = pConvertInterfaceNameToLuidW( NULL, NULL );
ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
memset( &luid, 0xff, sizeof(luid) );
ret = pConvertInterfaceNameToLuidW( NULL, &luid );
ok( ret == ERROR_INVALID_NAME, "got %u\n", ret );
ok( !luid.Info.Reserved, "got %x\n", luid.Info.Reserved );
ok( !luid.Info.NetLuidIndex, "got %u\n", luid.Info.NetLuidIndex );
ok( !luid.Info.IfType, "got %u\n", luid.Info.IfType );
ret = pConvertInterfaceNameToLuidW( nameW, NULL );
ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
memset( &luid, 0xff, sizeof(luid) );
ret = pConvertInterfaceNameToLuidW( nameW, &luid );
ok( !ret, "got %u\n", ret );
ok( !luid.Info.Reserved, "got %x\n", luid.Info.Reserved );
ok( luid.Info.NetLuidIndex, "got %u\n", luid.Info.NetLuidIndex );
ok( luid.Info.IfType == IF_TYPE_ETHERNET_CSMACD, "got %u\n", luid.Info.IfType );
/* ConvertInterfaceNameToLuidA */
ret = pConvertInterfaceNameToLuidA( NULL, NULL );
ok( ret == ERROR_INVALID_NAME, "got %u\n", ret );
memset( &luid, 0xff, sizeof(luid) );
ret = pConvertInterfaceNameToLuidA( NULL, &luid );
ok( ret == ERROR_INVALID_NAME, "got %u\n", ret );
ok( luid.Info.Reserved, "got %x\n", luid.Info.Reserved );
ok( luid.Info.NetLuidIndex, "got %u\n", luid.Info.NetLuidIndex );
ok( luid.Info.IfType, "got %u\n", luid.Info.IfType );
ret = pConvertInterfaceNameToLuidA( nameA, NULL );
ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
memset( &luid, 0xff, sizeof(luid) );
ret = pConvertInterfaceNameToLuidA( nameA, &luid );
ok( !ret, "got %u\n", ret );
ok( !luid.Info.Reserved, "got %x\n", luid.Info.Reserved );
ok( luid.Info.NetLuidIndex, "got %u\n", luid.Info.NetLuidIndex );
ok( luid.Info.IfType == IF_TYPE_ETHERNET_CSMACD, "got %u\n", luid.Info.IfType );
HeapFree( GetProcessHeap(), 0, buf );
}
START_TEST(iphlpapi)
{
@ -1647,6 +1841,7 @@ START_TEST(iphlpapi)
test_GetExtendedTcpTable();
test_GetExtendedUdpTable();
test_CreateSortedAddressPairs();
test_interface_identifier_conversion();
freeIPHlpApi();
}
}

View File

@ -475,6 +475,7 @@ SRCDIR_INCLUDES = \
msxmldid.h \
nb30.h \
ndrtypes.h \
netioapi.h \
nldef.h \
npapi.h \
nspapi.h \

32
include/netioapi.h Normal file
View File

@ -0,0 +1,32 @@
/*
* Copyright 2015 Hans Leidekker for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef __WINE_NETIOAPI_H
#define __WINE_NETIOAPI_H
DWORD WINAPI ConvertInterfaceGuidToLuid(const GUID*,NET_LUID*);
DWORD WINAPI ConvertInterfaceIndexToLuid(NET_IFINDEX,NET_LUID*);
DWORD WINAPI ConvertInterfaceLuidToGuid(const NET_LUID*,GUID*);
DWORD WINAPI ConvertInterfaceLuidToIndex(const NET_LUID*,NET_IFINDEX*);
DWORD WINAPI ConvertInterfaceLuidToNameA(const NET_LUID*,char*,SIZE_T);
DWORD WINAPI ConvertInterfaceLuidToNameW(const NET_LUID*,WCHAR*,SIZE_T);
DWORD WINAPI ConvertInterfaceNameToLuidA(const char*,NET_LUID*);
DWORD WINAPI ConvertInterfaceNameToLuidW(const WCHAR*,NET_LUID*);
void WINAPI FreeMibTable(void*);
#endif /* __WINE_NETIOAPI_H */