Windows Management Instrumentation (3)

前回作ったWmiResultクラスを整理してみました。
何となくさまになったかな・・・。

wmi.hのWmiResult定義を

typedef vector<long>            long_vector;
typedef vector<double>          double_vector;
typedef vector<bool>            bool_vector;
typedef vector<String>          string_vector;

typedef map<String, size_t>         property_set;
typedef property_set::iterator      psIter;
typedef property_set::const_iterator    pscIter;
typedef map<size_t, VARIANT>        result_row;
typedef result_row::iterator        rrIter;
typedef result_row::const_iterator  rrcIter;
typedef map<size_t, result_row>     result_set;
typedef result_set::iterator        rsIter;
typedef result_set::const_iterator  rscIter;

class WmiResult {
public:
    WmiResult();
    WmiResult(const WmiResult& from);
    ~WmiResult();

    HRESULT         loadProperties(IEnumWbemClassObject *pObjects);
    HRESULT         loadValues(IEnumWbemClassObject *pObjects);
    size_t          items();
    size_t          size();

    string_vector   getProperties();
    String          getProperty(size_t pos);
    result_set      getResult();

    VARIANT         *getValue(String prop, size_t row);
    VARTYPE         getValueType(String prop, size_t row);
    bool            isArray(String prop, size_t row);

    long            getLong(String prop, size_t row = 0, long deflong = 0);
    long_vector     getLongArray(String prop, size_t row = 0, long deflong = 0);
    double          getDouble(String prop, size_t row = 0, double defdouble = 0);
    double_vector   getDoubleArray(String prop, size_t row = 0, double defdouble = 0);
    bool            getBool(String prop, size_t row = 0, bool defbool = false);
    bool_vector     getBoolArray(String prop, size_t row = 0, bool defbool = false);
    String          getString(String prop, size_t row = 0);
    string_vector   getStringArray(String prop, size_t row = 0);

    String          print();

    static VARTYPE          getType(VARIANT *value); 
    static bool             isArray(VARIANT *value);
    static bool             isByRef(VARIANT *value);
    static long             getLong(VARIANT *value, long deflong = 0);
    static long_vector      getLongArray(VARIANT *value, long deflong = 0);
    static double           getDouble(VARIANT *value, double defdouble = 0);
    static double_vector    getDoubleArray(VARIANT *value, double defdouble = 0);
    static bool             getBool(VARIANT *value, bool defbool = false);
    static bool_vector      getBoolArray(VARIANT *value, bool defbool = false);
    static String           getString(VARIANT *value);
    static string_vector    getStringArray(VARIANT *value);

private:
    size_t          rows;
    size_t          cols;
    property_set    properties;
    result_set      results;
};

に、
wmi.cppのWmiResultクラスの本体を

//  Constructor
WmiResult::WmiResult() {
    cols = 0;
    rows = 0;
}

//  Copy Constructor
/*
 *  デフォルトのCopy Constructorでは、VARIANTのSAFEARRAYタイプのデータを
 *  正しくコピー出来ない為に作成
 */
WmiResult::WmiResult(const WmiResult& from) {
    cols = from.cols;
    rows = from.rows;
    for (pscIter keys = from.properties.begin(); keys != from.properties.end(); keys++) {
        properties[keys->first] = keys->second;
    }
    VARIANT to_value;
    for (rscIter rs = from.results.begin(); rs != from.results.end(); rs++) {
        result_row to_row = result_row();
        for (rrcIter rr = rs->second.begin(); rr != rs->second.end(); rr++) {
            /*
             *  VARIANTデータエリアの初期化(初期化しておかないとVariantCopyの時にエリアを開放しようとしてエラーになる)
             *  return : 無し
             *  参照:http://msdn.microsoft.com/en-us/library/ms221402.aspx
             */
            VariantInit(&to_value);
            /*
             *  VARIANTのデータをコピー
             *  return : S_OK = 正常にコピーできた(ここでは結果はチェックしない)
             *           その他 = エラー
             *  参照:http://msdn.microsoft.com/en-us/library/ms221697.aspx
             */
            VariantCopy(&to_value, (VARIANT*)&rr->second);
            to_row[rr->first] = to_value;
        }
        results[rs->first] = to_row;
    }
}

