使用msft_netadapter获取网络适配器的速度和IP

时间:2016-11-21 04:06:38

标签: c++ wmi wmi-query

我正在尝试获取与每个网络适配器关联的速度和IP地址。我曾经Win32_NetworkAdapterWin32_NetworkAdapterConfiguration,但根据MDSN,这个类已被弃用,并且已经实现了msft_netadapter。当我尝试使用这个类时,我在以下语句中得到0

  

HRESULT hr = pEnumerator-> Next(WBEM_INFINITE,1,                   & pclsObj,& uReturn);

以下是供您参考的代码:

HRESULT hres;

VARIANT activeAdapterGuid;
activeAdapterGuid.bstrVal = _T("");
bool COMIsLoaded = false;

// Step 1: --------------------------------------------------
// Initialize COM. ------------------------------------------

HRESULT hr = CoInitialize(NULL);
if (FAILED(hr))

{
    if (hr != RPC_E_CHANGED_MODE)
    {
        Utility::PrintFormatMessage(DebugMessageLevel::DBG_MSG_ERROR, GetLastError(), L"Failed to Initilize COM for getting the adapter information - WMI");
    }
}
else
{
    COMIsLoaded = true;
}
if (!COMIsLoaded)
{
    hres = CoInitializeEx(0, COINIT_MULTITHREADED);
    if (FAILED(hres))
    {
        return 1;                  // Program has failed.
    }

    // Step 2: --------------------------------------------------
    // Set general COM security levels --------------------------

    hres = CoInitializeSecurity(
        NULL,
        -1,                          // COM authentication
        NULL,                        // Authentication services
        NULL,                        // Reserved
        RPC_C_AUTHN_LEVEL_DEFAULT,   // Default authentication 
        RPC_C_IMP_LEVEL_IMPERSONATE, // Default Impersonation  
        NULL,                        // Authentication info
        EOAC_NONE,                   // Additional capabilities 
        NULL                         // Reserved
    );
    if (FAILED(hres))
    {
        CoUninitialize();
        return 1;                    // Program has failed.
    }
}

// Step 3: ---------------------------------------------------
// Obtain the initial locator to WMI -------------------------

IWbemLocator *pLoc = NULL;

hres = CoCreateInstance(
    CLSID_WbemLocator,
    0,
    CLSCTX_INPROC_SERVER,
    IID_IWbemLocator, (LPVOID *)&pLoc);

if (FAILED(hres))
{
    CoUninitialize();
    return 1;                 // Program has failed.
}

// Step 4: -----------------------------------------------------
// Connect to WMI through the IWbemLocator::ConnectServer method

IWbemServices *pSvc = NULL;

// Connect to the root\cimv2 namespace with
// the current user and obtain pointer pSvc
// to make IWbemServices calls.
hres = pLoc->ConnectServer(
    _bstr_t(L"ROOT\\CIMV2"), // Object path of WMI namespace
    NULL,                    // User name. NULL = current user
    NULL,                    // User password. NULL = current
    0,                       // Locale. NULL indicates current
    NULL,                    // Security flags.
    0,                       // Authority (for example, Kerberos)
    0,                       // Context object 
    &pSvc                    // pointer to IWbemServices proxy
);

if (FAILED(hres))
{
    pLoc->Release();
    CoUninitialize();
    return 1;                // Program has failed.
}

// Step 5: --------------------------------------------------
// Set security levels on the proxy -------------------------

hres = CoSetProxyBlanket(
    pSvc,                        // Indicates the proxy to set
    RPC_C_AUTHN_WINNT,           // RPC_C_AUTHN_xxx
    RPC_C_AUTHZ_NONE,            // RPC_C_AUTHZ_xxx
    NULL,                        // Server principal name 
    RPC_C_AUTHN_LEVEL_CALL,      // RPC_C_AUTHN_LEVEL_xxx 
    RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx
    NULL,                        // client identity
    EOAC_NONE                    // proxy capabilities 
);

if (FAILED(hres))
{
    pSvc->Release();
    pLoc->Release();
    CoUninitialize();
    return 1;               // Program has failed.
}

// Step 6: --------------------------------------------------
// Use the IWbemServices pointer to make requests of WMI ----

// For example, get the name of the operating system
IEnumWbemClassObject* pEnumerator = NULL;
hres = pSvc->ExecQuery(
    bstr_t("WQL"),
    bstr_t("SELECT * FROM Win32_NetworkAdapter"),
    WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
    NULL,
    &pEnumerator);

if (FAILED(hres))
{
    pSvc->Release();
    pLoc->Release();
    CoUninitialize();
    return 1;               // Program has failed.
}

