/*
 * msdaps initialisation.
 *
 * Copyright 2010 Huw Davies
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */
#include <stdarg.h>
#include <string.h>

#define COBJMACROS
#define NONAMELESSUNION
#define NONAMELESSSTRUCT

#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "winerror.h"
#include "objbase.h"
#include "oleauto.h"
#define DBINITCONSTANTS
#include "oledb.h"

#include "row_server.h"

#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(oledb);

extern BOOL WINAPI msdaps_DllMain(HINSTANCE, DWORD, LPVOID) DECLSPEC_HIDDEN;
extern HRESULT WINAPI msdaps_DllGetClassObject(REFCLSID, REFIID, LPVOID *) DECLSPEC_HIDDEN;
extern HRESULT WINAPI msdaps_DllCanUnloadNow(void) DECLSPEC_HIDDEN;

/*****************************************************************************
 *              DllMain
 */
BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
{
    return msdaps_DllMain(instance, reason, reserved);
}


/******************************************************************************
 * ClassFactory
 */
typedef struct
{
    const IClassFactoryVtbl *lpVtbl;
    HRESULT (*create_object)( IUnknown*, LPVOID* );
} cf;

static HRESULT WINAPI CF_QueryInterface(IClassFactory *iface, REFIID riid, void **obj)
{
    cf *This = (cf *)iface;

    TRACE("(%p, %s, %p)\n", This, debugstr_guid(riid), obj);

    if( IsEqualCLSID( riid, &IID_IUnknown ) ||
        IsEqualCLSID( riid, &IID_IClassFactory ) )
    {
        IClassFactory_AddRef( iface );
        *obj = iface;
        return S_OK;
    }
    return E_NOINTERFACE;
}

static ULONG WINAPI CF_AddRef(IClassFactory *iface)
{
    return 2;
}

static ULONG WINAPI CF_Release(IClassFactory *iface)
{
    return 1;
}

static HRESULT WINAPI CF_CreateInstance(IClassFactory *iface, IUnknown *pOuter, REFIID riid, void **obj)
{
    cf *This = (cf *)iface;
    IUnknown *unk = NULL;
    HRESULT r;

    TRACE("(%p, %p, %s, %p)\n", This, pOuter, debugstr_guid(riid), obj);

    r = This->create_object( pOuter, (void **) &unk );
    if (SUCCEEDED(r))
    {
        r = IUnknown_QueryInterface( unk, riid, obj );
        IUnknown_Release( unk );
    }
    return r;
}

static HRESULT WINAPI CF_LockServer(IClassFactory *iface, BOOL dolock)
{
    FIXME("(%p, %d): stub\n", iface, dolock);
    return S_OK;
}

static const IClassFactoryVtbl CF_Vtbl =
{
    CF_QueryInterface,
    CF_AddRef,
    CF_Release,
    CF_CreateInstance,
    CF_LockServer
};

static cf row_server_cf = { &CF_Vtbl, create_row_server };
static cf row_proxy_cf  = { &CF_Vtbl, create_row_marshal };
static cf rowset_server_cf = { &CF_Vtbl, create_rowset_server };
static cf rowset_proxy_cf  = { &CF_Vtbl, create_rowset_marshal };

/***********************************************************************
 *              DllGetClassObject
 */
HRESULT WINAPI DllGetClassObject(REFCLSID clsid, REFIID iid, LPVOID *obj)
{
    TRACE("(%s, %s, %p)\n", debugstr_guid(clsid), debugstr_guid(iid), obj);

    if (IsEqualCLSID(clsid, &CLSID_wine_row_server))
    {
        *obj = &row_server_cf;
        return S_OK;
    }

    if (IsEqualCLSID(clsid, &CLSID_wine_row_proxy))
    {
        *obj = &row_proxy_cf;
        return S_OK;
    }

    if (IsEqualCLSID(clsid, &CLSID_wine_rowset_server))
    {
        *obj = &rowset_server_cf;
        return S_OK;
    }

    if (IsEqualCLSID(clsid, &CLSID_wine_rowset_proxy))
    {
        *obj = &rowset_proxy_cf;
        return S_OK;
    }

    return msdaps_DllGetClassObject(clsid, iid, obj);
}

/***********************************************************************
 *              DllCanUnloadNow
 */
HRESULT WINAPI DllCanUnloadNow(void)
{
    return msdaps_DllCanUnloadNow();
}
