WMIについて質問です。

C++で開発しているのですが、MSNdis_80211_WLanBssIdクラスを用いてNdis80211SsIdとNdis80211Rssiの値を取得することができません。
どなたか、アドバイスをお願いします。
以下、ソースです。
// 接続開始
wbem_locator->ConnectServer(_bstr_t(L"\\\\.\\ROOT\\WMI"),NULL, NULL, 0, NULL,0, 0, &wbem_services);
wbem_services->ExecQuery(bstr_t("WQL"),bstr_t("SELECT * FROM MSNdis_80211_WLanBssId"),WBEM_FLAG_RETURN_IMMEDIATELY |WBEM_FLAG_FORWARD_ONLY , NULL, &wbem_enumerator);
IWbemClassObject *wbem_object;
ULONG returned = 0;

// プロパティ読み込み
while(wbem_enumerator) {
wbem_enumerator->Next(WBEM_INFINITE, 1,&wbem_object, &returned);
if(0 == returned)
break;
_bstr_t property_name[] = {L"Ndis80211SsId", L"Ndis80211Rssi"};
for(int item = 0; item < 1; item++) {
VARIANT property_value;
_bstr_t display_name;
VariantInit(&property_value);
wbem_object->Get(property_name[item], 0,&property_value, 0, 0);
display_name = property_value;
cout << property_name[item] <<" : " << display_name << endl;
VariantClear(&property_value);
}
}

回答の条件
  • 1人2回まで
  • 登録:
  • 終了:2008/05/14 16:25:02
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

回答2件)

id:mj99 No.1

回答回数138ベストアンサー獲得回数38

ポイント35pt

解決まで到達できませんでしたが、とりあえずわかったことだけ書いておきます。


----

cx20さんのコメントにあるwbemtest.exeで探ってみました。

使用するクエリーは

SELECT * FROM MSNDis_80211_BSSIList

で、NICの個数分、MSNDis_80211_BSSIList型のオブジェクトが取得できます。

その個々に対して、

wbem_object->Get(L"Ndis80211BSSIList", 0, &property_value, 0, 0);

とすると、property_value.vtが0x200D(VT_IUNKNOWN|VT_ARRAY)であることが分かります。

つまり、配列(Ndis80211BSSIList)の個々がMSNdis_80211_WLanBssId型であることまではわかりました。

ただ、

VT_IUNKNOWN|VT_ARRAYを配列分解して、QueryInterfaceでIUNKNOWNからMSNdis_80211_WLanBssIdのインターフェースを得て、

なおかつ、Ndis80211SsIdはVT_BYTE|VT_ARRAYであるので、また配列分解して、文字列にして、、、

と、まだまだ先は長そうです。

id:mj99 No.2

回答回数138ベストアンサー獲得回数38

ポイント35pt

とりあえず動く。とにかく長い、、

VBScriptなら20Step程度でかけそうだ。

// C ランタイム ヘッダー
#include <stdio.h>
#include <tchar.h>

// Windowsヘッダー
#define WIN32_LEAN_AND_MEAN
#include <windows.h>

// DCOM ヘッダー
#define _WIN32_DCOM
#include <comutil.h>
#pragma comment(lib, "comsupp.lib")
#include <wbemidl.h>
#pragma comment(lib, "wbemuuid.lib")

/*********************************************************************
 * MSNdis_80211_WLanBssIdオブジェクト処理
 ********************************************************************/
