// Copyright 2014 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 "content/child/font_warmup_win.h"

#include <dwrite.h>
#include <stdint.h>
#include <map>

#include "base/debug/alias.h"
#include "base/files/file_path.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/numerics/safe_conversions.h"
#include "base/numerics/safe_math.h"
#include "base/strings/utf_string_conversions.h"
#include "base/synchronization/lock.h"
#include "base/sys_byteorder.h"
#include "base/trace_event/trace_event.h"
#include "base/win/iat_patch_function.h"
#include "base/win/windows_version.h"
#include "ppapi/shared_impl/proxy_lock.h"
#include "skia/ext/fontmgr_default_win.h"
#include "skia/ext/refptr.h"
#include "third_party/skia/include/ports/SkFontMgr.h"
#include "third_party/skia/include/ports/SkTypeface_win.h"

namespace content {

namespace {

// The Skia font manager, used for the life of the process (leaked at the end).
SkFontMgr* g_warmup_fontmgr = nullptr;

base::win::IATPatchFunction g_iat_patch_open_sc_manager;
base::win::IATPatchFunction g_iat_patch_close_service_handle;
base::win::IATPatchFunction g_iat_patch_open_service;
base::win::IATPatchFunction g_iat_patch_start_service;
base::win::IATPatchFunction g_iat_patch_nt_connect_port;

// These are from ntddk.h
#if !defined(STATUS_ACCESS_DENIED)
#define STATUS_ACCESS_DENIED ((NTSTATUS)0xC0000022L)
#endif

typedef LONG NTSTATUS;

const uintptr_t kFakeSCMHandle = 0xdead0001;
const uintptr_t kFakeServiceHandle = 0xdead0002;

SC_HANDLE WINAPI OpenSCManagerWPatch(const wchar_t* machine_name,
                                     const wchar_t* database_name,
                                     DWORD access_mask) {
  ::SetLastError(0);
  return reinterpret_cast<SC_HANDLE>(kFakeSCMHandle);
}

SC_HANDLE WINAPI OpenServiceWPatch(SC_HANDLE sc_manager,
                                   const wchar_t* service_name,
                                   DWORD access_mask) {
  ::SetLastError(0);
  return reinterpret_cast<SC_HANDLE>(kFakeServiceHandle);
}

BOOL WINAPI CloseServiceHandlePatch(SC_HANDLE service_handle) {
  if (service_handle != reinterpret_cast<SC_HANDLE>(kFakeServiceHandle) &&
      service_handle != reinterpret_cast<SC_HANDLE>(kFakeSCMHandle))
    CHECK(false);
  ::SetLastError(0);
  return TRUE;
}

BOOL WINAPI StartServiceWPatch(SC_HANDLE service,
                               DWORD args,
                               const wchar_t** arg_vectors) {
  if (service != reinterpret_cast<SC_HANDLE>(kFakeServiceHandle))
    CHECK(false);
  ::SetLastError(ERROR_ACCESS_DENIED);
  return FALSE;
}

NTSTATUS WINAPI NtALpcConnectPortPatch(HANDLE* port_handle,
                                       void* port_name,
                                       void* object_attribs,
                                       void* port_attribs,
                                       DWORD flags,
                                       void* server_sid,
                                       void* message,
                                       DWORD* buffer_length,
                                       void* out_message_attributes,
                                       void* in_message_attributes,
                                       void* time_out) {
  return STATUS_ACCESS_DENIED;
}

// Class to fake out a DC or a Font object. Maintains a reference to a
// SkTypeFace to emulate the simple operation of a DC and Font.
class FakeGdiObject : public base::RefCountedThreadSafe<FakeGdiObject> {
 public:
  FakeGdiObject(uint32_t magic, void* handle)
      : handle_(handle), magic_(magic) {}

  void set_typeface(const skia::RefPtr<SkTypeface>& typeface) {
    typeface_ = typeface;
  }

  skia::RefPtr<SkTypeface> typeface() { return typeface_; }
  void* handle() { return handle_; }
  uint32_t magic() { return magic_; }

 private:
  friend class base::RefCountedThreadSafe<FakeGdiObject>;
  ~FakeGdiObject() {}

  void* handle_;
  uint32_t magic_;
  skia::RefPtr<SkTypeface> typeface_;

