// Copyright 2010-2015, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include "win32/custom_action/custom_action.h"

#include <windows.h>
#include <atlbase.h>
#if !defined(NO_LOGGING)
#include <atlstr.h>
#endif  // !NO_LOGGING
#include <msiquery.h>

#include <memory>
#include <string>
#include <vector>

#include "base/const.h"
#include "base/process.h"
#include "base/system_util.h"
#include "base/url.h"
#include "base/util.h"
#include "base/win_util.h"
#include "base/version.h"
#include "client/client_interface.h"
#include "config/stats_config_util.h"
#include "renderer/renderer_client.h"
#include "server/cache_service_manager.h"
#include "session/commands.pb.h"
#include "win32/base/imm_registrar.h"
#include "win32/base/imm_util.h"
#include "win32/base/keyboard_layout_id.h"
#include "win32/base/omaha_util.h"
#include "win32/base/tsf_registrar.h"
#include "win32/base/uninstall_helper.h"
#include "win32/custom_action/resource.h"


#ifdef _DEBUG
#define DEBUG_BREAK_FOR_DEBUGGER()  \
::OutputDebugStringA(  \
    (mozc::Version::GetMozcVersion() + ": " + __FUNCTION__).c_str()); \
if (::IsDebuggerPresent()) {        \
    __debugbreak();                 \
}
#else
#define DEBUG_BREAK_FOR_DEBUGGER()
#endif  // _DEBUG