//  Destructor
WmiResult::~WmiResult() {
    for (size_t i = 0; i < results.size(); i++) {
        rsIter rs = results.find(i);
        for (size_t j = 0; j < rs->second.size(); j++) {
            rrIter rr = rs->second.find(j);
            /*
             *  VARIANTデータエリアのクリア
             *  return : S_OK = 正常にクリアできた(ここでは結果はチェックしない)
             *           その他 = エラー
             *  参照:http://msdn.microsoft.com/en-us/library/ms221165.aspx
             */
            VariantClear(&rr->second);
        }
        rs->second.clear();
    }
    results.clear();
    properties.clear();
}

/*
 *  WMI呼び出しで戻ってきた結果セットからプロパティを保存する
 *  param   : 結果セット(IEnumWbemClassObjectポインター)
 *
 *  return  : HRESULT
 */
HRESULT WmiResult::loadProperties(IEnumWbemClassObject *pObjects) {
    HRESULT hRes;
    if (pObjects == NULL) {
        return WBEM_E_FAILED;
    }

    /*
     *  結果セットの現在行をリセットする
     *  return : WBEM_S_NO_ERROR = 正常にResetできた
     *           その他 = エラー
     *  参照:http://msdn.microsoft.com/en-us/library/aa390863(VS.85).aspx
     */
    if ((hRes = pObjects->Reset()) == WBEM_S_NO_ERROR) {
        wchar_t **names = NULL;
        ULONG uReturn = 0;
        IWbemClassObject *pclsObj[1];
        /*
         *  結果セットから現在行を取得し、行ポインターを次に進める
         *  return : WBEM_S_NO_ERROR = 正常にNextできた
         *           その他 = エラー
         *  参照:http://msdn.microsoft.com/en-us/library/aa390860(VS.85).aspx
         */
        if ((hRes = pObjects->Next(WBEM_INFINITE, 1, pclsObj, &uReturn)) == WBEM_S_NO_ERROR) {
            SAFEARRAY *pstrNames = NULL;
            /*
             *  結果セットからプロパティの取得
             *  return : WBEM_S_NO_ERROR = 正常にGetNamesできた
             *           その他 = エラー
             *  参照:http://msdn.microsoft.com/en-us/library/aa391447(VS.85).aspx
             */
            if ((hRes = pclsObj[0]->GetNames(NULL, WBEM_FLAG_ALWAYS, NULL, &pstrNames)) == WBEM_S_NO_ERROR) {
                long lb = 0, ub = 0;
                BSTR name;
                /*
                 *  配列エリアの開始位置の取得
                 *  return : S_OK = 正常に取得できた(ここでは結果はチェックしない)
                 *           その他 = エラー
                 *  参照:http://msdn.microsoft.com/en-us/library/ms221622.aspx
                 */
                SafeArrayGetLBound(pstrNames, 1, &lb);
                /*
                 *  配列エリアの終了位置の取得
                 *  return : S_OK = 正常に取得できた(ここでは結果はチェックしない)
                 *           その他 = エラー
                 *  参照:http://msdn.microsoft.com/en-us/library/ms221584.aspx
                 */
                SafeArrayGetUBound(pstrNames, 1, &ub);
                for (long i = 0; i <= (ub - lb); i++) {
                    /*
                     *  配列エリア~指定の位置にあるデータを取得
                     *  return : S_OK = 正常に取得できた(ここでは結果はチェックしない)
                     *           その他 = エラー
                     *  参照:http://msdn.microsoft.com/en-us/library/ms221255.aspx
                     */
                    SafeArrayGetElement(pstrNames, &i, (void*)&name);
                    String prop = String((_TCHAR *)name);
                    properties[prop] = cols++;
                }
                /*
                 *  配列エリア~を開放する
                 *  return : S_OK = 正常に取得できた(ここでは結果はチェックしない)
                 *           その他 = エラー
                 *  参照:http://msdn.microsoft.com/en-us/library/ms221702.aspx
                 */
                SafeArrayDestroy(pstrNames);
            }
        }
    }
    return hRes;
}

