locked
IHttpSecurity::GetWindow is crashing when trying to handle certificate errors

    Question

  • Hi,

    I am trying to use CAxWindow with IWebBrowser2 and IServiceProvider and IHttpSecuirty.

    My target is to handle the Certificate validation alerts/errors using IHttpSecurity::OnSecurityProblem().

    My code flow is like this, I didn't copy the error handling code -

    ///////////////////

    CAxWindow axwnd;

    // Create a child window.

    m_wndChild.Create(m_hWnd, rect2, NULL, WS_CHILD | WS_VISIBLE | WS_BORDER, 0, 1);

    // Attach the child window to the CAxWindow so we can access the  host that subclasses the child window.

    axwnd.Attach(m_wndChild);

    CComPtr<IUnknown> spControl;

    HRESULT hr = AtlAxCreateControl(OLESTR("Shell.Explorer.2"),  m_wndChild.m_hWnd , NULL,  NULL );

    hr = axwnd.QueryControl(&spControl);

    DispEventAdvise(spControl, &__uuidof(DWebBrowserEvents2));

    hr = spControl.QueryInterface(&m_pWB);

    //Create instance of my IServiceProvider implementation

    m_pWBServiceProvider = new CWBServiceProvider(&axwnd);

    IObjectWithSite* pObjWtSite = NULL;

    HRESULT hRes = axwnd.QueryHost(&pObjWtSite);

    pObjWtSite->SetSite((IUnknown*)m_pWBServiceProvider);

    ///////////////////////////////

    I also implemented IHttpSecurity interface.

    My IServiceProvider::QueryService() is getting called for IWindowForBindingUI and IHttpSecurity IIDs.

    But when IHttpSecurity::GetWindow() is getting called, I am not able to assign anything to phwnd param.

    The app is crashing even if I return E_NOTIMPL.

     

    What am I doing wrong? Can I get my IHttpSecurity::OnSecurityProblem() called with this implementation.

    My final goal is to bypass the Certificate validation alerts by handling OnSecurityProblem.

    Any inputs is appreciated and if there is another way to achieve this, please let me know.

    Thanks in advance,

    --Kumar Talinki

    Saturday, June 26, 2010 1:45 AM

Answers

