win32u: Respect per-monitor thread dpi awareness when getting window from point.
[wine.git] / dlls / msado15 / connection.c
blobd6ca0c2df3978ffc3153970b67860be46caf0953
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"
33 #include "msado15_private.h"
35 WINE_DEFAULT_DEBUG_CHANNEL(msado15);
37 struct connection;
39 struct connection_point
41 IConnectionPoint IConnectionPoint_iface;
42 struct connection *conn;
43 const IID *riid;
44 IUnknown **sinks;
45 ULONG sinks_size;
48 struct connection
50 _Connection Connection_iface;
51 ISupportErrorInfo ISupportErrorInfo_iface;
52 IConnectionPointContainer IConnectionPointContainer_iface;
53 ADOConnectionConstruction15 ADOConnectionConstruction15_iface;
54 LONG refs;
55 ObjectStateEnum state;
56 LONG timeout;
57 WCHAR *datasource;
58 WCHAR *provider;
59 ConnectModeEnum mode;
60 CursorLocationEnum location;
61 IUnknown *session;
62 struct connection_point cp_connev;
65 static inline struct connection *impl_from_Connection( _Connection *iface )
67 return CONTAINING_RECORD( iface, struct connection, Connection_iface );
70 static inline struct connection *impl_from_ISupportErrorInfo( ISupportErrorInfo *iface )
72 return CONTAINING_RECORD( iface, struct connection, ISupportErrorInfo_iface );
75 static inline struct connection *impl_from_IConnectionPointContainer( IConnectionPointContainer *iface )
77 return CONTAINING_RECORD( iface, struct connection, IConnectionPointContainer_iface );
80 static inline struct connection *impl_from_ADOConnectionConstruction15( ADOConnectionConstruction15 *iface )
82 return CONTAINING_RECORD( iface, struct connection, ADOConnectionConstruction15_iface );
85 static inline struct connection_point *impl_from_IConnectionPoint( IConnectionPoint *iface )
87 return CONTAINING_RECORD( iface, struct connection_point, IConnectionPoint_iface );
90 static ULONG WINAPI connection_AddRef( _Connection *iface )
92 struct connection *connection = impl_from_Connection( iface );
93 return InterlockedIncrement( &connection->refs );
96 static ULONG WINAPI connection_Release( _Connection *iface )
98 struct connection *connection = impl_from_Connection( iface );
99 LONG refs = InterlockedDecrement( &connection->refs );
100 ULONG i;
101 if (!refs)
103 TRACE( "destroying %p\n", connection );
104 for (i = 0; i < connection->cp_connev.sinks_size; ++i)
106 if (connection->cp_connev.sinks[i])
107 IUnknown_Release( connection->cp_connev.sinks[i] );
109 if (connection->session) IUnknown_Release( connection->session );
110 free( connection->cp_connev.sinks );
111 free( connection->provider );
112 free( connection->datasource );
113 free( connection );
115 return refs;
118 static HRESULT WINAPI connection_QueryInterface( _Connection *iface, REFIID riid, void **obj )
120 struct connection *connection = impl_from_Connection( iface );
121 TRACE( "%p, %s, %p\n", connection, debugstr_guid(riid), obj );
123 *obj = NULL;
125 if (IsEqualGUID( riid, &IID__Connection ) || IsEqualGUID( riid, &IID_IDispatch ) ||
126 IsEqualGUID( riid, &IID_IUnknown ))
128 *obj = iface;
130 else if(IsEqualGUID( riid, &IID_ISupportErrorInfo ))
132 *obj = &connection->ISupportErrorInfo_iface;
134 else if (IsEqualGUID( riid, &IID_IConnectionPointContainer ))
136 *obj = &connection->IConnectionPointContainer_iface;
138 else if (IsEqualGUID( riid, &IID_ADOConnectionConstruction15 ))
140 *obj = &connection->ADOConnectionConstruction15_iface;
142 else if (IsEqualGUID( riid, &IID_IRunnableObject ))
144 TRACE("IID_IRunnableObject not supported returning NULL\n");
145 return E_NOINTERFACE;
147 else
149 FIXME( "interface %s not implemented\n", debugstr_guid(riid) );
150 return E_NOINTERFACE;
152 connection_AddRef( iface );
153 return S_OK;
156 static HRESULT WINAPI connection_GetTypeInfoCount( _Connection *iface, UINT *count )
158 struct connection *connection = impl_from_Connection( iface );
159 TRACE( "%p, %p\n", connection, count );
160 *count = 1;
161 return S_OK;
164 static HRESULT WINAPI connection_GetTypeInfo( _Connection *iface, UINT index, LCID lcid, ITypeInfo **info )
166 struct connection *connection = impl_from_Connection( iface );
167 TRACE( "%p, %u, %lu, %p\n", connection, index, lcid, info );
168 return get_typeinfo(Connection_tid, info);
171 static HRESULT WINAPI connection_GetIDsOfNames( _Connection *iface, REFIID riid, LPOLESTR *names, UINT count,
172 LCID lcid, DISPID *dispid )
174 struct connection *connection = impl_from_Connection( iface );
175 HRESULT hr;
176 ITypeInfo *typeinfo;
178 TRACE( "%p, %s, %p, %u, %lu, %p\n", connection, debugstr_guid(riid), names, count, lcid, dispid );
180 hr = get_typeinfo(Connection_tid, &typeinfo);
181 if(SUCCEEDED(hr))
183 hr = ITypeInfo_GetIDsOfNames(typeinfo, names, count, dispid);
184 ITypeInfo_Release(typeinfo);
187 return hr;
190 static HRESULT WINAPI connection_Invoke( _Connection *iface, DISPID member, REFIID riid, LCID lcid, WORD flags,
191 DISPPARAMS *params, VARIANT *result, EXCEPINFO *excep_info, UINT *arg_err )
193 struct connection *connection = impl_from_Connection( iface );
194 HRESULT hr;
195 ITypeInfo *typeinfo;
197 TRACE( "%p, %ld, %s, %ld, %d, %p, %p, %p, %p\n", connection, member, debugstr_guid(riid), lcid, flags,
198 params, result, excep_info, arg_err );
200 hr = get_typeinfo(Connection_tid, &typeinfo);
201 if(SUCCEEDED(hr))
203 hr = ITypeInfo_Invoke(typeinfo, &connection->Connection_iface, member, flags, params,
204 result, excep_info, arg_err);
205 ITypeInfo_Release(typeinfo);
208 return hr;
211 static HRESULT WINAPI connection_get_Properties( _Connection *iface, Properties **obj )
213 FIXME( "%p, %p\n", iface, obj );
214 return E_NOTIMPL;
217 static HRESULT WINAPI connection_get_ConnectionString( _Connection *iface, BSTR *str )
219 struct connection *connection = impl_from_Connection( iface );
220 BSTR source = NULL;
222 TRACE( "%p, %p\n", connection, str );
224 if (connection->datasource && !(source = SysAllocString( connection->datasource ))) return E_OUTOFMEMORY;
225 *str = source;
226 return S_OK;
229 static HRESULT WINAPI connection_put_ConnectionString( _Connection *iface, BSTR str )
231 struct connection *connection = impl_from_Connection( iface );
232 WCHAR *source = NULL;
234 TRACE( "%p, %s\n", connection, debugstr_w( str && !wcsstr( str, L"Password" ) ? L"<hidden>" : str ) );
236 if (str && !(source = wcsdup( str ))) return E_OUTOFMEMORY;
237 free( connection->datasource );
238 connection->datasource = source;
239 return S_OK;
242 static HRESULT WINAPI connection_get_CommandTimeout( _Connection *iface, LONG *timeout )
244 struct connection *connection = impl_from_Connection( iface );
245 TRACE( "%p, %p\n", connection, timeout );
246 *timeout = connection->timeout;
247 return S_OK;
250 static HRESULT WINAPI connection_put_CommandTimeout( _Connection *iface, LONG timeout )
252 struct connection *connection = impl_from_Connection( iface );
253 TRACE( "%p, %ld\n", connection, timeout );
254 connection->timeout = timeout;
255 return S_OK;
258 static HRESULT WINAPI connection_get_ConnectionTimeout( _Connection *iface, LONG *timeout )
260 FIXME( "%p, %p\n", iface, timeout );
261 return E_NOTIMPL;
264 static HRESULT WINAPI connection_put_ConnectionTimeout( _Connection *iface, LONG timeout )
266 FIXME( "%p, %ld\n", iface, timeout );
267 return E_NOTIMPL;
270 static HRESULT WINAPI connection_get_Version( _Connection *iface, BSTR *str )
272 FIXME( "%p, %p\n", iface, str );
273 return E_NOTIMPL;
276 static HRESULT WINAPI connection_Close( _Connection *iface )
278 struct connection *connection = impl_from_Connection( iface );
280 TRACE( "%p\n", connection );
282 if (connection->state == adStateClosed) return MAKE_ADO_HRESULT( adErrObjectClosed );
284 if (connection->session)
286 IUnknown_Release( connection->session );
287 connection->session = NULL;
290 connection->state = adStateClosed;
291 return S_OK;
294 static HRESULT WINAPI connection_Execute( _Connection *iface, BSTR command, VARIANT *records_affected,
295 LONG options, _Recordset **record_set )
297 struct connection *connection = impl_from_Connection( iface );
298 HRESULT hr;
299 _Recordset *recordset;
300 VARIANT source, active;
301 IDispatch *dispatch;
303 FIXME( "%p, %s, %p, 0x%08lx, %p Semi-stub\n", iface, debugstr_w(command), records_affected, options, record_set );
305 if (connection->state == adStateClosed) return MAKE_ADO_HRESULT( adErrObjectClosed );
307 hr = Recordset_create( (void**)&recordset);
308 if (FAILED(hr))
310 return hr;
313 _Recordset_put_CursorLocation(recordset, connection->location);
315 V_VT(&source) = VT_BSTR;
316 V_BSTR(&source) = command;
318 hr = _Connection_QueryInterface(&connection->Connection_iface, &IID_IDispatch, (void**)&dispatch);
319 if (FAILED(hr))
321 _Recordset_Release(recordset);
322 return hr;
325 V_VT(&active) = VT_DISPATCH;
326 V_DISPATCH(&active) = dispatch;
328 hr = _Recordset_Open(recordset, source, active, adOpenDynamic, adLockPessimistic, 0);
329 VariantClear(&active);
330 if (FAILED(hr))
332 _Recordset_Release(recordset);
333 return hr;
336 if (records_affected)
338 ADO_LONGPTR count;
339 _Recordset_get_RecordCount(recordset, &count);
340 V_VT(records_affected) = VT_I4;
341 V_I4(records_affected) = count;
344 *record_set = recordset;
346 return hr;
349 static HRESULT WINAPI connection_BeginTrans( _Connection *iface, LONG *transaction_level )
351 FIXME( "%p, %p\n", iface, transaction_level );
352 return E_NOTIMPL;
355 static HRESULT WINAPI connection_CommitTrans( _Connection *iface )
357 FIXME( "%p\n", iface );
358 return E_NOTIMPL;
361 static HRESULT WINAPI connection_RollbackTrans( _Connection *iface )
363 FIXME( "%p\n", iface );
364 return E_NOTIMPL;
367 static HRESULT WINAPI connection_Open( _Connection *iface, BSTR connect_str, BSTR userid, BSTR password,
368 LONG options )
370 struct connection *connection = impl_from_Connection( iface );
371 IDBProperties *props;
372 IDBInitialize *dbinit = NULL;
373 IDataInitialize *datainit;
374 IDBCreateSession *session = NULL;
375 HRESULT hr;
377 TRACE( "%p, %s, %s, %p, %08lx\n", iface, debugstr_w(connect_str), debugstr_w(userid), password, options );
379 if (connection->state == adStateOpen) return MAKE_ADO_HRESULT( adErrObjectOpen );
380 if (!connect_str) return E_FAIL;
382 if ((hr = CoCreateInstance( &CLSID_MSDAINITIALIZE, NULL, CLSCTX_INPROC_SERVER, &IID_IDataInitialize,
383 (void **)&datainit )) != S_OK) return hr;
384 if ((hr = IDataInitialize_GetDataSource( datainit, NULL, CLSCTX_INPROC_SERVER, connect_str, &IID_IDBInitialize,
385 (IUnknown **)&dbinit )) != S_OK) goto done;
386 if ((hr = IDBInitialize_QueryInterface( dbinit, &IID_IDBProperties, (void **)&props )) != S_OK) goto done;
388 /* TODO - Update username/password if required. */
389 if ((userid && *userid) || (password && *password))
390 FIXME("Username/password parameters currently not supported\n");
392 if ((hr = IDBInitialize_Initialize( dbinit )) != S_OK) goto done;
393 if ((hr = IDBInitialize_QueryInterface( dbinit, &IID_IDBCreateSession, (void **)&session )) != S_OK) goto done;
394 if ((hr = IDBCreateSession_CreateSession( session, NULL, &IID_IUnknown, &connection->session )) == S_OK)
396 connection->state = adStateOpen;
398 IDBCreateSession_Release( session );
400 done:
401 if (hr != S_OK && connection->session)
403 IUnknown_Release( connection->session );
404 connection->session = NULL;
406 if (dbinit)
408 IDBInitialize_Uninitialize( dbinit );
409 IDBInitialize_Release( dbinit );
411 IDataInitialize_Release( datainit );
413 TRACE("ret 0x%08lx\n", hr);
414 return hr;
417 static HRESULT WINAPI connection_get_Errors( _Connection *iface, Errors **obj )
419 FIXME( "%p, %p\n", iface, obj );
420 return E_NOTIMPL;
423 static HRESULT WINAPI connection_get_DefaultDatabase( _Connection *iface, BSTR *str )
425 FIXME( "%p, %p\n", iface, str );
426 return E_NOTIMPL;
429 static HRESULT WINAPI connection_put_DefaultDatabase( _Connection *iface, BSTR str )
431 FIXME( "%p, %s\n", iface, debugstr_w(str) );
432 return E_NOTIMPL;
435 static HRESULT WINAPI connection_get_IsolationLevel( _Connection *iface, IsolationLevelEnum *level )
437 FIXME( "%p, %p\n", iface, level );
438 return E_NOTIMPL;
441 static HRESULT WINAPI connection_put_IsolationLevel( _Connection *iface, IsolationLevelEnum level )
443 FIXME( "%p, %d\n", iface, level );
444 return E_NOTIMPL;
447 static HRESULT WINAPI connection_get_Attributes( _Connection *iface, LONG *attr )
449 FIXME( "%p, %p\n", iface, attr );
450 return E_NOTIMPL;
453 static HRESULT WINAPI connection_put_Attributes( _Connection *iface, LONG attr )
455 FIXME( "%p, %ld\n", iface, attr );
456 return E_NOTIMPL;
459 static HRESULT WINAPI connection_get_CursorLocation( _Connection *iface, CursorLocationEnum *cursor_loc )
461 struct connection *connection = impl_from_Connection( iface );
463 TRACE( "%p, %p\n", iface, cursor_loc );
465 *cursor_loc = connection->location;
466 return S_OK;
469 static HRESULT WINAPI connection_put_CursorLocation( _Connection *iface, CursorLocationEnum cursor_loc )
471 struct connection *connection = impl_from_Connection( iface );
473 TRACE( "%p, %u\n", iface, cursor_loc );
475 connection->location = cursor_loc;
476 return S_OK;
479 static HRESULT WINAPI connection_get_Mode( _Connection *iface, ConnectModeEnum *mode )
481 struct connection *connection = impl_from_Connection( iface );
483 TRACE( "%p, %p\n", iface, mode );
485 *mode = connection->mode;
486 return S_OK;
489 static HRESULT WINAPI connection_put_Mode( _Connection *iface, ConnectModeEnum mode )
491 struct connection *connection = impl_from_Connection( iface );
493 TRACE( "%p, %u\n", iface, mode );
495 connection->mode = mode;
496 return S_OK;
499 static HRESULT WINAPI connection_get_Provider( _Connection *iface, BSTR *str )
501 struct connection *connection = impl_from_Connection( iface );
502 BSTR provider = NULL;
504 TRACE( "%p, %p\n", iface, str );
506 if (connection->provider && !(provider = SysAllocString( connection->provider ))) return E_OUTOFMEMORY;
507 *str = provider;
508 return S_OK;
511 static HRESULT WINAPI connection_put_Provider( _Connection *iface, BSTR str )
513 struct connection *connection = impl_from_Connection( iface );
514 WCHAR *provider = NULL;
516 TRACE( "%p, %s\n", iface, debugstr_w(str) );
518 if (!str) return MAKE_ADO_HRESULT(adErrInvalidArgument);
520 if (!(provider = wcsdup( str ))) return E_OUTOFMEMORY;
521 free( connection->provider );
522 connection->provider = provider;
523 return S_OK;
526 static HRESULT WINAPI connection_get_State( _Connection *iface, LONG *state )
528 struct connection *connection = impl_from_Connection( iface );
529 TRACE( "%p, %p\n", connection, state );
530 *state = connection->state;
531 return S_OK;
534 static HRESULT WINAPI connection_OpenSchema( _Connection *iface, SchemaEnum schema, VARIANT restrictions,
535 VARIANT schema_id, _Recordset **record_set )
537 FIXME( "%p, %d, %s, %s, %p\n", iface, schema, debugstr_variant(&restrictions),
538 debugstr_variant(&schema_id), record_set );
539 return E_NOTIMPL;
542 static HRESULT WINAPI connection_Cancel( _Connection *iface )
544 FIXME( "%p\n", iface );
545 return E_NOTIMPL;
548 static const struct _ConnectionVtbl connection_vtbl =
550 connection_QueryInterface,
551 connection_AddRef,
552 connection_Release,
553 connection_GetTypeInfoCount,
554 connection_GetTypeInfo,
555 connection_GetIDsOfNames,
556 connection_Invoke,
557 connection_get_Properties,
558 connection_get_ConnectionString,
559 connection_put_ConnectionString,
560 connection_get_CommandTimeout,
561 connection_put_CommandTimeout,
562 connection_get_ConnectionTimeout,
563 connection_put_ConnectionTimeout,
564 connection_get_Version,
565 connection_Close,
566 connection_Execute,
567 connection_BeginTrans,
568 connection_CommitTrans,
569 connection_RollbackTrans,
570 connection_Open,
571 connection_get_Errors,
572 connection_get_DefaultDatabase,
573 connection_put_DefaultDatabase,
574 connection_get_IsolationLevel,
575 connection_put_IsolationLevel,
576 connection_get_Attributes,
577 connection_put_Attributes,
578 connection_get_CursorLocation,
579 connection_put_CursorLocation,
580 connection_get_Mode,
581 connection_put_Mode,
582 connection_get_Provider,
583 connection_put_Provider,
584 connection_get_State,
585 connection_OpenSchema,
586 connection_Cancel
589 static HRESULT WINAPI supporterror_QueryInterface( ISupportErrorInfo *iface, REFIID riid, void **obj )
591 struct connection *connection = impl_from_ISupportErrorInfo( iface );
592 return connection_QueryInterface( &connection->Connection_iface, riid, obj );
595 static ULONG WINAPI supporterror_AddRef( ISupportErrorInfo *iface )
597 struct connection *connection = impl_from_ISupportErrorInfo( iface );
598 return connection_AddRef( &connection->Connection_iface );
601 static ULONG WINAPI supporterror_Release( ISupportErrorInfo *iface )
603 struct connection *connection = impl_from_ISupportErrorInfo( iface );
604 return connection_Release( &connection->Connection_iface );
607 static HRESULT WINAPI supporterror_InterfaceSupportsErrorInfo( ISupportErrorInfo *iface, REFIID riid )
609 struct connection *connection = impl_from_ISupportErrorInfo( iface );
610 FIXME( "%p, %s\n", connection, debugstr_guid(riid) );
611 return S_FALSE;
614 static const struct ISupportErrorInfoVtbl support_error_vtbl =
616 supporterror_QueryInterface,
617 supporterror_AddRef,
618 supporterror_Release,
619 supporterror_InterfaceSupportsErrorInfo
622 static HRESULT WINAPI connpointcontainer_QueryInterface( IConnectionPointContainer *iface,
623 REFIID riid, void **obj )
625 struct connection *connection = impl_from_IConnectionPointContainer( iface );
626 return connection_QueryInterface( &connection->Connection_iface, riid, obj );
629 static ULONG WINAPI connpointcontainer_AddRef( IConnectionPointContainer *iface )
631 struct connection *connection = impl_from_IConnectionPointContainer( iface );
632 return connection_AddRef( &connection->Connection_iface );
635 static ULONG WINAPI connpointcontainer_Release( IConnectionPointContainer *iface )
637 struct connection *connection = impl_from_IConnectionPointContainer( iface );
638 return connection_Release( &connection->Connection_iface );
641 static HRESULT WINAPI connpointcontainer_EnumConnectionPoints( IConnectionPointContainer *iface,
642 IEnumConnectionPoints **points )
644 struct connection *connection = impl_from_IConnectionPointContainer( iface );
645 FIXME( "%p, %p\n", connection, points );
646 return E_NOTIMPL;
649 static HRESULT WINAPI connpointcontainer_FindConnectionPoint( IConnectionPointContainer *iface,
650 REFIID riid, IConnectionPoint **point )
652 struct connection *connection = impl_from_IConnectionPointContainer( iface );
654 TRACE( "%p, %s %p\n", connection, debugstr_guid( riid ), point );
656 if (!point) return E_POINTER;
658 if (IsEqualIID( riid, connection->cp_connev.riid ))
660 *point = &connection->cp_connev.IConnectionPoint_iface;
661 IConnectionPoint_AddRef( *point );
662 return S_OK;
665 FIXME( "unsupported connection point %s\n", debugstr_guid( riid ) );
666 return CONNECT_E_NOCONNECTION;
669 static const struct IConnectionPointContainerVtbl connpointcontainer_vtbl =
671 connpointcontainer_QueryInterface,
672 connpointcontainer_AddRef,
673 connpointcontainer_Release,
674 connpointcontainer_EnumConnectionPoints,
675 connpointcontainer_FindConnectionPoint
678 static HRESULT WINAPI connpoint_QueryInterface( IConnectionPoint *iface, REFIID riid, void **obj )
680 struct connection_point *connpoint = impl_from_IConnectionPoint( iface );
682 if (IsEqualGUID( &IID_IUnknown, riid ) || IsEqualGUID( &IID_IConnectionPoint, riid ))
684 *obj = &connpoint->IConnectionPoint_iface;
686 else
688 FIXME( "interface %s not implemented\n", debugstr_guid( riid ) );
689 return E_NOINTERFACE;
692 connection_AddRef( &connpoint->conn->Connection_iface );
693 return S_OK;
696 static ULONG WINAPI connpoint_AddRef( IConnectionPoint *iface )
698 struct connection_point *connpoint = impl_from_IConnectionPoint( iface );
699 return IConnectionPointContainer_AddRef( &connpoint->conn->IConnectionPointContainer_iface );
702 static ULONG WINAPI connpoint_Release( IConnectionPoint *iface )
704 struct connection_point *connpoint = impl_from_IConnectionPoint( iface );
705 return IConnectionPointContainer_Release( &connpoint->conn->IConnectionPointContainer_iface );
708 static HRESULT WINAPI connpoint_GetConnectionInterface( IConnectionPoint *iface, IID *iid )
710 struct connection_point *connpoint = impl_from_IConnectionPoint( iface );
711 FIXME( "%p, %p\n", connpoint, iid );
712 return E_NOTIMPL;
715 static HRESULT WINAPI connpoint_GetConnectionPointContainer( IConnectionPoint *iface,
716 IConnectionPointContainer **container )
718 struct connection_point *connpoint = impl_from_IConnectionPoint( iface );
719 FIXME( "%p, %p\n", connpoint, container );
720 return E_NOTIMPL;
723 static HRESULT WINAPI connpoint_Advise( IConnectionPoint *iface, IUnknown *unk_sink,
724 DWORD *cookie )
726 struct connection_point *connpoint = impl_from_IConnectionPoint( iface );
727 IUnknown *sink, **tmp;
728 ULONG new_size;
729 HRESULT hr;
730 DWORD i;
732 TRACE( "%p, %p, %p\n", iface, unk_sink, cookie );
734 if (!unk_sink || !cookie) return E_FAIL;
736 if (FAILED(hr = IUnknown_QueryInterface( unk_sink, &IID_ConnectionEventsVt, (void**)&sink )))
738 *cookie = 0;
739 return E_FAIL;
742 if (connpoint->sinks)
744 for (i = 0; i < connpoint->sinks_size; ++i)
746 if (!connpoint->sinks[i])
747 break;
750 if (i == connpoint->sinks_size)
752 new_size = connpoint->sinks_size * 2;
753 if (!(tmp = realloc( connpoint->sinks, new_size * sizeof(*connpoint->sinks) )))
754 return E_OUTOFMEMORY;
755 memset( tmp + connpoint->sinks_size, 0, (new_size - connpoint->sinks_size) * sizeof(*connpoint->sinks) );
756 connpoint->sinks = tmp;
757 connpoint->sinks_size = new_size;
760 else
762 if (!(connpoint->sinks = calloc( 1, 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 = malloc( 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 = wcsdup( L"MSDASQL" )))
874 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;