/*
 *  WMI呼び出しで戻ってきた結果セットからデータを保存する
 *  param   : 結果セット(IEnumWbemClassObjectポインター)
 *
 *  return  : HRESULT
 */
HRESULT WmiResult::loadValues(IEnumWbemClassObject *pObjects) {
    HRESULT hRes;
    if (pObjects == NULL) {
        return WBEM_E_FAILED;
    }

    /*
     *  結果セットから現在行をリセットする
     *  return : WBEM_S_NO_ERROR = 正常にResetできた
     *           その他 = エラー
     *  参照:http://msdn.microsoft.com/en-us/library/aa390863(VS.85).aspx
     */
    if ((hRes = pObjects->Reset()) == WBEM_S_NO_ERROR) {
        VARIANT vtProp, value;
        VariantInit(&vtProp);
        ULONG uReturn = 0;
        IWbemClassObject *pclsObj[1];
        while (pObjects != NULL) {
            /*
             *  結果セットから現在行を取得し、行ポインターを次に進める
             *  return : WBEM_S_NO_ERROR = 正常にNextできた
             *           その他 = エラー
             *  参照:http://msdn.microsoft.com/en-us/library/aa390860(VS.85).aspx
             */
            if(pObjects->Next(WBEM_INFINITE, 1, pclsObj, &uReturn) == WBEM_S_NO_ERROR) {
                result_row one_row = result_row();
                for (psIter ps = properties.begin(); ps != properties.end(); ps++) {
                    size_t col_pos = ps->second;
                    _bstr_t key = bstr_t(ps->first.c_str());
                    /*
                     *  結果セットからデータの取得
                     *  return : WBEM_S_NO_ERROR = 正常にGetできた
                     *           その他 = エラー
                     *  参照:http://msdn.microsoft.com/en-us/library/aa391442(VS.85).aspx
                     */
                    if ((hRes = pclsObj[0]->Get(key, 0, &vtProp, 0, 0)) == WBEM_S_NO_ERROR) {
                        VariantInit(&value);
                        if (vtProp.vt != VT_NULL) {
                            VariantCopy(&value, &vtProp);
                        }
                        one_row[col_pos] = value;
                    }
                    VariantClear(&vtProp);
                }
                results[rows++] = one_row;
                pclsObj[0]->Release();
            }
            else
                break;
        }
    }
    return hRes;
}

/*
 *  結果セットの項目数を取得する
 *  param   : 無し
 *
 *  return  : size_t
 */
size_t WmiResult::items() {
    return properties.size();
}


/*
 *  結果セットの行数を取得する
 *  param   : 無し
 *
 *  return  : size_t
 */
size_t WmiResult::size() {
    return results.size();
}

/*
 *  結果セットのプロパティ一覧を取得する
 *  param   : 無し
 *
 *  return  : string_vector
 */
string_vector WmiResult::getProperties() {
    string_vector key_list;
    for (psIter item = properties.begin(); item != properties.end(); item++) {
        key_list.push_back(item->first);
    }
    return key_list;
}

/*
 *  結果セットのプロパティを取得する
 *  param   : 項目位置(size_t)
 *
 *  return  : String
 */
String WmiResult::getProperty(size_t pos) {
    string_vector key_list;
    for (psIter item = properties.begin(); item != properties.end(); item++) {
        if (item->second == pos)
            return item->first;
    }
    return _T("");
}

