std::wstring BrowserWrapper::GetTitle() {
	CComPtr<IDispatch> dispatch;
	HRESULT hr = this->browser_->get_Document(&dispatch);
	if (FAILED(hr)) {
		LOGHR(DEBUG, hr) << "Unable to get document";
		return L"";
	}

	CComPtr<IHTMLDocument2> doc;
	hr = dispatch->QueryInterface(&doc);
	if (FAILED(hr)) {
		LOGHR(WARN, hr) << "Have document but cannot cast";
		return L"";
	}

	CComBSTR title;
	hr = doc->get_title(&title);
	if (FAILED(hr)) {
		LOGHR(WARN, hr) << "Unable to get document title";
		return L"";
	}

	std::wstring title_string = (BSTR)title;
	return title_string;
}
bool ScriptWrapper::CreateAnonymousFunction(IDispatch* script_engine, DISPID eval_id, const std::wstring& script, VARIANT* result) {
	CComVariant script_variant(script.c_str());
	DISPPARAMS parameters = {0};
	memset(&parameters, 0, sizeof parameters);
	parameters.cArgs      = 1;
	parameters.rgvarg     = &script_variant;
	parameters.cNamedArgs = 0;

	EXCEPINFO exception;
	memset(&exception, 0, sizeof exception);

	HRESULT hr = script_engine->Invoke(eval_id, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &parameters, result, &exception, 0);
	if (FAILED(hr)) {
		if (DISP_E_EXCEPTION == hr) {
			LOGHR(INFO, hr) << "Exception message was: " << _bstr_t(exception.bstrDescription) << ": " << _bstr_t(script_variant);
		} else {
			LOGHR(DEBUG, hr) << "Failed to compile: " << _bstr_t(script_variant);
		}

		if (result) {
			result->vt = VT_USERDEFINED;
			if (exception.bstrDescription != NULL) {
				result->bstrVal = ::SysAllocStringByteLen((char*)exception.bstrDescription, ::SysStringByteLen(exception.bstrDescription));
			} else {
				result->bstrVal = ::SysAllocStringByteLen(NULL, 0);
			}
		}

		return false;
	}

	return true;
}
void BrowserWrapper::GetDocument(IHTMLDocument2 **doc) {
	CComPtr<IHTMLWindow2> window;

	if (this->focused_frame_window_ == NULL) {
		CComPtr<IDispatch> dispatch;
		HRESULT hr = this->browser_->get_Document(&dispatch);
		if (FAILED(hr)) {
			LOGHR(DEBUG, hr) << "Unable to get document";
			return;
		}

		CComPtr<IHTMLDocument2> dispatch_doc;
		hr = dispatch->QueryInterface(&dispatch_doc);
		if (FAILED(hr)) {
			LOGHR(WARN, hr) << "Have document but cannot cast";
			return;
		}

		dispatch_doc->get_parentWindow(&window);
	} else {
		window = this->focused_frame_window_;
	}

	if (window) {
		bool result = this->GetDocumentFromWindow(window, doc);
		if (!result) {
			LOG(WARN) << "Cannot get document";
		}
	}
}
std::string DocumentHost::GetPageSource() {
  LOG(TRACE) << "Entering DocumentHost::GetPageSource";

  CComPtr<IHTMLDocument2> doc;
  this->GetDocument(&doc);
    
  CComPtr<IHTMLDocument3> doc3;
  CComQIPtr<IHTMLDocument3> doc_qi_pointer(doc);
  if (doc_qi_pointer) {
    doc3 = doc_qi_pointer.Detach();
  }

  if (!doc3) {
    LOG(WARN) << "Unable to get document object, QueryInterface to IHTMLDocument3 failed";
    return "";
  }

  CComPtr<IHTMLElement> document_element;
  HRESULT hr = doc3->get_documentElement(&document_element);
  if (FAILED(hr)) {
    LOGHR(WARN, hr) << "Unable to get document element from page, call to IHTMLDocument3::get_documentElement failed";
    return "";
  }

  CComBSTR html;
  hr = document_element->get_outerHTML(&html);
  if (FAILED(hr)) {
    LOGHR(WARN, hr) << "Have document element but cannot read source, call to IHTMLElement::get_outerHTML failed";
    return "";
  }

  std::string page_source = CW2A(html, CP_UTF8);
  return page_source;
}
Example #5
0
void DocumentHost::SetFocusedFrameToParent() {
  LOG(TRACE) << "Entering DocumentHost::SetFocusedFrameToParent";
  // Three possible outcomes.
  // Outcome 1: Already at top-level browsing context. No-op.
  if (this->focused_frame_window_ != NULL) {
    CComPtr<IHTMLWindow2> parent_window;
    HRESULT hr = this->focused_frame_window_->get_parent(&parent_window);
    if (FAILED(hr)) {
      LOGHR(WARN, hr) << "IHTMLWindow2::get_parent call failed.";
    }
    CComPtr<IHTMLWindow2> top_window;
    hr = this->focused_frame_window_->get_top(&top_window);
    if (FAILED(hr)) {
      LOGHR(WARN, hr) << "IHTMLWindow2::get_top call failed.";
    }
    if (top_window.IsEqualObject(parent_window)) {
      // Outcome 2: Focus is on a frame one level deep, making the
      // parent the top-level browsing context. Set focused frame
      // pointer to NULL.
      this->focused_frame_window_ = NULL;
    } else {
      // Outcome 3: Focus is on a frame more than one level deep.
      // Set focused frame pointer to parent frame.
      this->focused_frame_window_ = parent_window;
    }
  }
}
bool VariantUtilities::GetVariantObjectPropertyValue(IDispatch* variant_object_dispatch,
                                                     std::wstring property_name,
                                                     VARIANT* property_value) {
  LPOLESTR property_name_pointer = reinterpret_cast<LPOLESTR>(const_cast<wchar_t*>(property_name.data()));
  DISPID dispid_property;
  HRESULT hr = variant_object_dispatch->GetIDsOfNames(IID_NULL,
                                                      &property_name_pointer,
                                                      1,
                                                      LOCALE_USER_DEFAULT,
                                                      &dispid_property);
  if (FAILED(hr)) {
    LOGHR(WARN, hr) << "Unable to get dispatch ID (dispid) for property "
                    << StringUtilities::ToString(property_name);
    return false;
  }

  // get the value of eval result
  DISPPARAMS no_args_dispatch_parameters = { 0 };
  hr = variant_object_dispatch->Invoke(dispid_property,
                                       IID_NULL,
                                       LOCALE_USER_DEFAULT,
                                       DISPATCH_PROPERTYGET,
                                       &no_args_dispatch_parameters,
                                       property_value,
                                       NULL,
                                       NULL);
  if (FAILED(hr)) {
    LOGHR(WARN, hr) << "Unable to get result for property "
                    << StringUtilities::ToString(property_name);
    return false;
  }
  return true;
}
Example #7
0
std::string DocumentHost::GetPageSource() {
  LOG(TRACE) << "Entering DocumentHost::GetPageSource";

  CComPtr<IHTMLDocument2> doc;
  this->GetDocument(&doc);
    
  CComPtr<IHTMLDocument3> doc3;
  HRESULT hr = doc->QueryInterface<IHTMLDocument3>(&doc3);
  if (FAILED(hr) || !doc3) {
    LOG(WARN) << "Unable to get document object, QueryInterface to IHTMLDocument3 failed";
    return "";
  }

  CComPtr<IHTMLElement> document_element;
  hr = doc3->get_documentElement(&document_element);
  if (FAILED(hr) || !document_element) {
    LOGHR(WARN, hr) << "Unable to get document element from page, call to IHTMLDocument3::get_documentElement failed";
    return "";
  }

  CComBSTR html;
  hr = document_element->get_outerHTML(&html);
  if (FAILED(hr)) {
    LOGHR(WARN, hr) << "Have document element but cannot read source, call to IHTMLElement::get_outerHTML failed";
    return "";
  }

  std::wstring converted_html = html;
  std::string page_source = StringUtilities::ToString(converted_html);
  return page_source;
}
Example #8
0
void Browser::GetDocument(IHTMLDocument2** doc) {
  LOG(TRACE) << "Entering Browser::GetDocument";
  CComPtr<IHTMLWindow2> window;

  if (this->focused_frame_window() == NULL) {
    LOG(INFO) << "No child frame focus. Focus is on top-level frame";

    CComPtr<IDispatch> dispatch;
    HRESULT hr = this->browser_->get_Document(&dispatch);
    if (FAILED(hr)) {
      LOGHR(WARN, hr) << "Unable to get document, IWebBrowser2::get_Document call failed";
      return;
    }

    CComPtr<IHTMLDocument2> dispatch_doc;
    hr = dispatch->QueryInterface(&dispatch_doc);
    if (FAILED(hr)) {
      LOGHR(WARN, hr) << "Have document but cannot cast, IDispatch::QueryInterface call failed";
      return;
    }

    dispatch_doc->get_parentWindow(&window);
  } else {
    window = this->focused_frame_window();
  }

  if (window) {
    bool result = this->GetDocumentFromWindow(window, doc);
    if (!result) {
      LOG(WARN) << "Cannot get document";
    }
  } else {
    LOG(WARN) << "No window is found";
  }
}
Example #9
0
std::string Browser::GetTitle() {
  LOG(TRACE) << "Entering Browser::GetTitle";

  CComPtr<IDispatch> dispatch;
  HRESULT hr = this->browser_->get_Document(&dispatch);
  if (FAILED(hr)) {
    LOGHR(WARN, hr) << "Unable to get document, IWebBrowser2::get_Document call failed";
    return "";
  }

  CComPtr<IHTMLDocument2> doc;
  hr = dispatch->QueryInterface(&doc);
  if (FAILED(hr)) {
    LOGHR(WARN, hr) << "Have document but cannot cast, IDispatch::QueryInterface call failed";
    return "";
  }

  CComBSTR title;
  hr = doc->get_title(&title);
  if (FAILED(hr)) {
    LOGHR(WARN, hr) << "Unable to get document title, call to IHTMLDocument2::get_title failed";
    return "";
  }

  std::wstring converted_title = title;
  std::string title_string = StringUtilities::ToString(converted_title);
  return title_string;
}
Example #10
0
HWND Browser::GetBrowserWindowHandle() {
  LOG(TRACE) << "Entering Browser::GetBrowserWindowHandle";

  HWND hwnd = NULL;
  CComPtr<IServiceProvider> service_provider;
  HRESULT hr = this->browser_->QueryInterface(IID_IServiceProvider,
                                              reinterpret_cast<void**>(&service_provider));
  if (SUCCEEDED(hr)) {
    CComPtr<IOleWindow> window;
    hr = service_provider->QueryService(SID_SShellBrowser,
                                        IID_IOleWindow,
                                        reinterpret_cast<void**>(&window));
    if (SUCCEEDED(hr)) {
      // This gets the TabWindowClass window in IE 7 and 8,
      // and the top-level window frame in IE 6.
      window->GetWindow(&hwnd);
    } else {
      LOGHR(WARN, hr) << "Unable to get window, call to IOleWindow::QueryService for SID_SShellBrowser failed";
    }
  } else {
    LOGHR(WARN, hr) << "Unable to get service, call to IWebBrowser2::QueryInterface for IID_IServiceProvider failed";
  }

  return hwnd;
}
Example #11
0
bool Script::CreateAnonymousFunction(VARIANT* result) {
  LOG(TRACE) << "Entering Script::CreateAnonymousFunction";

  std::wstring function_eval_script = L"window.document.__webdriver_script_fn = ";
  function_eval_script.append(this->source_code_.c_str());
  CComBSTR code(function_eval_script.c_str());
  CComBSTR lang(L"JScript");
  CComVariant exec_script_result;

  CComPtr<IHTMLWindow2> window;
  HRESULT hr = this->script_engine_host_->get_parentWindow(&window);
  if (FAILED(hr)) {
    LOGHR(WARN, hr) << "Unable to get parent window, call to IHTMLDocument2::get_parentWindow failed";
    return false;
  }
  //LAM: General Access Denied Error ( could be protected mode )
  hr = window->execScript(code, lang, &exec_script_result);
  if (FAILED(hr)) {
    LOGHR(WARN, hr) << "Unable to execute code, call to IHTMLWindow2::execScript failed";
	LOG(ERROR) << "Unable to execute code, call to IHTMLWindow2::execScript failed";
    return false;
  }

  bool get_result_success = VariantUtilities::GetVariantObjectPropertyValue(
      this->script_engine_host_,
      L"__webdriver_script_fn",
      result);
  return get_result_success;
}
Example #12
0
std::string Browser::GetWindowName() {
  LOG(TRACE) << "Entering Browser::GetWindowName";

  CComPtr<IDispatch> dispatch;
  HRESULT hr = this->browser_->get_Document(&dispatch);
  if (FAILED(hr)) {
    LOGHR(WARN, hr) << "Unable to get document, IWebBrowser2::get_Document call failed";
    return "";
  }

  CComQIPtr<IHTMLDocument2> doc(dispatch);
  if (!doc) {
    LOGHR(WARN, hr) << "Have document but cannot cast, IDispatch::QueryInterface call failed";
    return "";
  }

  CComPtr<IHTMLWindow2> window;
  hr = doc->get_parentWindow(&window);
  if (FAILED(hr)) {
    LOGHR(WARN, hr) << "Unable to get parent window, call to IHTMLDocument2::get_parentWindow failed";
    return "";
  }

  std::string name = "";
  CComBSTR window_name;
  hr = window->get_name(&window_name);
  if (window_name) {
    name = CW2A(window_name, CP_UTF8);
  } else {
    LOG(WARN) << "Unable to get window name, IHTMLWindow2::get_name failed or returned a NULL value";
  }

  return name;
}
  void ScreenshotCommandHandler::ExecuteInternal(
      const IECommandExecutor& executor,
      const ParametersMap& command_parameters,
      Response* response) {
    LOG(TRACE) << "Entering ScreenshotCommandHandler::ExecuteInternal";

    BrowserHandle browser_wrapper;
    int status_code = executor.GetCurrentBrowser(&browser_wrapper);
    if (status_code != WD_SUCCESS) {
      response->SetErrorResponse(status_code, "Unable to get browser");
      return;
    }

    bool isSameColour = true;
    HRESULT hr;
    int i = 0;
    int tries = 4;
    const bool should_resize_window = executor.enable_full_page_screenshot();
    do {
      this->ClearImage();

      this->image_ = new CImage();
      if (should_resize_window) {
        hr = this->CaptureFullPage(browser_wrapper);
      } else {
        hr = this->CaptureViewport(browser_wrapper);
      }
      if (FAILED(hr)) {
        LOGHR(WARN, hr) << "Failed to capture browser image at " << i << " try";
        this->ClearImage();
        response->SetSuccessResponse("");
        return;
      }

      isSameColour = IsSameColour();
      if (isSameColour) {
        ::Sleep(2000);
        LOG(DEBUG) << "Failed to capture non single color browser image at " << i << " try";
      }

      i++;
    } while ((i < tries) && isSameColour);

    // now either correct or single color image is got
    std::string base64_screenshot = "";
    hr = this->GetBase64Data(base64_screenshot);
    if (FAILED(hr)) {
      LOGHR(WARN, hr) << "Unable to transform browser image to Base64 format";
      this->ClearImage();
      response->SetSuccessResponse("");
      return;
    }

    this->ClearImage();
    response->SetSuccessResponse(base64_screenshot);
  }
