I'm currently trying to write an application to create "configuration profiles" for the network adapters, things like a profile with different dns and local ip address, gateway, etc.
I need the InterfaceLUID to use the WinApi calls I need to make those changes. So I'm using the GetIfTable2 provided by the CsWin32 library. I'm currently troubled by the fact that it returns 41 entries, and all of them seem to be "corrupted", i.e, empty aliases, aliases with unicode characters, japanese characters, fields with nonsense values, etc.
I also tried compiling in both x64 and x86. Both give the same nonsense results.
Trying this iteration of all the ones I tried until now. This is the first one that doesn't cause a System.ExecutionEngineException
or memory error:
public static MIB_IF_ROW2[] GetInterfaces()
{
MIB_IF_TABLE2 table;
List<MIB_IF_ROW2> rows = new();
unsafe
{
PInvoke.GetIfTable2(out MIB_IF_TABLE2* __pTable);
table = *__pTable;
MIB_IF_TABLE2* pTable = (MIB_IF_TABLE2*)Marshal.AllocCoTaskMem((int)(sizeof(MIB_IF_ROW2) * table.NumEntries));
for (int i = 0; i < table.NumEntries; i++)
{
MIB_IF_ROW2 row = pTable[i].Table._0;
rows.Add(row);
Debug.WriteLine(row.Alias);
}
}
return rows.Where(r => r.Type != 0).ToArray();
}
public static void Main(string[] args)
{
MIB_IF_ROW2[] interfaces = Dhcp.GetInterfaces();
foreach (var if_ in interfaces)
{
Debug.WriteLine("Alias: {0}", if_.Alias);
Debug.WriteLine("Luid: {0}", if_.InterfaceLuid.Value);
Debug.WriteLine(null);
}
}
I know I'm not freeing the CoTask memory. This should be just a working snippet until I make a disposable class out of it.
Example of a return:
Alias: -WFP Native MAC Layer LightWeight Filter-0000
Luid: 7163378107183810688
Alias:
Luid: 0
Alias:
Luid: 0
Alias:
Luid: 0
Alias:
Luid: 13511005043490930
I am dropping the ones with Type
0 because its not a valid value by GetIfTable2's documentation. This sometimes makes the entire method returns an empty array, sometimes 4 rows, etc. By the control panel, I have 4 Ethernet adapters, 3 of which are virtual adapters of proxies and vpns I have, and none of them has the single valid name I get of the rows "-WFP Native MAC Layer LightWeight Filter-0000".
So, should this call really be returning 41 entries? Why are those rows returning with those non-sense values and aliases?
*Currently using .NET 7 and CsWin32 0.3.49-beta.
I've tested the code generator you mentioned, CsWin32.
It turns out the MIB_IF_TABLE2.Table
is just an intermediate helper structure that implements some (not so helpful, IMO) methods.
The MIB_IF_TABLE2.Table._0
member is the required MIB_IF_ROW2 struct.
You can just use its address, and __pTable->NumEntries
for the loop.
I've added a call to FreeMibTable(), to release the buffers allocated by GetIfTable2() (1):
using Windows.Win32;
using Windows.Win32.Foundation;
using Windows.Win32.NetworkManagement.IpHelper;
public static IEnumerable<MIB_IF_ROW2> GetInterfaces() {
List<MIB_IF_ROW2> rows = new();
unsafe {
var err = PInvoke.GetIfTable2(out MIB_IF_TABLE2* __pTable);
if (err != WIN32_ERROR.NO_ERROR) return Enumerable.Empty<MIB_IF_ROW2>();
MIB_IF_ROW2* buffer = &__pTable->Table._0;
for (int i = 0; i < __pTable->NumEntries; i++) {
rows.Add(buffer[i]);
}
PInvoke.FreeMibTable(__pTable);
}
return rows;
}
(1) Add a try / finally block when you're done