/*
 *  結果セットを取得する
 *  param   : 無し
 *
 *  return  : result_set
 */
result_set WmiResult::getResult() {
    return results;
}

/*
 *  指定の行とプロパティで特定されるデータを取得する
 *  param   : プロパティ(String)
 *            行(size_t)
 *
 *  return  : VARIANT
 */
VARIANT *WmiResult::getValue(String prop, size_t row) {
    psIter ps = properties.find(prop);
    if (ps != properties.end()) {
        size_t col_pos = ps->second;
        rsIter rs = results.find(row);
        if (rs != results.end()) {
            rrIter rr = rs->second.find(col_pos);
            if (rr != rs->second.end()) {
                return &rr->second;
            }
        }
    }
    return NULL;
}

/*
 *  指定の行とプロパティで特定されるデータのタイプ取得する
 *  param   : プロパティ(String)
 *            行(size_t)
 *
 *  return  : VARTYPE
 */
VARTYPE WmiResult::getValueType(String prop, size_t row) {
    VARIANT *value = getValue(prop, row);
    return getType(value);
}

/*
 *  指定の行とプロパティで特定されるデータが配列(safaarray)かどうか確認する
 *  param   : プロパティ(String)
 *            行(size_t)
 *
 *  return  : bool
 */
bool WmiResult::isArray(String prop, size_t row) {
    VARIANT *value = getValue(prop, row);
    return isArray(value);
}

/*
 *  指定の行とプロパティで特定されるデータを整数値(long)で取得する
 *  param   : プロパティ(String)
 *            行(size_t)
 *            変換できないタイプの省略値(long)
 *
 *  return  : long
 */
long WmiResult::getLong(String prop, size_t row, long deflong) {
    VARIANT *value = getValue(prop, row);
    return getLong(value, deflong);
}

/*
 *  指定の行とプロパティで特定されるデータを整数値(long)リストで取得する
 *  param   : プロパティ(String)
 *            行(size_t)
 *            変換できないタイプの省略値(long)
 *
 *  return  : long_vector
 */
long_vector WmiResult::getLongArray(String prop, size_t row, long deflong) {
    VARIANT *value = getValue(prop, row);
    return getLongArray(value, deflong);
}

/*
 *  指定の行とプロパティで特定されるデータを浮動小数点値(double)で取得する
 *  param   : プロパティ(String)
 *            行(size_t)
 *            変換できないタイプの省略値(double)
 *
 *  return  : double
 */
double WmiResult::getDouble(String prop, size_t row, double defdouble) {
    VARIANT *value = getValue(prop, row);
    return getDouble(value, defdouble);
}

/*
 *  指定の行とプロパティで特定されるデータを浮動小数点値(double)リストで取得する
 *  param   : プロパティ(String)
 *            行(size_t)
 *            変換できないタイプの省略値(double)
 *
 *  return  : double_vector
 */
double_vector WmiResult::getDoubleArray(String prop, size_t row, double defdouble) {
    VARIANT *value = getValue(prop, row);
    return getDoubleArray(value, defdouble);
}

/*
 *  指定の行とプロパティで特定されるデータを論理値(bool)で取得する
 *  param   : プロパティ(String)
 *            行(size_t)
 *            変換できないタイプの省略値(bool)
 *
 *  return  : bool
 */
bool WmiResult::getBool(String prop, size_t row, bool defbool) {
    VARIANT *value = getValue(prop, row);
    return getBool(value, defbool);
}

/*
 *  指定の行とプロパティで特定されるデータを論理値(bool)リストで取得する
 *  param   : プロパティ(String)
 *            行(size_t)
 *            変換できないタイプの省略値(bool)
 *
 *  return  : bool_vector
 */
bool_vector WmiResult::getBoolArray(String prop, size_t row, bool defbool) {
    VARIANT *value = getValue(prop, row);
    return getBoolArray(value, defbool);
}

