// Copyright (c) 2012 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 "printing/backend/win_helper.h"

#include <stddef.h>
#include <wrl/client.h>

#include <algorithm>
#include <memory>

#include "base/debug/alias.h"
#include "base/file_version_info.h"
#include "base/files/file_path.h"
#include "base/logging.h"
#include "base/memory/free_deleter.h"
#include "base/numerics/safe_conversions.h"
#include "base/stl_util.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/win/windows_version.h"
#include "printing/backend/print_backend.h"
#include "printing/backend/print_backend_consts.h"
#include "printing/backend/printing_info_win.h"

namespace {

typedef HRESULT (WINAPI* PTOpenProviderProc)(PCWSTR printer_name,
                                             DWORD version,
                                             HPTPROVIDER* provider);

typedef HRESULT (WINAPI* PTGetPrintCapabilitiesProc)(HPTPROVIDER provider,
                                                     IStream* print_ticket,
                                                     IStream* capabilities,
                                                     BSTR* error_message);

typedef HRESULT (WINAPI* PTConvertDevModeToPrintTicketProc)(
    HPTPROVIDER provider,
    ULONG devmode_size_in_bytes,
    PDEVMODE devmode,
    EPrintTicketScope scope,
    IStream* print_ticket);

typedef HRESULT (WINAPI* PTConvertPrintTicketToDevModeProc)(
    HPTPROVIDER provider,
    IStream* print_ticket,
    EDefaultDevmodeType base_devmode_type,
    EPrintTicketScope scope,
    ULONG* devmode_byte_count,
    PDEVMODE* devmode,
    BSTR* error_message);

typedef HRESULT (WINAPI* PTMergeAndValidatePrintTicketProc)(
    HPTPROVIDER provider,
    IStream* base_ticket,
    IStream* delta_ticket,
    EPrintTicketScope scope,
    IStream* result_ticket,
    BSTR* error_message);

typedef HRESULT (WINAPI* PTReleaseMemoryProc)(PVOID buffer);

typedef HRESULT (WINAPI* PTCloseProviderProc)(HPTPROVIDER provider);

typedef HRESULT (WINAPI* StartXpsPrintJobProc)(
    const LPCWSTR printer_name,
    const LPCWSTR job_name,
    const LPCWSTR output_file_name,
    HANDLE progress_event,
    HANDLE completion_event,
    UINT8* printable_pages_on,
    UINT32 printable_pages_on_count,
    IXpsPrintJob** xps_print_job,
    IXpsPrintJobStream** document_stream,
    IXpsPrintJobStream** print_ticket_stream);

PTOpenProviderProc g_open_provider_proc = nullptr;
PTGetPrintCapabilitiesProc g_get_print_capabilities_proc = nullptr;
PTConvertDevModeToPrintTicketProc g_convert_devmode_to_print_ticket_proc =
    nullptr;
PTConvertPrintTicketToDevModeProc g_convert_print_ticket_to_devmode_proc =
    nullptr;
PTMergeAndValidatePrintTicketProc g_merge_and_validate_print_ticket_proc =
    nullptr;
PTReleaseMemoryProc g_release_memory_proc = nullptr;
PTCloseProviderProc g_close_provider_proc = nullptr;
StartXpsPrintJobProc g_start_xps_print_job_proc = nullptr;

HRESULT StreamFromPrintTicket(const std::string& print_ticket,
                              IStream** stream) {
  DCHECK(stream);
  HRESULT hr = CreateStreamOnHGlobal(nullptr, TRUE, stream);
  if (FAILED(hr)) {
    return hr;
  }
  ULONG bytes_written = 0;
  (*stream)->Write(print_ticket.c_str(),
                   base::checked_cast<ULONG>(print_ticket.length()),
                   &bytes_written);
  DCHECK(bytes_written == print_ticket.length());
  LARGE_INTEGER pos = {};
  ULARGE_INTEGER new_pos = {};
  (*stream)->Seek(pos, STREAM_SEEK_SET, &new_pos);
  return S_OK;
}

const char kXpsTicketTemplate[] =
  "<?xml version='1.0' encoding='UTF-8'?>"
  "<psf:PrintTicket "
  "xmlns:psf='"
  "http://schemas.microsoft.com/windows/2003/08/printing/printschemaframework' "
  "xmlns:psk="
  "'http://schemas.microsoft.com/windows/2003/08/printing/printschemakeywords' "
  "version='1'>"
  "<psf:Feature name='psk:PageOutputColor'>"
  "<psf:Option name='psk:%s'>"
  "</psf:Option>"
  "</psf:Feature>"
  "</psf:PrintTicket>";

const char kXpsTicketColor[] = "Color";
const char kXpsTicketMonochrome[] = "Monochrome";


}  // namespace


