See the question and my original answer on StackOverflow

You can use the Network Configuration Interfaces API, like this:

#include <windows.h>
#include <stdio.h>
#include <Netcfgx.h>
#include <devguid.h>

int main()
{
  INetCfg* cfg = nullptr;
  IEnumNetCfgComponent* components = nullptr;

  // TOTO: HRESULT checks omitted to be added
  auto hr = CoInitialize(nullptr);
  hr = CoCreateInstance(CLSID_CNetCfg, nullptr, CLSCTX_ALL, IID_PPV_ARGS(&cfg));
  hr = cfg->Initialize(nullptr);
  hr = cfg->EnumComponents(&GUID_DEVCLASS_NET, &components);
  do
  {
    INetCfgComponent* component = nullptr;
    hr = components->Next(1, &component, nullptr);
    if (FAILED(hr) || !component)
      break;

    DWORD characteristics = 0;
    component->GetCharacteristics(&characteristics);
    if ((characteristics & NCF_PHYSICAL) == NCF_PHYSICAL)
    {
      LPWSTR name = nullptr;
      component->GetDisplayName(&name);
      wprintf(L"%s 0x%08X\n", name, characteristics);
      if (name)
      {
        CoTaskMemFree(name);
      }
    }
    
    component->Release();

  } while (true);

  hr = cfg->Uninitialize();
  components->Release();
  cfg->Release();

  CoUninitialize();
  return 0;
}

Or you can use WMI with Win32_NetworkAdapter class as it has a boolean PhysicalAdapter property.

Or you can use WinRT and query for NetworkAdapter.IanaInterfaceType Property, like this in C#:

foreach (var profile in Windows.Networking.Connectivity.NetworkInformation.GetConnectionProfiles())
{
    Console.WriteLine(profile.ProfileName + " type:" + profile.NetworkAdapter.IanaInterfaceType);
}