/*
 *  指定の行とプロパティで特定されるデータを文字列値で取得する
 *  param   : プロパティ(String)
 *            行(size_t)
 *
 *  return  : String
 */
String WmiResult::getString(String prop, size_t row) {
    VARIANT *value = getValue(prop, row);
    return getString(value);
}

/*
 *  指定の行とプロパティで特定されるデータを文字列値リストで取得する
 *  param   : プロパティ(String)
 *            行(size_t)
 *
 *  return  : string_vector
 */
string_vector WmiResult::getStringArray(String prop, size_t row) {
    VARIANT *value = getValue(prop, row);
    return getStringArray(value);
}

/*
 *  保持しているデータを印刷できる形式に変換する
 *  param   : 無し
 *
 *  return  : String
 */
String WmiResult::print() {
    basic_stringstream<_TCHAR> buf;
    string_vector key_list = getProperties();
    for (size_t i = 0; i < rows; i++) {
        for (size_t j = 0; j < cols; j++) {
            String prop = key_list[j];
            VARIANT *val = getValue(prop, i);
            if (isArray(val)) {
                string_vector list = getStringArray(val);
                buf << i << _T("-") << j << _T("=") << prop << _T(" : ");
                for (size_t k = 0; k < list.size(); k++) {
                    if (k > 0) buf << _T(", ");
                    buf << list.at(k);
                }
                buf << endl;
            }
            else {
                buf << i << _T("-") << j << _T("=") << prop << _T(" : ") << getString(val) << endl;
            }
        }
    }
    return buf.str();
}

/*
 *  VARIANTデータのタイプ取得する
 *  param   : VARIANTデータ(VARIANTポインター)
 *
 *  return  : VARTYPE
 */
VARTYPE WmiResult::getType(VARIANT *value) {
    if (value != NULL) {
        VARTYPE vt = value->vt;
        vt -= ((vt & VT_BYREF) == VT_BYREF) ? VT_BYREF : 0;
        vt -= ((vt & VT_ARRAY) == VT_ARRAY) ? VT_ARRAY : 0;
        return vt;
    }
    return VT_UNKNOWN;
}

/*
 *  VARIANTデータが配列(safaarray)かどうか確認する
 *  param   : VARIANTデータ(VARIANTポインター)
 *
 *  return  : bool
 */
bool WmiResult::isArray(VARIANT *value) {
    if (value != NULL) {
        return ((value->vt & VT_ARRAY) == VT_ARRAY) ? true : false;
    }
    return false;
}

/*
 *  VARIANTデータが参照値(VT_BYREF)かどうか確認する
 *  param   : VARIANTデータ(VARIANTポインター)
 *
 *  return  : bool
 */
bool WmiResult::isByRef(VARIANT *value) {
    if (value != NULL) {
        return ((value->vt & VT_BYREF) == VT_BYREF) ? true : false;
    }
    return false;
}

/*
 *  VARIANTデータを整数値(long)に変換し取得する
 *  param   : データ(VARIANTポインター)
 *
 *  return  : long
 */
long WmiResult::getLong(VARIANT *value, long deflong) {
    long result = deflong;
    if (value != NULL) {
        if (isArray(value)) {
            long_vector list = getLongArray(value, deflong);
            if (!list.empty())
                result = list.at(0);
        }
        else {
            VARIANT to_value;
            VariantInit(&to_value);
            VARTYPE vt = getType(value);
            /*
             *  VARIANTデータのデータタイプを変換する
             *  return : S_OK = 正常に変換できた
             *           その他 = エラー
             *  参照:http://msdn.microsoft.com/en-us/library/ms221258.aspx
             */
            if (VariantChangeType(&to_value, value, 0, VT_UI4) == S_OK) {
                result = to_value.lVal;
            }
            VariantClear(&to_value);
        }
    }
    return result;
}

/*
 *  VARIANTデータ配列を整数値(long)リストに変換し取得する
 *  param   : データ(VARIANTポインター)
 *
 *  return  : long_vector
 */
