/* OLEDB Database tests
 *
 * Copyright 2012 Alistair Leslie-Hughes
 *
 * 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 <stdio.h>

#define COBJMACROS
#define CONST_VTABLE
#define DBINITCONSTANTS

#include "windef.h"
#include "winbase.h"
#include "ole2.h"
#include "msdadc.h"
#include "msdasc.h"
#include "msdaguid.h"
#include "initguid.h"
#include "oledb.h"
#include "oledberr.h"

#include "wine/test.h"

DEFINE_GUID(CSLID_MSDAER, 0xc8b522cf,0x5cf3,0x11ce,0xad,0xe5,0x00,0xaa,0x00,0x44,0x77,0x3d);

static WCHAR initstring_default[] = {'D','a','t','a',' ','S','o','u','r','c','e','=','d','u','m','m','y',';',0};

#define EXPECT_REF(obj,ref) _expect_ref((IUnknown*)obj, ref, __LINE__)
static void _expect_ref(IUnknown* obj, ULONG ref, int line)
{
    ULONG rc = IUnknown_AddRef(obj);
    IUnknown_Release(obj);
    ok_(__FILE__,line)(rc-1 == ref, "expected refcount %d, got %d\n", ref, rc-1);
}

static void test_GetDataSource(WCHAR *initstring)
{
    IDataInitialize *datainit = NULL;
    IDBInitialize *dbinit = NULL;
    HRESULT hr;

    trace("Data Source: %s\n", wine_dbgstr_w(initstring));

    hr = CoCreateInstance(&CLSID_MSDAINITIALIZE, NULL, CLSCTX_INPROC_SERVER, &IID_IDataInitialize,(void**)&datainit);
    ok(hr == S_OK, "got %08x\n", hr);

    EXPECT_REF(datainit, 1);

    /* a failure to create data source here may indicate provider is simply not present */
    hr = IDataInitialize_GetDataSource(datainit, NULL, CLSCTX_INPROC_SERVER, initstring, &IID_IDBInitialize, (IUnknown**)&dbinit);
    if(SUCCEEDED(hr))
    {
        IDBProperties *props = NULL;

        EXPECT_REF(datainit, 1);
        EXPECT_REF(dbinit, 1);

        hr = IDBInitialize_QueryInterface(dbinit, &IID_IDBProperties, (void**)&props);
        ok(hr == S_OK, "got %08x\n", hr);
        if(SUCCEEDED(hr))
        {
            ULONG cnt;
            DBPROPINFOSET *pInfoset;
            OLECHAR *ary;

            EXPECT_REF(dbinit, 2);
            EXPECT_REF(props, 2);
            hr = IDBProperties_GetPropertyInfo(props, 0, NULL, &cnt, &pInfoset, &ary);
            todo_wine ok(hr == S_OK, "got %08x\n", hr);
            if(hr == S_OK)
            {
                ULONG i;
                for(i =0; i < pInfoset->cPropertyInfos; i++)
                {
                    trace("(0x%04x) '%s' %d\n", pInfoset->rgPropertyInfos[i].dwPropertyID, wine_dbgstr_w(pInfoset->rgPropertyInfos[i].pwszDescription),
                                             pInfoset->rgPropertyInfos[i].vtType);
                }

                CoTaskMemFree(pInfoset);
                CoTaskMemFree(ary);
            }

            IDBProperties_Release(props);
        }

        EXPECT_REF(dbinit, 1);
        IDBInitialize_Release(dbinit);
    }

    EXPECT_REF(datainit, 1);
    IDataInitialize_Release(datainit);
}

/* IDBProperties stub */
static HRESULT WINAPI dbprops_QI(IDBProperties *iface, REFIID riid, void **obj)
{
    if (IsEqualIID(riid, &IID_IDBProperties) || IsEqualIID(riid, &IID_IUnknown)) {
        *obj = iface;
        IDBProperties_AddRef(iface);
        return S_OK;
    }

    *obj = NULL;
    return E_NOINTERFACE;
}

