コード例 #1
0
/**
 * Event: OnAttachForgeExtensions
 */
void __stdcall CBrowserHelperObject::OnAttachForgeExtensions(IDispatch *dispatch, const wstring& location, const wstring& eventsource)
{
	m_isAttached = false;
  auto manifest = _AtlModule.moduleManifest;
  CComPtr<IDispatch> disp = nullptr;
  CComQIPtr<IHTMLWindow2, &IID_IHTMLWindow2> htmlWindow2 = nullptr;
  HRESULT hr = S_OK;

  for (;;) {
    CComQIPtr<IWebBrowser2, &IID_IWebBrowser2> webBrowser2(dispatch);
    BreakOnNullWithErrorLog(webBrowser2, L"BrowserHelperObject::OnAttachForgeExtensions failed to obtain IWebBrowser2");

    logger->debug(L"BrowserHelperObject::OnAttachForgeExtensions -> " + boost::lexical_cast<wstring>(dispatch) +  L" -> " + location + L" -> " + eventsource);
    // get interfaces
    hr = webBrowser2->get_Document(&disp);
    BreakOnNullWithErrorLog(disp, L"BrowserHelperObject::OnAttachForgeExtensions get_Document failed");
    BreakOnFailed(hr);
    
    logger->debug(L"BrowserHelperObject::OnAttachForgeExtensions IDispatch -> " + boost::lexical_cast<wstring>(disp));

    CComQIPtr<IHTMLDocument2, &IID_IHTMLDocument2> htmlDocument2(disp);
    BreakOnNullWithErrorLog(htmlDocument2, L"BrowserHelperObject::OnAttachForgeExtensions IHTMLDocument2 failed");

    logger->debug(L"BrowserHelperObject::OnAttachForgeExtensions IHTMLDocument2 -> " + boost::lexical_cast<wstring>(htmlDocument2));

    hr = htmlDocument2->get_parentWindow(&htmlWindow2);
    BreakOnNullWithErrorLog(htmlWindow2, L"BrowserHelperObject::OnAttachForgeExtensions IHTMLWindow2 failed");
    BreakOnFailed(hr);
    
    logger->debug(L"BrowserHelperObject::OnAttachForgeExtensions IHTMLWindow2 -> " + boost::lexical_cast<wstring>(htmlWindow2));

    CComQIPtr<IDispatchEx> htmlWindow2Ex(htmlWindow2);
    BreakOnNullWithErrorLog(htmlWindow2Ex, L"BrowserHelperObject::OnAttachForgeExtensions IHTMLWindow2Ex failed");

    // Attach NativeAccessible (forge.tabs.*)
    if (m_nativeAccessible) {
      logger->error(L"BrowserHelperObject::OnAttachForgeExtensions resetting nativeAccessible");
      m_nativeAccessible.reset();
    }

    m_nativeAccessible = NativeAccessible::pointer(new NativeAccessible(webBrowser2));
    hr = Attach::NativeTabs(htmlWindow2Ex, L"accessible", m_nativeAccessible.get());
    BreakOnFailedWithErrorLog(hr, L"BrowserHelperObject::OnAttachForgeExtensions failed to attach NativeExtensions -> " + logger->parse(hr));

    // Attach NativeExtensions
    hr = Attach::NativeExtensions(manifest->uuid, htmlWindow2Ex, L"extensions", m_instanceId, location, &m_nativeExtensions.p);
    BreakOnFailedWithErrorLog(hr, L"BrowserHelperObject::OnAttachForgeExtensions failed to attach NativeExtensions -> " + logger->parse(hr));
    
    logger->debug(L"BrowserHelperObject::OnAttachForgeExtensions attached NativeExtensions");

    // Attach NativeMessaging
    hr = Attach::NativeMessaging(manifest->uuid, htmlWindow2Ex, L"messaging", m_instanceId, &m_nativeMessaging.p);
    BreakOnFailedWithErrorLog(hr, L"BrowserHelperObject::OnAttachForgeExtensions failed to attach NativeMessaging -> " + logger->parse(hr));

    /// finally
    logger->debug(L"BrowserHelperObject::OnAttachForgeExtensions attached NativeMessaging");
    m_isAttached = true;
    break;
  }
}
コード例 #2
0
/**
 * Event: OnNavigateComplete2
 */
