/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the ActiveQt framework of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** 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.
**
** BSD License Usage
** Alternatively, you may use this file under the terms of the BSD license
** as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
**   * Redistributions of source code must retain the above copyright
**     notice, this list of conditions and the following disclaimer.
**   * Redistributions in binary form must reproduce the above copyright
**     notice, this list of conditions and the following disclaimer in
**     the documentation and/or other materials provided with the
**     distribution.
**   * Neither the name of The Qt Company Ltd nor the names of its
**     contributors may be used to endorse or promote products derived
**     from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qaxfactory.h"

#include <qfile.h>
#include <qfileinfo.h>
#include <qmetaobject.h>
#include <qsettings.h>
#include <qwidget.h>
#include <qt_windows.h>

QT_BEGIN_NAMESPACE

extern wchar_t qAxModuleFilename[MAX_PATH];

/*!
    \class QAxFactory
    \brief The QAxFactory class defines a factory for the creation of COM components.

    \inmodule QAxServer

    Implement this factory once in your COM server to provide information
    about the components the server can create. Subclass QAxFactory and implement
    the pure virtual functions in any implementation file (e.g. main.cpp), and export
    the factory using the \c QAXFACTORY_EXPORT() macro.

    \snippet src_activeqt_control_qaxfactory.cpp 0

    If you use the \c Q_CLASSINFO() macro to provide the unique
    identifiers or other attributes for your class you can use the \c
    QAXFACTORY_BEGIN(), \c QAXCLASS() and \c QAXFACTORY_END() macros to
    expose one or more classes as COM objects.

    \snippet src_activeqt_control_qaxfactory.cpp 1


    Only one QAxFactory implementation may be instantiated and
    exported by an ActiveX server application. This instance is accessible
    through the global qAxFactory() function.

    A factory can also reimplement the registerClass() and
    unregisterClass() functions to set additional flags for an ActiveX
    control in the registry. To limit the number of methods or
    properties a widget class exposes from its parent classes
    reimplement exposeToSuperClass().

    \sa QAxAggregated, QAxBindable, {ActiveQt Framework}
*/

/*!
    Constructs a QAxFactory object that returns \a libid and \a appid
    in the implementation of the respective interface functions.
*/

QAxFactory::QAxFactory(const QUuid &libid, const QUuid &appid)
: typelib(libid), app(appid)
{
}

/*!
    Destroys the QAxFactory object.
*/
QAxFactory::~QAxFactory() = default;

/*!
    \fn QUuid QAxFactory::typeLibID() const

    Reimplement this function to return the ActiveX server's type
    library identifier.
*/
QUuid QAxFactory::typeLibID() const
{
    return typelib;
}

/*!
    \fn QUuid QAxFactory::appID() const

    Reimplement this function to return the ActiveX server's
    application identifier.
*/
QUuid QAxFactory::appID() const
{
    return app;
}

/*!
    \fn QStringList QAxFactory::featureList() const

    Reimplement this function to return a list of the widgets (class
    names) supported by this factory.
*/

/*!
    \fn QObject *QAxFactory::createObject(const QString &key)

    Reimplement this function to return a new object for \a key, or 0 if
    this factory doesn't support the value of \a key.

    If the object returned is a QWidget it will be exposed as an ActiveX
    control, otherwise the returned object will be exposed as a simple COM
    object.
*/

/*!
    \fn const QMetaObject *QAxFactory::metaObject(const QString &key) const

    Reimplement this function to return the QMetaObject corresponding to
    \a key, or 0 if this factory doesn't support the value of \a key.
*/

/*!
    \fn bool QAxFactory::createObjectWrapper(QObject *object, IDispatch **wrapper)

    Reimplement this function to provide the COM object for \a object
    in \a wrapper. Return true if the function was successful; otherwise
    return false.

    The default implementation creates a generic automation wrapper based
    on the meta object information of \a object.
*/
// implementation in qaxserverbase.cpp

/*!
    Reimplement this function to return the class identifier for each
    \a key returned by the featureList() implementation, or an empty
    QUuid if this factory doesn't support the value of \a key.

    The default implementation interprets \a key as the class name,
    and returns the value of the Q_CLASSINFO() entry "ClassID".
*/
QUuid QAxFactory::classID(const QString &key) const
{
    const QMetaObject *mo = metaObject(key);
    if (!mo)
        return QUuid();
    QString id = QString::fromLatin1(mo->classInfo(mo->indexOfClassInfo("ClassID")).value());

    return QUuid(id);
}