namespace {

using std::unique_ptr;
using mozc::win32::OmahaUtil;

const char kIEFrameDll[] = "ieframe.dll";
const wchar_t kSystemSharedKey[] = L"Software\\Microsoft\\CTF\\SystemShared";

HMODULE g_module = nullptr;

HRESULT CallSystemDllFunction(const char* dll_name,
                              const char* function_name) {
  HRESULT result = E_NOTIMPL;
  wstring wdll_name;
  mozc::Util::UTF8ToWide(dll_name, &wdll_name);
  const HMODULE dll = mozc::WinUtil::LoadSystemLibrary(wdll_name);
  if (dll != nullptr) {
    typedef HRESULT (*DllFunction)();
    DllFunction dll_function = reinterpret_cast<DllFunction>(
        ::GetProcAddress(dll, function_name));
    if (dll_function) {
      result = dll_function();
    } else {
       const DWORD error = GetLastError();
       result = HRESULT_FROM_WIN32(error);
     }
    FreeLibrary(dll);
  } else {
    result = E_FAIL;
  }
  return result;
}

wstring GetMozcComponentPath(const string &filename) {
  const string path = mozc::SystemUtil::GetServerDirectory() + "\\" + filename;
  wstring wpath;
  mozc::Util::UTF8ToWide(path.c_str(), &wpath);
  return wpath;
}

// Retrieves the value for an installer property.
// Returns an empty string if a property corresponding to |name| is not found or
// error occurs.
wstring GetProperty(MSIHANDLE msi, const wstring &name) {
  DWORD num_buf = 0;
  // Obtains the size of the property's string, without null termination.
  UINT result = MsiGetProperty(msi, name.c_str(), L"", &num_buf);
  if (ERROR_MORE_DATA != result) {
    return L"";
  }

  // add 1 for null termination
  ++num_buf;
  unique_ptr<wchar_t[]> buf(new wchar_t[num_buf]);
  result = MsiGetProperty(msi, name.c_str(), buf.get(), &num_buf);
  if (ERROR_SUCCESS != result) {
    return L"";
  }

  return wstring(buf.get());
}

bool SetProperty(MSIHANDLE msi, const wstring &name, const wstring &value) {
  if (MsiSetProperty(msi, name.c_str(), value.c_str()) != ERROR_SUCCESS) {
    return false;
  }
  return true;
}

#ifndef NO_LOGGING
bool DisableErrorReportingInternal(const wchar_t* key_name,
                                   const wchar_t* value_name,
                                   DWORD value,
                                   REGSAM additional_sam_desired) {
  CRegKey key;
  LONG result = key.Create(HKEY_LOCAL_MACHINE, key_name, REG_NONE,
                           REG_OPTION_NON_VOLATILE,
                           KEY_WRITE | additional_sam_desired);
  if (ERROR_SUCCESS != result) {
    return false;
  }
  result = key.SetDWORDValue(value_name, value);
  if (ERROR_SUCCESS != result) {
    return false;
  }
  return true;
}
#endif

wstring FormatMessageByResourceId(int resourceID, ...) {
  wchar_t format_message[4096];
  {
    const int length = ::LoadString(g_module, resourceID, format_message,
                                    arraysize(format_message));
    if (length <= 0 || arraysize(format_message) <= length) {
      return L"";
    }
  }
  va_list va_args = nullptr;
  va_start(va_args, resourceID);

  wchar_t buffer[4096];  // should be less than 64KB.
  // TODO(yukawa): Use message table instead of string table.
  {
    const DWORD num_chars =
        ::FormatMessage(FORMAT_MESSAGE_FROM_STRING, format_message, 0, 0,
                        &buffer[0], arraysize(buffer), &va_args);
    va_end(va_args);

    if (num_chars == 0 || num_chars >= arraysize(buffer)) {
      return L"";
    }
  }

  return buffer;
}

wstring GetVersionHeader() {
  return FormatMessageByResourceId(IDS_FORMAT_VERSION_INFO,
                                   mozc::Version::GetMozcVersionW().c_str());
}

bool WriteOmahaErrorById(int resource_id) {
  wchar_t buffer[4096];
  const int length
      = ::LoadString(g_module, resource_id, buffer, arraysize(buffer));
  if (length <= 0 || arraysize(buffer) <= length) {
    return false;
  }


  return OmahaUtil::WriteOmahaError(buffer, GetVersionHeader());
}

template <size_t num_elements>
bool WriteOmahaError(const wchar_t (&function)[num_elements], int line) {
#if !defined(NO_LOGGING)
  CStringW log;
  log.Format(L"%s: %s; %s(%d)", L"WriteOmahaError: ",
             mozc::Version::GetMozcVersionW().c_str(), function, line);
  ::OutputDebugStringW(log);
#endif
  const wstring &message =
      FormatMessageByResourceId(IDS_FORMAT_FUNCTION_AND_LINE,
                                function, line);
  return OmahaUtil::WriteOmahaError(message, GetVersionHeader());
}

// Compose an error message based on the function name and line number.
// This message will be displayed by Omaha meta installer on the error
// dialog.
#define LOG_ERROR_FOR_OMAHA() WriteOmahaError(_T(__FUNCTION__), __LINE__)

UINT RemovePreloadKeyByKLID(const mozc::win32::KeyboardLayoutID &klid) {
  if (!klid.has_id()) {
    // already removed.
    return ERROR_SUCCESS;
  }
  const mozc::win32::KeyboardLayoutID default_klid(
      mozc::kDefaultKeyboardLayout);
  const HRESULT result = mozc::win32::ImmRegistrar::RemoveKeyFromPreload(
      klid, default_klid);
  return SUCCEEDED(result) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE;
}
}

BOOL APIENTRY DllMain(HMODULE module,
                      DWORD  ul_reason_for_call,
                      LPVOID reserved) {
  switch (ul_reason_for_call) {
    case DLL_PROCESS_ATTACH:
      g_module = module;
      break;
    case DLL_PROCESS_DETACH:
      g_module = nullptr;
      break;
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
      break;
  }

  return TRUE;
}

UINT __stdcall RefreshPolicy(MSIHANDLE msi_handle) {
  DEBUG_BREAK_FOR_DEBUGGER();
  HRESULT result = CallSystemDllFunction(kIEFrameDll,
                                         "IERefreshElevationPolicy");
  if (FAILED(result)) {
    LOG_ERROR_FOR_OMAHA();
    return ERROR_INSTALL_FAILURE;
  }
  return ERROR_SUCCESS;
}

// [Return='ignore']
UINT __stdcall OpenUninstallSurveyPage(MSIHANDLE msi_handle) {
  DEBUG_BREAK_FOR_DEBUGGER();
  string url;
  mozc::URL::GetUninstallationSurveyURL(mozc::Version::GetMozcVersion(), &url);
  mozc::Process::OpenBrowser(url);
  return ERROR_SUCCESS;
}