namespace printing {

bool XPSModule::Init() {
  static bool initialized = InitImpl();
  return initialized;
}

bool XPSModule::InitImpl() {
  HMODULE prntvpt_module = LoadLibrary(L"prntvpt.dll");
  if (!prntvpt_module)
    return false;
  g_open_provider_proc = reinterpret_cast<PTOpenProviderProc>(
      GetProcAddress(prntvpt_module, "PTOpenProvider"));
  if (!g_open_provider_proc) {
    NOTREACHED();
    return false;
  }
  g_get_print_capabilities_proc = reinterpret_cast<PTGetPrintCapabilitiesProc>(
      GetProcAddress(prntvpt_module, "PTGetPrintCapabilities"));
  if (!g_get_print_capabilities_proc) {
    NOTREACHED();
    return false;
  }
  g_convert_devmode_to_print_ticket_proc =
      reinterpret_cast<PTConvertDevModeToPrintTicketProc>(
          GetProcAddress(prntvpt_module, "PTConvertDevModeToPrintTicket"));
  if (!g_convert_devmode_to_print_ticket_proc) {
    NOTREACHED();
    return false;
  }
  g_convert_print_ticket_to_devmode_proc =
      reinterpret_cast<PTConvertPrintTicketToDevModeProc>(
          GetProcAddress(prntvpt_module, "PTConvertPrintTicketToDevMode"));
  if (!g_convert_print_ticket_to_devmode_proc) {
    NOTREACHED();
    return false;
  }
  g_merge_and_validate_print_ticket_proc =
      reinterpret_cast<PTMergeAndValidatePrintTicketProc>(
          GetProcAddress(prntvpt_module, "PTMergeAndValidatePrintTicket"));
  if (!g_merge_and_validate_print_ticket_proc) {
    NOTREACHED();
    return false;
  }
  g_release_memory_proc =
      reinterpret_cast<PTReleaseMemoryProc>(
          GetProcAddress(prntvpt_module, "PTReleaseMemory"));
  if (!g_release_memory_proc) {
    NOTREACHED();
    return false;
  }
  g_close_provider_proc =
      reinterpret_cast<PTCloseProviderProc>(
          GetProcAddress(prntvpt_module, "PTCloseProvider"));
  if (!g_close_provider_proc) {
    NOTREACHED();
    return false;
  }
  return true;
}

HRESULT XPSModule::OpenProvider(const base::string16& printer_name,
                                DWORD version,
                                HPTPROVIDER* provider) {
  return g_open_provider_proc(printer_name.c_str(), version, provider);
}

HRESULT XPSModule::GetPrintCapabilities(HPTPROVIDER provider,
                                        IStream* print_ticket,
                                        IStream* capabilities,
                                        BSTR* error_message) {
  return g_get_print_capabilities_proc(provider,
                                       print_ticket,
                                       capabilities,
                                       error_message);
}

HRESULT XPSModule::ConvertDevModeToPrintTicket(HPTPROVIDER provider,
                                               ULONG devmode_size_in_bytes,
                                               PDEVMODE devmode,
                                               EPrintTicketScope scope,
                                               IStream* print_ticket) {
  return g_convert_devmode_to_print_ticket_proc(provider,
                                                devmode_size_in_bytes,
                                                devmode,
                                                scope,
                                                print_ticket);
}

HRESULT XPSModule::ConvertPrintTicketToDevMode(
    HPTPROVIDER provider,
    IStream* print_ticket,
    EDefaultDevmodeType base_devmode_type,
    EPrintTicketScope scope,
    ULONG* devmode_byte_count,
    PDEVMODE* devmode,
    BSTR* error_message) {
  return g_convert_print_ticket_to_devmode_proc(provider,
                                                print_ticket,
                                                base_devmode_type,
                                                scope,
                                                devmode_byte_count,
                                                devmode,
                                                error_message);
}

HRESULT XPSModule::MergeAndValidatePrintTicket(HPTPROVIDER provider,
                                               IStream* base_ticket,
                                               IStream* delta_ticket,
                                               EPrintTicketScope scope,
                                               IStream* result_ticket,
                                               BSTR* error_message) {
  return g_merge_and_validate_print_ticket_proc(provider,
                                                base_ticket,
                                                delta_ticket,
                                                scope,
                                                result_ticket,
                                                error_message);
}

HRESULT XPSModule::ReleaseMemory(PVOID buffer) {
  return g_release_memory_proc(buffer);
}

HRESULT XPSModule::CloseProvider(HPTPROVIDER provider) {
  return g_close_provider_proc(provider);
}

ScopedXPSInitializer::ScopedXPSInitializer() : initialized_(false) {
  if (!XPSModule::Init())
    return;
  // Calls to XPS APIs typically require the XPS provider to be opened with
  // PTOpenProvider. PTOpenProvider calls CoInitializeEx with
  // COINIT_MULTITHREADED. We have seen certain buggy HP printer driver DLLs
  // that call CoInitializeEx with COINIT_APARTMENTTHREADED in the context of
  // PTGetPrintCapabilities. This call fails but the printer driver calls
  // CoUninitialize anyway. This results in the apartment being torn down too
  // early and the msxml DLL being unloaded which in turn causes code in
  // unidrvui.dll to have a dangling pointer to an XML document which causes a
  // crash. To protect ourselves from such drivers we make sure we always have
  // an extra CoInitialize (calls to CoInitialize/CoUninitialize are
  // refcounted).
  HRESULT hr = CoInitializeEx(nullptr, COINIT_MULTITHREADED);
  // If this succeeded we are done because the PTOpenProvider call will provide
  // the extra refcount on the apartment. If it failed because someone already
  // called CoInitializeEx with COINIT_APARTMENTTHREADED, we try the other model
  // to provide the additional refcount (since we don't know which model buggy
  // printer drivers will use).
  if (!SUCCEEDED(hr))
    hr = CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);
  DCHECK(SUCCEEDED(hr));
  initialized_ = true;
}

