// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/process_singleton.h"

#include <windows.h>
#include <shellapi.h>
#include <stddef.h>

#include "base/base_paths.h"
#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/functional/bind.h"
#include "base/logging.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "base/process/process.h"
#include "base/process/process_info.h"
#include "base/strings/escape.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "base/time/time.h"
#include "base/trace_event/base_tracing.h"
#include "base/win/registry.h"
#include "base/win/scoped_handle.h"
#include "base/win/windows_version.h"
#include "base/win/wmi.h"
#include "chrome/browser/process_singleton_internal.h"
#include "chrome/browser/shell_integration.h"
#include "chrome/browser/ui/simple_message_box.h"
#include "chrome/browser/win/chrome_process_finder.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_paths_internal.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/grit/chromium_strings.h"
#include "content/public/common/result_codes.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/scoped_startup_resource_bundle.h"
#include "ui/gfx/win/hwnd_util.h"

namespace {

const char kLockfile[] = "lockfile";

// A helper class that acquires the given |mutex| while the AutoLockMutex is in
// scope.
class AutoLockMutex {
 public:
  explicit AutoLockMutex(HANDLE mutex) : mutex_(mutex) {
    TRACE_EVENT0("startup",
                 "ProcessSingleton:AutoLockMutex:WaitForSingleObject");
    DWORD result = ::WaitForSingleObject(mutex_, INFINITE);
    DPCHECK(result == WAIT_OBJECT_0) << "Result = " << result;
  }

  AutoLockMutex(const AutoLockMutex&) = delete;
  AutoLockMutex& operator=(const AutoLockMutex&) = delete;

  ~AutoLockMutex() {
    BOOL released = ::ReleaseMutex(mutex_);
    DPCHECK(released);
  }

