// 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 "base/win_util.h"

// skip all unless OS_WIN
#ifdef OS_WIN

#include <Aux_ulib.h>
#include <Psapi.h>
#include <Stringapiset.h>
#include <Winternl.h>

#define _ATL_NO_AUTOMATIC_NAMESPACE
#define _WTL_NO_AUTOMATIC_NAMESPACE
#include <atlbase.h>

#include <clocale>
#include <memory>

#include "base/logging.h"
#include "base/mutex.h"
#include "base/scoped_handle.h"
#include "base/system_util.h"
#include "base/util.h"

using std::unique_ptr;

namespace mozc {
namespace {

once_t g_aux_lib_initialized = MOZC_ONCE_INIT;

void CallAuxUlibInitialize() {
  ::AuxUlibInitialize();
}

// Adjusts privileges in the process token to be able to shutdown the machine.
// Returns true if the operation finishes without error.
// We do not use LOG functions in this function to avoid dependency to CRT.
bool AdjustPrivilegesForShutdown() {
  TOKEN_PRIVILEGES ns;
  HANDLE htoken;
  LUID LID;
  LUID_AND_ATTRIBUTES att;

  if (!::OpenProcessToken(::GetCurrentProcess(),
                          TOKEN_ADJUST_PRIVILEGES,
                          &htoken)) {
    // Cannot open process token
    return false;
  }

  if (!::LookupPrivilegeValue(nullptr, SE_SHUTDOWN_NAME, &LID)) {
    // LookupPrivilegeValue failed
    return false;
  }

  att.Attributes = SE_PRIVILEGE_ENABLED;
  att.Luid = LID;
  ns.PrivilegeCount = 1;
  ns.Privileges[0] = att;

  if (!::AdjustTokenPrivileges(htoken, FALSE, &ns, 0, nullptr, nullptr)) {
    // AdjustTokenPrivileges failed
    return false;
  }

  return true;
}

bool EqualLuid(const LUID &L1, const LUID &L2) {
  return (L1.LowPart == L2.LowPart && L1.HighPart == L2.HighPart);
}

}  // namespace

HMODULE WinUtil::LoadSystemLibrary(const wstring &base_filename) {
  wstring fullpath = SystemUtil::GetSystemDir();
  fullpath += L"\\";
  fullpath += base_filename;

  const HMODULE module = ::LoadLibraryExW(fullpath.c_str(),
                                          nullptr,
                                          LOAD_WITH_ALTERED_SEARCH_PATH);
  if (nullptr == module) {
    const int last_error = ::GetLastError();
    DLOG(WARNING) << "LoadLibraryEx failed."
                  << " fullpath = " << fullpath.c_str()
                  << " error = " << last_error;
  }
  return module;
}

HMODULE WinUtil::LoadMozcLibrary(const wstring &base_filename) {
  wstring fullpath;
  Util::UTF8ToWide(SystemUtil::GetServerDirectory().c_str(), &fullpath);
  fullpath += L"\\";
  fullpath += base_filename;

  const HMODULE module = ::LoadLibraryExW(fullpath.c_str(),
                                          nullptr,
                                          LOAD_WITH_ALTERED_SEARCH_PATH);
  if (nullptr == module) {
    const int last_error = ::GetLastError();
    DLOG(WARNING) << "LoadLibraryEx failed."
                  << " fullpath = " << fullpath.c_str()
                  << " error = " << last_error;
  }
  return module;
}

HMODULE WinUtil::GetSystemModuleHandle(const wstring &base_filename) {
  wstring fullpath = SystemUtil::GetSystemDir();
  fullpath += L"\\";
  fullpath += base_filename;

  HMODULE module = nullptr;
  if (GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
                         fullpath.c_str(), &module) == FALSE) {
    const int last_error = ::GetLastError();
    DLOG(WARNING) << "GetModuleHandleExW failed."
                  << " fullpath = " << fullpath.c_str()
                  << " error = " << last_error;
  }
  return module;
}

HMODULE WinUtil::GetSystemModuleHandleAndIncrementRefCount(
    const wstring &base_filename) {
  wstring fullpath = SystemUtil::GetSystemDir();
  fullpath += L"\\";
  fullpath += base_filename;

  HMODULE module = nullptr;
  if (GetModuleHandleExW(0, fullpath.c_str(), &module) == FALSE) {
    const int last_error = ::GetLastError();
    DLOG(WARNING) << "GetModuleHandleExW failed."
                  << " fullpath = " << fullpath.c_str()
                  << " error = " << last_error;
  }
  return module;
}

