msdasql: Support IAccessor in IRowset for Enumeration.
[wine.git] / dlls / msdasql / msdasql_main.c
blobb8d68287e6a8a88628ec7b188181a389e0cea9ca
1 /*
2 * Copyright 2019 Alistair Leslie-Hughes
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 #define COBJMACROS
21 #include <stdarg.h>
23 #include "windef.h"
24 #include "winbase.h"
25 #include "objbase.h"
26 #include "oledb.h"
27 #include "rpcproxy.h"
28 #include "wine/debug.h"
29 #include "oledberr.h"
31 #include "initguid.h"
32 #include "msdasql.h"
34 #include "msdasql_private.h"
36 WINE_DEFAULT_DEBUG_CHANNEL(msdasql);
38 DEFINE_GUID(DBPROPSET_DBINIT, 0xc8b522bc, 0x5cf3, 0x11ce, 0xad, 0xe5, 0x00, 0xaa, 0x00, 0x44, 0x77, 0x3d);
40 DEFINE_GUID(DBGUID_DEFAULT, 0xc8b521fb, 0x5cf3, 0x11ce, 0xad, 0xe5, 0x00, 0xaa, 0x00, 0x44, 0x77, 0x3d);
42 static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv)
44 *ppv = NULL;
46 if(IsEqualGUID(&IID_IUnknown, riid)) {
47 TRACE("(%p)->(IID_IUnknown %p)\n", iface, ppv);
48 *ppv = iface;
49 }else if(IsEqualGUID(&IID_IClassFactory, riid)) {
50 TRACE("(%p)->(IID_IClassFactory %p)\n", iface, ppv);
51 *ppv = iface;
54 if(*ppv) {
55 IUnknown_AddRef((IUnknown*)*ppv);
56 return S_OK;
59 WARN("(%p)->(%s %p)\n", iface, debugstr_guid(riid), ppv);
60 return E_NOINTERFACE;
63 static ULONG WINAPI ClassFactory_AddRef(IClassFactory *iface)
65 TRACE("(%p)\n", iface);
66 return 2;
69 static ULONG WINAPI ClassFactory_Release(IClassFactory *iface)
71 TRACE("(%p)\n", iface);
72 return 1;
75 static HRESULT create_msdasql_provider(REFIID riid, void **ppv);
76 static HRESULT create_msdasql_enumerator(REFIID riid, void **ppv);
78 HRESULT WINAPI msdasql_CreateInstance(IClassFactory *iface, IUnknown *outer, REFIID riid, void **ppv)
80 TRACE("(%p %s %p)\n", outer, debugstr_guid(riid), ppv);
82 return create_msdasql_provider(riid, ppv);
85 static HRESULT WINAPI ClassFactory_LockServer(IClassFactory *iface, BOOL fLock)
87 TRACE("(%p)->(%x)\n", iface, fLock);
88 return S_OK;
91 static const IClassFactoryVtbl cfmsdasqlVtbl = {
92 ClassFactory_QueryInterface,
93 ClassFactory_AddRef,
94 ClassFactory_Release,
95 msdasql_CreateInstance,
96 ClassFactory_LockServer
99 HRESULT WINAPI enumerationcf_CreateInstance(IClassFactory *iface, IUnknown *outer, REFIID riid, void **ppv)
101 TRACE("(%p %s %p)\n", outer, debugstr_guid(riid), ppv);
103 return create_msdasql_enumerator(riid, ppv);
106 static const IClassFactoryVtbl enumfactoryVtbl =
108 ClassFactory_QueryInterface,
109 ClassFactory_AddRef,
110 ClassFactory_Release,
111 enumerationcf_CreateInstance,
112 ClassFactory_LockServer
115 static IClassFactory cfmsdasql = { &cfmsdasqlVtbl };
116 static IClassFactory enumfactory = { &enumfactoryVtbl };
118 HRESULT WINAPI DllGetClassObject( REFCLSID rclsid, REFIID riid, void **ppv )
120 TRACE("%s %s %p\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
122 if (IsEqualGUID(&CLSID_MSDASQL, rclsid))
123 return IClassFactory_QueryInterface(&cfmsdasql, riid, ppv);
124 else if (IsEqualGUID(&CLSID_MSDASQL_ENUMERATOR, rclsid))
125 return IClassFactory_QueryInterface(&enumfactory, riid, ppv);
127 return CLASS_E_CLASSNOTAVAILABLE;
130 struct dbproperty
132 const WCHAR *name;
133 DBPROPID id;
134 DBPROPOPTIONS options;
135 VARTYPE type;
136 HRESULT (*convert_dbproperty)(const WCHAR *src, VARIANT *dest);
139 struct mode_propval
141 const WCHAR *name;
142 DWORD value;
145 static int __cdecl dbmodeprop_compare(const void *a, const void *b)
147 const WCHAR *src = a;
148 const struct mode_propval *propval = b;
149 return wcsicmp(src, propval->name);
152 static HRESULT convert_dbproperty_mode(const WCHAR *src, VARIANT *dest)
154 struct mode_propval mode_propvals[] =
156 { L"Read", DB_MODE_READ },
157 { L"ReadWrite", DB_MODE_READWRITE },
158 { L"Share Deny None", DB_MODE_SHARE_DENY_NONE },
159 { L"Share Deny Read", DB_MODE_SHARE_DENY_READ },
160 { L"Share Deny Write", DB_MODE_SHARE_DENY_WRITE },
161 { L"Share Exclusive", DB_MODE_SHARE_EXCLUSIVE },
162 { L"Write", DB_MODE_WRITE },
164 struct mode_propval *prop;
166 if ((prop = bsearch(src, mode_propvals, ARRAY_SIZE(mode_propvals),
167 sizeof(struct mode_propval), dbmodeprop_compare)))
169 V_VT(dest) = VT_I4;
170 V_I4(dest) = prop->value;
171 TRACE("%s = %#x\n", debugstr_w(src), prop->value);
172 return S_OK;
175 return E_FAIL;
178 static const struct dbproperty dbproperties[] =
180 { L"Password", DBPROP_AUTH_PASSWORD, DBPROPOPTIONS_OPTIONAL, VT_BSTR },
181 { L"Persist Security Info", DBPROP_AUTH_PERSIST_SENSITIVE_AUTHINFO, DBPROPOPTIONS_OPTIONAL, VT_BOOL },
182 { L"User ID", DBPROP_AUTH_USERID, DBPROPOPTIONS_OPTIONAL, VT_BSTR },
183 { L"Data Source", DBPROP_INIT_DATASOURCE, DBPROPOPTIONS_REQUIRED, VT_BSTR },
184 { L"Window Handle", DBPROP_INIT_HWND, DBPROPOPTIONS_OPTIONAL, sizeof(void *) == 8 ? VT_I8 : VT_I4 },
185 { L"Location", DBPROP_INIT_LOCATION, DBPROPOPTIONS_OPTIONAL, VT_BSTR },
186 { L"Mode", DBPROP_INIT_MODE, DBPROPOPTIONS_OPTIONAL, VT_I4, convert_dbproperty_mode },
187 { L"Prompt", DBPROP_INIT_PROMPT, DBPROPOPTIONS_OPTIONAL, VT_I2 },
188 { L"Connect Timeout", DBPROP_INIT_TIMEOUT, DBPROPOPTIONS_OPTIONAL, VT_I4 },
189 { L"Extended Properties", DBPROP_INIT_PROVIDERSTRING, DBPROPOPTIONS_REQUIRED, VT_BSTR },
190 { L"Locale Identifier", DBPROP_INIT_LCID, DBPROPOPTIONS_OPTIONAL, VT_I4 },
191 { L"Initial Catalog", DBPROP_INIT_CATALOG, DBPROPOPTIONS_OPTIONAL, VT_BSTR },
192 { L"OLE DB Services", DBPROP_INIT_OLEDBSERVICES, DBPROPOPTIONS_OPTIONAL, VT_I4 },
193 { L"General Timeout", DBPROP_INIT_GENERALTIMEOUT, DBPROPOPTIONS_OPTIONAL, VT_I4 },
196 struct msdasql
198 IUnknown MSDASQL_iface;
199 IDBProperties IDBProperties_iface;
200 IDBInitialize IDBInitialize_iface;
201 IDBCreateSession IDBCreateSession_iface;
202 IPersist IPersist_iface;
204 LONG ref;
207 static inline struct msdasql *impl_from_IUnknown(IUnknown *iface)
209 return CONTAINING_RECORD(iface, struct msdasql, MSDASQL_iface);
212 static inline struct msdasql *impl_from_IDBProperties(IDBProperties *iface)
214 return CONTAINING_RECORD(iface, struct msdasql, IDBProperties_iface);
217 static inline struct msdasql *impl_from_IDBInitialize(IDBInitialize *iface)
219 return CONTAINING_RECORD(iface, struct msdasql, IDBInitialize_iface);
222 static inline struct msdasql *impl_from_IDBCreateSession(IDBCreateSession *iface)
224 return CONTAINING_RECORD(iface, struct msdasql, IDBCreateSession_iface);
227 static inline struct msdasql *impl_from_IPersist( IPersist *iface )
229 return CONTAINING_RECORD( iface, struct msdasql, IPersist_iface );
232 static HRESULT WINAPI msdsql_QueryInterface(IUnknown *iface, REFIID riid, void **out)
234 struct msdasql *provider = impl_from_IUnknown(iface);
236 TRACE("(%p)->(%s %p)\n", provider, debugstr_guid(riid), out);
238 if(IsEqualGUID(riid, &IID_IUnknown) ||
239 IsEqualGUID(riid, &CLSID_MSDASQL))
241 *out = &provider->MSDASQL_iface;
243 else if(IsEqualGUID(riid, &IID_IDBProperties))
245 *out = &provider->IDBProperties_iface;
247 else if ( IsEqualGUID(riid, &IID_IDBInitialize))
249 *out = &provider->IDBInitialize_iface;
251 else if (IsEqualGUID(riid, &IID_IDBCreateSession))
253 *out = &provider->IDBCreateSession_iface;
255 else if(IsEqualGUID(&IID_IPersist, riid))
257 *out = &provider->IPersist_iface;
259 else
261 FIXME("(%s, %p)\n", debugstr_guid(riid), out);
262 *out = NULL;
263 return E_NOINTERFACE;
266 IUnknown_AddRef((IUnknown*)*out);
267 return S_OK;
270 static ULONG WINAPI msdsql_AddRef(IUnknown *iface)
272 struct msdasql *provider = impl_from_IUnknown(iface);
273 ULONG ref = InterlockedIncrement(&provider->ref);
275 TRACE("(%p) ref=%u\n", provider, ref);
277 return ref;
280 static ULONG WINAPI msdsql_Release(IUnknown *iface)
282 struct msdasql *provider = impl_from_IUnknown(iface);
283 ULONG ref = InterlockedDecrement(&provider->ref);
285 TRACE("(%p) ref=%u\n", provider, ref);
287 if (!ref)
289 free(provider);
292 return ref;
295 static const IUnknownVtbl msdsql_vtbl =
297 msdsql_QueryInterface,
298 msdsql_AddRef,
299 msdsql_Release
302 static HRESULT WINAPI dbprops_QueryInterface(IDBProperties *iface, REFIID riid, void **ppvObject)
304 struct msdasql *provider = impl_from_IDBProperties(iface);
306 return IUnknown_QueryInterface(&provider->MSDASQL_iface, riid, ppvObject);
309 static ULONG WINAPI dbprops_AddRef(IDBProperties *iface)
311 struct msdasql *provider = impl_from_IDBProperties(iface);
313 return IUnknown_AddRef(&provider->MSDASQL_iface);
316 static ULONG WINAPI dbprops_Release(IDBProperties *iface)
318 struct msdasql *provider = impl_from_IDBProperties(iface);
320 return IUnknown_Release(&provider->MSDASQL_iface);
323 static HRESULT WINAPI dbprops_GetProperties(IDBProperties *iface, ULONG cPropertyIDSets,
324 const DBPROPIDSET rgPropertyIDSets[], ULONG *pcPropertySets, DBPROPSET **prgPropertySets)
326 struct msdasql *provider = impl_from_IDBProperties(iface);
328 FIXME("(%p)->(%d %p %p %p)\n", provider, cPropertyIDSets, rgPropertyIDSets, pcPropertySets, prgPropertySets);
330 return E_NOTIMPL;
333 static HRESULT WINAPI dbprops_GetPropertyInfo(IDBProperties *iface, ULONG cPropertyIDSets,
334 const DBPROPIDSET rgPropertyIDSets[], ULONG *pcPropertyInfoSets,
335 DBPROPINFOSET **prgPropertyInfoSets, OLECHAR **ppDescBuffer)
337 struct msdasql *provider = impl_from_IDBProperties(iface);
338 int i;
339 DBPROPINFOSET *infoset;
340 int size = 1;
341 OLECHAR *ptr;
343 TRACE("(%p)->(%d %p %p %p %p)\n", provider, cPropertyIDSets, rgPropertyIDSets, pcPropertyInfoSets,
344 prgPropertyInfoSets, ppDescBuffer);
346 infoset = CoTaskMemAlloc(sizeof(DBPROPINFOSET));
347 memcpy(&infoset->guidPropertySet, &DBPROPSET_DBINIT, sizeof(GUID));
348 infoset->cPropertyInfos = ARRAY_SIZE(dbproperties);
349 infoset->rgPropertyInfos = CoTaskMemAlloc(sizeof(DBPROPINFO) * ARRAY_SIZE(dbproperties));
351 for(i=0; i < ARRAY_SIZE(dbproperties); i++)
353 size += lstrlenW(dbproperties[i].name) + 1;
356 ptr = *ppDescBuffer = CoTaskMemAlloc(size * sizeof(WCHAR));
357 memset(*ppDescBuffer, 0, size * sizeof(WCHAR));
359 for(i=0; i < ARRAY_SIZE(dbproperties); i++)
361 lstrcpyW(ptr, dbproperties[i].name);
362 infoset->rgPropertyInfos[i].pwszDescription = ptr;
363 infoset->rgPropertyInfos[i].dwPropertyID = dbproperties[i].id;
364 infoset->rgPropertyInfos[i].dwFlags = DBPROPFLAGS_DBINIT | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE;
365 infoset->rgPropertyInfos[i].vtType = dbproperties[i].type;
366 V_VT(&infoset->rgPropertyInfos[i].vValues) = VT_EMPTY;
368 ptr += lstrlenW(dbproperties[i].name) + 1;
371 *pcPropertyInfoSets = 1;
372 *prgPropertyInfoSets = infoset;
374 return S_OK;
377 static HRESULT WINAPI dbprops_SetProperties(IDBProperties *iface, ULONG cPropertySets,
378 DBPROPSET rgPropertySets[])
380 struct msdasql *provider = impl_from_IDBProperties(iface);
382 FIXME("(%p)->(%d %p)\n", provider, cPropertySets, rgPropertySets);
384 return E_NOTIMPL;
387 static const struct IDBPropertiesVtbl dbprops_vtbl =
389 dbprops_QueryInterface,
390 dbprops_AddRef,
391 dbprops_Release,
392 dbprops_GetProperties,
393 dbprops_GetPropertyInfo,
394 dbprops_SetProperties
397 static HRESULT WINAPI dbinit_QueryInterface(IDBInitialize *iface, REFIID riid, void **ppvObject)
399 struct msdasql *provider = impl_from_IDBInitialize(iface);
401 return IUnknown_QueryInterface(&provider->MSDASQL_iface, riid, ppvObject);
404 static ULONG WINAPI dbinit_AddRef(IDBInitialize *iface)
406 struct msdasql *provider = impl_from_IDBInitialize(iface);
408 return IUnknown_AddRef(&provider->MSDASQL_iface);
411 static ULONG WINAPI dbinit_Release(IDBInitialize *iface)
413 struct msdasql *provider = impl_from_IDBInitialize(iface);
415 return IUnknown_Release(&provider->MSDASQL_iface);
418 static HRESULT WINAPI dbinit_Initialize(IDBInitialize *iface)
420 struct msdasql *provider = impl_from_IDBInitialize(iface);
422 FIXME("%p stub\n", provider);
424 return S_OK;
427 static HRESULT WINAPI dbinit_Uninitialize(IDBInitialize *iface)
429 struct msdasql *provider = impl_from_IDBInitialize(iface);
431 FIXME("%p stub\n", provider);
433 return S_OK;
437 static const struct IDBInitializeVtbl dbinit_vtbl =
439 dbinit_QueryInterface,
440 dbinit_AddRef,
441 dbinit_Release,
442 dbinit_Initialize,
443 dbinit_Uninitialize
446 static HRESULT WINAPI dbsess_QueryInterface(IDBCreateSession *iface, REFIID riid, void **ppvObject)
448 struct msdasql *provider = impl_from_IDBCreateSession(iface);
450 return IUnknown_QueryInterface(&provider->MSDASQL_iface, riid, ppvObject);
453 static ULONG WINAPI dbsess_AddRef(IDBCreateSession *iface)
455 struct msdasql *provider = impl_from_IDBCreateSession(iface);
457 return IUnknown_AddRef(&provider->MSDASQL_iface);
460 static ULONG WINAPI dbsess_Release(IDBCreateSession *iface)
462 struct msdasql *provider = impl_from_IDBCreateSession(iface);
464 return IUnknown_Release(&provider->MSDASQL_iface);
467 static HRESULT WINAPI dbsess_CreateSession(IDBCreateSession *iface, IUnknown *outer, REFIID riid,
468 IUnknown **session)
470 struct msdasql *provider = impl_from_IDBCreateSession(iface);
471 HRESULT hr;
473 TRACE("%p, outer %p, riid %s, session %p stub\n", provider, outer, debugstr_guid(riid), session);
475 if (outer)
476 FIXME("outer currently not supported.\n");
478 hr = create_db_session(riid, (void**)session);
480 return hr;
483 static const struct IDBCreateSessionVtbl dbsess_vtbl =
485 dbsess_QueryInterface,
486 dbsess_AddRef,
487 dbsess_Release,
488 dbsess_CreateSession
491 static HRESULT WINAPI persist_QueryInterface(IPersist *iface, REFIID riid, void **ppv)
493 struct msdasql *provider = impl_from_IPersist( iface );
494 return IUnknown_QueryInterface(&provider->MSDASQL_iface, riid, ppv);
497 static ULONG WINAPI persist_AddRef(IPersist *iface)
499 struct msdasql *provider = impl_from_IPersist( iface );
500 return IUnknown_AddRef(&provider->MSDASQL_iface);
503 static ULONG WINAPI persist_Release(IPersist *iface)
505 struct msdasql *provider = impl_from_IPersist( iface );
506 return IUnknown_Release(&provider->MSDASQL_iface);
509 static HRESULT WINAPI persist_GetClassID(IPersist *iface, CLSID *classid)
511 struct msdasql *provider = impl_from_IPersist( iface );
513 TRACE("(%p)->(%p)\n", provider, classid);
515 if(!classid)
516 return E_INVALIDARG;
518 *classid = CLSID_MSDASQL;
519 return S_OK;
523 static const IPersistVtbl persistVtbl = {
524 persist_QueryInterface,
525 persist_AddRef,
526 persist_Release,
527 persist_GetClassID
530 static HRESULT create_msdasql_provider(REFIID riid, void **ppv)
532 struct msdasql *provider;
533 HRESULT hr;
535 provider = malloc(sizeof(struct msdasql));
536 if (!provider)
537 return E_OUTOFMEMORY;
539 provider->MSDASQL_iface.lpVtbl = &msdsql_vtbl;
540 provider->IDBProperties_iface.lpVtbl = &dbprops_vtbl;
541 provider->IDBInitialize_iface.lpVtbl = &dbinit_vtbl;
542 provider->IDBCreateSession_iface.lpVtbl = &dbsess_vtbl;
543 provider->IPersist_iface.lpVtbl = &persistVtbl;
544 provider->ref = 1;
546 hr = IUnknown_QueryInterface(&provider->MSDASQL_iface, riid, ppv);
547 IUnknown_Release(&provider->MSDASQL_iface);
548 return hr;
551 struct msdasql_enum
553 ISourcesRowset ISourcesRowset_iface;
554 LONG ref;
557 static inline struct msdasql_enum *msdasql_enum_from_ISourcesRowset(ISourcesRowset *iface)
559 return CONTAINING_RECORD(iface, struct msdasql_enum, ISourcesRowset_iface);
562 static HRESULT WINAPI msdasql_enum_QueryInterface(ISourcesRowset *iface, REFIID riid, void **out)
564 struct msdasql_enum *enumerator = msdasql_enum_from_ISourcesRowset(iface);
566 TRACE("(%p)->(%s %p)\n", enumerator, debugstr_guid(riid), out);
568 if(IsEqualGUID(riid, &IID_IUnknown) ||
569 IsEqualGUID(riid, &IID_ISourcesRowset ) )
571 *out = &enumerator->ISourcesRowset_iface;
573 else
575 FIXME("(%s, %p)\n", debugstr_guid(riid), out);
576 *out = NULL;
577 return E_NOINTERFACE;
580 IUnknown_AddRef((IUnknown*)*out);
581 return S_OK;
584 static ULONG WINAPI msdasql_enum_AddRef(ISourcesRowset *iface)
586 struct msdasql_enum *enumerator = msdasql_enum_from_ISourcesRowset(iface);
587 ULONG ref = InterlockedIncrement(&enumerator->ref);
589 TRACE("(%p) ref=%u\n", enumerator, ref);
591 return ref;
594 static ULONG WINAPI msdasql_enum_Release(ISourcesRowset *iface)
596 struct msdasql_enum *enumerator = msdasql_enum_from_ISourcesRowset(iface);
597 ULONG ref = InterlockedDecrement(&enumerator->ref);
599 TRACE("(%p) ref=%u\n", enumerator, ref);
601 if (!ref)
603 free(enumerator);
606 return ref;
609 struct msdasql_enum_rowset
611 IRowset IRowset_iface;
612 IAccessor IAccessor_iface;
613 LONG ref;
616 static inline struct msdasql_enum_rowset *msdasql_rs_from_IRowset(IRowset *iface)
618 return CONTAINING_RECORD(iface, struct msdasql_enum_rowset, IRowset_iface);
621 static inline struct msdasql_enum_rowset *msdasql_enum_from_IAccessor ( IAccessor *iface )
623 return CONTAINING_RECORD( iface, struct msdasql_enum_rowset, IAccessor_iface );
626 static HRESULT WINAPI enum_rowset_QueryInterface(IRowset *iface, REFIID riid, void **ppv)
628 struct msdasql_enum_rowset *rowset = msdasql_rs_from_IRowset( iface );
630 TRACE( "%p, %s, %p\n", rowset, debugstr_guid(riid), ppv );
631 *ppv = NULL;
633 if(IsEqualGUID(&IID_IUnknown, riid) ||
634 IsEqualGUID(&IID_IRowset, riid))
636 *ppv = &rowset->IRowset_iface;
638 else if(IsEqualGUID(&IID_IAccessor, riid))
640 *ppv = &rowset->IAccessor_iface;
643 if(*ppv)
645 IUnknown_AddRef((IUnknown*)*ppv);
646 return S_OK;
649 FIXME("(%p)->(%s %p)\n", iface, debugstr_guid(riid), ppv);
650 return E_NOINTERFACE;
653 static ULONG WINAPI enum_rowset_AddRef(IRowset *iface)
655 struct msdasql_enum_rowset *rowset = msdasql_rs_from_IRowset( iface );
656 LONG refs = InterlockedIncrement( &rowset->ref );
657 TRACE( "%p new refcount %d\n", rowset, refs );
658 return refs;
661 static ULONG WINAPI enum_rowset_Release(IRowset *iface)
663 struct msdasql_enum_rowset *rowset = msdasql_rs_from_IRowset( iface );
664 LONG refs = InterlockedDecrement( &rowset->ref );
665 TRACE( "%p new refcount %d\n", rowset, refs );
666 if (!refs)
668 TRACE( "destroying %p\n", rowset );
669 free( rowset );
671 return refs;
674 static HRESULT WINAPI enum_rowset_AddRefRows(IRowset *iface, DBCOUNTITEM count,
675 const HROW rows[], DBREFCOUNT ref_counts[], DBROWSTATUS status[])
677 struct msdasql_enum_rowset *rowset = msdasql_rs_from_IRowset( iface );
679 FIXME("%p, %ld, %p, %p, %p\n", rowset, count, rows, ref_counts, status);
681 return E_NOTIMPL;
684 static HRESULT WINAPI enum_rowset_GetData(IRowset *iface, HROW row, HACCESSOR accessor, void *data)
686 struct msdasql_enum_rowset *rowset = msdasql_rs_from_IRowset( iface );
688 FIXME("%p, %ld, %ld, %p\n", rowset, row, accessor, data);
690 return E_NOTIMPL;
693 static HRESULT WINAPI enum_rowset_GetNextRows(IRowset *iface, HCHAPTER reserved, DBROWOFFSET offset,
694 DBROWCOUNT count, DBCOUNTITEM *obtained, HROW **rows)
696 struct msdasql_enum_rowset *rowset = msdasql_rs_from_IRowset( iface );
698 FIXME("%p, %ld, %ld, %ld, %p, %p\n", rowset, reserved, offset, count, obtained, rows);
700 if (!obtained || !rows)
701 return E_INVALIDARG;
703 *obtained = 0;
705 if (!count)
706 return S_OK;
708 return DB_S_ENDOFROWSET;
711 static HRESULT WINAPI enum_rowset_ReleaseRows(IRowset *iface, DBCOUNTITEM count,
712 const HROW rows[], DBROWOPTIONS options[], DBREFCOUNT ref_counts[], DBROWSTATUS status[])
714 struct msdasql_enum_rowset *rowset = msdasql_rs_from_IRowset( iface );
716 FIXME("%p, %ld, %p, %p, %p, %p\n", rowset, count, rows, options, ref_counts, status);
718 return S_OK;
721 static HRESULT WINAPI enum_rowset_RestartPosition(IRowset *iface, HCHAPTER reserved)
723 struct msdasql_enum_rowset *rowset = msdasql_rs_from_IRowset( iface );
725 FIXME("%p, %ld\n", rowset, reserved);
727 return S_OK;
730 static const struct IRowsetVtbl enum_rowset_vtbl =
732 enum_rowset_QueryInterface,
733 enum_rowset_AddRef,
734 enum_rowset_Release,
735 enum_rowset_AddRefRows,
736 enum_rowset_GetData,
737 enum_rowset_GetNextRows,
738 enum_rowset_ReleaseRows,
739 enum_rowset_RestartPosition
742 static HRESULT WINAPI enum_rs_accessor_QueryInterface(IAccessor *iface, REFIID riid, void **out)
744 struct msdasql_enum_rowset *rowset = msdasql_enum_from_IAccessor( iface );
745 return IRowset_QueryInterface(&rowset->IRowset_iface, riid, out);
748 static ULONG WINAPI enum_rs_accessor_AddRef(IAccessor *iface)
750 struct msdasql_enum_rowset *rowset = msdasql_enum_from_IAccessor( iface );
751 return IRowset_AddRef(&rowset->IRowset_iface);
754 static ULONG WINAPI enum_rs_accessor_Release(IAccessor *iface)
756 struct msdasql_enum_rowset *rowset = msdasql_enum_from_IAccessor( iface );
757 return IRowset_Release(&rowset->IRowset_iface);
760 static HRESULT WINAPI enum_rs_accessor_AddRefAccessor(IAccessor *iface, HACCESSOR accessor, DBREFCOUNT *count)
762 struct msdasql_enum_rowset *rowset = msdasql_enum_from_IAccessor( iface );
763 FIXME("%p, %lu, %p\n", rowset, accessor, count);
764 return E_NOTIMPL;
767 static HRESULT WINAPI enum_rs_accessor_CreateAccessor(IAccessor *iface, DBACCESSORFLAGS flags,
768 DBCOUNTITEM count, const DBBINDING bindings[], DBLENGTH row_size, HACCESSOR *accessor,
769 DBBINDSTATUS status[])
771 struct msdasql_enum_rowset *rowset = msdasql_enum_from_IAccessor( iface );
773 FIXME("%p 0x%08x, %lu, %p, %lu, %p, %p\n", rowset, flags, count, bindings, row_size, accessor, status);
775 if (accessor)
776 *accessor = 0xdeadbeef;
778 return S_OK;
781 static HRESULT WINAPI enum_rs_accessor_GetBindings(IAccessor *iface, HACCESSOR accessor,
782 DBACCESSORFLAGS *flags, DBCOUNTITEM *count, DBBINDING **bindings)
784 struct msdasql_enum_rowset *rowset = msdasql_enum_from_IAccessor( iface );
785 FIXME("%p %lu, %p, %p, %p\n", rowset, accessor, flags, count, bindings);
786 return E_NOTIMPL;
789 static HRESULT WINAPI enum_rs_accessor_ReleaseAccessor(IAccessor *iface, HACCESSOR accessor, DBREFCOUNT *count)
791 struct msdasql_enum_rowset *rowset = msdasql_enum_from_IAccessor( iface );
793 FIXME("%p, %lu, %p\n", rowset, accessor, count);
795 if (count)
796 *count = 0;
798 return S_OK;
801 struct IAccessorVtbl enum_accessor_vtbl =
803 enum_rs_accessor_QueryInterface,
804 enum_rs_accessor_AddRef,
805 enum_rs_accessor_Release,
806 enum_rs_accessor_AddRefAccessor,
807 enum_rs_accessor_CreateAccessor,
808 enum_rs_accessor_GetBindings,
809 enum_rs_accessor_ReleaseAccessor
812 static HRESULT WINAPI msdasql_enum_GetSourcesRowset(ISourcesRowset *iface, IUnknown *outer, REFIID riid, ULONG sets,
813 DBPROPSET properties[], IUnknown **rowset)
815 struct msdasql_enum *enumerator = msdasql_enum_from_ISourcesRowset(iface);
816 struct msdasql_enum_rowset *enum_rs;
817 HRESULT hr;
819 TRACE("(%p) %p, %s, %d, %p, %p\n", enumerator, outer, debugstr_guid(riid), sets, properties, rowset);
821 enum_rs = malloc(sizeof(*enum_rs));
822 enum_rs->IRowset_iface.lpVtbl = &enum_rowset_vtbl;
823 enum_rs->IAccessor_iface.lpVtbl = &enum_accessor_vtbl;
824 enum_rs->ref = 1;
826 hr = IRowset_QueryInterface(&enum_rs->IRowset_iface, riid, (void**)rowset);
827 IRowset_Release(&enum_rs->IRowset_iface);
828 return hr;
831 static const ISourcesRowsetVtbl msdsqlenum_vtbl =
833 msdasql_enum_QueryInterface,
834 msdasql_enum_AddRef,
835 msdasql_enum_Release,
836 msdasql_enum_GetSourcesRowset
839 static HRESULT create_msdasql_enumerator(REFIID riid, void **ppv)
841 struct msdasql_enum *enumerator;
842 HRESULT hr;
844 enumerator = malloc(sizeof(*enumerator));
845 if (!enumerator)
846 return E_OUTOFMEMORY;
848 enumerator->ISourcesRowset_iface.lpVtbl = &msdsqlenum_vtbl;
849 enumerator->ref = 1;
851 hr = IUnknown_QueryInterface(&enumerator->ISourcesRowset_iface, riid, ppv);
852 IUnknown_Release(&enumerator->ISourcesRowset_iface);
853 return hr;