void __stdcall CBrowserHelperObject::OnNavigateComplete2(IDispatch *dispatch,  VARIANT   *url) 
{
  CComBSTR bstr = nullptr;
  wstring location;
  HRESULT hr = S_OK;

  for (;;) {
    CComQIPtr<IWebBrowser2, &IID_IWebBrowser2> webBrowser2(dispatch);
    BreakOnNullWithErrorLog(webBrowser2, L"BrowserHelperObject::OnNavigateComplete2 failed to obtain IWebBrowser2");

    // VARIANT *url chops off file:\\\ for local filesystem  
    hr = webBrowser2->get_LocationURL(&bstr);
    BreakOnFailed(hr);

    location = wstring(bstr);
    if (location.empty() && url->bstrVal)  // get_LocationURL fails in the most egregious of ways
      location = url->bstrVal;

    // match location against manifest 
    auto manifest = _AtlModule.moduleManifest;
    auto& match = MatchManifest(webBrowser2, manifest, location);
    if (match.first.empty() && match.second.empty()) {
      logger->debug(L"BrowserHelperObject::OnNavigateComplete2 not interested -> " + manifest->uuid + L" -> " + wstring(url->bstrVal) + L" -> " + location);
      break;
    }
  
    logger->debug(L"BrowserHelperObject::OnNavigateComplete2 -> " + manifest->uuid + L" -> " + location);
    break;
  }
  
  // attach forge extensions
  OnAttachForgeExtensions(dispatch, location, L"OnNavigateComplete2");
}
コード例 #3
0
/**
 * Event: OnNavigateComplete2
 */
void __stdcall CBrowserHelperObject::OnNavigateComplete2(IDispatch *dispatch,
                                                         VARIANT   *url) 
{
    CComQIPtr<IWebBrowser2, &IID_IWebBrowser2> webBrowser2(dispatch);
    if (!webBrowser2) {
        logger->debug(L"BrowserHelperObject::OnNavigateComplete2 "
                      L"failed to obtain IWebBrowser2");
        return;
    }

    // VARIANT *url chops off file:\\\ for local filesystem
    CComBSTR bstr;
    webBrowser2->get_LocationURL(&bstr); 
    wstring location(bstr);
	if (location == L"" && url->bstrVal) { // get_LocationURL fails in the most egregious of ways
		location = url->bstrVal;
	}

    // match location against manifest 
    Manifest::pointer manifest = _AtlModule.moduleManifest;
    std::pair<wstringvector, wstringvector> match = this->MatchManifest(webBrowser2, manifest, location);
    if (match.first.size() == 0 && match.second.size() == 0) {
        logger->debug(L"BrowserHelperObject::OnNavigateComplete2 not interested"
                      L" -> " + manifest->uuid + 
					  L" -> " + wstring(url->bstrVal) +
                      L" -> " + location);
        return;
    }

    logger->debug(L"BrowserHelperObject::OnNavigateComplete2"
                  L" -> " + manifest->uuid +
                  L" -> " + location);

	// attach forge extensions
	this->OnAttachForgeExtensions(dispatch, location, L"OnNavigateComplete2");
}
コード例 #4
0
/**
 * Event: OnAttachForgeExtensions
 */
