// 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.

#ifdef OS_WIN
#define PSAPI_VERSION 1  // for <psapi.h>
#include <windows.h>
#if !defined(NO_LOGGING)
#include <atlbase.h>
#include <atlstr.h>  // for CString
#endif  // !NO_LOGGING
#include <psapi.h>
#include "base/file_util.h"
#include "base/scoped_handle.h"
#include "base/singleton.h"
#include "base/system_util.h"
#include "base/util.h"
#include "base/winmain.h"   // use WinMain
#include "server/cache_service_manager.h"

namespace {
HANDLE g_stop_event = NULL;

#if defined(NO_LOGGING)
#define LOG_WIN32_ERROR(message)
#else
template <size_t num_elements>
void LogMessageImpl(
    const wchar_t (&file)[num_elements],
    int line,
    const wchar_t *message,
    int error_no) {
  CString buffer;
  buffer.Format(_T("%s (%d): %s (error: %d)\n"), file, line, message, error_no);
  ::OutputDebugString(buffer);
}
#define LOG_WIN32_ERROR(message) \
    LogMessageImpl(_T(__FILE__), __LINE__, message, ::GetLastError())
#endif

wstring GetMappedFileNameByAddress(LPVOID address) {
  wchar_t path[MAX_PATH];
  const int length = ::GetMappedFileName(::GetCurrentProcess(), address,
                                         path, arraysize(path));
  if (length == 0 || arraysize(path) <= length) {
    LOG_WIN32_ERROR(L"GetMappedFileName failed.");
    return L"";
  }
  return wstring(path, length);
}

// This function scans each section of a given mapped image section and
// changes memory protection attribute to read-only.
// Retruns true if all sections are changed to one read-only region.
// |result_info| contains the memory block information of the combined
// region if succeeds.
bool MakeReadOnlyForMappedModule(
    LPVOID address,
    MEMORY_BASIC_INFORMATION *result_info) {
  // For an IMAGE section, the mapped size may be slightly different from the
  // file size since each PE section should be aligned to the page boundary.
  // To investigate the actual mapped size, we scan each block of memory pages.
  // Fortunately, we can get the source filename of a given virtual address.
  // We can also rely on the MEMORY_BASIC_INFORMATION::Type.  If a given
  // address is inside of a view of an IMAGE section,
  // MEMORY_BASIC_INFORMATION::Type should be MEM_IMAGE.

  // Store the source filename.
  const wstring &filename = ::GetMappedFileNameByAddress(address);
  if (filename.empty()) {
    return false;
  }

  void *start_address = NULL;
  DWORD total_region_size = 0;

  void *current = address;
  while (true) {
    MEMORY_BASIC_INFORMATION mem_info;
    if (::VirtualQuery(current, &mem_info, sizeof(mem_info)) == 0) {
      LOG_WIN32_ERROR(L"VirtualQuery failed.");
      return false;
    }
    if (mem_info.Type != MEM_IMAGE) {
      break;
    }
    if (GetMappedFileNameByAddress(current) != filename) {
      break;
    }
    // If this region is not PAGE_READONLY, change the protection to readonly.
    if (mem_info.Protect != PAGE_READONLY) {
      DWORD old_protect = 0;
      if (::VirtualProtect(mem_info.BaseAddress, mem_info.RegionSize,
                           PAGE_READONLY, &old_protect) == 0) {
        LOG_WIN32_ERROR(L"VirtualProtect failed.");
        return false;
      }
    }

    if (start_address == NULL) {
      start_address = mem_info.BaseAddress;
    }
    total_region_size += mem_info.RegionSize;

    current = static_cast<char *>(mem_info.BaseAddress) + mem_info.RegionSize;
  }

  if (result_info != NULL &&
      ::VirtualQuery(address, result_info,
                     sizeof(MEMORY_BASIC_INFORMATION)) == 0) {
    LOG_WIN32_ERROR(L"VirtualQuery failed.");
    return false;
  }
  result_info->BaseAddress = start_address;
  result_info->RegionSize = total_region_size;
  return true;
}
}  // namespace

