Example #1
0
bool BrowserFactory::AttachToBrowser(ProcessWindowInfo* process_window_info,
                                     bool ignore_zoom_setting,
                                     std::string* error_message) {
  LOG(TRACE) << "Entering BrowserFactory::AttachToBrowser";
  while (process_window_info->hwndBrowser == NULL) {
    // TODO: create a timeout for this. We shouldn't need it, since
    // we got a valid process ID, but we should bulletproof it.
    ::EnumWindows(&BrowserFactory::FindBrowserWindow,
                  reinterpret_cast<LPARAM>(process_window_info));
    if (process_window_info->hwndBrowser == NULL) {
      ::Sleep(250);
    }
  }

  CComPtr<IHTMLDocument2> document;
  if (this->GetDocumentFromWindowHandle(process_window_info->hwndBrowser,
                                        &document)) {
    CComPtr<IHTMLWindow2> window;
    HRESULT hr = document->get_parentWindow(&window);

    // Test for zoom level = 100%
    int zoom_level = 100;
    LOG(DEBUG) << "Ignoring zoom setting: " << ignore_zoom_setting;
    if (!ignore_zoom_setting) {
      zoom_level = this->GetZoomLevel(document, window);
    }
    if (zoom_level != 100) {
      vector<char> zoom_level_buffer(10);
      _itoa_s(zoom_level, &zoom_level_buffer[0], 10, 10);
      std::string zoom(&zoom_level_buffer[0]);
      *error_message = "Browser zoom level was set to " + zoom + "%. It should be set to 100%";
      return false;
    }
    if (SUCCEEDED(hr)) {
      // http://support.microsoft.com/kb/257717
      CComQIPtr<IServiceProvider> provider(window);
      if (provider) {
        CComPtr<IServiceProvider> child_provider;
        hr = provider->QueryService(SID_STopLevelBrowser,
                                    IID_IServiceProvider,
                                    reinterpret_cast<void**>(&child_provider));
        if (SUCCEEDED(hr)) {
          IWebBrowser2* browser;
          hr = child_provider->QueryService(SID_SWebBrowserApp,
                                            IID_IWebBrowser2,
                                            reinterpret_cast<void**>(&browser));
          if (SUCCEEDED(hr)) {
            process_window_info->pBrowser = browser;
            return true;
          } else {
            LOGHR(WARN, hr) << "IServiceProvider::QueryService for SID_SWebBrowserApp failed";
          }
        } else {
          LOGHR(WARN, hr) << "IServiceProvider::QueryService for SID_STopLevelBrowser failed";
        }
      } else {
        LOG(WARN) << "QueryInterface for IServiceProvider failed";
      }
    } else {
      LOGHR(WARN, hr) << "Call to IHTMLDocument2::get_parentWindow failed";
    }
  } else {
    *error_message = "Could not get document from window handle";
  }
  return false;
}
Example #2
0
bool BrowserFactory::AttachToBrowser(ProcessWindowInfo* process_window_info,
                                     const int timeout_in_milliseconds,
                                     const bool ignore_zoom_setting,
                                     std::string* error_message) {
  LOG(TRACE) << "Entering BrowserFactory::AttachToBrowser";
  clock_t end = clock() + (timeout_in_milliseconds / 1000 * CLOCKS_PER_SEC);
  while (process_window_info->hwndBrowser == NULL) {
    if (timeout_in_milliseconds > 0 && (clock() > end)) {
      break;
    }
    ::EnumWindows(&BrowserFactory::FindBrowserWindow,
                  reinterpret_cast<LPARAM>(process_window_info));
    if (process_window_info->hwndBrowser == NULL) {
      ::Sleep(250);
    }
  }

  if (process_window_info->hwndBrowser == NULL) {
    int attach_fail_msg_count = _scprintf(ATTACH_TIMEOUT_ERROR_MESSAGE,
                                          process_window_info->dwProcessId,
                                          timeout_in_milliseconds);
    vector<char> attach_fail_msg_buffer(attach_fail_msg_count + 1);
    _snprintf_s(&attach_fail_msg_buffer[0],
                attach_fail_msg_buffer.size(),
                attach_fail_msg_count,
                ATTACH_TIMEOUT_ERROR_MESSAGE,
                process_window_info->dwProcessId,
                timeout_in_milliseconds);
    std::string attach_fail_msg = &attach_fail_msg_buffer[0];
    *error_message = attach_fail_msg;
    return false;
  }

  CComPtr<IHTMLDocument2> document;
  if (this->GetDocumentFromWindowHandle(process_window_info->hwndBrowser,
                                        &document)) {
    CComPtr<IHTMLWindow2> window;
    HRESULT hr = document->get_parentWindow(&window);

    // Test for zoom level = 100%
    int zoom_level = 100;
    LOG(DEBUG) << "Ignoring zoom setting: " << ignore_zoom_setting;
    if (!ignore_zoom_setting) {
      zoom_level = this->GetZoomLevel(document, window);
    }
    if (zoom_level != 100) {
      vector<char> zoom_level_buffer(10);
      _itoa_s(zoom_level, &zoom_level_buffer[0], 10, 10);
      std::string zoom(&zoom_level_buffer[0]);
      *error_message = "Browser zoom level was set to " + zoom + "%. It should be set to 100%";
      return false;
    }
    if (SUCCEEDED(hr)) {
      // http://support.microsoft.com/kb/257717
      CComPtr<IServiceProvider> provider;
      window->QueryInterface<IServiceProvider>(&provider);
      if (provider) {
        CComPtr<IServiceProvider> child_provider;
        hr = provider->QueryService(SID_STopLevelBrowser,
                                    IID_IServiceProvider,
                                    reinterpret_cast<void**>(&child_provider));
        if (SUCCEEDED(hr)) {
          IWebBrowser2* browser;
          hr = child_provider->QueryService(SID_SWebBrowserApp,
                                            IID_IWebBrowser2,
                                            reinterpret_cast<void**>(&browser));
          if (SUCCEEDED(hr)) {
            process_window_info->pBrowser = browser;
            return true;
          } else {
            LOGHR(WARN, hr) << "IServiceProvider::QueryService for SID_SWebBrowserApp failed";
          }
        } else {
          LOGHR(WARN, hr) << "IServiceProvider::QueryService for SID_STopLevelBrowser failed";
        }
      } else {
        LOG(WARN) << "QueryInterface for IServiceProvider failed";
      }
    } else {
      LOGHR(WARN, hr) << "Call to IHTMLDocument2::get_parentWindow failed";
    }
  } else {
    *error_message = "Could not get document from window handle";
  }
  return false;
}