bool WinUtil::IsDLLSynchronizationHeld(bool *lock_status) {
  mozc::CallOnce(&g_aux_lib_initialized, &CallAuxUlibInitialize);

  if (lock_status == nullptr) {
    return false;
  }

  BOOL synchronization_held = FALSE;
  const BOOL result =
      ::AuxUlibIsDLLSynchronizationHeld(&synchronization_held);
  if (!result) {
    const int error = ::GetLastError();
    DLOG(ERROR) << "AuxUlibIsDLLSynchronizationHeld failed. error = "
                << error;
    return false;
  }
  *lock_status = (synchronization_held != FALSE);
  return true;
}

bool WinUtil::Logoff() {
  if (!AdjustPrivilegesForShutdown()) {
    return false;
  }
  return (::ExitWindowsEx(EWX_LOGOFF, SHTDN_REASON_MINOR_INSTALLATION) != 0);
}

bool WinUtil::Win32EqualString(const wstring &lhs, const wstring &rhs,
                               bool ignore_case, bool *are_equal) {
  const int compare_result = ::CompareStringOrdinal(
      lhs.c_str(), lhs.size(), rhs.c_str(), rhs.size(),
      (ignore_case ? TRUE : FALSE));

  if (are_equal != nullptr) {
    *are_equal = (compare_result == CSTR_EQUAL);
  }

  return true;
}

bool WinUtil::NativeEqualString(const wstring &lhs, const wstring &rhs,
                                bool ignore_case, bool *are_equal) {
  // http://msdn.microsoft.com/en-us/library/ff561854.aspx
  typedef BOOLEAN (NTAPI *FPRtlEqualUnicodeString)(
      __in PCUNICODE_STRING String1,
      __in PCUNICODE_STRING String2,
      __in BOOLEAN CaseInSensitive);

  const HMODULE ntdll = GetSystemModuleHandle(L"ntdll.dll");
  if (ntdll == nullptr) {
    LOG(ERROR) << "GetSystemModuleHandle failed";
    return false;
  }

  const FPRtlEqualUnicodeString rtl_equal_unicode_string =
      reinterpret_cast<FPRtlEqualUnicodeString>(
          ::GetProcAddress(ntdll, "RtlEqualUnicodeString"));
  if (rtl_equal_unicode_string == nullptr) {
    return false;
  }

  const UNICODE_STRING lhs_string = {
    lhs.size(),                     // Length
    lhs.size() + sizeof(wchar_t),   // MaximumLength
    const_cast<PWSTR>(lhs.c_str())  // Buffer
  };
  const UNICODE_STRING rhs_string = {
    rhs.size(),                     // Length
    rhs.size() + sizeof(wchar_t),   // MaximumLength
    const_cast<PWSTR>(rhs.c_str())  // Buffer
  };
  const BOOL compare_result = rtl_equal_unicode_string(
    &lhs_string, &rhs_string, (ignore_case ? TRUE : FALSE));

  if (are_equal != nullptr) {
    *are_equal = (compare_result != FALSE);
  }

  return true;
}

void WinUtil::CrtEqualString(const wstring &lhs, const wstring &rhs,
                             bool ignore_case, bool *are_equal) {
  if (are_equal == nullptr) {
    return;
  }

  if (!ignore_case) {
    DCHECK_NE(nullptr, are_equal);
    *are_equal = (rhs == lhs);
    return;
  }

  const _locale_t locale_id = _create_locale(LC_ALL, "English");
  const int compare_result = _wcsicmp_l(lhs.c_str(), rhs.c_str(), locale_id);
  _free_locale(locale_id);

  DCHECK_NE(nullptr, are_equal);
  *are_equal = (compare_result == 0);
}