UINT __stdcall ShutdownServer(MSIHANDLE msi_handle) {
  DEBUG_BREAK_FOR_DEBUGGER();
  unique_ptr<mozc::client::ClientInterface> server_client(
      mozc::client::ClientFactory::NewClient());
  bool server_result = true;
  if (server_client->PingServer()) {
    server_result = server_client->Shutdown();
  }
  mozc::renderer::RendererClient renderer_client;
  const bool renderer_result = renderer_client.Shutdown(true);
  if (!server_result) {
    LOG_ERROR_FOR_OMAHA();
    return ERROR_INSTALL_FAILURE;
  }
  if (!renderer_result) {
    LOG_ERROR_FOR_OMAHA();
    return ERROR_INSTALL_FAILURE;
  }

  return ERROR_SUCCESS;
}

// [Return='ignore']
UINT __stdcall RestoreUserIMEEnvironment(MSIHANDLE msi_handle) {
  DEBUG_BREAK_FOR_DEBUGGER();
  const bool result =
      mozc::win32::UninstallHelper::RestoreUserIMEEnvironmentMain();
  return result ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE;
}

// [Return='ignore']
UINT __stdcall EnsureIMEIsDisabledForServiceAccount(MSIHANDLE msi_handle) {
  DEBUG_BREAK_FOR_DEBUGGER();
  bool is_service = false;
  if (!mozc::WinUtil::IsServiceAccount(&is_service)) {
    return ERROR_INSTALL_FAILURE;
  }
  if (!is_service) {
    // Do nothing if this is not a service account.
    return ERROR_SUCCESS;
  }

  const bool result =
      mozc::win32::UninstallHelper::EnsureIMEIsRemovedForCurrentUser(true);
  return result ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE;
}

// [Return='ignore']
// Hides the cancel button on a progress dialog shown by the installer shows.
// Please see the following page for details.
// http://msdn.microsoft.com/en-us/library/aa368791(VS.85).aspx
UINT __stdcall HideCancelButton(MSIHANDLE msi_handle) {
  DEBUG_BREAK_FOR_DEBUGGER();
  PMSIHANDLE record = MsiCreateRecord(2);
  if (!record) {
    return ERROR_INSTALL_FAILURE;
  }
  if ((ERROR_SUCCESS != MsiRecordSetInteger(record, 1, 2) ||
       ERROR_SUCCESS != MsiRecordSetInteger(record, 2, 0))) {
    return ERROR_INSTALL_FAILURE;
  }
  MsiProcessMessage(msi_handle, INSTALLMESSAGE_COMMONDATA, record);
  return ERROR_SUCCESS;
}

UINT __stdcall InitialInstallation(MSIHANDLE msi_handle) {
  DEBUG_BREAK_FOR_DEBUGGER();

  // Write a general error message in case any unexpected error occurs.
  WriteOmahaErrorById(IDS_UNEXPECTED_ERROR);

  // We cannot rely on the result of GetVersion(Ex) in custom actions.
  // http://b/2430094
  // http://blogs.msdn.com/cjacks/archive/2009/05/06/why-custom-actions-get-a-windows-vista-version-lie-on-windows-7.aspx
  // SystemUtil::IsPlatformSupported uses VerifyVersionInfo, which is expected
  // to be not affected by the version lie for GetVersion(Ex).
  // MsiEvaluateCondition API may be another way to check the condition.
  // http://msdn.microsoft.com/en-us/library/aa370104.aspx
  if (!mozc::SystemUtil::IsPlatformSupported()) {
    WriteOmahaErrorById(IDS_UNSUPPORTED_PLATFORM);
    return ERROR_INSTALL_FAILURE;
  }
  return ERROR_SUCCESS;
}

UINT __stdcall InitialInstallationCommit(MSIHANDLE msi_handle) {
  DEBUG_BREAK_FOR_DEBUGGER();

  // Set error code 0, which means success.
  OmahaUtil::ClearOmahaError();
  return ERROR_SUCCESS;
}

UINT __stdcall SaveCustomActionData(MSIHANDLE msi_handle) {
  DEBUG_BREAK_FOR_DEBUGGER();
  // store the CHANNEL value specified in the command line argument for
  // WriteApValue.
  const wstring channel = GetProperty(msi_handle, L"CHANNEL");
  if (!channel.empty()) {
    if (!SetProperty(msi_handle, L"WriteApValue", channel)) {
      LOG_ERROR_FOR_OMAHA();
      return ERROR_INSTALL_FAILURE;
    }
  }

  // store the original ap value for WriteApValueRollback.
  const wstring ap_value = OmahaUtil::ReadChannel();
  if (!SetProperty(msi_handle, L"WriteApValueRollback", ap_value.c_str())) {
    LOG_ERROR_FOR_OMAHA();
    return ERROR_INSTALL_FAILURE;
  }

  // store the current settings of the cache service.
  wstring backup;
  if (!mozc::CacheServiceManager::BackupStateAsString(&backup)) {
    LOG_ERROR_FOR_OMAHA();
    return ERROR_INSTALL_FAILURE;
  }
  if (!SetProperty(msi_handle, L"RestoreServiceState", backup.c_str())) {
    LOG_ERROR_FOR_OMAHA();
    return ERROR_INSTALL_FAILURE;
  }
  if (!SetProperty(msi_handle, L"RestoreServiceStateRollback",
                   backup.c_str())) {
    LOG_ERROR_FOR_OMAHA();
    return ERROR_INSTALL_FAILURE;
  }
  return ERROR_SUCCESS;
}

// [Return='ignore']
// This function is used for the following CustomActions:
// "RestoreServiceState" and "RestoreServiceStateRollback"
UINT __stdcall RestoreServiceState(MSIHANDLE msi_handle) {
  DEBUG_BREAK_FOR_DEBUGGER();
  const wstring &backup = GetProperty(msi_handle, L"CustomActionData");
  if (!mozc::CacheServiceManager::RestoreStateFromString(backup)) {
    return ERROR_INSTALL_FAILURE;
  }

  return ERROR_SUCCESS;
}

// [Return='ignore']
UINT __stdcall StopCacheService(MSIHANDLE msi_handle) {
  DEBUG_BREAK_FOR_DEBUGGER();
  if (!mozc::CacheServiceManager::EnsureServiceStopped()) {
    return ERROR_INSTALL_FAILURE;
  }

  return ERROR_SUCCESS;
}

UINT __stdcall WriteApValue(MSIHANDLE msi_handle) {
  DEBUG_BREAK_FOR_DEBUGGER();
  const wstring channel = GetProperty(msi_handle, L"CustomActionData");
  if (channel.empty()) {
    // OK. Does not change ap value when CustomActionData is not found.
    return ERROR_SUCCESS;
  }

  const bool result = OmahaUtil::WriteChannel(channel);
  if (!result) {
    LOG_ERROR_FOR_OMAHA();
    return ERROR_INSTALL_FAILURE;
  }
  return ERROR_SUCCESS;
}

UINT __stdcall WriteApValueRollback(MSIHANDLE msi_handle) {
  DEBUG_BREAK_FOR_DEBUGGER();
  const wstring ap_value = GetProperty(msi_handle, L"CustomActionData");
  if (ap_value.empty()) {
    // The ap value did not originally exist so attempt to delete the value.
    if (!OmahaUtil::ClearChannel()) {
      LOG_ERROR_FOR_OMAHA();
      return ERROR_INSTALL_FAILURE;
    }
    return ERROR_SUCCESS;
  }

  // Restore the original ap value.
  if (!OmahaUtil::WriteChannel(ap_value)) {
    LOG_ERROR_FOR_OMAHA();
    return ERROR_INSTALL_FAILURE;
  }
  return ERROR_SUCCESS;
}