int proc_object2(IWbemClassObject* pClassObject)
{
    /*------------------------------------------------------------------*
     * MSNdis_80211_WLanBssId::Ndis80211SsIdLength取得
     *------------------------------------------------------------------*/
    VARIANT v;
    BSTR strClassProp = SysAllocString(L"Ndis80211SsIdLength");
    HRESULT hr = pClassObject->Get(strClassProp, 0, &v, 0, 0);
    SysFreeString(strClassProp);
        
    if(FAILED(hr))
    {
        printf("!!!! Error !!!! pClassObject->Get(Ndis80211SsIdLength)\n");
        return 1;
    }
        
    /*------------------------------------------------------------------*
     * MSNdis_80211_WLanBssId::Ndis80211SsIdLengthはLONGか?
     *------------------------------------------------------------------*/
    if(V_VT(&v) != (VT_I4)) {
        printf("!!!! Error !!!! VARTYPE=%d\n", V_VT(&v));
        return 1;
    }
    
    /*------------------------------------------------------------------*
     * MSNdis_80211_WLanBssId::Ndis80211SsIdLengthは1~32になるはず
     *------------------------------------------------------------------*/
    LONG ssidLen = v.lVal;
    if(v.lVal < 1 || v.lVal > 32) {
        printf("!!!! Error !!!! Ndis80211SsIdLength=%d\n", v.lVal);
        return 0;
    }
    
    printf("\tNdis80211SsIdLength=%d\n", v.lVal);
    
    VariantClear(&v);
        
    /*------------------------------------------------------------------*
     * MSNdis_80211_WLanBssId::Ndis80211SsId取得
     *------------------------------------------------------------------*/
    strClassProp = SysAllocString(L"Ndis80211SsId");
    hr = pClassObject->Get(strClassProp, 0, &v, 0, 0);
    SysFreeString(strClassProp);

    if(FAILED(hr))
    {
        printf("!!!! Error !!!! pClassObject->Get(Ndis80211SsId)\n");
        return 1;
    }
        
    /*------------------------------------------------------------------*
     * MSNdis_80211_WLanBssId::Ndis80211SsIdはバイト配列か?
     *------------------------------------------------------------------*/
    if(V_VT(&v) != (VT_ARRAY|VT_UI1)) {
        printf("!!!! Error !!!! VARTYPE=%d\n", V_VT(&v));
        return 1;
    }
        
    /*------------------------------------------------------------------*
     * 配列分解処理を初期化
     *------------------------------------------------------------------*/
    SAFEARRAY* psa = V_ARRAY(&v);
    if(!SafeArrayGetDim(psa))
    {
        printf("!!!! Error !!!! SafeArrayGetDim\n");
        return 1;
    }
    
    /*------------------------------------------------------------------*
     * 一元配列か?
     *------------------------------------------------------------------*/
    if (psa->cDims != 1)
    {
        printf("!!!! Error !!!! psa->cDims=%d\n", psa->cDims);
        return 1;
    }

    /*------------------------------------------------------------------*
     * 配列のインデックス下限
     *------------------------------------------------------------------*/
    LONG lLBound;
    hr = SafeArrayGetLBound(psa, 1, &lLBound);
    if (FAILED(hr))
    {
        printf("!!!! Error !!!! SafeArrayGetLBound\n");
        return 1;
    }
    
    /*------------------------------------------------------------------*
     * 配列のインデックス上限
     *------------------------------------------------------------------*/
    LONG lUBound;
    hr = SafeArrayGetUBound(psa, 1, &lUBound);
    if (FAILED(hr))
    {
        printf("!!!! Error !!!! SafeArrayGetUBound\n");
        return 1;
    }
    
    byte b[32];
    memset(b, NULL, 32);

    int i;    
    LONG lIndex[1];
    for(lIndex[0] = lLBound, i = 0; lIndex[0] <= lUBound; lIndex[0]++, i++) {
    
        /*------------------------------------------------------------------*
         * 配列の要素(BYTE)を取得
         *------------------------------------------------------------------*/
        BYTE pb = NULL;
        hr = SafeArrayGetElement(psa, lIndex, &b[i]);
        if (FAILED(hr)) {
            printf("!!!! Error !!!! SafeArrayGetElement\n");
            return 1;
        }
    }
    
    printf("\tNdis80211SsId=%s\n", b);
    
    VariantClear(&v);
    
    /*------------------------------------------------------------------*
     * MSNdis_80211_WLanBssId::Ndis80211Rssi取得
     *------------------------------------------------------------------*/
    strClassProp = SysAllocString(L"Ndis80211Rssi");
    hr = pClassObject->Get(strClassProp, 0, &v, 0, 0);
    SysFreeString(strClassProp);

    if(FAILED(hr))
    {
        printf("!!!! Error !!!! pClassObject->Get(Ndis80211Rssi)\n");
        return 1;
    }
        
    /*------------------------------------------------------------------*
     * MSNdis_80211_WLanBssId::Ndis80211RssiはLONGか?
     *------------------------------------------------------------------*/
    if(V_VT(&v) != (VT_I4)) {
        printf("!!!! Error !!!! VARTYPE=%d\n", V_VT(&v));
        return 1;
    }
    
    printf("\tNdis80211Rssi=%d\n", v.lVal);
    
    /*------------------------------------------------------------------*
     * MSNdis_80211_WLanBssId::Ndis80211Rssi判定
     *------------------------------------------------------------------*/
    _TCHAR* msg = NULL;
    if (v.lVal >= 0) msg = "Error";
    else if(v.lVal >= -60) msg = "Excellent";
    else if(v.lVal >= -70) msg = "Very Good";
    else if(v.lVal >= -80) msg = "Good";
    else if(v.lVal >= -90) msg = "Low";
    else if(v.lVal >= -100) msg = "Very Low";
    else msg = "No Signal";
    
    printf("\tNdis80211RssiMessage=%s\n", msg);
    
    VariantClear(&v);
    
    return 0;    
}