void __stdcall CBrowserHelperObject::OnAttachForgeExtensions(IDispatch *dispatch, 
															 const wstring& location,
															 const wstring& eventsource)
{
	m_isAttached = false;

	CComQIPtr<IWebBrowser2, &IID_IWebBrowser2> webBrowser2(dispatch);
    if (!webBrowser2) {
        logger->debug(L"BrowserHelperObject::OnAttachForgeExtensions "
                      L"failed to obtain IWebBrowser2");
        return;
    } 

	logger->debug(L"BrowserHelperObject::OnAttachForgeExtensions"
				  L" -> " + boost::lexical_cast<wstring>(dispatch) +
				  L" -> " + location +
				  L" -> " + eventsource);

    Manifest::pointer manifest = _AtlModule.moduleManifest;

    // get interfaces
    CComPtr<IDispatch> disp;
    webBrowser2->get_Document(&disp);
    if (!disp) {
        logger->debug(L"BrowserHelperObject::OnAttachForgeExtensions get_Document failed");
        return;
    }
	logger->debug(L"BrowserHelperObject::OnAttachForgeExtensions "
				  L" IDispatch -> " + boost::lexical_cast<wstring>(disp)); 
    CComQIPtr<IHTMLDocument2, &IID_IHTMLDocument2> htmlDocument2(disp);
    if (!htmlDocument2) {
        logger->debug(L"BrowserHelperObject::OnAttachForgeExtensions IHTMLDocument2 failed");
        return;
    }
	logger->debug(L"BrowserHelperObject::OnAttachForgeExtensions "
				  L" IHTMLDocument2 -> " + boost::lexical_cast<wstring>(htmlDocument2)); 
    CComQIPtr<IHTMLWindow2, &IID_IHTMLWindow2> htmlWindow2;
    htmlDocument2->get_parentWindow(&htmlWindow2);    
    if (!htmlWindow2) {
        logger->debug(L"BrowserHelperObject::OnAttachForgeExtensions IHTMLWindow2 failed");
        return;
    }
	logger->debug(L"BrowserHelperObject::OnAttachForgeExtensions "
				  L" IHTMLWindow2 -> " + boost::lexical_cast<wstring>(htmlWindow2)); 
    CComQIPtr<IDispatchEx> htmlWindow2Ex(htmlWindow2);
    if (!htmlWindow2Ex) {
        logger->debug(L"BrowserHelperObject::OnAttachForgeExtensions IHTMLWindow2Ex failed");
        return;
    }

    HRESULT hr;

    // Attach NativeAccessible (forge.tabs.*)
    if (m_nativeAccessible) {
        logger->error(L"BrowserHelperObject::OnAttachForgeExtensions resetting nativeAccessible");
        m_nativeAccessible.reset();
    }
    m_nativeAccessible = NativeAccessible::pointer(new NativeAccessible(webBrowser2));
    hr = Attach::NativeTabs(htmlWindow2Ex, 
                            L"accessible",
                            m_nativeAccessible.get());
    if (FAILED(hr)) {
        logger->error(L"BrowserHelperObject::OnAttachForgeExtensions "
                      L"failed to attach NativeExtensions"
                      L" -> " + logger->parse(hr));
        return;
    }    

    // Attach NativeExtensions
    hr = Attach::NativeExtensions(manifest->uuid,
                                  htmlWindow2Ex, 
                                  L"extensions", 
                                  m_instanceId,
                                  location,
                                  &m_nativeExtensions.p); // "T** operator&() throw()" asserts on p==NULL
    if (FAILED(hr)) {
        logger->error(L"BrowserHelperObject::OnAttachForgeExtensions "
                      L"failed to attach NativeExtensions"
                      L" -> " + logger->parse(hr));
        return;
    }
	logger->debug(L"BrowserHelperObject::OnAttachForgeExtensions "
				  L"attached NativeExtensions");

    // Attach NativeMessaging
    hr = Attach::NativeMessaging(manifest->uuid,
                                 htmlWindow2Ex, 
                                 L"messaging", 
                                 m_instanceId,
                                 &m_nativeMessaging.p); // "T** operator&() throw()" asserts on p==NULL
    if (FAILED(hr)) {
        logger->error(L"BrowserHelperObject::OnAttachForgeExtensions "
                      L"failed to attach NativeMessaging"
                      L" -> " + logger->parse(hr));
        return;
    }

	logger->debug(L"BrowserHelperObject::OnAttachForgeExtensions "
				  L"attached NativeMessaging");

	m_isAttached = true;
}
コード例 #5
0
/**
 * Event: OnDocumentComplete
 */
