Windows Management Instrumentation (4-3)

以下のような処理に変更後テストをするとエラーが発生。

void Win32_OperatingSystem() {
    WmiResult resulta = wmi.access(_T("SELECT * FROM Win32_OperatingSystem"));
    if (resulta.items() == 0) {
        String msg = wmi.getErrorMessage();
        return;
    }
    COUT << resulta.print();

    String systemDrive = resulta.getString(_T("SystemDrive"));
    String wql = WmiCall::createSelect(_T("ASSOCIATORS OF {Win32_LogicalDisk.DeviceID=\"%s\"} WHERE AssocClass = Win32_LogicalDiskToPartition ResultClass = Win32_DiskPartition"), systemDrive.c_str(), NULL);
    resulta = wmi.access(wql);
    if (resulta.items() == 0) {
        String msg = wmi.getErrorMessage();
        return;
    }
    COUT << resulta.print();
}

デバッグしてみると、

resulta = wmi.access(wql);

でデータをコピーした後にデストラクタが起動している感じ・・・、"operator="を定義していなかったのが原因でした。

そこで、wmi.hに

    void            copy(const WmiResult& from);
    WmiResult&      operator=(const WmiResult& from);

を追加し、
wmi.cpp中のロジックを

/*
 *  WmiResultクラスをコピーする
 */
void WmiResult::copy(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;
    }
}

/*
 *  デフォルトのCopy Constructorでは、VARIANTのSAFEARRAYタイプのデータを
 *  正しくコピー出来ない為に作成
 */
WmiResult::WmiResult(const WmiResult& from) {
    copy(from);
}

/*
 *  "=(代入)"オペレータの処理
 */
WmiResult& WmiResult::operator=(const WmiResult& from) {
    copy(from);
    return *this;
}

に修正しました。