bool WinUtil::SystemEqualString(
      const wstring &lhs, const wstring &rhs, bool ignore_case) {
  bool are_equal = false;

  // We assume a string instance never contains NUL character in principle.
  // So we will raise an error to notify the unexpected situation in debug
  // builds.  In production, however, we will admit such an instance and
  // silently trim it at the first NUL character.
  const wstring::size_type lhs_null_pos = lhs.find_first_of(L'\0');
  const wstring::size_type rhs_null_pos = rhs.find_first_of(L'\0');
  DCHECK_EQ(lhs.npos, lhs_null_pos)
      << "|lhs| should not contain NUL character.";
  DCHECK_EQ(rhs.npos, rhs_null_pos)
      << "|rhs| should not contain NUL character.";
  const wstring &lhs_null_trimmed = lhs.substr(0, lhs_null_pos);
  const wstring &rhs_null_trimmed = rhs.substr(0, rhs_null_pos);

  if (Win32EqualString(
          lhs_null_trimmed, rhs_null_trimmed, ignore_case, &are_equal)) {
    return are_equal;
  }

  if (NativeEqualString(
          lhs_null_trimmed, rhs_null_trimmed, ignore_case, &are_equal)) {
    return are_equal;
  }

  CrtEqualString(lhs_null_trimmed, rhs_null_trimmed, ignore_case, &are_equal);

  return are_equal;
}

bool WinUtil::IsServiceUser(HANDLE hToken, bool *is_service) {
  if (is_service == nullptr) {
    return false;
  }

  TOKEN_STATISTICS ts;
  DWORD dwSize = 0;
  // Use token logon LUID instead of user SID, for brevity and safety
  if (!::GetTokenInformation(hToken, TokenStatistics,
                             (LPVOID)&ts, sizeof(ts), &dwSize)) {
    return false;
  }

  // Compare LUID
  const LUID SystemLuid = SYSTEM_LUID;
  const LUID LocalServiceLuid = LOCALSERVICE_LUID;
  const LUID NetworkServiceLuid = NETWORKSERVICE_LUID;
  if (EqualLuid(SystemLuid, ts.AuthenticationId) ||
      EqualLuid(LocalServiceLuid, ts.AuthenticationId) ||
      EqualLuid(NetworkServiceLuid, ts.AuthenticationId)) {
    *is_service = true;
    return true;
  }

  // Not a service account
  *is_service = false;
  return true;
}

bool WinUtil::IsServiceProcess(bool *is_service) {
  if (is_service == nullptr) {
    return false;
  }

  // Session 0 is dedicated to services
  DWORD dwSessionId = 0;
  if (!::ProcessIdToSessionId(::GetCurrentProcessId(), &dwSessionId) ||
      (dwSessionId == 0)) {
    *is_service = true;
    return true;
  }

  // Get process token
  HANDLE hProcessToken = nullptr;
  if (!::OpenProcessToken(::GetCurrentProcess(),
                          TOKEN_QUERY | TOKEN_QUERY_SOURCE,
                          &hProcessToken)) {
    return false;
  }

  ScopedHandle process_token(hProcessToken);

  // Process token is one for a service account.
  if (!IsServiceUser(process_token.get(), is_service)) {
    return false;
  }

  return true;
}

bool WinUtil::IsServiceThread(bool *is_service) {
  if (is_service == nullptr) {
    return false;
  }

  // Get thread token (if any)
  HANDLE hThreadToken = nullptr;
  if (!::OpenThreadToken(::GetCurrentThread(),
                        TOKEN_QUERY, TRUE, &hThreadToken) &&
      ERROR_NO_TOKEN != ::GetLastError()) {
    return false;
  }

  if (hThreadToken == nullptr) {
    // No thread token.
    *is_service = false;
    return true;
  }

  ScopedHandle thread_token(hThreadToken);

  // Check if the thread token (if any) is one for a service account.
  if (!IsServiceUser(thread_token.get(), is_service)) {
    return false;
  }
  return true;
}

bool WinUtil::IsServiceAccount(bool *is_service) {
  if (is_service == nullptr) {
    return false;
  }

  bool is_service_process = false;
  if (!WinUtil::IsServiceProcess(&is_service_process)) {
    DLOG(ERROR) << "WinUtil::IsServiceProcess failed.";
    return false;
  }

  if (is_service_process) {
    *is_service = true;
    return true;
  }

  // Process token is not one for service.
  // Check thread token just in case.
  bool is_service_thread = false;
  if (!WinUtil::IsServiceThread(&is_service_thread)) {
    DLOG(ERROR) << "WinUtil::IsServiceThread failed.";
    return false;
  }

  if (is_service_thread) {
    *is_service = true;
    return true;
  }

  *is_service = false;
  return true;
}