All replies

  • Kumar Talinki wrote:

    I also implemented IHttpSecurity interface.
    My IServiceProvider::QueryService() is getting called for  IWindowForBindingUI and IHttpSecurity IIDs.
    But when IHttpSecurity::GetWindow() is getting called, I am not able  to assign anything to phwnd param.

    IHttpSecurity doesn't have a method named GetWindow.

    Show what CWBServiceProvider implementation looks like.


    Igor Tandetnik

    Saturday, June 26, 2010 2:10 AM
  • Thanks Igor.

    I am using VC++ 6.0.

    IHttpSecurity is derived from IWindowForBindingUI.

    And IWindowForBindingUI contains GetWindow(). If I dont implement GetWindow() the code is not getting compiled.

    Here is my WBServiceProvider implementation.

    Thanks in advance,

    Kumar

    ////////////////////////////////////////////////////////////////////////

    //CWBServiceProvider

    /////////////////////////////////////////////////////////////////////////

    class CWBServiceProvider : public IServiceProvider

    {

    public:

    CWBServiceProvider(CAxWindow*);

    ~CWBServiceProvider();

     

        // IUnknown

        ULONG STDMETHODCALLTYPE AddRef();

        ULONG STDMETHODCALLTYPE Release();

        STDMETHODIMP QueryInterface(REFIID iid, void ** ppvObject);

     

    //QueryService

    STDMETHODIMP QueryService(REFGUID guidService,REFIID riid,void **ppv);

    private:

    ULONG m_ulRefCnt;

    CAxWindow* m_pWnd;

    CWBHttpSecurity* m_pWBHttpSecurity;

    };

     

    CWBServiceProvider::CWBServiceProvider(CAxWindow* pBW)

    {

    m_ulRefCnt = 1;

    m_pWnd = pBW;

    m_pWBHttpSecurity = new CWBHttpSecurity(pBW);

    }

     

    CWBServiceProvider::~CWBServiceProvider() 

    {

    }

     

    STDMETHODIMP CWBServiceProvider::QueryInterface(REFIID iid, void ** ppvObject)

    {

        if(ppvObject == NULL) return E_INVALIDARG;

        *ppvObject = NULL;

    //IID_IUnknown

    if(iid == IID_IUnknown)

    *ppvObject = (IUnknown *)this;

    //IID_IServiceProvider

    if(iid == IID_IServiceProvider)

    *ppvObject = (IServiceProvider *)this;

     

        if(*ppvObject == NULL) return E_NOINTERFACE;

        AddRef();

        return S_OK;

    }

     

    ULONG STDMETHODCALLTYPE CWBServiceProvider::AddRef()

    {

    return ++m_ulRefCnt; 

    }

     

    ULONG STDMETHODCALLTYPE CWBServiceProvider::Release()

    {

    if(--m_ulRefCnt == 0)

    delete this;

     

    return m_ulRefCnt;

    }

     

    //Many services are queried from this function

    STDMETHODIMP CWBServiceProvider::QueryService(REFGUID guidService, REFIID riid, void **ppv)

    {

    //IID_IServiceProvider

    if(riid == IID_IServiceProvider)

    {

    *ppv = (IServiceProvider*) m_pWBHttpSecurity;

    return S_OK; 

    }

    else

    if(riid == IID_IWindowForBindingUI) //QS

    {

    *ppv = (IWindowForBindingUI*) m_pWBHttpSecurity;

    return S_OK; 

    }

    else if(riid == IID_IHttpSecurity) //QS

    {

    *ppv = (IHttpSecurity*) m_pWBHttpSecurity;

    return S_OK;

    }

    *ppv = NULL;

        return E_NOINTERFACE;

    }

    Sunday, June 27, 2010 8:34 AM
  • Kumar Talinki wrote:

    STDMETHODIMP CWBServiceProvider::QueryService(REFGUID guidService,  REFIID riid, void **ppv)
    {
    //IID_IServiceProvider
    if(riid == IID_IServiceProvider)

    QueryService is supposed to branch on guidService, not riid. You are  supposed to use guidService to figure out what service is requested,  then QueryInterface the corresponding object for riid interface. It is  only accidentally that guidService and riid may be the same.

    {
    *ppv = (IServiceProvider*) m_pWBHttpSecurity;
    return S_OK;

    QueryService must AddRef the pointer it returns. You are undercounting  references. This is probably the cause of the crash - some objects being  destroyed prematurely.


    Igor Tandetnik

    Sunday, June 27, 2010 1:38 PM
  • Igor,

    thanks again for your valuable inputs.

    I changed QueryService to the following code, to branch off of guidService and not riid, when I do that, QueryService is not getting called for

    guidService == IID_IWindowForBindingUI

    guidService == IID_IServiceProvider

    guidService == IID_IHttpSecurity

    What am I missing? I can send you the whole application sources for you to take a look at.

    Please let me know your email id and I can send you the sources, its a sample application of 20KB zip file.

    thanks in advance,

    --Kumar 

    STDMETHODIMP CWBServiceProvider::QueryService(REFGUID guidService, REFIID riid, void **ppv)

    {

    //IID_IServiceProvider

    if(guidService == IID_IServiceProvider)

    {

    *ppv = (IServiceProvider*) this;

    return S_OK; 

    }

    else

    if(guidService == IID_IWindowForBindingUI) //QS

    {

    *ppv = (IWindowForBindingUI*) m_pWBHttpSecurity;

    m_pWBHttpSecurity->AddRef();

    return S_OK; 

    }

    else if(guidService == IID_IHttpSecurity) //QS

    {

    *ppv = (IHttpSecurity*) m_pWBHttpSecurity;

    m_pWBHttpSecurity->AddRef();

    return S_OK;

    }

    *ppv = NULL;

        return E_NOINTERFACE;

    }

    Sunday, June 27, 2010 7:26 PM
  • Kumar Talinki wrote:

    I changed QueryService to the following code, to branch off of  guidService and not riid, when I do that, QueryService is not
    getting called for

    guidService == IID_IWindowForBindingUI

    What is it being called for, then?

    What am I missing? I can send you the whole application sources for  you to take a look at.

    Ok, I'll look at it. itandetnik@mvps.org

    STDMETHODIMP CWBServiceProvider::QueryService(REFGUID guidService,  REFIID riid, void **ppv)

    {
    //IID_IServiceProvider

    if(guidService == IID_IServiceProvider)
    {
    *ppv = (IServiceProvider*) this;

    You aren't supposed to assume that the interface requested is  IServiceProvider. You are supposed to QueryIterface yourself for riid.  Something like this:

    IUnknown* service = NULL;

    if (guidService == IID_IServiceProvider) {
      service = this;
    } else if (guidService == IID_IWindowForBindingUI ||
                   guidService == IID_HttpSecurity) {
      service = m_pWBHttpSecurity;
    }

    if (service) {
      return service->QueryInterface(riid, ppv);
    }
    return E_NOINTERFACE;


    Igor Tandetnik

    Sunday, June 27, 2010 7:42 PM
  • Kumar Talinki wrote:

    I am trying to use CAxWindow with IWebBrowser2 and IServiceProvider  and IHttpSecuirty.

    Right after creating the control, navigate it to about:blank. Right  after that, navigate it to the page you wanted to go to. It's a known  problem that IServiceProvider doesn't work for the very first  navigation.

    When I did that in your sample, OnSecurityProblem was happily called. In  fact, it entered an infinite loop (since you always return RPC_E_RETRY  without actually remedying the problem, so the handler is called right  back).


    Igor Tandetnik

    Sunday, June 27, 2010 11:48 PM
  • Igor,

    thanks for info.

    Have you made any changes to my code, other than adding Navigate call to about:Blank?

    I added Navigate call to about:blank as followes

    pChild->m_pWB->put_RegisterAsBrowser(VARIANT_TRUE);

    pChild->m_pWB->Navigate(CComBSTR(_T("about:blank")), NULL, NULL, NULL, NULL);

    pChild->m_pWB->Navigate(CComBSTR(_T("https://192.168.159.130/Reporting/login/login.php")), NULL, NULL, NULL, NULL);


    But, my QueryService is not getting called for guidService ==  IServiceProvider or IHttpSecurity or IWindowForBindingUI 

    I am not sure how it is working fine in your environment?

    Whats your build environment, which version of VC and do you have any Platform SDK installed?

    In  fact, it entered an infinite loop (since you always return RPC_E_RETRY  without actually remedying the problem, so the handler is called right  back

    What do you mean by remedying? What is the correct return value I can return to avoid displaying the certificate security alert to the user?

     

    thank you so much,

    Kumar Talinki

    Monday, June 28, 2010 8:15 AM
  • Kumar Talinki wrote:

    Have you made any changes to my code, other than adding Navigate call  to about:Blank?

    I changed your original navigation to about:blank, and added a  WM_NCRBUTTONDOWN handler to perform a navigation to https://google.co.uk  (which happens to produce certificate error; the IP address you had  doesn't work for me, naturally). This way I could trigger the "real"  navigation by right-clicking the title bar.

    pChild->m_pWB->Navigate(CComBSTR(_T("about:blank")), NULL, NULL, NULL,  NULL);
     pChild->m_pWB->Navigate(CComBSTR(_T("https://192.168.159.130/Reporting/lo gin/login.php")), NULL, NULL, NULL, NULL);

    You need to wait for DocumentComplete event after navigating to  about:blank and before the next navigation.

    In fact, it entered an infinite loop (since you always return  RPC_E_RETRY without actually remedying the problem, so the handler
    is called right back


    What do you mean by remedying? What is the correct return value I can  return to avoid displaying the certificate security alert
    to the user?

    There doesn't seem to be a return value that does what you want. It  appears your choice is to either abort the navigation, or show the  dialog.

    If suppressing the dialog is all you want, try simply calling  IWebBrowser::put_Silent(VARIANT_TRUE) during initialization. This is  supposed to suppress all error messages and other dialogs. But I'm not  sure if this means automatically ignoring the errors, or automatically  aborting the navigation on any error.


    Igor Tandetnik

    Monday, June 28, 2010 12:06 PM
  • Hi Igor,

    I aslo added the navigation to about:blank and then to my IP Address.

    I had to change the GetWindow() implementation to assign GetDesktopWindow() return to phwnd.

    Then I started seeing the right calls.

    I am able to bypass the certificate security alerts when I return S_OK from IHttpSecurity::OnSecurityProblem().

    If I return E_ABORT the navigation is getting aborted and for S_FALSE the security alerts are getting displayed and for SOK the security alerts are suppressed.

    thank you so much for valueble help.

    I was also looking at your APP development tool kit, but the link for sources is not not valid anymore.

    http://itandetnik.150m.com/PassthruAPP.zip

    Whats the latest working link for the APP sources?

    thanks,

    Kumar

    Monday, June 28, 2010 10:37 PM
  • Kumar Talinki wrote:

    I was also looking at your APP development tool kit, but the link for  sources is not not valid anymore.

    http://itandetnik.150m.com/PassthruAPP.zip

    http://home.roadrunner.com/~itandetnik/PassthruAPP.zip

    You may want to use the copy from Google Gears:

    http://www.google.com/codesearch/p?hl=en#nJHaZQ1IJ84/trunk/third_party/ passthru_app/

    My original code is pretty old, developed with VC6. Google updated it to  work with IE7 and to build with modern MSVC versions. Note that mine is  public domain, while theirs is licensed under Apache license, in case it  matters.


    Igor Tandetnik

    Monday, June 28, 2010 10:48 PM
  • thanks Igore
    Tuesday, June 29, 2010 8:22 PM
  • Igore,

    how can I obtain certificate information? I would like to inspect the certificate fields and bypass the security warnings as needed. Is the IHttpSecurity::OnSecurityProblem is the right place to place this functionality?

    Which callback or interface gets the actual certificate?

     

    thanks,

    Kumar

    Thursday, July 22, 2010 8:32 PM
  • Kumar Talinki wrote:

    how can I obtain certificate information? I would like to inspect the  certificate fields and bypass the security warnings as
    needed. Is the IHttpSecurity::OnSecurityProblem is the right place to  place this functionality?

    I don't know of any way to get raw certificate - say, in the form of  CERT_CONTEXT - out of WinInet (which must have it internally, since it  knows how to display it in a dialog). The closest you get is  IWinInetInfo::QueryOption with INTERNET_OPTION_SECURITY_CERTIFICATE or  INTERNET_OPTION_SECURITY_CERTIFICATE_STRUCT, which gives you a limited  information about the certificate.


    Igor Tandetnik

    Thursday, July 22, 2010 8:48 PM
  • Thanks Igore.

    I have been playing with InternetQueryOption(INTERNET_OPTION_SECURITY_CERTIFICATE).

    I added the following code to my IHttpSecurity::OnSecurity() implementation

    HINTERNET hInternet = InternetOpen(NULL, INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, INTERNET_FLAG_ASYNC);

    InternetQueryOption(hInternet, INTERNET_OPTION_SECURITY_CERTIFICATE, pBuf, &dwBufLen);

     

    InternetQueryOption is failing with errorcode 12018 (ERROR_INTERNET_INCORRECT_HANDLE_TYPE)

    Am I calling the InternetOpen with the correct parameters?

    Can I call InternetOpen and InternetQueryOption in IHttpSecurity::OnSecurity() ?

     

    Thanks in advance,

    Kumar

     

     

     

     

    Thursday, July 22, 2010 10:57 PM
  • Kumar Talinki wrote:

    I have been playing with  InternetQueryOption(INTERNET_OPTION_SECURITY_CERTIFICATE).

    I added the following code to my IHttpSecurity::OnSecurity()  implementation

    HINTERNET hInternet = InternetOpen(NULL, INTERNET_OPEN_TYPE_DIRECT,  NULL, NULL, INTERNET_FLAG_ASYNC);

    InternetQueryOption(hInternet, INTERNET_OPTION_SECURITY_CERTIFICATE,  pBuf, &dwBufLen);

    You can't just call it on any random handle - you need to call it on the  handle which actually performed HTTPS transaction. Note that mentioned  IWinInetInfo::QueryOption, not InternetQueryOption.

    But I just realized I was thinking about an APP (where IWinInetInfo  would be available), whereas you have an application hosting WebBrowser  control. In this case, I don't know of any way to get even as little as  what INTERNET_OPTION_SECURITY_CERTIFICATE would return.


    Igor Tandetnik

    Thursday, July 22, 2010 11:57 PM
  • Igor,

    I am calling InternetOpen to a handle to internet connection. See my InternetOpen call before calling InternetQueryInfo. And I am using the HINTERNET that is returned from InternetOpen. I can try using IWinInetInfo.

    It is not clear from your reply that can we or can't we get any CERTIFICATE INFO with in an Application that hosts IWebBrowser control?

     

    thanks,

    Kumar

    Friday, July 23, 2010 2:19 AM
  • Kumar Talinki wrote:

    I am calling InternetOpen to a handle to internet connection. See my  InternetOpen call before calling InternetQueryInfo.

    You didn't create any connection. How could you, when you didn't even  specify any URL anywhere? Connection to what, exactly?

    It is not clear from your reply that can we or can't we get any  CERTIFICATE INFO with in an Application that hosts IWebBrowser
    control?

    Which part of "I don't know of any way" did you find unclear?


    Igor Tandetnik

    Friday, July 23, 2010 2:45 AM
  • Thanks Igor. Sorry for the confusion. I was trying to confirm what you are saying. Its very concerning that there is no known way to get the certificate info for the active HTTPS session.

    Is there a way to access / connect to the HTTPS session that is active and get info from the HTTPS session?

    thanks,

    Kumar

    Friday, July 23, 2010 5:52 PM
  • Igor,

    how can I obtain IWinInetInfo from CAxWindow or IWebBrowser2 control?

    Do I need to implement IBindStatusCallback? If I need to what is the flow?

    thanks in advance,

    -Kumar

     

    Friday, July 23, 2010 10:33 PM
  • Kumar Talinki wrote:

    how can I obtain IWinInetInfo from CAxWindow or IWebBrowser2 control?

    I don't know. I don't think it's possible: IWinInetInfo pertains to one  HTTP operation, but the browser juggles many of them in the course of  downloading a page.

    You could install an Asynchronous Pluggable Protocol (APP) handler,  perhaps one based on my code. This way, you get to watch every  individual HTTP request. You can then query for IWinInetInfo off the  real APP.


    Igor Tandetnik

    Friday, July 23, 2010 10:48 PM
  • Hi Igor,

    I am not able figure out how I can use PassthruAPP for getting the CERT_CONTEXT.

    What files do I need include in my project and what classes I can use?

     

    Another Q is, from the CAxWindow-IWebBrowserControl2 displayed page, Java Script is launching an IE browser window.

    What kind of callbacks I can get in my CAxWindow-IWebBrowserControl2 application?

    Can I have my IHttpSecurity called for the child IE Browser Window? so that I can suppress security alerts?

    Let me know if you know any way to do this?

     

    thanks in advance,

    Kumar

    Wednesday, August 4, 2010 1:58 AM
  • Kumar Talinki wrote:

    I am not able figure out how I can use PassthruAPP for getting the  CERT_CONTEXT.

    You can't, not to my knowledge. Like I said, the best you can have is  what INTERNET_OPTION_SECURITY_CERTIFICATE[_STRUCT] reports.

    Another Q is, from the CAxWindow-IWebBrowserControl2 displayed page,  Java Script is launching an IE browser window.

    What kind of callbacks I can get in my CAxWindow-IWebBrowserControl2  application?

    None. That's a separate process, completely unrelated to yours.

    See NewWindow2 event. By handling it, you can create your own window  hosting WebBrowser control, and have the same amount of control you have  over your main window.


    Igor Tandetnik

    Wednesday, August 4, 2010 2:21 AM
  • Thanks Igor.

    If we create my own child window (CAxWindow with IWebBrowser2), does it automatically navigate to the target URL or do we need to call Navigate explicitly?

    By launching my own child window, I can have my IHttpSecurity implementation to get  called back for the child window.

    But I am unable to set window size and title bar of the child window.

    OnOnNewWindow2() does not give us the target URL.

    --

    If I use the IE Browser Window for child windows, size and tab seems to be working good, but I cannot use my IHttpSecurity implementation to suppress security alerts.

    If launch child IE Browser window in OnnewWondow2  using the following code, a blank IE Browser window is getting displayed and not navigating to the target URL.

    Is my implementation correct? 

    Can I get the IDispatch* for the hosting application of Browser control?

    Can I get the IObjectWithSite of the hosting application of the child window, so that I can set the IServiceProvider? 

     

    OnNewWindow2(IDispatch **ppDisp,VARIANT_BOOL *Cancel)

    {

    *Cancel = VARIANT_TRUE;

    IWebBrowser2*    pBrowser2;

    HRESULT hr = S_OK;

    CoCreateInstance(CLSID_InternetExplorer, NULL, CLSCTX_LOCAL_SERVER, IID_IWebBrowser2, (void**)&pBrowser2);

    if (pBrowser2)

    {

    pBrowser2->put_Visible(VARIANT_TRUE);

    hr = pBrowser2->QueryInterface(IID_IDispatch, (void**)ppDisp); 

    }

    }

    thanks in advance, 

    Kumar

    Thursday, August 5, 2010 6:59 PM
  • Kumar Talinki wrote:

    If we create my own child window (CAxWindow with IWebBrowser2), does  it automatically navigate to the target URL or do we need to
    call Navigate explicitly?

    If you create a window with WebBrowser in it, and return its pointer via  an [out] parameter of NewWindow2, it will be automatically navigated.

    By launching my own child window, I can have my IHttpSecurity  implementation to get called back for the child window.

    The same code that works for the original browser would work for this  new one.

    But I am unable to set window size and title bar of the child window.

    For size, http://support.microsoft.com/kb/259963. For title, handle  TitleChange event.

    OnOnNewWindow2() does not give us the target URL.

    Correct.

    You could also use NewWindow3 - works like NewWindow2, but also comes  with the URL. If I recall correctly, only IE7 and up fire it.

    If I use the IE Browser Window for child windows, size and tab seems  to be working good, but I cannot use my IHttpSecurity
    implementation to suppress security alerts.

    Yes - it's a separate process.

    If launch child IE Browser window in OnnewWondow2 using the following  code, a blank IE Browser window is getting displayed and
    not navigating to the target URL.

    Is my implementation correct?

    You are cancelling the navigation, by setting *Cancel to true. Don't do  that.

    Can I get the IDispatch* for the hosting application of Browser  control?

    What hosting application? I don't understand this question.

    Can I get the IObjectWithSite of the hosting application of the child  window, so that I can set the IServiceProvider?

    Again, what is this "hosting application" you speak of?


    Igor Tandetnik

    Thursday, August 5, 2010 7:59 PM
  • Igor,

    thanks for your answers. when I say, hosting application, in case of IE browser, it is IE hosting webbrowser control.

    In case of my child window, child window is hosting the web browser control.

    I was trying to ask if I open the URL with child IE Browser, can I get IObjectWithSite* for IE Browser?

    I am trying to use JDIC (C++ -> Java) with Java applet console.

    And I am running in to issues with the child window.

    Child window gets displayed and OnBeforeNavigate is also getting called with the right target URL.

    The target URL is getting displayed if I have a MessageBox in OnBeforeNavigate(), otherwise the child window is frozen and the web page is not displayed.

    I can send the code if you wanna take a look.

    Thanks,

    Kumar

     

     

     

    Friday, August 6, 2010 9:43 PM
  • Kumar Talinki wrote:

    thanks for your answers. when I say, hosting application, in case of  IE browser, it is IE hosting webbrowser control.

    IE doesn't host WebBrowser controls. IE is an independent distinct  implementation of IWebBrowser2 interface.

    I was trying to ask if I open the URL with child IE Browser, can I get  IObjectWithSite* for IE Browser?

    IE doesn't implement IObjectWithSite, to my knowledge.

    I am trying to use JDIC (C++ -> Java) with Java applet console.

    And I am running in to issues with the child window.

    Child window gets displayed and OnBeforeNavigate is also getting  called with the right target URL.

    The target URL is getting displayed if I have a MessageBox in  OnBeforeNavigate(), otherwise the child window is frozen and the
    web page is not displayed.

    Are you creating the child window on a separate thread, by any chance?  Does this thread run a message loop? From your description, it sounds  like you don't pump messages for the new window.


    Igor Tandetnik

    Friday, August 6, 2010 9:56 PM
  • How does displaying a MessageBox can fix the problem of repainting?

    Yes I am not creating the child window in a separate thread.

     

    Friday, August 6, 2010 11:06 PM
  • Kumar Talinki wrote:

    How does displaying a MessageBox can fix the problem of repainting?

    MessageBox, and indeed any modal dialog, spins its own message pump.  That's how your windows still manage to paint themselves even though  MessageBox (or DialogBox) call doesn't return until the dialog is  dismissed.

    Yes I am not creating the child window in a separate thread.

    Any UI thread must run a message pump.


    Igor Tandetnik

    Friday, August 6, 2010 11:55 PM
  • Igor,

    how can I create a UI thread for the child window? Sorry I am not very familiar with this.

    If you can point me to KB or a sample to do this kind of thing, that would be awesome.

    My Child window is implementation looks like  

    class CChildWindow : public CWindowImpl<CChildWindow>

    {

    public:

        BEGIN_MSG_MAP(CChildWindow)

        END_MSG_MAP()

    };

     

    class CBrowserFrameWindow : public CWindowImpl<CBrowserFrameWindow, CWindow, CFrameWinTraits>,

    public IDispEventImpl<1, CBrowserFrameWindow, &__uuidof(DWebBrowserEvents2), &LIBID_SHDocVw, 1, 0>

    {

    CChildWindow m_wndChild;

    CAxWindow m_axwnd;

    CComPtr<IWebBrowser2> m_pWB; DECLARE_MAINFRAME_WND_CLASS("MainWindow", CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS, COLOR_WINDOW, 0) BEGIN_MSG_MAP(CBrowserFrameWindow) MESSAGE_HANDLER(WM_CREATE, OnCreate) MESSAGE_HANDLER(WM_DESTROY, OnDestroy) MESSAGE_HANDLER(WM_SIZE, OnSize) END_MSG_MAP() BEGIN_SINK_MAP(CBrowserFrameWindow) SINK_ENTRY_EX(1, __uuidof(DWebBrowserEvents2), DISPID_BEFORENAVIGATE2, OnBeforeNavigate) END_SINK_MAP()

    }

     

    LRESULT CBrowserFrameWindow::OnCreate(UINT, WPARAM, LPARAM, BOOL&)

    {

    RECT rect;

    GetClientRect(&rect);

     

    RECT rect2;

    rect2 = rect;    

    m_wndChild.Create(m_hWnd, rect2, NULL, WS_CHILD | WS_VISIBLE | WS_BORDER, 0, 1);

    // Attach the child window to the CAxWindow so we can access the 

    // host that subclasses the child window.

    m_axwnd.Attach(m_wndChild);

    if (m_axwnd.m_hWnd != NULL)

    {

    CComPtr<IUnknown> spControl;

    HRESULT hr = AtlAxCreateControl(OLESTR("Shell.Explorer.2"), m_wndChild.m_hWnd , 

    NULL, NULL);

         // have to obtain an interface to the control and set  up the sink

    if (SUCCEEDED(hr))

    {

    hr = m_axwnd.QueryControl(&spControl);

    if (SUCCEEDED(hr))

    {

    // Sink events form the control

    DispEventAdvise(spControl, &__uuidof(DWebBrowserEvents2));

    }

    }

         if (SUCCEEDED(hr))

    {

    // Use the returned IUnknown pointer.

    hr = spControl.QueryInterface(&m_pWB);

    }

    }

    return 0;

    }

     

    TIA,

    Kumar

    Monday, August 9, 2010 8:50 PM
  • Kumar Talinki wrote:

    how can I create a UI thread for the child window?

    The same way you create any other thread. A "UI thread" is just a thread  that happens to create windows. Theres is no special CreateUIThread API  or anything like that. The point is, as soon as a thread creates a  window, it needs to run a message pump to deliver messages to said  window.


    Igor Tandetnik

    Monday, August 9, 2010 9:59 PM
  • Igor,

    I got it working using separate UI thread for each child window.

    The web page is getting displayed properly, but when submit a form, I am seeing a crash in MSHTML.DLL

    The call stack at the time of crash looks like below. Are you aware of any known issue like this?

    Is it due child window being in a separate thread?

    <!-- /* Font Definitions */ @font-face {font-family:"MS Mincho"; panose-1:2 2 6 9 4 2 5 8 3 4; mso-font-alt:"MS 明朝"; mso-font-charset:128; mso-generic-font-family:modern; mso-font-pitch:fixed; mso-font-signature:-1610612033 1757936891 16 0 131231 0;} @font-face {font-family:"Cambria Math"; panose-1:2 4 5 3 5 4 6 3 2 4; mso-font-charset:1; mso-generic-font-family:roman; mso-font-format:other; mso-font-pitch:variable; mso-font-signature:0 0 0 0 0 0;} @font-face {font-family:Calibri; panose-1:2 15 5 2 2 2 4 3 2 4; mso-font-charset:0; mso-generic-font-family:swiss; mso-font-pitch:variable; mso-font-signature:-1610611985 1073750139 0 0 159 0;} @font-face {font-family:"\@MS Mincho"; panose-1:2 2 6 9 4 2 5 8 3 4; mso-font-charset:128; mso-generic-font-family:modern; mso-font-pitch:fixed; mso-font-signature:-1610612033 1757936891 16 0 131231 0;} /* Style Definitions */ p.MsoNormal, li.MsoNormal, div.MsoNormal {mso-style-unhide:no; mso-style-qformat:yes; mso-style-parent:""; margin:0in; margin-bottom:.0001pt; mso-pagination:widow-orphan; font-size:11.0pt; font-family:"Calibri","sans-serif"; mso-fareast-font-family:"MS Mincho"; mso-fareast-theme-font:minor-fareast; mso-bidi-font-family:"Times New Roman";} a:link, span.MsoHyperlink {mso-style-priority:99; color:blue; text-decoration:underline; text-underline:single;} a:visited, span.MsoHyperlinkFollowed {mso-style-noshow:yes; mso-style-priority:99; color:purple; mso-themecolor:followedhyperlink; text-decoration:underline; text-underline:single;} .MsoChpDefault {mso-style-type:export-only; mso-default-props:yes; font-size:10.0pt; mso-ansi-font-size:10.0pt; mso-bidi-font-size:10.0pt;} @page Section1 {size:8.5in 11.0in; margin:1.0in 1.0in 1.0in 1.0in; mso-header-margin:.5in; mso-footer-margin:.5in; mso-paper-source:0;} div.Section1 {page:Section1;} -->

                    mshtml.dll!CTreeNode::IsEditable()  + 0x14 bytes            

                    mshtml.dll!CElement::IsEditable()  + 0x34 bytes               

                    mshtml.dll!CLayout::IsEditable()  + 0x28 bytes   

                    mshtml.dll!CTableCellLayout::Notify()  + 0xa7 bytes       

                    mshtml.dll!NotifyElement()  + 0x38 bytes            

                    mshtml.dll!CMarkup::NotifyDescendents()  - 0x17a3b bytes      

                    mshtml.dll!CMarkup::SendNotification()  - 0x4afa bytes               

                    mshtml.dll!CMarkup::Notify()  + 0x78 bytes       

                    mshtml.dll!CMarkup::ShowWaitCursor()  - 0x81096 bytes            

                    mshtml.dll!CMarkup::LoadFromInfo()  + 0x10b bytes     

                    mshtml.dll!CDoc::DoNavigate()  + 0x881 bytes  

                    mshtml.dll!CDoc::FollowHyperlink2()  - 0xc bytes             

                    mshtml.dll!CFormElement::DoSubmit()  + 0x405 bytes  

                    mshtml.dll!CFormElement::submit()  + 0x11 bytes          

                    mshtml.dll!Method_void_void()  + 0x33 bytes  

                    mshtml.dll!CBase::ContextInvokeEx()  + 0x186 bytes     

                    mshtml.dll!CElement::ContextInvokeEx()  + 0x52 bytes

                    mshtml.dll!CFormElement::VersionedInvokeEx()  + 0x8e bytes

                    mshtml.dll!PlainInvokeEx()  + 0x88 bytes             

                    jscript.dll!IDispatchExInvokeEx2()  + 0x8e bytes

                    jscript.dll!IDispatchExInvokeEx()  + 0x4f bytes   

                    jscript.dll!InvokeDispatchEx()  + 0x98 bytes        

                    jscript.dll!VAR::InvokeByName()  + 0x2a23 bytes             

                    jscript.dll!VAR::InvokeDispName()  + 0x73 bytes              

                    jscript.dll!VAR::InvokeByDispID()  + 0x1f3d bytes             

                    jscript.dll!CScriptRuntime::Run()  + 0x41bd bytes             

                    jscript.dll!ScrFncObj::CallWithFrameOnStack()  + 0x9f bytes        

                    jscript.dll!ScrFncObj::Call()  - 0x3e796 bytes        

                    jscript.dll!CSession::Execute()  + 0x14a bytes     

                    jscript.dll!COleScript::ExecutePendingScripts()  + 0x1a0 bytes    

                    jscript.dll!COleScript::ParseScriptTextCore()  + 0x1e1 bytes         

                    jscript.dll!COleScript::ParseScriptText()  + 0x30 bytes     

                    mshtml.dll!CScriptCollection::ParseScriptText()  + 0x18d bytes  

                    mshtml.dll!CScriptElement::CommitCode()  + 0x1f2 bytes           

                    mshtml.dll!CScriptElement::Execute()  + 0x8f bytes        

                    mshtml.dll!CHtmParse::Execute()  + 0x577c bytes           

                    mshtml.dll!CHtmPost::Broadcast()  + 0xf bytes 

                    mshtml.dll!CHtmPost::Exec()  + 0x16a bytes       

                    mshtml.dll!CHtmPost::Run()  + 0x33c3 bytes      

                    mshtml.dll!PostManExecute()  + 0x90 bytes       

                    mshtml.dll!PostManResume()  + 0x92 bytes      

                    mshtml.dll!CHtmPost::OnDwnChanCallback()  + 0x10 bytes        

                    mshtml.dll!CDwnChan::OnMethodCall()  + 0x19 bytes   

                    mshtml.dll!GlobalWndOnMethodCall()  + 0xcc bytes      

                    mshtml.dll!GlobalWndProc()  + 0xae bytes         

                    user32.dll!_InternalCallWinProc@20()   + 0x28 bytes       

                    user32.dll!_UserCallWinProcCheckWow@32()   + 0xb7 bytes      

                    user32.dll!_DispatchMessageWorker@8()   + 0xdc bytes               

                    user32.dll!_DispatchMessageA@4()   + 0xf bytes              

                    IeEmbed.exe!00401d40()            

                    [Frames below may be incorrect and/or missing, no symbols loaded for IeEmbed.exe] 

                    mfc42.dll!_AfxThreadEntry()  + 0x100 bytes       

                    msvcrt.dll!__endthreadex()  + 0xa9 bytes           

                    kernel32.dll!_BaseThreadStart@8()   + 0x37 bytes 

     

    thanks,

    Kumar

    Friday, August 13, 2010 3:22 PM
  • Kumar Talinki wrote:

    I got it working using separate UI thread for each child window.

    The web page is getting displayed properly, but when submit a form, I  am seeing a crash in MSHTML.DLL

    The call stack at the time of crash looks like below. Are you aware of  any known issue like this?

    Is it due child window being in a separate thread?

    It appears you are closing the window and terminating the thread  immediately after submitting that form. If so, you are essentially  pulling a carpet from under the browser's feet. Any network request,  including form submission, proceeds asynchronously: whatever call you  make to initiate the process returns immediately, usually before the  request is even sent (let alone receiving any response).

    After initiating the request, wait for DocumentComplete event before  closing the window.


    Igor Tandetnik

    Friday, August 13, 2010 10:33 PM
  • Hi Igor,

    Returning S_OK from IHttpSecurity::OnSecurityProblem() to suppress the cert security alert dialogs, is working fine for IE7 and IE8.

    But with IE6 :

    Returning S_OK is causing the navigation issues. The webpages are not getting displayed.

    Looks like IE6 does not support it and it could be a compatibility issue.

    Returning RPC_E_RETRY causes the request to be retired several times and fails eventually.

    Returning S_FALSE, is making the certificate security alert dialog to appear.

    How can I make it work for IE6?

    Environment : Windows Server 2003 SP1 with IE6.


    thanks,

    Kumar

    Tuesday, October 26, 2010 8:08 PM
  • Wednesday, April 11, 2012 3:47 PM