Win32_USBControllerDeviceは、Win32_USBControllerとCIM_LogicalDeviceの関連性を列挙するクラス。
Win32_USBControllerDevice クラス - Win32 apps | Microsoft Docs
まずは、Win32_USBControllerDevice.cppで、
// クエリの実行. BSTR strQueryLanguage = SysAllocString(L"WQL"); // SysAllocStringでstrQueryLanguageを"WQL"で初期化. BSTR strQuery = SysAllocString(L"SELECT * FROM Win32_USBControllerDevice"); // SysAllocStringでstrQueryを"SELECT * FROM Win32_USBControllerDevice"で初期化. hr6 = pServices->ExecQuery(strQueryLanguage, strQuery, WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &pEnumerator); // IWbemServices::ExecQueryでクエリ実行. if (FAILED(hr6)){ // FAILEDマクロで判定. _tprintf(_T("FAILED!\n")); // "FAILED!"と出力. SysFreeString(strQuery); // SysFreeStringでstrQueryを解放. SysFreeString(strQueryLanguage); // SysFreeStringでstrQueryLanguageを解放. pServices->Release(); // IWbemServices::Releaseで解放. SysFreeString(strNetworkResource); // SysFreeStringでstrNetworkResourceを解放. pLocator->Release(); // IWbemLocator::Releaseで解放. CoUninitialize(); // CoUninitializeで終了処理. return -6; // -6を返して異常終了. } // pServices->ExecQueryは成功. _tprintf(_T("pServices->ExecQuery OK!\n")); // "pServices->ExecQuery OK!"と出力. // 取得したIEnumWbemClassObjectインターフェースポインタpEnumeratorを出力. _tprintf(_T("pEnumerator = 0x%08x\n"), (unsigned long)pEnumerator); // pEnumeratorを出力. // pEnumeratorの各要素を列挙. ULONG uReturn = 0; while (pEnumerator){ // pEnumeratorがNULLで無い限り続ける. hr7 = pEnumerator->Next(WBEM_INFINITE, 1, &pClassObject, &uReturn); // IEnumWbemClassObject::Nextで次の要素を取得. if (uReturn == 0){ // 終了. break; } if (SUCCEEDED(hr7)){ // SUCCEEDEDマクロで判定. // pEnumerator->Nextは成功. _tprintf(_T("pEnumerator->Next OK!\n")); // "pEnumerator->Next OK!"と出力. // 取得したIWbemClassObjectインターフェースポインタpClassObjectを出力. _tprintf(_T("pClassObject = 0x%08x\n"), (unsigned long)pClassObject); // pClassObjectを出力. // オブジェクトテキストの取得. BSTR strObjectText; hr8 = pClassObject->GetObjectText(0, &strObjectText); // IWbemClassObject::GetObjectTextでオブジェクトの内容をテキスト形式で取得. if (SUCCEEDED(hr8) && strObjectText){ // SUCCEEDEDマクロとstrObjectTextで判定. // pClassObject->GetObjectTextは成功. _tprintf(_T("pClassObject->GetObjectText OK!\n")); // "pClassObject->GetObjectText OK!"と出力. // ワイド文字をマルチバイト文字に変換する. int iBufLen = WideCharToMultiByte(CP_ACP, 0, strObjectText, -1, NULL, 0, NULL, NULL); // まずは長さを取得. char *pszBuf = new char[iBufLen]; // iBufLenのchar型バッファを確保. WideCharToMultiByte(CP_ACP, 0, strObjectText, -1, pszBuf, iBufLen, NULL, NULL); // 変換. printf("%s", pszBuf); // printfでpszBufを出力. delete [] pszBuf; // delete [] でpszBufを解放. SysFreeString(strObjectText); // SysFreeStringでstrObjectTextを解放. } } pClassObject->Release(); // IWbemClassObject::Releaseで解放. }
SELECT文で列挙してGetObjectTextで中身を見てみる。
結構な数はある・・・。
次に、
// クエリの実行. BSTR strQueryLanguage = SysAllocString(L"WQL"); // SysAllocStringでstrQueryLanguageを"WQL"で初期化. BSTR strQuery = SysAllocString(L"SELECT * FROM Win32_USBController"); // SysAllocStringでstrQueryを"SELECT * FROM Win32_USBController"で初期化. hr6 = pServices->ExecQuery(strQueryLanguage, strQuery, WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &pEnumerator); // IWbemServices::ExecQueryでクエリ実行. if (FAILED(hr6)){ // FAILEDマクロで判定. _tprintf(_T("FAILED!\n")); // "FAILED!"と出力. SysFreeString(strQuery); // SysFreeStringでstrQueryを解放. SysFreeString(strQueryLanguage); // SysFreeStringでstrQueryLanguageを解放. pServices->Release(); // IWbemServices::Releaseで解放. SysFreeString(strNetworkResource); // SysFreeStringでstrNetworkResourceを解放. pLocator->Release(); // IWbemLocator::Releaseで解放. CoUninitialize(); // CoUninitializeで終了処理. return -6; // -6を返して異常終了. } // pServices->ExecQueryは成功. _tprintf(_T("pServices->ExecQuery OK!\n")); // "pServices->ExecQuery OK!"と出力. // 取得したIEnumWbemClassObjectインターフェースポインタpEnumeratorを出力. _tprintf(_T("pEnumerator = 0x%08x\n"), (unsigned long)pEnumerator); // pEnumeratorを出力. // pEnumeratorの各要素を列挙. ULONG uReturn = 0; while (pEnumerator){ // pEnumeratorがNULLで無い限り続ける. hr7 = pEnumerator->Next(WBEM_INFINITE, 1, &pClassObject, &uReturn); // IEnumWbemClassObject::Nextで次の要素を取得. if (uReturn == 0){ // 終了. break; } if (SUCCEEDED(hr7)){ // SUCCEEDEDマクロで判定. // pEnumerator->Nextは成功. //_tprintf(_T("pEnumerator->Next OK!\n")); // "pEnumerator->Next OK!"と出力. // 取得したIWbemClassObjectインターフェースポインタpClassObjectを出力. //_tprintf(_T("pClassObject = 0x%08x\n"), (unsigned long)pClassObject); // pClassObjectを出力. // オブジェクトテキストの取得. BSTR strObjectText; hr8 = pClassObject->GetObjectText(0, &strObjectText); // IWbemClassObject::GetObjectTextでオブジェクトの内容をテキスト形式で取得. if (SUCCEEDED(hr8) && strObjectText){ // SUCCEEDEDマクロとstrObjectTextで判定. // pClassObject->GetObjectTextは成功. //_tprintf(_T("pClassObject->GetObjectText OK!\n")); // "pClassObject->GetObjectText OK!"と出力. // ワイド文字をマルチバイト文字に変換する. int iBufLen = WideCharToMultiByte(CP_ACP, 0, strObjectText, -1, NULL, 0, NULL, NULL); // まずは長さを取得. char *pszBuf = new char[iBufLen]; // iBufLenのchar型バッファを確保. WideCharToMultiByte(CP_ACP, 0, strObjectText, -1, pszBuf, iBufLen, NULL, NULL); // 変換. //printf("%s", pszBuf); // printfでpszBufを出力. delete [] pszBuf; // delete [] でpszBufを解放. SysFreeString(strObjectText); // SysFreeStringでstrObjectTextを解放. } // プロパティの取得. VARIANT vrDeviceID; // デバイスID. hr9 = pClassObject->Get(L"DeviceID", 0, &vrDeviceID, 0, 0); // IWbemClassObject::Getで"DeviceID"プロパティの値を取得. if (SUCCEEDED(hr9)){ // SUCCEEDEDマクロで判定. // pClassObject->Getは成功. //_tprintf(_T("pClassObject->Get OK!\n")); // "pClassObject->Get OK!"と出力. //wprintf(L"DeviceID: %s\n", vrDeviceID.bstrVal); // vrDeviceID.bstrValを出力. // クエリの実行. std::wstring q = L"ASSOCIATORS OF{Win32_USBController.DeviceID=\'"; // "ASSOCIATORS OF{Win32_USBController.DeviceID=\'"をqにセット. q = q + vrDeviceID.bstrVal; // vrDeviceID.bstrValを連結. q = q + L"\'}"; // "\'}"を連結. q = q + L" WHERE AssocClass = Win32_USBControllerDevice"; // " WHERE AssocClass = Win32_USBControllerDevice"を連結. BSTR strQuery2 = SysAllocString(q.c_str()); // SysAllocStringでstrQuery2をq.c_str()で初期化. hr10 = pServices->ExecQuery(strQueryLanguage, strQuery2, WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &pEnumerator2); // IWbemServices::ExecQueryでクエリ実行. if (SUCCEEDED(hr10)){ // SUCCEEDEDマクロで判定. // pServices->ExecQueryは成功. //_tprintf(_T("pServices->ExecQuery OK!\n")); // "pServices->ExecQuery OK!"と出力. // 取得したIEnumWbemClassObjectインターフェースポインタpEnumerator2を出力. //_tprintf(_T("pEnumerator2 = 0x%08x\n"), (unsigned long)pEnumerator2); // pEnumerator2を出力. // pEnumerator2の各要素を列挙. ULONG uReturn2 = 0; while (pEnumerator2){ // pEnumerator2がNULLで無い限り続ける. hr11 = pEnumerator2->Next(WBEM_INFINITE, 1, &pClassObject2, &uReturn2); // IEnumWbemClassObject::Nextで次の要素を取得. if (uReturn2 == 0){ // 終了. break; } if (SUCCEEDED(hr11)){ // SUCCEEDEDマクロで判定. // pEnumerator2->Nextは成功. //_tprintf(_T("pEnumerator2->Next OK!\n")); // "pEnumerator2->Next OK!"と出力. // 取得したIWbemClassObjectインターフェースポインタpClassObject2を出力. //_tprintf(_T("pClassObject2 = 0x%08x\n"), (unsigned long)pClassObject2); // pClassObject2を出力. // オブジェクトテキストの取得. BSTR strObjectText2; hr12 = pClassObject2->GetObjectText(0, &strObjectText2); // IWbemClassObject::GetObjectTextでオブジェクトの内容をテキスト形式で取得. if (SUCCEEDED(hr12) && strObjectText2){ // SUCCEEDEDマクロとstrObjectText2で判定. // pClassObject2->GetObjectTextは成功. //_tprintf(_T("pClassObject2->GetObjectText OK!\n")); // "pClassObject2->GetObjectText OK!"と出力. // ワイド文字をマルチバイト文字に変換する. int iBufLen2 = WideCharToMultiByte(CP_ACP, 0, strObjectText2, -1, NULL, 0, NULL, NULL); // まずは長さを取得. char *pszBuf2 = new char[iBufLen2]; // iBufLen2のchar型バッファを確保. WideCharToMultiByte(CP_ACP, 0, strObjectText2, -1, pszBuf2, iBufLen2, NULL, NULL); // 変換. //printf("%s", pszBuf2); // printfでpszBuf2を出力. delete [] pszBuf2; // delete [] でpszBuf2を解放. SysFreeString(strObjectText2); // SysFreeStringでstrObjectText2を解放. } // プロパティの取得. VARIANT vrDeviceID2; // デバイスID. hr13 = pClassObject2->Get(L"DeviceID", 0, &vrDeviceID2, 0, 0); // IWbemClassObject::Getで"DeviceID"プロパティの値を取得. if (SUCCEEDED(hr13)){ // SUCCEEDEDマクロで判定. // pClassObject2->Getは成功. //_tprintf(_T("pClassObject2->Get OK!\n")); // "pClassObject2->Get OK!"と出力. //wprintf(L" DeviceID: %s\n", vrDeviceID2.bstrVal); // vrDeviceID2.bstrValを出力. // vrDeviceID2のクリア. VariantClear(&vrDeviceID2); // VariantClearでvrDeviceID2をクリア. } VARIANT vrPNPDeviceID2; // PNPデバイスID. hr14 = pClassObject2->Get(L"PNPDeviceID", 0, &vrPNPDeviceID2, 0, 0); // IWbemClassObject::Getで"PNPDeviceID"プロパティの値を取得. if (SUCCEEDED(hr14)){ // SUCCEEDEDマクロで判定. // pClassObject2->Getは成功. //_tprintf(_T("pClassObject2->Get OK!\n")); // "pClassObject2->Get OK!"と出力. if (vrPNPDeviceID2.vt != VT_NULL){ // VT_NULLになることがあるようなので, この判定が必要. wprintf(L"PNPDeviceID: %s\n", vrPNPDeviceID2.bstrVal); // vrPNPDeviceID2.bstrValを出力. } // vrPNPDeviceID2のクリア. VariantClear(&vrPNPDeviceID2); // VariantClearでvrPNPDeviceID2をクリア. } } pClassObject2->Release(); // IWbemClassObject::Releaseで解放. } pEnumerator2->Release(); // IEnumWbemClassObject::Releaseで解放. } SysFreeString(strQuery2); // SysFreeStringでstrQuery2を解放. // vrDeviceIDのクリア. VariantClear(&vrDeviceID); // VariantClearでvrDeviceIDをクリア. } } pClassObject->Release(); // IWbemClassObject::Releaseで解放. }
Win32_USBControllerのDeviceIDを列挙し、それをASSOCIATORS OFのAssocClass = Win32_USBControllerDeviceにかけて、CIM_LogicalDeviceのPNPDeviceIDを列挙する。
USBHDD(旧モデル)を挿入してから実行すると、
一番下に、USBSTORが出てきた。これがUSBHDD(旧モデル)。
さて、これはなんのクラスなのか?
インスタンス名を切り出して表示すると、
Win32_PnPEntityだった。
Win32_PnPEntityからWin32_DiskDriveそしてドライブレターに繋がった。