void __stdcall CBrowserHelperObject::OnDocumentComplete(IDispatch *dispatch,
                                                        VARIANT   *url)
{
    Manifest::pointer manifest = _AtlModule.moduleManifest;

    CComQIPtr<IWebBrowser2, &IID_IWebBrowser2> webBrowser2(dispatch);
    if (!webBrowser2) {
        logger->debug(L"BrowserHelperObject::OnDocumentComplete "
                      L"failed to obtain IWebBrowser2");
        return;
    } 

    // VARIANT *url chops off file:\\\ for local filesystem
    CComBSTR bstr;
    webBrowser2->get_LocationURL(&bstr); 
    wstring location(bstr);
	if (location == L"" && url->bstrVal) { // get_LocationURL fails in the most egregious of ways
		location = url->bstrVal;
	}
	if (location == L"" && url->bstrVal == NULL) {
        logger->debug(L"BrowserHelperObject::OnDocumentComplete "
					  L"blank location, not interested"
                      L" -> " + manifest->uuid +
					  L" -> " + location);
		return;
	}

    // match location against manifest 
    std::pair<wstringvector, wstringvector> match = this->MatchManifest(webBrowser2, manifest, location);
    if (match.first.size() == 0 && match.second.size() == 0) {
        logger->debug(L"BrowserHelperObject::OnDocumentComplete not interested"
                      L" -> " + manifest->uuid +
					  L" -> " + wstring(url->bstrVal) +
                      L" -> " + location);
        return;
    }

    logger->debug(L"BrowserHelperObject::OnDocumentComplete"
                  L" -> " + manifest->uuid +
				  L" -> " + wstring(url->bstrVal) +
                  L" -> " + location);

    // get IHTMLWindow2
    CComPtr<IDispatch> disp;
    webBrowser2->get_Document(&disp);
    if (!disp) {
        logger->debug(L"BrowserHelperObject::OnDocumentComplete get_Document failed");
        return;
    }
    CComQIPtr<IHTMLDocument2, &IID_IHTMLDocument2> htmlDocument2(disp);
    if (!htmlDocument2) {
        logger->debug(L"BrowserHelperObject::OnDocumentComplete IHTMLDocument2 failed");
        return;
    }
    CComQIPtr<IHTMLWindow2, &IID_IHTMLWindow2> htmlWindow2;
    htmlDocument2->get_parentWindow(&htmlWindow2);    
    if (!htmlWindow2) {
        logger->debug(L"BrowserHelperObject::OnDocumentComplete IHTMLWindow2 failed");
        return;
    }

	// attach forge extensions when pages like target=_blank didn't trigger navComplete event
	if (!m_isAttached) {
		this->OnAttachForgeExtensions(dispatch, location, L"OnDocumentComplete");
	}

    // Inject styles
    wstringset dupes;
    HTMLDocument document(webBrowser2); 
    ScriptExtensions::scriptvector matches = m_scriptExtensions->read_styles(match.first);
    ScriptExtensions::scriptvector::const_iterator i = matches.begin();
    for (; i != matches.end(); i++) {
        if (dupes.find(i->first) != dupes.end()) {
            logger->debug(L"BrowserHelperObject::OnDocumentComplete already injected -> " + i->first);
            continue;
        }
        wstringpointer style = i->second;
        if (!style) {
            logger->debug(L"BrowserHelperObject::OnDocumentComplete invalid stylesheet -> " + i->first);
            continue;
        }
        HRESULT hr;
        hr = document.InjectStyle(style);
        if (FAILED(hr)) {
            logger->error(L"BrowserHelperObject::OnDocumentComplete failed to inject style"
                          L" -> " + i->first +
                          L" -> " + logger->parse(hr));
            continue;
        }
        dupes.insert(i->first);
        logger->debug(L"BrowserHelperObject::OnDocumentComplete injected: " + i->first);
    }    

    // Inject scripts
    dupes.clear();
    matches = m_scriptExtensions->read_scripts(match.second);
    i = matches.begin();
    for (; i != matches.end(); i++) {
        if (dupes.find(i->first) != dupes.end()) {
            logger->debug(L"BrowserHelperObject::OnDocumentComplete already injected -> " + i->first);
            continue;
        }
        wstringpointer script = i->second;
        if (!script) {
            logger->debug(L"BrowserHelperObject::OnDocumentComplete invalid script -> " + i->first);
            continue;
        }
        HRESULT hr;
        //hr = document.InjectScript(script);
        //hr = document.InjectScriptTag(HTMLDocument::attrScriptType, i->first);
        CComVariant ret;
        hr = htmlWindow2->execScript(CComBSTR(script->c_str()), L"javascript", &ret);
        if (FAILED(hr)) {
            logger->error(L"BrowserHelperObject::OnDocumentComplete failed to inject script"
                          L" -> " + i->first +
                          L" -> " + logger->parse(hr));
            continue;
        }
        dupes.insert(i->first);
        logger->debug(L"BrowserHelperObject::OnDocumentComplete injected"
                      L" -> " + location +
                      L" -> " + i->first);
    }

    /*// Test in-process IAccessible access
    SHANDLE_PTR phwnd;
    hr = webBrowser2->get_HWND(&phwnd);
    HWND hwnd = reinterpret_cast<HWND>(phwnd);
    AccessibleBrowser ab(hwnd);
    wstringvector tabs = ab.tabs();
    for (wstringvector::const_iterator tab = tabs.begin(); tab != tabs.end(); tab++) {
        logger->debug(L"BrowserHelperObject::OnDocumentComplete -> " + *tab);
        }*/
}
コード例 #6
0
// Implement refresh(F5 click, etc) based on
// http://www.codeproject.com/Articles/3632/Detecting-the-IE-Refresh-button-using-IWebBrowser2
void CBrowserHelperObject::OnRefresh()
{
   auto manifest = _AtlModule.moduleManifest;
   wstring location;
   wstringset dupes;

   CComBSTR bstr = nullptr;
   CComPtr<IDispatch> disp = nullptr;
   CComQIPtr<IHTMLWindow2, &IID_IHTMLWindow2> htmlWindow2 = nullptr;
   
   HRESULT hr = S_OK;
   
   for (;;) {
     // VARIANT *url chops off file:\\\ for local filesystem    
     CComQIPtr<IWebBrowser2, &IID_IWebBrowser2> webBrowser2(m_webBrowser2);
     BreakOnNull(webBrowser2, hr);
     hr = webBrowser2->get_LocationURL(&bstr);
     BreakOnFailed(hr);
     location = wstring(bstr); // was m_strUrl
     if (location.empty()) {
       logger->debug(L"BrowserHelperObject::OnRefresh blank location, not interested  -> " + manifest->uuid + L" -> " + location);
       break;
     }

     // match location against manifest 
     auto& match = MatchManifest(webBrowser2, manifest, location);
     if (match.first.empty() && match.second.empty()) {
       logger->debug(L"BrowserHelperObject::OnRefresh not interested -> " + manifest->uuid + L" -> " + location);
       break;
     }
     logger->debug(L"BrowserHelperObject::OnRefresh -> " + manifest->uuid + L" -> " + location);

     // get IHTMLWindow2
     hr = webBrowser2->get_Document(&disp);
     BreakOnNullWithErrorLog(disp, L"BrowserHelperObject::OnRefresh get_Document failed");
     BreakOnFailed(hr);

     CComQIPtr<IHTMLDocument2, &IID_IHTMLDocument2> htmlDocument2(disp);
     BreakOnNullWithErrorLog(htmlDocument2, L"BrowserHelperObject::OnRefresh IHTMLDocument2 failed");

     hr = htmlDocument2->get_parentWindow(&htmlWindow2);
     BreakOnNullWithErrorLog(htmlWindow2, L"BrowserHelperObject::OnRefresh IHTMLWindow2 failed");
     BreakOnFailed(hr);

     // attach forge extensions when pages like target=_blank didn't trigger navComplete event
     if (!m_isAttached)
       OnAttachForgeExtensions(m_webBrowser2, location, L"OnRefresh"); // was L"OnDocumentComplete"

     // Inject styles
     HTMLDocument document(webBrowser2);
     auto& matches = m_scriptExtensions->read_styles(match.first);
     for (auto& i : matches) {
       if (dupes.find(i.first) != dupes.end()) {
         logger->debug(L"BrowserHelperObject::OnRefresh already injected -> " + i.first);
         continue;
       }
       auto style = i.second;
       if (!style) {
         logger->debug(L"BrowserHelperObject::OnRefresh invalid stylesheet -> " + i.first);
         continue;
       }
       hr = document.InjectStyle(style);
       if (FAILED(hr)) {
         logger->error(L"BrowserHelperObject::OnRefresh failed to inject style -> " + i.first + L" -> " + logger->parse(hr));
         continue;
       }
       dupes.insert(i.first);
       logger->debug(L"BrowserHelperObject::OnRefresh injected: " + i.first);
     }

     // Inject scripts
     dupes.clear();
     matches = m_scriptExtensions->read_scripts(match.second);
     for (auto& i : matches) {
       if (dupes.find(i.first) != dupes.end()) {
         logger->debug(L"BrowserHelperObject::OnRefresh already injected -> " + i.first);
         continue;
       }
       auto script = i.second;
       if (!script) {
         logger->debug(L"BrowserHelperObject::OnRefresh invalid script -> " + i.first);
         continue;
       }
       CComVariant ret;
       hr = htmlWindow2->execScript(CComBSTR(script->c_str()), L"javascript", &ret);
       if (FAILED(hr)) {
         logger->error(L"BrowserHelperObject::OnRefresh failed to inject script -> " + i.first + L" -> " + logger->parse(hr));
         continue;
       }
       dupes.insert(i.first);
       logger->debug(L"BrowserHelperObject::OnRefresh injected -> " + location + L" -> " + i.first);
     }

     break;
   }   
}