bool WinUtil::IsProcessImmersive(HANDLE process_handle,
                                 bool *is_immersive) {
  if (is_immersive == nullptr) {
    return false;
  }
  *is_immersive = false;
  // ImmersiveMode is supported only in Windows8 and later.
  if (!SystemUtil::IsWindows8OrLater()) {
    return true;
  }

  const HMODULE module = WinUtil::GetSystemModuleHandle(L"user32.dll");
  if (module == nullptr) {
    return false;
  }

  typedef BOOL (WINAPI* IsImmersiveProcessFunc)(HANDLE process);
  IsImmersiveProcessFunc is_immersive_process =
      reinterpret_cast<IsImmersiveProcessFunc>(
          ::GetProcAddress(module, "IsImmersiveProcess"));
  if (is_immersive_process == nullptr) {
    return false;
  }

  *is_immersive = !!is_immersive_process(process_handle);
  return true;
}

bool WinUtil::IsProcessRestricted(HANDLE process_handle, bool *is_restricted) {
  if (is_restricted == nullptr) {
    return false;
  }
  *is_restricted = false;

  HANDLE token = nullptr;
  if (!::OpenProcessToken(process_handle, TOKEN_QUERY, &token)) {
    return false;
  }

  ScopedHandle process_token(token);
  ::SetLastError(NOERROR);
  if (::IsTokenRestricted(process_token.get()) == FALSE) {
    const DWORD error = ::GetLastError();
    if (error != NOERROR) {
      return false;
    }
  } else {
    *is_restricted = true;
  }
  return true;
}

bool WinUtil::IsProcessInAppContainer(HANDLE process_handle,
                                      bool *in_appcontainer) {
  if (in_appcontainer == nullptr) {
    return false;
  }
  *in_appcontainer = false;

  // AppContainer is supported only in Windows8 and later.
  if (!SystemUtil::IsWindows8OrLater()) {
    return true;
  }

  HANDLE token = nullptr;
  if (!::OpenProcessToken(process_handle, TOKEN_QUERY | TOKEN_QUERY_SOURCE,
                          &token)) {
    return false;
  }

  // TokenIsAppContainer is defined only in Windows SDK 8.0 and later.
  ScopedHandle process_token(token);
  const TOKEN_INFORMATION_CLASS kTokenIsAppContainer =
      static_cast<TOKEN_INFORMATION_CLASS>(29);  // TokenIsAppContainer
#if defined(_WIN32_WINNT_WIN8)
  static_assert(kTokenIsAppContainer == TokenIsAppContainer,
                "Checking |kTokenIsAppContainer| has correct value.");
#endif  // _WIN32_WINNT_WIN8
  DWORD returned_size = 0;
  DWORD retval = 0;
  if (!GetTokenInformation(process_token.get(), kTokenIsAppContainer,
                           &retval, sizeof(retval), &returned_size)) {
    return false;
  }
  if (returned_size != sizeof(retval)) {
    return false;
  }

  *in_appcontainer = (retval != 0);
  return true;
}

bool WinUtil::IsCuasEnabled() {
  // CUAS is always enabled on Vista or later.
  return true;
}

bool WinUtil::GetFileSystemInfoFromPath(
    const wstring &path, BY_HANDLE_FILE_INFORMATION *info) {
  // no read access is required.
  ScopedHandle handle(::CreateFileW(
      path.c_str(), 0, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
      nullptr, OPEN_EXISTING,
      FILE_FLAG_BACKUP_SEMANTICS | FILE_ATTRIBUTE_NORMAL, nullptr));

  // Caveats: handle.get() returns nullptr when it is initialized with
  //     INVALID_HANDLE_VALUE.
  if (handle.get() == nullptr) {
    return false;
  }
  return !!::GetFileInformationByHandle(handle.get(), info);
}

bool WinUtil::AreEqualFileSystemObject(const wstring &left_path,
                                       const wstring &right_path) {
  BY_HANDLE_FILE_INFORMATION left_info = {};
  if (!GetFileSystemInfoFromPath(left_path, &left_info)) {
    return false;
  }
  BY_HANDLE_FILE_INFORMATION right_info = {};
  if (!GetFileSystemInfoFromPath(right_path, &right_info)) {
    return false;
  }
  return (left_info.nFileIndexLow == right_info.nFileIndexLow) &&
         (left_info.nFileIndexHigh == right_info.nFileIndexHigh);
}

