未能在Windows七的Windows上创建高程com对象
题
我正在发展一个 com代理 C中的对象,我的应用程序将使用它来调用UAC高程对话框,以执行某些需要行政权利的操作。
该计划是使其导出一个函数,该函数将指针指向具有可变数量参数的函数,并在不同的上下文中执行它。这样,应用程序可以使用此对象对管理权执行某些操作,而他们需要做的就是使用该对象,并将其传递给必须使用上述权利执行的函数的指针。
这部分起作用,打电话 CROCEATEINSTANCE 顺利进行,传递功能指针并执行我的功能。但是,当我使用此对象的实例时 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, 0, 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 失败的“未注册”。
该对象通过创建以下注册表键进行注册(这是REG文件的正文)
[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生成的功能原型。
我试图使用 变体 类型:
v.vt = VT_PTR;
void (*myptr)(void);
myptr = &DoTheStuff;
v.byref = myptr;
hr = theElevated->CoTaskExecuter(0, v);
结果,我得到了“无效的参数类型”。
有人可以阐明这个主题吗?也许我试图实现的目标是不可能的?
没有正确的解决方案
其他提示
我相信您遇到的问题是设计,并且窗户安全改进的意图是有助于避免潜在的安全风险。
微软真的不希望您提升特权,如果它可以阻止您这样做。如果Windows甚至是一个相当安全的系统,则执行任意功能作为特权用户都不应以任何方式都不容易。您可能可能会尝试使用令牌模仿其他用户并以这种方式获得更好的访问权限,但即使如此,这也是一个范围。如果我没记错的话,用户模仿甚至无法保证您将获得完全访问权限。在这种情况下,最好的解决方案只是使用超级用户帐户并正确请求正确的特权。