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
23 #define DBINITCONSTANTS
29 #include "msado15_backcompat.h"
31 #include "wine/debug.h"
33 #include "msado15_private.h"
35 WINE_DEFAULT_DEBUG_CHANNEL(msado15
);
39 struct connection_point
41 IConnectionPoint IConnectionPoint_iface
;
42 struct connection
*conn
;
50 _Connection Connection_iface
;
51 ISupportErrorInfo ISupportErrorInfo_iface
;
52 IConnectionPointContainer IConnectionPointContainer_iface
;
53 ADOConnectionConstruction15 ADOConnectionConstruction15_iface
;
55 ObjectStateEnum state
;
60 CursorLocationEnum location
;
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
);
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
);
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
);
125 if (IsEqualGUID( riid
, &IID__Connection
) || IsEqualGUID( riid
, &IID_IDispatch
) ||
126 IsEqualGUID( riid
, &IID_IUnknown
))
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
;
149 FIXME( "interface %s not implemented\n", debugstr_guid(riid
) );
150 return E_NOINTERFACE
;
152 connection_AddRef( iface
);
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
);
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
);
178 TRACE( "%p, %s, %p, %u, %lu, %p\n", connection
, debugstr_guid(riid
), names
, count
, lcid
, dispid
);
180 hr
= get_typeinfo(Connection_tid
, &typeinfo
);
183 hr
= ITypeInfo_GetIDsOfNames(typeinfo
, names
, count
, dispid
);
184 ITypeInfo_Release(typeinfo
);
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
);
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
);
203 hr
= ITypeInfo_Invoke(typeinfo
, &connection
->Connection_iface
, member
, flags
, params
,
204 result
, excep_info
, arg_err
);
205 ITypeInfo_Release(typeinfo
);
211 static HRESULT WINAPI
connection_get_Properties( _Connection
*iface
, Properties
**obj
)
213 FIXME( "%p, %p\n", iface
, obj
);
217 static HRESULT WINAPI
connection_get_ConnectionString( _Connection
*iface
, BSTR
*str
)
219 struct connection
*connection
= impl_from_Connection( iface
);
222 TRACE( "%p, %p\n", connection
, str
);
224 if (connection
->datasource
&& !(source
= SysAllocString( connection
->datasource
))) return E_OUTOFMEMORY
;
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
;
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
;
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
;
258 static HRESULT WINAPI
connection_get_ConnectionTimeout( _Connection
*iface
, LONG
*timeout
)
260 FIXME( "%p, %p\n", iface
, timeout
);
264 static HRESULT WINAPI
connection_put_ConnectionTimeout( _Connection
*iface
, LONG timeout
)
266 FIXME( "%p, %ld\n", iface
, timeout
);
270 static HRESULT WINAPI
connection_get_Version( _Connection
*iface
, BSTR
*str
)
272 FIXME( "%p, %p\n", iface
, str
);
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
;
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
);
299 _Recordset
*recordset
;
300 VARIANT source
, active
;
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
);
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
);
321 _Recordset_Release(recordset
);
325 V_VT(&active
) = VT_DISPATCH
;
326 V_DISPATCH(&active
) = dispatch
;
328 hr
= _Recordset_Open(recordset
, source
, active
, adOpenDynamic
, adLockPessimistic
, 0);
329 VariantClear(&active
);
332 _Recordset_Release(recordset
);
336 if (records_affected
)
339 _Recordset_get_RecordCount(recordset
, &count
);
340 V_VT(records_affected
) = VT_I4
;
341 V_I4(records_affected
) = count
;
344 *record_set
= recordset
;
349 static HRESULT WINAPI
connection_BeginTrans( _Connection
*iface
, LONG
*transaction_level
)
351 FIXME( "%p, %p\n", iface
, transaction_level
);
355 static HRESULT WINAPI
connection_CommitTrans( _Connection
*iface
)
357 FIXME( "%p\n", iface
);
361 static HRESULT WINAPI
connection_RollbackTrans( _Connection
*iface
)
363 FIXME( "%p\n", iface
);
367 static HRESULT WINAPI
connection_Open( _Connection
*iface
, BSTR connect_str
, BSTR userid
, BSTR password
,
370 struct connection
*connection
= impl_from_Connection( iface
);
371 IDBProperties
*props
;
372 IDBInitialize
*dbinit
= NULL
;
373 IDataInitialize
*datainit
;
374 IDBCreateSession
*session
= NULL
;
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
);
401 if (hr
!= S_OK
&& connection
->session
)
403 IUnknown_Release( connection
->session
);
404 connection
->session
= NULL
;
408 IDBInitialize_Uninitialize( dbinit
);
409 IDBInitialize_Release( dbinit
);
411 IDataInitialize_Release( datainit
);
413 TRACE("ret 0x%08lx\n", hr
);
417 static HRESULT WINAPI
connection_get_Errors( _Connection
*iface
, Errors
**obj
)
419 FIXME( "%p, %p\n", iface
, obj
);
423 static HRESULT WINAPI
connection_get_DefaultDatabase( _Connection
*iface
, BSTR
*str
)
425 FIXME( "%p, %p\n", iface
, str
);
429 static HRESULT WINAPI
connection_put_DefaultDatabase( _Connection
*iface
, BSTR str
)
431 FIXME( "%p, %s\n", iface
, debugstr_w(str
) );
435 static HRESULT WINAPI
connection_get_IsolationLevel( _Connection
*iface
, IsolationLevelEnum
*level
)
437 FIXME( "%p, %p\n", iface
, level
);
441 static HRESULT WINAPI
connection_put_IsolationLevel( _Connection
*iface
, IsolationLevelEnum level
)
443 FIXME( "%p, %d\n", iface
, level
);
447 static HRESULT WINAPI
connection_get_Attributes( _Connection
*iface
, LONG
*attr
)
449 FIXME( "%p, %p\n", iface
, attr
);
453 static HRESULT WINAPI
connection_put_Attributes( _Connection
*iface
, LONG attr
)
455 FIXME( "%p, %ld\n", iface
, attr
);
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
);
542 static HRESULT WINAPI
connection_Cancel( _Connection
*iface
)
544 FIXME( "%p\n", iface
);
548 static const struct _ConnectionVtbl connection_vtbl
=
550 connection_QueryInterface
,
553 connection_GetTypeInfoCount
,
554 connection_GetTypeInfo
,
555 connection_GetIDsOfNames
,
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
,
567 connection_BeginTrans
,
568 connection_CommitTrans
,
569 connection_RollbackTrans
,
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
,
582 connection_get_Provider
,
583 connection_put_Provider
,
584 connection_get_State
,
585 connection_OpenSchema
,
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
) );
614 static const struct ISupportErrorInfoVtbl support_error_vtbl
=
616 supporterror_QueryInterface
,
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
);
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
);
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
;
688 FIXME( "interface %s not implemented\n", debugstr_guid( riid
) );
689 return E_NOINTERFACE
;
692 connection_AddRef( &connpoint
->conn
->Connection_iface
);
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
);
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
);
723 static HRESULT WINAPI
connpoint_Advise( IConnectionPoint
*iface
, IUnknown
*unk_sink
,
726 struct connection_point
*connpoint
= impl_from_IConnectionPoint( iface
);
727 IUnknown
*sink
, **tmp
;
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
)))
742 if (connpoint
->sinks
)
744 for (i
= 0; i
< connpoint
->sinks_size
; ++i
)
746 if (!connpoint
->sinks
[i
])
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
;
762 if (!(connpoint
->sinks
= calloc( 1, sizeof(*connpoint
->sinks
) ))) return E_OUTOFMEMORY
;
763 connpoint
->sinks_size
= 1;
767 connpoint
->sinks
[i
] = sink
;
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])
780 IUnknown_Release( connpoint
->sinks
[cookie
- 1] );
781 connpoint
->sinks
[cookie
- 1] = NULL
;
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
);
793 static const IConnectionPointVtbl connpoint_vtbl
=
795 connpoint_QueryInterface
,
798 connpoint_GetConnectionInterface
,
799 connpoint_GetConnectionPointContainer
,
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
);
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
;
837 IUnknown_AddRef(*session
);
841 static HRESULT WINAPI
adoconstruct_WrapDSOandSession(ADOConnectionConstruction15
*iface
, IUnknown
*dso
,
844 struct connection
*connection
= impl_from_ADOConnectionConstruction15( iface
);
845 FIXME("%p, %p, %p\n", connection
, dso
, session
);
849 struct ADOConnectionConstruction15Vtbl ado_construct_vtbl
=
851 adoconstruct_QueryInterface
,
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" )))
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
);