List Video and Audio capture devices

static HRESULT EnumerateDevices(REFGUID category, IEnumMoniker **ppEnum)
{
	// Create the System Device Enumerator.
	ICreateDevEnum *pDevEnum;
	HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL,
		CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pDevEnum));

	if (SUCCEEDED(hr))
	{
		// Create an enumerator for the category.
		hr = pDevEnum->CreateClassEnumerator(category, ppEnum, 0);
		if (hr == S_FALSE)
		{
			hr = VFW_E_NOT_FOUND;  // The category is empty. Treat as an error.
		}
		pDevEnum->Release();
	}
	return hr;
}

std::vector<CString> UpdatecameraLists()
{
	IMoniker *pMoniker = NULL;
	CString str;
	LPCTSTR buf;
	HRESULT hr;
	IEnumMoniker *pEnum;
	IPropertyBag *pPropBag;
	VARIANT var;


	hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);

	hr = EnumerateDevices(CLSID_VideoInputDeviceCategory, &pEnum);
	std::vector<CString> _camlist;

	if (SUCCEEDED(hr))
	{
		while (pEnum->Next(1, &pMoniker, NULL) == S_OK)
		{
			hr = pMoniker->BindToStorage(0, 0, IID_PPV_ARGS(&pPropBag));
			if (FAILED(hr))
			{
				pMoniker->Release();
				continue;
			}

			VariantInit(&var);

			// Get description or friendly name.
			hr = pPropBag->Read(L"Description", &var, 0);
			if (FAILED(hr))
			{
				hr = pPropBag->Read(L"FriendlyName", &var, 0);
			}
			if (SUCCEEDED(hr))
			{
				str.Format(L"%ls\n", var.bstrVal);
				buf = str;
				_camlist.push_back(str);
				//m_cameras.AddString(buf);
				VariantClear(&var);
			}

			hr = pPropBag->Write(L"FriendlyName", &var);

			// WaveInID applies only to audio capture devices.
			hr = pPropBag->Read(L"WaveInID", &var, 0);
			if (SUCCEEDED(hr))
			{
				printf("WaveIn ID: %d\n", var.lVal);
				VariantClear(&var);
			}

			hr = pPropBag->Read(L"DevicePath", &var, 0);
			if (SUCCEEDED(hr))
			{
				// The device path is not intended for display.
				printf("Device path: %S\n", var.bstrVal);
				VariantClear(&var);
			}

			pPropBag->Release();
			pMoniker->Release();
		}
		pEnum->Release();
	}
	CoUninitialize();

	return _camlist;
}