  DISALLOW_COPY_AND_ASSIGN(FakeGdiObject);
};

// This class acts as a factory for creating new fake GDI objects. It also maps
// the new instances of the FakeGdiObject class to an incrementing handle value
// which is passed to the caller of the emulated GDI function for later
// reference.  We can't be sure that this won't be used in a multi-threaded
// environment so we need to ensure a lock is taken before accessing the map of
// issued objects.
class FakeGdiObjectFactory {
 public:
  FakeGdiObjectFactory() : curr_handle_(0) {}

  // Find a corresponding fake GDI object and verify its magic value.
  // The returned value is either nullptr or the validated object.
  scoped_refptr<FakeGdiObject> Validate(void* obj, uint32_t magic) {
    if (obj) {
      base::AutoLock scoped_lock(objects_lock_);
      auto handle_entry = objects_.find(obj);
      if (handle_entry != objects_.end() &&
          handle_entry->second->magic() == magic) {
        return handle_entry->second;
      }
    }
    return nullptr;
  }

  scoped_refptr<FakeGdiObject> Create(uint32_t magic) {
    base::AutoLock scoped_lock(objects_lock_);
    curr_handle_++;
    // We don't support wrapping the fake handle value.
    void* handle = reinterpret_cast<void*>(curr_handle_.ValueOrDie());
    scoped_refptr<FakeGdiObject> object(new FakeGdiObject(magic, handle));
    objects_[handle] = object;
    return object;
  }

  bool DeleteObject(void* obj, uint32_t magic) {
    base::AutoLock scoped_lock(objects_lock_);
    auto handle_entry = objects_.find(obj);
    if (handle_entry != objects_.end() &&
        handle_entry->second->magic() == magic) {
      objects_.erase(handle_entry);
      return true;
    }
    return false;
  }

  size_t GetObjectCount() {
    base::AutoLock scoped_lock(objects_lock_);
    return objects_.size();
  }

  void ResetObjectHandles() {
    base::AutoLock scoped_lock(objects_lock_);
    curr_handle_ = 0;
    objects_.clear();
  }

 private:
  base::CheckedNumeric<uintptr_t> curr_handle_;
  std::map<void*, scoped_refptr<FakeGdiObject>> objects_;
  base::Lock objects_lock_;

