Exemplo n.º 1
0
void BrowserFactory::LaunchBrowserUsingCreateProcess(const std::string& initial_url,
                                                     const std::string& command_line_switches,
                                                     PROCESS_INFORMATION* proc_info,
                                                     std::string* error_message) {
  LOG(TRACE) << "Entering BrowserFactory::LaunchBrowserUsingCreateProcess";
  LOG(DEBUG) << "Starting IE using the CreateProcess API";

  STARTUPINFO start_info;
  ::ZeroMemory(&start_info, sizeof(start_info));
  start_info.cb = sizeof(start_info);

  std::wstring wide_initial_url = StringUtilities::ToWString(initial_url);
  std::wstring wide_ie_switches = StringUtilities::ToWString(command_line_switches);

  std::wstring executable_and_url = this->ie_executable_location_;
  if (wide_ie_switches.size() != 0) {
    executable_and_url.append(L" ");
    executable_and_url.append(wide_ie_switches);
  }
  executable_and_url.append(L" ");
  executable_and_url.append(wide_initial_url);

  LOG(TRACE) << "IE starting command line is: '" << LOGWSTRING(executable_and_url) << "'.";

  LPWSTR command_line = new WCHAR[executable_and_url.size() + 1];
  wcscpy_s(command_line,
           executable_and_url.size() + 1,
           executable_and_url.c_str());
  command_line[executable_and_url.size()] = L'\0';
  BOOL create_process_result = ::CreateProcess(NULL,
                                               command_line,
                                               NULL,
                                               NULL,
                                               FALSE,
                                               0,
                                               NULL,
                                               NULL,
                                               &start_info,
                                               proc_info);
  if (!create_process_result) {
    int create_proc_msg_count = _scwprintf(CREATEPROCESS_ERROR_MESSAGE,
                                           command_line);
    vector<wchar_t> create_proc_result_msg(create_proc_msg_count + 1);
    _snwprintf_s(&create_proc_result_msg[0],
                  create_proc_result_msg.size(),
                  create_proc_msg_count,
                  CREATEPROCESS_ERROR_MESSAGE,
                  command_line);
    std::string launch_error = StringUtilities::ToString(&create_proc_result_msg[0]);
    *error_message = launch_error;
  }
  delete[] command_line;
}
Exemplo n.º 2
0
DWORD BrowserFactory::LaunchBrowserProcess(const std::string& initial_url,
                                           const bool ignore_protected_mode_settings,
                                           std::string* error_message) {
  LOG(TRACE) << "Entering BrowserFactory::LaunchBrowserProcess";

  DWORD process_id = NULL;
  bool has_valid_protected_mode_settings = false;
  LOG(DEBUG) << "Ignoring Protected Mode Settings: "
             << ignore_protected_mode_settings;
  if (!ignore_protected_mode_settings) {
    LOG(DEBUG) << "Checking validity of Protected Mode settings.";
    has_valid_protected_mode_settings = this->ProtectedModeSettingsAreValid();
  }
  LOG(DEBUG) << "Has Valid Protected Mode Settings: "
             << has_valid_protected_mode_settings;
  if (ignore_protected_mode_settings || has_valid_protected_mode_settings) {
    STARTUPINFO start_info;
    PROCESS_INFORMATION proc_info;

    ::ZeroMemory(&start_info, sizeof(start_info));
    start_info.cb = sizeof(start_info);
    ::ZeroMemory(&proc_info, sizeof(proc_info));

    std::wstring wide_initial_url(CA2W(initial_url.c_str(), CP_UTF8));

    FARPROC proc_address = 0;
    HMODULE library_handle = ::LoadLibrary(IEFRAME_LIBRARY_NAME);
    if (library_handle != NULL) {
      proc_address = ::GetProcAddress(library_handle, IELAUNCHURL_FUNCTION_NAME);
    }

    std::string launch_api = "The IELaunchURL() API";
    std::string launch_error = "";
    if (proc_address != 0) {
      // If we have the IELaunchURL API, expressly use it. This will
      // guarantee a new session. Simply using CoCreateInstance to 
      // create the browser will merge sessions, making separate cookie
      // handling impossible.
      HRESULT launch_result = ::IELaunchURL(wide_initial_url.c_str(),
                                            &proc_info,
                                            NULL);
      if (FAILED(launch_result)) {
        size_t launch_msg_count = _scprintf(IELAUNCHURL_ERROR_MESSAGE,
                                            launch_result,
                                            initial_url);
        vector<char> launch_result_msg(launch_msg_count + 1);
        _snprintf_s(&launch_result_msg[0],
                    sizeof(launch_result_msg),
                    launch_msg_count + 1,
                    IELAUNCHURL_ERROR_MESSAGE,
                    launch_result,
                    initial_url);
        launch_error = &launch_result_msg[0];
        *error_message = launch_error;
      }
    } else {
      launch_api = "The CreateProcess() API";
      std::wstring executable_and_url = this->ie_executable_location_ +
                                        L" " + wide_initial_url;
      LPWSTR command_line = new WCHAR[executable_and_url.size() + 1];
      wcscpy_s(command_line,
               executable_and_url.size() + 1,
               executable_and_url.c_str());
      command_line[executable_and_url.size()] = L'\0';
      BOOL create_process_result = ::CreateProcess(NULL,
                                                   command_line,
                                                   NULL,
                                                   NULL,
                                                   FALSE,
                                                   0,
                                                   NULL,
                                                   NULL,
                                                   &start_info,
                                                   &proc_info);
      if (!create_process_result) {
        int create_proc_msg_count = _scwprintf(CREATEPROCESS_ERROR_MESSAGE,
                                               command_line);
        vector<wchar_t> create_proc_result_msg(create_proc_msg_count + 1);
        _snwprintf_s(&create_proc_result_msg[0],
                     sizeof(create_proc_result_msg),
                     create_proc_msg_count,
                     CREATEPROCESS_ERROR_MESSAGE,
                     command_line);
        launch_error = CW2A(&create_proc_result_msg[0], CP_UTF8);
        *error_message = launch_error;
      }
      delete[] command_line;
    }

    process_id = proc_info.dwProcessId;
    if (process_id == NULL) {
      // If whatever API we are using failed to launch the browser, we should
      // have a NULL value in the dwProcessId member of the PROCESS_INFORMATION
      // structure. In that case, we will have already set the approprate error
      // message. On the off chance that we haven't yet set the appropriate
      // error message, that means we successfully launched the browser (i.e.,
      // the browser launch API returned a success code), but we still have a
      // NULL process ID.
      if (launch_error.size() == 0) {
        *error_message = launch_api + NULL_PROCESS_ID_ERROR_MESSAGE;
      }
    }

    if (proc_info.hThread != NULL) {
      ::CloseHandle(proc_info.hThread);
    }

    if (proc_info.hProcess != NULL) {
      ::CloseHandle(proc_info.hProcess);
    }

    if (library_handle != NULL) {
      ::FreeLibrary(library_handle);
    }
  } else {
    *error_message = PROTECTED_MODE_SETTING_ERROR_MESSAGE;
  }
  return process_id;
}