long_vector WmiResult::getLongArray(VARIANT *value, long deflong) {
    long_vector list;
    if (value != NULL) {
        if (isArray(value)) {
            VARIANT array_var;
            VARTYPE vt = getType(value);
            long lb = 0, ub = 0;
            SAFEARRAY *array_val = ((isByRef(value)) ? *value->pparray : value->parray);
            SafeArrayGetLBound(array_val, 1, &lb);
            SafeArrayGetUBound(array_val, 1, &ub);
            for (long i = 0; i <= (ub - lb); i++) {
                VariantInit(&array_var);
                array_var.vt = vt;
                SafeArrayGetElement(array_val, &i, (void*)&array_var.punkVal);
                long result = getLong(&array_var, deflong);
                list.push_back(result);
            }
        }
        else {
            long result = getLong(value, deflong);
            list.push_back(result);
        }
    }
    return list;
}

/*
 *  VARIANTデータを浮動小数点値(double)に変換し取得する
 *  param   : データ(VARIANTポインター)
 *
 *  return  : double
 */
double WmiResult::getDouble(VARIANT *value, double defdouble) {
    double result = defdouble;
    if (value != NULL) {
        if (isArray(value)) {
            double_vector list = getDoubleArray(value, defdouble);
            if (!list.empty())
                result = list.at(0);
        }
        else {
            VARIANT to_value;
            VariantInit(&to_value);
            VARTYPE vt = getType(value);
            VariantChangeType(&to_value, value, 0, VT_R8);
            result = to_value.dblVal;
            VariantClear(&to_value);
        }
    }
    return result;
}

/*
 *  VARIANTデータ配列を浮動小数点値(double)リストに変換し取得する
 *  param   : データ(VARIANTポインター)
 *
 *  return  : double_vector
 */
double_vector WmiResult::getDoubleArray(VARIANT *value, double defdouble) {
    double_vector list;
    if (value != NULL) {
        if (isArray(value)) {
            VARIANT array_var;
            VARTYPE vt = getType(value);
            long lb = 0, ub = 0;
            SAFEARRAY *array_val = ((isByRef(value)) ? *value->pparray : value->parray);
            SafeArrayGetLBound(array_val, 1, &lb);
            SafeArrayGetUBound(array_val, 1, &ub);
            for (long i = 0; i <= (ub - lb); i++) {
                VariantInit(&array_var);
                array_var.vt = vt;
                SafeArrayGetElement(array_val, &i, (void*)&array_var.punkVal);
                double result = getDouble(&array_var, defdouble);
                list.push_back(result);
            }
        }
        else {
            double result = getDouble(value, defdouble);
            list.push_back(result);
        }
    }
    return list;
}

/*
 *  VARIANTデータを論理値(bool)に変換し取得する
 *  param   : データ(VARIANTポインター)
 *
 *  return  : bool
 */
bool WmiResult::getBool(VARIANT *value, bool defbool) {
    bool result = defbool;
    if (value != NULL) {
        if (isArray(value)) {
            bool_vector list = getBoolArray(value, defbool);
            if (!list.empty())
                result = list.at(0);
        }
        else {
            VARIANT to_value;
            VariantInit(&to_value);
            VARTYPE vt = getType(value);
            VariantChangeType(&to_value, value, 0, VT_BOOL);
            result = (to_value.boolVal != 0) ? true : false;
            VariantClear(&to_value);
        }
    }
    return result;
}

/*
 *  VARIANTデータ配列を論理値(bool)リストに変換し取得する
 *  param   : データ(VARIANTポインター)
 *
 *  return  : bool_vector
 */