/*!
    Reimplement this function to return the interface identifier for
    each \a key returned by the featureList() implementation, or an
    empty QUuid if this factory doesn't support the value of \a key.

    The default implementation interprets \a key as the class name,
    and returns the value of the Q_CLASSINFO() entry "InterfaceID".
*/
QUuid QAxFactory::interfaceID(const QString &key) const
{
    const QMetaObject *mo = metaObject(key);
    if (!mo)
        return QUuid();
    QString id = QString::fromLatin1(mo->classInfo(mo->indexOfClassInfo("InterfaceID")).value());

    return QUuid(id);
}

/*!
    Reimplement this function to return the identifier of the event
    interface for each \a key returned by the featureList()
    implementation, or an empty QUuid if this factory doesn't support
    the value of \a key.

    The default implementation interprets \a key as the class name,
    and returns the value of the Q_CLASSINFO() entry "EventsID".
*/
QUuid QAxFactory::eventsID(const QString &key) const
{
    const QMetaObject *mo = metaObject(key);
    if (!mo)
        return QUuid();
    QString id = QString::fromLatin1(mo->classInfo(mo->indexOfClassInfo("EventsID")).value());

    return QUuid(id);
}

/*!
    Registers additional values for the class \a key in the system
    registry using the \a settings object. The standard values have
    already been registered by the framework, but additional values,
    e.g. implemented categories, can be added in an implementation of
    this function.

    \snippet src_activeqt_control_qaxfactory.cpp 3

    If you reimplement this function you must also reimplement
    unregisterClass() to remove the additional registry values.

    \sa QSettings
*/
void QAxFactory::registerClass(const QString &key, QSettings *settings) const
{
    Q_UNUSED(key);
    Q_UNUSED(settings)
}

/*!
    Unregisters any additional values for the class \a key from the
    system registry using the \a settings object.

    \snippet src_activeqt_control_qaxfactory.cpp 4

    \sa registerClass(), QSettings
*/
void QAxFactory::unregisterClass(const QString &key, QSettings *settings) const
{
    Q_UNUSED(key);
    Q_UNUSED(settings)
}

/*!
    Reimplement this function to return true if \a licenseKey is a valid
    license for the class \a key, or if the current machine is licensed.

    The default implementation returns true if the class \a key is
    not licensed (ie. no \c Q_CLASSINFO() attribute "LicenseKey"), or
    if  \a licenseKey matches the value of the "LicenseKey"
    attribute, or if the machine is licensed through a .LIC file with
    the same filename as this COM server.
*/
bool QAxFactory::validateLicenseKey(const QString &key, const QString &licenseKey) const
{
    const QMetaObject *mo = metaObject(key);
    if (!mo)
        return true;

    QString classKey = QString::fromLatin1(mo->classInfo(mo->indexOfClassInfo("LicenseKey")).value());
    if (classKey.isEmpty())
        return true;

    if (licenseKey.isEmpty()) {
        QString licFile(QString::fromWCharArray(qAxModuleFilename));
        int lastDot = licFile.lastIndexOf(QLatin1Char('.'));
        licFile.truncate(lastDot);
        licFile += QLatin1String(".lic");
        return QFile::exists(licFile);
    }
    return licenseKey == classKey;
}

/*!
    Reimplement this function to return the name of the super class of
    \a key up to which methods and properties should be exposed by the
    ActiveX control.

    The default implementation interprets \a key as the class name,
    and returns the value of the \c Q_CLASSINFO() entry
    "ToSuperClass". If no such value is set the null-string is
    returned, and the functions  and properties of all the super
    classes including QWidget will be  exposed.

    To only expose the functions and properties of the class itself,
    reimplement this function to return \a key.
*/
QString QAxFactory::exposeToSuperClass(const QString &key) const
{
    const QMetaObject *mo = metaObject(key);
    if (!mo)
        return QString();
    return QString::fromLatin1(mo->classInfo(mo->indexOfClassInfo("ToSuperClass")).value());
}