/*********************************************************************
 * MSNDis_80211_BSSIListオブジェクト処理
 ********************************************************************/
int proc_object(IWbemClassObject* pClassObject)
{
    /*------------------------------------------------------------------*
     * MSNDis_80211_BSSIList::InstanceName取得(NIC名)
     *------------------------------------------------------------------*/
    VARIANT v;
    BSTR strClassProp = SysAllocString(L"InstanceName");
    HRESULT hr = pClassObject->Get(strClassProp, 0, &v, 0, 0);
    SysFreeString(strClassProp);

    if(FAILED(hr))
    {
        printf("!!!! Error !!!! pClassObject->Get(InstanceName)\n");
        return 1;
    }
    
    printf("InstanceName=%s\n", (_TCHAR*)(_bstr_t)&v);
    VariantClear(&v);

    /*------------------------------------------------------------------*
     * MSNDis_80211_BSSIList::Ndis80211BSSIList取得
     *------------------------------------------------------------------*/
    strClassProp = SysAllocString(L"Ndis80211BSSIList");
    hr = pClassObject->Get(strClassProp, 0, &v, 0, 0);
    SysFreeString(strClassProp);

    if(FAILED(hr))
    {
        printf("!!!! Error !!!! pClassObject->Get(Ndis80211BSSIList)\n");
        return 1;
    }

    /*------------------------------------------------------------------*
     * MSNDis_80211_BSSIList::Ndis80211BSSIListはオブジェクトの配列か?
     *------------------------------------------------------------------*/
    if(V_VT(&v) != (VT_ARRAY|VT_UNKNOWN)) {
        printf("!!!! Error !!!! VARTYPE=%d\n", V_VT(&v));
        return 1;
    }

    /*------------------------------------------------------------------*
     * 配列分解処理を初期化
     *------------------------------------------------------------------*/
    SAFEARRAY* psa = V_ARRAY(&v);
    if(!SafeArrayGetDim(psa))
    {
        printf("!!!! Error !!!! SafeArrayGetDim\n");
        return 1;
    }
    
    /*------------------------------------------------------------------*
     * 一元配列か?
     *------------------------------------------------------------------*/
    if (psa->cDims != 1)
    {
        printf("!!!! Error !!!! psa->cDims=%d\n", psa->cDims);
        return 1;
    }

    /*------------------------------------------------------------------*
     * 配列のインデックス下限
     *------------------------------------------------------------------*/
    LONG lLBound;
    hr = SafeArrayGetLBound(psa, 1, &lLBound);
    if (FAILED(hr))
    {
        printf("!!!! Error !!!! SafeArrayGetLBound\n");
        return 1;
    }
    
    /*------------------------------------------------------------------*
     * 配列のインデックス上限
     *------------------------------------------------------------------*/
    LONG lUBound;
    hr = SafeArrayGetUBound(psa, 1, &lUBound);
    if (FAILED(hr))
    {
        printf("!!!! Error !!!! SafeArrayGetUBound\n");
        return 1;
    }
    
    /*------------------------------------------------------------------*
     * 配列の要素数(MSNdis_80211_WLanBssIdオブジェクトの個数)
     *------------------------------------------------------------------*/
    printf("Ndis80211BSSIList Count=%d\n----------\n", lUBound-lLBound + 1);
    
    LONG lIndex[1];
    for(lIndex[0] = lLBound; lIndex[0] <= lUBound; lIndex[0]++) {
    
        /*------------------------------------------------------------------*
        * 配列の要素インデックス
        *------------------------------------------------------------------*/
        printf("Ndis80211BSSIList(%d)\n", lIndex[0]);
        
        /*------------------------------------------------------------------*
         * 配列の要素(MSNdis_80211_WLanBssId)を取得
         *------------------------------------------------------------------*/
        IWbemClassObject* pClassObject2 = NULL;
        hr = SafeArrayGetElement(psa, lIndex, &pClassObject2);
        if (FAILED(hr)) {
            printf("!!!! Error !!!! SafeArrayGetElement\n");
            return 1;
        }
        
        /*------------------------------------------------------------------*
         * MSNdis_80211_WLanBssIdオブジェクト処理
         *------------------------------------------------------------------*/
        if(proc_object2(pClassObject2) != 0) {
            return 1;
        }
        
        /*------------------------------------------------------------------*
         * MSNdis_80211_WLanBssIdオブジェクト開放
         *------------------------------------------------------------------*/
        pClassObject2->Release();
        
        printf("----------\n");

    }
    
    VariantClear(&v);
    
    return 0;    
}

