C++ 你能在没有管理员的情况下注册directshow筛选器吗?
我想注册一个虚拟directshow源设备而不需要管理员。在另一篇文章中,我看到有人提到,你可以通过HKEY_CURRENT_用户而不是HKEY_classes_ROOT或HKEY_LOCAL_机器注册每个用户帐户的COM类。这很有效,我可以通过HKEY_CURRENT_USER\Software\Classes注册该类,而无需UAC 要显示源代码/筛选器,我需要调用C++ 你能在没有管理员的情况下注册directshow筛选器吗?,c++,winapi,com,directshow,C++,Winapi,Com,Directshow,我想注册一个虚拟directshow源设备而不需要管理员。在另一篇文章中,我看到有人提到,你可以通过HKEY_CURRENT_用户而不是HKEY_classes_ROOT或HKEY_LOCAL_机器注册每个用户帐户的COM类。这很有效,我可以通过HKEY_CURRENT_USER\Software\Classes注册该类,而无需UAC 要显示源代码/筛选器,我需要调用IFilterMapper2::RegisterFilter。如果没有UAC的特权,这将失败。(E_ACCESSDENIED常规访
IFilterMapper2::RegisterFilter
。如果没有UAC的特权,这将失败。(E_ACCESSDENIED常规访问被拒绝错误。
)
微软并不清楚调用RegisterFilter的实际作用。我知道它在HKEY\U CLASSES\U ROOT\CLSID\category CLSID\Instance\filter CLSID
下创建了一个注册表项,但其中一个键值是FilterData,它是一个二进制值,理论上应该与此结构匹配;但是数据没有完全对齐,所以他们也必须在其中写入其他数据
是否仍要在用户帐户级别注册筛选器?注册信息位于
HKEY\U LOCAL\U MACHINE
下,因此您必须拥有本地管理员帐户和提升的权限才能进行注册。首先您必须注册服务器:
STDAPI AMovieSetupRegisterServerOverride(CLSID clsServer, LPCWSTR szDescription, LPCWSTR szFileName, LPCWSTR szThreadingModel = L"Both", LPCWSTR szServerType = L"InprocServer32")
{
TCHAR achTemp[MAX_PATH];
OLECHAR szCLSID[CHARS_IN_GUID];
HRESULT hr = StringFromGUID2(clsServer, szCLSID, CHARS_IN_GUID);
HKEY hkey;
DWORD d;
wsprintf(achTemp, TEXT("Software\\Classes\\CLSID\\%ls"), szCLSID);
LONG lreturn = RegCreateKeyEx(HKEY_CURRENT_USER, (LPCTSTR)achTemp, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hkey, &d);
if (ERROR_SUCCESS != lreturn)
{
return AmHresultFromWin32(lreturn);
}
wsprintf(achTemp, TEXT("%ls"), szDescription);
lreturn = RegSetValue(hkey, (LPCTSTR)NULL, REG_SZ, achTemp, sizeof(achTemp));
if (ERROR_SUCCESS != lreturn)
{
RegCloseKey(hkey);
return AmHresultFromWin32(lreturn);
}
HKEY hsubkey;
wsprintf(achTemp, TEXT("%ls"), szServerType);
lreturn = RegCreateKeyEx(hkey, achTemp, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hsubkey, &d);
if (ERROR_SUCCESS != lreturn)
{
RegCloseKey(hkey);
return AmHresultFromWin32(lreturn);
}
wsprintf(achTemp, TEXT("%ls"), szFileName);
lreturn = RegSetValue(hsubkey, (LPCTSTR)NULL, REG_SZ, (LPCTSTR)achTemp, sizeof(TCHAR) * (lstrlen(achTemp) + 1));
if (ERROR_SUCCESS != lreturn)
{
RegCloseKey(hkey);
RegCloseKey(hsubkey);
return AmHresultFromWin32(lreturn);
}
wsprintf(achTemp, TEXT("%ls"), szThreadingModel);
lreturn = RegSetValueEx(hsubkey, TEXT("ThreadingModel"), 0L, REG_SZ, (CONST BYTE*)achTemp, sizeof(TCHAR) * (lstrlen(achTemp) + 1));
RegCloseKey(hkey);
RegCloseKey(hsubkey);
ASSERT(SUCCEEDED(hr));
return HRESULT_FROM_WIN32(lreturn);
}
STDAPI
AMovieSetupUnregisterServerOverride(CLSID clsServer)
{
OLECHAR szCLSID[CHARS_IN_GUID];
HRESULT hr = StringFromGUID2(clsServer, szCLSID, CHARS_IN_GUID);
TCHAR achBuffer[260];
wsprintf(achBuffer, TEXT("CLSID\\%ls"), szCLSID);
hr = EliminateSubKey(HKEY_CLASSES_ROOT, achBuffer);
return NOERROR;
}
这是从winsdk方法复制的,但修改为使用Software\Classes注册表以避免UAC:
AMovieSetupRegisterServer
然后,您可以使用以下代码注册过滤器(注意,我没有完全弄清楚如何序列化过滤器数据,所以我向UAC注册了它,检查了二进制数据是什么,然后手动以这种方式填充。如果您想自己序列化过滤器数据,您可以(方法FilterTemplate::LoadFilterData)
考虑到它在HKEY_LOCAL_MACHINE/Software/Classes/CLSID/下注册,我很确定系统枚举器会检查HKEY_Classes_ROOT/CLSID,除此之外,还有什么原因它不能工作,因为registerfilter函数是硬编码来引用本地机器路径的吗?如果我用und信息编写自己的注册表项er HKEY_当前用户而不是使用::RegisterFilter,因为它与本地计算机类合并,因为HKEY_类根目录不起作用吗?我认为COM注册信息可以进入HKCU,因此您将依赖COM实例化子系统(在CoCreateInstance内)而是从HKCU获取注册数据。这部分可以解决问题。问题是
RegisterFilter
将其他信息写入HKLM,最重要的是,DirectShow Intelligent Connect在那里查找这些信息,而不知道这些数据的一部分也可能在HKCU下。我明白你的意思了我试图这么说,我理解。我并不特别关心intelligent connect;但我认为intelligent connect不工作是系统枚举器未看到筛选器的副产品。我通过组策略设置审核,并使用事件查看器尝试查看正在写入的注册表值,从我的快速测试中可以看出上面提到的注册表值是唯一添加的键。我的理论是,如果我能找出它将REGFILTER2结构转换为二进制FilterData值的顺序,我就可以模拟本地用户的register filter函数FilterData值的格式是已知的(这些应该是序列化数据)。问题是这些值仍在HKLM下,而不是HKCU下。您需要访问权限才能写入这些值,即使您想使用RegisterFilter
@letmaik刚刚添加的。
// {ae7416c6-637d-4b8e-970d-24af9a1dd02a}
DEFINE_GUID(CLSID_EXAMPLE_GUID,
0xae7416c6, 0x637d, 0x4b8e, 0x97, 0x0d, 0x24, 0xaf, 0x9a, 0x1d, 0xd0, 0x2a);
HRESULT RegisterCurrentUser(REGFILTER2 rf)
{
TCHAR achTemp[MAX_PATH];
OLECHAR szCLSID[CHARS_IN_GUID];
HRESULT hr = StringFromGUID2(CLSID_EXAMPLE_GUID, szCLSID, CHARS_IN_GUID);
HKEY hkey;
wsprintf(achTemp, TEXT("Software\\Classes\\CLSID\\{860BB310-5D01-11d0-BD3B-00A0C911CE86}\\Instance\\%ls"), szCLSID);
hr = RegCreateKey(HKEY_CURRENT_USER, (LPCTSTR)achTemp, &hkey);
wsprintf(achTemp, TEXT("%ls"), szCLSID);
hr = RegSetValueEx(hkey, TEXT("CLSID"), 0L, REG_SZ, (CONST BYTE*) achTemp, sizeof(TCHAR) * (lstrlen(achTemp) + 1));
DWORD data[20];
data[0] = 0x00000002; //Version
data[1] = 0x00200000; //Merit
data[2] = 0x00000001; //if v===1, pin#
data[3] = 0x00000000; //if v==2, pin #
data[4] = 0x33697030;
data[5] = 0x08000000;
data[6] = 0x00000000;
data[7] = 0x00000001;
data[8] = 0x00000000;
data[9] = 0x00000000;
data[10] = 0x33797430;
data[11] = 0x00000000;
data[12] = 0x00000038;
data[13] = 0x00000048;
data[14] = 0x73646976;
data[15] = 0x00100000;
data[16] = 0xAA000080;
data[17] = 0x719B3800;
data[18] = 0x00000000;
data[19] = 0x00000000;
hr = RegSetValueEx(hkey, TEXT("FilterData"), 0L, REG_BINARY, (BYTE*)data, sizeof(data));
wsprintf(achTemp, TEXT("%ls"), L"Example Filter");
hr = RegSetValueEx(hkey, TEXT("FriendlyName"), 0L, REG_SZ, (CONST BYTE*) achTemp, sizeof(TCHAR) * (lstrlen(achTemp) + 1));
return hr;
}