 private:
  HANDLE mutex_;
};

// Checks the visibility of the enumerated window and signals once a visible
// window has been found.
BOOL CALLBACK BrowserWindowEnumeration(HWND window, LPARAM param) {
  bool* result = reinterpret_cast<bool*>(param);
  *result = ::IsWindowVisible(window) != 0;
  // Stops enumeration if a visible window has been found.
  return !*result;
}

bool ParseCommandLine(const COPYDATASTRUCT* cds,
                      base::CommandLine* parsed_command_line,
                      base::FilePath* current_directory) {
  // We should have enough room for the shortest command (min_message_size)
  // and also be a multiple of wchar_t bytes. The shortest command
  // possible is L"START\0\0" (empty current directory and command line).
  static const int min_message_size = 7;
  if (cds->cbData < min_message_size * sizeof(wchar_t) ||
      cds->cbData % sizeof(wchar_t) != 0) {
    LOG(WARNING) << "Invalid WM_COPYDATA, length = " << cds->cbData;
    return false;
  }

  // We split the string into 4 parts on NULLs.
  DCHECK(cds->lpData);
  const std::wstring msg(static_cast<wchar_t*>(cds->lpData),
                         cds->cbData / sizeof(wchar_t));
  const std::wstring::size_type first_null = msg.find_first_of(L'\0');
  if (first_null == 0 || first_null == std::wstring::npos) {
    // no NULL byte, don't know what to do
    LOG(WARNING) << "Invalid WM_COPYDATA, length = " << msg.length() <<
      ", first null = " << first_null;
    return false;
  }

  // Decode the command, which is everything until the first NULL.
  if (msg.substr(0, first_null) == L"START") {
    // Another instance is starting parse the command line & do what it would
    // have done.
    VLOG(1) << "Handling STARTUP request from another process";
    const std::wstring::size_type second_null =
        msg.find_first_of(L'\0', first_null + 1);
    if (second_null == std::wstring::npos ||
        first_null == msg.length() - 1 || second_null == msg.length()) {
      LOG(WARNING) << "Invalid format for start command, we need a string in 4 "
        "parts separated by NULLs";
      return false;
    }

    // Get current directory.
    *current_directory = base::FilePath(msg.substr(first_null + 1,
                                                   second_null - first_null));

    const std::wstring::size_type third_null =
        msg.find_first_of(L'\0', second_null + 1);
    if (third_null == std::wstring::npos ||
        third_null == msg.length()) {
      LOG(WARNING) << "Invalid format for start command, we need a string in 4 "
        "parts separated by NULLs";
    }

    // Get command line.
    const std::wstring cmd_line =
        msg.substr(second_null + 1, third_null - second_null);
    *parsed_command_line = base::CommandLine::FromString(cmd_line);
    return true;
  }
  return false;
}

bool ProcessLaunchNotification(
    const ProcessSingleton::NotificationCallback& notification_callback,
    UINT message,
    WPARAM wparam,
    LPARAM lparam,
    LRESULT* result) {
  if (message != WM_COPYDATA)
    return false;

  TRACE_EVENT0("startup", "ProcessSingleton:ProcessLaunchNotification");

  // Handle the WM_COPYDATA message from another process.
  const COPYDATASTRUCT* cds = reinterpret_cast<COPYDATASTRUCT*>(lparam);

  base::CommandLine parsed_command_line(base::CommandLine::NO_PROGRAM);
  base::FilePath current_directory;
  if (!ParseCommandLine(cds, &parsed_command_line, &current_directory)) {
    *result = TRUE;
    return true;
  }

  *result = notification_callback.Run(parsed_command_line, current_directory) ?
      TRUE : FALSE;
  return true;
}

bool DisplayShouldKillMessageBox() {
  TRACE_EVENT0("startup", "ProcessSingleton:DisplayShouldKillMessageBox");

  // Ensure there is an instance of ResourceBundle that is initialized for
  // localized string resource accesses.
  ui::ScopedStartupResourceBundle startup_resource_bundle;

  return chrome::ShowQuestionMessageBoxSync(
             NULL, l10n_util::GetStringUTF16(IDS_PRODUCT_NAME),
             l10n_util::GetStringUTF16(IDS_BROWSER_HUNGBROWSER_MESSAGE)) !=
         chrome::MESSAGE_BOX_RESULT_NO;
}

// Function was copied from Process::Terminate.
void TerminateProcessWithHistograms(const base::Process& process,
                                    int exit_code) {
  TRACE_EVENT0("startup", "ProcessSingleton:TerminateProcessWithHistograms");
  DCHECK(process.IsValid());
  base::TimeTicks start_time = base::TimeTicks::Now();
  bool result = (::TerminateProcess(process.Handle(), exit_code) != FALSE);
  DWORD terminate_error = 0;
  if (result) {
    DWORD wait_error = 0;
    // The process may not end immediately due to pending I/O
    DWORD wait_result;
    {
      TRACE_EVENT0("startup",
                   "ProcessSingleton:TerminateProcessWithHistograms:"
                   "WaitForSingleObject");
      wait_result = ::WaitForSingleObject(process.Handle(), 60 * 1000);
    }

    if (wait_result != WAIT_OBJECT_0) {
      if (wait_result == WAIT_FAILED)
        wait_error = ::GetLastError();
      internal::SendRemoteProcessInteractionResultHistogram(
          ProcessSingleton::TERMINATE_WAIT_TIMEOUT);
      DPLOG(ERROR) << "Error waiting for process exit";
    } else {
      internal::SendRemoteProcessInteractionResultHistogram(
          ProcessSingleton::TERMINATE_SUCCEEDED);
    }
    UMA_HISTOGRAM_TIMES("Chrome.ProcessSingleton.TerminateProcessTime",
                        base::TimeTicks::Now() - start_time);
    base::UmaHistogramSparse(
        "Chrome.ProcessSingleton.TerminationWaitErrorCode.Windows", wait_error);
  } else {
    terminate_error = ::GetLastError();
    internal::SendRemoteProcessInteractionResultHistogram(
        ProcessSingleton::TERMINATE_FAILED);
    DPLOG(ERROR) << "Unable to terminate process";
  }
  base::UmaHistogramSparse(
      "Chrome.ProcessSingleton.TerminateProcessErrorCode.Windows",
      terminate_error);
}

}  // namespace

// Microsoft's Softricity virtualization breaks the sandbox processes.
// So, if we detect the Softricity DLL we use WMI Win32_Process.Create to
// break out of the virtualization environment.
// http://code.google.com/p/chromium/issues/detail?id=43650
bool ProcessSingleton::EscapeVirtualization(
    const base::FilePath& user_data_dir) {
  TRACE_EVENT0("startup", "ProcessSingleton:EscapeVirtualization");

  if (::GetModuleHandle(L"sftldr_wow64.dll") ||
      ::GetModuleHandle(L"sftldr.dll")) {
    int process_id;
    if (!base::win::WmiLaunchProcess(::GetCommandLineW(), &process_id))
      return false;
    is_virtualized_ = true;
    // The new window was spawned from WMI, and won't be in the foreground.
    // So, first we sleep while the new chrome.exe instance starts (because
    // WaitForInputIdle doesn't work here). Then we poll for up to two more
    // seconds and make the window foreground if we find it (or we give up).
    HWND hwnd = 0;
    ::Sleep(90);
    for (int tries = 200; tries; --tries) {
      hwnd = chrome::FindRunningChromeWindow(user_data_dir);
      if (hwnd) {
        ::SetForegroundWindow(hwnd);
        break;
      }
      ::Sleep(10);
    }
    return true;
  }
  return false;
}