/*********************************************************************
 * WMIクエリ結果列挙
 ********************************************************************/
int proc_enum(IEnumWbemClassObject* pEnumObject)
{
    /*------------------------------------------------------------------*
     * WMIクエリ結果列挙
     *------------------------------------------------------------------*/
    HRESULT hr = pEnumObject->Reset();
    while(true) {
    
        /*------------------------------------------------------------------*
         * MSNDis_80211_BSSIListオブジェクト取得(クエリ結果)
         *------------------------------------------------------------------*/
        ULONG uCount = 1, uReturned;
        IWbemClassObject* pClassObject = NULL;
        hr = pEnumObject->Next(WBEM_INFINITE, uCount, &pClassObject, &uReturned);

        if(FAILED(hr))
        {
            printf("!!!! Error !!!! pEnumObject->Next\n");
            return 1;
        }
        
        /*------------------------------------------------------------------*
         * クエリ結果終了?
         *------------------------------------------------------------------*/
        if(uReturned == 0)
            break;

        /*------------------------------------------------------------------*
         * MSNDis_80211_BSSIListオブジェクト処理
         *------------------------------------------------------------------*/
        if(proc_object(pClassObject) != 0) {
            return 1;
        }
        
        /*------------------------------------------------------------------*
         * MSNDis_80211_BSSIListオブジェクト開放
         *------------------------------------------------------------------*/
        pClassObject->Release();
    }

    return 0;    
}

/*********************************************************************
 * クエリ処理
 ********************************************************************/
int proc_query(IWbemServices* pWbemServices)
{
    /*------------------------------------------------------------------*
     * WMIクエリ発行
     *------------------------------------------------------------------*/
    IEnumWbemClassObject* pEnumObject = NULL;
    HRESULT hr = pWbemServices->ExecQuery(
        L"WQL",
        L"SELECT * FROM MSNDis_80211_BSSIList",
        WBEM_FLAG_RETURN_IMMEDIATELY,
        NULL,
        &pEnumObject
    );
    
    /*------------------------------------------------------------------*
     * WMIクエリ結果列挙
     *------------------------------------------------------------------*/
    if(proc_enum(pEnumObject) != 0) {
        return 1;
    }
    
    /*------------------------------------------------------------------*
     * WMIクエリ結果開放
     *------------------------------------------------------------------*/
    pEnumObject->Release();
    
    return 0;
}

