0

当我尝试在以 SYSTEM 用户身份启动的进程中为全局隔离专区建议 ITfCompartmentEventSink 时,AdviseSink 失败并显示 E_FAIL。我尝试冒充普通用户,但似乎没有帮助。

并且隔间 GetValue 会成功,但 SetValue 也会因 E_FAIL 而失败。

但是,当该过程以普通用户身份启动时,AdviseSink 可以正常工作。

以下示例代码中的 AdviseSink 对于 SYSTEM 用户也失败。

Windows-classic-samples\Samples\Win7Samples\winui\tsf\tsfcompart\monitor.cpp

那么我是否必须以某种方式设置安全描述符或使用特定选项初始化 COM 库才能使其工作?

谢谢。

HRESULT CCompartmentMonitor::Initialize(    const GUID *pguidCompartment,
                                            PCOMPARTMENTMONITORPROC pCallback, 
                                            LPARAM lParam)
{
    if(!IsEqualGUID(m_guidCompartment, GUID_NULL))
    {
        //Initialize() has already been called
        return E_UNEXPECTED;
    }

    m_guidCompartment = *pguidCompartment;
    m_pCallback = pCallback;
    m_lParam = lParam;
    
    HRESULT         hr;
    ITfThreadMgr    *pThreadMgr;
    
    //create a thread manager object
    hr = CoCreateInstance(CLSID_TF_ThreadMgr, 
        NULL, 
        CLSCTX_INPROC_SERVER, 
        IID_ITfThreadMgr, 
        (void**)&pThreadMgr);
    
    if(SUCCEEDED(hr))
    {
        ITfCompartmentMgr   *pCompMgr;

        //get the global compartment manager
        hr = pThreadMgr->GetGlobalCompartment(&pCompMgr);
        if(SUCCEEDED(hr))
        {
            //get the Speech UI compartment 
            hr = pCompMgr->GetCompartment(m_guidCompartment, 
                &m_pCompartment);
            if(SUCCEEDED(hr))
            {
                ITfSource   *pSource;
                
                //install the advise sink
                hr = m_pCompartment->QueryInterface(IID_ITfSource, 
                    (LPVOID*)&pSource);
                if(SUCCEEDED(hr))
                {
                    hr = pSource->AdviseSink(IID_ITfCompartmentEventSink, 
                        (ITfCompartmentEventSink*)this,
                        &m_dwCookie);
                    // AdviseSink fails with E_FAIL
                }
                
                //if something went wrong, release the member interface
                if(FAILED(hr))
                {
                    m_pCompartment->Release();
                    m_pCompartment = NULL;
                }
            }
            
            //release the compartment manager
            pCompMgr->Release();
        }
        
        //release the thread manager
        pThreadMgr->Release();
    }

    return hr;
}
4

0 回答 0