mshtml调用HideUI后FAST_FAIL_INCORRECT_STACK失败

mshtml fails with FAST_FAIL_INCORRECT_STACK after calling HideUI

本文关键字:FAIL INCORRECT STACK 失败 FAST 调用 HideUI mshtml      更新时间:2023-10-16

我已经编写了IDocHostUIHandler的实现,以便为JavaScript提供一个嵌入IE11控件的外部对象。一个类提供了IUnknown, IDispatch和IDocHostUIHandler的实现。IDispatch接口作为外部对象返回给GetExternal。所有对IDocHostUIHandler的调用,除了对原始处理程序的GetExternal调用。

例如,HideUI被实现为:

HRESULT STDMETHODCALLTYPE mtQtWebBrowserDocHandler::HideUI(void)
{
    qDebug("Calling HideUI");
    if(m_defaultDocHostUIHandler)
    {
        HRESULT hr = m_defaultDocHostUIHandler->HideUI();
        qDebug("Called HideUI");
        return hr;
    }
    return E_NOTIMPL;
}

相同的模式用于所有其他方法,除了GetExternal,它是:

HRESULT STDMETHODCALLTYPE mtQtWebBrowserDocHandler::GetExternal(IDispatch **ppDispatch)
{
    qDebug("Calling GetExternal");
    *ppDispatch = (IDispatch*)this;
    return S_OK;
}
在JavaScript中,我执行以下命令:
var r1 = window.external.Test1();

这将导致以下调试输出尾部:

'2016-10-10 11:09:19'    DEBUG  Calling GetHostInfo
'2016-10-10 11:09:19'    DEBUG  Called GetHostInfo
'2016-10-10 11:09:19'    DEBUG  mtQtWebBrowserDocHandler Release (ref now = 2)
'2016-10-10 11:09:19'    DEBUG  mtQtWebBrowserDocHandler AddRef (ref now = 3)
'2016-10-10 11:09:19'    DEBUG  Calling GetHostInfo
'2016-10-10 11:09:19'    DEBUG  Called GetHostInfo
'2016-10-10 11:09:19'    DEBUG  mtQtWebBrowserDocHandler Release (ref now = 2)
'2016-10-10 11:09:19'    DEBUG  Calling GetExternal
'2016-10-10 11:09:21'    DEBUG  mtQtWebBrowserDocHandler - IDispatch requested
'2016-10-10 11:09:21'    DEBUG  mtQtWebBrowserDocHandler AddRef (ref now = 3)
'2016-10-10 11:09:21'    DEBUG  mtQtWebBrowserDocHandler Release (ref now = 2)
'2016-10-10 11:09:21'    DEBUG  Calling ShowUI
'2016-10-10 11:09:21'    DEBUG  Called ShowUI
'2016-10-10 11:09:21'    DEBUG  Calling HideUI
'2016-10-10 11:09:21'    DEBUG  Called HideUI

HideUI的最终返回导致INT 29h错误,ecx = FAST_FAIL_INCORRECT_STACK。期望的堆栈是0x18D9C4,实际堆栈是0x18D9A4,差异为0x20。

我完全迷惑了。其他调用我的接口工作正常,它没有任何区别,如果我只是返回E_NOTIMPL从我的HideUI的实现。什么可能导致堆栈不平衡?

GetExternal函数中,您返回一个接口指针,而不增加引用计数,这将导致引用计数不匹配。一个更好的实现是:

HRESULT STDMETHODCALLTYPE mtQtWebBrowserDocHandler::GetExternal(IDispatch **ppDispatch)
{
    qDebug("Calling GetExternal");
    *ppDispatch = (IDispatch*)this;
    this->AddRef();
    return S_OK;
}

或者在这里使用QueryInterface。如果这是ATL, InternalQueryInterface。我怀疑这是你的错误的原因,因为你有一个引用的对象,可能已被销毁,由于更多的Release调用比AddRef调用。

答案似乎是,当mshtml由WebBrowser控件托管时,我正在浏览器文档上使用ICustomDoc。这显然不是个好主意!相反,您应该使用WebBrowser控件提供的现有站点。我在这里找到了一个实现IDocHostUI的正确方法的例子https://github.com/FastSpring/FsprgEmbeddedStoreWinMFC,它非常有帮助。