dinput: Enumerate user format object forwards.
[wine.git] / dlls / msado15 / connection.c
blobe1fbea187b0a9b9922e02a2ecfb77afb893c4ab0
1 /*
2 * Copyright 2019 Hans Leidekker for CodeWeavers
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 #include <stdarg.h>
20 #include "windef.h"
21 #include "winbase.h"
22 #define COBJMACROS
23 #define DBINITCONSTANTS
24 #include "initguid.h"
25 #include "ocidl.h"
26 #include "objbase.h"
27 #include "msdasc.h"
28 #include "olectl.h"
29 #include "msado15_backcompat.h"
31 #include "wine/debug.h"
32 #include "wine/heap.h"
34 #include "msado15_private.h"
36 WINE_DEFAULT_DEBUG_CHANNEL(msado15);
38 struct connection;
40 struct connection_point
42 IConnectionPoint IConnectionPoint_iface;
43 struct connection *conn;
44 const IID *riid;
45 IUnknown **sinks;
46 ULONG sinks_size;
49 struct connection
51 _Connection Connection_iface;
52 ISupportErrorInfo ISupportErrorInfo_iface;
53 IConnectionPointContainer IConnectionPointContainer_iface;
54 ADOConnectionConstruction15 ADOConnectionConstruction15_iface;
55 LONG refs;
56 ObjectStateEnum state;
57 LONG timeout;
58 WCHAR *datasource;
59 WCHAR *provider;
60 ConnectModeEnum mode;
61 CursorLocationEnum location;
62 IUnknown *session;
63 struct connection_point cp_connev;
66 static inline struct connection *impl_from_Connection( _Connection *iface )
68 return CONTAINING_RECORD( iface, struct connection, Connection_iface );
71 static inline struct connection *impl_from_ISupportErrorInfo( ISupportErrorInfo *iface )
73 return CONTAINING_RECORD( iface, struct connection, ISupportErrorInfo_iface );
76 static inline struct connection *impl_from_IConnectionPointContainer( IConnectionPointContainer *iface )
78 return CONTAINING_RECORD( iface, struct connection, IConnectionPointContainer_iface );
81 static inline struct connection *impl_from_ADOConnectionConstruction15( ADOConnectionConstruction15 *iface )
83 return CONTAINING_RECORD( iface, struct connection, ADOConnectionConstruction15_iface );
86 static inline struct connection_point *impl_from_IConnectionPoint( IConnectionPoint *iface )
88 return CONTAINING_RECORD( iface, struct connection_point, IConnectionPoint_iface );
91 static ULONG WINAPI connection_AddRef( _Connection *iface )
93 struct connection *connection = impl_from_Connection( iface );
94 return InterlockedIncrement( &connection->refs );
97 static ULONG WINAPI connection_Release( _Connection *iface )
99 struct connection *connection = impl_from_Connection( iface );
100 LONG refs = InterlockedDecrement( &connection->refs );
101 ULONG i;
102 if (!refs)
104 TRACE( "destroying %p\n", connection );
105 for (i = 0; i < connection->cp_connev.sinks_size; ++i)
107 if (connection->cp_connev.sinks[i])
108 IUnknown_Release( connection->cp_connev.sinks[i] );
110 if (connection->session) IUnknown_Release( connection->session );
111 heap_free( connection->cp_connev.sinks );
112 heap_free( connection->provider );
113 heap_free( connection->datasource );
114 heap_free( connection );
116 return refs;
119 static HRESULT WINAPI connection_QueryInterface( _Connection *iface, REFIID riid, void **obj )
121 struct connection *connection = impl_from_Connection( iface );
122 TRACE( "%p, %s, %p\n", connection, debugstr_guid(riid), obj );
124 *obj = NULL;
126 if (IsEqualGUID( riid, &IID__Connection ) || IsEqualGUID( riid, &IID_IDispatch ) ||
127 IsEqualGUID( riid, &IID_IUnknown ))
129 *obj = iface;
131 else if(IsEqualGUID( riid, &IID_ISupportErrorInfo ))
133 *obj = &connection->ISupportErrorInfo_iface;
135 else if (IsEqualGUID( riid, &IID_IConnectionPointContainer ))
137 *obj = &connection->IConnectionPointContainer_iface;
139 else if (IsEqualGUID( riid, &IID_ADOConnectionConstruction15 ))
141 *obj = &connection->ADOConnectionConstruction15_iface;
143 else if (IsEqualGUID( riid, &IID_IRunnableObject ))
145 TRACE("IID_IRunnableObject not supported returning NULL\n");
146 return E_NOINTERFACE;
148 else
150 FIXME( "interface %s not implemented\n", debugstr_guid(riid) );
151 return E_NOINTERFACE;
153 connection_AddRef( iface );
154 return S_OK;
157 static HRESULT WINAPI connection_GetTypeInfoCount( _Connection *iface, UINT *count )
159 struct connection *connection = impl_from_Connection( iface );
160 TRACE( "%p, %p\n", connection, count );
161 *count = 1;
162 return S_OK;
165 static HRESULT WINAPI connection_GetTypeInfo( _Connection *iface, UINT index, LCID lcid, ITypeInfo **info )
167 struct connection *connection = impl_from_Connection( iface );
168 TRACE( "%p, %u, %lu, %p\n", connection, index, lcid, info );
169 return get_typeinfo(Connection_tid, info);
172 static HRESULT WINAPI connection_GetIDsOfNames( _Connection *iface, REFIID riid, LPOLESTR *names, UINT count,
173 LCID lcid, DISPID *dispid )
175 struct connection *connection = impl_from_Connection( iface );
176 HRESULT hr;
177 ITypeInfo *typeinfo;
179 TRACE( "%p, %s, %p, %u, %lu, %p\n", connection, debugstr_guid(riid), names, count, lcid, dispid );
181 hr = get_typeinfo(Connection_tid, &typeinfo);
182 if(SUCCEEDED(hr))
184 hr = ITypeInfo_GetIDsOfNames(typeinfo, names, count, dispid);
185 ITypeInfo_Release(typeinfo);
188 return hr;
191 static HRESULT WINAPI connection_Invoke( _Connection *iface, DISPID member, REFIID riid, LCID lcid, WORD flags,
192 DISPPARAMS *params, VARIANT *result, EXCEPINFO *excep_info, UINT *arg_err )
194 struct connection *connection = impl_from_Connection( iface );
195 HRESULT hr;
196 ITypeInfo *typeinfo;
198 TRACE( "%p, %ld, %s, %ld, %d, %p, %p, %p, %p\n", connection, member, debugstr_guid(riid), lcid, flags,
199 params, result, excep_info, arg_err );
201 hr = get_typeinfo(Connection_tid, &typeinfo);
202 if(SUCCEEDED(hr))
204 hr = ITypeInfo_Invoke(typeinfo, &connection->Connection_iface, member, flags, params,
205 result, excep_info, arg_err);
206 ITypeInfo_Release(typeinfo);
209 return hr;
212 static HRESULT WINAPI connection_get_Properties( _Connection *iface, Properties **obj )
214 FIXME( "%p, %p\n", iface, obj );
215 return E_NOTIMPL;
218 static HRESULT WINAPI connection_get_ConnectionString( _Connection *iface, BSTR *str )
220 struct connection *connection = impl_from_Connection( iface );
221 BSTR source = NULL;
223 TRACE( "%p, %p\n", connection, str );
225 if (connection->datasource && !(source = SysAllocString( connection->datasource ))) return E_OUTOFMEMORY;
226 *str = source;
227 return S_OK;
230 static HRESULT WINAPI connection_put_ConnectionString( _Connection *iface, BSTR str )
232 struct connection *connection = impl_from_Connection( iface );
233 WCHAR *source = NULL;
235 TRACE( "%p, %s\n", connection, debugstr_w( str && !wcsstr( str, L"Password" ) ? L"<hidden>" : str ) );
237 if (str && !(source = strdupW( str ))) return E_OUTOFMEMORY;
238 heap_free( connection->datasource );
239 connection->datasource = source;
240 return S_OK;
243 static HRESULT WINAPI connection_get_CommandTimeout( _Connection *iface, LONG *timeout )
245 struct connection *connection = impl_from_Connection( iface );
246 TRACE( "%p, %p\n", connection, timeout );
247 *timeout = connection->timeout;
248 return S_OK;
251 static HRESULT WINAPI connection_put_CommandTimeout( _Connection *iface, LONG timeout )
253 struct connection *connection = impl_from_Connection( iface );
254 TRACE( "%p, %ld\n", connection, timeout );
255 connection->timeout = timeout;
256 return S_OK;
259 static HRESULT WINAPI connection_get_ConnectionTimeout( _Connection *iface, LONG *timeout )
261 FIXME( "%p, %p\n", iface, timeout );
262 return E_NOTIMPL;
265 static HRESULT WINAPI connection_put_ConnectionTimeout( _Connection *iface, LONG timeout )
267 FIXME( "%p, %ld\n", iface, timeout );
268 return E_NOTIMPL;
271 static HRESULT WINAPI connection_get_Version( _Connection *iface, BSTR *str )
273 FIXME( "%p, %p\n", iface, str );
274 return E_NOTIMPL;
277 static HRESULT WINAPI connection_Close( _Connection *iface )
279 struct connection *connection = impl_from_Connection( iface );
281 TRACE( "%p\n", connection );
283 if (connection->state == adStateClosed) return MAKE_ADO_HRESULT( adErrObjectClosed );
285 if (connection->session)
287 IUnknown_Release( connection->session );
288 connection->session = NULL;
291 connection->state = adStateClosed;
292 return S_OK;
295 static HRESULT WINAPI connection_Execute( _Connection *iface, BSTR command, VARIANT *records_affected,
296 LONG options, _Recordset **record_set )
298 struct connection *connection = impl_from_Connection( iface );
299 HRESULT hr;
300 _Recordset *recordset;
301 VARIANT source, active;
302 IDispatch *dispatch;
304 FIXME( "%p, %s, %p, 0x%08lx, %p Semi-stub\n", iface, debugstr_w(command), records_affected, options, record_set );
306 if (connection->state == adStateClosed) return MAKE_ADO_HRESULT( adErrObjectClosed );
308 hr = Recordset_create( (void**)&recordset);
309 if (FAILED(hr))
311 return hr;
314 _Recordset_put_CursorLocation(recordset, connection->location);
316 V_VT(&source) = VT_BSTR;
317 V_BSTR(&source) = command;
319 hr = _Connection_QueryInterface(&connection->Connection_iface, &IID_IDispatch, (void**)&dispatch);
320 if (FAILED(hr))
322 _Recordset_Release(recordset);
323 return hr;
326 V_VT(&active) = VT_DISPATCH;
327 V_DISPATCH(&active) = dispatch;
329 hr = _Recordset_Open(recordset, source, active, adOpenDynamic, adLockPessimistic, 0);
330 VariantClear(&active);
331 if (FAILED(hr))
333 _Recordset_Release(recordset);
334 return hr;
337 if (records_affected)
339 ADO_LONGPTR count;
340 _Recordset_get_RecordCount(recordset, &count);
341 V_VT(records_affected) = VT_I4;
342 V_I4(records_affected) = count;
345 *record_set = recordset;
347 return hr;
350 static HRESULT WINAPI connection_BeginTrans( _Connection *iface, LONG *transaction_level )
352 FIXME( "%p, %p\n", iface, transaction_level );
353 return E_NOTIMPL;
356 static HRESULT WINAPI connection_CommitTrans( _Connection *iface )
358 FIXME( "%p\n", iface );
359 return E_NOTIMPL;
362 static HRESULT WINAPI connection_RollbackTrans( _Connection *iface )
364 FIXME( "%p\n", iface );
365 return E_NOTIMPL;
368 static HRESULT WINAPI connection_Open( _Connection *iface, BSTR connect_str, BSTR userid, BSTR password,
369 LONG options )
371 struct connection *connection = impl_from_Connection( iface );
372 IDBProperties *props;
373 IDBInitialize *dbinit = NULL;
374 IDataInitialize *datainit;
375 IDBCreateSession *session = NULL;
376 HRESULT hr;
378 TRACE( "%p, %s, %s, %p, %08lx\n", iface, debugstr_w(connect_str), debugstr_w(userid), password, options );
380 if (connection->state == adStateOpen) return MAKE_ADO_HRESULT( adErrObjectOpen );
381 if (!connect_str) return E_FAIL;
383 if ((hr = CoCreateInstance( &CLSID_MSDAINITIALIZE, NULL, CLSCTX_INPROC_SERVER, &IID_IDataInitialize,
384 (void **)&datainit )) != S_OK) return hr;
385 if ((hr = IDataInitialize_GetDataSource( datainit, NULL, CLSCTX_INPROC_SERVER, connect_str, &IID_IDBInitialize,
386 (IUnknown **)&dbinit )) != S_OK) goto done;
387 if ((hr = IDBInitialize_QueryInterface( dbinit, &IID_IDBProperties, (void **)&props )) != S_OK) goto done;
389 /* TODO - Update username/password if required. */
390 if ((userid && *userid) || (password && *password))
391 FIXME("Username/password parameters currently not supported\n");
393 if ((hr = IDBInitialize_Initialize( dbinit )) != S_OK) goto done;
394 if ((hr = IDBInitialize_QueryInterface( dbinit, &IID_IDBCreateSession, (void **)&session )) != S_OK) goto done;
395 if ((hr = IDBCreateSession_CreateSession( session, NULL, &IID_IUnknown, &connection->session )) == S_OK)
397 connection->state = adStateOpen;
399 IDBCreateSession_Release( session );
401 done:
402 if (hr != S_OK && connection->session)
404 IUnknown_Release( connection->session );
405 connection->session = NULL;
407 if (dbinit)
409 IDBInitialize_Uninitialize( dbinit );
410 IDBInitialize_Release( dbinit );
412 IDataInitialize_Release( datainit );
414 TRACE("ret 0x%08lx\n", hr);
415 return hr;
418 static HRESULT WINAPI connection_get_Errors( _Connection *iface, Errors **obj )
420 FIXME( "%p, %p\n", iface, obj );
421 return E_NOTIMPL;
424 static HRESULT WINAPI connection_get_DefaultDatabase( _Connection *iface, BSTR *str )
426 FIXME( "%p, %p\n", iface, str );
427 return E_NOTIMPL;
430 static HRESULT WINAPI connection_put_DefaultDatabase( _Connection *iface, BSTR str )
432 FIXME( "%p, %s\n", iface, debugstr_w(str) );
433 return E_NOTIMPL;
436 static HRESULT WINAPI connection_get_IsolationLevel( _Connection *iface, IsolationLevelEnum *level )
438 FIXME( "%p, %p\n", iface, level );
439 return E_NOTIMPL;
442 static HRESULT WINAPI connection_put_IsolationLevel( _Connection *iface, IsolationLevelEnum level )
444 FIXME( "%p, %d\n", iface, level );
445 return E_NOTIMPL;
448 static HRESULT WINAPI connection_get_Attributes( _Connection *iface, LONG *attr )
450 FIXME( "%p, %p\n", iface, attr );
451 return E_NOTIMPL;
454 static HRESULT WINAPI connection_put_Attributes( _Connection *iface, LONG attr )
456 FIXME( "%p, %ld\n", iface, attr );
457 return E_NOTIMPL;
460 static HRESULT WINAPI connection_get_CursorLocation( _Connection *iface, CursorLocationEnum *cursor_loc )
462 struct connection *connection = impl_from_Connection( iface );
464 TRACE( "%p, %p\n", iface, cursor_loc );
466 *cursor_loc = connection->location;
467 return S_OK;
470 static HRESULT WINAPI connection_put_CursorLocation( _Connection *iface, CursorLocationEnum cursor_loc )
472 struct connection *connection = impl_from_Connection( iface );
474 TRACE( "%p, %u\n", iface, cursor_loc );
476 connection->location = cursor_loc;
477 return S_OK;
480 static HRESULT WINAPI connection_get_Mode( _Connection *iface, ConnectModeEnum *mode )
482 struct connection *connection = impl_from_Connection( iface );
484 TRACE( "%p, %p\n", iface, mode );
486 *mode = connection->mode;
487 return S_OK;
490 static HRESULT WINAPI connection_put_Mode( _Connection *iface, ConnectModeEnum mode )
492 struct connection *connection = impl_from_Connection( iface );
494 TRACE( "%p, %u\n", iface, mode );
496 connection->mode = mode;
497 return S_OK;
500 static HRESULT WINAPI connection_get_Provider( _Connection *iface, BSTR *str )
502 struct connection *connection = impl_from_Connection( iface );
503 BSTR provider = NULL;
505 TRACE( "%p, %p\n", iface, str );
507 if (connection->provider && !(provider = SysAllocString( connection->provider ))) return E_OUTOFMEMORY;
508 *str = provider;
509 return S_OK;
512 static HRESULT WINAPI connection_put_Provider( _Connection *iface, BSTR str )
514 struct connection *connection = impl_from_Connection( iface );
515 WCHAR *provider = NULL;
517 TRACE( "%p, %s\n", iface, debugstr_w(str) );
519 if (!str) return MAKE_ADO_HRESULT(adErrInvalidArgument);
521 if (!(provider = strdupW( str ))) return E_OUTOFMEMORY;
522 heap_free( connection->provider );
523 connection->provider = provider;
524 return S_OK;
527 static HRESULT WINAPI connection_get_State( _Connection *iface, LONG *state )
529 struct connection *connection = impl_from_Connection( iface );
530 TRACE( "%p, %p\n", connection, state );
531 *state = connection->state;
532 return S_OK;
535 static HRESULT WINAPI connection_OpenSchema( _Connection *iface, SchemaEnum schema, VARIANT restrictions,
536 VARIANT schema_id, _Recordset **record_set )
538 FIXME( "%p, %d, %s, %s, %p\n", iface, schema, debugstr_variant(&restrictions),
539 debugstr_variant(&schema_id), record_set );
540 return E_NOTIMPL;
543 static HRESULT WINAPI connection_Cancel( _Connection *iface )
545 FIXME( "%p\n", iface );
546 return E_NOTIMPL;
549 static const struct _ConnectionVtbl connection_vtbl =
551 connection_QueryInterface,
552 connection_AddRef,
553 connection_Release,
554 connection_GetTypeInfoCount,
555 connection_GetTypeInfo,
556 connection_GetIDsOfNames,
557 connection_Invoke,
558 connection_get_Properties,
559 connection_get_ConnectionString,
560 connection_put_ConnectionString,
561 connection_get_CommandTimeout,
562 connection_put_CommandTimeout,
563 connection_get_ConnectionTimeout,
564 connection_put_ConnectionTimeout,
565 connection_get_Version,
566 connection_Close,
567 connection_Execute,
568 connection_BeginTrans,
569 connection_CommitTrans,
570 connection_RollbackTrans,
571 connection_Open,
572 connection_get_Errors,
573 connection_get_DefaultDatabase,
574 connection_put_DefaultDatabase,
575 connection_get_IsolationLevel,
576 connection_put_IsolationLevel,
577 connection_get_Attributes,
578 connection_put_Attributes,
579 connection_get_CursorLocation,
580 connection_put_CursorLocation,
581 connection_get_Mode,
582 connection_put_Mode,
583 connection_get_Provider,
584 connection_put_Provider,
585 connection_get_State,
586 connection_OpenSchema,
587 connection_Cancel
590 static HRESULT WINAPI supporterror_QueryInterface( ISupportErrorInfo *iface, REFIID riid, void **obj )
592 struct connection *connection = impl_from_ISupportErrorInfo( iface );
593 return connection_QueryInterface( &connection->Connection_iface, riid, obj );
596 static ULONG WINAPI supporterror_AddRef( ISupportErrorInfo *iface )
598 struct connection *connection = impl_from_ISupportErrorInfo( iface );
599 return connection_AddRef( &connection->Connection_iface );
602 static ULONG WINAPI supporterror_Release( ISupportErrorInfo *iface )
604 struct connection *connection = impl_from_ISupportErrorInfo( iface );
605 return connection_Release( &connection->Connection_iface );
608 static HRESULT WINAPI supporterror_InterfaceSupportsErrorInfo( ISupportErrorInfo *iface, REFIID riid )
610 struct connection *connection = impl_from_ISupportErrorInfo( iface );
611 FIXME( "%p, %s\n", connection, debugstr_guid(riid) );
612 return S_FALSE;
615 static const struct ISupportErrorInfoVtbl support_error_vtbl =
617 supporterror_QueryInterface,
618 supporterror_AddRef,
619 supporterror_Release,
620 supporterror_InterfaceSupportsErrorInfo
623 static HRESULT WINAPI connpointcontainer_QueryInterface( IConnectionPointContainer *iface,
624 REFIID riid, void **obj )
626 struct connection *connection = impl_from_IConnectionPointContainer( iface );
627 return connection_QueryInterface( &connection->Connection_iface, riid, obj );
630 static ULONG WINAPI connpointcontainer_AddRef( IConnectionPointContainer *iface )
632 struct connection *connection = impl_from_IConnectionPointContainer( iface );
633 return connection_AddRef( &connection->Connection_iface );
636 static ULONG WINAPI connpointcontainer_Release( IConnectionPointContainer *iface )
638 struct connection *connection = impl_from_IConnectionPointContainer( iface );
639 return connection_Release( &connection->Connection_iface );
642 static HRESULT WINAPI connpointcontainer_EnumConnectionPoints( IConnectionPointContainer *iface,
643 IEnumConnectionPoints **points )
645 struct connection *connection = impl_from_IConnectionPointContainer( iface );
646 FIXME( "%p, %p\n", connection, points );
647 return E_NOTIMPL;
650 static HRESULT WINAPI connpointcontainer_FindConnectionPoint( IConnectionPointContainer *iface,
651 REFIID riid, IConnectionPoint **point )
653 struct connection *connection = impl_from_IConnectionPointContainer( iface );
655 TRACE( "%p, %s %p\n", connection, debugstr_guid( riid ), point );
657 if (!point) return E_POINTER;
659 if (IsEqualIID( riid, connection->cp_connev.riid ))
661 *point = &connection->cp_connev.IConnectionPoint_iface;
662 IConnectionPoint_AddRef( *point );
663 return S_OK;
666 FIXME( "unsupported connection point %s\n", debugstr_guid( riid ) );
667 return CONNECT_E_NOCONNECTION;
670 static const struct IConnectionPointContainerVtbl connpointcontainer_vtbl =
672 connpointcontainer_QueryInterface,
673 connpointcontainer_AddRef,
674 connpointcontainer_Release,
675 connpointcontainer_EnumConnectionPoints,
676 connpointcontainer_FindConnectionPoint
679 static HRESULT WINAPI connpoint_QueryInterface( IConnectionPoint *iface, REFIID riid, void **obj )
681 struct connection_point *connpoint = impl_from_IConnectionPoint( iface );
683 if (IsEqualGUID( &IID_IUnknown, riid ) || IsEqualGUID( &IID_IConnectionPoint, riid ))
685 *obj = &connpoint->IConnectionPoint_iface;
687 else
689 FIXME( "interface %s not implemented\n", debugstr_guid( riid ) );
690 return E_NOINTERFACE;
693 connection_AddRef( &connpoint->conn->Connection_iface );
694 return S_OK;
697 static ULONG WINAPI connpoint_AddRef( IConnectionPoint *iface )
699 struct connection_point *connpoint = impl_from_IConnectionPoint( iface );
700 return IConnectionPointContainer_AddRef( &connpoint->conn->IConnectionPointContainer_iface );
703 static ULONG WINAPI connpoint_Release( IConnectionPoint *iface )
705 struct connection_point *connpoint = impl_from_IConnectionPoint( iface );
706 return IConnectionPointContainer_Release( &connpoint->conn->IConnectionPointContainer_iface );
709 static HRESULT WINAPI connpoint_GetConnectionInterface( IConnectionPoint *iface, IID *iid )
711 struct connection_point *connpoint = impl_from_IConnectionPoint( iface );
712 FIXME( "%p, %p\n", connpoint, iid );
713 return E_NOTIMPL;
716 static HRESULT WINAPI connpoint_GetConnectionPointContainer( IConnectionPoint *iface,
717 IConnectionPointContainer **container )
719 struct connection_point *connpoint = impl_from_IConnectionPoint( iface );
720 FIXME( "%p, %p\n", connpoint, container );
721 return E_NOTIMPL;
724 static HRESULT WINAPI connpoint_Advise( IConnectionPoint *iface, IUnknown *unk_sink,
725 DWORD *cookie )
727 struct connection_point *connpoint = impl_from_IConnectionPoint( iface );
728 IUnknown *sink, **tmp;
729 ULONG new_size;
730 HRESULT hr;
731 DWORD i;
733 TRACE( "%p, %p, %p\n", iface, unk_sink, cookie );
735 if (!unk_sink || !cookie) return E_FAIL;
737 if (FAILED(hr = IUnknown_QueryInterface( unk_sink, &IID_ConnectionEventsVt, (void**)&sink )))
739 *cookie = 0;
740 return E_FAIL;
743 if (connpoint->sinks)
745 for (i = 0; i < connpoint->sinks_size; ++i)
747 if (!connpoint->sinks[i])
748 break;
751 if (i == connpoint->sinks_size)
753 new_size = connpoint->sinks_size * 2;
754 if (!(tmp = heap_realloc_zero( connpoint->sinks, new_size * sizeof(*connpoint->sinks) )))
755 return E_OUTOFMEMORY;
756 connpoint->sinks = tmp;
757 connpoint->sinks_size = new_size;
760 else
762 if (!(connpoint->sinks = heap_alloc_zero( sizeof(*connpoint->sinks) ))) return E_OUTOFMEMORY;
763 connpoint->sinks_size = 1;
764 i = 0;
767 connpoint->sinks[i] = sink;
768 *cookie = i + 1;
769 return S_OK;
772 static HRESULT WINAPI connpoint_Unadvise( IConnectionPoint *iface, DWORD cookie )
774 struct connection_point *connpoint = impl_from_IConnectionPoint( iface );
775 TRACE( "%p, %lu\n", connpoint, cookie );
777 if (!cookie || cookie > connpoint->sinks_size || !connpoint->sinks || !connpoint->sinks[cookie - 1])
778 return E_FAIL;
780 IUnknown_Release( connpoint->sinks[cookie - 1] );
781 connpoint->sinks[cookie - 1] = NULL;
782 return S_OK;
785 static HRESULT WINAPI connpoint_EnumConnections( IConnectionPoint *iface,
786 IEnumConnections **points )
788 struct connection_point *connpoint = impl_from_IConnectionPoint( iface );
789 FIXME( "%p, %p\n", connpoint, points );
790 return E_NOTIMPL;
793 static const IConnectionPointVtbl connpoint_vtbl =
795 connpoint_QueryInterface,
796 connpoint_AddRef,
797 connpoint_Release,
798 connpoint_GetConnectionInterface,
799 connpoint_GetConnectionPointContainer,
800 connpoint_Advise,
801 connpoint_Unadvise,
802 connpoint_EnumConnections
805 static HRESULT WINAPI adoconstruct_QueryInterface(ADOConnectionConstruction15 *iface, REFIID riid, void **obj)
807 struct connection *connection = impl_from_ADOConnectionConstruction15( iface );
808 return _Connection_QueryInterface( &connection->Connection_iface, riid, obj );
811 static ULONG WINAPI adoconstruct_AddRef(ADOConnectionConstruction15 *iface)
813 struct connection *connection = impl_from_ADOConnectionConstruction15( iface );
814 return _Connection_AddRef( &connection->Connection_iface );
817 static ULONG WINAPI adoconstruct_Release(ADOConnectionConstruction15 *iface)
819 struct connection *connection = impl_from_ADOConnectionConstruction15( iface );
820 return _Connection_Release( &connection->Connection_iface );
823 static HRESULT WINAPI adoconstruct_get_DSO(ADOConnectionConstruction15 *iface, IUnknown **dso)
825 struct connection *connection = impl_from_ADOConnectionConstruction15( iface );
826 FIXME("%p, %p\n", connection, dso);
827 return E_NOTIMPL;
830 static HRESULT WINAPI adoconstruct_get_Session(ADOConnectionConstruction15 *iface, IUnknown **session)
832 struct connection *connection = impl_from_ADOConnectionConstruction15( iface );
833 TRACE("%p, %p\n", connection, session);
835 *session = connection->session;
836 if (*session)
837 IUnknown_AddRef(*session);
838 return S_OK;
841 static HRESULT WINAPI adoconstruct_WrapDSOandSession(ADOConnectionConstruction15 *iface, IUnknown *dso,
842 IUnknown *session)
844 struct connection *connection = impl_from_ADOConnectionConstruction15( iface );
845 FIXME("%p, %p, %p\n", connection, dso, session);
846 return E_NOTIMPL;
849 struct ADOConnectionConstruction15Vtbl ado_construct_vtbl =
851 adoconstruct_QueryInterface,
852 adoconstruct_AddRef,
853 adoconstruct_Release,
854 adoconstruct_get_DSO,
855 adoconstruct_get_Session,
856 adoconstruct_WrapDSOandSession
859 HRESULT Connection_create( void **obj )
861 struct connection *connection;
863 if (!(connection = heap_alloc( sizeof(*connection) ))) return E_OUTOFMEMORY;
864 connection->Connection_iface.lpVtbl = &connection_vtbl;
865 connection->ISupportErrorInfo_iface.lpVtbl = &support_error_vtbl;
866 connection->IConnectionPointContainer_iface.lpVtbl = &connpointcontainer_vtbl;
867 connection->ADOConnectionConstruction15_iface.lpVtbl = &ado_construct_vtbl;
868 connection->refs = 1;
869 connection->state = adStateClosed;
870 connection->timeout = 30;
871 connection->datasource = NULL;
872 if (!(connection->provider = strdupW( L"MSDASQL" )))
874 heap_free( connection );
875 return E_OUTOFMEMORY;
877 connection->mode = adModeUnknown;
878 connection->location = adUseServer;
879 connection->session = NULL;
881 connection->cp_connev.conn = connection;
882 connection->cp_connev.riid = &DIID_ConnectionEvents;
883 connection->cp_connev.IConnectionPoint_iface.lpVtbl = &connpoint_vtbl;
884 connection->cp_connev.sinks = NULL;
885 connection->cp_connev.sinks_size = 0;
887 *obj = &connection->Connection_iface;
888 TRACE( "returning iface %p\n", *obj );
889 return S_OK;