Example #14
0
bool DocumentHost::IsHtmlPage(IHTMLDocument2* doc) {
  LOG(TRACE) << "Entering DocumentHost::IsHtmlPage";

  CComBSTR type;
  HRESULT hr = doc->get_mimeType(&type);
  if (FAILED(hr)) {
    LOGHR(WARN, hr) << "Unable to get mime type for document, call to IHTMLDocument2::get_mimeType failed";
    return false;
  }

  // Call once to get the required buffer size, then again to fill
  // the buffer.
  DWORD mime_type_name_buffer_size = 0;
  hr = ::AssocQueryString(0,
                          ASSOCSTR_FRIENDLYDOCNAME,
                          L".htm",
                          NULL,
                          NULL,
                          &mime_type_name_buffer_size);

  std::vector<wchar_t> mime_type_name_buffer(mime_type_name_buffer_size);
  hr = ::AssocQueryString(0,
                          ASSOCSTR_FRIENDLYDOCNAME,
                          L".htm",
                          NULL,
                          &mime_type_name_buffer[0],
                          &mime_type_name_buffer_size);

  if (FAILED(hr)) {
    LOGHR(WARN, hr) << "Call to AssocQueryString failed in getting friendly name of .htm documents";
    return false;
  }

  std::wstring mime_type_name = &mime_type_name_buffer[0];
  std::wstring type_string = type;
  if (type_string == mime_type_name) {
    return true;
  }

  // If the user set Firefox as a default browser at any point, the MIME type
  // appears to be "sticky". This isn't elegant, but it appears to alleviate
  // the worst symptoms. Tested by using both Safari and Opera as the default
  // browser, even after setting IE as the default after Firefox (so the chain
  // of defaults looks like (IE -> Firefox -> IE -> Opera)

  if (L"Firefox HTML Document" == mime_type_name) {
    LOG(INFO) << "It looks like Firefox was once the default browser. " 
              << "Guessing the page type from mime type alone";
    return true;
  }

  return false;
}
Example #15
0
std::string Alert::GetDirectUIDialogText() {
  LOG(TRACE) << "Entering Alert::GetDirectUIDialogText";
  std::string alert_text_value = "";
  HWND direct_ui_child_handle = this->GetDirectUIChild();

  CComPtr<IAccessible> window_object;
  HRESULT hr = ::AccessibleObjectFromWindow(
      direct_ui_child_handle,
      OBJID_WINDOW,
      IID_IAccessible,
      reinterpret_cast<void**>(&window_object));
  if (FAILED(hr)) {
    LOGHR(WARN, hr) << "Failed to get Active Accessibility window object from dialog";
    return alert_text_value;
  }

  // ASSUMPTION: There is an object with the role of "pane" as a child of
  // the window object.
  CComPtr<IAccessible> pane_object = this->GetChildWithRole(window_object,
                                                            ROLE_SYSTEM_PANE,
                                                            0);
  if (!pane_object) {
    LOG(WARN) << "Failed to get Active Accessibility pane child object from window";
    return alert_text_value;
  }

  // ASSUMPTION: The second "static text" accessibility object is the one
  // that contains the message.
  CComPtr<IAccessible> message_text_object = this->GetChildWithRole(
      pane_object,
      ROLE_SYSTEM_STATICTEXT,
      1);
  if (!message_text_object) {
    LOG(WARN) << "Failed to get Active Accessibility text child object from pane";
    return alert_text_value;
  }

  CComVariant child_id;
  child_id.vt = VT_I4;
  child_id.lVal = CHILDID_SELF;

  CComBSTR text_bstr;
  hr = message_text_object->get_accName(child_id, &text_bstr);
  if (FAILED(hr)) {
    LOGHR(WARN, hr) << "Failed to get accName property from text object";
    return alert_text_value;
  }

  std::wstring text = text_bstr;
  alert_text_value = StringUtilities::ToString(text);
  return alert_text_value;
}
Example #16
0
bool Script::CreateAnonymousFunction(VARIANT* result) {
  LOG(TRACE) << "Entering Script::CreateAnonymousFunction";

  CComBSTR function_eval_script(L"window.document.__webdriver_script_fn = ");
  HRESULT hr = function_eval_script.Append(this->source_code_.c_str());
  CComBSTR code(function_eval_script);
  CComBSTR lang(L"JScript");
  CComVariant exec_script_result;

  CComPtr<IHTMLWindow2> window;
  hr = this->script_engine_host_->get_parentWindow(&window);
  if (FAILED(hr)) {
    LOGHR(WARN, hr) << "Unable to get parent window, call to IHTMLDocument2::get_parentWindow failed";
    return false;
  }

  hr = window->execScript(code, lang, &exec_script_result);
  if (FAILED(hr)) {
    LOGHR(WARN, hr) << "Unable to execute code, call to IHTMLWindow2::execScript failed";
    return false;
  }

  OLECHAR FAR* function_object_name = L"__webdriver_script_fn";
  DISPID dispid_function_object;
  hr = this->script_engine_host_->GetIDsOfNames(IID_NULL,
                                                &function_object_name,
                                                1,
                                                LOCALE_USER_DEFAULT,
                                                &dispid_function_object);
  if (FAILED(hr)) {
    LOGHR(WARN, hr) << "Unable to get id of name __webdriver_script_fn";
    return false;
  }

  // get the value of eval result
  DISPPARAMS no_args_dispatch_parameters = { NULL, NULL, 0, 0 };
  hr = this->script_engine_host_->Invoke(dispid_function_object,
                                         IID_NULL,
                                         LOCALE_USER_DEFAULT,
                                         DISPATCH_PROPERTYGET,
                                         &no_args_dispatch_parameters,
                                         result,
                                         NULL,
                                         NULL);
  if (FAILED(hr)) {
    LOGHR(WARN, hr) << "Unable to get value of eval result";
    return false;
  }
  return true;
}
Example #17
0
bool Element::IsAttachedToDom() {
  // Verify that the element is still valid by getting the document
  // element and calling IHTMLElement::contains() to see if the document
  // contains this element.
  if (this->element_) {
    CComPtr<IHTMLDOMNode2> node;
    HRESULT hr = this->element_->QueryInterface<IHTMLDOMNode2>(&node);
    if (FAILED(hr)) {
      LOGHR(WARN, hr) << "Unable to cast element to IHTMLDomNode2";
      return false;
    }

    CComPtr<IDispatch> dispatch_doc;
    hr = node->get_ownerDocument(&dispatch_doc);
    if (FAILED(hr)) {
      LOGHR(WARN, hr) << "Unable to locate owning document, call to IHTMLDOMNode2::get_ownerDocument failed";
      return false;
    }

    if (dispatch_doc) {
      CComPtr<IHTMLDocument3> doc;
      hr = dispatch_doc.QueryInterface<IHTMLDocument3>(&doc);
      if (FAILED(hr)) {
        LOGHR(WARN, hr) << "Found document but it's not the expected type (IHTMLDocument3)";
        return false;
      }

      CComPtr<IHTMLElement> document_element;
      hr = doc->get_documentElement(&document_element);
      if (FAILED(hr)) {
        LOGHR(WARN, hr) << "Unable to locate document element, call to IHTMLDocument3::get_documentElement failed";
        return false;
      }

      if (document_element) {
        VARIANT_BOOL contains(VARIANT_FALSE);
        hr = document_element->contains(this->element_, &contains);
        if (FAILED(hr)) {
          LOGHR(WARN, hr) << "Call to IHTMLElement::contains failed";
          return false;
        }

        return contains == VARIANT_TRUE;
      }
    }
  }
  return false;
}
int DocumentHost::AddCookie(const std::string& cookie) {
  LOG(TRACE) << "Entering DocumentHost::AddCookie";

  CComBSTR cookie_bstr(CA2W(cookie.c_str(), CP_UTF8));

  CComPtr<IHTMLDocument2> doc;
  this->GetDocument(&doc);

  if (!doc) {
    LOG(WARN) << "Unable to get document";
    return EUNHANDLEDERROR;
  }

  if (!this->IsHtmlPage(doc)) {
    LOG(WARN) << "Unable to add cookie, document does not appear to be an HTML page";
    return ENOSUCHDOCUMENT;
  }

  HRESULT hr = doc->put_cookie(cookie_bstr);
  if (FAILED(hr)) {
    LOGHR(WARN, hr) << "Unable to put cookie to document, call to IHTMLDocument2::put_cookie failed";
    return EUNHANDLEDERROR;
  }

  return SUCCESS;
}
int DocumentHost::SetFocusedFrameByElement(IHTMLElement* frame_element) {
  LOG(TRACE) << "Entering DocumentHost::SetFocusedFrameByElement";

  HRESULT hr = S_OK;
  if (!frame_element) {
    this->focused_frame_window_ = NULL;
    return SUCCESS;
  }

  CComQIPtr<IHTMLFrameBase2> frame_base(frame_element);
  if (!frame_base) {
    LOG(WARN) << "IHTMLElement is not a FRAME or IFRAME element";
    return ENOSUCHFRAME;
  }

  CComQIPtr<IHTMLWindow2> interim_result;
  hr = frame_base->get_contentWindow(&interim_result);
  if (FAILED(hr)) {
    LOGHR(WARN, hr) << "Cannot get contentWindow from IHTMLFrameBase2, call to IHTMLFrameBase2::get_contentWindow failed";
    return ENOSUCHFRAME;
  }

  this->focused_frame_window_ = interim_result;
  return SUCCESS;
}
Example #20
0
bool BrowserFactory::GetDocumentFromWindowHandle(HWND window_handle,
                                                 IHTMLDocument2** document) {
  LOG(TRACE) << "Entering BrowserFactory::GetDocumentFromWindowHandle";

  if (window_handle != NULL && this->oleacc_instance_handle_) {
    LRESULT result;
    ::SendMessageTimeout(window_handle,
                         this->html_getobject_msg_,
                         0L,
                         0L,
                         SMTO_ABORTIFHUNG,
                         1000,
                         reinterpret_cast<PDWORD_PTR>(&result));

    LPFNOBJECTFROMLRESULT object_pointer = reinterpret_cast<LPFNOBJECTFROMLRESULT>(::GetProcAddress(this->oleacc_instance_handle_, "ObjectFromLresult"));
    if (object_pointer != NULL) {
      HRESULT hr;
      hr = (*object_pointer)(result,
                             IID_IHTMLDocument2,
                             0,
                             reinterpret_cast<void**>(document));
      if (SUCCEEDED(hr)) {
        return true;
      } else {
        LOGHR(WARN, hr) << "Unable to convert document object pointer to IHTMLDocument2 object via ObjectFromLresult";
      }
    } else {
      LOG(WARN) << "Unable to get address of ObjectFromLresult method from library; GetProcAddress() for ObjectFromLresult returned NULL";
    }
  } else {
    LOG(WARN) << "Window handle is invalid or OLEACC.DLL is not loaded properly";
  }
  return false;
}
Example #21
0
IWebBrowser2* BrowserFactory::CreateBrowser() {
    LOG(TRACE) << "Entering BrowserFactory::CreateBrowser";

    IWebBrowser2* browser = NULL;
    DWORD context = CLSCTX_LOCAL_SERVER;
    if (this->ie_major_version_ == 7 && this->windows_major_version_ >= 6) {
        // ONLY for IE 7 on Windows Vista. XP and below do not have Protected Mode;
        // Windows 7 shipped with IE8.
        context = context | CLSCTX_ENABLE_CLOAKING;
    }

    HRESULT hr = ::CoCreateInstance(CLSID_InternetExplorer,
                                    NULL,
                                    context,
                                    IID_IWebBrowser2,
                                    reinterpret_cast<void**>(&browser));
    // When IWebBrowser2::Quit() is called, the wrapper process doesn't
    // exit right away. When that happens, CoCreateInstance can fail while
    // the abandoned iexplore.exe instance is still valid. The "right" way
    // to do this would be to call ::EnumProcesses before calling
    // CoCreateInstance, finding all of the iexplore.exe processes, waiting
    // for one to exit, and then proceed. However, there is no way to tell
    // if a process ID belongs to an Internet Explorer instance, particularly
    // when a 32-bit process tries to enumerate 64-bit processes on 64-bit
    // Windows. So, we'll take the brute force way out, just retrying the call
    // to CoCreateInstance until it succeeds (the old iexplore.exe process has
    // exited), or we get a different error code. We'll also set a 45-second
    // timeout, with 45 seconds being chosen because it's below the default
    // 60 second HTTP request timeout of most language bindings.
    if (FAILED(hr) && HRESULT_CODE(hr) == ERROR_SHUTDOWN_IS_SCHEDULED) {
        LOG(DEBUG) << "CoCreateInstance for IWebBrowser2 failed due to a "
                   << "browser process that has not yet fully exited. Retrying "
                   << "until the browser process exits and a new instance can "
                   << "be successfully created.";
    }
    clock_t timeout = clock() + (45 * CLOCKS_PER_SEC);
    while (FAILED(hr) &&
            HRESULT_CODE(hr) == ERROR_SHUTDOWN_IS_SCHEDULED &&
            clock() < timeout) {
        ::Sleep(500);
        hr = ::CoCreateInstance(CLSID_InternetExplorer,
                                NULL,
                                context,
                                IID_IWebBrowser2,
                                reinterpret_cast<void**>(&browser));
    }
    if (FAILED(hr) && HRESULT_CODE(hr) != ERROR_SHUTDOWN_IS_SCHEDULED) {
        // If we hit this branch, the CoCreateInstance failed due to an unexpected
        // error, either before we looped, or at some point during the loop. In
        // in either case, there's not much else we can do except log the failure.
        LOGHR(WARN, hr) << "CoCreateInstance for IWebBrowser2 failed.";
    }

    if (browser != NULL) {
        browser->put_Visible(VARIANT_TRUE);
    }

    return browser;
}
Example #22
0
bool Browser::GetDocumentFromWindow(IHTMLWindow2* window,
                                    IHTMLDocument2** doc) {
  LOG(TRACE) << "Entering Browser::GetDocumentFromWindow";

  HRESULT hr = window->get_document(doc);
  if (SUCCEEDED(hr)) {
    return true;
  }

  if (hr == E_ACCESSDENIED) {
    // Cross-domain documents may throw Access Denied. If so,
    // get the document through the IWebBrowser2 interface.
    CComPtr<IServiceProvider> service_provider;
    hr = window->QueryInterface<IServiceProvider>(&service_provider);
    if (FAILED(hr)) {
      LOGHR(WARN, hr) << "Unable to get browser, call to IHTMLWindow2::QueryService failed for IServiceProvider";
      return false;
    }

    CComPtr<IWebBrowser2> window_browser;
    hr = service_provider->QueryService(IID_IWebBrowserApp, &window_browser);
    if (FAILED(hr)) {
      LOGHR(WARN, hr) << "Unable to get browser, call to IServiceProvider::QueryService failed for IID_IWebBrowserApp";
      return false;
    }

    CComPtr<IDispatch> document_dispatch;
    hr = window_browser->get_Document(&document_dispatch);
    if (FAILED(hr) || hr == S_FALSE) {
      LOGHR(WARN, hr) << "Unable to get document, call to IWebBrowser2::get_Document failed";
      return false;
    }

    hr = document_dispatch->QueryInterface(doc);
    if (FAILED(hr)) {
      LOGHR(WARN, hr) << "Unable to query document, call to IDispatch::QueryInterface failed.";
      return false;
    }

    return true;
  } else {
    LOGHR(WARN, hr) << "Unable to get main document, IHTMLWindow2::get_document returned other than E_ACCESSDENIED";
  }

  return false;
}
Example #23
0
IAccessible* Alert::GetChildWithRole(IAccessible* parent, long expected_role, int index) {
  LOG(TRACE) << "Entering Alert::GetChildWithRole";
  IAccessible* child = NULL;
  long child_count;
  HRESULT hr = parent->get_accChildCount(&child_count);
  if (FAILED(hr)) {
    LOGHR(WARN, hr) << "Failed to get accChildCount property from Active Accessibility object";
    return child;
  }

  long returned_children = 0;
  std::vector<CComVariant> child_array(child_count);
  hr = ::AccessibleChildren(parent, 0, child_count, &child_array[0], &returned_children);

  int found_index = 0;
  for (long i = 0; i < child_count; ++i) {
    if (child_array[i].vt == VT_DISPATCH) {
      CComPtr<IAccessible> child_object;
      hr = child_array[i].pdispVal->QueryInterface<IAccessible>(&child_object);
      if (FAILED(hr)) {
        LOGHR(WARN, hr) << "QueryInterface for IAccessible failed for child object with index " << i;
      }

      CComVariant child_id;
      child_id.vt = VT_I4;
      child_id.lVal = CHILDID_SELF;

      CComVariant actual_role;
      hr = child_object->get_accRole(child_id, &actual_role);
      if (FAILED(hr)) {
        LOGHR(WARN, hr) << "Failed to get accRole property from Active Accessibility object";
      }

      if (expected_role == actual_role.lVal) {
        if (found_index == index) {
          child = child_object.Detach();
        } else {
          ++found_index;
        }
      }
      LOG(DEBUG) << "accRole for child with index " << i << ": " << actual_role.lVal;
    }
  }
  return child;
}
Example #24
0
int Element::GetDocumentFromWindow(IHTMLWindow2* parent_window,
                                   IHTMLDocument2** parent_doc) {
  LOG(TRACE) << "Entering Element::GetParentDocument";

  HRESULT hr = parent_window->get_document(parent_doc);
  if (FAILED(hr)) {
    if (hr == E_ACCESSDENIED) {
      // Cross-domain documents may throw Access Denied. If so,
      // get the document through the IWebBrowser2 interface.
      CComPtr<IServiceProvider> service_provider;
      hr = parent_window->QueryInterface<IServiceProvider>(&service_provider);
      if (FAILED(hr)) {
        LOGHR(WARN, hr) << "Unable to get browser, call to IHTMLWindow2::QueryInterface failed for IServiceProvider";
        return ENOSUCHDOCUMENT;
      }
      CComPtr<IWebBrowser2> window_browser;
      hr = service_provider->QueryService(IID_IWebBrowserApp, &window_browser);
      if (FAILED(hr)) {
        LOGHR(WARN, hr) << "Unable to get browser, call to IServiceProvider::QueryService failed for IID_IWebBrowserApp";
        return ENOSUCHDOCUMENT;
      }
      CComPtr<IDispatch> parent_doc_dispatch;
      hr = window_browser->get_Document(&parent_doc_dispatch);
      if (FAILED(hr)) {
        LOGHR(WARN, hr) << "Unable to get document, call to IWebBrowser2::get_Document failed";
        return ENOSUCHDOCUMENT;
      }
      try {
        hr = parent_doc_dispatch->QueryInterface<IHTMLDocument2>(parent_doc);
        if (FAILED(hr)) {
          LOGHR(WARN, hr) << "Unable to get document, QueryInterface for IHTMLDocument2 failed";
          return ENOSUCHDOCUMENT;
        }
      } catch(...) {
        LOG(WARN) << "Unable to get document, exception thrown attempting to QueryInterface for IHTMLDocument2";
        return ENOSUCHDOCUMENT;
      }
    } else {
      LOGHR(WARN, hr) << "Unable to get document, IHTMLWindow2::get_document failed with error code other than E_ACCESSDENIED";
      return ENOSUCHDOCUMENT;
    }
  }
  return WD_SUCCESS;
}
Example #25
0
void Browser::Close() {
  LOG(TRACE) << "Entering Browser::Close";
  // Closing the browser, so having focus on a frame doesn't
  // make any sense.
  this->SetFocusedFrameByElement(NULL);
  HRESULT hr = this->browser_->Quit();
  if (FAILED(hr)) {
    LOGHR(WARN, hr) << "Call to IWebBrowser2::Quit failed";
  }
}
Example #26
0
int Element::GetContainingDocument(const bool use_dom_node,
                                   IHTMLDocument2** doc) {
  LOG(TRACE) << "Entering Element::GetContainingDocument";

  HRESULT hr = S_OK;
  CComPtr<IDispatch> dispatch_doc;

  if (use_dom_node) {
    CComPtr<IHTMLDOMNode2> node;
    hr = this->element_->QueryInterface(&node);
    if (FAILED(hr)) {
      LOGHR(WARN, hr) << "Unable to cast element to IHTMLDomNode2";
      return ENOSUCHDOCUMENT;
    }

    hr = node->get_ownerDocument(&dispatch_doc);
    if (FAILED(hr)) {
      LOGHR(WARN, hr) << "Unable to locate owning document, call to IHTMLDOMNode2::get_ownerDocument failed";
      return ENOSUCHDOCUMENT;
    }
  } else {
    hr = this->element_->get_document(&dispatch_doc);
    if (FAILED(hr)) {
      LOGHR(WARN, hr) << "Unable to locate document property, call to IHTMLELement::get_document failed";
      return ENOSUCHDOCUMENT;
    }

  }

  try {
    hr = dispatch_doc.QueryInterface<IHTMLDocument2>(doc);
    if (FAILED(hr)) {
      LOGHR(WARN, hr) << "Found document but it's not the expected type (IHTMLDocument2)";
      return ENOSUCHDOCUMENT;
    }
  } catch(...) {
    LOG(WARN) << "Found document but it's not the expected type (IHTMLDocument2)";
    return ENOSUCHDOCUMENT;
  }

  return WD_SUCCESS;
}
Example #27
0
int Browser::Refresh() {
  LOG(TRACE) << "Entering Browser::Refresh";

  HRESULT hr = this->browser_->Refresh();
  if (FAILED(hr)) {
    LOGHR(WARN, hr) << "Call to IWebBrowser2::Refresh failed";
  }

  this->set_wait_required(true);
  return WD_SUCCESS;
}
Example #28
0
HWND Browser::GetTopLevelWindowHandle() {
  LOG(TRACE) << "Entering Browser::GetTopLevelWindowHandle";

  HWND top_level_window_handle = NULL;
  HRESULT hr = this->browser_->get_HWND(reinterpret_cast<SHANDLE_PTR*>(&top_level_window_handle));
  if (FAILED(hr)) {
    LOGHR(WARN, hr) << "Getting HWND property of IWebBrowser2 object failed";
  }

  return top_level_window_handle;
}
Example #29
0
void HtmlDialog::GetDocument(IHTMLDocument2** doc) {
    HRESULT hr = S_OK;
    if (this->focused_frame_window() == NULL) {
        hr = this->window_->get_document(doc);
    } else {
        hr = this->focused_frame_window()->get_document(doc);
    }

    if (FAILED(hr)) {
        LOGHR(DEBUG, hr) << "Unable to get document";
    }
}
Example #30
0
std::string HtmlDialog::GetTitle() {
  CComPtr<IHTMLDocument2> doc;
  this->GetDocument(&doc);
  CComBSTR title;
  HRESULT hr = doc->get_title(&title);
  if (FAILED(hr)) {
    LOGHR(WARN, hr) << "Unable to get document title";
    return "";
  }

  std::string title_string = CW2A(title, CP_UTF8);
  return title_string;
}