// 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 "third_party/skia/include/core/SkRefCnt.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(sk_sp<SkTypeface> typeface) {
    typeface_ = std::move(typeface);
  }

  sk_sp<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_;
  sk_sp<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*>(
        static_cast<uintptr_t>(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';

sk_sp<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 sk_sp<SkTypeface>(
      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;

  sk_sp<SkTypeface> typeface = GetTypefaceFromLOGFONT(log_font);
  if (!typeface)
    return nullptr;

  scoped_refptr<FakeGdiObject> ret =
      g_fake_gdi_object_factory.Get().Create(kFakeFontMagic);
  ret->set_typeface(std::move(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;

  sk_sp<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;

  sk_sp<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;
  sk_sp<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(std::move(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().release();
  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(sk_sp<SkFontMgr> fontmgr) {
  SkSafeUnref(g_warmup_fontmgr);
  g_warmup_fontmgr = fontmgr.release();
}

}  // namespace content
