/****************************************************************************
**
** Copyright (C) 2017 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the tools applications 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 "appxengine.h"
#include "appxengine_p.h"

#include <QtCore/QDateTime>
#include <QtCore/QDir>
#include <QtCore/QDirIterator>
#include <QtCore/QFile>
#include <QtCore/QFileInfo>
#include <QtCore/QLoggingCategory>
#include <QtCore/QStandardPaths>

#include <ShlObj.h>
#include <Shlwapi.h>
#include <wsdevlicensing.h>
#include <AppxPackaging.h>
#include <wrl.h>
#include <windows.applicationmodel.h>
#include <windows.management.deployment.h>
#include <wincrypt.h>

using namespace Microsoft::WRL;
using namespace Microsoft::WRL::Wrappers;
using namespace ABI::Windows::Foundation;
using namespace ABI::Windows::Management::Deployment;
using namespace ABI::Windows::ApplicationModel;
using namespace ABI::Windows::System;

QT_USE_NAMESPACE

// *********** Taken from MSDN Example code
// https://msdn.microsoft.com/en-us/library/windows/desktop/jj835834%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396

#define SIGNER_SUBJECT_FILE    0x01
#define SIGNER_NO_ATTR          0x00
#define SIGNER_CERT_POLICY_CHAIN_NO_ROOT    0x08
#define SIGNER_CERT_STORE        0x02

typedef struct _SIGNER_FILE_INFO
{
    DWORD cbSize;
    LPCWSTR pwszFileName;
    HANDLE hFile;
} SIGNER_FILE_INFO;

typedef struct _SIGNER_BLOB_INFO
{
    DWORD cbSize;
    GUID *pGuidSubject;
    DWORD cbBlob;
    BYTE *pbBlob;
    LPCWSTR pwszDisplayName;
} SIGNER_BLOB_INFO;

typedef struct _SIGNER_SUBJECT_INFO
{
    DWORD cbSize;
    DWORD *pdwIndex;
    DWORD dwSubjectChoice;
    union
    {
        SIGNER_FILE_INFO *pSignerFileInfo;
        SIGNER_BLOB_INFO *pSignerBlobInfo;
    };
} SIGNER_SUBJECT_INFO, *PSIGNER_SUBJECT_INFO;

typedef struct _SIGNER_ATTR_AUTHCODE
{
    DWORD cbSize;
    BOOL fCommercial;
    BOOL fIndividual;
    LPCWSTR pwszName;
    LPCWSTR pwszInfo;
} SIGNER_ATTR_AUTHCODE;

typedef struct _SIGNER_SIGNATURE_INFO
{
    DWORD cbSize;
    ALG_ID algidHash;
    DWORD dwAttrChoice;
    union
    {
        SIGNER_ATTR_AUTHCODE *pAttrAuthcode;
    };
    PCRYPT_ATTRIBUTES psAuthenticated;
    PCRYPT_ATTRIBUTES psUnauthenticated;
} SIGNER_SIGNATURE_INFO, *PSIGNER_SIGNATURE_INFO;

typedef struct _SIGNER_PROVIDER_INFO
{
    DWORD cbSize;
    LPCWSTR pwszProviderName;
    DWORD dwProviderType;
    DWORD dwKeySpec;
    DWORD dwPvkChoice;
    union
    {
        LPWSTR pwszPvkFileName;
        LPWSTR pwszKeyContainer;
    };
} SIGNER_PROVIDER_INFO, *PSIGNER_PROVIDER_INFO;

typedef struct _SIGNER_SPC_CHAIN_INFO
{
    DWORD cbSize;
    LPCWSTR pwszSpcFile;
    DWORD dwCertPolicy;
    HCERTSTORE hCertStore;
} SIGNER_SPC_CHAIN_INFO;

typedef struct _SIGNER_CERT_STORE_INFO
{
    DWORD cbSize;
    PCCERT_CONTEXT pSigningCert;
    DWORD dwCertPolicy;
    HCERTSTORE hCertStore;
} SIGNER_CERT_STORE_INFO;

typedef struct _SIGNER_CERT
{
    DWORD cbSize;
    DWORD dwCertChoice;
    union
    {
        LPCWSTR pwszSpcFile;
        SIGNER_CERT_STORE_INFO *pCertStoreInfo;
        SIGNER_SPC_CHAIN_INFO *pSpcChainInfo;
    };
    HWND hwnd;
} SIGNER_CERT, *PSIGNER_CERT;

typedef struct _SIGNER_CONTEXT
{
    DWORD cbSize;
    DWORD cbBlob;
    BYTE *pbBlob;
} SIGNER_CONTEXT, *PSIGNER_CONTEXT;

typedef struct _SIGNER_SIGN_EX2_PARAMS
{
    DWORD dwFlags;
    PSIGNER_SUBJECT_INFO pSubjectInfo;
    PSIGNER_CERT pSigningCert;
    PSIGNER_SIGNATURE_INFO pSignatureInfo;
    PSIGNER_PROVIDER_INFO pProviderInfo;
    DWORD dwTimestampFlags;
    PCSTR pszAlgorithmOid;
    PCWSTR pwszTimestampURL;
    PCRYPT_ATTRIBUTES pCryptAttrs;
    PVOID pSipData;
    PSIGNER_CONTEXT *pSignerContext;
    PVOID pCryptoPolicy;
    PVOID pReserved;
} SIGNER_SIGN_EX2_PARAMS, *PSIGNER_SIGN_EX2_PARAMS;

typedef struct _APPX_SIP_CLIENT_DATA
{
    PSIGNER_SIGN_EX2_PARAMS pSignerParams;
    IUnknown* pAppxSipState;
} APPX_SIP_CLIENT_DATA, *PAPPX_SIP_CLIENT_DATA;

bool signAppxPackage(PCCERT_CONTEXT signingCertContext, LPCWSTR packageFilePath)
{
    HRESULT hr = S_OK;

    DWORD signerIndex = 0;

    SIGNER_FILE_INFO fileInfo = {};
    fileInfo.cbSize = sizeof(SIGNER_FILE_INFO);
    fileInfo.pwszFileName = packageFilePath;

    SIGNER_SUBJECT_INFO subjectInfo = {};
    subjectInfo.cbSize = sizeof(SIGNER_SUBJECT_INFO);
    subjectInfo.pdwIndex = &signerIndex;
    subjectInfo.dwSubjectChoice = SIGNER_SUBJECT_FILE;
    subjectInfo.pSignerFileInfo = &fileInfo;

    SIGNER_CERT_STORE_INFO certStoreInfo = {};
    certStoreInfo.cbSize = sizeof(SIGNER_CERT_STORE_INFO);
    certStoreInfo.dwCertPolicy = SIGNER_CERT_POLICY_CHAIN_NO_ROOT;
    certStoreInfo.pSigningCert = signingCertContext;

    SIGNER_CERT cert = {};
    cert.cbSize = sizeof(SIGNER_CERT);
    cert.dwCertChoice = SIGNER_CERT_STORE;
    cert.pCertStoreInfo = &certStoreInfo;

    // The algidHash of the signature to be created must match the
    // hash algorithm used to create the app package
    SIGNER_SIGNATURE_INFO signatureInfo = {};
    signatureInfo.cbSize = sizeof(SIGNER_SIGNATURE_INFO);
    signatureInfo.algidHash = CALG_SHA_512;
    signatureInfo.dwAttrChoice = SIGNER_NO_ATTR;

    SIGNER_SIGN_EX2_PARAMS signerParams = {};
    signerParams.pSubjectInfo = &subjectInfo;
    signerParams.pSigningCert = &cert;
    signerParams.pSignatureInfo = &signatureInfo;

    APPX_SIP_CLIENT_DATA sipClientData = {};
    sipClientData.pSignerParams = &signerParams;
    signerParams.pSipData = &sipClientData;

    // Type definition for invoking SignerSignEx2 via GetProcAddress
    typedef HRESULT (WINAPI *SignerSignEx2Function)(
        DWORD,
        PSIGNER_SUBJECT_INFO,
        PSIGNER_CERT,
        PSIGNER_SIGNATURE_INFO,
        PSIGNER_PROVIDER_INFO,
        DWORD,
        PCSTR,
        PCWSTR,
        PCRYPT_ATTRIBUTES,
        PVOID,
        PSIGNER_CONTEXT *,
        PVOID,
        PVOID);

    // Load the SignerSignEx2 function from MSSign32.dll
    HMODULE msSignModule = LoadLibraryEx(
        L"MSSign32.dll",
        NULL,
        LOAD_LIBRARY_SEARCH_SYSTEM32);

    if (!msSignModule) {
        qCWarning(lcWinRtRunner) << "LoadLibraryEx failed to load MSSign32.dll.";
        return false;
    }

    SignerSignEx2Function SignerSignEx2 = reinterpret_cast<SignerSignEx2Function>(
                                          GetProcAddress(msSignModule, "SignerSignEx2"));
    if (!SignerSignEx2) {
        qCWarning(lcWinRtRunner) << "Could not resolve SignerSignEx2";
        FreeLibrary(msSignModule);
        return false;
    }
    hr = SignerSignEx2(signerParams.dwFlags,
                       signerParams.pSubjectInfo,
                       signerParams.pSigningCert,
                       signerParams.pSignatureInfo,
                       signerParams.pProviderInfo,
                       signerParams.dwTimestampFlags,
                       signerParams.pszAlgorithmOid,
                       signerParams.pwszTimestampURL,
                       signerParams.pCryptAttrs,
                       signerParams.pSipData,
                       signerParams.pSignerContext,
                       signerParams.pCryptoPolicy,
                       signerParams.pReserved);

    FreeLibrary(msSignModule);

    RETURN_FALSE_IF_FAILED("Could not sign package.");

    if (sipClientData.pAppxSipState)
        sipClientData.pAppxSipState->Release();

    return true;
}
// ************ MSDN

bool AppxEngine::getManifestFile(const QString &fileName, QString *manifest)
{
    if (!QFile::exists(fileName)) {
        qCWarning(lcWinRtRunner) << fileName << "does not exist.";
        return false;
    }

    // If it looks like an appx manifest, we're done
    if (fileName.endsWith(QStringLiteral("AppxManifest.xml"))) {

        if (manifest)
            *manifest = fileName;
        return true;
    }

    // If it looks like an executable, check that manifest is next to it
    if (fileName.endsWith(QLatin1String(".exe"))) {
        QDir appDir = QFileInfo(fileName).absoluteDir();
        QString manifestFileName = appDir.absoluteFilePath(QStringLiteral("AppxManifest.xml"));
        if (!QFile::exists(manifestFileName)) {
            qCWarning(lcWinRtRunner) << manifestFileName << "does not exist.";
            return false;
        }

        if (manifest)
            *manifest = manifestFileName;
        return true;
    }

    if (fileName.endsWith(QLatin1String(".appx"))) {
        // For existing appx packages the manifest reader will be
        // instantiated later.
        return true;
    }

    qCWarning(lcWinRtRunner) << "Appx: unable to determine manifest for" << fileName << ".";
    return false;
}

#define CHECK_RESULT(errorMessage, action)\
    do {\
        if (FAILED(hr)) {\
            qCWarning(lcWinRtRunner).nospace() << errorMessage " (0x"\
                                               << QByteArray::number(hr, 16).constData()\
                                               << ' ' << qt_error_string(hr) << ')';\
            action;\
        }\
    } while (false)

#define CHECK_RESULT_FATAL(errorMessage, action)\
    do {CHECK_RESULT(errorMessage, d->hasFatalError = true; action;);} while (false)

static ProcessorArchitecture toProcessorArchitecture(APPX_PACKAGE_ARCHITECTURE appxArch)
{
    switch (appxArch) {
    case APPX_PACKAGE_ARCHITECTURE_X86:
        return ProcessorArchitecture_X86;
    case APPX_PACKAGE_ARCHITECTURE_ARM:
        return ProcessorArchitecture_Arm;
    case APPX_PACKAGE_ARCHITECTURE_X64:
        return ProcessorArchitecture_X64;
    case APPX_PACKAGE_ARCHITECTURE_NEUTRAL:
        // fall-through intended
    default:
        return ProcessorArchitecture_Neutral;
    }
}

AppxEngine::AppxEngine(Runner *runner, AppxEnginePrivate *dd)
    : d_ptr(dd)
{
    Q_D(AppxEngine);
    if (d->hasFatalError)
        return;

    d->runner = runner;
    d->processHandle = NULL;
    d->pid = -1;
    d->exitCode = UINT_MAX;

    HRESULT hr;
    hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Foundation_Uri).Get(),
                                IID_PPV_ARGS(&d->uriFactory));
    CHECK_RESULT_FATAL("Failed to instantiate URI factory.", return);

    hr = CoCreateInstance(CLSID_AppxFactory, nullptr, CLSCTX_INPROC_SERVER,
                          IID_IAppxFactory, &d->packageFactory);
    CHECK_RESULT_FATAL("Failed to instantiate package factory.", return);

    bool existingPackage = runner->app().endsWith(QLatin1String(".appx"));

    if (existingPackage) {
        ComPtr<IStream> appxStream;
        hr = SHCreateStreamOnFile(wchar(runner->app()), STGM_READ, &appxStream);
        CHECK_RESULT_FATAL("Failed to open appx stream.", return);

        ComPtr<IAppxPackageReader> packageReader;
        hr = d->packageFactory->CreatePackageReader(appxStream.Get(), &packageReader);
        if (FAILED(hr)) {
            qCWarning(lcWinRtRunner).nospace() << "Failed to instantiate package reader. (0x"
                                               << QByteArray::number(hr, 16).constData()
                                               << ' ' << qt_error_string(hr) << ')';
            d->hasFatalError = true;
            return;
        }

        hr = packageReader->GetManifest(&d->manifestReader);
        if (FAILED(hr)) {
            qCWarning(lcWinRtRunner).nospace() << "Failed to query manifext reader from package";
            d->hasFatalError = true;
            return;
        }
    } else {
        if (!getManifestFile(runner->app(), &d->manifest)) {
            qCWarning(lcWinRtRunner) << "Unable to determine manifest file from" << runner->app();
            d->hasFatalError = true;
            return;
        }

        ComPtr<IStream> manifestStream;
        hr = SHCreateStreamOnFile(wchar(d->manifest), STGM_READ, &manifestStream);
        CHECK_RESULT_FATAL("Failed to open manifest stream.", return);

        hr = d->packageFactory->CreateManifestReader(manifestStream.Get(), &d->manifestReader);
        if (FAILED(hr)) {
            qCWarning(lcWinRtRunner).nospace() << "Failed to instantiate manifest reader. (0x"
                                               << QByteArray::number(hr, 16).constData()
                                               << ' ' << qt_error_string(hr) << ')';
            // ### TODO: read detailed error from event log directly
            if (hr == APPX_E_INVALID_MANIFEST) {
                qCWarning(lcWinRtRunner) << "More information on the error can "
                                            "be found in the event log under "
                                            "Microsoft\\Windows\\AppxPackagingOM";
            }
            d->hasFatalError = true;
            return;
        }
    }
    ComPtr<IAppxManifestPackageId> packageId;
    hr = d->manifestReader->GetPackageId(&packageId);
    CHECK_RESULT_FATAL("Unable to obtain the package ID from the manifest.", return);

    APPX_PACKAGE_ARCHITECTURE arch;
    hr = packageId->GetArchitecture(&arch);
    CHECK_RESULT_FATAL("Failed to retrieve the app's architecture.", return);
    d->packageArchitecture = toProcessorArchitecture(arch);

    LPWSTR packageFullName;
    hr = packageId->GetPackageFullName(&packageFullName);
    CHECK_RESULT_FATAL("Unable to obtain the package full name from the manifest.", return);
    d->packageFullName = QString::fromWCharArray(packageFullName);
    CoTaskMemFree(packageFullName);

    LPWSTR packageFamilyName;
    hr = packageId->GetPackageFamilyName(&packageFamilyName);
    CHECK_RESULT_FATAL("Unable to obtain the package full family name from the manifest.", return);
    d->packageFamilyName = QString::fromWCharArray(packageFamilyName);
    CoTaskMemFree(packageFamilyName);

    LPWSTR publisher;
    packageId->GetPublisher(&publisher);
    CHECK_RESULT_FATAL("Failed to retrieve publisher name from package.", return);
    d->publisherName = QString::fromWCharArray(publisher);
    CoTaskMemFree(publisher);

    ComPtr<IAppxManifestApplicationsEnumerator> applications;
    hr = d->manifestReader->GetApplications(&applications);
    CHECK_RESULT_FATAL("Failed to get a list of applications from the manifest.", return);

    BOOL hasCurrent;
    hr = applications->GetHasCurrent(&hasCurrent);
    CHECK_RESULT_FATAL("Failed to iterate over applications in the manifest.", return);

    // For now, we are only interested in the first application
    ComPtr<IAppxManifestApplication> application;
    hr = applications->GetCurrent(&application);
    CHECK_RESULT_FATAL("Failed to access the first application in the manifest.", return);

    LPWSTR executable;
    application->GetStringValue(L"Executable", &executable);
    CHECK_RESULT_FATAL("Failed to retrieve the application executable from the manifest.", return);
    d->executable = QFileInfo(runner->app()).absoluteDir()
            .absoluteFilePath(QString::fromWCharArray(executable));
    CoTaskMemFree(executable);

    ComPtr<IAppxManifestPackageDependenciesEnumerator> dependencies;
    hr = d->manifestReader->GetPackageDependencies(&dependencies);
    CHECK_RESULT_FATAL("Failed to retrieve the package dependencies from the manifest.", return);

    hr = dependencies->GetHasCurrent(&hasCurrent);
    CHECK_RESULT_FATAL("Failed to iterate over dependencies in the manifest.", return);
    while (SUCCEEDED(hr) && hasCurrent) {
        ComPtr<IAppxManifestPackageDependency> dependency;
        hr = dependencies->GetCurrent(&dependency);
        CHECK_RESULT_FATAL("Failed to access dependency in the manifest.", return);

        LPWSTR name;
        hr = dependency->GetName(&name);
        CHECK_RESULT_FATAL("Failed to access dependency name.", return);
        d->dependencies.insert(QString::fromWCharArray(name));
        CoTaskMemFree(name);
        hr = dependencies->MoveNext(&hasCurrent);
    }
}

AppxEngine::~AppxEngine()
{
    Q_D(const AppxEngine);
    CloseHandle(d->processHandle);
}

qint64 AppxEngine::pid() const
{
    Q_D(const AppxEngine);
    qCDebug(lcWinRtRunner) << __FUNCTION__;

    return d->pid;
}

int AppxEngine::exitCode() const
{
    Q_D(const AppxEngine);
    qCDebug(lcWinRtRunner) << __FUNCTION__;

    return d->exitCode == UINT_MAX ? -1 : HRESULT_CODE(d->exitCode);
}

QString AppxEngine::executable() const
{
    Q_D(const AppxEngine);
    qCDebug(lcWinRtRunner) << __FUNCTION__;

    return d->executable;
}

bool AppxEngine::installDependencies()
{
    Q_D(AppxEngine);
    qCDebug(lcWinRtRunner) << __FUNCTION__;

    QSet<QString> toInstall;
    for (const QString &dependencyName : qAsConst(d->dependencies)) {
        toInstall.insert(dependencyName);
        qCDebug(lcWinRtRunner).nospace()
            << "dependency to be installed: " << dependencyName;
    }

    if (toInstall.isEmpty())
        return true;

    const QString extensionSdkDir = extensionSdkPath();
    if (!QFile::exists(extensionSdkDir)) {
        qCWarning(lcWinRtRunner).nospace().noquote()
                << QStringLiteral("The directory \"%1\" does not exist.").arg(
                       QDir::toNativeSeparators(extensionSdkDir));
        return false;
    }
    qCDebug(lcWinRtRunner).nospace().noquote()
        << "looking for dependency packages in \""
        << QDir::toNativeSeparators(extensionSdkDir) << '"';
    QDirIterator dit(extensionSdkDir, QStringList() << QStringLiteral("*.appx"),
                     QDir::Files,
                     QDirIterator::Subdirectories);
    while (dit.hasNext()) {
        dit.next();

        HRESULT hr;
        ComPtr<IStream> inputStream;
        forever {
            hr = SHCreateStreamOnFileEx(wchar(dit.filePath()),
                                        STGM_READ | STGM_SHARE_EXCLUSIVE,
                                        0, FALSE, NULL, &inputStream);
            if (HRESULT_CODE(hr) == ERROR_SHARING_VIOLATION) {
                qCWarning(lcWinRtRunner).nospace()
                    << "Input stream is locked by another process. Will retry...";
                Sleep(1000);
            } else {
                break;
            }
        }
        CHECK_RESULT("Failed to create input stream for package in ExtensionSdkDir.", continue);

        ComPtr<IAppxPackageReader> packageReader;
        hr = d->packageFactory->CreatePackageReader(inputStream.Get(), &packageReader);
        CHECK_RESULT("Failed to create package reader for package in ExtensionSdkDir.", continue);

        ComPtr<IAppxManifestReader> manifestReader;
        hr = packageReader->GetManifest(&manifestReader);
        CHECK_RESULT("Failed to create manifest reader for package in ExtensionSdkDir.", continue);

        ComPtr<IAppxManifestPackageId> packageId;
        hr = manifestReader->GetPackageId(&packageId);
        CHECK_RESULT("Failed to retrieve package id for package in ExtensionSdkDir.", continue);

        LPWSTR sz;
        hr = packageId->GetName(&sz);
        CHECK_RESULT("Failed to retrieve name from package in ExtensionSdkDir.", continue);
        const QString name = QString::fromWCharArray(sz);
        CoTaskMemFree(sz);

        if (!toInstall.contains(name))
            continue;

        APPX_PACKAGE_ARCHITECTURE arch;
        hr = packageId->GetArchitecture(&arch);
        CHECK_RESULT("Failed to retrieve architecture from package in ExtensionSdkDir.", continue);
        if (d->packageArchitecture != arch)
            continue;

        qCDebug(lcWinRtRunner).nospace().noquote()
            << "installing dependency \"" << name << "\" from \""
            << QDir::toNativeSeparators(dit.filePath()) << '"';
        if (!installPackage(manifestReader.Get(), dit.filePath())) {
            qCWarning(lcWinRtRunner) << "Failed to install package:" << name;
            return false;
        }
    }

    return true;
}

bool AppxEngine::createPackage(const QString &packageFileName)
{
    Q_D(AppxEngine);

    static QHash<QString, QString> contentTypes;
    if (contentTypes.isEmpty()) {
        contentTypes.insert(QStringLiteral("dll"), QStringLiteral("application/x-msdownload"));
        contentTypes.insert(QStringLiteral("exe"), QStringLiteral("application/x-msdownload"));
        contentTypes.insert(QStringLiteral("png"), QStringLiteral("image/png"));
        contentTypes.insert(QStringLiteral("xml"), QStringLiteral("vnd.ms-appx.manifest+xml"));
    }

    // Check for package map, or create one if needed
    QDir base = QFileInfo(d->manifest).absoluteDir();
    QFile packageFile(packageFileName);

    QHash<QString, QString> files;
    QFile mappingFile(base.absoluteFilePath(QStringLiteral("AppxManifest.map")));
    if (mappingFile.exists()) {
        qCWarning(lcWinRtRunner) << "Creating package from mapping file:" << mappingFile.fileName();
        if (!mappingFile.open(QFile::ReadOnly)) {
            qCWarning(lcWinRtRunner) << "Unable to read mapping file:" << mappingFile.errorString();
            return false;
        }

        QRegExp pattern(QStringLiteral("^\"([^\"]*)\"\\s*\"([^\"]*)\"$"));
        bool inFileSection = false;
        while (!mappingFile.atEnd()) {
            const QString line = QString::fromUtf8(mappingFile.readLine()).trimmed();
            if (line.startsWith(QLatin1Char('['))) {
                inFileSection = line == QStringLiteral("[Files]");
                continue;
            }
            if (pattern.cap(2).compare(QStringLiteral("AppxManifest.xml"), Qt::CaseInsensitive) == 0)
                continue;
            if (inFileSection && pattern.indexIn(line) >= 0 && pattern.captureCount() == 2) {
                QString inputFile = pattern.cap(1);
                if (!QFile::exists(inputFile))
                    inputFile = base.absoluteFilePath(inputFile);
                files.insert(QDir::toNativeSeparators(inputFile), QDir::toNativeSeparators(pattern.cap(2)));
            }
        }
    } else {
        qCWarning(lcWinRtRunner) << "No mapping file exists. Only recognized files will be packaged.";
        // Add executable
        files.insert(QDir::toNativeSeparators(d->executable), QFileInfo(d->executable).fileName());
        // Add all files but filtered artifacts
        const QStringList excludeFileTypes = QStringList()
                << QStringLiteral("ilk") << QStringLiteral("pdb") << QStringLiteral("obj")
                << QStringLiteral("appx");

        QDirIterator dirIterator(base.absolutePath(), QDir::Files, QDirIterator::Subdirectories);
        while (dirIterator.hasNext()) {
            const QString filePath = dirIterator.next();
            if (filePath.endsWith(QLatin1String("AppxManifest.xml"), Qt::CaseInsensitive))
                continue;
            const QFileInfo fileInfo(filePath);
            if (!excludeFileTypes.contains(fileInfo.suffix()))
                files.insert(QDir::toNativeSeparators(filePath), QDir::toNativeSeparators(base.relativeFilePath(filePath)));
        }
    }

    ComPtr<IStream> outputStream;
    HRESULT hr = SHCreateStreamOnFile(wchar(packageFile.fileName()), STGM_WRITE|STGM_CREATE, &outputStream);
    RETURN_FALSE_IF_FAILED("Failed to create package file output stream");

    ComPtr<IUri> hashMethod;
    hr = CreateUri(L"http://www.w3.org/2001/04/xmlenc#sha512", Uri_CREATE_CANONICALIZE, 0, &hashMethod);
    RETURN_FALSE_IF_FAILED("Failed to create the has method URI");

    APPX_PACKAGE_SETTINGS packageSettings = { FALSE, hashMethod.Get() };
    ComPtr<IAppxPackageWriter> packageWriter;
    hr = d->packageFactory->CreatePackageWriter(outputStream.Get(), &packageSettings, &packageWriter);
    RETURN_FALSE_IF_FAILED("Failed to create package writer");

    for (QHash<QString, QString>::const_iterator i = files.begin(); i != files.end(); ++i) {
        qCDebug(lcWinRtRunner) << "Packaging" << i.key() << i.value();
        ComPtr<IStream> inputStream;
        hr = SHCreateStreamOnFile(wchar(i.key()), STGM_READ, &inputStream);
        RETURN_FALSE_IF_FAILED("Failed to open file");
        const QString contentType = contentTypes.value(QFileInfo(i.key()).suffix().toLower(),
                                                       QStringLiteral("application/octet-stream"));
        hr = packageWriter->AddPayloadFile(wchar(i.value()), wchar(contentType),
                                           APPX_COMPRESSION_OPTION_NORMAL, inputStream.Get());
        RETURN_FALSE_IF_FAILED("Failed to add payload file");
    }

    // Write out the manifest
    ComPtr<IStream> manifestStream;
    hr = SHCreateStreamOnFile(wchar(d->manifest), STGM_READ, &manifestStream);
    RETURN_FALSE_IF_FAILED("Failed to open manifest for packaging");
    hr = packageWriter->Close(manifestStream.Get());
    RETURN_FALSE_IF_FAILED("Failed to finalize package.");

    return true;
}

bool AppxEngine::sign(const QString &fileName)
{
    Q_D(const AppxEngine);
    BYTE buffer[256];
    DWORD bufferSize = 256;

    if (!CertStrToName(X509_ASN_ENCODING, wchar(d->publisherName), CERT_X500_NAME_STR, 0, buffer, &bufferSize, 0)) {
        qCWarning(lcWinRtRunner) << "CertStrToName failed";
        return false;
    }
    CERT_NAME_BLOB certBlob;
    certBlob.cbData = bufferSize;
    certBlob.pbData = buffer;

    CRYPT_ALGORITHM_IDENTIFIER identifier;
    identifier.pszObjId = strdup(szOID_RSA_SHA256RSA);
    identifier.Parameters.cbData = 0;
    identifier.Parameters.pbData = NULL;

    CERT_EXTENSIONS extensions;
    extensions.cExtension = 2;
    extensions.rgExtension = new CERT_EXTENSION[2];

    // Basic Constraints
    CERT_BASIC_CONSTRAINTS2_INFO constraintsInfo;
    constraintsInfo.fCA = FALSE;
    constraintsInfo.fPathLenConstraint = FALSE;
    constraintsInfo.dwPathLenConstraint = 0;

    BYTE *constraintsEncoded = NULL;
    DWORD encodedSize = 0;
    CryptEncodeObject(X509_ASN_ENCODING, X509_BASIC_CONSTRAINTS2, &constraintsInfo,
                      constraintsEncoded, &encodedSize);
    constraintsEncoded = new BYTE[encodedSize];
    if (!CryptEncodeObject(X509_ASN_ENCODING, X509_BASIC_CONSTRAINTS2, &constraintsInfo,
                           constraintsEncoded, &encodedSize)) {
        qCWarning(lcWinRtRunner) << "Could not encode basic constraints.";
        delete [] constraintsEncoded;
        return false;
    }

    extensions.rgExtension[0].pszObjId = strdup(szOID_BASIC_CONSTRAINTS2);
    extensions.rgExtension[0].fCritical = TRUE;
    extensions.rgExtension[0].Value.cbData = encodedSize;
    extensions.rgExtension[0].Value.pbData = constraintsEncoded;

    // Code Signing
    char *codeSign = strdup(szOID_PKIX_KP_CODE_SIGNING);
    CERT_ENHKEY_USAGE enhancedUsage;
    enhancedUsage.cUsageIdentifier = 1;
    enhancedUsage.rgpszUsageIdentifier = &codeSign;

    BYTE *enhancedKeyEncoded = 0;
    encodedSize = 0;
    CryptEncodeObject(X509_ASN_ENCODING, X509_ENHANCED_KEY_USAGE, &enhancedUsage,
                      enhancedKeyEncoded, &encodedSize);
    enhancedKeyEncoded = new BYTE[encodedSize];
    if (!CryptEncodeObject(X509_ASN_ENCODING, X509_ENHANCED_KEY_USAGE, &enhancedUsage,
                           enhancedKeyEncoded, &encodedSize)) {
        qCWarning(lcWinRtRunner) << "Could not encode enhanced key usage.";
        delete [] constraintsEncoded;
        return false;
    }

    extensions.rgExtension[1].pszObjId = strdup(szOID_ENHANCED_KEY_USAGE);
    extensions.rgExtension[1].fCritical = TRUE;
    extensions.rgExtension[1].Value.cbData = encodedSize;
    extensions.rgExtension[1].Value.pbData = enhancedKeyEncoded;

    PCCERT_CONTEXT context = CertCreateSelfSignCertificate(NULL, &certBlob, NULL, NULL,
                                                           &identifier, NULL, NULL, &extensions);

    delete [] constraintsEncoded;

    if (!context) {
        qCWarning(lcWinRtRunner) << "Failed to create self sign certificate:" << GetLastError();
        return false;
    }

    return signAppxPackage(context, wchar(fileName));
}