ScopedXPSInitializer::~ScopedXPSInitializer() {
  if (initialized_)
    CoUninitialize();
  initialized_ = false;
}

bool XPSPrintModule::Init() {
  static bool initialized = InitImpl();
  return initialized;
}

bool XPSPrintModule::InitImpl() {
  HMODULE xpsprint_module = LoadLibrary(L"xpsprint.dll");
  if (!xpsprint_module)
    return false;
  g_start_xps_print_job_proc = reinterpret_cast<StartXpsPrintJobProc>(
      GetProcAddress(xpsprint_module, "StartXpsPrintJob"));
  if (!g_start_xps_print_job_proc) {
    NOTREACHED();
    return false;
  }
  return true;
}

HRESULT XPSPrintModule::StartXpsPrintJob(
    const LPCWSTR printer_name,
    const LPCWSTR job_name,
    const LPCWSTR output_file_name,
    HANDLE progress_event,
    HANDLE completion_event,
    UINT8* printable_pages_on,
    UINT32 printable_pages_on_count,
    IXpsPrintJob** xps_print_job,
    IXpsPrintJobStream** document_stream,
    IXpsPrintJobStream** print_ticket_stream) {
  return g_start_xps_print_job_proc(printer_name,
                                    job_name,
                                    output_file_name,
                                    progress_event,
                                    completion_event,
                                    printable_pages_on,
                                    printable_pages_on_count,
                                    xps_print_job,
                                    document_stream,
                                    print_ticket_stream);
}

bool InitBasicPrinterInfo(HANDLE printer, PrinterBasicInfo* printer_info) {
  DCHECK(printer);
  DCHECK(printer_info);
  if (!printer)
    return false;

  PrinterInfo2 info_2;
  if (!info_2.Init(printer))
    return false;

  printer_info->printer_name = base::WideToUTF8(info_2.get()->pPrinterName);
  if (info_2.get()->pComment) {
    printer_info->printer_description =
        base::WideToUTF8(info_2.get()->pComment);
  }
  if (info_2.get()->pLocation) {
    printer_info->options[kLocationTagName] =
        base::WideToUTF8(info_2.get()->pLocation);
  }
  if (info_2.get()->pDriverName) {
    printer_info->options[kDriverNameTagName] =
        base::WideToUTF8(info_2.get()->pDriverName);
  }
  printer_info->printer_status = info_2.get()->Status;

  std::string driver_info = GetDriverInfo(printer);
  if (!driver_info.empty())
    printer_info->options[kDriverInfoTagName] = driver_info;
  return true;
}

