// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// 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 <shellapi.h>

#include "base/base_paths.h"
#include "base/bind.h"
#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/path_service.h"
#include "base/process/kill.h"
#include "base/process/process_info.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/time/time.h"
#include "base/win/metro.h"
#include "base/win/registry.h"
#include "base/win/scoped_handle.h"
#include "base/win/windows_version.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/browser_process_platform_part.h"
#include "chrome/browser/chrome_process_finder_win.h"
#include "chrome/browser/metro_utils/metro_chrome_win.h"
#include "chrome/browser/shell_integration.h"
#include "chrome/browser/ui/simple_message_box.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/installer/util/wmi.h"
#include "content/public/common/result_codes.h"
#include "grit/chromium_strings.h"
#include "grit/generated_resources.h"
#include "net/base/escape.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/gfx/win/hwnd_util.h"

namespace {

const char kLockfile[] = "lockfile";

const int kMetroChromeActivationTimeoutMs = 3000;

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

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

 private:
  HANDLE mutex_;
  DISALLOW_COPY_AND_ASSIGN(AutoLockMutex);
};

// A helper class that releases the given |mutex| while the AutoUnlockMutex is
// in scope and immediately re-acquires it when going out of scope.
class AutoUnlockMutex {
 public:
  explicit AutoUnlockMutex(HANDLE mutex) : mutex_(mutex) {
    BOOL released = ::ReleaseMutex(mutex_);
    DPCHECK(released);
  }

  ~AutoUnlockMutex() {
    DWORD result = ::WaitForSingleObject(mutex_, INFINITE);
    DPCHECK(result == WAIT_OBJECT_0) << "Result = " << result;
  }

 private:
  HANDLE mutex_;
  DISALLOW_COPY_AND_ASSIGN(AutoUnlockMutex);
};

// 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,
                      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 = 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;

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

  CommandLine parsed_command_line(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;
}

// Returns true if Chrome needs to be relaunched into Windows 8 immersive mode.
// Following conditions apply:-
// 1. Windows 8 or greater.
// 2. Not in Windows 8 immersive mode.
// 3. Chrome is default browser.
// 4. Process integrity level is not high.
// 5. The profile data directory is the default directory.
// 6. Last used mode was immersive/machine is a tablet.
// TODO(ananta)
// Move this function to a common place as the Windows 8 delegate_execute
// handler can possibly use this.
bool ShouldLaunchInWindows8ImmersiveMode(const base::FilePath& user_data_dir) {
#if defined(USE_AURA)
  // Returning false from this function doesn't mean we don't launch immersive
  // mode in Aura. This function is specifically called in case when we need
  // to relaunch desktop launched chrome into immersive mode through 'relaunch'
  // menu. In case of Aura, we will use delegate_execute to do the relaunch.
  return false;
#else
  if (base::win::GetVersion() < base::win::VERSION_WIN8)
    return false;

  if (base::win::IsProcessImmersive(base::GetCurrentProcessHandle()))
    return false;

  if (ShellIntegration::GetDefaultBrowser() != ShellIntegration::IS_DEFAULT)
    return false;

  base::IntegrityLevel integrity_level = base::INTEGRITY_UNKNOWN;
  base::GetProcessIntegrityLevel(base::GetCurrentProcessHandle(),
                                 &integrity_level);
  if (integrity_level == base::HIGH_INTEGRITY)
    return false;

  base::FilePath default_user_data_dir;
  if (!chrome::GetDefaultUserDataDirectory(&default_user_data_dir))
    return false;

  if (default_user_data_dir != user_data_dir)
    return false;

  base::win::RegKey reg_key;
  DWORD reg_value = 0;
  if (reg_key.Create(HKEY_CURRENT_USER, chrome::kMetroRegistryPath,
                     KEY_READ) == ERROR_SUCCESS &&
      reg_key.ReadValueDW(chrome::kLaunchModeValue,
                          &reg_value) == ERROR_SUCCESS) {
    return reg_value == 1;
  }
  return false;
#endif
}

}  // 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) {
  if (::GetModuleHandle(L"sftldr_wow64.dll") ||
      ::GetModuleHandle(L"sftldr.dll")) {
    int process_id;
    if (!installer::WMIProcess::Launch(::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) {
}

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

// Code roughly based on Mozilla.
ProcessSingleton::NotifyResult 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_, false)) {
    case chrome::NOTIFY_SUCCESS:
      return PROCESS_NOTIFIED;
    case chrome::NOTIFY_FAILED:
      remote_window_ = NULL;
      return PROCESS_NONE;
    case chrome::NOTIFY_WINDOW_HUNG:
      remote_window_ = NULL;
      break;
  }

  DWORD process_id = 0;
  DWORD thread_id = ::GetWindowThreadProcessId(remote_window_, &process_id);
  if (!thread_id || !process_id) {
    remote_window_ = NULL;
    return PROCESS_NONE;
  }

  // The window is hung. Scan for every window to find a visible one.
  bool visible_window = false;
  ::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 &&
      chrome::ShowMessageBox(
          NULL,
          l10n_util::GetStringUTF16(IDS_PRODUCT_NAME),
          l10n_util::GetStringUTF16(IDS_BROWSER_HUNGBROWSER_MESSAGE),
          chrome::MESSAGE_BOX_TYPE_QUESTION) == chrome::MESSAGE_BOX_RESULT_NO) {
    // The user denied. Quit silently.
    return PROCESS_NOTIFIED;
  }

  // Time to take action. Kill the browser process.
  base::KillProcessById(process_id, content::RESULT_CODE_HUNG, true);
  remote_window_ = NULL;
  return PROCESS_NONE;
}

ProcessSingleton::NotifyResult
ProcessSingleton::NotifyOtherProcessOrCreate() {
  ProcessSingleton::NotifyResult result = PROCESS_NONE;
  if (!Create()) {
    result = NotifyOtherProcess();
    if (result == PROCESS_NONE)
      result = PROFILE_IN_USE;
  } else {
    g_browser_process->platform_part()->PlatformSpecificCommandLineProcessing(
        *CommandLine::ForCurrentProcess());
  }
  return result;
}

// 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() {
  static const wchar_t kMutexName[] = L"Local\\ChromeProcessSingletonStartup!";
  static const wchar_t kMetroActivationEventName[] =
      L"Local\\ChromeProcessSingletonStartupMetroActivation!";

  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));
    DPCHECK(only_me.IsValid());

    AutoLockMutex auto_lock_only_me(only_me);

    // 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_);


    // In Win8+, a new Chrome process launched in Desktop mode may need to be
    // transmuted into Metro Chrome (see ShouldLaunchInWindows8ImmersiveMode for
    // heuristics). To accomplish this, the current Chrome activates Metro
    // Chrome, releases the startup mutex, and waits for metro Chrome to take
    // the singleton. From that point onward, the command line for this Chrome
    // process will be sent to Metro Chrome by the usual channels.
    if (!remote_window_ && base::win::GetVersion() >= base::win::VERSION_WIN8 &&
        !base::win::IsMetroProcess()) {
      // |metro_activation_event| is created right before activating a Metro
      // Chrome (note that there can only be one Metro Chrome process; by OS
      // design); all following Desktop processes will then wait for this event
      // to be signaled by Metro Chrome which will do so as soon as it grabs
      // this singleton (should any of the waiting processes timeout waiting for
      // the signal they will try to grab the singleton for themselves which
      // will result in a forced Desktop Chrome launch in the worst case).
      base::win::ScopedHandle metro_activation_event(
          ::OpenEvent(SYNCHRONIZE, FALSE, kMetroActivationEventName));
      if (!metro_activation_event.IsValid() &&
          ShouldLaunchInWindows8ImmersiveMode(user_data_dir_)) {
        // No Metro activation is under way, but the desire is to launch in
        // Metro mode: activate and rendez-vous with the activated process.
        metro_activation_event.Set(
            ::CreateEvent(NULL, TRUE, FALSE, kMetroActivationEventName));
        if (!chrome::ActivateMetroChrome()) {
          // Failed to launch immersive Chrome, default to launching on Desktop.
          LOG(ERROR) << "Failed to launch immersive chrome";
          metro_activation_event.Close();
        }
      }

      if (metro_activation_event.IsValid()) {
        // Release |only_me| (to let Metro Chrome grab this singleton) and wait
        // until the event is signaled (i.e. Metro Chrome was successfully
        // activated). Ignore timeout waiting for |metro_activation_event|.
        {
          AutoUnlockMutex auto_unlock_only_me(only_me);

          DWORD result = ::WaitForSingleObject(metro_activation_event,
                                               kMetroChromeActivationTimeoutMs);
          DPCHECK(result == WAIT_OBJECT_0 || result == WAIT_TIMEOUT)
              << "Result = " << result;
        }

        // Check if this singleton was successfully grabbed by another process
        // (hopefully Metro Chrome). Failing to do so, this process will grab
        // the singleton and launch in Desktop mode.
        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.
      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.
        bool result = window_.CreateNamed(
            base::Bind(&ProcessLaunchNotification, notification_callback_),
            user_data_dir_.value());
        CHECK(result && window_.hwnd());
      }

      if (base::win::GetVersion() >= base::win::VERSION_WIN8) {
        // Make sure no one is still waiting on Metro activation whether it
        // succeeded (i.e., this is the Metro process) or failed.
        base::win::ScopedHandle metro_activation_event(
            ::OpenEvent(EVENT_MODIFY_STATE, FALSE, kMetroActivationEventName));
        if (metro_activation_event.IsValid())
          ::SetEvent(metro_activation_event);
      }
    }
  }

  return window_.hwnd() != NULL;
}

void ProcessSingleton::Cleanup() {
}