// Step 7: -------------------------------------------------
// Get the data from the query in step 6 -------------------

IWbemClassObject *pclsObj = NULL;
ULONG uReturn = 0;

while (pEnumerator)
{

    NetworkAdapterDefinition networkAdapterDefinition;

    HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1,
        &pclsObj, &uReturn);

    if (0 == uReturn)
    {
        break;
    }

    VARIANT vtProp;

    hr = pclsObj->Get(L"Name", 0, &vtProp, 0, 0);
    if (vtProp.bstrVal != NULL)
    {
        networkAdapterDefinition.m_strName =vtProp.bstrVal;
    }
    else
    {
        continue;
    }

    VariantClear(&vtProp);
    VariantChangeType(&vtProp, &vtProp, 0, VT_BSTR);
    hr = pclsObj->Get(L"Speed", 0, &vtProp, 0, 0);
    if (vtProp.bstrVal != NULL)
    {
        networkAdapterDefinition.m_speed = _wtoi(vtProp.bstrVal);
    }
    else
    {
        continue;
    }
    VariantClear(&vtProp);
    VARIANT vtPropConnection;
    VariantChangeType(&vtPropConnection, &vtPropConnection, 0, VT_UI2);
    hr = pclsObj->Get(L"NetConnectionStatus", 0, &vtPropConnection, 0, 0);
    if (vtPropConnection.uiVal != NULL)
    {
        VARIANT vtProp1;
        hr = pclsObj->Get(L"GUID", 0, &vtProp1, 0, 0);
        activeAdapterGuid.bstrVal = vtProp1.bstrVal;
    }
    else
    {
        continue;
    }

    IEnumWbemClassObject* pEnumerator = NULL;
    hres = pSvc->ExecQuery(
        bstr_t("WQL"),
        bstr_t("SELECT * FROM Win32_NetworkAdapterConfiguration"),
        WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
        NULL,
        &pEnumerator);

    if (FAILED(hres))
    {
        pSvc->Release();
        pLoc->Release();
        CoUninitialize();
        return 1;               // Program has failed.
    }

    // Step 7: -------------------------------------------------
    // Get the data from the query in step 6 -------------------

    IWbemClassObject *pclsObj = NULL;
    ULONG uReturn = 0;

    while (pEnumerator)
    {
        HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1,
            &pclsObj, &uReturn);

        if (0 == uReturn)
        {
            break;
        }

        VariantClear(&vtProp);
        VARIANT vtPropConfig;

        hr = pclsObj->Get(L"SettingID", 0, &vtPropConfig, 0, 0);
        if (vtPropConfig.bstrVal != NULL)
        {
            //wcout << " Guid of the Adapter: " << vtPropConfig.bstrVal << endl;
            if (wcscmp(vtPropConfig.bstrVal, activeAdapterGuid.bstrVal) == 0)
            {
                BSTR *pbstr = NULL;
                _variant_t ipAddress;
                hres = pclsObj->Get(L"IPAddress", 0, &ipAddress, NULL, NULL);
                if (ipAddress.parray == NULL)
                {
                    continue;
                }
                LONG lstart, lend;
                LONG idx = -1;
                HRESULT hr;
                SAFEARRAY *sa = V_ARRAY(&ipAddress);

                // Get the lower and upper bound
                hr = SafeArrayGetLBound(sa, 1, &lstart);
                if (FAILED(hr)) return hr;
                hr = SafeArrayGetUBound(sa, 1, &lend);
                if (FAILED(hr)) return hr;

                // loop
                hr = SafeArrayAccessData(sa, (void HUGEP**)&pbstr);
                if (SUCCEEDED(hr))
                {
                    for (idx = lstart; idx < lend; idx++)
                    {
                        BSTR bstrIpAddress;
                        bstrIpAddress = pbstr[idx];
                        std::string ipAddress = _bstr_t(bstrIpAddress, false);
                        networkAdapterDefinition.m_ipAddressList.push_back(ipAddress);
                    }
                    std::string adapterGUID = _bstr_t(activeAdapterGuid.bstrVal, false);
                    m_AdapterDefinition[adapterGUID] = networkAdapterDefinition;

                    hr = SafeArrayUnaccessData(sa);
                    if (FAILED(hr)) return hr;
                }
            }
        }
    }
}


// Cleanup
// ========
pSvc->Release();
pLoc->Release();
pEnumerator->Release();
CoUninitialize();
return S_OK;

1 个答案:

答案 0 :(得分:0)

看看这里: Using WMI in C++ to obtain the InterfaceIndex of an adapter

他们说RPC_C_IMP_LEVEL_IMPERSONATE

更改RPC_C_IMP_LEVEL_DELEGATE