//+--------------------------------------------------------------------------- // // Function: HrShowBindingPath // // Purpose: Display components of a binding path in the format: // foo -> bar -> adapter // // Arguments: // pncbp [in] pointer to INetCfgBindingPath object // // Returns: S_OK on success, otherwise an error code // // Notes: // HRESULT HrShowBindingPath(IN INetCfgBindingPath* pncbp) { HRESULT hr=S_OK; INetCfgBindingInterface* pncbi; INetCfgComponent* pncc = NULL; BOOL fFirstInterface=TRUE; PWSTR szComponentId; while (SUCCEEDED(hr) && (S_OK == (hr = HrGetNextBindingInterface(pncbp, &pncbi)))) { // for the first (top) interface we need to get the upper as well as // the lower component. for other interfaces we need to get // only the lower component. if (fFirstInterface) { fFirstInterface = FALSE; hr = pncbi->GetUpperComponent(&pncc); if (SUCCEEDED(hr)) { // get id so that we can display it // // for readability of the output, we have used the GetId // function. For non net class components, this // does not pose a problem. In case of net class components, // there may be more than one net adapters of the same type // in which case, GetId will return the same string. This will // make it impossible to distinguish between two binding // paths that end in two distinct identical cards. In such case, // it may be better to use the GetInstanceGuid function because // it will return unique GUID for each instance of an adapter. // hr = pncc->GetId(&szComponentId); ReleaseObj(pncc); if (SUCCEEDED(hr)) { LogPrintf(szComponentId); CoTaskMemFree(szComponentId); } } } if (SUCCEEDED(hr)) { hr = pncbi->GetLowerComponent(&pncc); if (SUCCEEDED(hr)) { hr = pncc->GetId(&szComponentId); if (SUCCEEDED(hr)) { LogPrintf(_T(" -> %s"), szComponentId); CoTaskMemFree(szComponentId); } ReleaseObj(pncc); } } ReleaseObj(pncbi); } LogPrintf(_T("\n")); if (hr == S_FALSE) { hr = S_OK; } return hr; }
//+--------------------------------------------------------------------------- // // Function: HrShowNetComponents // // Purpose: Display the list of installed components of the // specified class. // // Arguments: // pnc [in] pointer to INetCfg object // pguidClass [in] pointer to class GUID // // Returns: S_OK on success, otherwise an error code // // Notes: // HRESULT HrShowNetComponents(IN INetCfg* pnc, IN const GUID* pguidClass) { HRESULT hr=S_OK; PWSTR szInfId; PWSTR szDisplayName; DWORD dwcc; INetCfgComponent* pncc; INetCfgClass* pncclass; IEnumNetCfgComponent* pencc; ULONG celtFetched; hr = pnc->QueryNetCfgClass(pguidClass, IID_INetCfgClass, (void**)&pncclass); if (SUCCEEDED(hr)) { // get IEnumNetCfgComponent so that we can enumerate hr = pncclass->EnumComponents(&pencc); ReleaseObj(pncclass); while (SUCCEEDED(hr) && (S_OK == (hr = pencc->Next(1, &pncc, &celtFetched)))) { if (pguidClass == &GUID_DEVCLASS_NET) { // we are interested only in physical netcards // hr = pncc->GetCharacteristics(&dwcc); if (FAILED(hr) || !(dwcc & NCF_PHYSICAL)) { hr = S_OK; ReleaseObj(pncc); continue; } } hr = pncc->GetId(&szInfId); if (S_OK == hr) { hr = pncc->GetDisplayName(&szDisplayName); if (SUCCEEDED(hr)) { LogPrintf(_T("%-26s %s\n"), szInfId, szDisplayName); CoTaskMemFree(szDisplayName); } CoTaskMemFree(szInfId); } // we dont want to stop enumeration just because 1 component // failed either GetId or GetDisplayName, therefore reset hr to S_OK hr = S_OK; ReleaseObj(pncc); } ReleaseObj(pencc); } if (S_FALSE == hr) { hr = S_OK; } return hr; }