/* dxdiagn
 *
 * Copyright 2002, 2003 TransGaming Technologies
 *
 * David Hammert (david@transgaming.com)
 */

#include "windef.h"
#include "winbase.h"
#include "winreg.h"
#include "winuser.h"
#include "objbase.h"
#include "wine/debug.h"
#include "winerror.h"

#include "dxdiag.h"

#include "dxdiagn_private.h"

WINE_DEFAULT_DEBUG_CHANNEL(dxdiagn);

/* class factory definition taken from dpnet */
typedef struct
{
    /* IUnkown fields */
    ICOM_VFIELD(IClassFactory);
    DWORD ref;
    HRESULT (*pfnCreateInstance)(IUnknown *pOuter, REFIID riid,
                                 LPVOID *ppobj);
} IClassFactoryImpl;

static HRESULT WINAPI
DXDCF_QueryInterface(LPCLASSFACTORY iface, REFIID riid, LPVOID *ppobj)
{
    /*ICOM_THIS(IClassFactoryImpl, iface);*/

    FIXME("(%p)->(%s, %p): stub\n", iface, debugstr_guid(riid), ppobj);
    return E_NOINTERFACE;
}

static ULONG WINAPI DXDCF_AddRef(LPCLASSFACTORY iface)
{
    ICOM_THIS(IClassFactoryImpl,iface);
    return ++(This->ref);
}

static ULONG WINAPI DXDCF_Release(LPCLASSFACTORY iface)
{
    ICOM_THIS(IClassFactoryImpl,iface);
    /* static class, won't be  freed */
    return --(This->ref);
}

static HRESULT WINAPI
DXDCF_CreateInstance(LPCLASSFACTORY iface,
                    LPUNKNOWN pOuter,REFIID riid,LPVOID *ppobj)
{
    ICOM_THIS(IClassFactoryImpl,iface);

    TRACE("(%p)->(%p,%s,%p)\n",iface,pOuter,debugstr_guid(riid),ppobj);
    return This->pfnCreateInstance(pOuter, riid, ppobj);
}

static HRESULT WINAPI DXDCF_LockServer(LPCLASSFACTORY iface,BOOL dolock)
{
    /*ICOM_THIS(IClassFactoryImpl,iface);*/
    FIXME("(%p)->(%d),stub!\n",iface,dolock);
    return S_OK;
}

static ICOM_VTABLE(IClassFactory) DXDCF_Vtbl =
{
    ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
    DXDCF_QueryInterface,
    DXDCF_AddRef,
    DXDCF_Release,
    DXDCF_CreateInstance,
    DXDCF_LockServer
};

static IClassFactoryImpl DXDIAGN_CF_Provider = {&DXDCF_Vtbl, 1, DXDIAGN_CreateDxDiagProvider};

HRESULT WINAPI DXDIAGN_DllGetClassObject(REFCLSID rclsid, REFIID riid,
                                         LPVOID *ppv)
{
    TRACE("(%s, %s, %p\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
    if (!IsEqualGUID(riid, &IID_IClassFactory) &&
        !IsEqualGUID(riid, &IID_IUnknown))
    {
        ERR("(%s, %s, %p): no interface found.\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
        return CLASS_E_CLASSNOTAVAILABLE;
    }

    if (IsEqualGUID(rclsid, &CLSID_DxDiagProvider))
    {
        DXDCF_AddRef((IClassFactory *)&DXDIAGN_CF_Provider);
        *ppv = &DXDIAGN_CF_Provider;
        return S_OK;
    }
    ERR("(%s, %s, %p): no interface found.\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
    return CLASS_E_CLASSNOTAVAILABLE;
}