ProcessSingleton::ProcessSingleton(
    const base::FilePath& user_data_dir,
    const NotificationCallback& notification_callback)
    : notification_callback_(notification_callback),
      is_virtualized_(false),
      lock_file_(INVALID_HANDLE_VALUE),
      user_data_dir_(user_data_dir),
      should_kill_remote_process_callback_(
          base::BindRepeating(&DisplayShouldKillMessageBox)) {}

ProcessSingleton::~ProcessSingleton() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  if (lock_file_ != INVALID_HANDLE_VALUE)
    ::CloseHandle(lock_file_);
}

// Code roughly based on Mozilla.
ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcess() {
  TRACE_EVENT0("startup", "ProcessSingleton::NotifyOtherProcess");

  if (is_virtualized_)
    return PROCESS_NOTIFIED;  // We already spawned the process in this case.
  if (lock_file_ == INVALID_HANDLE_VALUE && !remote_window_) {
    return LOCK_ERROR;
  } else if (!remote_window_) {
    return PROCESS_NONE;
  }

  switch (chrome::AttemptToNotifyRunningChrome(remote_window_)) {
    case chrome::NOTIFY_SUCCESS:
      return PROCESS_NOTIFIED;
    case chrome::NOTIFY_FAILED:
      remote_window_ = NULL;
      internal::SendRemoteProcessInteractionResultHistogram(
          RUNNING_PROCESS_NOTIFY_ERROR);
      return PROCESS_NONE;
    case chrome::NOTIFY_WINDOW_HUNG:
      // Fall through and potentially terminate the hung browser.
      break;
  }

  // The window is hung.
  DWORD process_id = 0;
  DWORD thread_id = ::GetWindowThreadProcessId(remote_window_, &process_id);
  if (!thread_id || !process_id) {
    TRACE_EVENT_INSTANT(
        "startup",
        "ProcessSingleton::NotifyOtherProcess:GetWindowThreadProcessId failed");
    remote_window_ = NULL;
    internal::SendRemoteProcessInteractionResultHistogram(
        REMOTE_PROCESS_NOT_FOUND);
    return PROCESS_NONE;
  }

  // Get a handle to the process that created the window.
  base::Process process = base::Process::Open(process_id);

  // Scan for every window to find a visible one.
  bool visible_window = false;
  {
    TRACE_EVENT0("startup",
                 "ProcessSingleton::NotifyOtherProcess:EnumThreadWindows");
    ::EnumThreadWindows(thread_id, &BrowserWindowEnumeration,
                        reinterpret_cast<LPARAM>(&visible_window));
  }

  // If there is a visible browser window, ask the user before killing it.
  if (visible_window && !should_kill_remote_process_callback_.Run()) {
    internal::SendRemoteProcessInteractionResultHistogram(
        USER_REFUSED_TERMINATION);
    // The user denied. Quit silently.
    return PROCESS_NOTIFIED;
  }
  internal::SendRemoteHungProcessTerminateReasonHistogram(
      visible_window ? USER_ACCEPTED_TERMINATION : NO_VISIBLE_WINDOW_FOUND);

  // Time to take action. Kill the browser process.
  TerminateProcessWithHistograms(process, content::RESULT_CODE_HUNG);

  remote_window_ = NULL;
  return PROCESS_NONE;
}

ProcessSingleton::NotifyResult
ProcessSingleton::NotifyOtherProcessOrCreate() {
  TRACE_EVENT0("startup", "ProcessSingleton::NotifyOtherProcessOrCreate");
  const base::TimeTicks begin_ticks = base::TimeTicks::Now();
  for (int i = 0; i < 2; ++i) {
    if (Create()) {
      UMA_HISTOGRAM_MEDIUM_TIMES("Chrome.ProcessSingleton.TimeToCreate",
                                 base::TimeTicks::Now() - begin_ticks);
      return PROCESS_NONE;  // This is the single browser process.
    }
    ProcessSingleton::NotifyResult result = NotifyOtherProcess();
    if (result == PROCESS_NOTIFIED || result == LOCK_ERROR) {
      if (result == PROCESS_NOTIFIED) {
        UMA_HISTOGRAM_MEDIUM_TIMES("Chrome.ProcessSingleton.TimeToNotify",
                                   base::TimeTicks::Now() - begin_ticks);
      } else {
        UMA_HISTOGRAM_MEDIUM_TIMES("Chrome.ProcessSingleton.TimeToFailure",
                                   base::TimeTicks::Now() - begin_ticks);
      }
      // The single browser process was notified, the user chose not to
      // terminate a hung browser, or the lock file could not be created.
      // Nothing more to do.
      return result;
    }
    DCHECK_EQ(PROCESS_NONE, result);
    // The process could not be notified for some reason, or it was hung and
    // terminated. Retry once if this is the first time; otherwise, fall through
    // to report that the process must exit because the profile is in use.
  }
  UMA_HISTOGRAM_MEDIUM_TIMES("Chrome.ProcessSingleton.TimeToFailure",
                             base::TimeTicks::Now() - begin_ticks);
  return PROFILE_IN_USE;
}

// Look for a Chrome instance that uses the same profile directory. If there
// isn't one, create a message window with its title set to the profile
// directory path.
bool ProcessSingleton::Create() {
  TRACE_EVENT0("startup", "ProcessSingleton::Create");

  static const wchar_t kMutexName[] = L"Local\\ChromeProcessSingletonStartup!";

  remote_window_ = chrome::FindRunningChromeWindow(user_data_dir_);
  if (!remote_window_ && !EscapeVirtualization(user_data_dir_)) {
    // Make sure we will be the one and only process creating the window.
    // We use a named Mutex since we are protecting against multi-process
    // access. As documented, it's clearer to NOT request ownership on creation
    // since it isn't guaranteed we will get it. It is better to create it
    // without ownership and explicitly get the ownership afterward.
    base::win::ScopedHandle only_me(::CreateMutex(NULL, FALSE, kMutexName));
    if (!only_me.IsValid()) {
      DPLOG(FATAL) << "CreateMutex failed";
      return false;
    }

    AutoLockMutex auto_lock_only_me(only_me.Get());

    // We now own the mutex so we are the only process that can create the
    // window at this time, but we must still check if someone created it
    // between the time where we looked for it above and the time the mutex
    // was given to us.
    remote_window_ = chrome::FindRunningChromeWindow(user_data_dir_);

    if (!remote_window_) {
      // We have to make sure there is no Chrome instance running on another
      // machine that uses the same profile.
      {
        TRACE_EVENT0("startup", "ProcessSingleton::Create:CreateLockFile");
        base::FilePath lock_file_path = user_data_dir_.AppendASCII(kLockfile);
        lock_file_ = ::CreateFile(
            lock_file_path.value().c_str(), GENERIC_WRITE, FILE_SHARE_READ,
            NULL, CREATE_ALWAYS,
            FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE, NULL);
      }
      DWORD error = ::GetLastError();
      LOG_IF(WARNING, lock_file_ != INVALID_HANDLE_VALUE &&
          error == ERROR_ALREADY_EXISTS) << "Lock file exists but is writable.";
      LOG_IF(ERROR, lock_file_ == INVALID_HANDLE_VALUE)
          << "Lock file can not be created! Error code: " << error;

      if (lock_file_ != INVALID_HANDLE_VALUE) {
        // Set the window's title to the path of our user data directory so
        // other Chrome instances can decide if they should forward to us.
        TRACE_EVENT0("startup", "ProcessSingleton::Create:CreateWindow");
        bool result =
            window_.CreateNamed(base::BindRepeating(&ProcessLaunchNotification,
                                                    notification_callback_),
                                user_data_dir_.value());
        CHECK(result && window_.hwnd());
      }
    }
  }

  return window_.hwnd() != NULL;
}

void ProcessSingleton::StartWatching() {}

void ProcessSingleton::Cleanup() {
}

void ProcessSingleton::OverrideShouldKillRemoteProcessCallbackForTesting(
    const ShouldKillRemoteProcessCallback& display_dialog_callback) {
  should_kill_remote_process_callback_ = display_dialog_callback;
}