std::string GetDriverInfo(HANDLE printer) {
  DCHECK(printer);
  std::string driver_info;

  if (!printer)
    return driver_info;

  DriverInfo6 info_6;
  if (!info_6.Init(printer))
    return driver_info;

  std::string info[4];
  if (info_6.get()->pName)
    info[0] = base::WideToUTF8(info_6.get()->pName);

  if (info_6.get()->pDriverPath) {
    std::unique_ptr<FileVersionInfo> version_info(
        FileVersionInfo::CreateFileVersionInfo(
            base::FilePath(info_6.get()->pDriverPath)));
    if (version_info.get()) {
      info[1] = base::WideToUTF8(version_info->file_version());
      info[2] = base::WideToUTF8(version_info->product_name());
      info[3] = base::WideToUTF8(version_info->product_version());
    }
  }

  for (size_t i = 0; i < base::size(info); ++i) {
    std::replace(info[i].begin(), info[i].end(), ';', ',');
    driver_info.append(info[i]);
    if (i < base::size(info) - 1)
      driver_info.append(";");
  }
  return driver_info;
}

std::unique_ptr<DEVMODE, base::FreeDeleter> XpsTicketToDevMode(
    const base::string16& printer_name,
    const std::string& print_ticket) {
  std::unique_ptr<DEVMODE, base::FreeDeleter> dev_mode;
  ScopedXPSInitializer xps_initializer;
  if (!xps_initializer.initialized()) {
    // TODO(sanjeevr): Handle legacy proxy case (with no prntvpt.dll)
    return dev_mode;
  }

  ScopedPrinterHandle printer;
  if (!printer.OpenPrinter(printer_name.c_str()))
    return dev_mode;

  Microsoft::WRL::ComPtr<IStream> pt_stream;
  HRESULT hr = StreamFromPrintTicket(print_ticket, pt_stream.GetAddressOf());
  if (FAILED(hr))
    return dev_mode;

  HPTPROVIDER provider = nullptr;
  hr = XPSModule::OpenProvider(printer_name, 1, &provider);
  if (SUCCEEDED(hr)) {
    ULONG size = 0;
    DEVMODE* dm = nullptr;
    // Use kPTJobScope, because kPTDocumentScope breaks duplex.
    hr = XPSModule::ConvertPrintTicketToDevMode(
        provider, pt_stream.Get(), kUserDefaultDevmode, kPTJobScope, &size, &dm,
        nullptr);
    if (SUCCEEDED(hr)) {
      // Correct DEVMODE using DocumentProperties. See documentation for
      // PTConvertPrintTicketToDevMode.
      dev_mode = CreateDevMode(printer.Get(), dm);
      XPSModule::ReleaseMemory(dm);
    }
    XPSModule::CloseProvider(provider);
  }
  return dev_mode;
}

bool IsDevModeWithColor(const DEVMODE* devmode) {
  return (devmode->dmFields & DM_COLOR) && (devmode->dmColor == DMCOLOR_COLOR);
}

std::unique_ptr<DEVMODE, base::FreeDeleter> CreateDevModeWithColor(
    HANDLE printer,
    const base::string16& printer_name,
    bool color) {
  std::unique_ptr<DEVMODE, base::FreeDeleter> default_ticket =
      CreateDevMode(printer, nullptr);
  if (!default_ticket || IsDevModeWithColor(default_ticket.get()) == color)
    return default_ticket;

  default_ticket->dmFields |= DM_COLOR;
  default_ticket->dmColor = color ? DMCOLOR_COLOR : DMCOLOR_MONOCHROME;

  DriverInfo6 info_6;
  if (!info_6.Init(printer))
    return default_ticket;

  const DRIVER_INFO_6* p = info_6.get();

  // Only HP known to have issues.
  if (!p->pszMfgName || wcscmp(p->pszMfgName, L"HP") != 0)
    return default_ticket;

  // Need XPS for this workaround.
  ScopedXPSInitializer xps_initializer;
  if (!xps_initializer.initialized())
    return default_ticket;

  const char* xps_color = color ? kXpsTicketColor : kXpsTicketMonochrome;
  std::string xps_ticket = base::StringPrintf(kXpsTicketTemplate, xps_color);
  std::unique_ptr<DEVMODE, base::FreeDeleter> ticket =
      XpsTicketToDevMode(printer_name, xps_ticket);
  if (!ticket)
    return default_ticket;

  return ticket;
}