/*********************************************************************
 * WMI処理
 ********************************************************************/
int proc_wmi(IWbemLocator* pIWbemLocator)
{
    /*------------------------------------------------------------------*
     * WMI初期化
     *------------------------------------------------------------------*/
    IWbemServices* pWbemServices = NULL;
    HRESULT hr = pIWbemLocator->ConnectServer(
        L"root\\wmi",
        NULL,
        NULL,
        NULL,
        0,
        NULL,
        NULL,
        &pWbemServices
    );
    
    if(FAILED(hr))
    {
        printf("!!!! Error !!!! pIWbemLocator->ConnectServer\n");
        return 1;
    }
    
    /*------------------------------------------------------------------*
     * クエリ処理
     *------------------------------------------------------------------*/
    if(proc_query(pWbemServices) != 0) {
        return 1;
    }

    /*------------------------------------------------------------------*
     * WMI開放
     *------------------------------------------------------------------*/
    pWbemServices->Release();
    
    return 0;
}

/*********************************************************************
 * COM処理
 ********************************************************************/
int proc_com()
{
    /*------------------------------------------------------------------*
     * COM取得
     *------------------------------------------------------------------*/
    IWbemLocator* pIWbemLocator = NULL;
    HRESULT hr = CoCreateInstance(
        CLSID_WbemAdministrativeLocator,
        NULL,
        CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER,
        IID_IUnknown,
        (void**)&pIWbemLocator
    );
    
    if(FAILED(hr))
    {
        printf("!!!! Error !!!! CoCreateInstance\n");
        return 1;
    }
    
    /*------------------------------------------------------------------*
     * WMI処理
     *------------------------------------------------------------------*/
    if(proc_wmi(pIWbemLocator) != 0) {
        return 1;
    }

    /*------------------------------------------------------------------*
     * COM開放
     *------------------------------------------------------------------*/
    pIWbemLocator->Release();
    
	return 0;
}

/*********************************************************************
 * メイン
 ********************************************************************/
int _tmain(int argc, _TCHAR* argv[])
{
    /*------------------------------------------------------------------*
     * COM初期化
     *------------------------------------------------------------------*/
    HRESULT hr = CoInitializeEx(0, COINIT_MULTITHREADED); 

    if (FAILED(hr)) 
    { 
        printf("!!!! Error !!!! CoInitializeEx\n");
        return 1;
    }

    /*------------------------------------------------------------------*
     * COMアクセス定義
     *------------------------------------------------------------------*/
    hr = CoInitializeSecurity(
        NULL,
        -1,
        NULL,
        NULL,
        RPC_C_AUTHN_LEVEL_DEFAULT,
        RPC_C_IMP_LEVEL_IMPERSONATE,
        NULL,
        EOAC_NONE,
        NULL
    );

    if (FAILED(hr))
    {
        printf("!!!! Error !!!! CoInitializeSecurity\n");
        return 1;
    }
    
    /*------------------------------------------------------------------*
     * COM処理
     *------------------------------------------------------------------*/
    if(proc_com() != 0) {
        return 1;
    }
    
    /*------------------------------------------------------------------*
     * COM開放
     *------------------------------------------------------------------*/
    CoUninitialize();
    
    return 0;
}
  • id:cx20
    回答では無いですが・・・

    値の取得ができないというのは VBScript 等では取得できるが、C++ では取得できないということでしょうか?
    VBScript 等でも取得できないということであれば、そもそも値がセットされていない(オブジェクトがNULL)ということになります。

    WMI の情報を取得する方法は色々あるかと思いますが、
    OS 標準の「WMI Tester (wbemtest.exe)」というツールで確認できますので、
    試してみてはいかがでしょうか?

    <参考情報>
    ■ サンプルプログラム集 WMIイントロダクション
    http://homepage2.nifty.com/Mr_XRAY/Delphi/plSamples/A_WMI_Introduction.htm

    すでに確認済みでしたら、すみません。

この質問への反応(ブックマークコメント)

トラックバック

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません