我正在C中开发COM代理对象,我的应用程序将使用它来调用需要管理权限的某些操作的UAC高程对话框.
该计划是使其导出一个函数,该函数使用指向具有可变数量参数的函数的指针,并在不同的上下文中执行它.这样一来,一个应用程序可以使用这个对象来执行一些具有管理员权限的动作,所有他们需要做的就是使用该对象并传递一个指向必须用所述权限执行的函数的指针.
这部分工作,调用CoCreateInstance很好,函数指针被传递,我的函数被执行.但是,当我使用CoCreateInstanceAsAdmin创建此对象的实例时,会出现问题;这里是代码:
HRESULT CoCreateInstanceAsAdmin(HWND hwnd,REFCLSID rclsid,REFIID riid,__out void ** ppv) { // Manual implementation of CreateInstanceAsAdmin CComPtr BindCtx; HRESULT hr = CreateBindCtx(0,&BindCtx); BIND_OPTS3 bo; memset(&bo,sizeof(bo)); bo.cbStruct = sizeof(bo); bo.grfMode = STGM_READWRITE; bo.hwnd = hwnd; bo.dwClassContext = CLSCTX_LOCAL_SERVER; hr = BindCtx->SetBindOptions(&bo); if (SUCCEEDED(hr)) { // Use the passed in CLSID to help create the COM elevation moniker string CComPtr Moniker; WCHAR wszCLSID[50]; WCHAR wszMonikerName[300]; StringFromGUID2(rclsid,wszCLSID,sizeof(wszCLSID) / sizeof(wszCLSID[0])); //Elevation:Administrator!new hr = StringCchPrintfW(wszMonikerName,sizeof(wszMonikerName)/sizeof(wszMonikerName[0]),L"Elevation:Administrator!new:%s",wszCLSID); if (SUCCEEDED(hr)) { // Create the COM elevation moniker ULONG ulEaten = 0; ULONG ulLen = (ULONG)wcslen(wszMonikerName); LPBC pBindCtx = BindCtx.p; hr = MkParseDisplayName(pBindCtx,wszMonikerName,&ulEaten,&Moniker); if (SUCCEEDED(hr) && ulEaten == ulLen) { // Use passed in reference to IID to bind to the object IDispatch * pv = NULL; hr = Moniker->BindToObject(pBindCtx,NULL,riid,ppv); } } } return hr; }
调用CoCreateInstanceAsAdmin失败,“类未注册”.
[HKEY_CLASSES_ROOT\COMsurrogate] @="COMsurrogate Class" [HKEY_CLASSES_ROOT\COMsurrogate\CurVer] @="COMsurrogate.1" [HKEY_CLASSES_ROOT\COMsurrogate\CLSID] @="{686B6F70-06AE-4dfd-8C26-4564684D9F9F}" [HKEY_CLASSES_ROOT\CLSID\{686B6F70-06AE-4dfd-8C26-4564684D9F9F}] @="COMsurrogate Class" "LocalizedString"="@C:\\Windows\\system32\\COMsurrogate.dll,-101" "DllSurrogate"="" [HKEY_CLASSES_ROOT\CLSID\{686B6F70-06AE-4dfd-8C26-4564684D9F9F}\ProgID] @="COMsurrogate.1" [HKEY_CLASSES_ROOT\CLSID\{686B6F70-06AE-4dfd-8C26-4564684D9F9F}\VersionIndependentProgID] @="COMsurrogate" [HKEY_CLASSES_ROOT\CLSID\{686B6F70-06AE-4dfd-8C26-4564684D9F9F}\InprocServer32] @="@C:\\windows\system32\COMsurrogate.dll" "ThreadingModel"="Apartment" [HKEY_CLASSES_ROOT\CLSID\{686B6F70-06AE-4dfd-8C26-4564684D9F9F}\NotInsertable] [HKEY_CLASSES_ROOT\CLSID\{686B6F70-06AE-4dfd-8C26-4564684D9F9F}\Programmable]
我想有一些注册表项丢失 – 这是我读到错误消息时得出的结论.但是,这个注册表项列表是在浏览MSDN和其他站点上的文档后编译的 – 所以我很确定没有任何错误.
我试图解决的这个问题之一是通过ATL来实现它(使得注册自动化).这是有效的,但问题是我不能通过一个功能指针到MIDL生成的函数原型.
我尝试使用VARIANT类型传递它:
v.vt = VT_PTR; void (*myptr)(void); myptr = &DoTheStuff; v.byref = myptr; hr = theElevated->CoTaskExecuter(0,v);
结果我得到“参数类型无效”.
有人对这个问题有所了解吗?也许我想要实现的是不可能通过设计?
我相信您所面临的问题是设计,窗口安全改进的意图是为了避免潜在的安全隐患.