  DISALLOW_COPY_AND_ASSIGN(FakeGdiObjectFactory);
};

base::LazyInstance<FakeGdiObjectFactory>::Leaky g_fake_gdi_object_factory =
    LAZY_INSTANCE_INITIALIZER;

// Magic values for the fake GDI objects.
const uint32_t kFakeDCMagic = 'fkdc';
const uint32_t kFakeFontMagic = 'fkft';

skia::RefPtr<SkTypeface> GetTypefaceFromLOGFONT(const LOGFONTW* log_font) {
  CHECK(g_warmup_fontmgr);
  int weight = log_font->lfWeight;
  if (weight == FW_DONTCARE)
    weight = SkFontStyle::kNormal_Weight;

  SkFontStyle style(weight, log_font->lfWidth,
                    log_font->lfItalic ? SkFontStyle::kItalic_Slant
                                       : SkFontStyle::kUpright_Slant);

  std::string family_name = base::WideToUTF8(log_font->lfFaceName);
  ppapi::ProxyAutoLock lock;  // Needed for DirectWrite font proxy.
  return skia::AdoptRef(
      g_warmup_fontmgr->matchFamilyStyle(family_name.c_str(), style));
}

HDC WINAPI CreateCompatibleDCPatch(HDC dc_handle) {
  scoped_refptr<FakeGdiObject> ret =
      g_fake_gdi_object_factory.Get().Create(kFakeDCMagic);
  return static_cast<HDC>(ret->handle());
}

HFONT WINAPI CreateFontIndirectWPatch(const LOGFONTW* log_font) {
  if (!log_font)
    return nullptr;

  skia::RefPtr<SkTypeface> typeface = GetTypefaceFromLOGFONT(log_font);
  if (!typeface)
    return nullptr;

  scoped_refptr<FakeGdiObject> ret =
      g_fake_gdi_object_factory.Get().Create(kFakeFontMagic);
  ret->set_typeface(typeface);

  return static_cast<HFONT>(ret->handle());
}

BOOL WINAPI DeleteDCPatch(HDC dc_handle) {
  return g_fake_gdi_object_factory.Get().DeleteObject(dc_handle, kFakeDCMagic);
}

BOOL WINAPI DeleteObjectPatch(HGDIOBJ object_handle) {
  return g_fake_gdi_object_factory.Get().DeleteObject(object_handle,
                                                      kFakeFontMagic);
}

int WINAPI EnumFontFamiliesExWPatch(HDC dc_handle,
                                    LPLOGFONTW log_font,
                                    FONTENUMPROCW enum_callback,
                                    LPARAM callback_param,
                                    DWORD flags) {
  scoped_refptr<FakeGdiObject> dc_obj =
      g_fake_gdi_object_factory.Get().Validate(dc_handle, kFakeDCMagic);
  if (!dc_obj)
    return 1;

  if (!log_font || !enum_callback)
    return 1;

  skia::RefPtr<SkTypeface> typeface = GetTypefaceFromLOGFONT(log_font);
  if (!typeface)
    return 1;

  ENUMLOGFONTEXDVW enum_log_font = {};
  enum_log_font.elfEnumLogfontEx.elfLogFont = *log_font;
  // TODO: Fill in the rest of the text metric structure. Not yet needed for
  // Flash support but might be in the future.
  NEWTEXTMETRICEXW text_metric = {};
  text_metric.ntmTm.ntmFlags = NTM_PS_OPENTYPE;

  return enum_callback(&enum_log_font.elfEnumLogfontEx.elfLogFont,
                       reinterpret_cast<TEXTMETRIC*>(&text_metric),
                       TRUETYPE_FONTTYPE, callback_param);
}

DWORD WINAPI GetFontDataPatch(HDC dc_handle,
                              DWORD table_tag,
                              DWORD table_offset,
                              LPVOID buffer,
                              DWORD buffer_length) {
  scoped_refptr<FakeGdiObject> dc_obj =
      g_fake_gdi_object_factory.Get().Validate(dc_handle, kFakeDCMagic);
  if (!dc_obj)
    return GDI_ERROR;

  skia::RefPtr<SkTypeface> typeface = dc_obj->typeface();
  if (!typeface)
    return GDI_ERROR;

  // |getTableData| handles |buffer| being nullptr. However if it is nullptr
  // then set the size to INT32_MAX otherwise |getTableData| will return the
  // minimum value between the table entry size and the size passed in. The
  // common Windows idiom is to pass 0 as |buffer_length| when passing nullptr,
  // which would in this case result in |getTableData| returning 0 which isn't
  // the correct answer for emulating GDI. |table_tag| must also have its
  // byte order swapped to counter the swap which occurs in the called method.
  size_t length = typeface->getTableData(
      base::ByteSwap(base::strict_cast<uint32_t>(table_tag)), table_offset,
      buffer ? buffer_length : INT32_MAX, buffer);
  // We can't distinguish between an empty table and an error.
  if (length == 0)
    return GDI_ERROR;

  return base::checked_cast<DWORD>(length);
}

HGDIOBJ WINAPI SelectObjectPatch(HDC dc_handle, HGDIOBJ object_handle) {
  scoped_refptr<FakeGdiObject> dc_obj =
      g_fake_gdi_object_factory.Get().Validate(dc_handle, kFakeDCMagic);
  if (!dc_obj)
    return nullptr;

  scoped_refptr<FakeGdiObject> font_obj =
      g_fake_gdi_object_factory.Get().Validate(object_handle, kFakeFontMagic);
  if (!font_obj)
    return nullptr;

  // Construct a new fake font object to handle the old font if there's one.
  scoped_refptr<FakeGdiObject> new_font_obj;
  skia::RefPtr<SkTypeface> old_typeface = dc_obj->typeface();
  if (old_typeface) {
    new_font_obj = g_fake_gdi_object_factory.Get().Create(kFakeFontMagic);
    new_font_obj->set_typeface(old_typeface);
  }
  dc_obj->set_typeface(font_obj->typeface());

  if (new_font_obj)
    return static_cast<HGDIOBJ>(new_font_obj->handle());
  return nullptr;
}

void DoSingleGdiPatch(base::win::IATPatchFunction& patch,
                      const base::FilePath& path,
                      const char* function_name,
                      void* new_function) {
  patch.Patch(path.value().c_str(), "gdi32.dll", function_name, new_function);
}

class GdiFontPatchDataImpl : public content::GdiFontPatchData {
 public:
  GdiFontPatchDataImpl(const base::FilePath& path);