static ULONG WINAPI dbprops_AddRef(IDBProperties *iface)
{
    return 2;
}

static ULONG WINAPI dbprops_Release(IDBProperties *iface)
{
    return 1;
}

static HRESULT WINAPI dbprops_GetProperties(IDBProperties *iface, ULONG cPropertyIDSets,
    const DBPROPIDSET rgPropertyIDSets[], ULONG *pcPropertySets, DBPROPSET **prgPropertySets)
{
    ok(0, "unexpected call\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI dbprops_GetPropertyInfo(IDBProperties *iface, ULONG cPropertyIDSets,
    const DBPROPIDSET rgPropertyIDSets[], ULONG *pcPropertyInfoSets, DBPROPINFOSET **prgPropertyInfoSets,
    OLECHAR **ppDescBuffer)
{
    ok(0, "unexpected call\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI dbprops_SetProperties(IDBProperties *iface, ULONG set_count, DBPROPSET propsets[])
{
    ok(set_count == 1, "got %u\n", set_count);

    ok(IsEqualIID(&propsets->guidPropertySet, &DBPROPSET_DBINIT), "set guid %s\n", wine_dbgstr_guid(&propsets->guidPropertySet));
    ok(propsets->cProperties == 2, "got propcount %u\n", propsets->cProperties);

if (propsets->cProperties == 2) {
    ok(propsets->rgProperties[0].dwPropertyID == DBPROP_INIT_DATASOURCE, "got propid[0] %u\n", propsets->rgProperties[0].dwPropertyID);
    ok(propsets->rgProperties[0].dwOptions == DBPROPOPTIONS_REQUIRED, "got options[0] %u\n", propsets->rgProperties[0].dwOptions);
    ok(propsets->rgProperties[0].dwStatus == 0, "got status[0] %u\n", propsets->rgProperties[0].dwStatus);
    ok(V_VT(&propsets->rgProperties[0].vValue) == VT_BSTR, "got vartype[0] %u\n", V_VT(&propsets->rgProperties[0].vValue));

    ok(propsets->rgProperties[1].dwPropertyID == DBPROP_INIT_PROVIDERSTRING, "got propid[1] %u\n", propsets->rgProperties[1].dwPropertyID);
    ok(propsets->rgProperties[1].dwOptions == DBPROPOPTIONS_REQUIRED, "got options[1] %u\n", propsets->rgProperties[1].dwOptions);
    ok(propsets->rgProperties[1].dwStatus == 0, "got status[1] %u\n", propsets->rgProperties[1].dwStatus);
    ok(V_VT(&propsets->rgProperties[1].vValue) == VT_BSTR, "got vartype[1] %u\n", V_VT(&propsets->rgProperties[1].vValue));
}
    return S_OK;
}

static const IDBPropertiesVtbl dbpropsvtbl = {
    dbprops_QI,
    dbprops_AddRef,
    dbprops_Release,
    dbprops_GetProperties,
    dbprops_GetPropertyInfo,
    dbprops_SetProperties
};

static IDBProperties dbprops = { &dbpropsvtbl };

/* IPersist stub */
static HRESULT WINAPI dbpersist_QI(IPersist *iface, REFIID riid, void **obj)
{
    if (IsEqualIID(riid, &IID_IPersist) || IsEqualIID(riid, &IID_IUnknown)) {
        *obj = iface;
        IPersist_AddRef(iface);
        return S_OK;
    }

    *obj = NULL;
    return E_NOINTERFACE;
}

static ULONG WINAPI dbpersist_AddRef(IPersist *iface)
{
    return 2;
}

static ULONG WINAPI dbpersist_Release(IPersist *iface)
{
    return 1;
}

static HRESULT WINAPI dbpersist_GetClassID(IPersist *iface, CLSID *clsid)
{
    static const WCHAR msdasqlW[] = {'M','S','D','A','S','Q','L',0};
    return CLSIDFromProgID(msdasqlW, clsid);
}

static const IPersistVtbl dbpersistvtbl = {
    dbpersist_QI,
    dbpersist_AddRef,
    dbpersist_Release,
    dbpersist_GetClassID
};

static IPersist dbpersist = { &dbpersistvtbl };

/* IDBInitialize stub */
static HRESULT WINAPI dbinit_QI(IDBInitialize *iface, REFIID riid, void **obj)
{
    if (IsEqualIID(riid, &IID_IDBInitialize) || IsEqualIID(riid, &IID_IUnknown)) {
        *obj = iface;
        IDBInitialize_AddRef(iface);
        return S_OK;
    }
    else if (IsEqualIID(riid, &IID_IPersist)) {
        *obj = &dbpersist;
        return S_OK;
    }
    else if (IsEqualIID(riid, &IID_IDBProperties)) {
        *obj = &dbprops;
        return S_OK;
    }

    *obj = NULL;
    return E_NOINTERFACE;
}

static ULONG WINAPI dbinit_AddRef(IDBInitialize *iface)
{
    return 2;
}

static ULONG WINAPI dbinit_Release(IDBInitialize *iface)
{
    return 1;
}

static HRESULT WINAPI dbinit_Initialize(IDBInitialize *iface)
{
    ok(0, "unexpected call\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI dbinit_Uninitialize(IDBInitialize *iface)
{
    ok(0, "unexpected call\n");
    return E_NOTIMPL;
}

static const IDBInitializeVtbl dbinitvtbl = {
    dbinit_QI,
    dbinit_AddRef,
    dbinit_Release,
    dbinit_Initialize,
    dbinit_Uninitialize
};

static IDBInitialize dbinittest = { &dbinitvtbl };

static void test_GetDataSource2(WCHAR *initstring)
{
    IDataInitialize *datainit = NULL;
    IDBInitialize *dbinit = NULL;
    HRESULT hr;

    hr = CoCreateInstance(&CLSID_MSDAINITIALIZE, NULL, CLSCTX_INPROC_SERVER, &IID_IDataInitialize,(void**)&datainit);
    ok(hr == S_OK, "got %08x\n", hr);

    dbinit = &dbinittest;
    hr = IDataInitialize_GetDataSource(datainit, NULL, CLSCTX_INPROC_SERVER, initstring, &IID_IDBInitialize, (IUnknown**)&dbinit);
    ok(hr == S_OK, "got %08x\n", hr);

    IDataInitialize_Release(datainit);
}

static void test_database(void)
{
    static WCHAR initstring_jet[] = {'P','r','o','v','i','d','e','r','=','M','i','c','r','o','s','o','f','t','.',
         'J','e','t','.','O','L','E','D','B','.','4','.','0',';',
         'D','a','t','a',' ','S','o','u','r','c','e','=','d','u','m','m','y',';',
         'P','e','r','s','i','s','t',' ','S','e','c','u','r','i','t','y',' ','I','n','f','o','=','F','a','l','s','e',';',0};
    static WCHAR initstring_lower[] = {'d','a','t','a',' ','s','o','u','r','c','e','=','d','u','m','m','y',';',0};
    static WCHAR customprop[] = {'d','a','t','a',' ','s','o','u','r','c','e','=','d','u','m','m','y',';',
        'c','u','s','t','o','m','p','r','o','p','=','1','2','3','.','4',';',0};
    IDataInitialize *datainit = NULL;
    HRESULT hr;

    hr = CoCreateInstance(&CLSID_MSDAINITIALIZE, NULL, CLSCTX_INPROC_SERVER, &IID_IDataInitialize, (void**)&datainit);
    if (FAILED(hr))
    {
        win_skip("Unable to load oledb library\n");
        return;
    }
    IDataInitialize_Release(datainit);

    test_GetDataSource(NULL);
    test_GetDataSource(initstring_jet);
    test_GetDataSource(initstring_default);
    test_GetDataSource(initstring_lower);
    test_GetDataSource2(customprop);
}

static void test_errorinfo(void)
{
    HRESULT hr;
    IUnknown *unk = NULL;

    hr = CoCreateInstance(&CSLID_MSDAER, NULL, CLSCTX_INPROC_SERVER, &IID_IUnknown,(void**)&unk);
    ok(hr == S_OK, "got %08x\n", hr);
    if(hr == S_OK)
    {
        IErrorInfo *errorinfo;
        IErrorRecords *errrecs;

        hr = IUnknown_QueryInterface(unk, &IID_IErrorInfo, (void**)&errorinfo);
        ok(hr == S_OK, "got %08x\n", hr);
        if(hr == S_OK)
        {
            IErrorInfo_Release(errorinfo);
        }

        hr = IUnknown_QueryInterface(unk, &IID_IErrorRecords, (void**)&errrecs);
        ok(hr == S_OK, "got %08x\n", hr);
        if(hr == S_OK)
        {
            ERRORINFO info, info2, info3;
            ULONG cnt = 0;

            memset(&info, 0, sizeof(ERRORINFO));
            info.dwMinor = 1;
            memset(&info2, 0, sizeof(ERRORINFO));
            info2.dwMinor = 2;
            memset(&info3, 0, sizeof(ERRORINFO));

            hr = IErrorRecords_AddErrorRecord(errrecs, NULL, 268435456, NULL, NULL, 0);
            ok(hr == E_INVALIDARG, "got %08x\n", hr);

            hr = IErrorRecords_AddErrorRecord(errrecs, &info, 1, NULL, NULL, 0);
            ok(hr == S_OK, "got %08x\n", hr);

            hr = IErrorRecords_GetRecordCount(errrecs, &cnt);
            ok(hr == S_OK, "got %08x\n", hr);
            ok(cnt == 1, "expected 1 got %d\n", cnt);

            hr = IErrorRecords_AddErrorRecord(errrecs, &info2, 2, NULL, NULL, 0);
            ok(hr == S_OK, "got %08x\n", hr);

            hr = IErrorRecords_GetRecordCount(errrecs, &cnt);
            ok(hr == S_OK, "got %08x\n", hr);
            ok(cnt == 2, "expected 2 got %d\n", cnt);

            hr = IErrorRecords_GetBasicErrorInfo(errrecs, 0, NULL);
            ok(hr == E_INVALIDARG, "got %08x\n", hr);

            hr = IErrorRecords_GetBasicErrorInfo(errrecs, 100, &info3);
            ok(hr == DB_E_BADRECORDNUM, "got %08x\n", hr);

            hr = IErrorRecords_GetBasicErrorInfo(errrecs, 0, &info3);
            todo_wine ok(hr == S_OK, "got %08x\n", hr);
            if(hr == S_OK)
            {
                ok(info3.dwMinor == 2, "expected 2 got %d\n", info3.dwMinor);
            }

            IErrorRecords_Release(errrecs);
        }

        IUnknown_Release(unk);
    }
}

static void test_initializationstring(void)
{
    static const WCHAR initstring_msdasql[] = {'P','r','o','v','i','d','e','r','=','M','S','D','A','S','Q','L','.','1',';',
         'D','a','t','a',' ','S','o','u','r','c','e','=','d','u','m','m','y', 0};
    static const WCHAR initstring_msdasql2[] = {'p','R','o','V','i','D','e','R','=','M','S','D','A','S','Q','L','.','1',';',
         'D','a','t','a',' ','S','o','u','r','c','e','=','d','u','m','m','y', 0};
    static const WCHAR initstring_sqloledb[] = {'P','r','o','v','i','d','e','r','=','S','Q','L','O','L','E','D','B','.','1',';',
         'D','a','t','a',' ','S','o','u','r','c','e','=','d','u','m','m','y', 0};
    IDataInitialize *datainit = NULL;
    IDBInitialize *dbinit;
    HRESULT hr;
    WCHAR *initstring = NULL;

    hr = CoCreateInstance(&CLSID_MSDAINITIALIZE, NULL, CLSCTX_INPROC_SERVER, &IID_IDataInitialize,(void**)&datainit);
    ok(hr == S_OK, "got %08x\n", hr);
    if(SUCCEEDED(hr))
    {
        EXPECT_REF(datainit, 1);

        dbinit = NULL;
        hr = IDataInitialize_GetDataSource(datainit, NULL, CLSCTX_INPROC_SERVER, initstring_default,
                                                                &IID_IDBInitialize, (IUnknown**)&dbinit);
        if(SUCCEEDED(hr))
        {
            EXPECT_REF(datainit, 1);
            EXPECT_REF(dbinit, 1);

            hr = IDataInitialize_GetInitializationString(datainit, (IUnknown*)dbinit, 0, &initstring);
            ok(hr == S_OK, "got %08x\n", hr);
            if(hr == S_OK)
            {
                trace("Init String: %s\n", wine_dbgstr_w(initstring));
                todo_wine ok(!lstrcmpW(initstring_msdasql, initstring) ||
                             !lstrcmpW(initstring_sqloledb, initstring), "got %s\n", wine_dbgstr_w(initstring));
                CoTaskMemFree(initstring);
            }

            IDBInitialize_Release(dbinit);

            /* mixed casing string */
            dbinit = NULL;
            hr = IDataInitialize_GetDataSource(datainit, NULL, CLSCTX_INPROC_SERVER, (WCHAR*)initstring_msdasql2,
                &IID_IDBInitialize, (IUnknown**)&dbinit);
            ok(hr == S_OK, "got 0x%08x\n", hr);
            IDBInitialize_Release(dbinit);
        }
        else
            ok(dbinit == NULL, "got %p\n", dbinit);

        IDataInitialize_Release(datainit);
    }
}

static void test_rowposition(void)
{
    IEnumConnectionPoints *enum_points;
    IConnectionPointContainer *cpc;
    IConnectionPoint *cp;
    IRowPosition *rowpos;
    HRESULT hr;
    IID iid;

    hr = CoCreateInstance(&CLSID_OLEDB_ROWPOSITIONLIBRARY, NULL, CLSCTX_INPROC_SERVER, &IID_IRowPosition, (void**)&rowpos);
    ok(hr == S_OK, "got %08x\n", hr);

    hr = IRowPosition_QueryInterface(rowpos, &IID_IConnectionPointContainer, (void**)&cpc);
    ok(hr == S_OK, "got 0x%08x\n", hr);

    hr = IConnectionPointContainer_EnumConnectionPoints(cpc, &enum_points);
todo_wine
    ok(hr == S_OK, "got 0x%08x\n", hr);
if (hr == S_OK) {
    hr = IEnumConnectionPoints_Next(enum_points, 1, &cp, NULL);
    ok(hr == S_OK, "got 0x%08x\n", hr);
    hr = IConnectionPoint_GetConnectionInterface(cp, &iid);
    ok(hr == S_OK, "got 0x%08x\n", hr);
    ok(IsEqualIID(&iid, &IID_IRowPositionChange), "got %s\n", wine_dbgstr_guid(&iid));
    IConnectionPoint_Release(cp);

    hr = IEnumConnectionPoints_Next(enum_points, 1, &cp, NULL);
    ok(hr == S_FALSE, "got 0x%08x\n", hr);

    IEnumConnectionPoints_Release(enum_points);
}
    IConnectionPointContainer_Release(cpc);
    IRowPosition_Release(rowpos);
}

typedef struct
{
    IRowset IRowset_iface;
    IChapteredRowset IChapteredRowset_iface;
} test_rset_t;

static test_rset_t test_rset;

static HRESULT WINAPI rset_QI(IRowset *iface, REFIID riid, void **obj)
{
    if (IsEqualIID(riid, &IID_IUnknown) ||
        IsEqualIID(riid, &IID_IRowset))
    {
        *obj = &test_rset.IRowset_iface;
        return S_OK;
    }
    else if (IsEqualIID(riid, &IID_IChapteredRowset))
    {
        *obj = &test_rset.IChapteredRowset_iface;
        return S_OK;
    }

    ok(0, "unexpected riid %s\n", wine_dbgstr_guid(riid));
    return E_NOINTERFACE;
}

static ULONG WINAPI rset_AddRef(IRowset *iface)
{
    return 2;
}

static ULONG WINAPI rset_Release(IRowset *iface)
{
    return 1;
}

static HRESULT WINAPI rset_AddRefRows(IRowset *iface, DBCOUNTITEM cRows,
    const HROW rghRows[], DBREFCOUNT rgRefCounts[], DBROWSTATUS rgRowStatus[])
{
    trace("AddRefRows: %ld\n", rghRows[0]);
    return S_OK;
}

static HRESULT WINAPI rset_GetData(IRowset *iface, HROW hRow, HACCESSOR hAccessor, void *pData)
{
    ok(0, "unexpected call\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI rset_GetNextRows(IRowset *iface, HCHAPTER hReserved, DBROWOFFSET lRowsOffset,
    DBROWCOUNT cRows, DBCOUNTITEM *pcRowObtained, HROW **prghRows)
{
    ok(0, "unexpected call\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI rset_ReleaseRows(IRowset *iface, DBCOUNTITEM cRows, const HROW rghRows[], DBROWOPTIONS rgRowOptions[],
    DBREFCOUNT rgRefCounts[], DBROWSTATUS rgRowStatus[])
{
    return S_OK;
}

static HRESULT WINAPI rset_RestartPosition(IRowset *iface, HCHAPTER hReserved)
{
    ok(0, "unexpected call\n");
    return E_NOTIMPL;
}

static const IRowsetVtbl rset_vtbl = {
    rset_QI,
    rset_AddRef,
    rset_Release,
    rset_AddRefRows,
    rset_GetData,
    rset_GetNextRows,
    rset_ReleaseRows,
    rset_RestartPosition
};

static HRESULT WINAPI chrset_QI(IChapteredRowset *iface, REFIID riid, void **obj)
{
    return IRowset_QueryInterface(&test_rset.IRowset_iface, riid, obj);
}

static ULONG WINAPI chrset_AddRef(IChapteredRowset *iface)
{
    return IRowset_AddRef(&test_rset.IRowset_iface);
}

static ULONG WINAPI chrset_Release(IChapteredRowset *iface)
{
    return IRowset_Release(&test_rset.IRowset_iface);
}

static HRESULT WINAPI chrset_AddRefChapter(IChapteredRowset *iface, HCHAPTER chapter, DBREFCOUNT *refcount)
{
    return S_OK;
}

static HRESULT WINAPI chrset_ReleaseChapter(IChapteredRowset *iface, HCHAPTER chapter, DBREFCOUNT *refcount)
{
    return S_OK;
}

static const IChapteredRowsetVtbl chrset_vtbl = {
    chrset_QI,
    chrset_AddRef,
    chrset_Release,
    chrset_AddRefChapter,
    chrset_ReleaseChapter
};

static void init_test_rset(void)
{
    test_rset.IRowset_iface.lpVtbl = &rset_vtbl;
    test_rset.IChapteredRowset_iface.lpVtbl = &chrset_vtbl;
}

static void test_rowpos_initialize(void)
{
    IRowPosition *rowpos;
    HRESULT hr;

    hr = CoCreateInstance(&CLSID_OLEDB_ROWPOSITIONLIBRARY, NULL, CLSCTX_INPROC_SERVER, &IID_IRowPosition, (void**)&rowpos);
    ok(hr == S_OK, "got %08x\n", hr);

    init_test_rset();
    hr = IRowPosition_Initialize(rowpos, (IUnknown*)&test_rset.IRowset_iface);
    ok(hr == S_OK, "got %08x\n", hr);

    IRowPosition_Release(rowpos);
}

static HRESULT WINAPI onchange_QI(IRowPositionChange *iface, REFIID riid, void **obj)
{
    if (IsEqualIID(riid, &IID_IUnknown) ||
        IsEqualIID(riid, &IID_IRowPositionChange))
    {
        *obj = iface;
        return S_OK;
    }

    return E_NOINTERFACE;
}

static ULONG WINAPI onchange_AddRef(IRowPositionChange *iface)
{
    return 2;
}

static ULONG WINAPI onchange_Release(IRowPositionChange *iface)
{
    return 1;
}

static HRESULT WINAPI onchange_OnRowPositionChange(IRowPositionChange *iface, DBREASON reason,
    DBEVENTPHASE phase, BOOL cant_deny)
{
    trace("%d %d %d\n", reason, phase, cant_deny);
    return S_OK;
}

static const IRowPositionChangeVtbl onchange_vtbl = {
    onchange_QI,
    onchange_AddRef,
    onchange_Release,
    onchange_OnRowPositionChange
};

static IRowPositionChange onchangesink = { &onchange_vtbl };

static void init_onchange_sink(IRowPosition *rowpos)
{
    IConnectionPointContainer *cpc;
    IConnectionPoint *cp;
    DWORD cookie;
    HRESULT hr;

    hr = IRowPosition_QueryInterface(rowpos, &IID_IConnectionPointContainer, (void**)&cpc);
    ok(hr == S_OK, "got %08x\n", hr);
    hr = IConnectionPointContainer_FindConnectionPoint(cpc, &IID_IRowPositionChange, &cp);
    ok(hr == S_OK, "got %08x\n", hr);
    hr = IConnectionPoint_Advise(cp, (IUnknown*)&onchangesink, &cookie);
    ok(hr == S_OK, "got %08x\n", hr);
    IConnectionPoint_Release(cp);
    IConnectionPointContainer_Release(cpc);
}

static void test_rowpos_clearrowposition(void)
{
    DBPOSITIONFLAGS flags;
    IRowPosition *rowpos;
    HCHAPTER chapter;
    IUnknown *unk;
    HRESULT hr;
    HROW row;

    hr = CoCreateInstance(&CLSID_OLEDB_ROWPOSITIONLIBRARY, NULL, CLSCTX_INPROC_SERVER, &IID_IRowPosition, (void**)&rowpos);
    ok(hr == S_OK, "got %08x\n", hr);

    hr = IRowPosition_ClearRowPosition(rowpos);
    ok(hr == E_UNEXPECTED, "got %08x\n", hr);

    hr = IRowPosition_GetRowset(rowpos, &IID_IStream, &unk);
    ok(hr == E_UNEXPECTED, "got %08x\n", hr);

    chapter = 1;
    row = 1;
    flags = DBPOSITION_OK;
    hr = IRowPosition_GetRowPosition(rowpos, &chapter, &row, &flags);
    ok(hr == E_UNEXPECTED, "got %08x\n", hr);
    ok(chapter == DB_NULL_HCHAPTER, "got %ld\n", chapter);
    ok(row == DB_NULL_HROW, "got %ld\n", row);
    ok(flags == DBPOSITION_NOROW, "got %d\n", flags);

    init_test_rset();
    hr = IRowPosition_Initialize(rowpos, (IUnknown*)&test_rset.IRowset_iface);
    ok(hr == S_OK, "got %08x\n", hr);

    chapter = 1;
    row = 1;
    flags = DBPOSITION_OK;
    hr = IRowPosition_GetRowPosition(rowpos, &chapter, &row, &flags);
    ok(hr == S_OK, "got %08x\n", hr);
    ok(chapter == DB_NULL_HCHAPTER, "got %ld\n", chapter);
    ok(row == DB_NULL_HROW, "got %ld\n", row);
    ok(flags == DBPOSITION_NOROW, "got %d\n", flags);

    hr = IRowPosition_GetRowset(rowpos, &IID_IRowset, &unk);
    ok(hr == S_OK, "got %08x\n", hr);

    init_onchange_sink(rowpos);
    hr = IRowPosition_ClearRowPosition(rowpos);
    ok(hr == S_OK, "got %08x\n", hr);

    chapter = 1;
    row = 1;
    flags = DBPOSITION_OK;
    hr = IRowPosition_GetRowPosition(rowpos, &chapter, &row, &flags);
    ok(hr == S_OK, "got %08x\n", hr);
    ok(chapter == DB_NULL_HCHAPTER, "got %ld\n", chapter);
    ok(row == DB_NULL_HROW, "got %ld\n", row);
    ok(flags == DBPOSITION_NOROW, "got %d\n", flags);

    IRowPosition_Release(rowpos);
}

static void test_rowpos_setrowposition(void)
{
    IRowPosition *rowpos;
    HRESULT hr;

    hr = CoCreateInstance(&CLSID_OLEDB_ROWPOSITIONLIBRARY, NULL, CLSCTX_INPROC_SERVER, &IID_IRowPosition, (void**)&rowpos);
    ok(hr == S_OK, "got %08x\n", hr);

    init_test_rset();
    hr = IRowPosition_Initialize(rowpos, (IUnknown*)&test_rset.IRowset_iface);
    ok(hr == S_OK, "got %08x\n", hr);

    hr = IRowPosition_ClearRowPosition(rowpos);
    ok(hr == S_OK, "got %08x\n", hr);

    init_onchange_sink(rowpos);
    hr = IRowPosition_SetRowPosition(rowpos, 0x123, 0x456, DBPOSITION_OK);
    ok(hr == S_OK, "got %08x\n", hr);

    IRowPosition_Release(rowpos);
}

static void test_dslocator(void)
{
    IDataSourceLocator *dslocator = NULL;
    HRESULT hr;

    hr = CoCreateInstance(&CLSID_DataLinks, NULL, CLSCTX_INPROC_SERVER, &IID_IDataSourceLocator,(void**)&dslocator);
    ok(hr == S_OK, "got %08x\n", hr);
    if(SUCCEEDED(hr))
    {
        COMPATIBLE_LONG hwnd = 0;

        if (0) /* Crashes under Window 7 */
            hr = IDataSourceLocator_get_hWnd(dslocator, NULL);

        hr = IDataSourceLocator_get_hWnd(dslocator, &hwnd);
        ok(hr == S_OK, "got %08x\n", hr);
        ok(hwnd == 0, "got %p\n", (HWND)hwnd);

        hwnd = 0xDEADBEEF;
        hr = IDataSourceLocator_get_hWnd(dslocator, &hwnd);
        ok(hr == S_OK, "got %08x\n", hr);
        ok(hwnd == 0, "got %p\n", (HWND)hwnd);

        hwnd = 0xDEADBEEF;
        hr = IDataSourceLocator_put_hWnd(dslocator, hwnd);
        ok(hr == S_OK, "got %08x\n", hr);

        hwnd = 0;
        hr = IDataSourceLocator_get_hWnd(dslocator, &hwnd);
        ok(hr == S_OK, "got %08x\n", hr);
        ok(hwnd == 0xDEADBEEF, "got %p\n", (HWND)hwnd);

        hwnd = 0;
        hr = IDataSourceLocator_put_hWnd(dslocator, hwnd);
        ok(hr == S_OK, "got %08x\n", hr);

        hwnd = 0xDEADBEEF;
        hr = IDataSourceLocator_get_hWnd(dslocator, &hwnd);
        ok(hr == S_OK, "got %08x\n", hr);
        ok(hwnd == 0, "got %p\n", (HWND)hwnd);

        IDataSourceLocator_Release(dslocator);
    }
}

START_TEST(database)
{
    OleInitialize(NULL);

    test_database();
    test_errorinfo();
    test_initializationstring();
    test_dslocator();

    /* row position */
    test_rowposition();
    test_rowpos_initialize();
    test_rowpos_clearrowposition();
    test_rowpos_setrowposition();

    OleUninitialize();
}