void WINAPI ServiceHandlerProc(DWORD control_code) {
  switch (control_code) {
    // ignores the following code
    case SERVICE_CONTROL_PAUSE:
    case SERVICE_CONTROL_CONTINUE:
    case SERVICE_CONTROL_INTERROGATE:
      break;
    case SERVICE_CONTROL_STOP:
    case SERVICE_CONTROL_SHUTDOWN:
      if (NULL != g_stop_event) {
        if (!::SetEvent(g_stop_event)) {   // raise event
          // call ExitProcess() if SetEvent failed just in case.
          ::ExitProcess(0);
        }
      } else {
        ::ExitProcess(0);
      }
      break;
    default:
      break;
  }
}

#define STOP_SERVICE_AND_EXIT_FUNCTION() do { \
  service_status.dwCurrentState = SERVICE_STOPPED; \
  ::SetServiceStatus(service_status_handle, &service_status); \
  return; \
} while (false)

#if defined(DEBUG)
// This function try to make a temporary file in the same directory of the
// service if the arguments contains "--verify_privilege_restriction".
// This attempt should fail by ERROR_ACCESS_DENIED since the cache service
// runs under write-restricted SID in Windows Vista or later by default.
// See http://b/2470180 for the whole story.
bool VerifyPrivilegeRestrictionIfNeeded(DWORD dwArgc, LPTSTR *lpszArgv) {
  bool verify_privilege = false;
  const wstring test_mode = L"--verify_privilege_restriction";
  for (size_t i = 0; i < dwArgc; ++i) {
    if (test_mode == lpszArgv[i]) {
      verify_privilege = true;
      break;
    }
  }
  if (!verify_privilege) {
    return true;
  }

  const string temp_path =
      mozc::FileUtil::JoinPath(mozc::SystemUtil::GetServerDirectory(),
                               "delete_me.txt");
  wstring wtemp_path;
  mozc::Util::UTF8ToWide(temp_path.c_str(), &wtemp_path);
  const HANDLE temp_file = ::CreateFileW(
      wtemp_path.c_str(),
      GENERIC_READ | GENERIC_WRITE,
      FILE_SHARE_READ,
      NULL,
      CREATE_ALWAYS,
      FILE_ATTRIBUTE_NOT_CONTENT_INDEXED | FILE_ATTRIBUTE_TEMPORARY
      | FILE_FLAG_DELETE_ON_CLOSE,
      NULL);
  if (temp_file != INVALID_HANDLE_VALUE) {
    ::CloseHandle(temp_file);
    LOG_WIN32_ERROR(L"CreateEvent should have failed but succeeded.");
    return false;
  }
  if (ERROR_ACCESS_DENIED != ::GetLastError()) {
    LOG_WIN32_ERROR(L"Unexpected error code.");
    return false;
  }

  return true;
}
#endif  // DEBUG