bool PrinterHasValidPaperSize(const wchar_t* name, const wchar_t* port) {
  return DeviceCapabilities(name, port, DC_PAPERSIZE, nullptr, nullptr) > 0;
}

std::unique_ptr<DEVMODE, base::FreeDeleter> CreateDevMode(HANDLE printer,
                                                          DEVMODE* in) {
  wchar_t* device_name_ptr = const_cast<wchar_t*>(L"");
  LONG buffer_size = DocumentProperties(nullptr, printer, device_name_ptr,
                                        nullptr, nullptr, 0);
  if (buffer_size < static_cast<int>(sizeof(DEVMODE)))
    return nullptr;

  // Some drivers request buffers with size smaller than dmSize + dmDriverExtra.
  // crbug.com/421402
  buffer_size *= 2;

  std::unique_ptr<DEVMODE, base::FreeDeleter> out(
      reinterpret_cast<DEVMODE*>(calloc(buffer_size, 1)));
  DWORD flags = (in ? (DM_IN_BUFFER) : 0) | DM_OUT_BUFFER;

  PrinterInfo5 info_5;
  if (!info_5.Init(printer))
    return nullptr;

  // Check that valid paper sizes exist; some old drivers return no paper sizes
  // and crash in DocumentProperties if used with Win10. See crbug.com/679160,
  // crbug.com/724595
  const wchar_t* name = info_5.get()->pPrinterName;
  const wchar_t* port = info_5.get()->pPortName;
  if (!PrinterHasValidPaperSize(name, port)) {
    return nullptr;
  }

  if (DocumentProperties(nullptr, printer, device_name_ptr, out.get(), in,
                         flags) != IDOK) {
    return nullptr;
  }

  int size = out->dmSize;
  int extra_size = out->dmDriverExtra;

  // The CHECK_GE() below can fail. Alias the variable values so they are
  // recorded in crash dumps.
  // See https://crbug.com/780016 and https://crbug.com/806016 for example
  // crashes.
  base::debug::Alias(&size);
  base::debug::Alias(&extra_size);
  base::debug::Alias(&buffer_size);
  CHECK_GE(buffer_size, size + extra_size);
  return out;
}

std::unique_ptr<DEVMODE, base::FreeDeleter> PromptDevMode(
    HANDLE printer,
    const base::string16& printer_name,
    DEVMODE* in,
    HWND window,
    bool* canceled) {
  wchar_t* printer_name_ptr = const_cast<wchar_t*>(printer_name.c_str());
  LONG buffer_size = DocumentProperties(window, printer, printer_name_ptr,
                                        nullptr, nullptr, 0);
  if (buffer_size < static_cast<int>(sizeof(DEVMODE)))
    return std::unique_ptr<DEVMODE, base::FreeDeleter>();

  // Some drivers request buffers with size smaller than dmSize + dmDriverExtra.
  // crbug.com/421402
  buffer_size *= 2;

  std::unique_ptr<DEVMODE, base::FreeDeleter> out(
      reinterpret_cast<DEVMODE*>(calloc(buffer_size, 1)));
  DWORD flags = (in ? (DM_IN_BUFFER) : 0) | DM_OUT_BUFFER | DM_IN_PROMPT;
  LONG result = DocumentProperties(window, printer, printer_name_ptr, out.get(),
                                   in, flags);
  if (canceled)
    *canceled = (result == IDCANCEL);
  if (result != IDOK)
    return std::unique_ptr<DEVMODE, base::FreeDeleter>();

  int size = out->dmSize;
  int extra_size = out->dmDriverExtra;
  CHECK_GE(buffer_size, size + extra_size);
  return out;
}

}  // namespace printing
