/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtWebEngine module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include <qlibrary.h>
#include <qoperatingsystemversion.h>
#include <qsysinfo.h>
#include <qt_windows.h>
#include <TlHelp32.h>
#include "../3rdparty/chromium/sandbox/win/src/process_mitigations.h"
#include "../3rdparty/chromium/sandbox/win/src/sandbox_factory.h"

#ifndef NDEBUG
#include "../3rdparty/chromium/base/command_line.h"
#endif

class User32DLL {
public:
    User32DLL()
        : setProcessDPIAware(0)
    {
        library.setFileName(QStringLiteral("User32"));
        if (!library.load())
            return;
        setProcessDPIAware = (SetProcessDPIAware)library.resolve("SetProcessDPIAware");
    }

    bool isValid() const
    {
        return setProcessDPIAware;
    }

    typedef BOOL (WINAPI *SetProcessDPIAware)();

    // Windows Vista onwards
    SetProcessDPIAware setProcessDPIAware;

private:
    QLibrary library;
};

// This must match PROCESS_DPI_AWARENESS in ShellScalingApi.h
enum DpiAwareness {
    PROCESS_PER_UNAWARE = 0,
    PROCESS_PER_SYSTEM_DPI_AWARE = 1,
    PROCESS_PER_MONITOR_DPI_AWARE = 2
};

// Shell scaling library (Windows 8.1 onwards)
class ShcoreDLL {
public:
    ShcoreDLL()
        : getProcessDpiAwareness(0), setProcessDpiAwareness(0)
    {
        if (QOperatingSystemVersion::current() < QOperatingSystemVersion::Windows8_1)
            return;
        library.setFileName(QStringLiteral("SHCore"));
        if (!library.load())
            return;
        getProcessDpiAwareness = (GetProcessDpiAwareness)library.resolve("GetProcessDpiAwareness");
        setProcessDpiAwareness = (SetProcessDpiAwareness)library.resolve("SetProcessDpiAwareness");
    }

    bool isValid() const
    {
        return getProcessDpiAwareness && setProcessDpiAwareness;
    }

    typedef HRESULT (WINAPI *GetProcessDpiAwareness)(HANDLE, DpiAwareness *);
    typedef HRESULT (WINAPI *SetProcessDpiAwareness)(DpiAwareness);

    GetProcessDpiAwareness getProcessDpiAwareness;
    SetProcessDpiAwareness setProcessDpiAwareness;

private:
    QLibrary library;
};


static DWORD getParentProcessId()
{
    HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (hSnapshot == INVALID_HANDLE_VALUE) {
        qErrnoWarning(GetLastError(), "CreateToolhelp32Snapshot failed.");
        return NULL;
    }

    PROCESSENTRY32 pe = {0};
    pe.dwSize = sizeof(PROCESSENTRY32);

    if (!Process32First(hSnapshot, &pe)) {
        qWarning("Cannot retrieve parent process handle.");
        return NULL;
    }

    DWORD parentPid = NULL;
    const DWORD pid = GetCurrentProcessId();
    do {
        if (pe.th32ProcessID == pid) {
            parentPid = pe.th32ParentProcessID;
            break;
        }
    } while (Process32Next(hSnapshot, &pe));
    CloseHandle(hSnapshot);
    return parentPid;
}

namespace QtWebEngineCore {
extern __declspec(dllimport) sandbox::SandboxInterfaceInfo *staticSandboxInterfaceInfo(sandbox::SandboxInterfaceInfo *info = nullptr);
}

namespace QtWebEngineProcess {

// A duplicate of the function by same name in startup_helper_win.cc
static void InitializeSandboxInfo(sandbox::SandboxInterfaceInfo *info)
{
    info->broker_services = sandbox::SandboxFactory::GetBrokerServices();
    if (!info->broker_services) {
        info->target_services = sandbox::SandboxFactory::GetTargetServices();
    } else {
        // Ensure the proper mitigations are enforced for the browser process.
        sandbox::ApplyProcessMitigationsToCurrentProcess(
            sandbox::MITIGATION_DEP | sandbox::MITIGATION_DEP_NO_ATL_THUNK |
            sandbox::MITIGATION_HARDEN_TOKEN_IL_POLICY);
        // Note: these mitigations are "post-startup".  Some mitigations that need
        // to be enabled sooner (e.g. MITIGATION_EXTENSION_POINT_DISABLE) are done
        // so in Chrome_ELF.
    }
}

// Initializes the staticlib copy of //base and //sandbox used for Windows sandboxing
void initializeStaticCopy(int argc, const char **argv)
{
#ifndef NDEBUG
    // Initialize //base for debugging
    base::CommandLine::Init(argc, argv);
    logging::LoggingSettings settings;
    settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG;
    logging::InitLogging(settings);
#endif
    sandbox::SandboxInterfaceInfo *info = new sandbox::SandboxInterfaceInfo();
    memset(info, 0, sizeof(sandbox::SandboxInterfaceInfo));
    InitializeSandboxInfo(info);
    QtWebEngineCore::staticSandboxInterfaceInfo(info);
}

void initDpiAwareness()
{
    ShcoreDLL shcore;
    if (shcore.isValid()) {
        DpiAwareness dpiAwareness = PROCESS_PER_MONITOR_DPI_AWARE;
        const DWORD pid = getParentProcessId();
        if (pid) {
            HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid);
            DpiAwareness parentDpiAwareness;
            HRESULT hr = shcore.getProcessDpiAwareness(hProcess, &parentDpiAwareness);
            CloseHandle(hProcess);
            if (hr == S_OK)
                dpiAwareness = parentDpiAwareness;
        }
        if (shcore.setProcessDpiAwareness(dpiAwareness) != S_OK)
            qErrnoWarning(GetLastError(), "SetProcessDPIAwareness failed.");
    } else {
        // Fallback. Use SetProcessDPIAware unconditionally.
        User32DLL user32;
        if (user32.isValid())
            user32.setProcessDPIAware();
    }
}

} // namespace QtWebEngineProcess