bool_vector WmiResult::getBoolArray(VARIANT *value, bool defbool) {
    bool_vector list;
    if (value != NULL) {
        if (isArray(value)) {
            VARIANT array_var;
            VARTYPE vt = getType(value);
            long lb = 0, ub = 0;
            SAFEARRAY *array_val = ((isByRef(value)) ? *value->pparray : value->parray);
            SafeArrayGetLBound(array_val, 1, &lb);
            SafeArrayGetUBound(array_val, 1, &ub);
            for (long i = 0; i <= (ub - lb); i++) {
                VariantInit(&array_var);
                array_var.vt = vt;
                SafeArrayGetElement(array_val, &i, (void*)&array_var.punkVal);
                bool result = getBool(&array_var, defbool);
                list.push_back(result);
            }
        }
        else {
            bool result = getBool(value, defbool);
            list.push_back(result);
        }
    }
    return list;
}

/*
 *  VARIANTデータを文字列値に変換し取得する
 *  param   : データ(VARIANTポインター)
 *
 *  return  : String
 */
String WmiResult::getString(VARIANT *value) {
    String result;
    if (value != NULL) {
        if (isArray(value)) {
            string_vector list = getStringArray(value);
            if (!list.empty())
                result = list.at(0);
        }
        else {
            VARIANT to_value;
            VariantInit(&to_value);
            VARTYPE vt = getType(value);
            switch (vt) {
                case VT_BOOL:   //  VARIANT_BOOL
                    /*
                     *  VT_BOOL型のデータをVT_BST型のデータに変換
                     *  return : S_OK = 正常に変換できた(ここでは結果はチェックしない)
                     *           その他 = エラー
                     *  参照:http://msdn.microsoft.com/en-us/library/ms221338.aspx
                     */
                    VarBstrFromBool(((isByRef(value)) ? *value->pboolVal : value->boolVal), 0, LOCALE_NOUSEROVERRIDE, &to_value.bstrVal);
                    break;
                case VT_BSTR:   //  VT_BSTR
                    VariantCopy(&to_value, value);;
                    break;
                default:
                    VariantChangeType(&to_value, value, 0, VT_BSTR);
            }
            result = String(to_value.bstrVal);
            VariantClear(&to_value);
        }
    }
    return result;
}

/*
 *  VARIANTデータ配列を文字列値リストに変換し取得する
 *  param   : データ(VARIANTポインター)
 *
 *  return  : string_vector
 */
string_vector WmiResult::getStringArray(VARIANT *value) {
    string_vector list;
    if (value != NULL) {
        if (isArray(value)) {
            VARIANT array_var;
            VARTYPE vt = getType(value);
            long lb = 0, ub = 0;
            SAFEARRAY *array_val = ((isByRef(value)) ? *value->pparray : value->parray);
            SafeArrayGetLBound(array_val, 1, &lb);
            SafeArrayGetUBound(array_val, 1, &ub);
            for (long i = 0; i <= (ub - lb); i++) {
                VariantInit(&array_var);
                array_var.vt = vt;
                SafeArrayGetElement(array_val, &i, (void*)&array_var.punkVal);
                String result = getString(&array_var);
                list.push_back(result);
            }
        }
        else {
            String result = getString(value);
            list.push_back(result);
        }
    }
    return list;
}

にしてみました。

で、呼出すプログラムのコードは、

WmiCall wmi;

size_t key_wait(String question = _T("")) {
    if (question.empty())
        COUT << _T("\nPress enter key to continue :");
    else
        COUT << question;
    String value;
    getline(CIN, value, _T('\n'));
    return value.length();
}

void Win32_BootConfiguration() {
    WmiResult results = wmi.access(_T("SELECT * FROM Win32_BIOS"));
    if (results.items() == 0) {
        String msg = wmi.getErrorMessage();
        return;
    }

    COUT << results.print();
}

int _tmain(int argc, _TCHAR* argv[]) {
    if (wmi.init()) {
        Win32_BootConfiguration();
        wmi.term();
    }

    key_wait();
    return 0;
}

って感じで動作結果は・・・、色んな情報が入っていたので割愛しました。