UINT __stdcall InstallIME(MSIHANDLE msi_handle) {
  DEBUG_BREAK_FOR_DEBUGGER();

  const wstring ime_path =
      mozc::win32::ImmRegistrar::GetFullPathForIME();
  if (ime_path.empty()) {
    LOG_ERROR_FOR_OMAHA();
    return ERROR_INSTALL_FAILURE;
  }
  const wstring ime_filename =
      mozc::win32::ImmRegistrar::GetFileNameForIME();

  const wstring layout_name = mozc::win32::ImmRegistrar::GetLayoutName();
  if (layout_name.empty()) {
    LOG_ERROR_FOR_OMAHA();
    return ERROR_INSTALL_FAILURE;
  }

  // Install IME and obtain the corresponding HKL value.
  HKL hkl = nullptr;
  HRESULT result = mozc::win32::ImmRegistrar::Register(
      ime_filename, layout_name, ime_path,
      mozc::win32::ImmRegistrar::GetLayoutDisplayNameResourceId(), &hkl);
  if (result != S_OK) {
    LOG_ERROR_FOR_OMAHA();
    return ERROR_INSTALL_FAILURE;
  }

  return ERROR_SUCCESS;
}

UINT __stdcall InstallIMERollback(MSIHANDLE msi_handle) {
  DEBUG_BREAK_FOR_DEBUGGER();
  return RemovePreloadKeyByKLID(
      mozc::win32::ImmRegistrar::GetKLIDForIME());
}

UINT __stdcall UninstallIME(MSIHANDLE msi_handle) {
  DEBUG_BREAK_FOR_DEBUGGER();
  const wstring ime_filename =
      mozc::win32::ImmRegistrar::GetFileNameForIME();
  if (ime_filename.empty()) {
    return ERROR_INSTALL_FAILURE;
  }
  mozc::win32::ImmRegistrar::Unregister(ime_filename);
  return ERROR_SUCCESS;
}

UINT __stdcall UninstallIMERollback(MSIHANDLE msi_handle) {
  DEBUG_BREAK_FOR_DEBUGGER();

  return ERROR_SUCCESS;
}

UINT __stdcall RegisterTIP(MSIHANDLE msi_handle) {
  DEBUG_BREAK_FOR_DEBUGGER();
  mozc::ScopedCOMInitializer com_initializer;

#if defined(_M_X64)
  const wstring &path = GetMozcComponentPath(mozc::kMozcTIP64);
#elif defined(_M_IX86)
  const wstring &path = GetMozcComponentPath(mozc::kMozcTIP32);
#else
#error "Unsupported CPU architecture"
#endif  // _M_X64, _M_IX86, and others
  HRESULT result = mozc::win32::TsfRegistrar::RegisterCOMServer(path.c_str(),
                                                                path.length());
  if (FAILED(result)) {
    LOG_ERROR_FOR_OMAHA();
    UnregisterTIP(msi_handle);
    return ERROR_INSTALL_FAILURE;
  }

  result = mozc::win32::TsfRegistrar::RegisterProfiles(path.c_str(),
                                                       path.length());
  if (FAILED(result)) {
    LOG_ERROR_FOR_OMAHA();
    UnregisterTIP(msi_handle);
    return ERROR_INSTALL_FAILURE;
  }

  result = mozc::win32::TsfRegistrar::RegisterCategories();
  if (FAILED(result)) {
    LOG_ERROR_FOR_OMAHA();
    UnregisterTIP(msi_handle);
    return ERROR_INSTALL_FAILURE;
  }

  return ERROR_SUCCESS;
}

UINT __stdcall RegisterTIPRollback(MSIHANDLE msi_handle) {
  DEBUG_BREAK_FOR_DEBUGGER();
  return UnregisterTIP(msi_handle);
}

// [Return='ignore']
UINT __stdcall UnregisterTIP(MSIHANDLE msi_handle) {
  DEBUG_BREAK_FOR_DEBUGGER();
  mozc::ScopedCOMInitializer com_initializer;

  mozc::win32::TsfRegistrar::UnregisterCategories();
  mozc::win32::TsfRegistrar::UnregisterProfiles();
  mozc::win32::TsfRegistrar::UnregisterCOMServer();

  return ERROR_SUCCESS;
}

// [Return='ignore']
UINT __stdcall UnregisterTIPRollback(MSIHANDLE msi_handle) {
  DEBUG_BREAK_FOR_DEBUGGER();
  return RegisterTIP(msi_handle);
}