bool WinUtil::GetNtPath(const wstring &dos_path, wstring *nt_path) {
  if (nt_path == nullptr) {
    return false;
  }

  nt_path->clear();

  typedef DWORD (WINAPI *GetFinalPathNameByHandleWFunc)(
      __in HANDLE file,
      __out wchar_t *buffer,
      __in DWORD buffer_num_chars,
      __in DWORD flags);
  GetFinalPathNameByHandleWFunc get_final_path_name_by_handle =
      reinterpret_cast<GetFinalPathNameByHandleWFunc>(
          ::GetProcAddress(WinUtil::GetSystemModuleHandle(L"kernel32.dll"),
                           "GetFinalPathNameByHandleW"));
  if (get_final_path_name_by_handle == nullptr) {
    return false;
  }

  ScopedHandle file_handle(::CreateFileW(
      dos_path.c_str(), 0,
      FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
      nullptr, OPEN_EXISTING,
      FILE_FLAG_BACKUP_SEMANTICS | FILE_ATTRIBUTE_NORMAL, nullptr));
  if (file_handle.get() == nullptr) {
    // Caveats: |file_handle.get()| becomes nullptr instead of
    // INVALID_HANDLE_VALUE when failure.
    return false;
  }

  const size_t kMaxPath = 4096;
  unique_ptr<wchar_t[]> ntpath_buffer(
      new wchar_t[kMaxPath]);
  const DWORD copied_len_without_null = get_final_path_name_by_handle(
      file_handle.get(),
      ntpath_buffer.get(),
      kMaxPath,
      FILE_NAME_NORMALIZED | VOLUME_NAME_NT);
  if (copied_len_without_null == 0 ||
      copied_len_without_null > kMaxPath) {
    const DWORD error = ::GetLastError();
    VLOG(1) << "GetFinalPathNameByHandleW() failed: " << error;
    return false;
  }

  nt_path->assign(ntpath_buffer.get(), copied_len_without_null);
  return true;
}

bool WinUtil::GetProcessInitialNtPath(DWORD pid, wstring *nt_path) {
  if (nt_path == nullptr) {
    return false;
  }
  nt_path->clear();

  ScopedHandle process_handle(::OpenProcess(
      PROCESS_QUERY_LIMITED_INFORMATION, FALSE, pid));

  if (process_handle.get() == nullptr) {
    VLOG(1) << "OpenProcess() failed: " << ::GetLastError();
    return false;
  }

  const size_t kMaxPath = 4096;
  unique_ptr<wchar_t[]> ntpath_buffer(new wchar_t[kMaxPath]);
  const DWORD copied_len_without_null =
      ::GetProcessImageFileNameW(process_handle.get(),
                                 ntpath_buffer.get(),
                                 kMaxPath);
  if (copied_len_without_null == 0 || copied_len_without_null > kMaxPath) {
    const DWORD error = ::GetLastError();
    VLOG(1) << "GetProcessImageFileNameW() failed: " << error;
    return false;
  }

  nt_path->assign(ntpath_buffer.get(), copied_len_without_null);
  return true;
}

// SPI_GETTHREADLOCALINPUTSETTINGS is available on Windows 8 SDK and later.
#ifndef SPI_GETTHREADLOCALINPUTSETTINGS
#define SPI_GETTHREADLOCALINPUTSETTINGS 0x104E
#endif  // SPI_GETTHREADLOCALINPUTSETTINGS

bool WinUtil::IsPerUserInputSettingsEnabled() {
  if (!SystemUtil::IsWindows8OrLater()) {
    // Windows 7 and below does not support per-user input mode.
    return false;
  }
  BOOL is_thread_local = FALSE;
  if (::SystemParametersInfo(SPI_GETTHREADLOCALINPUTSETTINGS,
                             0,
                             reinterpret_cast<void *>(&is_thread_local),
                             0) == FALSE) {
    return false;
  }
  return !is_thread_local;
}

ScopedCOMInitializer::ScopedCOMInitializer()
    : hr_(::CoInitialize(nullptr)) {
}

ScopedCOMInitializer::~ScopedCOMInitializer() {
  if (SUCCEEDED(hr_)) {
    ::CoUninitialize();
  }
}

}  // namespace mozc

#endif  // OS_WIN
