187 lines
3.9 KiB
C++
187 lines
3.9 KiB
C++
|
||
#include <atlcomcli.h>
|
||
#include "GetCameraDeviceID.h"
|
||
#pragma comment(lib,"strmiids.lib")
|
||
|
||
//Converting a WChar string to a Ansi string
|
||
static string WChar2Ansi(LPCWSTR pwszSrc)
|
||
{
|
||
int nLen = WideCharToMultiByte(CP_ACP, 0, pwszSrc, -1, NULL, 0, NULL, NULL);
|
||
|
||
if (nLen <= 0) return string("");
|
||
|
||
char* pszDst = new char[nLen];
|
||
if (NULL == pszDst) return string("");
|
||
|
||
WideCharToMultiByte(CP_ACP, 0, pwszSrc, -1, pszDst, nLen, NULL, NULL);
|
||
pszDst[nLen - 1] = 0;
|
||
|
||
string strTemp(pszDst);
|
||
delete[] pszDst;
|
||
|
||
return strTemp;
|
||
}
|
||
static string ws2s(const wstring& inputws) { return WChar2Ansi(inputws.c_str()); }
|
||
/*
|
||
功能:通过设备的VID与PID获取对应的ID
|
||
入口参数:
|
||
[in] vid:设备VID
|
||
[in] pid:设备PID
|
||
返回值:
|
||
获取到的设备ID,-1:指定设备不存在
|
||
*/
|
||
int GetDeviceIDfromVIDandPID(string vid, string pid)
|
||
{
|
||
if (FAILED(CoInitialize(NULL)))
|
||
{
|
||
cout << "CoInitialize Failed ..." << endl;
|
||
return -1;
|
||
}
|
||
|
||
transform(vid.begin(), vid.end(), vid.begin(), ::tolower);
|
||
transform(pid.begin(), pid.end(), pid.begin(), ::tolower);
|
||
|
||
int id = 0;
|
||
ICreateDevEnum *pCreateDevEnum;
|
||
HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL,
|
||
CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, (void**)&pCreateDevEnum);
|
||
if (hr != NOERROR)
|
||
return -1;
|
||
|
||
ATL::CComPtr<IEnumMoniker> pEm;
|
||
hr = pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEm, 0);
|
||
if (hr != NOERROR)
|
||
return -1;
|
||
pEm->Reset();
|
||
|
||
ULONG cFetched;
|
||
IMoniker *pM;
|
||
while (hr = pEm->Next(1, &pM, &cFetched), hr == S_OK)
|
||
{
|
||
wstring str = L"";
|
||
wstring strVid, strPid;
|
||
int Count = 0;
|
||
|
||
IPropertyBag *pBag;
|
||
hr = pM->BindToStorage(0, 0, IID_IPropertyBag, (void **)&pBag);
|
||
if (SUCCEEDED(hr))
|
||
{
|
||
VARIANT var;
|
||
var.vt = VT_BSTR;
|
||
hr = pBag->Read(L"DevicePath", &var, NULL);
|
||
|
||
if (hr == 0)
|
||
{
|
||
while (var.bstrVal[Count] != 0x00)
|
||
{
|
||
str += var.bstrVal[Count];
|
||
Count++;
|
||
}
|
||
|
||
strVid = str.substr(str.find(L"vid_") + 4, 4);
|
||
strPid = str.substr(str.find(L"pid_") + 4, 4);
|
||
|
||
string tmpVid = ws2s(strVid);
|
||
string tmpPid = ws2s(strPid);
|
||
|
||
//cout << "Vid:" << tmpVid << " Pid:" << tmpPid << endl;
|
||
|
||
if (0 == strcmp(tmpVid.c_str(), vid.c_str()) && 0 == strcmp(tmpPid.c_str(), pid.c_str()))
|
||
{
|
||
return id;
|
||
break;
|
||
}
|
||
}
|
||
|
||
id++;
|
||
|
||
pBag->Release();
|
||
}
|
||
pM->Release();
|
||
}
|
||
return -1;
|
||
}
|
||
|
||
int EnumCameraDevices(vector<CameraDev> & cameras)
|
||
{
|
||
cameras.clear();
|
||
|
||
if (FAILED(CoInitialize(NULL)))
|
||
{
|
||
cout << "CoInitialize Failed ..." << endl;
|
||
return -1;
|
||
}
|
||
|
||
int id = 0;
|
||
ICreateDevEnum *pCreateDevEnum;
|
||
HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL,
|
||
CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, (void**)&pCreateDevEnum);
|
||
if (hr != NOERROR)
|
||
return -1;
|
||
|
||
ATL::CComPtr<IEnumMoniker> pEm;
|
||
hr = pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEm, 0);
|
||
if (hr != NOERROR)
|
||
return -1;
|
||
pEm->Reset();
|
||
|
||
ULONG cFetched;
|
||
IMoniker *pM;
|
||
while (hr = pEm->Next(1, &pM, &cFetched), hr == S_OK)
|
||
{
|
||
IPropertyBag *pBag;
|
||
hr = pM->BindToStorage(0, 0, IID_IPropertyBag, (void **)&pBag);
|
||
if (SUCCEEDED(hr))
|
||
{
|
||
CameraDev TmpCam;
|
||
TmpCam.devID = id;
|
||
|
||
VARIANT var;
|
||
var.vt = VT_BSTR;
|
||
hr = pBag->Read(L"DevicePath", &var, NULL);
|
||
if (hr == 0)
|
||
{
|
||
wstring str = L"";
|
||
wstring strVid, strPid;
|
||
int Count = 0;
|
||
while (var.bstrVal[Count] != 0x00)
|
||
{
|
||
str += var.bstrVal[Count];
|
||
Count++;
|
||
}
|
||
|
||
strVid = str.substr(str.find(L"vid_") + 4, 4);
|
||
strPid = str.substr(str.find(L"pid_") + 4, 4);
|
||
|
||
TmpCam.devVId = ws2s(strVid);
|
||
TmpCam.devPId = ws2s(strPid);
|
||
}
|
||
|
||
VARIANT var1;
|
||
var1.vt = VT_BSTR;
|
||
hr = pBag->Read(L"FriendlyName", &var1, NULL);
|
||
if (hr == 0)
|
||
{
|
||
wstring str = L"";
|
||
int Count = 0;
|
||
while (var1.bstrVal[Count] != 0x00)
|
||
{
|
||
str += var1.bstrVal[Count];
|
||
Count++;
|
||
}
|
||
|
||
TmpCam.devName = ws2s(str);
|
||
}
|
||
|
||
if (TmpCam.devName.find("screen-capture-recorder") == -1)
|
||
{
|
||
cameras.push_back(TmpCam);
|
||
id++;
|
||
}
|
||
|
||
pBag->Release();
|
||
}
|
||
pM->Release();
|
||
}
|
||
return id;
|
||
} |