VOID WINAPI ServiceMain(DWORD dwArgc, LPTSTR *lpszArgv) {
  SERVICE_STATUS_HANDLE service_status_handle = ::RegisterServiceCtrlHandler(
      mozc::CacheServiceManager::GetServiceName(),
      ServiceHandlerProc);

  if (NULL == service_status_handle) {
    return;
  }

  SERVICE_STATUS service_status = { 0 };

  service_status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
  service_status.dwWin32ExitCode = NO_ERROR;
  service_status.dwServiceSpecificExitCode = 0;
  service_status.dwCheckPoint = 0;
  service_status.dwWaitHint = 0;
  service_status.dwControlsAccepted = SERVICE_ACCEPT_STOP;

  service_status.dwCurrentState = SERVICE_RUNNING;
  ::SetServiceStatus(service_status_handle, &service_status);

#if defined(_DEBUG)
  if (!VerifyPrivilegeRestrictionIfNeeded(dwArgc, lpszArgv)) {
    STOP_SERVICE_AND_EXIT_FUNCTION();
  }
#endif

  if (!mozc::CacheServiceManager::HasEnoughMemory()) {
    STOP_SERVICE_AND_EXIT_FUNCTION();
  }

  mozc::ScopedHandle stop_event(::CreateEvent(NULL, TRUE, FALSE, NULL));
  g_stop_event = stop_event.get();
  if (NULL == g_stop_event) {
    LOG_WIN32_ERROR(L"CreateEvent failed.");
    STOP_SERVICE_AND_EXIT_FUNCTION();
  }

  // when low_memory_event is signaled, unkcok the memory image.
  mozc::ScopedHandle low_memory_event(
      ::CreateMemoryResourceNotification(LowMemoryResourceNotification));
  if (NULL == low_memory_event.get()) {
    LOG_WIN32_ERROR(L"CreateMemoryResourceNotification failed.");
    STOP_SERVICE_AND_EXIT_FUNCTION();
  }

  // when high_memory_event is signaled, lcok the memory image.
  mozc::ScopedHandle high_memory_event(
      ::CreateMemoryResourceNotification(HighMemoryResourceNotification));
  if (NULL == high_memory_event.get()) {
    LOG_WIN32_ERROR(L"CreateMemoryResourceNotification failed.");
    STOP_SERVICE_AND_EXIT_FUNCTION();
  }

  wstring server_path;
  mozc::Util::UTF8ToWide(mozc::SystemUtil::GetServerPath().c_str(),
                         &server_path);

  mozc::ScopedHandle file_handle(::CreateFile(server_path.c_str(),
                                              GENERIC_READ,
                                              FILE_SHARE_READ,
                                              0, OPEN_EXISTING,
                                              0, 0));
  if (NULL == file_handle.get()) {
    LOG_WIN32_ERROR(L"CreateFile failed.");
    STOP_SERVICE_AND_EXIT_FUNCTION();
  }

  const size_t size = ::GetFileSize(file_handle.get(), 0);

  // Do not load image if the file size is too big
  const DWORD kMaxImageSize = 100 * 1024 * 1024;   // 100MB
  if (size > kMaxImageSize) {
    STOP_SERVICE_AND_EXIT_FUNCTION();
  }

  // In general, there are two types of section object for a given file:
  // an IMAGE section and a (normal) MAPPED-FILE section.  The former is used
  // to load an executable file as a module (HMODULE) as opposed to the later
  // which maps a file into the virtual address space as data file.
  // Apparently, multiple IMAGE sections for the same executable share most of
  // memory pages through their mapped view.  This should be also true for
  // multiple MAPPED-FILE sections.  However, can IMAGE section and MAPPED-FILE
  // section for the same file share their memory pages?
  // Anyway we can use SEC_IMAGE to make an IMAGE section for a given file
  // through which we can keep the content of the file on-memory.
  mozc::ScopedHandle mmap_handle(::CreateFileMapping(file_handle.get(),
                                                     NULL,
                                                     PAGE_READONLY | SEC_IMAGE,
                                                     0, 0, NULL));
  if (NULL == mmap_handle.get()) {
    LOG_WIN32_ERROR(L"CreateFileMapping failed.");
    STOP_SERVICE_AND_EXIT_FUNCTION();
  }

  LPVOID image = reinterpret_cast<LPVOID>(
      ::MapViewOfFile(mmap_handle.get(), FILE_MAP_READ, 0, 0, 0));
  if (NULL == image) {
    LOG_WIN32_ERROR(L"MapViewOfFile failed.");
    STOP_SERVICE_AND_EXIT_FUNCTION();
  }


  // A mapped view of an IMAGE section may have multiple sections whose
  // protection attributes correspond to the attributes of PE sections.
  // Here is a result of a version of mapped GoogleIMEJaConverter.exe.
  // Address    Type    Size    Protection             Details
  // 00ED0000   Image   48,488  Execute/Copy on Write  GoogleIMEJaConverter.exe
  //  00ED0000  Image   4       Read                   Header
  //  00ED1000  Image   888     Execute/Read           .text
  //  00FAF000  Image   47,316  Read                   .rdata
  //  03DE4000  Image   16      Copy on write          .data
  //  03DE8000  Image   8       Read/Write             .data
  //  03DEA000  Image   4       Read                   .rsrc
  //  03DEB000  Image   252     Read                   .reloc
  // Although an initial protection attribute is not always read-only, you can
  // change each protection to read-only by VirtualProtect API.
  MEMORY_BASIC_INFORMATION mem_info;
  if (!MakeReadOnlyForMappedModule(image, &mem_info)) {
    STOP_SERVICE_AND_EXIT_FUNCTION();
  }

  const DWORD kMinAdditionalSize = 512 * 1024;  // 512KB
  const DWORD kMaxAdditionalSize = 2 * 1024 * 1024;  // 2MB

  if (!::SetProcessWorkingSetSize(::GetCurrentProcess(),
                                  mem_info.RegionSize + kMinAdditionalSize,
                                  mem_info.RegionSize + kMaxAdditionalSize)) {
    LOG_WIN32_ERROR(L"SetProcessWorkingSetSize failed.");
    STOP_SERVICE_AND_EXIT_FUNCTION();
  }

  DWORD lock_time = 0;
  DWORD unlock_time = 0;

 WAIT_HIGH:
  {
    const HANDLE handles[] = { g_stop_event, high_memory_event.get() };
    const DWORD result = ::WaitForMultipleObjects(arraysize(handles),
                                                  handles,
                                                  FALSE, INFINITE);
    switch (result) {
      case WAIT_OBJECT_0 + 1:   // high is signaled
        goto TRY_LOCK;
        break;
      case WAIT_OBJECT_0:   // ctrl or error
      default:
        STOP_SERVICE_AND_EXIT_FUNCTION();
    }
  }

 TRY_LOCK:
  {
    const int kMaxTimeout = 10 * 60 * 1000;   // 10 min.
    const int kMinTimeout = 1 * 60 * 1000;    // 1min.

    // if the low event is signaled just after calling VirtualLock(),
    // the VirtualLock() itself may indirectly raise the low event.
    // This eventually causes an infinite loop. To prevent this, we check
    // the duration between the last VirtualUnlock() and VirtualLock() and
    // set longer timeout, when the duration is shorter.
    const int duration = static_cast<int>(unlock_time - lock_time);
    const int timeout =
        unlock_time == 0 ? 0 : max(kMinTimeout, kMaxTimeout - max(0, duration));

    const DWORD result = ::WaitForSingleObject(g_stop_event, timeout);
    switch (result) {
      case WAIT_TIMEOUT:
        switch (::WaitForSingleObject(high_memory_event.get(), 0)) {
          case WAIT_OBJECT_0:
            if (::VirtualLock(mem_info.BaseAddress, mem_info.RegionSize) == 0) {
              LOG_WIN32_ERROR(L"VirtualLock failed.");
              STOP_SERVICE_AND_EXIT_FUNCTION();
            }
            lock_time = ::GetTickCount();
            goto WAIT_LOW;
            break;
          case WAIT_TIMEOUT:
            goto TRY_LOCK;
            break;
          default:
            STOP_SERVICE_AND_EXIT_FUNCTION();
        }
        break;
      case WAIT_OBJECT_0:
      default:
        STOP_SERVICE_AND_EXIT_FUNCTION();
    }
  }

 WAIT_LOW:
  {
    const HANDLE handles[] = { g_stop_event, low_memory_event.get() };
    const DWORD result = ::WaitForMultipleObjects(arraysize(handles),
                                                  handles,
                                                  FALSE, INFINITE);
    switch (result) {
      case WAIT_OBJECT_0 + 1:   // low is signaled
        if (!::VirtualUnlock(mem_info.BaseAddress, mem_info.RegionSize)) {
          LOG_WIN32_ERROR(L"VirtualUnlock failed.");
          STOP_SERVICE_AND_EXIT_FUNCTION();
        }
        unlock_time = ::GetTickCount();
        goto WAIT_HIGH;
        break;
      case WAIT_OBJECT_0:   // ctrl or error
      default:
        STOP_SERVICE_AND_EXIT_FUNCTION();
    }
  }

  STOP_SERVICE_AND_EXIT_FUNCTION();
}

int main(int argc, char **argv) {
  if (argc <= 1) {
    SERVICE_TABLE_ENTRY kDispatchTable[] = {
      { const_cast<wchar_t *>(
          mozc::CacheServiceManager::GetServiceName()), ServiceMain },
      { NULL, NULL }
    };

    ::StartServiceCtrlDispatcher(kDispatchTable);
    return 0;
  }
  return 0;
}
#endif