/*!
    Reimplement this function to return true if the ActiveX control \a key
    should be a top level window, e.g. a dialog. The default implementation
    returns false.
*/
bool QAxFactory::stayTopLevel(const QString &key) const
{
    Q_UNUSED(key)
    return false;
}

/*!
    Reimplement this function to return true if the ActiveX control
    \a key should support the standard ActiveX events
    \list
    \li Click
    \li DblClick
    \li KeyDown
    \li KeyPress
    \li KeyUp
    \li MouseDown
    \li MouseUp
    \li MouseMove
    \endlist

    The default implementation interprets \a key as the class name,
    and returns true if the value of the \c Q_CLASSINFO() entry
    "StockEvents" is "yes". Otherwise this function returns false.
*/
bool QAxFactory::hasStockEvents(const QString &key) const
{
    const QMetaObject *mo = metaObject(key);
    if (!mo)
        return false;
    return QString::fromLatin1(mo->classInfo(mo->indexOfClassInfo("StockEvents")).value()) == QLatin1String("yes");
}


extern bool qAxIsServer;

/*!
    Returns true if the application has been started (by COM) as an ActiveX
    server, otherwise returns false.

    \snippet src_activeqt_control_qaxfactory.cpp 5
*/

bool QAxFactory::isServer()
{
    return qAxIsServer;
}

/*!
    Returns the directory that contains the server binary.

    For out-of-process servers this is the same as
    \l {QCoreApplication::applicationDirPath()}. For in-process servers
    that function returns the directory that contains the hosting
    application.
*/
QString QAxFactory::serverDirPath()
{
    return QFileInfo(QString::fromWCharArray(qAxModuleFilename)).absolutePath();
}

/*!
    Returns the file path of the server binary.

    For out-of-process servers this is the same as
    \l {QCoreApplication::applicationFilePath()}. For in-process servers
    that function returns the file path of the hosting application.
*/
QString QAxFactory::serverFilePath()
{
    return QString::fromWCharArray(qAxModuleFilename);
}

/*!
    Reimplement this function to return true if the server is
    running as a persistent service (e.g. an NT service) and should
    not terminate even when all objects provided have been released.

    The default implementation returns false.
*/
bool QAxFactory::isService() const
{
    return false;
}

/*!
    \enum QAxFactory::ServerType

    This enum specifies the different types of servers that can be
    started with startServer.

    \value SingleInstance The server process can create only one instance of each
    exported class. COM starts a new process for each request. This is typically
    used in servers that export only one creatable class.
    \value MultipleInstances The server can create multiple instances of
    each exported class. This is the default. All instances will live in the same
    thread, and will share static resources.
*/

/*!
    \fn bool QAxFactory::startServer(ServerType type);

    Starts the COM server with \a type and returns true if successful,
    otherwise returns false.

    Calling this function if the server is already running (or for an
    in-process server) does nothing and returns true.

    The server is started automatically with \a type set to \c MultipleInstances
    if the server executable has been started with the \c -activex
    command line parameter. To switch to SingleInstance, call

    \snippet src_activeqt_control_qaxfactory.cpp 6

    in your own main() entry point function.
*/

/*!
    \fn bool QAxFactory::stopServer();

    Stops the COM server and returns true if successful, otherwise
    returns false.

    Calling this function if the server is not running (or for an
    in-process server) does nothing and returns true.

    Stopping the server will not invalidate existing objects, but no
    new objects can be created from the existing server process. Usually
    COM will start a new server process if additional objects are requested.

    The server is stopped automatically when the main() function returns.
*/

class ActiveObject : public QObject
{
public:
    ActiveObject(QObject *parent, QAxFactory *factory);
    ~ActiveObject() override;

    IDispatch *wrapper;
    DWORD cookie;
};

ActiveObject::ActiveObject(QObject *parent, QAxFactory *factory)
: QObject(parent), wrapper(nullptr), cookie(0)
{
    QLatin1String key(parent->metaObject()->className());

    factory->createObjectWrapper(parent, &wrapper);
    if (wrapper)
        RegisterActiveObject(wrapper, QUuid(factory->classID(key)), ACTIVEOBJECT_STRONG, &cookie);
}

ActiveObject::~ActiveObject()
{
    if (cookie)
        RevokeActiveObject(cookie, nullptr);
    if (wrapper)
        wrapper->Release();
}

/*!
    Registers the QObject \a object with COM as a running object, and returns true if
    the registration succeeded, otherwise returns false. The object is unregistered
    automatically when it is destroyed.

    This function should only be called if the application has been started by the user
    (i.e. not by COM to respond to a request), and only for one object, usually the
    toplevel object of the application's object hierarchy.

    This function does nothing and returns false if the object's class info for
    "RegisterObject" is not set to "yes", or if the server is an in-process server.
*/
bool QAxFactory::registerActiveObject(QObject *object)
{
    if (qstricmp(object->metaObject()->classInfo(object->metaObject()->indexOfClassInfo("RegisterObject")).value(), "yes"))
        return false;

    if (!QString::fromWCharArray(qAxModuleFilename).endsWith(QLatin1String(".exe"), Qt::CaseInsensitive))
        return false;

    ActiveObject *active = new ActiveObject(object, qAxFactory());
    if (!active->wrapper || !active->cookie) {
        delete active;
        return false;
    }
    return true;
}

/*!
    \macro QAXFACTORY_DEFAULT(Class, ClassID, InterfaceID, EventID, LibID, AppID)
    \relates QAxFactory
    \deprecated

    This macro can be used to export a single QObject subclass \a Class a this
    COM server through an implicitly declared QAxFactory implementation.

    This macro exports the class \a Class as a COM coclass with the CLSID \a ClassID.
    The properties and slots will be declared through a COM interface with the IID
    \a InterfaceID, and signals will be declared through a COM event interface with
    the IID \a EventID. All declarations will be in a type library with the id \a LibID,
    and if the server is an executable server then it will have the application id
    \a AppID.

    \snippet src_activeqt_control_qaxfactory.cpp 7

    \note This class has been deprecated in favor of QAXFACTORY_BEGIN().
    \sa QAXFACTORY_EXPORT()
*/

/*!
    \macro QAXFACTORY_EXPORT(Class, LibID, AppID)
    \relates QAxFactory

    This macro can be used to export a QAxFactory implementation \a Class from
    a COM server. All declarations will be in a type library with the id \a LibID,
    and if the server is an executable server then it will have the application id
    \a AppID.

    \snippet src_activeqt_control_qaxfactory.cpp 8

    \sa QAXFACTORY_BEGIN()
*/

/*!
    \macro QAXFACTORY_BEGIN(IDTypeLib, IDApp)
    \relates QAxFactory

    This macro can be used to export multiple QObject classes through an
    implicitly declared QAxFactory implementation. All QObject classes have to
    declare the ClassID, InterfaceID and EventsID (if applicable) through the
    Q_CLASSINFO() macro. All declarations will be in a type library with the id
    \a IDTypeLib, and if the server is an executable server then it will have the
    application id \a IDApp.

    This macro needs to be used together with the QAXCLASS(), QAXTYPE()
    and QAXFACTORY_END() macros.

    \snippet src_activeqt_control_qaxfactory.cpp 9
*/

/*!
    \macro QAXCLASS(Class)
    \relates QAxFactory

    This macro adds a creatable COM class \a Class to the QAxFactory declared
    with the QAXFACTORY_BEGIN() macro.

    \sa QAXFACTORY_BEGIN(), QAXTYPE(), QAXFACTORY_END(), Q_CLASSINFO()
*/

/*!
    \macro QAXTYPE(Class)
    \relates QAxFactory

    This macro adds a non-creatable COM class \a Class to the QAxFactory
    declared with the QAXFACTORY_BEGIN(). The class \a Class can be used
    in APIs of other COM classes exported through QAXTYPE() or QAXCLASS().

    Instances of type \a Class can only be retrieved using APIs of already
    instantiated objects.

    \sa QAXFACTORY_BEGIN(), QAXCLASS(), QAXFACTORY_END(), Q_CLASSINFO()
*/

/*!
    \macro QAXFACTORY_END()
    \relates QAxFactory

    Completes the QAxFactory declaration started with the QAXFACTORY_BEGIN()
    macro.

    \sa QAXFACTORY_BEGIN(), QAXCLASS(), QAXTYPE()
*/

QT_END_NAMESPACE
