Text Services Framework AdviseSink failed for global compartment if application runs as SYSTEM user

111 Views Asked by At

When I try to advise a ITfCompartmentEventSink for a global compartment in a process that has started as a SYSTEM user, the AdviseSink fails with E_FAIL. I tried with impersonating as normal user, but it doesn't seem to help.

And the compartment GetValue will succeed, but SetValue will also fail with E_FAIL.

However when the process is started as normal user, the AdviseSink works correctly.

The AdviseSink in following sample code also fails for SYSTEM user.

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

So do I have to somehow set a security descriptor or initialize COM library with a particular option to make this work?

Thanks.

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;
}
0

There are 0 best solutions below