 private:
  base::win::IATPatchFunction create_compatible_dc_patch_;
  base::win::IATPatchFunction create_font_indirect_patch_;
  base::win::IATPatchFunction create_delete_dc_patch_;
  base::win::IATPatchFunction create_delete_object_patch_;
  base::win::IATPatchFunction create_enum_font_families_patch_;
  base::win::IATPatchFunction create_get_font_data_patch_;
  base::win::IATPatchFunction create_select_object_patch_;
};

GdiFontPatchDataImpl::GdiFontPatchDataImpl(const base::FilePath& path) {
  DoSingleGdiPatch(create_compatible_dc_patch_, path, "CreateCompatibleDC",
                   CreateCompatibleDCPatch);
  DoSingleGdiPatch(create_font_indirect_patch_, path, "CreateFontIndirectW",
                   CreateFontIndirectWPatch);
  DoSingleGdiPatch(create_delete_dc_patch_, path, "DeleteDC", DeleteDCPatch);
  DoSingleGdiPatch(create_delete_object_patch_, path, "DeleteObject",
                   DeleteObjectPatch);
  DoSingleGdiPatch(create_enum_font_families_patch_, path,
                   "EnumFontFamiliesExW", EnumFontFamiliesExWPatch);
  DoSingleGdiPatch(create_get_font_data_patch_, path, "GetFontData",
                   GetFontDataPatch);
  DoSingleGdiPatch(create_select_object_patch_, path, "SelectObject",
                   SelectObjectPatch);
}

}  // namespace

// Directwrite connects to the font cache service to retrieve information about
// fonts installed on the system etc. This works well outside the sandbox and
// within the sandbox as long as the lpc connection maintained by the current
// process with the font cache service remains valid. It appears that there
// are cases when this connection is dropped after which directwrite is unable
// to connect to the font cache service which causes problems with characters
// disappearing.
// Directwrite has fallback code to enumerate fonts if it is unable to connect
// to the font cache service. We need to intercept the following APIs to
// ensure that it does not connect to the font cache service.
// NtALpcConnectPort
// OpenSCManagerW
// OpenServiceW
// StartServiceW
// CloseServiceHandle.
// These are all IAT patched.
void PatchServiceManagerCalls() {
  static bool is_patched = false;
  if (is_patched)
    return;
  const char* service_provider_dll =
      (base::win::GetVersion() >= base::win::VERSION_WIN8
           ? "api-ms-win-service-management-l1-1-0.dll"
           : "advapi32.dll");

  is_patched = true;

  DWORD patched =
      g_iat_patch_open_sc_manager.Patch(L"dwrite.dll", service_provider_dll,
                                        "OpenSCManagerW", OpenSCManagerWPatch);
  DCHECK(patched == 0);

  patched = g_iat_patch_close_service_handle.Patch(
      L"dwrite.dll", service_provider_dll, "CloseServiceHandle",
      CloseServiceHandlePatch);
  DCHECK(patched == 0);

  patched = g_iat_patch_open_service.Patch(L"dwrite.dll", service_provider_dll,
                                           "OpenServiceW", OpenServiceWPatch);
  DCHECK(patched == 0);

  patched = g_iat_patch_start_service.Patch(
      L"dwrite.dll", service_provider_dll, "StartServiceW", StartServiceWPatch);
  DCHECK(patched == 0);

  patched = g_iat_patch_nt_connect_port.Patch(
      L"dwrite.dll", "ntdll.dll", "NtAlpcConnectPort", NtALpcConnectPortPatch);
  DCHECK(patched == 0);
}

GdiFontPatchData* PatchGdiFontEnumeration(const base::FilePath& path) {
  if (!g_warmup_fontmgr)
    g_warmup_fontmgr = SkFontMgr_New_DirectWrite();
  DCHECK(g_warmup_fontmgr);
  return new GdiFontPatchDataImpl(path);
}

size_t GetEmulatedGdiHandleCountForTesting() {
  return g_fake_gdi_object_factory.Get().GetObjectCount();
}

void ResetEmulatedGdiHandlesForTesting() {
  g_fake_gdi_object_factory.Get().ResetObjectHandles();
}

void SetPreSandboxWarmupFontMgrForTesting(SkFontMgr* fontmgr) {
  g_warmup_fontmgr = fontmgr;
}

}  // namespace content
